@@ -26,6 +26,7 @@ extern "C" {
* @{
*/
+#define ODPH_TCPHDR_LEN 20 /**< Min length of TCP header (no options) */
/** TCP header */
typedef struct ODP_PACKED {
@@ -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)
@@ -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,
@@ -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);
new file mode 100644
@@ -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 *)(ð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 *)(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;
+}
new file mode 100644
@@ -0,0 +1,554 @@
+/* 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(¶m);
+ 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", ¶m);
+ if (ODP_POOL_INVALID == pool) {
+ fprintf(stderr, "Packet pool creation failed.\n");
+ return -1;
+ }
+
+ pool_default = odp_pool_lookup("classification_pmr_pool");
+ if (pool_default == ODP_POOL_INVALID)
+ return -1;
+
+ odp_atomic_init_u32(&seq, 0);
+ return 0;
+}
+
+odp_pktio_t create_pktio(odp_queue_type_t q_type)
+{
+ odp_pktio_t pktio;
+ odp_pktio_param_t pktio_param;
+ odp_pool_t pool;
+ int ret;
+
+ pool = odp_pool_lookup("classification_pmr_pool");
+ if (pool == ODP_POOL_INVALID)
+ return ODP_PKTIO_INVALID;
+
+ memset(&pktio_param, 0, sizeof(pktio_param));
+ if (q_type == ODP_QUEUE_TYPE_POLL)
+ pktio_param.in_mode = ODP_PKTIN_MODE_POLL;
+ else
+ pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
+
+ pktio = odp_pktio_open("loop", pool, &pktio_param);
+ if (pktio == ODP_PKTIO_INVALID) {
+ ret = odp_pool_destroy(pool);
+ if (ret)
+ fprintf(stderr, "unable to destroy pool.\n");
+ return ODP_PKTIO_INVALID;
+ }
+
+ ret = odp_pktio_start(pktio);
+ if (ret) {
+ fprintf(stderr, "unable to start loop\n");
+ return ODP_PKTIO_INVALID;
+ }
+
+ return pktio;
+}
+
+odp_queue_t create_default_inq(odp_pktio_t pktio, odp_queue_type_t qtype)
+{
+ odp_queue_param_t qparam;
+ odp_queue_t inq_def;
+ char inq_name[ODP_QUEUE_NAME_LEN];
+
+ odp_queue_param_init(&qparam);
+ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC;
+ qparam.sched.group = ODP_SCHED_GROUP_ALL;
+
+ snprintf(inq_name, sizeof(inq_name), "inq-pktio-%" PRIu64,
+ odp_pktio_to_u64(pktio));
+ inq_def = odp_queue_lookup(inq_name);
+ if (inq_def == ODP_QUEUE_INVALID)
+ inq_def = odp_queue_create(
+ inq_name,
+ ODP_QUEUE_TYPE_PKTIN,
+ qtype == ODP_QUEUE_TYPE_POLL ? NULL : &qparam);
+
+ CU_ASSERT(inq_def != ODP_QUEUE_INVALID);
+
+ if (0 > odp_pktio_inq_setdef(pktio, inq_def))
+ return ODP_QUEUE_INVALID;
+
+ return inq_def;
+}
+
+int classification_suite_pmr_term(void)
+{
+ int retcode = 0;
+
+ if (0 != odp_pool_destroy(pool_default)) {
+ fprintf(stderr, "pool_default destroy failed.\n");
+ retcode = -1;
+ }
+
+ return retcode;
+}
+
+static void classification_test_pmr_term_tcp_dport(void)
+{
+ odp_packet_t pkt;
+ odph_tcphdr_t *tcp;
+ uint32_t seqno;
+ uint16_t val;
+ uint16_t mask;
+ int retval;
+ odp_pktio_t pktio;
+ odp_queue_t queue;
+ odp_queue_t retqueue;
+ odp_queue_t defqueue;
+ odp_pmr_t pmr;
+ odp_cos_t cos;
+ char cosname[ODP_QUEUE_NAME_LEN];
+ char queuename[ODP_QUEUE_NAME_LEN];
+
+ val = CLS_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);
+
+ pmr = odp_pmr_create(ODP_PMR_TCP_DPORT, &val,
+ &mask, sizeof(val));
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ sprintf(cosname, "tcp_dport");
+ cos = odp_cos_create(cosname);
+ CU_ASSERT(cos != ODP_COS_INVALID);
+
+ sprintf(queuename, "%s", "tcp_dport1");
+
+ queue = queue_create(queuename, true);
+ CU_ASSERT(queue != ODP_QUEUE_INVALID);
+
+ retval = odp_cos_queue_set(cos, queue);
+ CU_ASSERT(retval == 0);
+
+ retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+ CU_ASSERT(retval == 0);
+
+ pkt = create_packet(pool_default, false, &seq, false);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+ tcp->dst_port = odp_cpu_to_be_16(CLS_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];
+
+ val = CLS_DEFAULT_SPORT;
+ mask = 0xffff;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+ defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+ pmr = odp_pmr_create(ODP_PMR_TCP_SPORT, &val,
+ &mask, sizeof(val));
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ sprintf(cosname, "tcp_sport");
+ cos = odp_cos_create(cosname);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ sprintf(queuename, "%s", "tcp_sport");
+
+ queue = queue_create(queuename, true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ retval = odp_cos_queue_set(cos, queue);
+ CU_ASSERT(retval == 0);
+
+ retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+ CU_ASSERT(retval == 0);
+
+ pkt = create_packet(pool_default, false, &seq, false);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ tcp = (odph_tcphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+ tcp->src_port = odp_cpu_to_be_16(CLS_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];
+
+ val = CLS_DEFAULT_DPORT;
+ mask = 0xffff;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+ defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+ pmr = odp_pmr_create(ODP_PMR_UDP_DPORT, &val,
+ &mask, sizeof(val));
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ sprintf(cosname, "udp_dport");
+ cos = odp_cos_create(cosname);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ sprintf(queuename, "%s", "udp_dport");
+
+ queue = queue_create(queuename, true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ retval = odp_cos_queue_set(cos, queue);
+ CU_ASSERT(retval == 0);
+
+ retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+ CU_ASSERT(retval == 0);
+
+ pkt = create_packet(pool_default, false, &seq, true);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+ udp->dst_port = odp_cpu_to_be_16(CLS_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];
+
+ val = CLS_DEFAULT_SPORT;
+ mask = 0xffff;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+ defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+ pmr = odp_pmr_create(ODP_PMR_UDP_SPORT, &val,
+ &mask, sizeof(val));
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ sprintf(cosname, "udp_sport");
+ cos = odp_cos_create(cosname);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ sprintf(queuename, "%s", "udp_sport");
+
+ queue = queue_create(queuename, true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ retval = odp_cos_queue_set(cos, queue);
+ CU_ASSERT(retval == 0);
+
+ retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+ CU_ASSERT(retval == 0);
+
+ pkt = create_packet(pool_default, false, &seq, true);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ udp = (odph_udphdr_t *)odp_packet_l4_ptr(pkt, NULL);
+ udp->src_port = odp_cpu_to_be_16(CLS_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];
+
+ val = ODPH_IPPROTO_UDP;
+ mask = 0xff;
+ seqno = 0;
+
+ pktio = create_pktio(ODP_QUEUE_TYPE_SCHED);
+ defqueue = create_default_inq(pktio, ODP_QUEUE_TYPE_SCHED);
+
+ pmr = odp_pmr_create(ODP_PMR_IPPROTO, &val,
+ &mask, sizeof(val));
+ CU_ASSERT(pmr != ODP_PMR_INVAL);
+
+ sprintf(cosname, "ipproto");
+ cos = odp_cos_create(cosname);
+ CU_ASSERT_FATAL(cos != ODP_COS_INVALID);
+
+ sprintf(queuename, "%s", "ipproto");
+
+ queue = queue_create(queuename, true);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ retval = odp_cos_queue_set(cos, queue);
+ CU_ASSERT(retval == 0);
+
+ retval = odp_pktio_pmr_cos(pmr, pktio, cos);
+ CU_ASSERT(retval == 0);
+
+ pkt = create_packet(pool_default, false, &seq, true);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+ CU_ASSERT(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == queue);
+ odp_packet_free(pkt);
+
+ /* Other packets delivered to default queue */
+ pkt = create_packet(pool_default, false, &seq, false);
+ seqno = cls_pkt_get_seq(pkt);
+ CU_ASSERT(seqno != TEST_SEQ_INVALID);
+
+ enqueue_pktio_interface(pkt, pktio);
+
+ pkt = receive_packet(&retqueue, ODP_TIME_SEC);
+ CU_ASSERT(pkt != ODP_PACKET_INVALID);
+ CU_ASSERT(cls_pkt_get_seq(pkt) != TEST_SEQ_INVALID);
+ CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
+ CU_ASSERT(retqueue == defqueue);
+
+ odp_cos_destroy(cos);
+ odp_pmr_destroy(pmr);
+ odp_packet_free(pkt);
+ destroy_inq(pktio);
+ odp_queue_destroy(queue);
+ odp_pktio_close(pktio);
+}
+
+CU_TestInfo classification_suite_pmr[] = {
+ _CU_TEST_INFO(classification_test_pmr_term_tcp_dport),
+ _CU_TEST_INFO(classification_test_pmr_term_tcp_sport),
+ _CU_TEST_INFO(classification_test_pmr_term_udp_dport),
+ _CU_TEST_INFO(classification_test_pmr_term_udp_sport),
+ _CU_TEST_INFO(classification_test_pmr_term_ipproto),
+ CU_TEST_INFO_NULL,
+};
@@ -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 *)(ð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 *)(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", ¶m);
- if (ODP_POOL_INVALID == pool) {
+ pool_default = odp_pool_create("classification_pool", ¶m);
+ if (ODP_POOL_INVALID == pool_default) {
fprintf(stderr, "Packet pool creation failed.\n");
return -1;
}
- pool_default = odp_pool_lookup("classification_pool");
- if (pool_default == ODP_POOL_INVALID)
- return -1;
-
memset(&pktio_param, 0, sizeof(pktio_param));
pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;
@@ -393,6 +168,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,
@@ -452,10 +228,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);
@@ -465,25 +243,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);
}
@@ -519,16 +301,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);
}
@@ -568,15 +353,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);
@@ -659,19 +445,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 *)(ðhdr->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);
}
}
@@ -720,16 +508,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);
}
@@ -795,10 +585,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);
@@ -807,10 +599,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);
}
@@ -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);
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> --- v4: Move hash defines to header file 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 | 554 +++++++++++++++++++++ .../classification/odp_classification_tests.c | 309 ++---------- .../classification/odp_classification_testsuites.h | 15 +- 8 files changed, 923 insertions(+), 259 deletions(-) create mode 100644 test/validation/classification/odp_classification_common.c create mode 100644 test/validation/classification/odp_classification_test_pmr.c