From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 30F5C42B55;
	Sat, 20 May 2023 21:53:53 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id B752342BC9;
	Sat, 20 May 2023 21:53:52 +0200 (CEST)
Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com
 [209.85.221.52]) by mails.dpdk.org (Postfix) with ESMTP id A329F40395
 for <dev@dpdk.org>; Sat, 20 May 2023 21:53:51 +0200 (CEST)
Received: by mail-wr1-f52.google.com with SMTP id
 ffacd0b85a97d-3095557dd99so1791412f8f.1
 for <dev@dpdk.org>; Sat, 20 May 2023 12:53:51 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20221208; t=1684612431; x=1687204431;
 h=cc:to:subject:message-id:date:from:in-reply-to:references
 :mime-version:from:to:cc:subject:date:message-id:reply-to;
 bh=8uhEFIOK+mzVFeliYBtTnAXmYTUyU587KEGp4gWroHM=;
 b=X+DssB7lqBgkPeHGHWaEIchN3fgQMFBFczl3di7innOXqvN12GYSKCYbM4OZlCJ7wf
 H0LuphPzc7TtzCj4+WM8VrRXislJ8y6hsYeKWNz08DMNQEesr+9czUgGswlUYK1BRJQ4
 Gk+BcfLG1XkYfnP1JpKDRq0jvk5u0xDkWIX8lWanwQWKkdZFe+rdTEc9O2gbuf0gNmux
 JeRr7GVmwzux69zAb29O97VrUh1bXJTErE0bhpyRzvWOn8P9pxcMUTJa7dx9J7aPrLX+
 qKgt7t/jIBBPj24MAXGboxHyhsaMulRrW3RijSi1k6muEwbz1MW7EbZ+W+PM7MuQctPb
 /Uvw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20221208; t=1684612431; x=1687204431;
 h=cc:to:subject:message-id:date:from:in-reply-to:references
 :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id
 :reply-to;
 bh=8uhEFIOK+mzVFeliYBtTnAXmYTUyU587KEGp4gWroHM=;
 b=iU3UpOENyvilO/tisjU+0NS2Pq+i0SRI5hDMxrKhF84TcDAACe/cFhIST6deiThs2C
 CBksUja7hVb5Aayn544HitDWMf/JHQCgpJ2b94nlPTm8m8N1MeW3anntwGjx7gkk7fqZ
 0Ff9YRAGfArU7Mhf3uk6xFBBJFZK7VkfYQsVh4/6xt5J+ExZG5nm/Q0Yvi3gEa6acnZ9
 vYFQK5qSh/8qyOmZLVRkFby8WpBd/LTLASHDhhZj99V6GWyemVGm94tvjOKUK6ferOQM
 /beKQ6YpkAXfCCe/qCbbvd1roOYG7oigibJ0PuiVQaKcuWPMk8Es5lSm5QygzuNsYxHP
 sxxg==
X-Gm-Message-State: AC+VfDzoGvT1xtIRbhxGwNf5IHhhUyyfFJ937mI3V8NHnmUGpllrcP4M
 k2LsKXImx50G0YArgcPFouLMVlf+sIh139GdPic=
X-Google-Smtp-Source: ACHHUZ4JdSHIJLqtZgoD7UKlR7iYCqVsX7c0W/+lJ4Q1qAA68xcbAfWH2iYjoo1LgzcvbzM/sgHmCHbbCPLPVHyHzOc=
X-Received: by 2002:adf:e689:0:b0:309:38af:d300 with SMTP id
 r9-20020adfe689000000b0030938afd300mr3877048wrm.33.1684612430898; Sat, 20 May
 2023 12:53:50 -0700 (PDT)
MIME-Version: 1.0
References: <20230219224334.309-1-tanxeel1.ahmed@gmail.com>
 <20230225135343.262-1-tanxeel1.ahmed@gmail.com>
 <CAAJ7kpJ8bJ098jXtL3FDgbQ+rseFZnFR7d_y5on4jfWg5e00Xw@mail.gmail.com>
 <CAAJ7kp+cd3hRncJQnYF5DiFT6qV5K_oKxGW5NUFhTyE-OaPX0w@mail.gmail.com>
In-Reply-To: <CAAJ7kp+cd3hRncJQnYF5DiFT6qV5K_oKxGW5NUFhTyE-OaPX0w@mail.gmail.com>
From: Tanzeel Ahmed <tanxeel1.ahmed@gmail.com>
Date: Sun, 21 May 2023 00:53:13 +0500
Message-ID: <CAAJ7kpK4efkoF0A=JikSHgm8amj8F9kVqaar07JLcMbr7iDTUQ@mail.gmail.com>
Subject: Re: [PATCH v4] lib/net: add MPLS insert and strip functionality
To: olivier.matz@6wind.com, thomas@monjalon.net, tanzeelahmed713@gmail.com
Cc: dev@dpdk.org
Content-Type: multipart/alternative; boundary="000000000000872a7805fc256529"
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

--000000000000872a7805fc256529
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Gentle Ping

On Tue, Apr 18, 2023 at 6:18=E2=80=AFPM Tanzeel Ahmed <tanxeel1.ahmed@gmail=
.com>
wrote:

> Ping.
>
> On Thu, Mar 9, 2023 at 11:35=E2=80=AFPM Tanzeel Ahmed <tanxeel1.ahmed@gma=
il.com>
> wrote:
>
>> Any updates?
>>
>>
>> On Sat, Feb 25, 2023 at 6:53=E2=80=AFPM Tanzeel-inline <tanxeel1.ahmed@g=
mail.com>
>> wrote:
>>
>>> From: Tanzeel Ahmed <tanxeel1.ahmed@gmail.com>
>>>
>>> This patch is new version of [PATCH] lib/net: added push MPLS header AP=
I.
>>> I have also added the MPLS strip functionality to address the question
>>> asked in last patch.
>>>
>>> > You should explain why you add this function.
>>> None of the foundational NICs currently supports MPLS insertion and
>>> stripping, this functionality can help users who rely on MPLS in their
>>> network application.
>>>
>>> > I'm not sure it should be inline
>>> I did for performance in high-traffic application.
>>>
>>> Signed-off-by: Tanzeel Ahmed <tanxeel1.ahmed@gmail.com>
>>>
>>> ---
>>> v4:
>>> * Removed extra void cast.
>>> * rte_pktmbuf_append/mtod now return void*.
>>>   The memmove result is casted to rte_ether_hdr*.
>>>
>>> v3:
>>> * fixed patch check failure issue
>>>
>>> v2:
>>> * marked experimental
>>> * coding style fixed
>>> * changed rte_memcpy to memcpy
>>> * mpls header marked as const in parameter
>>> * added MPLS stripping functionality
>>> ---
>>>  .mailmap           |  1 +
>>>  lib/net/rte_mpls.h | 97
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 98 insertions(+)
>>>
>>> diff --git a/.mailmap b/.mailmap
>>> index a9f4f28..2af4e0d 100644
>>> --- a/.mailmap
>>> +++ b/.mailmap
>>> @@ -1312,6 +1312,7 @@ Takeshi Yoshimura <tyos@jp.ibm.com> <
>>> t.yoshimura8869@gmail.com>
>>>  Takuya Asada <syuu@cloudius-systems.com>
>>>  Tal Avraham <talavr@annapurnalabs.com>
>>>  Tal Shnaiderman <talshn@nvidia.com> <talshn@mellanox.com>
>>> +Tanzeel Ahmed <tanxeel1.ahmed@gmail.com>
>>>  Tao Y Yang <tao.y.yang@intel.com>
>>>  Tao Zhu <taox.zhu@intel.com>
>>>  Taripin Samuel <samuel.taripin@intel.com>
>>> diff --git a/lib/net/rte_mpls.h b/lib/net/rte_mpls.h
>>> index 51523e7..d7e267f 100644
>>> --- a/lib/net/rte_mpls.h
>>> +++ b/lib/net/rte_mpls.h
>>> @@ -13,6 +13,8 @@
>>>
>>>  #include <stdint.h>
>>>  #include <rte_byteorder.h>
>>> +#include <rte_ether.h>
>>> +#include <rte_mbuf.h>
>>>
>>>  #ifdef __cplusplus
>>>  extern "C" {
>>> @@ -36,6 +38,101 @@ struct rte_mpls_hdr {
>>>         uint8_t  ttl;       /**< Time to live. */
>>>  } __rte_packed;
>>>
>>> +#define RTE_MPLS_HLEN 4 /**< Length of MPLS header. */
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice.
>>> + *
>>> + * Insert MPLS header into the packet.
>>> + * If it's first MPLS header to be inserted in the packet,
>>> + *  - Updates the ether type.
>>> + *  - Sets the MPLS bottom-of-stack bit to 1.
>>> + *
>>> + * @param m
>>> + *   The pointer to the mbuf.
>>> + * @param mp
>>> + *   The pointer to the MPLS header.
>>> + * @return
>>> + *   0 on success, -1 on error
>>> + */
>>> +__rte_experimental
>>> +static inline int
>>> +rte_mpls_push_over_l2(struct rte_mbuf **m, const struct rte_mpls_hdr
>>> *mp)
>>> +{
>>> +       void *os, *ns;
>>> +       struct rte_ether_hdr *nh;
>>> +       struct rte_mpls_hdr *mph;
>>> +
>>> +       /* Can't insert header if mbuf is shared */
>>> +       if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_read(*m) > 1)
>>> +               return -EINVAL;
>>> +
>>> +       /* Can't insert header if ethernet frame doesn't exist */
>>> +       if (rte_pktmbuf_data_len(*m) < RTE_ETHER_HDR_LEN)
>>> +               return -EINVAL;
>>> +
>>> +       os =3D rte_pktmbuf_mtod(*m, void *);
>>> +       ns =3D (void *)rte_pktmbuf_prepend(*m, sizeof(struct
>>> rte_mpls_hdr));
>>> +       if (ns =3D=3D NULL)
>>> +               return -ENOSPC;
>>> +
>>> +       nh =3D (struct rte_ether_hdr *)memmove(ns, os, RTE_ETHER_HDR_LE=
N);
>>> +
>>> +       /* Copy the MPLS header after ethernet frame */
>>> +       mph =3D rte_pktmbuf_mtod_offset(*m, struct rte_mpls_hdr*,
>>> +                       sizeof(struct rte_ether_hdr));
>>> +       memcpy(mph, mp, RTE_MPLS_HLEN);
>>> +
>>> +       mph->tag_msb =3D rte_cpu_to_be_16(mp->tag_msb);
>>> +
>>> +       /* If first MPLS header, update ether type and bottom-of-stack
>>> bit */
>>> +       if (nh->ether_type !=3D rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) =
{
>>> +               nh->ether_type =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS=
);
>>> +               mph->bs =3D 1;
>>> +       } else {
>>> +               mph->bs =3D 0;
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +/**
>>> + * @warning
>>> + * @b EXPERIMENTAL: this API may change without prior notice.
>>> + *
>>> + * Strips MPLS from the packet. Doesn't update the ether type
>>> + *
>>> + * @param m
>>> + *   The pointer to the mbuf.
>>> + * @return
>>> + *   0 on success, -1 on error
>>> + */
>>> +__rte_experimental
>>> +static inline int
>>> +rte_mpls_strip_over_l2(struct rte_mbuf *m)
>>> +{
>>> +       struct rte_ether_hdr *eh =3D rte_pktmbuf_mtod(m, struct
>>> rte_ether_hdr *);
>>> +       struct rte_mpls_hdr *mph;
>>> +       bool mpls_exist =3D true;
>>> +
>>> +       if (eh->ether_type !=3D rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS))
>>> +               return -1;
>>> +
>>> +       /* Stripping all MPLS header */
>>> +       while (mpls_exist) {
>>> +               mph =3D rte_pktmbuf_mtod_offset(m, struct rte_mpls_hdr*=
,
>>> +               sizeof(struct rte_ether_hdr));
>>> +               if (mph->bs & 1)
>>> +                       mpls_exist =3D false;
>>> +               memmove(rte_pktmbuf_adj(m, sizeof(struct rte_mpls_hdr))=
,
>>> +               eh, sizeof(struct rte_ether_hdr));
>>> +               eh =3D rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +
>>>  #ifdef __cplusplus
>>>  }
>>>  #endif
>>> --
>>> 1.8.3.1
>>>
>>>

--000000000000872a7805fc256529
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Gentle Ping</div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr" class=3D"gmail_attr">On Tue, Apr 18, 2023 at 6:18=E2=80=AFPM Tanze=
el Ahmed &lt;<a href=3D"mailto:tanxeel1.ahmed@gmail.com">tanxeel1.ahmed@gma=
il.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr">Ping.</div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr" class=3D"gmail_attr">On Thu, Mar 9, 2023 at 11:35=E2=80=AFPM Tanze=
el Ahmed &lt;<a href=3D"mailto:tanxeel1.ahmed@gmail.com" target=3D"_blank">=
tanxeel1.ahmed@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204=
,204);padding-left:1ex"><div dir=3D"ltr">Any updates?</div><div dir=3D"ltr"=
><br></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_a=
ttr">On Sat, Feb 25, 2023 at 6:53=E2=80=AFPM Tanzeel-inline &lt;<a href=3D"=
mailto:tanxeel1.ahmed@gmail.com" target=3D"_blank">tanxeel1.ahmed@gmail.com=
</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
From: Tanzeel Ahmed &lt;<a href=3D"mailto:tanxeel1.ahmed@gmail.com" target=
=3D"_blank">tanxeel1.ahmed@gmail.com</a>&gt;<br>
<br>
This patch is new version of [PATCH] lib/net: added push MPLS header API.<b=
r>
I have also added the MPLS strip functionality to address the question<br>
asked in last patch.<br>
<br>
&gt; You should explain why you add this function.<br>
None of the foundational NICs currently supports MPLS insertion and<br>
stripping, this functionality can help users who rely on MPLS in their<br>
network application.<br>
<br>
&gt; I&#39;m not sure it should be inline<br>
I did for performance in high-traffic application.<br>
<br>
Signed-off-by: Tanzeel Ahmed &lt;<a href=3D"mailto:tanxeel1.ahmed@gmail.com=
" target=3D"_blank">tanxeel1.ahmed@gmail.com</a>&gt;<br>
<br>
---<br>
v4:<br>
* Removed extra void cast.<br>
* rte_pktmbuf_append/mtod now return void*.<br>
=C2=A0 The memmove result is casted to rte_ether_hdr*.<br>
<br>
v3:<br>
* fixed patch check failure issue<br>
<br>
v2:<br>
* marked experimental<br>
* coding style fixed<br>
* changed rte_memcpy to memcpy<br>
* mpls header marked as const in parameter<br>
* added MPLS stripping functionality<br>
---<br>
=C2=A0.mailmap=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 1 +<br>
=C2=A0lib/net/rte_mpls.h | 97 +++++++++++++++++++++++++++++++++++++++++++++=
+++++++++<br>
=C2=A02 files changed, 98 insertions(+)<br>
<br>
diff --git a/.mailmap b/.mailmap<br>
index a9f4f28..2af4e0d 100644<br>
--- a/.mailmap<br>
+++ b/.mailmap<br>
@@ -1312,6 +1312,7 @@ Takeshi Yoshimura &lt;<a href=3D"mailto:tyos@jp.ibm.c=
om" target=3D"_blank">tyos@jp.ibm.com</a>&gt; &lt;<a href=3D"mailto:t.yoshi=
mura8869@gmail.com" target=3D"_blank">t.yoshimura8869@gmail.com</a>&gt;<br>
=C2=A0Takuya Asada &lt;<a href=3D"mailto:syuu@cloudius-systems.com" target=
=3D"_blank">syuu@cloudius-systems.com</a>&gt;<br>
=C2=A0Tal Avraham &lt;<a href=3D"mailto:talavr@annapurnalabs.com" target=3D=
"_blank">talavr@annapurnalabs.com</a>&gt;<br>
=C2=A0Tal Shnaiderman &lt;<a href=3D"mailto:talshn@nvidia.com" target=3D"_b=
lank">talshn@nvidia.com</a>&gt; &lt;<a href=3D"mailto:talshn@mellanox.com" =
target=3D"_blank">talshn@mellanox.com</a>&gt;<br>
+Tanzeel Ahmed &lt;<a href=3D"mailto:tanxeel1.ahmed@gmail.com" target=3D"_b=
lank">tanxeel1.ahmed@gmail.com</a>&gt;<br>
=C2=A0Tao Y Yang &lt;<a href=3D"mailto:tao.y.yang@intel.com" target=3D"_bla=
nk">tao.y.yang@intel.com</a>&gt;<br>
=C2=A0Tao Zhu &lt;<a href=3D"mailto:taox.zhu@intel.com" target=3D"_blank">t=
aox.zhu@intel.com</a>&gt;<br>
=C2=A0Taripin Samuel &lt;<a href=3D"mailto:samuel.taripin@intel.com" target=
=3D"_blank">samuel.taripin@intel.com</a>&gt;<br>
diff --git a/lib/net/rte_mpls.h b/lib/net/rte_mpls.h<br>
index 51523e7..d7e267f 100644<br>
--- a/lib/net/rte_mpls.h<br>
+++ b/lib/net/rte_mpls.h<br>
@@ -13,6 +13,8 @@<br>
<br>
=C2=A0#include &lt;stdint.h&gt;<br>
=C2=A0#include &lt;rte_byteorder.h&gt;<br>
+#include &lt;rte_ether.h&gt;<br>
+#include &lt;rte_mbuf.h&gt;<br>
<br>
=C2=A0#ifdef __cplusplus<br>
=C2=A0extern &quot;C&quot; {<br>
@@ -36,6 +38,101 @@ struct rte_mpls_hdr {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uint8_t=C2=A0 ttl;=C2=A0 =C2=A0 =C2=A0 =C2=A0/*=
*&lt; Time to live. */<br>
=C2=A0} __rte_packed;<br>
<br>
+#define RTE_MPLS_HLEN 4 /**&lt; Length of MPLS header. */<br>
+<br>
+/**<br>
+ * @warning<br>
+ * @b EXPERIMENTAL: this API may change without prior notice.<br>
+ *<br>
+ * Insert MPLS header into the packet.<br>
+ * If it&#39;s first MPLS header to be inserted in the packet,<br>
+ *=C2=A0 - Updates the ether type.<br>
+ *=C2=A0 - Sets the MPLS bottom-of-stack bit to 1.<br>
+ *<br>
+ * @param m<br>
+ *=C2=A0 =C2=A0The pointer to the mbuf.<br>
+ * @param mp<br>
+ *=C2=A0 =C2=A0The pointer to the MPLS header.<br>
+ * @return<br>
+ *=C2=A0 =C2=A00 on success, -1 on error<br>
+ */<br>
+__rte_experimental<br>
+static inline int<br>
+rte_mpls_push_over_l2(struct rte_mbuf **m, const struct rte_mpls_hdr *mp)<=
br>
+{<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0void *os, *ns;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_ether_hdr *nh;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_mpls_hdr *mph;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Can&#39;t insert header if mbuf is shared */=
<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_rea=
d(*m) &gt; 1)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Can&#39;t insert header if ethernet frame do=
esn&#39;t exist */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (rte_pktmbuf_data_len(*m) &lt; RTE_ETHER_HDR=
_LEN)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0os =3D rte_pktmbuf_mtod(*m, void *);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0ns =3D (void *)rte_pktmbuf_prepend(*m, sizeof(s=
truct rte_mpls_hdr));<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (ns =3D=3D NULL)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENOSPC;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0nh =3D (struct rte_ether_hdr *)memmove(ns, os, =
RTE_ETHER_HDR_LEN);<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Copy the MPLS header after ethernet frame */=
<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0mph =3D rte_pktmbuf_mtod_offset(*m, struct rte_=
mpls_hdr*,<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0sizeof(struct rte_ether_hdr));<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(mph, mp, RTE_MPLS_HLEN);<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0mph-&gt;tag_msb =3D rte_cpu_to_be_16(mp-&gt;tag=
_msb);<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* If first MPLS header, update ether type and =
bottom-of-stack bit */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (nh-&gt;ether_type !=3D rte_cpu_to_be_16(RTE=
_ETHER_TYPE_MPLS)) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0nh-&gt;ether_type =
=3D rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mph-&gt;bs =3D 1;<b=
r>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mph-&gt;bs =3D 0;<b=
r>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
+}<br>
+<br>
+/**<br>
+ * @warning<br>
+ * @b EXPERIMENTAL: this API may change without prior notice.<br>
+ *<br>
+ * Strips MPLS from the packet. Doesn&#39;t update the ether type<br>
+ *<br>
+ * @param m<br>
+ *=C2=A0 =C2=A0The pointer to the mbuf.<br>
+ * @return<br>
+ *=C2=A0 =C2=A00 on success, -1 on error<br>
+ */<br>
+__rte_experimental<br>
+static inline int<br>
+rte_mpls_strip_over_l2(struct rte_mbuf *m)<br>
+{<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_ether_hdr *eh =3D rte_pktmbuf_mtod(m=
, struct rte_ether_hdr *);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_mpls_hdr *mph;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0bool mpls_exist =3D true;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (eh-&gt;ether_type !=3D rte_cpu_to_be_16(RTE=
_ETHER_TYPE_MPLS))<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Stripping all MPLS header */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0while (mpls_exist) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mph =3D rte_pktmbuf=
_mtod_offset(m, struct rte_mpls_hdr*,<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(struct rte_e=
ther_hdr));<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (mph-&gt;bs &amp=
; 1)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0mpls_exist =3D false;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0memmove(rte_pktmbuf=
_adj(m, sizeof(struct rte_mpls_hdr)),<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0eh, sizeof(struct r=
te_ether_hdr));<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0eh =3D rte_pktmbuf_=
mtod(m, struct rte_ether_hdr *);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
+}<br>
+<br>
=C2=A0#ifdef __cplusplus<br>
=C2=A0}<br>
=C2=A0#endif<br>
-- <br>
1.8.3.1<br>
<br>
</blockquote></div>
</blockquote></div>
</blockquote></div>

--000000000000872a7805fc256529--