aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.shippable.yml9
-rw-r--r--.travis.yml4
-rw-r--r--DEPENDENCIES39
-rw-r--r--Makefile.am10
-rw-r--r--configure.ac3
-rw-r--r--doc/Doxyfile_common2
-rw-r--r--doc/application-api-guide/api_guide_lines.dox14
-rw-r--r--doc/application-api-guide/examples.dox15
-rw-r--r--doc/application-api-guide/odp.dox4
-rw-r--r--doc/application-api-guide/release.dox2
-rw-r--r--doc/helper-guide/Doxyfile2
-rw-r--r--doc/m4/configure.m441
-rw-r--r--example/Makefile.am3
-rw-r--r--example/debug/.gitignore3
-rw-r--r--example/debug/Makefile.am9
-rw-r--r--example/debug/odp_debug.c335
-rw-r--r--example/generator/Makefile.am20
-rw-r--r--example/ipsec/.gitignore1
-rw-r--r--example/ipsec/Makefile.am37
-rw-r--r--example/ipsec_api/Makefile.am20
-rw-r--r--example/ipsec_api/README157
-rw-r--r--example/ipsec_api/odp_ipsec.c4
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_live.sh6
l---------example/ipsec_api/odp_ipsec_fwd_db.c2
l---------example/ipsec_api/odp_ipsec_fwd_db.h2
l---------example/ipsec_api/odp_ipsec_misc.h2
l---------example/ipsec_api/odp_ipsec_sa_db.c2
l---------example/ipsec_api/odp_ipsec_sa_db.h2
l---------example/ipsec_api/odp_ipsec_sp_db.c2
l---------example/ipsec_api/odp_ipsec_sp_db.h2
l---------example/ipsec_api/odp_ipsec_stream.c2
l---------example/ipsec_api/odp_ipsec_stream.h2
-rw-r--r--example/ipsec_crypto/.gitignore1
-rw-r--r--example/ipsec_crypto/Makefile.am58
-rw-r--r--example/ipsec_crypto/README (renamed from example/ipsec/README)20
-rw-r--r--example/ipsec_crypto/odp_ipsec.c (renamed from example/ipsec/odp_ipsec.c)2
-rw-r--r--example/ipsec_crypto/odp_ipsec_cache.c (renamed from example/ipsec/odp_ipsec_cache.c)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_cache.h (renamed from example/ipsec/odp_ipsec_cache.h)0
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh (renamed from example/ipsec/odp_ipsec_run_ah_in.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh (renamed from example/ipsec/odp_ipsec_run_ah_out.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh (renamed from example/ipsec/odp_ipsec_run_both_in.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh (renamed from example/ipsec/odp_ipsec_run_both_out.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh (renamed from example/ipsec/odp_ipsec_run_esp_in.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh (renamed from example/ipsec/odp_ipsec_run_esp_out.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_live.sh (renamed from example/ipsec/odp_ipsec_run_live.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_router.sh (renamed from example/ipsec/odp_ipsec_run_router.sh)2
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_simple.sh (renamed from example/ipsec/odp_ipsec_run_simple.sh)2
-rw-r--r--example/ipsec_crypto/odp_ipsec_fwd_db.c (renamed from example/ipsec/odp_ipsec_fwd_db.c)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_fwd_db.h (renamed from example/ipsec/odp_ipsec_fwd_db.h)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_misc.h (renamed from example/ipsec/odp_ipsec_misc.h)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_sa_db.c (renamed from example/ipsec/odp_ipsec_sa_db.c)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_sa_db.h (renamed from example/ipsec/odp_ipsec_sa_db.h)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_sp_db.c (renamed from example/ipsec/odp_ipsec_sp_db.c)9
-rw-r--r--example/ipsec_crypto/odp_ipsec_sp_db.h (renamed from example/ipsec/odp_ipsec_sp_db.h)7
-rw-r--r--example/ipsec_crypto/odp_ipsec_stream.c (renamed from example/ipsec/odp_ipsec_stream.c)0
-rw-r--r--example/ipsec_crypto/odp_ipsec_stream.h (renamed from example/ipsec/odp_ipsec_stream.h)0
-rw-r--r--example/l2fwd_simple/.gitignore1
-rw-r--r--example/l2fwd_simple/Makefile.am22
-rwxr-xr-xexample/l2fwd_simple/l2fwd_simple_run.sh33
-rw-r--r--example/l3fwd/.gitignore1
-rw-r--r--example/l3fwd/Makefile.am22
-rwxr-xr-xexample/l3fwd/odp_l3fwd_run.sh29
-rw-r--r--example/m4/configure.m43
-rw-r--r--example/packet/.gitignore1
-rw-r--r--example/packet/Makefile.am22
-rwxr-xr-xexample/packet/packet_dump_run.sh17
-rwxr-xr-xexample/packet/pktio_run.sh65
-rw-r--r--example/ping/.gitignore1
-rw-r--r--example/ping/Makefile.am22
-rwxr-xr-xexample/ping/ping_run.sh29
-rw-r--r--example/simple_pipeline/.gitignore1
-rw-r--r--example/simple_pipeline/Makefile.am22
-rwxr-xr-xexample/simple_pipeline/simple_pipeline_run.sh22
-rw-r--r--example/switch/.gitignore1
-rw-r--r--example/switch/Makefile.am22
-rwxr-xr-xexample/switch/switch_run.sh36
-rw-r--r--helper/test/Makefile.am20
-rw-r--r--include/odp/api/spec/classification.h63
-rw-r--r--include/odp/api/spec/crypto.h16
-rw-r--r--include/odp/api/spec/packet.h14
-rw-r--r--platform/linux-generic/include/odp/api/plat/packet_inline_types.h1
-rw-r--r--platform/linux-generic/include/odp_classification_datamodel.h6
-rw-r--r--platform/linux-generic/include/odp_packet_internal.h9
-rw-r--r--platform/linux-generic/include/odp_pkt_queue_internal.h3
-rw-r--r--platform/linux-generic/include/odp_traffic_mngr_internal.h1
-rw-r--r--platform/linux-generic/m4/configure.m47
-rw-r--r--platform/linux-generic/odp_classification.c46
-rw-r--r--platform/linux-generic/odp_crypto_null.c14
-rw-r--r--platform/linux-generic/odp_crypto_openssl.c14
-rw-r--r--platform/linux-generic/odp_ishm.c2
-rw-r--r--platform/linux-generic/odp_packet.c13
-rw-r--r--platform/linux-generic/odp_pkt_queue.c44
-rw-r--r--platform/linux-generic/odp_traffic_mngr.c18
-rw-r--r--platform/linux-generic/test/Makefile.am27
-rw-r--r--platform/linux-generic/test/example/Makefile.am7
-rw-r--r--platform/linux-generic/test/example/l2fwd_simple/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/l2fwd_simple/pktio_env47
-rw-r--r--platform/linux-generic/test/example/l3fwd/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/l3fwd/pktio_env51
-rw-r--r--platform/linux-generic/test/example/packet/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/packet/pktio_env50
-rw-r--r--platform/linux-generic/test/example/ping/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/ping/pktio_env50
-rw-r--r--platform/linux-generic/test/example/simple_pipeline/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/simple_pipeline/pktio_env47
-rw-r--r--platform/linux-generic/test/example/switch/Makefile.am1
-rw-r--r--platform/linux-generic/test/example/switch/pktio_env53
-rwxr-xr-xplatform/linux-generic/test/ipsec/ipsec_crypto_example.sh (renamed from platform/linux-generic/test/ipsec/ipsec_example.sh)8
-rw-r--r--platform/linux-generic/test/pktio_ipc/Makefile.am20
-rw-r--r--platform/linux-generic/test/validation/api/pktio/Makefile.am20
-rw-r--r--test/Makefile.am1
-rw-r--r--test/README5
-rw-r--r--test/m4/configure.m43
-rw-r--r--test/performance/Makefile.am20
-rw-r--r--test/performance/odp_bench_packet.c8
-rw-r--r--test/performance/odp_crypto.c2
-rw-r--r--test/performance/odp_ipsec.c2
-rw-r--r--test/performance/odp_l2fwd.c42
-rw-r--r--test/performance/odp_packet_gen.c279
-rwxr-xr-xtest/performance/odp_packet_gen_run.sh21
-rw-r--r--test/performance/odp_pktio_perf.c2
-rw-r--r--test/performance/odp_pool_perf.c2
-rw-r--r--test/performance/odp_queue_perf.c4
-rw-r--r--test/performance/odp_sched_perf.c2
-rw-r--r--test/performance/odp_timer_perf.c2
-rw-r--r--test/validation/api/classification/odp_classification_common.c30
-rw-r--r--test/validation/api/classification/odp_classification_test_pmr.c77
-rw-r--r--test/validation/api/crypto/odp_crypto_test_inp.c50
-rw-r--r--test/validation/api/crypto/test_vectors.h4
-rw-r--r--test/validation/api/ipsec/ipsec.c71
-rw-r--r--test/validation/api/ipsec/ipsec.h9
-rw-r--r--test/validation/api/ipsec/ipsec_test_out.c477
-rw-r--r--test/validation/api/ipsec/test_vectors.h28
-rw-r--r--test/validation/api/packet/packet.c3
-rw-r--r--test/validation/api/pktio/pktio.c1
-rw-r--r--test/validation/api/scheduler/scheduler.c149
-rw-r--r--test/validation/api/system/system.c68
137 files changed, 2595 insertions, 689 deletions
diff --git a/.shippable.yml b/.shippable.yml
index 1fcb16851..fcaef7d68 100644
--- a/.shippable.yml
+++ b/.shippable.yml
@@ -4,6 +4,15 @@ compiler:
- gcc
- clang
+integrations:
+ notifications:
+ - integrationName: email
+ type: email
+ on_success: never
+ on_failure: never
+ on_cancel: never
+ on_pull_request: never
+
env:
- CONF="--disable-test-perf"
- CONF="--disable-abi-compat --disable-test-perf"
diff --git a/.travis.yml b/.travis.yml
index accd76092..b48379437 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -139,7 +139,7 @@ jobs:
-e ODP_SCHEDULER=sp
${DOCKER_NAMESPACE}/travis-odp-${OS}-${ARCH} /odp/scripts/ci/check.sh
- stage: test
- env: TEST=dpdk-19.11
+ env: TEST=dpdk-18.11
install:
- true
compiler: gcc
@@ -149,7 +149,7 @@ jobs:
-v `pwd`:/odp --shm-size 8g
-e CC="${CC}"
-e CONF=""
- ${DOCKER_NAMESPACE}/travis-odp-${OS}-${ARCH}-dpdk_19.11 /odp/scripts/ci/check.sh
+ ${DOCKER_NAMESPACE}/travis-odp-${OS}-${ARCH}-dpdk_18.11 /odp/scripts/ci/check.sh
- stage: test
env: TEST=distcheck
canfail: yes
diff --git a/DEPENDENCIES b/DEPENDENCIES
index fdcf9ccb7..e28afc0d3 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -171,12 +171,12 @@ Prerequisites for building the OpenDataPlane (ODP) API
3.4 DPDK packet I/O support (optional)
- Use DPDK for ODP packet I/O. Currently supported DPDK versions are v18.11
- and v19.11.
+ Use DPDK for ODP packet I/O. Currently supported DPDK versions are v19.11
+ (recommended) and v18.11.
- Note: only packet I/O is accelerated with DPDK. Use
+ Note: only packet I/O is accelerated with DPDK. See
https://github.com/OpenDataPlane/odp-dpdk.git
- for fully accelerated odp dpdk platform.
+ for a full DPDK based ODP implementation.
3.4.1 DPDK pktio requirements
@@ -190,24 +190,23 @@ Prerequisites for building the OpenDataPlane (ODP) API
# Debian/Ubuntu starting from 18.04
$ sudo apt-get install dpdk-dev
-3.4.2 Built DPDK from src
- git clone --branch=18.11 http://dpdk.org/git/dpdk-stable dpdk
+3.4.2 Build DPDK from source
+ $ git clone --branch=19.11 http://dpdk.org/git/dpdk-stable dpdk
- #Make and edit DPDK configuration
- TARGET="x86_64-native-linuxapp-gcc"
- make config T=${TARGET} O=${TARGET}
- pushd ${TARGET}
+ # Make and edit DPDK configuration
+ $ export TARGET="x86_64-native-linuxapp-gcc"
+ $ make config T=${TARGET} O=${TARGET}
+ $ pushd ${TARGET}
- #To use I/O without DPDK supported NIC's enable pcap pmd:
- sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config
- popd
+ # Enable pcap PMD to use DPDK pktio without supported NICs:
+ $ sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config
+ $ popd
- #Build DPDK
- make build O=${TARGET} EXTRA_CFLAGS="-fPIC"
- make install O=${TARGET} DESTDIR=${TARGET}
+ # Build and install DPDK
+ $ make install T=${TARGET} EXTRA_CFLAGS="-fPIC" DESTDIR=./install
- #compile ODP
- ./configure --with-dpdk-path=<dpdk_install_dir>
+ # Compile ODP
+ $ ./configure --with-dpdk-path=<dpdk_install_dir>
3.4.3 Setup system
@@ -216,9 +215,9 @@ Prerequisites for building the OpenDataPlane (ODP) API
$ cd <dpdk-dir>
$ sudo insmod x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
- Reserve and mount hugepages and bind supported interfaces to DPDK modules
+ Reserve and mount huge pages and bind supported interfaces to DPDK modules
following the DPDK documentation. ODP DPDK packet I/O has been tested with
- 512 x 2MB hugepages. All this can be done with the DPDK setup script
+ 512 x 2MB huge pages. All this can be done with the DPDK setup script
(<dpdk-dir>/usertools/dpdk-setup.sh).
3.4.4 Running ODP with DPDK pktio
diff --git a/Makefile.am b/Makefile.am
index 0cf84a59f..e7b88032b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,12 +21,20 @@ SUBDIRS = \
helper \
doc
+# Tests are run in this SUBDIRS order. The intention is to run validation tests first,
+# then example/performance/platform specific tests.
+if WITH_TESTS
+SUBDIRS += test/common
+SUBDIRS += test/miscellaneous
+SUBDIRS += test/validation
+endif
+
if WITH_EXAMPLES
SUBDIRS += example
endif
if WITH_TESTS
-SUBDIRS += test
+SUBDIRS += test/performance
SUBDIRS += helper/test
SUBDIRS += $(PLATFORM_TEST_DIR)
endif
diff --git a/configure.ac b/configure.ac
index 4ec907bf3..7ce004274 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ AC_PREREQ([2.5])
##########################################################################
m4_define([odpapi_generation_version], [1])
m4_define([odpapi_major_version], [24])
-m4_define([odpapi_minor_version], [1])
+m4_define([odpapi_minor_version], [2])
m4_define([odpapi_point_version], [0])
m4_define([odpapi_version],
[odpapi_generation_version.odpapi_major_version.odpapi_minor_version.odpapi_point_version])
@@ -454,6 +454,7 @@ AC_SUBST([ODP_LIB_NAME])
DX_HTML_FEATURE(ON)
DX_PDF_FEATURE(OFF)
DX_PS_FEATURE(OFF)
+DX_DOT_FEATURE(ON)
DX_ENV_APPEND(WITH_PLATFORM, $with_platform)
DX_INIT_DOXYGEN($PACKAGE_NAME,
diff --git a/doc/Doxyfile_common b/doc/Doxyfile_common
index 19007d02d..29a311491 100644
--- a/doc/Doxyfile_common
+++ b/doc/Doxyfile_common
@@ -17,7 +17,7 @@ QHP_NAMESPACE =
GENERATE_TREEVIEW = YES
PAPER_TYPE = a4
CLASS_DIAGRAMS = NO
-HAVE_DOT = YES
+HAVE_DOT = $(HAVE_DOT)
CALL_GRAPH = YES
DOT_MULTI_TARGETS = NO
EXAMPLE_PATTERNS = *.c
diff --git a/doc/application-api-guide/api_guide_lines.dox b/doc/application-api-guide/api_guide_lines.dox
index 957d525fa..75f5ab01f 100644
--- a/doc/application-api-guide/api_guide_lines.dox
+++ b/doc/application-api-guide/api_guide_lines.dox
@@ -39,7 +39,7 @@ typedef struct odp_<descriptive_name>_s {
} odp_<descriptive_name>_t;
@endcode
-The use of typedef allows implementations to choose underlying data representations that map efficiently to platform capabilities while providing accessor functions to provide structured access to implementation information in a portable manner
+The use of typedef allows implementations to choose underlying data representations that map efficiently to platform capabilities while providing accessor functions to provide structured access to implementation information in a portable manner.
Similarly, the use of enum is RECOMMENDED to provide value abstraction for API parameters while enabling the implementation to choose code points that map well to platform native values.
Several native C types are used conventionally within ODP and SHOULD be employed in API design:
@@ -59,7 +59,7 @@ Minimizing pathlength in API design involves several considerations:
- The number of parameters passed to a call.
In general, ODP APIs designed for frequent use SHOULD have few parameters.
Limiting parameter count to one or two well-chosen parameters SHOULD be the goal for APIs designed for frequent use.
- If a call requires more complex parameter data then it is RECOMMENDED that instead of multiple parameters a single pointer to a struct that can be statically templated and modified by the caller be used.
+ If a call requires more complex parameter data then it is RECOMMENDED that instead of multiple parameters, a single pointer to a struct that can be statically templated and modified by the caller be used.
- The use of macros and inlining.
ODP APIs MAY be implemented as preprocessor macros and/or inline functions.
This is especially true for accessor functions that are designed to provide getters/setters for object meta data.
@@ -85,7 +85,7 @@ Functions must attempt to be so clear in their intent that referencing the docum
@subsection getters Getting information
@subsubsection is_has Is / Has
-An api with "is" or "has" are both considered @ref boolean questions. They can only return true or false and it reflects the current state of something.
+An API with "is" or "has" are both considered @ref boolean questions. They can only return true or false and it reflects the current state of something.
An example might be a packet interface, you might want to know if it is in promiscuous mode.
@code odp_bool_t state = odp_pktio_is_promiscuous(pktio handle) @endcode
@@ -98,10 +98,10 @@ Another case might be if a packet has a vlan flag set
@subsubsection get Get
Where possible returned information should be an enum if it reflects a finite list of information.
-In general get apis drop the actual tag "get" in the function name.
+In general, get APIs drop the actual tag "get" in the function name.
@subsection converter Converter Functions
-To maintain efficiency in fastpath code converter functions should expect correct inputs with undefined results otherwise.
+To maintain efficiency in fastpath code, converter functions should expect correct inputs with undefined results otherwise.
@code
static inline odp_foo_t _odp_foo_from_bar(odp_bar_t bar)
@@ -147,7 +147,7 @@ An example of this might be the number of queues that an application can create.
An attempt to allocate more queues than the underlying implementation supports would result in this failure code being returned via errno.
@subsection boolean Boolean
-For odp all booleans are integers. To aid application readability they are defined as the type odp_bool_t.
+For ODP all booleans are integers. To aid application readability they are defined as the type odp_bool_t.
The values !0 = true, 0 = false are used for this purpose.
@subsection success Success and Failure
@@ -203,6 +203,6 @@ For example an API marked as deprecated in 1.1.0 will still be present in 1.2.0
A deprecated API will contain the doxygen tag \@deprecated with a description of the reason for the change.
@section defaults Default behaviours
-When an API has a default behaviour it must be possible for the application to explicitly call for that behaviour, this guards against the default changing and breaking the application.
+When an API has a default behaviour it must be possible for the application to explicitly call for that behaviour; this guards against the default changing and breaking the application.
*/
diff --git a/doc/application-api-guide/examples.dox b/doc/application-api-guide/examples.dox
index 93491a993..a45c3127e 100644
--- a/doc/application-api-guide/examples.dox
+++ b/doc/application-api-guide/examples.dox
@@ -10,6 +10,11 @@
*/
/**
+ * @example odp_debug.c
+ * Debug example application
+ */
+
+/**
* @example odp_generator.c
* Traffic generator and loopback demo application
*/
@@ -24,16 +29,16 @@
* IPv4 lock-free fragmentation and reassembly example application
*/
- /**
- * @example ipsec/odp_ipsec.c
- * IPsec example application using crypto API
- */
-
/**
* @example ipsec_api/odp_ipsec.c
* IPsec example application using IPsec API
*/
+ /**
+ * @example ipsec_crypto/odp_ipsec.c
+ * IPsec example application using crypto API
+ */
+
/**
* @example ipsec_offload/odp_ipsec_offload.c
* IPsec offload example application
diff --git a/doc/application-api-guide/odp.dox b/doc/application-api-guide/odp.dox
index 08b95de2b..ee328329e 100644
--- a/doc/application-api-guide/odp.dox
+++ b/doc/application-api-guide/odp.dox
@@ -25,9 +25,9 @@
* compiled against a specific ODP implementation layer. The purpose
* of the implementation layer is to provide an optimal mapping of ODP
* APIs to the underlying capabilities (including hardware
- * co-processing and acceleration support) of of SoCs hosting ODP
+ * co-processing and acceleration support) of SoCs hosting ODP
* implementations. As a bootstrapping mechanism for applications, as
- * well as to provide a model for ODP implementers, ODP provides a
+ * well as provide a model for ODP implementers, ODP provides a
* 'linux-generic' reference implementation designed to run on any SoC
* which has a Linux kernel. While linux-generic is not a performance
* target, it does provide a starting point for ODP implementers and
diff --git a/doc/application-api-guide/release.dox b/doc/application-api-guide/release.dox
index 5708a1cbc..3577878c1 100644
--- a/doc/application-api-guide/release.dox
+++ b/doc/application-api-guide/release.dox
@@ -48,7 +48,7 @@ Existing application code shall not have to change if the new API is not used.
- New element to an enum that is an input to ODP
@subsection minor Minor
-The digit is used for backward compatible changes
+The digit is used for backward compatible changes.
Any existing app should work as before.
- Documentation updates
diff --git a/doc/helper-guide/Doxyfile b/doc/helper-guide/Doxyfile
index 26b008efd..52d542e73 100644
--- a/doc/helper-guide/Doxyfile
+++ b/doc/helper-guide/Doxyfile
@@ -22,7 +22,7 @@ QHP_NAMESPACE =
GENERATE_TREEVIEW = YES
PAPER_TYPE = a4
CLASS_DIAGRAMS = NO
-HAVE_DOT = YES
+HAVE_DOT = $(HAVE_DOT)
CALL_GRAPH = YES
DOT_MULTI_TARGETS = NO
EXAMPLE_PATTERNS = *.c
diff --git a/doc/m4/configure.m4 b/doc/m4/configure.m4
index 4abb0129c..8dcb3025e 100644
--- a/doc/m4/configure.m4
+++ b/doc/m4/configure.m4
@@ -1,12 +1,4 @@
##########################################################################
-# Check for doxygen availability
-##########################################################################
-AC_CHECK_PROGS([DOXYGEN], [doxygen])
-if test -z "$DOXYGEN";
- then AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])
-fi
-
-##########################################################################
# Check for asciidoctor availability
##########################################################################
AC_CHECK_PROGS([ASCIIDOCTOR], [asciidoctor])
@@ -15,6 +7,22 @@ if test -z "$ASCIIDOCTOR";
fi
##########################################################################
+# Check for mscgen availability
+##########################################################################
+AC_CHECK_PROGS([MSCGEN], [mscgen])
+if test -z "$MSCGEN";
+ then AC_MSG_WARN([mscgen not found - continuing without sequence message support])
+fi
+
+##########################################################################
+# Check for dot availability
+##########################################################################
+AC_CHECK_PROGS([DOT], [dot])
+if test -z "$DOT";
+ then AC_MSG_WARN([dot not found - continuing without dot graphics support])
+fi
+
+##########################################################################
# Enable/disable user guide generation
##########################################################################
user_guides=no
@@ -24,19 +32,16 @@ AC_ARG_ENABLE([user-guides],
[if test "x$enableval" = "xyes"; then
if test -z "$ASCIIDOCTOR";
then AC_MSG_ERROR([cannot generate user guides without asciidoctor])
- else
- user_guides=yes
fi
+ if test -z "$MSCGEN";
+ then AC_MSG_ERROR([cannot generate user guides without mscgen])
+ fi
+ if test -z "$DOT";
+ then AC_MSG_ERROR([cannot generate user guides without dot])
+ fi
+ user_guides=yes
fi])
-##########################################################################
-# Check for mscgen availability
-##########################################################################
- AC_CHECK_PROGS([MSCGEN], [mscgen])
- if test -z "$MSCGEN";
- then AC_MSG_WARN([mscgen not found - continuing without sequence message support])
- fi
-
AC_CONFIG_FILES([doc/application-api-guide/Makefile
doc/helper-guide/Makefile
doc/implementers-guide/Makefile
diff --git a/example/Makefile.am b/example/Makefile.am
index 26723a9e4..02ef55faf 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -1,8 +1,9 @@
SUBDIRS = classifier \
+ debug \
generator \
hello \
- ipsec \
ipsec_api \
+ ipsec_crypto \
ipsec_offload \
l2fwd_simple \
l3fwd \
diff --git a/example/debug/.gitignore b/example/debug/.gitignore
new file mode 100644
index 000000000..c5f758048
--- /dev/null
+++ b/example/debug/.gitignore
@@ -0,0 +1,3 @@
+odp_debug
+*.log
+*.trs
diff --git a/example/debug/Makefile.am b/example/debug/Makefile.am
new file mode 100644
index 000000000..d6f128af0
--- /dev/null
+++ b/example/debug/Makefile.am
@@ -0,0 +1,9 @@
+include $(top_srcdir)/example/Makefile.inc
+
+bin_PROGRAMS = odp_debug
+
+odp_debug_SOURCES = odp_debug.c
+
+if test_example
+TESTS = odp_debug
+endif
diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c
new file mode 100644
index 000000000..ef9597906
--- /dev/null
+++ b/example/debug/odp_debug.c
@@ -0,0 +1,335 @@
+/* Copyright (c) 2020, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <odp_api.h>
+
+typedef struct test_global_t {
+ int shm;
+ int shm_all;
+ int pool;
+ int queue;
+
+} test_global_t;
+
+static test_global_t test_global;
+
+static void print_usage(void)
+{
+ printf("This example prints out debug information on various ODP objects.\n"
+ "Select debug functions to be called with options. All listed functions\n"
+ "are called when no options are given.\n"
+ "\n"
+ "OPTIONS:\n"
+ " -S, --shm_all Call odp_shm_print_all()\n"
+ " -s, --shm Create a SHM and call odp_shm_print()\n"
+ " -p, --pool Create various types of pools and call odp_pool_print()\n"
+ " -q, --queue Create various types of queues and call odp_queue_print()\n"
+ " -h, --help Display help and exit.\n\n");
+}
+
+static int parse_options(int argc, char *argv[], test_global_t *global)
+{
+ int opt, long_index;
+
+ const struct option longopts[] = {
+ {"shm_all", no_argument, NULL, 'S'},
+ {"shm", no_argument, NULL, 's'},
+ {"pool", no_argument, NULL, 'p'},
+ {"queue", no_argument, NULL, 'q'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+ const char *shortopts = "+Sspqh";
+ int ret = 0;
+
+ while (1) {
+ opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
+
+ if (opt == -1)
+ break; /* No more options */
+
+ switch (opt) {
+ case 'S':
+ global->shm_all = 1;
+ break;
+ case 's':
+ global->shm = 1;
+ break;
+ case 'p':
+ global->pool = 1;
+ break;
+ case 'q':
+ global->queue = 1;
+ break;
+ case 'h':
+ default:
+ print_usage();
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+static int shm_debug(test_global_t *global)
+{
+ const char *name = "debug_shm";
+ odp_shm_t shm = ODP_SHM_INVALID;
+
+ if (global->shm) {
+ shm = odp_shm_reserve(name, 8 * 1024, 64, 0);
+ if (shm == ODP_SHM_INVALID) {
+ printf("SHM reserve failed: %s\n", name);
+ return -1;
+ }
+ }
+
+ if (global->shm_all) {
+ printf("\n");
+ odp_shm_print_all();
+ }
+
+ if (global->shm) {
+ printf("\n");
+ odp_shm_print(shm);
+
+ if (odp_shm_free(shm)) {
+ printf("SHM free failed: %s\n", name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int buffer_debug(odp_pool_t pool)
+{
+ odp_buffer_t buf = odp_buffer_alloc(pool);
+
+ if (buf == ODP_BUFFER_INVALID) {
+ printf("Buffer alloc failed\n");
+ return -1;
+ }
+
+ printf("\n");
+ odp_buffer_print(buf);
+
+ odp_buffer_free(buf);
+
+ return 0;
+}
+
+static int packet_debug(odp_pool_t pool, int len)
+{
+ odp_packet_t pkt = odp_packet_alloc(pool, len);
+
+ if (pkt == ODP_PACKET_INVALID) {
+ printf("Packet alloc failed\n");
+ return -1;
+ }
+
+ printf("\n");
+ odp_packet_print(pkt);
+
+ odp_packet_free(pkt);
+
+ return 0;
+}
+
+static int pool_debug(void)
+{
+ odp_pool_t pool;
+ odp_pool_param_t param;
+ const char *name;
+ int pkt_len = 100;
+
+ name = "debug_buffer_pool";
+ odp_pool_param_init(&param);
+ param.type = ODP_POOL_BUFFER;
+ param.buf.num = 10;
+ param.buf.size = 1000;
+
+ pool = odp_pool_create(name, &param);
+
+ if (pool == ODP_POOL_INVALID) {
+ printf("Pool create failed: %s\n", name);
+ return -1;
+ }
+
+ printf("\n");
+ odp_pool_print(pool);
+
+ if (buffer_debug(pool))
+ return -1;
+
+ if (odp_pool_destroy(pool)) {
+ printf("Pool destroy failed: %s\n", name);
+ return -1;
+ }
+
+ name = "debug_packet_pool";
+ odp_pool_param_init(&param);
+ param.type = ODP_POOL_PACKET;
+ param.pkt.num = 10;
+ param.pkt.len = pkt_len;
+ param.pkt.max_len = 1000;
+
+ pool = odp_pool_create(name, &param);
+
+ if (pool == ODP_POOL_INVALID) {
+ printf("Pool create failed: %s\n", name);
+ return -1;
+ }
+
+ printf("\n");
+ odp_pool_print(pool);
+
+ if (packet_debug(pool, pkt_len))
+ return -1;
+
+ if (odp_pool_destroy(pool)) {
+ printf("Pool destroy failed: %s\n", name);
+ return -1;
+ }
+
+ name = "debug_tmo_pool";
+ odp_pool_param_init(&param);
+ param.type = ODP_POOL_TIMEOUT;
+ param.tmo.num = 10;
+
+ pool = odp_pool_create(name, &param);
+
+ if (pool == ODP_POOL_INVALID) {
+ printf("Pool create failed: %s\n", name);
+ return -1;
+ }
+
+ printf("\n");
+ odp_pool_print(pool);
+
+ if (odp_pool_destroy(pool)) {
+ printf("Pool destroy failed: %s\n", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int queue_debug(void)
+{
+ odp_queue_t queue;
+ odp_queue_param_t param;
+ const char *name;
+
+ name = "debug_plain_queue";
+ odp_queue_param_init(&param);
+ param.type = ODP_QUEUE_TYPE_PLAIN;
+
+ queue = odp_queue_create(name, &param);
+
+ if (queue == ODP_QUEUE_INVALID) {
+ printf("Queue create failed: %s\n", name);
+ return -1;
+ }
+
+ printf("\n");
+ odp_queue_print(queue);
+
+ if (odp_queue_destroy(queue)) {
+ printf("Queue destroy failed: %s\n", name);
+ return -1;
+ }
+
+ /* Configure scheduler before creating any scheduled queues */
+ if (odp_schedule_config(NULL)) {
+ printf("Schedule config failed\n");
+ return -1;
+ }
+
+ name = "debug_sched_queue";
+ odp_queue_param_init(&param);
+ param.type = ODP_QUEUE_TYPE_SCHED;
+
+ queue = odp_queue_create(name, &param);
+
+ if (queue == ODP_QUEUE_INVALID) {
+ printf("Queue create failed: %s\n", name);
+ return -1;
+ }
+
+ printf("\n");
+ odp_queue_print(queue);
+
+ if (odp_queue_destroy(queue)) {
+ printf("Queue destroy failed: %s\n", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ odp_instance_t inst;
+ test_global_t *global = &test_global;
+
+ printf("ODP debug example\n\n");
+ memset(global, 0, sizeof(test_global_t));
+
+ if (argc < 2) {
+ /* If not arguments, run all test cases */
+ global->shm_all = 1;
+ global->shm = 1;
+ global->pool = 1;
+ global->queue = 1;
+ } else {
+ if (parse_options(argc, argv, global))
+ return -1;
+ }
+
+ if (odp_init_global(&inst, NULL, NULL)) {
+ printf("Global init failed.\n");
+ return -1;
+ }
+
+ if (odp_init_local(inst, ODP_THREAD_CONTROL)) {
+ printf("Local init failed.\n");
+ return -1;
+ }
+
+ odp_sys_info_print();
+
+ if ((global->shm_all || global->shm) && shm_debug(global)) {
+ printf("SHM debug failed.\n");
+ return -1;
+ }
+
+ if (global->pool && pool_debug()) {
+ printf("Pool debug failed.\n");
+ return -1;
+ }
+
+ if (global->queue && queue_debug()) {
+ printf("Queue debug failed.\n");
+ return -1;
+ }
+
+ if (odp_term_local()) {
+ printf("Local term failed.\n");
+ return -1;
+ }
+
+ if (odp_term_global(inst)) {
+ printf("Global term failed.\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/example/generator/Makefile.am b/example/generator/Makefile.am
index 112ebbf63..fd32949e2 100644
--- a/example/generator/Makefile.am
+++ b/example/generator/Makefile.am
@@ -11,3 +11,23 @@ TESTS = generator_null_test.sh
TESTS_ENVIRONMENT += ODP_PLATFORM=$(with_platform)
endif
EXTRA_DIST = generator_null_test.sh
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/ipsec/.gitignore b/example/ipsec/.gitignore
deleted file mode 100644
index 5b410d31b..000000000
--- a/example/ipsec/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-odp_ipsec
diff --git a/example/ipsec/Makefile.am b/example/ipsec/Makefile.am
deleted file mode 100644
index f4b150d28..000000000
--- a/example/ipsec/Makefile.am
+++ /dev/null
@@ -1,37 +0,0 @@
-include $(top_srcdir)/example/Makefile.inc
-
-bin_PROGRAMS = odp_ipsec
-
-dist_check_SCRIPTS = \
- odp_ipsec_run_ah_in.sh \
- odp_ipsec_run_ah_out.sh \
- odp_ipsec_run_both_in.sh \
- odp_ipsec_run_both_out.sh \
- odp_ipsec_run_esp_in.sh \
- odp_ipsec_run_esp_out.sh \
- odp_ipsec_run_live.sh \
- odp_ipsec_run_router.sh \
- odp_ipsec_run_simple.sh
-
-odp_ipsec_SOURCES = odp_ipsec.c \
- odp_ipsec_sa_db.c \
- odp_ipsec_sp_db.c \
- odp_ipsec_fwd_db.c \
- odp_ipsec_cache.c \
- odp_ipsec_cache.h \
- odp_ipsec_fwd_db.h \
- odp_ipsec_misc.h \
- odp_ipsec_sa_db.h \
- odp_ipsec_sp_db.h
-
-if WITH_OPENSSL
-odp_ipsec_SOURCES += \
- odp_ipsec_stream.c \
- odp_ipsec_stream.h
-
-AM_CPPFLAGS = $(OPENSSL_CPPFLAGS)
-LDADD += $(OPENSSL_LIBS)
-
-else
-AM_CPPFLAGS = -DNO_OPENSSL
-endif
diff --git a/example/ipsec_api/Makefile.am b/example/ipsec_api/Makefile.am
index 16b1fbfd0..b3621fcd2 100644
--- a/example/ipsec_api/Makefile.am
+++ b/example/ipsec_api/Makefile.am
@@ -38,3 +38,23 @@ LDADD += $(OPENSSL_LIBS)
else
AM_CPPFLAGS = -DNO_OPENSSL
endif
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/ipsec_api/README b/example/ipsec_api/README
new file mode 100644
index 000000000..b391a6bfd
--- /dev/null
+++ b/example/ipsec_api/README
@@ -0,0 +1,157 @@
+Copyright (c) 2014-2018, Linaro Limited
+Copyright (c) 2020, Nokia
+All rights reserved.
+
+SPDX-License-Identifier: BSD-3-Clause
+
+1. Intro
+
+The IPsec API example application "odp_ipsec_api" functions as a simple L3 IPv4
+router which supports IPsec AH and ESP protocols in both transmit and receive
+directions. AH and ESP protocols are not supported simultaneously.
+
+With ESP, the application supports 3DES and NULL encryption algorithms, with
+NULL authentication. With AH, HMAC-MD5 or HMAC-SHA-256 integrity algorithms are
+supported.
+
+2. Prerequisites
+
+ 2.1 SSL development libraries
+
+Development has been done to this point with the openssl-devel libraries,
+the makefile specifically links with "-lcrypto".
+
+3. Topology
+
+The following test topology was used for development. Each of the VMs
+is running Fedora 32. Sanity testing consists of pinging VM2 from VM0
+such that the packets traverse VM1. Packets between VM1 and VM2 are
+IPsec AH or ESP encapsulated.
+
+ VM0 VM1 (UUT) VM2
++------------+ +--------------+ +------------+
+| | (clear) | | (crypto) | |
+| | subnet | | subnet | |
+| p7p1 |<---------------->| p7p1 p8p1 |<---------------->| p7p1 |
+| .2 | 192.168.111.0 | .1 .1 | 192.168.222.0 | .2 |
+| | | | | |
++------------+ +--------------+ +------------+
+
+4. VM configurations
+
+ 4.1 VM0 configuration
+
+VM0 has the following interface configuration:
+
+$ cat /etc/sysconfig/network-scripts/ifcfg-p7p1
+DEVICE=p7p1
+HWADDR=08:00:27:76:B5:E0
+BOOTPROTO=static
+IPADDR=192.168.111.2
+NETMASK=255.255.255.0
+ONBOOT=yes
+
+In addition, static ARP and IPv4 routes must be added on VM0:
+
+$ sudo ip route add 192.168.222.0/24 via 192.168.111.1
+$ sudo arp -s 192.168.111.1 08:00:27:04:BF:8C
+
+ 4.2 VM1 configuration
+
+For the unit under test, IP forwarding and IP tables were disabled.
+
+VM1 has the following interface configurations:
+
+$ cat /etc/sysconfig/network-scripts/ifcfg-p7p1
+DEVICE=p7p1
+HWADDR=08:00:27:04:BF:8C
+BOOTPROTO=static
+IPADDR=192.168.111.1
+NETMASK=255.255.255.0
+ONBOOT=yes
+
+$ cat /etc/sysconfig/network-scripts/ifcfg-p8p1
+DEVICE=p8p1
+HWADDR=08:00:27:4C:55:CC
+BOOTPROTO=static
+IPADDR=192.168.222.1
+NETMASK=255.255.255.0
+ONBOOT=yes
+
+The application is launched on VM1 with the following command:
+
+$ sudo ./odp_ipsec_api -i p7p1,p8p1 \
+-r 192.168.111.2/32:p7p1:08.00.27.76.B5.E0 \
+-r 192.168.222.2/32:p8p1:08.00.27.F5.8B.DB \
+-p 192.168.111.0/24:192.168.222.0/24:out:esp \
+-e 192.168.111.2:192.168.222.2:3des:201:656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
+-p 192.168.222.0/24:192.168.111.0/24:in:esp \
+-e 192.168.222.2:192.168.111.2:3des:301:c966199f24d095f3990a320d749056401e82b26570320292 \
+-c 2 -m 0
+
+ 4.3 VM2 configuration
+
+VM2 has the following interface configuration:
+
+$ cat /etc/sysconfig/network-scripts/ifcfg-p7p1
+DEVICE=p7p1
+HWADDR=08:00:27:F5:8B:DB
+BOOTPROTO=static
+IPADDR=192.168.222.2
+NETMASK=255.255.255.0
+ONBOOT=yes
+
+In addition, static ARP and IPv4 routes must be added on VM2:
+
+$ sudo ip route add 192.168.111.0/24 via 192.168.222.1
+$ sudo arp -s 192.168.222.1 08:00:27:4C:55:CC
+
+VM2 must be setup with an IPsec configuration complementing the configuration
+used by the "odp_ipsec_api" application running on VM1. The configuration is
+applied using "setkey" (provided by ipsec-tools package).
+
+VM2 uses the following setkey configuration:
+
+$ cat setkey_vm2.conf
+# Flush the SAD and SPD
+flush;
+spdflush;
+add 192.168.111.2 192.168.222.2 esp 0x201 -E 3des-cbc
+0x656c8523255ccc23a66c1917aa0cf30991fce83532a4b224;
+add 192.168.222.2 192.168.111.2 esp 0x301 -E 3des-cbc
+0xc966199f24d095f3990a320d749056401e82b26570320292;
+spdadd 192.168.111.2 192.168.222.2 any -P in ipsec esp/transport//require;
+spdadd 192.168.222.2 192.168.111.2 any -P out ipsec esp/transport//require;
+
+Apply the setkey configuration:
+$ sudo setkey -f setkey_vm2.conf
+
+5. Sanity Test with Real Traffic
+
+Once all three VMs have been configured, static ARP and route entries added,
+setkey configuration applied, and odp_ipsec_api application is running, VM0
+should be able to ping VM2 at the 192.168.222.2 address.
+
+At VM0 console issue the ping to VM2's address:
+
+$ sudo ping -c 2 -i 0.1 192.168.222.2
+PING 192.168.222.2 (192.168.222.2) 56(84) bytes of data.
+64 bytes from 192.168.222.2: icmp_seq=1 ttl=64 time=0.614 ms
+64 bytes from 192.168.222.2: icmp_seq=2 ttl=64 time=0.560 ms
+
+At VM2 console use tcpdump to observe IPsec packets:
+
+$ sudo tcpdump -nt -i p7p1
+dropped privs to tcpdump
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on enp0s9, link-type EN10MB (Ethernet), capture size 262144 bytes
+IP 192.168.111.2 > 192.168.222.2: ESP(spi=0x00000201,seq=0x196), length 88
+IP 192.168.222.2 > 192.168.111.2: ESP(spi=0x00000301,seq=0xf4), length 88
+IP 192.168.111.2 > 192.168.222.2: ESP(spi=0x00000201,seq=0x197), length 88
+IP 192.168.222.2 > 192.168.111.2: ESP(spi=0x00000301,seq=0xf5), length 88
+
+6. Standalone Loopback Tests
+
+Bash script files are also included to run several simple loopback tests that
+do not require any packet IO. The scripts create internal "loopback" packet
+interfaces.
diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c
index 3487b27b3..e6a3716be 100644
--- a/example/ipsec_api/odp_ipsec.c
+++ b/example/ipsec_api/odp_ipsec.c
@@ -1237,7 +1237,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
break;
case 'p':
- rc = create_sp_db_entry(optarg);
+ rc = create_sp_db_entry(optarg, FALSE);
break;
case 'a':
@@ -1326,7 +1326,7 @@ static void usage(char *progname)
"\n"
"Routing / IPSec OPTIONS:\n"
" -r, --route SubNet:Intf:NextHopMAC\n"
- " -p, --policy SrcSubNet:DstSubNet:(in|out):(ah|esp|both)\n"
+ " -p, --policy SrcSubNet:DstSubNet:(in|out):(ah|esp)\n"
" -e, --esp SrcIP:DstIP:(3des|null):SPI:Key192\n"
" -a, --ah SrcIP:DstIP:(sha256|md5|null):SPI:Key(256|128)\n"
"\n"
diff --git a/example/ipsec_api/odp_ipsec_api_run_live.sh b/example/ipsec_api/odp_ipsec_api_run_live.sh
index 4a455ba85..3af05d110 100755
--- a/example/ipsec_api/odp_ipsec_api_run_live.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_live.sh
@@ -6,12 +6,10 @@
sudo ./odp_ipsec_api -i p7p1,p8p1 \
-r 192.168.111.2/32:p7p1:08.00.27.76.B5.E0 \
-r 192.168.222.2/32:p8p1:08.00.27.F5.8B.DB \
--p 192.168.111.0/24:192.168.222.0/24:out:both \
+-p 192.168.111.0/24:192.168.222.0/24:out:esp \
-e 192.168.111.2:192.168.222.2:\
3des:201:656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
--a 192.168.111.2:192.168.222.2:md5:200:a731649644c5dee92cbd9c2e7e188ee6 \
--p 192.168.222.0/24:192.168.111.0/24:in:both \
+-p 192.168.222.0/24:192.168.111.0/24:in:esp \
-e 192.168.222.2:192.168.111.2:\
3des:301:c966199f24d095f3990a320d749056401e82b26570320292 \
--a 192.168.222.2:192.168.111.2:md5:300:27f6d123d7077b361662fc6e451f65d8 \
-c 2 "$@"
diff --git a/example/ipsec_api/odp_ipsec_fwd_db.c b/example/ipsec_api/odp_ipsec_fwd_db.c
index 63b0d36d6..aba996aaf 120000
--- a/example/ipsec_api/odp_ipsec_fwd_db.c
+++ b/example/ipsec_api/odp_ipsec_fwd_db.c
@@ -1 +1 @@
-../ipsec/odp_ipsec_fwd_db.c \ No newline at end of file
+../ipsec_crypto/odp_ipsec_fwd_db.c \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_fwd_db.h b/example/ipsec_api/odp_ipsec_fwd_db.h
index 5a709f212..f9a8ab957 120000
--- a/example/ipsec_api/odp_ipsec_fwd_db.h
+++ b/example/ipsec_api/odp_ipsec_fwd_db.h
@@ -1 +1 @@
-../ipsec/odp_ipsec_fwd_db.h \ No newline at end of file
+../ipsec_crypto/odp_ipsec_fwd_db.h \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_misc.h b/example/ipsec_api/odp_ipsec_misc.h
index f1de214a4..7bb7de030 120000
--- a/example/ipsec_api/odp_ipsec_misc.h
+++ b/example/ipsec_api/odp_ipsec_misc.h
@@ -1 +1 @@
-../ipsec/odp_ipsec_misc.h \ No newline at end of file
+../ipsec_crypto/odp_ipsec_misc.h \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_sa_db.c b/example/ipsec_api/odp_ipsec_sa_db.c
index d9c593fa8..7ce1a5292 120000
--- a/example/ipsec_api/odp_ipsec_sa_db.c
+++ b/example/ipsec_api/odp_ipsec_sa_db.c
@@ -1 +1 @@
-../ipsec/odp_ipsec_sa_db.c \ No newline at end of file
+../ipsec_crypto/odp_ipsec_sa_db.c \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_sa_db.h b/example/ipsec_api/odp_ipsec_sa_db.h
index 57d50f3c2..9b022c202 120000
--- a/example/ipsec_api/odp_ipsec_sa_db.h
+++ b/example/ipsec_api/odp_ipsec_sa_db.h
@@ -1 +1 @@
-../ipsec/odp_ipsec_sa_db.h \ No newline at end of file
+../ipsec_crypto/odp_ipsec_sa_db.h \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_sp_db.c b/example/ipsec_api/odp_ipsec_sp_db.c
index c4f785fa6..c7bd160fa 120000
--- a/example/ipsec_api/odp_ipsec_sp_db.c
+++ b/example/ipsec_api/odp_ipsec_sp_db.c
@@ -1 +1 @@
-../ipsec/odp_ipsec_sp_db.c \ No newline at end of file
+../ipsec_crypto/odp_ipsec_sp_db.c \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_sp_db.h b/example/ipsec_api/odp_ipsec_sp_db.h
index e37f78432..26369e9bb 120000
--- a/example/ipsec_api/odp_ipsec_sp_db.h
+++ b/example/ipsec_api/odp_ipsec_sp_db.h
@@ -1 +1 @@
-../ipsec/odp_ipsec_sp_db.h \ No newline at end of file
+../ipsec_crypto/odp_ipsec_sp_db.h \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_stream.c b/example/ipsec_api/odp_ipsec_stream.c
index 4835150d1..57e25fe0e 120000
--- a/example/ipsec_api/odp_ipsec_stream.c
+++ b/example/ipsec_api/odp_ipsec_stream.c
@@ -1 +1 @@
-../ipsec/odp_ipsec_stream.c \ No newline at end of file
+../ipsec_crypto/odp_ipsec_stream.c \ No newline at end of file
diff --git a/example/ipsec_api/odp_ipsec_stream.h b/example/ipsec_api/odp_ipsec_stream.h
index 1cabba28c..6ad6700cc 120000
--- a/example/ipsec_api/odp_ipsec_stream.h
+++ b/example/ipsec_api/odp_ipsec_stream.h
@@ -1 +1 @@
-../ipsec/odp_ipsec_stream.h \ No newline at end of file
+../ipsec_crypto/odp_ipsec_stream.h \ No newline at end of file
diff --git a/example/ipsec_crypto/.gitignore b/example/ipsec_crypto/.gitignore
new file mode 100644
index 000000000..2467edfd4
--- /dev/null
+++ b/example/ipsec_crypto/.gitignore
@@ -0,0 +1 @@
+odp_ipsec_crypto
diff --git a/example/ipsec_crypto/Makefile.am b/example/ipsec_crypto/Makefile.am
new file mode 100644
index 000000000..2e3652252
--- /dev/null
+++ b/example/ipsec_crypto/Makefile.am
@@ -0,0 +1,58 @@
+include $(top_srcdir)/example/Makefile.inc
+
+bin_PROGRAMS = odp_ipsec_crypto
+
+dist_check_SCRIPTS = \
+ odp_ipsec_crypto_run_ah_in.sh \
+ odp_ipsec_crypto_run_ah_out.sh \
+ odp_ipsec_crypto_run_both_in.sh \
+ odp_ipsec_crypto_run_both_out.sh \
+ odp_ipsec_crypto_run_esp_in.sh \
+ odp_ipsec_crypto_run_esp_out.sh \
+ odp_ipsec_crypto_run_live.sh \
+ odp_ipsec_crypto_run_router.sh \
+ odp_ipsec_crypto_run_simple.sh
+
+odp_ipsec_crypto_SOURCES = \
+ odp_ipsec.c \
+ odp_ipsec_sa_db.c \
+ odp_ipsec_sp_db.c \
+ odp_ipsec_fwd_db.c \
+ odp_ipsec_cache.c \
+ odp_ipsec_cache.h \
+ odp_ipsec_fwd_db.h \
+ odp_ipsec_misc.h \
+ odp_ipsec_sa_db.h \
+ odp_ipsec_sp_db.h
+
+if WITH_OPENSSL
+odp_ipsec_crypto_SOURCES += \
+ odp_ipsec_stream.c \
+ odp_ipsec_stream.h
+
+AM_CPPFLAGS = $(OPENSSL_CPPFLAGS)
+LDADD += $(OPENSSL_LIBS)
+
+else
+AM_CPPFLAGS = -DNO_OPENSSL
+endif
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/ipsec/README b/example/ipsec_crypto/README
index da9d6d1f2..9a3fdc4b9 100644
--- a/example/ipsec/README
+++ b/example/ipsec_crypto/README
@@ -5,9 +5,11 @@ SPDX-License-Identifier: BSD-3-Clause
1. Intro
-The IPsec example application "odp_ipsec" functions as a simple L3 IPv4 router
-with support IPsec 3DES cipher and HMAC-MD5 authentication in both the transmit
-and receive directions. Note that only IPsec "transport" mode is supported.
+The odp_ipsec_crypto example application demonstrates an IPsec implementation
+using ODP crypto APIs. The application functions as a simple L3 IPv4 router
+which supports IPsec 3DES cipher and HMAC-MD5 authentication in both the
+transmit and receive directions. Note that only IPsec "transport" mode is
+supported.
2. Prerequisites
@@ -75,7 +77,7 @@ VM1 has the following interface configurations:
The application is launched on VM1 with the following command:
- sudo ./odp_ipsec -i p7p1,p8p1 \
+ sudo ./odp_ipsec_crypto -i p7p1,p8p1 \
-r 192.168.111.2/32:p7p1:08.00.27.76.B5.E0 \
-r 192.168.222.2/32:p8p1:08.00.27.F5.8B.DB \
-p 192.168.111.0/24:192.168.222.0/24:out:both \
@@ -104,7 +106,7 @@ In addition, static ARP and IPv4 routes must be added on VM2:
sudo arp -s 192.168.222.1 08:00:27:4c:55:cc
VM2 must be setup with an IPsec configuration complementing
-the configuration used by the "odp_ipsec" application running
+the configuration used by the "odp_ipsec_crypto" application running
on VM1. The configuration is applied using "setkey" (provided by ipsec-tools
package).
@@ -139,8 +141,8 @@ Apply the setkey configuration:
5. Sanity Test with Real Traffic
Once all three VMs have been configured, static ARP and route entries added,
-setkey configuration applied, and odp_ipsec application is running, VM0 should
-be able to ping VM2 at the 192.168.222.2 address.
+setkey configuration applied, and odp_ipsec_crypto application is running, VM0
+should be able to ping VM2 at the 192.168.222.2 address.
At VM0 console issue the ping to VM2's address:
@@ -165,5 +167,5 @@ At VM2 console use tcpdump to observe IPsec packets:
BASH batch files are now included to run several simple loopback tests that
do not require any packet IO. The scripts create internal "loopback" packet
interfaces.
-Before running the example bash scripts add odp_ipsec to your PATH
-export PATH="<path_to_odp_ipsec>:$PATH"
+Before running the example bash scripts add odp_ipsec_crypto to your PATH
+export PATH="<path_to_odp_ipsec_crypto>:$PATH"
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec_crypto/odp_ipsec.c
index e382bc0e5..c4f34cbfa 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec_crypto/odp_ipsec.c
@@ -1538,7 +1538,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
break;
case 'p':
- rc = create_sp_db_entry(optarg);
+ rc = create_sp_db_entry(optarg, TRUE);
break;
case 'a':
diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec_crypto/odp_ipsec_cache.c
index 044538c59..044538c59 100644
--- a/example/ipsec/odp_ipsec_cache.c
+++ b/example/ipsec_crypto/odp_ipsec_cache.c
diff --git a/example/ipsec/odp_ipsec_cache.h b/example/ipsec_crypto/odp_ipsec_cache.h
index 1523778ff..1523778ff 100644
--- a/example/ipsec/odp_ipsec_cache.h
+++ b/example/ipsec_crypto/odp_ipsec_cache.h
diff --git a/example/ipsec/odp_ipsec_run_ah_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh
index 5ff168760..18045c7e9 100755
--- a/example/ipsec/odp_ipsec_run_ah_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh
@@ -4,7 +4,7 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec -i loop1,loop2 \
+./odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.111.2/32:loop1:08.00.27.76.B5.E0 \
-p 192.168.222.0/24:192.168.111.0/24:in:ah \
-a 192.168.222.2:192.168.111.2:md5:300:27f6d123d7077b361662fc6e451f65d8 \
diff --git a/example/ipsec/odp_ipsec_run_ah_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh
index 53ddd2fb1..8ddfd203d 100755
--- a/example/ipsec/odp_ipsec_run_ah_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh
@@ -4,7 +4,7 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec -i loop1,loop2 \
+./odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.222.2/32:loop2:08.00.27.F5.8B.DB \
-p 192.168.111.0/24:192.168.222.0/24:out:ah \
-a 192.168.111.2:192.168.222.2:md5:200:a731649644c5dee92cbd9c2e7e188ee6 \
diff --git a/example/ipsec/odp_ipsec_run_both_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh
index 502f14a7d..4ad08a784 100755
--- a/example/ipsec/odp_ipsec_run_both_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh
@@ -4,7 +4,7 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec -i loop1,loop2 \
+./odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.111.2/32:loop1:08.00.27.76.B5.E0 \
-p 192.168.222.0/24:192.168.111.0/24:in:both \
-a 192.168.222.2:192.168.111.2:md5:300:27f6d123d7077b361662fc6e451f65d8 \
diff --git a/example/ipsec/odp_ipsec_run_both_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh
index 3086e6f12..a9e3ac8af 100755
--- a/example/ipsec/odp_ipsec_run_both_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh
@@ -4,7 +4,7 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec -i loop1,loop2 \
+./odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.222.2/32:loop2:08.00.27.F5.8B.DB \
-p 192.168.111.0/24:192.168.222.0/24:out:both \
-e 192.168.111.2:192.168.222.2:\
diff --git a/example/ipsec/odp_ipsec_run_esp_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh
index a206cc401..62f73cf7d 100755
--- a/example/ipsec/odp_ipsec_run_esp_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh
@@ -4,7 +4,7 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec -i loop1,loop2 \
+./odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.111.2/32:loop1:08.00.27.76.B5.E0 \
-p 192.168.222.0/24:192.168.111.0/24:in:esp \
-e 192.168.222.2:192.168.111.2:\
diff --git a/example/ipsec/odp_ipsec_run_esp_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh
index f8645f0fb..cd9db1e2a 100755
--- a/example/ipsec/odp_ipsec_run_esp_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh
@@ -9,7 +9,7 @@ if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${IPSEC_EXAMPLE_PATH}/odp_ipsec -i loop1,loop2 \
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.222.2/32:loop2:08.00.27.F5.8B.DB \
-p 192.168.111.0/24:192.168.222.0/24:out:esp \
-e 192.168.111.2:192.168.222.2:\
diff --git a/example/ipsec/odp_ipsec_run_live.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh
index f61d4e38f..e893674bc 100755
--- a/example/ipsec/odp_ipsec_run_live.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh
@@ -3,7 +3,7 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-sudo ./odp_ipsec -i p7p1,p8p1 \
+sudo ./odp_ipsec_crypto -i p7p1,p8p1 \
-r 192.168.111.2/32:p7p1:08.00.27.76.B5.E0 \
-r 192.168.222.2/32:p8p1:08.00.27.F5.8B.DB \
-p 192.168.111.0/24:192.168.222.0/24:out:both \
diff --git a/example/ipsec/odp_ipsec_run_router.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh
index 55ad766f5..920f28e0d 100755
--- a/example/ipsec/odp_ipsec_run_router.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh
@@ -3,7 +3,7 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-sudo ./odp_ipsec -i p7p1,p8p1 \
+sudo ./odp_ipsec_crypto -i p7p1,p8p1 \
-r 192.168.111.2/32:p7p1:08.00.27.76.B5.E0 \
-r 192.168.222.2/32:p8p1:08.00.27.F5.8B.DB \
-c 1 -m $1
diff --git a/example/ipsec/odp_ipsec_run_simple.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh
index 3c3710f5f..3613fe5fd 100755
--- a/example/ipsec/odp_ipsec_run_simple.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh
@@ -9,7 +9,7 @@ if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${IPSEC_EXAMPLE_PATH}/odp_ipsec -i loop1,loop2 \
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i loop1,loop2 \
-r 192.168.222.2/32:loop2:08.00.27.F5.8B.DB \
-s 192.168.111.2:192.168.222.2:loop1:loop2:10:100 \
-c 2 "$@"
diff --git a/example/ipsec/odp_ipsec_fwd_db.c b/example/ipsec_crypto/odp_ipsec_fwd_db.c
index ca0abf6c1..ca0abf6c1 100644
--- a/example/ipsec/odp_ipsec_fwd_db.c
+++ b/example/ipsec_crypto/odp_ipsec_fwd_db.c
diff --git a/example/ipsec/odp_ipsec_fwd_db.h b/example/ipsec_crypto/odp_ipsec_fwd_db.h
index 278259729..278259729 100644
--- a/example/ipsec/odp_ipsec_fwd_db.h
+++ b/example/ipsec_crypto/odp_ipsec_fwd_db.h
diff --git a/example/ipsec/odp_ipsec_misc.h b/example/ipsec_crypto/odp_ipsec_misc.h
index 71d8f63c4..71d8f63c4 100644
--- a/example/ipsec/odp_ipsec_misc.h
+++ b/example/ipsec_crypto/odp_ipsec_misc.h
diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec_crypto/odp_ipsec_sa_db.c
index 9a7c593b3..9a7c593b3 100644
--- a/example/ipsec/odp_ipsec_sa_db.c
+++ b/example/ipsec_crypto/odp_ipsec_sa_db.c
diff --git a/example/ipsec/odp_ipsec_sa_db.h b/example/ipsec_crypto/odp_ipsec_sa_db.h
index 729d98d56..729d98d56 100644
--- a/example/ipsec/odp_ipsec_sa_db.h
+++ b/example/ipsec_crypto/odp_ipsec_sa_db.h
diff --git a/example/ipsec/odp_ipsec_sp_db.c b/example/ipsec_crypto/odp_ipsec_sp_db.c
index 88ac55298..1e5820b47 100644
--- a/example/ipsec/odp_ipsec_sp_db.c
+++ b/example/ipsec_crypto/odp_ipsec_sp_db.c
@@ -43,7 +43,7 @@ void init_sp_db(void)
memset(sp_db, 0, sizeof(*sp_db));
}
-int create_sp_db_entry(char *input)
+int create_sp_db_entry(char *input, odp_bool_t both_supported)
{
int pos = 0;
char *local;
@@ -108,6 +108,13 @@ int create_sp_db_entry(char *input)
pos++;
}
+ /* Check if enabling both AH and ESP protocols is supported */
+ if (!both_supported && (entry->ah && entry->esp)) {
+ printf("ERROR: enabling both AH and ESP is not supported\n");
+ free(local);
+ return -1;
+ }
+
/* Verify we parsed exactly the number of tokens we expected */
if (4 != pos) {
printf("ERROR: \"%s\" contains %d tokens, expected 4\n",
diff --git a/example/ipsec/odp_ipsec_sp_db.h b/example/ipsec_crypto/odp_ipsec_sp_db.h
index ffb52eb87..878f3a7c4 100644
--- a/example/ipsec/odp_ipsec_sp_db.h
+++ b/example/ipsec_crypto/odp_ipsec_sp_db.h
@@ -43,13 +43,14 @@ void init_sp_db(void);
/**
* Create an SP DB entry
*
- * String is of the format "SrcSubNet:DstSubNet:(in|out):(ah|esp|both)"
+ * String is of the format "SrcSubNet:DstSubNet:(in|out):(ah|esp|[both])"
*
- * @param input Pointer to string describing SP
+ * @param input Pointer to a string describing SP
+ * @param both_supported Enabling both AH and ESP is supported
*
* @return 0 if successful else -1
*/
-int create_sp_db_entry(char *input);
+int create_sp_db_entry(char *input, odp_bool_t both_supported);
/**
* Display one SP DB entry
diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec_crypto/odp_ipsec_stream.c
index d689c6198..d689c6198 100644
--- a/example/ipsec/odp_ipsec_stream.c
+++ b/example/ipsec_crypto/odp_ipsec_stream.c
diff --git a/example/ipsec/odp_ipsec_stream.h b/example/ipsec_crypto/odp_ipsec_stream.h
index b32f1d7cb..b32f1d7cb 100644
--- a/example/ipsec/odp_ipsec_stream.h
+++ b/example/ipsec_crypto/odp_ipsec_stream.h
diff --git a/example/l2fwd_simple/.gitignore b/example/l2fwd_simple/.gitignore
index b59fa7e9b..8d15c2726 100644
--- a/example/l2fwd_simple/.gitignore
+++ b/example/l2fwd_simple/.gitignore
@@ -1,3 +1,4 @@
odp_l2fwd_simple
+pktio_env
*.log
*.trs
diff --git a/example/l2fwd_simple/Makefile.am b/example/l2fwd_simple/Makefile.am
index dfde589c2..e23b47881 100644
--- a/example/l2fwd_simple/Makefile.am
+++ b/example/l2fwd_simple/Makefile.am
@@ -10,3 +10,25 @@ TESTS = l2fwd_simple_run.sh
endif
endif
EXTRA_DIST = l2fwd_simple_run.sh udp64.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/l2fwd_simple/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/l2fwd_simple/l2fwd_simple_run.sh b/example/l2fwd_simple/l2fwd_simple_run.sh
index 43c66fe86..b44e10ae1 100755
--- a/example/l2fwd_simple/l2fwd_simple_run.sh
+++ b/example/l2fwd_simple/l2fwd_simple_run.sh
@@ -6,32 +6,17 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-echo "using PCAP_IN = ${PCAP_IN}"
-
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=pcapout.pcap \
---vdev net_pcap1,rx_pcap=${PCAP_IN},tx_pcap=pcapout.pcap"
-
-./odp_l2fwd_simple${EXEEXT} 0 1 \
- 02:00:00:00:00:01 02:00:00:00:00:02 -t 2
-STATUS=$?
-
-if [ "$STATUS" -ne 0 ]; then
- echo "Error: status was: $STATUS, expected 0"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
exit 1
fi
-if [ `stat -c %s pcapout.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
- echo "File sizes disagree"
- exit 1
-fi
-
-rm -f pcapout.pcap
-unset ODP_PLATFORM_PARAMS
+setup_interfaces
-./odp_l2fwd_simple${EXEEXT} null:0 null:1 \
- 02:00:00:00:00:01 02:00:00:00:00:02 -t 2
+./odp_l2fwd_simple${EXEEXT} $IF0 $IF1 02:00:00:00:00:01 02:00:00:00:00:02 -t 2
STATUS=$?
if [ "$STATUS" -ne 0 ]; then
@@ -39,4 +24,8 @@ if [ "$STATUS" -ne 0 ]; then
exit 1
fi
+validate_result
+
+cleanup_interfaces
+
exit 0
diff --git a/example/l3fwd/.gitignore b/example/l3fwd/.gitignore
index 3411830e4..8b9e2355f 100644
--- a/example/l3fwd/.gitignore
+++ b/example/l3fwd/.gitignore
@@ -1,3 +1,4 @@
odp_l3fwd
+pktio_env
*.log
*.trs
diff --git a/example/l3fwd/Makefile.am b/example/l3fwd/Makefile.am
index 483a6381f..dc4fe08b3 100644
--- a/example/l3fwd/Makefile.am
+++ b/example/l3fwd/Makefile.am
@@ -15,3 +15,25 @@ TESTS = odp_l3fwd_run.sh
endif
endif
EXTRA_DIST = odp_l3fwd_run.sh udp64.pcap empty.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/l3fwd/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/l3fwd/odp_l3fwd_run.sh b/example/l3fwd/odp_l3fwd_run.sh
index 2f9c8cc47..33ac2258d 100755
--- a/example/l3fwd/odp_l3fwd_run.sh
+++ b/example/l3fwd/odp_l3fwd_run.sh
@@ -6,28 +6,27 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-PCAP_EMPTY=`find . ${TEST_DIR} $(dirname $0) -name empty.pcap -print -quit`
-PCAP_OUT="pcapout.pcap"
-PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
-echo "using PCAP_IN = ${PCAP_IN}, PCAP_OUT = ${PCAP_OUT}"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=/dev/null \
---vdev net_pcap1,rx_pcap=${PCAP_EMPTY},tx_pcap=${PCAP_OUT}"
+setup_interfaces
-./odp_l3fwd${EXEEXT} -i 0,1 \
- -r "10.0.0.0/24,1" -d 30
+./odp_l3fwd${EXEEXT} -i $IF0,$IF1 -r "10.0.0.0/24,$IF1" -d 30
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 1
fi
-echo "Pass: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+validate_result
+
+cleanup_interfaces
exit 0
diff --git a/example/m4/configure.m4 b/example/m4/configure.m4
index d9a70767b..a3cc1ddbe 100644
--- a/example/m4/configure.m4
+++ b/example/m4/configure.m4
@@ -20,10 +20,11 @@ AC_ARG_ENABLE([test-example],
AM_CONDITIONAL([test_example], [test x$test_example = xyes ])
AC_CONFIG_FILES([example/classifier/Makefile
+ example/debug/Makefile
example/generator/Makefile
example/hello/Makefile
- example/ipsec/Makefile
example/ipsec_api/Makefile
+ example/ipsec_crypto/Makefile
example/ipfragreass/Makefile
example/ipsec_offload/Makefile
example/l2fwd_simple/Makefile
diff --git a/example/packet/.gitignore b/example/packet/.gitignore
index 02752853e..b3869816f 100644
--- a/example/packet/.gitignore
+++ b/example/packet/.gitignore
@@ -1,5 +1,6 @@
odp_packet_dump
odp_pktio
+pktio_env
*.log
*.trs
pcapout.pcap
diff --git a/example/packet/Makefile.am b/example/packet/Makefile.am
index 3682d26d5..5e4d9f5ea 100644
--- a/example/packet/Makefile.am
+++ b/example/packet/Makefile.am
@@ -13,3 +13,25 @@ TESTS = packet_dump_run.sh pktio_run.sh
endif
endif
EXTRA_DIST = packet_dump_run.sh pktio_run.sh udp64.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/packet/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/packet/packet_dump_run.sh b/example/packet/packet_dump_run.sh
index c9994d715..4e7861b1c 100755
--- a/example/packet/packet_dump_run.sh
+++ b/example/packet/packet_dump_run.sh
@@ -6,18 +6,23 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=/dev/null"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
-echo "Packet dump test using PCAP_IN = ${PCAP_IN}"
+setup_interfaces
-./odp_packet_dump${EXEEXT} -i 0 -n 10 -o 0 -l 64
+./odp_packet_dump${EXEEXT} -i $IF0 -n 10 -o 0 -l 64
STATUS=$?
if [ "$STATUS" -ne 0 ]; then
echo "Error: status was: $STATUS, expected 0"
exit 1
fi
+cleanup_interfaces
+
exit 0
diff --git a/example/packet/pktio_run.sh b/example/packet/pktio_run.sh
index caf8649a7..8f9e6f7d3 100755
--- a/example/packet/pktio_run.sh
+++ b/example/packet/pktio_run.sh
@@ -6,60 +6,63 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-PCAP_OUT="pcapout.pcap"
-PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
-echo "using PCAP in=${PCAP_IN}:out=${PCAP_OUT} size %${PCAP_IN_SIZE}"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=${PCAP_OUT}"
+setup_interfaces
# burst mode
-./odp_pktio${EXEEXT} -i 0 -t 5 -m 0
+./odp_pktio${EXEEXT} -i $IF1 -t 5 -m 0
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 1
fi
-echo "Pass -m 0: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+
+validate_result
+echo "Pass -m 0: status ${STATUS}"
# queue mode
-./odp_pktio${EXEEXT} -i 0 -t 5 -m 1
+./odp_pktio${EXEEXT} -i $IF1 -t 5 -m 1
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 2
fi
-echo "Pass -m 1: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+
+validate_result
+echo "Pass -m 1: status ${STATUS}"
# sched/queue mode
-./odp_pktio${EXEEXT} -i 0 -t 5 -m 2
+./odp_pktio${EXEEXT} -i $IF1 -t 5 -m 2
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 3
fi
-echo "Pass -m 2: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+
+validate_result
+echo "Pass -m 2: status ${STATUS}"
# cpu number option test 1
-./odp_pktio${EXEEXT} -i 0 -t 5 -m 0 -c 1
+./odp_pktio${EXEEXT} -i $IF1 -t 5 -m 0 -c 1
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 4
fi
-echo "Pass -m 0 -c 1: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+
+validate_result
+echo "Pass -m 0 -c 1: status ${STATUS}"
+
+cleanup_interfaces
exit 0
diff --git a/example/ping/.gitignore b/example/ping/.gitignore
index 12b2bef41..6222c2866 100644
--- a/example/ping/.gitignore
+++ b/example/ping/.gitignore
@@ -1,4 +1,5 @@
odp_ping
+pktio_env
*.log
*.trs
pcapout.pcap
diff --git a/example/ping/Makefile.am b/example/ping/Makefile.am
index df02d567b..009b0993a 100644
--- a/example/ping/Makefile.am
+++ b/example/ping/Makefile.am
@@ -10,3 +10,25 @@ TESTS = ping_run.sh
endif
endif
EXTRA_DIST = ping_run.sh icmp_echo_req.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/ping/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/ping/ping_run.sh b/example/ping/ping_run.sh
index fd14eac2c..5fa7a649f 100755
--- a/example/ping/ping_run.sh
+++ b/example/ping/ping_run.sh
@@ -6,24 +6,29 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name icmp_echo_req.pcap -print -quit`
-PCAP_OUT="pcapout.pcap"
-PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
-echo "using PCAP in=${PCAP_IN}:out=${PCAP_OUT} size %${PCAP_IN_SIZE}"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=${PCAP_OUT}"
+setup_interfaces
# Ping test with 100 ICMP echo request packets (verbose mode)
-./odp_ping${EXEEXT} -v -n 100 -i0
+./odp_ping${EXEEXT} -v -n 100 -i $IF0
STATUS=$?
-PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
-rm -f ${PCAP_OUT}
-if [ ${STATUS} -ne 0 ] || [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
- echo "Error: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
exit 1
fi
-echo "Pass: status ${STATUS}, in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+
+validate_result
+
+cleanup_interfaces
+
+echo "Pass: status ${STATUS}"
exit 0
diff --git a/example/simple_pipeline/.gitignore b/example/simple_pipeline/.gitignore
index 3b1c20744..28cb24d41 100644
--- a/example/simple_pipeline/.gitignore
+++ b/example/simple_pipeline/.gitignore
@@ -1,3 +1,4 @@
odp_simple_pipeline
+pktio_env
*.log
*.trs
diff --git a/example/simple_pipeline/Makefile.am b/example/simple_pipeline/Makefile.am
index 5a4c523e4..f258434aa 100644
--- a/example/simple_pipeline/Makefile.am
+++ b/example/simple_pipeline/Makefile.am
@@ -10,3 +10,25 @@ TESTS = simple_pipeline_run.sh
endif
endif
EXTRA_DIST = simple_pipeline_run.sh udp64.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/simple_pipeline/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/simple_pipeline/simple_pipeline_run.sh b/example/simple_pipeline/simple_pipeline_run.sh
index 4f81a9bae..7d84df303 100755
--- a/example/simple_pipeline/simple_pipeline_run.sh
+++ b/example/simple_pipeline/simple_pipeline_run.sh
@@ -9,19 +9,22 @@
# Exit code expected by automake for skipped tests
TEST_SKIPPED=77
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-echo "using PCAP_IN = ${PCAP_IN}"
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
if [ $(nproc --all) -lt 3 ]; then
echo "Not enough CPU cores. Skipping test."
exit $TEST_SKIPPED
fi
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=/dev/null \
---vdev net_pcap1,rx_pcap=${PCAP_IN},tx_pcap=pcapout.pcap"
+setup_interfaces
-./odp_simple_pipeline${EXEEXT} -i 0,1 -e -t 2
+./odp_simple_pipeline${EXEEXT} -i $IF0,$IF1 -e -t 2
STATUS=$?
if [ "$STATUS" -ne 0 ]; then
@@ -29,11 +32,8 @@ if [ "$STATUS" -ne 0 ]; then
exit 1
fi
-if [ `stat -c %s pcapout.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
- echo "File sizes disagree"
- exit 1
-fi
+validate_result
-rm -f pcapout.pcap
+cleanup_interfaces
exit 0
diff --git a/example/switch/.gitignore b/example/switch/.gitignore
index 1bd93e32d..63ef8af6e 100644
--- a/example/switch/.gitignore
+++ b/example/switch/.gitignore
@@ -1,3 +1,4 @@
odp_switch
+pktio_env
*.log
*.trs
diff --git a/example/switch/Makefile.am b/example/switch/Makefile.am
index e0d5c4296..66639272d 100644
--- a/example/switch/Makefile.am
+++ b/example/switch/Makefile.am
@@ -10,3 +10,25 @@ TESTS = switch_run.sh
endif
endif
EXTRA_DIST = switch_run.sh udp64.pcap empty.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+ ln -f -s $(top_srcdir)/platform/$(with_platform)/test/example/switch/pktio_env \
+ pktio_env
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/switch/switch_run.sh b/example/switch/switch_run.sh
index de7685fdd..3b6212239 100755
--- a/example/switch/switch_run.sh
+++ b/example/switch/switch_run.sh
@@ -6,39 +6,27 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-NUM_RX_PORT=3
RETVAL=0
-PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
-PCAP_EMPTY=`find . ${TEST_DIR} $(dirname $0) -name empty.pcap -print -quit`
-
-echo "Switch test using PCAP_IN = ${PCAP_IN}"
-
-RX_PORTS=""
-RX_VDEVS=""
-for i in `seq 1 $NUM_RX_PORT`;
-do
- RX_PORTS="${RX_PORTS},${i}"
- RX_VDEVS="${RX_VDEVS} --vdev net_pcap${i},rx_pcap=${PCAP_EMPTY},tx_pcap=pcapout${i}.pcap"
-done
+if [ -f ./pktio_env ]; then
+ . ./pktio_env
+else
+ echo "BUG: unable to find pktio_env!"
+ echo "pktio_env has to be in current directory"
+ exit 1
+fi
-export ODP_PLATFORM_PARAMS="--no-pci \
---vdev net_pcap0,rx_pcap=${PCAP_IN},tx_pcap=/dev/null ${RX_VDEVS}"
+setup_interfaces
-./odp_switch${EXEEXT} -i 0${RX_PORTS} -t 1
+./odp_switch${EXEEXT} -i $IF0,$IF1,$IF2,$IF3 -t 1
STATUS=$?
if [ "$STATUS" -ne 0 ]; then
echo "Error: status was: $STATUS, expected 0"
RETVAL=1
fi
-for i in `seq 1 $NUM_RX_PORT`;
-do
- if [ `stat -c %s pcapout${i}.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
- echo "Error: Output file $i size not matching"
- RETVAL=1
- fi
- rm -f pcapout${i}.pcap
-done
+validate_result
+
+cleanup_interfaces
exit $RETVAL
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index 386c9c221..76bfac8fe 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -40,3 +40,23 @@ table_SOURCES = table.c
iplookuptable_SOURCES = iplookuptable.c
version_SOURCES = version.c
debug_SOURCES = debug.c
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h
index 5fd546484..176c53ff3 100644
--- a/include/odp/api/spec/classification.h
+++ b/include/odp/api/spec/classification.h
@@ -204,6 +204,10 @@ typedef struct odp_cls_capability_t {
/** Supported threshold type for BP */
odp_threshold_types_t threshold_bp;
+
+ /** Maximum value of odp_pmr_create_opt_t::mark */
+ uint64_t max_mark;
+
} odp_cls_capability_t;
/**
@@ -606,6 +610,30 @@ typedef struct odp_pmr_param_t {
} odp_pmr_param_t;
/**
+ * Packet Matching Rule creation options
+ */
+typedef struct odp_pmr_create_opt_t {
+ /** PMR terms
+ *
+ * Array of odp_pmr_param_t entries, one entry per term desired.
+ * Use odp_cls_pmr_param_init() to initialize parameters into their default values.
+ */
+ odp_pmr_param_t *terms;
+
+ /** Number of terms in the match rule. */
+ int num_terms;
+
+ /** Classification mark value
+ *
+ * Value to be set in the CLS mark of a packet when the packet matches this
+ * Packet Matching Rule. The default value is zero. The maximum value is indicated in
+ * odp_cls_capability_t::max_mark capability.
+ */
+ uint64_t mark;
+
+} odp_pmr_create_opt_t;
+
+/**
* Initialize packet matching rule parameters
*
* Initialize an odp_pmr_param_t to its default values for all fields
@@ -615,6 +643,15 @@ typedef struct odp_pmr_param_t {
void odp_cls_pmr_param_init(odp_pmr_param_t *param);
/**
+ * Initialize packet matching rule creation option
+ *
+ * Initialize an odp_pmr_create_opt_t to its default values for all fields
+ *
+ * @param opt Address of the odp_pmr_create_opt_t to be initialized
+ */
+void odp_cls_pmr_create_opt_init(odp_pmr_create_opt_t *opt);
+
+/**
* Create a packet matching rule
*
* Create a packet match rule between source and destination class of service.
@@ -640,11 +677,37 @@ void odp_cls_pmr_param_init(odp_pmr_param_t *param);
*
* @return Handle to the Packet Match Rule.
* @retval ODP_PMR_INVALID on failure
+ *
+ * @note Matching PMR rule created through this function sets the CLS mark metadata
+ * of the packet to zero.
+ *
+ * @note Rules created through this function are equivalent to rules created through
+ * odp_cls_pmr_create_opt() with the same PMR terms and with the additional option
+ * fields set to their default values.
*/
odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
odp_cos_t src_cos, odp_cos_t dst_cos);
/**
+ * Create a packet matching rule with options
+ *
+ * Similar to odp_cls_pmr_create() function with additional PMR creation
+ * options specified through odp_pmr_create_opt_t.
+ *
+ * Use odp_cls_pmr_create_opt_init() to initialize options into their default
+ * values.
+ *
+ * @param opt points to PMR create options
+ * @param src_cos source CoS handle
+ * @param dst_cos destination CoS handle
+ *
+ * @return Handle to the Packet Match Rule.
+ * @retval ODP_PMR_INVALID on failure
+ *
+ */
+odp_pmr_t odp_cls_pmr_create_opt(const odp_pmr_create_opt_t *opt,
+ odp_cos_t src_cos, odp_cos_t dst_cos);
+/**
* Function to destroy a packet match rule
* Destroying a PMR removes the link between the source and destination
* class of service and this PMR will no longer be applied for packets arriving
diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h
index ae96214e2..446d93a51 100644
--- a/include/odp/api/spec/crypto.h
+++ b/include/odp/api/spec/crypto.h
@@ -915,9 +915,12 @@ typedef struct odp_crypto_cipher_capability_t {
* which is not divisible by 8 is unsupported and will result in
* unspecified behaviour.
*
- * Note2: currently data length MUST be divisible by 8. Specifying data
- * which does not consist of full bytes will result in unspecified
- * behaviour.
+ * Note2: If the data length is not a multiple of 8, the remaining
+ * bits of the data in the last byte of the input/output will be the
+ * most significant bits, i.e. the most significant bit is considered
+ * to be the first bit of a byte for the purpose of input and output
+ * data range. The output bits that fall out of the output range are
+ * undefined.
*/
odp_bool_t bit_mode;
@@ -958,6 +961,13 @@ typedef struct odp_crypto_auth_capability_t {
* Note: data buffer MUST start on the byte boundary, using offset
* which is not divisible by 8 is unsupported and will result in
* unpredictable behaviour.
+ *
+ * Note2: If the data length is not a multiple of 8, the remaining
+ * bits of the data in the last byte of the input/output will be the
+ * most significant bits, i.e. the most significant bit is considered
+ * to be the first bit of a byte for the purpose of input and output
+ * data range. The output bits that fall out of the output range are
+ * undefined.
*/
odp_bool_t bit_mode;
diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h
index 604f1cf61..b2dcf28f2 100644
--- a/include/odp/api/spec/packet.h
+++ b/include/odp/api/spec/packet.h
@@ -1990,6 +1990,20 @@ int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt);
*/
void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj);
+/**
+ * Classification mark value
+ *
+ * Get the value of the CLS mark of the packet. The mark value is zero by default, but may be
+ * changed by the classification subsystem.
+ *
+ * @param pkt Packet handle
+ *
+ * @return mark value
+ *
+ * @see odp_cls_capability_t::max_mark, odp_pmr_create_opt_t::mark, odp_cls_pmr_create_opt()
+ */
+uint64_t odp_packet_cls_mark(odp_packet_t pkt);
+
/*
*
* Debugging
diff --git a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
index fd18488fd..1b6f3bc45 100644
--- a/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
+++ b/platform/linux-generic/include/odp/api/plat/packet_inline_types.h
@@ -59,6 +59,7 @@ typedef union {
/* Individual input flags */
struct {
uint64_t dst_queue:1; /* Dst queue present */
+ uint64_t cls_mark: 1; /* Classifier mark value present*/
uint64_t flow_hash:1; /* Flow hash present */
uint64_t timestamp:1; /* Timestamp present */
diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h
index 9ebb2a509..83063a853 100644
--- a/platform/linux-generic/include/odp_classification_datamodel.h
+++ b/platform/linux-generic/include/odp_classification_datamodel.h
@@ -145,14 +145,12 @@ typedef union cos_u {
uint8_t pad[ROUNDUP_CACHE_LINE(sizeof(struct cos_s))];
} cos_t;
-/**
-Packet Matching Rule
-
-**/
+/* Pattern Matching Rule */
struct pmr_s {
uint32_t valid; /* Validity Flag */
odp_atomic_u32_t count; /* num of packets matching this rule */
uint32_t num_pmr; /* num of PMR Term Values*/
+ uint16_t mark;
odp_spinlock_t lock; /* pmr lock*/
cos_t *src_cos; /* source CoS where PMR is attached */
pmr_term_value_t pmr_term_value[CLS_PMRTERM_MAX];
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index ef9b3ba89..83a6fdfed 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -123,6 +123,9 @@ typedef struct odp_packet_hdr_t {
/* Flow hash value */
uint32_t flow_hash;
+ /* Classifier mark */
+ uint16_t cls_mark;
+
union {
struct {
/* Result for crypto packet op */
@@ -198,8 +201,9 @@ static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len)
last->seg_len = seg_len;
}
- pkt_hdr->p.input_flags.all = 0;
- pkt_hdr->p.flags.all_flags = 0;
+ /* Clear all flags. Resets also return value of cls_mark, user_ptr, etc. */
+ pkt_hdr->p.input_flags.all = 0;
+ pkt_hdr->p.flags.all_flags = 0;
pkt_hdr->p.l2_offset = 0;
pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID;
@@ -233,6 +237,7 @@ static inline void copy_packet_cls_metadata(odp_packet_hdr_t *src_hdr,
dst_hdr->dst_queue = src_hdr->dst_queue;
dst_hdr->flow_hash = src_hdr->flow_hash;
dst_hdr->timestamp = src_hdr->timestamp;
+ dst_hdr->cls_mark = src_hdr->cls_mark;
}
static inline void *packet_data(odp_packet_hdr_t *pkt_hdr)
diff --git a/platform/linux-generic/include/odp_pkt_queue_internal.h b/platform/linux-generic/include/odp_pkt_queue_internal.h
index 23eb2b41b..11ac97de1 100644
--- a/platform/linux-generic/include/odp_pkt_queue_internal.h
+++ b/platform/linux-generic/include/odp_pkt_queue_internal.h
@@ -43,6 +43,9 @@ _odp_int_queue_pool_t _odp_queue_pool_create(uint32_t max_num_queues,
_odp_int_pkt_queue_t _odp_pkt_queue_create(_odp_int_queue_pool_t queue_pool);
+void _odp_pkt_queue_destroy(_odp_int_queue_pool_t queue_pool,
+ _odp_int_pkt_queue_t pkt_queue);
+
int _odp_pkt_queue_append(_odp_int_queue_pool_t queue_pool,
_odp_int_pkt_queue_t pkt_queue,
odp_packet_t pkt);
diff --git a/platform/linux-generic/include/odp_traffic_mngr_internal.h b/platform/linux-generic/include/odp_traffic_mngr_internal.h
index 040bb117a..8a65a1685 100644
--- a/platform/linux-generic/include/odp_traffic_mngr_internal.h
+++ b/platform/linux-generic/include/odp_traffic_mngr_internal.h
@@ -372,7 +372,6 @@ struct tm_system_s {
_odp_int_name_t name_tbl_id;
void *trace_buffer;
- uint32_t next_queue_num;
tm_queue_obj_t *queue_num_tbl[ODP_TM_MAX_TM_QUEUES];
input_work_queue_t input_work_queue;
tm_queue_cnts_t priority_queue_cnts;
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index 79b2b9ffa..c084d844b 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -41,6 +41,13 @@ AC_CONFIG_FILES([platform/linux-generic/Makefile
platform/linux-generic/libodp-linux.pc
platform/linux-generic/dumpconfig/Makefile
platform/linux-generic/test/Makefile
+ platform/linux-generic/test/example/Makefile
+ platform/linux-generic/test/example/l2fwd_simple/Makefile
+ platform/linux-generic/test/example/l3fwd/Makefile
+ platform/linux-generic/test/example/packet/Makefile
+ platform/linux-generic/test/example/ping/Makefile
+ platform/linux-generic/test/example/simple_pipeline/Makefile
+ platform/linux-generic/test/example/switch/Makefile
platform/linux-generic/test/validation/api/shmem/Makefile
platform/linux-generic/test/validation/api/pktio/Makefile
platform/linux-generic/test/pktio_ipc/Makefile])
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c
index 8637e611f..1d5384c9e 100644
--- a/platform/linux-generic/odp_classification.c
+++ b/platform/linux-generic/odp_classification.c
@@ -26,8 +26,11 @@
#include <string.h>
#include <errno.h>
#include <stdbool.h>
+#include <inttypes.h>
#include <odp/api/spinlock.h>
+#define MAX_MARK UINT16_MAX
+
#define LOCK(a) odp_spinlock_lock(a)
#define UNLOCK(a) odp_spinlock_unlock(a)
#define LOCK_INIT(a) odp_spinlock_init(a)
@@ -180,9 +183,17 @@ int odp_cls_capability(odp_cls_capability_t *capability)
capability->threshold_red.all_bits = 0;
capability->threshold_bp.all_bits = 0;
capability->max_hash_queues = CLS_COS_QUEUE_MAX;
+ capability->max_mark = MAX_MARK;
return 0;
}
+void odp_cls_pmr_create_opt_init(odp_pmr_create_opt_t *opt)
+{
+ opt->terms = NULL;
+ opt->num_terms = 0;
+ opt->mark = 0;
+}
+
static void _odp_cls_update_hash_proto(cos_t *cos,
odp_pktin_hash_proto_t hash_proto)
{
@@ -692,8 +703,8 @@ no_rule:
return 0;
}
-odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
- odp_cos_t src_cos, odp_cos_t dst_cos)
+static odp_pmr_t cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, uint16_t mark,
+ odp_cos_t src_cos, odp_cos_t dst_cos)
{
pmr_t *pmr;
int i;
@@ -729,6 +740,8 @@ odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
}
}
+ pmr->s.mark = mark;
+
loc = odp_atomic_fetch_inc_u32(&cos_src->s.num_rule);
cos_src->s.pmr[loc] = pmr;
cos_src->s.linked_cos[loc] = cos_dst;
@@ -738,6 +751,28 @@ odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
return id;
}
+odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms,
+ odp_cos_t src_cos, odp_cos_t dst_cos)
+{
+ return cls_pmr_create(terms, num_terms, 0, src_cos, dst_cos);
+}
+
+odp_pmr_t odp_cls_pmr_create_opt(const odp_pmr_create_opt_t *opt,
+ odp_cos_t src_cos, odp_cos_t dst_cos)
+{
+ if (opt == NULL) {
+ ODP_ERR("Bad parameter\n");
+ return ODP_PMR_INVALID;
+ }
+
+ if (opt->mark > MAX_MARK) {
+ ODP_ERR("Too large mark value: %" PRIu64 "\n", opt->mark);
+ return ODP_PMR_INVALID;
+ }
+
+ return cls_pmr_create(opt->terms, opt->num_terms, opt->mark, src_cos, dst_cos);
+}
+
int odp_cls_cos_pool_set(odp_cos_t cos_id, odp_pool_t pool)
{
cos_t *cos;
@@ -1298,6 +1333,13 @@ static cos_t *match_pmr_cos(cos_t *cos, const uint8_t *pkt_addr, pmr_t *pmr,
return NULL;
if (verify_pmr(pmr, pkt_addr, hdr)) {
+ /* PRM matched */
+ hdr->p.input_flags.cls_mark = 0;
+ if (pmr->s.mark) {
+ hdr->p.input_flags.cls_mark = 1;
+ hdr->cls_mark = pmr->s.mark;
+ }
+
/* This gets called recursively. First matching leaf or branch
* is returned. */
num_rule = odp_atomic_load_u32(&cos->s.num_rule);
diff --git a/platform/linux-generic/odp_crypto_null.c b/platform/linux-generic/odp_crypto_null.c
index 8dfac007d..6dd98a2b7 100644
--- a/platform/linux-generic/odp_crypto_null.c
+++ b/platform/linux-generic/odp_crypto_null.c
@@ -530,10 +530,10 @@ int odp_crypto_op(const odp_packet_t pkt_in[],
int i, rc;
odp_crypto_generic_session_t *session;
- session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
- ODP_ASSERT(ODP_CRYPTO_SYNC == session->p.op_mode);
-
for (i = 0; i < num_pkt; i++) {
+ session = (odp_crypto_generic_session_t *)(intptr_t)param[i].session;
+ ODP_ASSERT(ODP_CRYPTO_SYNC == session->p.op_mode);
+
rc = crypto_int(pkt_in[i], &pkt_out[i], &param[i]);
if (rc < 0)
break;
@@ -552,11 +552,11 @@ int odp_crypto_op_enq(const odp_packet_t pkt_in[],
odp_crypto_generic_session_t *session;
int i, rc;
- session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
- ODP_ASSERT(ODP_CRYPTO_ASYNC == session->p.op_mode);
- ODP_ASSERT(ODP_QUEUE_INVALID != session->p.compl_queue);
-
for (i = 0; i < num_pkt; i++) {
+ session = (odp_crypto_generic_session_t *)(intptr_t)param[i].session;
+ ODP_ASSERT(ODP_CRYPTO_ASYNC == session->p.op_mode);
+ ODP_ASSERT(ODP_QUEUE_INVALID != session->p.compl_queue);
+
pkt = pkt_out[i];
rc = crypto_int(pkt_in[i], &pkt, &param[i]);
if (rc < 0)
diff --git a/platform/linux-generic/odp_crypto_openssl.c b/platform/linux-generic/odp_crypto_openssl.c
index 2a8d4fb9b..64984e201 100644
--- a/platform/linux-generic/odp_crypto_openssl.c
+++ b/platform/linux-generic/odp_crypto_openssl.c
@@ -2818,10 +2818,10 @@ int odp_crypto_op(const odp_packet_t pkt_in[],
int i, rc;
odp_crypto_generic_session_t *session;
- session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
- ODP_ASSERT(ODP_CRYPTO_SYNC == session->p.op_mode);
-
for (i = 0; i < num_pkt; i++) {
+ session = (odp_crypto_generic_session_t *)(intptr_t)param[i].session;
+ ODP_ASSERT(ODP_CRYPTO_SYNC == session->p.op_mode);
+
rc = crypto_int(pkt_in[i], &pkt_out[i], &param[i]);
if (rc < 0)
break;
@@ -2840,11 +2840,11 @@ int odp_crypto_op_enq(const odp_packet_t pkt_in[],
odp_crypto_generic_session_t *session;
int i, rc;
- session = (odp_crypto_generic_session_t *)(intptr_t)param->session;
- ODP_ASSERT(ODP_CRYPTO_ASYNC == session->p.op_mode);
- ODP_ASSERT(ODP_QUEUE_INVALID != session->p.compl_queue);
-
for (i = 0; i < num_pkt; i++) {
+ session = (odp_crypto_generic_session_t *)(intptr_t)param[i].session;
+ ODP_ASSERT(ODP_CRYPTO_ASYNC == session->p.op_mode);
+ ODP_ASSERT(ODP_QUEUE_INVALID != session->p.compl_queue);
+
pkt = pkt_out[i];
rc = crypto_int(pkt_in[i], &pkt, &param[i]);
if (rc < 0)
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index 8e34feecd..6b2d03d40 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -1775,7 +1775,7 @@ int _odp_ishm_init_global(const odp_init_t *init)
ishm_ftbl->unused_fragmnts = &ishm_ftbl->fragment[1];
/*
- * We run _odp_ishm_init_local() directely here to give the
+ * We run _odp_ishm_init_local() directly here to give the
* possibility to run shm_reserve() before the odp_init_local()
* is performed for the main thread... Many init_global() functions
* indeed assume the availability of odp_shm_reserve()...:
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 430839be6..e47d3b724 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -1579,6 +1579,8 @@ void odp_packet_print(odp_packet_t pkt)
}
len += snprintf(&str[len], n - len, " flags 0x%" PRIx32 "\n",
hdr->p.flags.all_flags);
+ len += snprintf(&str[len], n - len, " cls_mark %" PRIu64 "\n",
+ odp_packet_cls_mark(pkt));
len += snprintf(&str[len], n - len,
" l2_offset %" PRIu32 "\n", hdr->p.l2_offset);
len += snprintf(&str[len], n - len,
@@ -1718,6 +1720,7 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt)
dsthdr->input = srchdr->input;
dsthdr->dst_queue = srchdr->dst_queue;
+ dsthdr->cls_mark = srchdr->cls_mark;
dsthdr->buf_hdr.user_ptr = srchdr->buf_hdr.user_ptr;
if (dsthdr->buf_hdr.uarea_addr != NULL &&
srchdr->buf_hdr.uarea_addr != NULL) {
@@ -2843,3 +2846,13 @@ odp_proto_l4_type_t odp_packet_l4_type(odp_packet_t pkt)
return ODP_PROTO_L4_TYPE_NONE;
}
+
+uint64_t odp_packet_cls_mark(odp_packet_t pkt)
+{
+ odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt);
+
+ if (pkt_hdr->p.input_flags.cls_mark)
+ return pkt_hdr->cls_mark;
+
+ return 0;
+}
diff --git a/platform/linux-generic/odp_pkt_queue.c b/platform/linux-generic/odp_pkt_queue.c
index edc82803b..556e034f8 100644
--- a/platform/linux-generic/odp_pkt_queue.c
+++ b/platform/linux-generic/odp_pkt_queue.c
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include <odp_api.h>
#include <odp_pkt_queue_internal.h>
+#include <odp_traffic_mngr_internal.h>
#include <odp_debug_internal.h>
#include <odp_macros_internal.h>
@@ -46,6 +47,7 @@ typedef struct {
} queue_region_desc_t;
typedef struct {
+ uint8_t queue_status[ODP_TM_MAX_TM_QUEUES];
uint64_t total_pkt_appends;
uint64_t total_pkt_removes;
uint64_t total_bad_removes;
@@ -55,7 +57,7 @@ typedef struct {
uint32_t free_list_head_idx;
uint32_t max_queue_num;
uint32_t max_queued_pkts;
- uint32_t next_queue_num;
+ uint32_t num_queues;
queue_region_desc_t queue_region_descs[16];
uint32_t *queue_num_tbl;
uint8_t current_region;
@@ -251,7 +253,7 @@ _odp_int_queue_pool_t _odp_queue_pool_create(uint32_t max_num_queues,
pool->max_queue_num = max_num_queues;
pool->max_queued_pkts = max_queued_pkts;
- pool->next_queue_num = 1;
+ pool->num_queues = 0;
pool->min_free_list_size = pool->free_list_size;
pool->peak_free_list_size = pool->free_list_size;
@@ -260,15 +262,35 @@ _odp_int_queue_pool_t _odp_queue_pool_create(uint32_t max_num_queues,
_odp_int_pkt_queue_t _odp_pkt_queue_create(_odp_int_queue_pool_t queue_pool)
{
- queue_pool_t *pool;
- uint32_t queue_num;
+ queue_pool_t *pool = (queue_pool_t *)(uintptr_t)queue_pool;
+ uint32_t i;
- pool = (queue_pool_t *)(uintptr_t)queue_pool;
- queue_num = pool->next_queue_num++;
- if (pool->max_queue_num < queue_num)
+ if (pool->num_queues >= pool->max_queue_num)
return _ODP_INT_PKT_QUEUE_INVALID;
- return (_odp_int_pkt_queue_t)queue_num;
+ for (i = 0; i < pool->max_queue_num; i++) {
+ if (pool->queue_status[i] == TM_STATUS_FREE) {
+ pool->queue_status[i] = TM_STATUS_RESERVED;
+ pool->num_queues++;
+ return (_odp_int_pkt_queue_t)(i + 1);
+ }
+ }
+ return _ODP_INT_PKT_QUEUE_INVALID;
+}
+
+void _odp_pkt_queue_destroy(_odp_int_queue_pool_t queue_pool,
+ _odp_int_pkt_queue_t pkt_queue)
+{
+ queue_pool_t *pool = (queue_pool_t *)(uintptr_t)queue_pool;
+ uint32_t queue_num = (uint32_t)pkt_queue;
+
+ if ((queue_num == 0) || (queue_num > pool->max_queue_num)) {
+ ODP_ERR("Invalid TM packet queue ID\n");
+ return;
+ }
+
+ pool->queue_status[queue_num - 1] = TM_STATUS_FREE;
+ pool->num_queues--;
}
int _odp_pkt_queue_append(_odp_int_queue_pool_t queue_pool,
@@ -390,9 +412,9 @@ void _odp_pkt_queue_stats_print(_odp_int_queue_pool_t queue_pool)
pool = (queue_pool_t *)(uintptr_t)queue_pool;
ODP_PRINT("pkt_queue_stats - queue_pool=0x%" PRIX64 "\n", queue_pool);
- ODP_PRINT(" max_queue_num=%u max_queued_pkts=%u next_queue_num=%u\n",
- pool->max_queue_num, pool->max_queued_pkts,
- pool->next_queue_num);
+ ODP_PRINT(" max_queue_num=%" PRIu32 " max_queued_pkts=%" PRIu32 " "
+ "num_queues=%" PRIu32 "\n", pool->max_queue_num,
+ pool->max_queued_pkts, pool->num_queues);
ODP_PRINT(" total pkt appends=%" PRIu64 " total pkt removes=%" PRIu64
" bad removes=%" PRIu64 "\n",
pool->total_pkt_appends, pool->total_pkt_removes,
diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c
index 278929c99..ebd7d1785 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -367,25 +367,25 @@ static void free_tbl_entry(profile_tbl_t *profile_tbl,
switch (profile_kind) {
case TM_SHAPER_PROFILE:
odp_ticketlock_lock(&profile_tbl->shaper.lock);
- profile_tbl->shaper.profile[idx].status = TM_STATUS_RESERVED;
+ profile_tbl->shaper.profile[idx].status = TM_STATUS_FREE;
odp_ticketlock_unlock(&profile_tbl->shaper.lock);
return;
case TM_SCHED_PROFILE:
odp_ticketlock_lock(&profile_tbl->sched.lock);
- profile_tbl->sched.profile[idx].status = TM_STATUS_RESERVED;
+ profile_tbl->sched.profile[idx].status = TM_STATUS_FREE;
odp_ticketlock_unlock(&profile_tbl->sched.lock);
return;
case TM_THRESHOLD_PROFILE:
odp_ticketlock_lock(&profile_tbl->threshold.lock);
- profile_tbl->threshold.profile[idx].status = TM_STATUS_RESERVED;
+ profile_tbl->threshold.profile[idx].status = TM_STATUS_FREE;
odp_ticketlock_unlock(&profile_tbl->threshold.lock);
return;
case TM_WRED_PROFILE:
odp_ticketlock_lock(&profile_tbl->wred.lock);
- profile_tbl->wred.profile[idx].status = TM_STATUS_RESERVED;
+ profile_tbl->wred.profile[idx].status = TM_STATUS_FREE;
odp_ticketlock_unlock(&profile_tbl->wred.lock);
return;
@@ -2959,7 +2959,6 @@ odp_tm_t odp_tm_create(const char *name,
tm_system_capabilities_set(&tm_system->capabilities,
&tm_system->requirements);
- tm_system->next_queue_num = 1;
tm_system->root_node.is_root_node = true;
tm_init_random_data(&tm_system->tm_random_data);
@@ -3973,7 +3972,7 @@ odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm,
queue_obj->user_context = params->user_context;
queue_obj->priority = params->priority;
queue_obj->tm_idx = tm_system->tm_idx;
- queue_obj->queue_num = tm_system->next_queue_num++;
+ queue_obj->queue_num = (uint32_t)_odp_int_pkt_queue;
queue_obj->_odp_int_pkt_queue = _odp_int_pkt_queue;
queue_obj->pkt = ODP_PACKET_INVALID;
odp_ticketlock_init(&queue_obj->tm_wred_node.tm_wred_node_lock);
@@ -4052,6 +4051,8 @@ int odp_tm_queue_destroy(odp_tm_queue_t tm_queue)
odp_queue_destroy(tm_queue_obj->queue);
odp_ticketlock_lock(&tm_glb->queue_obj.lock);
+ _odp_pkt_queue_destroy(tm_system->_odp_int_queue_pool,
+ tm_queue_obj->_odp_int_pkt_queue);
tm_queue_obj->status = TM_STATUS_FREE;
odp_ticketlock_unlock(&tm_glb->queue_obj.lock);
@@ -4683,7 +4684,7 @@ void odp_tm_stats_print(odp_tm_t odp_tm)
input_work_queue_t *input_work_queue;
tm_queue_obj_t *tm_queue_obj;
tm_system_t *tm_system;
- uint32_t queue_num, max_queue_num;
+ uint32_t queue_num;
tm_system = GET_TM_SYSTEM(odp_tm);
input_work_queue = &tm_system->input_work_queue;
@@ -4706,8 +4707,7 @@ void odp_tm_stats_print(odp_tm_t odp_tm)
_odp_timer_wheel_stats_print(tm_system->_odp_int_timer_wheel);
_odp_sorted_list_stats_print(tm_system->_odp_int_sorted_pool);
- max_queue_num = tm_system->next_queue_num;
- for (queue_num = 1; queue_num < max_queue_num; queue_num++) {
+ for (queue_num = 1; queue_num <= ODP_TM_MAX_TM_QUEUES; queue_num++) {
tm_queue_obj = tm_system->queue_num_tbl[queue_num - 1];
if (tm_queue_obj && tm_queue_obj->pkts_rcvd_cnt != 0)
ODP_PRINT("queue_num=%u priority=%u rcvd=%u enqueued=%u "
diff --git a/platform/linux-generic/test/Makefile.am b/platform/linux-generic/test/Makefile.am
index b025d1331..c32bd274b 100644
--- a/platform/linux-generic/test/Makefile.am
+++ b/platform/linux-generic/test/Makefile.am
@@ -14,16 +14,17 @@ TESTS = validation/api/pktio/pktio_run.sh \
validation/api/pktio/pktio_run_tap.sh \
validation/api/shmem/shmem_linux$(EXEEXT) \
ipsec/ipsec_api_example.sh \
- ipsec/ipsec_example.sh
+ ipsec/ipsec_crypto_example.sh
dist_check_SCRIPTS = ipsec/ipsec_api_example.sh \
- ipsec/ipsec_example.sh
+ ipsec/ipsec_crypto_example.sh
test_SCRIPTS = $(dist_check_SCRIPTS)
SUBDIRS += validation/api/pktio\
validation/api/shmem\
- pktio_ipc
+ pktio_ipc \
+ example
if ODP_PKTIO_PCAP
TESTS += validation/api/pktio/pktio_run_pcap.sh
@@ -62,3 +63,23 @@ if test_installdir
installcheck-local:
$(DESTDIR)/$(testdir)/run-test.sh $(TESTNAME)
endif
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/platform/linux-generic/test/example/Makefile.am b/platform/linux-generic/test/example/Makefile.am
new file mode 100644
index 000000000..2e6a7ce6c
--- /dev/null
+++ b/platform/linux-generic/test/example/Makefile.am
@@ -0,0 +1,7 @@
+SUBDIRS = \
+ l2fwd_simple \
+ l3fwd \
+ packet \
+ ping \
+ simple_pipeline \
+ switch
diff --git a/platform/linux-generic/test/example/l2fwd_simple/Makefile.am b/platform/linux-generic/test/example/l2fwd_simple/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/l2fwd_simple/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/l2fwd_simple/pktio_env b/platform/linux-generic/test/example/l2fwd_simple/pktio_env
new file mode 100644
index 000000000..e1fbe87cc
--- /dev/null
+++ b/platform/linux-generic/test/example/l2fwd_simple/pktio_env
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 <---> IF1
+
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+echo "using PCAP_IN = ${PCAP_IN}"
+
+IF0=pcap:in=${PCAP_IN}
+IF1=pcap:out=pcapout.pcap
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ if [ `stat -c %s pcapout.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
+ echo "File sizes disagree"
+ exit 1
+ fi
+
+ rm -f pcapout.pcap
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1."
+ return 0
+}
diff --git a/platform/linux-generic/test/example/l3fwd/Makefile.am b/platform/linux-generic/test/example/l3fwd/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/l3fwd/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/l3fwd/pktio_env b/platform/linux-generic/test/example/l3fwd/pktio_env
new file mode 100644
index 000000000..a692d79bc
--- /dev/null
+++ b/platform/linux-generic/test/example/l3fwd/pktio_env
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 <---> IF1
+
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+PCAP_OUT="pcapout.pcap"
+PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
+echo "using PCAP_IN = ${PCAP_IN}, PCAP_OUT = ${PCAP_OUT}"
+
+IF0=pcap:in=${PCAP_IN}
+IF1=pcap:out=${PCAP_OUT}
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
+ if [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
+ echo "in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+ exit 1
+ fi
+
+ echo "Pass: in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+ rm -f pcapout.pcap
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1."
+ return 0
+}
diff --git a/platform/linux-generic/test/example/packet/Makefile.am b/platform/linux-generic/test/example/packet/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/packet/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/packet/pktio_env b/platform/linux-generic/test/example/packet/pktio_env
new file mode 100644
index 000000000..4e1914e2e
--- /dev/null
+++ b/platform/linux-generic/test/example/packet/pktio_env
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 <---> IF1
+
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+PCAP_OUT="pcapout.pcap"
+PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
+echo "using PCAP in=${PCAP_IN}:out=${PCAP_OUT} size %${PCAP_IN_SIZE}"
+
+IF0=pcap:in=${PCAP_IN}:loops=10
+IF1=pcap:in=${PCAP_IN}:out=${PCAP_OUT}
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
+ if [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
+ echo "Error: in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+ exit 1
+ fi
+
+ rm -f pcapout.pcap
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1."
+ return 0
+}
diff --git a/platform/linux-generic/test/example/ping/Makefile.am b/platform/linux-generic/test/example/ping/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/ping/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/ping/pktio_env b/platform/linux-generic/test/example/ping/pktio_env
new file mode 100644
index 000000000..90106da9d
--- /dev/null
+++ b/platform/linux-generic/test/example/ping/pktio_env
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 <---> IF1
+
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name icmp_echo_req.pcap -print -quit`
+PCAP_OUT="pcapout.pcap"
+PCAP_IN_SIZE=`stat -c %s ${PCAP_IN}`
+echo "using PCAP in=${PCAP_IN}:out=${PCAP_OUT} size %${PCAP_IN_SIZE}"
+
+IF0=pcap:in=${PCAP_IN}:out=${PCAP_OUT}
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ PCAP_OUT_SIZE=`stat -c %s ${PCAP_OUT}`
+ if [ ${PCAP_IN_SIZE} -ne ${PCAP_OUT_SIZE} ]; then
+ echo "Error: in:${PCAP_IN_SIZE} out:${PCAP_OUT_SIZE}"
+ exit 1
+ fi
+
+ echo "pcap in size:${PCAP_IN_SIZE} pcap out size:${PCAP_OUT_SIZE}"
+ rm -f pcapout.pcap
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1."
+ return 0
+}
diff --git a/platform/linux-generic/test/example/simple_pipeline/Makefile.am b/platform/linux-generic/test/example/simple_pipeline/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/simple_pipeline/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/simple_pipeline/pktio_env b/platform/linux-generic/test/example/simple_pipeline/pktio_env
new file mode 100644
index 000000000..e1fbe87cc
--- /dev/null
+++ b/platform/linux-generic/test/example/simple_pipeline/pktio_env
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 <---> IF1
+
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+echo "using PCAP_IN = ${PCAP_IN}"
+
+IF0=pcap:in=${PCAP_IN}
+IF1=pcap:out=pcapout.pcap
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ if [ `stat -c %s pcapout.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
+ echo "File sizes disagree"
+ exit 1
+ fi
+
+ rm -f pcapout.pcap
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1."
+ return 0
+}
diff --git a/platform/linux-generic/test/example/switch/Makefile.am b/platform/linux-generic/test/example/switch/Makefile.am
new file mode 100644
index 000000000..2ffced539
--- /dev/null
+++ b/platform/linux-generic/test/example/switch/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = pktio_env
diff --git a/platform/linux-generic/test/example/switch/pktio_env b/platform/linux-generic/test/example/switch/pktio_env
new file mode 100644
index 000000000..cbf5c4ddc
--- /dev/null
+++ b/platform/linux-generic/test/example/switch/pktio_env
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Copyright (C) 2020, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# For linux-generic the default behavior is to create two pcap interfaces
+# and one interface uses udp64.pcap to inject traffic. An output pcap file
+# is generated via second interface.
+#
+# Network set-up
+# IF0 |---> IF1
+# |---> IF2
+# |---> IF3
+
+NUM_RX_PORT=3
+PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit`
+echo "Switch test using PCAP_IN = ${PCAP_IN}"
+
+IF0=pcap:in=${PCAP_IN}
+IF1=pcap:out=pcapout1.pcap
+IF2=pcap:out=pcapout2.pcap
+IF3=pcap:out=pcapout3.pcap
+
+if [ "$0" = "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+fi
+
+validate_result()
+{
+ for i in `seq 1 $NUM_RX_PORT`;
+ do
+ if [ `stat -c %s pcapout${i}.pcap` -ne `stat -c %s ${PCAP_IN}` ]; then
+ echo "Error: Output file $i size not matching"
+ fi
+ rm -f pcapout${i}.pcap
+ done
+}
+
+setup_interfaces()
+{
+ echo "pktio: setting up test interfaces $IF0, $IF1, $IF2, $IF3."
+ return 0
+}
+
+cleanup_interfaces()
+{
+ echo "pktio: cleaning up test interfaces $IF0, $IF1, $IF2, $IF3."
+ return 0
+}
diff --git a/platform/linux-generic/test/ipsec/ipsec_example.sh b/platform/linux-generic/test/ipsec/ipsec_crypto_example.sh
index e38350c03..d99fc3bd2 100755
--- a/platform/linux-generic/test/ipsec/ipsec_example.sh
+++ b/platform/linux-generic/test/ipsec/ipsec_crypto_example.sh
@@ -15,16 +15,16 @@ fi
# Absolute path to the example binary. This is needed during distcheck, which
# keeps scripts and binaries in different directories (scripts are not copied
# into the distribution directory).
-export IPSEC_EXAMPLE_PATH=$(pwd)/../../../example/ipsec
+export IPSEC_EXAMPLE_PATH=$(pwd)/../../../example/ipsec_crypto
declare -i RESULT=0
-pushd $(dirname $0)/../../../../example/ipsec
+pushd $(dirname $0)/../../../../example/ipsec_crypto
-./odp_ipsec_run_simple.sh
+./odp_ipsec_crypto_run_simple.sh
RESULT+=$?
-./odp_ipsec_run_esp_out.sh
+./odp_ipsec_crypto_run_esp_out.sh
RESULT+=$?
popd
diff --git a/platform/linux-generic/test/pktio_ipc/Makefile.am b/platform/linux-generic/test/pktio_ipc/Makefile.am
index 4287fbc08..b9623cc76 100644
--- a/platform/linux-generic/test/pktio_ipc/Makefile.am
+++ b/platform/linux-generic/test/pktio_ipc/Makefile.am
@@ -9,3 +9,23 @@ pktio_ipc2_SOURCES = pktio_ipc2.c ipc_common.c ipc_common.h
dist_check_SCRIPTS = pktio_ipc_run.sh
test_SCRIPTS = $(dist_check_SCRIPTS)
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/platform/linux-generic/test/validation/api/pktio/Makefile.am b/platform/linux-generic/test/validation/api/pktio/Makefile.am
index 385700de8..98b8b233d 100644
--- a/platform/linux-generic/test/validation/api/pktio/Makefile.am
+++ b/platform/linux-generic/test/validation/api/pktio/Makefile.am
@@ -13,3 +13,23 @@ dist_check_SCRIPTS += pktio_run_dpdk.sh
endif
test_SCRIPTS = $(dist_check_SCRIPTS)
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/test/Makefile.am b/test/Makefile.am
deleted file mode 100644
index ba13eae88..000000000
--- a/test/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = common validation performance miscellaneous
diff --git a/test/README b/test/README
index b2a9048de..4ef634d53 100644
--- a/test/README
+++ b/test/README
@@ -15,3 +15,8 @@ $ make
$ cd test/<platform_name>
$ make check-valgrind
+To run these tests with gdb, use the following libtool command:
+$ libtool --mode=execute gdb ./<test_name>
+
+Refer to the prerequisites section of the DEPENDENCIES file for how to
+install the libtool package.
diff --git a/test/m4/configure.m4 b/test/m4/configure.m4
index 2d59d8859..67db257b7 100644
--- a/test/m4/configure.m4
+++ b/test/m4/configure.m4
@@ -13,8 +13,7 @@ m4_include([test/m4/miscellaneous.m4])
m4_include([test/m4/performance.m4])
m4_include([test/m4/validation.m4])
-AC_CONFIG_FILES([test/Makefile
- test/common/Makefile
+AC_CONFIG_FILES([test/common/Makefile
test/miscellaneous/Makefile
test/performance/Makefile
test/validation/Makefile
diff --git a/test/performance/Makefile.am b/test/performance/Makefile.am
index 80df4e85e..57e38a2da 100644
--- a/test/performance/Makefile.am
+++ b/test/performance/Makefile.am
@@ -61,3 +61,23 @@ example-generator:
dist_check_SCRIPTS = $(TESTSCRIPTS)
dist_check_DATA = udp64.pcap
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS) $(dist_check_DATA); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(dist_check_SCRIPTS) $(dist_check_DATA); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/test/performance/odp_bench_packet.c b/test/performance/odp_bench_packet.c
index c6798556e..ff7eb2c93 100644
--- a/test/performance/odp_bench_packet.c
+++ b/test/performance/odp_bench_packet.c
@@ -858,7 +858,7 @@ static int bench_packet_extend_head(void)
uint32_t *data_tbl = gbl_args->output_tbl;
for (i = 0; i < TEST_REPEAT_COUNT; i++)
- ret += odp_packet_extend_head(&pkt_tbl[i], len, ptr_tbl[i],
+ ret += odp_packet_extend_head(&pkt_tbl[i], len, &ptr_tbl[i],
&data_tbl[i]);
return ret >= 0;
}
@@ -873,7 +873,7 @@ static int bench_packet_trunc_head(void)
uint32_t *data_tbl = gbl_args->output_tbl;
for (i = 0; i < TEST_REPEAT_COUNT; i++)
- ret += odp_packet_trunc_head(&pkt_tbl[i], len, ptr_tbl[i],
+ ret += odp_packet_trunc_head(&pkt_tbl[i], len, &ptr_tbl[i],
&data_tbl[i]);
return ret >= 0;
}
@@ -888,7 +888,7 @@ static int bench_packet_extend_tail(void)
uint32_t *data_tbl = gbl_args->output_tbl;
for (i = 0; i < TEST_REPEAT_COUNT; i++)
- ret += odp_packet_extend_tail(&pkt_tbl[i], len, ptr_tbl[i],
+ ret += odp_packet_extend_tail(&pkt_tbl[i], len, &ptr_tbl[i],
&data_tbl[i]);
return ret >= 0;
}
@@ -903,7 +903,7 @@ static int bench_packet_trunc_tail(void)
uint32_t *data_tbl = gbl_args->output_tbl;
for (i = 0; i < TEST_REPEAT_COUNT; i++)
- ret += odp_packet_trunc_tail(&pkt_tbl[i], len, ptr_tbl[i],
+ ret += odp_packet_trunc_tail(&pkt_tbl[i], len, &ptr_tbl[i],
&data_tbl[i]);
return ret >= 0;
}
diff --git a/test/performance/odp_crypto.c b/test/performance/odp_crypto.c
index ded97c03e..07463ab68 100644
--- a/test/performance/odp_crypto.c
+++ b/test/performance/odp_crypto.c
@@ -1064,6 +1064,8 @@ int main(int argc, char *argv[])
/* Init this thread */
odp_init_local(instance, ODP_THREAD_WORKER);
+ odp_sys_info_print();
+
if (odp_crypto_capability(&crypto_capa)) {
app_err("Crypto capability request failed.\n");
exit(EXIT_FAILURE);
diff --git a/test/performance/odp_ipsec.c b/test/performance/odp_ipsec.c
index efdef0749..df4e6085e 100644
--- a/test/performance/odp_ipsec.c
+++ b/test/performance/odp_ipsec.c
@@ -1051,6 +1051,8 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ odp_sys_info_print();
+
if (odp_pool_capability(&capa)) {
app_err("Pool capability request failed.\n");
exit(EXIT_FAILURE);
diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 267e74950..6df04e4ab 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -94,6 +94,7 @@ typedef struct {
int pool_per_if; /* Create pool per interface */
uint32_t num_pkt; /* Number of packets per pool */
int verbose; /* Verbose output */
+ int promisc_mode; /* Promiscuous mode enabled */
} appl_args_t;
/* Statistics */
@@ -434,6 +435,22 @@ static int run_worker_sched_mode(void *arg)
stats->s.packets += pkts;
}
+ /*
+ * Free prefetched packets before entering the thread barrier.
+ * Such packets can block sending of later packets in other threads
+ * that then would never enter the thread barrier and we would
+ * end up in a dead-lock.
+ */
+ odp_schedule_pause();
+ while (1) {
+ odp_event_t ev;
+
+ ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
+ if (ev == ODP_EVENT_INVALID)
+ break;
+ odp_event_free(ev);
+ }
+
/* Make sure that latest stat writes are visible to other threads */
odp_mb_full();
@@ -441,6 +458,7 @@ static int run_worker_sched_mode(void *arg)
odp_barrier_wait(&gbl_args->term_barrier);
/* Free remaining events in queues */
+ odp_schedule_resume();
while (1) {
odp_event_t ev;
@@ -774,6 +792,20 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx,
odp_pktio_config(pktio, &config);
+ if (gbl_args->appl.promisc_mode) {
+ if (!pktio_capa.set_op.op.promisc_mode) {
+ ODPH_ERR("Error: promisc mode set not supported %s\n",
+ dev);
+ return -1;
+ }
+
+ /* Enable promisc mode */
+ if (odp_pktio_promisc_mode_set(pktio, true)) {
+ ODPH_ERR("Error: promisc mode enable failed %s\n", dev);
+ return -1;
+ }
+ }
+
odp_pktin_queue_param_init(&pktin_param);
odp_pktout_queue_param_init(&pktout_param);
@@ -1212,6 +1244,7 @@ static void usage(char *progname)
" 1: Create a pool per interface\n"
" -n, --num_pkt <num> Number of packets per pool. Default is 16k or\n"
" the maximum capability. Use 0 for the default.\n"
+ " -P, --promisc_mode Enable promiscuous mode.\n"
" -v, --verbose Verbose output.\n"
" -h, --help Display help and exit.\n\n"
"\n", NO_PATH(progname), NO_PATH(progname), MAX_PKTIOS
@@ -1250,12 +1283,13 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
{"packet_copy", required_argument, NULL, 'p'},
{"pool_per_if", required_argument, NULL, 'y'},
{"num_pkt", required_argument, NULL, 'n'},
+ {"promisc_mode", no_argument, NULL, 'P'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
- static const char *shortopts = "+c:t:a:i:m:o:r:d:s:e:k:g:b:p:y:n:vh";
+ static const char *shortopts = "+c:t:a:i:m:o:r:d:s:e:k:g:b:p:y:n:Pvh";
appl_args->time = 0; /* loop forever if time to run is 0 */
appl_args->accuracy = 1; /* get and print pps stats second */
@@ -1270,6 +1304,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
appl_args->chksum = 0; /* don't use checksum offload by default */
appl_args->pool_per_if = 0;
appl_args->num_pkt = 0;
+ appl_args->promisc_mode = 0;
while (1) {
opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
@@ -1410,6 +1445,9 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args)
case 'n':
appl_args->num_pkt = atoi(optarg);
break;
+ case 'P':
+ appl_args->promisc_mode = 1;
+ break;
case 'v':
appl_args->verbose = 1;
break;
@@ -1486,6 +1524,8 @@ static void print_info(appl_args_t *appl_args)
else
printf("PKTOUT_DIRECT\n");
+ printf("Promisc mode: %s\n", appl_args->promisc_mode ?
+ "enabled" : "disabled");
printf("Burst size: %i\n", appl_args->burst_rx);
printf("Number of pools: %i\n", appl_args->pool_per_if ?
appl_args->if_count : 1);
diff --git a/test/performance/odp_packet_gen.c b/test/performance/odp_packet_gen.c
index e0b540ed2..8184eacad 100644
--- a/test/performance/odp_packet_gen.c
+++ b/test/performance/odp_packet_gen.c
@@ -26,6 +26,10 @@
#define RX_THREAD 1
#define TX_THREAD 2
#define MAX_VLANS 4
+/* Number of random 16-bit words used to generate random length packets */
+#define RAND_16BIT_WORDS 128
+/* Max retries to generate random data */
+#define MAX_RAND_RETRIES 1000
/* Minimum number of packets to receive in CI test */
#define MIN_RX_PACKETS_CI 800
@@ -40,6 +44,10 @@ typedef struct test_options_t {
uint32_t num_pktio;
uint32_t num_pkt;
uint32_t pkt_len;
+ uint8_t use_rand_pkt_len;
+ uint32_t rand_pkt_len_min;
+ uint32_t rand_pkt_len_max;
+ uint32_t rand_pkt_len_bins;
uint32_t hdr_len;
uint32_t burst_size;
uint32_t bursts;
@@ -83,6 +91,7 @@ typedef struct ODP_ALIGNED_CACHE thread_stat_t {
uint64_t tx_timeouts;
uint64_t tx_packets;
+ uint64_t tx_bytes;
uint64_t tx_drops;
int thread_type;
@@ -145,6 +154,14 @@ static void print_usage(void)
" -t, --num_tx Number of transmit threads. Default: 1\n"
" -n, --num_pkt Number of packets in the pool. Default: 1000\n"
" -l, --len Packet length. Default: 512\n"
+ " -L, --len_range <min,max,bins>\n"
+ " Random packet length. Specify the minimum and maximum\n"
+ " packet lengths and the number of bins. To reduce pool size\n"
+ " requirement the length range can be divined into even sized\n"
+ " bins. Min and max size packets are always used and included\n"
+ " into the number of bins (bins >= 2). Bin value of 0 means\n"
+ " that each packet length is used. Comma-separated (no spaces).\n"
+ " Overrides standard packet length option.\n"
" -b, --burst_size Transmit burst size. Default: 8\n"
" -x, --bursts Number of bursts per one transmit round. Default: 1\n"
" -g, --gap Gap between transmit rounds in nsec. Default: 1000000\n"
@@ -156,7 +173,7 @@ static void print_usage(void)
" -p, --udp_dst UDP destination port. Default: 20000\n"
" -c, --c_mode <counts> Counter mode for incrementing UDP port numbers.\n"
" Specify the number of port numbers used starting from\n"
- " udp_src/udp_dst. Comma-serarated (no spaces) list of\n"
+ " udp_src/udp_dst. Comma-separated (no spaces) list of\n"
" count values: <udp_src count>,<udp_dst count>\n"
" Default value: 0,0\n"
" -q, --quit Quit after this many transmit rounds.\n"
@@ -212,7 +229,7 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
{
int opt, i, len, str_len, long_index, udp_port;
unsigned long int count;
- uint32_t min_packets, num_tx_pkt;
+ uint32_t min_packets, num_tx_pkt, pkt_len, val;
char *name, *str, *end;
test_options_t *test_options = &global->test_options;
int ret = 0;
@@ -226,6 +243,7 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
{"num_tx", required_argument, NULL, 't'},
{"num_pkt", required_argument, NULL, 'n'},
{"len", required_argument, NULL, 'l'},
+ {"len_range", required_argument, NULL, 'L'},
{"burst_size", required_argument, NULL, 'b'},
{"bursts", required_argument, NULL, 'x'},
{"gap", required_argument, NULL, 'g'},
@@ -242,13 +260,14 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
{NULL, 0, NULL, 0}
};
- static const char *shortopts = "+i:e:r:t:n:l:b:x:g:v:s:d:o:p:c:q:u:w:h";
+ static const char *shortopts = "+i:e:r:t:n:l:L:b:x:g:v:s:d:o:p:c:q:u:w:h";
test_options->num_pktio = 0;
test_options->num_rx = 1;
test_options->num_tx = 1;
test_options->num_pkt = 1000;
test_options->pkt_len = 512;
+ test_options->use_rand_pkt_len = 0;
test_options->burst_size = 8;
test_options->bursts = 1;
test_options->gap_nsec = 1000000;
@@ -368,6 +387,17 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
case 'l':
test_options->pkt_len = atoi(optarg);
break;
+ case 'L':
+ pkt_len = strtoul(optarg, &end, 0);
+ test_options->rand_pkt_len_min = pkt_len;
+ end++;
+ pkt_len = strtoul(end, &str, 0);
+ test_options->rand_pkt_len_max = pkt_len;
+ str++;
+ val = strtoul(str, NULL, 0);
+ test_options->rand_pkt_len_bins = val;
+ test_options->use_rand_pkt_len = 1;
+ break;
case 'b':
test_options->burst_size = atoi(optarg);
break;
@@ -444,9 +474,37 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
test_options->num_cpu = test_options->num_rx + test_options->num_tx;
+ num_tx_pkt = test_options->burst_size * test_options->bursts;
+ if (test_options->use_rand_pkt_len) {
+ uint32_t pkt_sizes = test_options->rand_pkt_len_max -
+ test_options->rand_pkt_len_min + 1;
+ uint32_t pkt_bins = test_options->rand_pkt_len_bins;
+ uint32_t req_pkts;
+
+ if (test_options->rand_pkt_len_max <= test_options->rand_pkt_len_min) {
+ printf("Error: Bad max packet length\n");
+ ret = -1;
+ }
+ if (pkt_bins == 1) {
+ printf("Error: Invalid bins value\n");
+ ret = -1;
+ }
+ if (pkt_sizes < pkt_bins) {
+ printf("Error: Not enough packet sizes for %" PRIu32 " bins\n", pkt_bins);
+ ret = -1;
+ }
+ if (pkt_bins && num_tx_pkt > pkt_bins && num_tx_pkt % pkt_bins)
+ printf("\nWARNING: Transmit packet count is not evenly divisible into packet length bins.\n\n");
+ else if (!pkt_bins && num_tx_pkt > pkt_sizes && num_tx_pkt % pkt_sizes)
+ printf("\nWARNING: Transmit packet count is not evenly divisible into packet lengths.\n\n");
+
+ req_pkts = pkt_bins ? pkt_bins : pkt_sizes;
+ if (req_pkts > num_tx_pkt)
+ num_tx_pkt = req_pkts;
+ }
+
/* Pool needs to have enough packets for all tx side bursts and
* one rx side burst */
- num_tx_pkt = test_options->burst_size * test_options->bursts;
min_packets = (test_options->num_pktio * test_options->num_tx *
num_tx_pkt) +
(test_options->num_pktio * test_options->num_rx *
@@ -479,9 +537,10 @@ static int parse_options(int argc, char *argv[], test_global_t *global)
(test_options->num_vlan * ODPH_VLANHDR_LEN) +
ODPH_IPV4HDR_LEN + ODPH_UDPHDR_LEN;
- if (test_options->hdr_len >= test_options->pkt_len) {
- printf("Error: Headers do not fit into packet length %u\n",
- test_options->pkt_len);
+ pkt_len = test_options->use_rand_pkt_len ?
+ test_options->rand_pkt_len_min : test_options->pkt_len;
+ if (test_options->hdr_len >= pkt_len) {
+ printf("Error: Headers do not fit into packet length %" PRIu32 "\n", pkt_len);
ret = -1;
}
@@ -555,7 +614,8 @@ static int open_pktios(test_global_t *global)
int num_tx = test_options->num_tx;
uint32_t num_pktio = test_options->num_pktio;
uint32_t num_pkt = test_options->num_pkt;
- uint32_t pkt_len = test_options->pkt_len;
+ uint32_t pkt_len = test_options->use_rand_pkt_len ?
+ test_options->rand_pkt_len_max : test_options->pkt_len;
odp_pktout_queue_t pktout[num_tx];
printf("\nODP packet generator\n");
@@ -564,7 +624,13 @@ static int open_pktios(test_global_t *global)
printf(" num rx threads %u\n", num_rx);
printf(" num tx threads %i\n", num_tx);
printf(" num packets %u\n", num_pkt);
- printf(" packet length %u bytes\n", pkt_len);
+ if (test_options->use_rand_pkt_len)
+ printf(" packet length %u-%u bytes, %u bins\n",
+ test_options->rand_pkt_len_min,
+ test_options->rand_pkt_len_max,
+ test_options->rand_pkt_len_bins);
+ else
+ printf(" packet length %u bytes\n", pkt_len);
printf(" tx burst size %u\n", test_options->burst_size);
printf(" tx bursts %u\n", test_options->bursts);
printf(" tx burst gap %" PRIu64 " nsec\n",
@@ -615,8 +681,7 @@ static int open_pktios(test_global_t *global)
return -1;
}
- if (pool_capa.pkt.max_len &&
- pkt_len > pool_capa.pkt.max_len) {
+ if (pool_capa.pkt.max_len && pkt_len > pool_capa.pkt.max_len) {
printf("Error: Too large packets. Max %u supported length.\n",
pool_capa.pkt.max_len);
return -1;
@@ -1089,23 +1154,70 @@ static int init_packets(test_global_t *global, int pktio,
return 0;
}
+static inline int update_rand_data(uint8_t *data, uint32_t data_len)
+{
+ uint32_t generated = 0;
+ uint32_t retries = 0;
+
+ while (generated < data_len) {
+ int32_t ret = odp_random_data(data, data_len - generated, ODP_RANDOM_BASIC);
+
+ if (odp_unlikely(ret < 0)) {
+ printf("Error: odp_random_data() failed: %" PRId32 "\n", ret);
+ return -1;
+ } else if (odp_unlikely(ret == 0)) {
+ retries++;
+ if (odp_unlikely(retries > MAX_RAND_RETRIES)) {
+ printf("Error: Failed to create random data\n");
+ return -1;
+ }
+ continue;
+ }
+ data += ret;
+ generated += ret;
+ }
+ return 0;
+}
+
static inline int send_burst(odp_pktout_queue_t pktout, odp_packet_t pkt[],
- int burst_size) {
+ int burst_size, odp_bool_t use_rand_len, uint32_t pkts_per_pktio,
+ uint64_t *sent_bytes) {
int i, sent;
+ int ret = 0;
int num = burst_size;
odp_packet_t pkt_ref[burst_size];
+ static __thread int rand_idx = RAND_16BIT_WORDS;
+ static __thread uint16_t rand_data[RAND_16BIT_WORDS];
+ uint64_t bytes_total = 0;
for (i = 0; i < burst_size; i++) {
- pkt_ref[i] = odp_packet_ref_static(pkt[i]);
+ int idx = i;
- if (pkt_ref[i] == ODP_PACKET_INVALID) {
+ if (use_rand_len) {
+ if (rand_idx >= RAND_16BIT_WORDS) {
+ if (odp_unlikely(update_rand_data((uint8_t *)rand_data,
+ RAND_16BIT_WORDS * 2))) {
+ num = i;
+ ret = -1;
+ break;
+ }
+ rand_idx = 0;
+ }
+ idx = rand_data[rand_idx++] % pkts_per_pktio;
+ }
+
+ pkt_ref[i] = odp_packet_ref_static(pkt[idx]);
+ if (odp_unlikely(pkt_ref[i] == ODP_PACKET_INVALID)) {
num = i;
break;
}
+ bytes_total += odp_packet_len(pkt_ref[i]);
}
- if (odp_unlikely(num == 0))
- return 0;
+ if (odp_unlikely(num == 0)) {
+ *sent_bytes = 0;
+ return ret;
+ }
sent = odp_pktout_send(pktout, pkt_ref, num);
@@ -1115,12 +1227,69 @@ static inline int send_burst(odp_pktout_queue_t pktout, odp_packet_t pkt[],
if (odp_unlikely(sent != num)) {
uint32_t num_drop = num - sent;
+ for (i = sent; i < num; i++)
+ bytes_total -= odp_packet_len(pkt_ref[i]);
odp_packet_free_multi(&pkt_ref[sent], num_drop);
}
+ *sent_bytes = bytes_total;
return sent;
}
+static int alloc_test_packets(odp_pool_t pool, odp_packet_t *pkt_tbl, int num_pkt,
+ int pkts_per_pktio, test_options_t *test_options)
+{
+ int num_alloc = 0;
+
+ if (test_options->use_rand_pkt_len) {
+ int i, j;
+ int num_pktio = test_options->num_pktio;
+ uint32_t pkt_bins = test_options->rand_pkt_len_bins;
+ uint32_t pkt_len_min = test_options->rand_pkt_len_min;
+ uint32_t pkt_len_max = test_options->rand_pkt_len_max;
+ uint32_t bin_size = 1;
+
+ if (pkt_bins)
+ bin_size = (pkt_len_max - pkt_len_min + 1) / (pkt_bins - 1);
+
+ for (i = 0; i < num_pktio; i++) {
+ uint32_t cur_bin = 0;
+ uint32_t pkt_len = pkt_len_min;
+
+ for (j = 0; j < pkts_per_pktio; j++) {
+ if (pkt_bins) {
+ if (cur_bin + 1 < pkt_bins) {
+ pkt_len = pkt_len_min + (cur_bin * bin_size);
+ cur_bin++;
+ } else {
+ cur_bin = 0;
+ pkt_len = pkt_len_max;
+ }
+ }
+
+ pkt_tbl[num_alloc] = odp_packet_alloc(pool, pkt_len);
+ if (pkt_tbl[num_alloc] == ODP_PACKET_INVALID) {
+ printf("Error: Alloc of %dB packet failed\n", pkt_len);
+ break;
+ }
+ num_alloc++;
+
+ if (!pkt_bins) {
+ pkt_len++;
+ if (pkt_len > pkt_len_max)
+ pkt_len = pkt_len_min;
+ }
+ }
+ }
+ return num_alloc;
+ }
+ num_alloc = odp_packet_alloc_multi(pool, test_options->pkt_len, pkt_tbl, num_pkt);
+ if (num_alloc != num_pkt)
+ printf("Error: Alloc of %u packets failed\n", num_pkt);
+
+ return num_alloc;
+}
+
static int tx_thread(void *arg)
{
int i, thr, tx_thr, num_alloc;
@@ -1135,36 +1304,47 @@ static int tx_thread(void *arg)
uint64_t gap_nsec = test_options->gap_nsec;
uint64_t quit = test_options->quit;
uint64_t tx_timeouts = 0;
+ uint64_t tx_bytes = 0;
uint64_t tx_packets = 0;
uint64_t tx_drops = 0;
int ret = 0;
int burst_size = test_options->burst_size;
int bursts = test_options->bursts;
uint32_t num_tx = test_options->num_tx;
- uint32_t pkt_len = test_options->pkt_len;
+ odp_bool_t use_rand_len = test_options->use_rand_pkt_len;
int num_pktio = test_options->num_pktio;
- int num_pkt = num_pktio * bursts * burst_size;
+ int num_pkt;
odp_pktout_queue_t pktout[num_pktio];
+ uint32_t pkts_per_pktio = bursts * burst_size;
+
+ if (use_rand_len) {
+ uint32_t pkt_sizes = test_options->rand_pkt_len_max -
+ test_options->rand_pkt_len_min + 1;
+
+ if (test_options->rand_pkt_len_bins)
+ pkt_sizes = test_options->rand_pkt_len_bins;
+ if (pkt_sizes > pkts_per_pktio)
+ pkts_per_pktio = pkt_sizes;
+ }
+ num_pkt = num_pktio * pkts_per_pktio;
+
odp_packet_t pkt[num_pkt];
thr = odp_thread_id();
tx_thr = thread_arg->tx_thr;
global->stat[thr].thread_type = TX_THREAD;
- num_alloc = odp_packet_alloc_multi(pool, pkt_len, pkt, num_pkt);
-
- if (num_alloc != num_pkt) {
- printf("Error: alloc of %u packets failed (%i)\n",
- num_pkt, thr);
+ /* Preallocate test packets */
+ num_alloc = alloc_test_packets(pool, pkt, num_pkt, pkts_per_pktio, test_options);
+ if (num_alloc != num_pkt)
ret = -1;
- }
/* Initialize packets per pktio interface */
for (i = 0; ret == 0 && i < num_pktio; i++) {
- int f = i * bursts * burst_size;
+ int f = i * pkts_per_pktio;
pktout[i] = thread_arg->pktout[i];
- if (init_packets(global, i, &pkt[f], bursts * burst_size, f)) {
+ if (init_packets(global, i, &pkt[f], pkts_per_pktio, f)) {
ret = -1;
break;
}
@@ -1199,12 +1379,14 @@ static int tx_thread(void *arg)
/* Send bursts to each pktio */
for (i = 0; i < num_pktio; i++) {
int sent, j;
- int first = i * bursts * burst_size;
+ int first = i * bursts * pkts_per_pktio;
+ uint64_t sent_bytes;
for (j = 0; j < bursts; j++) {
sent = send_burst(pktout[i],
&pkt[first + j * burst_size],
- burst_size);
+ burst_size, use_rand_len,
+ pkts_per_pktio, &sent_bytes);
if (odp_unlikely(sent < 0)) {
ret = -1;
@@ -1212,6 +1394,7 @@ static int tx_thread(void *arg)
break;
}
+ tx_bytes += sent_bytes;
tx_packets += sent;
if (odp_unlikely(sent < burst_size))
tx_drops += burst_size - sent;
@@ -1232,6 +1415,7 @@ static int tx_thread(void *arg)
/* Update stats */
global->stat[thr].time_nsec = diff_ns;
global->stat[thr].tx_timeouts = tx_timeouts;
+ global->stat[thr].tx_bytes = tx_bytes;
global->stat[thr].tx_packets = tx_packets;
global->stat[thr].tx_drops = tx_drops;
@@ -1358,13 +1542,13 @@ static int print_final_stat(test_global_t *global)
test_options_t *test_options = &global->test_options;
int num_rx = test_options->num_rx;
int num_tx = test_options->num_tx;
- uint32_t pkt_len = test_options->pkt_len;
uint64_t rx_nsec_sum = 0;
uint64_t rx_pkt_sum = 0;
uint64_t rx_byte_sum = 0;
uint64_t rx_tmo_sum = 0;
uint64_t tx_nsec_sum = 0;
uint64_t tx_pkt_sum = 0;
+ uint64_t tx_byte_sum = 0;
uint64_t tx_drop_sum = 0;
uint64_t tx_tmo_sum = 0;
double rx_pkt_per_sec = 0.0;
@@ -1372,6 +1556,7 @@ static int print_final_stat(test_global_t *global)
double rx_pkt_len = 0.0;
double rx_sec = 0.0;
double tx_pkt_per_sec = 0.0;
+ double tx_byte_per_sec = 0.0;
double tx_sec = 0.0;
printf("\nRESULTS PER THREAD\n");
@@ -1423,6 +1608,7 @@ static int print_final_stat(test_global_t *global)
} else if (global->stat[i].thread_type == TX_THREAD) {
tx_tmo_sum += global->stat[i].tx_timeouts;
tx_pkt_sum += global->stat[i].tx_packets;
+ tx_byte_sum += global->stat[i].tx_bytes;
tx_drop_sum += global->stat[i].tx_drops;
tx_nsec_sum += global->stat[i].time_nsec;
}
@@ -1445,12 +1631,15 @@ static int print_final_stat(test_global_t *global)
if (tx_nsec_sum) {
tx_pkt_per_sec = (1000000000.0 * (double)tx_pkt_sum) /
(double)tx_nsec_sum;
+
+ tx_byte_per_sec = 1000000000.0;
+ tx_byte_per_sec *= (tx_byte_sum + 24 * tx_pkt_sum);
+ tx_byte_per_sec /= (double)tx_nsec_sum;
}
/* Total Mbit/s */
rx_mbit_per_sec = (num_rx * 8 * rx_byte_per_sec) / 1000000.0;
- tx_mbit_per_sec = (num_tx * 8 * tx_pkt_per_sec * (pkt_len + 24))
- / 1000000.0;
+ tx_mbit_per_sec = (num_tx * 8 * tx_byte_per_sec) / 1000000.0;
if (rx_pkt_sum)
rx_pkt_len = (double)rx_byte_sum / rx_pkt_sum;
@@ -1514,13 +1703,13 @@ int main(int argc, char **argv)
/* Init ODP before calling anything else */
if (odp_init_global(&instance, &init, NULL)) {
printf("Error: Global init failed.\n");
- return -1;
+ return 1;
}
/* Init this thread */
if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
printf("Error: Local init failed.\n");
- return -1;
+ return 1;
}
shm = odp_shm_reserve("packet_gen_global", sizeof(test_global_t),
@@ -1528,7 +1717,7 @@ int main(int argc, char **argv)
if (shm == ODP_SHM_INVALID) {
printf("Error: SHM reserve failed.\n");
- return -1;
+ return 1;
}
global = odp_shm_addr(shm);
@@ -1541,24 +1730,26 @@ int main(int argc, char **argv)
global->thread_arg[i].global = global;
if (parse_options(argc, argv, global)) {
- ret = -1;
+ ret = 1;
goto term;
}
+ odp_sys_info_print();
+
odp_schedule_config(NULL);
if (set_num_cpu(global)) {
- ret = -1;
+ ret = 1;
goto term;
}
if (open_pktios(global)) {
- ret = -1;
+ ret = 1;
goto term;
}
if (start_pktios(global)) {
- ret = -1;
+ ret = 1;
goto term;
}
@@ -1577,30 +1768,30 @@ int main(int argc, char **argv)
global->test_options.num_cpu);
if (stop_pktios(global))
- ret = -1;
+ ret = 1;
drain_queues(global);
if (close_pktios(global))
- ret = -1;
+ ret = 1;
if (print_final_stat(global))
- ret = -2;
+ ret = 2;
term:
if (odp_shm_free(shm)) {
printf("Error: SHM free failed.\n");
- return -1;
+ return 1;
}
if (odp_term_local()) {
printf("Error: term local failed.\n");
- return -1;
+ return 1;
}
if (odp_term_global(instance)) {
printf("Error: term global failed.\n");
- return -1;
+ return 1;
}
return ret;
diff --git a/test/performance/odp_packet_gen_run.sh b/test/performance/odp_packet_gen_run.sh
index d743742d1..f7dc0aa09 100755
--- a/test/performance/odp_packet_gen_run.sh
+++ b/test/performance/odp_packet_gen_run.sh
@@ -52,15 +52,30 @@ run_packet_gen()
# Runs 500 * 10ms = 5 sec
# Sends 500 packets through both interfaces => total 1000 packets
+
+ # Static packet length
odp_packet_gen${EXEEXT} -i 0,1 -b 1 -g 10000000 -q 500 -w 10
+ ret=$?
+ if [ $ret -eq 2 ]; then
+ echo "FAIL: too few packets received"
+ fi
+ if [ $ret -ne 0 ]; then
+ echo "FAIL: test failed: $ret"
+ cleanup_pktio_env
+ exit $ret
+ fi
+
+ # Random packet length
+ odp_packet_gen${EXEEXT} -i 0,1 -b 1 -g 10000000 -q 500 -L 60,1514,10 -w 10
ret=$?
- if [ $ret -eq -1 ]; then
- echo "FAIL: test failed"
- elif [ $ret -eq -2 ]; then
+ if [ $ret -eq 2 ]; then
echo "FAIL: too few packets received"
fi
+ if [ $ret -ne 0 ]; then
+ echo "FAIL: test failed: $ret"
+ fi
cleanup_pktio_env
diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c
index 3418f62f4..35c5a4176 100644
--- a/test/performance/odp_pktio_perf.c
+++ b/test/performance/odp_pktio_perf.c
@@ -1058,6 +1058,8 @@ int main(int argc, char **argv)
if (odp_init_local(instance, ODP_THREAD_CONTROL) != 0)
ODPH_ABORT("Failed local init.\n");
+ odp_sys_info_print();
+
shm = odp_shm_reserve("test_globals",
sizeof(test_globals_t), ODP_CACHE_LINE_SIZE, 0);
if (shm == ODP_SHM_INVALID)
diff --git a/test/performance/odp_pool_perf.c b/test/performance/odp_pool_perf.c
index 85dd4ba12..28471875c 100644
--- a/test/performance/odp_pool_perf.c
+++ b/test/performance/odp_pool_perf.c
@@ -547,6 +547,8 @@ int main(int argc, char **argv)
return -1;
}
+ odp_sys_info_print();
+
if (set_num_cpu(global))
return -1;
diff --git a/test/performance/odp_queue_perf.c b/test/performance/odp_queue_perf.c
index 893861688..036cfc1ea 100644
--- a/test/performance/odp_queue_perf.c
+++ b/test/performance/odp_queue_perf.c
@@ -513,7 +513,7 @@ static void print_stat(test_global_t *global)
printf("------------------------------------------\n");
printf(" duration: %.3f msec\n", nsec_ave / 1000000);
printf(" num cycles: %.3f M\n", cycles_ave / 1000000);
- printf(" evenst per dequeue: %.3f\n",
+ printf(" events per dequeue: %.3f\n",
events_ave / rounds_ave);
printf(" cycles per event: %.3f\n",
cycles_ave / events_ave);
@@ -560,6 +560,8 @@ int main(int argc, char **argv)
if (parse_options(argc, argv, &global->options))
return -1;
+ odp_sys_info_print();
+
global->instance = instance;
if (create_queues(global)) {
diff --git a/test/performance/odp_sched_perf.c b/test/performance/odp_sched_perf.c
index f35a9bd90..29f6e4ac1 100644
--- a/test/performance/odp_sched_perf.c
+++ b/test/performance/odp_sched_perf.c
@@ -1114,6 +1114,8 @@ int main(int argc, char **argv)
return -1;
}
+ odp_sys_info_print();
+
if (global->test_options.ctx_size) {
uint64_t size = global->test_options.ctx_size *
global->test_options.tot_queue;
diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c
index 7834d4e56..443c53a2b 100644
--- a/test/performance/odp_timer_perf.c
+++ b/test/performance/odp_timer_perf.c
@@ -704,6 +704,8 @@ int main(int argc, char **argv)
return -1;
}
+ odp_sys_info_print();
+
odp_schedule_config(NULL);
if (set_num_cpu(global))
diff --git a/test/validation/api/classification/odp_classification_common.c b/test/validation/api/classification/odp_classification_common.c
index 28d762f65..bb5d94ff1 100644
--- a/test/validation/api/classification/odp_classification_common.c
+++ b/test/validation/api/classification/odp_classification_common.c
@@ -253,7 +253,6 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
uint16_t l3_hdr_len = 0;
uint16_t l4_hdr_len = 0;
uint16_t eth_type;
- odp_u16be_t *vlan_type;
odph_vlanhdr_t *vlan_hdr;
uint8_t src_mac[] = CLS_DEFAULT_SMAC;
uint8_t dst_mac[] = CLS_DEFAULT_DMAC;
@@ -282,23 +281,24 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN);
memcpy(ethhdr->dst.addr, &dst_mac, ODPH_ETHADDR_LEN);
- vlan_type = (odp_u16be_t *)(void *)&ethhdr->type;
vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1);
- if (pkt_info.vlan_qinq) {
- odp_packet_has_vlan_qinq_set(pkt, 1);
- *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN_OUTER);
- vlan_hdr->tci = odp_cpu_to_be_16(0);
- vlan_type = (uint16_t *)(void *)&vlan_hdr->type;
- vlan_hdr++;
- }
if (pkt_info.vlan) {
+ if (pkt_info.vlan_qinq) {
+ odp_packet_has_vlan_qinq_set(pkt, 1);
+ ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN_OUTER);
+ vlan_hdr->tci = odp_cpu_to_be_16(0);
+ vlan_hdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
+ vlan_hdr++;
+ } else {
+ ethhdr->type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
+ }
/* Default vlan header */
odp_packet_has_vlan_set(pkt, 1);
- *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN);
vlan_hdr->tci = odp_cpu_to_be_16(0);
vlan_hdr->type = odp_cpu_to_be_16(eth_type);
} else {
+ CU_ASSERT_FATAL(!pkt_info.vlan_qinq);
ethhdr->type = odp_cpu_to_be_16(eth_type);
}
@@ -316,11 +316,13 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
ip->src_addr = odp_cpu_to_be_32(addr);
ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN;
ip->id = odp_cpu_to_be_16(seqno);
- odph_ipv4_csum_update(pkt);
ip->proto = next_hdr;
ip->tot_len = odp_cpu_to_be_16(l3_len);
ip->ttl = DEFAULT_TTL;
+ ip->frag_offset = 0;
+ ip->tos = 0;
odp_packet_has_ipv4_set(pkt, 1);
+ odph_ipv4_csum_update(pkt);
} else {
/* ipv6 */
odp_packet_has_ipv6_set(pkt, 1);
@@ -357,7 +359,13 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info)
} else {
tcp->src_port = odp_cpu_to_be_16(CLS_DEFAULT_SPORT);
tcp->dst_port = odp_cpu_to_be_16(CLS_DEFAULT_DPORT);
+ tcp->doffset_flags = 0;
+ tcp->seq_no = 0;
+ tcp->ack_no = 0;
+ tcp->window = 0;
+ tcp->urgptr = 0;
tcp->hl = ODPH_TCPHDR_LEN / 4;
+ tcp->ack = 1;
tcp->cksm = 0;
odp_packet_has_tcp_set(pkt, 1);
if (odph_udp_tcp_chksum(pkt, ODPH_CHKSUM_GENERATE, NULL) != 0) {
diff --git a/test/validation/api/classification/odp_classification_test_pmr.c b/test/validation/api/classification/odp_classification_test_pmr.c
index 97d1084b7..b5a68058f 100644
--- a/test/validation/api/classification/odp_classification_test_pmr.c
+++ b/test/validation/api/classification/odp_classification_test_pmr.c
@@ -9,6 +9,10 @@
#include "classification.h"
#include <odp_cunit_common.h>
+#define MAX_NUM_UDP 4
+#define MARK_IP 1
+#define MARK_UDP 2
+
static odp_pool_t pkt_pool;
/** sequence number of IP packets */
static odp_atomic_u32_t seq;
@@ -2176,7 +2180,7 @@ static void test_pmr_term_custom(int custom_l3)
* dst IP dst UDP[0 ... 3]
* default_cos -> cos_ip -> cos_udp[0 ... 3]
*/
-static void test_pmr_series(const int num_udp)
+static void test_pmr_series(const int num_udp, int marking)
{
odp_packet_t pkt;
uint32_t seqno;
@@ -2196,6 +2200,7 @@ static void test_pmr_series(const int num_udp)
uint32_t dst_mask;
odp_pmr_param_t pmr_param;
odp_cls_cos_param_t cls_param;
+ odp_pmr_create_opt_t create_opt;
odph_ethhdr_t *eth;
odph_ipv4hdr_t *ip;
odph_udphdr_t *udp;
@@ -2237,7 +2242,17 @@ static void test_pmr_series(const int num_udp)
pmr_param.val_sz = sizeof(dst_addr_be);
pmr_param.offset = 0;
- pmr_ip = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos_ip);
+ if (marking) {
+ odp_cls_pmr_create_opt_init(&create_opt);
+ create_opt.terms = &pmr_param;
+ create_opt.num_terms = 1;
+ create_opt.mark = MARK_IP;
+
+ pmr_ip = odp_cls_pmr_create_opt(&create_opt, default_cos, cos_ip);
+ } else {
+ pmr_ip = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos_ip);
+ }
+
CU_ASSERT_FATAL(pmr_ip != ODP_PMR_INVALID);
/* Dest UDP port */
@@ -2265,8 +2280,17 @@ static void test_pmr_series(const int num_udp)
pmr_param.val_sz = 2;
pmr_param.offset = 0;
- pmr_udp[i] = odp_cls_pmr_create(&pmr_param, 1,
- cos_ip, cos_udp[i]);
+ if (marking) {
+ odp_cls_pmr_create_opt_init(&create_opt);
+ create_opt.terms = &pmr_param;
+ create_opt.num_terms = 1;
+ create_opt.mark = MARK_UDP + i;
+
+ pmr_udp[i] = odp_cls_pmr_create_opt(&create_opt, cos_ip, cos_udp[i]);
+ } else {
+ pmr_udp[i] = odp_cls_pmr_create(&pmr_param, 1, cos_ip, cos_udp[i]);
+ }
+
CU_ASSERT_FATAL(pmr_udp[i] != ODP_PMR_INVALID);
}
@@ -2283,6 +2307,7 @@ static void test_pmr_series(const int num_udp)
odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
ip->dst_addr = dst_addr_be;
+ odph_ipv4_csum_update(pkt);
seqno = cls_pkt_get_seq(pkt);
CU_ASSERT(seqno != TEST_SEQ_INVALID);
@@ -2293,6 +2318,16 @@ static void test_pmr_series(const int num_udp)
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
CU_ASSERT(retqueue == queue_ip);
+
+ if (marking) {
+ CU_ASSERT(odp_packet_cls_mark(pkt) == MARK_IP);
+ CU_ASSERT(odp_packet_reset(pkt, odp_packet_len(pkt)) == 0);
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
+ } else {
+ /* Default is 0 */
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
+ }
+
odp_packet_free(pkt);
/* Matching UDP/IP packets */
@@ -2310,6 +2345,7 @@ static void test_pmr_series(const int num_udp)
odp_pktio_mac_addr(pktio, eth->src.addr, ODPH_ETHADDR_LEN);
odp_pktio_mac_addr(pktio, eth->dst.addr, ODPH_ETHADDR_LEN);
ip->dst_addr = dst_addr_be;
+ odph_ipv4_csum_update(pkt);
udp->dst_port = odp_cpu_to_be_16(dst_port + i);
seqno = cls_pkt_get_seq(pkt);
@@ -2321,6 +2357,14 @@ static void test_pmr_series(const int num_udp)
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);
CU_ASSERT(seqno == cls_pkt_get_seq(pkt));
CU_ASSERT(retqueue == queue_udp[i]);
+
+ if (marking) {
+ CU_ASSERT(odp_packet_cls_mark(pkt) == (uint64_t)(MARK_UDP + i));
+ } else {
+ /* Default is 0 */
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
+ }
+
odp_packet_free(pkt);
}
@@ -2364,12 +2408,17 @@ static void test_pmr_series(const int num_udp)
static void classification_test_pmr_serial(void)
{
- test_pmr_series(1);
+ test_pmr_series(1, 0);
}
static void classification_test_pmr_parallel(void)
{
- test_pmr_series(4);
+ test_pmr_series(MAX_NUM_UDP, 0);
+}
+
+static void classification_test_pmr_marking(void)
+{
+ test_pmr_series(MAX_NUM_UDP, 1);
}
static void classification_test_pmr_term_custom_frame(void)
@@ -2477,6 +2526,20 @@ static int check_capa_pmr_series(void)
return support;
}
+static int check_capa_pmr_marking(void)
+{
+ uint64_t terms;
+
+ terms = cls_capa.supported_terms.bit.dip_addr &&
+ cls_capa.supported_terms.bit.udp_dport;
+
+ /* one PMR for IP, MAX_NUM_UDP PMRs for UDP */
+ if (terms && cls_capa.max_mark >= (MARK_UDP + MAX_NUM_UDP - 1))
+ return 1;
+
+ return 0;
+}
+
odp_testinfo_t classification_suite_pmr[] = {
ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_term_tcp_dport,
check_capa_tcp_dport),
@@ -2520,5 +2583,7 @@ odp_testinfo_t classification_suite_pmr[] = {
check_capa_pmr_series),
ODP_TEST_INFO(classification_test_pktin_classifier_flag),
ODP_TEST_INFO(classification_test_pmr_term_tcp_dport_multi),
+ ODP_TEST_INFO_CONDITIONAL(classification_test_pmr_marking,
+ check_capa_pmr_marking),
ODP_TEST_INFO_NULL,
};
diff --git a/test/validation/api/crypto/odp_crypto_test_inp.c b/test/validation/api/crypto/odp_crypto_test_inp.c
index b14b3d484..b04c4d830 100644
--- a/test/validation/api/crypto/odp_crypto_test_inp.c
+++ b/test/validation/api/crypto/odp_crypto_test_inp.c
@@ -23,8 +23,32 @@ struct suite_context_s {
static struct suite_context_s suite_context;
-static int packet_cmp_mem(odp_packet_t pkt, uint32_t offset,
- void *s, uint32_t len)
+static int packet_cmp_mem_bits(odp_packet_t pkt, uint32_t offset,
+ uint8_t *s, uint32_t len)
+{
+ int rc = -1;
+ uint32_t len_bytes = ((len + 7) / 8);
+ uint8_t leftover_bits = len % 8;
+ uint8_t buf[len_bytes];
+
+ odp_packet_copy_to_mem(pkt, offset, len_bytes, buf);
+
+ /* Compare till the last full byte */
+ rc = memcmp(buf, s, leftover_bits ? len_bytes - 1 : len_bytes);
+
+ if (rc == 0 && leftover_bits) {
+ /* Do masked comparison for the leftover bits */
+ uint8_t mask = 0xff << (8 - leftover_bits);
+
+ rc = !((mask & buf[len_bytes - 1]) ==
+ (mask & s[len_bytes - 1]));
+ }
+
+ return rc;
+}
+
+static int packet_cmp_mem_bytes(odp_packet_t pkt, uint32_t offset,
+ uint8_t *s, uint32_t len)
{
uint8_t buf[len];
@@ -33,6 +57,19 @@ static int packet_cmp_mem(odp_packet_t pkt, uint32_t offset,
return memcmp(buf, s, len);
}
+static int packet_cmp_mem(odp_packet_t pkt, uint32_t offset,
+ uint8_t *s, uint32_t len, odp_bool_t bit_mode)
+{
+ int rc = -1;
+
+ if (bit_mode)
+ rc = packet_cmp_mem_bits(pkt, offset, s, len);
+ else
+ rc = packet_cmp_mem_bytes(pkt, offset, s, len);
+
+ return rc;
+}
+
static const char *auth_alg_name(odp_auth_alg_t auth)
{
switch (auth) {
@@ -484,14 +521,17 @@ static void alg_test(odp_crypto_op_t op,
if (op == ODP_CRYPTO_OP_ENCODE) {
CU_ASSERT(!packet_cmp_mem(pkt, 0,
ref->ciphertext,
- reflength));
+ ref->length,
+ bit_mode));
CU_ASSERT(!packet_cmp_mem(pkt, reflength,
ref->digest,
- ref->digest_length));
+ ref->digest_length,
+ bit_mode));
} else {
CU_ASSERT(!packet_cmp_mem(pkt, 0,
ref->plaintext,
- reflength));
+ ref->length,
+ bit_mode));
}
}
diff --git a/test/validation/api/crypto/test_vectors.h b/test/validation/api/crypto/test_vectors.h
index 6c4fc5b59..c377a5e0a 100644
--- a/test/validation/api/crypto/test_vectors.h
+++ b/test/validation/api/crypto/test_vectors.h
@@ -2548,7 +2548,7 @@ static crypto_test_reference_t aes_eea2_reference[] = {
0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1},
.cipher_iv_length = AES_EEA2_IV_LEN,
.cipher_iv = { 0x39, 0x8a, 0x59, 0xb4, 0xac, },
- .length = 248 /* + 5 */, /* 253 bits originally = 31 + 1 bytes*/
+ .length = 253,
.plaintext = { 0x98, 0x1B, 0xA6, 0x82, 0x4C, 0x1B, 0xFB, 0x1A,
0xB4, 0x85, 0x47, 0x20, 0x29, 0xB7, 0x1D, 0x80,
0x8C, 0xE3, 0x3E, 0x2C, 0xC3, 0xC0, 0xB5, 0xFC,
@@ -2564,7 +2564,7 @@ static crypto_test_reference_t aes_eea2_reference[] = {
0x95, 0x2C, 0x49, 0x10, 0x48, 0x05, 0xFF, 0x48},
.cipher_iv_length = AES_EEA2_IV_LEN,
.cipher_iv = { 0xc6, 0x75, 0xa6, 0x4b, 0x64, },
- .length = 99 /* + 6 */, /* 798 bits originally = 99 + 1 bytes */
+ .length = 798,
.plaintext = { 0x7E, 0xC6, 0x12, 0x72, 0x74, 0x3B, 0xF1, 0x61,
0x47, 0x26, 0x44, 0x6A, 0x6C, 0x38, 0xCE, 0xD1,
0x66, 0xF6, 0xCA, 0x76, 0xEB, 0x54, 0x30, 0x04,
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c
index 8009d5564..e1e735727 100644
--- a/test/validation/api/ipsec/ipsec.c
+++ b/test/validation/api/ipsec/ipsec.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2017-2018, Linaro Limited
- * Copyright (c) 2019, Nokia
+ * Copyright (c) 2019-2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -184,6 +184,10 @@ int ipsec_check(odp_bool_t ah,
if (!capa.ciphers.bit.aes_gcm)
return ODP_TEST_INACTIVE;
break;
+ case ODP_CIPHER_ALG_AES_CCM:
+ if (!capa.ciphers.bit.aes_ccm)
+ return ODP_TEST_INACTIVE;
+ break;
case ODP_CIPHER_ALG_CHACHA20_POLY1305:
if (!capa.ciphers.bit.chacha20_poly1305)
return ODP_TEST_INACTIVE;
@@ -231,6 +235,10 @@ int ipsec_check(odp_bool_t ah,
if (!capa.auths.bit.aes_gmac)
return ODP_TEST_INACTIVE;
break;
+ case ODP_AUTH_ALG_AES_CCM:
+ if (!capa.auths.bit.aes_ccm)
+ return ODP_TEST_INACTIVE;
+ break;
case ODP_AUTH_ALG_CHACHA20_POLY1305:
if (!capa.auths.bit.chacha20_poly1305)
return ODP_TEST_INACTIVE;
@@ -318,6 +326,12 @@ int ipsec_check_esp_aes_gcm_128(void)
ODP_AUTH_ALG_AES_GCM, 0);
}
+int ipsec_check_esp_aes_gcm_192(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 192,
+ ODP_AUTH_ALG_AES_GCM, 0);
+}
+
int ipsec_check_esp_aes_gcm_256(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 256,
@@ -330,12 +344,54 @@ int ipsec_check_ah_aes_gmac_128(void)
ODP_AUTH_ALG_AES_GMAC, 128);
}
+int ipsec_check_ah_aes_gmac_192(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
+ ODP_AUTH_ALG_AES_GMAC, 192);
+}
+
+int ipsec_check_ah_aes_gmac_256(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
+ ODP_AUTH_ALG_AES_GMAC, 256);
+}
+
int ipsec_check_esp_null_aes_gmac_128(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
ODP_AUTH_ALG_AES_GMAC, 128);
}
+int ipsec_check_esp_null_aes_gmac_192(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
+ ODP_AUTH_ALG_AES_GMAC, 192);
+}
+
+int ipsec_check_esp_null_aes_gmac_256(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
+ ODP_AUTH_ALG_AES_GMAC, 256);
+}
+
+int ipsec_check_esp_aes_ccm_128(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_AES_CCM, 128,
+ ODP_AUTH_ALG_AES_CCM, 0);
+}
+
+int ipsec_check_esp_aes_ccm_192(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_AES_CCM, 192,
+ ODP_AUTH_ALG_AES_CCM, 0);
+}
+
+int ipsec_check_esp_aes_ccm_256(void)
+{
+ return ipsec_check_esp(ODP_CIPHER_ALG_AES_CCM, 256,
+ ODP_AUTH_ALG_AES_CCM, 0);
+}
+
int ipsec_check_esp_chacha20_poly1305(void)
{
return ipsec_check_esp(ODP_CIPHER_ALG_CHACHA20_POLY1305, 256,
@@ -655,12 +711,13 @@ static int ipsec_send_out_one(const ipsec_test_part *part,
param.opt = &part->opt;
if (ODP_IPSEC_OP_MODE_SYNC == suite_context.outbound_op_mode) {
- CU_ASSERT_EQUAL(part->out_pkt, odp_ipsec_out(&pkt, 1,
- pkto, &num_out,
- &param));
- CU_ASSERT_EQUAL(num_out, part->out_pkt);
- CU_ASSERT(odp_packet_subtype(*pkto) ==
- ODP_EVENT_PACKET_IPSEC);
+ CU_ASSERT_EQUAL(1, odp_ipsec_out(&pkt, 1, pkto, &num_out,
+ &param));
+ CU_ASSERT_EQUAL(num_out, 1);
+ if (num_out == 1) {
+ CU_ASSERT(odp_packet_subtype(*pkto) ==
+ ODP_EVENT_PACKET_IPSEC);
+ }
} else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode) {
num_out = odp_ipsec_out_enq(&pkt, 1, &param);
CU_ASSERT_EQUAL(1, num_out);
diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h
index 2a6713d10..7aa38dce4 100644
--- a/test/validation/api/ipsec/ipsec.h
+++ b/test/validation/api/ipsec/ipsec.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2017-2018, Linaro Limited
+ * Copyright (c) 2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -94,9 +95,17 @@ int ipsec_check_esp_aes_cbc_128_null(void);
int ipsec_check_esp_aes_cbc_128_sha256(void);
int ipsec_check_esp_aes_ctr_128_null(void);
int ipsec_check_esp_aes_gcm_128(void);
+int ipsec_check_esp_aes_gcm_192(void);
int ipsec_check_esp_aes_gcm_256(void);
int ipsec_check_ah_aes_gmac_128(void);
+int ipsec_check_ah_aes_gmac_192(void);
+int ipsec_check_ah_aes_gmac_256(void);
int ipsec_check_esp_null_aes_gmac_128(void);
+int ipsec_check_esp_null_aes_gmac_192(void);
+int ipsec_check_esp_null_aes_gmac_256(void);
+int ipsec_check_esp_aes_ccm_128(void);
+int ipsec_check_esp_aes_ccm_192(void);
+int ipsec_check_esp_aes_ccm_256(void);
int ipsec_check_esp_chacha20_poly1305(void);
#endif
diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c
index 9b91743f0..9a3ba2bd3 100644
--- a/test/validation/api/ipsec/ipsec_test_out.c
+++ b/test/validation/api/ipsec/ipsec_test_out.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2017-2018, Linaro Limited
+ * Copyright (c) 2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -8,6 +9,54 @@
#include "test_vectors.h"
+struct cipher_param {
+ const char *name;
+ odp_cipher_alg_t algo;
+ const odp_crypto_key_t *key;
+ const odp_crypto_key_t *key_extra;
+};
+
+struct auth_param {
+ const char *name;
+ odp_auth_alg_t algo;
+ const odp_crypto_key_t *key;
+ const odp_crypto_key_t *key_extra;
+};
+
+#define ALG(alg, key, key_extra) { #alg, alg, key, key_extra }
+
+/*
+ * Ciphers that can be used in ESP and combined with any integrity
+ * algorithm. This excludes combined mode algorithms such as AES-GCM.
+ */
+static struct cipher_param ciphers[] = {
+ ALG(ODP_CIPHER_ALG_NULL, NULL, NULL),
+ ALG(ODP_CIPHER_ALG_DES, &key_des_64, NULL),
+ ALG(ODP_CIPHER_ALG_3DES_CBC, &key_des_192, NULL),
+ ALG(ODP_CIPHER_ALG_AES_CBC, &key_a5_128, NULL),
+ ALG(ODP_CIPHER_ALG_AES_CBC, &key_a5_192, NULL),
+ ALG(ODP_CIPHER_ALG_AES_CBC, &key_a5_256, NULL),
+ ALG(ODP_CIPHER_ALG_AES_CTR, &key_a5_128, &key_mcgrew_gcm_salt_3),
+ ALG(ODP_CIPHER_ALG_AES_CTR, &key_a5_192, &key_mcgrew_gcm_salt_3),
+ ALG(ODP_CIPHER_ALG_AES_CTR, &key_a5_256, &key_mcgrew_gcm_salt_3)
+};
+
+/*
+ * Integrity algorithms that can be used in ESP and AH. This excludes
+ * AES-GMAC which is defined for ESP as a combined-mode algorithm.
+ */
+static struct auth_param auths[] = {
+ ALG(ODP_AUTH_ALG_NULL, NULL, NULL),
+ ALG(ODP_AUTH_ALG_MD5_HMAC, &key_5a_128, NULL),
+ ALG(ODP_AUTH_ALG_SHA1_HMAC, &key_5a_160, NULL),
+ ALG(ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, NULL),
+ ALG(ODP_AUTH_ALG_SHA384_HMAC, &key_5a_384, NULL),
+ ALG(ODP_AUTH_ALG_SHA512_HMAC, &key_5a_512, NULL),
+ ALG(ODP_AUTH_ALG_AES_XCBC_MAC, &key_5a_128, NULL)
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
static void test_out_ipv4_ah_sha256(void)
{
odp_ipsec_sa_param_t param;
@@ -243,31 +292,37 @@ static void test_out_ipv4_esp_null_sha256_tun_ipv6(void)
ipsec_sa_destroy(sa);
}
-static void test_out_ipv4_esp_aes_cbc_null(void)
+static void test_out_in_common(odp_bool_t ah,
+ odp_cipher_alg_t cipher,
+ const odp_crypto_key_t *cipher_key,
+ odp_auth_alg_t auth,
+ const odp_crypto_key_t *auth_key,
+ const odp_crypto_key_t *cipher_key_extra,
+ const odp_crypto_key_t *auth_key_extra)
{
odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t sa;
- odp_ipsec_sa_t sa2;
+ odp_ipsec_sa_t sa_out;
+ odp_ipsec_sa_t sa_in;
ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
- ODP_AUTH_ALG_NULL, NULL,
- NULL, NULL);
+ false, ah, 123, NULL,
+ cipher, cipher_key,
+ auth, auth_key,
+ cipher_key_extra, auth_key_extra);
- sa = odp_ipsec_sa_create(&param);
+ sa_out = odp_ipsec_sa_create(&param);
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+ CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa_out);
ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
- ODP_AUTH_ALG_NULL, NULL,
- NULL, NULL);
+ true, ah, 123, NULL,
+ cipher, cipher_key,
+ auth, auth_key,
+ cipher_key_extra, auth_key_extra);
- sa2 = odp_ipsec_sa_create(&param);
+ sa_in = odp_ipsec_sa_create(&param);
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
+ CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa_in);
ipsec_test_part test = {
.pkt_in = &pkt_ipv4_icmp_0,
@@ -281,305 +336,205 @@ static void test_out_ipv4_esp_aes_cbc_null(void)
},
};
- ipsec_check_out_in_one(&test, sa, sa2);
+ ipsec_check_out_in_one(&test, sa_out, sa_in);
- ipsec_sa_destroy(sa2);
- ipsec_sa_destroy(sa);
+ ipsec_sa_destroy(sa_out);
+ ipsec_sa_destroy(sa_in);
}
-static void test_out_ipv4_esp_udp_null_sha256(void)
+static void test_esp_out_in(struct cipher_param *cipher,
+ struct auth_param *auth)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t sa;
+ int cipher_keylen = cipher->key ? 8 * cipher->key->length : 0;
+ int auth_keylen = auth->key ? 8 * auth->key->length : 0;
- ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_NULL, NULL,
- ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256,
- NULL, NULL);
- param.opt.udp_encap = 1;
-
- sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
-
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .pkt_out = &pkt_ipv4_icmp_0_esp_udp_null_sha256_1 },
- },
- };
+ if (ipsec_check_esp(cipher->algo, cipher_keylen,
+ auth->algo, auth_keylen) != ODP_TEST_ACTIVE)
+ return;
- ipsec_check_out_one(&test, sa);
+ printf("\n %s (keylen %d) %s (keylen %d) ",
+ cipher->name, cipher_keylen, auth->name, auth_keylen);
- ipsec_sa_destroy(sa);
+ test_out_in_common(false /* ESP */,
+ cipher->algo, cipher->key,
+ auth->algo, auth->key,
+ cipher->key_extra, auth->key_extra);
}
-static void test_out_ipv4_esp_aes_cbc_sha256(void)
+/*
+ * Test ESP output followed by input with all combinations of normal
+ * mode (not combined mode) ciphers and integrity algorithms.
+ *
+ * Combined mode algorithms are tested one-by-one in their own test cases.
+ */
+static void test_esp_out_in_all(void)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t sa;
- odp_ipsec_sa_t sa2;
+ uint32_t c;
+ uint32_t a;
- ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
- ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256,
- NULL, NULL);
-
- sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
+ for (c = 0; c < ARRAY_SIZE(ciphers); c++)
+ for (a = 0; a < ARRAY_SIZE(auths); a++)
+ test_esp_out_in(&ciphers[c], &auths[a]);
+ printf("\n ");
+}
- ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CBC, &key_a5_128,
- ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256,
- NULL, NULL);
+static void test_ah_out_in(struct auth_param *auth)
+{
+ int auth_keylen = auth->key ? 8 * auth->key->length : 0;
- sa2 = odp_ipsec_sa_create(&param);
+ if (ipsec_check_ah(auth->algo, auth_keylen) != ODP_TEST_ACTIVE)
+ return;
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
+ printf("\n %s (keylen %d) ", auth->name, auth_keylen);
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
- },
- };
+ test_out_in_common(true /* AH */,
+ ODP_CIPHER_ALG_NULL, NULL,
+ auth->algo, auth->key,
+ NULL, auth->key_extra);
+}
- ipsec_check_out_in_one(&test, sa, sa2);
+static void test_ah_out_in_all(void)
+{
+ uint32_t a;
- ipsec_sa_destroy(sa2);
- ipsec_sa_destroy(sa);
+ for (a = 0; a < ARRAY_SIZE(auths); a++)
+ test_ah_out_in(&auths[a]);
+ printf("\n ");
}
-static void test_out_ipv4_esp_aes_ctr_null(void)
+static void test_out_ipv4_esp_udp_null_sha256(void)
{
odp_ipsec_sa_param_t param;
odp_ipsec_sa_t sa;
- odp_ipsec_sa_t sa2;
ipsec_sa_param_fill(&param,
false, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CTR, &key_a5_128,
- ODP_AUTH_ALG_NULL, NULL,
- &key_mcgrew_gcm_salt_3, NULL);
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256,
+ NULL, NULL);
+ param.opt.udp_encap = 1;
sa = odp_ipsec_sa_create(&param);
CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
- ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_AES_CTR, &key_a5_128,
- ODP_AUTH_ALG_NULL, NULL,
- &key_mcgrew_gcm_salt_3, NULL);
-
- sa2 = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
-
ipsec_test_part test = {
.pkt_in = &pkt_ipv4_icmp_0,
.out_pkt = 1,
.out = {
{ .status.warn.all = 0,
.status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
+ .pkt_out = &pkt_ipv4_icmp_0_esp_udp_null_sha256_1 },
},
};
- ipsec_check_out_in_one(&test, sa, sa2);
+ ipsec_check_out_one(&test, sa);
- ipsec_sa_destroy(sa2);
ipsec_sa_destroy(sa);
}
static void test_out_ipv4_esp_aes_gcm128(void)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t sa;
- odp_ipsec_sa_t sa2;
-
- ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_AES_GCM, &key_a5_128,
- ODP_AUTH_ALG_AES_GCM, &key_a5_128,
- &key_mcgrew_gcm_salt_2, NULL);
-
- sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
-
- ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_AES_GCM, &key_a5_128,
- ODP_AUTH_ALG_AES_GCM, &key_a5_128,
- &key_mcgrew_gcm_salt_2, NULL);
-
- sa2 = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
-
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
- },
- };
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_GCM, &key_a5_128,
+ ODP_AUTH_ALG_AES_GCM, NULL,
+ &key_mcgrew_gcm_salt_2, NULL);
+}
- ipsec_check_out_in_one(&test, sa, sa2);
+static void test_out_ipv4_esp_aes_gcm192(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_GCM, &key_a5_192,
+ ODP_AUTH_ALG_AES_GCM, NULL,
+ &key_mcgrew_gcm_salt_2, NULL);
+}
- ipsec_sa_destroy(sa2);
- ipsec_sa_destroy(sa);
+static void test_out_ipv4_esp_aes_gcm256(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_GCM, &key_a5_256,
+ ODP_AUTH_ALG_AES_GCM, NULL,
+ &key_mcgrew_gcm_salt_2, NULL);
}
static void test_out_ipv4_ah_aes_gmac_128(void)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t out_sa;
- odp_ipsec_sa_t in_sa;
-
- ipsec_sa_param_fill(&param,
- false, true, 123, NULL,
- ODP_CIPHER_ALG_NULL, NULL,
- ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
- NULL, &key_mcgrew_gcm_salt_2);
-
- out_sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa);
-
- ipsec_sa_param_fill(&param,
- true, true, 123, NULL,
- ODP_CIPHER_ALG_NULL, NULL,
- ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
- NULL, &key_mcgrew_gcm_salt_2);
-
- in_sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa);
-
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
- },
- };
+ test_out_in_common(true,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
+ NULL, &key_mcgrew_gcm_salt_2);
+}
- ipsec_check_out_in_one(&test, out_sa, in_sa);
+static void test_out_ipv4_ah_aes_gmac_192(void)
+{
+ test_out_in_common(true,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_192,
+ NULL, &key_mcgrew_gcm_salt_2);
+}
- ipsec_sa_destroy(out_sa);
- ipsec_sa_destroy(in_sa);
+static void test_out_ipv4_ah_aes_gmac_256(void)
+{
+ test_out_in_common(true,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_256,
+ NULL, &key_mcgrew_gcm_salt_2);
}
static void test_out_ipv4_esp_null_aes_gmac_128(void)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t out_sa;
- odp_ipsec_sa_t in_sa;
-
- ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_NULL, NULL,
- ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
- NULL, &key_mcgrew_gcm_salt_2);
-
- out_sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa);
-
- ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_NULL, NULL,
- ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
- NULL, &key_mcgrew_gcm_salt_2);
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_128,
+ NULL, &key_mcgrew_gcm_salt_2);
+}
- in_sa = odp_ipsec_sa_create(&param);
+static void test_out_ipv4_esp_null_aes_gmac_192(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_192,
+ NULL, &key_mcgrew_gcm_salt_2);
+}
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa);
+static void test_out_ipv4_esp_null_aes_gmac_256(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_NULL, NULL,
+ ODP_AUTH_ALG_AES_GMAC, &key_a5_256,
+ NULL, &key_mcgrew_gcm_salt_2);
+}
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
- },
- };
+static void test_out_ipv4_esp_aes_ccm128(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_CCM, &key_a5_128,
+ ODP_AUTH_ALG_AES_CCM, NULL,
+ &key_3byte_salt, NULL);
+}
- ipsec_check_out_in_one(&test, out_sa, in_sa);
+static void test_out_ipv4_esp_aes_ccm192(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_CCM, &key_a5_192,
+ ODP_AUTH_ALG_AES_CCM, NULL,
+ &key_3byte_salt, NULL);
+}
- ipsec_sa_destroy(out_sa);
- ipsec_sa_destroy(in_sa);
+static void test_out_ipv4_esp_aes_ccm256(void)
+{
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_AES_CCM, &key_a5_256,
+ ODP_AUTH_ALG_AES_CCM, NULL,
+ &key_3byte_salt, NULL);
}
static void test_out_ipv4_esp_chacha20_poly1305(void)
{
- odp_ipsec_sa_param_t param;
- odp_ipsec_sa_t sa;
- odp_ipsec_sa_t sa2;
-
- ipsec_sa_param_fill(&param,
- false, false, 123, NULL,
- ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634,
- ODP_AUTH_ALG_CHACHA20_POLY1305, NULL,
- &key_rfc7634_salt, NULL);
-
- sa = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa);
-
- ipsec_sa_param_fill(&param,
- true, false, 123, NULL,
- ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634,
- ODP_AUTH_ALG_CHACHA20_POLY1305, NULL,
- &key_rfc7634_salt, NULL);
-
- sa2 = odp_ipsec_sa_create(&param);
-
- CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2);
-
- ipsec_test_part test = {
- .pkt_in = &pkt_ipv4_icmp_0,
- .out_pkt = 1,
- .out = {
- { .status.warn.all = 0,
- .status.error.all = 0,
- .l3_type = ODP_PROTO_L3_TYPE_IPV4,
- .l4_type = ODP_PROTO_L4_TYPE_ICMPV4,
- .pkt_out = &pkt_ipv4_icmp_0 },
- },
- };
-
- ipsec_check_out_in_one(&test, sa, sa2);
-
- ipsec_sa_destroy(sa2);
- ipsec_sa_destroy(sa);
+ test_out_in_common(false,
+ ODP_CIPHER_ALG_CHACHA20_POLY1305, &key_rfc7634,
+ ODP_AUTH_ALG_CHACHA20_POLY1305, NULL,
+ &key_rfc7634_salt, NULL);
}
static void test_out_ipv4_ah_sha256_frag_check(void)
@@ -1206,18 +1161,30 @@ odp_testinfo_t ipsec_out_suite[] = {
ipsec_check_esp_null_sha256),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_udp_null_sha256,
ipsec_check_esp_null_sha256),
- ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_cbc_null,
- ipsec_check_esp_aes_cbc_128_null),
- ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_cbc_sha256,
- ipsec_check_esp_aes_cbc_128_sha256),
- ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_ctr_null,
- ipsec_check_esp_aes_ctr_128_null),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_gcm128,
ipsec_check_esp_aes_gcm_128),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_gcm192,
+ ipsec_check_esp_aes_gcm_192),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_gcm256,
+ ipsec_check_esp_aes_gcm_256),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_aes_gmac_128,
ipsec_check_ah_aes_gmac_128),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_aes_gmac_192,
+ ipsec_check_ah_aes_gmac_192),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_aes_gmac_256,
+ ipsec_check_ah_aes_gmac_256),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_null_aes_gmac_128,
ipsec_check_esp_null_aes_gmac_128),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_null_aes_gmac_192,
+ ipsec_check_esp_null_aes_gmac_192),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_null_aes_gmac_256,
+ ipsec_check_esp_null_aes_gmac_256),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_ccm128,
+ ipsec_check_esp_aes_ccm_128),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_ccm192,
+ ipsec_check_esp_aes_ccm_192),
+ ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_aes_ccm256,
+ ipsec_check_esp_aes_ccm_256),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_esp_chacha20_poly1305,
ipsec_check_esp_chacha20_poly1305),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_ah_sha256_frag_check,
@@ -1248,5 +1215,7 @@ odp_testinfo_t ipsec_out_suite[] = {
ipsec_check_esp_null_sha256),
ODP_TEST_INFO_CONDITIONAL(test_out_ipv4_udp_esp_null_sha256,
ipsec_check_esp_null_sha256),
+ ODP_TEST_INFO(test_esp_out_in_all),
+ ODP_TEST_INFO(test_ah_out_in_all),
ODP_TEST_INFO_NULL,
};
diff --git a/test/validation/api/ipsec/test_vectors.h b/test/validation/api/ipsec/test_vectors.h
index e9b8634f2..f16956d1f 100644
--- a/test/validation/api/ipsec/test_vectors.h
+++ b/test/validation/api/ipsec/test_vectors.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2017-2018, Linaro Limited
+ * Copyright (c) 2020, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -18,6 +19,12 @@ KEY(key_a5_128, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5);
KEY(key_5a_128, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
+KEY(key_5a_160, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a);
+KEY(key_a5_192, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+ 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
+ 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5);
KEY(key_a5_256, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
@@ -26,6 +33,20 @@ KEY(key_5a_256, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
+KEY(key_5a_384, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
+KEY(key_5a_512, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a);
KEY(key_rfc3602, 0x90, 0xd3, 0x82, 0xb4, 0x10, 0xee, 0xba, 0x7a,
0xd9, 0x38, 0xc4, 0x6c, 0xec, 0x1a, 0x82, 0xbf);
@@ -53,6 +74,13 @@ KEY(key_rfc7634, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f);
KEY(key_rfc7634_salt, 0xa0, 0xa1, 0xa2, 0xa3);
+KEY(key_3byte_salt, 0x01, 0x02, 0x03);
+
+/* DES keys have parity bits so that each byte has odd parity */
+KEY(key_des_64, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4);
+KEY(key_des_192, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
+ 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4);
static const ODP_UNUSED ipsec_test_packet pkt_ipv4_icmp_0 = {
.len = 142,
diff --git a/test/validation/api/packet/packet.c b/test/validation/api/packet/packet.c
index 51d251630..0172e526c 100644
--- a/test/validation/api/packet/packet.c
+++ b/test/validation/api/packet/packet.c
@@ -661,6 +661,8 @@ static void packet_test_basic_metadata(void)
odp_packet_has_flow_hash_clr(pkt);
CU_ASSERT(!odp_packet_has_flow_hash(pkt));
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
+
ts = odp_time_global();
odp_packet_ts_set(pkt, ts);
CU_ASSERT_FATAL(odp_packet_has_ts(pkt));
@@ -737,6 +739,7 @@ static void packet_test_reset(void)
ptr_len = (uintptr_t)odp_packet_data(pkt) -
(uintptr_t)odp_packet_head(pkt);
CU_ASSERT(ptr_len == headroom);
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
tail = odp_packet_tail(pkt);
new_tail = odp_packet_pull_tail(pkt, 1);
diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c
index 4fa8f6d13..907951cbc 100644
--- a/test/validation/api/pktio/pktio.c
+++ b/test/validation/api/pktio/pktio.c
@@ -879,6 +879,7 @@ static void pktio_txrx_multi(pktio_info_t *pktio_info_a,
}
CU_ASSERT(odp_packet_user_ptr(pkt) == NULL);
+ CU_ASSERT(odp_packet_cls_mark(pkt) == 0);
odp_packet_input_set(pkt, ODP_PKTIO_INVALID);
CU_ASSERT(odp_packet_input(pkt) == ODP_PKTIO_INVALID);
diff --git a/test/validation/api/scheduler/scheduler.c b/test/validation/api/scheduler/scheduler.c
index 3d5639ab2..ca8af7920 100644
--- a/test/validation/api/scheduler/scheduler.c
+++ b/test/validation/api/scheduler/scheduler.c
@@ -53,7 +53,9 @@
#define CHAOS_PTR_TO_NDX(p) ((uint64_t)(uint32_t)(uintptr_t)p)
#define CHAOS_NDX_TO_PTR(n) ((void *)(uintptr_t)n)
-#define WAIT_TOLERANCE (150 * ODP_TIME_MSEC_IN_NS)
+#define WAIT_TIMEOUT (1000 * ODP_TIME_MSEC_IN_NS)
+#define WAIT_ROUNDS 5
+#define WAIT_TOLERANCE (150 * ODP_TIME_MSEC_IN_NS)
#define WAIT_1MS_RETRIES 1000
#define SCHED_AND_PLAIN_ROUNDS 10000
@@ -155,10 +157,12 @@ static void scheduler_test_wait_time(void)
{
int i;
odp_queue_t queue;
+ odp_event_t ev;
uint64_t wait_time;
odp_queue_param_t qp;
odp_time_t lower_limit, upper_limit;
odp_time_t start_time, end_time, diff;
+ uint64_t duration_ns = WAIT_ROUNDS * WAIT_TIMEOUT;
/* check on read */
wait_time = odp_schedule_wait_time(0);
@@ -173,10 +177,11 @@ static void scheduler_test_wait_time(void)
queue = odp_queue_create("dummy_queue", &qp);
CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
- wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS);
+ wait_time = odp_schedule_wait_time(WAIT_TIMEOUT);
start_time = odp_time_local();
- odp_schedule(&queue, ODP_SCHED_NO_WAIT);
+ ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
end_time = odp_time_local();
+ CU_ASSERT_FATAL(ev == ODP_EVENT_INVALID);
diff = odp_time_diff(end_time, start_time);
lower_limit = ODP_TIME_NULL;
@@ -186,28 +191,27 @@ static void scheduler_test_wait_time(void)
CU_ASSERT(odp_time_cmp(diff, upper_limit) <= 0);
/* check time correctness */
+ printf("\nTesting wait time for %.3f sec ...\n", (double)duration_ns / ODP_TIME_SEC_IN_NS);
start_time = odp_time_local();
- for (i = 1; i < 6; i++)
- odp_schedule(&queue, wait_time);
+ for (i = 0; i < WAIT_ROUNDS; i++) {
+ ev = odp_schedule(NULL, wait_time);
+ CU_ASSERT_FATAL(ev == ODP_EVENT_INVALID);
+ }
end_time = odp_time_local();
diff = odp_time_diff(end_time, start_time);
- lower_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS -
- WAIT_TOLERANCE);
- upper_limit = odp_time_local_from_ns(5 * ODP_TIME_SEC_IN_NS +
- WAIT_TOLERANCE);
+ lower_limit = odp_time_local_from_ns(duration_ns - WAIT_TOLERANCE);
+ upper_limit = odp_time_local_from_ns(duration_ns + WAIT_TOLERANCE);
if (odp_time_cmp(diff, lower_limit) <= 0) {
- fprintf(stderr, "Exceed lower limit: "
- "diff is %" PRIu64 ", lower_limit %" PRIu64 "\n",
- odp_time_to_ns(diff), odp_time_to_ns(lower_limit));
+ ODPH_ERR("Exceed lower limit: diff is %" PRIu64 ", lower_limit %" PRIu64 "\n",
+ odp_time_to_ns(diff), odp_time_to_ns(lower_limit));
CU_FAIL("Exceed lower limit\n");
}
if (odp_time_cmp(diff, upper_limit) >= 0) {
- fprintf(stderr, "Exceed upper limit: "
- "diff is %" PRIu64 ", upper_limit %" PRIu64 "\n",
- odp_time_to_ns(diff), odp_time_to_ns(upper_limit));
+ ODPH_ERR("Exceed upper limit: diff is %" PRIu64 ", upper_limit %" PRIu64 "\n",
+ odp_time_to_ns(diff), odp_time_to_ns(upper_limit));
CU_FAIL("Exceed upper limit\n");
}
@@ -1847,6 +1851,104 @@ static void scheduler_test_pause_resume(void)
CU_ASSERT(drain_queues() == 0);
}
+static void scheduler_test_pause_enqueue(void)
+{
+ odp_queue_t queue;
+ odp_buffer_t buf;
+ odp_event_t ev;
+ odp_event_t ev_tbl[NUM_BUFS_BEFORE_PAUSE];
+ odp_queue_t from;
+ odp_pool_t pool;
+ int i;
+ int ret;
+ int local_bufs;
+
+ queue = odp_queue_lookup("sched_0_0_n");
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ pool = odp_pool_lookup(MSG_POOL_NAME);
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ for (i = 0; i < NUM_BUFS_PAUSE; i++) {
+ buf = odp_buffer_alloc(pool);
+ CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
+ ev = odp_buffer_to_event(buf);
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT_FATAL(ret == 0);
+ }
+
+ for (i = 0; i < NUM_BUFS_BEFORE_PAUSE; i++) {
+ from = ODP_QUEUE_INVALID;
+ ev = odp_schedule(&from, ODP_SCHED_WAIT);
+ CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID);
+ CU_ASSERT(from == queue);
+ ev_tbl[i] = ev;
+ }
+
+ /* Pause, enqueue, schedule, resume */
+ odp_schedule_pause();
+
+ for (i = 0; i < NUM_BUFS_BEFORE_PAUSE; i++) {
+ ev = ev_tbl[i];
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT_FATAL(ret == 0);
+ }
+
+ local_bufs = 0;
+ while (1) {
+ from = ODP_QUEUE_INVALID;
+ ev = odp_schedule(&from, ODP_SCHED_NO_WAIT);
+ if (ev == ODP_EVENT_INVALID)
+ break;
+
+ CU_ASSERT(from == queue);
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT_FATAL(ret == 0);
+
+ local_bufs++;
+ CU_ASSERT_FATAL(local_bufs <= NUM_BUFS_PAUSE);
+ }
+
+ odp_schedule_resume();
+
+ for (i = 0; i < NUM_BUFS_BEFORE_PAUSE; i++) {
+ from = ODP_QUEUE_INVALID;
+ ev = odp_schedule(&from, ODP_SCHED_WAIT);
+ CU_ASSERT_FATAL(ev != ODP_EVENT_INVALID);
+ CU_ASSERT(from == queue);
+ ev_tbl[i] = ev;
+ }
+
+ /* Pause, schedule, enqueue, resume */
+ odp_schedule_pause();
+
+ local_bufs = 0;
+ while (1) {
+ from = ODP_QUEUE_INVALID;
+ ev = odp_schedule(&from, ODP_SCHED_NO_WAIT);
+ if (ev == ODP_EVENT_INVALID)
+ break;
+
+ CU_ASSERT(from == queue);
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT_FATAL(ret == 0);
+
+ local_bufs++;
+ CU_ASSERT_FATAL(local_bufs <= NUM_BUFS_PAUSE - NUM_BUFS_BEFORE_PAUSE);
+ }
+
+ for (i = 0; i < NUM_BUFS_BEFORE_PAUSE; i++) {
+ ev = ev_tbl[i];
+ ret = odp_queue_enq(queue, ev);
+ CU_ASSERT_FATAL(ret == 0);
+ }
+
+ odp_schedule_resume();
+
+ /* Free all */
+ CU_ASSERT(drain_queues() == NUM_BUFS_PAUSE);
+}
+
/* Basic, single threaded ordered lock API testing */
static void scheduler_test_ordered_lock(void)
{
@@ -2479,7 +2581,7 @@ static int destroy_queues(void)
}
if (odp_pool_destroy(globals->queue_ctx_pool) != 0) {
- fprintf(stderr, "error: failed to destroy queue ctx pool\n");
+ ODPH_ERR("Failed to destroy queue ctx pool\n");
return -1;
}
@@ -2492,21 +2594,21 @@ static int scheduler_suite_term(void)
odp_shm_t shm;
if (destroy_queues() != 0) {
- fprintf(stderr, "error: failed to destroy queues\n");
+ ODPH_ERR("Failed to destroy queues\n");
return -1;
}
pool = odp_pool_lookup(MSG_POOL_NAME);
if (odp_pool_destroy(pool) != 0)
- fprintf(stderr, "error: failed to destroy pool\n");
+ ODPH_ERR("Failed to destroy pool\n");
shm = odp_shm_lookup(SHM_THR_ARGS_NAME);
if (odp_shm_free(shm) != 0)
- fprintf(stderr, "error: failed to free shm\n");
+ ODPH_ERR("Failed to free shm\n");
shm = odp_shm_lookup(GLOBALS_SHM_NAME);
if (odp_shm_free(shm) != 0)
- fprintf(stderr, "error: failed to free shm\n");
+ ODPH_ERR("Failed to free shm\n");
if (odp_cunit_print_inactive())
return -1;
@@ -2646,6 +2748,7 @@ odp_testinfo_t scheduler_suite[] = {
ODP_TEST_INFO(scheduler_test_order_ignore),
ODP_TEST_INFO(scheduler_test_groups),
ODP_TEST_INFO(scheduler_test_pause_resume),
+ ODP_TEST_INFO(scheduler_test_pause_enqueue),
ODP_TEST_INFO(scheduler_test_ordered_lock),
ODP_TEST_INFO_CONDITIONAL(scheduler_test_flow_aware,
check_flow_aware_support),
@@ -2697,7 +2800,7 @@ static int global_init(odp_instance_t *inst)
odph_helper_options_t helper_options;
if (odph_options(&helper_options)) {
- fprintf(stderr, "error: odph_options() failed.\n");
+ ODPH_ERR("odph_options() failed.\n");
return -1;
}
@@ -2705,12 +2808,12 @@ static int global_init(odp_instance_t *inst)
init_param.mem_model = helper_options.mem_model;
if (0 != odp_init_global(inst, &init_param, NULL)) {
- fprintf(stderr, "error: odp_init_global() failed.\n");
+ ODPH_ERR("odp_init_global() failed.\n");
return -1;
}
if (0 != odp_init_local(*inst, ODP_THREAD_CONTROL)) {
- fprintf(stderr, "error: odp_init_local() failed.\n");
+ ODPH_ERR("odp_init_local() failed.\n");
return -1;
}
diff --git a/test/validation/api/system/system.c b/test/validation/api/system/system.c
index cc5d007d1..edad418bf 100644
--- a/test/validation/api/system/system.c
+++ b/test/validation/api/system/system.c
@@ -10,15 +10,15 @@
#include "odp_cunit_common.h"
-#define DIFF_TRY_NUM 160
-#define RES_TRY_NUM 10
-#define PAGESZ_NUM 10
+#define PERIODS_100_MSEC 160
+#define RES_TRY_NUM 10
+#define PAGESZ_NUM 10
#define GIGA_HZ 1000000000ULL
#define KILO_HZ 1000ULL
/* 10 usec wait time assumes >100kHz resolution on CPU cycles counter */
-#define CPU_CYCLES_WAIT_NS 10000
+#define WAIT_TIME (10 * ODP_TIME_USEC_IN_NS)
static void test_version_api_str(void)
{
@@ -86,13 +86,28 @@ static void system_test_odp_cpu_count(void)
static void system_test_cpu_cycles(void)
{
- uint64_t c2, c1;
+ uint64_t c2, c1, diff, max;
c1 = odp_cpu_cycles();
- odp_time_wait_ns(CPU_CYCLES_WAIT_NS);
+ odp_time_wait_ns(WAIT_TIME);
c2 = odp_cpu_cycles();
CU_ASSERT(c2 != c1);
+
+ max = odp_cpu_cycles_max();
+
+ /* With 10 usec delay, diff should be small compared to the maximum.
+ * Otherwise, counter is going backwards. */
+ if (c2 > c1) {
+ diff = c2 - c1;
+ CU_ASSERT(diff < (max - diff));
+ }
+
+ /* Same applies also when there was a wrap. */
+ if (c2 < c1) {
+ diff = max - c1 + c2;
+ CU_ASSERT(diff < (max - diff));
+ }
}
static void system_test_cpu_cycles_max(void)
@@ -101,14 +116,14 @@ static void system_test_cpu_cycles_max(void)
uint64_t max1, max2;
max1 = odp_cpu_cycles_max();
- odp_time_wait_ns(CPU_CYCLES_WAIT_NS);
+ odp_time_wait_ns(WAIT_TIME);
max2 = odp_cpu_cycles_max();
CU_ASSERT(max1 >= UINT32_MAX / 2);
CU_ASSERT(max1 == max2);
c1 = odp_cpu_cycles();
- odp_time_wait_ns(CPU_CYCLES_WAIT_NS);
+ odp_time_wait_ns(WAIT_TIME);
c2 = odp_cpu_cycles();
CU_ASSERT(c1 <= max1 && c2 <= max1);
@@ -138,13 +153,24 @@ static void system_test_cpu_cycles_resolution(void)
static void system_test_cpu_cycles_diff(void)
{
- int i;
- uint64_t c2, c1, c3, max;
+ uint64_t c2, c1, max;
uint64_t tmp, diff, res;
res = odp_cpu_cycles_resolution();
max = odp_cpu_cycles_max();
+ c1 = res;
+ c2 = 2 * res;
+ diff = odp_cpu_cycles_diff(c2, c1);
+ CU_ASSERT(diff == res);
+
+ c1 = odp_cpu_cycles();
+ odp_time_wait_ns(WAIT_TIME);
+ c2 = odp_cpu_cycles();
+ diff = odp_cpu_cycles_diff(c2, c1);
+ CU_ASSERT(diff > 0);
+ CU_ASSERT(diff < (max - diff));
+
/* check resolution for wrap */
c1 = max - 2 * res;
do
@@ -165,9 +191,21 @@ static void system_test_cpu_cycles_diff(void)
diff = odp_cpu_cycles_diff(c1, c2);
CU_ASSERT(diff == tmp);
CU_ASSERT(diff % res == 0);
+}
+
+static void system_test_cpu_cycles_long_period(void)
+{
+ int i;
+ uint64_t c2, c1, c3, max;
+ uint64_t tmp, diff, res;
+
+ printf("\n Testing CPU cycles for %i seconds... ", PERIODS_100_MSEC / 10);
+
+ res = odp_cpu_cycles_resolution();
+ max = odp_cpu_cycles_max();
c3 = odp_cpu_cycles();
- for (i = 0; i < DIFF_TRY_NUM; i++) {
+ for (i = 0; i < PERIODS_100_MSEC; i++) {
c1 = odp_cpu_cycles();
odp_time_wait_ns(100 * ODP_TIME_MSEC_IN_NS + i);
c2 = odp_cpu_cycles();
@@ -192,14 +230,16 @@ static void system_test_cpu_cycles_diff(void)
}
/* wrap was detected, no need to continue */
- if (i < DIFF_TRY_NUM)
+ if (i < PERIODS_100_MSEC) {
+ printf("wrap was detected.\n");
return;
+ }
/* wrap has to be detected if possible */
CU_ASSERT(max > UINT32_MAX);
CU_ASSERT((max - c3) > UINT32_MAX);
- printf("wrap was not detected...");
+ printf("wrap was not detected.\n");
}
static void system_test_odp_sys_cache_line_size(void)
@@ -451,6 +491,8 @@ odp_testinfo_t system_suite[] = {
system_check_cycle_counter),
ODP_TEST_INFO_CONDITIONAL(system_test_cpu_cycles_diff,
system_check_cycle_counter),
+ ODP_TEST_INFO_CONDITIONAL(system_test_cpu_cycles_long_period,
+ system_check_cycle_counter),
ODP_TEST_INFO(system_test_info_print),
ODP_TEST_INFO_NULL,
};