From patchwork Thu Oct 5 11:02:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Kavanagh X-Patchwork-Id: 29675 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 073031B1B8; Thu, 5 Oct 2017 13:02:32 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id DE06B1AF03 for ; Thu, 5 Oct 2017 13:02:26 +0200 (CEST) Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Oct 2017 04:02:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,481,1500966000"; d="scan'208";a="159160339" Received: from silpixa00380299.ir.intel.com ([10.237.222.17]) by fmsmga005.fm.intel.com with ESMTP; 05 Oct 2017 04:02:24 -0700 From: Mark Kavanagh To: dev@dpdk.org Cc: jiayu.hu@intel.com, jianfeng.tan@intel.com, konstantin.ananyev@intel.com, ferruh.yigit@intel.com, thomas@monjalon.net, Mark Kavanagh Date: Thu, 5 Oct 2017 12:02:09 +0100 Message-Id: <1507201331-228465-5-git-send-email-mark.b.kavanagh@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1507201331-228465-1-git-send-email-mark.b.kavanagh@intel.com> References: <1506962749-106779-1-git-send-email-mark.b.kavanagh@intel.com> <1507201331-228465-1-git-send-email-mark.b.kavanagh@intel.com> Subject: [dpdk-dev] [PATCH v7 4/6] gso: add GRE GSO support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds GSO support for GRE-tunneled packets. Supported GRE packets must contain an outer IPv4 header, and inner TCP/IPv4 headers. They may also contain a single VLAN tag. GRE GSO doesn't check if all input packets have correct checksums and doesn't update checksums for output packets. Additionally, it doesn't process IP fragmented packets. As with VxLAN GSO, GRE GSO uses a two-segment MBUF to organize each output packet, which requires multi-segment mbuf support in the TX functions of the NIC driver. Also, if a packet is GSOed, GRE GSO reduces its MBUF refcnt by 1. As a result, when all of its GSOed segments are freed, the packet is freed automatically. Signed-off-by: Mark Kavanagh Signed-off-by: Jiayu Hu --- doc/guides/rel_notes/release_17_11.rst | 2 ++ lib/librte_gso/gso_common.h | 5 +++++ lib/librte_gso/gso_tunnel_tcp4.c | 14 ++++++++++---- lib/librte_gso/rte_gso.c | 9 ++++++--- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst index c58eeb1..2faa630 100644 --- a/doc/guides/rel_notes/release_17_11.rst +++ b/doc/guides/rel_notes/release_17_11.rst @@ -50,6 +50,8 @@ New Features * TCP/IPv4 packets. * VxLAN packets, which must have an outer IPv4 header, and contain an inner TCP/IPv4 packet. + * GRE packets, which must contain an outer IPv4 header, and inner + TCP/IPv4 headers. The GSO library doesn't check if the input packets have correct checksums, and doesn't update checksums for output packets. diff --git a/lib/librte_gso/gso_common.h b/lib/librte_gso/gso_common.h index 95d54e7..145ea49 100644 --- a/lib/librte_gso/gso_common.h +++ b/lib/librte_gso/gso_common.h @@ -55,6 +55,11 @@ (PKT_TX_TCP_SEG | PKT_TX_IPV4 | PKT_TX_OUTER_IPV4 | \ PKT_TX_TUNNEL_VXLAN)) +#define IS_IPV4_GRE_TCP4(flag) (((flag) & (PKT_TX_TCP_SEG | PKT_TX_IPV4 | \ + PKT_TX_OUTER_IPV4 | PKT_TX_TUNNEL_GRE)) == \ + (PKT_TX_TCP_SEG | PKT_TX_IPV4 | PKT_TX_OUTER_IPV4 | \ + PKT_TX_TUNNEL_GRE)) + /** * Internal function which updates the UDP header of a packet, following * segmentation. This is required to update the header's datagram length field. diff --git a/lib/librte_gso/gso_tunnel_tcp4.c b/lib/librte_gso/gso_tunnel_tcp4.c index 5e8c8e5..8d0cfd7 100644 --- a/lib/librte_gso/gso_tunnel_tcp4.c +++ b/lib/librte_gso/gso_tunnel_tcp4.c @@ -42,11 +42,13 @@ struct tcp_hdr *tcp_hdr; uint32_t sent_seq; uint16_t outer_id, inner_id, tail_idx, i; - uint16_t outer_ipv4_offset, inner_ipv4_offset, udp_offset, tcp_offset; + uint16_t outer_ipv4_offset, inner_ipv4_offset; + uint16_t udp_gre_offset, tcp_offset; + uint8_t update_udp_hdr; outer_ipv4_offset = pkt->outer_l2_len; - udp_offset = outer_ipv4_offset + pkt->outer_l3_len; - inner_ipv4_offset = udp_offset + pkt->l2_len; + udp_gre_offset = outer_ipv4_offset + pkt->outer_l3_len; + inner_ipv4_offset = udp_gre_offset + pkt->l2_len; tcp_offset = inner_ipv4_offset + pkt->l3_len; /* Outer IPv4 header. */ @@ -63,9 +65,13 @@ sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq); tail_idx = nb_segs - 1; + /* Only update UDP header for VxLAN packets. */ + update_udp_hdr = (pkt->ol_flags & PKT_TX_TUNNEL_VXLAN) ? 1 : 0; + for (i = 0; i < nb_segs; i++) { update_ipv4_header(segs[i], outer_ipv4_offset, outer_id); - update_udp_header(segs[i], udp_offset); + if (update_udp_hdr) + update_udp_header(segs[i], udp_gre_offset); update_ipv4_header(segs[i], inner_ipv4_offset, inner_id); update_tcp_header(segs[i], tcp_offset, sent_seq, i < tail_idx); outer_id++; diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c index a6f38e2..1d4082a 100644 --- a/lib/librte_gso/rte_gso.c +++ b/lib/librte_gso/rte_gso.c @@ -61,7 +61,8 @@ if ((gso_ctx->gso_size < RTE_GSO_SEG_SIZE_MIN) || (gso_ctx->gso_size >= pkt->pkt_len) || (gso_ctx->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | - DEV_TX_OFFLOAD_VXLAN_TNL_TSO)) != + DEV_TX_OFFLOAD_VXLAN_TNL_TSO | + DEV_TX_OFFLOAD_GRE_TNL_TSO)) != gso_ctx->gso_types) { pkt->ol_flags &= (~PKT_TX_TCP_SEG); pkts_out[0] = pkt; @@ -74,8 +75,10 @@ ipid_delta = (gso_ctx->flag != RTE_GSO_FLAG_IPID_FIXED); ol_flags = pkt->ol_flags; - if (IS_IPV4_VXLAN_TCP4(pkt->ol_flags) - && (gso_ctx->gso_types & DEV_TX_OFFLOAD_VXLAN_TNL_TSO)) { + if ((IS_IPV4_VXLAN_TCP4(pkt->ol_flags) && + (gso_ctx->gso_types & DEV_TX_OFFLOAD_VXLAN_TNL_TSO)) || + ((IS_IPV4_GRE_TCP4(pkt->ol_flags) && + (gso_ctx->gso_types & DEV_TX_OFFLOAD_GRE_TNL_TSO)))) { pkt->ol_flags &= (~PKT_TX_TCP_SEG); ret = gso_tunnel_tcp4_segment(pkt, gso_size, ipid_delta, direct_pool, indirect_pool,