Message ID | 1470154104-23566-1-git-send-email-maxim.uvarov@linaro.org |
---|---|
State | Superseded |
Headers | show |
On Tue, Aug 2, 2016 at 11:08 AM, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > add pcap play back test which takes 2 arguments: 1 - pcap file, > 2 - packet mask to match. Intend is to test odp with different > input traffic to check internal implementation functions. In > current case it's test for vlan tag instertion for packet mmap: > pkt_mmap_vlan_insert(). > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > Reviewed-and-tested-by: Bill Fischofer <bill.fischofer@linaro.org> > --- > v2: up the patch, dirrect execution looks like works. > > test/linux-generic/.gitignore | 1 + > test/linux-generic/Makefile.am | 10 +- > test/linux-generic/cls/.gitignore | 3 + > test/linux-generic/cls/Makefile.am | 13 ++ > test/linux-generic/cls/cls.c | 349 ++++++++++++++++++++++++++++++ > ++++++ > test/linux-generic/cls/cls_main.c | 12 ++ > test/linux-generic/cls/cls_suites.h | 1 + > test/linux-generic/cls/vlan.pcap | Bin 0 -> 9728 bytes > test/linux-generic/cls/vlan_run.sh | 49 +++++ > test/linux-generic/m4/configure.m4 | 1 + > 10 files changed, 435 insertions(+), 4 deletions(-) > create mode 100644 test/linux-generic/cls/.gitignore > create mode 100644 test/linux-generic/cls/Makefile.am > create mode 100644 test/linux-generic/cls/cls.c > create mode 100644 test/linux-generic/cls/cls_main.c > create mode 100644 test/linux-generic/cls/cls_suites.h > create mode 100644 test/linux-generic/cls/vlan.pcap > create mode 100755 test/linux-generic/cls/vlan_run.sh > > diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore > index 5dabf91..f65c7c1 100644 > --- a/test/linux-generic/.gitignore > +++ b/test/linux-generic/.gitignore > @@ -1,3 +1,4 @@ > *.log > *.trs > tests-validation.env > +test_out.pcap > diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile. > am > index f5cc52d..9acbab0 100644 > --- a/test/linux-generic/Makefile.am > +++ b/test/linux-generic/Makefile.am > @@ -1,5 +1,8 @@ > include $(top_srcdir)/test/Makefile.inc > TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation > +TEST_EXTENSIONS = .sh > + > +dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > > ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api > > @@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \ > > SUBDIRS += validation/api/pktio\ > validation/api/shmem\ > + cls\ > pktio_ipc\ > ring > > if HAVE_PCAP > TESTS += validation/api/pktio/pktio_run_pcap.sh > +TESTS += cls/vlan_run.sh > +dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap > endif > if netmap_support > TESTS += validation/api/pktio/pktio_run_netmap.sh > @@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio > endif > endif > > -TEST_EXTENSIONS = .sh > - > -dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > - > test_SCRIPTS = $(dist_check_SCRIPTS) > > tests-validation.env: > diff --git a/test/linux-generic/cls/.gitignore b/test/linux-generic/cls/. > gitignore > new file mode 100644 > index 0000000..9447625 > --- /dev/null > +++ b/test/linux-generic/cls/.gitignore > @@ -0,0 +1,3 @@ > +cls_main > +*.log > +*.trs > diff --git a/test/linux-generic/cls/Makefile.am b/test/linux-generic/cls/ > Makefile.am > new file mode 100644 > index 0000000..43fb0bc > --- /dev/null > +++ b/test/linux-generic/cls/Makefile.am > @@ -0,0 +1,13 @@ > +include ../Makefile.inc > + > +noinst_LTLIBRARIES = libtestcls.la > +libtestcls_la_SOURCES = cls.c > +libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP) > + > +test_PROGRAMS = cls_main$(EXEEXT) > +dist_cls_main_SOURCES = cls_main.c > + > +cls_main_LDFLAGS = $(AM_LDFLAGS) > +cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP) > + > +noinst_HEADERS = cls_suites.h > diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c > new file mode 100644 > index 0000000..d527ec8 > --- /dev/null > +++ b/test/linux-generic/cls/cls.c > @@ -0,0 +1,349 @@ > +/* Copyright (c) 2016, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <stdlib.h> > +#include <string.h> > +#include <getopt.h> > +#include <unistd.h> > +#include <inttypes.h> > + > +#include <test_debug.h> > + > +#include <odp_api.h> > +#include <odp/helper/linux.h> > +#include <odp/helper/eth.h> > +#include <odp/helper/ip.h> > + > +#include <odp_packet_internal.h> > + > +#include "cls_suites.h" > + > +/** Get rid of path in filename - only for unix-type paths using '/' */ > +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ > + strrchr((file_name), '/') + 1 : (file_name)) > + > +/** > + * Print usage information > + */ > +static void usage(char *progname) > +{ > + printf("\n" > + "This is test application to verify that linux-generic > classifier\n" > + "correctly classifies packets on input. Main intend is add > more code\n" > + "coverage for internal functions playing different traffic > recorded to\n" > + "pcap files." > + "\n" > + "Usage: %s OPTIONS\n" > + " E.g. %s -i pcap_file -e expected_bitmask\n" > + "\n" > + "Mandatory OPTIONS:\n" > + " -i, pcap file name\n" > + " -e, expected packet bitmask\n" > + "\n", NO_PATH(progname), NO_PATH(progname) > + ); > +} > + > +/** @def SHM_PKT_POOL_SIZE > + * @brief Size of the shared memory block > + */ > +#define SHM_PKT_POOL_SIZE 512 > + > +/** @def SHM_PKT_POOL_BUF_SIZE > + * @brief Buffer size of the packet pool buffer > + */ > +#define SHM_PKT_POOL_BUF_SIZE 1856 > + > +/** > + * Parsed command line application arguments > + */ > +typedef struct { > + char *file_name; /**< File name for pcap pktio */ > + odp_pktio_t pktio; /**< Pktio dev */ > + input_flags_t expected_bits; /**< Expected bits from test run */ > +} appl_args_t; > + > +/** > + * Grouping of both parsed CL args and thread specific args - alloc > together > + */ > +typedef struct { > + /** Application (parsed) arguments */ > + appl_args_t appl; > +} args_t; > + > +/** Global pointer to args */ > +static args_t *args; > +/** Fill this bit struct to check which packet fields were classified */ > +static input_flags_t packet_flags; > + > +/** > + * Parse and store the command line arguments > + * > + * @param argc argument count > + * @param argv[] argument vector > + * @param appl_args Store application arguments here > + */ > +static void parse_args(int argc, char *argv[], appl_args_t *appl_args) > +{ > + int opt; > + int long_index; > + static const struct option longopts[] = { > + {"interface", required_argument, NULL, 'i'}, /* return > 'i' */ > + {"extected", required_argument, NULL, 'e'}, /* return > 'e' */ > + {"help", no_argument, NULL, 'h'}, /* return > 'h' */ > + {NULL, 0, NULL, 0} > + }; > + > + static const char *shortopts = ":i:e:h"; > + > + /* let helper collect its own arguments (e.g. --odph_proc) */ > + odph_parse_options(argc, argv, shortopts, longopts); > + > + appl_args->file_name = NULL; > + opterr = 0; /* do not issue errors on helper options */ > + appl_args->expected_bits.all = 0; > + > + while (1) { > + opt = getopt_long(argc, argv, shortopts, longopts, > &long_index); > + > + if (opt == -1) > + break; /* No more options */ > + > + switch (opt) { > + case 'i': > + appl_args->file_name = optarg; > + break; > + case 'e': > + appl_args->expected_bits.all = atoll(optarg); > + break; > + > + case 'h': > + usage(argv[0]); > + exit(EXIT_SUCCESS); > + break; > + default: > + break; > + } > + } > + > + if (!appl_args->file_name) { > + usage(argv[0]); > + exit(EXIT_SUCCESS); > + } > + > + optind = 1; /* reset 'extern optind' from the getopt > lib */ > +} > + > +/** > + * Create a pktio handle, optionally associating a default input queue. > + * > + * @param dev Name of device to open > + * @param pool Pool to associate with device for packet RX/TX > + * @param mode Packet processing mode for this device (BURST or QUEUE) > + * > + * @return The handle of the created pktio object. > + * @retval ODP_PKTIO_INVALID if the create fails. > + */ > +static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool) > +{ > + odp_pktio_t pktio; > + int ret; > + odp_pktio_param_t pktio_param; > + odp_pktin_queue_param_t pktin_param; > + char dev[255]; > + > + odp_pktio_param_init(&pktio_param); > + pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; > + > + memset(dev, 0, 255); > + sprintf(dev, "pcap:in=%s:out=test_out.pcap", fname); > + > + /* Open a packet IO instance */ > + pktio = odp_pktio_open(dev, pool, &pktio_param); > + if (pktio == ODP_PKTIO_INVALID) > + LOG_ABORT("Error: pktio create failed for %s\n", dev); > + > + odp_pktin_queue_param_init(&pktin_param); > + > + pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; > + > + if (odp_pktin_queue_config(pktio, &pktin_param)) > + LOG_ABORT("Error: pktin config failed for %s\n", dev); > + > + if (odp_pktout_queue_config(pktio, NULL)) > + LOG_ABORT("Error: pktout config failed for %s\n", dev); > + > + ret = odp_pktio_start(pktio); > + if (ret != 0) > + LOG_ABORT("Error: unable to start %s\n", dev); > + > + printf(" created pktio:%02" PRIu64 > + ", dev:%s, queue mode (ATOMIC queues)\n" > + " \tdefault pktio%02" PRIu64 "\n", > + odp_pktio_to_u64(pktio), dev, > + odp_pktio_to_u64(pktio)); > + > + return pktio; > +} > + > +/** > + * Packet IO loopback worker thread using ODP queues > + * > + * @param arg thread arguments of type 'thread_args_t *' > + */ > +static int pktio_queue_thread(void *arg ODP_UNUSED) > +{ > + int thr = odp_thread_id(); > + odp_pktout_queue_t pktout; > + odp_packet_t pkt; > + odp_event_t ev; > + uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS > * 100); > + > + packet_flags.all = 0; > + > + /* Loop packets */ > + while (1) { > + odp_pktio_t pktio_tmp; > + > + ev = odp_schedule(NULL, sched_wait); > + if (ev == ODP_EVENT_INVALID) > + break; > + > + pkt = odp_packet_from_event(ev); > + if (!odp_packet_is_valid(pkt)) > + continue; > + > + pktio_tmp = odp_packet_input(pkt); > + > + if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) { > + LOG_ERR(" [%02i] Error: no pktout queue\n", thr); > + return -1; > + } > + > + /* Extend bits here for more additional tests */ > + if (odp_packet_has_l2(pkt)) > + packet_flags.parsed_l2 = 1; > + if (odp_packet_has_vlan(pkt)) > + packet_flags.vlan = 1; > + > + /* Enqueue the packet for output */ > + if (odp_pktout_send(pktout, &pkt, 1) != 1) { > + LOG_ERR(" [%i] Packet send failed.\n", thr); > + odp_packet_free(pkt); > + continue; > + } > + } > + > + return 0; > +} > + > +int cls_main(int argc, char *argv[]) > +{ > + odph_odpthread_t thread_tbl[1]; > + odp_pool_t pool; > + int num_workers; > + int i; > + int cpu; > + odp_cpumask_t cpumask; > + char cpumaskstr[ODP_CPUMASK_STR_SIZE]; > + odp_pool_param_t params; > + odp_instance_t instance; > + odph_odpthread_params_t thr_params; > + > + args = calloc(1, sizeof(args_t)); > + if (args == NULL) { > + LOG_ERR("Error: args mem alloc failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + parse_args(argc, argv, &args->appl); > + > + /* Init ODP before calling anything else */ > + if (odp_init_global(&instance, NULL, NULL)) { > + LOG_ERR("Error: ODP global init failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + /* Init this thread */ > + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { > + LOG_ERR("Error: ODP local init failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + num_workers = odp_cpumask_default_worker(&cpumask, 1); > + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, > sizeof(cpumaskstr)); > + > + /* Create packet pool */ > + odp_pool_param_init(¶ms); > + params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; > + params.pkt.len = SHM_PKT_POOL_BUF_SIZE; > + params.pkt.num = SHM_PKT_POOL_SIZE; > + params.type = ODP_POOL_PACKET; > + > + pool = odp_pool_create("packet_pool", ¶ms); > + if (pool == ODP_POOL_INVALID) { > + LOG_ERR("Error: packet pool create failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + args->appl.pktio = create_pktio(args->appl.file_name, pool); > + > + /* Create and init worker threads */ > + memset(thread_tbl, 0, sizeof(thread_tbl)); > + > + memset(&thr_params, 0, sizeof(thr_params)); > + thr_params.thr_type = ODP_THREAD_WORKER; > + thr_params.instance = instance; > + > + cpu = odp_cpumask_first(&cpumask); > + for (i = 0; i < num_workers; ++i) { > + odp_cpumask_t thd_mask; > + int (*thr_run_func)(void *); > + > + thr_run_func = pktio_queue_thread; > + /* > + * Create threads one-by-one instead of all-at-once, > + * because each thread might get different arguments. > + * Calls odp_thread_create(cpu) for each thread > + */ > + odp_cpumask_zero(&thd_mask); > + odp_cpumask_set(&thd_mask, cpu); > + > + thr_params.start = thr_run_func; > + thr_params.arg = &args; > + > + odph_odpthreads_create(&thread_tbl[i], &thd_mask, > &thr_params); > + cpu = odp_cpumask_next(&cpumask, cpu); > + } > + > + /* Master thread waits for other threads to exit */ > + for (i = 0; i < num_workers; ++i) > + odph_odpthreads_join(&thread_tbl[i]); > + > + odp_pktio_stop(args->appl.pktio); > + odp_pktio_close(args->appl.pktio); > + > + while (1) { > + odp_event_t ev; > + > + ev = odp_schedule(NULL, 0); > + if (ev == ODP_EVENT_INVALID) > + break; > + } > + > + odp_pool_destroy(pool); > + odp_term_local(); > + odp_term_global(instance); > + > + if (packet_flags.all != args->appl.expected_bits.all) { > + LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n", > + packet_flags.all, args->appl.expected_bits.all); > + free(args); > + return -1; > + } > + > + free(args); > + return 0; > +} > diff --git a/test/linux-generic/cls/cls_main.c > b/test/linux-generic/cls/cls_main.c > new file mode 100644 > index 0000000..40179b9 > --- /dev/null > +++ b/test/linux-generic/cls/cls_main.c > @@ -0,0 +1,12 @@ > +/* Copyright (c) 2016, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include "cls_suites.h" > + > +int main(int argc, char *argv[]) > +{ > + return cls_main(argc, argv); > +} > diff --git a/test/linux-generic/cls/cls_suites.h > b/test/linux-generic/cls/cls_suites.h > new file mode 100644 > index 0000000..94c9b55 > --- /dev/null > +++ b/test/linux-generic/cls/cls_suites.h > @@ -0,0 +1 @@ > +int cls_main(int argc, char *argv[]); > diff --git a/test/linux-generic/cls/vlan.pcap > b/test/linux-generic/cls/vlan.pcap > new file mode 100644 > index 0000000000000000000000000000000000000000.. > 106ccb682e51495b4025337518a0bce63c2c7681 > GIT binary patch > literal 9728 > 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 > H$A|v_$relS > > literal 0 > HcmV?d00001 > > diff --git a/test/linux-generic/cls/vlan_run.sh > b/test/linux-generic/cls/vlan_run.sh > new file mode 100755 > index 0000000..7875eaf > --- /dev/null > +++ b/test/linux-generic/cls/vlan_run.sh > @@ -0,0 +1,49 @@ > +#!/bin/sh > +# > +# Copyright (c) 2016, Linaro Limited > +# All rights reserved. > +# > +# SPDX-License-Identifier: BSD-3-Clause > +# > + > +# directories where binary can be found: > +# -in the validation dir when running make check (intree or out of tree) > +# -in the script directory, when running after 'make install', or > +# -in the validation when running standalone intree, > +# -in the _build directory, when running after 'make distcheck', > +# -in the current directory. > +# running stand alone out of tree requires setting PATH > +PATH=${TEST_DIR}/linux-generic/cls:$PATH > +PATH=$(dirname $0):$PATH > +PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH > +PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH > +PATH=.:$PATH > + > +bin_path=$(which cls_main${EXEEXT}) > +if [ -x "$bin_path" ] ; then > + echo "Running with $bin_path" > +else > + echo "Cannot find cls_main${EXEEXT}" > + echo "Please set you PATH for it. PATH=$PATH" > +fi > + > +# Test1: find vlan packets in pcap file and test internal > pkt_mmap_vlan_insert() > +# function. Load packets from vlan.pcap file and check that > classifier > +# set vlan bits fisible with odp_packet_has_vlan(). > + > +PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit` > + > +cls_main -i $PCAP -e 4097 > +ret=$? > + > +PCAP_IN_SIZE=`stat -c %s $PCAP` > +PCAP_OUT_SIZE=`stat -c %s test_out.pcap` > + > +rm -f test_out.pcap > + > +if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then > + echo "Error: status ${ret}, in:${PCAP_IN_SIZE} > out:${PCAP_OUT_SIZE}" > + exit 3 > +fi > + > +echo "PASS: test 1 passed" > diff --git a/test/linux-generic/m4/configure.m4 b/test/linux-generic/m4/ > configure.m4 > index 9eec545..375ead2 100644 > --- a/test/linux-generic/m4/configure.m4 > +++ b/test/linux-generic/m4/configure.m4 > @@ -1,5 +1,6 @@ > AC_CONFIG_FILES([test/linux-generic/Makefile > test/linux-generic/validation/api/shmem/Makefile > test/linux-generic/validation/api/pktio/Makefile > + test/linux-generic/cls/Makefile > test/linux-generic/pktio_ipc/Makefile > test/linux-generic/ring/Makefile]) > -- > 2.7.1.250.gff4ea60 > >
On 2016-08-02 19:08, Maxim Uvarov wrote: > add pcap play back test which takes 2 arguments: 1 - pcap file, > 2 - packet mask to match. Intend is to test odp with different > input traffic to check internal implementation functions. In > current case it's test for vlan tag instertion for packet mmap: > pkt_mmap_vlan_insert(). > > Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > --- > v2: up the patch, dirrect execution looks like works. > > test/linux-generic/.gitignore | 1 + > test/linux-generic/Makefile.am | 10 +- > test/linux-generic/cls/.gitignore | 3 + > test/linux-generic/cls/Makefile.am | 13 ++ > test/linux-generic/cls/cls.c | 349 ++++++++++++++++++++++++++++++++++++ > test/linux-generic/cls/cls_main.c | 12 ++ > test/linux-generic/cls/cls_suites.h | 1 + > test/linux-generic/cls/vlan.pcap | Bin 0 -> 9728 bytes > test/linux-generic/cls/vlan_run.sh | 49 +++++ > test/linux-generic/m4/configure.m4 | 1 + > 10 files changed, 435 insertions(+), 4 deletions(-) > create mode 100644 test/linux-generic/cls/.gitignore > create mode 100644 test/linux-generic/cls/Makefile.am > create mode 100644 test/linux-generic/cls/cls.c > create mode 100644 test/linux-generic/cls/cls_main.c > create mode 100644 test/linux-generic/cls/cls_suites.h > create mode 100644 test/linux-generic/cls/vlan.pcap > create mode 100755 test/linux-generic/cls/vlan_run.sh > > diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore > index 5dabf91..f65c7c1 100644 > --- a/test/linux-generic/.gitignore > +++ b/test/linux-generic/.gitignore > @@ -1,3 +1,4 @@ > *.log > *.trs > tests-validation.env > +test_out.pcap > diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am > index f5cc52d..9acbab0 100644 > --- a/test/linux-generic/Makefile.am > +++ b/test/linux-generic/Makefile.am > @@ -1,5 +1,8 @@ > include $(top_srcdir)/test/Makefile.inc > TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation > +TEST_EXTENSIONS = .sh > + > +dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > > ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api > > @@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \ > > SUBDIRS += validation/api/pktio\ > validation/api/shmem\ > + cls\ > pktio_ipc\ > ring > > if HAVE_PCAP > TESTS += validation/api/pktio/pktio_run_pcap.sh > +TESTS += cls/vlan_run.sh > +dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap > endif > if netmap_support > TESTS += validation/api/pktio/pktio_run_netmap.sh > @@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio > endif > endif > > -TEST_EXTENSIONS = .sh > - > -dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > - > test_SCRIPTS = $(dist_check_SCRIPTS) > > tests-validation.env: > diff --git a/test/linux-generic/cls/.gitignore b/test/linux-generic/cls/.gitignore > new file mode 100644 > index 0000000..9447625 > --- /dev/null > +++ b/test/linux-generic/cls/.gitignore > @@ -0,0 +1,3 @@ > +cls_main > +*.log > +*.trs log and trs shouldn't be needed here, since its in test/linux-generic/.gitignore. This isn't done in a common way anywhere... Maybe we need to look into it? > diff --git a/test/linux-generic/cls/Makefile.am b/test/linux-generic/cls/Makefile.am > new file mode 100644 > index 0000000..43fb0bc > --- /dev/null > +++ b/test/linux-generic/cls/Makefile.am > @@ -0,0 +1,13 @@ > +include ../Makefile.inc > + > +noinst_LTLIBRARIES = libtestcls.la Why do we need to create a library? > +libtestcls_la_SOURCES = cls.c > +libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP) > + > +test_PROGRAMS = cls_main$(EXEEXT) > +dist_cls_main_SOURCES = cls_main.c > + > +cls_main_LDFLAGS = $(AM_LDFLAGS) > +cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP) > + > +noinst_HEADERS = cls_suites.h > diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c > new file mode 100644 > index 0000000..d527ec8 > --- /dev/null > +++ b/test/linux-generic/cls/cls.c > @@ -0,0 +1,349 @@ > +/* Copyright (c) 2016, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <stdlib.h> > +#include <string.h> > +#include <getopt.h> > +#include <unistd.h> > +#include <inttypes.h> > + > +#include <test_debug.h> > + > +#include <odp_api.h> > +#include <odp/helper/linux.h> > +#include <odp/helper/eth.h> > +#include <odp/helper/ip.h> > + > +#include <odp_packet_internal.h> why do we include an internal header file? > + > +#include "cls_suites.h" > + > +/** Get rid of path in filename - only for unix-type paths using '/' */ > +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ > + strrchr((file_name), '/') + 1 : (file_name)) Maybe its enough basename? http://linux.die.net/man/3/basename > + > +/** > + * Print usage information > + */ > +static void usage(char *progname) > +{ > + printf("\n" > + "This is test application to verify that linux-generic classifier\n" > + "correctly classifies packets on input. Main intend is add more code\n" > + "coverage for internal functions playing different traffic recorded to\n" > + "pcap files." > + "\n" > + "Usage: %s OPTIONS\n" > + " E.g. %s -i pcap_file -e expected_bitmask\n" Maybe expected_pkt_bitmask ? > + "\n" > + "Mandatory OPTIONS:\n" > + " -i, pcap file name\n" > + " -e, expected packet bitmask\n" > + "\n", NO_PATH(progname), NO_PATH(progname) > + ); > +} > + > +/** @def SHM_PKT_POOL_SIZE > + * @brief Size of the shared memory block > + */ > +#define SHM_PKT_POOL_SIZE 512 > + > +/** @def SHM_PKT_POOL_BUF_SIZE > + * @brief Buffer size of the packet pool buffer > + */ > +#define SHM_PKT_POOL_BUF_SIZE 1856 > + > +/** > + * Parsed command line application arguments > + */ > +typedef struct { > + char *file_name; /**< File name for pcap pktio */ > + odp_pktio_t pktio; /**< Pktio dev */ > + input_flags_t expected_bits; /**< Expected bits from test run */ > +} appl_args_t; > + > +/** > + * Grouping of both parsed CL args and thread specific args - alloc together > + */ > +typedef struct { > + /** Application (parsed) arguments */ > + appl_args_t appl; > +} args_t; > + > +/** Global pointer to args */ > +static args_t *args; > +/** Fill this bit struct to check which packet fields were classified */ > +static input_flags_t packet_flags; > + > +/** > + * Parse and store the command line arguments > + * > + * @param argc argument count > + * @param argv[] argument vector > + * @param appl_args Store application arguments here > + */ > +static void parse_args(int argc, char *argv[], appl_args_t *appl_args) > +{ > + int opt; > + int long_index; > + static const struct option longopts[] = { > + {"interface", required_argument, NULL, 'i'}, /* return 'i' */ > + {"extected", required_argument, NULL, 'e'}, /* return 'e' */ > + {"help", no_argument, NULL, 'h'}, /* return 'h' */ > + {NULL, 0, NULL, 0} > + }; > + > + static const char *shortopts = ":i:e:h"; > + > + /* let helper collect its own arguments (e.g. --odph_proc) */ > + odph_parse_options(argc, argv, shortopts, longopts); > + > + appl_args->file_name = NULL; > + opterr = 0; /* do not issue errors on helper options */ > + appl_args->expected_bits.all = 0; > + > + while (1) { > + opt = getopt_long(argc, argv, shortopts, longopts, &long_index); > + > + if (opt == -1) > + break; /* No more options */ > + > + switch (opt) { > + case 'i': > + appl_args->file_name = optarg; > + break; > + case 'e': > + appl_args->expected_bits.all = atoll(optarg); > + break; > + > + case 'h': > + usage(argv[0]); > + exit(EXIT_SUCCESS); > + break; > + default: > + break; > + } > + } > + > + if (!appl_args->file_name) { > + usage(argv[0]); > + exit(EXIT_SUCCESS); > + } > + > + optind = 1; /* reset 'extern optind' from the getopt lib */ > +} > + > +/** > + * Create a pktio handle, optionally associating a default input queue. > + * > + * @param dev Name of device to open > + * @param pool Pool to associate with device for packet RX/TX > + * @param mode Packet processing mode for this device (BURST or QUEUE) > + * > + * @return The handle of the created pktio object. > + * @retval ODP_PKTIO_INVALID if the create fails. > + */ The doxygen text match the function definition. > +static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool) > +{ > + odp_pktio_t pktio; > + int ret; > + odp_pktio_param_t pktio_param; > + odp_pktin_queue_param_t pktin_param; > + char dev[255]; > + > + odp_pktio_param_init(&pktio_param); > + pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; > + > + memset(dev, 0, 255); > + sprintf(dev, "pcap:in=%s:out=test_out.pcap", fname); > + > + /* Open a packet IO instance */ > + pktio = odp_pktio_open(dev, pool, &pktio_param); > + if (pktio == ODP_PKTIO_INVALID) > + LOG_ABORT("Error: pktio create failed for %s\n", dev); > + > + odp_pktin_queue_param_init(&pktin_param); > + > + pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; > + > + if (odp_pktin_queue_config(pktio, &pktin_param)) > + LOG_ABORT("Error: pktin config failed for %s\n", dev); > + > + if (odp_pktout_queue_config(pktio, NULL)) > + LOG_ABORT("Error: pktout config failed for %s\n", dev); > + > + ret = odp_pktio_start(pktio); > + if (ret != 0) > + LOG_ABORT("Error: unable to start %s\n", dev); > + > + printf(" created pktio:%02" PRIu64 > + ", dev:%s, queue mode (ATOMIC queues)\n" > + " \tdefault pktio%02" PRIu64 "\n", > + odp_pktio_to_u64(pktio), dev, > + odp_pktio_to_u64(pktio)); > + > + return pktio; > +} > + > +/** > + * Packet IO loopback worker thread using ODP queues > + * > + * @param arg thread arguments of type 'thread_args_t *' > + */ Document what we return ? > +static int pktio_queue_thread(void *arg ODP_UNUSED) > +{ > + int thr = odp_thread_id(); > + odp_pktout_queue_t pktout; > + odp_packet_t pkt; > + odp_event_t ev; > + uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100); > + > + packet_flags.all = 0; > + > + /* Loop packets */ > + while (1) { > + odp_pktio_t pktio_tmp; > + > + ev = odp_schedule(NULL, sched_wait); > + if (ev == ODP_EVENT_INVALID) > + break; > + > + pkt = odp_packet_from_event(ev); > + if (!odp_packet_is_valid(pkt)) > + continue; > + > + pktio_tmp = odp_packet_input(pkt); > + > + if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) { > + LOG_ERR(" [%02i] Error: no pktout queue\n", thr); > + return -1; > + } > + > + /* Extend bits here for more additional tests */ > + if (odp_packet_has_l2(pkt)) > + packet_flags.parsed_l2 = 1; > + if (odp_packet_has_vlan(pkt)) > + packet_flags.vlan = 1; > + > + /* Enqueue the packet for output */ > + if (odp_pktout_send(pktout, &pkt, 1) != 1) { > + LOG_ERR(" [%i] Packet send failed.\n", thr); > + odp_packet_free(pkt); > + continue; > + } > + } > + > + return 0; > +} > + > +int cls_main(int argc, char *argv[]) > +{ > + odph_odpthread_t thread_tbl[1]; > + odp_pool_t pool; > + int num_workers; > + int i; > + int cpu; > + odp_cpumask_t cpumask; > + char cpumaskstr[ODP_CPUMASK_STR_SIZE]; > + odp_pool_param_t params; > + odp_instance_t instance; > + odph_odpthread_params_t thr_params; > + > + args = calloc(1, sizeof(args_t)); > + if (args == NULL) { > + LOG_ERR("Error: args mem alloc failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + parse_args(argc, argv, &args->appl); > + > + /* Init ODP before calling anything else */ > + if (odp_init_global(&instance, NULL, NULL)) { > + LOG_ERR("Error: ODP global init failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + /* Init this thread */ > + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { > + LOG_ERR("Error: ODP local init failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + num_workers = odp_cpumask_default_worker(&cpumask, 1); > + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); > + > + /* Create packet pool */ > + odp_pool_param_init(¶ms); > + params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; > + params.pkt.len = SHM_PKT_POOL_BUF_SIZE; > + params.pkt.num = SHM_PKT_POOL_SIZE; > + params.type = ODP_POOL_PACKET; > + > + pool = odp_pool_create("packet_pool", ¶ms); > + if (pool == ODP_POOL_INVALID) { > + LOG_ERR("Error: packet pool create failed.\n"); > + exit(EXIT_FAILURE); > + } > + > + args->appl.pktio = create_pktio(args->appl.file_name, pool); > + > + /* Create and init worker threads */ > + memset(thread_tbl, 0, sizeof(thread_tbl)); > + > + memset(&thr_params, 0, sizeof(thr_params)); > + thr_params.thr_type = ODP_THREAD_WORKER; > + thr_params.instance = instance; > + > + cpu = odp_cpumask_first(&cpumask); > + for (i = 0; i < num_workers; ++i) { > + odp_cpumask_t thd_mask; > + int (*thr_run_func)(void *); > + > + thr_run_func = pktio_queue_thread; > + /* > + * Create threads one-by-one instead of all-at-once, > + * because each thread might get different arguments. > + * Calls odp_thread_create(cpu) for each thread > + */ > + odp_cpumask_zero(&thd_mask); > + odp_cpumask_set(&thd_mask, cpu); > + > + thr_params.start = thr_run_func; > + thr_params.arg = &args; > + > + odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params); > + cpu = odp_cpumask_next(&cpumask, cpu); > + } > + > + /* Master thread waits for other threads to exit */ > + for (i = 0; i < num_workers; ++i) > + odph_odpthreads_join(&thread_tbl[i]); > + > + odp_pktio_stop(args->appl.pktio); > + odp_pktio_close(args->appl.pktio); > + > + while (1) { > + odp_event_t ev; > + > + ev = odp_schedule(NULL, 0); > + if (ev == ODP_EVENT_INVALID) > + break; > + } > + > + odp_pool_destroy(pool); > + odp_term_local(); > + odp_term_global(instance); > + > + if (packet_flags.all != args->appl.expected_bits.all) { > + LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n", > + packet_flags.all, args->appl.expected_bits.all); > + free(args); > + return -1; > + } > + > + free(args); > + return 0; > +} > diff --git a/test/linux-generic/cls/cls_main.c b/test/linux-generic/cls/cls_main.c > new file mode 100644 > index 0000000..40179b9 > --- /dev/null > +++ b/test/linux-generic/cls/cls_main.c > @@ -0,0 +1,12 @@ > +/* Copyright (c) 2016, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include "cls_suites.h" > + > +int main(int argc, char *argv[]) > +{ > + return cls_main(argc, argv); > +} > diff --git a/test/linux-generic/cls/cls_suites.h b/test/linux-generic/cls/cls_suites.h > new file mode 100644 > index 0000000..94c9b55 > --- /dev/null > +++ b/test/linux-generic/cls/cls_suites.h > @@ -0,0 +1 @@ > +int cls_main(int argc, char *argv[]); > diff --git a/test/linux-generic/cls/vlan.pcap b/test/linux-generic/cls/vlan.pcap > new file mode 100644 > index 0000000000000000000000000000000000000000..106ccb682e51495b4025337518a0bce63c2c7681 > GIT binary patch > literal 9728 > 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 > H$A|v_$relS > > literal 0 > HcmV?d00001 > > diff --git a/test/linux-generic/cls/vlan_run.sh b/test/linux-generic/cls/vlan_run.sh > new file mode 100755 > index 0000000..7875eaf > --- /dev/null > +++ b/test/linux-generic/cls/vlan_run.sh > @@ -0,0 +1,49 @@ > +#!/bin/sh > +# > +# Copyright (c) 2016, Linaro Limited > +# All rights reserved. > +# > +# SPDX-License-Identifier: BSD-3-Clause > +# > + > +# directories where binary can be found: > +# -in the validation dir when running make check (intree or out of tree) > +# -in the script directory, when running after 'make install', or > +# -in the validation when running standalone intree, > +# -in the _build directory, when running after 'make distcheck', > +# -in the current directory. > +# running stand alone out of tree requires setting PATH > +PATH=${TEST_DIR}/linux-generic/cls:$PATH > +PATH=$(dirname $0):$PATH > +PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH > +PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH > +PATH=.:$PATH > + > +bin_path=$(which cls_main${EXEEXT}) > +if [ -x "$bin_path" ] ; then > + echo "Running with $bin_path" > +else > + echo "Cannot find cls_main${EXEEXT}" > + echo "Please set you PATH for it. PATH=$PATH" > +fi > + > +# Test1: find vlan packets in pcap file and test internal pkt_mmap_vlan_insert() > +# function. Load packets from vlan.pcap file and check that classifier > +# set vlan bits fisible with odp_packet_has_vlan(). > + > +PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit` > + > +cls_main -i $PCAP -e 4097 > +ret=$? > + > +PCAP_IN_SIZE=`stat -c %s $PCAP` > +PCAP_OUT_SIZE=`stat -c %s test_out.pcap` > + > +rm -f test_out.pcap > + > +if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then > + echo "Error: status ${ret}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}" > + exit 3 > +fi > + > +echo "PASS: test 1 passed" > diff --git a/test/linux-generic/m4/configure.m4 b/test/linux-generic/m4/configure.m4 > index 9eec545..375ead2 100644 > --- a/test/linux-generic/m4/configure.m4 > +++ b/test/linux-generic/m4/configure.m4 > @@ -1,5 +1,6 @@ > AC_CONFIG_FILES([test/linux-generic/Makefile > test/linux-generic/validation/api/shmem/Makefile > test/linux-generic/validation/api/pktio/Makefile > + test/linux-generic/cls/Makefile Alphabetic order? Cheers, Anders
Hello Anders, thanks for review, there are 2 comments bellow. Will send v2. Maxim. On 08/06/16 22:30, Anders Roxell wrote: > On 2016-08-02 19:08, Maxim Uvarov wrote: >> add pcap play back test which takes 2 arguments: 1 - pcap file, >> 2 - packet mask to match. Intend is to test odp with different >> input traffic to check internal implementation functions. In >> current case it's test for vlan tag instertion for packet mmap: >> pkt_mmap_vlan_insert(). >> >> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> >> --- >> v2: up the patch, dirrect execution looks like works. >> >> test/linux-generic/.gitignore | 1 + >> test/linux-generic/Makefile.am | 10 +- >> test/linux-generic/cls/.gitignore | 3 + >> test/linux-generic/cls/Makefile.am | 13 ++ >> test/linux-generic/cls/cls.c | 349 ++++++++++++++++++++++++++++++++++++ >> test/linux-generic/cls/cls_main.c | 12 ++ >> test/linux-generic/cls/cls_suites.h | 1 + >> test/linux-generic/cls/vlan.pcap | Bin 0 -> 9728 bytes >> test/linux-generic/cls/vlan_run.sh | 49 +++++ >> test/linux-generic/m4/configure.m4 | 1 + >> 10 files changed, 435 insertions(+), 4 deletions(-) >> create mode 100644 test/linux-generic/cls/.gitignore >> create mode 100644 test/linux-generic/cls/Makefile.am >> create mode 100644 test/linux-generic/cls/cls.c >> create mode 100644 test/linux-generic/cls/cls_main.c >> create mode 100644 test/linux-generic/cls/cls_suites.h >> create mode 100644 test/linux-generic/cls/vlan.pcap >> create mode 100755 test/linux-generic/cls/vlan_run.sh >> >> diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore >> index 5dabf91..f65c7c1 100644 >> --- a/test/linux-generic/.gitignore >> +++ b/test/linux-generic/.gitignore >> @@ -1,3 +1,4 @@ >> *.log >> *.trs >> tests-validation.env >> +test_out.pcap >> diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am >> index f5cc52d..9acbab0 100644 >> --- a/test/linux-generic/Makefile.am >> +++ b/test/linux-generic/Makefile.am >> @@ -1,5 +1,8 @@ >> include $(top_srcdir)/test/Makefile.inc >> TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation >> +TEST_EXTENSIONS = .sh >> + >> +dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) >> >> ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api >> >> @@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \ >> >> SUBDIRS += validation/api/pktio\ >> validation/api/shmem\ >> + cls\ >> pktio_ipc\ >> ring >> >> if HAVE_PCAP >> TESTS += validation/api/pktio/pktio_run_pcap.sh >> +TESTS += cls/vlan_run.sh >> +dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap >> endif >> if netmap_support >> TESTS += validation/api/pktio/pktio_run_netmap.sh >> @@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio >> endif >> endif >> >> -TEST_EXTENSIONS = .sh >> - >> -dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) >> - >> test_SCRIPTS = $(dist_check_SCRIPTS) >> >> tests-validation.env: >> diff --git a/test/linux-generic/cls/.gitignore b/test/linux-generic/cls/.gitignore >> new file mode 100644 >> index 0000000..9447625 >> --- /dev/null >> +++ b/test/linux-generic/cls/.gitignore >> @@ -0,0 +1,3 @@ >> +cls_main >> +*.log >> +*.trs > log and trs shouldn't be needed here, since its in > test/linux-generic/.gitignore. > > This isn't done in a common way anywhere... Maybe we need to look into > it? > >> diff --git a/test/linux-generic/cls/Makefile.am b/test/linux-generic/cls/Makefile.am >> new file mode 100644 >> index 0000000..43fb0bc >> --- /dev/null >> +++ b/test/linux-generic/cls/Makefile.am >> @@ -0,0 +1,13 @@ >> +include ../Makefile.inc >> + >> +noinst_LTLIBRARIES = libtestcls.la > Why do we need to create a library? we do it everywhere, I just follow existence Makefiles. As Christophe explained me it's because all tests will be combined to one library and later be executed. >> +libtestcls_la_SOURCES = cls.c >> +libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP) >> + >> +test_PROGRAMS = cls_main$(EXEEXT) >> +dist_cls_main_SOURCES = cls_main.c >> + >> +cls_main_LDFLAGS = $(AM_LDFLAGS) >> +cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP) >> + >> +noinst_HEADERS = cls_suites.h >> diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c >> new file mode 100644 >> index 0000000..d527ec8 >> --- /dev/null >> +++ b/test/linux-generic/cls/cls.c >> @@ -0,0 +1,349 @@ >> +/* Copyright (c) 2016, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +#include <stdlib.h> >> +#include <string.h> >> +#include <getopt.h> >> +#include <unistd.h> >> +#include <inttypes.h> >> + >> +#include <test_debug.h> >> + >> +#include <odp_api.h> >> +#include <odp/helper/linux.h> >> +#include <odp/helper/eth.h> >> +#include <odp/helper/ip.h> >> + >> +#include <odp_packet_internal.h> > why do we include an internal header file? > because we need access to classifier bits, that is why this test is under linux-generic. >> + >> +#include "cls_suites.h" >> + >> +/** Get rid of path in filename - only for unix-type paths using '/' */ >> +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ >> + strrchr((file_name), '/') + 1 : (file_name)) > Maybe its enough basename? > http://linux.die.net/man/3/basename yes, but again this define in almost each our test file. Probably separate patch to change all NO_PATH to basename(). >> + >> +/** >> + * Print usage information >> + */ >> +static void usage(char *progname) >> +{ >> + printf("\n" >> + "This is test application to verify that linux-generic classifier\n" >> + "correctly classifies packets on input. Main intend is add more code\n" >> + "coverage for internal functions playing different traffic recorded to\n" >> + "pcap files." >> + "\n" >> + "Usage: %s OPTIONS\n" >> + " E.g. %s -i pcap_file -e expected_bitmask\n" > Maybe expected_pkt_bitmask ? I don't mind, if you think it's better will change in v2. >> + "\n" >> + "Mandatory OPTIONS:\n" >> + " -i, pcap file name\n" >> + " -e, expected packet bitmask\n" >> + "\n", NO_PATH(progname), NO_PATH(progname) >> + ); >> +} >> + >> +/** @def SHM_PKT_POOL_SIZE >> + * @brief Size of the shared memory block >> + */ >> +#define SHM_PKT_POOL_SIZE 512 >> + >> +/** @def SHM_PKT_POOL_BUF_SIZE >> + * @brief Buffer size of the packet pool buffer >> + */ >> +#define SHM_PKT_POOL_BUF_SIZE 1856 >> + >> +/** >> + * Parsed command line application arguments >> + */ >> +typedef struct { >> + char *file_name; /**< File name for pcap pktio */ >> + odp_pktio_t pktio; /**< Pktio dev */ >> + input_flags_t expected_bits; /**< Expected bits from test run */ >> +} appl_args_t; >> + >> +/** >> + * Grouping of both parsed CL args and thread specific args - alloc together >> + */ >> +typedef struct { >> + /** Application (parsed) arguments */ >> + appl_args_t appl; >> +} args_t; >> + >> +/** Global pointer to args */ >> +static args_t *args; >> +/** Fill this bit struct to check which packet fields were classified */ >> +static input_flags_t packet_flags; >> + >> +/** >> + * Parse and store the command line arguments >> + * >> + * @param argc argument count >> + * @param argv[] argument vector >> + * @param appl_args Store application arguments here >> + */ >> +static void parse_args(int argc, char *argv[], appl_args_t *appl_args) >> +{ >> + int opt; >> + int long_index; >> + static const struct option longopts[] = { >> + {"interface", required_argument, NULL, 'i'}, /* return 'i' */ >> + {"extected", required_argument, NULL, 'e'}, /* return 'e' */ >> + {"help", no_argument, NULL, 'h'}, /* return 'h' */ >> + {NULL, 0, NULL, 0} >> + }; >> + >> + static const char *shortopts = ":i:e:h"; >> + >> + /* let helper collect its own arguments (e.g. --odph_proc) */ >> + odph_parse_options(argc, argv, shortopts, longopts); >> + >> + appl_args->file_name = NULL; >> + opterr = 0; /* do not issue errors on helper options */ >> + appl_args->expected_bits.all = 0; >> + >> + while (1) { >> + opt = getopt_long(argc, argv, shortopts, longopts, &long_index); >> + >> + if (opt == -1) >> + break; /* No more options */ >> + >> + switch (opt) { >> + case 'i': >> + appl_args->file_name = optarg; >> + break; >> + case 'e': >> + appl_args->expected_bits.all = atoll(optarg); >> + break; >> + >> + case 'h': >> + usage(argv[0]); >> + exit(EXIT_SUCCESS); >> + break; >> + default: >> + break; >> + } >> + } >> + >> + if (!appl_args->file_name) { >> + usage(argv[0]); >> + exit(EXIT_SUCCESS); >> + } >> + >> + optind = 1; /* reset 'extern optind' from the getopt lib */ >> +} >> + >> +/** >> + * Create a pktio handle, optionally associating a default input queue. >> + * >> + * @param dev Name of device to open >> + * @param pool Pool to associate with device for packet RX/TX >> + * @param mode Packet processing mode for this device (BURST or QUEUE) >> + * >> + * @return The handle of the created pktio object. >> + * @retval ODP_PKTIO_INVALID if the create fails. >> + */ > The doxygen text match the function definition. > >> +static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool) >> +{ >> + odp_pktio_t pktio; >> + int ret; >> + odp_pktio_param_t pktio_param; >> + odp_pktin_queue_param_t pktin_param; >> + char dev[255]; >> + >> + odp_pktio_param_init(&pktio_param); >> + pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; >> + >> + memset(dev, 0, 255); >> + sprintf(dev, "pcap:in=%s:out=test_out.pcap", fname); >> + >> + /* Open a packet IO instance */ >> + pktio = odp_pktio_open(dev, pool, &pktio_param); >> + if (pktio == ODP_PKTIO_INVALID) >> + LOG_ABORT("Error: pktio create failed for %s\n", dev); >> + >> + odp_pktin_queue_param_init(&pktin_param); >> + >> + pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; >> + >> + if (odp_pktin_queue_config(pktio, &pktin_param)) >> + LOG_ABORT("Error: pktin config failed for %s\n", dev); >> + >> + if (odp_pktout_queue_config(pktio, NULL)) >> + LOG_ABORT("Error: pktout config failed for %s\n", dev); >> + >> + ret = odp_pktio_start(pktio); >> + if (ret != 0) >> + LOG_ABORT("Error: unable to start %s\n", dev); >> + >> + printf(" created pktio:%02" PRIu64 >> + ", dev:%s, queue mode (ATOMIC queues)\n" >> + " \tdefault pktio%02" PRIu64 "\n", >> + odp_pktio_to_u64(pktio), dev, >> + odp_pktio_to_u64(pktio)); >> + >> + return pktio; >> +} >> + >> +/** >> + * Packet IO loopback worker thread using ODP queues >> + * >> + * @param arg thread arguments of type 'thread_args_t *' >> + */ > Document what we return ? > >> +static int pktio_queue_thread(void *arg ODP_UNUSED) >> +{ >> + int thr = odp_thread_id(); >> + odp_pktout_queue_t pktout; >> + odp_packet_t pkt; >> + odp_event_t ev; >> + uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100); >> + >> + packet_flags.all = 0; >> + >> + /* Loop packets */ >> + while (1) { >> + odp_pktio_t pktio_tmp; >> + >> + ev = odp_schedule(NULL, sched_wait); >> + if (ev == ODP_EVENT_INVALID) >> + break; >> + >> + pkt = odp_packet_from_event(ev); >> + if (!odp_packet_is_valid(pkt)) >> + continue; >> + >> + pktio_tmp = odp_packet_input(pkt); >> + >> + if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) { >> + LOG_ERR(" [%02i] Error: no pktout queue\n", thr); >> + return -1; >> + } >> + >> + /* Extend bits here for more additional tests */ >> + if (odp_packet_has_l2(pkt)) >> + packet_flags.parsed_l2 = 1; >> + if (odp_packet_has_vlan(pkt)) >> + packet_flags.vlan = 1; >> + >> + /* Enqueue the packet for output */ >> + if (odp_pktout_send(pktout, &pkt, 1) != 1) { >> + LOG_ERR(" [%i] Packet send failed.\n", thr); >> + odp_packet_free(pkt); >> + continue; >> + } >> + } >> + >> + return 0; >> +} >> + >> +int cls_main(int argc, char *argv[]) >> +{ >> + odph_odpthread_t thread_tbl[1]; >> + odp_pool_t pool; >> + int num_workers; >> + int i; >> + int cpu; >> + odp_cpumask_t cpumask; >> + char cpumaskstr[ODP_CPUMASK_STR_SIZE]; >> + odp_pool_param_t params; >> + odp_instance_t instance; >> + odph_odpthread_params_t thr_params; >> + >> + args = calloc(1, sizeof(args_t)); >> + if (args == NULL) { >> + LOG_ERR("Error: args mem alloc failed.\n"); >> + exit(EXIT_FAILURE); >> + } >> + >> + parse_args(argc, argv, &args->appl); >> + >> + /* Init ODP before calling anything else */ >> + if (odp_init_global(&instance, NULL, NULL)) { >> + LOG_ERR("Error: ODP global init failed.\n"); >> + exit(EXIT_FAILURE); >> + } >> + >> + /* Init this thread */ >> + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { >> + LOG_ERR("Error: ODP local init failed.\n"); >> + exit(EXIT_FAILURE); >> + } >> + >> + num_workers = odp_cpumask_default_worker(&cpumask, 1); >> + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); >> + >> + /* Create packet pool */ >> + odp_pool_param_init(¶ms); >> + params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; >> + params.pkt.len = SHM_PKT_POOL_BUF_SIZE; >> + params.pkt.num = SHM_PKT_POOL_SIZE; >> + params.type = ODP_POOL_PACKET; >> + >> + pool = odp_pool_create("packet_pool", ¶ms); >> + if (pool == ODP_POOL_INVALID) { >> + LOG_ERR("Error: packet pool create failed.\n"); >> + exit(EXIT_FAILURE); >> + } >> + >> + args->appl.pktio = create_pktio(args->appl.file_name, pool); >> + >> + /* Create and init worker threads */ >> + memset(thread_tbl, 0, sizeof(thread_tbl)); >> + >> + memset(&thr_params, 0, sizeof(thr_params)); >> + thr_params.thr_type = ODP_THREAD_WORKER; >> + thr_params.instance = instance; >> + >> + cpu = odp_cpumask_first(&cpumask); >> + for (i = 0; i < num_workers; ++i) { >> + odp_cpumask_t thd_mask; >> + int (*thr_run_func)(void *); >> + >> + thr_run_func = pktio_queue_thread; >> + /* >> + * Create threads one-by-one instead of all-at-once, >> + * because each thread might get different arguments. >> + * Calls odp_thread_create(cpu) for each thread >> + */ >> + odp_cpumask_zero(&thd_mask); >> + odp_cpumask_set(&thd_mask, cpu); >> + >> + thr_params.start = thr_run_func; >> + thr_params.arg = &args; >> + >> + odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params); >> + cpu = odp_cpumask_next(&cpumask, cpu); >> + } >> + >> + /* Master thread waits for other threads to exit */ >> + for (i = 0; i < num_workers; ++i) >> + odph_odpthreads_join(&thread_tbl[i]); >> + >> + odp_pktio_stop(args->appl.pktio); >> + odp_pktio_close(args->appl.pktio); >> + >> + while (1) { >> + odp_event_t ev; >> + >> + ev = odp_schedule(NULL, 0); >> + if (ev == ODP_EVENT_INVALID) >> + break; >> + } >> + >> + odp_pool_destroy(pool); >> + odp_term_local(); >> + odp_term_global(instance); >> + >> + if (packet_flags.all != args->appl.expected_bits.all) { >> + LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n", >> + packet_flags.all, args->appl.expected_bits.all); >> + free(args); >> + return -1; >> + } >> + >> + free(args); >> + return 0; >> +} >> diff --git a/test/linux-generic/cls/cls_main.c b/test/linux-generic/cls/cls_main.c >> new file mode 100644 >> index 0000000..40179b9 >> --- /dev/null >> +++ b/test/linux-generic/cls/cls_main.c >> @@ -0,0 +1,12 @@ >> +/* Copyright (c) 2016, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +#include "cls_suites.h" >> + >> +int main(int argc, char *argv[]) >> +{ >> + return cls_main(argc, argv); >> +} >> diff --git a/test/linux-generic/cls/cls_suites.h b/test/linux-generic/cls/cls_suites.h >> new file mode 100644 >> index 0000000..94c9b55 >> --- /dev/null >> +++ b/test/linux-generic/cls/cls_suites.h >> @@ -0,0 +1 @@ >> +int cls_main(int argc, char *argv[]); >> diff --git a/test/linux-generic/cls/vlan.pcap b/test/linux-generic/cls/vlan.pcap >> new file mode 100644 >> index 0000000000000000000000000000000000000000..106ccb682e51495b4025337518a0bce63c2c7681 >> GIT binary patch >> literal 9728 >> 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 >> H$A|v_$relS >> >> literal 0 >> HcmV?d00001 >> >> diff --git a/test/linux-generic/cls/vlan_run.sh b/test/linux-generic/cls/vlan_run.sh >> new file mode 100755 >> index 0000000..7875eaf >> --- /dev/null >> +++ b/test/linux-generic/cls/vlan_run.sh >> @@ -0,0 +1,49 @@ >> +#!/bin/sh >> +# >> +# Copyright (c) 2016, Linaro Limited >> +# All rights reserved. >> +# >> +# SPDX-License-Identifier: BSD-3-Clause >> +# >> + >> +# directories where binary can be found: >> +# -in the validation dir when running make check (intree or out of tree) >> +# -in the script directory, when running after 'make install', or >> +# -in the validation when running standalone intree, >> +# -in the _build directory, when running after 'make distcheck', >> +# -in the current directory. >> +# running stand alone out of tree requires setting PATH >> +PATH=${TEST_DIR}/linux-generic/cls:$PATH >> +PATH=$(dirname $0):$PATH >> +PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH >> +PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH >> +PATH=.:$PATH >> + >> +bin_path=$(which cls_main${EXEEXT}) >> +if [ -x "$bin_path" ] ; then >> + echo "Running with $bin_path" >> +else >> + echo "Cannot find cls_main${EXEEXT}" >> + echo "Please set you PATH for it. PATH=$PATH" >> +fi >> + >> +# Test1: find vlan packets in pcap file and test internal pkt_mmap_vlan_insert() >> +# function. Load packets from vlan.pcap file and check that classifier >> +# set vlan bits fisible with odp_packet_has_vlan(). >> + >> +PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit` >> + >> +cls_main -i $PCAP -e 4097 >> +ret=$? >> + >> +PCAP_IN_SIZE=`stat -c %s $PCAP` >> +PCAP_OUT_SIZE=`stat -c %s test_out.pcap` >> + >> +rm -f test_out.pcap >> + >> +if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then >> + echo "Error: status ${ret}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}" >> + exit 3 >> +fi >> + >> +echo "PASS: test 1 passed" >> diff --git a/test/linux-generic/m4/configure.m4 b/test/linux-generic/m4/configure.m4 >> index 9eec545..375ead2 100644 >> --- a/test/linux-generic/m4/configure.m4 >> +++ b/test/linux-generic/m4/configure.m4 >> @@ -1,5 +1,6 @@ >> AC_CONFIG_FILES([test/linux-generic/Makefile >> test/linux-generic/validation/api/shmem/Makefile >> test/linux-generic/validation/api/pktio/Makefile >> + test/linux-generic/cls/Makefile > Alphabetic order? > > Cheers, > Anders
On 08/06/16 22:30, Anders Roxell wrote: > --- a/test/linux-generic/m4/configure.m4 > >+++ b/test/linux-generic/m4/configure.m4 > >@@ -1,5 +1,6 @@ > > AC_CONFIG_FILES([test/linux-generic/Makefile > > test/linux-generic/validation/api/shmem/Makefile > > test/linux-generic/validation/api/pktio/Makefile > >+ test/linux-generic/cls/Makefile here is validation group and all non validation tests are in alphabetic order bellow. Maxim.
Hello Anders, do you agree with current order? My answer was bellow. Thank you, Maxim. On 08/09/16 15:46, Maxim Uvarov wrote: > On 08/06/16 22:30, Anders Roxell wrote: >> --- a/test/linux-generic/m4/configure.m4 >> >+++ b/test/linux-generic/m4/configure.m4 >> >@@ -1,5 +1,6 @@ >> > AC_CONFIG_FILES([test/linux-generic/Makefile >> > test/linux-generic/validation/api/shmem/Makefile >> > test/linux-generic/validation/api/pktio/Makefile >> >+ test/linux-generic/cls/Makefile > here is validation group and all non validation tests are in > alphabetic order bellow. > > Maxim.
On 2016-08-08 09:59, Maxim Uvarov wrote: > Hello Anders, > > thanks for review, there are 2 comments bellow. Will send v2. > > Maxim. > > On 08/06/16 22:30, Anders Roxell wrote: > >On 2016-08-02 19:08, Maxim Uvarov wrote: > >>add pcap play back test which takes 2 arguments: 1 - pcap file, > >>2 - packet mask to match. Intend is to test odp with different > >>input traffic to check internal implementation functions. In > >>current case it's test for vlan tag instertion for packet mmap: > >>pkt_mmap_vlan_insert(). > >> > >>Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> > >>--- > >> v2: up the patch, dirrect execution looks like works. > >> > >> test/linux-generic/.gitignore | 1 + > >> test/linux-generic/Makefile.am | 10 +- > >> test/linux-generic/cls/.gitignore | 3 + > >> test/linux-generic/cls/Makefile.am | 13 ++ > >> test/linux-generic/cls/cls.c | 349 ++++++++++++++++++++++++++++++++++++ > >> test/linux-generic/cls/cls_main.c | 12 ++ > >> test/linux-generic/cls/cls_suites.h | 1 + > >> test/linux-generic/cls/vlan.pcap | Bin 0 -> 9728 bytes > >> test/linux-generic/cls/vlan_run.sh | 49 +++++ > >> test/linux-generic/m4/configure.m4 | 1 + > >> 10 files changed, 435 insertions(+), 4 deletions(-) > >> create mode 100644 test/linux-generic/cls/.gitignore > >> create mode 100644 test/linux-generic/cls/Makefile.am > >> create mode 100644 test/linux-generic/cls/cls.c > >> create mode 100644 test/linux-generic/cls/cls_main.c > >> create mode 100644 test/linux-generic/cls/cls_suites.h > >> create mode 100644 test/linux-generic/cls/vlan.pcap > >> create mode 100755 test/linux-generic/cls/vlan_run.sh > >> > >>diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore > >>index 5dabf91..f65c7c1 100644 > >>--- a/test/linux-generic/.gitignore > >>+++ b/test/linux-generic/.gitignore > >>@@ -1,3 +1,4 @@ > >> *.log > >> *.trs > >> tests-validation.env > >>+test_out.pcap > >>diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am > >>index f5cc52d..9acbab0 100644 > >>--- a/test/linux-generic/Makefile.am > >>+++ b/test/linux-generic/Makefile.am > >>@@ -1,5 +1,8 @@ > >> include $(top_srcdir)/test/Makefile.inc > >> TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation > >>+TEST_EXTENSIONS = .sh > >>+ > >>+dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > >> ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api > >>@@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \ > >> SUBDIRS += validation/api/pktio\ > >> validation/api/shmem\ > >>+ cls\ > >> pktio_ipc\ > >> ring > >> if HAVE_PCAP > >> TESTS += validation/api/pktio/pktio_run_pcap.sh > >>+TESTS += cls/vlan_run.sh > >>+dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap > >> endif > >> if netmap_support > >> TESTS += validation/api/pktio/pktio_run_netmap.sh > >>@@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio > >> endif > >> endif > >>-TEST_EXTENSIONS = .sh > >>- > >>-dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) > >>- > >> test_SCRIPTS = $(dist_check_SCRIPTS) > >> tests-validation.env: > >>diff --git a/test/linux-generic/cls/.gitignore b/test/linux-generic/cls/.gitignore > >>new file mode 100644 > >>index 0000000..9447625 > >>--- /dev/null > >>+++ b/test/linux-generic/cls/.gitignore > >>@@ -0,0 +1,3 @@ > >>+cls_main > >>+*.log > >>+*.trs > >log and trs shouldn't be needed here, since its in > >test/linux-generic/.gitignore. > > > >This isn't done in a common way anywhere... Maybe we need to look into > >it? > > > >>diff --git a/test/linux-generic/cls/Makefile.am b/test/linux-generic/cls/Makefile.am > >>new file mode 100644 > >>index 0000000..43fb0bc > >>--- /dev/null > >>+++ b/test/linux-generic/cls/Makefile.am > >>@@ -0,0 +1,13 @@ > >>+include ../Makefile.inc > >>+ > >>+noinst_LTLIBRARIES = libtestcls.la > >Why do we need to create a library? > > we do it everywhere, I just follow existence Makefiles. As Christophe > explained me it's because all tests > will be combined to one library and later be executed. OK. > > >>+libtestcls_la_SOURCES = cls.c > >>+libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP) > >>+ > >>+test_PROGRAMS = cls_main$(EXEEXT) > >>+dist_cls_main_SOURCES = cls_main.c > >>+ > >>+cls_main_LDFLAGS = $(AM_LDFLAGS) > >>+cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP) > >>+ > >>+noinst_HEADERS = cls_suites.h > >>diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c > >>new file mode 100644 > >>index 0000000..d527ec8 > >>--- /dev/null > >>+++ b/test/linux-generic/cls/cls.c > >>@@ -0,0 +1,349 @@ > >>+/* Copyright (c) 2016, Linaro Limited > >>+ * All rights reserved. > >>+ * > >>+ * SPDX-License-Identifier: BSD-3-Clause > >>+ */ > >>+ > >>+#include <stdlib.h> > >>+#include <string.h> > >>+#include <getopt.h> > >>+#include <unistd.h> > >>+#include <inttypes.h> > >>+ > >>+#include <test_debug.h> > >>+ > >>+#include <odp_api.h> > >>+#include <odp/helper/linux.h> > >>+#include <odp/helper/eth.h> > >>+#include <odp/helper/ip.h> > >>+ > >>+#include <odp_packet_internal.h> > >why do we include an internal header file? > > > > because we need access to classifier bits, that is why this test is under > linux-generic. OK, but do we really have to fiddle with internal classifier bits? > > >>+ > >>+#include "cls_suites.h" > >>+ > >>+/** Get rid of path in filename - only for unix-type paths using '/' */ > >>+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ > >>+ strrchr((file_name), '/') + 1 : (file_name)) > >Maybe its enough basename? > >http://linux.die.net/man/3/basename > > yes, but again this define in almost each our test file. Oh, I missed that. > Probably separate > patch to change all NO_PATH > to basename(). OK. > > >>+ > >>+/** > >>+ * Print usage information > >>+ */ > >>+static void usage(char *progname) > >>+{ > >>+ printf("\n" > >>+ "This is test application to verify that linux-generic classifier\n" > >>+ "correctly classifies packets on input. Main intend is add more code\n" > >>+ "coverage for internal functions playing different traffic recorded to\n" > >>+ "pcap files." > >>+ "\n" > >>+ "Usage: %s OPTIONS\n" > >>+ " E.g. %s -i pcap_file -e expected_bitmask\n" > >Maybe expected_pkt_bitmask ? > > I don't mind, if you think it's better will change in v2. Do as you please. Cheers, Anders > > >>+ "\n" > >>+ "Mandatory OPTIONS:\n" > >>+ " -i, pcap file name\n" > >>+ " -e, expected packet bitmask\n" > >>+ "\n", NO_PATH(progname), NO_PATH(progname) > >>+ ); > >>+} > >>+ > >>+/** @def SHM_PKT_POOL_SIZE > >>+ * @brief Size of the shared memory block > >>+ */ > >>+#define SHM_PKT_POOL_SIZE 512 > >>+ > >>+/** @def SHM_PKT_POOL_BUF_SIZE > >>+ * @brief Buffer size of the packet pool buffer > >>+ */ > >>+#define SHM_PKT_POOL_BUF_SIZE 1856 > >>+ > >>+/** > >>+ * Parsed command line application arguments > >>+ */ > >>+typedef struct { > >>+ char *file_name; /**< File name for pcap pktio */ > >>+ odp_pktio_t pktio; /**< Pktio dev */ > >>+ input_flags_t expected_bits; /**< Expected bits from test run */ > >>+} appl_args_t; > >>+ > >>+/** > >>+ * Grouping of both parsed CL args and thread specific args - alloc together > >>+ */ > >>+typedef struct { > >>+ /** Application (parsed) arguments */ > >>+ appl_args_t appl; > >>+} args_t; > >>+ > >>+/** Global pointer to args */ > >>+static args_t *args; > >>+/** Fill this bit struct to check which packet fields were classified */ > >>+static input_flags_t packet_flags; > >>+ > >>+/** > >>+ * Parse and store the command line arguments > >>+ * > >>+ * @param argc argument count > >>+ * @param argv[] argument vector > >>+ * @param appl_args Store application arguments here > >>+ */ > >>+static void parse_args(int argc, char *argv[], appl_args_t *appl_args) > >>+{ > >>+ int opt; > >>+ int long_index; > >>+ static const struct option longopts[] = { > >>+ {"interface", required_argument, NULL, 'i'}, /* return 'i' */ > >>+ {"extected", required_argument, NULL, 'e'}, /* return 'e' */ > >>+ {"help", no_argument, NULL, 'h'}, /* return 'h' */ > >>+ {NULL, 0, NULL, 0} > >>+ }; > >>+ > >>+ static const char *shortopts = ":i:e:h"; > >>+ > >>+ /* let helper collect its own arguments (e.g. --odph_proc) */ > >>+ odph_parse_options(argc, argv, shortopts, longopts); > >>+ > >>+ appl_args->file_name = NULL; > >>+ opterr = 0; /* do not issue errors on helper options */ > >>+ appl_args->expected_bits.all = 0; > >>+ > >>+ while (1) { > >>+ opt = getopt_long(argc, argv, shortopts, longopts, &long_index); > >>+ > >>+ if (opt == -1) > >>+ break; /* No more options */ > >>+ > >>+ switch (opt) { > >>+ case 'i': > >>+ appl_args->file_name = optarg; > >>+ break; > >>+ case 'e': > >>+ appl_args->expected_bits.all = atoll(optarg); > >>+ break; > >>+ > >>+ case 'h': > >>+ usage(argv[0]); > >>+ exit(EXIT_SUCCESS); > >>+ break; > >>+ default: > >>+ break; > >>+ } > >>+ } > >>+ > >>+ if (!appl_args->file_name) { > >>+ usage(argv[0]); > >>+ exit(EXIT_SUCCESS); > >>+ } > >>+ > >>+ optind = 1; /* reset 'extern optind' from the getopt lib */ > >>+} > >>+ > >>+/** > >>+ * Create a pktio handle, optionally associating a default input queue. > >>+ * > >>+ * @param dev Name of device to open > >>+ * @param pool Pool to associate with device for packet RX/TX > >>+ * @param mode Packet processing mode for this device (BURST or QUEUE) > >>+ * > >>+ * @return The handle of the created pktio object. > >>+ * @retval ODP_PKTIO_INVALID if the create fails. > >>+ */ > >The doxygen text match the function definition. > > > >>+static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool) > >>+{ > >>+ odp_pktio_t pktio; > >>+ int ret; > >>+ odp_pktio_param_t pktio_param; > >>+ odp_pktin_queue_param_t pktin_param; > >>+ char dev[255]; > >>+ > >>+ odp_pktio_param_init(&pktio_param); > >>+ pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; > >>+ > >>+ memset(dev, 0, 255); > >>+ sprintf(dev, "pcap:in=%s:out=test_out.pcap", fname); > >>+ > >>+ /* Open a packet IO instance */ > >>+ pktio = odp_pktio_open(dev, pool, &pktio_param); > >>+ if (pktio == ODP_PKTIO_INVALID) > >>+ LOG_ABORT("Error: pktio create failed for %s\n", dev); > >>+ > >>+ odp_pktin_queue_param_init(&pktin_param); > >>+ > >>+ pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; > >>+ > >>+ if (odp_pktin_queue_config(pktio, &pktin_param)) > >>+ LOG_ABORT("Error: pktin config failed for %s\n", dev); > >>+ > >>+ if (odp_pktout_queue_config(pktio, NULL)) > >>+ LOG_ABORT("Error: pktout config failed for %s\n", dev); > >>+ > >>+ ret = odp_pktio_start(pktio); > >>+ if (ret != 0) > >>+ LOG_ABORT("Error: unable to start %s\n", dev); > >>+ > >>+ printf(" created pktio:%02" PRIu64 > >>+ ", dev:%s, queue mode (ATOMIC queues)\n" > >>+ " \tdefault pktio%02" PRIu64 "\n", > >>+ odp_pktio_to_u64(pktio), dev, > >>+ odp_pktio_to_u64(pktio)); > >>+ > >>+ return pktio; > >>+} > >>+ > >>+/** > >>+ * Packet IO loopback worker thread using ODP queues > >>+ * > >>+ * @param arg thread arguments of type 'thread_args_t *' > >>+ */ > >Document what we return ? > > > >>+static int pktio_queue_thread(void *arg ODP_UNUSED) > >>+{ > >>+ int thr = odp_thread_id(); > >>+ odp_pktout_queue_t pktout; > >>+ odp_packet_t pkt; > >>+ odp_event_t ev; > >>+ uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100); > >>+ > >>+ packet_flags.all = 0; > >>+ > >>+ /* Loop packets */ > >>+ while (1) { > >>+ odp_pktio_t pktio_tmp; > >>+ > >>+ ev = odp_schedule(NULL, sched_wait); > >>+ if (ev == ODP_EVENT_INVALID) > >>+ break; > >>+ > >>+ pkt = odp_packet_from_event(ev); > >>+ if (!odp_packet_is_valid(pkt)) > >>+ continue; > >>+ > >>+ pktio_tmp = odp_packet_input(pkt); > >>+ > >>+ if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) { > >>+ LOG_ERR(" [%02i] Error: no pktout queue\n", thr); > >>+ return -1; > >>+ } > >>+ > >>+ /* Extend bits here for more additional tests */ > >>+ if (odp_packet_has_l2(pkt)) > >>+ packet_flags.parsed_l2 = 1; > >>+ if (odp_packet_has_vlan(pkt)) > >>+ packet_flags.vlan = 1; > >>+ > >>+ /* Enqueue the packet for output */ > >>+ if (odp_pktout_send(pktout, &pkt, 1) != 1) { > >>+ LOG_ERR(" [%i] Packet send failed.\n", thr); > >>+ odp_packet_free(pkt); > >>+ continue; > >>+ } > >>+ } > >>+ > >>+ return 0; > >>+} > >>+ > >>+int cls_main(int argc, char *argv[]) > >>+{ > >>+ odph_odpthread_t thread_tbl[1]; > >>+ odp_pool_t pool; > >>+ int num_workers; > >>+ int i; > >>+ int cpu; > >>+ odp_cpumask_t cpumask; > >>+ char cpumaskstr[ODP_CPUMASK_STR_SIZE]; > >>+ odp_pool_param_t params; > >>+ odp_instance_t instance; > >>+ odph_odpthread_params_t thr_params; > >>+ > >>+ args = calloc(1, sizeof(args_t)); > >>+ if (args == NULL) { > >>+ LOG_ERR("Error: args mem alloc failed.\n"); > >>+ exit(EXIT_FAILURE); > >>+ } > >>+ > >>+ parse_args(argc, argv, &args->appl); > >>+ > >>+ /* Init ODP before calling anything else */ > >>+ if (odp_init_global(&instance, NULL, NULL)) { > >>+ LOG_ERR("Error: ODP global init failed.\n"); > >>+ exit(EXIT_FAILURE); > >>+ } > >>+ > >>+ /* Init this thread */ > >>+ if (odp_init_local(instance, ODP_THREAD_CONTROL)) { > >>+ LOG_ERR("Error: ODP local init failed.\n"); > >>+ exit(EXIT_FAILURE); > >>+ } > >>+ > >>+ num_workers = odp_cpumask_default_worker(&cpumask, 1); > >>+ (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); > >>+ > >>+ /* Create packet pool */ > >>+ odp_pool_param_init(¶ms); > >>+ params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; > >>+ params.pkt.len = SHM_PKT_POOL_BUF_SIZE; > >>+ params.pkt.num = SHM_PKT_POOL_SIZE; > >>+ params.type = ODP_POOL_PACKET; > >>+ > >>+ pool = odp_pool_create("packet_pool", ¶ms); > >>+ if (pool == ODP_POOL_INVALID) { > >>+ LOG_ERR("Error: packet pool create failed.\n"); > >>+ exit(EXIT_FAILURE); > >>+ } > >>+ > >>+ args->appl.pktio = create_pktio(args->appl.file_name, pool); > >>+ > >>+ /* Create and init worker threads */ > >>+ memset(thread_tbl, 0, sizeof(thread_tbl)); > >>+ > >>+ memset(&thr_params, 0, sizeof(thr_params)); > >>+ thr_params.thr_type = ODP_THREAD_WORKER; > >>+ thr_params.instance = instance; > >>+ > >>+ cpu = odp_cpumask_first(&cpumask); > >>+ for (i = 0; i < num_workers; ++i) { > >>+ odp_cpumask_t thd_mask; > >>+ int (*thr_run_func)(void *); > >>+ > >>+ thr_run_func = pktio_queue_thread; > >>+ /* > >>+ * Create threads one-by-one instead of all-at-once, > >>+ * because each thread might get different arguments. > >>+ * Calls odp_thread_create(cpu) for each thread > >>+ */ > >>+ odp_cpumask_zero(&thd_mask); > >>+ odp_cpumask_set(&thd_mask, cpu); > >>+ > >>+ thr_params.start = thr_run_func; > >>+ thr_params.arg = &args; > >>+ > >>+ odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params); > >>+ cpu = odp_cpumask_next(&cpumask, cpu); > >>+ } > >>+ > >>+ /* Master thread waits for other threads to exit */ > >>+ for (i = 0; i < num_workers; ++i) > >>+ odph_odpthreads_join(&thread_tbl[i]); > >>+ > >>+ odp_pktio_stop(args->appl.pktio); > >>+ odp_pktio_close(args->appl.pktio); > >>+ > >>+ while (1) { > >>+ odp_event_t ev; > >>+ > >>+ ev = odp_schedule(NULL, 0); > >>+ if (ev == ODP_EVENT_INVALID) > >>+ break; > >>+ } > >>+ > >>+ odp_pool_destroy(pool); > >>+ odp_term_local(); > >>+ odp_term_global(instance); > >>+ > >>+ if (packet_flags.all != args->appl.expected_bits.all) { > >>+ LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n", > >>+ packet_flags.all, args->appl.expected_bits.all); > >>+ free(args); > >>+ return -1; > >>+ } > >>+ > >>+ free(args); > >>+ return 0; > >>+} > >>diff --git a/test/linux-generic/cls/cls_main.c b/test/linux-generic/cls/cls_main.c > >>new file mode 100644 > >>index 0000000..40179b9 > >>--- /dev/null > >>+++ b/test/linux-generic/cls/cls_main.c > >>@@ -0,0 +1,12 @@ > >>+/* Copyright (c) 2016, Linaro Limited > >>+ * All rights reserved. > >>+ * > >>+ * SPDX-License-Identifier: BSD-3-Clause > >>+ */ > >>+ > >>+#include "cls_suites.h" > >>+ > >>+int main(int argc, char *argv[]) > >>+{ > >>+ return cls_main(argc, argv); > >>+} > >>diff --git a/test/linux-generic/cls/cls_suites.h b/test/linux-generic/cls/cls_suites.h > >>new file mode 100644 > >>index 0000000..94c9b55 > >>--- /dev/null > >>+++ b/test/linux-generic/cls/cls_suites.h > >>@@ -0,0 +1 @@ > >>+int cls_main(int argc, char *argv[]); > >>diff --git a/test/linux-generic/cls/vlan.pcap b/test/linux-generic/cls/vlan.pcap > >>new file mode 100644 > >>index 0000000000000000000000000000000000000000..106ccb682e51495b4025337518a0bce63c2c7681 > >>GIT binary patch > >>literal 9728 > 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 > >>H$A|v_$relS > >> > >>literal 0 > >>HcmV?d00001 > >> > >>diff --git a/test/linux-generic/cls/vlan_run.sh b/test/linux-generic/cls/vlan_run.sh > >>new file mode 100755 > >>index 0000000..7875eaf > >>--- /dev/null > >>+++ b/test/linux-generic/cls/vlan_run.sh > >>@@ -0,0 +1,49 @@ > >>+#!/bin/sh > >>+# > >>+# Copyright (c) 2016, Linaro Limited > >>+# All rights reserved. > >>+# > >>+# SPDX-License-Identifier: BSD-3-Clause > >>+# > >>+ > >>+# directories where binary can be found: > >>+# -in the validation dir when running make check (intree or out of tree) > >>+# -in the script directory, when running after 'make install', or > >>+# -in the validation when running standalone intree, > >>+# -in the _build directory, when running after 'make distcheck', > >>+# -in the current directory. > >>+# running stand alone out of tree requires setting PATH > >>+PATH=${TEST_DIR}/linux-generic/cls:$PATH > >>+PATH=$(dirname $0):$PATH > >>+PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH > >>+PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH > >>+PATH=.:$PATH > >>+ > >>+bin_path=$(which cls_main${EXEEXT}) > >>+if [ -x "$bin_path" ] ; then > >>+ echo "Running with $bin_path" > >>+else > >>+ echo "Cannot find cls_main${EXEEXT}" > >>+ echo "Please set you PATH for it. PATH=$PATH" > >>+fi > >>+ > >>+# Test1: find vlan packets in pcap file and test internal pkt_mmap_vlan_insert() > >>+# function. Load packets from vlan.pcap file and check that classifier > >>+# set vlan bits fisible with odp_packet_has_vlan(). > >>+ > >>+PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit` > >>+ > >>+cls_main -i $PCAP -e 4097 > >>+ret=$? > >>+ > >>+PCAP_IN_SIZE=`stat -c %s $PCAP` > >>+PCAP_OUT_SIZE=`stat -c %s test_out.pcap` > >>+ > >>+rm -f test_out.pcap > >>+ > >>+if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then > >>+ echo "Error: status ${ret}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}" > >>+ exit 3 > >>+fi > >>+ > >>+echo "PASS: test 1 passed" > >>diff --git a/test/linux-generic/m4/configure.m4 b/test/linux-generic/m4/configure.m4 > >>index 9eec545..375ead2 100644 > >>--- a/test/linux-generic/m4/configure.m4 > >>+++ b/test/linux-generic/m4/configure.m4 > >>@@ -1,5 +1,6 @@ > >> AC_CONFIG_FILES([test/linux-generic/Makefile > >> test/linux-generic/validation/api/shmem/Makefile > >> test/linux-generic/validation/api/pktio/Makefile > >>+ test/linux-generic/cls/Makefile > >Alphabetic order? > > > >Cheers, > >Anders >
On 2016-08-09 15:46, Maxim Uvarov wrote: > On 08/06/16 22:30, Anders Roxell wrote: > >--- a/test/linux-generic/m4/configure.m4 > >>+++ b/test/linux-generic/m4/configure.m4 > >>@@ -1,5 +1,6 @@ > >> AC_CONFIG_FILES([test/linux-generic/Makefile > >> test/linux-generic/validation/api/shmem/Makefile > >> test/linux-generic/validation/api/pktio/Makefile > >>+ test/linux-generic/cls/Makefile > here is validation group and all non validation tests are in alphabetic > order bellow. Basically, they are in some order. I see what you are trying to achieve. Then we need some more patches to fix it. Cheers, Anders
On 08/25/16 00:34, Anders Roxell wrote: >>>> +#include <odp_packet_internal.h> >>> > >why do we include an internal header file? >>> > > >> > >> >because we need access to classifier bits, that is why this test is under >> >linux-generic. > OK, but do we really have to fiddle with internal classifier bits? > That is good question. For linux-generic it's bit's for other platform it might be something else. I would like to change input_flags_t (linux-generic internal) to something else which might be common for all platforms. From other point of view if bit field will be changed in linux-generic we should not loose testing functionality. I'm not sure that all platforms support now pcap so that removing internal header might be not needed as this is internal platform test. When we will move to common then of course we need to remove internals. How about make it separate patch? Maxim.
On Thu, Aug 25, 2016 at 3:14 AM, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > On 08/25/16 00:34, Anders Roxell wrote: > >> +#include <odp_packet_internal.h> >>>>> >>>> > >why do we include an internal header file? >>>> > > >>>> >>> > >>> >because we need access to classifier bits, that is why this test is >>> under >>> >linux-generic. >>> >> OK, but do we really have to fiddle with internal classifier bits? >> >> > That is good question. For linux-generic it's bit's for other platform it > might be something else. > I would like to change input_flags_t (linux-generic internal) to something > else which might be common > for all platforms. From other point of view if bit field will be changed > in linux-generic we should not > loose testing functionality. I'm not sure that all platforms support now > pcap so that removing internal > header might be not needed as this is internal platform test. When we will > move to common then > of course we need to remove internals. How about make it separate patch? As I recall, Matias reorganized those bits a couple of months back to get some measurable performance gains, so I'd be cautious about making changes just for 'tidiness' without measuring any impact > > > Maxim. > > >
On 25 August 2016 at 10:14, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > On 08/25/16 00:34, Anders Roxell wrote: >>>>> >>>>> +#include <odp_packet_internal.h> >>>> >>>> > >why do we include an internal header file? >>>> > > >>> >>> > >>> >because we need access to classifier bits, that is why this test is >>> > under >>> >linux-generic. >> >> OK, but do we really have to fiddle with internal classifier bits? >> > > That is good question. For linux-generic it's bit's for other platform it > might be something else. > I would like to change input_flags_t (linux-generic internal) to something > else which might be common > for all platforms. By definition if we want to extend something that will be useful for all platforms it should be in the public API. > From other point of view if bit field will be changed in > linux-generic we should not > loose testing functionality. I'm not sure that all platforms support now > pcap so that removing internal > header might be not needed as this is internal platform test. When we will > move to common then > of course we need to remove internals. How about make it separate patch? Yes if you include that first I'm all for it. Anders
diff --git a/test/linux-generic/.gitignore b/test/linux-generic/.gitignore index 5dabf91..f65c7c1 100644 --- a/test/linux-generic/.gitignore +++ b/test/linux-generic/.gitignore @@ -1,3 +1,4 @@ *.log *.trs tests-validation.env +test_out.pcap diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index f5cc52d..9acbab0 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -1,5 +1,8 @@ include $(top_srcdir)/test/Makefile.inc TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/common_plat/validation +TEST_EXTENSIONS = .sh + +dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) ALL_API_VALIDATION_DIR = ${top_builddir}/test/common_plat/validation/api @@ -37,11 +40,14 @@ TESTS = validation/api/pktio/pktio_run.sh \ SUBDIRS += validation/api/pktio\ validation/api/shmem\ + cls\ pktio_ipc\ ring if HAVE_PCAP TESTS += validation/api/pktio/pktio_run_pcap.sh +TESTS += cls/vlan_run.sh +dist_check_SCRIPTS += cls/vlan_run.sh cls/vlan.pcap endif if netmap_support TESTS += validation/api/pktio/pktio_run_netmap.sh @@ -61,10 +67,6 @@ SUBDIRS += validation/api/pktio endif endif -TEST_EXTENSIONS = .sh - -dist_check_SCRIPTS = run-test tests-validation.env $(LOG_COMPILER) - test_SCRIPTS = $(dist_check_SCRIPTS) tests-validation.env: diff --git a/test/linux-generic/cls/.gitignore b/test/linux-generic/cls/.gitignore new file mode 100644 index 0000000..9447625 --- /dev/null +++ b/test/linux-generic/cls/.gitignore @@ -0,0 +1,3 @@ +cls_main +*.log +*.trs diff --git a/test/linux-generic/cls/Makefile.am b/test/linux-generic/cls/Makefile.am new file mode 100644 index 0000000..43fb0bc --- /dev/null +++ b/test/linux-generic/cls/Makefile.am @@ -0,0 +1,13 @@ +include ../Makefile.inc + +noinst_LTLIBRARIES = libtestcls.la +libtestcls_la_SOURCES = cls.c +libtestcls_la_CFLAGS = $(AM_CFLAGS) $(INCCUNIT_COMMON) $(INCODP) + +test_PROGRAMS = cls_main$(EXEEXT) +dist_cls_main_SOURCES = cls_main.c + +cls_main_LDFLAGS = $(AM_LDFLAGS) +cls_main_LDADD = libtestcls.la $(LIBCUNIT_COMMON) $(LIBODP) + +noinst_HEADERS = cls_suites.h diff --git a/test/linux-generic/cls/cls.c b/test/linux-generic/cls/cls.c new file mode 100644 index 0000000..d527ec8 --- /dev/null +++ b/test/linux-generic/cls/cls.c @@ -0,0 +1,349 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <unistd.h> +#include <inttypes.h> + +#include <test_debug.h> + +#include <odp_api.h> +#include <odp/helper/linux.h> +#include <odp/helper/eth.h> +#include <odp/helper/ip.h> + +#include <odp_packet_internal.h> + +#include "cls_suites.h" + +/** Get rid of path in filename - only for unix-type paths using '/' */ +#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ + strrchr((file_name), '/') + 1 : (file_name)) + +/** + * Print usage information + */ +static void usage(char *progname) +{ + printf("\n" + "This is test application to verify that linux-generic classifier\n" + "correctly classifies packets on input. Main intend is add more code\n" + "coverage for internal functions playing different traffic recorded to\n" + "pcap files." + "\n" + "Usage: %s OPTIONS\n" + " E.g. %s -i pcap_file -e expected_bitmask\n" + "\n" + "Mandatory OPTIONS:\n" + " -i, pcap file name\n" + " -e, expected packet bitmask\n" + "\n", NO_PATH(progname), NO_PATH(progname) + ); +} + +/** @def SHM_PKT_POOL_SIZE + * @brief Size of the shared memory block + */ +#define SHM_PKT_POOL_SIZE 512 + +/** @def SHM_PKT_POOL_BUF_SIZE + * @brief Buffer size of the packet pool buffer + */ +#define SHM_PKT_POOL_BUF_SIZE 1856 + +/** + * Parsed command line application arguments + */ +typedef struct { + char *file_name; /**< File name for pcap pktio */ + odp_pktio_t pktio; /**< Pktio dev */ + input_flags_t expected_bits; /**< Expected bits from test run */ +} appl_args_t; + +/** + * Grouping of both parsed CL args and thread specific args - alloc together + */ +typedef struct { + /** Application (parsed) arguments */ + appl_args_t appl; +} args_t; + +/** Global pointer to args */ +static args_t *args; +/** Fill this bit struct to check which packet fields were classified */ +static input_flags_t packet_flags; + +/** + * Parse and store the command line arguments + * + * @param argc argument count + * @param argv[] argument vector + * @param appl_args Store application arguments here + */ +static void parse_args(int argc, char *argv[], appl_args_t *appl_args) +{ + int opt; + int long_index; + static const struct option longopts[] = { + {"interface", required_argument, NULL, 'i'}, /* return 'i' */ + {"extected", required_argument, NULL, 'e'}, /* return 'e' */ + {"help", no_argument, NULL, 'h'}, /* return 'h' */ + {NULL, 0, NULL, 0} + }; + + static const char *shortopts = ":i:e:h"; + + /* let helper collect its own arguments (e.g. --odph_proc) */ + odph_parse_options(argc, argv, shortopts, longopts); + + appl_args->file_name = NULL; + opterr = 0; /* do not issue errors on helper options */ + appl_args->expected_bits.all = 0; + + while (1) { + opt = getopt_long(argc, argv, shortopts, longopts, &long_index); + + if (opt == -1) + break; /* No more options */ + + switch (opt) { + case 'i': + appl_args->file_name = optarg; + break; + case 'e': + appl_args->expected_bits.all = atoll(optarg); + break; + + case 'h': + usage(argv[0]); + exit(EXIT_SUCCESS); + break; + default: + break; + } + } + + if (!appl_args->file_name) { + usage(argv[0]); + exit(EXIT_SUCCESS); + } + + optind = 1; /* reset 'extern optind' from the getopt lib */ +} + +/** + * Create a pktio handle, optionally associating a default input queue. + * + * @param dev Name of device to open + * @param pool Pool to associate with device for packet RX/TX + * @param mode Packet processing mode for this device (BURST or QUEUE) + * + * @return The handle of the created pktio object. + * @retval ODP_PKTIO_INVALID if the create fails. + */ +static odp_pktio_t create_pktio(const char *fname, odp_pool_t pool) +{ + odp_pktio_t pktio; + int ret; + odp_pktio_param_t pktio_param; + odp_pktin_queue_param_t pktin_param; + char dev[255]; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; + + memset(dev, 0, 255); + sprintf(dev, "pcap:in=%s:out=test_out.pcap", fname); + + /* Open a packet IO instance */ + pktio = odp_pktio_open(dev, pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) + LOG_ABORT("Error: pktio create failed for %s\n", dev); + + odp_pktin_queue_param_init(&pktin_param); + + pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; + + if (odp_pktin_queue_config(pktio, &pktin_param)) + LOG_ABORT("Error: pktin config failed for %s\n", dev); + + if (odp_pktout_queue_config(pktio, NULL)) + LOG_ABORT("Error: pktout config failed for %s\n", dev); + + ret = odp_pktio_start(pktio); + if (ret != 0) + LOG_ABORT("Error: unable to start %s\n", dev); + + printf(" created pktio:%02" PRIu64 + ", dev:%s, queue mode (ATOMIC queues)\n" + " \tdefault pktio%02" PRIu64 "\n", + odp_pktio_to_u64(pktio), dev, + odp_pktio_to_u64(pktio)); + + return pktio; +} + +/** + * Packet IO loopback worker thread using ODP queues + * + * @param arg thread arguments of type 'thread_args_t *' + */ +static int pktio_queue_thread(void *arg ODP_UNUSED) +{ + int thr = odp_thread_id(); + odp_pktout_queue_t pktout; + odp_packet_t pkt; + odp_event_t ev; + uint64_t sched_wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS * 100); + + packet_flags.all = 0; + + /* Loop packets */ + while (1) { + odp_pktio_t pktio_tmp; + + ev = odp_schedule(NULL, sched_wait); + if (ev == ODP_EVENT_INVALID) + break; + + pkt = odp_packet_from_event(ev); + if (!odp_packet_is_valid(pkt)) + continue; + + pktio_tmp = odp_packet_input(pkt); + + if (odp_pktout_queue(pktio_tmp, &pktout, 1) != 1) { + LOG_ERR(" [%02i] Error: no pktout queue\n", thr); + return -1; + } + + /* Extend bits here for more additional tests */ + if (odp_packet_has_l2(pkt)) + packet_flags.parsed_l2 = 1; + if (odp_packet_has_vlan(pkt)) + packet_flags.vlan = 1; + + /* Enqueue the packet for output */ + if (odp_pktout_send(pktout, &pkt, 1) != 1) { + LOG_ERR(" [%i] Packet send failed.\n", thr); + odp_packet_free(pkt); + continue; + } + } + + return 0; +} + +int cls_main(int argc, char *argv[]) +{ + odph_odpthread_t thread_tbl[1]; + odp_pool_t pool; + int num_workers; + int i; + int cpu; + odp_cpumask_t cpumask; + char cpumaskstr[ODP_CPUMASK_STR_SIZE]; + odp_pool_param_t params; + odp_instance_t instance; + odph_odpthread_params_t thr_params; + + args = calloc(1, sizeof(args_t)); + if (args == NULL) { + LOG_ERR("Error: args mem alloc failed.\n"); + exit(EXIT_FAILURE); + } + + parse_args(argc, argv, &args->appl); + + /* Init ODP before calling anything else */ + if (odp_init_global(&instance, NULL, NULL)) { + LOG_ERR("Error: ODP global init failed.\n"); + exit(EXIT_FAILURE); + } + + /* Init this thread */ + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { + LOG_ERR("Error: ODP local init failed.\n"); + exit(EXIT_FAILURE); + } + + num_workers = odp_cpumask_default_worker(&cpumask, 1); + (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); + + /* Create packet pool */ + odp_pool_param_init(¶ms); + params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; + params.pkt.len = SHM_PKT_POOL_BUF_SIZE; + params.pkt.num = SHM_PKT_POOL_SIZE; + params.type = ODP_POOL_PACKET; + + pool = odp_pool_create("packet_pool", ¶ms); + if (pool == ODP_POOL_INVALID) { + LOG_ERR("Error: packet pool create failed.\n"); + exit(EXIT_FAILURE); + } + + args->appl.pktio = create_pktio(args->appl.file_name, pool); + + /* Create and init worker threads */ + memset(thread_tbl, 0, sizeof(thread_tbl)); + + memset(&thr_params, 0, sizeof(thr_params)); + thr_params.thr_type = ODP_THREAD_WORKER; + thr_params.instance = instance; + + cpu = odp_cpumask_first(&cpumask); + for (i = 0; i < num_workers; ++i) { + odp_cpumask_t thd_mask; + int (*thr_run_func)(void *); + + thr_run_func = pktio_queue_thread; + /* + * Create threads one-by-one instead of all-at-once, + * because each thread might get different arguments. + * Calls odp_thread_create(cpu) for each thread + */ + odp_cpumask_zero(&thd_mask); + odp_cpumask_set(&thd_mask, cpu); + + thr_params.start = thr_run_func; + thr_params.arg = &args; + + odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params); + cpu = odp_cpumask_next(&cpumask, cpu); + } + + /* Master thread waits for other threads to exit */ + for (i = 0; i < num_workers; ++i) + odph_odpthreads_join(&thread_tbl[i]); + + odp_pktio_stop(args->appl.pktio); + odp_pktio_close(args->appl.pktio); + + while (1) { + odp_event_t ev; + + ev = odp_schedule(NULL, 0); + if (ev == ODP_EVENT_INVALID) + break; + } + + odp_pool_destroy(pool); + odp_term_local(); + odp_term_global(instance); + + if (packet_flags.all != args->appl.expected_bits.all) { + LOG_ERR("Flags %" PRIu64 " expected %" PRIu64 "\n", + packet_flags.all, args->appl.expected_bits.all); + free(args); + return -1; + } + + free(args); + return 0; +} diff --git a/test/linux-generic/cls/cls_main.c b/test/linux-generic/cls/cls_main.c new file mode 100644 index 0000000..40179b9 --- /dev/null +++ b/test/linux-generic/cls/cls_main.c @@ -0,0 +1,12 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "cls_suites.h" + +int main(int argc, char *argv[]) +{ + return cls_main(argc, argv); +} diff --git a/test/linux-generic/cls/cls_suites.h b/test/linux-generic/cls/cls_suites.h new file mode 100644 index 0000000..94c9b55 --- /dev/null +++ b/test/linux-generic/cls/cls_suites.h @@ -0,0 +1 @@ +int cls_main(int argc, char *argv[]); diff --git a/test/linux-generic/cls/vlan.pcap b/test/linux-generic/cls/vlan.pcap new file mode 100644 index 0000000000000000000000000000000000000000..106ccb682e51495b4025337518a0bce63c2c7681 GIT binary patch literal 9728 zcmeHNeQXrR6@R<F^Iq)3b|{=(C16{8IUt}71RM^-2~wIU*pOl>ikyh3QAN~9xK+}$ z4T)^-QnlAgC4W>Yk*X>mRlo92km}Nw!c|oiNTn)LBLcyK0BKSYLZiA0xI}f|@6FEc z&CT8}Zu4i?dS2hYnK$pf`MuxF&iVB}9(>lN6zOYfipb#)S3BqRK6jeva#{)P%KZ4H z2`Z!uf1f`})Rm#nP<lLnYk>-l2Nx8d?iyv8ohr8v56pV)=ly+yzZvNmzS?$(tvQ({ zN`3H(bKv=xSCLCcs6x0O=6jaXv{mjz%{=NyEc#gk|LwB0u=KHqz1)uIAM9Usn@mg_ zk2Z3jR&?;MUcTp8vTSb+>k8B@8d$;SEO~No<@;@ZpT?k%M|X%lk9|?s`aqYWyx8+Z z0ekoid$_k!Cq3-<X$<;!oI~ik=uuzyOrT5ATGkaPBO2JlXV}BNmHltQH1XBQqGIxB zljw+U^mWzt`dC-+XBzhK8TN2Tj(!$l@3W%oreFHHd@xpu)``6eKOy$gmCxBdp4?km zcOk;wono&-@A$eG`7XZiNzwWmd-x3haEHC`0}y;QvZ#0!b{bfxaRTgY=FeI7XemDg zrt~v(2bR#*#*@ZM8*9~NW2GVr#A;%NVz9F1ZjF^e?ya$>uoBL#iIo(6N4XHj>S(MG zeb3ib&#l6WQUqAxJ_;+1G%sQ<6jmy<(AQPlQ&<V@nONzj-$&R}SgBCO*Ck?w=N1@3 ztzC_<r?BGDHD4ECg)ywKqF4*@npnxu3)8|1QTKm^m5M(TBzz!q>u6q?Ejk-3sTiy% zJLqU*1*lbZW@5#)vBLROyi$q5N@&mI6<4qV_HQ01DswYP6#Khh&#x#j`~T|OCi|bb zN3;J^@0;w82*T>sY!!z<-^(tatsc~D<=O~jv?n9bxA(ZuR@_G+(2YT0#YW(iMxbxc zLZBOiz%;k6x2kCtQg)HA>t~@#46@u{#j=rA!7#$$CbB9q$Z}(l71}eARf%CCH-?2m zdtf0!=0&0c`wW?qD??ss=9y8V-J`2{2h$^47+;s#M(N!gA6oF=4y70DLnrRc7wjFF zOx)+JEMT8A&qVskA84dEJRcza81^~gx*CC0u1|&3bPQLjeGd2o2!%a`RQ9+oSCWm? zfGfKtTAM4q7^HeU`u~Dd8B&mS{p)1}QkhfLdKua?kxJ7;D%*=(FFD6*y`<?OmF>l^ zmt?b5fB`qaKtG2kYe<9MTZQq~VxY+<h-x;~d#f3~&R#D=d**scG&arkGRI?>d#f#X zC-1F%$Jh;<)qLNa>FllkkCp7lgq7o*eqgVOD_&tEZf{L=#F~HiI`-D;-3T*n&wsd= zGr8jW-oxxwEwpEHg=cUD*#9!K|9#A<kf?o*vpIho*njMx$^K{hH2Xg}X0pFjF;}?S zg?TY+W$2}>m0g;Fych=ZV%Eygp6u8k*ZU<ehJierftb<2IMr{9CIfj?pMlb(8K@Rj z$o3L`#oxq<hN#m7mGe>mOo3LGZ$h?rzm4+*WW0SiRYs-<W}WF9Y1=#eX@6JA>+A&1 z6<~FR<Af&_1)NcsR@39<n_=~fdE4sQ?IRtJ?fAxsnnT~}v0Trei#VBp-~zsz<$QwZ zhdl$C?4;5|r=G9K9Q(-%d8OMrIdwGG^Oqt{A0Ybbl^XN=lhQ-iCC@izetSZ-RQ+Es zq7ope$T_TPtm>cZIbrB=T4CznDB`pN0v}Lu>#O=_=?(F(i=TJYjDJ}CKUqZOK;XlW zW&ce>|FES$T?GCi@Bt?r&luyM7XKF29e=!tnt;HE4=wv=3_VUm%=ph1@rDb54>%Dq z$3H9n?W;TfTSe3m1U~Gy?4LLEI6X1Pzfi<34+0->f|57lzaakAAOGzlY7PP){$$yI z$I#=n#T@_LB6b82_<$3a7acH@#^1Z*-@Ll<|E&nzLEyuqyhAYUUo`YMoiX*7ia3dZ z;A-ItTIyoYpzG&S@h;ZoU6)S)@O)!t$5R`F`pHhJ{%EiI)z;Ss3HYC|@IPqeU+H0A z)kSUn{WAgI9~yd`*qHHOG4PL58xwz5#6O%M&W^0Vs|oo2m!ZcAk2(G|1OGVXF~`3q z{ykZD{Ergw{cl5$6Crc_DFgo%)|>dB694LtPo--7+xT`x5BA^1?EeJsNFY&biu+J` z4%q)ozcAT<=luh-6#JLUCj0BE!@HIlRYR$|s&F=CR#ig@)wZy1R#T<ws<Nx5(a_@@ z%N##bs;#PSqpC6`RMm2>s%&Icss8L9pLwC`YO5++s$O;MRi&*|y(-wKpH-@6Z5x#x zrD|5SQFF5~>vsOT67sV!!T-ex{x3`L|JGRlfyPUW#!Z}ANYs9kR_0d$jlVvQ-3<__ zzBM_!y}xhg{UdE(-nw?Pv7elP)eUZ<)zxD4m~D0Fz)0JJ9Z^=tXR=k^G(w^(C$+LX z7girQXI9S80aZDBhZpdHIlkcu_f4x3W^hfy3>Fe*@Q#ETyfa}2H^<Iku4ju>uwJ*p zTm8nmq4bzs#b>qa#@2-RKWFH%k2WiOo53*HOPdU{P5i^@`pn36V=y7VpEvY)^Eb!e zVKGe3V3-}kF!PyVnj;xT^+$eGzgmVFN|@hW3G@3v!u;+|nBRvI^1sK*|8Zmfl^*e_ z=jQy+d~7(#FE;^v<b46{KXnc71z)xDd&J1E(xbh4UYozK1^L4&Wi#|Q6Y}>&LjLw8 z<nLRt`2$xCe<G2qdWEZAvAJp&bJgDA`4a&H9tX3)>LcwAy~<gEMDpsP{Ow|OL!{M? zy~CGxnpQXQw}sm|hc~d`YNjsQ!0+vN*2Ln_T-HGxxocg<Z{H-n@T)WE2V0J`$8Y@1 z4RoIL>tx#yoVIkz`Sa8B9XijSA(4^2mR}>0-BJ_Tss29B7e_YvoEaIu-^}r7-=$^F z6~cGXX+DRoz`pSeQC2_O!0pfvZ7;gZocCA|HJ+)q%N#r>S}s!E9?#x$mpi>Ywi-)) zzlqPPulkI+{1I<Q$9P~!WW+Dz^Aho(8Sz_>=!jps-HaGs&hb6xvm83*LP+jfr{?Bf zI_W|jxoaKf2D63d>gQgWH`vr!f<1NJC-ZiBu|or#2S`*D&f5H1L^1ZenkfFNqp0wI zSNQ)QAvgyjv46|5;Cj<-r46np&s0uZI3frlYYB8{@6ZhP9)c)li1)B%M;7X4_~V3; zweY?r!UwhjTaiBax{uQbVC0ia6YITCFtX0f?z#7McFRAtvy0s`aDWT^itOSU<``9e z*o8Q9*E$t7pW+Ae-z3@9wtyG(Q9m~XI#usY+z*2OO@f;?E}jJRuan5`F(W(w6&+cA zwHX;uyoe*XMIvi=PPq_Zq+RM4y2TP<&N=BqfRS9F>k(Zw`a|6ku?bs}H2&4@V19<y zID}Ini24?e_AhE5T`)?NmT%$iQtg$F&ri|}c4@KSDc;0y{aiISvdwh*S?0(k1@)&> zQ7plIU*=6|dR#J=D<oFhda1NSH5ognGq!{Y*RQl!v7!LwU*O1E{OJDRV*$_b-zLDq zQO3ei&J^yz0(2S+l^`1m3)&VifIih&fKFqf!Wckb+_euHkKzNjM0<@#!v|j%=L2j_ H$A|v_$relS literal 0 HcmV?d00001 diff --git a/test/linux-generic/cls/vlan_run.sh b/test/linux-generic/cls/vlan_run.sh new file mode 100755 index 0000000..7875eaf --- /dev/null +++ b/test/linux-generic/cls/vlan_run.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (c) 2016, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# directories where binary can be found: +# -in the validation dir when running make check (intree or out of tree) +# -in the script directory, when running after 'make install', or +# -in the validation when running standalone intree, +# -in the _build directory, when running after 'make distcheck', +# -in the current directory. +# running stand alone out of tree requires setting PATH +PATH=${TEST_DIR}/linux-generic/cls:$PATH +PATH=$(dirname $0):$PATH +PATH=$(dirname $0)/../../../../test/linux-generic/cls:$PATH +PATH=$(dirname $0)/../../../../_build/test/linux-generic/cls:$PATH +PATH=.:$PATH + +bin_path=$(which cls_main${EXEEXT}) +if [ -x "$bin_path" ] ; then + echo "Running with $bin_path" +else + echo "Cannot find cls_main${EXEEXT}" + echo "Please set you PATH for it. PATH=$PATH" +fi + +# Test1: find vlan packets in pcap file and test internal pkt_mmap_vlan_insert() +# function. Load packets from vlan.pcap file and check that classifier +# set vlan bits fisible with odp_packet_has_vlan(). + +PCAP=`find . ${TEST_DIR} $(dirname $0) -name vlan.pcap -print -quit` + +cls_main -i $PCAP -e 4097 +ret=$? + +PCAP_IN_SIZE=`stat -c %s $PCAP` +PCAP_OUT_SIZE=`stat -c %s test_out.pcap` + +rm -f test_out.pcap + +if [ ${ret} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then + echo "Error: status ${ret}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}" + exit 3 +fi + +echo "PASS: test 1 passed" diff --git a/test/linux-generic/m4/configure.m4 b/test/linux-generic/m4/configure.m4 index 9eec545..375ead2 100644 --- a/test/linux-generic/m4/configure.m4 +++ b/test/linux-generic/m4/configure.m4 @@ -1,5 +1,6 @@ AC_CONFIG_FILES([test/linux-generic/Makefile test/linux-generic/validation/api/shmem/Makefile test/linux-generic/validation/api/pktio/Makefile + test/linux-generic/cls/Makefile test/linux-generic/pktio_ipc/Makefile test/linux-generic/ring/Makefile])
add pcap play back test which takes 2 arguments: 1 - pcap file, 2 - packet mask to match. Intend is to test odp with different input traffic to check internal implementation functions. In current case it's test for vlan tag instertion for packet mmap: pkt_mmap_vlan_insert(). Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> --- v2: up the patch, dirrect execution looks like works. test/linux-generic/.gitignore | 1 + test/linux-generic/Makefile.am | 10 +- test/linux-generic/cls/.gitignore | 3 + test/linux-generic/cls/Makefile.am | 13 ++ test/linux-generic/cls/cls.c | 349 ++++++++++++++++++++++++++++++++++++ test/linux-generic/cls/cls_main.c | 12 ++ test/linux-generic/cls/cls_suites.h | 1 + test/linux-generic/cls/vlan.pcap | Bin 0 -> 9728 bytes test/linux-generic/cls/vlan_run.sh | 49 +++++ test/linux-generic/m4/configure.m4 | 1 + 10 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 test/linux-generic/cls/.gitignore create mode 100644 test/linux-generic/cls/Makefile.am create mode 100644 test/linux-generic/cls/cls.c create mode 100644 test/linux-generic/cls/cls_main.c create mode 100644 test/linux-generic/cls/cls_suites.h create mode 100644 test/linux-generic/cls/vlan.pcap create mode 100755 test/linux-generic/cls/vlan_run.sh -- 2.7.1.250.gff4ea60