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.davido...@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