From patchwork Wed Jun 21 08:25:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumara Parameshwaran X-Patchwork-Id: 128883 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1958242D12; Wed, 21 Jun 2023 10:25:54 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E863D42D0C; Wed, 21 Jun 2023 10:25:51 +0200 (CEST) Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) by mails.dpdk.org (Postfix) with ESMTP id 9EC0842D17 for ; Wed, 21 Jun 2023 10:25:49 +0200 (CEST) Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-1b525af07a6so26529295ad.1 for ; Wed, 21 Jun 2023 01:25:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687335949; x=1689927949; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bIe/VaFOi/ZzSk1qBEUav8zmcEJ5OvNRZEboX1I8NNQ=; b=H/imaKLOVb0u4Z+QRf5nf2EE52bFyahCqrRwCoMXl3yHMSOU1LkGgctiaKG0vZy2Xy hW095uSzNoo7tddOv7L+Q+B1MuTuCNvH1aqO4Kbrv611AUyakNKkVChFAJmYDeevpOir v9ZrCyt73pa7rX5a0n5jnguYLuV5+kM+4s3M5TFW5G7DumqGPZMzZkwH8iCClNO6Gelp MW03K1hOBS/eFU0/MppdmeVD6JShG5f3EMN82nyRytkvHd0QCpAzYd+PwSVrcc/f+FYh tbsbR8RuQDwjWY4CTvs87ouBHhKFSsN5BZ1K8Au+w1d0eHBmNL5K4L18CJrqLnmjPxHQ cRgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687335949; x=1689927949; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bIe/VaFOi/ZzSk1qBEUav8zmcEJ5OvNRZEboX1I8NNQ=; b=eCK2TI7RY0iljjqv6Mwmo6RILWFeAtv7hwcSkf1wkT6qO0nmaUOaxiqI8+PVykpAh3 yDdctm3YqH1hmRtZ8/3hUCsMBlD8VwKsFdEAHYW1k9JWUUZ84h4cEBxxgI25RZhUD6ug 2eLIeehFs/Bg1PneabxFGQ4AhoAMY9sQJGasPssR4DGJuJ0lI4Y7QrJgbc1p4d9ERHMr 7ggLRQ1KhOrSuNuTiuNLzAB1AwCg4wNjkbDS3AY1HdirUqAABY3QKB/Ol9khptDaJrrD GmvLsNDtyXbOEwpk7b0QiMEuaEQvpQkAxUzBjXxueY+b/Db/hZwNebrDnV2uz/JXwhXl feXQ== X-Gm-Message-State: AC+VfDz7jAmmVSswpmiLMVLS9w90wL8WyeUzdgLe8SF0hAc1N52LeRft TSHTd2h0KE6lvHtnVG3qiqM= X-Google-Smtp-Source: ACHHUZ4BJTutYbX5hl11AVK9hYbXh9IeVPz+YZ/pJ5x0EpLJ592GiYdZF6eyo0FO3IkoK9GcNN8izg== X-Received: by 2002:a17:902:ab54:b0:1ae:8e58:eb25 with SMTP id ij20-20020a170902ab5400b001ae8e58eb25mr8956238plb.28.1687335948662; Wed, 21 Jun 2023 01:25:48 -0700 (PDT) Received: from kparameshw7KFWX.vmware.com.com ([103.19.213.32]) by smtp.gmail.com with ESMTPSA id j6-20020a170902690600b001ab0159b9edsm2862253plk.250.2023.06.21.01.25.47 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 21 Jun 2023 01:25:48 -0700 (PDT) From: Kumara Parameshwaran To: jiayu.hu@intel.com Cc: dev@dpdk.org, Kumara Parameshwaran Subject: [PATCH v10 2/2] gro : add support for IPv6 GRO Date: Wed, 21 Jun 2023 13:55:17 +0530 Message-Id: <20230621082517.61697-2-kumaraparamesh92@gmail.com> X-Mailer: git-send-email 2.37.1 (Apple Git-137.1) In-Reply-To: <20230621082517.61697-1-kumaraparamesh92@gmail.com> References: <20221020181425.48006-1-kumaraparmesh92@gmail.com> <20230621082517.61697-1-kumaraparamesh92@gmail.com> MIME-Version: 1.0 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 Signed-off-by: Kumara Parameshwaran --- v1: * Changes to support GRO for TCP/ipv6 packets. This does not include vxlan changes. * The GRO is performed only for ipv6 packets that does not contain extension headers. * The logic for the TCP coalescing remains the same, in ipv6 header the source address, destination address, flow label, version fields are expected to be the same. * Re-organised the code to reuse certain tcp functions for both ipv4 and ipv6 flows. v2: * Fix comments in gro_tcp6.h header file. v3: * Adderess review comments to fix code duplication for v4 and v6 v4: * Addresses review comments for v3, do not use callbacks v5: * Address review comments v6: * Fix warning and coding style issues v7: * Fix build compilation issue v8: * Use gro_tcp_internal.h for functions used for gro_tcp4 and gro_tcp6 and use gro_tcp.h for data structures and functions used across gro_vxlan_tcp4 v9: * Resolve merge conflict and add gro_tcp.h in proper path v10: * Refactor the code to contain 2 patches. This patch contains support for IPv6 GRO .../generic_receive_offload_lib.rst | 21 ++--- doc/guides/rel_notes/release_23_07.rst | 2 + lib/gro/meson.build | 1 + lib/gro/rte_gro.c | 81 ++++++++++++++++--- lib/gro/rte_gro.h | 3 + 5 files changed, 85 insertions(+), 23 deletions(-) diff --git a/doc/guides/prog_guide/generic_receive_offload_lib.rst b/doc/guides/prog_guide/generic_receive_offload_lib.rst index 98a5d29bbc..533cda7f5c 100644 --- a/doc/guides/prog_guide/generic_receive_offload_lib.rst +++ b/doc/guides/prog_guide/generic_receive_offload_lib.rst @@ -138,20 +138,21 @@ The key-based algorithm has two characters: Key-based Reassembly Algorithm -TCP/IPv4 GRO ------------- +TCP-IPv4/IPv6 GRO +----------------- -The table structure used by TCP/IPv4 GRO contains two arrays: flow array +The table structure used by TCP-IPv4/IPv6 GRO contains two arrays: flow array and item array. The flow array keeps flow information, and the item array -keeps packet information. +keeps packet information. The flow array is different for IPv4 and IPv6 while +the item array is the same. -Header fields used to define a TCP/IPv4 flow include: +Header fields used to define a TCP-IPv4/IPv6 flow include: -- source and destination: Ethernet and IP address, TCP port +- common tcp key fields : Ethernet address, TCP port, TCP acknowledge number +- version specific IP address +- IPv6 flow label for IPv6 flow -- TCP acknowledge number - -TCP/IPv4 packets whose FIN, SYN, RST, URG, PSH, ECE or CWR bit is set +TCP packets whose FIN, SYN, RST, URG, PSH, ECE or CWR bit is set won't be processed. Header fields deciding if two packets are neighbors include: @@ -159,7 +160,7 @@ Header fields deciding if two packets are neighbors include: - TCP sequence number - IPv4 ID. The IPv4 ID fields of the packets, whose DF bit is 0, should - be increased by 1. + be increased by 1. This is applicable only for IPv4 VxLAN GRO --------- diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst index 027ae7bd2d..7124cf45c7 100644 --- a/doc/guides/rel_notes/release_23_07.rst +++ b/doc/guides/rel_notes/release_23_07.rst @@ -170,6 +170,8 @@ New Features See :doc:`../prog_guide/pdcp_lib` for more information. +* **Added support for TCP/IPv6 GRO.** + * Enhanced the existing library to support GRO for TCP packets over IPv6 network. Removed Items ------------- diff --git a/lib/gro/meson.build b/lib/gro/meson.build index e4fa2958bd..dbce05220d 100644 --- a/lib/gro/meson.build +++ b/lib/gro/meson.build @@ -4,6 +4,7 @@ sources = files( 'rte_gro.c', 'gro_tcp4.c', + 'gro_tcp6.c', 'gro_udp4.c', 'gro_vxlan_tcp4.c', 'gro_vxlan_udp4.c', diff --git a/lib/gro/rte_gro.c b/lib/gro/rte_gro.c index ac3d1cdc94..d824eebd93 100644 --- a/lib/gro/rte_gro.c +++ b/lib/gro/rte_gro.c @@ -8,6 +8,7 @@ #include "rte_gro.h" #include "gro_tcp4.h" +#include "gro_tcp6.h" #include "gro_udp4.h" #include "gro_vxlan_tcp4.h" #include "gro_vxlan_udp4.h" @@ -20,14 +21,16 @@ typedef uint32_t (*gro_tbl_pkt_count_fn)(void *tbl); static gro_tbl_create_fn tbl_create_fn[RTE_GRO_TYPE_MAX_NUM] = { gro_tcp4_tbl_create, gro_vxlan_tcp4_tbl_create, - gro_udp4_tbl_create, gro_vxlan_udp4_tbl_create, NULL}; + gro_udp4_tbl_create, gro_vxlan_udp4_tbl_create, gro_tcp6_tbl_create, NULL}; static gro_tbl_destroy_fn tbl_destroy_fn[RTE_GRO_TYPE_MAX_NUM] = { gro_tcp4_tbl_destroy, gro_vxlan_tcp4_tbl_destroy, gro_udp4_tbl_destroy, gro_vxlan_udp4_tbl_destroy, + gro_tcp6_tbl_destroy, NULL}; static gro_tbl_pkt_count_fn tbl_pkt_count_fn[RTE_GRO_TYPE_MAX_NUM] = { gro_tcp4_tbl_pkt_count, gro_vxlan_tcp4_tbl_pkt_count, gro_udp4_tbl_pkt_count, gro_vxlan_udp4_tbl_pkt_count, + gro_tcp6_tbl_pkt_count, NULL}; #define IS_IPV4_TCP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \ @@ -35,6 +38,12 @@ static gro_tbl_pkt_count_fn tbl_pkt_count_fn[RTE_GRO_TYPE_MAX_NUM] = { ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) +/* GRO with extension headers is not supported */ +#define IS_IPV6_TCP_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \ + ((ptype & RTE_PTYPE_L4_TCP) == RTE_PTYPE_L4_TCP) && \ + ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \ + (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) + #define IS_IPV4_UDP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \ ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \ (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0)) @@ -149,6 +158,10 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, struct gro_tcp4_flow tcp_flows[RTE_GRO_MAX_BURST_ITEM_NUM]; struct gro_tcp_item tcp_items[RTE_GRO_MAX_BURST_ITEM_NUM] = {{0} }; + struct gro_tcp6_tbl tcp6_tbl; + struct gro_tcp6_flow tcp6_flows[RTE_GRO_MAX_BURST_ITEM_NUM]; + struct gro_tcp_item tcp6_items[RTE_GRO_MAX_BURST_ITEM_NUM] = {{0} }; + /* allocate a reassembly table for UDP/IPv4 GRO */ struct gro_udp4_tbl udp_tbl; struct gro_udp4_flow udp_flows[RTE_GRO_MAX_BURST_ITEM_NUM]; @@ -171,10 +184,10 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, int32_t ret; uint16_t i, unprocess_num = 0, nb_after_gro = nb_pkts; uint8_t do_tcp4_gro = 0, do_vxlan_tcp_gro = 0, do_udp4_gro = 0, - do_vxlan_udp_gro = 0; + do_vxlan_udp_gro = 0, do_tcp6_gro = 0; if (unlikely((param->gro_types & (RTE_GRO_IPV4_VXLAN_TCP_IPV4 | - RTE_GRO_TCP_IPV4 | + RTE_GRO_TCP_IPV4 | RTE_GRO_TCP_IPV6 | RTE_GRO_IPV4_VXLAN_UDP_IPV4 | RTE_GRO_UDP_IPV4)) == 0)) return nb_pkts; @@ -236,6 +249,18 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, do_udp4_gro = 1; } + if (param->gro_types & RTE_GRO_TCP_IPV6) { + for (i = 0; i < item_num; i++) + tcp6_flows[i].start_index = INVALID_ARRAY_INDEX; + + tcp6_tbl.flows = tcp6_flows; + tcp6_tbl.items = tcp6_items; + tcp6_tbl.flow_num = 0; + tcp6_tbl.item_num = 0; + tcp6_tbl.max_flow_num = item_num; + tcp6_tbl.max_item_num = item_num; + do_tcp6_gro = 1; + } for (i = 0; i < nb_pkts; i++) { /* @@ -276,6 +301,14 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, nb_after_gro--; else if (ret < 0) unprocess_pkts[unprocess_num++] = pkts[i]; + } else if (IS_IPV6_TCP_PKT(pkts[i]->packet_type) && + do_tcp6_gro) { + ret = gro_tcp6_reassemble(pkts[i], &tcp6_tbl, 0); + if (ret > 0) + /* merge successfully */ + nb_after_gro--; + else if (ret < 0) + unprocess_pkts[unprocess_num++] = pkts[i]; } else unprocess_pkts[unprocess_num++] = pkts[i]; } @@ -283,9 +316,17 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, if ((nb_after_gro < nb_pkts) || (unprocess_num < nb_pkts)) { i = 0; + /* Copy unprocessed packets */ + if (unprocess_num > 0) { + memcpy(&pkts[i], unprocess_pkts, + sizeof(struct rte_mbuf *) * + unprocess_num); + i = unprocess_num; + } + /* Flush all packets from the tables */ if (do_vxlan_tcp_gro) { - i = gro_vxlan_tcp4_tbl_timeout_flush(&vxlan_tcp_tbl, + i += gro_vxlan_tcp4_tbl_timeout_flush(&vxlan_tcp_tbl, 0, pkts, nb_pkts); } @@ -304,13 +345,11 @@ rte_gro_reassemble_burst(struct rte_mbuf **pkts, i += gro_udp4_tbl_timeout_flush(&udp_tbl, 0, &pkts[i], nb_pkts - i); } - /* Copy unprocessed packets */ - if (unprocess_num > 0) { - memcpy(&pkts[i], unprocess_pkts, - sizeof(struct rte_mbuf *) * - unprocess_num); + + if (do_tcp6_gro) { + i += gro_tcp6_tbl_timeout_flush(&tcp6_tbl, 0, + &pkts[i], nb_pkts - i); } - nb_after_gro = i + unprocess_num; } return nb_after_gro; @@ -323,13 +362,13 @@ rte_gro_reassemble(struct rte_mbuf **pkts, { struct rte_mbuf *unprocess_pkts[nb_pkts]; struct gro_ctx *gro_ctx = ctx; - void *tcp_tbl, *udp_tbl, *vxlan_tcp_tbl, *vxlan_udp_tbl; + void *tcp_tbl, *udp_tbl, *vxlan_tcp_tbl, *vxlan_udp_tbl, *tcp6_tbl; uint64_t current_time; uint16_t i, unprocess_num = 0; - uint8_t do_tcp4_gro, do_vxlan_tcp_gro, do_udp4_gro, do_vxlan_udp_gro; + uint8_t do_tcp4_gro, do_vxlan_tcp_gro, do_udp4_gro, do_vxlan_udp_gro, do_tcp6_gro; if (unlikely((gro_ctx->gro_types & (RTE_GRO_IPV4_VXLAN_TCP_IPV4 | - RTE_GRO_TCP_IPV4 | + RTE_GRO_TCP_IPV4 | RTE_GRO_TCP_IPV6 | RTE_GRO_IPV4_VXLAN_UDP_IPV4 | RTE_GRO_UDP_IPV4)) == 0)) return nb_pkts; @@ -338,6 +377,7 @@ rte_gro_reassemble(struct rte_mbuf **pkts, vxlan_tcp_tbl = gro_ctx->tbls[RTE_GRO_IPV4_VXLAN_TCP_IPV4_INDEX]; udp_tbl = gro_ctx->tbls[RTE_GRO_UDP_IPV4_INDEX]; vxlan_udp_tbl = gro_ctx->tbls[RTE_GRO_IPV4_VXLAN_UDP_IPV4_INDEX]; + tcp6_tbl = gro_ctx->tbls[RTE_GRO_TCP_IPV6_INDEX]; do_tcp4_gro = (gro_ctx->gro_types & RTE_GRO_TCP_IPV4) == RTE_GRO_TCP_IPV4; @@ -347,6 +387,7 @@ rte_gro_reassemble(struct rte_mbuf **pkts, RTE_GRO_UDP_IPV4; do_vxlan_udp_gro = (gro_ctx->gro_types & RTE_GRO_IPV4_VXLAN_UDP_IPV4) == RTE_GRO_IPV4_VXLAN_UDP_IPV4; + do_tcp6_gro = (gro_ctx->gro_types & RTE_GRO_TCP_IPV6) == RTE_GRO_TCP_IPV6; current_time = rte_rdtsc(); @@ -371,6 +412,11 @@ rte_gro_reassemble(struct rte_mbuf **pkts, if (gro_udp4_reassemble(pkts[i], udp_tbl, current_time) < 0) unprocess_pkts[unprocess_num++] = pkts[i]; + } else if (IS_IPV6_TCP_PKT(pkts[i]->packet_type) && + do_tcp6_gro) { + if (gro_tcp6_reassemble(pkts[i], tcp6_tbl, + current_time) < 0) + unprocess_pkts[unprocess_num++] = pkts[i]; } else unprocess_pkts[unprocess_num++] = pkts[i]; } @@ -426,6 +472,15 @@ rte_gro_timeout_flush(void *ctx, gro_ctx->tbls[RTE_GRO_UDP_IPV4_INDEX], flush_timestamp, &out[num], left_nb_out); + left_nb_out = max_nb_out - num; + } + + if ((gro_types & RTE_GRO_TCP_IPV6) && left_nb_out > 0) { + num += gro_tcp6_tbl_timeout_flush( + gro_ctx->tbls[RTE_GRO_TCP_IPV6_INDEX], + flush_timestamp, + &out[num], left_nb_out); + } return num; diff --git a/lib/gro/rte_gro.h b/lib/gro/rte_gro.h index 9f9ed4935a..c83dfd9ad1 100644 --- a/lib/gro/rte_gro.h +++ b/lib/gro/rte_gro.h @@ -38,6 +38,9 @@ extern "C" { #define RTE_GRO_IPV4_VXLAN_UDP_IPV4_INDEX 3 #define RTE_GRO_IPV4_VXLAN_UDP_IPV4 (1ULL << RTE_GRO_IPV4_VXLAN_UDP_IPV4_INDEX) /**< VxLAN UDP/IPv4 GRO flag. */ +#define RTE_GRO_TCP_IPV6_INDEX 4 +#define RTE_GRO_TCP_IPV6 (1ULL << RTE_GRO_TCP_IPV6_INDEX) +/**< TCP/IPv6 GRO flag. */ /** * Structure used to create GRO context objects or used to pass