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 *)ðhdr->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