@@ -146,6 +146,7 @@ typedef union {
uint64_t sctp:1; /**< SCTP */
uint64_t icmp:1; /**< ICMP */
+ uint64_t vxlan:1; /**< VXLAN */
uint64_t color:2; /**< Packet color for traffic mgmt */
uint64_t nodrop:1; /**< Drop eligibility status */
};
@@ -24,6 +24,7 @@ extern "C" {
#include <protocols/ipsec.h>
#include <protocols/udp.h>
#include <protocols/tcp.h>
+#include <protocols/vxlan.h>
#include <odp_packet_internal.h>
#include <stdio.h>
#include <inttypes.h>
@@ -304,11 +305,25 @@ static inline int verify_pmr_ipsec_spi(const uint8_t *pkt_addr,
return 0;
}
-static inline int verify_pmr_ld_vni(const uint8_t *pkt_addr ODP_UNUSED,
- odp_packet_hdr_t *pkt_hdr ODP_UNUSED,
- pmr_term_value_t *term_value ODP_UNUSED)
+static inline int verify_pmr_ld_vni(const uint8_t *pkt_addr,
+ odp_packet_hdr_t *pkt_hdr,
+ pmr_term_value_t *term_value)
{
- ODP_UNIMPLEMENTED();
+ uint32_t vni;
+ uint32_t vni_be;
+ const _odp_vxlanhdr_t *vxlan;
+
+ if (!pkt_hdr->p.input_flags.vxlan)
+ return 0;
+
+ pkt_addr += pkt_hdr->p.l4_offset;
+ pkt_addr += _ODP_UDPHDR_LEN;
+ vxlan = (const _odp_vxlanhdr_t *)pkt_addr;
+ vni = odp_be_to_cpu_32(vxlan->vni);
+ vni_be = ODPH_VXLAN_VNI(vni);
+ if (term_value->match.value == (vni_be & term_value->match.mask))
+ return 1;
+
return 0;
}
@@ -120,6 +120,7 @@ typedef struct {
*/
packet_parser_t p;
+ packet_parser_t inner_p;
odp_pktio_t input;
@@ -310,8 +311,8 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts)
}
}
-int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr,
- uint32_t pkt_len, uint32_t seg_len,
+int packet_parse_common(packet_parser_t *pkt_hdr, packet_parser_t *innner_prs,
+ const uint8_t *ptr, uint32_t pkt_len, uint32_t seg_len,
odp_pktio_parser_layer_t layer);
int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr);
@@ -856,8 +856,8 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base,
packet_parse_reset(pkt_hdr);
packet_set_len(pkt_hdr, pkt_len);
- packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len,
- ODP_PKTIO_PARSER_LAYER_ALL);
+ packet_parse_common(&pkt_hdr->p, &pkt_hdr->inner_p, base, pkt_len,
+ seg_len, ODP_PKTIO_PARSER_LAYER_ALL);
cos = cls_select_cos(entry, base, pkt_hdr);
if (cos == NULL)
@@ -17,6 +17,7 @@
#include <protocols/ip.h>
#include <protocols/tcp.h>
#include <protocols/udp.h>
+#include <protocols/vxlan.h>
#include <errno.h>
#include <string.h>
@@ -1982,12 +1983,31 @@ static inline void parse_tcp(packet_parser_t *prs,
*parseptr += (uint32_t)tcp->hl * 4;
}
+static inline void parse_vxlan(packet_parser_t *prs, packet_parser_t *in_prs,
+ const uint8_t **parseptr, uint32_t *offset,
+ uint32_t frame_len, uint32_t seg_len)
+{
+ const _odp_vxlanhdr_t *vxlan = (const _odp_vxlanhdr_t *)*parseptr;
+
+ if (ODPH_VXLAN_BIT(vxlan->flags))
+ prs->input_flags.vxlan = 1;
+
+ if (offset)
+ *offset += sizeof(_odp_vxlanhdr_t);
+
+ *parseptr += sizeof(_odp_vxlanhdr_t);
+ packet_parse_common(in_prs, prs, *parseptr, frame_len, seg_len,
+ ODP_PKTIO_PARSER_LAYER_L4);
+}
+
/**
* Parser helper function for UDP
*/
-static inline void parse_udp(packet_parser_t *prs,
- const uint8_t **parseptr, uint32_t *offset)
+static inline void parse_udp(packet_parser_t *prs, packet_parser_t *in_p,
+ const uint8_t **parseptr, uint32_t *offset,
+ uint32_t frame_len, uint32_t seg_len)
{
+ uint16_t dport;
const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr;
uint32_t udplen = odp_be_to_cpu_16(udp->length);
@@ -1996,7 +2016,10 @@ static inline void parse_udp(packet_parser_t *prs,
if (offset)
*offset += sizeof(_odp_udphdr_t);
- *parseptr += sizeof(_odp_udphdr_t);
+ *parseptr += _ODP_UDPHDR_LEN;
+ dport = odp_be_to_cpu_16(udp->dst_port);
+ if (dport == _ODP_UDP_VXLAN_PORT)
+ parse_vxlan(prs, in_p, parseptr, offset, frame_len, seg_len);
}
/**
@@ -2005,9 +2028,9 @@ static inline void parse_udp(packet_parser_t *prs,
* The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be
* available from the ptr.
*/
-int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
- uint32_t frame_len, uint32_t seg_len,
- odp_pktio_parser_layer_t layer)
+int packet_parse_common(packet_parser_t *prs, packet_parser_t *inner_prs,
+ const uint8_t *ptr, uint32_t frame_len,
+ uint32_t seg_len, odp_pktio_parser_layer_t layer)
{
uint32_t offset;
uint16_t ethtype;
@@ -2142,7 +2165,7 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len))
return -1;
prs->input_flags.udp = 1;
- parse_udp(prs, &parseptr, NULL);
+ parse_udp(prs, inner_prs, &parseptr, NULL, frame_len, seg_len);
break;
case _ODP_IPPROTO_AH:
@@ -2177,8 +2200,8 @@ int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
uint32_t seg_len = packet_first_seg_len(pkt_hdr);
void *base = packet_data(pkt_hdr);
- return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len,
- seg_len, layer);
+ return packet_parse_common(&pkt_hdr->p, &pkt_hdr->inner_p, base,
+ pkt_hdr->frame_len, seg_len, layer);
}
uint64_t odp_packet_to_u64(odp_packet_t hdl)
@@ -78,6 +78,11 @@ int odp_packet_has_vlan(odp_packet_t pkt)
retflag(pkt, input_flags.vlan);
}
+int odp_packet_has_vxlan(odp_packet_t pkt)
+{
+ retflag(pkt, input_flags.vxlan);
+}
+
int odp_packet_has_vlan_qinq(odp_packet_t pkt)
{
retflag(pkt, input_flags.vlan_qinq);
@@ -271,6 +276,11 @@ void odp_packet_has_udp_set(odp_packet_t pkt, int val)
setflag(pkt, input_flags.udp, val);
}
+void odp_packet_has_vxlan_set(odp_packet_t pkt, int val)
+{
+ setflag(pkt, input_flags.vxlan, val);
+}
+
void odp_packet_has_tcp_set(odp_packet_t pkt, int val)
{
setflag(pkt, input_flags.tcp, val);