From patchwork Fri Jan 23 16:44:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balasubramanian Manoharan X-Patchwork-Id: 43681 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1BDE7240D9 for ; Fri, 23 Jan 2015 16:45:20 +0000 (UTC) Received: by mail-lb0-f199.google.com with SMTP id f15sf4852708lbj.2 for ; Fri, 23 Jan 2015 08:45:19 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=2M6DBUchJzJsGZ5IV/kPQQHCNUO8FWwsSta3HD+wrSc=; b=PNPr4kjZ4FB7vSvILVgtxL+tO0R+rkf5Uac4kmFaBR8WlT0wRpLfaHv1dClAETLCd1 Xt0VMM5/o9gjTUT1ikqlWaXVHj4sYQ+4QGFlNQoHxh0fQnUroFyRzk+5MLAuALGidhQI uexrt5VtsZl33lecAw1iwRUCbv5LAn4bihyox1RB3fZAZT6V/c+cndLlL6vaZIZkEr/k ov0nEUPv4qqyGyA/RehMp8H7cGcNMYqsP2H5OchnDCa7jWLqfInezKSqo/jrWqjhcm48 szrSjgdsoqld5ExQVIuSlXg7CrJ1xO5bTWpF2CGlQW9Ge/Ob92bluD2jBnQ754vMNT1r Ybaw== X-Gm-Message-State: ALoCoQn7wwEC+J9Hyfxh4MeuZM/Icn+0ptLOyWtZ6GXd+zYYcApmayuJG2tkU5YyCCcebHeNkxEe X-Received: by 10.180.74.140 with SMTP id t12mr432848wiv.2.1422031518883; Fri, 23 Jan 2015 08:45:18 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.205.38 with SMTP id ld6ls313561lac.50.gmail; Fri, 23 Jan 2015 08:45:18 -0800 (PST) X-Received: by 10.152.115.212 with SMTP id jq20mr8425240lab.36.1422031518703; Fri, 23 Jan 2015 08:45:18 -0800 (PST) Received: from mail-la0-f52.google.com (mail-la0-f52.google.com. [209.85.215.52]) by mx.google.com with ESMTPS id k5si1195610lak.12.2015.01.23.08.45.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Jan 2015 08:45:18 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) client-ip=209.85.215.52; Received: by mail-la0-f52.google.com with SMTP id ge10so4144748lab.11 for ; Fri, 23 Jan 2015 08:45:18 -0800 (PST) X-Received: by 10.112.41.234 with SMTP id i10mr8454126lbl.25.1422031518592; Fri, 23 Jan 2015 08:45:18 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.9.200 with SMTP id c8csp315601lbb; Fri, 23 Jan 2015 08:45:17 -0800 (PST) X-Received: by 10.224.63.20 with SMTP id z20mr15949155qah.62.1422031516863; Fri, 23 Jan 2015 08:45:16 -0800 (PST) Received: from ip-10-35-177-41.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id fk7si2660959qcb.6.2015.01.23.08.45.15 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 23 Jan 2015 08:45:16 -0800 (PST) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-35-177-41.ec2.internal) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YEhM8-0001hM-KJ; Fri, 23 Jan 2015 16:45:12 +0000 Received: from mail-pa0-f41.google.com ([209.85.220.41]) by ip-10-35-177-41.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1YEhM3-0001g9-30 for lng-odp@lists.linaro.org; Fri, 23 Jan 2015 16:45:07 +0000 Received: by mail-pa0-f41.google.com with SMTP id kq14so6990883pab.0 for ; Fri, 23 Jan 2015 08:45:01 -0800 (PST) X-Received: by 10.70.43.144 with SMTP id w16mr12837456pdl.62.1422031501653; Fri, 23 Jan 2015 08:45:01 -0800 (PST) Received: from localhost.localdomain ([59.90.234.135]) by mx.google.com with ESMTPSA id fm4sm2374835pdb.88.2015.01.23.08.44.59 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 Jan 2015 08:45:01 -0800 (PST) From: bala.manoharan@linaro.org To: lng-odp@lists.linaro.org Date: Fri, 23 Jan 2015 22:14:31 +0530 Message-Id: <1422031471-30427-2-git-send-email-bala.manoharan@linaro.org> X-Mailer: git-send-email 2.0.1.472.g6f92e5f In-Reply-To: <1422031471-30427-1-git-send-email-bala.manoharan@linaro.org> References: <1422031471-30427-1-git-send-email-bala.manoharan@linaro.org> X-Topics: Classification patch Subject: [lng-odp] [PATCH v2 2/2] validation: classification validataion suite X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: bala.manoharan@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.52 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Balasubramanian Manoharan Classification validation consists of two suites * classification basic This suite tests the basic classification APIs for creation and deletion of various PMRs and CoS. * classification test This suite tests behavious of different CoS once they are linked to the pktio. This suite sends packets with different PMR TERM values across a loopback interface and tests the assigned CoS. Signed-off-by: Balasubramanian Manoharan Reviewed-by: Mike Holmes --- v2: Incorporates review comments from Mike test/validation/.gitignore | 1 + test/validation/Makefile.am | 8 +- .../classification/odp_classification_basic.c | 178 +++++ .../classification/odp_classification_tests.c | 816 +++++++++++++++++++++ .../classification/odp_classification_testsuites.h | 38 + test/validation/odp_classification.c | 19 + 6 files changed, 1058 insertions(+), 2 deletions(-) create mode 100644 test/validation/classification/odp_classification_basic.c create mode 100644 test/validation/classification/odp_classification_tests.c create mode 100644 test/validation/classification/odp_classification_testsuites.h create mode 100644 test/validation/odp_classification.c diff --git a/test/validation/.gitignore b/test/validation/.gitignore index a1d4d15..4a1ccb4 100644 --- a/test/validation/.gitignore +++ b/test/validation/.gitignore @@ -3,6 +3,7 @@ odp_init odp_queue odp_crypto +odp_classification odp_schedule odp_shm odp_system diff --git a/test/validation/Makefile.am b/test/validation/Makefile.am index 0f5799c..c0e14cb 100644 --- a/test/validation/Makefile.am +++ b/test/validation/Makefile.am @@ -6,13 +6,14 @@ AM_LDFLAGS += -static TESTS_ENVIRONMENT = ODP_PLATFORM=${with_platform} if test_vald -TESTS = odp_init odp_queue odp_crypto odp_shm odp_schedule odp_pktio_run odp_buffer odp_system odp_timer odp_time odp_synchronizers +TESTS = odp_init odp_queue odp_crypto odp_shm odp_schedule odp_pktio_run odp_buffer odp_system odp_timer odp_time odp_synchronizers odp_classification check_PROGRAMS = ${bin_PROGRAMS} endif -bin_PROGRAMS = odp_init odp_queue odp_crypto odp_shm odp_schedule odp_pktio odp_buffer odp_system odp_timer odp_time odp_synchronizers +bin_PROGRAMS = odp_init odp_queue odp_crypto odp_shm odp_schedule odp_pktio odp_buffer odp_system odp_timer odp_time odp_synchronizers odp_classification odp_crypto_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/crypto odp_buffer_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/buffer +odp_classification_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/classification dist_odp_init_SOURCES = odp_init.c dist_odp_pktio_SOURCES = odp_pktio.c common/odp_cunit_common.c @@ -32,3 +33,6 @@ dist_odp_timer_SOURCES = odp_timer.c common/odp_cunit_common.c dist_odp_time_SOURCES = odp_time.c common/odp_cunit_common.c dist_odp_synchronizers_SOURCES = odp_synchronizers.c \ common/odp_cunit_common.c +dist_odp_classification_SOURCES = classification/odp_classification_tests.c \ + classification/odp_classification_basic.c \ + odp_classification.c common/odp_cunit_common.c diff --git a/test/validation/classification/odp_classification_basic.c b/test/validation/classification/odp_classification_basic.c new file mode 100644 index 0000000..844b66e --- /dev/null +++ b/test/validation/classification/odp_classification_basic.c @@ -0,0 +1,178 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "odp_classification_testsuites.h" + +#define PMR_SET_NUM 5 + +static void classification_create_cos(void) +{ + odp_cos_t cos; + char name[ODP_COS_NAME_LEN]; + sprintf(name, "ClassOfService"); + cos = odp_cos_create(name); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + odp_cos_destroy(cos); +} + +static void classification_destroy_cos(void) +{ + odp_cos_t cos; + char name[ODP_COS_NAME_LEN]; + int retval; + sprintf(name, "ClassOfService"); + cos = odp_cos_create(name); + CU_ASSERT_FATAL(cos != ODP_COS_INVALID); + retval = odp_cos_destroy(cos); + CU_ASSERT(retval == 0); + retval = odp_cos_destroy(ODP_COS_INVALID); + CU_ASSERT(retval < 0); +} + +static void classification_create_pmr_match(void) +{ + odp_pmr_t pmr; + uint16_t val; + uint16_t mask; + val = 1024; + mask = 0xffff; + pmr = odp_pmr_create_match(ODP_PMR_TCP_SPORT, &val, &mask, sizeof(val)); + CU_ASSERT(pmr != ODP_PMR_INVAL); + odp_pmr_destroy(pmr); +} + +static void classification_create_pmr_range(void) +{ + odp_pmr_t pmr; + uint16_t val1; + uint16_t val2; + val1 = 1024; + val2 = 2048; + pmr = odp_pmr_create_range(ODP_PMR_TCP_SPORT, &val1, + &val2, sizeof(val1)); + CU_ASSERT(pmr != ODP_PMR_INVAL); + odp_pmr_destroy(pmr); +} + +static void classification_destroy_pmr(void) +{ + odp_pmr_t pmr; + uint16_t val; + uint16_t mask; + int retval; + val = 1024; + mask = 0xffff; + pmr = odp_pmr_create_match(ODP_PMR_TCP_SPORT, &val, &mask, sizeof(val)); + retval = odp_pmr_destroy(pmr); + CU_ASSERT(retval == 0); + retval = odp_pmr_destroy(ODP_PMR_INVAL); + retval = odp_pmr_destroy(ODP_PMR_INVAL); + CU_ASSERT(retval < 0); +} + +static void classification_cos_set_queue(void) +{ + int retval; + char cosname[ODP_COS_NAME_LEN]; + char queuename[ODP_QUEUE_NAME_LEN]; + odp_queue_param_t qparam; + odp_queue_t queue_cos; + odp_cos_t cos_queue; + sprintf(cosname, "CoSQueue"); + cos_queue = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_queue != ODP_COS_INVALID); + + qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "QueueCoS"); + + queue_cos = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, &qparam); + retval = odp_cos_set_queue(cos_queue, queue_cos); + CU_ASSERT(retval == 0); + odp_cos_destroy(cos_queue); + odp_queue_destroy(queue_cos); +} + +static void classification_cos_set_drop(void) +{ + int retval; + char cosname[ODP_COS_NAME_LEN]; + sprintf(cosname, "CoSDrop"); + odp_cos_t cos_drop; + cos_drop = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_drop != ODP_COS_INVALID); + + retval = odp_cos_set_drop(cos_drop, ODP_COS_DROP_POOL); + CU_ASSERT(retval == 0); + retval = odp_cos_set_drop(cos_drop, ODP_COS_DROP_NEVER); + CU_ASSERT(retval == 0); + odp_cos_destroy(cos_drop); +} + +static void classification_pmr_match_set_create(void) +{ + odp_pmr_set_t pmr_set; + int retval; + odp_pmr_match_t pmr_terms[PMR_SET_NUM]; + uint16_t val = 1024; + uint16_t mask = 0xffff; + int i; + for (i = 0; i < PMR_SET_NUM; i++) { + pmr_terms[i].match_type = ODP_PMR_MASK; + pmr_terms[i].mask.term = ODP_PMR_TCP_DPORT; + pmr_terms[i].mask.val = &val; + pmr_terms[i].mask.mask = &mask; + pmr_terms[i].mask.val_sz = sizeof(val); + } + + retval = odp_pmr_match_set_create(PMR_SET_NUM, pmr_terms, &pmr_set); + CU_ASSERT(retval > 0); + + retval = odp_pmr_match_set_destroy(pmr_set); + CU_ASSERT(retval == 0); +} + +static void classification_pmr_match_set_destroy(void) +{ + odp_pmr_set_t pmr_set; + int retval; + odp_pmr_match_t pmr_terms[PMR_SET_NUM]; + uint16_t val = 1024; + uint16_t mask = 0xffff; + int i; + + retval = odp_pmr_match_set_destroy(ODP_PMR_INVAL); + CU_ASSERT(retval < 0); + + for (i = 0; i < PMR_SET_NUM; i++) { + pmr_terms[i].match_type = ODP_PMR_MASK; + pmr_terms[i].mask.term = ODP_PMR_TCP_DPORT; + pmr_terms[i].mask.val = &val; + pmr_terms[i].mask.mask = &mask; + pmr_terms[i].mask.val_sz = sizeof(val); + } + + retval = odp_pmr_match_set_create(PMR_SET_NUM, pmr_terms, &pmr_set); + CU_ASSERT(retval > 0); + + retval = odp_pmr_match_set_destroy(pmr_set); + CU_ASSERT(retval == 0); +} + +CU_TestInfo classification_basic[] = { + _CU_TEST_INFO(classification_create_cos), + _CU_TEST_INFO(classification_destroy_cos), + _CU_TEST_INFO(classification_create_pmr_match), + _CU_TEST_INFO(classification_create_pmr_range), + _CU_TEST_INFO(classification_destroy_pmr), + _CU_TEST_INFO(classification_cos_set_queue), + _CU_TEST_INFO(classification_cos_set_drop), + _CU_TEST_INFO(classification_pmr_match_set_create), + _CU_TEST_INFO(classification_pmr_match_set_destroy), + CU_TEST_INFO_NULL, +}; diff --git a/test/validation/classification/odp_classification_tests.c b/test/validation/classification/odp_classification_tests.c new file mode 100644 index 0000000..778172c --- /dev/null +++ b/test/validation/classification/odp_classification_tests.c @@ -0,0 +1,816 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "odp_classification_testsuites.h" +#include +#include +#include + +#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]; +static odp_pmr_set_t pmr_set; + +static odp_buffer_pool_t pool_default; +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_queue_t defqueue = odp_pktio_outq_getdef(pktio_loop); + odp_queue_enq(defqueue, odp_packet_to_buffer(pkt)); +} + +static inline +odp_packet_t receive_packet(odp_queue_t *queue, uint64_t ns) +{ + odp_buffer_t buf; + odp_packet_t pkt; + buf = odp_schedule(queue, ns); + pkt = odp_packet_from_buffer(buf); + return pkt; +} + +static int cls_pkt_set_seq(odp_packet_t pkt) +{ + static uint32_t seq; + cls_test_packet_t data; + uint32_t offset; + + data.magic = DATA_MAGIC; + data.seq = ++seq; + + offset = odp_packet_l4_offset(pkt); + CU_ASSERT_FATAL(offset != 0); + + odp_packet_copydata_in(pkt, offset + ODPH_UDPHDR_LEN, + sizeof(data), &data); + + return 0; +} + +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; +} +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 *)(ðhdr->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 *)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; + 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_tests_init(void) +{ + odp_buffer_pool_t pool; + odp_buffer_pool_param_t param; + odp_queue_t inq_def; + odp_queue_param_t qparam; + char queuename[ODP_QUEUE_NAME_LEN]; + int i; + + param.buf_size = SHM_PKT_BUF_SIZE; + param.num_bufs = SHM_PKT_NUM_BUFS; + param.buf_type = ODP_BUFFER_TYPE_PACKET; + param.buf_align = 0; + pool = odp_buffer_pool_create("classification_pool", + ODP_SHM_NULL, ¶m); + if (ODP_BUFFER_POOL_INVALID == pool) { + fprintf(stderr, "Packet pool creation failed.\n"); + return -1; + } + + pool_default = odp_buffer_pool_lookup("classification_pool"); + if (pool_default == ODP_BUFFER_POOL_INVALID) + goto error_pool_default; + + pktio_loop = odp_pktio_open("loop", pool_default); + if (pktio_loop == ODP_PKTIO_INVALID) + goto error_pktio_loop; + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; + qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; + qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; + + sprintf(queuename, "%s", "inq_loop"); + inq_def = odp_queue_create(queuename, + ODP_QUEUE_TYPE_PKTIN, &qparam); + odp_pktio_inq_setdef(pktio_loop, inq_def); + + for (i = 0; i < CLS_ENTRIES; i++) + cos_list[i] = ODP_COS_INVALID; + + for (i = 0; i < CLS_ENTRIES; i++) + pmr_list[i] = ODP_PMR_INVAL; + + for (i = 0; i < CLS_ENTRIES; i++) + queue_list[i] = ODP_QUEUE_INVALID; + + return 0; + +error_pktio_loop: + odp_buffer_pool_destroy(pool_default); + +error_pool_default: + return -1; +} + +int classification_tests_finalize(void) +{ + int i; + if (0 > odp_pktio_close(pktio_loop)) + return -1; + + if (0 != odp_buffer_pool_destroy(pool_default)) + return -1; + + for (i = 0; i < CLS_ENTRIES; i++) + odp_cos_destroy(cos_list[i]); + + for (i = 0; i < CLS_ENTRIES; i++) + odp_pmr_destroy(pmr_list[i]); + + for (i = 0; i < CLS_ENTRIES; i++) + odp_queue_destroy(queue_list[i]); + return 0; +} + +void configure_cls_pmr_chain(void) +{ + /* PKTIO --> PMR_SRC(SRC IP ADDR) --> PMR_DST (TCP SPORT) */ + + /* Packet matching only the SRC IP ADDR should be delivered + in queue[CLS_PMR_CHAIN_SRC] and a packet matching both SRC IP ADDR and + TCP SPORT should be delivered to queue[CLS_PMR_CHAIN_DST] */ + + uint16_t val; + uint16_t maskport; + int retval; + char cosname[ODP_QUEUE_NAME_LEN]; + odp_queue_param_t qparam; + char queuename[ODP_QUEUE_NAME_LEN]; + uint32_t addr; + uint32_t mask; + + sprintf(cosname, "SrcCos"); + cos_list[CLS_PMR_CHAIN_SRC] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_SRC] != ODP_COS_INVALID) + + qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "SrcQueue"); + + queue_list[CLS_PMR_CHAIN_SRC] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, + &qparam); + + CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_SRC] != ODP_QUEUE_INVALID); + retval = odp_cos_set_queue(cos_list[CLS_PMR_CHAIN_SRC], + queue_list[CLS_PMR_CHAIN_SRC]); + CU_ASSERT(retval == 0); + + sprintf(cosname, "DstCos"); + cos_list[CLS_PMR_CHAIN_DST] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_PMR_CHAIN_DST] != ODP_COS_INVALID); + + qparam.sched.prio = ODP_SCHED_PRIO_NORMAL; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "DstQueue"); + + queue_list[CLS_PMR_CHAIN_DST] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, + &qparam); + CU_ASSERT_FATAL(queue_list[CLS_PMR_CHAIN_DST] != ODP_QUEUE_INVALID); + + retval = odp_cos_set_queue(cos_list[CLS_PMR_CHAIN_DST], + queue_list[CLS_PMR_CHAIN_DST]); + + parse_ipv4_string(CLS_PMR_CHAIN_SADDR, &addr, &mask); + pmr_list[CLS_PMR_CHAIN_SRC] = odp_pmr_create_match(ODP_PMR_SIP_ADDR, + &addr, &mask, + sizeof(addr)); + CU_ASSERT_FATAL(pmr_list[CLS_PMR_CHAIN_SRC] != ODP_PMR_INVAL); + + val = CLS_PMR_CHAIN_SPORT; + maskport = 0xffff; + pmr_list[CLS_PMR_CHAIN_DST] = odp_pmr_create_match(ODP_PMR_UDP_SPORT, + &val, &maskport, + sizeof(val)); + CU_ASSERT_FATAL(pmr_list[CLS_PMR_CHAIN_DST] != ODP_PMR_INVAL); + + retval = odp_pktio_pmr_cos(pmr_list[CLS_PMR_CHAIN_SRC], pktio_loop, + cos_list[CLS_PMR_CHAIN_SRC]); + CU_ASSERT(retval == 0); + + retval = odp_cos_pmr_cos(pmr_list[CLS_PMR_CHAIN_DST], + cos_list[CLS_PMR_CHAIN_SRC], + cos_list[CLS_PMR_CHAIN_DST]); + CU_ASSERT(retval == 0); +} + +void test_cls_pmr_chain(void) +{ + odp_packet_t pkt; + odph_ipv4hdr_t *ip; + odph_udphdr_t *udp; + odp_queue_t queue; + uint32_t addr = 0; + uint32_t mask; + uint32_t seq; + + 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); + 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); + + pkt = receive_packet(&queue, ODP_TIME_SEC); + CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_DST]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + odp_packet_free(pkt); + + 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); + + enqueue_loop_interface(pkt); + pkt = receive_packet(&queue, ODP_TIME_SEC); + CU_ASSERT(queue == queue_list[CLS_PMR_CHAIN_SRC]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + + CU_ASSERT(1 == odp_pmr_match_count(pmr_list[CLS_PMR_CHAIN_DST])); + odp_packet_free(pkt); +} + +void configure_pktio_default_cos(void) +{ + int retval; + odp_queue_param_t qparam; + char cosname[ODP_COS_NAME_LEN]; + char queuename[ODP_QUEUE_NAME_LEN]; + + sprintf(cosname, "DefaultCoS"); + cos_list[CLS_DEFAULT] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_DEFAULT] != ODP_COS_INVALID); + + qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "DefaultQueue"); + queue_list[CLS_DEFAULT] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, &qparam); + CU_ASSERT_FATAL(queue_list[CLS_DEFAULT] != ODP_QUEUE_INVALID); + + retval = odp_cos_set_queue(cos_list[CLS_DEFAULT], + queue_list[CLS_DEFAULT]); + CU_ASSERT(retval == 0); + + retval = odp_pktio_default_cos_set(pktio_loop, cos_list[CLS_DEFAULT]); + CU_ASSERT(retval == 0); +} + +void test_pktio_default_cos(void) +{ + odp_packet_t pkt; + odp_queue_t queue; + uint32_t seq; + /* create a default packet */ + pkt = create_packet(false); + seq = cls_pkt_get_seq(pkt); + enqueue_loop_interface(pkt); + + pkt = receive_packet(&queue, ODP_TIME_SEC); + /* Default packet should be received in default queue */ + CU_ASSERT(queue == queue_list[CLS_DEFAULT]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + + odp_packet_free(pkt); +} + +void configure_pktio_error_cos(void) +{ + int retval; + odp_queue_param_t qparam; + char queuename[ODP_QUEUE_NAME_LEN]; + char cosname[ODP_COS_NAME_LEN]; + + qparam.sched.prio = ODP_SCHED_PRIO_LOWEST; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "ErrorCos"); + + queue_list[CLS_ERROR] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, + &qparam); + CU_ASSERT_FATAL(queue_list[CLS_ERROR] != ODP_QUEUE_INVALID); + + sprintf(cosname, "%s", "ErrorCos"); + cos_list[CLS_ERROR] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_ERROR] != ODP_COS_INVALID); + + retval = odp_cos_set_queue(cos_list[CLS_ERROR], queue_list[CLS_ERROR]); + CU_ASSERT(retval == 0); + + retval = odp_pktio_error_cos_set(pktio_loop, cos_list[CLS_ERROR]); + CU_ASSERT(retval == 0); +} + +void test_pktio_error_cos(void) +{ + odp_queue_t queue; + odp_packet_t pkt; + + /*Create an error packet */ + pkt = create_packet(false); + 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); + + pkt = receive_packet(&queue, ODP_TIME_SEC); + /* Error packet should be received in error queue */ + CU_ASSERT(queue == queue_list[CLS_ERROR]); + odp_packet_free(pkt); +} + +static void classification_pktio_set_skip(void) +{ + int retval; + size_t offset = 5; + retval = odp_pktio_skip_set(pktio_loop, offset); + CU_ASSERT(retval == 0); + + retval = odp_pktio_skip_set(ODP_PKTIO_INVALID, offset); + CU_ASSERT(retval < 0); +} + +static void classification_pktio_set_headroom(void) +{ + size_t headroom; + int retval; + headroom = 5; + retval = odp_pktio_headroom_set(pktio_loop, headroom); + CU_ASSERT(retval == 0); + + retval = odp_pktio_headroom_set(ODP_PKTIO_INVALID, headroom); + CU_ASSERT(retval < 0); +} + +void configure_cos_with_l2_priority(void) +{ + uint8_t num_qos = CLS_L2_QOS_MAX; + odp_cos_t cos_tbl[CLS_L2_QOS_MAX]; + odp_queue_t queue_tbl[CLS_L2_QOS_MAX]; + uint8_t qos_tbl[CLS_L2_QOS_MAX]; + char cosname[ODP_COS_NAME_LEN]; + char queuename[ODP_QUEUE_NAME_LEN]; + int retval; + int i; + odp_queue_param_t qparam; + + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + for (i = 0; i < num_qos; i++) { + qparam.sched.prio = ODP_SCHED_PRIO_LOWEST - i; + sprintf(cosname, "%s_%d", "L2_Cos", i); + cos_tbl[i] = odp_cos_create(cosname); + if (cos_tbl[i] == ODP_COS_INVALID) + break; + + cos_list[CLS_L2_QOS_0 + i] = cos_tbl[i]; + sprintf(queuename, "%s_%d", "L2_Queue", i); + queue_tbl[i] = odp_queue_create(queuename, ODP_QUEUE_TYPE_SCHED, + &qparam); + CU_ASSERT_FATAL(queue_tbl[i] != ODP_QUEUE_INVALID); + queue_list[CLS_L2_QOS_0 + i] = queue_tbl[i]; + retval = odp_cos_set_queue(cos_tbl[i], queue_tbl[i]); + CU_ASSERT(retval == 0); + qos_tbl[i] = i; + } + /* count 'i' is passed instead of num_qos to handle the rare scenario + if the odp_cos_create() failed in the middle*/ + retval = odp_cos_with_l2_priority(pktio_loop, i, qos_tbl, cos_tbl); + CU_ASSERT(retval == 0); +} + +void test_cos_with_l2_priority(void) +{ + odp_packet_t pkt; + odph_ethhdr_t *ethhdr; + odph_vlanhdr_t *vlan; + odp_queue_t queue; + uint32_t seq; + + uint8_t i; + for (i = 0; i < CLS_L2_QOS_MAX; i++) { + pkt = create_packet(true); + seq = cls_pkt_get_seq(pkt); + ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); + vlan = (odph_vlanhdr_t *)(ðhdr->type); + vlan->tci = odp_cpu_to_be_16(i << 13); + enqueue_loop_interface(pkt); + pkt = receive_packet(&queue, ODP_TIME_SEC); + CU_ASSERT(queue == queue_list[CLS_L2_QOS_0 + i]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + odp_packet_free(pkt); + } +} + +void configure_pmr_cos(void) +{ + uint16_t val; + uint16_t mask; + int retval; + val = CLS_PMR_SPORT; + mask = 0xffff; + odp_queue_param_t qparam; + char cosname[ODP_COS_NAME_LEN]; + char queuename[ODP_QUEUE_NAME_LEN]; + + pmr_list[CLS_PMR] = odp_pmr_create_match(ODP_PMR_UDP_SPORT, &val, + &mask, sizeof(val)); + CU_ASSERT(pmr_list[CLS_PMR] != ODP_PMR_INVAL); + + sprintf(cosname, "PMR_CoS"); + cos_list[CLS_PMR] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_PMR] != ODP_COS_INVALID); + + qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "PMR_CoS"); + + queue_list[CLS_PMR] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, + &qparam); + CU_ASSERT_FATAL(queue_list[CLS_PMR] != ODP_QUEUE_INVALID); + + retval = odp_cos_set_queue(cos_list[CLS_PMR], + queue_list[CLS_PMR]); + CU_ASSERT(retval == 0); + + retval = odp_pktio_pmr_cos(pmr_list[CLS_PMR], pktio_loop, + cos_list[CLS_PMR]); + CU_ASSERT(retval == 0); +} + +void test_pmr_cos(void) +{ + odp_packet_t pkt; + odph_udphdr_t *udp; + odp_queue_t queue; + uint32_t seq; + + pkt = create_packet(false); + seq = cls_pkt_get_seq(pkt); + 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); + pkt = receive_packet(&queue, ODP_TIME_SEC); + CU_ASSERT(queue == queue_list[CLS_PMR]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + CU_ASSERT(1 == odp_pmr_match_count(pmr_list[CLS_PMR])); + odp_packet_free(pkt); +} + +void configure_pktio_pmr_match_set_cos(void) +{ + int retval; + odp_pmr_match_t pmr_terms[2]; + uint16_t val; + uint16_t maskport; + int num_terms = 2; /* one pmr for each L3 and L4 */ + odp_queue_param_t qparam; + char cosname[ODP_COS_NAME_LEN]; + char queuename[ODP_QUEUE_NAME_LEN]; + uint32_t addr = 0; + uint32_t mask; + + parse_ipv4_string(CLS_PMR_SET_SADDR, &addr, &mask); + pmr_terms[0].match_type = ODP_PMR_MASK; + pmr_terms[0].mask.term = ODP_PMR_SIP_ADDR; + pmr_terms[0].mask.val = &addr; + pmr_terms[0].mask.mask = &mask; + pmr_terms[0].mask.val_sz = sizeof(addr); + + + val = CLS_PMR_SET_SPORT; + maskport = 0xffff; + pmr_terms[1].match_type = ODP_PMR_MASK; + pmr_terms[1].mask.term = ODP_PMR_UDP_SPORT; + pmr_terms[1].mask.val = &val; + pmr_terms[1].mask.mask = &maskport; + pmr_terms[1].mask.val_sz = sizeof(val); + + retval = odp_pmr_match_set_create(num_terms, pmr_terms, &pmr_set); + CU_ASSERT(retval > 0); + + sprintf(cosname, "cos_pmr_set"); + cos_list[CLS_PMR_SET] = odp_cos_create(cosname); + CU_ASSERT_FATAL(cos_list[CLS_PMR_SET] != ODP_COS_INVALID) + + qparam.sched.prio = ODP_SCHED_PRIO_HIGHEST; + qparam.sched.sync = ODP_SCHED_SYNC_NONE; + qparam.sched.group = ODP_SCHED_GROUP_ALL; + sprintf(queuename, "%s", "cos_pmr_set_queue"); + + queue_list[CLS_PMR_SET] = odp_queue_create(queuename, + ODP_QUEUE_TYPE_SCHED, + &qparam); + CU_ASSERT_FATAL(queue_list[CLS_PMR_SET] != ODP_QUEUE_INVALID); + + retval = odp_cos_set_queue(cos_list[CLS_PMR_SET], + queue_list[CLS_PMR_SET]); + CU_ASSERT(retval == 0); + + retval = odp_pktio_pmr_match_set_cos(pmr_set, pktio_loop, + cos_list[CLS_PMR_SET]); + CU_ASSERT(retval == 0); +} + +void test_pktio_pmr_match_set_cos(void) +{ + uint32_t addr = 0; + uint32_t mask; + odph_ipv4hdr_t *ip; + odph_udphdr_t *udp; + odp_packet_t pkt; + odp_queue_t queue; + uint32_t seq; + + 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); + 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); + pkt = receive_packet(&queue, ODP_TIME_SEC); + CU_ASSERT(queue == queue_list[CLS_PMR_SET]); + CU_ASSERT(seq == cls_pkt_get_seq(pkt)); + odp_packet_free(pkt); +} + +static void classification_pmr_match_count(void) +{ + odp_pmr_t pmr; + uint16_t val; + uint16_t mask; + val = 1024; + mask = 0xffff; + int retval; + pmr = odp_pmr_create_match(ODP_PMR_TCP_SPORT, &val, &mask, sizeof(val)); + CU_ASSERT(pmr != ODP_PMR_INVAL); + + retval = odp_pmr_match_count(pmr); + CU_ASSERT(retval == 0); + + odp_pmr_destroy(pmr); +} + +static void classification_pmr_terms_avail(void) +{ + int retval; + /* Since this API called at the start of the suite the return value + should be greater than 0 */ + retval = odp_pmr_terms_avail(); + CU_ASSERT(retval > 0); +} + +static void classification_pmr_terms_cap(void) +{ + unsigned long long retval; + /* Need to check different values for different platforms */ + retval = odp_pmr_terms_cap(); + CU_ASSERT(retval | (1 << ODP_PMR_IPPROTO)); +} + +static void classification_pktio_configure(void) +{ + /* Configure the Different CoS for the pktio interface */ + if (TEST_DEFAULT) + configure_pktio_default_cos(); + if (TEST_ERROR) + configure_pktio_error_cos(); + if (TEST_PMR_CHAIN) + configure_cls_pmr_chain(); + if (TEST_L2_QOS) + configure_cos_with_l2_priority(); + if (TEST_PMR) + configure_pmr_cos(); + if (TEST_PMR_SET) + configure_pktio_pmr_match_set_cos(); +} +static void classification_pktio_test(void) +{ + /* Test Different CoS on the pktio interface */ + if (TEST_DEFAULT) + test_pktio_default_cos(); + if (TEST_ERROR) + test_pktio_error_cos(); + if (TEST_PMR_CHAIN) + test_cls_pmr_chain(); + if (TEST_L2_QOS) + test_cos_with_l2_priority(); + if (TEST_PMR) + test_pmr_cos(); + if (TEST_PMR_SET) + test_pktio_pmr_match_set_cos(); +} + +CU_TestInfo classification_tests[] = { + _CU_TEST_INFO(classification_pmr_terms_avail), + _CU_TEST_INFO(classification_pktio_set_skip), + _CU_TEST_INFO(classification_pktio_set_headroom), + _CU_TEST_INFO(classification_pmr_terms_cap), + _CU_TEST_INFO(classification_pktio_configure), + _CU_TEST_INFO(classification_pktio_test), + _CU_TEST_INFO(classification_pmr_match_count), + CU_TEST_INFO_NULL, +}; diff --git a/test/validation/classification/odp_classification_testsuites.h b/test/validation/classification/odp_classification_testsuites.h new file mode 100644 index 0000000..0ac5eda --- /dev/null +++ b/test/validation/classification/odp_classification_testsuites.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_CLASSIFICATION_TESTSUITES_H_ +#define ODP_CLASSIFICATION_TESTSUITES_H_ + +#include +#include +#include + +/* Helper macro for CU_TestInfo initialization */ +#define _CU_TEST_INFO(test_func) {#test_func, test_func} + +extern CU_TestInfo classification_tests[]; +extern CU_TestInfo classification_basic[]; + +extern int classification_tests_init(void); +extern int classification_tests_finalize(void); + +odp_packet_t create_packet(bool vlan); +void configure_pktio_default_cos(void); +void test_pktio_default_cos(void); +void configure_pktio_error_cos(void); +void test_pktio_error_cos(void); +void configure_cls_pmr_chain(void); +void test_cls_pmr_chain(void); +void configure_cos_with_l2_priority(void); +void test_cos_with_l2_priority(void); +void configure_pmr_cos(void); +void test_pmr_cos(void); +void configure_pktio_pmr_match_set_cos(void); +void test_pktio_pmr_match_set_cos(void); + + +#endif /* ODP_BUFFER_TESTSUITES_H_ */ diff --git a/test/validation/odp_classification.c b/test/validation/odp_classification.c new file mode 100644 index 0000000..b501015 --- /dev/null +++ b/test/validation/odp_classification.c @@ -0,0 +1,19 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "odp_classification_testsuites.h" + +CU_SuiteInfo odp_testsuites[] = { + { .pName = "classification basic", + .pTests = classification_basic, + }, + { .pName = "classification tests", + .pTests = classification_tests, + .pInitFunc = classification_tests_init, + .pCleanupFunc = classification_tests_finalize, + }, + CU_SUITE_INFO_NULL, +};