diff mbox series

[PATCHv2,2/2] validation: classification: add test case for ipv6 src and dst addr

Message ID 1485844956-14926-2-git-send-email-bala.manoharan@linaro.org
State Superseded
Headers show
Series [PATCHv2,1/2] linux-generic: classification: implement ipv6 packet matching rule | expand

Commit Message

Balasubramanian Manoharan Jan. 31, 2017, 6:42 a.m. UTC
Adds test case for ipv6 source and destination address matching

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

---
 .../validation/api/classification/classification.h |  21 ++
 .../api/classification/odp_classification_common.c | 149 ++++++-----
 .../classification/odp_classification_test_pmr.c   | 292 +++++++++++++++++++--
 .../api/classification/odp_classification_tests.c  |  42 ++-
 .../classification/odp_classification_testsuites.h |  14 +-
 5 files changed, 421 insertions(+), 97 deletions(-)

-- 
1.9.1
diff mbox series

Patch

diff --git a/test/common_plat/validation/api/classification/classification.h b/test/common_plat/validation/api/classification/classification.h
index d73c821..0192e24 100644
--- a/test/common_plat/validation/api/classification/classification.h
+++ b/test/common_plat/validation/api/classification/classification.h
@@ -55,6 +55,27 @@ 
 #define DATA_MAGIC		0x01020304
 #define TEST_SEQ_INVALID	((uint32_t)~0)
 
+/* Test packet Time-to-live */
+#define DEFAULT_TTL              128
+
+/* Test packet default DSCP value */
+#define LOW_DROP_PRECEDENCE      0x02
+#define MEDIUM_DROP_PRECEDENCE   0x04
+#define HIGH_DROP_PRECEDENCE     0x06
+#define DROP_PRECEDENCE_MASK     0x06
+#define DSCP_CLASS1              0x08
+#define DSCP_CLASS2              0x10
+#define DSCP_CLASS3              0x18
+#define DSCP_CLASS4              0x20
+#define DEFAULT_DSCP             (DSCP_CLASS2 | LOW_DROP_PRECEDENCE)
+
+/* Test packet default ECN */
+#define DEFAULT_ECN              ODPH_IP_ECN_ECT0
+
+/* Test packet default TOS */
+#define DEFAULT_TOS              ((DEFAULT_DSCP << ODPH_IP_TOS_DSCP_SHIFT) | \
+					DEFAULT_ECN)
+
 /* test functions: */
 void classification_test_create_cos(void);
 void classification_test_destroy_cos(void);
diff --git a/test/common_plat/validation/api/classification/odp_classification_common.c b/test/common_plat/validation/api/classification/odp_classification_common.c
index f7ec6e5..0ca9083 100644
--- a/test/common_plat/validation/api/classification/odp_classification_common.c
+++ b/test/common_plat/validation/api/classification/odp_classification_common.c
@@ -14,6 +14,16 @@  typedef struct cls_test_packet {
 	odp_u32be_t seq;
 } cls_test_packet_t;
 
+static uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = {
+	/* I.e. ::ffff:10.0.0.1 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 1
+};
+
+static uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = {
+	/* I.e. ::ffff:10.0.0.100 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 0, 0, 100
+};
+
 odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool)
 {
 	odp_pktio_t pktio;
@@ -211,30 +221,30 @@  odp_pool_t pool_create(const char *poolname)
 	return odp_pool_create(poolname, &param);
 }
 
-odp_packet_t create_packet(odp_pool_t pool, bool vlan,
-			   odp_atomic_u32_t *seq, bool flag_udp)
-{
-	return create_packet_len(pool, vlan, seq, flag_udp, 0);
-}
-
-odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
-			       odp_atomic_u32_t *seq, bool flag_udp,
-			       uint16_t len)
+odp_packet_t create_packet(cls_packet_info_t pkt_info)
 {
 	uint32_t seqno;
 	odph_ethhdr_t *ethhdr;
 	odph_udphdr_t *udp;
 	odph_tcphdr_t *tcp;
 	odph_ipv4hdr_t *ip;
+	odph_ipv6hdr_t *ipv6;
 	uint16_t payload_len;
 	uint64_t src_mac = CLS_DEFAULT_SMAC;
 	uint64_t dst_mac = CLS_DEFAULT_DMAC;
 	uint64_t dst_mac_be;
 	uint32_t addr = 0;
 	uint32_t mask;
-	int offset;
 	odp_packet_t pkt;
 	int packet_len = 0;
+	uint32_t        version, tc, flow, ver_tc_flow;
+	uint8_t         *buf, next_hdr;
+	uint32_t        l4_len, l3_len, l2_len, l3_offset, l4_offset;
+	uint16_t vlan_hdr_len = 0;
+	uint16_t l2_hdr_len = 0;
+	uint16_t l3_hdr_len = 0;
+	uint16_t l4_hdr_len = 0;
+	uint16_t eth_type;
 
 	/* 48 bit ethernet address needs to be left shifted for proper
 	value after changing to be*/
@@ -242,77 +252,85 @@  odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
 	if (dst_mac != dst_mac_be)
 		dst_mac_be = dst_mac_be >> (64 - 8 * ODPH_ETHADDR_LEN);
 
-	payload_len = sizeof(cls_test_packet_t) + len;
-	packet_len += ODPH_ETHHDR_LEN;
-	packet_len += ODPH_IPV4HDR_LEN;
-	if (flag_udp)
-		packet_len += ODPH_UDPHDR_LEN;
-	else
-		packet_len += ODPH_TCPHDR_LEN;
-	packet_len += payload_len;
-
-	if (vlan)
-		packet_len += ODPH_VLANHDR_LEN;
-
-	pkt = odp_packet_alloc(pool, packet_len);
+	payload_len = sizeof(cls_test_packet_t) + pkt_info.len;
+	seqno = odp_atomic_fetch_inc_u32(pkt_info.seq);
+
+	vlan_hdr_len = pkt_info.vlan ? ODPH_VLANHDR_LEN : 0;
+	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;
+	l2_hdr_len   = ODPH_ETHHDR_LEN + vlan_hdr_len;
+	l4_len	= l4_hdr_len + payload_len;
+	l3_len	= l3_hdr_len + l4_len;
+	l2_len	= l2_hdr_len + l3_len;
+	packet_len	= l2_len;
+
+	pkt = odp_packet_alloc(pkt_info.pool, packet_len);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 
 	/* Ethernet Header */
-	offset = 0;
-	odp_packet_l2_offset_set(pkt, offset);
+	buf = odp_packet_data(pkt);
+	odp_packet_l2_offset_set(pkt, 0);
 	ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 	memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN);
 	memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN);
-	offset += sizeof(odph_ethhdr_t);
-	if (vlan) {
+	if (pkt_info.vlan) {
 		/* Default vlan header */
 		odph_vlanhdr_t *vlan_hdr;
-
+		odp_packet_has_vlan_set(pkt, 1);
 		ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
 		vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
 		vlan_hdr->tci = odp_cpu_to_be_16(0);
-		vlan_hdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
-		offset += sizeof(odph_vlanhdr_t);
+		vlan_hdr->type = odp_cpu_to_be_16(eth_type);
 	} else {
-		ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
+		ethhdr->type = odp_cpu_to_be_16(eth_type);
 	}
 
-	odp_packet_l3_offset_set(pkt, offset);
-
-	/* ipv4 */
-	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
-
-	parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
-	ip->dst_addr = odp_cpu_to_be_32(addr);
-
-	parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
-	ip->src_addr = odp_cpu_to_be_32(addr);
-	ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
-	odp_packet_has_ipv4_set(pkt, 1);
-
-	if (flag_udp)
-		ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
-					       ODPH_IPV4HDR_LEN);
-	else
-		ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN + payload_len +
-					       ODPH_IPV4HDR_LEN);
-
-	ip->ttl = 128;
-	if (flag_udp)
-		ip->proto = ODPH_IPPROTO_UDP;
-	else
-		ip->proto = ODPH_IPPROTO_TCP;
+	l3_offset = l2_hdr_len;
+	odp_packet_l3_offset_set(pkt, l3_offset);
+
+	if (!pkt_info.ipv6) {
+		/* ipv4 */
+		ip = (odph_ipv4hdr_t *)(buf + l3_offset);
+
+		parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
+		ip->dst_addr = odp_cpu_to_be_32(addr);
+
+		parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
+		ip->src_addr = odp_cpu_to_be_32(addr);
+		ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
+		ip->id = odp_cpu_to_be_16(seqno);
+		ip->chksum = 0;
+		ip->chksum = odph_ipv4_csum_update(pkt);
+		ip->proto = next_hdr;
+		ip->tot_len = odp_cpu_to_be_16(l3_len);
+		ip->ttl = DEFAULT_TTL;
+		odp_packet_has_ipv4_set(pkt, 1);
+	} else {
+		/* ipv6 */
+		odp_packet_has_ipv6_set(pkt, 1);
+		ipv6 = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+		version     = ODPH_IPV6        << ODPH_IPV6HDR_VERSION_SHIFT;
+		tc          = DEFAULT_TOS << ODPH_IPV6HDR_TC_SHIFT;
+		flow        = seqno       << ODPH_IPV6HDR_FLOW_LABEL_SHIFT;
+		ver_tc_flow = version | tc | flow;
+
+		ipv6->ver_tc_flow = odp_cpu_to_be_32(ver_tc_flow);
+		ipv6->payload_len = odp_cpu_to_be_16(l4_len);
+		ipv6->next_hdr    = next_hdr;
+		ipv6->hop_limit   = DEFAULT_TTL;
+		memcpy(ipv6->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN);
+		memcpy(ipv6->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN);
+	}
 
-	seqno = odp_atomic_fetch_inc_u32(seq);
-	ip->id = odp_cpu_to_be_16(seqno);
-	ip->chksum = 0;
-	ip->chksum = odph_ipv4_csum_update(pkt);
-	offset += ODPH_IPV4HDR_LEN;
+	l4_offset = l3_offset + l3_hdr_len;
+	odp_packet_l4_offset_set(pkt, l4_offset);
+	tcp = (odph_tcphdr_t *)(buf + l4_offset);
+	udp = (odph_udphdr_t *)(buf + l4_offset);
 
 	/* udp */
-	if (flag_udp) {
-		odp_packet_l4_offset_set(pkt, offset);
-		udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	if (pkt_info.udp) {
 		udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
 		udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
 		udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
@@ -323,8 +341,6 @@  odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
 			return ODP_PACKET_INVALID;
 		}
 	} else {
-		odp_packet_l4_offset_set(pkt, offset);
-		tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 		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;
@@ -334,6 +350,7 @@  odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
 			LOG_ERR("odph_udp_tcp_chksum failed\n");
 			return ODP_PACKET_INVALID;
 		}
+
 	}
 
 	/* set pkt sequence number */
diff --git a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
index a54954e..c714549 100644
--- a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
+++ b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
@@ -9,10 +9,11 @@ 
 #include <odp_cunit_common.h>
 
 static odp_pool_t pkt_pool;
-
 /** sequence number of IP packets */
 odp_atomic_u32_t seq;
 
+static cls_packet_info_t default_pkt_info;
+
 int classification_suite_pmr_init(void)
 {
 	pkt_pool = pool_create("classification_pmr_pool");
@@ -21,7 +22,12 @@  int classification_suite_pmr_init(void)
 		return -1;
 	}
 
+	memset(&default_pkt_info, 0, sizeof(cls_packet_info_t));
+	default_pkt_info.pool = pkt_pool;
+	default_pkt_info.seq = &seq;
+
 	odp_atomic_init_u32(&seq, 0);
+
 	return 0;
 }
 
@@ -103,7 +109,6 @@  void classification_test_pmr_term_tcp_dport(void)
 	odp_pool_t pool_recv;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
-
 	val = CLS_DEFAULT_DPORT;
 	mask = 0xffff;
 	seqno = 0;
@@ -140,7 +145,7 @@  void classification_test_pmr_term_tcp_dport(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -163,7 +168,7 @@  void classification_test_pmr_term_tcp_dport(void)
 	odp_packet_free(pkt);
 
 	/* Other packets are delivered to default queue */
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -254,7 +259,7 @@  void classification_test_pmr_term_tcp_sport(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -275,7 +280,7 @@  void classification_test_pmr_term_tcp_sport(void)
 	CU_ASSERT(recvpool == pool);
 	odp_packet_free(pkt);
 
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -329,6 +334,7 @@  void classification_test_pmr_term_udp_dport(void)
 	odp_pmr_param_t pmr_param;
 	odp_cls_cos_param_t cls_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = CLS_DEFAULT_DPORT;
 	mask = 0xffff;
@@ -366,7 +372,9 @@  void classification_test_pmr_term_udp_dport(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -388,7 +396,7 @@  void classification_test_pmr_term_udp_dport(void)
 	odp_packet_free(pkt);
 
 	/* Other packets received in default queue */
-	pkt = create_packet(pkt_pool, false, &seq, 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);
@@ -442,6 +450,7 @@  void classification_test_pmr_term_udp_sport(void)
 	odp_pmr_param_t pmr_param;
 	odp_cls_cos_param_t cls_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = CLS_DEFAULT_SPORT;
 	mask = 0xffff;
@@ -479,7 +488,9 @@  void classification_test_pmr_term_udp_sport(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -500,7 +511,7 @@  void classification_test_pmr_term_udp_sport(void)
 	CU_ASSERT(recvpool == pool);
 	odp_packet_free(pkt);
 
-	pkt = create_packet(pkt_pool, false, &seq, 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);
@@ -553,6 +564,7 @@  void classification_test_pmr_term_ipproto(void)
 	odp_cls_cos_param_t cls_param;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = ODPH_IPPROTO_UDP;
 	mask = 0xff;
@@ -590,7 +602,9 @@  void classification_test_pmr_term_ipproto(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -609,7 +623,7 @@  void classification_test_pmr_term_ipproto(void)
 	odp_packet_free(pkt);
 
 	/* Other packets delivered to default queue */
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -659,6 +673,7 @@  void classification_test_pmr_term_dmac(void)
 	odp_cls_cos_param_t cls_param;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = CLS_DEFAULT_DMAC; /* 48 bit Ethernet Mac address */
 	mask = 0xffffffffffff;
@@ -696,7 +711,9 @@  void classification_test_pmr_term_dmac(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -712,7 +729,7 @@  void classification_test_pmr_term_dmac(void)
 	odp_packet_free(pkt);
 
 	/* Other packets delivered to default queue */
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	pkt = create_packet(default_pkt_info);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 	eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 	memset(eth->dst.addr, 0, ODPH_ETHADDR_LEN);
@@ -762,6 +779,7 @@  void classification_test_pmr_term_packet_len(void)
 	odp_cls_cos_param_t cls_param;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = 1024;
 	/*Mask value will match any packet of length 1000 - 1099*/
@@ -801,7 +819,10 @@  void classification_test_pmr_term_packet_len(void)
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
 	/* create packet of payload length 1024 */
-	pkt = create_packet_len(pkt_pool, false, &seq, true, 1024);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = true;
+	pkt_info.len = 1024;
+	pkt = create_packet(pkt_info);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 	seqno = cls_pkt_get_seq(pkt);
 	CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -820,7 +841,7 @@  void classification_test_pmr_term_packet_len(void)
 	odp_packet_free(pkt);
 
 	/* Other packets delivered to default queue */
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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);
@@ -871,6 +892,7 @@  static void classification_test_pmr_pool_set(void)
 	odp_cls_cos_param_t cls_param;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = ODPH_IPPROTO_UDP;
 	mask = 0xff;
@@ -915,7 +937,9 @@  static void classification_test_pmr_pool_set(void)
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
 
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -967,6 +991,7 @@  static void classification_test_pmr_queue_set(void)
 	odp_cls_cos_param_t cls_param;
 	odp_pmr_param_t pmr_param;
 	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
 
 	val = ODPH_IPPROTO_UDP;
 	mask = 0xff;
@@ -1010,8 +1035,9 @@  static void classification_test_pmr_queue_set(void)
 
 	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
 	CU_ASSERT(pmr != ODP_PMR_INVAL);
-
-	pkt = create_packet(pkt_pool, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -1098,7 +1124,7 @@  static void classification_test_pmr_term_daddr(void)
 
 	/* packet with dst ip address matching PMR rule to be
 	received in the CoS queue*/
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	pkt = create_packet(default_pkt_info);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 	eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 	odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
@@ -1119,7 +1145,229 @@  static void classification_test_pmr_term_daddr(void)
 	odp_packet_free(pkt);
 
 	/* Other packets delivered to default queue */
-	pkt = create_packet(pkt_pool, false, &seq, false);
+	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));
+	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);
+}
+
+static void classification_test_pmr_term_ipv6daddr(void)
+{
+	odp_packet_t pkt;
+	uint32_t seqno;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t default_queue;
+	odp_pool_t pool;
+	odp_pool_t default_pool;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	odp_cos_t default_cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	odp_pmr_param_t pmr_param;
+	odp_cls_cos_param_t cls_param;
+	odph_ipv6hdr_t *ip;
+	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
+
+	uint8_t IPV6_DST_ADDR[ODPH_IPV6ADDR_LEN] = {
+		/* I.e. ::ffff:10.1.1.100 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 100
+	};
+	uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+	};
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+	retval = start_pktio(pktio);
+	CU_ASSERT(retval == 0);
+
+	configure_default_cos(pktio, &default_cos,
+			      &default_queue, &default_pool);
+
+	queue = queue_create("daddr", true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	pool = pool_create("daddr");
+	CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+	sprintf(cosname, "daddr");
+	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_DIP6_ADDR;
+	pmr_param.match.value = IPV6_DST_ADDR;
+	pmr_param.match.mask = ipv6_mask;
+	pmr_param.val_sz = ODPH_IPV6ADDR_LEN;
+
+	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+	CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL);
+
+	/* packet with dst ip address matching PMR rule to be
+	received in the CoS queue*/
+	pkt_info = default_pkt_info;
+	pkt_info.ipv6 = true;
+	pkt = create_packet(pkt_info);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_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);
+	ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+	memcpy(ip->dst_addr, IPV6_DST_ADDR, ODPH_IPV6ADDR_LEN);
+
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	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));
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	/* Other packets delivered to default queue */
+	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);
+
+	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));
+	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);
+}
+
+static void classification_test_pmr_term_ipv6saddr(void)
+{
+	odp_packet_t pkt;
+	uint32_t seqno;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t default_queue;
+	odp_pool_t pool;
+	odp_pool_t default_pool;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	odp_cos_t default_cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	odp_pmr_param_t pmr_param;
+	odp_cls_cos_param_t cls_param;
+	odph_ipv6hdr_t *ip;
+	odph_ethhdr_t *eth;
+	cls_packet_info_t pkt_info;
+	uint8_t IPV6_SRC_ADDR[ODPH_IPV6ADDR_LEN] = {
+		/* I.e. ::ffff:10.0.0.100 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 10, 1, 1, 1
+	};
+	uint8_t ipv6_mask[ODPH_IPV6ADDR_LEN] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+	};
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+	retval = start_pktio(pktio);
+	CU_ASSERT(retval == 0);
+
+	configure_default_cos(pktio, &default_cos,
+			      &default_queue, &default_pool);
+
+	queue = queue_create("saddr", true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	pool = pool_create("saddr");
+	CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+	sprintf(cosname, "saddr");
+	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_SIP6_ADDR;
+	pmr_param.match.value = IPV6_SRC_ADDR;
+	pmr_param.match.mask = ipv6_mask;
+	pmr_param.val_sz = ODPH_IPV6ADDR_LEN;
+
+	pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+	CU_ASSERT_FATAL(pmr != ODP_PMR_INVAL);
+
+	/* packet with dst ip address matching PMR rule to be
+	received in the CoS queue*/
+	pkt_info = default_pkt_info;
+	pkt_info.ipv6 = true;
+
+	pkt = create_packet(pkt_info);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_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);
+	ip = (odph_ipv6hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+	memcpy(ip->src_addr, IPV6_SRC_ADDR, ODPH_IPV6ADDR_LEN);
+
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	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));
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	/* Other packets delivered to default queue */
+	pkt = create_packet(pkt_info);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 	seqno = cls_pkt_get_seq(pkt);
 	CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -1156,6 +1404,8 @@  odp_testinfo_t classification_suite_pmr[] = {
 	ODP_TEST_INFO(classification_test_pmr_pool_set),
 	ODP_TEST_INFO(classification_test_pmr_queue_set),
 	ODP_TEST_INFO(classification_test_pmr_term_daddr),
+	ODP_TEST_INFO(classification_test_pmr_term_ipv6saddr),
+	ODP_TEST_INFO(classification_test_pmr_term_ipv6daddr),
 	ODP_TEST_INFO(classification_test_pmr_term_packet_len),
 	ODP_TEST_INFO_NULL,
 };
diff --git a/test/common_plat/validation/api/classification/odp_classification_tests.c b/test/common_plat/validation/api/classification/odp_classification_tests.c
index 4f1aecd..4f43082 100644
--- a/test/common_plat/validation/api/classification/odp_classification_tests.c
+++ b/test/common_plat/validation/api/classification/odp_classification_tests.c
@@ -19,6 +19,9 @@  static odp_pktio_t pktio_loop;
 /** sequence number of IP packets */
 odp_atomic_u32_t seq;
 
+/* default packet info */
+static cls_packet_info_t default_pkt_info;
+
 int classification_suite_init(void)
 {
 	int i;
@@ -43,6 +46,10 @@  int classification_suite_init(void)
 		return -1;
 	}
 
+	memset(&default_pkt_info, 0, sizeof(cls_packet_info_t));
+	default_pkt_info.pool = pool_default;
+	default_pkt_info.seq = &seq;
+
 	odp_pktin_queue_param_init(&pktin_param);
 	pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
 
@@ -216,8 +223,11 @@  void test_cls_pmr_chain(void)
 	uint32_t addr = 0;
 	uint32_t mask;
 	uint32_t seqno = 0;
+	cls_packet_info_t pkt_info;
 
-	pkt = create_packet(pool_default, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -240,7 +250,7 @@  void test_cls_pmr_chain(void)
 	CU_ASSERT(pool == pool_list[CLS_PMR_CHAIN_DST]);
 	odp_packet_free(pkt);
 
-	pkt = create_packet(pool_default, false, &seq, 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);
@@ -301,8 +311,12 @@  void test_pktio_default_cos(void)
 	odp_queue_t queue;
 	uint32_t seqno = 0;
 	odp_pool_t pool;
+	cls_packet_info_t pkt_info;
+
 	/* create a default packet */
-	pkt = create_packet(pool_default, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -360,9 +374,12 @@  void test_pktio_error_cos(void)
 	odp_queue_t queue;
 	odp_packet_t pkt;
 	odp_pool_t pool;
+	cls_packet_info_t pkt_info;
 
 	/*Create an error packet */
-	pkt = create_packet(pool_default, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = true;
+	pkt = create_packet(pkt_info);
 	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
 	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 
@@ -472,10 +489,15 @@  void test_cos_with_l2_priority(void)
 	odp_queue_t queue;
 	odp_pool_t pool;
 	uint32_t seqno = 0;
+	cls_packet_info_t pkt_info;
 	uint8_t i;
 
+	pkt_info = default_pkt_info;
+	pkt_info.udp = true;
+	pkt_info.vlan = true;
+
 	for (i = 0; i < CLS_L2_QOS_MAX; i++) {
-		pkt = create_packet(pool_default, true, &seq, 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);
@@ -546,8 +568,11 @@  void test_pmr_cos(void)
 	odp_queue_t queue;
 	odp_pool_t pool;
 	uint32_t seqno = 0;
+	cls_packet_info_t pkt_info;
 
-	pkt = create_packet(pool_default, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
@@ -629,8 +654,11 @@  void test_pktio_pmr_composite_cos(void)
 	odp_pool_t pool;
 	odp_queue_t queue;
 	uint32_t seqno = 0;
+	cls_packet_info_t pkt_info;
 
-	pkt = create_packet(pool_default, false, &seq, true);
+	pkt_info = default_pkt_info;
+	pkt_info.udp = 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);
diff --git a/test/common_plat/validation/api/classification/odp_classification_testsuites.h b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
index f9fd908..d5ffef7 100644
--- a/test/common_plat/validation/api/classification/odp_classification_testsuites.h
+++ b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
@@ -12,6 +12,15 @@ 
 #include <odp_cunit_common.h>
 #include <stdbool.h>
 
+typedef struct cls_packet_info {
+	odp_pool_t pool;
+	bool	vlan;
+	odp_atomic_u32_t *seq;
+	bool	udp;
+	bool	ipv6;
+	uint32_t len;
+} cls_packet_info_t;
+
 extern odp_testinfo_t classification_suite[];
 extern odp_testinfo_t classification_suite_basic[];
 extern odp_testinfo_t classification_suite_pmr[];
@@ -22,11 +31,10 @@  int classification_suite_term(void);
 int classification_suite_pmr_term(void);
 int classification_suite_pmr_init(void);
 
-odp_packet_t create_packet(odp_pool_t pool, bool vlan,
-			   odp_atomic_u32_t *seq, bool udp);
+odp_packet_t create_packet(cls_packet_info_t pkt_info);
 odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
 			       odp_atomic_u32_t *seq, bool flag_udp,
-			       uint16_t len);
+			       bool ipv4, uint16_t len);
 int cls_pkt_set_seq(odp_packet_t pkt);
 uint32_t cls_pkt_get_seq(odp_packet_t pkt);
 odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool);