diff mbox

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

Message ID 1443105806-24575-1-git-send-email-bala.manoharan@linaro.org
State New
Headers show

Commit Message

Balasubramanian Manoharan Sept. 24, 2015, 2:43 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>
---
v3: Incorporates review comments from Ivan

 helper/include/odp/helper/tcp.h                    |   1 +
 test/validation/classification/Makefile.am         |   2 +
 test/validation/classification/classification.c    |   5 +
 .../classification/odp_classification_common.c     | 267 ++++++++++
 .../classification/odp_classification_test_pmr.c   | 569 +++++++++++++++++++++
 .../classification/odp_classification_tests.c      | 265 ++--------
 .../classification/odp_classification_testsuites.h |  15 +-
 7 files changed, 909 insertions(+), 215 deletions(-)
 create mode 100644 test/validation/classification/odp_classification_common.c
 create mode 100644 test/validation/classification/odp_classification_test_pmr.c

Comments

Mike Holmes Sept. 30, 2015, 4:04 p.m. UTC | #1
On 24 September 2015 at 10:43, Balasubramanian Manoharan <
bala.manoharan@linaro.org> wrote:

> 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>
>

This does cover the listed bugs, but there are still a lot of untested
related APIs in that header file

Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0 verify_pmr_ipv4_daddr 0
verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x



> ---
> v3: Incorporates review comments from Ivan
>
>  helper/include/odp/helper/tcp.h                    |   1 +
>  test/validation/classification/Makefile.am         |   2 +
>  test/validation/classification/classification.c    |   5 +
>  .../classification/odp_classification_common.c     | 267 ++++++++++
>  .../classification/odp_classification_test_pmr.c   | 569
> +++++++++++++++++++++
>  .../classification/odp_classification_tests.c      | 265 ++--------
>  .../classification/odp_classification_testsuites.h |  15 +-
>  7 files changed, 909 insertions(+), 215 deletions(-)
>  create mode 100644
> test/validation/classification/odp_classification_common.c
>  create mode 100644
> test/validation/classification/odp_classification_test_pmr.c
>
> 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/odp_classification_common.c
> b/test/validation/classification/odp_classification_common.c
> new file mode 100644
> index 0000000..9b05ad6
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_common.c
> @@ -0,0 +1,267 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.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>
> +
> +#define SHM_PKT_NUM_BUFS        32
> +#define SHM_PKT_BUF_SIZE        1024
> +
> +#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
> +
> +#define CLS_TEST_SPORT         4096
> +#define CLS_TEST_DPORT         8192
> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> +
> +/* Test Packet values */
> +#define DATA_MAGIC             0x01020304
> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> +
> +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..b90af22
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_test_pmr.c
> @@ -0,0 +1,569 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.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>
> +
> +#define SHM_PKT_NUM_BUFS        32
>
Also set in the common and tests file - same for many other defines -
should they be in .h file ?


> +#define SHM_PKT_BUF_SIZE        1024
> +
> +#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
> +
> +#define CLS_TEST_SPORT         4096
> +#define CLS_TEST_DPORT         8192
> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> +
> +/* Test Packet values */
> +#define DATA_MAGIC             0x01020304
> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> +
> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
> --- a/test/validation/classification/odp_classification_tests.c
> +++ b/test/validation/classification/odp_classification_tests.c
> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
> @@ -451,10 +271,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);
> @@ -464,25 +286,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);
>  }
>
> @@ -518,16 +344,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);
>  }
> @@ -567,15 +396,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);
> @@ -658,19 +488,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);
>         }
>  }
> @@ -719,16 +551,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);
>  }
>
> @@ -794,10 +628,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);
> @@ -806,10 +642,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);
> --
> 1.9.1
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
>
Balasubramanian Manoharan Oct. 1, 2015, 7:05 a.m. UTC | #2
On 30 September 2015 at 21:34, Mike Holmes <mike.holmes@linaro.org> wrote:
>
>
> On 24 September 2015 at 10:43, Balasubramanian Manoharan
> <bala.manoharan@linaro.org> wrote:
>>
>> 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>
>
>
> This does cover the listed bugs, but there are still a lot of untested
> related APIs in that header file
>
> Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
> verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0 verify_pmr_ipv4_daddr 0
> verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
> verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x

Once the test suite module is added onto the repo it supports modular
addition of individual test cases and these missing APIs can be added
as individual patches.

Regards,
Bala
>
>
>>
>> ---
>> v3: Incorporates review comments from Ivan
>>
>>  helper/include/odp/helper/tcp.h                    |   1 +
>>  test/validation/classification/Makefile.am         |   2 +
>>  test/validation/classification/classification.c    |   5 +
>>  .../classification/odp_classification_common.c     | 267 ++++++++++
>>  .../classification/odp_classification_test_pmr.c   | 569
>> +++++++++++++++++++++
>>  .../classification/odp_classification_tests.c      | 265 ++--------
>>  .../classification/odp_classification_testsuites.h |  15 +-
>>  7 files changed, 909 insertions(+), 215 deletions(-)
>>  create mode 100644
>> test/validation/classification/odp_classification_common.c
>>  create mode 100644
>> test/validation/classification/odp_classification_test_pmr.c
>>
>> 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/odp_classification_common.c
>> b/test/validation/classification/odp_classification_common.c
>> new file mode 100644
>> index 0000000..9b05ad6
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_common.c
>> @@ -0,0 +1,267 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.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>
>> +
>> +#define SHM_PKT_NUM_BUFS        32
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +#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
>> +
>> +#define CLS_TEST_SPORT         4096
>> +#define CLS_TEST_DPORT         8192
>> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>> +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..b90af22
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>> @@ -0,0 +1,569 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.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>
>> +
>> +#define SHM_PKT_NUM_BUFS        32
>
> Also set in the common and tests file - same for many other defines - should
> they be in .h file ?
>
>>
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +#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
>> +
>> +#define CLS_TEST_SPORT         4096
>> +#define CLS_TEST_DPORT         8192
>> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
>> --- a/test/validation/classification/odp_classification_tests.c
>> +++ b/test/validation/classification/odp_classification_tests.c
>> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
>> @@ -451,10 +271,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);
>> @@ -464,25 +286,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);
>>  }
>>
>> @@ -518,16 +344,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);
>>  }
>> @@ -567,15 +396,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);
>> @@ -658,19 +488,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);
>>         }
>>  }
>> @@ -719,16 +551,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);
>>  }
>>
>> @@ -794,10 +628,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);
>> @@ -806,10 +642,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);
>> --
>> 1.9.1
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
>
>
>
>
> --
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org │ Open source software for ARM SoCs
>
>
Mike Holmes Oct. 1, 2015, 2:43 p.m. UTC | #3
Thanks - I added a bug for each case

On 1 October 2015 at 03:05, Bala Manoharan <bala.manoharan@linaro.org>
wrote:

> On 30 September 2015 at 21:34, Mike Holmes <mike.holmes@linaro.org> wrote:
> >
> >
> > On 24 September 2015 at 10:43, Balasubramanian Manoharan
> > <bala.manoharan@linaro.org> wrote:
> >>
> >> 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>
> >
> >
> > This does cover the listed bugs, but there are still a lot of untested
> > related APIs in that header file
> >
> > Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
> > verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0 verify_pmr_ipv4_daddr 0
> > verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
> > verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x
>
> Once the test suite module is added onto the repo it supports modular
> addition of individual test cases and these missing APIs can be added
> as individual patches.
>
> Regards,
> Bala
> >
> >
> >>
> >> ---
> >> v3: Incorporates review comments from Ivan
> >>
> >>  helper/include/odp/helper/tcp.h                    |   1 +
> >>  test/validation/classification/Makefile.am         |   2 +
> >>  test/validation/classification/classification.c    |   5 +
> >>  .../classification/odp_classification_common.c     | 267 ++++++++++
> >>  .../classification/odp_classification_test_pmr.c   | 569
> >> +++++++++++++++++++++
> >>  .../classification/odp_classification_tests.c      | 265 ++--------
> >>  .../classification/odp_classification_testsuites.h |  15 +-
> >>  7 files changed, 909 insertions(+), 215 deletions(-)
> >>  create mode 100644
> >> test/validation/classification/odp_classification_common.c
> >>  create mode 100644
> >> test/validation/classification/odp_classification_test_pmr.c
> >>
> >> 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/odp_classification_common.c
> >> b/test/validation/classification/odp_classification_common.c
> >> new file mode 100644
> >> index 0000000..9b05ad6
> >> --- /dev/null
> >> +++ b/test/validation/classification/odp_classification_common.c
> >> @@ -0,0 +1,267 @@
> >> +/* Copyright (c) 2015, Linaro Limited
> >> + * All rights reserved.
> >> + *
> >> + * SPDX-License-Identifier:    BSD-3-Clause
> >> + */
> >> +
> >> +#include "odp_classification_testsuites.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>
> >> +
> >> +#define SHM_PKT_NUM_BUFS        32
> >> +#define SHM_PKT_BUF_SIZE        1024
> >> +
> >> +#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
> >> +
> >> +#define CLS_TEST_SPORT         4096
> >> +#define CLS_TEST_DPORT         8192
> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> >> +
> >> +/* Test Packet values */
> >> +#define DATA_MAGIC             0x01020304
> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> >> +
> >> +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..b90af22
> >> --- /dev/null
> >> +++ b/test/validation/classification/odp_classification_test_pmr.c
> >> @@ -0,0 +1,569 @@
> >> +/* Copyright (c) 2015, Linaro Limited
> >> + * All rights reserved.
> >> + *
> >> + * SPDX-License-Identifier:    BSD-3-Clause
> >> + */
> >> +
> >> +#include "odp_classification_testsuites.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>
> >> +
> >> +#define SHM_PKT_NUM_BUFS        32
> >
> > Also set in the common and tests file - same for many other defines -
> should
> > they be in .h file ?
> >
> >>
> >> +#define SHM_PKT_BUF_SIZE        1024
> >> +
> >> +#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
> >> +
> >> +#define CLS_TEST_SPORT         4096
> >> +#define CLS_TEST_DPORT         8192
> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> >> +
> >> +/* Test Packet values */
> >> +#define DATA_MAGIC             0x01020304
> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> >> +
> >> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
> >> --- a/test/validation/classification/odp_classification_tests.c
> >> +++ b/test/validation/classification/odp_classification_tests.c
> >> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
> >> @@ -451,10 +271,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);
> >> @@ -464,25 +286,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);
> >>  }
> >>
> >> @@ -518,16 +344,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);
> >>  }
> >> @@ -567,15 +396,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);
> >> @@ -658,19 +488,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);
> >>         }
> >>  }
> >> @@ -719,16 +551,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);
> >>  }
> >>
> >> @@ -794,10 +628,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);
> >> @@ -806,10 +642,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);
> >> --
> >> 1.9.1
> >>
> >> _______________________________________________
> >> lng-odp mailing list
> >> lng-odp@lists.linaro.org
> >> https://lists.linaro.org/mailman/listinfo/lng-odp
> >
> >
> >
> >
> > --
> > Mike Holmes
> > Technical Manager - Linaro Networking Group
> > Linaro.org │ Open source software for ARM SoCs
> >
> >
>
Balasubramanian Manoharan Oct. 6, 2015, 10:51 a.m. UTC | #4
Ping.

On Thursday 01 October 2015 08:13 PM, Mike Holmes wrote:
> Thanks - I added a bug for each case
>
> On 1 October 2015 at 03:05, Bala Manoharan <bala.manoharan@linaro.org 
> <mailto:bala.manoharan@linaro.org>> wrote:
>
>     On 30 September 2015 at 21:34, Mike Holmes <mike.holmes@linaro.org
>     <mailto:mike.holmes@linaro.org>> wrote:
>     >
>     >
>     > On 24 September 2015 at 10:43, Balasubramanian Manoharan
>     > <bala.manoharan@linaro.org <mailto:bala.manoharan@linaro.org>>
>     wrote:
>     >>
>     >> 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 <mailto:bala.manoharan@linaro.org>>
>     >
>     >
>     > This does cover the listed bugs, but there are still a lot of
>     untested
>     > related APIs in that header file
>     >
>     > Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
>     > verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0
>     verify_pmr_ipv4_daddr 0
>     > verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
>     > verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x
>
>     Once the test suite module is added onto the repo it supports modular
>     addition of individual test cases and these missing APIs can be added
>     as individual patches.
>
>     Regards,
>     Bala
>     >
>     >
>     >>
>     >> ---
>     >> v3: Incorporates review comments from Ivan
>     >>
>     >>  helper/include/odp/helper/tcp.h     |   1 +
>     >>  test/validation/classification/Makefile.am      |   2 +
>     >> test/validation/classification/classification.c    |   5 +
>     >> .../classification/odp_classification_common.c     | 267 ++++++++++
>     >> .../classification/odp_classification_test_pmr.c   | 569
>     >> +++++++++++++++++++++
>     >>  .../classification/odp_classification_tests.c     | 265 ++--------
>     >> .../classification/odp_classification_testsuites.h |  15 +-
>     >>  7 files changed, 909 insertions(+), 215 deletions(-)
>     >>  create mode 100644
>     >> test/validation/classification/odp_classification_common.c
>     >>  create mode 100644
>     >> test/validation/classification/odp_classification_test_pmr.c
>     >>
>     >> 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
>     <http://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/odp_classification_common.c
>     >> b/test/validation/classification/odp_classification_common.c
>     >> new file mode 100644
>     >> index 0000000..9b05ad6
>     >> --- /dev/null
>     >> +++ b/test/validation/classification/odp_classification_common.c
>     >> @@ -0,0 +1,267 @@
>     >> +/* Copyright (c) 2015, Linaro Limited
>     >> + * All rights reserved.
>     >> + *
>     >> + * SPDX-License-Identifier:    BSD-3-Clause
>     >> + */
>     >> +
>     >> +#include "odp_classification_testsuites.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>
>     >> +
>     >> +#define SHM_PKT_NUM_BUFS        32
>     >> +#define SHM_PKT_BUF_SIZE        1024
>     >> +
>     >> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32 <http://10.0.0.1/32>"
>     >> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32
>     <http://10.0.0.100/32>"
>     >> +#define CLS_DEFAULT_SPORT      1024
>     >> +#define CLS_DEFAULT_DPORT      2048
>     >> +
>     >> +#define CLS_TEST_SPORT         4096
>     >> +#define CLS_TEST_DPORT         8192
>     >> +#define CLS_TEST_DADDR         "10.0.0.5/32 <http://10.0.0.5/32>"
>     >> +
>     >> +/* Test Packet values */
>     >> +#define DATA_MAGIC             0x01020304
>     >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>     >> +
>     >> +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..b90af22
>     >> --- /dev/null
>     >> +++ b/test/validation/classification/odp_classification_test_pmr.c
>     >> @@ -0,0 +1,569 @@
>     >> +/* Copyright (c) 2015, Linaro Limited
>     >> + * All rights reserved.
>     >> + *
>     >> + * SPDX-License-Identifier:    BSD-3-Clause
>     >> + */
>     >> +
>     >> +#include "odp_classification_testsuites.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>
>     >> +
>     >> +#define SHM_PKT_NUM_BUFS        32
>     >
>     > Also set in the common and tests file - same for many other
>     defines - should
>     > they be in .h file ?
>     >
>     >>
>     >> +#define SHM_PKT_BUF_SIZE        1024
>     >> +
>     >> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32 <http://10.0.0.1/32>"
>     >> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32
>     <http://10.0.0.100/32>"
>     >> +#define CLS_DEFAULT_SPORT      1024
>     >> +#define CLS_DEFAULT_DPORT      2048
>     >> +
>     >> +#define CLS_TEST_SPORT         4096
>     >> +#define CLS_TEST_DPORT         8192
>     >> +#define CLS_TEST_DADDR         "10.0.0.5/32 <http://10.0.0.5/32>"
>     >> +
>     >> +/* Test Packet values */
>     >> +#define DATA_MAGIC             0x01020304
>     >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>     >> +
>     >> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
>     >> --- a/test/validation/classification/odp_classification_tests.c
>     >> +++ b/test/validation/classification/odp_classification_tests.c
>     >> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
>     >> @@ -451,10 +271,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);
>     >> @@ -464,25 +286,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);
>     >>  }
>     >>
>     >> @@ -518,16 +344,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);
>     >>  }
>     >> @@ -567,15 +396,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);
>     >> @@ -658,19 +488,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);
>     >>         }
>     >>  }
>     >> @@ -719,16 +551,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);
>     >>  }
>     >>
>     >> @@ -794,10 +628,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);
>     >> @@ -806,10 +642,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);
>     >> --
>     >> 1.9.1
>     >>
>     >> _______________________________________________
>     >> lng-odp mailing list
>     >> lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>
>     >> https://lists.linaro.org/mailman/listinfo/lng-odp
>     >
>     >
>     >
>     >
>     > --
>     > Mike Holmes
>     > Technical Manager - Linaro Networking Group
>     > Linaro.org │ Open source software for ARM SoCs
>     >
>     >
>
>
>
>
> -- 
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs
>
Mike Holmes Oct. 6, 2015, 11:05 a.m. UTC | #5
I might have missed the answer, but many of the #defines are repeated
between the files, should they be in a shared headder

On 6 October 2015 at 11:51, Balasubramanian Manoharan <
bala.manoharan@linaro.org> wrote:

> Ping.
>
> On Thursday 01 October 2015 08:13 PM, Mike Holmes wrote:
>
> Thanks - I added a bug for each case
>
> On 1 October 2015 at 03:05, Bala Manoharan <bala.manoharan@linaro.org>
> wrote:
>
>> On 30 September 2015 at 21:34, Mike Holmes < <mike.holmes@linaro.org>
>> mike.holmes@linaro.org> wrote:
>> >
>> >
>> > On 24 September 2015 at 10:43, Balasubramanian Manoharan
>> > <bala.manoharan@linaro.org> wrote:
>> >>
>> >> 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>
>> bala.manoharan@linaro.org>
>> >
>> >
>> > This does cover the listed bugs, but there are still a lot of untested
>> > related APIs in that header file
>> >
>> > Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
>> > verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0 verify_pmr_ipv4_daddr 0
>> > verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
>> > verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x
>>
>> Once the test suite module is added onto the repo it supports modular
>> addition of individual test cases and these missing APIs can be added
>> as individual patches.
>>
>> Regards,
>> Bala
>> >
>> >
>> >>
>> >> ---
>> >> v3: Incorporates review comments from Ivan
>> >>
>> >>  helper/include/odp/helper/tcp.h                    |   1 +
>> >>  test/validation/classification/Makefile.am         |   2 +
>> >>  test/validation/classification/classification.c    |   5 +
>> >>  .../classification/odp_classification_common.c     | 267 ++++++++++
>> >>  .../classification/odp_classification_test_pmr.c   | 569
>> >> +++++++++++++++++++++
>> >>  .../classification/odp_classification_tests.c      | 265 ++--------
>> >>  .../classification/odp_classification_testsuites.h |  15 +-
>> >>  7 files changed, 909 insertions(+), 215 deletions(-)
>> >>  create mode 100644
>> >> test/validation/classification/odp_classification_common.c
>> >>  create mode 100644
>> >> test/validation/classification/odp_classification_test_pmr.c
>> >>
>> >> 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/odp_classification_common.c
>> >> b/test/validation/classification/odp_classification_common.c
>> >> new file mode 100644
>> >> index 0000000..9b05ad6
>> >> --- /dev/null
>> >> +++ b/test/validation/classification/odp_classification_common.c
>> >> @@ -0,0 +1,267 @@
>> >> +/* Copyright (c) 2015, Linaro Limited
>> >> + * All rights reserved.
>> >> + *
>> >> + * SPDX-License-Identifier:    BSD-3-Clause
>> >> + */
>> >> +
>> >> +#include "odp_classification_testsuites.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>
>> >> +
>> >> +#define SHM_PKT_NUM_BUFS        32
>> >> +#define SHM_PKT_BUF_SIZE        1024
>> >> +
>> >> +#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
>> >> +
>> >> +#define CLS_TEST_SPORT         4096
>> >> +#define CLS_TEST_DPORT         8192
>> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> >> +
>> >> +/* Test Packet values */
>> >> +#define DATA_MAGIC             0x01020304
>> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> >> +
>> >> +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..b90af22
>> >> --- /dev/null
>> >> +++ b/test/validation/classification/odp_classification_test_pmr.c
>> >> @@ -0,0 +1,569 @@
>> >> +/* Copyright (c) 2015, Linaro Limited
>> >> + * All rights reserved.
>> >> + *
>> >> + * SPDX-License-Identifier:    BSD-3-Clause
>> >> + */
>> >> +
>> >> +#include "odp_classification_testsuites.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>
>> >> +
>> >> +#define SHM_PKT_NUM_BUFS        32
>> >
>> > Also set in the common and tests file - same for many other defines -
>> should
>> > they be in .h file ?
>> >
>> >>
>> >> +#define SHM_PKT_BUF_SIZE        1024
>> >> +
>> >> +#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
>> >> +
>> >> +#define CLS_TEST_SPORT         4096
>> >> +#define CLS_TEST_DPORT         8192
>> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> >> +
>> >> +/* Test Packet values */
>> >> +#define DATA_MAGIC             0x01020304
>> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> >> +
>> >> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
>> >> --- a/test/validation/classification/odp_classification_tests.c
>> >> +++ b/test/validation/classification/odp_classification_tests.c
>> >> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
>> >> @@ -451,10 +271,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);
>> >> @@ -464,25 +286,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);
>> >>  }
>> >>
>> >> @@ -518,16 +344,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);
>> >>  }
>> >> @@ -567,15 +396,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);
>> >> @@ -658,19 +488,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);
>> >>         }
>> >>  }
>> >> @@ -719,16 +551,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);
>> >>  }
>> >>
>> >> @@ -794,10 +628,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);
>> >> @@ -806,10 +642,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);
>> >> --
>> >> 1.9.1
>> >>
>> >> _______________________________________________
>> >> lng-odp mailing list
>> >> lng-odp@lists.linaro.org
>> >> https://lists.linaro.org/mailman/listinfo/lng-odp
>> >
>> >
>> >
>> >
>> > --
>> > Mike Holmes
>> > Technical Manager - Linaro Networking Group
>> > Linaro.org │ Open source software for ARM SoCs
>> >
>> >
>>
>
>
>
> --
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
>
>
>
Balasubramanian Manoharan Oct. 7, 2015, 12:50 p.m. UTC | #6
Hi Mike,

I have fixed this in the latest patch.

Regards,
Bala

On 6 October 2015 at 16:35, Mike Holmes <mike.holmes@linaro.org> wrote:
> I might have missed the answer, but many of the #defines are repeated
> between the files, should they be in a shared headder
>
> On 6 October 2015 at 11:51, Balasubramanian Manoharan
> <bala.manoharan@linaro.org> wrote:
>>
>> Ping.
>>
>> On Thursday 01 October 2015 08:13 PM, Mike Holmes wrote:
>>
>> Thanks - I added a bug for each case
>>
>> On 1 October 2015 at 03:05, Bala Manoharan <bala.manoharan@linaro.org>
>> wrote:
>>>
>>> On 30 September 2015 at 21:34, Mike Holmes <mike.holmes@linaro.org>
>>> wrote:
>>> >
>>> >
>>> > On 24 September 2015 at 10:43, Balasubramanian Manoharan
>>> > <bala.manoharan@linaro.org> wrote:
>>> >>
>>> >> 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>
>>> >
>>> >
>>> > This does cover the listed bugs, but there are still a lot of untested
>>> > related APIs in that header file
>>> >
>>> > Function Name Hit count verify_pmr_dmac 0 verify_pmr_eth_type_0 0
>>> > verify_pmr_eth_type_x 0 verify_pmr_ipsec_spi 0 verify_pmr_ipv4_daddr 0
>>> > verify_pmr_ipv6_daddr 0 verify_pmr_ipv6_saddr 0 verify_pmr_ld_vni 0
>>> > verify_pmr_packet_len 0 verify_pmr_vlan_id_0 0 verify_pmr_vlan_id_x
>>>
>>> Once the test suite module is added onto the repo it supports modular
>>> addition of individual test cases and these missing APIs can be added
>>> as individual patches.
>>>
>>> Regards,
>>> Bala
>>> >
>>> >
>>> >>
>>> >> ---
>>> >> v3: Incorporates review comments from Ivan
>>> >>
>>> >>  helper/include/odp/helper/tcp.h                    |   1 +
>>> >>  test/validation/classification/Makefile.am         |   2 +
>>> >>  test/validation/classification/classification.c    |   5 +
>>> >>  .../classification/odp_classification_common.c     | 267 ++++++++++
>>> >>  .../classification/odp_classification_test_pmr.c   | 569
>>> >> +++++++++++++++++++++
>>> >>  .../classification/odp_classification_tests.c      | 265 ++--------
>>> >>  .../classification/odp_classification_testsuites.h |  15 +-
>>> >>  7 files changed, 909 insertions(+), 215 deletions(-)
>>> >>  create mode 100644
>>> >> test/validation/classification/odp_classification_common.c
>>> >>  create mode 100644
>>> >> test/validation/classification/odp_classification_test_pmr.c
>>> >>
>>> >> 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/odp_classification_common.c
>>> >> b/test/validation/classification/odp_classification_common.c
>>> >> new file mode 100644
>>> >> index 0000000..9b05ad6
>>> >> --- /dev/null
>>> >> +++ b/test/validation/classification/odp_classification_common.c
>>> >> @@ -0,0 +1,267 @@
>>> >> +/* Copyright (c) 2015, Linaro Limited
>>> >> + * All rights reserved.
>>> >> + *
>>> >> + * SPDX-License-Identifier:    BSD-3-Clause
>>> >> + */
>>> >> +
>>> >> +#include "odp_classification_testsuites.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>
>>> >> +
>>> >> +#define SHM_PKT_NUM_BUFS        32
>>> >> +#define SHM_PKT_BUF_SIZE        1024
>>> >> +
>>> >> +#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
>>> >> +
>>> >> +#define CLS_TEST_SPORT         4096
>>> >> +#define CLS_TEST_DPORT         8192
>>> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>>> >> +
>>> >> +/* Test Packet values */
>>> >> +#define DATA_MAGIC             0x01020304
>>> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> >> +
>>> >> +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..b90af22
>>> >> --- /dev/null
>>> >> +++ b/test/validation/classification/odp_classification_test_pmr.c
>>> >> @@ -0,0 +1,569 @@
>>> >> +/* Copyright (c) 2015, Linaro Limited
>>> >> + * All rights reserved.
>>> >> + *
>>> >> + * SPDX-License-Identifier:    BSD-3-Clause
>>> >> + */
>>> >> +
>>> >> +#include "odp_classification_testsuites.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>
>>> >> +
>>> >> +#define SHM_PKT_NUM_BUFS        32
>>> >
>>> > Also set in the common and tests file - same for many other defines -
>>> > should
>>> > they be in .h file ?
>>> >
>>> >>
>>> >> +#define SHM_PKT_BUF_SIZE        1024
>>> >> +
>>> >> +#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
>>> >> +
>>> >> +#define CLS_TEST_SPORT         4096
>>> >> +#define CLS_TEST_DPORT         8192
>>> >> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>>> >> +
>>> >> +/* Test Packet values */
>>> >> +#define DATA_MAGIC             0x01020304
>>> >> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> >> +
>>> >> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
>>> >> --- a/test/validation/classification/odp_classification_tests.c
>>> >> +++ b/test/validation/classification/odp_classification_tests.c
>>> >> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
>>> >> @@ -451,10 +271,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);
>>> >> @@ -464,25 +286,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);
>>> >>  }
>>> >>
>>> >> @@ -518,16 +344,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);
>>> >>  }
>>> >> @@ -567,15 +396,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);
>>> >> @@ -658,19 +488,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);
>>> >>         }
>>> >>  }
>>> >> @@ -719,16 +551,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);
>>> >>  }
>>> >>
>>> >> @@ -794,10 +628,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);
>>> >> @@ -806,10 +642,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);
>>> >> --
>>> >> 1.9.1
>>> >>
>>> >> _______________________________________________
>>> >> lng-odp mailing list
>>> >> lng-odp@lists.linaro.org
>>> >> https://lists.linaro.org/mailman/listinfo/lng-odp
>>> >
>>> >
>>> >
>>> >
>>> > --
>>> > Mike Holmes
>>> > Technical Manager - Linaro Networking Group
>>> > Linaro.org │ Open source software for ARM SoCs
>>> >
>>> >
>>
>>
>>
>>
>> --
>> Mike Holmes
>> Technical Manager - Linaro Networking Group
>> Linaro.org │ Open source software for ARM SoCs
>>
>>
>
>
>
> --
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org │ Open source software for ARM SoCs
>
>
Mike Holmes Oct. 14, 2015, 8:19 p.m. UTC | #7
On 24 September 2015 at 10:43, Balasubramanian Manoharan <
bala.manoharan@linaro.org> wrote:

> 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>
>

Reviewed-by: Mike Holmes <mike.holmes@linaro.org>


> ---
> v3: Incorporates review comments from Ivan
>
>  helper/include/odp/helper/tcp.h                    |   1 +
>  test/validation/classification/Makefile.am         |   2 +
>  test/validation/classification/classification.c    |   5 +
>  .../classification/odp_classification_common.c     | 267 ++++++++++
>  .../classification/odp_classification_test_pmr.c   | 569
> +++++++++++++++++++++
>  .../classification/odp_classification_tests.c      | 265 ++--------
>  .../classification/odp_classification_testsuites.h |  15 +-
>  7 files changed, 909 insertions(+), 215 deletions(-)
>  create mode 100644
> test/validation/classification/odp_classification_common.c
>  create mode 100644
> test/validation/classification/odp_classification_test_pmr.c
>
> 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/odp_classification_common.c
> b/test/validation/classification/odp_classification_common.c
> new file mode 100644
> index 0000000..9b05ad6
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_common.c
> @@ -0,0 +1,267 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.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>
> +
> +#define SHM_PKT_NUM_BUFS        32
> +#define SHM_PKT_BUF_SIZE        1024
> +
> +#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
> +
> +#define CLS_TEST_SPORT         4096
> +#define CLS_TEST_DPORT         8192
> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> +
> +/* Test Packet values */
> +#define DATA_MAGIC             0x01020304
> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> +
> +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..b90af22
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_test_pmr.c
> @@ -0,0 +1,569 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.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>
> +
> +#define SHM_PKT_NUM_BUFS        32
> +#define SHM_PKT_BUF_SIZE        1024
> +
> +#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
> +
> +#define CLS_TEST_SPORT         4096
> +#define CLS_TEST_DPORT         8192
> +#define CLS_TEST_DADDR         "10.0.0.5/32"
> +
> +/* Test Packet values */
> +#define DATA_MAGIC             0x01020304
> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
> +
> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
> --- a/test/validation/classification/odp_classification_tests.c
> +++ b/test/validation/classification/odp_classification_tests.c
> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
> @@ -451,10 +271,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);
> @@ -464,25 +286,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);
>  }
>
> @@ -518,16 +344,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);
>  }
> @@ -567,15 +396,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);
> @@ -658,19 +488,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);
>         }
>  }
> @@ -719,16 +551,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);
>  }
>
> @@ -794,10 +628,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);
> @@ -806,10 +642,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);
> --
> 1.9.1
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
>
Mike Holmes Oct. 14, 2015, 8:19 p.m. UTC | #8
sorry it needs to be on v5

On 14 October 2015 at 16:19, Mike Holmes <mike.holmes@linaro.org> wrote:

>
>
> On 24 September 2015 at 10:43, Balasubramanian Manoharan <
> bala.manoharan@linaro.org> wrote:
>
>> 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>
>>
>
> Reviewed-by: Mike Holmes <mike.holmes@linaro.org>
>
>
>> ---
>> v3: Incorporates review comments from Ivan
>>
>>  helper/include/odp/helper/tcp.h                    |   1 +
>>  test/validation/classification/Makefile.am         |   2 +
>>  test/validation/classification/classification.c    |   5 +
>>  .../classification/odp_classification_common.c     | 267 ++++++++++
>>  .../classification/odp_classification_test_pmr.c   | 569
>> +++++++++++++++++++++
>>  .../classification/odp_classification_tests.c      | 265 ++--------
>>  .../classification/odp_classification_testsuites.h |  15 +-
>>  7 files changed, 909 insertions(+), 215 deletions(-)
>>  create mode 100644
>> test/validation/classification/odp_classification_common.c
>>  create mode 100644
>> test/validation/classification/odp_classification_test_pmr.c
>>
>> 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/odp_classification_common.c
>> b/test/validation/classification/odp_classification_common.c
>> new file mode 100644
>> index 0000000..9b05ad6
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_common.c
>> @@ -0,0 +1,267 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.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>
>> +
>> +#define SHM_PKT_NUM_BUFS        32
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +#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
>> +
>> +#define CLS_TEST_SPORT         4096
>> +#define CLS_TEST_DPORT         8192
>> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>> +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..b90af22
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>> @@ -0,0 +1,569 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.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>
>> +
>> +#define SHM_PKT_NUM_BUFS        32
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +#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
>> +
>> +#define CLS_TEST_SPORT         4096
>> +#define CLS_TEST_DPORT         8192
>> +#define CLS_TEST_DADDR         "10.0.0.5/32"
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>> +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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
>> --- a/test/validation/classification/odp_classification_tests.c
>> +++ b/test/validation/classification/odp_classification_tests.c
>> @@ -66,99 +66,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 +92,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 +109,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 +212,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,
>> @@ -451,10 +271,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);
>> @@ -464,25 +286,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);
>>  }
>>
>> @@ -518,16 +344,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);
>>  }
>> @@ -567,15 +396,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);
>> @@ -658,19 +488,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);
>>         }
>>  }
>> @@ -719,16 +551,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);
>>  }
>>
>> @@ -794,10 +628,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);
>> @@ -806,10 +642,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);
>> --
>> 1.9.1
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/lng-odp
>>
>
>
>
> --
> Mike Holmes
> Technical Manager - Linaro Networking Group
> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
>
>
>
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/odp_classification_common.c b/test/validation/classification/odp_classification_common.c
new file mode 100644
index 0000000..9b05ad6
--- /dev/null
+++ b/test/validation/classification/odp_classification_common.c
@@ -0,0 +1,267 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include "odp_classification_testsuites.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>
+
+#define SHM_PKT_NUM_BUFS        32
+#define SHM_PKT_BUF_SIZE        1024
+
+#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
+
+#define CLS_TEST_SPORT		4096
+#define CLS_TEST_DPORT		8192
+#define CLS_TEST_DADDR		"10.0.0.5/32"
+
+/* Test Packet values */
+#define DATA_MAGIC		0x01020304
+#define TEST_SEQ_INVALID	((uint32_t)~0)
+
+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..b90af22
--- /dev/null
+++ b/test/validation/classification/odp_classification_test_pmr.c
@@ -0,0 +1,569 @@ 
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include "odp_classification_testsuites.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>
+
+#define SHM_PKT_NUM_BUFS        32
+#define SHM_PKT_BUF_SIZE        1024
+
+#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
+
+#define CLS_TEST_SPORT		4096
+#define CLS_TEST_DPORT		8192
+#define CLS_TEST_DADDR		"10.0.0.5/32"
+
+/* Test Packet values */
+#define DATA_MAGIC		0x01020304
+#define TEST_SEQ_INVALID	((uint32_t)~0)
+
+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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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_TEST_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 69a71b1..ba8b508 100644
--- a/test/validation/classification/odp_classification_tests.c
+++ b/test/validation/classification/odp_classification_tests.c
@@ -66,99 +66,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 +92,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 +109,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 +212,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,
@@ -451,10 +271,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);
@@ -464,25 +286,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);
 }
 
@@ -518,16 +344,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);
 }
@@ -567,15 +396,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);
@@ -658,19 +488,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);
 	}
 }
@@ -719,16 +551,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);
 }
 
@@ -794,10 +628,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);
@@ -806,10 +642,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);