[dpdk-dev] [PATCH v3 24/25] app/testpmd: add queue actions to flow command

Adrien Mazarguil adrien.mazarguil at 6wind.com
Mon Dec 19 18:49:14 CET 2016


- QUEUE: assign packets to a given queue index.
- DUP: duplicate packets to a given queue index.
- RSS: spread packets among several queues.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil at 6wind.com>
Acked-by: Olga Shern <olgas at mellanox.com>
---
 app/test-pmd/cmdline_flow.c | 152 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 90712bf..2376b8f 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -156,8 +156,15 @@ enum index {
 	ACTION_MARK,
 	ACTION_MARK_ID,
 	ACTION_FLAG,
+	ACTION_QUEUE,
+	ACTION_QUEUE_INDEX,
 	ACTION_DROP,
 	ACTION_COUNT,
+	ACTION_DUP,
+	ACTION_DUP_INDEX,
+	ACTION_RSS,
+	ACTION_RSS_QUEUES,
+	ACTION_RSS_QUEUE,
 	ACTION_PF,
 	ACTION_VF,
 	ACTION_VF_ORIGINAL,
@@ -171,6 +178,14 @@ enum index {
 #define ITEM_RAW_SIZE \
 	(offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
 
+/** Number of queue[] entries in struct rte_flow_action_rss. */
+#define ACTION_RSS_NUM 32
+
+/** Storage size for struct rte_flow_action_rss including queues. */
+#define ACTION_RSS_SIZE \
+	(offsetof(struct rte_flow_action_rss, queue) + \
+	 sizeof(*((struct rte_flow_action_rss *)0)->queue) * ACTION_RSS_NUM)
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -487,8 +502,11 @@ static const enum index next_action[] = {
 	ACTION_PASSTHRU,
 	ACTION_MARK,
 	ACTION_FLAG,
+	ACTION_QUEUE,
 	ACTION_DROP,
 	ACTION_COUNT,
+	ACTION_DUP,
+	ACTION_RSS,
 	ACTION_PF,
 	ACTION_VF,
 	ZERO,
@@ -500,6 +518,24 @@ static const enum index action_mark[] = {
 	ZERO,
 };
 
+static const enum index action_queue[] = {
+	ACTION_QUEUE_INDEX,
+	ACTION_NEXT,
+	ZERO,
+};
+
+static const enum index action_dup[] = {
+	ACTION_DUP_INDEX,
+	ACTION_NEXT,
+	ZERO,
+};
+
+static const enum index action_rss[] = {
+	ACTION_RSS_QUEUES,
+	ACTION_NEXT,
+	ZERO,
+};
+
 static const enum index action_vf[] = {
 	ACTION_VF_ORIGINAL,
 	ACTION_VF_ID,
@@ -517,6 +553,9 @@ static int parse_vc_spec(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 			 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_action_rss_queue(struct context *, const struct token *,
+				     const char *, unsigned int, void *,
+				     unsigned int);
 static int parse_destroy(struct context *, const struct token *,
 			 const char *, unsigned int,
 			 void *, unsigned int);
@@ -566,6 +605,8 @@ static int comp_port(struct context *, const struct token *,
 		     unsigned int, char *, unsigned int);
 static int comp_rule_id(struct context *, const struct token *,
 			unsigned int, char *, unsigned int);
+static int comp_vc_action_rss_queue(struct context *, const struct token *,
+				    unsigned int, char *, unsigned int);
 
 /** Token definitions. */
 static const struct token token_list[] = {
@@ -1163,6 +1204,21 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
+	[ACTION_QUEUE] = {
+		.name = "queue",
+		.help = "assign packets to a given queue index",
+		.priv = PRIV_ACTION(QUEUE,
+				    sizeof(struct rte_flow_action_queue)),
+		.next = NEXT(action_queue),
+		.call = parse_vc,
+	},
+	[ACTION_QUEUE_INDEX] = {
+		.name = "index",
+		.help = "queue index to use",
+		.next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+		.call = parse_vc_conf,
+	},
 	[ACTION_DROP] = {
 		.name = "drop",
 		.help = "drop packets (note: passthru has priority)",
@@ -1177,6 +1233,39 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
+	[ACTION_DUP] = {
+		.name = "dup",
+		.help = "duplicate packets to a given queue index",
+		.priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
+		.next = NEXT(action_dup),
+		.call = parse_vc,
+	},
+	[ACTION_DUP_INDEX] = {
+		.name = "index",
+		.help = "queue index to duplicate packets to",
+		.next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
+		.call = parse_vc_conf,
+	},
+	[ACTION_RSS] = {
+		.name = "rss",
+		.help = "spread packets among several queues",
+		.priv = PRIV_ACTION(RSS, ACTION_RSS_SIZE),
+		.next = NEXT(action_rss),
+		.call = parse_vc,
+	},
+	[ACTION_RSS_QUEUES] = {
+		.name = "queues",
+		.help = "queue indices to use",
+		.next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)),
+		.call = parse_vc_conf,
+	},
+	[ACTION_RSS_QUEUE] = {
+		.name = "{queue}",
+		.help = "queue index",
+		.call = parse_vc_action_rss_queue,
+		.comp = comp_vc_action_rss_queue,
+	},
 	[ACTION_PF] = {
 		.name = "pf",
 		.help = "redirect packets to physical device function",
@@ -1556,6 +1645,51 @@ parse_vc_conf(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/**
+ * Parse queue field for RSS action.
+ *
+ * Valid tokens are queue indices and the "end" token.
+ */
+static int
+parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
+			  const char *str, unsigned int len,
+			  void *buf, unsigned int size)
+{
+	static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE);
+	int ret;
+	int i;
+
+	(void)token;
+	(void)buf;
+	(void)size;
+	if (ctx->curr != ACTION_RSS_QUEUE)
+		return -1;
+	i = ctx->objdata >> 16;
+	if (!strncmp(str, "end", len)) {
+		ctx->objdata &= 0xffff;
+		return len;
+	}
+	if (i >= ACTION_RSS_NUM)
+		return -1;
+	if (push_args(ctx, ARGS_ENTRY(struct rte_flow_action_rss, queue[i])))
+		return -1;
+	ret = parse_int(ctx, token, str, len, NULL, 0);
+	if (ret < 0) {
+		pop_args(ctx);
+		return -1;
+	}
+	++i;
+	ctx->objdata = i << 16 | (ctx->objdata & 0xffff);
+	/* Repeat token. */
+	if (ctx->next_num == RTE_DIM(ctx->next))
+		return -1;
+	ctx->next[ctx->next_num++] = next;
+	if (!ctx->object)
+		return len;
+	((struct rte_flow_action_rss *)ctx->object)->num = i;
+	return len;
+}
+
 /** Parse tokens for destroy command. */
 static int
 parse_destroy(struct context *ctx, const struct token *token,
@@ -2130,6 +2264,24 @@ comp_rule_id(struct context *ctx, const struct token *token,
 	return i;
 }
 
+/** Complete queue field for RSS action. */
+static int
+comp_vc_action_rss_queue(struct context *ctx, const struct token *token,
+			 unsigned int ent, char *buf, unsigned int size)
+{
+	static const char *const str[] = { "", "end", NULL };
+	unsigned int i;
+
+	(void)ctx;
+	(void)token;
+	for (i = 0; str[i] != NULL; ++i)
+		if (buf && i == ent)
+			return snprintf(buf, size, "%s", str[i]);
+	if (buf)
+		return -1;
+	return i;
+}
+
 /** Internal context. */
 static struct context cmd_flow_context;
 
-- 
2.1.4



More information about the dev mailing list