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 87EFB45B5F; Thu, 17 Oct 2024 16:23:05 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4AD3940673; Thu, 17 Oct 2024 16:22:43 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by mails.dpdk.org (Postfix) with ESMTP id 0D14640654 for ; Thu, 17 Oct 2024 16:22:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729174958; x=1760710958; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=J7TFaBnIG9DVTS2hm2lr4gbqfuMn6X7vDmQXoYCgIoI=; b=TW/f55NLgccPpNPJQttQdCDhgQ9mkbDgIj7raxMRtrdAcHDcU+JAahfh qszwfSIRQp5ryPeNyRUnq5pqRLPtTF9bPvEZaXex3Y7vGEX+fo1iPExjb jO+ohGTjt50/i97VcmQav1PT39dIp8Fp8hvPXscsFXpVSR481zvolyRPQ wVQx9VDPWEMfRmo74TrpDWch7AQ0METHwGVjeK9tiDaxBcrQNn3YKScqP apOY8rEenLQJsLDHMbVwzm04Wv4RYea6KEkNtBXZz5S0Y4t9artQiSM0q eknCLN9/nRIPZ5pR5ulTzSFBWsnYhQHr4+ljb4LZB29LMvZxrZLl/VWD7 w==; X-CSE-ConnectionGUID: 0H/vjOJeRHOnls/t3g1BCQ== X-CSE-MsgGUID: ruzSP+uJSCWJTPnkSwj6Qw== X-IronPort-AV: E=McAfee;i="6700,10204,11228"; a="28131730" X-IronPort-AV: E=Sophos;i="6.11,211,1725346800"; d="scan'208";a="28131730" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Oct 2024 07:22:38 -0700 X-CSE-ConnectionGUID: V0bExVgFSrqs//NpdEW6tg== X-CSE-MsgGUID: +oDGiHtKSyi0G/7xnPr+rA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,211,1725346800"; d="scan'208";a="101867848" Received: from unknown (HELO silpixa00401385.ir.intel.com) ([10.237.214.25]) by fmviesa002.fm.intel.com with ESMTP; 17 Oct 2024 07:22:36 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: Bruce Richardson , Jerin Jacob , Aman Singh , Konstantin Ananyev Subject: [PATCH 5/6] net: add smaller IPv4 cksum function for simple cases Date: Thu, 17 Oct 2024 15:22:12 +0100 Message-ID: <20241017142214.1669370-6-bruce.richardson@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241017142214.1669370-1-bruce.richardson@intel.com> References: <20241017142214.1669370-1-bruce.richardson@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 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 --- 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