DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Denis  Davidoglu" <denis.davidoglu@b-ulltech.com>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Cc: "dev@dpdk.org" <dev@dpdk.org>
Subject: [PATCH] net: support Arista L2 headers
Date: Tue, 4 Feb 2025 15:41:46 +0000	[thread overview]
Message-ID: <GV1P190MB20413FBFFA4FC719AC6E982EA1F42@GV1P190MB2041.EURP190.PROD.OUTLOOK.COM> (raw)

[-- Attachment #1: Type: text/plain, Size: 12279 bytes --]

Packet parsing and type detection fail for packets containing
Arista Vendor Specific Protocol (AVSP) headers. This patch adds
support for three L2 headers: Arista TGen, Arista 64-bit Timestamp
and Arista 48-bit Timestamp.

Signed-off-by: Denis Davidoglu <denis.davidoglu@b-ulltech.com>
---
 lib/net/rte_ether.h | 31 ++++++++++++++
 lib/net/rte_net.c   | 99 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/lib/net/rte_ether.h b/lib/net/rte_ether.h
index c9a0b536c3..054a54af40 100644
--- a/lib/net/rte_ether.h
+++ b/lib/net/rte_ether.h
@@ -62,6 +62,13 @@ extern "C" {
                               ((pri) << RTE_VLAN_PRI_SHIFT) |    \
                               ((dei) << RTE_VLAN_DEI_SHIFT))

+/* Arista Vendor Specific Protocol (AVSP) Header Types */
+#define RTE_AVSP_SUBTYPE_TGEN            0xCAFE
+#define RTE_AVSP_VERSION_TGEN            0x0001
+#define RTE_AVSP_SUBTYPE_TIMESTAMP 0x0001
+#define RTE_AVSP_VERSION_64_MASK   0x0010
+#define RTE_AVSP_VERSION_48_MASK   0x0020
+
 /**
  * Ethernet address:
  * A universally administered address is uniquely assigned to a device by its
@@ -323,7 +330,30 @@ static_assert(sizeof(struct rte_vlan_hdr) == 4,
 static_assert(alignof(struct rte_vlan_hdr) == 2,
            "alignof(struct rte_vlan_hdr) == 2");

+/* Arista Vendor Specific Protocol (AVSP) Headers */
+struct __rte_packed_begin rte_avsp_common_hdr {
+     rte_be16_t subtype;
+     rte_be16_t version;
+} __rte_packed_end;
+
+struct __rte_packed_begin rte_avsp_tgen_hdr {
+     struct rte_avsp_common_hdr common;
+     rte_be16_t eth_proto; /**< Ethernet type of encapsulated frame. */
+} __rte_packed_end;
+
+struct __rte_packed_begin rte_avsp_timestamp_64_hdr {
+     struct rte_avsp_common_hdr common;
+     rte_be32_t sec; /**< Seconds (IEEE 1588 time of day format). */
+     rte_be32_t ns;  /**< Nanoseconds (IEEE 1588 time of day format). */
+     rte_be16_t eth_proto; /**< Ethernet type of encapsulated frame. */
+} __rte_packed_end;

+struct __rte_packed_begin rte_avsp_timestamp_48_hdr {
+     struct rte_avsp_common_hdr common;
+     rte_be16_t sec; /**< Seconds (IEEE 1588 time of day format). */
+     rte_be32_t ns;  /**< Nanoseconds (IEEE 1588 time of day format). */
+     rte_be16_t eth_proto; /**< Ethernet type of encapsulated frame. */
+} __rte_packed_end;

 /* Ethernet frame types */
 #define RTE_ETHER_TYPE_IPV4 0x0800 /**< IPv4 Protocol. */
@@ -346,6 +376,7 @@ static_assert(alignof(struct rte_vlan_hdr) == 2,
 #define RTE_ETHER_TYPE_MPLS 0x8847 /**< MPLS ethertype. */
 #define RTE_ETHER_TYPE_MPLSM 0x8848 /**< MPLS multicast ethertype. */
 #define RTE_ETHER_TYPE_ECPRI 0xAEFE /**< eCPRI ethertype (.1Q supported). */
+#define RTE_ETHER_TYPE_AVSP 0xD28B  /**< Arista ethertype */

 /**
  * Extract VLAN tag information into mbuf
diff --git a/lib/net/rte_net.c b/lib/net/rte_net.c
index d680accc16..d260cfdf0a 100644
--- a/lib/net/rte_net.c
+++ b/lib/net/rte_net.c
@@ -269,7 +269,56 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
            off += 2 * sizeof(*vh);
            hdr_lens->l2_len += 2 * sizeof(*vh);
            proto = vh->eth_proto;
-     } else if ((proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) ||
+     }
+     if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_AVSP)) {
+           union {
+                 const struct rte_avsp_common_hdr *common;
+                 const struct rte_avsp_tgen_hdr *tgen;
+                 const struct rte_avsp_timestamp_64_hdr *t64;
+                 const struct rte_avsp_timestamp_48_hdr *t48;
+           } ah;
+           union {
+                 struct rte_avsp_common_hdr common;
+                 struct rte_avsp_tgen_hdr tgen;
+                 struct rte_avsp_timestamp_64_hdr t64;
+                 struct rte_avsp_timestamp_48_hdr t48;
+           } ah_copy;
+
+           ah.common = rte_pktmbuf_read(m, off, sizeof(*ah.common),
+                                                      &ah_copy.common);
+           if (unlikely(ah.common == NULL))
+                 return pkt_type;
+           uint16_t subtype = rte_be_to_cpu_16(ah.common->subtype);
+           uint16_t version = rte_be_to_cpu_16(ah.common->version);
+
+           if (subtype == RTE_AVSP_SUBTYPE_TGEN &&
+                       (version == RTE_AVSP_VERSION_TGEN)) {
+                 ah.tgen = rte_pktmbuf_read(m, off, sizeof(*ah.tgen), &ah_copy);
+                 if (unlikely(ah.tgen == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.tgen);
+                 hdr_lens->l2_len += sizeof(*ah.tgen);
+                 proto = ah.tgen->eth_proto;
+           } else if ((subtype == RTE_AVSP_SUBTYPE_TIMESTAMP &&
+                             (version & RTE_AVSP_VERSION_64_MASK) != 0)) {
+                 ah.t64 = rte_pktmbuf_read(m, off, sizeof(*ah.t64), &ah_copy);
+                 if (unlikely(ah.t64 == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.t64);
+                 hdr_lens->l2_len += sizeof(*ah.t64);
+                 proto = ah.t64->eth_proto;
+           } else if ((subtype == RTE_AVSP_SUBTYPE_TIMESTAMP &&
+                             (version & RTE_AVSP_VERSION_48_MASK) != 0)) {
+                 ah.t48 = rte_pktmbuf_read(m, off, sizeof(*ah.t48), &ah_copy);
+                 if (unlikely(ah.t48 == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.t48);
+                 hdr_lens->l2_len += sizeof(*ah.t48);
+                 proto = ah.t48->eth_proto;
+           } else
+                 return pkt_type;
+     }
+     if ((proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLS)) ||
            (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_MPLSM))) {
            unsigned int i;
            const struct rte_mpls_hdr *mh;
@@ -421,6 +470,54 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
            hdr_lens->inner_l2_len += 2 * sizeof(*vh);
            proto = vh->eth_proto;
      }
+     if (proto == rte_cpu_to_be_16(RTE_ETHER_TYPE_AVSP)) {
+           union {
+                 const struct rte_avsp_common_hdr *common;
+                 const struct rte_avsp_tgen_hdr *tgen;
+                 const struct rte_avsp_timestamp_64_hdr *t64;
+                 const struct rte_avsp_timestamp_48_hdr *t48;
+           } ah;
+           union {
+                 struct rte_avsp_common_hdr common;
+                 struct rte_avsp_tgen_hdr tgen;
+                 struct rte_avsp_timestamp_64_hdr t64;
+                 struct rte_avsp_timestamp_48_hdr t48;
+           } ah_copy;
+
+           ah.common = rte_pktmbuf_read(m, off, sizeof(*ah.common),
+                                                      &ah_copy.common);
+           if (unlikely(ah.common == NULL))
+                 return pkt_type;
+           uint16_t subtype = rte_be_to_cpu_16(ah.common->subtype);
+           uint16_t version = rte_be_to_cpu_16(ah.common->version);
+
+           if (subtype == RTE_AVSP_SUBTYPE_TGEN &&
+                       (version == RTE_AVSP_VERSION_TGEN)) {
+                 ah.tgen = rte_pktmbuf_read(m, off, sizeof(*ah.tgen), &ah_copy);
+                 if (unlikely(ah.tgen == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.tgen);
+                 hdr_lens->inner_l2_len += sizeof(*ah.tgen);
+                 proto = ah.tgen->eth_proto;
+           } else if ((subtype == RTE_AVSP_SUBTYPE_TIMESTAMP &&
+                             (version & RTE_AVSP_VERSION_64_MASK) != 0)) {
+                 ah.t64 = rte_pktmbuf_read(m, off, sizeof(*ah.t64), &ah_copy);
+                 if (unlikely(ah.t64 == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.t64);
+                 hdr_lens->inner_l2_len += sizeof(*ah.t64);
+                 proto = ah.t64->eth_proto;
+           } else if ((subtype == RTE_AVSP_SUBTYPE_TIMESTAMP &&
+                             (version & RTE_AVSP_VERSION_48_MASK) != 0)) {
+                 ah.t48 = rte_pktmbuf_read(m, off, sizeof(*ah.t48), &ah_copy);
+                 if (unlikely(ah.t48 == NULL))
+                       return pkt_type;
+                 off += sizeof(*ah.t48);
+                 hdr_lens->inner_l2_len += sizeof(*ah.t48);
+                 proto = ah.t48->eth_proto;
+           } else
+                 return pkt_type;
+     }

      if ((layers & RTE_PTYPE_INNER_L3_MASK) == 0)
            return pkt_type;
--
2.48.1


[-- Attachment #2: Type: text/html, Size: 41575 bytes --]

             reply	other threads:[~2025-02-04 15:41 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-04 15:41 Denis  Davidoglu [this message]
2025-02-04 16:02 ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=GV1P190MB20413FBFFA4FC719AC6E982EA1F42@GV1P190MB2041.EURP190.PROD.OUTLOOK.COM \
    --to=denis.davidoglu@b-ulltech.com \
    --cc=dev@dpdk.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).