DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH] net: support Arista L2 headers
@ 2025-02-04 15:41 Denis  Davidoglu
  2025-02-04 16:02 ` Thomas Monjalon
  0 siblings, 1 reply; 2+ messages in thread
From: Denis  Davidoglu @ 2025-02-04 15:41 UTC (permalink / raw)
  To: stephen; +Cc: dev

[-- 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 --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] net: support Arista L2 headers
  2025-02-04 15:41 [PATCH] net: support Arista L2 headers Denis  Davidoglu
@ 2025-02-04 16:02 ` Thomas Monjalon
  0 siblings, 0 replies; 2+ messages in thread
From: Thomas Monjalon @ 2025-02-04 16:02 UTC (permalink / raw)
  To: Denis Davidoglu; +Cc: stephen, dev

04/02/2025 16:41, Denis  Davidoglu:
> 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.

I'm not familiar with these headers.
Are they standardized?
Is there a RFC?

> +/* 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

I'm not sure about adding vendor specific protocols.
What should be the policy here?



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-02-04 16:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-04 15:41 [PATCH] net: support Arista L2 headers Denis  Davidoglu
2025-02-04 16:02 ` Thomas Monjalon

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).