From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 042B6A0548; Wed, 1 Jun 2022 16:15:18 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CA7B242B84; Wed, 1 Jun 2022 16:15:01 +0200 (CEST) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mails.dpdk.org (Postfix) with ESMTP id A0F5242B84 for ; Wed, 1 Jun 2022 16:14:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1654092899; x=1685628899; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=br5k1yihzz20Apwplp9d85LcvKjip54BLcuwKraetvc=; b=nJ0LFeWdiqgc7v6vNYPkUEJayK2Gh2OPkRp144LbDAKo3XDrB6ivhWW9 mbqn364tPWG7nRHaSsuRbjBtgoKlyWOrmRT1HpT7Q2ESLG1VSGqNcUnAm RtrXMxPjW0FwBe1BmxP/YghF58qYhrp2AWp8mYsl+FKD5sdDCnGTjmqcw KTUUGsF+yaqdqc7Gx5xPedGYxOzLIJiKHxJhXiAoxcy2uobvv5Suh93OI wslzI5nVvDv1isR4HSioNyl+L1zx0d3/aF7KZP9JIATRrxbO1gLpIK2Mx 4V1TV3KXW/Sv1P/0Vps8R+2IHMtMHWNsA1PXRb1m2QYDeVA7C2WvR53bu Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10365"; a="338647498" X-IronPort-AV: E=Sophos;i="5.91,268,1647327600"; d="scan'208";a="338647498" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jun 2022 07:14:59 -0700 X-IronPort-AV: E=Sophos;i="5.91,268,1647327600"; d="scan'208";a="606287186" Received: from unknown (HELO localhost.localdomain) ([10.239.251.3]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jun 2022 07:14:55 -0700 From: wenxuanx.wu@intel.com To: thomas@monjalon.net, andrew.rybchenko@oktetlabs.ru, xiaoyun.li@intel.com, ferruh.yigit@xilinx.com, aman.deep.singh@intel.com, dev@dpdk.org, yuying.zhang@intel.com, qi.z.zhang@intel.com, jerinjacobk@gmail.com Cc: stephen@networkplumber.org, Wenxuan Wu , Xuan Ding , Yuan Wang Subject: [PATCH v8 3/3] app/testpmd: add rxhdrs commands and parameters Date: Wed, 1 Jun 2022 13:50:59 +0000 Message-Id: <20220601135059.958882-5-wenxuanx.wu@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220601135059.958882-1-wenxuanx.wu@intel.com> References: <20220303060136.36427-1-xuan.ding@intel.com> <20220601135059.958882-1-wenxuanx.wu@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Wenxuan Wu Add command line parameter: --rxhdrs=mac,[ipv4,udp] Set the protocol_hdr of segments to scatter packets on receiving if split feature is engaged. And the queues with BUFFER_SPLIT flag. Add interative mode command: testpmd>set rxhdrs mac,ipv4,l3,tcp,udp,sctp (protocol sequence and nb_segs should be valid) The protocol split feature is off by default. To enable protocol split, you need: 1. Start testpmd with two mempools. e.g. --mbuf-size=2048,2048 2. Configure Rx queue with rx_offload buffer split on. 3. Set the protocol type of buffer split.e.g. set rxhdrs mac,ipv4 (Supported protocols: mac|ipv4|ipv6|l3|tcp|udp|sctp|l4|inner_mac| inner_ipv4|inner_ipv6|inner_l3|inner_tcp| inner_udp|inner_sctp|inner_l4) Signed-off-by: Wenxuan Wu Signed-off-by: Xuan Ding Signed-off-by: Yuan Wang Reviewed-by: Qi Zhang --- app/test-pmd/cmdline.c | 127 +++++++++++++++++++++++++++++++++++++- app/test-pmd/config.c | 81 ++++++++++++++++++++++++ app/test-pmd/parameters.c | 15 ++++- app/test-pmd/testpmd.c | 6 +- app/test-pmd/testpmd.h | 6 ++ 5 files changed, 228 insertions(+), 7 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 6ffea8e21a..52e98e1c06 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -183,7 +183,7 @@ static void cmd_help_long_parsed(void *parsed_result, "show (rxq|txq) info (port_id) (queue_id)\n" " Display information for configured RX/TX queue.\n\n" - "show config (rxtx|cores|fwd|rxoffs|rxpkts|txpkts)\n" + "show config (rxtx|cores|fwd|rxoffs|rxpkts|rxhdrs|txpkts)\n" " Display the given configuration.\n\n" "read rxd (port_id) (queue_id) (rxd_id)\n" @@ -316,6 +316,15 @@ static void cmd_help_long_parsed(void *parsed_result, " Affects only the queues configured with split" " offloads.\n\n" + "set rxhdrs (mac[,ipv4])*\n" + " Set the protocol hdr of each segment to scatter" + " packets on receiving if split feature is engaged." + " Affects only the queues configured with split" + " offloads.\n\n" + " Supported proto header: mac|ipv4|ipv6|l3|tcp|udp|sctp|l4|" + "inner_mac|inner_ipv4|inner_ipv6|inner_l3|inner_tcp|" + "inner_udp|inner_sctp\n" + "set txpkts (x[,y]*)\n" " Set the length of each segment of TXONLY" " and optionally CSUM packets.\n\n" @@ -3617,6 +3626,72 @@ cmdline_parse_inst_t cmd_stop = { }, }; +static unsigned int +get_ptype(char *value) +{ + uint32_t protocol; + if (!strcmp(value, "mac")) + protocol = RTE_PTYPE_L2_ETHER; + else if (!strcmp(value, "ipv4")) + protocol = RTE_PTYPE_L3_IPV4; + else if (!strcmp(value, "ipv6")) + protocol = RTE_PTYPE_L3_IPV6; + else if (!strcmp(value, "l3")) + protocol = RTE_PTYPE_L3_IPV4|RTE_PTYPE_L3_IPV6; + else if (!strcmp(value, "tcp")) + protocol = RTE_PTYPE_L4_TCP; + else if (!strcmp(value, "udp")) + protocol = RTE_PTYPE_L4_UDP; + else if (!strcmp(value, "sctp")) + protocol = RTE_PTYPE_L4_SCTP; + else if (!strcmp(value, "l4")) + protocol = RTE_PTYPE_L4_TCP|RTE_PTYPE_L4_UDP|RTE_PTYPE_L4_SCTP; + else if (!strcmp(value, "inner_mac")) + protocol = RTE_PTYPE_INNER_L2_ETHER; + else if (!strcmp(value, "inner_ipv4")) + protocol = RTE_PTYPE_INNER_L3_IPV4; + else if (!strcmp(value, "inner_ipv6")) + protocol = RTE_PTYPE_INNER_L3_IPV6; + else if (!strcmp(value, "inner_l3")) + protocol = RTE_PTYPE_INNER_L3_IPV4|RTE_PTYPE_INNER_L3_IPV6; + else if (!strcmp(value, "inner_tcp")) + protocol = RTE_PTYPE_INNER_L4_TCP; + else if (!strcmp(value, "inner_udp")) + protocol = RTE_PTYPE_INNER_L4_UDP; + else if (!strcmp(value, "inner_sctp")) + protocol = RTE_PTYPE_INNER_L4_SCTP; + else { + fprintf(stderr, "Unknown protocol name: %s\n", value); + return 0; + } + return protocol; +} +/* *** SET RXHDRSLIST *** */ + +unsigned int +parse_hdrs_list(const char *str, const char *item_name, unsigned int max_items, + unsigned int *parsed_items, int check_hdrs_sequence) +{ + unsigned int nb_item; + char *cur; + char *tmp; + nb_item = 0; + char *str2 = strdup(str); + cur = strtok_r(str2, ",", &tmp); + while (cur != NULL) { + parsed_items[nb_item] = get_ptype(cur); + cur = strtok_r(NULL, ",", &tmp); + nb_item++; + } + if (nb_item > max_items) + fprintf(stderr, "Number of %s = %u > %u (maximum items)\n", + item_name, nb_item + 1, max_items); + set_rx_pkt_hdrs(parsed_items, nb_item); + free(str2); + if (!check_hdrs_sequence) + return nb_item; + return nb_item; +} /* *** SET CORELIST and PORTLIST CONFIGURATION *** */ unsigned int @@ -3986,6 +4061,49 @@ cmdline_parse_inst_t cmd_set_rxpkts = { }, }; +/* *** SET SEGMENT HEADERS OF RX PACKETS SPLIT *** */ +struct cmd_set_rxhdrs_result { + cmdline_fixed_string_t cmd_keyword; + cmdline_fixed_string_t rxhdrs; + cmdline_fixed_string_t seg_hdrs; +}; + +static void +cmd_set_rxhdrs_parsed(void *parsed_result, + __rte_unused struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_set_rxhdrs_result *res; + unsigned int seg_hdrs[MAX_SEGS_BUFFER_SPLIT]; + unsigned int nb_segs; + + res = parsed_result; + nb_segs = parse_hdrs_list(res->seg_hdrs, "segment hdrs", + MAX_SEGS_BUFFER_SPLIT, seg_hdrs, 0); + if (nb_segs >= 1) + set_rx_pkt_hdrs(seg_hdrs, nb_segs); + cmd_reconfig_device_queue(RTE_PORT_ALL, 0, 1); +} +cmdline_parse_token_string_t cmd_set_rxhdrs_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result, + cmd_keyword, "set"); +cmdline_parse_token_string_t cmd_set_rxhdrs_name = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result, + rxhdrs, "rxhdrs"); +cmdline_parse_token_string_t cmd_set_rxhdrs_seg_hdrs = + TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result, + seg_hdrs, NULL); +cmdline_parse_inst_t cmd_set_rxhdrs = { + .f = cmd_set_rxhdrs_parsed, + .data = NULL, + .help_str = "set rxhdrs ", + .tokens = { + (void *)&cmd_set_rxhdrs_keyword, + (void *)&cmd_set_rxhdrs_name, + (void *)&cmd_set_rxhdrs_seg_hdrs, + NULL, + }, +}; /* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */ struct cmd_set_txpkts_result { @@ -8058,6 +8176,8 @@ static void cmd_showcfg_parsed(void *parsed_result, show_rx_pkt_offsets(); else if (!strcmp(res->what, "rxpkts")) show_rx_pkt_segments(); + else if (!strcmp(res->what, "rxhdrs")) + show_rx_pkt_hdrs(); else if (!strcmp(res->what, "txpkts")) show_tx_pkt_segments(); else if (!strcmp(res->what, "txtimes")) @@ -8070,12 +8190,12 @@ cmdline_parse_token_string_t cmd_showcfg_port = TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config"); cmdline_parse_token_string_t cmd_showcfg_what = TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what, - "rxtx#cores#fwd#rxoffs#rxpkts#txpkts#txtimes"); + "rxtx#cores#fwd#rxoffs#rxpkts#rxhdrs#txpkts#txtimes"); cmdline_parse_inst_t cmd_showcfg = { .f = cmd_showcfg_parsed, .data = NULL, - .help_str = "show config rxtx|cores|fwd|rxoffs|rxpkts|txpkts|txtimes", + .help_str = "show config rxtx|cores|fwd|rxoffs|rxpkts|rxhdrs|txpkts|txtimes", .tokens = { (void *)&cmd_showcfg_show, (void *)&cmd_showcfg_port, @@ -17833,6 +17953,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_set_log, (cmdline_parse_inst_t *)&cmd_set_rxoffs, (cmdline_parse_inst_t *)&cmd_set_rxpkts, + (cmdline_parse_inst_t *)&cmd_set_rxhdrs, (cmdline_parse_inst_t *)&cmd_set_txpkts, (cmdline_parse_inst_t *)&cmd_set_txsplit, (cmdline_parse_inst_t *)&cmd_set_txtimes, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index cc8e7aa138..742473456a 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -4757,6 +4757,87 @@ show_rx_pkt_segments(void) printf("%hu\n", rx_pkt_seg_lengths[i]); } } +static const char *get_ptype_str(uint32_t ptype) +{ + switch (ptype) { + case RTE_PTYPE_L2_ETHER: + return "mac"; + case RTE_PTYPE_L3_IPV4: + return "ipv4"; + case RTE_PTYPE_L3_IPV6: + return "ipv6"; + case RTE_PTYPE_L3_IPV6|RTE_PTYPE_L3_IPV4: + return "l3"; + case RTE_PTYPE_L4_TCP: + return "tcp"; + case RTE_PTYPE_L4_UDP: + return "udp"; + case RTE_PTYPE_L4_SCTP: + return "sctp"; + case RTE_PTYPE_L4_TCP|RTE_PTYPE_L4_UDP|RTE_PTYPE_L4_SCTP: + return "l4"; + case RTE_PTYPE_INNER_L2_ETHER: + return "inner_mac"; + case RTE_PTYPE_INNER_L3_IPV4: + return "inner_ipv4"; + case RTE_PTYPE_INNER_L3_IPV6: + return "inner_ipv6"; + case RTE_PTYPE_INNER_L4_TCP: + return "inner_tcp"; + case RTE_PTYPE_INNER_L4_UDP: + return "inner_udp"; + case RTE_PTYPE_INNER_L4_SCTP: + return "inner_sctp"; + default: + return "unknown"; + } +} +void +show_rx_pkt_hdrs(void) +{ + uint32_t i, n; + + n = rx_pkt_nb_segs; + printf("Number of segments: %u\n", n); + if (n) { + printf("Packet segs: "); + for (i = 0; i != n - 1; i++) + printf("%s, ", get_ptype_str(rx_pkt_hdr_protos[i])); + printf("%s\n", rx_pkt_hdr_protos[i] == 0 ? "payload" : + get_ptype_str(rx_pkt_hdr_protos[i])); + } +} +void +set_rx_pkt_hdrs(unsigned int *seg_hdrs, unsigned int nb_segs) +{ + unsigned int i; + + if (nb_segs >= MAX_SEGS_BUFFER_SPLIT) { + printf("nb segments per RX packets=%u >= " + "MAX_SEGS_BUFFER_SPLIT - ignored\n", nb_segs); + return; + } + + /* + * No extra check here, the segment length will be checked by PMD + * in the extended queue setup. + */ + for (i = 0; i < nb_segs; i++) { + if (!(seg_hdrs[i] & RTE_BUFFER_SPLIT_PROTO_HDR_MASK)) { + printf("ptype [%u]=%u > is not supported - give up\n", + i, seg_hdrs[i]); + return; + } + } + + for (i = 0; i < nb_segs; i++) + rx_pkt_hdr_protos[i] = (uint32_t) seg_hdrs[i]; + /* + * We calculate the number of hdrs, but payload is not included, + * so rx_pkt_nb_segs would increase 1. + */ + rx_pkt_nb_segs = (uint8_t) nb_segs + 1; +} void set_rx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs) diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index daf6a31b2b..f86d626276 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -161,6 +161,7 @@ usage(char* progname) " Used mainly with PCAP drivers.\n"); printf(" --rxoffs=X[,Y]*: set RX segment offsets for split.\n"); printf(" --rxpkts=X[,Y]*: set RX segment sizes to split.\n"); + printf(" --rxhdrs=mac[,ipv4]*: set RX segment protocol to split.\n"); printf(" --txpkts=X[,Y]*: set TX segment sizes" " or total packet length.\n"); printf(" --txonly-multi-flow: generate multiple flows in txonly mode\n"); @@ -673,6 +674,7 @@ launch_args_parse(int argc, char** argv) { "flow-isolate-all", 0, 0, 0 }, { "rxoffs", 1, 0, 0 }, { "rxpkts", 1, 0, 0 }, + { "rxhdrs", 1, 0, 0 }, { "txpkts", 1, 0, 0 }, { "txonly-multi-flow", 0, 0, 0 }, { "rxq-share", 2, 0, 0 }, @@ -1327,7 +1329,6 @@ launch_args_parse(int argc, char** argv) if (!strcmp(lgopts[opt_idx].name, "rxpkts")) { unsigned int seg_len[MAX_SEGS_BUFFER_SPLIT]; unsigned int nb_segs; - nb_segs = parse_item_list (optarg, "rxpkt segments", MAX_SEGS_BUFFER_SPLIT, @@ -1337,6 +1338,18 @@ launch_args_parse(int argc, char** argv) else rte_exit(EXIT_FAILURE, "bad rxpkts\n"); } + if (!strcmp(lgopts[opt_idx].name, "rxhdrs")) { + unsigned int seg_hdrs[MAX_SEGS_BUFFER_SPLIT]; + unsigned int nb_segs; + nb_segs = parse_hdrs_list + (optarg, "rxpkt segments", + MAX_SEGS_BUFFER_SPLIT, + seg_hdrs, 0); + if (nb_segs >= 1) + set_rx_pkt_hdrs(seg_hdrs, nb_segs); + else + rte_exit(EXIT_FAILURE, "bad rxpkts\n"); + } if (!strcmp(lgopts[opt_idx].name, "txpkts")) { unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT]; unsigned int nb_segs; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index fe2ce19f99..77379b7aa9 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -240,6 +240,7 @@ uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT]; uint8_t rx_pkt_nb_segs; /**< Number of segments to split */ uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT]; uint8_t rx_pkt_nb_offs; /**< Number of specified offsets */ +uint32_t rx_pkt_hdr_protos[MAX_SEGS_BUFFER_SPLIT]; /* * Configuration of packet segments used by the "txonly" processing engine. @@ -2586,12 +2587,11 @@ rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id, mp_n = (i > mbuf_data_size_n) ? mbuf_data_size_n - 1 : i; mpx = mbuf_pool_find(socket_id, mp_n); /* Handle zero as mbuf data buffer size. */ - rx_seg->length = rx_pkt_seg_lengths[i] ? - rx_pkt_seg_lengths[i] : - mbuf_data_size[mp_n]; + rx_seg->length = rx_pkt_seg_lengths[i]; rx_seg->offset = i < rx_pkt_nb_offs ? rx_pkt_seg_offsets[i] : 0; rx_seg->mp = mpx ? mpx : mp; + rx_seg->proto_hdr = rx_pkt_hdr_protos[i]; } rx_conf->rx_nseg = rx_pkt_nb_segs; rx_conf->rx_seg = rx_useg; diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 31f766c965..e791b9becd 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -534,6 +534,7 @@ extern uint32_t max_rx_pkt_len; * Configuration of packet segments used to scatter received packets * if some of split features is configured. */ +extern uint32_t rx_pkt_hdr_protos[MAX_SEGS_BUFFER_SPLIT]; extern uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT]; extern uint8_t rx_pkt_nb_segs; /**< Number of segments to split */ extern uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT]; @@ -864,6 +865,9 @@ inc_tx_burst_stats(struct fwd_stream *fs, uint16_t nb_tx) unsigned int parse_item_list(const char *str, const char *item_name, unsigned int max_items, unsigned int *parsed_items, int check_unique_values); +unsigned int parse_hdrs_list(const char *str, const char *item_name, + unsigned int max_item, + unsigned int *parsed_items, int check_unique_values); void launch_args_parse(int argc, char** argv); void cmdline_read_from_file(const char *filename); void prompt(void); @@ -1018,6 +1022,8 @@ void set_record_core_cycles(uint8_t on_off); void set_record_burst_stats(uint8_t on_off); void set_verbose_level(uint16_t vb_level); void set_rx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs); +void set_rx_pkt_hdrs(unsigned int *seg_protos, unsigned int nb_segs); +void show_rx_pkt_hdrs(void); void show_rx_pkt_segments(void); void set_rx_pkt_offsets(unsigned int *seg_offsets, unsigned int nb_offs); void show_rx_pkt_offsets(void); -- 2.25.1