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 F02BAA0C41 for ; Mon, 18 Oct 2021 04:31:20 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E19EF410DA; Mon, 18 Oct 2021 04:31:20 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id 2056E4003C; Mon, 18 Oct 2021 04:31:17 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10140"; a="228038352" X-IronPort-AV: E=Sophos;i="5.85,381,1624345200"; d="scan'208";a="228038352" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Oct 2021 19:31:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,381,1624345200"; d="scan'208";a="493399237" Received: from dpdk-xiaoyunl.sh.intel.com ([10.67.110.194]) by orsmga008.jf.intel.com with ESMTP; 17 Oct 2021 19:31:15 -0700 From: Xiaoyun Li To: ferruh.yigit@intel.com, david.marchand@redhat.com Cc: dev@dpdk.org, Xiaoyun Li , stable@dpdk.org Date: Mon, 18 Oct 2021 10:16:37 +0800 Message-Id: <20211018021637.26145-1-xiaoyun.li@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211015051306.320328-1-xiaoyun.li@intel.com> References: <20211015051306.320328-1-xiaoyun.li@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-stable] [PATCH v2] app/testpmd: fix l4 sw csum over multi segments X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" In csum forwarding mode, software UDP/TCP csum calculation only takes the first segment into account while using the whole packet length so the calculation will read invalid memory region with multi-segments packets and will get wrong value. This patch fixes this issue. Fixes: af75078fece3 ("first public release") Cc: stable@dpdk.org Signed-off-by: Xiaoyun Li --- v2: * Use static stack memory instead of dynamic allocating in datapath. --- app/test-pmd/csumonly.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 090797318a..9f78ac74e1 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -56,6 +56,11 @@ #define GRE_SUPPORTED_FIELDS (GRE_CHECKSUM_PRESENT | GRE_KEY_PRESENT |\ GRE_SEQUENCE_PRESENT) +/* When UDP or TCP or outer UDP csum offload is off, sw l4 csum is needed */ +#define UDP_TCP_CSUM (DEV_TX_OFFLOAD_UDP_CKSUM |\ + DEV_TX_OFFLOAD_TCP_CKSUM |\ + DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) + /* We cannot use rte_cpu_to_be_16() on a constant in a switch/case */ #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN #define _htons(x) ((uint16_t)((((x) & 0x00ffU) << 8) | (((x) & 0xff00U) >> 8))) @@ -602,12 +607,8 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, /* do not recalculate udp cksum if it was 0 */ if (udp_hdr->dgram_cksum != 0) { udp_hdr->dgram_cksum = 0; - if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4)) - udp_hdr->dgram_cksum = - rte_ipv4_udptcp_cksum(ipv4_hdr, udp_hdr); - else - udp_hdr->dgram_cksum = - rte_ipv6_udptcp_cksum(ipv6_hdr, udp_hdr); + udp_hdr->dgram_cksum = get_udptcp_checksum(outer_l3_hdr, + udp_hdr, info->outer_ethertype); } return ol_flags; @@ -877,7 +878,17 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, ð_hdr->src_addr); parse_ethernet(eth_hdr, &info); - l3_hdr = (char *)eth_hdr + info.l2_len; + /* When sw csum is needed, multi-segs needs a buf to contain + * the whole packet for later UDP/TCP csum calculation. + */ + if (m->nb_segs > 1 && !(tx_ol_flags & PKT_TX_TCP_SEG) && + !(tx_offloads & UDP_TCP_CSUM)) { + char l3_buf[RTE_IPV4_MAX_PKT_LEN + 1]; + rte_pktmbuf_read(m, info.l2_len, + info.pkt_len - info.l2_len, l3_buf); + l3_hdr = l3_buf; + } else + l3_hdr = (char *)eth_hdr + info.l2_len; /* check if it's a supported tunnel */ if (txp->parse_tunnel) { -- 2.25.1