add test command to configure flexible masks for each flow type

Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
Acked-by: Chen Jing D(Mark) <jing.d.chen at intel.com>
Acked-by: Helin Zhang <helin.zhang at intel.com>
---
 app/test-pmd/cmdline.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 173 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index da77752..073b929 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -690,6 +690,11 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "flow_director_flex_payload (port_id)"
                        " (l2|l3|l4) (config)\n"
                        "    configure flexible payload selection.\n\n"
+
+                       "flow_director_flex_mask (port_id)"
+                       " flow (ether|ip4|tcp4|udp4|sctp4|ip6|tcp6|udp6|sctp6)"
+                       " words_mask (words) (word_mask_list)"
+                       "    configure masks of flexible payload.\n\n"
                );
        }
 }
@@ -8046,6 +8051,173 @@ cmdline_parse_inst_t cmd_set_flow_director_flex_payload 
= {
        },
 };

+/* *** deal with flow director mask on flexible payload *** */
+struct cmd_flow_director_flex_mask_result {
+       cmdline_fixed_string_t flow_director_flexmask;
+       uint8_t port_id;
+       cmdline_fixed_string_t flow;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t words_mask;
+       uint8_t words;
+       cmdline_fixed_string_t word_mask_list;
+};
+
+static inline int
+parse_word_masks_cfg(const char *q_arg,
+                            struct rte_eth_fdir_flex_masks *masks)
+{
+       char s[256];
+       const char *p, *p0 = q_arg;
+       char *end;
+       enum fieldnames {
+               FLD_OFFSET = 0,
+               FLD_MASK,
+               _NUM_FLD
+       };
+       unsigned long int_fld[_NUM_FLD];
+       char *str_fld[_NUM_FLD];
+       int i;
+       unsigned size;
+
+       masks->nb_field = 0;
+       p = strchr(p0, '(');
+       while (p != NULL) {
+               ++p;
+               p0 = strchr(p, ')');
+               if (p0 == NULL)
+                       return -1;
+
+               size = p0 - p;
+               if (size >= sizeof(s))
+                       return -1;
+
+               snprintf(s, sizeof(s), "%.*s", size, p);
+               if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != 
_NUM_FLD)
+                       return -1;
+               for (i = 0; i < _NUM_FLD; i++) {
+                       errno = 0;
+                       int_fld[i] = strtoul(str_fld[i], &end, 0);
+                       if (errno != 0 || end == str_fld[i] || int_fld[i] > 
UINT16_MAX)
+                               return -1;
+               }
+               masks->field[masks->nb_field].offset =
+                       (uint16_t)int_fld[FLD_OFFSET];
+               masks->field[masks->nb_field].bitmask =
+                       ~(uint16_t)int_fld[FLD_MASK];
+               masks->nb_field++;
+               if (masks->nb_field > 2) {
+                       printf("exceeded max number of fields: %hu\n",
+                               masks->nb_field);
+                       return -1;
+               }
+               p = strchr(p0, '(');
+       }
+       return 0;
+}
+
+static void
+cmd_flow_director_flex_mask_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_flex_mask_result *res = parsed_result;
+       struct rte_eth_fdir_flex_masks *flex_masks;
+       struct rte_eth_fdir_cfg fdir_cfg;
+       int ret = 0;
+       int cfg_size = 2 * sizeof(struct rte_eth_flex_mask) +
+                 offsetof(struct rte_eth_fdir_flex_masks, field);
+
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
+       if (ret < 0) {
+               printf("flow director is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       memset(&fdir_cfg, 0, sizeof(struct rte_eth_fdir_cfg));
+
+       flex_masks = (struct rte_eth_fdir_flex_masks *)rte_zmalloc_socket("CLI",
+               cfg_size, CACHE_LINE_SIZE, rte_socket_id());
+
+       if (flex_masks == NULL) {
+               printf("fail to malloc memory to configure flexi masks\n");
+               return;
+       }
+
+       if (!strcmp(res->flow_type, "ip4"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_IPV4_OTHER;
+       else if (!strcmp(res->flow_type, "udp4"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_UDPV4;
+       else if (!strcmp(res->flow_type, "tcp4"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_TCPV4;
+       else if (!strcmp(res->flow_type, "sctp4"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_SCTPV4;
+       else if (!strcmp(res->flow_type, "ip6"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_IPV6_OTHER;
+       else if (!strcmp(res->flow_type, "udp6"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_UDPV6;
+       else if (!strcmp(res->flow_type, "tcp6"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_TCPV6;
+       else if (!strcmp(res->flow_type, "sctp6"))
+               flex_masks->flow_type = RTE_ETH_FLOW_TYPE_SCTPV6;
+
+       flex_masks->words_mask = res->words;
+       ret = parse_word_masks_cfg(res->word_mask_list, flex_masks);
+       if (ret < 0) {
+               printf("fdir flex masks error\n");
+               rte_free(flex_masks);
+               return;
+       }
+
+       fdir_cfg.cmd = RTE_ETH_FDIR_CFG_FLX_MASK;
+       fdir_cfg.cfg = flex_masks;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                    RTE_ETH_FILTER_OP_SET, &fdir_cfg);
+       if (ret < 0)
+               printf("fdir flex mask setting error: (%s)\n", strerror(-ret));
+       rte_free(flex_masks);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_flexmask =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                flow_director_flexmask,
+                                "flow_director_flex_mask");
+cmdline_parse_token_num_t cmd_flow_director_flexmask_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                flow, "flow");
+cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                flow_type,
+                                "ip4#tcp4#udp4#sctp4#ip6#tcp6#udp6#sctp6");
+cmdline_parse_token_string_t cmd_flow_director_flexmask_words_mask =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                words_mask, "words_mask");
+cmdline_parse_token_num_t cmd_flow_director_flexmask_words =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                             words, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_flexmask_word_mask_list =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                word_mask_list, NULL);
+
+cmdline_parse_inst_t cmd_set_flow_director_flex_mask = {
+       .f = cmd_flow_director_flex_mask_parsed,
+       .data = NULL,
+       .help_str = "set flow director's flex masks on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_flexmask,
+               (void *)&cmd_flow_director_flexmask_port_id,
+               (void *)&cmd_flow_director_flexmask_flow,
+               (void *)&cmd_flow_director_flexmask_flow_type,
+               (void *)&cmd_flow_director_flexmask_words_mask,
+               (void *)&cmd_flow_director_flexmask_words,
+               (void *)&cmd_flow_director_flexmask_word_mask_list,
+               NULL,
+       },
+};
+
 /* 
********************************************************************************
 */

 /* list of instructions */
@@ -8177,6 +8349,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
        (cmdline_parse_inst_t *)&cmd_flush_flow_director,
        (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
        NULL,
 };

-- 
1.8.1.4

Reply via email to