From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: david.marchand@redhat.com,
"Bruce Richardson" <bruce.richardson@intel.com>,
"Stephen Hemminger" <stephen@networkplumber.org>,
"Morten Brørup" <mb@smartsharesystems.com>,
"Jerin Jacob" <jerinj@marvell.com>,
"Aman Singh" <aman.deep.singh@intel.com>,
"Konstantin Ananyev" <konstantin.v.ananyev@yandex.ru>
Subject: [PATCH v2 5/6] net: add smaller IPv4 cksum function for simple cases
Date: Fri, 25 Oct 2024 17:50:18 +0100 [thread overview]
Message-ID: <20241025165020.1856733-6-bruce.richardson@intel.com> (raw)
In-Reply-To: <20241025165020.1856733-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>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Morten Brørup <mb@smartsharesystems.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_ip4.h | 32 ++++++++++++++++
6 files changed, 38 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 4ef23ae67a..c87b7a80df 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 c9ff5257f0..4c17737739 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 245ab3fa7d..69cf029468 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_ip4.h b/lib/net/rte_ip4.h
index d9840b3cff..3dc0c5a017 100644
--- a/lib/net/rte_ip4.h
+++ b/lib/net/rte_ip4.h
@@ -163,6 +163,38 @@ 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);
+ return (uint16_t)(~ip_cksum);
+}
+
/**
* Process the pseudo-header checksum of an IPv4 header.
*
--
2.43.0
next prev parent reply other threads:[~2024-10-25 16:51 UTC|newest]
Thread overview: 33+ 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 ` [PATCH 5/6] net: add smaller IPv4 cksum function for simple cases Bruce Richardson
2024-10-17 16:24 ` 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 ` Bruce Richardson [this message]
2024-10-25 16:50 ` [PATCH v2 6/6] build: limit scope of packed member warning disabling 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=20241025165020.1856733-6-bruce.richardson@intel.com \
--to=bruce.richardson@intel.com \
--cc=aman.deep.singh@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=jerinj@marvell.com \
--cc=konstantin.v.ananyev@yandex.ru \
--cc=mb@smartsharesystems.com \
--cc=stephen@networkplumber.org \
/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).