From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <konstantin.ananyev@intel.com>
Received: from mga02.intel.com (mga02.intel.com [134.134.136.20])
 by dpdk.org (Postfix) with ESMTP id DA4A71B64F
 for <dev@dpdk.org>; Wed,  4 Oct 2017 15:11:06 +0200 (CEST)
Received: from fmsmga001.fm.intel.com ([10.253.24.23])
 by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;
 04 Oct 2017 06:11:05 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.42,477,1500966000"; d="scan'208";a="1202118007"
Received: from irsmsx153.ger.corp.intel.com ([163.33.192.75])
 by fmsmga001.fm.intel.com with ESMTP; 04 Oct 2017 06:11:04 -0700
Received: from irsmsx155.ger.corp.intel.com (163.33.192.3) by
 IRSMSX153.ger.corp.intel.com (163.33.192.75) with Microsoft SMTP Server (TLS)
 id 14.3.319.2; Wed, 4 Oct 2017 14:11:03 +0100
Received: from irsmsx103.ger.corp.intel.com ([169.254.3.49]) by
 irsmsx155.ger.corp.intel.com ([169.254.14.169]) with mapi id 14.03.0319.002;
 Wed, 4 Oct 2017 14:11:03 +0100
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: "Kavanagh, Mark B" <mark.b.kavanagh@intel.com>, "dev@dpdk.org"
 <dev@dpdk.org>
CC: "Hu, Jiayu" <jiayu.hu@intel.com>, "Tan, Jianfeng"
 <jianfeng.tan@intel.com>, "Yigit, Ferruh" <ferruh.yigit@intel.com>,
 "thomas@monjalon.net" <thomas@monjalon.net>
Thread-Topic: [PATCH v6 1/6] gso: add Generic Segmentation Offload API
 framework
Thread-Index: AQHTO532smAHnj77EUqFE721+XihbqLTrB0A
Date: Wed, 4 Oct 2017 13:11:02 +0000
Message-ID: <2601191342CEEE43887BDE71AB9772585FAA3D06@IRSMSX103.ger.corp.intel.com>
References: <1506636833-25851-1-git-send-email-mark.b.kavanagh@intel.com>
 <1506962749-106779-1-git-send-email-mark.b.kavanagh@intel.com>
 <1506962749-106779-2-git-send-email-mark.b.kavanagh@intel.com>
In-Reply-To: <1506962749-106779-2-git-send-email-mark.b.kavanagh@intel.com>
Accept-Language: en-IE, en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiM2M1MjQxN2YtM2NiOS00MzliLTgxMzctNGE1OTY1OTMxNjMyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6IkVmOXZ3NjFDVVVQUnptUkhHRTlpMTFHc3lIOWJHZTJQRFdUaTVWV1NOTGs9In0=
x-ctpclassification: CTP_IC
dlp-product: dlpe-windows
dlp-version: 11.0.0.116
dlp-reaction: no-action
x-originating-ip: [163.33.239.182]
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Subject: Re: [dpdk-dev] [PATCH v6 1/6] gso: add Generic Segmentation Offload
 API framework
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Wed, 04 Oct 2017 13:11:07 -0000



> -----Original Message-----
> From: Kavanagh, Mark B
> Sent: Monday, October 2, 2017 5:46 PM
> To: dev@dpdk.org
> Cc: Hu, Jiayu <jiayu.hu@intel.com>; Tan, Jianfeng <jianfeng.tan@intel.com=
>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>; thomas@monjalon.net; Kavanagh, Mark B <m=
ark.b.kavanagh@intel.com>
> Subject: [PATCH v6 1/6] gso: add Generic Segmentation Offload API framewo=
rk
>=20
> From: Jiayu Hu <jiayu.hu@intel.com>
>=20
> Generic Segmentation Offload (GSO) is a SW technique to split large
> packets into small ones. Akin to TSO, GSO enables applications to
> operate on large packets, thus reducing per-packet processing overhead.
>=20
> To enable more flexibility to applications, DPDK GSO is implemented
> as a standalone library. Applications explicitly use the GSO library
> to segment packets. To segment a packet requires two steps. The first
> is to set proper flags to mbuf->ol_flags, where the flags are the same
> as that of TSO. The second is to call the segmentation API,
> rte_gso_segment(). This patch introduces the GSO API framework to DPDK.
>=20
> rte_gso_segment() splits an input packet into small ones in each
> invocation. The GSO library refers to these small packets generated
> by rte_gso_segment() as GSO segments. Each of the newly-created GSO
> segments is organized as a two-segment MBUF, where the first segment is a
> standard MBUF, which stores a copy of packet header, and the second is an
> indirect MBUF which points to a section of data in the input packet.
> rte_gso_segment() reduces the refcnt of the input packet by 1. Therefore,
> when all GSO segments are freed, the input packet is freed automatically.
> Additionally, since each GSO segment has multiple MBUFs (i.e. 2 MBUFs),
> the driver of the interface which the GSO segments are sent to should
> support to transmit multi-segment packets.
>=20
> The GSO framework clears the PKT_TX_TCP_SEG flag for both the input
> packet, and all produced GSO segments in the event of success, since
> segmentation in hardware is no longer required at that point.
>=20
> Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
> ---
>  config/common_base                     |   5 ++
>  doc/api/doxy-api-index.md              |   1 +
>  doc/api/doxy-api.conf                  |   1 +
>  doc/guides/rel_notes/release_17_11.rst |   1 +
>  lib/Makefile                           |   2 +
>  lib/librte_gso/Makefile                |  49 +++++++++++
>  lib/librte_gso/rte_gso.c               |  52 ++++++++++++
>  lib/librte_gso/rte_gso.h               | 145 +++++++++++++++++++++++++++=
++++++
>  lib/librte_gso/rte_gso_version.map     |   7 ++
>  mk/rte.app.mk                          |   1 +
>  10 files changed, 264 insertions(+)
>  create mode 100644 lib/librte_gso/Makefile
>  create mode 100644 lib/librte_gso/rte_gso.c
>  create mode 100644 lib/librte_gso/rte_gso.h
>  create mode 100644 lib/librte_gso/rte_gso_version.map
>=20
> diff --git a/config/common_base b/config/common_base
> index 12f6be9..58ca5c0 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -653,6 +653,11 @@ CONFIG_RTE_LIBRTE_IP_FRAG_TBL_STAT=3Dn
>  CONFIG_RTE_LIBRTE_GRO=3Dy
>=20
>  #
> +# Compile GSO library
> +#
> +CONFIG_RTE_LIBRTE_GSO=3Dy
> +
> +#
>  # Compile librte_meter
>  #
>  CONFIG_RTE_LIBRTE_METER=3Dy
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 19e0d4f..6512918 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -101,6 +101,7 @@ The public API headers are grouped by topics:
>    [TCP]                (@ref rte_tcp.h),
>    [UDP]                (@ref rte_udp.h),
>    [GRO]                (@ref rte_gro.h),
> +  [GSO]                (@ref rte_gso.h),
>    [frag/reass]         (@ref rte_ip_frag.h),
>    [LPM IPv4 route]     (@ref rte_lpm.h),
>    [LPM IPv6 route]     (@ref rte_lpm6.h),
> diff --git a/doc/api/doxy-api.conf b/doc/api/doxy-api.conf
> index 823554f..408f2e6 100644
> --- a/doc/api/doxy-api.conf
> +++ b/doc/api/doxy-api.conf
> @@ -47,6 +47,7 @@ INPUT                   =3D doc/api/doxy-api-index.md \
>                            lib/librte_ether \
>                            lib/librte_eventdev \
>                            lib/librte_gro \
> +                          lib/librte_gso \
>                            lib/librte_hash \
>                            lib/librte_ip_frag \
>                            lib/librte_jobstats \
> diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_note=
s/release_17_11.rst
> index 8bf91bd..7508be7 100644
> --- a/doc/guides/rel_notes/release_17_11.rst
> +++ b/doc/guides/rel_notes/release_17_11.rst
> @@ -174,6 +174,7 @@ The libraries prepended with a plus sign were increme=
nted in this version.
>       librte_ethdev.so.7
>       librte_eventdev.so.2
>       librte_gro.so.1
> +   + librte_gso.so.1
>       librte_hash.so.2
>       librte_ip_frag.so.1
>       librte_jobstats.so.1
> diff --git a/lib/Makefile b/lib/Makefile
> index 86caba1..3d123f4 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -108,6 +108,8 @@ DIRS-$(CONFIG_RTE_LIBRTE_REORDER) +=3D librte_reorder
>  DEPDIRS-librte_reorder :=3D librte_eal librte_mempool librte_mbuf
>  DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) +=3D librte_pdump
>  DEPDIRS-librte_pdump :=3D librte_eal librte_mempool librte_mbuf librte_e=
ther
> +DIRS-$(CONFIG_RTE_LIBRTE_GSO) +=3D librte_gso
> +DEPDIRS-librte_gso :=3D librte_eal librte_mbuf librte_ether librte_net
>=20
>  ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
>  DIRS-$(CONFIG_RTE_LIBRTE_KNI) +=3D librte_kni
> diff --git a/lib/librte_gso/Makefile b/lib/librte_gso/Makefile
> new file mode 100644
> index 0000000..aeaacbc
> --- /dev/null
> +++ b/lib/librte_gso/Makefile
> @@ -0,0 +1,49 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2017 Intel Corporation. All rights reserved.
> +#   All rights reserved.
> +#
> +#   Redistribution and use in source and binary forms, with or without
> +#   modification, are permitted provided that the following conditions
> +#   are met:
> +#
> +#     * Redistributions of source code must retain the above copyright
> +#       notice, this list of conditions and the following disclaimer.
> +#     * Redistributions in binary form must reproduce the above copyrigh=
t
> +#       notice, this list of conditions and the following disclaimer in
> +#       the documentation and/or other materials provided with the
> +#       distribution.
> +#     * Neither the name of Intel Corporation nor the names of its
> +#       contributors may be used to endorse or promote products derived
> +#       from this software without specific prior written permission.
> +#
> +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FO=
R
> +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL=
,
> +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE=
,
> +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON AN=
Y
> +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE US=
E
> +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +# library name
> +LIB =3D librte_gso.a
> +
> +CFLAGS +=3D $(WERROR_FLAGS) -I$(SRCDIR) -O3
> +
> +EXPORT_MAP :=3D rte_gso_version.map
> +
> +LIBABIVER :=3D 1
> +
> +#source files
> +SRCS-$(CONFIG_RTE_LIBRTE_GSO) +=3D rte_gso.c
> +
> +# install this header file
> +SYMLINK-$(CONFIG_RTE_LIBRTE_GSO)-include +=3D rte_gso.h
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_gso/rte_gso.c b/lib/librte_gso/rte_gso.c
> new file mode 100644
> index 0000000..b773636
> --- /dev/null
> +++ b/lib/librte_gso/rte_gso.c
> @@ -0,0 +1,52 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyrig=
ht
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS F=
OR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGH=
T
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA=
L,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US=
E,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A=
NY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U=
SE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE=
.
> + */
> +
> +#include <errno.h>
> +
> +#include "rte_gso.h"
> +
> +int
> +rte_gso_segment(struct rte_mbuf *pkt,
> +		const struct rte_gso_ctx *gso_ctx,
> +		struct rte_mbuf **pkts_out,
> +		uint16_t nb_pkts_out)
> +{
> +	if (pkt =3D=3D NULL || pkts_out =3D=3D NULL || gso_ctx =3D=3D NULL ||
> +			nb_pkts_out < 1)
> +		return -EINVAL;
> +
> +	pkt->ol_flags &=3D (~PKT_TX_TCP_SEG);
> +	pkts_out[0] =3D pkt;
> +
> +	return 1;
> +}
> diff --git a/lib/librte_gso/rte_gso.h b/lib/librte_gso/rte_gso.h
> new file mode 100644
> index 0000000..53725e6
> --- /dev/null
> +++ b/lib/librte_gso/rte_gso.h
> @@ -0,0 +1,145 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2017 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyrig=
ht
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS F=
OR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGH=
T
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA=
L,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF US=
E,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A=
NY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE U=
SE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE=
.
> + */
> +
> +#ifndef _RTE_GSO_H_
> +#define _RTE_GSO_H_
> +
> +/**
> + * @file
> + * Interface to GSO library
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdint.h>
> +#include <rte_mbuf.h>
> +
> +/* GSO IP id flags for the IPv4 header */
> +#define RTE_GSO_IPID_FIXED (1ULL << 0)
> +/**< Use fixed IP ids for output GSO segments. Setting
> + * !RTE_GSO_IPID_FIXED indicates using incremental IP ids.
> + */
> +
> +/**
> + * GSO context structure.
> + */
> +struct rte_gso_ctx {
> +	struct rte_mempool *direct_pool;
> +	/**< MBUF pool for allocating direct buffers, which are used
> +	 * to store packet headers for GSO segments.
> +	 */
> +	struct rte_mempool *indirect_pool;
> +	/**< MBUF pool for allocating indirect buffers, which are used
> +	 * to locate packet payloads for GSO segments. The indirect
> +	 * buffer doesn't contain any data, but simply points to an
> +	 * offset within the packet to segment.
> +	 */
> +	uint64_t ipid_flag;
> +	/**< flag to indicate GSO uses fixed or incremental IP ids for
> +	 * IPv4 headers of output GSO segments. If applications want
> +	 * fixed IP ids, set RTE_GSO_IPID_FIXED to ipid_flag. Conversely,
> +	 * if applications want incremental IP ids, set !RTE_GSO_IPID_FIXED.
> +	 */

Minor nit - I think better to just name it 'flag' - as in future some other=
=20
non IPID related flags might be added.
Also make sure that all flag values have RTE_GSO_FLAG (or so prefixes),
and move explanation of particular flag value to its definition.=20
Konstantin

> +	uint32_t gso_types;
> +	/**< the bit mask of required GSO types. The GSO library
> +	 * uses the same macros as that of describing device TX
> +	 * offloading capabilities (i.e. DEV_TX_OFFLOAD_*_TSO) for
> +	 * gso_types.
> +	 *
> +	 * For example, if applications want to segment TCP/IPv4
> +	 * packets, set DEV_TX_OFFLOAD_TCP_TSO in gso_types.
> +	 */
> +	uint16_t gso_size;
> +	/**< maximum size of an output GSO segment, including packet
> +	 * header and payload, measured in bytes.
> +	 */
> +};
> +
> +/**
> + * Segmentation function, which supports processing of both single- and
> + * multi- MBUF packets.
> + *
> + * Note that we refer to the packets that are segmented from the input
> + * packet as 'GSO segments'. rte_gso_segment() doesn't check if the
> + * input packet has correct checksums, and doesn't update checksums for
> + * output GSO segments. Additionally, it doesn't process IP fragment
> + * packets.
> + *
> + * Before calling rte_gso_segment(), applications must set proper ol_fla=
gs
> + * for the packet. The GSO library uses the same macros as that of TSO.
> + * For example, set PKT_TX_TCP_SEG and PKT_TX_IPV4 in ol_flags to segmen=
t
> + * a TCP/IPv4 packet. If rte_gso_segment() succceds, the PKT_TX_TCP_SEG
> + * flag is removed for all GSO segments and the input packet.
> + *
> + * Each of the newly-created GSO segments is organized as a two-segment
> + * MBUF, where the first segment is a standard MBUF, which stores a copy
> + * of packet header, and the second is an indirect MBUF which points to
> + * a section of data in the input packet. Since each GSO segment has
> + * multiple MBUFs (i.e. typically 2 MBUFs), the driver of the interface =
which
> + * the GSO segments are sent to should support transmission of multi-seg=
ment
> + * packets.
> + *
> + * If the input packet is GSO'd, its mbuf refcnt reduces by 1. Therefore=
,
> + * when all GSO segments are freed, the input packet is freed automatica=
lly.
> + *
> + * If the memory space in pkts_out or MBUF pools is insufficient, this
> + * function fails, and it returns (-1) * errno. Otherwise, GSO succeeds,
> + * and this function returns the number of output GSO segments filled in
> + * pkts_out.
> + *
> + * @param pkt
> + *  The packet mbuf to segment.
> + * @param ctx
> + *  GSO context object pointer.
> + * @param pkts_out
> + *  Pointer array used to store the MBUF addresses of output GSO
> + *  segments, when rte_gso_segment() succeeds.
> + * @param nb_pkts_out
> + *  The max number of items that pkts_out can keep.
> + *
> + * @return
> + *  - The number of GSO segments filled in pkts_out on success.
> + *  - Return -ENOMEM if run out of memory in MBUF pools.
> + *  - Return -EINVAL for invalid parameters.
> + */
> +int rte_gso_segment(struct rte_mbuf *pkt,
> +		const struct rte_gso_ctx *ctx,
> +		struct rte_mbuf **pkts_out,
> +		uint16_t nb_pkts_out);
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_GSO_H_ */
> diff --git a/lib/librte_gso/rte_gso_version.map b/lib/librte_gso/rte_gso_=
version.map
> new file mode 100644
> index 0000000..e1fd453
> --- /dev/null
> +++ b/lib/librte_gso/rte_gso_version.map
> @@ -0,0 +1,7 @@
> +DPDK_17.11 {
> +	global:
> +
> +	rte_gso_segment;
> +
> +	local: *;
> +};
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index c25fdd9..d4c9873 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -66,6 +66,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PDUMP)          +=3D -lrte_=
pdump
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR)    +=3D -lrte_distributor
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG)        +=3D -lrte_ip_frag
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_GRO)            +=3D -lrte_gro
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_GSO)            +=3D -lrte_gso
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_METER)          +=3D -lrte_meter
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED)          +=3D -lrte_sched
>  _LDLIBS-$(CONFIG_RTE_LIBRTE_LPM)            +=3D -lrte_lpm
> --
> 1.9.3