diff mbox series

[v2,4/4] validation: cls: add test case for LD_VNI pmr term

Message ID 1513270810-29728-5-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>


Add test case for 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
 **/
 .../validation/api/classification/classification.h |   1 +
 .../api/classification/odp_classification_common.c |  98 ++++++++++++++++--
 .../classification/odp_classification_test_pmr.c   | 114 +++++++++++++++++++++
 .../classification/odp_classification_testsuites.h |   1 +
 4 files changed, 206 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/test/validation/api/classification/classification.h b/test/validation/api/classification/classification.h
index 326177ad8..8d1f174b6 100644
--- a/test/validation/api/classification/classification.h
+++ b/test/validation/api/classification/classification.h
@@ -100,6 +100,7 @@  void classification_test_pmr_term_dmac(void);
 void classification_test_pmr_term_packet_len(void);
 void classification_test_pmr_term_vlan_id_0(void);
 void classification_test_pmr_term_vlan_id_x(void);
+void classification_test_pmr_term_ld_vni(void);
 void classification_test_pmr_term_eth_type_0(void);
 void classification_test_pmr_term_eth_type_x(void);
 void classification_test_pktin_classifier_flag(void);
diff --git a/test/validation/api/classification/odp_classification_common.c b/test/validation/api/classification/odp_classification_common.c
index 60e20ea87..314843675 100644
--- a/test/validation/api/classification/odp_classification_common.c
+++ b/test/validation/api/classification/odp_classification_common.c
@@ -107,8 +107,23 @@  int cls_pkt_set_seq(odp_packet_t pkt)
 	CU_ASSERT_FATAL(offset != ODP_PACKET_OFFSET_INVALID);
 
 	if (ip->proto == ODPH_IPPROTO_UDP)
-		status = odp_packet_copy_from_mem(pkt, offset + ODPH_UDPHDR_LEN,
-						  sizeof(data), &data);
+		if (odp_packet_has_vxlan(pkt)) {
+			/* TODO: Inner header parsing is not supported
+			 * in this ODP release. Hence the packet parsing
+			 * is skipped. This code has to be modifies once
+			 * inner header parsing support is added */
+
+			/* skipping inner header for Vxlan */
+			offset += ODPH_UDPHDR_LEN;
+			offset += ODPH_ETHADDR_LEN;
+			offset += ODPH_IPV4HDR_LEN;
+			offset += ODPH_TCPHDR_LEN;
+			status = odp_packet_copy_from_mem(pkt, offset,
+							  sizeof(data), &data);
+		} else
+			status = odp_packet_copy_from_mem(pkt, offset +
+							  ODPH_UDPHDR_LEN,
+							  sizeof(data), &data);
 	else {
 		tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 		status = odp_packet_copy_from_mem(pkt, offset + tcp->hl * 4,
@@ -132,8 +147,19 @@  uint32_t cls_pkt_get_seq(odp_packet_t pkt)
 		return TEST_SEQ_INVALID;
 
 	if (ip->proto == ODPH_IPPROTO_UDP)
-		odp_packet_copy_to_mem(pkt, offset + ODPH_UDPHDR_LEN,
-				       sizeof(data), &data);
+		/* get packet magic from inner header */
+		if (odp_packet_has_vxlan(pkt)) {
+			/* skipping inner header for Vxlan */
+			offset += ODPH_UDPHDR_LEN;
+			offset += ODPH_ETHADDR_LEN;
+			offset += ODPH_IPV4HDR_LEN;
+			offset += ODPH_TCPHDR_LEN;
+			odp_packet_copy_to_mem(pkt, offset,
+					       sizeof(data), &data);
+		} else {
+			odp_packet_copy_to_mem(pkt, offset + ODPH_UDPHDR_LEN,
+					       sizeof(data), &data);
+		}
 	else {
 		tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 		odp_packet_copy_to_mem(pkt, offset + tcp->hl * 4,
@@ -249,9 +275,11 @@  odp_packet_t create_packet(cls_packet_info_t pkt_info)
 	uint16_t l2_hdr_len = 0;
 	uint16_t l3_hdr_len = 0;
 	uint16_t l4_hdr_len = 0;
+	uint16_t vxlan_len;
 	uint16_t eth_type;
 	odp_u16be_t *vlan_type;
 	odph_vlanhdr_t *vlan_hdr;
+	uint16_t inner_hdr_len;
 
 	/* 48 bit ethernet address needs to be left shifted for proper
 	value after changing to be*/
@@ -262,14 +290,16 @@  odp_packet_t create_packet(cls_packet_info_t pkt_info)
 	payload_len = sizeof(cls_test_packet_t) + pkt_info.len;
 	seqno = odp_atomic_fetch_inc_u32(pkt_info.seq);
 
+	inner_hdr_len = ODPH_ETHADDR_LEN + ODPH_IPV4HDR_LEN + ODPH_TCPHDR_LEN;
 	vlan_hdr_len = pkt_info.vlan ? ODPH_VLANHDR_LEN : 0;
 	vlan_hdr_len = pkt_info.vlan_qinq ? 2 * vlan_hdr_len : vlan_hdr_len;
 	l3_hdr_len = pkt_info.ipv6 ? ODPH_IPV6HDR_LEN : ODPH_IPV4HDR_LEN;
 	l4_hdr_len = pkt_info.udp ? ODPH_UDPHDR_LEN : ODPH_TCPHDR_LEN;
 	eth_type = pkt_info.ipv6 ? ODPH_ETHTYPE_IPV6 : ODPH_ETHTYPE_IPV4;
 	next_hdr = pkt_info.udp ? ODPH_IPPROTO_UDP : ODPH_IPPROTO_TCP;
+	vxlan_len = pkt_info.vxlan ? ODPH_VXLANHDR_LEN + inner_hdr_len : 0;
 	l2_hdr_len   = ODPH_ETHHDR_LEN + vlan_hdr_len;
-	l4_len	= l4_hdr_len + payload_len;
+	l4_len	= l4_hdr_len + payload_len + vxlan_len;
 	l3_len	= l3_hdr_len + l4_len;
 	l2_len	= l2_hdr_len + l3_len;
 	packet_len	= l2_len;
@@ -351,9 +381,61 @@  odp_packet_t create_packet(cls_packet_info_t pkt_info)
 		udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
 		udp->chksum = 0;
 		odp_packet_has_udp_set(pkt, 1);
-		if (odph_udp_tcp_chksum(pkt, ODPH_CHKSUM_GENERATE, NULL) != 0) {
-			LOG_ERR("odph_udp_tcp_chksum failed\n");
-			return ODP_PACKET_INVALID;
+
+		/* vxlan */
+		if (pkt_info.vxlan) {
+			odph_vxlanhdr_t *vxlan;
+			uint32_t vni;
+			odph_ethhdr_t *eth;
+			odph_ipv4hdr_t *ipv4;
+			odph_tcphdr_t *tcp;
+			uint8_t *ptr;
+
+			/* Outer header UDP chksum set to zero */
+			udp->chksum = 0;
+			odp_packet_has_vxlan_set(pkt, 1);
+			vxlan = (odph_vxlanhdr_t *)(buf + l4_offset +
+						    ODPH_UDPHDR_LEN);
+			ptr = (uint8_t *)vxlan;
+			vxlan->flags = 0x08;
+			vni = 1000 << 8;
+			vxlan->vni = odp_cpu_to_be_32(vni);
+
+			/* inner header L2 */
+			eth = (odph_ethhdr_t *)(ptr + ODPH_VXLANHDR_LEN);
+			ptr += ODPH_VXLANHDR_LEN;
+			memcpy(eth->src.addr, &src_mac, ODPH_ETHADDR_LEN);
+			memcpy(eth->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN);
+			eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
+
+			/* inner header L3 */
+			ipv4 = (odph_ipv4hdr_t *)(ptr + ODPH_ETHADDR_LEN);
+			parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
+			ipv4->dst_addr = odp_cpu_to_be_32(addr);
+
+			parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
+			ipv4->src_addr = odp_cpu_to_be_32(addr);
+			ipv4->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
+			ipv4->id = odp_cpu_to_be_16(seqno);
+			ipv4->proto = next_hdr;
+			ipv4->tot_len = odp_cpu_to_be_16(l3_len);
+			ipv4->ttl = DEFAULT_TTL;
+			ptr += ODPH_IPV4HDR_LEN;
+
+			/* inner header L4 */
+			tcp = (odph_tcphdr_t *)(ptr + ODPH_IPV4HDR_LEN);
+			tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
+			tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
+			tcp->hl = ODPH_TCPHDR_LEN / 4;
+			tcp->cksm = 0;
+			odp_packet_has_tcp_set(pkt, 1);
+			ptr += ODPH_TCPHDR_LEN;
+		} else {
+			if (odph_udp_tcp_chksum(pkt, ODPH_CHKSUM_GENERATE,
+						NULL) != 0) {
+				LOG_ERR("odph_udp_tcp_chksum failed\n");
+				return ODP_PACKET_INVALID;
+			}
 		}
 	} else {
 		tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c
index 87d04b6be..4ae5bb628 100644
--- a/test/validation/api/classification/odp_classification_test_pmr.c
+++ b/test/validation/api/classification/odp_classification_test_pmr.c
@@ -1195,6 +1195,119 @@  void classification_test_pmr_term_vlan_id_x(void)
 	odp_pktio_close(pktio);
 }
 
+void classification_test_pmr_term_ld_vni(void)
+{
+	odp_packet_t pkt;
+	uint32_t seqno;
+	uint32_t val;
+	uint32_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t default_queue;
+	odp_cos_t default_cos;
+	odp_pool_t default_pool;
+	odp_pool_t pool;
+	odp_pool_t recvpool;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_COS_NAME_LEN];
+	odp_cls_cos_param_t cls_param;
+	odp_pmr_param_t pmr_param;
+	odph_ethhdr_t *eth;
+	odph_udphdr_t *udp;
+	cls_packet_info_t pkt_info;
+
+	val = 1000;
+	mask = 0xffff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool, true);
+	CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+	retval = start_pktio(pktio);
+	CU_ASSERT(retval == 0);
+
+	configure_default_cos(pktio, &default_cos,
+			      &default_queue, &default_pool);
+
+	queue = queue_create("ld_vni", true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	pool = pool_create("ld_vni");
+	CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+	sprintf(cosname, "ld_vni");
+	odp_cls_cos_param_init(&cls_param);
+	cls_param.pool = pool;
+	cls_param.queue = queue;
+	cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+	cos = odp_cls_cos_create(cosname, &cls_param);
+	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+	odp_cls_pmr_param_init(&pmr_param);
+	pmr_param.term = ODP_PMR_LD_VNI;
+	pmr_param.match.value = &val;
+	pmr_param.match.mask = &mask;
+	pmr_param.val_sz = sizeof(val);
+
+	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	pkt_info = default_pkt_info;
+	pkt_info.vlan = true;
+	pkt_info.udp = true;
+	pkt_info.vxlan = true;
+	pkt = create_packet(pkt_info);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+	eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+	odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+	odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	udp->dst_port = odp_cpu_to_be_16(ODPH_UDP_VXLAN_PORT);
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	recvpool = odp_packet_pool(pkt);
+	CU_ASSERT(recvpool == pool);
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	/* Other packets delivered to default queue */
+	pkt = create_packet(default_pkt_info);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+	eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+	odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+	odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	recvpool = odp_packet_pool(pkt);
+	CU_ASSERT(recvpool == default_pool);
+	CU_ASSERT(retqueue == default_queue);
+
+	odp_cos_destroy(cos);
+	odp_cos_destroy(default_cos);
+	odp_cls_pmr_destroy(pmr);
+	odp_packet_free(pkt);
+	stop_pktio(pktio);
+	odp_pool_destroy(default_pool);
+	odp_pool_destroy(pool);
+	odp_queue_destroy(queue);
+	odp_queue_destroy(default_queue);
+	odp_pktio_close(pktio);
+}
+
 void classification_test_pmr_term_eth_type_0(void)
 {
 	odp_packet_t pkt;
@@ -1956,6 +2069,7 @@  odp_testinfo_t classification_suite_pmr[] = {
 	ODP_TEST_INFO(classification_test_pmr_term_packet_len),
 	ODP_TEST_INFO(classification_test_pmr_term_vlan_id_0),
 	ODP_TEST_INFO(classification_test_pmr_term_vlan_id_x),
+	ODP_TEST_INFO(classification_test_pmr_term_ld_vni),
 	ODP_TEST_INFO(classification_test_pmr_term_eth_type_0),
 	ODP_TEST_INFO(classification_test_pmr_term_eth_type_x),
 	ODP_TEST_INFO(classification_test_pktin_classifier_flag),
diff --git a/test/validation/api/classification/odp_classification_testsuites.h b/test/validation/api/classification/odp_classification_testsuites.h
index e1624162f..6b449b40e 100644
--- a/test/validation/api/classification/odp_classification_testsuites.h
+++ b/test/validation/api/classification/odp_classification_testsuites.h
@@ -18,6 +18,7 @@  typedef struct cls_packet_info {
 	bool	vlan_qinq;
 	odp_atomic_u32_t *seq;
 	bool	udp;
+	bool	vxlan;
 	bool	ipv6;
 	uint32_t len;
 } cls_packet_info_t;