From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Zhao1, Wei" Subject: Re: [PATCH v5 19/26] app/testpmd: add item raw to flow command Date: Thu, 11 May 2017 06:53:52 +0000 Message-ID: References: <180091c2bf814c846abbbfb1c2c50e9ec32d7324.1482331076.git.adrien.mazarguil@6wind.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Cc: "Xing, Beilei" , "Lu, Wenzhuo" To: Adrien Mazarguil , "dev@dpdk.org" Return-path: Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 3D3301C00 for ; Thu, 11 May 2017 08:54:22 +0200 (CEST) In-Reply-To: <180091c2bf814c846abbbfb1c2c50e9ec32d7324.1482331076.git.adrien.mazarguil@6wind.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi, Adrien > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil > Sent: Wednesday, December 21, 2016 10:52 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [PATCH v5 19/26] app/testpmd: add item raw to flow > command >=20 > Matches arbitrary byte strings with properties: >=20 > - 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. >=20 > Signed-off-by: Adrien Mazarguil > Acked-by: Olga Shern > --- > app/test-pmd/cmdline_flow.c | 208 > +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 208 insertions(+) >=20 > 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, >=20 > /* Validate/create actions. */ > ACTIONS, > @@ -115,6 +123,13 @@ enum index { > ACTION_PASSTHRU, > }; >=20 > +/** 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 o= f 128 byte, and the reason to=20 Define it as 36 is ?If it is the max length of pattern, maybe 128 is more = appropriate?=20 Maybe I have not understand your purpose. Thank you. > + > /** Maximum number of subsequent tokens and arguments on the stack. > */ #define CTX_STACK_SIZE 16 >=20 > @@ -216,6 +231,13 @@ struct token { > .size =3D sizeof(*((s *)0)->f), \ > }) >=20 > +/** Static initializer for ARGS() with arbitrary size. */ #define > +ARGS_ENTRY_USZ(s, f, sz) \ > + (&(const struct arg){ \ > + .offset =3D offsetof(s, f), \ > + .size =3D (sz), \ > + }) > + > /** Parser output buffer layout expected by cmd_flow_parsed(). */ struc= t > buffer { > enum index command; /**< Flow command. */ @@ -306,6 +328,7 > @@ static const enum index next_item[] =3D { > ITEM_PF, > ITEM_VF, > ITEM_PORT, > + ITEM_RAW, > ZERO, > }; >=20 > @@ -327,6 +350,16 @@ static const enum index item_port[] =3D { > ZERO, > }; >=20 > +static const enum index item_raw[] =3D { > + ITEM_RAW_RELATIVE, > + ITEM_RAW_SEARCH, > + ITEM_RAW_OFFSET, > + ITEM_RAW_LIMIT, > + ITEM_RAW_PATTERN, > + ITEM_NEXT, > + ZERO, > +}; > + > static const enum index next_action[] =3D { > 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[] =3D { > .call =3D parse_prefix, > .comp =3D comp_none, > }, > + [BOOLEAN] =3D { > + .name =3D "{boolean}", > + .type =3D "BOOLEAN", > + .help =3D "any boolean value", > + .call =3D parse_boolean, > + .comp =3D comp_boolean, > + }, > + [STRING] =3D { > + .name =3D "{string}", > + .type =3D "STRING", > + .help =3D "fixed string", > + .call =3D parse_string, > + .comp =3D comp_none, > + }, > [RULE_ID] =3D { > .name =3D "{rule id}", > .type =3D "RULE ID", > @@ -654,6 +709,52 @@ static const struct token token_list[] =3D { > .next =3D NEXT(item_port, NEXT_ENTRY(UNSIGNED), > item_param), > .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_port, > index)), > }, > + [ITEM_RAW] =3D { > + .name =3D "raw", > + .help =3D "match an arbitrary byte string", > + .priv =3D PRIV_ITEM(RAW, ITEM_RAW_SIZE), > + .next =3D NEXT(item_raw), > + .call =3D parse_vc, > + }, > + [ITEM_RAW_RELATIVE] =3D { > + .name =3D "relative", > + .help =3D "look for pattern after the previous item", > + .next =3D NEXT(item_raw, NEXT_ENTRY(BOOLEAN), > item_param), > + .args =3D ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, > + relative, 1)), > + }, > + [ITEM_RAW_SEARCH] =3D { > + .name =3D "search", > + .help =3D "search pattern from offset (see also limit)", > + .next =3D NEXT(item_raw, NEXT_ENTRY(BOOLEAN), > item_param), > + .args =3D ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, > + search, 1)), > + }, > + [ITEM_RAW_OFFSET] =3D { > + .name =3D "offset", > + .help =3D "absolute or relative offset for pattern", > + .next =3D NEXT(item_raw, NEXT_ENTRY(INTEGER), > item_param), > + .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_raw, > offset)), > + }, > + [ITEM_RAW_LIMIT] =3D { > + .name =3D "limit", > + .help =3D "search area limit for start of pattern", > + .next =3D NEXT(item_raw, NEXT_ENTRY(UNSIGNED), > item_param), > + .args =3D ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), > + }, > + [ITEM_RAW_PATTERN] =3D { > + .name =3D "pattern", > + .help =3D "byte string to look for", > + .next =3D NEXT(item_raw, > + NEXT_ENTRY(STRING), > + NEXT_ENTRY(ITEM_PARAM_IS, > + ITEM_PARAM_SPEC, > + ITEM_PARAM_MASK)), > + .args =3D 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] =3D { > .name =3D "actions", > @@ -1246,6 +1347,96 @@ parse_int(struct context *ctx, const struct token > *token, > return -1; > } >=20 > +/** > + * 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 =3D pop_args(ctx); > + const struct arg *arg_len =3D 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 =3D 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 =3D snprintf(tmp, sizeof(tmp), "%u", len); > + if (ret < 0) > + goto error; > + push_args(ctx, arg_len); > + ret =3D parse_int(ctx, token, tmp, ret, NULL, 0); > + if (ret < 0) { > + pop_args(ctx); > + goto error; > + } > + buf =3D (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[] =3D { > + "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 =3D pop_args(ctx); > + unsigned int i; > + int ret; > + > + /* Argument is expected. */ > + if (!arg) > + return -1; > + for (i =3D 0; boolean_name[i]; ++i) > + if (!strncmp(str, boolean_name[i], len)) > + break; > + /* Process token as integer. */ > + if (boolean_name[i]) > + str =3D i & 1 ? "1" : "0"; > + push_args(ctx, arg); > + ret =3D 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; > } >=20 > +/** 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 =3D 0; boolean_name[i]; ++i) > + if (buf && i =3D=3D 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