From: Qi Zhang <qi.z.zhang@intel.com>
To: aman.deep.singh@intel.com, yuying.zhang@intel.com
Cc: dev@dpdk.org, cristian.dumitrescu@intel.com, orika@nvidia.com,
ferruh.yigit@amd.com, Qi Zhang <qi.z.zhang@intel.com>
Subject: [PATCH v4] app/testpmd: enable cli for programmable action
Date: Sat, 7 Oct 2023 06:47:30 -0400 [thread overview]
Message-ID: <20231007104730.441719-1-qi.z.zhang@intel.com> (raw)
In-Reply-To: <20231005100246.242970-1-qi.z.zhang@intel.com>
Parsing command line for rte_flow_action_prog.
Syntax:
"prog name <name> [arguments <arg_name_0> <arg_value_0> \
<arg_name_1> <arg_value1> ... end]"
Use parse_string0 to parse name string.
Use parse_hex to parse hex string.
Use struct action_prog_data to store parsed result.
Example:
Action with 2 arguments:
"prog name action0 arguments field0 03FF field1 55AA end"
Action without argument:
"prog name action1"
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
v4:
- be more generous on the max size of name and value.
v3:
- refine struct action_prog_data
- enlarge the max size
v2:
- fix title
- minor coding style refine.
app/test-pmd/cmdline_flow.c | 232 ++++++++++++++++++++++++++++++++++++
1 file changed, 232 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 21828c144c..ae5556e704 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -719,6 +719,13 @@ enum index {
ACTION_IPV6_EXT_PUSH,
ACTION_IPV6_EXT_PUSH_INDEX,
ACTION_IPV6_EXT_PUSH_INDEX_VALUE,
+ ACTION_PROG,
+ ACTION_PROG_NAME,
+ ACTION_PROG_NAME_STRING,
+ ACTION_PROG_ARGUMENTS,
+ ACTION_PROG_ARG_NAME,
+ ACTION_PROG_ARG_VALUE,
+ ACTION_PROG_ARG_END,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -749,6 +756,23 @@ struct action_rss_data {
uint16_t queue[ACTION_RSS_QUEUE_NUM];
};
+#define ACTION_PROG_NAME_SIZE_MAX 256
+#define ACTION_PROG_ARG_NUM_MAX 16
+#define ACTION_PROG_ARG_VALUE_SIZE_MAX 64
+
+/** Storage for struct rte_flow_action_prog including external data. */
+struct action_prog_data {
+ struct rte_flow_action_prog conf;
+ struct {
+ char name[ACTION_PROG_NAME_SIZE_MAX];
+ struct rte_flow_action_prog_argument args[ACTION_PROG_ARG_NUM_MAX];
+ struct {
+ char names[ACTION_PROG_NAME_SIZE_MAX];
+ uint8_t value[ACTION_PROG_ARG_VALUE_SIZE_MAX];
+ } arg_data[ACTION_PROG_ARG_NUM_MAX];
+ } data;
+};
+
/** Maximum data size in struct rte_flow_action_raw_encap. */
#define ACTION_RAW_ENCAP_MAX_DATA 512
#define RAW_ENCAP_CONFS_MAX_NUM 8
@@ -2169,6 +2193,7 @@ static const enum index next_action[] = {
ACTION_QUOTA_QU,
ACTION_IPV6_EXT_REMOVE,
ACTION_IPV6_EXT_PUSH,
+ ACTION_PROG,
ZERO,
};
@@ -2510,6 +2535,13 @@ static const enum index action_represented_port[] = {
ZERO,
};
+static const enum index action_prog[] = {
+ ACTION_PROG_NAME,
+ ACTION_PROG_ARGUMENTS,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -2786,6 +2818,18 @@ static int
parse_qu_mode_name(struct context *ctx, const struct token *token,
const char *str, unsigned int len, void *buf,
unsigned int size);
+static int
+parse_vc_action_prog(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_name(struct context *, const struct token *,
+ const char *, unsigned int, void *,
+ unsigned int);
+static int
+parse_vc_action_prog_arg_value(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 *,
@@ -7518,6 +7562,48 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue,
tx_queue)),
},
+ [ACTION_PROG] = {
+ .name = "prog",
+ .help = "match a programmable action",
+ .priv = PRIV_ACTION(PROG, sizeof(struct action_prog_data)),
+ .next = NEXT(action_prog),
+ .call = parse_vc_action_prog,
+ },
+ [ACTION_PROG_NAME] = {
+ .name = "name",
+ .help = "programble action name",
+ .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_NAME_STRING)),
+ .args = ARGS(ARGS_ENTRY(struct action_prog_data, data.name)),
+ },
+ [ACTION_PROG_NAME_STRING] = {
+ .name = "{string}",
+ .type = "STRING",
+ .help = "programmable action name string",
+ .call = parse_string0,
+ },
+ [ACTION_PROG_ARGUMENTS] = {
+ .name = "arguments",
+ .help = "programmable action name",
+ .next = NEXT(action_prog, NEXT_ENTRY(ACTION_PROG_ARG_NAME)),
+ .call = parse_vc_conf,
+ },
+ [ACTION_PROG_ARG_NAME] = {
+ .name = "{string}",
+ .help = "programmable action argument name",
+ .next = NEXT(NEXT_ENTRY(ACTION_PROG_ARG_VALUE)),
+ .call = parse_vc_action_prog_arg_name,
+ },
+ [ACTION_PROG_ARG_VALUE] = {
+ .name = "{hex}",
+ .help = "programmable action argument value",
+ .next = NEXT(NEXT_ENTRY(ACTION_PROG_ARG_END, ACTION_PROG_ARG_NAME)),
+ .call = parse_vc_action_prog_arg_value,
+ },
+ [ACTION_PROG_ARG_END] = {
+ .name = "end",
+ .help = "end of the programmable action arguments",
+ },
+
};
/** Remove and return last entry from argument stack. */
@@ -11675,6 +11761,152 @@ parse_qu_mode_name(struct context *ctx, const struct token *token,
(uint32_t *)&out->args.ia.qu_mode);
}
+/** Parse prog action. */
+static int
+parse_vc_action_prog(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct buffer *out = buf;
+ struct rte_flow_action *action;
+ struct action_prog_data *action_prog_data;
+ uint16_t i;
+ int ret;
+
+ ret = parse_vc(ctx, token, str, len, buf, size);
+ if (ret < 0)
+ return ret;
+
+ if (!out)
+ return ret;
+
+ if (!out->args.vc.actions_n)
+ return -1;
+
+ action = &out->args.vc.actions[out->args.vc.actions_n - 1];
+ ctx->object = out->args.vc.data;
+ action_prog_data = ctx->object;
+ *action_prog_data = (struct action_prog_data) {
+ .conf = (struct rte_flow_action_prog) {
+ .args_num = 0,
+ .name = action_prog_data->data.name,
+ .args = action_prog_data->data.args,
+ },
+ };
+
+ for (i = 0; i < ACTION_PROG_ARG_NUM_MAX; ++i)
+ action_prog_data->data.args[i].name = action_prog_data->data.arg_data[i].names;
+ action->conf = &action_prog_data->conf;
+
+ return ret;
+}
+
+static int
+parse_vc_action_prog_arg_name(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct action_prog_data *action_prog_data;
+ struct buffer *out = buf;
+ const struct arg *arg;
+ uint32_t i;
+ int ret;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ACTION_PROG_ARG_NAME)
+ return -1;
+
+ if (!out)
+ return len;
+
+ action_prog_data = (void *)out->args.vc.data;
+ i = action_prog_data->conf.args_num;
+
+ if (i >= ACTION_PROG_ARG_NUM_MAX)
+ return -1;
+
+ arg = ARGS_ENTRY_ARB(offsetof(struct action_prog_data,
+ data.arg_data[i].names),
+ ACTION_PROG_NAME_SIZE_MAX);
+
+ if (push_args(ctx, arg))
+ return -1;
+
+ ret = parse_string0(ctx, token, str, len, NULL, 0);
+ if (ret < 0) {
+ pop_args(ctx);
+ return -1;
+ }
+
+ return len;
+}
+
+static int
+parse_vc_action_prog_arg_value(struct context *ctx, const struct token *token,
+ const char *str, unsigned int len,
+ void *buf, unsigned int size)
+{
+ struct action_prog_data *action_prog_data;
+ const struct arg *arg_addr;
+ const struct arg *arg_size;
+ const struct arg *arg_data;
+ struct buffer *out = buf;
+ uint32_t i;
+ int ret;
+
+ (void)token;
+ (void)buf;
+ (void)size;
+ if (ctx->curr != ACTION_PROG_ARG_VALUE)
+ return -1;
+
+ if (!out)
+ return len;
+
+ action_prog_data = (void *)out->args.vc.data;
+ i = action_prog_data->conf.args_num;
+
+ arg_addr = ARGS_ENTRY_ARB(offsetof(struct action_prog_data,
+ data.args[i].value),
+ sizeof(action_prog_data->data.args[i].value));
+
+ arg_size = ARGS_ENTRY_ARB(offsetof(struct action_prog_data,
+ data.args[i].size),
+ sizeof(action_prog_data->data.args[i].size));
+
+ arg_data = ARGS_ENTRY_ARB(offsetof(struct action_prog_data,
+ data.arg_data[i].value),
+ ACTION_PROG_ARG_VALUE_SIZE_MAX);
+
+ if (push_args(ctx, arg_addr))
+ return -1;
+
+ if (push_args(ctx, arg_size)) {
+ pop_args(ctx);
+ return -1;
+ }
+
+ if (push_args(ctx, arg_data)) {
+ pop_args(ctx);
+ pop_args(ctx);
+ return -1;
+ }
+
+ ret = parse_hex(ctx, token, str, len, NULL, 0);
+ if (ret < 0) {
+ pop_args(ctx);
+ pop_args(ctx);
+ pop_args(ctx);
+ return -1;
+ }
+
+ action_prog_data->conf.args_num++;
+
+ return len;
+}
+
/** No completion. */
static int
comp_none(struct context *ctx, const struct token *token,
--
2.31.1
next prev parent reply other threads:[~2023-10-07 2:27 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-05 10:02 [PATCH 1/2] " Qi Zhang
2023-10-05 11:42 ` [PATCH v2] " Qi Zhang
2023-10-05 4:32 ` Stephen Hemminger
2023-10-06 2:37 ` Zhang, Qi Z
2023-10-06 11:07 ` [PATCH v3] " Qi Zhang
2023-10-06 12:35 ` Dumitrescu, Cristian
2023-10-07 1:50 ` Zhang, Qi Z
2023-10-07 10:47 ` Qi Zhang [this message]
2023-10-08 0:06 ` [PATCH v4] " Dumitrescu, Cristian
2023-10-10 10:49 ` Ferruh Yigit
2023-10-11 2:24 ` Zhang, Qi Z
2023-10-11 10:20 ` Ferruh Yigit
2023-10-11 13:19 ` Zhang, Qi Z
2023-10-12 0:04 ` Zhang, Qi Z
2023-10-12 1:32 ` Stephen Hemminger
2023-10-27 11:06 ` Zhang, Qi Z
2023-10-11 11:58 ` [PATCH v5] " Qi Zhang
2023-10-11 12:03 ` [PATCH v6] " Qi Zhang
2024-02-08 1:10 ` Ferruh Yigit
2024-04-18 15:39 ` Ferruh Yigit
2024-10-07 18:12 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231007104730.441719-1-qi.z.zhang@intel.com \
--to=qi.z.zhang@intel.com \
--cc=aman.deep.singh@intel.com \
--cc=cristian.dumitrescu@intel.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
--cc=orika@nvidia.com \
--cc=yuying.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).