Adds test case for outer and inner vlan id packet matching rule

Signed-off-by: Balasubramanian Manoharan <bala.manoha...@linaro.org>
---
 .../validation/api/classification/classification.h |   2 +
 .../api/classification/odp_classification_common.c |  17 +-
 .../classification/odp_classification_test_pmr.c   | 229 +++++++++++++++++++++
 .../classification/odp_classification_testsuites.h |   4 +-
 4 files changed, 246 insertions(+), 6 deletions(-)

diff --git a/test/common_plat/validation/api/classification/classification.h 
b/test/common_plat/validation/api/classification/classification.h
index 0192e24..66e3208 100644
--- a/test/common_plat/validation/api/classification/classification.h
+++ b/test/common_plat/validation/api/classification/classification.h
@@ -98,6 +98,8 @@ void classification_test_pmr_term_udp_sport(void);
 void classification_test_pmr_term_ipproto(void);
 void classification_test_pmr_term_dmac(void);
 void classification_test_pmr_term_packet_len(void);
+void classification_test_pmr_term_vlan_id_0(void);
+void classification_test_pmr_term_vlan_id_x(void);
 
 /* test arrays: */
 extern odp_testinfo_t classification_suite_basic[];
diff --git 
a/test/common_plat/validation/api/classification/odp_classification_common.c 
b/test/common_plat/validation/api/classification/odp_classification_common.c
index 0ca9083..3b379c1 100644
--- a/test/common_plat/validation/api/classification/odp_classification_common.c
+++ b/test/common_plat/validation/api/classification/odp_classification_common.c
@@ -245,6 +245,8 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
        uint16_t l3_hdr_len = 0;
        uint16_t l4_hdr_len = 0;
        uint16_t eth_type;
+       odp_u16be_t *vlan_type;
+       odph_vlanhdr_t *vlan_hdr;
 
        /* 48 bit ethernet address needs to be left shifted for proper
        value after changing to be*/
@@ -256,6 +258,7 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
        seqno = odp_atomic_fetch_inc_u32(pkt_info.seq);
 
        vlan_hdr_len = pkt_info.vlan ? ODPH_VLANHDR_LEN : 0;
+       vlan_hdr_len = pkt_info.vlan_qinq ? 2 * vlan_hdr_len : vlan_hdr_len;
        l3_hdr_len = pkt_info.ipv6 ? ODPH_IPV6HDR_LEN : ODPH_IPV4HDR_LEN;
        l4_hdr_len = pkt_info.udp ? ODPH_UDPHDR_LEN : ODPH_TCPHDR_LEN;
        eth_type = pkt_info.ipv6 ? ODPH_ETHTYPE_IPV6 : ODPH_ETHTYPE_IPV4;
@@ -275,12 +278,20 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
        ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
        memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN);
        memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN);
+       vlan_type = (odp_u16be_t *)&ethhdr->type;
+       vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
+
+       if (pkt_info.vlan_qinq) {
+               odp_packet_has_vlan_qinq_set(pkt, 1);
+               *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN_OUTER);
+               vlan_hdr->tci = odp_cpu_to_be_16(0);
+               vlan_type = (uint16_t *)&vlan_hdr->type;
+               vlan_hdr++;
+       }
        if (pkt_info.vlan) {
                /* Default vlan header */
-               odph_vlanhdr_t *vlan_hdr;
                odp_packet_has_vlan_set(pkt, 1);
-               ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
-               vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
+               *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
                vlan_hdr->tci = odp_cpu_to_be_16(0);
                vlan_hdr->type = odp_cpu_to_be_16(eth_type);
        } else {
diff --git 
a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c 
b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
index c714549..d01f716 100644
--- 
a/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
+++ 
b/test/common_plat/validation/api/classification/odp_classification_test_pmr.c
@@ -870,6 +870,233 @@ void classification_test_pmr_term_packet_len(void)
        odp_pktio_close(pktio);
 }
 
+void classification_test_pmr_term_vlan_id_0(void)
+{
+       odp_packet_t pkt;
+       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 default_queue;
+       odp_cos_t default_cos;
+       odp_pool_t default_pool;
+       odp_pool_t pool;
+       odp_pool_t recvpool;
+       odp_pmr_t pmr;
+       odp_cos_t cos;
+       char cosname[ODP_COS_NAME_LEN];
+       odp_cls_cos_param_t cls_param;
+       odp_pmr_param_t pmr_param;
+       odph_ethhdr_t *eth;
+       odph_vlanhdr_t *vlan_0;
+       cls_packet_info_t pkt_info;
+
+       val = 1024;
+       mask = 0xff00;
+       seqno = 0;
+
+       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+       CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+       retval = start_pktio(pktio);
+       CU_ASSERT(retval == 0);
+
+       configure_default_cos(pktio, &default_cos,
+                             &default_queue, &default_pool);
+
+       queue = queue_create("vlan_id_0", true);
+       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+       pool = pool_create("vlan_id_0");
+       CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+       sprintf(cosname, "vlan_id_0");
+       odp_cls_cos_param_init(&cls_param);
+       cls_param.pool = pool;
+       cls_param.queue = queue;
+       cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+       cos = odp_cls_cos_create(cosname, &cls_param);
+       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+       odp_cls_pmr_param_init(&pmr_param);
+       pmr_param.term = ODP_PMR_VLAN_ID_0;
+       pmr_param.match.value = &val;
+       pmr_param.match.mask = &mask;
+       pmr_param.val_sz = sizeof(val);
+
+       pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+       CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+       /* create packet of payload length 1024 */
+       pkt_info = default_pkt_info;
+       pkt_info.vlan = true;
+       pkt_info.vlan_qinq = true;
+       pkt = create_packet(pkt_info);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       seqno = cls_pkt_get_seq(pkt);
+       CU_ASSERT(seqno != TEST_SEQ_INVALID);
+       eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+       odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+       odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+       vlan_0 = (odph_vlanhdr_t *)(eth + 1);
+       vlan_0->tci = odp_cpu_to_be_16(1024);
+       enqueue_pktio_interface(pkt, pktio);
+
+       pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+       recvpool = odp_packet_pool(pkt);
+       CU_ASSERT(recvpool == pool);
+       CU_ASSERT(retqueue == queue);
+       odp_packet_free(pkt);
+
+       /* Other packets delivered to default queue */
+       pkt = create_packet(default_pkt_info);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       seqno = cls_pkt_get_seq(pkt);
+       CU_ASSERT(seqno != TEST_SEQ_INVALID);
+       eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+       odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+       odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+       enqueue_pktio_interface(pkt, pktio);
+
+       pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+       recvpool = odp_packet_pool(pkt);
+       CU_ASSERT(recvpool == default_pool);
+       CU_ASSERT(retqueue == default_queue);
+
+       odp_cos_destroy(cos);
+       odp_cos_destroy(default_cos);
+       odp_cls_pmr_destroy(pmr);
+       odp_packet_free(pkt);
+       stop_pktio(pktio);
+       odp_pool_destroy(default_pool);
+       odp_pool_destroy(pool);
+       odp_queue_destroy(queue);
+       odp_queue_destroy(default_queue);
+       odp_pktio_close(pktio);
+}
+
+void classification_test_pmr_term_vlan_id_x(void)
+{
+       odp_packet_t pkt;
+       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 default_queue;
+       odp_cos_t default_cos;
+       odp_pool_t default_pool;
+       odp_pool_t pool;
+       odp_pool_t recvpool;
+       odp_pmr_t pmr;
+       odp_cos_t cos;
+       char cosname[ODP_COS_NAME_LEN];
+       odp_cls_cos_param_t cls_param;
+       odp_pmr_param_t pmr_param;
+       odph_ethhdr_t *eth;
+       odph_vlanhdr_t *vlan_x;
+       cls_packet_info_t pkt_info;
+
+       val = 1024;
+       mask = 0xff00;
+       seqno = 0;
+
+       pktio = create_pktio(ODP_QUEUE_TYPE_SCHED, pkt_pool);
+       CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID);
+       retval = start_pktio(pktio);
+       CU_ASSERT(retval == 0);
+
+       configure_default_cos(pktio, &default_cos,
+                             &default_queue, &default_pool);
+
+       queue = queue_create("vlan_id_x", true);
+       CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+       pool = pool_create("vlan_id_x");
+       CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+       sprintf(cosname, "vlan_id_x");
+       odp_cls_cos_param_init(&cls_param);
+       cls_param.pool = pool;
+       cls_param.queue = queue;
+       cls_param.drop_policy = ODP_COS_DROP_POOL;
+
+       cos = odp_cls_cos_create(cosname, &cls_param);
+       CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+       odp_cls_pmr_param_init(&pmr_param);
+       pmr_param.term = ODP_PMR_VLAN_ID_X;
+       pmr_param.match.value = &val;
+       pmr_param.match.mask = &mask;
+       pmr_param.val_sz = sizeof(val);
+
+       pmr = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos);
+       CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+       /* create packet of payload length 1024 */
+       pkt_info = default_pkt_info;
+       pkt_info.vlan = true;
+       pkt_info.vlan_qinq = true;
+       pkt = create_packet(pkt_info);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       seqno = cls_pkt_get_seq(pkt);
+       CU_ASSERT(seqno != TEST_SEQ_INVALID);
+       eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+       odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+       odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+       vlan_x = (odph_vlanhdr_t *)(eth + 1);
+       vlan_x++;
+       vlan_x->tci = odp_cpu_to_be_16(1024);
+       enqueue_pktio_interface(pkt, pktio);
+
+       pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+       recvpool = odp_packet_pool(pkt);
+       CU_ASSERT(recvpool == pool);
+       CU_ASSERT(retqueue == queue);
+       odp_packet_free(pkt);
+
+       /* Other packets delivered to default queue */
+       pkt = create_packet(default_pkt_info);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       seqno = cls_pkt_get_seq(pkt);
+       CU_ASSERT(seqno != TEST_SEQ_INVALID);
+       eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
+       odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
+       odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
+
+       enqueue_pktio_interface(pkt, pktio);
+
+       pkt = receive_packet(&retqueue, ODP_TIME_SEC_IN_NS);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+       recvpool = odp_packet_pool(pkt);
+       CU_ASSERT(recvpool == default_pool);
+       CU_ASSERT(retqueue == default_queue);
+
+       odp_cos_destroy(cos);
+       odp_cos_destroy(default_cos);
+       odp_cls_pmr_destroy(pmr);
+       odp_packet_free(pkt);
+       stop_pktio(pktio);
+       odp_pool_destroy(default_pool);
+       odp_pool_destroy(pool);
+       odp_queue_destroy(queue);
+       odp_queue_destroy(default_queue);
+       odp_pktio_close(pktio);
+}
+
 static void classification_test_pmr_pool_set(void)
 {
        odp_packet_t pkt;
@@ -1407,5 +1634,7 @@ odp_testinfo_t classification_suite_pmr[] = {
        ODP_TEST_INFO(classification_test_pmr_term_ipv6saddr),
        ODP_TEST_INFO(classification_test_pmr_term_ipv6daddr),
        ODP_TEST_INFO(classification_test_pmr_term_packet_len),
+       ODP_TEST_INFO(classification_test_pmr_term_vlan_id_0),
+       ODP_TEST_INFO(classification_test_pmr_term_vlan_id_x),
        ODP_TEST_INFO_NULL,
 };
diff --git 
a/test/common_plat/validation/api/classification/odp_classification_testsuites.h
 
b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
index d5ffef7..d296923 100644
--- 
a/test/common_plat/validation/api/classification/odp_classification_testsuites.h
+++ 
b/test/common_plat/validation/api/classification/odp_classification_testsuites.h
@@ -15,6 +15,7 @@
 typedef struct cls_packet_info {
        odp_pool_t pool;
        bool    vlan;
+       bool    vlan_qinq;
        odp_atomic_u32_t *seq;
        bool    udp;
        bool    ipv6;
@@ -32,9 +33,6 @@ int classification_suite_pmr_term(void);
 int classification_suite_pmr_init(void);
 
 odp_packet_t create_packet(cls_packet_info_t pkt_info);
-odp_packet_t create_packet_len(odp_pool_t pool, bool vlan,
-                              odp_atomic_u32_t *seq, bool flag_udp,
-                              bool ipv4, uint16_t len);
 int cls_pkt_set_seq(odp_packet_t pkt);
 uint32_t cls_pkt_get_seq(odp_packet_t pkt);
 odp_pktio_t create_pktio(odp_queue_type_t q_type, odp_pool_t pool);
-- 
1.9.1

Reply via email to