[PATCH v4] lib/net: add MPLS insert and strip functionality
Tanzeel Ahmed
tanxeel1.ahmed at gmail.com
Thu Mar 9 19:35:08 CET 2023
Any updates?
On Sat, Feb 25, 2023 at 6:53 PM Tanzeel-inline <tanxeel1.ahmed at gmail.com>
wrote:
> From: Tanzeel Ahmed <tanxeel1.ahmed at gmail.com>
>
> This patch is new version of [PATCH] lib/net: added push MPLS header API.
> 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 at 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 at jp.ibm.com> <
> t.yoshimura8869 at gmail.com>
> Takuya Asada <syuu at cloudius-systems.com>
> Tal Avraham <talavr at annapurnalabs.com>
> Tal Shnaiderman <talshn at nvidia.com> <talshn at mellanox.com>
> +Tanzeel Ahmed <tanxeel1.ahmed at gmail.com>
> Tao Y Yang <tao.y.yang at intel.com>
> Tao Zhu <taox.zhu at intel.com>
> Taripin Samuel <samuel.taripin at 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 = rte_pktmbuf_mtod(*m, void *);
> + ns = (void *)rte_pktmbuf_prepend(*m, sizeof(struct rte_mpls_hdr));
> + if (ns == NULL)
> + return -ENOSPC;
> +
> + nh = (struct rte_ether_hdr *)memmove(ns, os, RTE_ETHER_HDR_LEN);
> +
> + /* Copy the MPLS header after ethernet frame */
> + mph = rte_pktmbuf_mtod_offset(*m, struct rte_mpls_hdr*,
> + sizeof(struct rte_ether_hdr));
> + memcpy(mph, mp, RTE_MPLS_HLEN);
> +
> + mph->tag_msb = rte_cpu_to_be_16(mp->tag_msb);
> +
> + /* If first MPLS header, update ether type and bottom-of-stack bit
> */
> + if (nh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) {
> + nh->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS);
> + mph->bs = 1;
> + } else {
> + mph->bs = 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 = rte_pktmbuf_mtod(m, struct
> rte_ether_hdr *);
> + struct rte_mpls_hdr *mph;
> + bool mpls_exist = true;
> +
> + if (eh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS))
> + return -1;
> +
> + /* Stripping all MPLS header */
> + while (mpls_exist) {
> + mph = rte_pktmbuf_mtod_offset(m, struct rte_mpls_hdr*,
> + sizeof(struct rte_ether_hdr));
> + if (mph->bs & 1)
> + mpls_exist = false;
> + memmove(rte_pktmbuf_adj(m, sizeof(struct rte_mpls_hdr)),
> + eh, sizeof(struct rte_ether_hdr));
> + eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
> + }
> +
> + return 0;
> +}
> +
> #ifdef __cplusplus
> }
> #endif
> --
> 1.8.3.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mails.dpdk.org/archives/dev/attachments/20230309/acecde62/attachment.htm>
More information about the dev
mailing list