diff mbox

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

Message ID 1444798980-16402-1-git-send-email-bala.manoharan@linaro.org
State Accepted
Commit cd83d24e012adc852a4ae2cca1e584039dec2bab
Headers show

Commit Message

Balasubramanian Manoharan Oct. 14, 2015, 5:03 a.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>
---
v5: rebase on latest api-next

 helper/include/odp/helper/tcp.h                    |   1 +
 test/validation/classification/Makefile.am         |   2 +
 test/validation/classification/classification.c    |   5 +
 test/validation/classification/classification.h    |  44 ++
 .../classification/odp_classification_common.c     | 252 +++++++++
 .../classification/odp_classification_test_pmr.c   | 579 +++++++++++++++++++++
 .../classification/odp_classification_tests.c      | 309 ++---------
 .../classification/odp_classification_testsuites.h |  15 +-
 8 files changed, 948 insertions(+), 259 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 Oct. 14, 2015, 8:20 p.m. UTC | #1
On 14 October 2015 at 01:03, 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>



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

I posted a patch earlier to add the missing odp_pktio_param_init() API
call.  We'll need to update this when that patch is reviewed/merged for
consistency.


> +       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];
> +       odp_pmr_match_t match;
> +
> +       val = CLS_DEFAULT_DPORT;
> +       mask = 0xffff;
> +       seqno = 0;
> +
> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
> +
> +       match.term = ODP_PMR_TCP_DPORT;
> +       match.val = &val;
> +       match.mask = &mask;
> +       match.val_sz = sizeof(val);
> +
> +       pmr = odp_pmr_create(&match);
> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +       sprintf(cosname, "tcp_dport");
> +       cos = odp_cos_create(cosname);
> +       CU_ASSERT(cos != ODP_COS_INVALID);
> +
> +       sprintf(queuename, "%s", "tcp_dport1");
> +
> +       queue = queue_create(queuename, true);
> +       CU_ASSERT(queue != ODP_QUEUE_INVALID);
> +
> +       retval = odp_cos_queue_set(cos, queue);
> +       CU_ASSERT(retval == 0);
> +
> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +       CU_ASSERT(retval == 0);
> +
> +       pkt = create_packet(pool_default, false, &seq, false);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(retqueue == queue);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +
> +       odp_packet_free(pkt);
> +
> +       /* Other packets are delivered to default queue */
> +       pkt = create_packet(pool_default, false, &seq, false);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == defqueue);
> +
> +       odp_packet_free(pkt);
> +       odp_cos_destroy(cos);
> +       odp_pmr_destroy(pmr);
> +       destroy_inq(pktio);
> +       odp_queue_destroy(queue);
> +       odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_tcp_sport(void)
> +{
> +       odp_packet_t pkt;
> +       odph_tcphdr_t *tcp;
> +       uint32_t seqno;
> +       uint16_t val;
> +       uint16_t mask;
> +       int retval;
> +       odp_pktio_t pktio;
> +       odp_queue_t queue;
> +       odp_queue_t retqueue;
> +       odp_queue_t defqueue;
> +       odp_pmr_t pmr;
> +       odp_cos_t cos;
> +       char cosname[ODP_QUEUE_NAME_LEN];
> +       char queuename[ODP_QUEUE_NAME_LEN];
> +       odp_pmr_match_t match;
> +
> +       val = CLS_DEFAULT_SPORT;
> +       mask = 0xffff;
> +       seqno = 0;
> +
> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +       match.term = ODP_PMR_TCP_SPORT;
> +       match.val = &val;
> +       match.mask = &mask;
> +       match.val_sz = sizeof(val);
> +
> +       pmr = odp_pmr_create(&match);
> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +       sprintf(cosname, "tcp_sport");
> +       cos = odp_cos_create(cosname);
> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +       sprintf(queuename, "%s", "tcp_sport");
> +
> +       queue = queue_create(queuename, true);
> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +       retval = odp_cos_queue_set(cos, queue);
> +       CU_ASSERT(retval == 0);
> +
> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +       CU_ASSERT(retval == 0);
> +
> +       pkt = create_packet(pool_default, false, &seq, false);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == queue);
> +       odp_packet_free(pkt);
> +
> +       pkt = create_packet(pool_default, false, &seq, false);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == defqueue);
> +
> +       odp_packet_free(pkt);
> +       odp_cos_destroy(cos);
> +       odp_pmr_destroy(pmr);
> +       destroy_inq(pktio);
> +       odp_queue_destroy(queue);
> +       odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_udp_dport(void)
> +{
> +       odp_packet_t pkt;
> +       odph_udphdr_t *udp;
> +       uint32_t seqno;
> +       uint16_t val;
> +       uint16_t mask;
> +       int retval;
> +       odp_pktio_t pktio;
> +       odp_queue_t queue;
> +       odp_queue_t retqueue;
> +       odp_queue_t defqueue;
> +       odp_pmr_t pmr;
> +       odp_cos_t cos;
> +       char cosname[ODP_QUEUE_NAME_LEN];
> +       char queuename[ODP_QUEUE_NAME_LEN];
> +       odp_pmr_match_t match;
> +
> +       val = CLS_DEFAULT_DPORT;
> +       mask = 0xffff;
> +       seqno = 0;
> +
> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +       match.term = ODP_PMR_UDP_DPORT;
> +       match.val = &val;
> +       match.mask = &mask;
> +       match.val_sz = sizeof(val);
> +
> +       pmr = odp_pmr_create(&match);
> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +       sprintf(cosname, "udp_dport");
> +       cos = odp_cos_create(cosname);
> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +       sprintf(queuename, "%s", "udp_dport");
> +
> +       queue = queue_create(queuename, true);
> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +       retval = odp_cos_queue_set(cos, queue);
> +       CU_ASSERT(retval == 0);
> +
> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +       CU_ASSERT(retval == 0);
> +
> +       pkt = create_packet(pool_default, false, &seq, true);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == queue);
> +       odp_packet_free(pkt);
> +
> +       /* Other packets received in default queue */
> +       pkt = create_packet(pool_default, false, &seq, true);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == defqueue);
> +
> +       odp_packet_free(pkt);
> +       odp_cos_destroy(cos);
> +       odp_pmr_destroy(pmr);
> +       destroy_inq(pktio);
> +       odp_queue_destroy(queue);
> +       odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_udp_sport(void)
> +{
> +       odp_packet_t pkt;
> +       odph_udphdr_t *udp;
> +       uint32_t seqno;
> +       uint16_t val;
> +       uint16_t mask;
> +       int retval;
> +       odp_pktio_t pktio;
> +       odp_queue_t queue;
> +       odp_queue_t retqueue;
> +       odp_queue_t defqueue;
> +       odp_pmr_t pmr;
> +       odp_cos_t cos;
> +       char cosname[ODP_QUEUE_NAME_LEN];
> +       char queuename[ODP_QUEUE_NAME_LEN];
> +       odp_pmr_match_t match;
> +
> +       val = CLS_DEFAULT_SPORT;
> +       mask = 0xffff;
> +       seqno = 0;
> +
> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +       match.term = ODP_PMR_UDP_SPORT;
> +       match.val = &val;
> +       match.mask = &mask;
> +       match.val_sz = sizeof(val);
> +
> +       pmr = odp_pmr_create(&match);
> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +       sprintf(cosname, "udp_sport");
> +       cos = odp_cos_create(cosname);
> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +       sprintf(queuename, "%s", "udp_sport");
> +
> +       queue = queue_create(queuename, true);
> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +       retval = odp_cos_queue_set(cos, queue);
> +       CU_ASSERT(retval == 0);
> +
> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +       CU_ASSERT(retval == 0);
> +
> +       pkt = create_packet(pool_default, false, &seq, true);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == queue);
> +       odp_packet_free(pkt);
> +
> +       pkt = create_packet(pool_default, false, &seq, true);
> +       seqno = cls_pkt_get_seq(pkt);
> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
> +
> +       enqueue_pktio_interface(pkt, pktio);
> +
> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +       CU_ASSERT(retqueue == defqueue);
> +       odp_packet_free(pkt);
> +
> +       odp_cos_destroy(cos);
> +       odp_pmr_destroy(pmr);
> +       destroy_inq(pktio);
> +       odp_queue_destroy(queue);
> +       odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_ipproto(void)
> +{
> +       odp_packet_t pkt;
> +       uint32_t seqno;
> +       uint8_t val;
> +       uint8_t mask;
> +       int retval;
> +       odp_pktio_t pktio;
> +       odp_queue_t queue;
> +       odp_queue_t retqueue;
> +       odp_queue_t defqueue;
> +       odp_pmr_t pmr;
> +       odp_cos_t cos;
> +       char cosname[ODP_QUEUE_NAME_LEN];
> +       char queuename[ODP_QUEUE_NAME_LEN];
> +       odp_pmr_match_t match;
> +
> +       val = ODPH_IPPROTO_UDP;
> +       mask = 0xff;
> +       seqno = 0;
> +
> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +       match.term = ODP_PMR_IPPROTO;
> +       match.val = &val;
> +       match.mask = &mask;
> +       match.val_sz = sizeof(val);
> +
> +       pmr = odp_pmr_create(&match);
> +       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 8840e53..74d1060 100644
> --- a/test/validation/classification/odp_classification_tests.c
> +++ b/test/validation/classification/odp_classification_tests.c
> @@ -11,50 +11,6 @@
>  #include <odp/helper/ip.h>
>  #include <odp/helper/udp.h>
>
> -#define SHM_PKT_NUM_BUFS        32
> -#define SHM_PKT_BUF_SIZE        1024
> -
> -/* Config values for Default CoS */
> -#define TEST_DEFAULT           1
> -#define        CLS_DEFAULT             0
> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
> -#define CLS_DEFAULT_SPORT      1024
> -#define CLS_DEFAULT_DPORT      2048
> -
> -/* Config values for Error CoS */
> -#define TEST_ERROR             1
> -#define CLS_ERROR              1
> -
> -/* Config values for PMR_CHAIN */
> -#define TEST_PMR_CHAIN         1
> -#define CLS_PMR_CHAIN_SRC      2
> -#define CLS_PMR_CHAIN_DST      3
> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
> -#define CLS_PMR_CHAIN_SPORT    3000
> -
> -/* Config values for PMR */
> -#define TEST_PMR               1
> -#define CLS_PMR                        4
> -#define CLS_PMR_SPORT          4000
> -
> -/* Config values for PMR SET */
> -#define TEST_PMR_SET           1
> -#define CLS_PMR_SET            5
> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
> -#define CLS_PMR_SET_SPORT      5000
> -
> -/* Config values for CoS L2 Priority */
> -#define TEST_L2_QOS            1
> -#define CLS_L2_QOS_0           6
> -#define CLS_L2_QOS_MAX         5
> -
> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
> -
> -/* Test Packet values */
> -#define DATA_MAGIC             0x01020304
> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
> -
>  static odp_cos_t cos_list[CLS_ENTRIES];
>  static odp_pmr_t pmr_list[CLS_ENTRIES];
>  static odp_queue_t queue_list[CLS_ENTRIES];
> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>  /** sequence number of IP packets */
>  odp_atomic_u32_t seq;
>
> -typedef struct cls_test_packet {
> -       uint32be_t magic;
> -       uint32be_t seq;
> -} cls_test_packet_t;
> -
> -static inline
> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
> *mask)
> -{
> -       int b[4];
> -       int qualifier = 32;
> -       int converted;
> -
> -       if (strchr(ipaddress, '/')) {
> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
> -                               &b[3], &b[2], &b[1], &b[0],
> -                               &qualifier);
> -               if (5 != converted)
> -                       return -1;
> -       } else {
> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
> -                               &b[3], &b[2], &b[1], &b[0]);
> -               if (4 != converted)
> -                       return -1;
> -       }
> -
> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
> -               return -1;
> -       if (!qualifier || (qualifier > 32))
> -               return -1;
> -
> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
> -       if (mask)
> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
> -
> -       return 0;
> -}
> -
> -static inline
> -void enqueue_loop_interface(odp_packet_t pkt)
> -{
> -       odp_event_t ev;
> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
> -
> -       ev = odp_packet_to_event(pkt);
> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
> -               odp_packet_free(pkt);
> -}
> -
> -static inline
> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
> -{
> -       odp_event_t ev;
> -
> -       ev = odp_schedule(queue, ns);
> -       return odp_packet_from_event(ev);
> -}
> -
> -static int cls_pkt_set_seq(odp_packet_t pkt)
> -{
> -       static uint32_t seq;
> -       cls_test_packet_t data;
> -       uint32_t offset;
> -       int status;
> -
> -       data.magic = DATA_MAGIC;
> -       data.seq = ++seq;
> -
> -       offset = odp_packet_l4_offset(pkt);
> -       CU_ASSERT_FATAL(offset != 0);
> -
> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
> -                                       sizeof(data), &data);
> -
> -       return status;
> -}
> -
> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
> -{
> -       uint32_t offset;
> -       cls_test_packet_t data;
> -
> -       offset = odp_packet_l4_offset(pkt);
> -       if (offset) {
> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
> -                                       sizeof(data), &data);
> -
> -               if (data.magic == DATA_MAGIC)
> -                       return data.seq;
> -       }
> -
> -       return TEST_SEQ_INVALID;
> -}
> -
>  static int destroy_inq(odp_pktio_t pktio)
>  {
>         odp_queue_t inq;
> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>
>         return odp_queue_destroy(inq);
>  }
> -odp_packet_t create_packet(bool vlan)
> -{
> -       uint32_t seqno;
> -       odph_ethhdr_t *ethhdr;
> -       odph_udphdr_t *udp;
> -       odph_ipv4hdr_t *ip;
> -       uint8_t payload_len;
> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
> -       uint32_t addr = 0;
> -       uint32_t mask;
> -       int offset;
> -       odp_packet_t pkt;
> -       int packet_len = 0;
> -
> -       payload_len = sizeof(cls_test_packet_t);
> -       packet_len += ODPH_ETHHDR_LEN;
> -       packet_len += ODPH_IPV4HDR_LEN;
> -       packet_len += ODPH_UDPHDR_LEN;
> -       packet_len += payload_len;
> -
> -       if (vlan)
> -               packet_len += ODPH_VLANHDR_LEN;
> -
> -       pkt = odp_packet_alloc(pool_default, packet_len);
> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
> -
> -       /* Ethernet Header */
> -       offset = 0;
> -       odp_packet_l2_offset_set(pkt, offset);
> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
> -       offset += sizeof(odph_ethhdr_t);
> -       if (vlan) {
> -               /* Default vlan header */
> -               uint8_t *parseptr;
> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
> -               parseptr = (uint8_t *)vlan;
> -               vlan->tci = odp_cpu_to_be_16(0);
> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
> -               offset += sizeof(odph_vlanhdr_t);
> -               parseptr += sizeof(odph_vlanhdr_t);
> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> -       } else {
> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> -       }
> -
> -       odp_packet_l3_offset_set(pkt, offset);
> -
> -       /* ipv4 */
> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
> -
> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
> -       ip->dst_addr = odp_cpu_to_be_32(addr);
> -
> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
> -       ip->src_addr = odp_cpu_to_be_32(addr);
> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
> -                       ODPH_IPV4HDR_LEN);
> -       ip->ttl = 128;
> -       ip->proto = ODPH_IPPROTO_UDP;
> -       seqno = odp_atomic_fetch_inc_u32(&seq);
> -       ip->id = odp_cpu_to_be_16(seqno);
> -       ip->chksum = 0;
> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
> -       offset += ODPH_IPV4HDR_LEN;
> -
> -       /* udp */
> -       odp_packet_l4_offset_set(pkt, offset);
> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
> -       udp->chksum = 0;
> -
> -       /* set pkt sequence number */
> -       cls_pkt_set_seq(pkt);
> -
> -       return pkt;
> -}
>
>  int classification_suite_init(void)
>  {
> -       odp_pool_t pool;
>         odp_pool_param_t param;
>         odp_queue_t inq_def;
>         odp_queue_param_t qparam;
> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>         param.pkt.num     = SHM_PKT_NUM_BUFS;
>         param.type        = ODP_POOL_PACKET;
>
> -       pool = odp_pool_create("classification_pool", &param);
> -       if (ODP_POOL_INVALID == pool) {
> +       pool_default = odp_pool_create("classification_pool", &param);
> +       if (ODP_POOL_INVALID == pool_default) {
>                 fprintf(stderr, "Packet pool creation failed.\n");
>                 return -1;
>         }
>
> -       pool_default = odp_pool_lookup("classification_pool");
> -       if (pool_default == ODP_POOL_INVALID)
> -               return -1;
> -
>         memset(&pktio_param, 0, sizeof(pktio_param));
>

Same comment as above here


>         pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>
> @@ -394,6 +169,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,
> @@ -459,10 +235,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);
> @@ -472,25 +250,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);
>  }
>
> @@ -526,16 +308,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);
>  }
> @@ -575,15 +360,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);
> @@ -666,19 +452,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);
>         }
>  }
> @@ -732,16 +520,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);
>  }
>
> @@ -807,10 +597,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);
> @@ -819,10 +611,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. 15, 2015, 5:54 a.m. UTC | #3
Hi Bill,

Agreed. Maybe we can merge this patch and then I will send a separate
patch to resolve the conflict so that both your patch and the conflict
patch could be merged together.
IMO, if this patch is acceptable we can merge this as it is now and
then I can send a conflict resolution patch to be merged with your
patch.

Regards,
Bala

On 15 October 2015 at 02:20, Bill Fischofer <bill.fischofer@linaro.org> wrote:
>
> On Wed, Oct 14, 2015 at 12:03 AM, 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>
>> ---
>> v5: rebase on latest api-next
>>
>>  helper/include/odp/helper/tcp.h                    |   1 +
>>  test/validation/classification/Makefile.am         |   2 +
>>  test/validation/classification/classification.c    |   5 +
>>  test/validation/classification/classification.h    |  44 ++
>>  .../classification/odp_classification_common.c     | 252 +++++++++
>>  .../classification/odp_classification_test_pmr.c   | 579
>> +++++++++++++++++++++
>>  .../classification/odp_classification_tests.c      | 309 ++---------
>>  .../classification/odp_classification_testsuites.h |  15 +-
>>  8 files changed, 948 insertions(+), 259 deletions(-)
>>  create mode 100644
>> test/validation/classification/odp_classification_common.c
>>  create mode 100644
>> test/validation/classification/odp_classification_test_pmr.c
>>
>> diff --git a/helper/include/odp/helper/tcp.h
>> b/helper/include/odp/helper/tcp.h
>> index defe422..42f0cbe 100644
>> --- a/helper/include/odp/helper/tcp.h
>> +++ b/helper/include/odp/helper/tcp.h
>> @@ -26,6 +26,7 @@ extern "C" {
>>   *  @{
>>   */
>>
>> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
>>
>>  /** TCP header */
>>  typedef struct ODP_PACKED {
>> diff --git a/test/validation/classification/Makefile.am
>> b/test/validation/classification/Makefile.am
>> index 5881665..4235309 100644
>> --- a/test/validation/classification/Makefile.am
>> +++ b/test/validation/classification/Makefile.am
>> @@ -3,6 +3,8 @@ include ../Makefile.inc
>>  noinst_LTLIBRARIES = libtestclassification.la
>>  libtestclassification_la_SOURCES = odp_classification_basic.c \
>>                                odp_classification_tests.c \
>> +                              odp_classification_test_pmr.c \
>> +                              odp_classification_common.c \
>>                                classification.c
>>
>>  bin_PROGRAMS = classification_main$(EXEEXT)
>> diff --git a/test/validation/classification/classification.c
>> b/test/validation/classification/classification.c
>> index d0fef93..6641893 100644
>> --- a/test/validation/classification/classification.c
>> +++ b/test/validation/classification/classification.c
>> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>>         { .pName = "classification basic",
>>                         .pTests = classification_suite_basic,
>>         },
>> +       { .pName = "classification pmr tests",
>> +                       .pTests = classification_suite_pmr,
>> +                       .pInitFunc = classification_suite_pmr_init,
>> +                       .pCleanupFunc = classification_suite_pmr_term,
>> +       },
>>         { .pName = "classification tests",
>>                         .pTests = classification_suite,
>>                         .pInitFunc = classification_suite_init,
>> diff --git a/test/validation/classification/classification.h
>> b/test/validation/classification/classification.h
>> index d2847e5..de9c37e 100644
>> --- a/test/validation/classification/classification.h
>> +++ b/test/validation/classification/classification.h
>> @@ -9,6 +9,50 @@
>>
>>  #include <CUnit/Basic.h>
>>
>> +#define SHM_PKT_NUM_BUFS        32
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +/* Config values for Default CoS */
>> +#define TEST_DEFAULT           1
>> +#define        CLS_DEFAULT             0
>> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>> +#define CLS_DEFAULT_SPORT      1024
>> +#define CLS_DEFAULT_DPORT      2048
>> +
>> +/* Config values for Error CoS */
>> +#define TEST_ERROR             1
>> +#define CLS_ERROR              1
>> +
>> +/* Config values for PMR_CHAIN */
>> +#define TEST_PMR_CHAIN         1
>> +#define CLS_PMR_CHAIN_SRC      2
>> +#define CLS_PMR_CHAIN_DST      3
>> +#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>> +#define CLS_PMR_CHAIN_SPORT    3000
>> +
>> +/* Config values for PMR */
>> +#define TEST_PMR               1
>> +#define CLS_PMR                        4
>> +#define CLS_PMR_SPORT          4000
>> +
>> +/* Config values for PMR SET */
>> +#define TEST_PMR_SET           1
>> +#define CLS_PMR_SET            5
>> +#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>> +#define CLS_PMR_SET_SPORT      5000
>> +
>> +/* Config values for CoS L2 Priority */
>> +#define TEST_L2_QOS            1
>> +#define CLS_L2_QOS_0           6
>> +#define CLS_L2_QOS_MAX         5
>> +
>> +#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>>  /* test functions: */
>>  void classification_test_create_cos(void);
>>  void classification_test_destroy_cos(void);
>> diff --git a/test/validation/classification/odp_classification_common.c
>> b/test/validation/classification/odp_classification_common.c
>> new file mode 100644
>> index 0000000..b975dfb
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_common.c
>> @@ -0,0 +1,252 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.h"
>> +#include "classification.h"
>> +#include <odp_cunit_common.h>
>> +#include <odp/helper/eth.h>
>> +#include <odp/helper/ip.h>
>> +#include <odp/helper/udp.h>
>> +#include <odp/helper/tcp.h>
>> +
>> +typedef struct cls_test_packet {
>> +       uint32be_t magic;
>> +       uint32be_t seq;
>> +} cls_test_packet_t;
>> +
>> +int cls_pkt_set_seq(odp_packet_t pkt)
>> +{
>> +       static uint32_t seq;
>> +       cls_test_packet_t data;
>> +       uint32_t offset;
>> +       odph_ipv4hdr_t *ip;
>> +       int status;
>> +
>> +       data.magic = DATA_MAGIC;
>> +       data.seq = ++seq;
>> +
>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>> +       offset = odp_packet_l4_offset(pkt);
>> +       CU_ASSERT_FATAL(offset != 0);
>> +
>> +       if (ip->proto == ODPH_IPPROTO_UDP)
>> +               status = odp_packet_copydata_in(pkt, offset +
>> ODPH_UDPHDR_LEN,
>> +                                               sizeof(data), &data);
>> +       else
>> +               status = odp_packet_copydata_in(pkt, offset +
>> ODPH_TCPHDR_LEN,
>> +                                               sizeof(data), &data);
>> +
>> +       return status;
>> +}
>> +
>> +uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>> +{
>> +       uint32_t offset;
>> +       cls_test_packet_t data;
>> +       odph_ipv4hdr_t *ip;
>> +
>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>> +       offset = odp_packet_l4_offset(pkt);
>> +
>> +       if (!offset && !ip)
>> +               return TEST_SEQ_INVALID;
>> +
>> +       if (ip->proto == ODPH_IPPROTO_UDP)
>> +               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>> +                                       sizeof(data), &data);
>> +       else
>> +               odp_packet_copydata_out(pkt, offset + ODPH_TCPHDR_LEN,
>> +                                       sizeof(data), &data);
>> +
>> +       if (data.magic == DATA_MAGIC)
>> +               return data.seq;
>> +
>> +       return TEST_SEQ_INVALID;
>> +}
>> +
>> +int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>> *mask)
>> +{
>> +       int b[4];
>> +       int qualifier = 32;
>> +       int converted;
>> +
>> +       if (strchr(ipaddress, '/')) {
>> +               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>> +                                  &b[3], &b[2], &b[1], &b[0],
>> +                                  &qualifier);
>> +               if (5 != converted)
>> +                       return -1;
>> +       } else {
>> +               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>> +                                  &b[3], &b[2], &b[1], &b[0]);
>> +               if (4 != converted)
>> +                       return -1;
>> +       }
>> +
>> +       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>> +               return -1;
>> +       if (!qualifier || (qualifier > 32))
>> +               return -1;
>> +
>> +       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>> +       if (mask)
>> +               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>> +
>> +       return 0;
>> +}
>> +
>> +void enqueue_pktio_interface(odp_packet_t pkt, odp_pktio_t pktio)
>> +{
>> +       odp_event_t ev;
>> +       odp_queue_t defqueue;
>> +
>> +       defqueue  = odp_pktio_outq_getdef(pktio);
>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>> +
>> +       ev = odp_packet_to_event(pkt);
>> +       CU_ASSERT(odp_queue_enq(defqueue, ev) == 0);
>> +}
>> +
>> +odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>> +{
>> +       odp_event_t ev;
>> +
>> +       ev = odp_schedule(queue, ns);
>> +       return odp_packet_from_event(ev);
>> +}
>> +
>> +odp_queue_t queue_create(char *queuename, bool sched)
>> +{
>> +       odp_queue_t queue;
>> +       odp_queue_param_t qparam;
>> +
>> +       if (sched) {
>> +               odp_queue_param_init(&qparam);
>> +               qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST;
>> +               qparam.sched.sync = ODP_SCHED_SYNC_NONE;
>> +               qparam.sched.group = ODP_SCHED_GROUP_ALL;
>> +
>> +               queue = odp_queue_create(queuename,
>> +                                        ODP_QUEUE_TYPE_SCHED,
>> +                                        &qparam);
>> +       } else {
>> +               queue = odp_queue_create(queuename,
>> +                                        ODP_QUEUE_TYPE_POLL,
>> +                                        NULL);
>> +       }
>> +
>> +       return queue;
>> +}
>> +
>> +odp_packet_t create_packet(odp_pool_t pool, bool vlan,
>> +                          odp_atomic_u32_t *seq, bool flag_udp)
>> +{
>> +       uint32_t seqno;
>> +       odph_ethhdr_t *ethhdr;
>> +       odph_udphdr_t *udp;
>> +       odph_tcphdr_t *tcp;
>> +       odph_ipv4hdr_t *ip;
>> +       uint8_t payload_len;
>> +       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>> +       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>> +       uint32_t addr = 0;
>> +       uint32_t mask;
>> +       int offset;
>> +       odp_packet_t pkt;
>> +       int packet_len = 0;
>> +
>> +       payload_len = sizeof(cls_test_packet_t);
>> +       packet_len += ODPH_ETHHDR_LEN;
>> +       packet_len += ODPH_IPV4HDR_LEN;
>> +       if (flag_udp)
>> +               packet_len += ODPH_UDPHDR_LEN;
>> +       else
>> +               packet_len += ODPH_TCPHDR_LEN;
>> +       packet_len += payload_len;
>> +
>> +       if (vlan)
>> +               packet_len += ODPH_VLANHDR_LEN;
>> +
>> +       pkt = odp_packet_alloc(pool, packet_len);
>> +       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>> +
>> +       /* Ethernet Header */
>> +       offset = 0;
>> +       odp_packet_l2_offset_set(pkt, offset);
>> +       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>> +       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>> +       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>> +       offset += sizeof(odph_ethhdr_t);
>> +       if (vlan) {
>> +               /* Default vlan header */
>> +               uint8_t *parseptr;
>> +               odph_vlanhdr_t *vlan;
>> +
>> +               vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>> +               parseptr = (uint8_t *)vlan;
>> +               vlan->tci = odp_cpu_to_be_16(0);
>> +               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>> +               offset += sizeof(odph_vlanhdr_t);
>> +               parseptr += sizeof(odph_vlanhdr_t);
>> +               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>> +               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> +       } else {
>> +               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> +       }
>> +
>> +       odp_packet_l3_offset_set(pkt, offset);
>> +
>> +       /* ipv4 */
>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>> +
>> +       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>> +       ip->dst_addr = odp_cpu_to_be_32(addr);
>> +
>> +       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>> +       ip->src_addr = odp_cpu_to_be_32(addr);
>> +       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>> +       if (flag_udp)
>> +               ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN +
>> payload_len +
>> +                                              ODPH_IPV4HDR_LEN);
>> +       else
>> +               ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN +
>> payload_len +
>> +                                              ODPH_IPV4HDR_LEN);
>> +
>> +       ip->ttl = 128;
>> +       if (flag_udp)
>> +               ip->proto = ODPH_IPPROTO_UDP;
>> +       else
>> +               ip->proto = ODPH_IPPROTO_TCP;
>> +
>> +       seqno = odp_atomic_fetch_inc_u32(seq);
>> +       ip->id = odp_cpu_to_be_16(seqno);
>> +       ip->chksum = 0;
>> +       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>> +       offset += ODPH_IPV4HDR_LEN;
>> +
>> +       /* udp */
>> +       if (flag_udp) {
>> +               odp_packet_l4_offset_set(pkt, offset);
>> +               udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +               udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +               udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +               udp->length = odp_cpu_to_be_16(payload_len +
>> ODPH_UDPHDR_LEN);
>> +               udp->chksum = 0;
>> +       } else {
>> +               odp_packet_l4_offset_set(pkt, offset);
>> +               tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +               tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +               tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +               tcp->hl = ODPH_TCPHDR_LEN / 4;
>> +               /* TODO: checksum field has to be updated */
>> +               tcp->cksm = 0;
>> +       }
>> +
>> +       /* set pkt sequence number */
>> +       cls_pkt_set_seq(pkt);
>> +
>> +       return pkt;
>> +}
>> diff --git a/test/validation/classification/odp_classification_test_pmr.c
>> b/test/validation/classification/odp_classification_test_pmr.c
>> new file mode 100644
>> index 0000000..37de892
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>> @@ -0,0 +1,579 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.h"
>> +#include "classification.h"
>> +#include <odp_cunit_common.h>
>> +#include <odp/helper/eth.h>
>> +#include <odp/helper/ip.h>
>> +#include <odp/helper/udp.h>
>> +#include <odp/helper/tcp.h>
>> +
>> +static odp_pool_t pool_default;
>> +
>> +/** sequence number of IP packets */
>> +odp_atomic_u32_t seq;
>> +
>> +static int destroy_inq(odp_pktio_t pktio)
>> +{
>> +       odp_queue_t inq;
>> +       odp_event_t ev;
>> +
>> +       inq = odp_pktio_inq_getdef(pktio);
>> +
>> +       if (inq == ODP_QUEUE_INVALID) {
>> +               CU_FAIL("attempting to destroy invalid inq");
>> +               return -1;
>> +       }
>> +
>> +       if (0 > odp_pktio_inq_remdef(pktio))
>> +               return -1;
>> +
>> +       while (1) {
>> +               ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
>> +
>> +               if (ev != ODP_EVENT_INVALID)
>> +                       odp_buffer_free(odp_buffer_from_event(ev));
>> +               else
>> +                       break;
>> +       }
>> +
>> +       return odp_queue_destroy(inq);
>> +}
>> +
>> +int classification_suite_pmr_init(void)
>> +{
>> +       odp_pool_t pool;
>> +       odp_pool_param_t param;
>> +
>> +       odp_pool_param_init(&param);
>> +       param.pkt.seg_len = SHM_PKT_BUF_SIZE;
>> +       param.pkt.len     = SHM_PKT_BUF_SIZE;
>> +       param.pkt.num     = SHM_PKT_NUM_BUFS;
>> +       param.type        = ODP_POOL_PACKET;
>> +
>> +       pool = odp_pool_create("classification_pmr_pool", &param);
>> +       if (ODP_POOL_INVALID == pool) {
>> +               fprintf(stderr, "Packet pool creation failed.\n");
>> +               return -1;
>> +       }
>> +
>> +       pool_default = odp_pool_lookup("classification_pmr_pool");
>> +       if (pool_default == ODP_POOL_INVALID)
>> +               return -1;
>> +
>> +       odp_atomic_init_u32(&seq, 0);
>> +       return 0;
>> +}
>> +
>> +odp_pktio_t create_pktio(odp_queue_type_t q_type)
>> +{
>> +       odp_pktio_t pktio;
>> +       odp_pktio_param_t pktio_param;
>> +       odp_pool_t pool;
>> +       int ret;
>> +
>> +       pool = odp_pool_lookup("classification_pmr_pool");
>> +       if (pool == ODP_POOL_INVALID)
>> +               return ODP_PKTIO_INVALID;
>> +
>> +       memset(&pktio_param, 0, sizeof(pktio_param));
>
>
> I posted a patch earlier to add the missing odp_pktio_param_init() API call.
> We'll need to update this when that patch is reviewed/merged for
> consistency.
>
>>
>> +       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];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_DPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>> +
>> +       match.term = ODP_PMR_TCP_DPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "tcp_dport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "tcp_dport1");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(retqueue == queue);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +
>> +       odp_packet_free(pkt);
>> +
>> +       /* Other packets are delivered to default queue */
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_tcp_sport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_tcphdr_t *tcp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_SPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_TCP_SPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "tcp_sport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "tcp_sport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_udp_dport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_udphdr_t *udp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_DPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_UDP_DPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "udp_dport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "udp_dport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       /* Other packets received in default queue */
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_udp_sport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_udphdr_t *udp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_SPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_UDP_SPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "udp_sport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "udp_sport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +       odp_packet_free(pkt);
>> +
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_ipproto(void)
>> +{
>> +       odp_packet_t pkt;
>> +       uint32_t seqno;
>> +       uint8_t val;
>> +       uint8_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = ODPH_IPPROTO_UDP;
>> +       mask = 0xff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_IPPROTO;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       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 8840e53..74d1060 100644
>> --- a/test/validation/classification/odp_classification_tests.c
>> +++ b/test/validation/classification/odp_classification_tests.c
>> @@ -11,50 +11,6 @@
>>  #include <odp/helper/ip.h>
>>  #include <odp/helper/udp.h>
>>
>> -#define SHM_PKT_NUM_BUFS        32
>> -#define SHM_PKT_BUF_SIZE        1024
>> -
>> -/* Config values for Default CoS */
>> -#define TEST_DEFAULT           1
>> -#define        CLS_DEFAULT             0
>> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>> -#define CLS_DEFAULT_SPORT      1024
>> -#define CLS_DEFAULT_DPORT      2048
>> -
>> -/* Config values for Error CoS */
>> -#define TEST_ERROR             1
>> -#define CLS_ERROR              1
>> -
>> -/* Config values for PMR_CHAIN */
>> -#define TEST_PMR_CHAIN         1
>> -#define CLS_PMR_CHAIN_SRC      2
>> -#define CLS_PMR_CHAIN_DST      3
>> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>> -#define CLS_PMR_CHAIN_SPORT    3000
>> -
>> -/* Config values for PMR */
>> -#define TEST_PMR               1
>> -#define CLS_PMR                        4
>> -#define CLS_PMR_SPORT          4000
>> -
>> -/* Config values for PMR SET */
>> -#define TEST_PMR_SET           1
>> -#define CLS_PMR_SET            5
>> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>> -#define CLS_PMR_SET_SPORT      5000
>> -
>> -/* Config values for CoS L2 Priority */
>> -#define TEST_L2_QOS            1
>> -#define CLS_L2_QOS_0           6
>> -#define CLS_L2_QOS_MAX         5
>> -
>> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>> -
>> -/* Test Packet values */
>> -#define DATA_MAGIC             0x01020304
>> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> -
>>  static odp_cos_t cos_list[CLS_ENTRIES];
>>  static odp_pmr_t pmr_list[CLS_ENTRIES];
>>  static odp_queue_t queue_list[CLS_ENTRIES];
>> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>>  /** sequence number of IP packets */
>>  odp_atomic_u32_t seq;
>>
>> -typedef struct cls_test_packet {
>> -       uint32be_t magic;
>> -       uint32be_t seq;
>> -} cls_test_packet_t;
>> -
>> -static inline
>> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>> *mask)
>> -{
>> -       int b[4];
>> -       int qualifier = 32;
>> -       int converted;
>> -
>> -       if (strchr(ipaddress, '/')) {
>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>> -                               &b[3], &b[2], &b[1], &b[0],
>> -                               &qualifier);
>> -               if (5 != converted)
>> -                       return -1;
>> -       } else {
>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>> -                               &b[3], &b[2], &b[1], &b[0]);
>> -               if (4 != converted)
>> -                       return -1;
>> -       }
>> -
>> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>> -               return -1;
>> -       if (!qualifier || (qualifier > 32))
>> -               return -1;
>> -
>> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>> -       if (mask)
>> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>> -
>> -       return 0;
>> -}
>> -
>> -static inline
>> -void enqueue_loop_interface(odp_packet_t pkt)
>> -{
>> -       odp_event_t ev;
>> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
>> -
>> -       ev = odp_packet_to_event(pkt);
>> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
>> -               odp_packet_free(pkt);
>> -}
>> -
>> -static inline
>> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>> -{
>> -       odp_event_t ev;
>> -
>> -       ev = odp_schedule(queue, ns);
>> -       return odp_packet_from_event(ev);
>> -}
>> -
>> -static int cls_pkt_set_seq(odp_packet_t pkt)
>> -{
>> -       static uint32_t seq;
>> -       cls_test_packet_t data;
>> -       uint32_t offset;
>> -       int status;
>> -
>> -       data.magic = DATA_MAGIC;
>> -       data.seq = ++seq;
>> -
>> -       offset = odp_packet_l4_offset(pkt);
>> -       CU_ASSERT_FATAL(offset != 0);
>> -
>> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
>> -                                       sizeof(data), &data);
>> -
>> -       return status;
>> -}
>> -
>> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>> -{
>> -       uint32_t offset;
>> -       cls_test_packet_t data;
>> -
>> -       offset = odp_packet_l4_offset(pkt);
>> -       if (offset) {
>> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>> -                                       sizeof(data), &data);
>> -
>> -               if (data.magic == DATA_MAGIC)
>> -                       return data.seq;
>> -       }
>> -
>> -       return TEST_SEQ_INVALID;
>> -}
>> -
>>  static int destroy_inq(odp_pktio_t pktio)
>>  {
>>         odp_queue_t inq;
>> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>>
>>         return odp_queue_destroy(inq);
>>  }
>> -odp_packet_t create_packet(bool vlan)
>> -{
>> -       uint32_t seqno;
>> -       odph_ethhdr_t *ethhdr;
>> -       odph_udphdr_t *udp;
>> -       odph_ipv4hdr_t *ip;
>> -       uint8_t payload_len;
>> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>> -       uint32_t addr = 0;
>> -       uint32_t mask;
>> -       int offset;
>> -       odp_packet_t pkt;
>> -       int packet_len = 0;
>> -
>> -       payload_len = sizeof(cls_test_packet_t);
>> -       packet_len += ODPH_ETHHDR_LEN;
>> -       packet_len += ODPH_IPV4HDR_LEN;
>> -       packet_len += ODPH_UDPHDR_LEN;
>> -       packet_len += payload_len;
>> -
>> -       if (vlan)
>> -               packet_len += ODPH_VLANHDR_LEN;
>> -
>> -       pkt = odp_packet_alloc(pool_default, packet_len);
>> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>> -
>> -       /* Ethernet Header */
>> -       offset = 0;
>> -       odp_packet_l2_offset_set(pkt, offset);
>> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>> -       offset += sizeof(odph_ethhdr_t);
>> -       if (vlan) {
>> -               /* Default vlan header */
>> -               uint8_t *parseptr;
>> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>> -               parseptr = (uint8_t *)vlan;
>> -               vlan->tci = odp_cpu_to_be_16(0);
>> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>> -               offset += sizeof(odph_vlanhdr_t);
>> -               parseptr += sizeof(odph_vlanhdr_t);
>> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> -       } else {
>> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> -       }
>> -
>> -       odp_packet_l3_offset_set(pkt, offset);
>> -
>> -       /* ipv4 */
>> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>> -
>> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>> -       ip->dst_addr = odp_cpu_to_be_32(addr);
>> -
>> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>> -       ip->src_addr = odp_cpu_to_be_32(addr);
>> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
>> -                       ODPH_IPV4HDR_LEN);
>> -       ip->ttl = 128;
>> -       ip->proto = ODPH_IPPROTO_UDP;
>> -       seqno = odp_atomic_fetch_inc_u32(&seq);
>> -       ip->id = odp_cpu_to_be_16(seqno);
>> -       ip->chksum = 0;
>> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>> -       offset += ODPH_IPV4HDR_LEN;
>> -
>> -       /* udp */
>> -       odp_packet_l4_offset_set(pkt, offset);
>> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
>> -       udp->chksum = 0;
>> -
>> -       /* set pkt sequence number */
>> -       cls_pkt_set_seq(pkt);
>> -
>> -       return pkt;
>> -}
>>
>>  int classification_suite_init(void)
>>  {
>> -       odp_pool_t pool;
>>         odp_pool_param_t param;
>>         odp_queue_t inq_def;
>>         odp_queue_param_t qparam;
>> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>>         param.pkt.num     = SHM_PKT_NUM_BUFS;
>>         param.type        = ODP_POOL_PACKET;
>>
>> -       pool = odp_pool_create("classification_pool", &param);
>> -       if (ODP_POOL_INVALID == pool) {
>> +       pool_default = odp_pool_create("classification_pool", &param);
>> +       if (ODP_POOL_INVALID == pool_default) {
>>                 fprintf(stderr, "Packet pool creation failed.\n");
>>                 return -1;
>>         }
>>
>> -       pool_default = odp_pool_lookup("classification_pool");
>> -       if (pool_default == ODP_POOL_INVALID)
>> -               return -1;
>> -
>>         memset(&pktio_param, 0, sizeof(pktio_param));
>
>
> Same comment as above here
>
>>
>>         pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>>
>> @@ -394,6 +169,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,
>> @@ -459,10 +235,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);
>> @@ -472,25 +250,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);
>>  }
>>
>> @@ -526,16 +308,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);
>>  }
>> @@ -575,15 +360,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);
>> @@ -666,19 +452,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);
>>         }
>>  }
>> @@ -732,16 +520,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);
>>  }
>>
>> @@ -807,10 +597,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);
>> @@ -819,10 +611,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
>
>
Maxim Uvarov Oct. 15, 2015, 10:48 a.m. UTC | #4
Merged,
Maxim.

On 10/15/2015 08:54, Bala Manoharan wrote:
> Hi Bill,
>
> Agreed. Maybe we can merge this patch and then I will send a separate
> patch to resolve the conflict so that both your patch and the conflict
> patch could be merged together.
> IMO, if this patch is acceptable we can merge this as it is now and
> then I can send a conflict resolution patch to be merged with your
> patch.
>
> Regards,
> Bala
>
> On 15 October 2015 at 02:20, Bill Fischofer <bill.fischofer@linaro.org> wrote:
>> On Wed, Oct 14, 2015 at 12:03 AM, 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>
>>> ---
>>> v5: rebase on latest api-next
>>>
>>>   helper/include/odp/helper/tcp.h                    |   1 +
>>>   test/validation/classification/Makefile.am         |   2 +
>>>   test/validation/classification/classification.c    |   5 +
>>>   test/validation/classification/classification.h    |  44 ++
>>>   .../classification/odp_classification_common.c     | 252 +++++++++
>>>   .../classification/odp_classification_test_pmr.c   | 579
>>> +++++++++++++++++++++
>>>   .../classification/odp_classification_tests.c      | 309 ++---------
>>>   .../classification/odp_classification_testsuites.h |  15 +-
>>>   8 files changed, 948 insertions(+), 259 deletions(-)
>>>   create mode 100644
>>> test/validation/classification/odp_classification_common.c
>>>   create mode 100644
>>> test/validation/classification/odp_classification_test_pmr.c
>>>
>>> diff --git a/helper/include/odp/helper/tcp.h
>>> b/helper/include/odp/helper/tcp.h
>>> index defe422..42f0cbe 100644
>>> --- a/helper/include/odp/helper/tcp.h
>>> +++ b/helper/include/odp/helper/tcp.h
>>> @@ -26,6 +26,7 @@ extern "C" {
>>>    *  @{
>>>    */
>>>
>>> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
>>>
>>>   /** TCP header */
>>>   typedef struct ODP_PACKED {
>>> diff --git a/test/validation/classification/Makefile.am
>>> b/test/validation/classification/Makefile.am
>>> index 5881665..4235309 100644
>>> --- a/test/validation/classification/Makefile.am
>>> +++ b/test/validation/classification/Makefile.am
>>> @@ -3,6 +3,8 @@ include ../Makefile.inc
>>>   noinst_LTLIBRARIES = libtestclassification.la
>>>   libtestclassification_la_SOURCES = odp_classification_basic.c \
>>>                                 odp_classification_tests.c \
>>> +                              odp_classification_test_pmr.c \
>>> +                              odp_classification_common.c \
>>>                                 classification.c
>>>
>>>   bin_PROGRAMS = classification_main$(EXEEXT)
>>> diff --git a/test/validation/classification/classification.c
>>> b/test/validation/classification/classification.c
>>> index d0fef93..6641893 100644
>>> --- a/test/validation/classification/classification.c
>>> +++ b/test/validation/classification/classification.c
>>> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>>>          { .pName = "classification basic",
>>>                          .pTests = classification_suite_basic,
>>>          },
>>> +       { .pName = "classification pmr tests",
>>> +                       .pTests = classification_suite_pmr,
>>> +                       .pInitFunc = classification_suite_pmr_init,
>>> +                       .pCleanupFunc = classification_suite_pmr_term,
>>> +       },
>>>          { .pName = "classification tests",
>>>                          .pTests = classification_suite,
>>>                          .pInitFunc = classification_suite_init,
>>> diff --git a/test/validation/classification/classification.h
>>> b/test/validation/classification/classification.h
>>> index d2847e5..de9c37e 100644
>>> --- a/test/validation/classification/classification.h
>>> +++ b/test/validation/classification/classification.h
>>> @@ -9,6 +9,50 @@
>>>
>>>   #include <CUnit/Basic.h>
>>>
>>> +#define SHM_PKT_NUM_BUFS        32
>>> +#define SHM_PKT_BUF_SIZE        1024
>>> +
>>> +/* Config values for Default CoS */
>>> +#define TEST_DEFAULT           1
>>> +#define        CLS_DEFAULT             0
>>> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>> +#define CLS_DEFAULT_SPORT      1024
>>> +#define CLS_DEFAULT_DPORT      2048
>>> +
>>> +/* Config values for Error CoS */
>>> +#define TEST_ERROR             1
>>> +#define CLS_ERROR              1
>>> +
>>> +/* Config values for PMR_CHAIN */
>>> +#define TEST_PMR_CHAIN         1
>>> +#define CLS_PMR_CHAIN_SRC      2
>>> +#define CLS_PMR_CHAIN_DST      3
>>> +#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>> +#define CLS_PMR_CHAIN_SPORT    3000
>>> +
>>> +/* Config values for PMR */
>>> +#define TEST_PMR               1
>>> +#define CLS_PMR                        4
>>> +#define CLS_PMR_SPORT          4000
>>> +
>>> +/* Config values for PMR SET */
>>> +#define TEST_PMR_SET           1
>>> +#define CLS_PMR_SET            5
>>> +#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>> +#define CLS_PMR_SET_SPORT      5000
>>> +
>>> +/* Config values for CoS L2 Priority */
>>> +#define TEST_L2_QOS            1
>>> +#define CLS_L2_QOS_0           6
>>> +#define CLS_L2_QOS_MAX         5
>>> +
>>> +#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>> +
>>> +/* Test Packet values */
>>> +#define DATA_MAGIC             0x01020304
>>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> +
>>>   /* test functions: */
>>>   void classification_test_create_cos(void);
>>>   void classification_test_destroy_cos(void);
>>> diff --git a/test/validation/classification/odp_classification_common.c
>>> b/test/validation/classification/odp_classification_common.c
>>> new file mode 100644
>>> index 0000000..b975dfb
>>> --- /dev/null
>>> +++ b/test/validation/classification/odp_classification_common.c
>>> @@ -0,0 +1,252 @@
>>> +/* Copyright (c) 2015, Linaro Limited
>>> + * All rights reserved.
>>> + *
>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>> + */
>>> +
>>> +#include "odp_classification_testsuites.h"
>>> +#include "classification.h"
>>> +#include <odp_cunit_common.h>
>>> +#include <odp/helper/eth.h>
>>> +#include <odp/helper/ip.h>
>>> +#include <odp/helper/udp.h>
>>> +#include <odp/helper/tcp.h>
>>> +
>>> +typedef struct cls_test_packet {
>>> +       uint32be_t magic;
>>> +       uint32be_t seq;
>>> +} cls_test_packet_t;
>>> +
>>> +int cls_pkt_set_seq(odp_packet_t pkt)
>>> +{
>>> +       static uint32_t seq;
>>> +       cls_test_packet_t data;
>>> +       uint32_t offset;
>>> +       odph_ipv4hdr_t *ip;
>>> +       int status;
>>> +
>>> +       data.magic = DATA_MAGIC;
>>> +       data.seq = ++seq;
>>> +
>>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>> +       offset = odp_packet_l4_offset(pkt);
>>> +       CU_ASSERT_FATAL(offset != 0);
>>> +
>>> +       if (ip->proto == ODPH_IPPROTO_UDP)
>>> +               status = odp_packet_copydata_in(pkt, offset +
>>> ODPH_UDPHDR_LEN,
>>> +                                               sizeof(data), &data);
>>> +       else
>>> +               status = odp_packet_copydata_in(pkt, offset +
>>> ODPH_TCPHDR_LEN,
>>> +                                               sizeof(data), &data);
>>> +
>>> +       return status;
>>> +}
>>> +
>>> +uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>>> +{
>>> +       uint32_t offset;
>>> +       cls_test_packet_t data;
>>> +       odph_ipv4hdr_t *ip;
>>> +
>>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>> +       offset = odp_packet_l4_offset(pkt);
>>> +
>>> +       if (!offset && !ip)
>>> +               return TEST_SEQ_INVALID;
>>> +
>>> +       if (ip->proto == ODPH_IPPROTO_UDP)
>>> +               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>>> +                                       sizeof(data), &data);
>>> +       else
>>> +               odp_packet_copydata_out(pkt, offset + ODPH_TCPHDR_LEN,
>>> +                                       sizeof(data), &data);
>>> +
>>> +       if (data.magic == DATA_MAGIC)
>>> +               return data.seq;
>>> +
>>> +       return TEST_SEQ_INVALID;
>>> +}
>>> +
>>> +int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>>> *mask)
>>> +{
>>> +       int b[4];
>>> +       int qualifier = 32;
>>> +       int converted;
>>> +
>>> +       if (strchr(ipaddress, '/')) {
>>> +               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>>> +                                  &b[3], &b[2], &b[1], &b[0],
>>> +                                  &qualifier);
>>> +               if (5 != converted)
>>> +                       return -1;
>>> +       } else {
>>> +               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>>> +                                  &b[3], &b[2], &b[1], &b[0]);
>>> +               if (4 != converted)
>>> +                       return -1;
>>> +       }
>>> +
>>> +       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>>> +               return -1;
>>> +       if (!qualifier || (qualifier > 32))
>>> +               return -1;
>>> +
>>> +       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>>> +       if (mask)
>>> +               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +void enqueue_pktio_interface(odp_packet_t pkt, odp_pktio_t pktio)
>>> +{
>>> +       odp_event_t ev;
>>> +       odp_queue_t defqueue;
>>> +
>>> +       defqueue  = odp_pktio_outq_getdef(pktio);
>>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>>> +
>>> +       ev = odp_packet_to_event(pkt);
>>> +       CU_ASSERT(odp_queue_enq(defqueue, ev) == 0);
>>> +}
>>> +
>>> +odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>>> +{
>>> +       odp_event_t ev;
>>> +
>>> +       ev = odp_schedule(queue, ns);
>>> +       return odp_packet_from_event(ev);
>>> +}
>>> +
>>> +odp_queue_t queue_create(char *queuename, bool sched)
>>> +{
>>> +       odp_queue_t queue;
>>> +       odp_queue_param_t qparam;
>>> +
>>> +       if (sched) {
>>> +               odp_queue_param_init(&qparam);
>>> +               qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST;
>>> +               qparam.sched.sync = ODP_SCHED_SYNC_NONE;
>>> +               qparam.sched.group = ODP_SCHED_GROUP_ALL;
>>> +
>>> +               queue = odp_queue_create(queuename,
>>> +                                        ODP_QUEUE_TYPE_SCHED,
>>> +                                        &qparam);
>>> +       } else {
>>> +               queue = odp_queue_create(queuename,
>>> +                                        ODP_QUEUE_TYPE_POLL,
>>> +                                        NULL);
>>> +       }
>>> +
>>> +       return queue;
>>> +}
>>> +
>>> +odp_packet_t create_packet(odp_pool_t pool, bool vlan,
>>> +                          odp_atomic_u32_t *seq, bool flag_udp)
>>> +{
>>> +       uint32_t seqno;
>>> +       odph_ethhdr_t *ethhdr;
>>> +       odph_udphdr_t *udp;
>>> +       odph_tcphdr_t *tcp;
>>> +       odph_ipv4hdr_t *ip;
>>> +       uint8_t payload_len;
>>> +       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>>> +       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>>> +       uint32_t addr = 0;
>>> +       uint32_t mask;
>>> +       int offset;
>>> +       odp_packet_t pkt;
>>> +       int packet_len = 0;
>>> +
>>> +       payload_len = sizeof(cls_test_packet_t);
>>> +       packet_len += ODPH_ETHHDR_LEN;
>>> +       packet_len += ODPH_IPV4HDR_LEN;
>>> +       if (flag_udp)
>>> +               packet_len += ODPH_UDPHDR_LEN;
>>> +       else
>>> +               packet_len += ODPH_TCPHDR_LEN;
>>> +       packet_len += payload_len;
>>> +
>>> +       if (vlan)
>>> +               packet_len += ODPH_VLANHDR_LEN;
>>> +
>>> +       pkt = odp_packet_alloc(pool, packet_len);
>>> +       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>>> +
>>> +       /* Ethernet Header */
>>> +       offset = 0;
>>> +       odp_packet_l2_offset_set(pkt, offset);
>>> +       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>>> +       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>>> +       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>>> +       offset += sizeof(odph_ethhdr_t);
>>> +       if (vlan) {
>>> +               /* Default vlan header */
>>> +               uint8_t *parseptr;
>>> +               odph_vlanhdr_t *vlan;
>>> +
>>> +               vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>>> +               parseptr = (uint8_t *)vlan;
>>> +               vlan->tci = odp_cpu_to_be_16(0);
>>> +               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>>> +               offset += sizeof(odph_vlanhdr_t);
>>> +               parseptr += sizeof(odph_vlanhdr_t);
>>> +               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>>> +               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> +       } else {
>>> +               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> +       }
>>> +
>>> +       odp_packet_l3_offset_set(pkt, offset);
>>> +
>>> +       /* ipv4 */
>>> +       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>> +
>>> +       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>>> +       ip->dst_addr = odp_cpu_to_be_32(addr);
>>> +
>>> +       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>>> +       ip->src_addr = odp_cpu_to_be_32(addr);
>>> +       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>>> +       if (flag_udp)
>>> +               ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN +
>>> payload_len +
>>> +                                              ODPH_IPV4HDR_LEN);
>>> +       else
>>> +               ip->tot_len = odp_cpu_to_be_16(ODPH_TCPHDR_LEN +
>>> payload_len +
>>> +                                              ODPH_IPV4HDR_LEN);
>>> +
>>> +       ip->ttl = 128;
>>> +       if (flag_udp)
>>> +               ip->proto = ODPH_IPPROTO_UDP;
>>> +       else
>>> +               ip->proto = ODPH_IPPROTO_TCP;
>>> +
>>> +       seqno = odp_atomic_fetch_inc_u32(seq);
>>> +       ip->id = odp_cpu_to_be_16(seqno);
>>> +       ip->chksum = 0;
>>> +       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>>> +       offset += ODPH_IPV4HDR_LEN;
>>> +
>>> +       /* udp */
>>> +       if (flag_udp) {
>>> +               odp_packet_l4_offset_set(pkt, offset);
>>> +               udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +               udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +               udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +               udp->length = odp_cpu_to_be_16(payload_len +
>>> ODPH_UDPHDR_LEN);
>>> +               udp->chksum = 0;
>>> +       } else {
>>> +               odp_packet_l4_offset_set(pkt, offset);
>>> +               tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +               tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +               tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +               tcp->hl = ODPH_TCPHDR_LEN / 4;
>>> +               /* TODO: checksum field has to be updated */
>>> +               tcp->cksm = 0;
>>> +       }
>>> +
>>> +       /* set pkt sequence number */
>>> +       cls_pkt_set_seq(pkt);
>>> +
>>> +       return pkt;
>>> +}
>>> diff --git a/test/validation/classification/odp_classification_test_pmr.c
>>> b/test/validation/classification/odp_classification_test_pmr.c
>>> new file mode 100644
>>> index 0000000..37de892
>>> --- /dev/null
>>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>>> @@ -0,0 +1,579 @@
>>> +/* Copyright (c) 2015, Linaro Limited
>>> + * All rights reserved.
>>> + *
>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>> + */
>>> +
>>> +#include "odp_classification_testsuites.h"
>>> +#include "classification.h"
>>> +#include <odp_cunit_common.h>
>>> +#include <odp/helper/eth.h>
>>> +#include <odp/helper/ip.h>
>>> +#include <odp/helper/udp.h>
>>> +#include <odp/helper/tcp.h>
>>> +
>>> +static odp_pool_t pool_default;
>>> +
>>> +/** sequence number of IP packets */
>>> +odp_atomic_u32_t seq;
>>> +
>>> +static int destroy_inq(odp_pktio_t pktio)
>>> +{
>>> +       odp_queue_t inq;
>>> +       odp_event_t ev;
>>> +
>>> +       inq = odp_pktio_inq_getdef(pktio);
>>> +
>>> +       if (inq == ODP_QUEUE_INVALID) {
>>> +               CU_FAIL("attempting to destroy invalid inq");
>>> +               return -1;
>>> +       }
>>> +
>>> +       if (0 > odp_pktio_inq_remdef(pktio))
>>> +               return -1;
>>> +
>>> +       while (1) {
>>> +               ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
>>> +
>>> +               if (ev != ODP_EVENT_INVALID)
>>> +                       odp_buffer_free(odp_buffer_from_event(ev));
>>> +               else
>>> +                       break;
>>> +       }
>>> +
>>> +       return odp_queue_destroy(inq);
>>> +}
>>> +
>>> +int classification_suite_pmr_init(void)
>>> +{
>>> +       odp_pool_t pool;
>>> +       odp_pool_param_t param;
>>> +
>>> +       odp_pool_param_init(&param);
>>> +       param.pkt.seg_len = SHM_PKT_BUF_SIZE;
>>> +       param.pkt.len     = SHM_PKT_BUF_SIZE;
>>> +       param.pkt.num     = SHM_PKT_NUM_BUFS;
>>> +       param.type        = ODP_POOL_PACKET;
>>> +
>>> +       pool = odp_pool_create("classification_pmr_pool", &param);
>>> +       if (ODP_POOL_INVALID == pool) {
>>> +               fprintf(stderr, "Packet pool creation failed.\n");
>>> +               return -1;
>>> +       }
>>> +
>>> +       pool_default = odp_pool_lookup("classification_pmr_pool");
>>> +       if (pool_default == ODP_POOL_INVALID)
>>> +               return -1;
>>> +
>>> +       odp_atomic_init_u32(&seq, 0);
>>> +       return 0;
>>> +}
>>> +
>>> +odp_pktio_t create_pktio(odp_queue_type_t q_type)
>>> +{
>>> +       odp_pktio_t pktio;
>>> +       odp_pktio_param_t pktio_param;
>>> +       odp_pool_t pool;
>>> +       int ret;
>>> +
>>> +       pool = odp_pool_lookup("classification_pmr_pool");
>>> +       if (pool == ODP_POOL_INVALID)
>>> +               return ODP_PKTIO_INVALID;
>>> +
>>> +       memset(&pktio_param, 0, sizeof(pktio_param));
>>
>> I posted a patch earlier to add the missing odp_pktio_param_init() API call.
>> We'll need to update this when that patch is reviewed/merged for
>> consistency.
>>
>>> +       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];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_DPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>>> +
>>> +       match.term = ODP_PMR_TCP_DPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "tcp_dport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "tcp_dport1");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(retqueue == queue);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +
>>> +       odp_packet_free(pkt);
>>> +
>>> +       /* Other packets are delivered to default queue */
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_tcp_sport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_tcphdr_t *tcp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_SPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_TCP_SPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "tcp_sport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "tcp_sport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_udp_dport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_udphdr_t *udp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_DPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_UDP_DPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "udp_dport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "udp_dport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       /* Other packets received in default queue */
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_udp_sport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_udphdr_t *udp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_SPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_UDP_SPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "udp_sport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "udp_sport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_ipproto(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       uint32_t seqno;
>>> +       uint8_t val;
>>> +       uint8_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = ODPH_IPPROTO_UDP;
>>> +       mask = 0xff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_IPPROTO;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       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 8840e53..74d1060 100644
>>> --- a/test/validation/classification/odp_classification_tests.c
>>> +++ b/test/validation/classification/odp_classification_tests.c
>>> @@ -11,50 +11,6 @@
>>>   #include <odp/helper/ip.h>
>>>   #include <odp/helper/udp.h>
>>>
>>> -#define SHM_PKT_NUM_BUFS        32
>>> -#define SHM_PKT_BUF_SIZE        1024
>>> -
>>> -/* Config values for Default CoS */
>>> -#define TEST_DEFAULT           1
>>> -#define        CLS_DEFAULT             0
>>> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>> -#define CLS_DEFAULT_SPORT      1024
>>> -#define CLS_DEFAULT_DPORT      2048
>>> -
>>> -/* Config values for Error CoS */
>>> -#define TEST_ERROR             1
>>> -#define CLS_ERROR              1
>>> -
>>> -/* Config values for PMR_CHAIN */
>>> -#define TEST_PMR_CHAIN         1
>>> -#define CLS_PMR_CHAIN_SRC      2
>>> -#define CLS_PMR_CHAIN_DST      3
>>> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>> -#define CLS_PMR_CHAIN_SPORT    3000
>>> -
>>> -/* Config values for PMR */
>>> -#define TEST_PMR               1
>>> -#define CLS_PMR                        4
>>> -#define CLS_PMR_SPORT          4000
>>> -
>>> -/* Config values for PMR SET */
>>> -#define TEST_PMR_SET           1
>>> -#define CLS_PMR_SET            5
>>> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>> -#define CLS_PMR_SET_SPORT      5000
>>> -
>>> -/* Config values for CoS L2 Priority */
>>> -#define TEST_L2_QOS            1
>>> -#define CLS_L2_QOS_0           6
>>> -#define CLS_L2_QOS_MAX         5
>>> -
>>> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>> -
>>> -/* Test Packet values */
>>> -#define DATA_MAGIC             0x01020304
>>> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> -
>>>   static odp_cos_t cos_list[CLS_ENTRIES];
>>>   static odp_pmr_t pmr_list[CLS_ENTRIES];
>>>   static odp_queue_t queue_list[CLS_ENTRIES];
>>> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>>>   /** sequence number of IP packets */
>>>   odp_atomic_u32_t seq;
>>>
>>> -typedef struct cls_test_packet {
>>> -       uint32be_t magic;
>>> -       uint32be_t seq;
>>> -} cls_test_packet_t;
>>> -
>>> -static inline
>>> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>>> *mask)
>>> -{
>>> -       int b[4];
>>> -       int qualifier = 32;
>>> -       int converted;
>>> -
>>> -       if (strchr(ipaddress, '/')) {
>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>>> -                               &b[3], &b[2], &b[1], &b[0],
>>> -                               &qualifier);
>>> -               if (5 != converted)
>>> -                       return -1;
>>> -       } else {
>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>>> -                               &b[3], &b[2], &b[1], &b[0]);
>>> -               if (4 != converted)
>>> -                       return -1;
>>> -       }
>>> -
>>> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>>> -               return -1;
>>> -       if (!qualifier || (qualifier > 32))
>>> -               return -1;
>>> -
>>> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>>> -       if (mask)
>>> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>>> -
>>> -       return 0;
>>> -}
>>> -
>>> -static inline
>>> -void enqueue_loop_interface(odp_packet_t pkt)
>>> -{
>>> -       odp_event_t ev;
>>> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
>>> -
>>> -       ev = odp_packet_to_event(pkt);
>>> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
>>> -               odp_packet_free(pkt);
>>> -}
>>> -
>>> -static inline
>>> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>>> -{
>>> -       odp_event_t ev;
>>> -
>>> -       ev = odp_schedule(queue, ns);
>>> -       return odp_packet_from_event(ev);
>>> -}
>>> -
>>> -static int cls_pkt_set_seq(odp_packet_t pkt)
>>> -{
>>> -       static uint32_t seq;
>>> -       cls_test_packet_t data;
>>> -       uint32_t offset;
>>> -       int status;
>>> -
>>> -       data.magic = DATA_MAGIC;
>>> -       data.seq = ++seq;
>>> -
>>> -       offset = odp_packet_l4_offset(pkt);
>>> -       CU_ASSERT_FATAL(offset != 0);
>>> -
>>> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
>>> -                                       sizeof(data), &data);
>>> -
>>> -       return status;
>>> -}
>>> -
>>> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>>> -{
>>> -       uint32_t offset;
>>> -       cls_test_packet_t data;
>>> -
>>> -       offset = odp_packet_l4_offset(pkt);
>>> -       if (offset) {
>>> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>>> -                                       sizeof(data), &data);
>>> -
>>> -               if (data.magic == DATA_MAGIC)
>>> -                       return data.seq;
>>> -       }
>>> -
>>> -       return TEST_SEQ_INVALID;
>>> -}
>>> -
>>>   static int destroy_inq(odp_pktio_t pktio)
>>>   {
>>>          odp_queue_t inq;
>>> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>>>
>>>          return odp_queue_destroy(inq);
>>>   }
>>> -odp_packet_t create_packet(bool vlan)
>>> -{
>>> -       uint32_t seqno;
>>> -       odph_ethhdr_t *ethhdr;
>>> -       odph_udphdr_t *udp;
>>> -       odph_ipv4hdr_t *ip;
>>> -       uint8_t payload_len;
>>> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>>> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>>> -       uint32_t addr = 0;
>>> -       uint32_t mask;
>>> -       int offset;
>>> -       odp_packet_t pkt;
>>> -       int packet_len = 0;
>>> -
>>> -       payload_len = sizeof(cls_test_packet_t);
>>> -       packet_len += ODPH_ETHHDR_LEN;
>>> -       packet_len += ODPH_IPV4HDR_LEN;
>>> -       packet_len += ODPH_UDPHDR_LEN;
>>> -       packet_len += payload_len;
>>> -
>>> -       if (vlan)
>>> -               packet_len += ODPH_VLANHDR_LEN;
>>> -
>>> -       pkt = odp_packet_alloc(pool_default, packet_len);
>>> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>>> -
>>> -       /* Ethernet Header */
>>> -       offset = 0;
>>> -       odp_packet_l2_offset_set(pkt, offset);
>>> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>>> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>>> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>>> -       offset += sizeof(odph_ethhdr_t);
>>> -       if (vlan) {
>>> -               /* Default vlan header */
>>> -               uint8_t *parseptr;
>>> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>>> -               parseptr = (uint8_t *)vlan;
>>> -               vlan->tci = odp_cpu_to_be_16(0);
>>> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>>> -               offset += sizeof(odph_vlanhdr_t);
>>> -               parseptr += sizeof(odph_vlanhdr_t);
>>> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>>> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> -       } else {
>>> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> -       }
>>> -
>>> -       odp_packet_l3_offset_set(pkt, offset);
>>> -
>>> -       /* ipv4 */
>>> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>> -
>>> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>>> -       ip->dst_addr = odp_cpu_to_be_32(addr);
>>> -
>>> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>>> -       ip->src_addr = odp_cpu_to_be_32(addr);
>>> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>>> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
>>> -                       ODPH_IPV4HDR_LEN);
>>> -       ip->ttl = 128;
>>> -       ip->proto = ODPH_IPPROTO_UDP;
>>> -       seqno = odp_atomic_fetch_inc_u32(&seq);
>>> -       ip->id = odp_cpu_to_be_16(seqno);
>>> -       ip->chksum = 0;
>>> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>>> -       offset += ODPH_IPV4HDR_LEN;
>>> -
>>> -       /* udp */
>>> -       odp_packet_l4_offset_set(pkt, offset);
>>> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
>>> -       udp->chksum = 0;
>>> -
>>> -       /* set pkt sequence number */
>>> -       cls_pkt_set_seq(pkt);
>>> -
>>> -       return pkt;
>>> -}
>>>
>>>   int classification_suite_init(void)
>>>   {
>>> -       odp_pool_t pool;
>>>          odp_pool_param_t param;
>>>          odp_queue_t inq_def;
>>>          odp_queue_param_t qparam;
>>> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>>>          param.pkt.num     = SHM_PKT_NUM_BUFS;
>>>          param.type        = ODP_POOL_PACKET;
>>>
>>> -       pool = odp_pool_create("classification_pool", &param);
>>> -       if (ODP_POOL_INVALID == pool) {
>>> +       pool_default = odp_pool_create("classification_pool", &param);
>>> +       if (ODP_POOL_INVALID == pool_default) {
>>>                  fprintf(stderr, "Packet pool creation failed.\n");
>>>                  return -1;
>>>          }
>>>
>>> -       pool_default = odp_pool_lookup("classification_pool");
>>> -       if (pool_default == ODP_POOL_INVALID)
>>> -               return -1;
>>> -
>>>          memset(&pktio_param, 0, sizeof(pktio_param));
>>
>> Same comment as above here
>>
>>>          pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>>>
>>> @@ -394,6 +169,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,
>>> @@ -459,10 +235,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);
>>> @@ -472,25 +250,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);
>>>   }
>>>
>>> @@ -526,16 +308,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);
>>>   }
>>> @@ -575,15 +360,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);
>>> @@ -666,19 +452,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);
>>>          }
>>>   }
>>> @@ -732,16 +520,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);
>>>   }
>>>
>>> @@ -807,10 +597,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);
>>> @@ -819,10 +611,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
>>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> https://lists.linaro.org/mailman/listinfo/lng-odp
Ivan Khoronzhuk Oct. 15, 2015, 11:23 a.m. UTC | #5
Hi, Bala

Just compared this version with requirements for v2 and saw some mistmaches.
I didn't analize it deeply, seemply checked what was needed to be changed.
See comments below.

Sorry, I haven't found v4, and haven't revewed v3.

On 14.10.15 08:03, Balasubramanian Manoharan 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>
> ---
> v5: rebase on latest api-next
>
>   helper/include/odp/helper/tcp.h                    |   1 +
>   test/validation/classification/Makefile.am         |   2 +
>   test/validation/classification/classification.c    |   5 +
>   test/validation/classification/classification.h    |  44 ++
>   .../classification/odp_classification_common.c     | 252 +++++++++
>   .../classification/odp_classification_test_pmr.c   | 579 +++++++++++++++++++++
>   .../classification/odp_classification_tests.c      | 309 ++---------
>   .../classification/odp_classification_testsuites.h |  15 +-
>   8 files changed, 948 insertions(+), 259 deletions(-)
>   create mode 100644 test/validation/classification/odp_classification_common.c
>   create mode 100644 test/validation/classification/odp_classification_test_pmr.c
>
> diff --git a/helper/include/odp/helper/tcp.h b/helper/include/odp/helper/tcp.h
> index defe422..42f0cbe 100644
> --- a/helper/include/odp/helper/tcp.h
> +++ b/helper/include/odp/helper/tcp.h
> @@ -26,6 +26,7 @@ extern "C" {
>    *  @{
>    */
>
> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
>
>   /** TCP header */
>   typedef struct ODP_PACKED {
> diff --git a/test/validation/classification/Makefile.am b/test/validation/classification/Makefile.am
> index 5881665..4235309 100644
> --- a/test/validation/classification/Makefile.am
> +++ b/test/validation/classification/Makefile.am
> @@ -3,6 +3,8 @@ include ../Makefile.inc
>   noinst_LTLIBRARIES = libtestclassification.la
>   libtestclassification_la_SOURCES = odp_classification_basic.c \
>   			       odp_classification_tests.c \
> +			       odp_classification_test_pmr.c \
> +			       odp_classification_common.c \
>   			       classification.c
>
>   bin_PROGRAMS = classification_main$(EXEEXT)
> diff --git a/test/validation/classification/classification.c b/test/validation/classification/classification.c
> index d0fef93..6641893 100644
> --- a/test/validation/classification/classification.c
> +++ b/test/validation/classification/classification.c
> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>   	{ .pName = "classification basic",
>   			.pTests = classification_suite_basic,
>   	},
> +	{ .pName = "classification pmr tests",
> +			.pTests = classification_suite_pmr,
> +			.pInitFunc = classification_suite_pmr_init,
> +			.pCleanupFunc = classification_suite_pmr_term,
> +	},
>   	{ .pName = "classification tests",
>   			.pTests = classification_suite,
>   			.pInitFunc = classification_suite_init,
> diff --git a/test/validation/classification/classification.h b/test/validation/classification/classification.h
> index d2847e5..de9c37e 100644
> --- a/test/validation/classification/classification.h
> +++ b/test/validation/classification/classification.h
> @@ -9,6 +9,50 @@
>
>   #include <CUnit/Basic.h>
>
> +#define SHM_PKT_NUM_BUFS        32
> +#define SHM_PKT_BUF_SIZE        1024
> +
> +/* Config values for Default CoS */
> +#define TEST_DEFAULT		1
> +#define	CLS_DEFAULT		0
> +#define CLS_DEFAULT_SADDR	"10.0.0.1/32"
> +#define CLS_DEFAULT_DADDR	"10.0.0.100/32"
> +#define CLS_DEFAULT_SPORT	1024
> +#define CLS_DEFAULT_DPORT	2048
> +
> +/* Config values for Error CoS */
> +#define TEST_ERROR		1
> +#define CLS_ERROR		1
> +
> +/* Config values for PMR_CHAIN */
> +#define TEST_PMR_CHAIN		1
> +#define CLS_PMR_CHAIN_SRC	2
> +#define CLS_PMR_CHAIN_DST	3
> +#define CLS_PMR_CHAIN_SADDR	"10.0.0.5/32"
> +#define CLS_PMR_CHAIN_SPORT	3000
> +
> +/* Config values for PMR */
> +#define TEST_PMR		1
> +#define CLS_PMR			4
> +#define CLS_PMR_SPORT		4000
> +
> +/* Config values for PMR SET */
> +#define TEST_PMR_SET		1
> +#define CLS_PMR_SET		5
> +#define CLS_PMR_SET_SADDR	"10.0.0.6/32"
> +#define CLS_PMR_SET_SPORT	5000
> +
> +/* Config values for CoS L2 Priority */
> +#define TEST_L2_QOS		1
> +#define CLS_L2_QOS_0		6
> +#define CLS_L2_QOS_MAX		5
> +
> +#define CLS_ENTRIES		(CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
> +
> +/* Test Packet values */
> +#define DATA_MAGIC		0x01020304
> +#define TEST_SEQ_INVALID	((uint32_t)~0)
> +
>   /* test functions: */
>   void classification_test_create_cos(void);
>   void classification_test_destroy_cos(void);
> diff --git a/test/validation/classification/odp_classification_common.c b/test/validation/classification/odp_classification_common.c
> new file mode 100644
> index 0000000..b975dfb
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_common.c
> @@ -0,0 +1,252 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:	BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.h"
> +#include "classification.h"
> +#include <odp_cunit_common.h>
> +#include <odp/helper/eth.h>
> +#include <odp/helper/ip.h>
> +#include <odp/helper/udp.h>
> +#include <odp/helper/tcp.h>
> +
> +typedef struct cls_test_packet {
> +	uint32be_t magic;
> +	uint32be_t seq;

Why be?
Seems you wanted to change it.
"
But I think there is a potential bug since get_seq() and set_seq() function is not converting this cls_test_packet_t variables to cpu_endian before accessing the value.
I will update in the next patch.
"

> +} 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);

Seems last time I saw it you was fine to change this to read the header length from
tcp header field.

> +
> +	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);

same here.

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

Better to use "seq" internally.
I poroposed to delete this static var from idividual test and leave it in common.
See below.

> +{
> +	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..37de892
> --- /dev/null
> +++ b/test/validation/classification/odp_classification_test_pmr.c
> @@ -0,0 +1,579 @@
> +/* Copyright (c) 2015, Linaro Limited
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:	BSD-3-Clause
> + */
> +
> +#include "odp_classification_testsuites.h"
> +#include "classification.h"
> +#include <odp_cunit_common.h>
> +#include <odp/helper/eth.h>
> +#include <odp/helper/ip.h>
> +#include <odp/helper/udp.h>
> +#include <odp/helper/tcp.h>
> +
> +static odp_pool_t pool_default;
> +
> +/** sequence number of IP packets */
> +odp_atomic_u32_t seq;
> +
> +static int destroy_inq(odp_pktio_t pktio)

Seems you agreeed tom make it common.

> +{
> +	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");

You changed name but agreed to delete this redundancy from here.
This test doesn't check pool API here, so better to remove it.

> +	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];
> +	odp_pmr_match_t match;
> +
> +	val = CLS_DEFAULT_DPORT;
> +	mask = 0xffff;
> +	seqno = 0;
> +
> +	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +	CU_ASSERT(pktio != ODP_PKTIO_INVALID);
> +	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +	CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
> +
> +	match.term = ODP_PMR_TCP_DPORT;
> +	match.val = &val;
> +	match.mask = &mask;
> +	match.val_sz = sizeof(val);
> +
> +	pmr = odp_pmr_create(&match);
> +	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);

seq is not used anywere in the code, it's not required to know this value.
If value is needed to know, the cls_pkt_get_seq() is used.
Why not simply use common var in common file.
If you want to reset it to 0 for each test, then add common function like
set seq or cls_reset_pkt_seq() and call it at init. Then we don't need to
pass redundant argument each time when create packet.

> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(retqueue == queue);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +
> +	odp_packet_free(pkt);
> +
> +	/* Other packets are delivered to default queue */
> +	pkt = create_packet(pool_default, false, &seq, false);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == defqueue);
> +
> +	odp_packet_free(pkt);
> +	odp_cos_destroy(cos);
> +	odp_pmr_destroy(pmr);
> +	destroy_inq(pktio);
> +	odp_queue_destroy(queue);
> +	odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_tcp_sport(void)
> +{
> +	odp_packet_t pkt;
> +	odph_tcphdr_t *tcp;
> +	uint32_t seqno;
> +	uint16_t val;
> +	uint16_t mask;
> +	int retval;
> +	odp_pktio_t pktio;
> +	odp_queue_t queue;
> +	odp_queue_t retqueue;
> +	odp_queue_t defqueue;
> +	odp_pmr_t pmr;
> +	odp_cos_t cos;
> +	char cosname[ODP_QUEUE_NAME_LEN];
> +	char queuename[ODP_QUEUE_NAME_LEN];
> +	odp_pmr_match_t match;
> +
> +	val = CLS_DEFAULT_SPORT;
> +	mask = 0xffff;
> +	seqno = 0;
> +
> +	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +	match.term = ODP_PMR_TCP_SPORT;
> +	match.val = &val;
> +	match.mask = &mask;
> +	match.val_sz = sizeof(val);
> +
> +	pmr = odp_pmr_create(&match);
> +	CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +	sprintf(cosname, "tcp_sport");
> +	cos = odp_cos_create(cosname);
> +	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +	sprintf(queuename, "%s", "tcp_sport");
> +
> +	queue = queue_create(queuename, true);
> +	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +	retval = odp_cos_queue_set(cos, queue);
> +	CU_ASSERT(retval == 0);
> +
> +	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +	CU_ASSERT(retval == 0);
> +
> +	pkt = create_packet(pool_default, false, &seq, false);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == queue);
> +	odp_packet_free(pkt);
> +
> +	pkt = create_packet(pool_default, false, &seq, false);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == defqueue);
> +
> +	odp_packet_free(pkt);
> +	odp_cos_destroy(cos);
> +	odp_pmr_destroy(pmr);
> +	destroy_inq(pktio);
> +	odp_queue_destroy(queue);
> +	odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_udp_dport(void)
> +{
> +	odp_packet_t pkt;
> +	odph_udphdr_t *udp;
> +	uint32_t seqno;
> +	uint16_t val;
> +	uint16_t mask;
> +	int retval;
> +	odp_pktio_t pktio;
> +	odp_queue_t queue;
> +	odp_queue_t retqueue;
> +	odp_queue_t defqueue;
> +	odp_pmr_t pmr;
> +	odp_cos_t cos;
> +	char cosname[ODP_QUEUE_NAME_LEN];
> +	char queuename[ODP_QUEUE_NAME_LEN];
> +	odp_pmr_match_t match;
> +
> +	val = CLS_DEFAULT_DPORT;
> +	mask = 0xffff;
> +	seqno = 0;
> +
> +	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +	match.term = ODP_PMR_UDP_DPORT;
> +	match.val = &val;
> +	match.mask = &mask;
> +	match.val_sz = sizeof(val);
> +
> +	pmr = odp_pmr_create(&match);
> +	CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +	sprintf(cosname, "udp_dport");
> +	cos = odp_cos_create(cosname);
> +	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +	sprintf(queuename, "%s", "udp_dport");
> +
> +	queue = queue_create(queuename, true);
> +	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +	retval = odp_cos_queue_set(cos, queue);
> +	CU_ASSERT(retval == 0);
> +
> +	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +	CU_ASSERT(retval == 0);
> +
> +	pkt = create_packet(pool_default, false, &seq, true);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == queue);
> +	odp_packet_free(pkt);
> +
> +	/* Other packets received in default queue */
> +	pkt = create_packet(pool_default, false, &seq, true);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == defqueue);
> +
> +	odp_packet_free(pkt);
> +	odp_cos_destroy(cos);
> +	odp_pmr_destroy(pmr);
> +	destroy_inq(pktio);
> +	odp_queue_destroy(queue);
> +	odp_pktio_close(pktio);
> +}
> +
> +static void classification_test_pmr_term_udp_sport(void)
> +{
> +	odp_packet_t pkt;
> +	odph_udphdr_t *udp;
> +	uint32_t seqno;
> +	uint16_t val;
> +	uint16_t mask;
> +	int retval;
> +	odp_pktio_t pktio;
> +	odp_queue_t queue;
> +	odp_queue_t retqueue;
> +	odp_queue_t defqueue;
> +	odp_pmr_t pmr;
> +	odp_cos_t cos;
> +	char cosname[ODP_QUEUE_NAME_LEN];
> +	char queuename[ODP_QUEUE_NAME_LEN];
> +	odp_pmr_match_t match;
> +
> +	val = CLS_DEFAULT_SPORT;
> +	mask = 0xffff;
> +	seqno = 0;
> +
> +	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +	match.term = ODP_PMR_UDP_SPORT;
> +	match.val = &val;
> +	match.mask = &mask;
> +	match.val_sz = sizeof(val);
> +
> +	pmr = odp_pmr_create(&match);
> +	CU_ASSERT(pmr != ODP_PMR_INVAL);
> +
> +	sprintf(cosname, "udp_sport");
> +	cos = odp_cos_create(cosname);
> +	CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
> +
> +	sprintf(queuename, "%s", "udp_sport");
> +
> +	queue = queue_create(queuename, true);
> +	CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
> +
> +	retval = odp_cos_queue_set(cos, queue);
> +	CU_ASSERT(retval == 0);
> +
> +	retval = odp_pktio_pmr_cos(pmr, pktio, cos);
> +	CU_ASSERT(retval == 0);
> +
> +	pkt = create_packet(pool_default, false, &seq, true);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
> +	CU_ASSERT(retqueue == queue);
> +	odp_packet_free(pkt);
> +
> +	pkt = create_packet(pool_default, false, &seq, true);
> +	seqno = cls_pkt_get_seq(pkt);
> +	CU_ASSERT(seqno != TEST_SEQ_INVALID);
> +
> +	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> +	udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
> +
> +	enqueue_pktio_interface(pkt, pktio);
> +
> +	pkt = receive_packet(&retqueue, ODP_TIME_SEC);
> +	CU_ASSERT(pkt != ODP_PACKET_INVALID);
> +	CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);

Forget to remove?
TEST_SEQ_INVALID check, why are you doing it here?
If it's needed then why it's not done a little above and in functions:
classification_test_pmr_term_udp_dport();
classification_test_pmr_term_tcp_sport();
classification_test_pmr_term_tcp_dport();

> +	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];
> +	odp_pmr_match_t match;
> +
> +	val = ODPH_IPPROTO_UDP;
> +	mask = 0xff;
> +	seqno = 0;
> +
> +	pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
> +	defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
> +
> +	match.term = ODP_PMR_IPPROTO;
> +	match.val = &val;
> +	match.mask = &mask;
> +	match.val_sz = sizeof(val);
> +
> +	pmr = odp_pmr_create(&match);
> +	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);

redundancy like above?

> +	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 8840e53..74d1060 100644
> --- a/test/validation/classification/odp_classification_tests.c
> +++ b/test/validation/classification/odp_classification_tests.c
> @@ -11,50 +11,6 @@
>   #include <odp/helper/ip.h>
>   #include <odp/helper/udp.h>
>
> -#define SHM_PKT_NUM_BUFS        32
> -#define SHM_PKT_BUF_SIZE        1024
> -
> -/* Config values for Default CoS */
> -#define TEST_DEFAULT		1
> -#define	CLS_DEFAULT		0
> -#define CLS_DEFAULT_SADDR	"10.0.0.1/32"
> -#define CLS_DEFAULT_DADDR	"10.0.0.100/32"
> -#define CLS_DEFAULT_SPORT	1024
> -#define CLS_DEFAULT_DPORT	2048
> -
> -/* Config values for Error CoS */
> -#define TEST_ERROR		1
> -#define CLS_ERROR		1
> -
> -/* Config values for PMR_CHAIN */
> -#define TEST_PMR_CHAIN		1
> -#define CLS_PMR_CHAIN_SRC	2
> -#define CLS_PMR_CHAIN_DST	3
> -#define CLS_PMR_CHAIN_SADDR	"10.0.0.5/32"
> -#define CLS_PMR_CHAIN_SPORT	3000
> -
> -/* Config values for PMR */
> -#define TEST_PMR		1
> -#define CLS_PMR			4
> -#define CLS_PMR_SPORT		4000
> -
> -/* Config values for PMR SET */
> -#define TEST_PMR_SET		1
> -#define CLS_PMR_SET		5
> -#define CLS_PMR_SET_SADDR	"10.0.0.6/32"
> -#define CLS_PMR_SET_SPORT	5000
> -
> -/* Config values for CoS L2 Priority */
> -#define TEST_L2_QOS		1
> -#define CLS_L2_QOS_0		6
> -#define CLS_L2_QOS_MAX		5
> -
> -#define CLS_ENTRIES		(CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
> -
> -/* Test Packet values */
> -#define DATA_MAGIC		0x01020304
> -#define TEST_SEQ_INVALID	((uint32_t)~0)
> -
>   static odp_cos_t cos_list[CLS_ENTRIES];
>   static odp_pmr_t pmr_list[CLS_ENTRIES];
>   static odp_queue_t queue_list[CLS_ENTRIES];
> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>   /** sequence number of IP packets */
>   odp_atomic_u32_t seq;
>
> -typedef struct cls_test_packet {
> -	uint32be_t magic;
> -	uint32be_t seq;
> -} cls_test_packet_t;
> -
> -static inline
> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t *mask)
> -{
> -	int b[4];
> -	int qualifier = 32;
> -	int converted;
> -
> -	if (strchr(ipaddress, '/')) {
> -		converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
> -				&b[3], &b[2], &b[1], &b[0],
> -				&qualifier);
> -		if (5 != converted)
> -			return -1;
> -	} else {
> -		converted = sscanf(ipaddress, "%d.%d.%d.%d",
> -				&b[3], &b[2], &b[1], &b[0]);
> -		if (4 != converted)
> -			return -1;
> -	}
> -
> -	if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
> -		return -1;
> -	if (!qualifier || (qualifier > 32))
> -		return -1;
> -
> -	*addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
> -	if (mask)
> -		*mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
> -
> -	return 0;
> -}
> -
> -static inline
> -void enqueue_loop_interface(odp_packet_t pkt)
> -{
> -	odp_event_t ev;
> -	odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
> -
> -	ev = odp_packet_to_event(pkt);
> -	if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
> -		odp_packet_free(pkt);
> -}
> -
> -static inline
> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
> -{
> -	odp_event_t ev;
> -
> -	ev = odp_schedule(queue, ns);
> -	return odp_packet_from_event(ev);
> -}
> -
> -static int cls_pkt_set_seq(odp_packet_t pkt)
> -{
> -	static uint32_t seq;
> -	cls_test_packet_t data;
> -	uint32_t offset;
> -	int status;
> -
> -	data.magic = DATA_MAGIC;
> -	data.seq = ++seq;
> -
> -	offset = odp_packet_l4_offset(pkt);
> -	CU_ASSERT_FATAL(offset != 0);
> -
> -	status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
> -					sizeof(data), &data);
> -
> -	return status;
> -}
> -
> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
> -{
> -	uint32_t offset;
> -	cls_test_packet_t data;
> -
> -	offset = odp_packet_l4_offset(pkt);
> -	if (offset) {
> -		odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
> -					sizeof(data), &data);
> -
> -		if (data.magic == DATA_MAGIC)
> -			return data.seq;
> -	}
> -
> -	return TEST_SEQ_INVALID;
> -}
> -
>   static int destroy_inq(odp_pktio_t pktio)
>   {
>   	odp_queue_t inq;
> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>
>   	return odp_queue_destroy(inq);
>   }
> -odp_packet_t create_packet(bool vlan)
> -{
> -	uint32_t seqno;
> -	odph_ethhdr_t *ethhdr;
> -	odph_udphdr_t *udp;
> -	odph_ipv4hdr_t *ip;
> -	uint8_t payload_len;
> -	char src_mac[ODPH_ETHADDR_LEN]  = {0};
> -	char dst_mac[ODPH_ETHADDR_LEN] = {0};
> -	uint32_t addr = 0;
> -	uint32_t mask;
> -	int offset;
> -	odp_packet_t pkt;
> -	int packet_len = 0;
> -
> -	payload_len = sizeof(cls_test_packet_t);
> -	packet_len += ODPH_ETHHDR_LEN;
> -	packet_len += ODPH_IPV4HDR_LEN;
> -	packet_len += ODPH_UDPHDR_LEN;
> -	packet_len += payload_len;
> -
> -	if (vlan)
> -		packet_len += ODPH_VLANHDR_LEN;
> -
> -	pkt = odp_packet_alloc(pool_default, packet_len);
> -	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
> -
> -	/* Ethernet Header */
> -	offset = 0;
> -	odp_packet_l2_offset_set(pkt, offset);
> -	ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
> -	memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
> -	memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
> -	offset += sizeof(odph_ethhdr_t);
> -	if (vlan) {
> -		/* Default vlan header */
> -		uint8_t *parseptr;
> -		odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
> -		parseptr = (uint8_t *)vlan;
> -		vlan->tci = odp_cpu_to_be_16(0);
> -		vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
> -		offset += sizeof(odph_vlanhdr_t);
> -		parseptr += sizeof(odph_vlanhdr_t);
> -		uint16be_t *type = (uint16be_t *)(void *)parseptr;
> -		*type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> -	} else {
> -		ethhdr->type =	odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
> -	}
> -
> -	odp_packet_l3_offset_set(pkt, offset);
> -
> -	/* ipv4 */
> -	ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
> -
> -	parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
> -	ip->dst_addr = odp_cpu_to_be_32(addr);
> -
> -	parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
> -	ip->src_addr = odp_cpu_to_be_32(addr);
> -	ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
> -	ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
> -			ODPH_IPV4HDR_LEN);
> -	ip->ttl = 128;
> -	ip->proto = ODPH_IPPROTO_UDP;
> -	seqno = odp_atomic_fetch_inc_u32(&seq);
> -	ip->id = odp_cpu_to_be_16(seqno);
> -	ip->chksum = 0;
> -	ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
> -	offset += ODPH_IPV4HDR_LEN;
> -
> -	/* udp */
> -	odp_packet_l4_offset_set(pkt, offset);
> -	udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
> -	udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
> -	udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
> -	udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
> -	udp->chksum = 0;
> -
> -	/* set pkt sequence number */
> -	cls_pkt_set_seq(pkt);
> -
> -	return pkt;
> -}
>
>   int classification_suite_init(void)
>   {
> -	odp_pool_t pool;
>   	odp_pool_param_t param;
>   	odp_queue_t inq_def;
>   	odp_queue_param_t qparam;
> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>   	param.pkt.num     = SHM_PKT_NUM_BUFS;
>   	param.type        = ODP_POOL_PACKET;
>
> -	pool = odp_pool_create("classification_pool", &param);
> -	if (ODP_POOL_INVALID == pool) {
> +	pool_default = odp_pool_create("classification_pool", &param);
> +	if (ODP_POOL_INVALID == pool_default) {
>   		fprintf(stderr, "Packet pool creation failed.\n");
>   		return -1;
>   	}
>
> -	pool_default = odp_pool_lookup("classification_pool");
> -	if (pool_default == ODP_POOL_INVALID)
> -		return -1;
> -
>   	memset(&pktio_param, 0, sizeof(pktio_param));
>   	pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>
> @@ -394,6 +169,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,
> @@ -459,10 +235,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);
> @@ -472,25 +250,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);
>   }
>
> @@ -526,16 +308,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);
>   }
> @@ -575,15 +360,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);
> @@ -666,19 +452,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);
>   	}
>   }
> @@ -732,16 +520,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);
>   }
>
> @@ -807,10 +597,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);
> @@ -819,10 +611,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);
>
Balasubramanian Manoharan Oct. 15, 2015, 1:39 p.m. UTC | #6
Hi Ivan,

Thanks for pointing out the issues. Since this patch is merged I will
create a bug and add the missing points.
Pls provide your inputs on the comments.

On 15 October 2015 at 16:53, Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> wrote:
> Hi, Bala
>
> Just compared this version with requirements for v2 and saw some mistmaches.
> I didn't analize it deeply, seemply checked what was needed to be changed.
> See comments below.
>
> Sorry, I haven't found v4, and haven't revewed v3.
>
>
> On 14.10.15 08:03, Balasubramanian Manoharan 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>
>> ---
>> v5: rebase on latest api-next
>>
>>   helper/include/odp/helper/tcp.h                    |   1 +
>>   test/validation/classification/Makefile.am         |   2 +
>>   test/validation/classification/classification.c    |   5 +
>>   test/validation/classification/classification.h    |  44 ++
>>   .../classification/odp_classification_common.c     | 252 +++++++++
>>   .../classification/odp_classification_test_pmr.c   | 579
>> +++++++++++++++++++++
>>   .../classification/odp_classification_tests.c      | 309 ++---------
>>   .../classification/odp_classification_testsuites.h |  15 +-
>>   8 files changed, 948 insertions(+), 259 deletions(-)
>>   create mode 100644
>> test/validation/classification/odp_classification_common.c
>>   create mode 100644
>> test/validation/classification/odp_classification_test_pmr.c
>>
>> diff --git a/helper/include/odp/helper/tcp.h
>> b/helper/include/odp/helper/tcp.h
>> index defe422..42f0cbe 100644
>> --- a/helper/include/odp/helper/tcp.h
>> +++ b/helper/include/odp/helper/tcp.h
>> @@ -26,6 +26,7 @@ extern "C" {
>>    *  @{
>>    */
>>
>> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
>>
>>   /** TCP header */
>>   typedef struct ODP_PACKED {
>> diff --git a/test/validation/classification/Makefile.am
>> b/test/validation/classification/Makefile.am
>> index 5881665..4235309 100644
>> --- a/test/validation/classification/Makefile.am
>> +++ b/test/validation/classification/Makefile.am
>> @@ -3,6 +3,8 @@ include ../Makefile.inc
>>   noinst_LTLIBRARIES = libtestclassification.la
>>   libtestclassification_la_SOURCES = odp_classification_basic.c \
>>                                odp_classification_tests.c \
>> +                              odp_classification_test_pmr.c \
>> +                              odp_classification_common.c \
>>                                classification.c
>>
>>   bin_PROGRAMS = classification_main$(EXEEXT)
>> diff --git a/test/validation/classification/classification.c
>> b/test/validation/classification/classification.c
>> index d0fef93..6641893 100644
>> --- a/test/validation/classification/classification.c
>> +++ b/test/validation/classification/classification.c
>> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>>         { .pName = "classification basic",
>>                         .pTests = classification_suite_basic,
>>         },
>> +       { .pName = "classification pmr tests",
>> +                       .pTests = classification_suite_pmr,
>> +                       .pInitFunc = classification_suite_pmr_init,
>> +                       .pCleanupFunc = classification_suite_pmr_term,
>> +       },
>>         { .pName = "classification tests",
>>                         .pTests = classification_suite,
>>                         .pInitFunc = classification_suite_init,
>> diff --git a/test/validation/classification/classification.h
>> b/test/validation/classification/classification.h
>> index d2847e5..de9c37e 100644
>> --- a/test/validation/classification/classification.h
>> +++ b/test/validation/classification/classification.h
>> @@ -9,6 +9,50 @@
>>
>>   #include <CUnit/Basic.h>
>>
>> +#define SHM_PKT_NUM_BUFS        32
>> +#define SHM_PKT_BUF_SIZE        1024
>> +
>> +/* Config values for Default CoS */
>> +#define TEST_DEFAULT           1
>> +#define        CLS_DEFAULT             0
>> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>> +#define CLS_DEFAULT_SPORT      1024
>> +#define CLS_DEFAULT_DPORT      2048
>> +
>> +/* Config values for Error CoS */
>> +#define TEST_ERROR             1
>> +#define CLS_ERROR              1
>> +
>> +/* Config values for PMR_CHAIN */
>> +#define TEST_PMR_CHAIN         1
>> +#define CLS_PMR_CHAIN_SRC      2
>> +#define CLS_PMR_CHAIN_DST      3
>> +#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>> +#define CLS_PMR_CHAIN_SPORT    3000
>> +
>> +/* Config values for PMR */
>> +#define TEST_PMR               1
>> +#define CLS_PMR                        4
>> +#define CLS_PMR_SPORT          4000
>> +
>> +/* Config values for PMR SET */
>> +#define TEST_PMR_SET           1
>> +#define CLS_PMR_SET            5
>> +#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>> +#define CLS_PMR_SET_SPORT      5000
>> +
>> +/* Config values for CoS L2 Priority */
>> +#define TEST_L2_QOS            1
>> +#define CLS_L2_QOS_0           6
>> +#define CLS_L2_QOS_MAX         5
>> +
>> +#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>> +
>> +/* Test Packet values */
>> +#define DATA_MAGIC             0x01020304
>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> +
>>   /* test functions: */
>>   void classification_test_create_cos(void);
>>   void classification_test_destroy_cos(void);
>> diff --git a/test/validation/classification/odp_classification_common.c
>> b/test/validation/classification/odp_classification_common.c
>> new file mode 100644
>> index 0000000..b975dfb
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_common.c
>> @@ -0,0 +1,252 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.h"
>> +#include "classification.h"
>> +#include <odp_cunit_common.h>
>> +#include <odp/helper/eth.h>
>> +#include <odp/helper/ip.h>
>> +#include <odp/helper/udp.h>
>> +#include <odp/helper/tcp.h>
>> +
>> +typedef struct cls_test_packet {
>> +       uint32be_t magic;
>> +       uint32be_t seq;
>
>
> Why be?
> Seems you wanted to change it.
> "
> But I think there is a potential bug since get_seq() and set_seq() function
> is not converting this cls_test_packet_t variables to cpu_endian before
> accessing the value.
> I will update in the next patch.
> "

Actually I dint want to change the "be" variable format, I was only
concerned about a potential bug.
uint32be_t is just a typedef with __attribute__(bitwise) so that
Sparse can generate warning and since we are sending the packet
through the interface it is better to note that the packets are in
network byte order hence it is better to define these variables as Big
Endian.

The bug which I thought was there was actually incorrectly noted by me
as since the magic is generated by the same machine which receives the
packet there will not be an issue.

>
>> +} 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);
>
>
> Seems last time I saw it you was fine to change this to read the header
> length from
> tcp header field.

Yes. But since we only receive locally generated packet I retained a
hard-coded TCP header length.

>
>> +
>> +       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);
>
>
> same here.
>
>
>> +
>> +       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)
>
>
> Better to use "seq" internally.
> I poroposed to delete this static var from idividual test and leave it in
> common.
> See below.

This "seq" variable is used to fill the "identification" field in ipv4
header and it is NOT the seq number we use in the cls_pkt_get_seq()
function. It is better to have this sequence individually controllable
per module so that during debug it is easy to differentiate packets
belonging to different modules. Lets say if we capture the packets in
wireshark if the user assigns different "seq" number per module then
the packets are easily traceable.

>
>
>> +{
>> +       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..37de892
>> --- /dev/null
>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>> @@ -0,0 +1,579 @@
>> +/* Copyright (c) 2015, Linaro Limited
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include "odp_classification_testsuites.h"
>> +#include "classification.h"
>> +#include <odp_cunit_common.h>
>> +#include <odp/helper/eth.h>
>> +#include <odp/helper/ip.h>
>> +#include <odp/helper/udp.h>
>> +#include <odp/helper/tcp.h>
>> +
>> +static odp_pool_t pool_default;
>> +
>> +/** sequence number of IP packets */
>> +odp_atomic_u32_t seq;
>> +
>> +static int destroy_inq(odp_pktio_t pktio)
>
>
> Seems you agreeed tom make it common.

Oops. I missed this. Will add this as a separate patch.

>
>
>> +{
>> +       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");
>
>
> You changed name but agreed to delete this redundancy from here.
> This test doesn't check pool API here, so better to remove it.

I think i modified this in one module and forgot to change in other module.

>
>
>> +       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];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_DPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>> +
>> +       match.term = ODP_PMR_TCP_DPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       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);
>
>
> seq is not used anywere in the code, it's not required to know this value.
> If value is needed to know, the cls_pkt_get_seq() is used.
> Why not simply use common var in common file.
> If you want to reset it to 0 for each test, then add common function like
> set seq or cls_reset_pkt_seq() and call it at init. Then we don't need to
> pass redundant argument each time when create packet.

Actually only the Common variable is only used for the sequence number
inside the packet.
This sequence number is used to update the "Identification" field in
ipv4 header for debug purpose as explained above.

>
>
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(retqueue == queue);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +
>> +       odp_packet_free(pkt);
>> +
>> +       /* Other packets are delivered to default queue */
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_tcp_sport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_tcphdr_t *tcp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_SPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_TCP_SPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "tcp_sport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "tcp_sport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, false);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_udp_dport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_udphdr_t *udp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_DPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_UDP_DPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "udp_dport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "udp_dport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       /* Other packets received in default queue */
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == defqueue);
>> +
>> +       odp_packet_free(pkt);
>> +       odp_cos_destroy(cos);
>> +       odp_pmr_destroy(pmr);
>> +       destroy_inq(pktio);
>> +       odp_queue_destroy(queue);
>> +       odp_pktio_close(pktio);
>> +}
>> +
>> +static void classification_test_pmr_term_udp_sport(void)
>> +{
>> +       odp_packet_t pkt;
>> +       odph_udphdr_t *udp;
>> +       uint32_t seqno;
>> +       uint16_t val;
>> +       uint16_t mask;
>> +       int retval;
>> +       odp_pktio_t pktio;
>> +       odp_queue_t queue;
>> +       odp_queue_t retqueue;
>> +       odp_queue_t defqueue;
>> +       odp_pmr_t pmr;
>> +       odp_cos_t cos;
>> +       char cosname[ODP_QUEUE_NAME_LEN];
>> +       char queuename[ODP_QUEUE_NAME_LEN];
>> +       odp_pmr_match_t match;
>> +
>> +       val = CLS_DEFAULT_SPORT;
>> +       mask = 0xffff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_UDP_SPORT;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>> +
>> +       sprintf(cosname, "udp_sport");
>> +       cos = odp_cos_create(cosname);
>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>> +
>> +       sprintf(queuename, "%s", "udp_sport");
>> +
>> +       queue = queue_create(queuename, true);
>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>> +
>> +       retval = odp_cos_queue_set(cos, queue);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>> +       CU_ASSERT(retval == 0);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>> +       CU_ASSERT(retqueue == queue);
>> +       odp_packet_free(pkt);
>> +
>> +       pkt = create_packet(pool_default, false, &seq, true);
>> +       seqno = cls_pkt_get_seq(pkt);
>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>> +
>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>> +
>> +       enqueue_pktio_interface(pkt, pktio);
>> +
>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
>
>
> Forget to remove?
> TEST_SEQ_INVALID check, why are you doing it here?
> If it's needed then why it's not done a little above and in functions:
> classification_test_pmr_term_udp_dport();
> classification_test_pmr_term_tcp_sport();
> classification_test_pmr_term_tcp_dport();

Yes. This is my mistake. Seems like I forgot to remove.
>
>
>> +       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];
>> +       odp_pmr_match_t match;
>> +
>> +       val = ODPH_IPPROTO_UDP;
>> +       mask = 0xff;
>> +       seqno = 0;
>> +
>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>> +
>> +       match.term = ODP_PMR_IPPROTO;
>> +       match.val = &val;
>> +       match.mask = &mask;
>> +       match.val_sz = sizeof(val);
>> +
>> +       pmr = odp_pmr_create(&match);
>> +       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);
>
>
> redundancy like above?

Yes.
>
>
>> +       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 8840e53..74d1060 100644
>> --- a/test/validation/classification/odp_classification_tests.c
>> +++ b/test/validation/classification/odp_classification_tests.c
>> @@ -11,50 +11,6 @@
>>   #include <odp/helper/ip.h>
>>   #include <odp/helper/udp.h>
>>
>> -#define SHM_PKT_NUM_BUFS        32
>> -#define SHM_PKT_BUF_SIZE        1024
>> -
>> -/* Config values for Default CoS */
>> -#define TEST_DEFAULT           1
>> -#define        CLS_DEFAULT             0
>> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>> -#define CLS_DEFAULT_SPORT      1024
>> -#define CLS_DEFAULT_DPORT      2048
>> -
>> -/* Config values for Error CoS */
>> -#define TEST_ERROR             1
>> -#define CLS_ERROR              1
>> -
>> -/* Config values for PMR_CHAIN */
>> -#define TEST_PMR_CHAIN         1
>> -#define CLS_PMR_CHAIN_SRC      2
>> -#define CLS_PMR_CHAIN_DST      3
>> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>> -#define CLS_PMR_CHAIN_SPORT    3000
>> -
>> -/* Config values for PMR */
>> -#define TEST_PMR               1
>> -#define CLS_PMR                        4
>> -#define CLS_PMR_SPORT          4000
>> -
>> -/* Config values for PMR SET */
>> -#define TEST_PMR_SET           1
>> -#define CLS_PMR_SET            5
>> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>> -#define CLS_PMR_SET_SPORT      5000
>> -
>> -/* Config values for CoS L2 Priority */
>> -#define TEST_L2_QOS            1
>> -#define CLS_L2_QOS_0           6
>> -#define CLS_L2_QOS_MAX         5
>> -
>> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>> -
>> -/* Test Packet values */
>> -#define DATA_MAGIC             0x01020304
>> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
>> -
>>   static odp_cos_t cos_list[CLS_ENTRIES];
>>   static odp_pmr_t pmr_list[CLS_ENTRIES];
>>   static odp_queue_t queue_list[CLS_ENTRIES];
>> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>>   /** sequence number of IP packets */
>>   odp_atomic_u32_t seq;
>>
>> -typedef struct cls_test_packet {
>> -       uint32be_t magic;
>> -       uint32be_t seq;
>> -} cls_test_packet_t;
>> -
>> -static inline
>> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>> *mask)
>> -{
>> -       int b[4];
>> -       int qualifier = 32;
>> -       int converted;
>> -
>> -       if (strchr(ipaddress, '/')) {
>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>> -                               &b[3], &b[2], &b[1], &b[0],
>> -                               &qualifier);
>> -               if (5 != converted)
>> -                       return -1;
>> -       } else {
>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>> -                               &b[3], &b[2], &b[1], &b[0]);
>> -               if (4 != converted)
>> -                       return -1;
>> -       }
>> -
>> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>> -               return -1;
>> -       if (!qualifier || (qualifier > 32))
>> -               return -1;
>> -
>> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>> -       if (mask)
>> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>> -
>> -       return 0;
>> -}
>> -
>> -static inline
>> -void enqueue_loop_interface(odp_packet_t pkt)
>> -{
>> -       odp_event_t ev;
>> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
>> -
>> -       ev = odp_packet_to_event(pkt);
>> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
>> -               odp_packet_free(pkt);
>> -}
>> -
>> -static inline
>> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>> -{
>> -       odp_event_t ev;
>> -
>> -       ev = odp_schedule(queue, ns);
>> -       return odp_packet_from_event(ev);
>> -}
>> -
>> -static int cls_pkt_set_seq(odp_packet_t pkt)
>> -{
>> -       static uint32_t seq;
>> -       cls_test_packet_t data;
>> -       uint32_t offset;
>> -       int status;
>> -
>> -       data.magic = DATA_MAGIC;
>> -       data.seq = ++seq;
>> -
>> -       offset = odp_packet_l4_offset(pkt);
>> -       CU_ASSERT_FATAL(offset != 0);
>> -
>> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
>> -                                       sizeof(data), &data);
>> -
>> -       return status;
>> -}
>> -
>> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>> -{
>> -       uint32_t offset;
>> -       cls_test_packet_t data;
>> -
>> -       offset = odp_packet_l4_offset(pkt);
>> -       if (offset) {
>> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>> -                                       sizeof(data), &data);
>> -
>> -               if (data.magic == DATA_MAGIC)
>> -                       return data.seq;
>> -       }
>> -
>> -       return TEST_SEQ_INVALID;
>> -}
>> -
>>   static int destroy_inq(odp_pktio_t pktio)
>>   {
>>         odp_queue_t inq;
>> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>>
>>         return odp_queue_destroy(inq);
>>   }
>> -odp_packet_t create_packet(bool vlan)
>> -{
>> -       uint32_t seqno;
>> -       odph_ethhdr_t *ethhdr;
>> -       odph_udphdr_t *udp;
>> -       odph_ipv4hdr_t *ip;
>> -       uint8_t payload_len;
>> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>> -       uint32_t addr = 0;
>> -       uint32_t mask;
>> -       int offset;
>> -       odp_packet_t pkt;
>> -       int packet_len = 0;
>> -
>> -       payload_len = sizeof(cls_test_packet_t);
>> -       packet_len += ODPH_ETHHDR_LEN;
>> -       packet_len += ODPH_IPV4HDR_LEN;
>> -       packet_len += ODPH_UDPHDR_LEN;
>> -       packet_len += payload_len;
>> -
>> -       if (vlan)
>> -               packet_len += ODPH_VLANHDR_LEN;
>> -
>> -       pkt = odp_packet_alloc(pool_default, packet_len);
>> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>> -
>> -       /* Ethernet Header */
>> -       offset = 0;
>> -       odp_packet_l2_offset_set(pkt, offset);
>> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>> -       offset += sizeof(odph_ethhdr_t);
>> -       if (vlan) {
>> -               /* Default vlan header */
>> -               uint8_t *parseptr;
>> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>> -               parseptr = (uint8_t *)vlan;
>> -               vlan->tci = odp_cpu_to_be_16(0);
>> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>> -               offset += sizeof(odph_vlanhdr_t);
>> -               parseptr += sizeof(odph_vlanhdr_t);
>> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> -       } else {
>> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>> -       }
>> -
>> -       odp_packet_l3_offset_set(pkt, offset);
>> -
>> -       /* ipv4 */
>> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>> -
>> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>> -       ip->dst_addr = odp_cpu_to_be_32(addr);
>> -
>> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>> -       ip->src_addr = odp_cpu_to_be_32(addr);
>> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
>> -                       ODPH_IPV4HDR_LEN);
>> -       ip->ttl = 128;
>> -       ip->proto = ODPH_IPPROTO_UDP;
>> -       seqno = odp_atomic_fetch_inc_u32(&seq);
>> -       ip->id = odp_cpu_to_be_16(seqno);
>> -       ip->chksum = 0;
>> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>> -       offset += ODPH_IPV4HDR_LEN;
>> -
>> -       /* udp */
>> -       odp_packet_l4_offset_set(pkt, offset);
>> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
>> -       udp->chksum = 0;
>> -
>> -       /* set pkt sequence number */
>> -       cls_pkt_set_seq(pkt);
>> -
>> -       return pkt;
>> -}
>>
>>   int classification_suite_init(void)
>>   {
>> -       odp_pool_t pool;
>>         odp_pool_param_t param;
>>         odp_queue_t inq_def;
>>         odp_queue_param_t qparam;
>> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>>         param.pkt.num     = SHM_PKT_NUM_BUFS;
>>         param.type        = ODP_POOL_PACKET;
>>
>> -       pool = odp_pool_create("classification_pool", &param);
>> -       if (ODP_POOL_INVALID == pool) {
>> +       pool_default = odp_pool_create("classification_pool", &param);
>> +       if (ODP_POOL_INVALID == pool_default) {
>>                 fprintf(stderr, "Packet pool creation failed.\n");
>>                 return -1;
>>         }
>>
>> -       pool_default = odp_pool_lookup("classification_pool");
>> -       if (pool_default == ODP_POOL_INVALID)
>> -               return -1;
>> -
>>         memset(&pktio_param, 0, sizeof(pktio_param));
>>         pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>>
>> @@ -394,6 +169,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,
>> @@ -459,10 +235,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);
>> @@ -472,25 +250,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);
>>   }
>>
>> @@ -526,16 +308,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);
>>   }
>> @@ -575,15 +360,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);
>> @@ -666,19 +452,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);
>>         }
>>   }
>> @@ -732,16 +520,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);
>>   }
>>
>> @@ -807,10 +597,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);
>> @@ -819,10 +611,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);
>>
>
> --
> Regards,
> Ivan Khoronzhuk

Regards,
Bala
Ivan Khoronzhuk Oct. 15, 2015, 2:28 p.m. UTC | #7
On 15.10.15 16:39, Bala Manoharan wrote:
> Hi Ivan,
>
> Thanks for pointing out the issues. Since this patch is merged I will
> create a bug and add the missing points.
> Pls provide your inputs on the comments.
>
> On 15 October 2015 at 16:53, Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> wrote:
>> Hi, Bala
>>
>> Just compared this version with requirements for v2 and saw some mistmaches.
>> I didn't analize it deeply, seemply checked what was needed to be changed.
>> See comments below.
>>
>> Sorry, I haven't found v4, and haven't revewed v3.
>>
>>
>> On 14.10.15 08:03, Balasubramanian Manoharan 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>
>>> ---
>>> v5: rebase on latest api-next
>>>
>>>    helper/include/odp/helper/tcp.h                    |   1 +
>>>    test/validation/classification/Makefile.am         |   2 +
>>>    test/validation/classification/classification.c    |   5 +
>>>    test/validation/classification/classification.h    |  44 ++
>>>    .../classification/odp_classification_common.c     | 252 +++++++++
>>>    .../classification/odp_classification_test_pmr.c   | 579
>>> +++++++++++++++++++++
>>>    .../classification/odp_classification_tests.c      | 309 ++---------
>>>    .../classification/odp_classification_testsuites.h |  15 +-
>>>    8 files changed, 948 insertions(+), 259 deletions(-)
>>>    create mode 100644
>>> test/validation/classification/odp_classification_common.c
>>>    create mode 100644
>>> test/validation/classification/odp_classification_test_pmr.c
>>>
>>> diff --git a/helper/include/odp/helper/tcp.h
>>> b/helper/include/odp/helper/tcp.h
>>> index defe422..42f0cbe 100644
>>> --- a/helper/include/odp/helper/tcp.h
>>> +++ b/helper/include/odp/helper/tcp.h
>>> @@ -26,6 +26,7 @@ extern "C" {
>>>     *  @{
>>>     */
>>>
>>> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
>>>
>>>    /** TCP header */
>>>    typedef struct ODP_PACKED {
>>> diff --git a/test/validation/classification/Makefile.am
>>> b/test/validation/classification/Makefile.am
>>> index 5881665..4235309 100644
>>> --- a/test/validation/classification/Makefile.am
>>> +++ b/test/validation/classification/Makefile.am
>>> @@ -3,6 +3,8 @@ include ../Makefile.inc
>>>    noinst_LTLIBRARIES = libtestclassification.la
>>>    libtestclassification_la_SOURCES = odp_classification_basic.c \
>>>                                 odp_classification_tests.c \
>>> +                              odp_classification_test_pmr.c \
>>> +                              odp_classification_common.c \
>>>                                 classification.c
>>>
>>>    bin_PROGRAMS = classification_main$(EXEEXT)
>>> diff --git a/test/validation/classification/classification.c
>>> b/test/validation/classification/classification.c
>>> index d0fef93..6641893 100644
>>> --- a/test/validation/classification/classification.c
>>> +++ b/test/validation/classification/classification.c
>>> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>>>          { .pName = "classification basic",
>>>                          .pTests = classification_suite_basic,
>>>          },
>>> +       { .pName = "classification pmr tests",
>>> +                       .pTests = classification_suite_pmr,
>>> +                       .pInitFunc = classification_suite_pmr_init,
>>> +                       .pCleanupFunc = classification_suite_pmr_term,
>>> +       },
>>>          { .pName = "classification tests",
>>>                          .pTests = classification_suite,
>>>                          .pInitFunc = classification_suite_init,
>>> diff --git a/test/validation/classification/classification.h
>>> b/test/validation/classification/classification.h
>>> index d2847e5..de9c37e 100644
>>> --- a/test/validation/classification/classification.h
>>> +++ b/test/validation/classification/classification.h
>>> @@ -9,6 +9,50 @@
>>>
>>>    #include <CUnit/Basic.h>
>>>
>>> +#define SHM_PKT_NUM_BUFS        32
>>> +#define SHM_PKT_BUF_SIZE        1024
>>> +
>>> +/* Config values for Default CoS */
>>> +#define TEST_DEFAULT           1
>>> +#define        CLS_DEFAULT             0
>>> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>> +#define CLS_DEFAULT_SPORT      1024
>>> +#define CLS_DEFAULT_DPORT      2048
>>> +
>>> +/* Config values for Error CoS */
>>> +#define TEST_ERROR             1
>>> +#define CLS_ERROR              1
>>> +
>>> +/* Config values for PMR_CHAIN */
>>> +#define TEST_PMR_CHAIN         1
>>> +#define CLS_PMR_CHAIN_SRC      2
>>> +#define CLS_PMR_CHAIN_DST      3
>>> +#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>> +#define CLS_PMR_CHAIN_SPORT    3000
>>> +
>>> +/* Config values for PMR */
>>> +#define TEST_PMR               1
>>> +#define CLS_PMR                        4
>>> +#define CLS_PMR_SPORT          4000
>>> +
>>> +/* Config values for PMR SET */
>>> +#define TEST_PMR_SET           1
>>> +#define CLS_PMR_SET            5
>>> +#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>> +#define CLS_PMR_SET_SPORT      5000
>>> +
>>> +/* Config values for CoS L2 Priority */
>>> +#define TEST_L2_QOS            1
>>> +#define CLS_L2_QOS_0           6
>>> +#define CLS_L2_QOS_MAX         5
>>> +
>>> +#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>> +
>>> +/* Test Packet values */
>>> +#define DATA_MAGIC             0x01020304
>>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> +
>>>    /* test functions: */
>>>    void classification_test_create_cos(void);
>>>    void classification_test_destroy_cos(void);
>>> diff --git a/test/validation/classification/odp_classification_common.c
>>> b/test/validation/classification/odp_classification_common.c
>>> new file mode 100644
>>> index 0000000..b975dfb
>>> --- /dev/null
>>> +++ b/test/validation/classification/odp_classification_common.c
>>> @@ -0,0 +1,252 @@
>>> +/* Copyright (c) 2015, Linaro Limited
>>> + * All rights reserved.
>>> + *
>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>> + */
>>> +
>>> +#include "odp_classification_testsuites.h"
>>> +#include "classification.h"
>>> +#include <odp_cunit_common.h>
>>> +#include <odp/helper/eth.h>
>>> +#include <odp/helper/ip.h>
>>> +#include <odp/helper/udp.h>
>>> +#include <odp/helper/tcp.h>
>>> +
>>> +typedef struct cls_test_packet {
>>> +       uint32be_t magic;
>>> +       uint32be_t seq;
>>
>>
>> Why be?
>> Seems you wanted to change it.
>> "
>> But I think there is a potential bug since get_seq() and set_seq() function
>> is not converting this cls_test_packet_t variables to cpu_endian before
>> accessing the value.
>> I will update in the next patch.
>> "
>
> Actually I dint want to change the "be" variable format, I was only
> concerned about a potential bug.
> uint32be_t is just a typedef with __attribute__(bitwise) so that
> Sparse can generate warning and since we are sending the packet
> through the interface it is better to note that the packets are in
> network byte order hence it is better to define these variables as Big
> Endian.
>
> The bug which I thought was there was actually incorrectly noted by me
> as since the magic is generated by the same machine which receives the
> packet there will not be an issue.
>
>>
>>> +} 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);
>>
>>
>> Seems last time I saw it you was fine to change this to read the header
>> length from
>> tcp header field.
>
> Yes. But since we only receive locally generated packet I retained a
> hard-coded TCP header length.

Anyway UDP, TCP split is made with ip->proto,
so redundancy is minimum and it's correct to make it option independent initially
as it's common function.... Up to you.


>
>>
>>> +
>>> +       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);
>>
>>
>> same here.
>>
>>
>>> +
>>> +       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)
>>
>>
>> Better to use "seq" internally.
>> I poroposed to delete this static var from idividual test and leave it in
>> common.
>> See below.
>
> This "seq" variable is used to fill the "identification" field in ipv4

Let it be, but seems it doesn't break the idea.

> header and it is NOT the seq number we use in the cls_pkt_get_seq()
> function. It is better to have this sequence individually controllable
> per module so that during debug it is easy to differentiate packets
> belonging to different modules. Lets say if we capture the packets in
> wireshark if the user assigns different "seq" number per module then
> the packets are easily traceable.

What disable to trace it directly in common function?
And set it at test init?

>
>>
>>
>>> +{
>>> +       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..37de892
>>> --- /dev/null
>>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>>> @@ -0,0 +1,579 @@
>>> +/* Copyright (c) 2015, Linaro Limited
>>> + * All rights reserved.
>>> + *
>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>> + */
>>> +
>>> +#include "odp_classification_testsuites.h"
>>> +#include "classification.h"
>>> +#include <odp_cunit_common.h>
>>> +#include <odp/helper/eth.h>
>>> +#include <odp/helper/ip.h>
>>> +#include <odp/helper/udp.h>
>>> +#include <odp/helper/tcp.h>
>>> +
>>> +static odp_pool_t pool_default;
>>> +
>>> +/** sequence number of IP packets */
>>> +odp_atomic_u32_t seq;
>>> +
>>> +static int destroy_inq(odp_pktio_t pktio)
>>
>>
>> Seems you agreeed tom make it common.
>
> Oops. I missed this. Will add this as a separate patch.
>
>>
>>
>>> +{
>>> +       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");
>>
>>
>> You changed name but agreed to delete this redundancy from here.
>> This test doesn't check pool API here, so better to remove it.
>
> I think i modified this in one module and forgot to change in other module.
>
>>
>>
>>> +       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];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_DPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>>> +
>>> +       match.term = ODP_PMR_TCP_DPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       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);
>>
>>
>> seq is not used anywere in the code, it's not required to know this value.
>> If value is needed to know, the cls_pkt_get_seq() is used.
>> Why not simply use common var in common file.
>> If you want to reset it to 0 for each test, then add common function like
>> set seq or cls_reset_pkt_seq() and call it at init. Then we don't need to
>> pass redundant argument each time when create packet.
>
> Actually only the Common variable is only used for the sequence number
> inside the packet.
> This sequence number is used to update the "Identification" field in
> ipv4 header for debug purpose as explained above.
>
>>
>>
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(retqueue == queue);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +
>>> +       odp_packet_free(pkt);
>>> +
>>> +       /* Other packets are delivered to default queue */
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_tcp_sport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_tcphdr_t *tcp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_SPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_TCP_SPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "tcp_sport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "tcp_sport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_udp_dport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_udphdr_t *udp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_DPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_UDP_DPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "udp_dport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "udp_dport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       /* Other packets received in default queue */
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == defqueue);
>>> +
>>> +       odp_packet_free(pkt);
>>> +       odp_cos_destroy(cos);
>>> +       odp_pmr_destroy(pmr);
>>> +       destroy_inq(pktio);
>>> +       odp_queue_destroy(queue);
>>> +       odp_pktio_close(pktio);
>>> +}
>>> +
>>> +static void classification_test_pmr_term_udp_sport(void)
>>> +{
>>> +       odp_packet_t pkt;
>>> +       odph_udphdr_t *udp;
>>> +       uint32_t seqno;
>>> +       uint16_t val;
>>> +       uint16_t mask;
>>> +       int retval;
>>> +       odp_pktio_t pktio;
>>> +       odp_queue_t queue;
>>> +       odp_queue_t retqueue;
>>> +       odp_queue_t defqueue;
>>> +       odp_pmr_t pmr;
>>> +       odp_cos_t cos;
>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = CLS_DEFAULT_SPORT;
>>> +       mask = 0xffff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_UDP_SPORT;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>> +
>>> +       sprintf(cosname, "udp_sport");
>>> +       cos = odp_cos_create(cosname);
>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>> +
>>> +       sprintf(queuename, "%s", "udp_sport");
>>> +
>>> +       queue = queue_create(queuename, true);
>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>> +
>>> +       retval = odp_cos_queue_set(cos, queue);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>> +       CU_ASSERT(retval == 0);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>> +       CU_ASSERT(retqueue == queue);
>>> +       odp_packet_free(pkt);
>>> +
>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>> +       seqno = cls_pkt_get_seq(pkt);
>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>> +
>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>> +
>>> +       enqueue_pktio_interface(pkt, pktio);
>>> +
>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
>>
>>
>> Forget to remove?
>> TEST_SEQ_INVALID check, why are you doing it here?
>> If it's needed then why it's not done a little above and in functions:
>> classification_test_pmr_term_udp_dport();
>> classification_test_pmr_term_tcp_sport();
>> classification_test_pmr_term_tcp_dport();
>
> Yes. This is my mistake. Seems like I forgot to remove.
>>
>>
>>> +       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];
>>> +       odp_pmr_match_t match;
>>> +
>>> +       val = ODPH_IPPROTO_UDP;
>>> +       mask = 0xff;
>>> +       seqno = 0;
>>> +
>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>> +
>>> +       match.term = ODP_PMR_IPPROTO;
>>> +       match.val = &val;
>>> +       match.mask = &mask;
>>> +       match.val_sz = sizeof(val);
>>> +
>>> +       pmr = odp_pmr_create(&match);
>>> +       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);
>>
>>
>> redundancy like above?
>
> Yes.
>>
>>
>>> +       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 8840e53..74d1060 100644
>>> --- a/test/validation/classification/odp_classification_tests.c
>>> +++ b/test/validation/classification/odp_classification_tests.c
>>> @@ -11,50 +11,6 @@
>>>    #include <odp/helper/ip.h>
>>>    #include <odp/helper/udp.h>
>>>
>>> -#define SHM_PKT_NUM_BUFS        32
>>> -#define SHM_PKT_BUF_SIZE        1024
>>> -
>>> -/* Config values for Default CoS */
>>> -#define TEST_DEFAULT           1
>>> -#define        CLS_DEFAULT             0
>>> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>> -#define CLS_DEFAULT_SPORT      1024
>>> -#define CLS_DEFAULT_DPORT      2048
>>> -
>>> -/* Config values for Error CoS */
>>> -#define TEST_ERROR             1
>>> -#define CLS_ERROR              1
>>> -
>>> -/* Config values for PMR_CHAIN */
>>> -#define TEST_PMR_CHAIN         1
>>> -#define CLS_PMR_CHAIN_SRC      2
>>> -#define CLS_PMR_CHAIN_DST      3
>>> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>> -#define CLS_PMR_CHAIN_SPORT    3000
>>> -
>>> -/* Config values for PMR */
>>> -#define TEST_PMR               1
>>> -#define CLS_PMR                        4
>>> -#define CLS_PMR_SPORT          4000
>>> -
>>> -/* Config values for PMR SET */
>>> -#define TEST_PMR_SET           1
>>> -#define CLS_PMR_SET            5
>>> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>> -#define CLS_PMR_SET_SPORT      5000
>>> -
>>> -/* Config values for CoS L2 Priority */
>>> -#define TEST_L2_QOS            1
>>> -#define CLS_L2_QOS_0           6
>>> -#define CLS_L2_QOS_MAX         5
>>> -
>>> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>> -
>>> -/* Test Packet values */
>>> -#define DATA_MAGIC             0x01020304
>>> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>> -
>>>    static odp_cos_t cos_list[CLS_ENTRIES];
>>>    static odp_pmr_t pmr_list[CLS_ENTRIES];
>>>    static odp_queue_t queue_list[CLS_ENTRIES];
>>> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>>>    /** sequence number of IP packets */
>>>    odp_atomic_u32_t seq;
>>>
>>> -typedef struct cls_test_packet {
>>> -       uint32be_t magic;
>>> -       uint32be_t seq;
>>> -} cls_test_packet_t;
>>> -
>>> -static inline
>>> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>>> *mask)
>>> -{
>>> -       int b[4];
>>> -       int qualifier = 32;
>>> -       int converted;
>>> -
>>> -       if (strchr(ipaddress, '/')) {
>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>>> -                               &b[3], &b[2], &b[1], &b[0],
>>> -                               &qualifier);
>>> -               if (5 != converted)
>>> -                       return -1;
>>> -       } else {
>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>>> -                               &b[3], &b[2], &b[1], &b[0]);
>>> -               if (4 != converted)
>>> -                       return -1;
>>> -       }
>>> -
>>> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] > 255))
>>> -               return -1;
>>> -       if (!qualifier || (qualifier > 32))
>>> -               return -1;
>>> -
>>> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>>> -       if (mask)
>>> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) - 1));
>>> -
>>> -       return 0;
>>> -}
>>> -
>>> -static inline
>>> -void enqueue_loop_interface(odp_packet_t pkt)
>>> -{
>>> -       odp_event_t ev;
>>> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
>>> -
>>> -       ev = odp_packet_to_event(pkt);
>>> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
>>> -               odp_packet_free(pkt);
>>> -}
>>> -
>>> -static inline
>>> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>>> -{
>>> -       odp_event_t ev;
>>> -
>>> -       ev = odp_schedule(queue, ns);
>>> -       return odp_packet_from_event(ev);
>>> -}
>>> -
>>> -static int cls_pkt_set_seq(odp_packet_t pkt)
>>> -{
>>> -       static uint32_t seq;
>>> -       cls_test_packet_t data;
>>> -       uint32_t offset;
>>> -       int status;
>>> -
>>> -       data.magic = DATA_MAGIC;
>>> -       data.seq = ++seq;
>>> -
>>> -       offset = odp_packet_l4_offset(pkt);
>>> -       CU_ASSERT_FATAL(offset != 0);
>>> -
>>> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
>>> -                                       sizeof(data), &data);
>>> -
>>> -       return status;
>>> -}
>>> -
>>> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>>> -{
>>> -       uint32_t offset;
>>> -       cls_test_packet_t data;
>>> -
>>> -       offset = odp_packet_l4_offset(pkt);
>>> -       if (offset) {
>>> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>>> -                                       sizeof(data), &data);
>>> -
>>> -               if (data.magic == DATA_MAGIC)
>>> -                       return data.seq;
>>> -       }
>>> -
>>> -       return TEST_SEQ_INVALID;
>>> -}
>>> -
>>>    static int destroy_inq(odp_pktio_t pktio)
>>>    {
>>>          odp_queue_t inq;
>>> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>>>
>>>          return odp_queue_destroy(inq);
>>>    }
>>> -odp_packet_t create_packet(bool vlan)
>>> -{
>>> -       uint32_t seqno;
>>> -       odph_ethhdr_t *ethhdr;
>>> -       odph_udphdr_t *udp;
>>> -       odph_ipv4hdr_t *ip;
>>> -       uint8_t payload_len;
>>> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>>> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>>> -       uint32_t addr = 0;
>>> -       uint32_t mask;
>>> -       int offset;
>>> -       odp_packet_t pkt;
>>> -       int packet_len = 0;
>>> -
>>> -       payload_len = sizeof(cls_test_packet_t);
>>> -       packet_len += ODPH_ETHHDR_LEN;
>>> -       packet_len += ODPH_IPV4HDR_LEN;
>>> -       packet_len += ODPH_UDPHDR_LEN;
>>> -       packet_len += payload_len;
>>> -
>>> -       if (vlan)
>>> -               packet_len += ODPH_VLANHDR_LEN;
>>> -
>>> -       pkt = odp_packet_alloc(pool_default, packet_len);
>>> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>>> -
>>> -       /* Ethernet Header */
>>> -       offset = 0;
>>> -       odp_packet_l2_offset_set(pkt, offset);
>>> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>>> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>>> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>>> -       offset += sizeof(odph_ethhdr_t);
>>> -       if (vlan) {
>>> -               /* Default vlan header */
>>> -               uint8_t *parseptr;
>>> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t *)(&ethhdr->type);
>>> -               parseptr = (uint8_t *)vlan;
>>> -               vlan->tci = odp_cpu_to_be_16(0);
>>> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>>> -               offset += sizeof(odph_vlanhdr_t);
>>> -               parseptr += sizeof(odph_vlanhdr_t);
>>> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>>> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> -       } else {
>>> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>> -       }
>>> -
>>> -       odp_packet_l3_offset_set(pkt, offset);
>>> -
>>> -       /* ipv4 */
>>> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>> -
>>> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>>> -       ip->dst_addr = odp_cpu_to_be_32(addr);
>>> -
>>> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>>> -       ip->src_addr = odp_cpu_to_be_32(addr);
>>> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>>> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
>>> -                       ODPH_IPV4HDR_LEN);
>>> -       ip->ttl = 128;
>>> -       ip->proto = ODPH_IPPROTO_UDP;
>>> -       seqno = odp_atomic_fetch_inc_u32(&seq);
>>> -       ip->id = odp_cpu_to_be_16(seqno);
>>> -       ip->chksum = 0;
>>> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>>> -       offset += ODPH_IPV4HDR_LEN;
>>> -
>>> -       /* udp */
>>> -       odp_packet_l4_offset_set(pkt, offset);
>>> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
>>> -       udp->chksum = 0;
>>> -
>>> -       /* set pkt sequence number */
>>> -       cls_pkt_set_seq(pkt);
>>> -
>>> -       return pkt;
>>> -}
>>>
>>>    int classification_suite_init(void)
>>>    {
>>> -       odp_pool_t pool;
>>>          odp_pool_param_t param;
>>>          odp_queue_t inq_def;
>>>          odp_queue_param_t qparam;
>>> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>>>          param.pkt.num     = SHM_PKT_NUM_BUFS;
>>>          param.type        = ODP_POOL_PACKET;
>>>
>>> -       pool = odp_pool_create("classification_pool", &param);
>>> -       if (ODP_POOL_INVALID == pool) {
>>> +       pool_default = odp_pool_create("classification_pool", &param);
>>> +       if (ODP_POOL_INVALID == pool_default) {
>>>                  fprintf(stderr, "Packet pool creation failed.\n");
>>>                  return -1;
>>>          }
>>>
>>> -       pool_default = odp_pool_lookup("classification_pool");
>>> -       if (pool_default == ODP_POOL_INVALID)
>>> -               return -1;
>>> -
>>>          memset(&pktio_param, 0, sizeof(pktio_param));
>>>          pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>>>
>>> @@ -394,6 +169,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,
>>> @@ -459,10 +235,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);
>>> @@ -472,25 +250,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);
>>>    }
>>>
>>> @@ -526,16 +308,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);
>>>    }
>>> @@ -575,15 +360,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);
>>> @@ -666,19 +452,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);
>>>          }
>>>    }
>>> @@ -732,16 +520,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);
>>>    }
>>>
>>> @@ -807,10 +597,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);
>>> @@ -819,10 +611,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);
>>>
>>
>> --
>> Regards,
>> Ivan Khoronzhuk
>
> Regards,
> Bala
>
Balasubramanian Manoharan Oct. 16, 2015, 11:05 a.m. UTC | #8
Hi Ivan,

Comments inline.

On 15 October 2015 at 19:58, Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> wrote:
>
>
> On 15.10.15 16:39, Bala Manoharan wrote:
>>
>> Hi Ivan,
>>
>> Thanks for pointing out the issues. Since this patch is merged I will
>> create a bug and add the missing points.
>> Pls provide your inputs on the comments.
>>
>> On 15 October 2015 at 16:53, Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> wrote:
>>>
>>> Hi, Bala
>>>
>>> Just compared this version with requirements for v2 and saw some
>>> mistmaches.
>>> I didn't analize it deeply, seemply checked what was needed to be
>>> changed.
>>> See comments below.
>>>
>>> Sorry, I haven't found v4, and haven't revewed v3.
>>>
>>>
>>> On 14.10.15 08:03, Balasubramanian Manoharan 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>
>>>> ---
>>>> v5: rebase on latest api-next
>>>>
>>>>    helper/include/odp/helper/tcp.h                    |   1 +
>>>>    test/validation/classification/Makefile.am         |   2 +
>>>>    test/validation/classification/classification.c    |   5 +
>>>>    test/validation/classification/classification.h    |  44 ++
>>>>    .../classification/odp_classification_common.c     | 252 +++++++++
>>>>    .../classification/odp_classification_test_pmr.c   | 579
>>>> +++++++++++++++++++++
>>>>    .../classification/odp_classification_tests.c      | 309 ++---------
>>>>    .../classification/odp_classification_testsuites.h |  15 +-
>>>>    8 files changed, 948 insertions(+), 259 deletions(-)
>>>>    create mode 100644
>>>> test/validation/classification/odp_classification_common.c
>>>>    create mode 100644
>>>> test/validation/classification/odp_classification_test_pmr.c
>>>>
>>>> diff --git a/helper/include/odp/helper/tcp.h
>>>> b/helper/include/odp/helper/tcp.h
>>>> index defe422..42f0cbe 100644
>>>> --- a/helper/include/odp/helper/tcp.h
>>>> +++ b/helper/include/odp/helper/tcp.h
>>>> @@ -26,6 +26,7 @@ extern "C" {
>>>>     *  @{
>>>>     */
>>>>
>>>> +#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options)
>>>> */
>>>>
>>>>    /** TCP header */
>>>>    typedef struct ODP_PACKED {
>>>> diff --git a/test/validation/classification/Makefile.am
>>>> b/test/validation/classification/Makefile.am
>>>> index 5881665..4235309 100644
>>>> --- a/test/validation/classification/Makefile.am
>>>> +++ b/test/validation/classification/Makefile.am
>>>> @@ -3,6 +3,8 @@ include ../Makefile.inc
>>>>    noinst_LTLIBRARIES = libtestclassification.la
>>>>    libtestclassification_la_SOURCES = odp_classification_basic.c \
>>>>                                 odp_classification_tests.c \
>>>> +                              odp_classification_test_pmr.c \
>>>> +                              odp_classification_common.c \
>>>>                                 classification.c
>>>>
>>>>    bin_PROGRAMS = classification_main$(EXEEXT)
>>>> diff --git a/test/validation/classification/classification.c
>>>> b/test/validation/classification/classification.c
>>>> index d0fef93..6641893 100644
>>>> --- a/test/validation/classification/classification.c
>>>> +++ b/test/validation/classification/classification.c
>>>> @@ -13,6 +13,11 @@ CU_SuiteInfo classification_suites[] = {
>>>>          { .pName = "classification basic",
>>>>                          .pTests = classification_suite_basic,
>>>>          },
>>>> +       { .pName = "classification pmr tests",
>>>> +                       .pTests = classification_suite_pmr,
>>>> +                       .pInitFunc = classification_suite_pmr_init,
>>>> +                       .pCleanupFunc = classification_suite_pmr_term,
>>>> +       },
>>>>          { .pName = "classification tests",
>>>>                          .pTests = classification_suite,
>>>>                          .pInitFunc = classification_suite_init,
>>>> diff --git a/test/validation/classification/classification.h
>>>> b/test/validation/classification/classification.h
>>>> index d2847e5..de9c37e 100644
>>>> --- a/test/validation/classification/classification.h
>>>> +++ b/test/validation/classification/classification.h
>>>> @@ -9,6 +9,50 @@
>>>>
>>>>    #include <CUnit/Basic.h>
>>>>
>>>> +#define SHM_PKT_NUM_BUFS        32
>>>> +#define SHM_PKT_BUF_SIZE        1024
>>>> +
>>>> +/* Config values for Default CoS */
>>>> +#define TEST_DEFAULT           1
>>>> +#define        CLS_DEFAULT             0
>>>> +#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>>> +#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>>> +#define CLS_DEFAULT_SPORT      1024
>>>> +#define CLS_DEFAULT_DPORT      2048
>>>> +
>>>> +/* Config values for Error CoS */
>>>> +#define TEST_ERROR             1
>>>> +#define CLS_ERROR              1
>>>> +
>>>> +/* Config values for PMR_CHAIN */
>>>> +#define TEST_PMR_CHAIN         1
>>>> +#define CLS_PMR_CHAIN_SRC      2
>>>> +#define CLS_PMR_CHAIN_DST      3
>>>> +#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>>> +#define CLS_PMR_CHAIN_SPORT    3000
>>>> +
>>>> +/* Config values for PMR */
>>>> +#define TEST_PMR               1
>>>> +#define CLS_PMR                        4
>>>> +#define CLS_PMR_SPORT          4000
>>>> +
>>>> +/* Config values for PMR SET */
>>>> +#define TEST_PMR_SET           1
>>>> +#define CLS_PMR_SET            5
>>>> +#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>>> +#define CLS_PMR_SET_SPORT      5000
>>>> +
>>>> +/* Config values for CoS L2 Priority */
>>>> +#define TEST_L2_QOS            1
>>>> +#define CLS_L2_QOS_0           6
>>>> +#define CLS_L2_QOS_MAX         5
>>>> +
>>>> +#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>>> +
>>>> +/* Test Packet values */
>>>> +#define DATA_MAGIC             0x01020304
>>>> +#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>>> +
>>>>    /* test functions: */
>>>>    void classification_test_create_cos(void);
>>>>    void classification_test_destroy_cos(void);
>>>> diff --git a/test/validation/classification/odp_classification_common.c
>>>> b/test/validation/classification/odp_classification_common.c
>>>> new file mode 100644
>>>> index 0000000..b975dfb
>>>> --- /dev/null
>>>> +++ b/test/validation/classification/odp_classification_common.c
>>>> @@ -0,0 +1,252 @@
>>>> +/* Copyright (c) 2015, Linaro Limited
>>>> + * All rights reserved.
>>>> + *
>>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>>> + */
>>>> +
>>>> +#include "odp_classification_testsuites.h"
>>>> +#include "classification.h"
>>>> +#include <odp_cunit_common.h>
>>>> +#include <odp/helper/eth.h>
>>>> +#include <odp/helper/ip.h>
>>>> +#include <odp/helper/udp.h>
>>>> +#include <odp/helper/tcp.h>
>>>> +
>>>> +typedef struct cls_test_packet {
>>>> +       uint32be_t magic;
>>>> +       uint32be_t seq;
>>>
>>>
>>>
>>> Why be?
>>> Seems you wanted to change it.
>>> "
>>> But I think there is a potential bug since get_seq() and set_seq()
>>> function
>>> is not converting this cls_test_packet_t variables to cpu_endian before
>>> accessing the value.
>>> I will update in the next patch.
>>> "
>>
>>
>> Actually I dint want to change the "be" variable format, I was only
>> concerned about a potential bug.
>> uint32be_t is just a typedef with __attribute__(bitwise) so that
>> Sparse can generate warning and since we are sending the packet
>> through the interface it is better to note that the packets are in
>> network byte order hence it is better to define these variables as Big
>> Endian.
>>
>> The bug which I thought was there was actually incorrectly noted by me
>> as since the magic is generated by the same machine which receives the
>> packet there will not be an issue.
>>
>>>
>>>> +} 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);
>>>
>>>
>>>
>>> Seems last time I saw it you was fine to change this to read the header
>>> length from
>>> tcp header field.
>>
>>
>> Yes. But since we only receive locally generated packet I retained a
>> hard-coded TCP header length.
>
>
> Anyway UDP, TCP split is made with ip->proto,
> so redundancy is minimum and it's correct to make it option independent
> initially
> as it's common function.... Up to you.
>
>
>
>>
>>>
>>>> +
>>>> +       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);
>>>
>>>
>>>
>>> same here.
>>>
>>>
>>>> +
>>>> +       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)
>>>
>>>
>>>
>>> Better to use "seq" internally.
>>> I poroposed to delete this static var from idividual test and leave it in
>>> common.
>>> See below.
>>
>>
>> This "seq" variable is used to fill the "identification" field in ipv4
>
>
> Let it be, but seems it doesn't break the idea.
>
>> header and it is NOT the seq number we use in the cls_pkt_get_seq()
>> function. It is better to have this sequence individually controllable
>> per module so that during debug it is easy to differentiate packets
>> belonging to different modules. Lets say if we capture the packets in
>> wireshark if the user assigns different "seq" number per module then
>> the packets are easily traceable.
>
>
> What disable to trace it directly in common function?
> And set it at test init?

Both the approach should be fine. The logical reason why I had made
this atomic variable specific to each validation suite is that this
might be useful if we enhance the validation to run different modules
simultaneously in different threads in the multi-thread environment
and also since this library creates a default packet this could be
moved to a generic common file used by all the different validation
modules.
I am open to different view point from your side.

Since apart from this point we seems to agree on rest of the issues I
will send patch to fix the remaining.

Regards,
Bala
>
>
>>
>>>
>>>
>>>> +{
>>>> +       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..37de892
>>>> --- /dev/null
>>>> +++ b/test/validation/classification/odp_classification_test_pmr.c
>>>> @@ -0,0 +1,579 @@
>>>> +/* Copyright (c) 2015, Linaro Limited
>>>> + * All rights reserved.
>>>> + *
>>>> + * SPDX-License-Identifier:    BSD-3-Clause
>>>> + */
>>>> +
>>>> +#include "odp_classification_testsuites.h"
>>>> +#include "classification.h"
>>>> +#include <odp_cunit_common.h>
>>>> +#include <odp/helper/eth.h>
>>>> +#include <odp/helper/ip.h>
>>>> +#include <odp/helper/udp.h>
>>>> +#include <odp/helper/tcp.h>
>>>> +
>>>> +static odp_pool_t pool_default;
>>>> +
>>>> +/** sequence number of IP packets */
>>>> +odp_atomic_u32_t seq;
>>>> +
>>>> +static int destroy_inq(odp_pktio_t pktio)
>>>
>>>
>>>
>>> Seems you agreeed tom make it common.
>>
>>
>> Oops. I missed this. Will add this as a separate patch.
>>
>>>
>>>
>>>> +{
>>>> +       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");
>>>
>>>
>>>
>>> You changed name but agreed to delete this redundancy from here.
>>> This test doesn't check pool API here, so better to remove it.
>>
>>
>> I think i modified this in one module and forgot to change in other
>> module.
>>
>>>
>>>
>>>> +       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];
>>>> +       odp_pmr_match_t match;
>>>> +
>>>> +       val = CLS_DEFAULT_DPORT;
>>>> +       mask = 0xffff;
>>>> +       seqno = 0;
>>>> +
>>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>>> +       CU_ASSERT(pktio != ODP_PKTIO_INVALID);
>>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>>> +       CU_ASSERT(defqueue != ODP_QUEUE_INVALID);
>>>> +
>>>> +       match.term = ODP_PMR_TCP_DPORT;
>>>> +       match.val = &val;
>>>> +       match.mask = &mask;
>>>> +       match.val_sz = sizeof(val);
>>>> +
>>>> +       pmr = odp_pmr_create(&match);
>>>> +       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);
>>>
>>>
>>>
>>> seq is not used anywere in the code, it's not required to know this
>>> value.
>>> If value is needed to know, the cls_pkt_get_seq() is used.
>>> Why not simply use common var in common file.
>>> If you want to reset it to 0 for each test, then add common function like
>>> set seq or cls_reset_pkt_seq() and call it at init. Then we don't need to
>>> pass redundant argument each time when create packet.
>>
>>
>> Actually only the Common variable is only used for the sequence number
>> inside the packet.
>> This sequence number is used to update the "Identification" field in
>> ipv4 header for debug purpose as explained above.
>>
>>>
>>>
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(retqueue == queue);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +
>>>> +       odp_packet_free(pkt);
>>>> +
>>>> +       /* Other packets are delivered to default queue */
>>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == defqueue);
>>>> +
>>>> +       odp_packet_free(pkt);
>>>> +       odp_cos_destroy(cos);
>>>> +       odp_pmr_destroy(pmr);
>>>> +       destroy_inq(pktio);
>>>> +       odp_queue_destroy(queue);
>>>> +       odp_pktio_close(pktio);
>>>> +}
>>>> +
>>>> +static void classification_test_pmr_term_tcp_sport(void)
>>>> +{
>>>> +       odp_packet_t pkt;
>>>> +       odph_tcphdr_t *tcp;
>>>> +       uint32_t seqno;
>>>> +       uint16_t val;
>>>> +       uint16_t mask;
>>>> +       int retval;
>>>> +       odp_pktio_t pktio;
>>>> +       odp_queue_t queue;
>>>> +       odp_queue_t retqueue;
>>>> +       odp_queue_t defqueue;
>>>> +       odp_pmr_t pmr;
>>>> +       odp_cos_t cos;
>>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>>> +       odp_pmr_match_t match;
>>>> +
>>>> +       val = CLS_DEFAULT_SPORT;
>>>> +       mask = 0xffff;
>>>> +       seqno = 0;
>>>> +
>>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>>> +
>>>> +       match.term = ODP_PMR_TCP_SPORT;
>>>> +       match.val = &val;
>>>> +       match.mask = &mask;
>>>> +       match.val_sz = sizeof(val);
>>>> +
>>>> +       pmr = odp_pmr_create(&match);
>>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>>> +
>>>> +       sprintf(cosname, "tcp_sport");
>>>> +       cos = odp_cos_create(cosname);
>>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>>> +
>>>> +       sprintf(queuename, "%s", "tcp_sport");
>>>> +
>>>> +       queue = queue_create(queuename, true);
>>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>>> +
>>>> +       retval = odp_cos_queue_set(cos, queue);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == queue);
>>>> +       odp_packet_free(pkt);
>>>> +
>>>> +       pkt = create_packet(pool_default, false, &seq, false);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == defqueue);
>>>> +
>>>> +       odp_packet_free(pkt);
>>>> +       odp_cos_destroy(cos);
>>>> +       odp_pmr_destroy(pmr);
>>>> +       destroy_inq(pktio);
>>>> +       odp_queue_destroy(queue);
>>>> +       odp_pktio_close(pktio);
>>>> +}
>>>> +
>>>> +static void classification_test_pmr_term_udp_dport(void)
>>>> +{
>>>> +       odp_packet_t pkt;
>>>> +       odph_udphdr_t *udp;
>>>> +       uint32_t seqno;
>>>> +       uint16_t val;
>>>> +       uint16_t mask;
>>>> +       int retval;
>>>> +       odp_pktio_t pktio;
>>>> +       odp_queue_t queue;
>>>> +       odp_queue_t retqueue;
>>>> +       odp_queue_t defqueue;
>>>> +       odp_pmr_t pmr;
>>>> +       odp_cos_t cos;
>>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>>> +       odp_pmr_match_t match;
>>>> +
>>>> +       val = CLS_DEFAULT_DPORT;
>>>> +       mask = 0xffff;
>>>> +       seqno = 0;
>>>> +
>>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>>> +
>>>> +       match.term = ODP_PMR_UDP_DPORT;
>>>> +       match.val = &val;
>>>> +       match.mask = &mask;
>>>> +       match.val_sz = sizeof(val);
>>>> +
>>>> +       pmr = odp_pmr_create(&match);
>>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>>> +
>>>> +       sprintf(cosname, "udp_dport");
>>>> +       cos = odp_cos_create(cosname);
>>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>>> +
>>>> +       sprintf(queuename, "%s", "udp_dport");
>>>> +
>>>> +       queue = queue_create(queuename, true);
>>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>>> +
>>>> +       retval = odp_cos_queue_set(cos, queue);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == queue);
>>>> +       odp_packet_free(pkt);
>>>> +
>>>> +       /* Other packets received in default queue */
>>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT + 1);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == defqueue);
>>>> +
>>>> +       odp_packet_free(pkt);
>>>> +       odp_cos_destroy(cos);
>>>> +       odp_pmr_destroy(pmr);
>>>> +       destroy_inq(pktio);
>>>> +       odp_queue_destroy(queue);
>>>> +       odp_pktio_close(pktio);
>>>> +}
>>>> +
>>>> +static void classification_test_pmr_term_udp_sport(void)
>>>> +{
>>>> +       odp_packet_t pkt;
>>>> +       odph_udphdr_t *udp;
>>>> +       uint32_t seqno;
>>>> +       uint16_t val;
>>>> +       uint16_t mask;
>>>> +       int retval;
>>>> +       odp_pktio_t pktio;
>>>> +       odp_queue_t queue;
>>>> +       odp_queue_t retqueue;
>>>> +       odp_queue_t defqueue;
>>>> +       odp_pmr_t pmr;
>>>> +       odp_cos_t cos;
>>>> +       char cosname[ODP_QUEUE_NAME_LEN];
>>>> +       char queuename[ODP_QUEUE_NAME_LEN];
>>>> +       odp_pmr_match_t match;
>>>> +
>>>> +       val = CLS_DEFAULT_SPORT;
>>>> +       mask = 0xffff;
>>>> +       seqno = 0;
>>>> +
>>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>>> +
>>>> +       match.term = ODP_PMR_UDP_SPORT;
>>>> +       match.val = &val;
>>>> +       match.mask = &mask;
>>>> +       match.val_sz = sizeof(val);
>>>> +
>>>> +       pmr = odp_pmr_create(&match);
>>>> +       CU_ASSERT(pmr != ODP_PMR_INVAL);
>>>> +
>>>> +       sprintf(cosname, "udp_sport");
>>>> +       cos = odp_cos_create(cosname);
>>>> +       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
>>>> +
>>>> +       sprintf(queuename, "%s", "udp_sport");
>>>> +
>>>> +       queue = queue_create(queuename, true);
>>>> +       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
>>>> +
>>>> +       retval = odp_cos_queue_set(cos, queue);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       retval = odp_pktio_pmr_cos(pmr, pktio, cos);
>>>> +       CU_ASSERT(retval == 0);
>>>> +
>>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
>>>> +       CU_ASSERT(retqueue == queue);
>>>> +       odp_packet_free(pkt);
>>>> +
>>>> +       pkt = create_packet(pool_default, false, &seq, true);
>>>> +       seqno = cls_pkt_get_seq(pkt);
>>>> +       CU_ASSERT(seqno != TEST_SEQ_INVALID);
>>>> +
>>>> +       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> +       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT + 1);
>>>> +
>>>> +       enqueue_pktio_interface(pkt, pktio);
>>>> +
>>>> +       pkt = receive_packet(&retqueue, ODP_TIME_SEC);
>>>> +       CU_ASSERT(pkt != ODP_PACKET_INVALID);
>>>> +       CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
>>>
>>>
>>>
>>> Forget to remove?
>>> TEST_SEQ_INVALID check, why are you doing it here?
>>> If it's needed then why it's not done a little above and in functions:
>>> classification_test_pmr_term_udp_dport();
>>> classification_test_pmr_term_tcp_sport();
>>> classification_test_pmr_term_tcp_dport();
>>
>>
>> Yes. This is my mistake. Seems like I forgot to remove.
>>>
>>>
>>>
>>>> +       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];
>>>> +       odp_pmr_match_t match;
>>>> +
>>>> +       val = ODPH_IPPROTO_UDP;
>>>> +       mask = 0xff;
>>>> +       seqno = 0;
>>>> +
>>>> +       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
>>>> +       defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
>>>> +
>>>> +       match.term = ODP_PMR_IPPROTO;
>>>> +       match.val = &val;
>>>> +       match.mask = &mask;
>>>> +       match.val_sz = sizeof(val);
>>>> +
>>>> +       pmr = odp_pmr_create(&match);
>>>> +       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);
>>>
>>>
>>>
>>> redundancy like above?
>>
>>
>> Yes.
>>>
>>>
>>>
>>>> +       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 8840e53..74d1060 100644
>>>> --- a/test/validation/classification/odp_classification_tests.c
>>>> +++ b/test/validation/classification/odp_classification_tests.c
>>>> @@ -11,50 +11,6 @@
>>>>    #include <odp/helper/ip.h>
>>>>    #include <odp/helper/udp.h>
>>>>
>>>> -#define SHM_PKT_NUM_BUFS        32
>>>> -#define SHM_PKT_BUF_SIZE        1024
>>>> -
>>>> -/* Config values for Default CoS */
>>>> -#define TEST_DEFAULT           1
>>>> -#define        CLS_DEFAULT             0
>>>> -#define CLS_DEFAULT_SADDR      "10.0.0.1/32"
>>>> -#define CLS_DEFAULT_DADDR      "10.0.0.100/32"
>>>> -#define CLS_DEFAULT_SPORT      1024
>>>> -#define CLS_DEFAULT_DPORT      2048
>>>> -
>>>> -/* Config values for Error CoS */
>>>> -#define TEST_ERROR             1
>>>> -#define CLS_ERROR              1
>>>> -
>>>> -/* Config values for PMR_CHAIN */
>>>> -#define TEST_PMR_CHAIN         1
>>>> -#define CLS_PMR_CHAIN_SRC      2
>>>> -#define CLS_PMR_CHAIN_DST      3
>>>> -#define CLS_PMR_CHAIN_SADDR    "10.0.0.5/32"
>>>> -#define CLS_PMR_CHAIN_SPORT    3000
>>>> -
>>>> -/* Config values for PMR */
>>>> -#define TEST_PMR               1
>>>> -#define CLS_PMR                        4
>>>> -#define CLS_PMR_SPORT          4000
>>>> -
>>>> -/* Config values for PMR SET */
>>>> -#define TEST_PMR_SET           1
>>>> -#define CLS_PMR_SET            5
>>>> -#define CLS_PMR_SET_SADDR      "10.0.0.6/32"
>>>> -#define CLS_PMR_SET_SPORT      5000
>>>> -
>>>> -/* Config values for CoS L2 Priority */
>>>> -#define TEST_L2_QOS            1
>>>> -#define CLS_L2_QOS_0           6
>>>> -#define CLS_L2_QOS_MAX         5
>>>> -
>>>> -#define CLS_ENTRIES            (CLS_L2_QOS_0 + CLS_L2_QOS_MAX)
>>>> -
>>>> -/* Test Packet values */
>>>> -#define DATA_MAGIC             0x01020304
>>>> -#define TEST_SEQ_INVALID       ((uint32_t)~0)
>>>> -
>>>>    static odp_cos_t cos_list[CLS_ENTRIES];
>>>>    static odp_pmr_t pmr_list[CLS_ENTRIES];
>>>>    static odp_queue_t queue_list[CLS_ENTRIES];
>>>> @@ -66,99 +22,6 @@ static odp_pktio_t pktio_loop;
>>>>    /** sequence number of IP packets */
>>>>    odp_atomic_u32_t seq;
>>>>
>>>> -typedef struct cls_test_packet {
>>>> -       uint32be_t magic;
>>>> -       uint32be_t seq;
>>>> -} cls_test_packet_t;
>>>> -
>>>> -static inline
>>>> -int parse_ipv4_string(const char *ipaddress, uint32_t *addr, uint32_t
>>>> *mask)
>>>> -{
>>>> -       int b[4];
>>>> -       int qualifier = 32;
>>>> -       int converted;
>>>> -
>>>> -       if (strchr(ipaddress, '/')) {
>>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d/%d",
>>>> -                               &b[3], &b[2], &b[1], &b[0],
>>>> -                               &qualifier);
>>>> -               if (5 != converted)
>>>> -                       return -1;
>>>> -       } else {
>>>> -               converted = sscanf(ipaddress, "%d.%d.%d.%d",
>>>> -                               &b[3], &b[2], &b[1], &b[0]);
>>>> -               if (4 != converted)
>>>> -                       return -1;
>>>> -       }
>>>> -
>>>> -       if ((b[0] > 255) || (b[1] > 255) || (b[2] > 255) || (b[3] >
>>>> 255))
>>>> -               return -1;
>>>> -       if (!qualifier || (qualifier > 32))
>>>> -               return -1;
>>>> -
>>>> -       *addr = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24;
>>>> -       if (mask)
>>>> -               *mask = ~(0xFFFFFFFF & ((1ULL << (32 - qualifier)) -
>>>> 1));
>>>> -
>>>> -       return 0;
>>>> -}
>>>> -
>>>> -static inline
>>>> -void enqueue_loop_interface(odp_packet_t pkt)
>>>> -{
>>>> -       odp_event_t ev;
>>>> -       odp_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop);
>>>> -
>>>> -       ev = odp_packet_to_event(pkt);
>>>> -       if (!(CU_ASSERT(odp_queue_enq(defqueue, ev) == 0)))
>>>> -               odp_packet_free(pkt);
>>>> -}
>>>> -
>>>> -static inline
>>>> -odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns)
>>>> -{
>>>> -       odp_event_t ev;
>>>> -
>>>> -       ev = odp_schedule(queue, ns);
>>>> -       return odp_packet_from_event(ev);
>>>> -}
>>>> -
>>>> -static int cls_pkt_set_seq(odp_packet_t pkt)
>>>> -{
>>>> -       static uint32_t seq;
>>>> -       cls_test_packet_t data;
>>>> -       uint32_t offset;
>>>> -       int status;
>>>> -
>>>> -       data.magic = DATA_MAGIC;
>>>> -       data.seq = ++seq;
>>>> -
>>>> -       offset = odp_packet_l4_offset(pkt);
>>>> -       CU_ASSERT_FATAL(offset != 0);
>>>> -
>>>> -       status = odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN,
>>>> -                                       sizeof(data), &data);
>>>> -
>>>> -       return status;
>>>> -}
>>>> -
>>>> -static uint32_t cls_pkt_get_seq(odp_packet_t pkt)
>>>> -{
>>>> -       uint32_t offset;
>>>> -       cls_test_packet_t data;
>>>> -
>>>> -       offset = odp_packet_l4_offset(pkt);
>>>> -       if (offset) {
>>>> -               odp_packet_copydata_out(pkt, offset + ODPH_UDPHDR_LEN,
>>>> -                                       sizeof(data), &data);
>>>> -
>>>> -               if (data.magic == DATA_MAGIC)
>>>> -                       return data.seq;
>>>> -       }
>>>> -
>>>> -       return TEST_SEQ_INVALID;
>>>> -}
>>>> -
>>>>    static int destroy_inq(odp_pktio_t pktio)
>>>>    {
>>>>          odp_queue_t inq;
>>>> @@ -185,93 +48,9 @@ static int destroy_inq(odp_pktio_t pktio)
>>>>
>>>>          return odp_queue_destroy(inq);
>>>>    }
>>>> -odp_packet_t create_packet(bool vlan)
>>>> -{
>>>> -       uint32_t seqno;
>>>> -       odph_ethhdr_t *ethhdr;
>>>> -       odph_udphdr_t *udp;
>>>> -       odph_ipv4hdr_t *ip;
>>>> -       uint8_t payload_len;
>>>> -       char src_mac[ODPH_ETHADDR_LEN]  = {0};
>>>> -       char dst_mac[ODPH_ETHADDR_LEN] = {0};
>>>> -       uint32_t addr = 0;
>>>> -       uint32_t mask;
>>>> -       int offset;
>>>> -       odp_packet_t pkt;
>>>> -       int packet_len = 0;
>>>> -
>>>> -       payload_len = sizeof(cls_test_packet_t);
>>>> -       packet_len += ODPH_ETHHDR_LEN;
>>>> -       packet_len += ODPH_IPV4HDR_LEN;
>>>> -       packet_len += ODPH_UDPHDR_LEN;
>>>> -       packet_len += payload_len;
>>>> -
>>>> -       if (vlan)
>>>> -               packet_len += ODPH_VLANHDR_LEN;
>>>> -
>>>> -       pkt = odp_packet_alloc(pool_default, packet_len);
>>>> -       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
>>>> -
>>>> -       /* Ethernet Header */
>>>> -       offset = 0;
>>>> -       odp_packet_l2_offset_set(pkt, offset);
>>>> -       ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
>>>> -       memcpy(ethhdr->src.addr, src_mac, ODPH_ETHADDR_LEN);
>>>> -       memcpy(ethhdr->dst.addr, dst_mac, ODPH_ETHADDR_LEN);
>>>> -       offset += sizeof(odph_ethhdr_t);
>>>> -       if (vlan) {
>>>> -               /* Default vlan header */
>>>> -               uint8_t *parseptr;
>>>> -               odph_vlanhdr_t *vlan = (odph_vlanhdr_t
>>>> *)(&ethhdr->type);
>>>> -               parseptr = (uint8_t *)vlan;
>>>> -               vlan->tci = odp_cpu_to_be_16(0);
>>>> -               vlan->tpid = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
>>>> -               offset += sizeof(odph_vlanhdr_t);
>>>> -               parseptr += sizeof(odph_vlanhdr_t);
>>>> -               uint16be_t *type = (uint16be_t *)(void *)parseptr;
>>>> -               *type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>>> -       } else {
>>>> -               ethhdr->type =  odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4);
>>>> -       }
>>>> -
>>>> -       odp_packet_l3_offset_set(pkt, offset);
>>>> -
>>>> -       /* ipv4 */
>>>> -       ip = (odph_ipv4hdr_t *)odp_packet_l3_ptr(pkt, NULL);
>>>> -
>>>> -       parse_ipv4_string(CLS_DEFAULT_SADDR, &addr, &mask);
>>>> -       ip->dst_addr = odp_cpu_to_be_32(addr);
>>>> -
>>>> -       parse_ipv4_string(CLS_DEFAULT_DADDR, &addr, &mask);
>>>> -       ip->src_addr = odp_cpu_to_be_32(addr);
>>>> -       ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
>>>> -       ip->tot_len = odp_cpu_to_be_16(ODPH_UDPHDR_LEN + payload_len +
>>>> -                       ODPH_IPV4HDR_LEN);
>>>> -       ip->ttl = 128;
>>>> -       ip->proto = ODPH_IPPROTO_UDP;
>>>> -       seqno = odp_atomic_fetch_inc_u32(&seq);
>>>> -       ip->id = odp_cpu_to_be_16(seqno);
>>>> -       ip->chksum = 0;
>>>> -       ip->chksum = odp_cpu_to_be_16(odph_ipv4_csum_update(pkt));
>>>> -       offset += ODPH_IPV4HDR_LEN;
>>>> -
>>>> -       /* udp */
>>>> -       odp_packet_l4_offset_set(pkt, offset);
>>>> -       udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
>>>> -       udp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
>>>> -       udp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
>>>> -       udp->length = odp_cpu_to_be_16(payload_len + ODPH_UDPHDR_LEN);
>>>> -       udp->chksum = 0;
>>>> -
>>>> -       /* set pkt sequence number */
>>>> -       cls_pkt_set_seq(pkt);
>>>> -
>>>> -       return pkt;
>>>> -}
>>>>
>>>>    int classification_suite_init(void)
>>>>    {
>>>> -       odp_pool_t pool;
>>>>          odp_pool_param_t param;
>>>>          odp_queue_t inq_def;
>>>>          odp_queue_param_t qparam;
>>>> @@ -286,16 +65,12 @@ int classification_suite_init(void)
>>>>          param.pkt.num     = SHM_PKT_NUM_BUFS;
>>>>          param.type        = ODP_POOL_PACKET;
>>>>
>>>> -       pool = odp_pool_create("classification_pool", &param);
>>>> -       if (ODP_POOL_INVALID == pool) {
>>>> +       pool_default = odp_pool_create("classification_pool", &param);
>>>> +       if (ODP_POOL_INVALID == pool_default) {
>>>>                  fprintf(stderr, "Packet pool creation failed.\n");
>>>>                  return -1;
>>>>          }
>>>>
>>>> -       pool_default = odp_pool_lookup("classification_pool");
>>>> -       if (pool_default == ODP_POOL_INVALID)
>>>> -               return -1;
>>>> -
>>>>          memset(&pktio_param, 0, sizeof(pktio_param));
>>>>          pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
>>>>
>>>> @@ -394,6 +169,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,
>>>> @@ -459,10 +235,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);
>>>> @@ -472,25 +250,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);
>>>>    }
>>>>
>>>> @@ -526,16 +308,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);
>>>>    }
>>>> @@ -575,15 +360,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);
>>>> @@ -666,19 +452,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);
>>>>          }
>>>>    }
>>>> @@ -732,16 +520,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);
>>>>    }
>>>>
>>>> @@ -807,10 +597,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);
>>>> @@ -819,10 +611,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);
>>>>
>>>
>>> --
>>> Regards,
>>> Ivan Khoronzhuk
>>
>>
>> Regards,
>> Bala
>>
>
> --
> Regards,
> Ivan Khoronzhuk
Ivan Khoronzhuk Oct. 16, 2015, 11:23 a.m. UTC | #9
Ok.
diff mbox

Patch

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