From patchwork Wed Nov 16 16:23:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrien Mazarguil X-Patchwork-Id: 17035 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 6A3D4D4A2; Wed, 16 Nov 2016 17:25:25 +0100 (CET) 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) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6w9dpyDM3UxcCTVcZPidX/Ft1wNAUOkiwVfw8479eK4=; b=m8YcG0L2hzcVVsgYWvvGqTIixVuwyKEoIFJPZ5Kze1smPH+bX8xzn7JFLYU+7Udr9g rm5Wm3A0P0kFxtlvoCB275VodJgRR6DtuHJWr4QTa8SStdhwpuXOsZEKI7LaRAMdQx+n 6BRUMZyIf34asjsxd3/6I6vGmWmuM5gsSClTVeFHKXSedhlLj5g1yRzIlyX6c30BfFhK 3Otrwr4hzPHkUVlJQQ7bAS0iba/Fci9JQI2NLVEcDfxE89GWOdF5aejV3c6hAnZd14HV LvJlNVMaWGFaLBsgCxfdUI/u8xgIyJNCq5rt0ABwGXjSdCwX072J3hGh+20Ugs3Zmwv0 WcIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6w9dpyDM3UxcCTVcZPidX/Ft1wNAUOkiwVfw8479eK4=; b=kSFv0ImTmXpVzUT8gQ6g4Jc+vLkPo9xTyFpOND76Tw8Dg+T0U+y75OVxGOKQIlovU2 NModw2h+15gBjfnzJqShpzj2J1JAMNdGLPTQYi4FQ/LVGnlrVo4LvtVywxV2hla0FhRX t9OQNvG2MLGZ3ceHdADhsWufJ14KvRG5GiceP9dgTq21045yDcuzJGSqxEvFO4sZeQok LnApHMNd86b8joTzrHgHMj0LId9saojbP0x9gAeq11JupTpYq0kfrVJq0jDW6Aa/NgYx OEVeUoE95VRP06CYueBGwYJhvuWa6MkfPTbjMl0tOeEq1TqaJAlIPSUb+n+Hg09RGtNn TWIg== X-Gm-Message-State: ABUngveGV8F29Yjhg4cU3SQ4iG6eAjQsVgFUhy3s4qS2KGOrz8xQ+ApUzcaGUxn+NL5luKbp X-Received: by 10.28.167.139 with SMTP id q133mr12037940wme.15.1479313472573; Wed, 16 Nov 2016 08:24:32 -0800 (PST) Received: from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net. [82.239.227.177]) by smtp.gmail.com with ESMTPSA id 191sm7855573wmr.11.2016.11.16.08.24.29 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 16 Nov 2016 08:24:31 -0800 (PST) From: Adrien Mazarguil To: dev@dpdk.org Cc: Thomas Monjalon , Pablo de Lara , Olivier Matz Date: Wed, 16 Nov 2016 17:23:37 +0100 Message-Id: <12249d4ce53dbb4e9a967fff6d75be165d0c34e4.1479309720.git.adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: Subject: [dpdk-dev] [PATCH 11/22] app/testpmd: add flow query command X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list 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);