> -----Original Message----- > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Jingjing Wu > Sent: Friday, September 26, 2014 7:04 AM > To: dev at dpdk.org > Subject: [dpdk-dev] [PATCH v3 20/20] app/test-pmd: add test command to > configure flexible masks > > 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);
masks->nb_field is an uint8_t, so you should change from %hu to %hhu or %PRIu8. > + 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