From patchwork Thu Sep 28 22:13:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Kavanagh X-Patchwork-Id: 29397 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 9A33F1B1A0; Fri, 29 Sep 2017 00:14:47 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 0D67D3195 for ; Fri, 29 Sep 2017 00:14:39 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Sep 2017 15:14:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.42,451,1500966000"; d="scan'208"; a="1200210902" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga001.fm.intel.com with ESMTP; 28 Sep 2017 15:14:38 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id v8SMEbAJ005336; Thu, 28 Sep 2017 23:14:37 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id v8SMEben026290; Thu, 28 Sep 2017 23:14:37 +0100 Received: (from mbkavana@localhost) by sivswdev01.ir.intel.com with LOCAL id v8SMEbG2026286; Thu, 28 Sep 2017 23:14:37 +0100 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, 28 Sep 2017 23:13:51 +0100 Message-Id: <1506636833-25851-5-git-send-email-mark.b.kavanagh@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1505806379-71355-1-git-send-email-jiayu.hu@intel.com> References: <1505806379-71355-1-git-send-email-jiayu.hu@intel.com> Subject: [dpdk-dev] [PATCH v5 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 | 3 +++ lib/librte_gso/gso_common.h | 5 +++++ lib/librte_gso/gso_tunnel_tcp4.c | 14 ++++++++++---- lib/librte_gso/rte_gso.c | 8 +++++--- 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 25b8a78..808f537 100644 --- a/doc/guides/rel_notes/release_17_11.rst +++ b/doc/guides/rel_notes/release_17_11.rst @@ -51,6 +51,9 @@ New Features * VxLAN packets, which must have an outer IPv4 header (prepended by an optional VLAN tag), and contain an inner TCP/IPv4 packet (with an optional VLAN tag). + * GRE packets, which must contain an outer IPv4 header (prepended by + an optional VLAN tag), and inner TCP/IPv4 headers (with an optional + VLAN tag). 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 c051295..1e99cc0 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 34bbbd7..d79fc6b 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 6095689..b748ab1 100644 --- a/lib/librte_gso/rte_gso.c +++ b/lib/librte_gso/rte_gso.c @@ -60,8 +60,9 @@ if ((gso_ctx->gso_size >= pkt->pkt_len) || (gso_ctx->gso_types & (DEV_TX_OFFLOAD_TCP_TSO | - DEV_TX_OFFLOAD_VXLAN_TNL_TSO)) != - gso_ctx->gso_types) { + 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; return 1; @@ -73,7 +74,8 @@ ipid_delta = (gso_ctx->ipid_flag != RTE_GSO_IPID_FIXED); ol_flags = pkt->ol_flags; - if (IS_IPV4_VXLAN_TCP4(pkt->ol_flags)) { + if (IS_IPV4_VXLAN_TCP4(pkt->ol_flags) || + IS_IPV4_GRE_TCP4(pkt->ol_flags)) { pkt->ol_flags &= (~PKT_TX_TCP_SEG); ret = gso_tunnel_tcp4_segment(pkt, gso_size, ipid_delta, direct_pool, indirect_pool,