<div dir="ltr">Gentle Ping</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 18, 2023 at 6:18 PM Tanzeel Ahmed <<a href="mailto:tanxeel1.ahmed@gmail.com">tanxeel1.ahmed@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Ping.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 9, 2023 at 11:35 PM Tanzeel Ahmed <<a href="mailto:tanxeel1.ahmed@gmail.com" target="_blank">tanxeel1.ahmed@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Any updates?</div><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Feb 25, 2023 at 6:53 PM Tanzeel-inline <<a href="mailto:tanxeel1.ahmed@gmail.com" target="_blank">tanxeel1.ahmed@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Tanzeel Ahmed <<a href="mailto:tanxeel1.ahmed@gmail.com" target="_blank">tanxeel1.ahmed@gmail.com</a>><br>
<br>
This patch is new version of [PATCH] lib/net: added push MPLS header API.<br>
I have also added the MPLS strip functionality to address the question<br>
asked in last patch.<br>
<br>
> 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>
> I'm not sure it should be inline<br>
I did for performance in high-traffic application.<br>
<br>
Signed-off-by: Tanzeel Ahmed <<a href="mailto:tanxeel1.ahmed@gmail.com" target="_blank">tanxeel1.ahmed@gmail.com</a>><br>
<br>
---<br>
v4:<br>
* Removed extra void cast.<br>
* rte_pktmbuf_append/mtod now return void*.<br>
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>
.mailmap | 1 +<br>
lib/net/rte_mpls.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++<br>
2 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 <<a href="mailto:tyos@jp.ibm.com" target="_blank">tyos@jp.ibm.com</a>> <<a href="mailto:t.yoshimura8869@gmail.com" target="_blank">t.yoshimura8869@gmail.com</a>><br>
Takuya Asada <<a href="mailto:syuu@cloudius-systems.com" target="_blank">syuu@cloudius-systems.com</a>><br>
Tal Avraham <<a href="mailto:talavr@annapurnalabs.com" target="_blank">talavr@annapurnalabs.com</a>><br>
Tal Shnaiderman <<a href="mailto:talshn@nvidia.com" target="_blank">talshn@nvidia.com</a>> <<a href="mailto:talshn@mellanox.com" target="_blank">talshn@mellanox.com</a>><br>
+Tanzeel Ahmed <<a href="mailto:tanxeel1.ahmed@gmail.com" target="_blank">tanxeel1.ahmed@gmail.com</a>><br>
Tao Y Yang <<a href="mailto:tao.y.yang@intel.com" target="_blank">tao.y.yang@intel.com</a>><br>
Tao Zhu <<a href="mailto:taox.zhu@intel.com" target="_blank">taox.zhu@intel.com</a>><br>
Taripin Samuel <<a href="mailto:samuel.taripin@intel.com" target="_blank">samuel.taripin@intel.com</a>><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>
#include <stdint.h><br>
#include <rte_byteorder.h><br>
+#include <rte_ether.h><br>
+#include <rte_mbuf.h><br>
<br>
#ifdef __cplusplus<br>
extern "C" {<br>
@@ -36,6 +38,101 @@ struct rte_mpls_hdr {<br>
uint8_t ttl; /**< Time to live. */<br>
} __rte_packed;<br>
<br>
+#define RTE_MPLS_HLEN 4 /**< 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's first MPLS header to be inserted in the packet,<br>
+ * - Updates the ether type.<br>
+ * - Sets the MPLS bottom-of-stack bit to 1.<br>
+ *<br>
+ * @param m<br>
+ * The pointer to the mbuf.<br>
+ * @param mp<br>
+ * The pointer to the MPLS header.<br>
+ * @return<br>
+ * 0 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>
+ void *os, *ns;<br>
+ struct rte_ether_hdr *nh;<br>
+ struct rte_mpls_hdr *mph;<br>
+<br>
+ /* Can't insert header if mbuf is shared */<br>
+ if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_read(*m) > 1)<br>
+ return -EINVAL;<br>
+<br>
+ /* Can't insert header if ethernet frame doesn't exist */<br>
+ if (rte_pktmbuf_data_len(*m) < RTE_ETHER_HDR_LEN)<br>
+ return -EINVAL;<br>
+<br>
+ os = rte_pktmbuf_mtod(*m, void *);<br>
+ ns = (void *)rte_pktmbuf_prepend(*m, sizeof(struct rte_mpls_hdr));<br>
+ if (ns == NULL)<br>
+ return -ENOSPC;<br>
+<br>
+ nh = (struct rte_ether_hdr *)memmove(ns, os, RTE_ETHER_HDR_LEN);<br>
+<br>
+ /* Copy the MPLS header after ethernet frame */<br>
+ mph = rte_pktmbuf_mtod_offset(*m, struct rte_mpls_hdr*,<br>
+ sizeof(struct rte_ether_hdr));<br>
+ memcpy(mph, mp, RTE_MPLS_HLEN);<br>
+<br>
+ mph->tag_msb = rte_cpu_to_be_16(mp->tag_msb);<br>
+<br>
+ /* If first MPLS header, update ether type and bottom-of-stack bit */<br>
+ if (nh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) {<br>
+ nh->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS);<br>
+ mph->bs = 1;<br>
+ } else {<br>
+ mph->bs = 0;<br>
+ }<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
+/**<br>
+ * @warning<br>
+ * @b EXPERIMENTAL: this API may change without prior notice.<br>
+ *<br>
+ * Strips MPLS from the packet. Doesn't update the ether type<br>
+ *<br>
+ * @param m<br>
+ * The pointer to the mbuf.<br>
+ * @return<br>
+ * 0 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>
+ struct rte_ether_hdr *eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);<br>
+ struct rte_mpls_hdr *mph;<br>
+ bool mpls_exist = true;<br>
+<br>
+ if (eh->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS))<br>
+ return -1;<br>
+<br>
+ /* Stripping all MPLS header */<br>
+ while (mpls_exist) {<br>
+ mph = rte_pktmbuf_mtod_offset(m, struct rte_mpls_hdr*,<br>
+ sizeof(struct rte_ether_hdr));<br>
+ if (mph->bs & 1)<br>
+ mpls_exist = false;<br>
+ memmove(rte_pktmbuf_adj(m, sizeof(struct rte_mpls_hdr)),<br>
+ eh, sizeof(struct rte_ether_hdr));<br>
+ eh = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);<br>
+ }<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
#ifdef __cplusplus<br>
}<br>
#endif<br>
-- <br>
1.8.3.1<br>
<br>
</blockquote></div>
</blockquote></div>
</blockquote></div>