[dpdk-dev] [PATCH v5 19/26] app/testpmd: add item raw to flow command

Zhao1, Wei wei.zhao1 at intel.com
Thu May 11 08:53:52 CEST 2017


Hi, Adrien

> -----Original Message-----
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Wednesday, December 21, 2016 10:52 PM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH v5 19/26] app/testpmd: add item raw to flow
> command
> 
> Matches arbitrary byte strings with properties:
> 
> - relative: look for pattern after the previous item.
> - search: search pattern from offset (see also limit).
> - offset: absolute or relative offset for pattern.
> - limit: search area limit for start of pattern.
> - length: pattern length.
> - pattern: byte string to look for.
> 
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
> Acked-by: Olga Shern <olgas at mellanox.com>
> ---
>  app/test-pmd/cmdline_flow.c | 208
> +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 208 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index 0592969..c52a8f7 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -57,6 +57,8 @@ enum index {
>  	INTEGER,
>  	UNSIGNED,
>  	PREFIX,
> +	BOOLEAN,
> +	STRING,
>  	RULE_ID,
>  	PORT_ID,
>  	GROUP_ID,
> @@ -106,6 +108,12 @@ enum index {
>  	ITEM_VF_ID,
>  	ITEM_PORT,
>  	ITEM_PORT_INDEX,
> +	ITEM_RAW,
> +	ITEM_RAW_RELATIVE,
> +	ITEM_RAW_SEARCH,
> +	ITEM_RAW_OFFSET,
> +	ITEM_RAW_LIMIT,
> +	ITEM_RAW_PATTERN,
> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -115,6 +123,13 @@ enum index {
>  	ACTION_PASSTHRU,
>  };
> 
> +/** Size of pattern[] field in struct rte_flow_item_raw. */ #define
> +ITEM_RAW_PATTERN_SIZE 36
> +
> +/** Storage size for struct rte_flow_item_raw including pattern. */
> +#define ITEM_RAW_SIZE \
> +	(offsetof(struct rte_flow_item_raw, pattern) +
> ITEM_RAW_PATTERN_SIZE)

#define  ITEM_RAW_PATTERN_SIZE 36

The size of NIC i350 flex byte filter can accommodate the max length size of 128 byte, and the reason to 
Define it as 36 is ?If it is the max length of pattern, maybe 128  is more appropriate? 
Maybe I have not understand your purpose.

Thank you.

> +
>  /** Maximum number of subsequent tokens and arguments on the stack.
> */  #define CTX_STACK_SIZE 16
> 
> @@ -216,6 +231,13 @@ struct token {
>  		.size = sizeof(*((s *)0)->f), \
>  	})
> 
> +/** Static initializer for ARGS() with arbitrary size. */ #define
> +ARGS_ENTRY_USZ(s, f, sz) \
> +	(&(const struct arg){ \
> +		.offset = offsetof(s, f), \
> +		.size = (sz), \
> +	})
> +
>  /** Parser output buffer layout expected by cmd_flow_parsed(). */  struct
> buffer {
>  	enum index command; /**< Flow command. */ @@ -306,6 +328,7
> @@ static const enum index next_item[] = {
>  	ITEM_PF,
>  	ITEM_VF,
>  	ITEM_PORT,
> +	ITEM_RAW,
>  	ZERO,
>  };
> 
> @@ -327,6 +350,16 @@ static const enum index item_port[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_raw[] = {
> +	ITEM_RAW_RELATIVE,
> +	ITEM_RAW_SEARCH,
> +	ITEM_RAW_OFFSET,
> +	ITEM_RAW_LIMIT,
> +	ITEM_RAW_PATTERN,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -363,11 +396,19 @@ static int parse_int(struct context *, const struct
> token *,  static int parse_prefix(struct context *, const struct token *,
>  			const char *, unsigned int,
>  			void *, unsigned int);
> +static int parse_boolean(struct context *, const struct token *,
> +			 const char *, unsigned int,
> +			 void *, unsigned int);
> +static int parse_string(struct context *, const struct token *,
> +			const char *, unsigned int,
> +			void *, unsigned int);
>  static int parse_port(struct context *, const struct token *,
>  		      const char *, unsigned int,
>  		      void *, unsigned int);
>  static int comp_none(struct context *, const struct token *,
>  		     unsigned int, char *, unsigned int);
> +static int comp_boolean(struct context *, const struct token *,
> +			unsigned int, char *, unsigned int);
>  static int comp_action(struct context *, const struct token *,
>  		       unsigned int, char *, unsigned int);  static int
> comp_port(struct context *, const struct token *, @@ -410,6 +451,20 @@
> static const struct token token_list[] = {
>  		.call = parse_prefix,
>  		.comp = comp_none,
>  	},
> +	[BOOLEAN] = {
> +		.name = "{boolean}",
> +		.type = "BOOLEAN",
> +		.help = "any boolean value",
> +		.call = parse_boolean,
> +		.comp = comp_boolean,
> +	},
> +	[STRING] = {
> +		.name = "{string}",
> +		.type = "STRING",
> +		.help = "fixed string",
> +		.call = parse_string,
> +		.comp = comp_none,
> +	},
>  	[RULE_ID] = {
>  		.name = "{rule id}",
>  		.type = "RULE ID",
> @@ -654,6 +709,52 @@ static const struct token token_list[] = {
>  		.next = NEXT(item_port, NEXT_ENTRY(UNSIGNED),
> item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port,
> index)),
>  	},
> +	[ITEM_RAW] = {
> +		.name = "raw",
> +		.help = "match an arbitrary byte string",
> +		.priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
> +		.next = NEXT(item_raw),
> +		.call = parse_vc,
> +	},
> +	[ITEM_RAW_RELATIVE] = {
> +		.name = "relative",
> +		.help = "look for pattern after the previous item",
> +		.next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN),
> item_param),
> +		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
> +					   relative, 1)),
> +	},
> +	[ITEM_RAW_SEARCH] = {
> +		.name = "search",
> +		.help = "search pattern from offset (see also limit)",
> +		.next = NEXT(item_raw, NEXT_ENTRY(BOOLEAN),
> item_param),
> +		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw,
> +					   search, 1)),
> +	},
> +	[ITEM_RAW_OFFSET] = {
> +		.name = "offset",
> +		.help = "absolute or relative offset for pattern",
> +		.next = NEXT(item_raw, NEXT_ENTRY(INTEGER),
> item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw,
> offset)),
> +	},
> +	[ITEM_RAW_LIMIT] = {
> +		.name = "limit",
> +		.help = "search area limit for start of pattern",
> +		.next = NEXT(item_raw, NEXT_ENTRY(UNSIGNED),
> item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)),
> +	},
> +	[ITEM_RAW_PATTERN] = {
> +		.name = "pattern",
> +		.help = "byte string to look for",
> +		.next = NEXT(item_raw,
> +			     NEXT_ENTRY(STRING),
> +			     NEXT_ENTRY(ITEM_PARAM_IS,
> +					ITEM_PARAM_SPEC,
> +					ITEM_PARAM_MASK)),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw,
> length),
> +			     ARGS_ENTRY_USZ(struct rte_flow_item_raw,
> +					    pattern,
> +					    ITEM_RAW_PATTERN_SIZE)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -1246,6 +1347,96 @@ parse_int(struct context *ctx, const struct token
> *token,
>  	return -1;
>  }
> 
> +/**
> + * Parse a string.
> + *
> + * Two arguments (ctx->args) are retrieved from the stack to store data
> +and
> + * its length (in that order).
> + */
> +static int
> +parse_string(struct context *ctx, const struct token *token,
> +	     const char *str, unsigned int len,
> +	     void *buf, unsigned int size)
> +{
> +	const struct arg *arg_data = pop_args(ctx);
> +	const struct arg *arg_len = pop_args(ctx);
> +	char tmp[16]; /* Ought to be enough. */
> +	int ret;
> +
> +	/* Arguments are expected. */
> +	if (!arg_data)
> +		return -1;
> +	if (!arg_len) {
> +		push_args(ctx, arg_data);
> +		return -1;
> +	}
> +	size = arg_data->size;
> +	/* Bit-mask fill is not supported. */
> +	if (arg_data->mask || size < len)
> +		goto error;
> +	if (!ctx->object)
> +		return len;
> +	/* Let parse_int() fill length information first. */
> +	ret = snprintf(tmp, sizeof(tmp), "%u", len);
> +	if (ret < 0)
> +		goto error;
> +	push_args(ctx, arg_len);
> +	ret = parse_int(ctx, token, tmp, ret, NULL, 0);
> +	if (ret < 0) {
> +		pop_args(ctx);
> +		goto error;
> +	}
> +	buf = (uint8_t *)ctx->object + arg_data->offset;
> +	/* Output buffer is not necessarily NUL-terminated. */
> +	memcpy(buf, str, len);
> +	memset((uint8_t *)buf + len, 0x55, size - len);
> +	if (ctx->objmask)
> +		memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff,
> len);
> +	return len;
> +error:
> +	push_args(ctx, arg_len);
> +	push_args(ctx, arg_data);
> +	return -1;
> +}
> +
> +/** Boolean values (even indices stand for false). */ static const char
> +*const boolean_name[] = {
> +	"0", "1",
> +	"false", "true",
> +	"no", "yes",
> +	"N", "Y",
> +	NULL,
> +};
> +
> +/**
> + * Parse a boolean value.
> + *
> + * Last argument (ctx->args) is retrieved to determine storage size and
> + * location.
> + */
> +static int
> +parse_boolean(struct context *ctx, const struct token *token,
> +	      const char *str, unsigned int len,
> +	      void *buf, unsigned int size)
> +{
> +	const struct arg *arg = pop_args(ctx);
> +	unsigned int i;
> +	int ret;
> +
> +	/* Argument is expected. */
> +	if (!arg)
> +		return -1;
> +	for (i = 0; boolean_name[i]; ++i)
> +		if (!strncmp(str, boolean_name[i], len))
> +			break;
> +	/* Process token as integer. */
> +	if (boolean_name[i])
> +		str = i & 1 ? "1" : "0";
> +	push_args(ctx, arg);
> +	ret = parse_int(ctx, token, str, strlen(str), buf, size);
> +	return ret > 0 ? (int)len : ret;
> +}
> +
>  /** Parse port and update context. */
>  static int
>  parse_port(struct context *ctx, const struct token *token, @@ -1284,6
> +1475,23 @@ comp_none(struct context *ctx, const struct token *token,
>  	return 0;
>  }
> 
> +/** Complete boolean values. */
> +static int
> +comp_boolean(struct context *ctx, const struct token *token,
> +	     unsigned int ent, char *buf, unsigned int size) {
> +	unsigned int i;
> +
> +	(void)ctx;
> +	(void)token;
> +	for (i = 0; boolean_name[i]; ++i)
> +		if (buf && i == ent)
> +			return snprintf(buf, size, "%s", boolean_name[i]);
> +	if (buf)
> +		return -1;
> +	return i;
> +}
> +
>  /** Complete action names. */
>  static int
>  comp_action(struct context *ctx, const struct token *token,
> --
> 2.1.4



More information about the dev mailing list