From: Xuan Ding <xuan.d...@intel.com>

This patch adds header split configuration in testpmd. The header split
feature is off by default. To enable header split, you need:
1. Configure Rx queue with rx_offload header split on.
2. Set the protocol type of header split.

Command for set header split protocol type:
testpmd> port config <port_id> header_split 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: Xuan Ding <xuan.d...@intel.com>
Signed-off-by: Yuan Wang <yuanx.w...@intel.com>
---
 app/test-pmd/cmdline.c | 117 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.c |   6 ++-
 app/test-pmd/testpmd.h |   2 +
 3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6ffea8e21a..abda81b4bc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -866,6 +866,12 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "     Enable or disable a per port Rx offloading"
                        " on all Rx queues of a port\n\n"
 
+                       "port config <port_id> header_split 
mac|ipv4|ipv6|l3|tcp|udp|sctp|l4|"
+                       "inner_mac|inner_ipv4|inner_ipv6|inner_l3|inner_tcp|"
+                       "inner_udp|inner_sctp|inner_l4\n"
+                       "     Configure protocol for header split"
+                       " on all Rx queues of a port\n\n"
+
                        "port (port_id) rxq (queue_id) rx_offload vlan_strip|"
                        "ipv4_cksum|udp_cksum|tcp_cksum|tcp_lro|qinq_strip|"
                        "outer_ipv4_cksum|macsec_strip|header_split|"
@@ -16353,6 +16359,116 @@ cmdline_parse_inst_t cmd_config_per_port_rx_offload = 
{
        }
 };
 
+/* config a per port header split protocol */
+struct cmd_config_per_port_headersplit_protocol_result {
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t config;
+       uint16_t port_id;
+       cmdline_fixed_string_t headersplit;
+       cmdline_fixed_string_t protocol;
+};
+
+cmdline_parse_token_string_t 
cmd_config_per_port_headersplit_protocol_result_port =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_config_per_port_headersplit_protocol_result,
+                port, "port");
+cmdline_parse_token_string_t 
cmd_config_per_port_headersplit_protocol_result_config =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_config_per_port_headersplit_protocol_result,
+                config, "config");
+cmdline_parse_token_num_t 
cmd_config_per_port_headersplit_protocol_result_port_id =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_config_per_port_headersplit_protocol_result,
+                port_id, RTE_UINT16);
+cmdline_parse_token_string_t 
cmd_config_per_port_headersplit_protocol_result_headersplit =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_config_per_port_headersplit_protocol_result,
+                headersplit, "header_split");
+cmdline_parse_token_string_t 
cmd_config_per_port_headersplit_protocol_result_protocol =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_config_per_port_headersplit_protocol_result,
+                protocol, "mac#ipv4#ipv6#l3#tcp#udp#sctp#l4#"
+                          "inner_mac#inner_ipv4#inner_ipv6#inner_l3#inner_tcp#"
+                          "inner_udp#inner_sctp#inner_l4");
+
+static void
+cmd_config_per_port_headersplit_protocol_parsed(void *parsed_result,
+                               __rte_unused struct cmdline *cl,
+                               __rte_unused void *data)
+{
+       struct cmd_config_per_port_headersplit_protocol_result *res = 
parsed_result;
+       portid_t port_id = res->port_id;
+       struct rte_port *port = &ports[port_id];
+       uint16_t protocol;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       if (port->port_status != RTE_PORT_STOPPED) {
+               fprintf(stderr,
+                       "Error: Can't config offload when Port %d is not 
stopped\n",
+                       port_id);
+               return;
+       }
+
+       if (!strcmp(res->protocol, "mac"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_MAC;
+       else if (!strcmp(res->protocol, "ipv4"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_IPV4;
+       else if (!strcmp(res->protocol, "ipv6"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_IPV6;
+       else if (!strcmp(res->protocol, "l3"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_L3;
+       else if (!strcmp(res->protocol, "tcp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_TCP;
+       else if (!strcmp(res->protocol, "udp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_UDP;
+       else if (!strcmp(res->protocol, "sctp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_SCTP;
+       else if (!strcmp(res->protocol, "l4"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_L4;
+       else if (!strcmp(res->protocol, "inner_mac"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_MAC;
+       else if (!strcmp(res->protocol, "inner_ipv4"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_IPV4;
+       else if (!strcmp(res->protocol, "inner_ipv6"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_IPV6;
+       else if (!strcmp(res->protocol, "inner_l3"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_L3;
+       else if (!strcmp(res->protocol, "inner_tcp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_TCP;
+       else if (!strcmp(res->protocol, "inner_udp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_UDP;
+       else if (!strcmp(res->protocol, "inner_sctp"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_SCTP;
+       else if (!strcmp(res->protocol, "inner_l4"))
+               protocol = RTE_ETH_RX_HEADER_SPLIT_INNER_L4;
+       else {
+               fprintf(stderr, "Unknown protocol name: %s\n", res->protocol);
+               return;
+       }
+
+       rx_pkt_header_split_proto = protocol;
+
+       cmd_reconfig_device_queue(port_id, 1, 1);
+}
+
+cmdline_parse_inst_t cmd_config_per_port_headersplit_protocol = {
+       .f = cmd_config_per_port_headersplit_protocol_parsed,
+       .data = NULL,
+       .help_str = "port config <port_id> header_split 
mac|ipv4|ipv6|l3|tcp|udp|sctp|l4|"
+                   "inner_mac|inner_ipv4|inner_ipv6|inner_l3|inner_tcp|"
+                   "inner_udp|inner_sctp|inner_l4",
+       .tokens = {
+               (void *)&cmd_config_per_port_headersplit_protocol_result_port,
+               (void *)&cmd_config_per_port_headersplit_protocol_result_config,
+               (void 
*)&cmd_config_per_port_headersplit_protocol_result_port_id,
+               (void 
*)&cmd_config_per_port_headersplit_protocol_result_headersplit,
+               (void 
*)&cmd_config_per_port_headersplit_protocol_result_protocol,
+               NULL,
+       }
+};
+
 /* Enable/Disable a per queue offloading */
 struct cmd_config_per_queue_rx_offload_result {
        cmdline_fixed_string_t port;
@@ -18071,6 +18187,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_rx_offload_get_capa,
        (cmdline_parse_inst_t *)&cmd_rx_offload_get_configuration,
        (cmdline_parse_inst_t *)&cmd_config_per_port_rx_offload,
+       (cmdline_parse_inst_t *)&cmd_config_per_port_headersplit_protocol,
        (cmdline_parse_inst_t *)&cmd_config_per_queue_rx_offload,
        (cmdline_parse_inst_t *)&cmd_tx_offload_get_capa,
        (cmdline_parse_inst_t *)&cmd_tx_offload_get_configuration,
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index fe2ce19f99..a00fa0e236 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -253,6 +253,8 @@ uint8_t  tx_pkt_nb_segs = 1; /**< Number of segments in 
TXONLY packets */
 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
 /**< Split policy for packets to TX. */
 
+uint8_t rx_pkt_header_split_proto;
+
 uint8_t txonly_multi_flow;
 /**< Whether multiple flows are generated in TXONLY mode. */
 
@@ -2568,7 +2570,8 @@ rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
        int ret;
 
        if (rx_pkt_nb_segs <= 1 ||
-           (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) {
+           (((rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) &&
+            ((rx_conf->offloads & RTE_ETH_RX_OFFLOAD_HEADER_SPLIT) == 0))) {
                rx_conf->rx_seg = NULL;
                rx_conf->rx_nseg = 0;
                ret = rte_eth_rx_queue_setup(port_id, rx_queue_id,
@@ -2592,6 +2595,7 @@ rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
                rx_seg->offset = i < rx_pkt_nb_offs ?
                                   rx_pkt_seg_offsets[i] : 0;
                rx_seg->mp = mpx ? mpx : mp;
+               rx_seg->proto = rx_pkt_header_split_proto;
        }
        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..021e2768be 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -557,6 +557,8 @@ enum tx_pkt_split {
 
 extern enum tx_pkt_split tx_pkt_split;
 
+extern uint8_t rx_pkt_header_split_proto;
+
 extern uint8_t txonly_multi_flow;
 
 extern uint32_t rxq_share;
-- 
2.17.1

Reply via email to