From mboxrd@z Thu Jan 1 00:00:00 1970 From: Adrien Mazarguil Subject: [PATCH 11/22] app/testpmd: add flow query command Date: Wed, 16 Nov 2016 17:23:37 +0100 Message-ID: <12249d4ce53dbb4e9a967fff6d75be165d0c34e4.1479309720.git.adrien.mazarguil@6wind.com> References: Cc: Thomas Monjalon , Pablo de Lara , Olivier Matz To: dev@dpdk.org Return-path: Received: from mail-wm0-f47.google.com (mail-wm0-f47.google.com [74.125.82.47]) by dpdk.org (Postfix) with ESMTP id 0A2CC5684 for ; Wed, 16 Nov 2016 17:24:32 +0100 (CET) Received: by mail-wm0-f47.google.com with SMTP id t79so83424941wmt.0 for ; Wed, 16 Nov 2016 08:24:32 -0800 (PST) In-Reply-To: List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Syntax: flow query {port_id} {rule_id} {action} Query a specific action of an existing flow rule. Signed-off-by: Adrien Mazarguil --- app/test-pmd/cmdline.c | 3 + app/test-pmd/cmdline_flow.c | 121 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 851cc16..edd1ee3 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -831,6 +831,9 @@ static void cmd_help_long_parsed(void *parsed_result, "flow flush {port_id}\n" " Destroy all flow rules.\n\n" + "flow query {port_id} {rule_id} {action}\n" + " Query an existing flow rule.\n\n" + "flow list {port_id} [group {group_id}] [...]\n" " List existing flow rules sorted by priority," " filtered by group identifiers.\n\n" diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 1874849..e70e8e2 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -69,11 +69,15 @@ enum index { CREATE, DESTROY, FLUSH, + QUERY, LIST, /* Destroy arguments. */ DESTROY_RULE, + /* Query arguments. */ + QUERY_ACTION, + /* List arguments. */ LIST_GROUP, @@ -208,6 +212,10 @@ struct buffer { uint32_t rule_n; } destroy; /**< Destroy arguments. */ struct { + uint32_t rule; + enum rte_flow_action_type action; + } query; /**< Query arguments. */ + struct { uint32_t *group; uint32_t group_n; } list; /**< List arguments. */ @@ -285,6 +293,12 @@ static int parse_destroy(struct context *, const struct token *, static int parse_flush(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_query(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); +static int parse_action(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_list(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -296,6 +310,8 @@ static int parse_port(struct context *, const struct token *, void *, unsigned int); static int comp_none(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 *, unsigned int, char *, unsigned int); static int comp_rule_id(struct context *, const struct token *, @@ -367,7 +383,8 @@ static const struct token token_list[] = { CREATE, DESTROY, FLUSH, - LIST)), + LIST, + QUERY)), .call = parse_init, }, /* Sub-level commands. */ @@ -399,6 +416,17 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY(struct buffer, port)), .call = parse_flush, }, + [QUERY] = { + .name = "query", + .help = "query an existing flow rule", + .next = NEXT(NEXT_ENTRY(QUERY_ACTION), + NEXT_ENTRY(RULE_ID), + NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action), + ARGS_ENTRY(struct buffer, args.query.rule), + ARGS_ENTRY(struct buffer, port)), + .call = parse_query, + }, [LIST] = { .name = "list", .help = "list existing flow rules", @@ -414,6 +442,14 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), .call = parse_destroy, }, + /* Query arguments. */ + [QUERY_ACTION] = { + .name = "{action}", + .type = "ACTION", + .help = "action to query, must be part of the rule", + .call = parse_action, + .comp = comp_action, + }, /* List arguments. */ [LIST_GROUP] = { .name = "group", @@ -730,6 +766,67 @@ parse_flush(struct context *ctx, const struct token *token, return len; } +/** Parse tokens for query command. */ +static int +parse_query(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != QUERY) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + } + return len; +} + +/** Parse action names. */ +static int +parse_action(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + const struct arg *arg = pop_args(ctx); + unsigned int i; + + (void)size; + /* Argument is expected. */ + if (!arg) + return -1; + /* Parse action name. */ + for (i = 0; next_action[i]; ++i) { + const struct parse_action_priv *priv; + + token = &token_list[next_action[i]]; + if (strncmp(token->name, str, len)) + continue; + priv = token->priv; + if (!priv) + goto error; + if (out) + memcpy((uint8_t *)ctx->object + arg->offset, + &priv->type, + arg->size); + return len; + } +error: + push_args(ctx, arg); + return -1; +} + /** Parse tokens for list command. */ static int parse_list(struct context *ctx, const struct token *token, @@ -853,6 +950,24 @@ comp_none(struct context *ctx, const struct token *token, return 0; } +/** Complete action names. */ +static int +comp_action(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; next_action[i]; ++i) + if (buf && i == ent) + return snprintf(buf, size, "%s", + token_list[next_action[i]].name); + if (buf) + return -1; + return i; +} + /** Complete available ports. */ static int comp_port(struct context *ctx, const struct token *token, @@ -1155,6 +1270,10 @@ cmd_flow_parsed(const struct buffer *in) case FLUSH: port_flow_flush(in->port); break; + case QUERY: + port_flow_query(in->port, in->args.query.rule, + in->args.query.action); + break; case LIST: port_flow_list(in->port, in->args.list.group_n, in->args.list.group); -- 2.1.4