diff mbox

[API-NEXT/PATCHv4] validation: classification: added additional suite to test individual PMRs

Message ID 1444222169-31323-1-git-send-email-bala.manoharan@linaro.org
State Superseded
Headers show

Commit Message

Balasubramanian Manoharan Oct. 7, 2015, 12:49 p.m. UTC
Additional test suite is added to classification validation suite to test
individual PMRs. This suite will test the defined PMRs by configuring
pktio separately for every test case.

Fixes:
https://bugs.linaro.org/show_bug.cgi?id=1542
https://bugs.linaro.org/show_bug.cgi?id=1544
https://bugs.linaro.org/show_bug.cgi?id=1545
https://bugs.linaro.org/show_bug.cgi?id=1546

Signed-off-by: Balasubramanian Manoharan <bala.manoharan@linaro.org>
---
v4: Move hash defines to header file

 helper/include/odp/helper/tcp.h                    |   1 +
 test/validation/classification/Makefile.am         |   2 +
 test/validation/classification/classification.c    |   5 +
 test/validation/classification/classification.h    |  44 ++
 .../classification/odp_classification_common.c     | 252 ++++++++++
 .../classification/odp_classification_test_pmr.c   | 554 +++++++++++++++++++++
 .../classification/odp_classification_tests.c      | 309 ++----------
 .../classification/odp_classification_testsuites.h |  15 +-
 8 files changed, 923 insertions(+), 259 deletions(-)
 create mode 100644 test/validation/classification/odp_classification_common.c
 create mode 100644 test/validation/classification/odp_classification_test_pmr.c
diff mbox

Patch

diff --git a/helper/include/odp/helper/tcp.h b/helper/include/odp/helper/tcp.h
index defe422..42f0cbe 100644
--- a/helper/include/odp/helper/tcp.h
+++ b/helper/include/odp/helper/tcp.h
@@ -26,6 +26,7 @@  extern "C" {
  *  @{
  */
 
+#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
 
 /** TCP header */
 typedef struct ODP_PACKED {
diff --git a/test/validation/classification/Makefile.am b/test/validation/classification/Makefile.am
index 5881665..4235309 100644
--- a/test/validation/classification/Makefile.am
+++ b/test/validation/classification/Makefile.am
@@ -3,6 +3,8 @@  include ../Makefile.inc
 noinst_LTLIBRARIES = libtestclassification.la
 libtestclassification_la_SOURCES = odp_classification_basic.c \
 			       odp_classification_tests.c \
+			       odp_classification_test_pmr.c \
+			       odp_classification_common.c \
 			       classification.c
 
 bin_PROGRAMS = classification_main$(EXEEXT)
diff --git a/test/validation/classification/classification.c b/test/validation/classification/classification.c
index d0fef93..6641893 100644
--- a/test/validation/classification/classification.c
+++ b/test/validation/classification/classification.c
@@ -13,6 +13,11 @@  CU_SuiteInfo classification_suites[] = {
 	{ .pName = "classification basic",
 			.pTests = classification_suite_basic,
 	},
+	{ .pName = "classification pmr tests",
+			.pTests = classification_suite_pmr,
+			.pInitFunc = classification_suite_pmr_init,
+			.pCleanupFunc = classification_suite_pmr_term,
+	},
 	{ .pName = "classification tests",
 			.pTests = classification_suite,
 			.pInitFunc = classification_suite_init,
diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h
index d2847e5..de9c37e 100644
--- a/test/validation/classification/classification.h
+++ b/test/validation/classification/classification.h
@@ -9,6 +9,50 @@ 
 
 #include <CUnit/Basic.h>
 
+#define SHM_PKT_NUM_BUFS        32
+#define SHM_PKT_BUF_SIZE        1024
+
+/* Config values for Default CoS */
+#define TEST_DEFAULT		1
+#define	CLS_DEFAULT		0
+#define CLS_DEFAULT_SADDR	"10.0.0.1/32"
+#define CLS_DEFAULT_DADDR	"10.0.0.100/32"
+#define CLS_DEFAULT_SPORT	1024
+#define CLS_DEFAULT_DPORT	2048
+
+/* Config values for Error CoS */
+#define TEST_ERROR		1
+#define CLS_ERROR		1
+
+/* Config values for PMR_CHAIN */
+#define TEST_PMR_CHAIN		1
+#define CLS_PMR_CHAIN_SRC	2
+#define CLS_PMR_CHAIN_DST	3
+#define CLS_PMR_CHAIN_SADDR	"10.0.0.5/32"
+#define CLS_PMR_CHAIN_SPORT	3000
+
+/* Config values for PMR */
+#define TEST_PMR		1
+#define CLS_PMR			4
+#define CLS_PMR_SPORT		4000
+
+/* Config values for PMR SET */
+#define TEST_PMR_SET		1
+#define CLS_PMR_SET		5
+#define CLS_PMR_SET_SADDR	"10.0.0.6/32"
+#define CLS_PMR_SET_SPORT	5000
+
+/* Config values for CoS L2 Priority */
+#define TEST_L2_QOS		1
+#define CLS_L2_QOS_0		6
+#define CLS_L2_QOS_MAX		5
+
+#define CLS_ENTRIES		(CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
+
+/* Test Packet values */
+#define DATA_MAGIC		0x01020304
+#define TEST_SEQ_INVALID	((uint32_t)~0)
+
 /* test functions: */
 void classification_test_create_cos(void);
 void classification_test_destroy_cos(void);
diff --git a/test/validation/classification/odp_classification_common.c b/test/validation/classification/odp_classification_common.c
new file mode 100644
index 0000000..b975dfb
--- /dev/null
+++ b/test/validation/classification/odp_classification_common.c
@@ -0,0 +1,252 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include "odp_classification_testsuites.h"
+#include "classification.h"
+#include <odp_cunit_common.h>
+#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
+#include <odp/helper/udp.h>
+#include <odp/helper/tcp.h>
+
+typedef struct cls_test_packet {
+	uint32be_t magic;
+	uint32be_t seq;
+} cls_test_packet_t;
+
+int cls_pkt_set_seq(odp_packet_t pkt)
+{
+	static uint32_t seq;
+	cls_test_packet_t data;
+	uint32_t offset;
+	odph_ipv4hdr_t *ip;
+	int status;
+
+	data.magic = DATA_MAGIC;
+	data.seq = ++seq;
+
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+	offset = odp_packet_l4_offset(pkt);
+	CU_ASSERT_FATAL(offset != 0);
+
+	if (ip->proto == ODPH_IPPROTO_UDP)
+		status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
+						sizeof(data), &data);
+	else
+		status = odp_packet_copydata_in(pkt, offset + ODPH_TCPHDR_LEN,
+						sizeof(data), &data);
+
+	return status;
+}
+
+uint32_t cls_pkt_get_seq(odp_packet_t pkt)
+{
+	uint32_t offset;
+	cls_test_packet_t data;
+	odph_ipv4hdr_t *ip;
+
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+	offset = odp_packet_l4_offset(pkt);
+
+	if (!offset && !ip)
+		return TEST_SEQ_INVALID;
+
+	if (ip->proto == ODPH_IPPROTO_UDP)
+		odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
+					sizeof(data), &data);
+	else
+		odp_packet_copydata_out(pkt, offset + ODPH_TCPHDR_LEN,
+					sizeof(data), &data);
+
+	if (data.magic == DATA_MAGIC)
+		return data.seq;
+
+	return TEST_SEQ_INVALID;
+}
+
+int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t *mask)
+{
+	int b[4];
+	int qualifier = 32;
+	int converted;
+
+	if (strchr(ipaddress, '/')) {
+		converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
+				   &b[3], &b[2], &b[1], &b[0],
+				   &qualifier);
+		if (5 != converted)
+			return -1;
+	} else {
+		converted = sscanf(ipaddress, "%d.%d.%d.%d",
+				   &b[3], &b[2], &b[1], &b[0]);
+		if (4 != converted)
+			return -1;
+	}
+
+	if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
+		return -1;
+	if (!qualifier || (qualifier > 32))
+		return -1;
+
+	*addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
+	if (mask)
+		*mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
+
+	return 0;
+}
+
+void enqueue_pktio_interface(odp_packet_t pkt, odp_pktio_t pktio)
+{
+	odp_event_t ev;
+	odp_queue_t defqueue;
+
+	defqueue  = odp_pktio_outq_getdef(pktio);
+	CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
+
+	ev = odp_packet_to_event(pkt);
+	CU_ASSERT(odp_queue_enq(defqueue, ev) == 0);
+}
+
+odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
+{
+	odp_event_t ev;
+
+	ev = odp_schedule(queue, ns);
+	return odp_packet_from_event(ev);
+}
+
+odp_queue_t queue_create(char *queuename, bool sched)
+{
+	odp_queue_t queue;
+	odp_queue_param_t qparam;
+
+	if (sched) {
+		odp_queue_param_init(&qparam);
+		qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST;
+		qparam.sched.sync = ODP_SCHED_SYNC_NONE;
+		qparam.sched.group = ODP_SCHED_GROUP_ALL;
+
+		queue = odp_queue_create(queuename,
+					 ODP_QUEUE_TYPE_SCHED,
+					 &qparam);
+	} else {
+		queue = odp_queue_create(queuename,
+					 ODP_QUEUE_TYPE_POLL,
+					 NULL);
+	}
+
+	return queue;
+}
+
+odp_packet_t create_packet(odp_pool_t pool, bool vlan,
+			   odp_atomic_u32_t *seq, bool flag_udp)
+{
+	uint32_t seqno;
+	odph_ethhdr_t *ethhdr;
+	odph_udphdr_t *udp;
+	odph_tcphdr_t *tcp;
+	odph_ipv4hdr_t *ip;
+	uint8_t payload_len;
+	char src_mac[ODPH_ETHADDR_LEN]  = {0};
+	char dst_mac[ODPH_ETHADDR_LEN] = {0};
+	uint32_t addr = 0;
+	uint32_t mask;
+	int offset;
+	odp_packet_t pkt;
+	int packet_len = 0;
+
+	payload_len = sizeof(cls_test_packet_t);
+	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);
+	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+
+	/* Ethernet Header */
+	offset = 0;
+	odp_packet_l2_offset_set(pkt, offset);
+	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, ODPH_ETHADDR_LEN);
+	offset += sizeof(odph_ethhdr_t);
+	if (vlan) {
+		/* Default vlan header */
+		uint8_t *parseptr;
+		odph_vlanhdr_t *vlan;
+
+		vlan = (odph_vlanhdr_t *)(&ethhdr->type);
+		parseptr = (uint8_t *)vlan;
+		vlan->tci = odp_cpu_to_be_16(0);
+		vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
+		offset += sizeof(odph_vlanhdr_t);
+		parseptr += sizeof(odph_vlanhdr_t);
+		uint16be_t *type = (uint16be_t *)(void *)parseptr;
+		*type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
+	} else {
+		ethhdr->type =	odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
+	}
+
+	odp_packet_l3_offset_set(pkt, offset);
+
+	/* ipv4 */
+	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
+
+	parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
+	ip->dst_addr = odp_cpu_to_be_32(addr);
+
+	parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
+	ip->src_addr = odp_cpu_to_be_32(addr);
+	ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
+	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;
+
+	seqno = odp_atomic_fetch_inc_u32(seq);
+	ip->id = odp_cpu_to_be_16(seqno);
+	ip->chksum = 0;
+	ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
+	offset += ODPH_IPV4HDR_LEN;
+
+	/* udp */
+	if (flag_udp) {
+		odp_packet_l4_offset_set(pkt, offset);
+		udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+		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);
+		udp->chksum = 0;
+	} 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;
+		/* TODO: checksum field has to be updated */
+		tcp->cksm = 0;
+	}
+
+	/* set pkt sequence number */
+	cls_pkt_set_seq(pkt);
+
+	return pkt;
+}
diff --git a/test/validation/classification/odp_classification_test_pmr.c b/test/validation/classification/odp_classification_test_pmr.c
new file mode 100644
index 0000000..8d59031
--- /dev/null
+++ b/test/validation/classification/odp_classification_test_pmr.c
@@ -0,0 +1,554 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include "odp_classification_testsuites.h"
+#include "classification.h"
+#include <odp_cunit_common.h>
+#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
+#include <odp/helper/udp.h>
+#include <odp/helper/tcp.h>
+
+static odp_pool_t pool_default;
+
+/** sequence number of IP packets */
+odp_atomic_u32_t seq;
+
+static int destroy_inq(odp_pktio_t pktio)
+{
+	odp_queue_t inq;
+	odp_event_t ev;
+
+	inq = odp_pktio_inq_getdef(pktio);
+
+	if (inq == ODP_QUEUE_INVALID) {
+		CU_FAIL("attempting to destroy invalid inq");
+		return -1;
+	}
+
+	if (0 > odp_pktio_inq_remdef(pktio))
+		return -1;
+
+	while (1) {
+		ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
+
+		if (ev != ODP_EVENT_INVALID)
+			odp_buffer_free(odp_buffer_from_event(ev));
+		else
+			break;
+	}
+
+	return odp_queue_destroy(inq);
+}
+
+int classification_suite_pmr_init(void)
+{
+	odp_pool_t pool;
+	odp_pool_param_t param;
+
+	odp_pool_param_init(&param);
+	param.pkt.seg_len = SHM_PKT_BUF_SIZE;
+	param.pkt.len     = SHM_PKT_BUF_SIZE;
+	param.pkt.num     = SHM_PKT_NUM_BUFS;
+	param.type        = ODP_POOL_PACKET;
+
+	pool = odp_pool_create("classification_pmr_pool", &param);
+	if (ODP_POOL_INVALID == pool) {
+		fprintf(stderr, "Packet pool creation failed.\n");
+		return -1;
+	}
+
+	pool_default = odp_pool_lookup("classification_pmr_pool");
+	if (pool_default == ODP_POOL_INVALID)
+		return -1;
+
+	odp_atomic_init_u32(&seq, 0);
+	return 0;
+}
+
+odp_pktio_t create_pktio(odp_queue_type_t q_type)
+{
+	odp_pktio_t pktio;
+	odp_pktio_param_t pktio_param;
+	odp_pool_t pool;
+	int ret;
+
+	pool = odp_pool_lookup("classification_pmr_pool");
+	if (pool == ODP_POOL_INVALID)
+		return ODP_PKTIO_INVALID;
+
+	memset(&pktio_param, 0, sizeof(pktio_param));
+	if (q_type == ODP_QUEUE_TYPE_POLL)
+		pktio_param.in_mode = ODP_PKTIN_MODE_POLL;
+	else
+		pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+
+	pktio = odp_pktio_open("loop", pool, &pktio_param);
+	if (pktio == ODP_PKTIO_INVALID) {
+		ret = odp_pool_destroy(pool);
+		if (ret)
+			fprintf(stderr, "unable to destroy pool.\n");
+		return ODP_PKTIO_INVALID;
+	}
+
+	ret = odp_pktio_start(pktio);
+	if (ret) {
+		fprintf(stderr, "unable to start loop\n");
+		return ODP_PKTIO_INVALID;
+	}
+
+	return pktio;
+}
+
+odp_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype)
+{
+	odp_queue_param_t qparam;
+	odp_queue_t inq_def;
+	char inq_name[ODP_QUEUE_NAME_LEN];
+
+	odp_queue_param_init(&qparam);
+	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
+	qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
+	qparam.sched.group = ODP_SCHED_GROUP_ALL;
+
+	snprintf(inq_name, sizeof(inq_name), "inq-pktio-%" PRIu64,
+		 odp_pktio_to_u64(pktio));
+	inq_def = odp_queue_lookup(inq_name);
+	if (inq_def == ODP_QUEUE_INVALID)
+		inq_def = odp_queue_create(
+				inq_name,
+				ODP_QUEUE_TYPE_PKTIN,
+				qtype == ODP_QUEUE_TYPE_POLL ? NULL : &qparam);
+
+	CU_ASSERT(inq_def != ODP_QUEUE_INVALID);
+
+	if (0 > odp_pktio_inq_setdef(pktio, inq_def))
+		return ODP_QUEUE_INVALID;
+
+	return inq_def;
+}
+
+int classification_suite_pmr_term(void)
+{
+	int retcode = 0;
+
+	if (0 != odp_pool_destroy(pool_default)) {
+		fprintf(stderr, "pool_default destroy failed.\n");
+		retcode = -1;
+	}
+
+	return retcode;
+}
+
+static void classification_test_pmr_term_tcp_dport(void)
+{
+	odp_packet_t pkt;
+	odph_tcphdr_t *tcp;
+	uint32_t seqno;
+	uint16_t val;
+	uint16_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t defqueue;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	char queuename[ODP_QUEUE_NAME_LEN];
+
+	val = CLS_DEFAULT_DPORT;
+	mask = 0xffff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+	CU_ASSERT(pktio != ODP_PKTIO_INVALID);
+	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+	CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
+
+	pmr = odp_pmr_create(ODP_PMR_TCP_DPORT, &val,
+			     &mask, sizeof(val));
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	sprintf(cosname, "tcp_dport");
+	cos = odp_cos_create(cosname);
+	CU_ASSERT(cos != ODP_COS_INVALID);
+
+	sprintf(queuename, "%s", "tcp_dport1");
+
+	queue = queue_create(queuename, true);
+	CU_ASSERT(queue != ODP_QUEUE_INVALID);
+
+	retval = odp_cos_queue_set(cos, queue);
+	CU_ASSERT(retval == 0);
+
+	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+	CU_ASSERT(retval == 0);
+
+	pkt = create_packet(pool_default, false, &seq, false);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(retqueue == queue);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+
+	odp_packet_free(pkt);
+
+	/* Other packets are delivered to default queue */
+	pkt = create_packet(pool_default, false, &seq, false);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == defqueue);
+
+	odp_packet_free(pkt);
+	odp_cos_destroy(cos);
+	odp_pmr_destroy(pmr);
+	destroy_inq(pktio);
+	odp_queue_destroy(queue);
+	odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_tcp_sport(void)
+{
+	odp_packet_t pkt;
+	odph_tcphdr_t *tcp;
+	uint32_t seqno;
+	uint16_t val;
+	uint16_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t defqueue;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	char queuename[ODP_QUEUE_NAME_LEN];
+
+	val = CLS_DEFAULT_SPORT;
+	mask = 0xffff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+	pmr = odp_pmr_create(ODP_PMR_TCP_SPORT, &val,
+			     &mask, sizeof(val));
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	sprintf(cosname, "tcp_sport");
+	cos = odp_cos_create(cosname);
+	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+	sprintf(queuename, "%s", "tcp_sport");
+
+	queue = queue_create(queuename, true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	retval = odp_cos_queue_set(cos, queue);
+	CU_ASSERT(retval == 0);
+
+	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+	CU_ASSERT(retval == 0);
+
+	pkt = create_packet(pool_default, false, &seq, false);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	pkt = create_packet(pool_default, false, &seq, false);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == defqueue);
+
+	odp_packet_free(pkt);
+	odp_cos_destroy(cos);
+	odp_pmr_destroy(pmr);
+	destroy_inq(pktio);
+	odp_queue_destroy(queue);
+	odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_udp_dport(void)
+{
+	odp_packet_t pkt;
+	odph_udphdr_t *udp;
+	uint32_t seqno;
+	uint16_t val;
+	uint16_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t defqueue;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	char queuename[ODP_QUEUE_NAME_LEN];
+
+	val = CLS_DEFAULT_DPORT;
+	mask = 0xffff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+	pmr = odp_pmr_create(ODP_PMR_UDP_DPORT, &val,
+			     &mask, sizeof(val));
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	sprintf(cosname, "udp_dport");
+	cos = odp_cos_create(cosname);
+	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+	sprintf(queuename, "%s", "udp_dport");
+
+	queue = queue_create(queuename, true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	retval = odp_cos_queue_set(cos, queue);
+	CU_ASSERT(retval == 0);
+
+	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+	CU_ASSERT(retval == 0);
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	/* Other packets received in default queue */
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == defqueue);
+
+	odp_packet_free(pkt);
+	odp_cos_destroy(cos);
+	odp_pmr_destroy(pmr);
+	destroy_inq(pktio);
+	odp_queue_destroy(queue);
+	odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_udp_sport(void)
+{
+	odp_packet_t pkt;
+	odph_udphdr_t *udp;
+	uint32_t seqno;
+	uint16_t val;
+	uint16_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t defqueue;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	char queuename[ODP_QUEUE_NAME_LEN];
+
+	val = CLS_DEFAULT_SPORT;
+	mask = 0xffff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+	pmr = odp_pmr_create(ODP_PMR_UDP_SPORT, &val,
+			     &mask, sizeof(val));
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	sprintf(cosname, "udp_sport");
+	cos = odp_cos_create(cosname);
+	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+	sprintf(queuename, "%s", "udp_sport");
+
+	queue = queue_create(queuename, true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	retval = odp_cos_queue_set(cos, queue);
+	CU_ASSERT(retval == 0);
+
+	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+	CU_ASSERT(retval == 0);
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == queue);
+	odp_packet_free(pkt);
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+	udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == defqueue);
+	odp_packet_free(pkt);
+
+	odp_cos_destroy(cos);
+	odp_pmr_destroy(pmr);
+	destroy_inq(pktio);
+	odp_queue_destroy(queue);
+	odp_pktio_close(pktio);
+}
+
+static void classification_test_pmr_term_ipproto(void)
+{
+	odp_packet_t pkt;
+	uint32_t seqno;
+	uint8_t val;
+	uint8_t mask;
+	int retval;
+	odp_pktio_t pktio;
+	odp_queue_t queue;
+	odp_queue_t retqueue;
+	odp_queue_t defqueue;
+	odp_pmr_t pmr;
+	odp_cos_t cos;
+	char cosname[ODP_QUEUE_NAME_LEN];
+	char queuename[ODP_QUEUE_NAME_LEN];
+
+	val = ODPH_IPPROTO_UDP;
+	mask = 0xff;
+	seqno = 0;
+
+	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+	pmr = odp_pmr_create(ODP_PMR_IPPROTO, &val,
+			     &mask, sizeof(val));
+	CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+	sprintf(cosname, "ipproto");
+	cos = odp_cos_create(cosname);
+	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+	sprintf(queuename, "%s", "ipproto");
+
+	queue = queue_create(queuename, true);
+	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+	retval = odp_cos_queue_set(cos, queue);
+	CU_ASSERT(retval == 0);
+
+	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+	CU_ASSERT(retval == 0);
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(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(pool_default, false, &seq, false);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	enqueue_pktio_interface(pkt, pktio);
+
+	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
+	CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+	CU_ASSERT(retqueue == defqueue);
+
+	odp_cos_destroy(cos);
+	odp_pmr_destroy(pmr);
+	odp_packet_free(pkt);
+	destroy_inq(pktio);
+	odp_queue_destroy(queue);
+	odp_pktio_close(pktio);
+}
+
+CU_TestInfo classification_suite_pmr[] = {
+	_CU_TEST_INFO(classification_test_pmr_term_tcp_dport),
+	_CU_TEST_INFO(classification_test_pmr_term_tcp_sport),
+	_CU_TEST_INFO(classification_test_pmr_term_udp_dport),
+	_CU_TEST_INFO(classification_test_pmr_term_udp_sport),
+	_CU_TEST_INFO(classification_test_pmr_term_ipproto),
+	CU_TEST_INFO_NULL,
+};
diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c
index 0fb624d..8a60e5e 100644
--- a/test/validation/classification/odp_classification_tests.c
+++ b/test/validation/classification/odp_classification_tests.c
@@ -11,50 +11,6 @@ 
 #include <odp/helper/ip.h>
 #include <odp/helper/udp.h>
 
-#define SHM_PKT_NUM_BUFS        32
-#define SHM_PKT_BUF_SIZE        1024
-
-/* Config values for Default CoS */
-#define TEST_DEFAULT		1
-#define	CLS_DEFAULT		0
-#define CLS_DEFAULT_SADDR	"10.0.0.1/32"
-#define CLS_DEFAULT_DADDR	"10.0.0.100/32"
-#define CLS_DEFAULT_SPORT	1024
-#define CLS_DEFAULT_DPORT	2048
-
-/* Config values for Error CoS */
-#define TEST_ERROR		1
-#define CLS_ERROR		1
-
-/* Config values for PMR_CHAIN */
-#define TEST_PMR_CHAIN		1
-#define CLS_PMR_CHAIN_SRC	2
-#define CLS_PMR_CHAIN_DST	3
-#define CLS_PMR_CHAIN_SADDR	"10.0.0.5/32"
-#define CLS_PMR_CHAIN_SPORT	3000
-
-/* Config values for PMR */
-#define TEST_PMR		1
-#define CLS_PMR			4
-#define CLS_PMR_SPORT		4000
-
-/* Config values for PMR SET */
-#define TEST_PMR_SET		1
-#define CLS_PMR_SET		5
-#define CLS_PMR_SET_SADDR	"10.0.0.6/32"
-#define CLS_PMR_SET_SPORT	5000
-
-/* Config values for CoS L2 Priority */
-#define TEST_L2_QOS		1
-#define CLS_L2_QOS_0		6
-#define CLS_L2_QOS_MAX		5
-
-#define CLS_ENTRIES		(CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
-
-/* Test Packet values */
-#define DATA_MAGIC		0x01020304
-#define TEST_SEQ_INVALID	((uint32_t)~0)
-
 static odp_cos_t cos_list[CLS_ENTRIES];
 static odp_pmr_t pmr_list[CLS_ENTRIES];
 static odp_queue_t queue_list[CLS_ENTRIES];
@@ -66,99 +22,6 @@  static odp_pktio_t pktio_loop;
 /** sequence number of IP packets */
 odp_atomic_u32_t seq;
 
-typedef struct cls_test_packet {
-	uint32be_t magic;
-	uint32be_t seq;
-} cls_test_packet_t;
-
-static inline
-int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t *mask)
-{
-	int b[4];
-	int qualifier = 32;
-	int converted;
-
-	if (strchr(ipaddress, '/')) {
-		converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
-				&b[3], &b[2], &b[1], &b[0],
-				&qualifier);
-		if (5 != converted)
-			return -1;
-	} else {
-		converted = sscanf(ipaddress, "%d.%d.%d.%d",
-				&b[3], &b[2], &b[1], &b[0]);
-		if (4 != converted)
-			return -1;
-	}
-
-	if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
-		return -1;
-	if (!qualifier || (qualifier > 32))
-		return -1;
-
-	*addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
-	if (mask)
-		*mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
-
-	return 0;
-}
-
-static inline
-void enqueue_loop_interface(odp_packet_t pkt)
-{
-	odp_event_t ev;
-	odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
-
-	ev = odp_packet_to_event(pkt);
-	if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
-		odp_packet_free(pkt);
-}
-
-static inline
-odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
-{
-	odp_event_t ev;
-
-	ev = odp_schedule(queue, ns);
-	return odp_packet_from_event(ev);
-}
-
-static int cls_pkt_set_seq(odp_packet_t pkt)
-{
-	static uint32_t seq;
-	cls_test_packet_t data;
-	uint32_t offset;
-	int status;
-
-	data.magic = DATA_MAGIC;
-	data.seq = ++seq;
-
-	offset = odp_packet_l4_offset(pkt);
-	CU_ASSERT_FATAL(offset != 0);
-
-	status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
-					sizeof(data), &data);
-
-	return status;
-}
-
-static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
-{
-	uint32_t offset;
-	cls_test_packet_t data;
-
-	offset = odp_packet_l4_offset(pkt);
-	if (offset) {
-		odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
-					sizeof(data), &data);
-
-		if (data.magic == DATA_MAGIC)
-			return data.seq;
-	}
-
-	return TEST_SEQ_INVALID;
-}
-
 static int destroy_inq(odp_pktio_t pktio)
 {
 	odp_queue_t inq;
@@ -185,93 +48,9 @@  static int destroy_inq(odp_pktio_t pktio)
 
 	return odp_queue_destroy(inq);
 }
-odp_packet_t create_packet(bool vlan)
-{
-	uint32_t seqno;
-	odph_ethhdr_t *ethhdr;
-	odph_udphdr_t *udp;
-	odph_ipv4hdr_t *ip;
-	uint8_t payload_len;
-	char src_mac[ODPH_ETHADDR_LEN]  = {0};
-	char dst_mac[ODPH_ETHADDR_LEN] = {0};
-	uint32_t addr = 0;
-	uint32_t mask;
-	int offset;
-	odp_packet_t pkt;
-	int packet_len = 0;
-
-	payload_len = sizeof(cls_test_packet_t);
-	packet_len += ODPH_ETHHDR_LEN;
-	packet_len += ODPH_IPV4HDR_LEN;
-	packet_len += ODPH_UDPHDR_LEN;
-	packet_len += payload_len;
-
-	if (vlan)
-		packet_len += ODPH_VLANHDR_LEN;
-
-	pkt = odp_packet_alloc(pool_default, packet_len);
-	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
-
-	/* Ethernet Header */
-	offset = 0;
-	odp_packet_l2_offset_set(pkt, offset);
-	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, ODPH_ETHADDR_LEN);
-	offset += sizeof(odph_ethhdr_t);
-	if (vlan) {
-		/* Default vlan header */
-		uint8_t *parseptr;
-		odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
-		parseptr = (uint8_t *)vlan;
-		vlan->tci = odp_cpu_to_be_16(0);
-		vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
-		offset += sizeof(odph_vlanhdr_t);
-		parseptr += sizeof(odph_vlanhdr_t);
-		uint16be_t *type = (uint16be_t *)(void *)parseptr;
-		*type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
-	} else {
-		ethhdr->type =	odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
-	}
-
-	odp_packet_l3_offset_set(pkt, offset);
-
-	/* ipv4 */
-	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
-
-	parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
-	ip->dst_addr = odp_cpu_to_be_32(addr);
-
-	parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
-	ip->src_addr = odp_cpu_to_be_32(addr);
-	ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
-	ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
-			ODPH_IPV4HDR_LEN);
-	ip->ttl = 128;
-	ip->proto = ODPH_IPPROTO_UDP;
-	seqno = odp_atomic_fetch_inc_u32(&seq);
-	ip->id = odp_cpu_to_be_16(seqno);
-	ip->chksum = 0;
-	ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
-	offset += ODPH_IPV4HDR_LEN;
-
-	/* udp */
-	odp_packet_l4_offset_set(pkt, offset);
-	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
-	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);
-	udp->chksum = 0;
-
-	/* set pkt sequence number */
-	cls_pkt_set_seq(pkt);
-
-	return pkt;
-}
 
 int classification_suite_init(void)
 {
-	odp_pool_t pool;
 	odp_pool_param_t param;
 	odp_queue_t inq_def;
 	odp_queue_param_t qparam;
@@ -286,16 +65,12 @@  int classification_suite_init(void)
 	param.pkt.num     = SHM_PKT_NUM_BUFS;
 	param.type        = ODP_POOL_PACKET;
 
-	pool = odp_pool_create("classification_pool", &param);
-	if (ODP_POOL_INVALID == pool) {
+	pool_default = odp_pool_create("classification_pool", &param);
+	if (ODP_POOL_INVALID == pool_default) {
 		fprintf(stderr, "Packet pool creation failed.\n");
 		return -1;
 	}
 
-	pool_default = odp_pool_lookup("classification_pool");
-	if (pool_default == ODP_POOL_INVALID)
-		return -1;
-
 	memset(&pktio_param, 0, sizeof(pktio_param));
 	pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
 
@@ -393,6 +168,7 @@  void configure_cls_pmr_chain(void)
 	qparam.sched.prio = ODP_SCHED_PRIO_NORMAL;
 	qparam.sched.sync = ODP_SCHED_SYNC_NONE;
 	qparam.sched.group = ODP_SCHED_GROUP_ALL;
+	qparam.sched.lock_count = ODP_CONFIG_MAX_ORDERED_LOCKS_PER_QUEUE;
 	sprintf(queuename, "%s", "SrcQueue");
 
 	queue_list[CLS_PMR_CHAIN_SRC] = odp_queue_create(queuename,
@@ -452,10 +228,12 @@  void test_cls_pmr_chain(void)
 	odp_queue_t queue;
 	uint32_t addr = 0;
 	uint32_t mask;
-	uint32_t seq;
+	uint32_t seqno = 0;
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
 
-	pkt = create_packet(false);
-	seq = cls_pkt_get_seq(pkt);
 	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 	parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask);
 	ip->src_addr = odp_cpu_to_be_32(addr);
@@ -465,25 +243,29 @@  void test_cls_pmr_chain(void)
 	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 	udp->src_port = odp_cpu_to_be_16(CLS_PMR_CHAIN_SPORT);
 
-	enqueue_loop_interface(pkt);
+	enqueue_pktio_interface(pkt, pktio_loop);
 
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_DST]);
-	CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 	odp_packet_free(pkt);
 
-	pkt = create_packet(false);
-	seq = cls_pkt_get_seq(pkt);
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
 	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 	parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask);
 	ip->src_addr = odp_cpu_to_be_32(addr);
 	ip->chksum = 0;
 	ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
 
-	enqueue_loop_interface(pkt);
+	enqueue_pktio_interface(pkt, pktio_loop);
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_SRC]);
-	CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 	odp_packet_free(pkt);
 }
 
@@ -519,16 +301,19 @@  void test_pktio_default_cos(void)
 {
 	odp_packet_t pkt;
 	odp_queue_t queue;
-	uint32_t seq;
+	uint32_t seqno = 0;
 	/* create a default packet */
-	pkt = create_packet(false);
-	seq = cls_pkt_get_seq(pkt);
-	enqueue_loop_interface(pkt);
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+	enqueue_pktio_interface(pkt, pktio_loop);
 
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	/* Default packet should be received in default queue */
 	CU_ASSERT(queue == queue_list[CLS_DEFAULT]);
-	CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 
 	odp_packet_free(pkt);
 }
@@ -568,15 +353,16 @@  void test_pktio_error_cos(void)
 	odp_packet_t pkt;
 
 	/*Create an error packet */
-	pkt = create_packet(false);
+	pkt = create_packet(pool_default, false, &seq, true);
 	odph_ipv4hdr_t *ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 
 	/* Incorrect IpV4 version */
 	ip->ver_ihl = 8 << 4 | ODPH_IPV4HDR_IHL_MIN;
 	ip->chksum = 0;
-	enqueue_loop_interface(pkt);
+	enqueue_pktio_interface(pkt, pktio_loop);
 
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	/* Error packet should be received in error queue */
 	CU_ASSERT(queue == queue_list[CLS_ERROR]);
 	odp_packet_free(pkt);
@@ -659,19 +445,21 @@  void test_cos_with_l2_priority(void)
 	odph_ethhdr_t *ethhdr;
 	odph_vlanhdr_t *vlan;
 	odp_queue_t queue;
-	uint32_t seq;
+	uint32_t seqno = 0;
 
 	uint8_t i;
 	for (i = 0; i < CLS_L2_QOS_MAX; i++) {
-		pkt = create_packet(true);
-		seq = cls_pkt_get_seq(pkt);
+		pkt = create_packet(pool_default, true, &seq, true);
+		seqno = cls_pkt_get_seq(pkt);
+		CU_ASSERT(seqno != TEST_SEQ_INVALID);
 		ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
 		vlan = (odph_vlanhdr_t *)(&ethhdr->type);
 		vlan->tci = odp_cpu_to_be_16(i << 13);
-		enqueue_loop_interface(pkt);
+		enqueue_pktio_interface(pkt, pktio_loop);
 		pkt = receive_packet(&queue, ODP_TIME_SEC);
+		CU_ASSERT(pkt != ODP_PACKET_INVALID);
 		CU_ASSERT(queue == queue_list[CLS_L2_QOS_0 + i]);
-		CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+		CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 		odp_packet_free(pkt);
 	}
 }
@@ -720,16 +508,18 @@  void test_pmr_cos(void)
 	odp_packet_t pkt;
 	odph_udphdr_t *udp;
 	odp_queue_t queue;
-	uint32_t seq;
+	uint32_t seqno = 0;
 
-	pkt = create_packet(false);
-	seq = cls_pkt_get_seq(pkt);
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
 	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 	udp->src_port = odp_cpu_to_be_16(CLS_PMR_SPORT);
-	enqueue_loop_interface(pkt);
+	enqueue_pktio_interface(pkt, pktio_loop);
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	CU_ASSERT(queue == queue_list[CLS_PMR]);
-	CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 	odp_packet_free(pkt);
 }
 
@@ -795,10 +585,12 @@  void test_pktio_pmr_match_set_cos(void)
 	odph_udphdr_t *udp;
 	odp_packet_t pkt;
 	odp_queue_t queue;
-	uint32_t seq;
+	uint32_t seqno = 0;
+
+	pkt = create_packet(pool_default, false, &seq, true);
+	seqno = cls_pkt_get_seq(pkt);
+	CU_ASSERT(seqno != TEST_SEQ_INVALID);
 
-	pkt = create_packet(false);
-	seq = cls_pkt_get_seq(pkt);
 	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
 	parse_ipv4_string(CLS_PMR_SET_SADDR, &addr, &mask);
 	ip->src_addr = odp_cpu_to_be_32(addr);
@@ -807,10 +599,11 @@  void test_pktio_pmr_match_set_cos(void)
 
 	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
 	udp->src_port = odp_cpu_to_be_16(CLS_PMR_SET_SPORT);
-	enqueue_loop_interface(pkt);
+	enqueue_pktio_interface(pkt, pktio_loop);
 	pkt = receive_packet(&queue, ODP_TIME_SEC);
+	CU_ASSERT(pkt != ODP_PACKET_INVALID);
 	CU_ASSERT(queue == queue_list[CLS_PMR_SET]);
-	CU_ASSERT(seq == cls_pkt_get_seq(pkt));
+	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
 	odp_packet_free(pkt);
 }
 
diff --git a/test/validation/classification/odp_classification_testsuites.h b/test/validation/classification/odp_classification_testsuites.h
index 37c019d..33547a7 100644
--- a/test/validation/classification/odp_classification_testsuites.h
+++ b/test/validation/classification/odp_classification_testsuites.h
@@ -13,11 +13,24 @@ 
 
 extern CU_TestInfo classification_suite[];
 extern CU_TestInfo classification_suite_basic[];
+extern CU_TestInfo classification_suite_pmr[];
 
 int classification_suite_init(void);
 int classification_suite_term(void);
 
-odp_packet_t create_packet(bool vlan);
+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);
+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_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype);
+int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t *mask);
+void enqueue_pktio_interface(odp_packet_t pkt, odp_pktio_t pktio);
+odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns);
+odp_queue_t queue_create(char *queuename, bool sched);
 void configure_pktio_default_cos(void);
 void test_pktio_default_cos(void);
 void configure_pktio_error_cos(void);