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 56AFC4611C; Fri, 24 Jan 2025 10:55:56 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 39CDE410D4; Fri, 24 Jan 2025 10:55:56 +0100 (CET) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id A64FF410D0 for ; Fri, 24 Jan 2025 10:55:47 +0100 (CET) Received: from mail.maildlp.com (unknown [172.19.163.174]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4YfY555GBnz11T37; Fri, 24 Jan 2025 17:52:25 +0800 (CST) Received: from kwepemf500004.china.huawei.com (unknown [7.202.181.242]) by mail.maildlp.com (Postfix) with ESMTPS id C500C1401E9; Fri, 24 Jan 2025 17:55:37 +0800 (CST) Received: from localhost.localdomain (10.28.79.22) by kwepemf500004.china.huawei.com (7.202.181.242) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 24 Jan 2025 17:55:37 +0800 From: Jie Hai To: , , , CC: , , , Subject: [PATCH v2 2/2] app/test-pmd: use ptype API parse packets Date: Fri, 24 Jan 2025 17:43:32 +0800 Message-ID: <20250124094333.11449-3-haijie1@huawei.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20250124094333.11449-1-haijie1@huawei.com> References: <20250108024632.12152-1-haijie1@huawei.com> <20250124094333.11449-1-haijie1@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.28.79.22] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemf500004.china.huawei.com (7.202.181.242) 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 1. Use rte_net_get_ptype() to parse packets instead. 2. Support TSO for packets with ipv6 extension header. Signed-off-by: Jie Hai --- app/test-pmd/csumonly.c | 522 ++++++++++------------------------------ 1 file changed, 128 insertions(+), 394 deletions(-) diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index d77a140641f3..2dcd6efedcb1 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -46,6 +46,7 @@ #include #endif #include +#include #include "testpmd.h" @@ -104,88 +105,6 @@ get_udptcp_checksum(struct rte_mbuf *m, void *l3_hdr, uint16_t l4_off, return rte_ipv6_udptcp_cksum_mbuf(m, l3_hdr, l4_off); } -/* Parse an IPv4 header to fill l3_len, l4_len, and l4_proto */ -static void -parse_ipv4(struct rte_ipv4_hdr *ipv4_hdr, struct testpmd_offload_info *info) -{ - struct rte_tcp_hdr *tcp_hdr; - - info->l3_len = rte_ipv4_hdr_len(ipv4_hdr); - info->l4_proto = ipv4_hdr->next_proto_id; - - /* only fill l4_len for TCP, it's useful for TSO */ - if (info->l4_proto == IPPROTO_TCP) { - tcp_hdr = (struct rte_tcp_hdr *) - ((char *)ipv4_hdr + info->l3_len); - info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; - } else if (info->l4_proto == IPPROTO_UDP) - info->l4_len = sizeof(struct rte_udp_hdr); - else - info->l4_len = 0; -} - -/* Parse an IPv6 header to fill l3_len, l4_len, and l4_proto */ -static void -parse_ipv6(struct rte_ipv6_hdr *ipv6_hdr, struct testpmd_offload_info *info) -{ - struct rte_tcp_hdr *tcp_hdr; - - info->l3_len = sizeof(struct rte_ipv6_hdr); - info->l4_proto = ipv6_hdr->proto; - - /* only fill l4_len for TCP, it's useful for TSO */ - if (info->l4_proto == IPPROTO_TCP) { - tcp_hdr = (struct rte_tcp_hdr *) - ((char *)ipv6_hdr + info->l3_len); - info->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; - } else if (info->l4_proto == IPPROTO_UDP) - info->l4_len = sizeof(struct rte_udp_hdr); - else - info->l4_len = 0; -} - -/* - * Parse an ethernet header to fill the ethertype, l2_len, l3_len and - * ipproto. This function is able to recognize IPv4/IPv6 with optional VLAN - * headers. The l4_len argument is only set in case of TCP (useful for TSO). - */ -static void -parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info) -{ - struct rte_ipv4_hdr *ipv4_hdr; - struct rte_ipv6_hdr *ipv6_hdr; - struct rte_vlan_hdr *vlan_hdr; - - info->l2_len = sizeof(struct rte_ether_hdr); - info->ethertype = eth_hdr->ether_type; - - while (info->ethertype == _htons(RTE_ETHER_TYPE_VLAN) || - info->ethertype == _htons(RTE_ETHER_TYPE_QINQ)) { - vlan_hdr = (struct rte_vlan_hdr *) - ((char *)eth_hdr + info->l2_len); - info->l2_len += sizeof(struct rte_vlan_hdr); - info->ethertype = vlan_hdr->eth_proto; - } - - switch (info->ethertype) { - case _htons(RTE_ETHER_TYPE_IPV4): - ipv4_hdr = (struct rte_ipv4_hdr *) - ((char *)eth_hdr + info->l2_len); - parse_ipv4(ipv4_hdr, info); - break; - case _htons(RTE_ETHER_TYPE_IPV6): - ipv6_hdr = (struct rte_ipv6_hdr *) - ((char *)eth_hdr + info->l2_len); - parse_ipv6(ipv6_hdr, info); - break; - default: - info->l4_len = 0; - info->l3_len = 0; - info->l4_proto = 0; - break; - } -} - /* Fill in outer layers length */ static void update_tunnel_outer(struct testpmd_offload_info *info) @@ -195,262 +114,7 @@ update_tunnel_outer(struct testpmd_offload_info *info) info->outer_l2_len = info->l2_len; info->outer_l3_len = info->l3_len; info->outer_l4_proto = info->l4_proto; -} - -/* - * Parse a GTP protocol header. - * No optional fields and next extension header type. - */ -static void -parse_gtp(struct rte_udp_hdr *udp_hdr, - struct testpmd_offload_info *info) -{ - struct rte_ipv4_hdr *ipv4_hdr; - struct rte_ipv6_hdr *ipv6_hdr; - struct rte_gtp_hdr *gtp_hdr; - uint8_t gtp_len = sizeof(*gtp_hdr); - uint8_t ip_ver; - - /* Check udp destination port. */ - if (udp_hdr->dst_port != _htons(RTE_GTPC_UDP_PORT) && - udp_hdr->src_port != _htons(RTE_GTPC_UDP_PORT) && - udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT)) - return; - - update_tunnel_outer(info); - info->l2_len = 0; - - gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr + - sizeof(struct rte_udp_hdr)); - if (gtp_hdr->e || gtp_hdr->s || gtp_hdr->pn) - gtp_len += sizeof(struct rte_gtp_hdr_ext_word); - /* - * Check message type. If message type is 0xff, it is - * a GTP data packet. If not, it is a GTP control packet - */ - if (gtp_hdr->msg_type == 0xff) { - ip_ver = *(uint8_t *)((char *)gtp_hdr + gtp_len); - ip_ver = (ip_ver) & 0xf0; - - if (ip_ver == RTE_GTP_TYPE_IPV4) { - ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr + - gtp_len); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); - parse_ipv4(ipv4_hdr, info); - } else if (ip_ver == RTE_GTP_TYPE_IPV6) { - ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr + - gtp_len); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); - parse_ipv6(ipv6_hdr, info); - } - } else { - info->ethertype = 0; - info->l4_len = 0; - info->l3_len = 0; - info->l4_proto = 0; - } - - info->l2_len += gtp_len + sizeof(*udp_hdr); -} - -/* Parse a vxlan header */ -static void -parse_vxlan(struct rte_udp_hdr *udp_hdr, - struct testpmd_offload_info *info) -{ - struct rte_ether_hdr *eth_hdr; - - /* check udp destination port, RTE_VXLAN_DEFAULT_PORT (4789) is the - * default vxlan port (rfc7348) or that the rx offload flag is set - * (i40e only currently) - */ - if (udp_hdr->dst_port != _htons(RTE_VXLAN_DEFAULT_PORT)) - return; - - update_tunnel_outer(info); - - eth_hdr = (struct rte_ether_hdr *)((char *)udp_hdr + - sizeof(struct rte_udp_hdr) + - sizeof(struct rte_vxlan_hdr)); - - parse_ethernet(eth_hdr, info); - info->l2_len += RTE_ETHER_VXLAN_HLEN; /* add udp + vxlan */ -} - -/* Parse a vxlan-gpe header */ -static void -parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, - struct testpmd_offload_info *info) -{ - struct rte_ether_hdr *eth_hdr; - struct rte_ipv4_hdr *ipv4_hdr; - struct rte_ipv6_hdr *ipv6_hdr; - struct rte_vxlan_gpe_hdr *vxlan_gpe_hdr; - uint8_t vxlan_gpe_len = sizeof(*vxlan_gpe_hdr); - - /* Check udp destination port. */ - if (udp_hdr->dst_port != _htons(vxlan_gpe_udp_port)) - return; - - vxlan_gpe_hdr = (struct rte_vxlan_gpe_hdr *)((char *)udp_hdr + - sizeof(struct rte_udp_hdr)); - - if (!vxlan_gpe_hdr->proto || vxlan_gpe_hdr->proto == - RTE_VXLAN_GPE_TYPE_IPV4) { - update_tunnel_outer(info); - - ipv4_hdr = (struct rte_ipv4_hdr *)((char *)vxlan_gpe_hdr + - vxlan_gpe_len); - - parse_ipv4(ipv4_hdr, info); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); - info->l2_len = 0; - - } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_IPV6) { - update_tunnel_outer(info); - - ipv6_hdr = (struct rte_ipv6_hdr *)((char *)vxlan_gpe_hdr + - vxlan_gpe_len); - - info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); - parse_ipv6(ipv6_hdr, info); - info->l2_len = 0; - - } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_ETH) { - update_tunnel_outer(info); - - eth_hdr = (struct rte_ether_hdr *)((char *)vxlan_gpe_hdr + - vxlan_gpe_len); - - parse_ethernet(eth_hdr, info); - } else - return; - - info->l2_len += RTE_ETHER_VXLAN_GPE_HLEN; -} - -/* Parse a geneve header */ -static void -parse_geneve(struct rte_udp_hdr *udp_hdr, - struct testpmd_offload_info *info) -{ - struct rte_ether_hdr *eth_hdr; - struct rte_ipv4_hdr *ipv4_hdr; - struct rte_ipv6_hdr *ipv6_hdr; - struct rte_geneve_hdr *geneve_hdr; - uint16_t geneve_len; - - /* Check udp destination port. */ - if (udp_hdr->dst_port != _htons(geneve_udp_port)) - return; - - geneve_hdr = (struct rte_geneve_hdr *)((char *)udp_hdr + - sizeof(struct rte_udp_hdr)); - geneve_len = sizeof(struct rte_geneve_hdr) + geneve_hdr->opt_len * 4; - if (!geneve_hdr->proto || geneve_hdr->proto == - _htons(RTE_ETHER_TYPE_IPV4)) { - update_tunnel_outer(info); - ipv4_hdr = (struct rte_ipv4_hdr *)((char *)geneve_hdr + - geneve_len); - parse_ipv4(ipv4_hdr, info); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); - info->l2_len = 0; - } else if (geneve_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { - update_tunnel_outer(info); - ipv6_hdr = (struct rte_ipv6_hdr *)((char *)geneve_hdr + - geneve_len); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); - parse_ipv6(ipv6_hdr, info); - info->l2_len = 0; - - } else if (geneve_hdr->proto == _htons(RTE_GENEVE_TYPE_ETH)) { - update_tunnel_outer(info); - eth_hdr = (struct rte_ether_hdr *)((char *)geneve_hdr + - geneve_len); - parse_ethernet(eth_hdr, info); - } else - return; - - info->l2_len += - (sizeof(struct rte_udp_hdr) + sizeof(struct rte_geneve_hdr) + - ((struct rte_geneve_hdr *)geneve_hdr)->opt_len * 4); -} - -/* Parse a gre header */ -static void -parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) -{ - struct rte_ether_hdr *eth_hdr; - struct rte_ipv4_hdr *ipv4_hdr; - struct rte_ipv6_hdr *ipv6_hdr; - uint8_t gre_len = 0; - - gre_len += sizeof(struct simple_gre_hdr); - - if (gre_hdr->flags & _htons(GRE_KEY_PRESENT)) - gre_len += GRE_EXT_LEN; - if (gre_hdr->flags & _htons(GRE_SEQUENCE_PRESENT)) - gre_len += GRE_EXT_LEN; - if (gre_hdr->flags & _htons(GRE_CHECKSUM_PRESENT)) - gre_len += GRE_EXT_LEN; - - if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV4)) { - update_tunnel_outer(info); - - ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gre_hdr + gre_len); - - parse_ipv4(ipv4_hdr, info); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); - info->l2_len = 0; - - } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { - update_tunnel_outer(info); - - ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gre_hdr + gre_len); - - info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); - parse_ipv6(ipv6_hdr, info); - info->l2_len = 0; - - } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_TEB)) { - update_tunnel_outer(info); - - eth_hdr = (struct rte_ether_hdr *)((char *)gre_hdr + gre_len); - - parse_ethernet(eth_hdr, info); - } else - return; - - info->l2_len += gre_len; -} - - -/* Parse an encapsulated ip or ipv6 header */ -static void -parse_encap_ip(void *encap_ip, struct testpmd_offload_info *info) -{ - struct rte_ipv4_hdr *ipv4_hdr = encap_ip; - struct rte_ipv6_hdr *ipv6_hdr = encap_ip; - uint8_t ip_version; - - ip_version = (ipv4_hdr->version_ihl & 0xf0) >> 4; - - if (ip_version != 4 && ip_version != 6) - return; - - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - - if (ip_version == 4) { - parse_ipv4(ipv4_hdr, info); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); - } else { - parse_ipv6(ipv6_hdr, info); - info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); - } - info->l2_len = 0; + info->l4_proto = 0; } /* if possible, calculate the checksum of a packet in hw or sw, @@ -799,6 +463,109 @@ pkts_ip_csum_recalc(struct rte_mbuf **pkts_burst, const uint16_t nb_pkts, uint64 } #endif +static uint32_t +get_ethertype_by_ptype(struct rte_ether_hdr *eth_hdr, uint32_t ptype) +{ + struct rte_vlan_hdr *vlan_hdr; + uint16_t ethertype; + + switch (ptype) { + case RTE_PTYPE_L3_IPV4: + case RTE_PTYPE_L3_IPV4_EXT: + case RTE_PTYPE_L3_IPV4_EXT_UNKNOWN: + case RTE_PTYPE_INNER_L3_IPV4: + case RTE_PTYPE_INNER_L3_IPV4_EXT: + case RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN: + return _htons(RTE_ETHER_TYPE_IPV4); + case RTE_PTYPE_L3_IPV6: + case RTE_PTYPE_L3_IPV6_EXT: + case RTE_PTYPE_L3_IPV6_EXT_UNKNOWN: + case RTE_PTYPE_INNER_L3_IPV6: + case RTE_PTYPE_INNER_L3_IPV6_EXT: + case RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN: + return _htons(RTE_ETHER_TYPE_IPV6); + default: + ethertype = eth_hdr->ether_type; + while (eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_VLAN) || + eth_hdr->ether_type == _htons(RTE_ETHER_TYPE_QINQ)) { + vlan_hdr = (struct rte_vlan_hdr *) + ((char *)eth_hdr + sizeof(*eth_hdr)); + ethertype = vlan_hdr->eth_proto; + } + return ethertype; + } +} + +static uint64_t +get_tunnel_ol_flags_by_ptype(uint32_t ptype) +{ + switch ((ptype & RTE_PTYPE_TUNNEL_MASK)) { + case RTE_PTYPE_TUNNEL_GTPC: + case RTE_PTYPE_TUNNEL_GTPU: + return RTE_MBUF_F_TX_TUNNEL_GTP; + case RTE_PTYPE_TUNNEL_VXLAN_GPE: + return RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE; + case RTE_PTYPE_TUNNEL_VXLAN: + return RTE_MBUF_F_TX_TUNNEL_VXLAN; + case RTE_PTYPE_TUNNEL_GENEVE: + return RTE_MBUF_F_TX_TUNNEL_GENEVE; + case RTE_PTYPE_TUNNEL_NVGRE: + case RTE_PTYPE_TUNNEL_GRE: + return RTE_MBUF_F_TX_TUNNEL_GRE; + case RTE_PTYPE_TUNNEL_IP: + return RTE_MBUF_F_TX_TUNNEL_IPIP; + default: + printf("unrecognized tunnel ptype: %x\n", + (ptype & RTE_PTYPE_TUNNEL_MASK)); + return 0; + } +} + +static void +parse_inner_l4_proto(void *outer_l3_hdr, + struct testpmd_offload_info *info) +{ + struct rte_ipv4_hdr *ipv4_hdr = outer_l3_hdr; + struct rte_ipv6_hdr *ipv6_hdr = outer_l3_hdr; + if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV4)) + info->l4_proto = ipv4_hdr->next_proto_id; + else + info->l4_proto = ipv6_hdr->proto; +} + +static uint8_t +parse_l4_proto(const struct rte_mbuf *m, uint32_t off, uint32_t ptype) +{ + int frag = 0, ret; + + if (RTE_ETH_IS_IPV4_HDR(ptype)) { + const struct rte_ipv4_hdr *ip4h; + struct rte_ipv4_hdr ip4h_copy; + ip4h = rte_pktmbuf_read(m, off, sizeof(*ip4h), &ip4h_copy); + if (unlikely(ip4h == NULL)) + return 0; + + return ip4h->next_proto_id; + } else if (RTE_ETH_IS_IPV6_HDR(ptype)) { + const struct rte_ipv6_hdr *ip6h; + struct rte_ipv6_hdr ip6h_copy; + ip6h = rte_pktmbuf_read(m, off, sizeof(*ip6h), &ip6h_copy); + if (unlikely(ip6h == NULL)) + return 0; + + if ((ptype & RTE_PTYPE_INNER_L3_MASK) == + RTE_PTYPE_INNER_L3_IPV6_EXT) { + ret = rte_net_skip_ip6_ext(ip6h->proto, m, &off, &frag); + if (ret < 0) + return 0; + return ret; + } + + return ip6h->proto; + } + return 0; +} + /* * Receive a burst of packets, and for each packet: * - parse packet, and try to recognize a supported packet type (1) @@ -856,6 +623,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint32_t rx_bad_outer_l4_csum; uint32_t rx_bad_outer_ip_csum; struct testpmd_offload_info info; + struct rte_net_hdr_lens hdr_lens = {0}; + uint32_t ptype; /* receive a burst of packet */ nb_rx = common_fwd_stream_receive(fs, pkts_burst, nb_pkt_per_burst); @@ -924,70 +693,35 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, ð_hdr->src_addr); } - parse_ethernet(eth_hdr, &info); - l3_hdr = (char *)eth_hdr + info.l2_len; + ptype = rte_net_get_ptype(m, &hdr_lens, RTE_PTYPE_ALL_MASK); + info.l2_len = hdr_lens.l2_len; + info.l3_len = hdr_lens.l3_len; + info.l4_len = hdr_lens.l4_len; + info.ethertype = get_ethertype_by_ptype(eth_hdr, + ptype & RTE_PTYPE_L3_MASK); + info.l4_proto = parse_l4_proto(m, info.l2_len, ptype); + + l3_hdr = (char *)eth_hdr + info.l2_len; /* check if it's a supported tunnel */ - if (txp->parse_tunnel) { - if (info.l4_proto == IPPROTO_UDP) { - struct rte_udp_hdr *udp_hdr; - - udp_hdr = (struct rte_udp_hdr *) - ((char *)l3_hdr + info.l3_len); - parse_gtp(udp_hdr, &info); - if (info.is_tunnel) { - tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GTP; - goto tunnel_update; - } - parse_vxlan_gpe(udp_hdr, &info); - if (info.is_tunnel) { - tx_ol_flags |= - RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE; - goto tunnel_update; - } - parse_vxlan(udp_hdr, &info); - if (info.is_tunnel) { - tx_ol_flags |= - RTE_MBUF_F_TX_TUNNEL_VXLAN; - goto tunnel_update; - } - parse_geneve(udp_hdr, &info); - if (info.is_tunnel) { - tx_ol_flags |= - RTE_MBUF_F_TX_TUNNEL_GENEVE; - goto tunnel_update; - } - /* Always keep last. */ - if (unlikely(RTE_ETH_IS_TUNNEL_PKT( - m->packet_type) != 0)) { - TESTPMD_LOG(DEBUG, "Unknown tunnel packet. UDP dst port: %hu", - udp_hdr->dst_port); - } - } else if (info.l4_proto == IPPROTO_GRE) { - struct simple_gre_hdr *gre_hdr; - - gre_hdr = (struct simple_gre_hdr *) - ((char *)l3_hdr + info.l3_len); - parse_gre(gre_hdr, &info); - if (info.is_tunnel) - tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GRE; - } else if (info.l4_proto == IPPROTO_IPIP) { - void *encap_ip_hdr; - - encap_ip_hdr = (char *)l3_hdr + info.l3_len; - parse_encap_ip(encap_ip_hdr, &info); - if (info.is_tunnel) - tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_IPIP; - } + if (txp->parse_tunnel && RTE_ETH_IS_TUNNEL_PKT(ptype) != 0) { + info.is_tunnel = 1; + update_tunnel_outer(&info); + info.l2_len = hdr_lens.inner_l2_len + hdr_lens.tunnel_len; + info.l3_len = hdr_lens.inner_l3_len; + info.l4_len = hdr_lens.inner_l4_len; + eth_hdr = (struct rte_ether_hdr *)(char *)l3_hdr + + info.outer_l3_len + hdr_lens.tunnel_len; + info.ethertype = get_ethertype_by_ptype(eth_hdr, + ptype & RTE_PTYPE_INNER_L3_MASK); + tx_ol_flags |= get_tunnel_ol_flags_by_ptype(ptype); } - -tunnel_update: /* update l3_hdr and outer_l3_hdr if a tunnel was parsed */ if (info.is_tunnel) { outer_l3_hdr = l3_hdr; l3_hdr = (char *)l3_hdr + info.outer_l3_len + info.l2_len; + parse_inner_l4_proto(l3_hdr, &info); } - /* step 2: depending on user command line configuration, * recompute checksum either in software or flag the * mbuf to offload the calculation to the NIC. If TSO -- 2.22.0