- 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>
---
 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 e166045..70e2b76 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -157,8 +157,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,
@@ -172,6 +179,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

@@ -489,8 +504,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,
        0,
@@ -502,6 +520,24 @@ static const enum index action_mark[] = {
        0,
 };

+static const enum index action_queue[] = {
+       ACTION_QUEUE_INDEX,
+       ACTION_NEXT,
+       0,
+};
+
+static const enum index action_dup[] = {
+       ACTION_DUP_INDEX,
+       ACTION_NEXT,
+       0,
+};
+
+static const enum index action_rss[] = {
+       ACTION_RSS_QUEUES,
+       ACTION_NEXT,
+       0,
+};
+
 static const enum index action_vf[] = {
        ACTION_VF_ORIGINAL,
        ACTION_VF_ID,
@@ -519,6 +555,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);
@@ -568,6 +607,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[] = {
@@ -1169,6 +1210,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)",
@@ -1183,6 +1239,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",
@@ -1562,6 +1651,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 const 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)->queues = i;
+       return len;
+}
+
 /** Parse tokens for destroy command. */
 static int
 parse_destroy(struct context *ctx, const struct token *token,
@@ -2136,6 +2270,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

Reply via email to