test/bonding: fix RSS test when disable RSS
[dpdk.git] / app / test-pmd / cmdline_flow.c
index af36975..cfd55c5 100644 (file)
@@ -95,6 +95,7 @@ enum index {
        FLEX,
        QUEUE,
        PUSH,
+       PULL,
 
        /* Flex arguments */
        FLEX_ITEM_INIT,
@@ -126,6 +127,7 @@ enum index {
        /* Queue arguments. */
        QUEUE_CREATE,
        QUEUE_DESTROY,
+       QUEUE_INDIRECT_ACTION,
 
        /* Queue create arguments. */
        QUEUE_CREATE_ID,
@@ -139,9 +141,32 @@ enum index {
        QUEUE_DESTROY_ID,
        QUEUE_DESTROY_POSTPONE,
 
+       /* Queue indirect action arguments */
+       QUEUE_INDIRECT_ACTION_CREATE,
+       QUEUE_INDIRECT_ACTION_UPDATE,
+       QUEUE_INDIRECT_ACTION_DESTROY,
+
+       /* Queue indirect action create arguments */
+       QUEUE_INDIRECT_ACTION_CREATE_ID,
+       QUEUE_INDIRECT_ACTION_INGRESS,
+       QUEUE_INDIRECT_ACTION_EGRESS,
+       QUEUE_INDIRECT_ACTION_TRANSFER,
+       QUEUE_INDIRECT_ACTION_CREATE_POSTPONE,
+       QUEUE_INDIRECT_ACTION_SPEC,
+
+       /* Queue indirect action update arguments */
+       QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
+
+       /* Queue indirect action destroy arguments */
+       QUEUE_INDIRECT_ACTION_DESTROY_ID,
+       QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE,
+
        /* Push arguments. */
        PUSH_QUEUE,
 
+       /* Pull arguments. */
+       PULL_QUEUE,
+
        /* Table arguments. */
        TABLE_CREATE,
        TABLE_DESTROY,
@@ -770,7 +795,8 @@ static const char *const modify_field_ids[] = {
        "tcp_seq_num", "tcp_ack_num", "tcp_flags",
        "udp_port_src", "udp_port_dst",
        "vxlan_vni", "geneve_vni", "gtp_teid",
-       "tag", "mark", "meta", "pointer", "value", NULL
+       "tag", "mark", "meta", "pointer", "value",
+       "ipv4_ecn", "ipv6_ecn", NULL
 };
 
 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -1131,6 +1157,7 @@ static const enum index next_table_destroy_attr[] = {
 static const enum index next_queue_subcmd[] = {
        QUEUE_CREATE,
        QUEUE_DESTROY,
+       QUEUE_INDIRECT_ACTION,
        ZERO,
 };
 
@@ -1140,6 +1167,36 @@ static const enum index next_queue_destroy_attr[] = {
        ZERO,
 };
 
+static const enum index next_qia_subcmd[] = {
+       QUEUE_INDIRECT_ACTION_CREATE,
+       QUEUE_INDIRECT_ACTION_UPDATE,
+       QUEUE_INDIRECT_ACTION_DESTROY,
+       ZERO,
+};
+
+static const enum index next_qia_create_attr[] = {
+       QUEUE_INDIRECT_ACTION_CREATE_ID,
+       QUEUE_INDIRECT_ACTION_INGRESS,
+       QUEUE_INDIRECT_ACTION_EGRESS,
+       QUEUE_INDIRECT_ACTION_TRANSFER,
+       QUEUE_INDIRECT_ACTION_CREATE_POSTPONE,
+       QUEUE_INDIRECT_ACTION_SPEC,
+       ZERO,
+};
+
+static const enum index next_qia_update_attr[] = {
+       QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE,
+       QUEUE_INDIRECT_ACTION_SPEC,
+       ZERO,
+};
+
+static const enum index next_qia_destroy_attr[] = {
+       QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE,
+       QUEUE_INDIRECT_ACTION_DESTROY_ID,
+       END,
+       ZERO,
+};
+
 static const enum index next_ia_create_attr[] = {
        INDIRECT_ACTION_CREATE_ID,
        INDIRECT_ACTION_INGRESS,
@@ -2256,9 +2313,18 @@ static int parse_qo(struct context *, const struct token *,
 static int parse_qo_destroy(struct context *, const struct token *,
                            const char *, unsigned int,
                            void *, unsigned int);
+static int parse_qia(struct context *, const struct token *,
+                    const char *, unsigned int,
+                    void *, unsigned int);
+static int parse_qia_destroy(struct context *, const struct token *,
+                            const char *, unsigned int,
+                            void *, unsigned int);
 static int parse_push(struct context *, const struct token *,
                      const char *, unsigned int,
                      void *, unsigned int);
+static int parse_pull(struct context *, const struct token *,
+                     const char *, unsigned int,
+                     void *, unsigned int);
 static int parse_tunnel(struct context *, const struct token *,
                        const char *, unsigned int,
                        void *, unsigned int);
@@ -2538,7 +2604,8 @@ static const struct token token_list[] = {
                              TUNNEL,
                              FLEX,
                              QUEUE,
-                             PUSH)),
+                             PUSH,
+                             PULL)),
                .call = parse_init,
        },
        /* Top-level command. */
@@ -2865,6 +2932,13 @@ static const struct token token_list[] = {
                .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
                .call = parse_qo_destroy,
        },
+       [QUEUE_INDIRECT_ACTION] = {
+               .name = "indirect_action",
+               .help = "queue indirect actions",
+               .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+               .call = parse_qia,
+       },
        /* Queue  arguments. */
        [QUEUE_TEMPLATE_TABLE] = {
                .name = "template table",
@@ -2918,6 +2992,90 @@ static const struct token token_list[] = {
                                            args.destroy.rule)),
                .call = parse_qo_destroy,
        },
+       /* Queue indirect action arguments */
+       [QUEUE_INDIRECT_ACTION_CREATE] = {
+               .name = "create",
+               .help = "create indirect action",
+               .next = NEXT(next_qia_create_attr),
+               .call = parse_qia,
+       },
+       [QUEUE_INDIRECT_ACTION_UPDATE] = {
+               .name = "update",
+               .help = "update indirect action",
+               .next = NEXT(next_qia_update_attr,
+                            NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+               .call = parse_qia,
+       },
+       [QUEUE_INDIRECT_ACTION_DESTROY] = {
+               .name = "destroy",
+               .help = "destroy indirect action",
+               .next = NEXT(next_qia_destroy_attr),
+               .call = parse_qia_destroy,
+       },
+       /* Indirect action destroy arguments. */
+       [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = {
+               .name = "postpone",
+               .help = "postpone destroy operation",
+               .next = NEXT(next_qia_destroy_attr,
+                            NEXT_ENTRY(COMMON_BOOLEAN)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+       },
+       [QUEUE_INDIRECT_ACTION_DESTROY_ID] = {
+               .name = "action_id",
+               .help = "specify a indirect action id to destroy",
+               .next = NEXT(next_qia_destroy_attr,
+                            NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+               .args = ARGS(ARGS_ENTRY_PTR(struct buffer,
+                                           args.ia_destroy.action_id)),
+               .call = parse_qia_destroy,
+       },
+       /* Indirect action update arguments. */
+       [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = {
+               .name = "postpone",
+               .help = "postpone update operation",
+               .next = NEXT(next_qia_update_attr,
+                            NEXT_ENTRY(COMMON_BOOLEAN)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+       },
+       /* Indirect action create arguments. */
+       [QUEUE_INDIRECT_ACTION_CREATE_ID] = {
+               .name = "action_id",
+               .help = "specify a indirect action id to create",
+               .next = NEXT(next_qia_create_attr,
+                            NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)),
+       },
+       [QUEUE_INDIRECT_ACTION_INGRESS] = {
+               .name = "ingress",
+               .help = "affect rule to ingress",
+               .next = NEXT(next_qia_create_attr),
+               .call = parse_qia,
+       },
+       [QUEUE_INDIRECT_ACTION_EGRESS] = {
+               .name = "egress",
+               .help = "affect rule to egress",
+               .next = NEXT(next_qia_create_attr),
+               .call = parse_qia,
+       },
+       [QUEUE_INDIRECT_ACTION_TRANSFER] = {
+               .name = "transfer",
+               .help = "affect rule to transfer",
+               .next = NEXT(next_qia_create_attr),
+               .call = parse_qia,
+       },
+       [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = {
+               .name = "postpone",
+               .help = "postpone create operation",
+               .next = NEXT(next_qia_create_attr,
+                            NEXT_ENTRY(COMMON_BOOLEAN)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, postpone)),
+       },
+       [QUEUE_INDIRECT_ACTION_SPEC] = {
+               .name = "action",
+               .help = "specify action to create indirect handle",
+               .next = NEXT(next_action),
+       },
        /* Top-level command. */
        [PUSH] = {
                .name = "push",
@@ -2934,6 +3092,21 @@ static const struct token token_list[] = {
                .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
        },
        /* Top-level command. */
+       [PULL] = {
+               .name = "pull",
+               .help = "pull flow operations results",
+               .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+               .call = parse_pull,
+       },
+       /* Sub-level commands. */
+       [PULL_QUEUE] = {
+               .name = "queue",
+               .help = "specify queue id",
+               .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, queue)),
+       },
+       /* Top-level command. */
        [INDIRECT_ACTION] = {
                .name = "indirect_action",
                .type = "{command} {port_id} [{arg} [...]]",
@@ -6478,6 +6651,110 @@ parse_ia_destroy(struct context *ctx, const struct token *token,
        return len;
 }
 
+/** Parse tokens for indirect action commands. */
+static int
+parse_qia(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 != QUEUE)
+                       return -1;
+               if (sizeof(*out) > size)
+                       return -1;
+               out->args.vc.data = (uint8_t *)out + size;
+               return len;
+       }
+       switch (ctx->curr) {
+       case QUEUE_INDIRECT_ACTION:
+               return len;
+       case QUEUE_INDIRECT_ACTION_CREATE:
+       case QUEUE_INDIRECT_ACTION_UPDATE:
+               out->args.vc.actions =
+                       (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
+                                              sizeof(double));
+               out->args.vc.attr.group = UINT32_MAX;
+               out->command = ctx->curr;
+               ctx->objdata = 0;
+               ctx->object = out;
+               ctx->objmask = NULL;
+               return len;
+       case QUEUE_INDIRECT_ACTION_EGRESS:
+               out->args.vc.attr.egress = 1;
+               return len;
+       case QUEUE_INDIRECT_ACTION_INGRESS:
+               out->args.vc.attr.ingress = 1;
+               return len;
+       case QUEUE_INDIRECT_ACTION_TRANSFER:
+               out->args.vc.attr.transfer = 1;
+               return len;
+       case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE:
+               return len;
+       default:
+               return -1;
+       }
+}
+
+/** Parse tokens for indirect action destroy command. */
+static int
+parse_qia_destroy(struct context *ctx, const struct token *token,
+                 const char *str, unsigned int len,
+                 void *buf, unsigned int size)
+{
+       struct buffer *out = buf;
+       uint32_t *action_id;
+
+       /* 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 || out->command == QUEUE) {
+               if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY)
+                       return -1;
+               if (sizeof(*out) > size)
+                       return -1;
+               out->command = ctx->curr;
+               ctx->objdata = 0;
+               ctx->object = out;
+               ctx->objmask = NULL;
+               out->args.ia_destroy.action_id =
+                       (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
+                                              sizeof(double));
+               return len;
+       }
+       switch (ctx->curr) {
+       case QUEUE_INDIRECT_ACTION:
+               out->command = ctx->curr;
+               ctx->objdata = 0;
+               ctx->object = out;
+               ctx->objmask = NULL;
+               return len;
+       case QUEUE_INDIRECT_ACTION_DESTROY_ID:
+               action_id = out->args.ia_destroy.action_id
+                               + out->args.ia_destroy.action_id_n++;
+               if ((uint8_t *)action_id > (uint8_t *)out + size)
+                       return -1;
+               ctx->objdata = 0;
+               ctx->object = action_id;
+               ctx->objmask = NULL;
+               return len;
+       case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE:
+               return len;
+       default:
+               return -1;
+       }
+}
+
 /** Parse tokens for meter policy action commands. */
 static int
 parse_mp(struct context *ctx, const struct token *token,
@@ -6588,6 +6865,14 @@ parse_vc(struct context *ctx, const struct token *token,
                ctx->object = out->args.vc.pattern;
                ctx->objmask = NULL;
                return len;
+       case ITEM_END:
+               if ((out->command == VALIDATE || out->command == CREATE) &&
+                   ctx->last)
+                       return -1;
+               if (out->command == PATTERN_TEMPLATE_CREATE &&
+                   !ctx->last)
+                       return -1;
+               break;
        case ACTIONS:
                out->args.vc.actions =
                        (void *)RTE_ALIGN_CEIL((uintptr_t)
@@ -8786,6 +9071,34 @@ parse_push(struct context *ctx, const struct token *token,
        return len;
 }
 
+/** Parse tokens for pull command. */
+static int
+parse_pull(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 != PULL)
+                       return -1;
+               if (sizeof(*out) > size)
+                       return -1;
+               out->command = ctx->curr;
+               ctx->objdata = 0;
+               ctx->object = out;
+               ctx->objmask = NULL;
+               out->args.vc.data = (uint8_t *)out + size;
+       }
+       return len;
+}
+
 static int
 parse_flex(struct context *ctx, const struct token *token,
             const char *str, unsigned int len,
@@ -9026,11 +9339,7 @@ parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
        const uint8_t *head = dst;
        uint32_t left;
 
-       /* Check input parameters */
-       if ((src == NULL) ||
-               (dst == NULL) ||
-               (size == NULL) ||
-               (*size == 0))
+       if (*size == 0)
                return -1;
 
        left = *size;
@@ -10174,6 +10483,32 @@ cmd_flow_parsed(const struct buffer *in)
        case PUSH:
                port_queue_flow_push(in->port, in->queue);
                break;
+       case PULL:
+               port_queue_flow_pull(in->port, in->queue);
+               break;
+       case QUEUE_INDIRECT_ACTION_CREATE:
+               port_queue_action_handle_create(
+                               in->port, in->queue, in->postpone,
+                               in->args.vc.attr.group,
+                               &((const struct rte_flow_indir_action_conf) {
+                                       .ingress = in->args.vc.attr.ingress,
+                                       .egress = in->args.vc.attr.egress,
+                                       .transfer = in->args.vc.attr.transfer,
+                               }),
+                               in->args.vc.actions);
+               break;
+       case QUEUE_INDIRECT_ACTION_DESTROY:
+               port_queue_action_handle_destroy(in->port,
+                                          in->queue, in->postpone,
+                                          in->args.ia_destroy.action_id_n,
+                                          in->args.ia_destroy.action_id);
+               break;
+       case QUEUE_INDIRECT_ACTION_UPDATE:
+               port_queue_action_handle_update(in->port,
+                                               in->queue, in->postpone,
+                                               in->args.vc.attr.group,
+                                               in->args.vc.actions);
+               break;
        case INDIRECT_ACTION_CREATE:
                port_action_handle_create(
                                in->port, in->args.vc.attr.group,
@@ -10636,7 +10971,8 @@ cmd_set_raw_parsed(const struct buffer *in)
                case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
                        opt = (const struct rte_flow_item_geneve_opt *)
                                                                item->spec;
-                       size = offsetof(struct rte_flow_item_geneve_opt, data);
+                       size = offsetof(struct rte_flow_item_geneve_opt,
+                                       option_len) + sizeof(uint8_t);
                        if (opt->option_len && opt->data) {
                                *total_size += opt->option_len *
                                               sizeof(uint32_t);
@@ -10893,16 +11229,16 @@ cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
        } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM);
 }
 
-cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
+static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show =
        TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
                        cmd_show, "show");
-cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
+static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what =
        TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
                        cmd_what, "raw_encap#raw_decap");
-cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
+static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index =
        TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result,
                        cmd_index, RTE_UINT16);
-cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
+static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all =
        TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result,
                        cmd_all, "all");
 cmdline_parse_inst_t cmd_show_set_raw = {