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 D075145BCB; Fri, 25 Oct 2024 18:51:43 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1807240650; Fri, 25 Oct 2024 18:51:25 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) by mails.dpdk.org (Postfix) with ESMTP id 7BF95402CD for ; Fri, 25 Oct 2024 18:51:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1729875078; x=1761411078; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ek4d29ixQtgQLui39N+6hkr0h+I66SK0zUczihRmN0g=; b=b8uDqkyQxNz25Pdu7wNkqRct4N/ukzuvG64X9rOIbAuY96YDhHoNWB0b y38NbW9zFK6kXYJINYcDhx4Xm0kqhvehz/64UVizipXeCqBeqpFH+r/Fh uDOVF4CJS5uzCaJV95fE5zwAItxZ+BFZ6Zu6h280/ki9pCLK0EmbdNzfv fWMG14Pg9g8sryyPQ9Lxk45u1XK+4vgjXCdKpQzeN5hCAhXbN4dd+q86S LZwYVT7fsMAUZyoqX8qMrHJ0u8s9B6gv/kxxVEK8hYp7G+zSTHdo5zWRf 4sI25x/g2Pj9d3iy6Bj8bZEB5Qc6Z9XbOQrVLplG7S49MJxEFFFAloE7X A==; X-CSE-ConnectionGUID: ffHf6MxtThWqmmxV4q7rgw== X-CSE-MsgGUID: OAR/7/0GTnKMLxEPp/2YZw== X-IronPort-AV: E=McAfee;i="6700,10204,11236"; a="54956174" X-IronPort-AV: E=Sophos;i="6.11,232,1725346800"; d="scan'208";a="54956174" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Oct 2024 09:50:43 -0700 X-CSE-ConnectionGUID: qIzcUeZ5R6+RL9d4QAONDw== X-CSE-MsgGUID: FmTeNKERQA2/HZyVdLIlIg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,232,1725346800"; d="scan'208";a="118417519" Received: from unknown (HELO silpixa00401385.ir.intel.com) ([10.237.214.25]) by orviesa001.jf.intel.com with ESMTP; 25 Oct 2024 09:50:42 -0700 From: Bruce Richardson To: dev@dpdk.org Cc: david.marchand@redhat.com, Bruce Richardson , Stephen Hemminger , =?UTF-8?q?Morten=20Br=C3=B8rup?= , Jerin Jacob , Aman Singh , Konstantin Ananyev Subject: [PATCH v2 5/6] net: add smaller IPv4 cksum function for simple cases Date: Fri, 25 Oct 2024 17:50:18 +0100 Message-ID: <20241025165020.1856733-6-bruce.richardson@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241025165020.1856733-1-bruce.richardson@intel.com> References: <20241017142214.1669370-1-bruce.richardson@intel.com> <20241025165020.1856733-1-bruce.richardson@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 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 Acked-by: Stephen Hemminger Acked-by: Morten Brørup --- 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