DPDK patches and discussions
 help / color / mirror / Atom feed
From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: Bruce Richardson <bruce.richardson@intel.com>,
	Jerin Jacob <jerinj@marvell.com>,
	Aman Singh <aman.deep.singh@intel.com>,
	Konstantin Ananyev <konstantin.v.ananyev@yandex.ru>
Subject: [PATCH 5/6] net: add smaller IPv4 cksum function for simple cases
Date: Thu, 17 Oct 2024 15:22:12 +0100	[thread overview]
Message-ID: <20241017142214.1669370-6-bruce.richardson@intel.com> (raw)
In-Reply-To: <20241017142214.1669370-1-bruce.richardson@intel.com>

There are multiple instances in the DPDK app folder where we set up an
IP header and then compute the checksum field by direct addition of
nine uint16_t values in the header (20 bytes less the cksum field).
The existing rte_ip.h checksum function is more general than necessary
here and requires that the checksum field is already set to zero -
rather than having it skipped.

Fix the code duplication present in the apps by creating a new
rte_ipv4_cksum_simple function - taking the code from the existing
testpmd icmpecho.c file - and using that in app/test, testpmd and
testeventdev.

Within that new function, we can adjust slightly how the typecasting to
uint16_t is done, and thereby ensure that the app can all be compiled
without -Wno-address-of-packed-member compiler flag.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 app/test-eventdev/test_pipeline_common.c | 25 +-----------
 app/test-pmd/icmpecho.c                  | 23 +----------
 app/test-pmd/txonly.c                    | 22 +----------
 app/test/packet_burst_generator.c        | 49 +-----------------------
 app/test/test_reassembly_perf.c          | 29 +-------------
 lib/net/rte_ip.h                         | 33 ++++++++++++++++
 6 files changed, 39 insertions(+), 142 deletions(-)

diff --git a/app/test-eventdev/test_pipeline_common.c b/app/test-eventdev/test_pipeline_common.c
index b111690b7c..204117ef7f 100644
--- a/app/test-eventdev/test_pipeline_common.c
+++ b/app/test-eventdev/test_pipeline_common.c
@@ -74,8 +74,6 @@ setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 			 struct rte_udp_hdr *udp_hdr, uint16_t pkt_data_len,
 			 uint8_t port, uint8_t flow)
 {
-	uint16_t *ptr16;
-	uint32_t ip_cksum;
 	uint16_t pkt_len;
 
 	/*
@@ -104,28 +102,7 @@ setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 	/*
 	 * Compute IP header checksum.
 	 */
-	ptr16 = (unaligned_uint16_t *)ip_hdr;
-	ip_cksum = 0;
-	ip_cksum += ptr16[0];
-	ip_cksum += ptr16[1];
-	ip_cksum += ptr16[2];
-	ip_cksum += ptr16[3];
-	ip_cksum += ptr16[4];
-	ip_cksum += ptr16[6];
-	ip_cksum += ptr16[7];
-	ip_cksum += ptr16[8];
-	ip_cksum += ptr16[9];
-
-	/*
-	 * Reduce 32 bit checksum to 16 bits and complement it.
-	 */
-	ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) + (ip_cksum & 0x0000FFFF);
-	if (ip_cksum > 65535)
-		ip_cksum -= 65535;
-	ip_cksum = (~ip_cksum) & 0x0000FFFF;
-	if (ip_cksum == 0)
-		ip_cksum = 0xFFFF;
-	ip_hdr->hdr_checksum = (uint16_t)ip_cksum;
+	ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr);
 }
 
 static void
diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c
index 68524484e3..754a3bc758 100644
--- a/app/test-pmd/icmpecho.c
+++ b/app/test-pmd/icmpecho.c
@@ -241,27 +241,6 @@ ipv4_addr_dump(const char *what, uint32_t be_ipv4_addr)
 	printf("%s", buf);
 }
 
-static uint16_t
-ipv4_hdr_cksum(struct rte_ipv4_hdr *ip_h)
-{
-	uint16_t *v16_h;
-	uint32_t ip_cksum;
-
-	/*
-	 * Compute the sum of successive 16-bit words of the IPv4 header,
-	 * skipping the checksum field of the header.
-	 */
-	v16_h = (unaligned_uint16_t *) ip_h;
-	ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
-		v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
-
-	/* reduce 32 bit checksum to 16 bits and complement it */
-	ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
-	ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
-	ip_cksum = (~ip_cksum) & 0x0000FFFF;
-	return (ip_cksum == 0) ? 0xFFFF : (uint16_t) ip_cksum;
-}
-
 #define is_multicast_ipv4_addr(ipv4_addr) \
 	(((rte_be_to_cpu_32((ipv4_addr)) >> 24) & 0x000000FF) == 0xE0)
 
@@ -458,7 +437,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs)
 				ip_src = (ip_src & 0xFFFFFFFC) | 0x00000001;
 			ip_h->src_addr = rte_cpu_to_be_32(ip_src);
 			ip_h->dst_addr = ip_addr;
-			ip_h->hdr_checksum = ipv4_hdr_cksum(ip_h);
+			ip_h->hdr_checksum = rte_ipv4_cksum_simple(ip_h);
 		} else {
 			ip_h->src_addr = ip_h->dst_addr;
 			ip_h->dst_addr = ip_addr;
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index c2b88764be..59d821a22d 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -106,8 +106,6 @@ setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 			 struct rte_udp_hdr *udp_hdr,
 			 uint16_t pkt_data_len)
 {
-	uint16_t *ptr16;
-	uint32_t ip_cksum;
 	uint16_t pkt_len;
 
 	/*
@@ -136,25 +134,7 @@ setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
 	/*
 	 * Compute IP header checksum.
 	 */
-	ptr16 = (unaligned_uint16_t*) ip_hdr;
-	ip_cksum = 0;
-	ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
-	ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
-	ip_cksum += ptr16[4];
-	ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
-	ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
-
-	/*
-	 * Reduce 32 bit checksum to 16 bits and complement it.
-	 */
-	ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
-		(ip_cksum & 0x0000FFFF);
-	if (ip_cksum > 65535)
-		ip_cksum -= 65535;
-	ip_cksum = (~ip_cksum) & 0x0000FFFF;
-	if (ip_cksum == 0)
-		ip_cksum = 0xFFFF;
-	ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
+	ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr);
 }
 
 static inline void
diff --git a/app/test/packet_burst_generator.c b/app/test/packet_burst_generator.c
index 867a88da00..6547d2a07f 100644
--- a/app/test/packet_burst_generator.c
+++ b/app/test/packet_burst_generator.c
@@ -159,8 +159,6 @@ initialize_ipv4_header(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
 		uint32_t dst_addr, uint16_t pkt_data_len)
 {
 	uint16_t pkt_len;
-	unaligned_uint16_t *ptr16;
-	uint32_t ip_cksum;
 
 	/*
 	 * Initialize IP header.
@@ -177,27 +175,7 @@ initialize_ipv4_header(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
 	ip_hdr->src_addr = rte_cpu_to_be_32(src_addr);
 	ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr);
 
-	/*
-	 * Compute IP header checksum.
-	 */
-	ptr16 = (unaligned_uint16_t *)ip_hdr;
-	ip_cksum = 0;
-	ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
-	ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
-	ip_cksum += ptr16[4];
-	ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
-	ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
-
-	/*
-	 * Reduce 32 bit checksum to 16 bits and complement it.
-	 */
-	ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
-		(ip_cksum & 0x0000FFFF);
-	ip_cksum %= 65536;
-	ip_cksum = (~ip_cksum) & 0x0000FFFF;
-	if (ip_cksum == 0)
-		ip_cksum = 0xFFFF;
-	ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
+	ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr);
 
 	return pkt_len;
 }
@@ -207,8 +185,6 @@ initialize_ipv4_header_proto(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
 		uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto)
 {
 	uint16_t pkt_len;
-	unaligned_uint16_t *ptr16;
-	uint32_t ip_cksum;
 
 	/*
 	 * Initialize IP header.
@@ -224,28 +200,7 @@ initialize_ipv4_header_proto(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr,
 	ip_hdr->total_length   = rte_cpu_to_be_16(pkt_len);
 	ip_hdr->src_addr = rte_cpu_to_be_32(src_addr);
 	ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr);
-
-	/*
-	 * Compute IP header checksum.
-	 */
-	ptr16 = (unaligned_uint16_t *)ip_hdr;
-	ip_cksum = 0;
-	ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
-	ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
-	ip_cksum += ptr16[4];
-	ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
-	ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
-
-	/*
-	 * Reduce 32 bit checksum to 16 bits and complement it.
-	 */
-	ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
-		(ip_cksum & 0x0000FFFF);
-	ip_cksum %= 65536;
-	ip_cksum = (~ip_cksum) & 0x0000FFFF;
-	if (ip_cksum == 0)
-		ip_cksum = 0xFFFF;
-	ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
+	ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr);
 
 	return pkt_len;
 }
diff --git a/app/test/test_reassembly_perf.c b/app/test/test_reassembly_perf.c
index 3912179022..32fee984a0 100644
--- a/app/test/test_reassembly_perf.c
+++ b/app/test/test_reassembly_perf.c
@@ -136,9 +136,7 @@ ipv4_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
 	for (i = 0; i < nb_frags; i++) {
 		struct rte_mbuf *frag = mbuf[i];
 		uint16_t frag_offset = 0;
-		uint32_t ip_cksum;
 		uint16_t pkt_len;
-		uint16_t *ptr16;
 
 		frag_offset = i * (frag_len / 8);
 
@@ -189,32 +187,7 @@ ipv4_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
 		ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR(flow_id));
 		ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR(flow_id));
 
-		/*
-		 * Compute IP header checksum.
-		 */
-		ptr16 = (unaligned_uint16_t *)ip_hdr;
-		ip_cksum = 0;
-		ip_cksum += ptr16[0];
-		ip_cksum += ptr16[1];
-		ip_cksum += ptr16[2];
-		ip_cksum += ptr16[3];
-		ip_cksum += ptr16[4];
-		ip_cksum += ptr16[6];
-		ip_cksum += ptr16[7];
-		ip_cksum += ptr16[8];
-		ip_cksum += ptr16[9];
-
-		/*
-		 * Reduce 32 bit checksum to 16 bits and complement it.
-		 */
-		ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
-			   (ip_cksum & 0x0000FFFF);
-		if (ip_cksum > 65535)
-			ip_cksum -= 65535;
-		ip_cksum = (~ip_cksum) & 0x0000FFFF;
-		if (ip_cksum == 0)
-			ip_cksum = 0xFFFF;
-		ip_hdr->hdr_checksum = (uint16_t)ip_cksum;
+		ip_hdr->hdr_checksum = (uint16_t)rte_ipv4_cksum_simple(ip_hdr);
 
 		frag->data_len = sizeof(struct rte_ether_hdr) + pkt_len;
 		frag->pkt_len = frag->data_len;
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 0d103d4127..9980be8a2d 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -309,6 +309,39 @@ rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
 	return (uint16_t)~cksum;
 }
 
+/**
+ * Process the IPv4 checksum of an IPv4 header without any extensions.
+ *
+ * The checksum field does NOT have to be set by the caller, the field
+ * is skipped by the calculation.
+ *
+ * @param ipv4_hdr
+ *   The pointer to the contiguous IPv4 header.
+ * @return
+ *   The complemented checksum to set in the IP packet.
+ */
+__rte_experimental
+static inline uint16_t
+rte_ipv4_cksum_simple(const struct rte_ipv4_hdr *ipv4_hdr)
+{
+	const uint16_t *v16_h;
+	uint32_t ip_cksum;
+
+	/*
+	 * Compute the sum of successive 16-bit words of the IPv4 header,
+	 * skipping the checksum field of the header.
+	 */
+	v16_h = (const unaligned_uint16_t *)&ipv4_hdr->version_ihl;
+	ip_cksum = v16_h[0] + v16_h[1] + v16_h[2] + v16_h[3] +
+		v16_h[4] + v16_h[6] + v16_h[7] + v16_h[8] + v16_h[9];
+
+	/* reduce 32 bit checksum to 16 bits and complement it */
+	ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
+	ip_cksum = (ip_cksum & 0xffff) + (ip_cksum >> 16);
+	ip_cksum = (~ip_cksum) & 0x0000FFFF;
+	return (ip_cksum == 0) ? 0xFFFF : (uint16_t) ip_cksum;
+}
+
 /**
  * Process the pseudo-header checksum of an IPv4 header.
  *
-- 
2.43.0


  parent reply	other threads:[~2024-10-17 14:23 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-17 14:22 [PATCH 0/6] Reduce scope address-of-packed-member warning Bruce Richardson
2024-10-17 14:22 ` [PATCH 1/6] ip_frag: remove use of unaligned variable Bruce Richardson
2024-10-17 16:26   ` Stephen Hemminger
2024-10-17 16:42   ` Konstantin Ananyev
2024-10-17 14:22 ` [PATCH 2/6] efd: remove unnecessary packed attributes Bruce Richardson
2024-10-17 16:22   ` Stephen Hemminger
2024-10-17 14:22 ` [PATCH 3/6] bus/ifpga: remove packed attribute Bruce Richardson
2024-10-17 14:52   ` Xu, Rosen
2024-10-17 16:25   ` Stephen Hemminger
2024-10-17 14:22 ` [PATCH 4/6] pipeline: " Bruce Richardson
2024-10-17 14:24   ` Bruce Richardson
2024-10-17 16:25   ` Stephen Hemminger
2024-10-17 14:22 ` Bruce Richardson [this message]
2024-10-17 16:24   ` [PATCH 5/6] net: add smaller IPv4 cksum function for simple cases Stephen Hemminger
2024-10-17 17:01     ` Bruce Richardson
2024-10-17 17:15   ` Morten Brørup
2024-10-17 19:03     ` Bruce Richardson
2024-10-17 19:34       ` Stephen Hemminger
2024-10-18  0:32         ` Morten Brørup
2024-10-17 14:22 ` [PATCH 6/6] build: limit scope of packed member warning disabling Bruce Richardson
2024-10-17 16:21 ` [PATCH 0/6] Reduce scope address-of-packed-member warning Stephen Hemminger
2024-10-17 17:02   ` Bruce Richardson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241017142214.1669370-6-bruce.richardson@intel.com \
    --to=bruce.richardson@intel.com \
    --cc=aman.deep.singh@intel.com \
    --cc=dev@dpdk.org \
    --cc=jerinj@marvell.com \
    --cc=konstantin.v.ananyev@yandex.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).