Test packet parsing using predefined test packets (byte arrays). Test
packets are looped through tested pktio interfaces to force packet parsing.

Signed-off-by: Matias Elo <[email protected]>
Reviewed-and-tested-by: Bill Fischofer <[email protected]>
---
 test/common_plat/validation/api/pktio/Makefile.am |   4 +-
 test/common_plat/validation/api/pktio/parser.c    | 545 ++++++++++++++++++++++
 test/common_plat/validation/api/pktio/parser.h    | 180 +++++++
 test/common_plat/validation/api/pktio/pktio.c     |   5 +-
 test/common_plat/validation/api/pktio/pktio.h     |   3 +
 5 files changed, 733 insertions(+), 4 deletions(-)
 create mode 100644 test/common_plat/validation/api/pktio/parser.c
 create mode 100644 test/common_plat/validation/api/pktio/parser.h

diff --git a/test/common_plat/validation/api/pktio/Makefile.am 
b/test/common_plat/validation/api/pktio/Makefile.am
index 466d690..c6368fb 100644
--- a/test/common_plat/validation/api/pktio/Makefile.am
+++ b/test/common_plat/validation/api/pktio/Makefile.am
@@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la
 libtestpktio_la_SOURCES = pktio.c
 
 test_PROGRAMS = pktio_main$(EXEEXT)
-dist_pktio_main_SOURCES = pktio_main.c
+dist_pktio_main_SOURCES = pktio_main.c parser.c
 pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP)
 
-EXTRA_DIST = pktio.h
+EXTRA_DIST = pktio.h parser.h
diff --git a/test/common_plat/validation/api/pktio/parser.c 
b/test/common_plat/validation/api/pktio/parser.c
new file mode 100644
index 0000000..ad7101d
--- /dev/null
+++ b/test/common_plat/validation/api/pktio/parser.c
@@ -0,0 +1,545 @@
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+#include <odp_api.h>
+#include <odp_cunit_common.h>
+
+#include <odp/helper/odph_api.h>
+
+#include <stdlib.h>
+#include "parser.h"
+#include "pktio.h"
+
+#define MAX_NUM_IFACES         2
+#define PKT_POOL_NUM           256
+#define PKT_POOL_BUF_LEN       (2 * 1024)
+
+/**
+ * local container for pktio attributes
+ */
+typedef struct {
+       const char *name;
+       odp_pktio_t hdl;
+       odp_pktout_queue_t pktout;
+       odp_pktin_queue_t pktin;
+} pktio_info_t;
+
+/** Interface names used for testing */
+static const char *iface_name[MAX_NUM_IFACES];
+
+/** Test interfaces */
+pktio_info_t pktios[MAX_NUM_IFACES];
+pktio_info_t *pktio_a;
+pktio_info_t *pktio_b;
+
+/** Number of interfaces being used (1=loopback, 2=pair) */
+static int num_ifaces;
+
+/** While testing real-world interfaces additional time may be needed for
+ *  external network to enable link to pktio interface that just become up.
+ */
+static bool wait_for_network;
+
+/** Parser packet pool */
+odp_pool_t parser_pool = ODP_POOL_INVALID;
+
+static inline void wait_linkup(odp_pktio_t pktio)
+{
+       /* wait 1 second for link up */
+       uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS);
+       int wait_num = 100;
+       int i;
+       int ret = -1;
+
+       for (i = 0; i < wait_num; i++) {
+               ret = odp_pktio_link_status(pktio);
+               if (ret < 0 || ret == 1)
+                       break;
+               /* link is down, call status again after delay */
+               odp_time_wait_ns(wait_ns);
+       }
+}
+
+static int pkt_pool_create(void)
+{
+       odp_pool_capability_t capa;
+       odp_pool_param_t params;
+
+       if (odp_pool_capability(&capa) != 0) {
+               printf("Error: unable to query pool capability.\n");
+               return -1;
+       }
+
+       if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) {
+               printf("Error: packet pool size not supported.\n");
+               printf("MAX: %" PRIu32 "\n", capa.pkt.max_num);
+               return -1;
+       } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) {
+               printf("Error: packet length not supported.\n");
+               return -1;
+       } else if (capa.pkt.max_seg_len &&
+                  capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) {
+               printf("Error: segment length not supported.\n");
+               return -1;
+       }
+
+       odp_pool_param_init(&params);
+       params.pkt.seg_len = PKT_POOL_BUF_LEN;
+       params.pkt.len = PKT_POOL_BUF_LEN;
+       params.pkt.num     = PKT_POOL_NUM;
+       params.type        = ODP_POOL_PACKET;
+
+       parser_pool = odp_pool_create("pkt_pool_default", &params);
+       if (parser_pool == ODP_POOL_INVALID) {
+               printf("Error: packet pool create failed.\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool)
+{
+       odp_pktio_t pktio;
+       odp_pktio_config_t config;
+       odp_pktio_param_t pktio_param;
+       const char *iface = iface_name[iface_idx];
+
+       odp_pktio_param_init(&pktio_param);
+       pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT;
+       pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
+
+       pktio = odp_pktio_open(iface, pool, &pktio_param);
+       if (pktio == ODP_PKTIO_INVALID) {
+               printf("Error: failed to open %s\n", iface);
+               return ODP_PKTIO_INVALID;
+       }
+
+       odp_pktio_config_init(&config);
+       config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL;
+       if (odp_pktio_config(pktio, &config)) {
+               printf("Error:  failed to configure %s\n", iface);
+               return ODP_PKTIO_INVALID;
+       }
+
+       /* By default, single input and output queue is used */
+       if (odp_pktin_queue_config(pktio, NULL)) {
+               printf("Error: failed to config input queue for %s\n", iface);
+               return ODP_PKTIO_INVALID;
+       }
+       if (odp_pktout_queue_config(pktio, NULL)) {
+               printf("Error: failed to config output queue for %s\n", iface);
+               return ODP_PKTIO_INVALID;
+       }
+
+       if (wait_for_network)
+               odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4);
+
+       return pktio;
+}
+
+static odp_packet_t create_packet(const uint8_t *data, uint32_t len)
+{
+       odp_packet_t pkt;
+
+       pkt = odp_packet_alloc(parser_pool, len);
+       if (pkt == ODP_PACKET_INVALID)
+               return ODP_PACKET_INVALID;
+
+       if (odp_packet_copy_from_mem(pkt, 0, len, data)) {
+               printf("Error: failed to copy test packet data\n");
+               odp_packet_free(pkt);
+               return ODP_PACKET_INVALID;
+       }
+
+       odp_packet_l2_offset_set(pkt, 0);
+
+       return pkt;
+}
+
+/**
+ * Receive incoming packets and compare them to the original. Function returns
+ * a valid packet handle only when the received packet matches to the original
+ * packet.
+ */
+static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin,
+                                       odp_packet_t orig_pkt, uint64_t ns)
+{
+       odp_packet_t pkt = ODP_PACKET_INVALID;
+       odp_time_t wait_time, end;
+       uint32_t orig_len;
+       uint8_t *orig_data;
+
+       orig_len = odp_packet_len(orig_pkt);
+       orig_data = odp_packet_data(orig_pkt);
+       wait_time = odp_time_local_from_ns(ns);
+       end = odp_time_sum(odp_time_local(), wait_time);
+
+       do {
+               int ret;
+               odp_packet_t tmp_pkt;
+
+               ret = odp_pktin_recv(pktin, &tmp_pkt, 1);
+               if (ret < 0)
+                       break;
+
+               if (ret == 1) {
+                       uint32_t len;
+                       uint8_t *data;
+
+                       len = odp_packet_len(tmp_pkt);
+                       data = odp_packet_data(tmp_pkt);
+
+                       if (len == orig_len &&
+                           memcmp(data, orig_data, len) == 0) {
+                               pkt = tmp_pkt;
+                               break;
+                       }
+                       odp_packet_free(tmp_pkt);
+               }
+       } while (odp_time_cmp(end, odp_time_local()) > 0);
+
+       return pkt;
+}
+
+/**
+ * Creates a test packet from data array and loops it through the test pktio
+ * interfaces forcing packet parsing.
+ */
+static odp_packet_t loopback_packet(pktio_info_t *pktio_a,
+                                   pktio_info_t *pktio_b, const uint8_t *data,
+                                   uint32_t len)
+{
+       odp_packet_t pkt;
+       odp_packet_t sent_pkt;
+
+       pkt = create_packet(data, len);
+       if (pkt == ODP_PACKET_INVALID) {
+               CU_FAIL("failed to generate test packet");
+               return ODP_PACKET_INVALID;
+       }
+
+       pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl);
+
+       sent_pkt = odp_packet_copy(pkt, parser_pool);
+       if (sent_pkt == ODP_PACKET_INVALID) {
+               CU_FAIL_FATAL("failed to copy test packet");
+               odp_packet_free(pkt);
+               return ODP_PACKET_INVALID;
+       }
+
+       while (1) {
+               int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1);
+
+               if (ret < 0) {
+                       CU_FAIL_FATAL("failed to send test packet");
+                       odp_packet_free(pkt);
+                       odp_packet_free(sent_pkt);
+                       return ODP_PACKET_INVALID;
+               }
+               if (ret == 1)
+                       break;
+       }
+
+       /* and wait for them to arrive back */
+       pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS);
+       odp_packet_free(sent_pkt);
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl);
+       CU_ASSERT(odp_packet_has_error(pkt) == 0);
+
+       return pkt;
+}
+
+void parser_test_arp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp,
+                             sizeof(test_packet_arp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_arp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv4(pkt));
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv4_icmp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp,
+                             sizeof(test_packet_ipv4_icmp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv4(pkt));
+       CU_ASSERT(odp_packet_has_icmp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+       CU_ASSERT(!odp_packet_has_udp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv4_tcp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp,
+                             sizeof(test_packet_ipv4_tcp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv4(pkt));
+       CU_ASSERT(odp_packet_has_tcp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+       CU_ASSERT(!odp_packet_has_udp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv4_udp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp,
+                             sizeof(test_packet_ipv4_udp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv4(pkt));
+       CU_ASSERT(odp_packet_has_udp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_vlan_ipv4_udp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp,
+                             sizeof(test_packet_vlan_ipv4_udp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_vlan(pkt));
+       CU_ASSERT(odp_packet_has_ipv4(pkt));
+       CU_ASSERT(odp_packet_has_udp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_vlan_qinq_ipv4_udp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp,
+                             sizeof(test_packet_vlan_qinq_ipv4_udp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_vlan(pkt));
+       CU_ASSERT(odp_packet_has_vlan_qinq(pkt));
+       CU_ASSERT(odp_packet_has_ipv4(pkt));
+       CU_ASSERT(odp_packet_has_udp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv6(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv6_icmp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp,
+                             sizeof(test_packet_ipv6_icmp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv6(pkt));
+       CU_ASSERT(odp_packet_has_icmp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv4(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+       CU_ASSERT(!odp_packet_has_udp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv6_tcp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp,
+                             sizeof(test_packet_ipv6_tcp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv6(pkt));
+       CU_ASSERT(odp_packet_has_tcp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv4(pkt));
+       CU_ASSERT(!odp_packet_has_udp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_ipv6_udp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp,
+                             sizeof(test_packet_ipv6_udp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_ipv6(pkt));
+       CU_ASSERT(odp_packet_has_udp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv4(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+void parser_test_vlan_ipv6_udp(void)
+{
+       odp_packet_t pkt;
+
+       pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp,
+                             sizeof(test_packet_vlan_ipv6_udp));
+       CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
+       CU_ASSERT(odp_packet_has_eth(pkt));
+       CU_ASSERT(odp_packet_has_vlan(pkt));
+       CU_ASSERT(odp_packet_has_ipv6(pkt));
+       CU_ASSERT(odp_packet_has_udp(pkt));
+
+       CU_ASSERT(!odp_packet_has_ipv4(pkt));
+       CU_ASSERT(!odp_packet_has_tcp(pkt));
+
+       odp_packet_free(pkt);
+}
+
+int parser_suite_init(void)
+{
+       int i;
+
+       if (getenv("ODP_WAIT_FOR_NETWORK"))
+               wait_for_network = true;
+
+       iface_name[0] = getenv("ODP_PKTIO_IF0");
+       iface_name[1] = getenv("ODP_PKTIO_IF1");
+       num_ifaces = 1;
+
+       if (!iface_name[0]) {
+               printf("No interfaces specified, using default \"loop\".\n");
+               iface_name[0] = "loop";
+       } else if (!iface_name[1]) {
+               printf("Using loopback interface: %s\n", iface_name[0]);
+       } else {
+               num_ifaces = 2;
+               printf("Using paired interfaces: %s %s\n",
+                      iface_name[0], iface_name[1]);
+       }
+
+       if (pkt_pool_create() != 0) {
+               printf("Error: failed to create parser pool\n");
+               return -1;
+       }
+
+       /* Create pktios and associate input/output queues */
+       for (i = 0; i < num_ifaces; ++i) {
+               pktio_info_t *io;
+
+               io = &pktios[i];
+               io->name = iface_name[i];
+               io->hdl   = create_pktio(i, parser_pool);
+               if (io->hdl == ODP_PKTIO_INVALID) {
+                       printf("Error: failed to open iface");
+                       return -1;
+               }
+
+               if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) {
+                       printf("Error: failed to start iface: %s\n", io->name);
+                       return -1;
+               }
+
+               if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) {
+                       printf("Error: failed to start iface: %s\n", io->name);
+                       return -1;
+               }
+
+               if (odp_pktio_start(io->hdl)) {
+                       printf("Error: failed to start iface: %s\n", io->name);
+                       return -1;
+               }
+
+               wait_linkup(io->hdl);
+       }
+
+       pktio_a = &pktios[0];
+       pktio_b = &pktios[1];
+       if (num_ifaces == 1)
+               pktio_b = pktio_a;
+
+       return 0;
+}
+
+int parser_suite_term(void)
+{
+       int i;
+       int ret = 0;
+
+       for (i = 0; i < num_ifaces; ++i) {
+               if (odp_pktio_stop(pktios[i].hdl)) {
+                       printf("Error: failed to stop pktio: %s\n",
+                              pktios[i].name);
+                       ret = -1;
+               }
+               if (odp_pktio_close(pktios[i].hdl)) {
+                       printf("Error: failed to close pktio: %s\n",
+                              pktios[i].name);
+                       ret = -1;
+               }
+       }
+
+       if (odp_pool_destroy(parser_pool) != 0) {
+               printf("Error: failed to destroy packet pool\n");
+               ret = -1;
+       }
+
+       return ret;
+}
+
+/**
+ * Certain tests can only be run with 'loop' pktio.
+ */
+static int loop_pktio(void)
+{
+       if (strcmp(iface_name[0], "loop") == 0)
+               return ODP_TEST_ACTIVE;
+       else
+               return ODP_TEST_INACTIVE;
+}
+
+odp_testinfo_t parser_suite[] = {
+       ODP_TEST_INFO(parser_test_arp),
+       ODP_TEST_INFO(parser_test_ipv4_icmp),
+       ODP_TEST_INFO(parser_test_ipv4_tcp),
+       ODP_TEST_INFO(parser_test_ipv4_udp),
+       ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio),
+       ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio),
+       ODP_TEST_INFO(parser_test_ipv6_icmp),
+       ODP_TEST_INFO(parser_test_ipv6_tcp),
+       ODP_TEST_INFO(parser_test_ipv6_udp),
+       ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio),
+       ODP_TEST_INFO_NULL
+};
diff --git a/test/common_plat/validation/api/pktio/parser.h 
b/test/common_plat/validation/api/pktio/parser.h
new file mode 100644
index 0000000..57c6238
--- /dev/null
+++ b/test/common_plat/validation/api/pktio/parser.h
@@ -0,0 +1,180 @@
+/* Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef _ODP_TEST_PARSER_H_
+#define _ODP_TEST_PARSER_H_
+
+#include <odp_cunit_common.h>
+
+/* test functions: */
+void parser_test_arp(void);
+void parser_test_ipv4_icmp(void);
+void parser_test_ipv4_tcp(void);
+void parser_test_ipv4_udp(void);
+void parser_test_vlan_ipv4_udp(void);
+void parser_test_vlan_qinq_ipv4_udp(void);
+void parser_test_ipv6_icmp(void);
+void parser_test_ipv6_tcp(void);
+void parser_test_ipv6_udp(void);
+void parser_test_vlan_ipv6_udp(void);
+
+/* test array init/term functions: */
+int parser_suite_term(void);
+int parser_suite_init(void);
+
+/* test arrays: */
+extern odp_testinfo_t parser_suite[];
+
+/**
+ * ARP request
+ */
+static const uint8_t test_packet_arp[] = {
+       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01,
+       0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8,
+       0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+       0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+       0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43,
+};
+
+/**
+ * ICMPv4 echo reply
+ */
+static const uint8_t test_packet_ipv4_icmp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00,
+       0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+       0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8,
+       0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01,
+       0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+       0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+       0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02,
+};
+
+/**
+ * IPv4 TCP
+ */
+static const uint8_t test_packet_ipv4_tcp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00,
+       0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06,
+       0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8,
+       0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00,
+       0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00,
+       0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48,
+};
+
+/**
+ * IPv4 UDP
+ */
+static const uint8_t test_packet_ipv4_udp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00,
+       0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11,
+       0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8,
+       0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A,
+       0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+       0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+       0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6,
+};
+
+/**
+ * VLAN IPv4 UDP
+ * - ID: 23
+ */
+static const uint8_t test_packet_vlan_ipv4_udp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17,
+       0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00,
+       0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8,
+       0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F,
+       0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01,
+       0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+       0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29,
+};
+
+/**
+ * VLAN Q-in-Q IPv4 UDP
+ * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1
+ * - Inner: Tag Protocol ID 0x8100, VLAN ID 2
+ */
+static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01,
+       0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00,
+       0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11,
+       0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8,
+       0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12,
+       0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+       0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18,
+};
+
+/**
+ * ICMPv6 echo request
+ */
+static const uint8_t test_packet_ipv6_icmp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30,
+       0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55,
+       0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77,
+       0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00,
+       0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68,
+       0x0E, 0xBA,
+};
+
+/**
+ * IPv6 TCP
+ */
+static const uint8_t test_packet_ipv6_tcp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30,
+       0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55,
+       0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77,
+       0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2,
+       0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+       0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37,
+       0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF,
+};
+
+/**
+ * IPv6 UDP
+ */
+static const uint8_t test_packet_ipv6_udp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30,
+       0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+       0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55,
+       0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77,
+       0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F,
+       0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3,
+       0x64, 0x49,
+};
+
+/**
+ * VLAN IPv6
+ * - ID: 23
+ */
+static const uint8_t test_packet_vlan_ipv6_udp[] = {
+       0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00,
+       0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17,
+       0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08,
+       0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00,
+       0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66,
+       0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88,
+       0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08,
+       0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C,
+};
+
+#endif
diff --git a/test/common_plat/validation/api/pktio/pktio.c 
b/test/common_plat/validation/api/pktio/pktio.c
index a5af901..d3eb838 100644
--- a/test/common_plat/validation/api/pktio/pktio.c
+++ b/test/common_plat/validation/api/pktio/pktio.c
@@ -10,6 +10,7 @@
 
 #include <stdlib.h>
 #include "pktio.h"
+#include "parser.h"
 
 #define PKT_BUF_NUM            32
 #define PKT_BUF_SIZE           (9 * 1024)
@@ -140,8 +141,7 @@ static void set_pool_len(odp_pool_param_t *params, 
odp_pool_capability_t *capa)
        }
 }
 
-static void pktio_pkt_set_macs(odp_packet_t pkt,
-                              odp_pktio_t src, odp_pktio_t dst)
+void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst)
 {
        uint32_t len;
        odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len);
@@ -2187,6 +2187,7 @@ odp_suiteinfo_t pktio_suites[] = {
         pktio_suite_term, pktio_suite_unsegmented},
        {"Packet I/O Segmented", pktio_suite_init_segmented,
         pktio_suite_term, pktio_suite_segmented},
+       {"Packet parser", parser_suite_init, parser_suite_term, parser_suite},
        ODP_SUITE_INFO_NULL
 };
 
diff --git a/test/common_plat/validation/api/pktio/pktio.h 
b/test/common_plat/validation/api/pktio/pktio.h
index 8131d05..b8799d9 100644
--- a/test/common_plat/validation/api/pktio/pktio.h
+++ b/test/common_plat/validation/api/pktio/pktio.h
@@ -61,4 +61,7 @@ extern odp_suiteinfo_t pktio_suites[];
 /* main test program: */
 int pktio_main(int argc, char *argv[]);
 
+/* functions shared by parser test suite */
+void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst);
+
 #endif
-- 
2.7.4

Reply via email to