diff mbox series

[v2,3/4] linux-gen: cls: LD_VNI pmr term implementation

Message ID 1513270810-29728-4-git-send-email-odpbot@yandex.ru
State New
Headers show
Series [v2,1/4] helper: add vxlan protocol header structure | expand

Commit Message

Github ODP bot Dec. 14, 2017, 5 p.m. UTC
From: Balasubramanian Manoharan <bala.manoharan@linaro.org>


Update packet parsing function to handle inner header packet parsing for
vxlan packets. Add classification verification function for pmr term
ODP_PMR_TERM_LD_VNI.

Signed-off-by: Balasubramanian Manoharan <bala.manoharan@linaro.org>

---
/** Email created from pull request 345 (bala-manoharan:BUG2903)
 ** https://github.com/Linaro/odp/pull/345
 ** Patch: https://github.com/Linaro/odp/pull/345.patch
 ** Base sha: 6b5cdc77eb9759a2349b10372a964648559bc92c
 ** Merge commit sha: 65c561d30ea4c8c5f8ae17c2b407df9c6cc35f3d
 **/
 .../include/odp/api/plat/packet_types.h            |  1 +
 .../include/odp_classification_inlines.h           | 23 +++++++++---
 .../linux-generic/include/odp_packet_internal.h    |  5 +--
 platform/linux-generic/odp_classification.c        |  4 +--
 platform/linux-generic/odp_packet.c                | 41 +++++++++++++++++-----
 platform/linux-generic/odp_packet_flags.c          | 10 ++++++
 6 files changed, 67 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h
index 009a3aa7c..89eff1b70 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_types.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_types.h
@@ -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 */
 	};
diff --git a/platform/linux-generic/include/odp_classification_inlines.h b/platform/linux-generic/include/odp_classification_inlines.h
index 2747db8cc..f48bbf514 100644
--- a/platform/linux-generic/include/odp_classification_inlines.h
+++ b/platform/linux-generic/include/odp_classification_inlines.h
@@ -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;
 }
 
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index fb3d44498..94cca9aa3 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -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);
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c
index 3dabb3873..cab74e159 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -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)
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 04f1f33bb..d2cbf5b46 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -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)
diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c
index 2e26ad601..e58850431 100644
--- a/platform/linux-generic/odp_packet_flags.c
+++ b/platform/linux-generic/odp_packet_flags.c
@@ -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);