From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 187BD23B for ; Wed, 20 Sep 2017 04:53:57 +0200 (CEST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Sep 2017 19:53:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.42,420,1500966000"; d="scan'208";a="137331429" Received: from tanjianf-mobl.ccr.corp.intel.com (HELO [10.67.64.93]) ([10.67.64.93]) by orsmga002.jf.intel.com with ESMTP; 19 Sep 2017 19:53:54 -0700 To: Jiayu Hu , dev@dpdk.org References: <1505184211-36728-1-git-send-email-jiayu.hu@intel.com> <1505806379-71355-1-git-send-email-jiayu.hu@intel.com> <1505806379-71355-5-git-send-email-jiayu.hu@intel.com> Cc: konstantin.ananyev@intel.com, mark.b.kavanagh@intel.com, ferruh.yigit@intel.com, thomas@monjalon.net From: "Tan, Jianfeng" Message-ID: <8abc1a5e-9f74-6b83-2cca-99623ad9e95c@intel.com> Date: Wed, 20 Sep 2017 10:53:53 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <1505806379-71355-5-git-send-email-jiayu.hu@intel.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH v4 4/5] 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: , X-List-Received-Date: Wed, 20 Sep 2017 02:53:58 -0000 Hi, On 9/19/2017 3:32 PM, Jiayu Hu wrote: > From: Mark Kavanagh > > 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. > > GRE GSO clears the PKT_TX_TCP_SEG flag for the input packet and GSO > segments on the event of success. > > Signed-off-by: Mark Kavanagh > Signed-off-by: Jiayu Hu > --- > doc/guides/rel_notes/release_17_11.rst | 3 +++ > lib/librte_gso/gso_common.c | 31 +++++++++++++++++++++++++++++++ > lib/librte_gso/gso_common.h | 25 +++++++++++++++++++++++++ > lib/librte_gso/gso_tunnel_tcp4.c | 2 ++ > lib/librte_gso/rte_gso.c | 8 +++++--- > 5 files changed, 66 insertions(+), 3 deletions(-) > > diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst > index 2dc6b89..119f662 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.c b/lib/librte_gso/gso_common.c > index 90fcb2a..3629625 100644 > --- a/lib/librte_gso/gso_common.c > +++ b/lib/librte_gso/gso_common.c > @@ -37,6 +37,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -258,3 +259,33 @@ update_ipv4_vxlan_tcp4_header(struct rte_mbuf *pkt, uint8_t ipid_delta, > sent_seq += (segs[i]->pkt_len - segs[i]->data_len); > } > } > + > +void > +update_ipv4_gre_tcp4_header(struct rte_mbuf *pkt, uint8_t ipid_delta, > + struct rte_mbuf **segs, uint16_t nb_segs) > +{ This function seems to have too many duplicated code with above function, can we merge? > + struct ipv4_hdr *ipv4_hdr; > + struct tcp_hdr *tcp_hdr; > + uint32_t sent_seq; > + uint16_t l2_len, outer_id, inner_id, tail_idx, i; > + > + ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt, char *) + > + pkt->outer_l2_len); > + outer_id = rte_be_to_cpu_16(ipv4_hdr->packet_id); > + > + l2_len = pkt->outer_l2_len + pkt->outer_l3_len + pkt->l2_len; > + ipv4_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod(pkt, char *) + l2_len); > + inner_id = rte_be_to_cpu_16(ipv4_hdr->packet_id); > + tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + pkt->l3_len); > + sent_seq = rte_be_to_cpu_32(tcp_hdr->sent_seq); > + tail_idx = nb_segs - 1; > + for (i = 0; i < nb_segs; i++) { > + __update_outer_ipv4_header(segs[i], outer_id); > + outer_id += ipid_delta; We should update both outer and inner IPID? Could you add some spec reference here? > + > + __update_ipv4_tcp_header(segs[i], l2_len, inner_id, sent_seq, > + i < tail_idx); > + inner_id += ipid_delta; > + sent_seq += (segs[i]->pkt_len - segs[i]->data_len); > + } > +} > diff --git a/lib/librte_gso/gso_common.h b/lib/librte_gso/gso_common.h > index 0b0d8ed..433e952 100644 > --- a/lib/librte_gso/gso_common.h > +++ b/lib/librte_gso/gso_common.h > @@ -53,6 +53,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 relevant packet headers for TCP/IPv4 > * packets, following segmentation. This is required to update, for > @@ -94,6 +99,26 @@ void update_ipv4_vxlan_tcp4_header(struct rte_mbuf *pkt, > uint16_t nb_segs); > > /** > + * Internal function which updates relevant packet headers for GRE > + * packets, following segmentation. This is required to update, for > + * example, the IPv4 'total_length' field, to reflect the reduced > + * length of the now-segmented packet. > + * > + * @param pkt > + * The original packet. > + * @param ipid_delta > + * The increasing uint of IP ids. uint -> unit? > + * @param segs > + * Pointer array used for storing mbuf addresses for GSO segments. > + * @param nb_segs > + * The number of GSO segments placed in segs. > + */ > +void update_ipv4_gre_tcp4_header(struct rte_mbuf *pkt, > + uint8_t ipid_delta, > + struct rte_mbuf **segs, > + uint16_t nb_segs); > + > +/** > * Internal function which divides the input packet into small segments. > * Each of the newly-created segments is organized as a two-segment MBUF, > * where the first segment is a standard mbuf, which stores a copy of > diff --git a/lib/librte_gso/gso_tunnel_tcp4.c b/lib/librte_gso/gso_tunnel_tcp4.c > index cc017bd..5d5930a 100644 > --- a/lib/librte_gso/gso_tunnel_tcp4.c > +++ b/lib/librte_gso/gso_tunnel_tcp4.c > @@ -82,6 +82,8 @@ gso_tunnel_tcp4_segment(struct rte_mbuf *pkt, > > if (pkt->ol_flags & PKT_TX_TUNNEL_VXLAN) > update_ipv4_vxlan_tcp4_header(pkt, ipid_delta, pkts_out, ret); > + else if (pkt->ol_flags & PKT_TX_TUNNEL_GRE) > + update_ipv4_gre_tcp4_header(pkt, ipid_delta, pkts_out, ret); > > return ret; > } > diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c > index d1a723b..5464831 100644 > --- a/lib/librte_gso/rte_gso.c > +++ b/lib/librte_gso/rte_gso.c > @@ -60,8 +60,9 @@ rte_gso_segment(struct rte_mbuf *pkt, > > 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 ret; > @@ -73,7 +74,8 @@ rte_gso_segment(struct rte_mbuf *pkt, > 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,