* [PATCH] net: support Arista L2 headers
@ 2025-02-04 15:41 Denis Davidoglu
2025-02-04 16:02 ` Thomas Monjalon
0 siblings, 1 reply; 3+ 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] 3+ 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
[not found] ` <GV1P190MB20415A820BF2090AE8151B2BA1F12@GV1P190MB2041.EURP190.PROD.OUTLOOK.COM>
0 siblings, 1 reply; 3+ 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] 3+ messages in thread
* Re: [PATCH] net: support Arista L2 headers
[not found] ` <GV1P190MB20415A820BF2090AE8151B2BA1F12@GV1P190MB2041.EURP190.PROD.OUTLOOK.COM>
@ 2025-02-07 17:54 ` Stephen Hemminger
0 siblings, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2025-02-07 17:54 UTC (permalink / raw)
To: Denis Davidoglu; +Cc: Thomas Monjalon, dev, Volkan Atlı
On Fri, 7 Feb 2025 09:07:57 +0000
"Denis Davidoglu" <denis.davidoglu@b-ulltech.com> wrote:
> From: Thomas Monjalon <thomas@monjalon.net>
> > I'm not familiar with these headers.
> > Are they standardized?
> > Is there a RFC?
>
> Arista Vendor Specific Protocol is not publicly disclosed yet. However, Wireshark already includes a dissector implementetation and its source code can serve for now as a reference:
> https://gitlab.com/wireshark/wireshark/-/blob/master/epan/dissectors/packet-avsp.c
>
> > I'm not sure about adding vendor specific protocols.
> > What should be the policy here?
>
> Given the large number of registered EtherType™ assignments related to IEEE 802.3™ (ISO/IEC 8802-3) standard, supporting vendor-specific protocols should be considered. Though probably not in the way I organized it, mixing RFC-standardized and proprietary protocols in the same files. ./lib/net can have a new subdirectory for keeping them separate.
>
> Arista timestamp is particularly valuable for stock exchanges due to efficiency. The timestamp extension is already in use at German Eurex Exchange and it needs to undergo PoC trials at Borsa İstanbul, which utilizes Nasdaq infrastructure. Some parts of it rely on DPDK and this patch will be especially useful.
The rte_net_ptype() is intended to provide a software equivalent for the packet type
matching done in many smart NIC's. It is not meant to be a general purpose L2 packet
parser.
If a user needs to do this kind of packet processing, it belongs in the application
and all the data and metadata is exposed to do this.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-02-07 17:54 UTC | newest]
Thread overview: 3+ 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
[not found] ` <GV1P190MB20415A820BF2090AE8151B2BA1F12@GV1P190MB2041.EURP190.PROD.OUTLOOK.COM>
2025-02-07 17:54 ` Stephen Hemminger
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).