patches for DPDK stable branches
 help / color / mirror / Atom feed
* [PATCH 21.11] net: fix outer UDP checksum in Intel prepare helper
@ 2024-08-29 11:21 David Marchand
  2024-09-04 14:30 ` Kevin Traynor
  0 siblings, 1 reply; 2+ messages in thread
From: David Marchand @ 2024-08-29 11:21 UTC (permalink / raw)
  To: stable; +Cc: ktraynor, Ali Alnubani

[ upstream commit f876dbef080932dbeb1de075d7ca3cbe2ed6d7eb ]

Setting a pseudo header checksum in the outer UDP checksum is a Intel
(and some other vendors) requirement.
Applications (like OVS) requesting outer UDP checksum without doing this
extra setup have broken outer UDP checksums.

Move this specific setup from testpmd to the "common" helper
rte_net_intel_cksum_flags_prepare().

net/hns3 can then be adjusted.

Bugzilla ID: 1406
Fixes: d8e5e69f3a9b ("app/testpmd: add GTP parsing and Tx checksum offload")

Signed-off-by: David Marchand <david.marchand@redhat.com>
Tested-by: Ali Alnubani <alialnu@nvidia.com>
---
 app/test-pmd/csumonly.c      |  7 ---
 drivers/net/hns3/hns3_rxtx.c | 93 ++++++++++--------------------------
 lib/net/rte_net.h            | 18 ++++++-
 3 files changed, 42 insertions(+), 76 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index b314b15e0c..37cddf4690 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -585,13 +585,6 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) {
-		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
-			udp_hdr->dgram_cksum
-				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
-		else
-			udp_hdr->dgram_cksum
-				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
-
 		ol_flags |= RTE_MBUF_F_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 3e905f8aac..1834382cc6 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -3625,58 +3625,6 @@ hns3_pkt_need_linearized(struct rte_mbuf *tx_pkts, uint32_t bd_num,
 	return false;
 }
 
-static bool
-hns3_outer_ipv4_cksum_prepared(struct rte_mbuf *m, uint64_t ol_flags,
-				uint32_t *l4_proto)
-{
-	struct rte_ipv4_hdr *ipv4_hdr;
-	ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
-					   m->outer_l2_len);
-	if (ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM)
-		ipv4_hdr->hdr_checksum = 0;
-	if (ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
-		struct rte_udp_hdr *udp_hdr;
-		/*
-		 * If OUTER_UDP_CKSUM is support, HW can calculate the pseudo
-		 * header for TSO packets
-		 */
-		if (ol_flags & RTE_MBUF_F_TX_TCP_SEG)
-			return true;
-		udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
-				m->outer_l2_len + m->outer_l3_len);
-		udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
-
-		return true;
-	}
-	*l4_proto = ipv4_hdr->next_proto_id;
-	return false;
-}
-
-static bool
-hns3_outer_ipv6_cksum_prepared(struct rte_mbuf *m, uint64_t ol_flags,
-				uint32_t *l4_proto)
-{
-	struct rte_ipv6_hdr *ipv6_hdr;
-	ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *,
-					   m->outer_l2_len);
-	if (ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
-		struct rte_udp_hdr *udp_hdr;
-		/*
-		 * If OUTER_UDP_CKSUM is support, HW can calculate the pseudo
-		 * header for TSO packets
-		 */
-		if (ol_flags & RTE_MBUF_F_TX_TCP_SEG)
-			return true;
-		udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
-				m->outer_l2_len + m->outer_l3_len);
-		udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
-
-		return true;
-	}
-	*l4_proto = ipv6_hdr->proto;
-	return false;
-}
-
 static void
 hns3_outer_header_cksum_prepare(struct rte_mbuf *m)
 {
@@ -3684,29 +3632,38 @@ hns3_outer_header_cksum_prepare(struct rte_mbuf *m)
 	uint32_t paylen, hdr_len, l4_proto;
 	struct rte_udp_hdr *udp_hdr;
 
-	if (!(ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6)))
+	if (!(ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6)) &&
+			((ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) ||
+			!(ol_flags & RTE_MBUF_F_TX_TCP_SEG)))
 		return;
 
 	if (ol_flags & RTE_MBUF_F_TX_OUTER_IPV4) {
-		if (hns3_outer_ipv4_cksum_prepared(m, ol_flags, &l4_proto))
-			return;
+		struct rte_ipv4_hdr *ipv4_hdr;
+
+		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
+			m->outer_l2_len);
+		l4_proto = ipv4_hdr->next_proto_id;
 	} else {
-		if (hns3_outer_ipv6_cksum_prepared(m, ol_flags, &l4_proto))
-			return;
+		struct rte_ipv6_hdr *ipv6_hdr;
+
+		ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *,
+					   m->outer_l2_len);
+		l4_proto = ipv6_hdr->proto;
 	}
 
+	if (l4_proto != IPPROTO_UDP)
+		return;
+
 	/* driver should ensure the outer udp cksum is 0 for TUNNEL TSO */
-	if (l4_proto == IPPROTO_UDP && (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
-		hdr_len = m->l2_len + m->l3_len + m->l4_len;
-		hdr_len += m->outer_l2_len + m->outer_l3_len;
-		paylen = m->pkt_len - hdr_len;
-		if (paylen <= m->tso_segsz)
-			return;
-		udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
-						  m->outer_l2_len +
-						  m->outer_l3_len);
-		udp_hdr->dgram_cksum = 0;
-	}
+	hdr_len = m->l2_len + m->l3_len + m->l4_len;
+	hdr_len += m->outer_l2_len + m->outer_l3_len;
+	paylen = m->pkt_len - hdr_len;
+	if (paylen <= m->tso_segsz)
+		return;
+	udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
+					  m->outer_l2_len +
+					  m->outer_l3_len);
+	udp_hdr->dgram_cksum = 0;
 }
 
 static int
diff --git a/lib/net/rte_net.h b/lib/net/rte_net.h
index 53a7f4d360..f2aeba8404 100644
--- a/lib/net/rte_net.h
+++ b/lib/net/rte_net.h
@@ -122,7 +122,8 @@ rte_net_intel_cksum_flags_prepare(struct rte_mbuf *m, uint64_t ol_flags)
 	 * no offloads are requested.
 	 */
 	if (!(ol_flags & (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK | RTE_MBUF_F_TX_TCP_SEG |
-			  RTE_MBUF_F_TX_OUTER_IP_CKSUM)))
+					RTE_MBUF_F_TX_OUTER_IP_CKSUM |
+					RTE_MBUF_F_TX_OUTER_UDP_CKSUM)))
 		return 0;
 
 	if (ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6)) {
@@ -136,6 +137,21 @@ rte_net_intel_cksum_flags_prepare(struct rte_mbuf *m, uint64_t ol_flags)
 					struct rte_ipv4_hdr *, m->outer_l2_len);
 			ipv4_hdr->hdr_checksum = 0;
 		}
+		if (ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM) {
+			if (ol_flags & RTE_MBUF_F_TX_OUTER_IPV4) {
+				ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
+					m->outer_l2_len);
+				udp_hdr = (struct rte_udp_hdr *)((char *)ipv4_hdr +
+					m->outer_l3_len);
+				udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, m->ol_flags);
+			} else {
+				ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *,
+					m->outer_l2_len);
+				udp_hdr = rte_pktmbuf_mtod_offset(m, struct rte_udp_hdr *,
+					 m->outer_l2_len + m->outer_l3_len);
+				udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, m->ol_flags);
+			}
+		}
 	}
 
 	/*
-- 
2.46.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-09-04 14:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-29 11:21 [PATCH 21.11] net: fix outer UDP checksum in Intel prepare helper David Marchand
2024-09-04 14:30 ` Kevin Traynor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).