All of lore.kernel.org
 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: 42+ 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-19 15:38   ` Stephen Hemminger
2024-10-17 16:21 ` [PATCH 0/6] Reduce scope address-of-packed-member warning Stephen Hemminger
2024-10-17 17:02   ` Bruce Richardson
2024-10-25 13:24 ` David Marchand
2024-10-25 14:55   ` David Marchand
2024-10-25 16:51     ` Bruce Richardson
2024-10-25 16:50 ` [PATCH v2 " Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 1/6] ip_frag: remove use of unaligned variable Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 2/6] efd: remove unnecessary packed attributes Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 3/6] bus/ifpga: remove packed attribute Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 4/6] pipeline: " Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 5/6] net: add smaller IPv4 cksum function for simple cases Bruce Richardson
2024-10-30 11:21     ` David Marchand
2024-10-30 11:27       ` Bruce Richardson
2024-10-30 11:32         ` Morten Brørup
2024-10-30 12:28           ` Bruce Richardson
2024-10-30 12:33             ` Morten Brørup
2024-10-30 14:08           ` David Marchand
2024-10-30 14:45             ` Bruce Richardson
2024-10-25 16:50   ` [PATCH v2 6/6] build: limit scope of packed member warning disabling Bruce Richardson
2024-10-28 12:51   ` [PATCH v2 0/6] Reduce scope address-of-packed-member warning fengchengwen
2024-10-30  8:22   ` David Marchand

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.