From: Gregory Etelson <getel...@nvidia.com>

Syntax:
actions .. indirect_list handle H conf C ..

H references shared action resources related to that handle.
C references configuration array:
if H was created from a list of actions A1 / A2 / ... / END,
C[i] points to a flow configuration update of A[i].

Signed-off-by: Gregory Etelson <getel...@nvidia.com>
---
 app/test-pmd/cmdline_flow.c | 227 +++++++++++++++++++++++++++++++++---
 app/test-pmd/config.c       |   5 +-
 app/test-pmd/testpmd.h      |   2 +-
 3 files changed, 215 insertions(+), 19 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7eb8e045b4..1644328bf4 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -66,6 +66,7 @@ enum index {
        COMMON_ACTIONS_TEMPLATE_ID,
        COMMON_TABLE_ID,
        COMMON_QUEUE_ID,
+       COMMON_METER_COLOR_NAME,
 
        /* TOP-level command. */
        ADD,
@@ -253,6 +254,7 @@ enum index {
        /* Indirect action arguments */
        INDIRECT_ACTION_CREATE,
        INDIRECT_ACTION_LIST_CREATE,
+       INDIRECT_ACTION_FLOW_CONF_CREATE,
        INDIRECT_ACTION_UPDATE,
        INDIRECT_ACTION_DESTROY,
        INDIRECT_ACTION_QUERY,
@@ -265,6 +267,7 @@ enum index {
        INDIRECT_ACTION_TRANSFER,
        INDIRECT_ACTION_SPEC,
        INDIRECT_ACTION_LIST,
+       INDIRECT_ACTION_FLOW_CONF,
 
        /* Indirect action destroy arguments */
        INDIRECT_ACTION_DESTROY_ID,
@@ -529,7 +532,6 @@ enum index {
        ITEM_PPP_PROTO_ID,
        ITEM_METER,
        ITEM_METER_COLOR,
-       ITEM_METER_COLOR_NAME,
        ITEM_QUOTA,
        ITEM_QUOTA_STATE,
        ITEM_QUOTA_STATE_NAME,
@@ -585,6 +587,8 @@ enum index {
        ACTION_METER_COLOR_RED,
        ACTION_METER_ID,
        ACTION_METER_MARK,
+       ACTION_METER_MARK_CONF,
+       ACTION_METER_MARK_CONF_COLOR,
        ACTION_METER_PROFILE,
        ACTION_METER_PROFILE_ID2PTR,
        ACTION_METER_POLICY,
@@ -669,6 +673,10 @@ enum index {
        ACTION_SAMPLE_INDEX_VALUE,
        ACTION_INDIRECT,
        ACTION_INDIRECT_LIST,
+       ACTION_INDIRECT_LIST_HANDLE,
+       ACTION_INDIRECT_LIST_CONF,
+       INDIRECT_LIST_ACTION_ID2PTR_HANDLE,
+       INDIRECT_LIST_ACTION_ID2PTR_CONF,
        ACTION_SHARED_INDIRECT,
        INDIRECT_ACTION_ID2PTR,
        ACTION_MODIFY_FIELD,
@@ -1366,6 +1374,7 @@ static const enum index next_ia_create_attr[] = {
        INDIRECT_ACTION_TRANSFER,
        INDIRECT_ACTION_SPEC,
        INDIRECT_ACTION_LIST,
+       INDIRECT_ACTION_FLOW_CONF,
        ZERO,
 };
 
@@ -1375,6 +1384,13 @@ static const enum index next_ia[] = {
        ZERO
 };
 
+static const enum index next_ial[] = {
+       ACTION_INDIRECT_LIST_HANDLE,
+       ACTION_INDIRECT_LIST_CONF,
+       ACTION_NEXT,
+       ZERO
+};
+
 static const enum index next_shia[] = {
        COMMON_INDIRECT_ACTION_PORT,
        ACTION_NEXT,
@@ -2075,6 +2091,7 @@ static const enum index next_action[] = {
        ACTION_METER,
        ACTION_METER_COLOR,
        ACTION_METER_MARK,
+       ACTION_METER_MARK_CONF,
        ACTION_OF_DEC_NW_TTL,
        ACTION_OF_POP_VLAN,
        ACTION_OF_PUSH_VLAN,
@@ -2754,6 +2771,10 @@ static int parse_ia_destroy(struct context *ctx, const 
struct token *token,
 static int parse_ia_id2ptr(struct context *ctx, const struct token *token,
                           const char *str, unsigned int len, void *buf,
                           unsigned int size);
+
+static int parse_indlst_id2ptr(struct context *ctx, const struct token *token,
+                              const char *str, unsigned int len, void *buf,
+                              unsigned int size);
 static int parse_ia_port(struct context *ctx, const struct token *token,
                         const char *str, unsigned int len, void *buf,
                         unsigned int size);
@@ -2842,6 +2863,16 @@ static int comp_insertion_table_type(struct context *, 
const struct token *,
 static int comp_hash_table_type(struct context *, const struct token *,
                                unsigned int, char *, unsigned int);
 
+struct indlst_conf {
+       uint32_t id;
+       uint32_t conf_num;
+       struct rte_flow_action *actions;
+       const void **conf;
+       SLIST_ENTRY(indlst_conf) next;
+};
+
+static const struct indlst_conf *indirect_action_list_conf_get(uint32_t 
conf_id);
+
 /** Token definitions. */
 static const struct token token_list[] = {
        /* Special tokens. */
@@ -3026,6 +3057,12 @@ static const struct token token_list[] = {
                .call = parse_int,
                .comp = comp_queue_id,
        },
+       [COMMON_METER_COLOR_NAME] = {
+               .name = "color_name",
+               .help = "meter color name",
+               .call = parse_meter_color,
+               .comp = comp_meter_color,
+       },
        /* Top-level command. */
        [FLOW] = {
                .name = "flow",
@@ -5769,17 +5806,11 @@ static const struct token token_list[] = {
                .name = "color",
                .help = "meter color",
                .next = NEXT(item_meter,
-                            NEXT_ENTRY(ITEM_METER_COLOR_NAME),
+                            NEXT_ENTRY(COMMON_METER_COLOR_NAME),
                             item_param),
                .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color,
                                        color)),
        },
-       [ITEM_METER_COLOR_NAME] = {
-               .name = "color_name",
-               .help = "meter color name",
-               .call = parse_meter_color,
-               .comp = comp_meter_color,
-       },
        [ITEM_QUOTA] = {
                .name = "quota",
                .help = "match quota",
@@ -6165,6 +6196,23 @@ static const struct token token_list[] = {
                .next = NEXT(action_meter_mark),
                .call = parse_vc,
        },
+       [ACTION_METER_MARK_CONF] = {
+               .name = "meter_mark_conf",
+               .help = "meter mark configuration",
+               .priv = PRIV_ACTION(METER_MARK,
+                                   sizeof(struct rte_flow_action_meter_mark)),
+               .next = NEXT(NEXT_ENTRY(ACTION_METER_MARK_CONF_COLOR)),
+               .call = parse_vc,
+       },
+       [ACTION_METER_MARK_CONF_COLOR] = {
+               .name = "mtr_update_init_color",
+               .help = "meter update init color",
+               .next = NEXT(NEXT_ENTRY(ACTION_NEXT),
+                            NEXT_ENTRY(COMMON_METER_COLOR_NAME)),
+               .args = ARGS(ARGS_ENTRY
+                            (struct rte_flow_indirect_update_flow_meter_mark,
+                             init_color)),
+       },
        [ACTION_METER_PROFILE] = {
                .name = "mtr_profile",
                .help = "meter profile id to use",
@@ -7277,11 +7325,36 @@ static const struct token token_list[] = {
        [ACTION_INDIRECT_LIST] = {
                .name = "indirect_list",
                .help = "apply indirect list action by id",
-               .priv = PRIV_ACTION(INDIRECT_LIST, 0),
-               .next = NEXT(next_ia),
-               .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))),
+               .priv = PRIV_ACTION(INDIRECT_LIST,
+                                   sizeof(struct
+                                          rte_flow_action_indirect_list)),
+               .next = NEXT(next_ial),
                .call = parse_vc,
        },
+       [ACTION_INDIRECT_LIST_HANDLE] = {
+               .name = "handle",
+               .help = "indirect list handle",
+               .next = NEXT(next_ial, 
NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)),
+               .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))),
+       },
+       [ACTION_INDIRECT_LIST_CONF] = {
+               .name = "conf",
+               .help = "indirect list configuration",
+               .next = NEXT(next_ial, 
NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)),
+               .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uintptr_t))),
+       },
+       [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = {
+               .type = "UNSIGNED",
+               .help = "unsigned integer value",
+               .call = parse_indlst_id2ptr,
+//             .comp = comp_none,
+       },
+       [INDIRECT_LIST_ACTION_ID2PTR_CONF] = {
+               .type = "UNSIGNED",
+               .help = "unsigned integer value",
+               .call = parse_indlst_id2ptr,
+//             .comp = comp_none,
+       },
        [ACTION_SHARED_INDIRECT] = {
                .name = "shared_indirect",
                .help = "apply indirect action by id and port",
@@ -7336,6 +7409,12 @@ static const struct token token_list[] = {
                .next = NEXT(NEXT_ENTRY(ACTIONS, END)),
                .call = parse_ia,
        },
+       [INDIRECT_ACTION_FLOW_CONF] = {
+               .name = "flow_conf",
+               .help = "specify actions configuration for indirect handle 
list",
+               .next = NEXT(NEXT_ENTRY(ACTIONS, END)),
+               .call = parse_ia,
+       },
        [ACTION_POL_G] = {
                .name = "g_actions",
                .help = "submit a list of associated actions for green",
@@ -7811,6 +7890,9 @@ parse_ia(struct context *ctx, const struct token *token,
        case INDIRECT_ACTION_LIST:
                out->command = INDIRECT_ACTION_LIST_CREATE;
                return len;
+        case INDIRECT_ACTION_FLOW_CONF:
+               out->command = INDIRECT_ACTION_FLOW_CONF_CREATE;
+               return len;
        default:
                return -1;
        }
@@ -11317,6 +11399,49 @@ parse_ia_id2ptr(struct context *ctx, const struct 
token *token,
        return ret;
 }
 
+static int
+parse_indlst_id2ptr(struct context *ctx, const struct token *token,
+                   const char *str, unsigned int len,
+                   void __rte_unused *buf, unsigned int __rte_unused size)
+{
+       struct rte_flow_action *action = ctx->object;
+       struct rte_flow_action_indirect_list *action_conf;
+       const struct indlst_conf *indlst_conf;
+       uint32_t id;
+       int ret;
+
+       if (!action)
+               return -1;
+       ctx->objdata = 0;
+       ctx->object = &id;
+       ctx->objmask = NULL;
+       ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id));
+       if (ret != (int)len)
+               return ret;
+       ctx->object = action;
+       action_conf = (void *)(uintptr_t)action->conf;
+       action_conf->conf = NULL;
+       switch (ctx->curr) {
+       case INDIRECT_LIST_ACTION_ID2PTR_HANDLE:
+        action_conf->handle = (typeof(action_conf->handle))
+                               port_action_handle_get_by_id(ctx->port, id);
+               if (!action_conf->handle) {
+                       printf("no indirect list handle for id %u\n", id);
+                       return -1;
+               }
+               break;
+       case INDIRECT_LIST_ACTION_ID2PTR_CONF:
+               indlst_conf = indirect_action_list_conf_get(id);
+               if (!indlst_conf)
+                       return -1;
+               action_conf->conf = (const void **)indlst_conf->conf;
+               break;
+       default:
+               break;
+       }
+       return ret;
+}
+
 static int
 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token,
                const char *str, unsigned int len,
@@ -11549,11 +11674,10 @@ parse_meter_color(struct context *ctx, const struct 
token *token,
                  const char *str, unsigned int len, void *buf,
                  unsigned int size)
 {
-       struct rte_flow_item_meter_color *meter_color;
        unsigned int i;
+       struct buffer *out = buf;
 
        (void)token;
-       (void)buf;
        (void)size;
        for (i = 0; meter_colors[i]; ++i)
                if (!strcmp_partial(meter_colors[i], str, len))
@@ -11562,8 +11686,18 @@ parse_meter_color(struct context *ctx, const struct 
token *token,
                return -1;
        if (!ctx->object)
                return len;
-       meter_color = ctx->object;
-       meter_color->color = (enum rte_color)i;
+       if (ctx->prev == ACTION_METER_MARK_CONF_COLOR) {
+               struct rte_flow_action *action =
+                       out->args.vc.actions + out->args.vc.actions_n - 1;
+               const struct arg *arg = pop_args(ctx);
+
+               if (!arg)
+                       return -1;
+               *(int *)RTE_PTR_ADD(action->conf, arg->offset) = i;
+       } else {
+               ((struct rte_flow_item_meter_color *)
+                       ctx->object)->color = (enum rte_color)i;
+       }
        return len;
 }
 
@@ -12356,6 +12490,64 @@ cmd_flow_tok(cmdline_parse_token_hdr_t **hdr,
        *hdr = &cmd_flow_token_hdr;
 }
 
+static SLIST_HEAD(, indlst_conf) indlst_conf_head =
+       SLIST_HEAD_INITIALIZER();
+
+static void
+indirect_action_flow_conf_create(const struct buffer *in)
+{
+       int len, ret;
+       uint32_t i;
+       struct indlst_conf *indlst_conf = NULL;
+       size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8);
+       struct rte_flow_action *src = in->args.vc.actions;
+
+       if (!in->args.vc.actions_n)
+               goto end;
+       len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL);
+       if (len <= 0)
+               goto end;
+       len = RTE_ALIGN(len, 16);
+
+       indlst_conf = calloc(1, base + len +
+                            in->args.vc.actions_n * sizeof(uintptr_t));
+       if (!indlst_conf)
+               goto end;
+       indlst_conf->id = in->args.vc.attr.group;
+       indlst_conf->conf_num = in->args.vc.actions_n - 1;
+       indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base);
+       ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions,
+                           len, src, NULL);
+       if (ret <= 0) {
+               free(indlst_conf);
+               indlst_conf = NULL;
+               goto end;
+       }
+       indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len);
+       for (i = 0; i < indlst_conf->conf_num; i++)
+               indlst_conf->conf[i] = indlst_conf->actions[i].conf;
+       SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next);
+end:
+       if (indlst_conf)
+        printf("created indirect action list configuration %u\n",
+               in->args.vc.attr.group);
+       else
+        printf("cannot create indirect action list configuration %u\n",
+               in->args.vc.attr.group);
+}
+
+static const struct indlst_conf *
+indirect_action_list_conf_get(uint32_t conf_id)
+{
+       const struct indlst_conf *conf;
+
+       SLIST_FOREACH(conf, &indlst_conf_head, next) {
+               if (conf->id == conf_id)
+                       return conf;
+       }
+       return NULL;
+}
+
 /** Dispatch parsed buffer to function calls. */
 static void
 cmd_flow_parsed(const struct buffer *in)
@@ -12479,6 +12671,7 @@ cmd_flow_parsed(const struct buffer *in)
        case INDIRECT_ACTION_LIST_CREATE:
                port_action_handle_create(
                                in->port, in->args.vc.attr.group,
+                               in->command == INDIRECT_ACTION_LIST_CREATE,
                                &((const struct rte_flow_indir_action_conf) {
                                        .ingress = in->args.vc.attr.ingress,
                                        .egress = in->args.vc.attr.egress,
@@ -12486,6 +12679,9 @@ cmd_flow_parsed(const struct buffer *in)
                                }),
                                in->args.vc.actions);
                break;
+       case INDIRECT_ACTION_FLOW_CONF_CREATE:
+               indirect_action_flow_conf_create(in);
+               break;
        case INDIRECT_ACTION_DESTROY:
                port_action_handle_destroy(in->port,
                                           in->args.ia_destroy.action_id_n,
@@ -12563,6 +12759,7 @@ cmd_flow_parsed(const struct buffer *in)
        default:
                break;
        }
+       fflush(stdout);
 }
 
 /** Token generator and output processing callback (cmdline API). */
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 36cfa7fe95..5ae4cb9a25 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1780,21 +1780,20 @@ action_list_handle_create(portid_t port_id,
 }
 /** Create indirect action */
 int
-port_action_handle_create(portid_t port_id, uint32_t id,
+port_action_handle_create(portid_t port_id, uint32_t id, bool indirect_list,
                          const struct rte_flow_indir_action_conf *conf,
                          const struct rte_flow_action *action)
 {
        struct port_indirect_action *pia;
        int ret;
        struct rte_flow_error error;
-       bool is_indirect_list = action[1].type != RTE_FLOW_ACTION_TYPE_END;
 
        ret = action_alloc(port_id, id, &pia);
        if (ret)
                return ret;
        /* Poisoning to make sure PMDs update it in case of error. */
        memset(&error, 0x22, sizeof(error));
-       ret = is_indirect_list ?
+       ret = indirect_list ?
               action_list_handle_create(port_id, pia, conf, action, &error) :
               action_handle_create(port_id, pia, conf, action, &error);
        if (ret) {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index eed5c70608..2e888cb2f9 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -903,7 +903,7 @@ void update_fwd_ports(portid_t new_pid);
 void set_fwd_eth_peer(portid_t port_id, char *peer_addr);
 
 void port_mtu_set(portid_t port_id, uint16_t mtu);
-int port_action_handle_create(portid_t port_id, uint32_t id,
+int port_action_handle_create(portid_t port_id, uint32_t id, bool 
indirect_list,
                              const struct rte_flow_indir_action_conf *conf,
                              const struct rte_flow_action *action);
 int port_action_handle_destroy(portid_t port_id,
-- 
2.18.1

Reply via email to