aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2021-07-08 09:07:13 +0300
committerGitHub <noreply@github.com>2021-07-08 09:07:13 +0300
commit6c7ac017886e2f1f63a27871254326d7cd1b48d1 (patch)
treea89fd543bacd9483642ebc27517ff59577ba55ad
parent3a7a24023021f5959dd2f00fe83cf2635bf25c2d (diff)
parent75b2e7ed219c2f087b7068c4e8b708d475c9026a (diff)
Merge ODP v1.30.0.0v1.30.0.0_DPDK_19.11
Merge ODP linux-generic v1.30.0.0 into ODP-DPDK.
-rw-r--r--.github/workflows/ci-pipeline-arm64.yml204
-rw-r--r--.github/workflows/ci-pipeline.yml41
-rw-r--r--.github/workflows/gh-pages.yml2
-rw-r--r--CHANGELOG44
-rw-r--r--config/odp-linux-dpdk.conf51
-rw-r--r--config/odp-linux-generic.conf51
-rw-r--r--configure.ac6
-rw-r--r--example/cli/odp_cli.c32
-rw-r--r--example/debug/odp_debug.c16
-rw-r--r--example/ipfragreass/odp_ipfragreass_reassemble.c10
-rw-r--r--example/ipsec_api/.gitignore1
-rw-r--r--example/ipsec_api/Makefile.am42
-rw-r--r--example/ipsec_api/odp_ipsec.c18
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_ah_in.sh39
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_ah_out.sh39
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_ah_tun_in.sh41
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_ah_tun_out.sh41
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_esp_in.sh40
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_esp_out.sh39
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_esp_tun_in.sh42
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_esp_tun_out.sh40
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_live.sh66
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_router.sh56
-rwxr-xr-xexample/ipsec_api/odp_ipsec_api_run_simple.sh34
-rw-r--r--example/ipsec_crypto/.gitignore1
-rw-r--r--example/ipsec_crypto/Makefile.am38
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh43
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh43
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh46
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh46
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh44
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh39
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_live.sh72
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_router.sh56
-rwxr-xr-xexample/ipsec_crypto/odp_ipsec_crypto_run_simple.sh34
-rw-r--r--example/ipsec_crypto/odp_ipsec_stream.c8
-rw-r--r--example/sysinfo/odp_sysinfo.c2
-rw-r--r--example/timer/odp_timer_accuracy.c22
-rw-r--r--example/timer/odp_timer_simple.c4
-rw-r--r--example/timer/odp_timer_test.c16
-rw-r--r--example/traffic_mgmt/odp_traffic_mgmt.c38
-rw-r--r--helper/cli.c409
-rw-r--r--helper/include/odp/helper/cli.h86
-rw-r--r--helper/ipsec.c4
-rw-r--r--helper/test/cli.c12
-rw-r--r--include/odp/api/spec/ipsec.h9
-rw-r--r--include/odp/api/spec/packet_io.h8
-rw-r--r--include/odp/api/spec/time.h55
-rw-r--r--include/odp/api/spec/timer.h109
-rw-r--r--include/odp/api/spec/traffic_mngr.h132
-rw-r--r--platform/linux-dpdk/Makefile.am2
-rw-r--r--platform/linux-dpdk/include/odp/api/plat/time_inlines.h55
-rw-r--r--platform/linux-dpdk/include/odp_packet_io_internal.h7
-rw-r--r--platform/linux-dpdk/m4/configure.m42
-rw-r--r--platform/linux-dpdk/m4/odp_libconfig.m42
-rw-r--r--platform/linux-dpdk/odp_packet.c1
-rw-r--r--platform/linux-dpdk/odp_pool.c2
-rw-r--r--platform/linux-dpdk/odp_queue_basic.c4
-rw-r--r--platform/linux-dpdk/odp_queue_eventdev.c4
-rw-r--r--platform/linux-dpdk/odp_system_info.c2
-rw-r--r--platform/linux-dpdk/odp_time.c14
-rw-r--r--platform/linux-dpdk/odp_timer.c14
-rw-r--r--platform/linux-dpdk/test/Makefile.am31
-rw-r--r--platform/linux-dpdk/test/example/Makefile.am2
-rw-r--r--platform/linux-dpdk/test/example/ipsec_api/Makefile.am23
-rw-r--r--platform/linux-dpdk/test/example/ipsec_api/pktio_env66
-rw-r--r--platform/linux-dpdk/test/example/ipsec_crypto/Makefile.am23
-rw-r--r--platform/linux-dpdk/test/example/ipsec_crypto/pktio_env72
-rw-r--r--platform/linux-dpdk/test/sched-basic.conf2
-rw-r--r--platform/linux-generic/Makefile.am2
-rw-r--r--platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h50
-rw-r--r--platform/linux-generic/arch/aarch64/odp_global_time.c34
-rw-r--r--platform/linux-generic/arch/default/odp/api/abi/cpu_time.h1
-rw-r--r--platform/linux-generic/arch/default/odp_global_time.c5
-rw-r--r--platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h6
-rw-r--r--platform/linux-generic/include/odp/api/plat/time_inlines.h44
-rw-r--r--platform/linux-generic/include/odp_debug_internal.h7
-rw-r--r--platform/linux-generic/include/odp_ipsec_internal.h17
-rw-r--r--platform/linux-generic/include/odp_packet_io_internal.h7
-rw-r--r--platform/linux-generic/m4/configure.m42
-rw-r--r--platform/linux-generic/m4/odp_libconfig.m42
-rw-r--r--platform/linux-generic/odp_comp.c4
-rw-r--r--platform/linux-generic/odp_fdserver.c26
-rw-r--r--platform/linux-generic/odp_ipsec.c156
-rw-r--r--platform/linux-generic/odp_ipsec_sad.c113
-rw-r--r--platform/linux-generic/odp_ishm.c20
-rw-r--r--platform/linux-generic/odp_ishmpool.c2
-rw-r--r--platform/linux-generic/odp_name_table.c1
-rw-r--r--platform/linux-generic/odp_packet_io.c125
-rw-r--r--platform/linux-generic/odp_queue_basic.c4
-rw-r--r--platform/linux-generic/odp_queue_scalable.c2
-rw-r--r--platform/linux-generic/odp_system_info.c2
-rw-r--r--platform/linux-generic/odp_timer.c30
-rw-r--r--platform/linux-generic/odp_traffic_mngr.c67
-rw-r--r--platform/linux-generic/pktio/dpdk.c2
-rw-r--r--platform/linux-generic/pktio/ipc.c6
-rw-r--r--platform/linux-generic/pktio/pktio_common.c5
-rw-r--r--platform/linux-generic/test/Makefile.am34
-rw-r--r--platform/linux-generic/test/example/Makefile.am2
-rw-r--r--platform/linux-generic/test/example/ipsec_api/Makefile.am23
-rw-r--r--platform/linux-generic/test/example/ipsec_api/pktio_env66
-rw-r--r--platform/linux-generic/test/example/ipsec_crypto/Makefile.am23
-rw-r--r--platform/linux-generic/test/example/ipsec_crypto/pktio_env72
-rw-r--r--platform/linux-generic/test/inline-timer.conf2
-rwxr-xr-xplatform/linux-generic/test/ipsec/ipsec_api_example.sh32
-rwxr-xr-xplatform/linux-generic/test/ipsec/ipsec_crypto_example.sh32
-rw-r--r--platform/linux-generic/test/packet_align.conf2
-rw-r--r--platform/linux-generic/test/process-mode.conf2
-rw-r--r--platform/linux-generic/test/sched-basic.conf2
-rwxr-xr-xscripts/ci/build.sh4
-rwxr-xr-xscripts/ci/build_arm64.sh4
-rwxr-xr-xscripts/ci/check.sh2
-rwxr-xr-xscripts/ci/check_inline_timer.sh2
-rwxr-xr-xscripts/ci/check_pktio.sh2
-rwxr-xr-xscripts/ci/coverage.sh2
-rwxr-xr-xscripts/shippable-post.sh15
-rw-r--r--test/common/odp_cunit_common.c45
-rw-r--r--test/common/odp_cunit_common.h4
-rw-r--r--test/performance/odp_ipsec.c7
-rw-r--r--test/performance/odp_sched_pktio.c6
-rw-r--r--test/performance/odp_timer_perf.c6
-rw-r--r--test/validation/api/ipsec/ipsec.c9
-rw-r--r--test/validation/api/ipsec/ipsec.h2
-rw-r--r--test/validation/api/ipsec/ipsec_test_in.c322
-rw-r--r--test/validation/api/ipsec/ipsec_test_out.c40
-rw-r--r--test/validation/api/packet/packet.c32
-rw-r--r--test/validation/api/pktio/pktio.c165
-rw-r--r--test/validation/api/scheduler/scheduler.c124
-rw-r--r--test/validation/api/time/time.c88
-rw-r--r--test/validation/api/timer/timer.c122
-rw-r--r--test/validation/api/traffic_mngr/traffic_mngr.c277
131 files changed, 3897 insertions, 1116 deletions
diff --git a/.github/workflows/ci-pipeline-arm64.yml b/.github/workflows/ci-pipeline-arm64.yml
new file mode 100644
index 000000000..ceedec3e3
--- /dev/null
+++ b/.github/workflows/ci-pipeline-arm64.yml
@@ -0,0 +1,204 @@
+name: CI arm64
+
+# github.repository has been used to ensure CI is only run on the repo where
+# self-hosted runners are installed. This will prevent [self-hosted, ARM64] CI failing on forks
+
+on: [push, pull_request]
+env:
+ ARCH: arm64
+ CC: gcc
+ CONTAINER_NAMESPACE: ghcr.io/opendataplane/odp-docker-images
+ OS: ubuntu_20.04
+
+jobs:
+
+ Build:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ cc: [gcc, clang]
+ conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', '--enable-lto',
+ '--enable-lto --enable-abi-compat', '--enable-pcapng-support']
+ exclude:
+ - cc: clang
+ conf: '--enable-lto'
+ - cc: clang
+ conf: '--enable-lto --enable-abi-compat'
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}"
+ -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh
+
+ Build_OS:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ cc: [gcc, clang]
+ os: ['ubuntu_16.04', 'ubuntu_18.04']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}"
+ -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${{matrix.os}}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh
+
+ Build_gcc-10:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ env:
+ CC: gcc-10
+ strategy:
+ fail-fast: false
+ matrix:
+ conf: ['', '--enable-lto']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh
+
+ Build_out-of-tree:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/out_of_tree.sh
+
+
+ Build_sched_config:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ -e CONF="--enable-debug=full" -e ODP_CONFIG_FILE=/odp/platform/linux-generic/test/sched-basic.conf
+ $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/build_${ARCH}.sh
+
+ Run_distcheck:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ conf: ['--enable-user-guides', '--enable-user-guides --enable-abi-compat']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}"
+ -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/distcheck.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+
+ Run:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ cc: [gcc, clang]
+ conf: ['', '--enable-abi-compat', '--enable-deprecated --enable-debug=full',
+ '--enable-dpdk-zero-copy --disable-static-applications',
+ '--disable-host-optimization', '--disable-host-optimization --enable-abi-compat',
+ '--without-openssl --without-pcap']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}"
+ -e CXX=g++-10 -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+
+ Run_OS:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ os: ['ubuntu_18.04']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${{matrix.os}}-${ARCH}-native /odp/scripts/ci/check.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+ Run_scheduler_sp:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" -e ODP_SCHEDULER=sp $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+ Run_scheduler_scalable:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" -e ODP_SCHEDULER=scalable -e CI_SKIP=pktio_test_pktin_event_sched $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+ Run_inline_timer:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" -e ODP_CONFIG_FILE=/odp/platform/linux-generic/test/inline-timer.conf
+ $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check_inline_timer.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+
+ Run_packet_align:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" -e ODP_CONFIG_FILE=/odp/platform/linux-generic/test/packet_align.conf
+ $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-native /odp/scripts/ci/check_pktio.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
+
+
+ Run_dpdk-18_11:
+ if: ${{ github.repository == 'OpenDataPlane/odp' }}
+ runs-on: [self-hosted, ARM64]
+ strategy:
+ fail-fast: false
+ matrix:
+ os: ['ubuntu_18.04']
+ steps:
+ - uses: AutoModality/action-clean@v1.1.0
+ - uses: actions/checkout@v2
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${{matrix.os}}-${ARCH}-native-dpdk_18.11 /odp/scripts/ci/check.sh
+ - name: Failure log
+ if: ${{ failure() }}
+ run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml
index c3109ff2c..089d96c2c 100644
--- a/.github/workflows/ci-pipeline.yml
+++ b/.github/workflows/ci-pipeline.yml
@@ -1,4 +1,4 @@
-name: CI
+name: CI x86_64
on: [push, pull_request]
env:
@@ -58,15 +58,14 @@ jobs:
make doxygen-doc 2>&1 | tee ./doxygen.log
! fgrep -rq warning ./doxygen.log
- Build_x86_64:
+ Build:
runs-on: ubuntu-18.04
- env:
- ARCH: x86_64
strategy:
fail-fast: false
matrix:
cc: [gcc, clang]
- conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', '--enable-lto', '--enable-lto --enable-abi-compat', '--enable-pcapng-support']
+ conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', '--enable-lto',
+ '--enable-lto --enable-abi-compat', '--enable-pcapng-support']
exclude:
- cc: clang
conf: '--enable-lto'
@@ -135,8 +134,6 @@ jobs:
Build_OS:
runs-on: ubuntu-18.04
- env:
- ARCH: x86_64
strategy:
fail-fast: false
matrix:
@@ -151,7 +148,6 @@ jobs:
Build_gcc-10:
runs-on: ubuntu-18.04
env:
- ARCH: x86_64
CC: gcc-10
OS: ubuntu_20.04
strategy:
@@ -214,18 +210,19 @@ jobs:
if: ${{ failure() }}
run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
- Run_x86_64:
+ Run:
runs-on: ubuntu-18.04
- env:
- ARCH: x86_64
strategy:
fail-fast: false
matrix:
cc: [gcc, clang]
- conf: ['', '--enable-abi-compat', '--enable-deprecated', '--disable-static-applications', '--disable-host-optimization', '--disable-host-optimization --enable-abi-compat', '--without-openssl --without-pcap']
+ conf: ['', '--enable-abi-compat', '--enable-deprecated --enable-debug=full',
+ '--disable-static-applications',
+ '--disable-host-optimization', '--disable-host-optimization --enable-abi-compat',
+ '--without-openssl --without-pcap']
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}"
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}"
-e CXX=g++-10 -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
@@ -240,22 +237,18 @@ jobs:
os: ['ubuntu_20.04']
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}"
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}"
-e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${{matrix.os}}-${ARCH} /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
- Run_scheduler:
+ Run_scheduler_sp:
runs-on: ubuntu-18.04
- strategy:
- fail-fast: false
- matrix:
- scheduler: ['sp']
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
- -e CONF="${CONF}" -e ODP_SCHEDULER=${{matrix.scheduler}} $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
+ -e CONF="${CONF}" -e ODP_SCHEDULER=sp $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
@@ -264,7 +257,7 @@ jobs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
-e CONF="${CONF}" -e ODPH_PROC_MODE=1 $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
@@ -274,7 +267,7 @@ jobs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
-e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-dpdk_18.11 /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
@@ -287,7 +280,7 @@ jobs:
OS: ubuntu_20.04
steps:
- uses: actions/checkout@v2
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}"
+ - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" -e ARCH="${ARCH}"
-e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH}-dpdk_20.11 /odp/scripts/ci/check.sh
- name: Failure log
if: ${{ failure() }}
diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml
index 0c5e187c4..e347efa6f 100644
--- a/.github/workflows/gh-pages.yml
+++ b/.github/workflows/gh-pages.yml
@@ -29,8 +29,6 @@ jobs:
run: |
pushd doc
mkdir gh-pages
- # Prevent Shippable run on gh-pages branch
- printf "branches:\n except:\n - gh-pages\n" >> gh-pages/.shippable.yml
cp -r application-api-guide/output/html/* gh-pages/
cp -r platform-api-guide/output/html/ gh-pages/platform-api-guide
cp -r helper-guide/output/html/ gh-pages/helper-guide
diff --git a/CHANGELOG b/CHANGELOG
index 0c2fcbda3..5d771cf7d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,47 @@
+== OpenDataPlane (1.30.0.0)
+=== API
+==== IPsec
+* New success bytes field in stats (`odp_ipsec_stats_t.success_bytes`)
+
+==== Packet IO
+* Specify explicitly that an application may enqueue to packet input side event
+queues, and cannot dequeue from output side event queues
+
+==== Time
+* Added time stamp read functions which read time stamp value more strictly
+in the program order: `odp_time_local_strict()`, `odp_time_local_strict_ns()`,
+`odp_time_global_strict()`, `odp_time_global_strict_ns()`
+
+==== Timer
+* Added new default clock source enumeration `ODP_CLOCK_DEFAULT`
+(=`ODP_CLOCK_SRC_0`) and support for multiple clock sources (`ODP_CLOCK_SRC_1`,
+`ODP_CLOCK_SRC_2`...). The old `ODP_CLOCK_CPU` and `ODP_CLOCK_EXT` enumerations
+will be deprecated in the future.
+* Renamed set operation return codes (`odp_timer_set_t`) to better document
+expiration time position to current time:
+`ODP_TIMER_TOOEARLY` -> `ODP_TIMER_TOO_NEAR`, `ODP_TIMER_TOOLATE` ->
+`ODP_TIMER_TOO_FAR`
+* Renamed set operation failure code (`odp_timer_set_t`) to cover all error
+cases: `ODP_TIMER_NOEVENT` -> `ODP_TIMER_FAIL`
+
+==== Traffic Manager
+* Added option to enable packet mode shaper (packets per second as opposed to
+bits per second)
+* Added new mandatory `odp_tm_start()` and `odp_tm_stop()` calls for starting and
+stopping traffic manager system
+* Added capabilities (`odp_tm_capabilities_t`) for supported dynamic
+configuration updates
+* Deprecated shaper commit information rate bps
+(`odp_tm_shaper_params_t.commit_bps`) and peak information rate bps
+(`odp_tm_shaper_params_t.peak_bps`) fields. `odp_tm_shaper_params_t.commit_rate`
+and `odp_tm_shaper_params_t.peak_rate` fields should be used instead.
+
+=== Helper (1.1.0)
+* Added new mandatory `odph_cli_init()` and `odph_cli_term()` functions for
+initializing and terminating the CLI helper
+* Added `odph_cli_register_command()` function for registering user defined CLI
+commands
+
== OpenDataPlane (1.29.0.0)
=== API
==== Packet IO
diff --git a/config/odp-linux-dpdk.conf b/config/odp-linux-dpdk.conf
index 0c541fdd5..cc63c1576 100644
--- a/config/odp-linux-dpdk.conf
+++ b/config/odp-linux-dpdk.conf
@@ -16,7 +16,7 @@
# Mandatory fields
odp_implementation = "linux-dpdk"
-config_file_version = "0.1.11"
+config_file_version = "0.1.12"
# System options
system: {
@@ -171,3 +171,52 @@ timer: {
# accordingly.
inline_poll_interval_nsec = 500000
}
+
+ipsec: {
+ # Packet ordering method for asynchronous IPsec processing
+ #
+ # Asynchronous IPsec processing maintains original packet order when
+ # started within ordered or atomic scheduling context. In addition
+ # to that, ODP API specifies that the order of IPsec processing
+ # (i.e. anti-replay window update and sequence number generation)
+ # is the same as the original packet order.
+ #
+ # The following settings control how the order is maintained in
+ # asynchronous IPsec operations. They have no effect on synchronous
+ # operations where the ODP application is responsible of the ordering.
+ #
+ # Values:
+ #
+ # 0: Ordering is not attempted.
+ #
+ # This has the lowest overhead and the greatest parallelism but
+ # is not fully compliant with the API specification.
+ #
+ # Lack of ordering means that outbound IPsec packets, although
+ # remaining in the correct order, may have their sequence numbers
+ # assigned out of order. This can cause unexpected packet loss if
+ # the anti-replay window of the receiving end is not large enough
+ # to cover the possible misordering.
+ #
+ # Similarly, since anti-replay check is not done in the reception
+ # order, the anti-replay check sees additional packet misordering
+ # on top of the true misordering of the received packets. This
+ # means that a larger anti-replay window may be required to avoid
+ # packet loss.
+ #
+ # 1: Ordering by waiting
+ #
+ # Correct processing order is maintained by a simple mechanism
+ # that makes a thread wait until its scheduling context has
+ # reached the head of its input queue.
+ #
+ # This limits parallelism when single input queue is used, even
+ # when packets get distributed to multiple SAs.
+ ordering: {
+ # Odering method for asynchronous inbound operations.
+ async_inbound = 0
+
+ # Odering method for asynchronous outbound operations.
+ async_outbound = 0
+ }
+}
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf
index 8469b72d7..3ac3e3e58 100644
--- a/config/odp-linux-generic.conf
+++ b/config/odp-linux-generic.conf
@@ -16,7 +16,7 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.15"
+config_file_version = "0.1.16"
# System options
system: {
@@ -234,3 +234,52 @@ timer: {
# 2: Only control threads process non-private timer pools
inline_thread_type = 0
}
+
+ipsec: {
+ # Packet ordering method for asynchronous IPsec processing
+ #
+ # Asynchronous IPsec processing maintains original packet order when
+ # started within ordered or atomic scheduling context. In addition
+ # to that, ODP API specifies that the order of IPsec processing
+ # (i.e. anti-replay window update and sequence number generation)
+ # is the same as the original packet order.
+ #
+ # The following settings control how the order is maintained in
+ # asynchronous IPsec operations. They have no effect on synchronous
+ # operations where the ODP application is responsible of the ordering.
+ #
+ # Values:
+ #
+ # 0: Ordering is not attempted.
+ #
+ # This has the lowest overhead and the greatest parallelism but
+ # is not fully compliant with the API specification.
+ #
+ # Lack of ordering means that outbound IPsec packets, although
+ # remaining in the correct order, may have their sequence numbers
+ # assigned out of order. This can cause unexpected packet loss if
+ # the anti-replay window of the receiving end is not large enough
+ # to cover the possible misordering.
+ #
+ # Similarly, since anti-replay check is not done in the reception
+ # order, the anti-replay check sees additional packet misordering
+ # on top of the true misordering of the received packets. This
+ # means that a larger anti-replay window may be required to avoid
+ # packet loss.
+ #
+ # 1: Ordering by waiting
+ #
+ # Correct processing order is maintained by a simple mechanism
+ # that makes a thread wait until its scheduling context has
+ # reached the head of its input queue.
+ #
+ # This limits parallelism when single input queue is used, even
+ # when packets get distributed to multiple SAs.
+ ordering: {
+ # Odering method for asynchronous inbound operations.
+ async_inbound = 0
+
+ # Odering method for asynchronous outbound operations.
+ async_outbound = 0
+ }
+}
diff --git a/configure.ac b/configure.ac
index e84cb3297..1bc682712 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.5])
# ODP API version
##########################################################################
m4_define([odpapi_generation_version], [1])
-m4_define([odpapi_major_version], [29])
+m4_define([odpapi_major_version], [30])
m4_define([odpapi_minor_version], [0])
m4_define([odpapi_point_version], [0])
m4_define([odpapi_version],
@@ -21,8 +21,8 @@ AC_SUBST(ODP_VERSION_API_MINOR)
# Helper library version
##########################################################################
m4_define([odph_version_generation], [1])
-m4_define([odph_version_major], [0])
-m4_define([odph_version_minor], [6])
+m4_define([odph_version_major], [1])
+m4_define([odph_version_minor], [0])
m4_define([odph_version],
[odph_version_generation.odph_version_major.odph_version_minor])
diff --git a/example/cli/odp_cli.c b/example/cli/odp_cli.c
index e3998129c..597d01812 100644
--- a/example/cli/odp_cli.c
+++ b/example/cli/odp_cli.c
@@ -88,6 +88,14 @@ static void sig_handler(int signo)
shutdown_sig = 1;
}
+static void my_cmd(int argc, char *argv[])
+{
+ odph_cli_log("%s(%d): %s\n", __FILE__, __LINE__, __func__);
+
+ for (int i = 0; i < argc; i++)
+ odph_cli_log("argv[%d]: %s\n", i, argv[i]);
+}
+
int main(int argc, char *argv[])
{
signal(SIGINT, sig_handler);
@@ -140,13 +148,27 @@ int main(int argc, char *argv[])
if (opt.port)
cli_param.port = opt.port;
+ /* Initialize CLI helper. */
+ if (odph_cli_init(inst, &cli_param)) {
+ ODPH_ERR("CLI helper initialization failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Register user command. */
+ if (odph_cli_register_command("my_command", my_cmd,
+ "Example user command.")) {
+ ODPH_ERR("Registering user command failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
/* Start CLI server. */
- if (odph_cli_start(inst, &cli_param)) {
+ if (odph_cli_start()) {
ODPH_ERR("CLI start failed.\n");
exit(EXIT_FAILURE);
}
- printf("CLI server started on %s:%d\n", cli_param.address, cli_param.port);
+ printf("CLI server started on %s:%d\n", cli_param.address,
+ cli_param.port);
/* Wait for the given number of seconds. */
for (int i = 0; (opt.time < 0 || i < opt.time) && !shutdown_sig; i++)
@@ -160,6 +182,12 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ /* Terminate CLI helper. */
+ if (odph_cli_term()) {
+ ODPH_ERR("CLI helper termination failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
/* Terminate ODP. */
if (odp_term_local()) {
diff --git a/example/debug/odp_debug.c b/example/debug/odp_debug.c
index 48591134a..24364a688 100644
--- a/example/debug/odp_debug.c
+++ b/example/debug/odp_debug.c
@@ -346,6 +346,7 @@ static int timer_debug(void)
odp_pool_t pool;
odp_pool_param_t pool_param;
odp_timeout_t timeout;
+ odp_timer_res_capability_t timer_res_capa;
odp_timer_capability_t timer_capa;
odp_timer_pool_t timer_pool;
odp_timer_pool_param_t timer_param;
@@ -374,7 +375,7 @@ static int timer_debug(void)
return -1;
}
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)) {
ODPH_ERR("Timer capa failed\n");
return -1;
}
@@ -382,15 +383,22 @@ static int timer_debug(void)
if (timer_capa.max_tmo.max_tmo < max_tmo)
max_tmo = timer_capa.max_tmo.max_tmo;
- if (timer_capa.max_tmo.res_ns > res)
- res = timer_capa.max_tmo.res_ns;
+ memset(&timer_res_capa, 0, sizeof(odp_timer_res_capability_t));
+ timer_res_capa.max_tmo = max_tmo;
+ if (odp_timer_res_capability(ODP_CLOCK_DEFAULT, &timer_res_capa)) {
+ ODPH_ERR("Timer resolution capability failed\n");
+ return -1;
+ }
+
+ if (timer_res_capa.res_ns > res)
+ res = timer_res_capa.res_ns;
memset(&timer_param, 0, sizeof(timer_param));
timer_param.res_ns = res;
timer_param.min_tmo = max_tmo / 10;
timer_param.max_tmo = max_tmo;
timer_param.num_timers = 10;
- timer_param.clk_src = ODP_CLOCK_CPU;
+ timer_param.clk_src = ODP_CLOCK_DEFAULT;
timer_pool = odp_timer_pool_create("debug_timer", &timer_param);
diff --git a/example/ipfragreass/odp_ipfragreass_reassemble.c b/example/ipfragreass/odp_ipfragreass_reassemble.c
index 35742d3a5..fba900f7a 100644
--- a/example/ipfragreass/odp_ipfragreass_reassemble.c
+++ b/example/ipfragreass/odp_ipfragreass_reassemble.c
@@ -303,11 +303,17 @@ static int send_packet(struct packet *tail, odp_queue_t out)
*/
while (current && equal_flow(current, &result)) {
struct packet new_result = *current;
- int concat_success;
+ int concat_success, trunc_success;
current = prev_packet(new_result);
header = odp_packet_data(result.handle);
- odp_packet_pull_head(result.handle, ipv4hdr_ihl(*header));
+ trunc_success = odp_packet_trunc_head(&result.handle, ipv4hdr_ihl(*header),
+ NULL, NULL);
+ if (trunc_success < 0) {
+ fprintf(stderr, "ERROR: odp_packet_trunc_head\n");
+ return -1;
+ }
+
concat_success = odp_packet_concat(&new_result.handle,
result.handle);
if (concat_success < 0) {
diff --git a/example/ipsec_api/.gitignore b/example/ipsec_api/.gitignore
index 78ef1173c..77f399c54 100644
--- a/example/ipsec_api/.gitignore
+++ b/example/ipsec_api/.gitignore
@@ -1 +1,2 @@
odp_ipsec_api
+pktio_env
diff --git a/example/ipsec_api/Makefile.am b/example/ipsec_api/Makefile.am
index b3621fcd2..05471008d 100644
--- a/example/ipsec_api/Makefile.am
+++ b/example/ipsec_api/Makefile.am
@@ -2,18 +2,31 @@ include $(top_srcdir)/example/Makefile.inc
bin_PROGRAMS = odp_ipsec_api
-dist_check_SCRIPTS = \
- odp_ipsec_api_run_ah_in.sh \
- odp_ipsec_api_run_ah_out.sh \
- odp_ipsec_api_run_ah_tun_in.sh \
- odp_ipsec_api_run_ah_tun_out.sh \
- odp_ipsec_api_run_esp_in.sh \
- odp_ipsec_api_run_esp_out.sh \
- odp_ipsec_api_run_esp_tun_in.sh \
- odp_ipsec_api_run_esp_tun_out.sh \
- odp_ipsec_api_run_live.sh \
- odp_ipsec_api_run_router.sh \
- odp_ipsec_api_run_simple.sh
+if test_example
+TESTS = \
+ odp_ipsec_api_run_ah_in.sh \
+ odp_ipsec_api_run_ah_out.sh \
+ odp_ipsec_api_run_ah_tun_in.sh \
+ odp_ipsec_api_run_ah_tun_out.sh \
+ odp_ipsec_api_run_esp_in.sh \
+ odp_ipsec_api_run_esp_out.sh \
+ odp_ipsec_api_run_esp_tun_in.sh \
+ odp_ipsec_api_run_esp_tun_out.sh \
+ odp_ipsec_api_run_simple.sh
+endif
+
+EXTRA_DIST = \
+ odp_ipsec_api_run_ah_in.sh \
+ odp_ipsec_api_run_ah_out.sh \
+ odp_ipsec_api_run_ah_tun_in.sh \
+ odp_ipsec_api_run_ah_tun_out.sh \
+ odp_ipsec_api_run_esp_in.sh \
+ odp_ipsec_api_run_esp_out.sh \
+ odp_ipsec_api_run_esp_tun_in.sh \
+ odp_ipsec_api_run_esp_tun_out.sh \
+ odp_ipsec_api_run_live.sh \
+ odp_ipsec_api_run_router.sh \
+ odp_ipsec_api_run_simple.sh
odp_ipsec_api_SOURCES = \
odp_ipsec.c \
@@ -45,16 +58,17 @@ endif
# So copy all script and data files explicitly here.
all-local:
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
- for f in $(dist_check_SCRIPTS); do \
+ 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 ../../platform/$(with_platform)/test/example/ipsec_api/pktio_env pktio_env
clean-local:
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
- for f in $(dist_check_SCRIPTS); do \
+ for f in $(EXTRA_DIST); do \
rm -f $(builddir)/$$f; \
done \
fi
diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c
index 98e31d6ce..d23eeb2c6 100644
--- a/example/ipsec_api/odp_ipsec.c
+++ b/example/ipsec_api/odp_ipsec.c
@@ -640,11 +640,20 @@ pkt_disposition_e do_ipsec_in_classify(odp_packet_t *ppkt)
return PKT_POSTED;
} else {
int out = 1;
+ odp_ipsec_packet_result_t result;
rc = odp_ipsec_in(ppkt, 1, ppkt, &out, &in_param);
if (rc <= 0)
return PKT_DROP;
+ if (odp_ipsec_result(&result, *ppkt) < 0) {
+ ODPH_DBG("odp_ipsec_result() failed\n");
+ return PKT_DROP;
+ }
+ if (result.status.error.all != 0) {
+ ODPH_DBG("Error in inbound IPsec processing\n");
+ return PKT_DROP;
+ }
return PKT_CONTINUE;
}
}
@@ -704,11 +713,20 @@ pkt_disposition_e do_ipsec_out_classify(odp_packet_t *ppkt, pkt_ctx_t *ctx)
return PKT_POSTED;
} else {
int out = 1;
+ odp_ipsec_packet_result_t result;
rc = odp_ipsec_out(ppkt, 1, ppkt, &out, &out_param);
if (rc <= 0)
return PKT_DROP;
+ if (odp_ipsec_result(&result, *ppkt) < 0) {
+ ODPH_DBG("odp_ipsec_result() failed\n");
+ return PKT_DROP;
+ }
+ if (result.status.error.all != 0) {
+ ODPH_DBG("Error in outbound IPsec processing\n");
+ return PKT_DROP;
+ }
return PKT_CONTINUE;
}
}
diff --git a/example/ipsec_api/odp_ipsec_api_run_ah_in.sh b/example/ipsec_api/odp_ipsec_api_run_ah_in.sh
index 22a56f380..3aa8ea577 100755
--- a/example/ipsec_api/odp_ipsec_api_run_ah_in.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_ah_in.sh
@@ -4,9 +4,36 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_ah_out.sh b/example/ipsec_api/odp_ipsec_api_run_ah_out.sh
index 8194485a4..2712da52a 100755
--- a/example/ipsec_api/odp_ipsec_api_run_ah_out.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_ah_out.sh
@@ -4,9 +4,36 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_ah_tun_in.sh b/example/ipsec_api/odp_ipsec_api_run_ah_tun_in.sh
index 89331bbea..f6efc3869 100755
--- a/example/ipsec_api/odp_ipsec_api_run_ah_tun_in.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_ah_tun_in.sh
@@ -4,10 +4,37 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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 \
--t 192.168.222.2,192.168.111.2,10.0.222.2,10.0.111.2 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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 \
+ -t 192.168.222.2,192.168.111.2,10.0.222.2,10.0.111.2 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_ah_tun_out.sh b/example/ipsec_api/odp_ipsec_api_run_ah_tun_out.sh
index bd15f5956..ec888d314 100755
--- a/example/ipsec_api/odp_ipsec_api_run_ah_tun_out.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_ah_tun_out.sh
@@ -4,10 +4,37 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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 \
--t 192.168.111.2,192.168.222.2,10.0.111.2,10.0.222.2 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -t 192.168.111.2,192.168.222.2,10.0.111.2,10.0.222.2 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_esp_in.sh b/example/ipsec_api/odp_ipsec_api_run_esp_in.sh
index 61873bf76..1c3414498 100755
--- a/example/ipsec_api/odp_ipsec_api_run_esp_in.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_esp_in.sh
@@ -4,10 +4,36 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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,\
-3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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,3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_esp_out.sh b/example/ipsec_api/odp_ipsec_api_run_esp_out.sh
index 834daa4cc..c9809e8ac 100755
--- a/example/ipsec_api/odp_ipsec_api_run_esp_out.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_esp_out.sh
@@ -5,14 +5,39 @@
# - 10 packets
# - Specify API mode on command line
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${IPSEC_EXAMPLE_PATH}/odp_ipsec_api -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,\
-3des,201,656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 "$@"
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_api -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_esp_tun_in.sh b/example/ipsec_api/odp_ipsec_api_run_esp_tun_in.sh
index 42be4559f..3b4f91e41 100755
--- a/example/ipsec_api/odp_ipsec_api_run_esp_tun_in.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_esp_tun_in.sh
@@ -4,11 +4,37 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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,\
-3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
--t 192.168.222.2,192.168.111.2,10.0.222.2,10.0.111.2 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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,3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
+ -t 192.168.222.2,192.168.111.2,10.0.222.2,10.0.111.2 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_esp_tun_out.sh b/example/ipsec_api/odp_ipsec_api_run_esp_tun_out.sh
index 7b0c42bcb..a4c62e226 100755
--- a/example/ipsec_api/odp_ipsec_api_run_esp_tun_out.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_esp_tun_out.sh
@@ -4,10 +4,36 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./odp_ipsec_api -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,\
-3des,201,656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+./odp_ipsec_api -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_api/odp_ipsec_api_run_live.sh b/example/ipsec_api/odp_ipsec_api_run_live.sh
index 318e640fe..da8523485 100755
--- a/example/ipsec_api/odp_ipsec_api_run_live.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_live.sh
@@ -3,13 +3,59 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-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 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=1
+
+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
+
+setup_interfaces
+
+# this just turns off output buffering so that you still get periodic
+# output while piping to tee, as long as stdbuf is available.
+STDBUF="`which stdbuf 2>/dev/null` -o 0" || STDBUF=
+LOG=odp_ipsec_api_tmp.log
+PID=app_pid
+
+($STDBUF \
+ ./odp_ipsec_api -i $IF0,$IF1 \
+ -r 192.168.111.2/32,$IF0,$NEXT_HOP_MAC0 \
+ -r 192.168.222.2/32,$IF1,$NEXT_HOP_MAC1 \
+ -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 "$@" & echo $! > $PID) | tee $LOG &
+
+APP_PID=`cat $PID`
+
+# Wait till application thread starts.
+APP_READY="Pktio thread \[..\] starts"
+
+until [ -f $LOG ]
+do
+ sleep 1
+done
+
+tail -f $LOG | grep -qm 1 "$APP_READY"
+
+validate_result
+ret=$?
+
+kill -2 ${APP_PID}
+
+# Wait till the application exits
+tail --pid=$APP_PID -f /dev/null
+
+rm -f $PID
+rm -f $LOG
+
+cleanup_interfaces
+
+exit $ret
diff --git a/example/ipsec_api/odp_ipsec_api_run_router.sh b/example/ipsec_api/odp_ipsec_api_run_router.sh
index 2cdbd2272..79a0ef5c6 100755
--- a/example/ipsec_api/odp_ipsec_api_run_router.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_router.sh
@@ -3,7 +3,55 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-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 \
--c 1 "$@"
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=2
+
+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
+
+setup_interfaces
+
+# this just turns off output buffering so that you still get periodic
+# output while piping to tee, as long as stdbuf is available.
+STDBUF="`which stdbuf 2>/dev/null` -o 0" || STDBUF=
+LOG=odp_ipsec_api_tmp.log
+PID=app_pid
+
+($STDBUF \
+ ./odp_ipsec_api -i $IF0,$IF1 \
+ -r 192.168.111.2/32,$IF0,$NEXT_HOP_MAC0 \
+ -r 192.168.222.2/32,$IF1,$NEXT_HOP_MAC1 \
+ -c 1 "$@" & echo $! > $PID) | tee -a $LOG &
+
+APP_PID=`cat $PID`
+
+# Wait till application thread starts.
+APP_READY="Pktio thread \[..\] starts"
+
+until [ -f $LOG ]
+do
+ sleep 1
+done
+
+tail -f $LOG | grep -qm 1 "$APP_READY"
+
+validate_result
+ret=$?
+
+kill -2 ${APP_PID}
+
+# Wait till the application stops
+tail --pid=$APP_PID -f /dev/null
+
+rm -f $PID
+rm -f $LOG
+
+cleanup_interfaces
+
+exit $ret
diff --git a/example/ipsec_api/odp_ipsec_api_run_simple.sh b/example/ipsec_api/odp_ipsec_api_run_simple.sh
index 56c022291..2921f978b 100755
--- a/example/ipsec_api/odp_ipsec_api_run_simple.sh
+++ b/example/ipsec_api/odp_ipsec_api_run_simple.sh
@@ -5,11 +5,37 @@
# - 10 packets
# - Specify API mode on command line
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${IPSEC_EXAMPLE_PATH}/odp_ipsec_api -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 "$@"
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_api -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,08:00:27:F5:8B:DB \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/.gitignore b/example/ipsec_crypto/.gitignore
index 2467edfd4..e8b9e69a1 100644
--- a/example/ipsec_crypto/.gitignore
+++ b/example/ipsec_crypto/.gitignore
@@ -1 +1,2 @@
odp_ipsec_crypto
+pktio_env
diff --git a/example/ipsec_crypto/Makefile.am b/example/ipsec_crypto/Makefile.am
index 2e3652252..1db0d72d0 100644
--- a/example/ipsec_crypto/Makefile.am
+++ b/example/ipsec_crypto/Makefile.am
@@ -2,16 +2,28 @@ 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
+if test_example
+TESTS = \
+ 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
+endif
+EXTRA_DIST = \
+ 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 \
@@ -43,16 +55,18 @@ endif
# So copy all script and data files explicitly here.
all-local:
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
- for f in $(dist_check_SCRIPTS); do \
+ 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 ../../platform/$(with_platform)/test/example/ipsec_crypto/pktio_env pktio_env
clean-local:
if [ "x$(srcdir)" != "x$(builddir)" ]; then \
- for f in $(dist_check_SCRIPTS); do \
+ for f in $(EXTRA_DIST); do \
rm -f $(builddir)/$$f; \
done \
fi
+ rm -f pktio_env
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh
index b64fd7d2d..0c8112306 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_in.sh
@@ -4,9 +4,40 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./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 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
+IPSEC_EXAMPLE_PATH=.
+fi
+
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh
index 0ff42289c..b0bb210f5 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_ah_out.sh
@@ -4,9 +4,40 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./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 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
+IPSEC_EXAMPLE_PATH=.
+fi
+
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh
index a986b713e..4b8c6ab63 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_both_in.sh
@@ -4,11 +4,41 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./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 \
--e 192.168.222.2,192.168.111.2,\
-3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
+IPSEC_EXAMPLE_PATH=.
+fi
+
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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 \
+ -e 192.168.222.2,192.168.111.2,3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh
index ebbcde071..665534d98 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_both_out.sh
@@ -4,11 +4,41 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./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,\
-3des,201,656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
--a 192.168.111.2,192.168.222.2,md5,200,a731649644c5dee92cbd9c2e7e188ee6 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
+IPSEC_EXAMPLE_PATH=.
+fi
+
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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,3des,201,656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
+ -a 192.168.111.2,192.168.222.2,md5,200,a731649644c5dee92cbd9c2e7e188ee6 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh
index cdf84c517..6e6ff5769 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_in.sh
@@ -4,10 +4,40 @@
# - 2 loop interfaces
# - 10 packets
# - Specify API mode on command line
-./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,\
-3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
--s 192.168.222.2,192.168.111.2,loop2,loop1,10,100 \
--c 2 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
+if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
+IPSEC_EXAMPLE_PATH=.
+fi
+
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.111.2/32,$ROUTE_IF_INB,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,3des,301,c966199f24d095f3990a320d749056401e82b26570320292 \
+ -s 192.168.222.2,192.168.111.2,$OUT_IF,$IN_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh
index ae257be4f..2b7107f80 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_esp_out.sh
@@ -5,14 +5,39 @@
# - 10 packets
# - Specify API mode on command line
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${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,\
-3des,201,656c8523255ccc23a66c1917aa0cf30991fce83532a4b224 \
--s 192.168.111.2,192.168.222.2,loop1,loop2,10,100 \
--c 2 "$@"
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,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 \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh
index c212097e0..90dda11ec 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_live.sh
@@ -3,15 +3,63 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-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 \
--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 \
--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 -m $1
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=1
+
+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
+
+setup_interfaces
+
+# this just turns off output buffering so that you still get periodic
+# output while piping to tee, as long as stdbuf is available.
+STDBUF="`which stdbuf 2>/dev/null` -o 0" || STDBUF=
+LOG=odp_ipsec_crypto_tmp.log
+PID=app_pid
+
+($STDBUF \
+ ./odp_ipsec_crypto -i $IF0,$IF1 \
+ -r 192.168.111.2/32,$IF0,$NEXT_HOP_MAC0 \
+ -r 192.168.222.2/32,$IF1,$NEXT_HOP_MAC1 \
+ -p 192.168.111.0/24,192.168.222.0/24,out,both \
+ -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 \
+ -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 "$@" & echo $! > $PID) | tee -a $LOG &
+
+APP_PID=`cat $PID`
+
+# Wait till application thread starts.
+APP_READY="Pktio thread \[..\] starts"
+
+until [ -f $LOG ]
+do
+ sleep 1
+done
+
+tail -f $LOG | grep -qm 1 "$APP_READY"
+
+validate_result
+ret=$?
+
+kill -2 ${APP_PID}
+
+# Wait till the application exits
+tail --pid=$APP_PID -f /dev/null
+
+rm -f $PID
+rm -f $LOG
+
+cleanup_interfaces
+
+exit $ret
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh
index d08490946..675027b59 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_router.sh
@@ -3,7 +3,55 @@
# Live router test
# - 2 interfaces interfaces
# - Specify API mode on command line
-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
+
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=2
+
+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
+
+setup_interfaces
+
+# this just turns off output buffering so that you still get periodic
+# output while piping to tee, as long as stdbuf is available.
+STDBUF="`which stdbuf 2>/dev/null` -o 0" || STDBUF=
+LOG=odp_ipsec_crypto_tmp.log
+PID=app_pid
+
+($STDBUF \
+ ./odp_ipsec_crypto -i $IF0,$IF1 \
+ -r 192.168.111.2/32,$IF0,$NEXT_HOP_MAC0 \
+ -r 192.168.222.2/32,$IF1,$NEXT_HOP_MAC1 \
+ -c 1 "$@" & echo $! > $PID) | tee -a $LOG &
+
+APP_PID=`cat $PID`
+
+# Wait till application thread starts.
+APP_READY="Pktio thread \[..\] starts"
+
+until [ -f $LOG ]
+do
+ sleep 1
+done
+
+tail -f $LOG | grep -qm 1 "$APP_READY"
+
+validate_result
+ret=$?
+
+kill -2 ${APP_PID}
+
+# Wait till the application exits
+tail --pid=$APP_PID -f /dev/null
+
+rm -f $PID
+rm -f $LOG
+
+cleanup_interfaces
+
+exit $ret
diff --git a/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh b/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh
index 5d3abcd51..00b176b36 100755
--- a/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh
+++ b/example/ipsec_crypto/odp_ipsec_crypto_run_simple.sh
@@ -5,11 +5,37 @@
# - 10 packets
# - Specify API mode on command line
+# IPSEC_APP_MODE: 0 - STANDALONE, 1 - LIVE, 2 - ROUTER
+IPSEC_APP_MODE=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
+
+setup_interfaces
+
if [ -z "$IPSEC_EXAMPLE_PATH" ]; then
IPSEC_EXAMPLE_PATH=.
fi
-${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 "$@"
+${IPSEC_EXAMPLE_PATH}/odp_ipsec_crypto -i $IF_LIST \
+ -r 192.168.222.2/32,$ROUTE_IF_OUTB,08:00:27:F5:8B:DB \
+ -s 192.168.111.2,192.168.222.2,$IN_IF,$OUT_IF,10,100 \
+ -c 2 "$@"
+
+STATUS=$?
+
+if [ ${STATUS} -ne 0 ]; then
+ echo "Error: status ${STATUS}"
+ exit 1
+fi
+
+validate_result
+
+cleanup_interfaces
+
+exit 0
diff --git a/example/ipsec_crypto/odp_ipsec_stream.c b/example/ipsec_crypto/odp_ipsec_stream.c
index e53dbce0d..0ca5138bc 100644
--- a/example/ipsec_crypto/odp_ipsec_stream.c
+++ b/example/ipsec_crypto/odp_ipsec_stream.c
@@ -272,6 +272,10 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
inner_ip = (odph_ipv4hdr_t *)data;
memset((char *)inner_ip, 0, sizeof(*inner_ip));
inner_ip->ver_ihl = 0x45;
+ inner_ip->tot_len = odp_cpu_to_be_16(sizeof(odph_ipv4hdr_t) +
+ sizeof(odph_icmphdr_t) +
+ sizeof(stream_pkt_hdr_t) +
+ stream->length);
inner_ip->proto = ODPH_IPPROTO_ICMPV4;
inner_ip->id = odp_cpu_to_be_16(stream->id);
inner_ip->ttl = 64;
@@ -322,8 +326,8 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream,
encrypt_len = ESP_ENCODE_LEN(payload_len + sizeof(*esp_t),
entry->esp.block_len);
- memset(data, 0, encrypt_len - payload_len);
- data += encrypt_len - payload_len;
+ for (int n = 0; n < encrypt_len - payload_len; n++)
+ *data++ = n + 1;
esp_t = (odph_esptrl_t *)(data) - 1;
esp_t->pad_len = encrypt_len - payload_len - sizeof(*esp_t);
diff --git a/example/sysinfo/odp_sysinfo.c b/example/sysinfo/odp_sysinfo.c
index cad87b121..9e4ed4147 100644
--- a/example/sysinfo/odp_sysinfo.c
+++ b/example/sysinfo/odp_sysinfo.c
@@ -408,7 +408,7 @@ int main(void)
return -1;
}
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)) {
printf("timer capability failed\n");
return -1;
}
diff --git a/example/timer/odp_timer_accuracy.c b/example/timer/odp_timer_accuracy.c
index cafe362a7..df1fd5919 100644
--- a/example/timer/odp_timer_accuracy.c
+++ b/example/timer/odp_timer_accuracy.c
@@ -37,7 +37,7 @@ typedef struct {
uint64_t num_exact;
uint64_t num_after;
- uint64_t num_tooearly;
+ uint64_t num_too_near;
} test_stat_t;
@@ -103,11 +103,11 @@ static void print_usage(void)
" 1: Set first burst of timers at init. Restart timers during test with absolute time.\n"
" 2: Set first burst of timers at init. Restart timers during test with relative time.\n"
" -o, --output <file> Output file for measurement logs\n"
- " -e, --early_retry <num> When timer restart fails due to ODP_TIMER_TOOEARLY, retry this many times\n"
+ " -e, --early_retry <num> When timer restart fails due to ODP_TIMER_TOO_NEAR, retry this many times\n"
" with expiration time incremented by the period. Default: 0\n"
" -s, --clk_src Clock source select (default 0):\n"
- " 0: ODP_CLOCK_CPU\n"
- " 1: ODP_CLOCK_EXT\n"
+ " 0: ODP_CLOCK_DEFAULT\n"
+ " 1: ODP_CLOCK_SRC_1, ...\n"
" -i, --init Set global init parameters. Default: init params not set.\n"
" -h, --help Display help and exit.\n\n");
}
@@ -144,7 +144,7 @@ static int parse_options(int argc, char *argv[], test_global_t *test_global)
test_global->opt.burst = 1;
test_global->opt.burst_gap = 0;
test_global->opt.mode = 0;
- test_global->opt.clk_src = 0;
+ test_global->opt.clk_src = ODP_CLOCK_DEFAULT;
test_global->opt.init = 0;
test_global->opt.output = 0;
test_global->opt.early_retry = 0;
@@ -289,11 +289,7 @@ static int start_timers(test_global_t *test_global)
}
test_global->timeout_pool = pool;
-
- if (test_global->opt.clk_src == 0)
- clk_src = ODP_CLOCK_CPU;
- else
- clk_src = ODP_CLOCK_EXT;
+ clk_src = test_global->opt.clk_src;
if (odp_timer_capability(clk_src, &timer_capa)) {
printf("Timer capa failed\n");
@@ -565,7 +561,7 @@ static void print_stat(test_global_t *test_global)
printf(" num exact: %12" PRIu64 " / %.2f%%\n",
stat->num_exact, 100.0 * stat->num_exact / tot_timers);
printf(" num retry: %12" PRIu64 " / %.2f%%\n",
- stat->num_tooearly, 100.0 * stat->num_tooearly / tot_timers);
+ stat->num_too_near, 100.0 * stat->num_too_near / tot_timers);
printf(" error after (nsec):\n");
printf(" min: %12" PRIu64 " / %.3fx resolution\n",
stat->nsec_after_min, (double)stat->nsec_after_min / res_ns);
@@ -674,8 +670,8 @@ static void run_test(test_global_t *test_global)
ret = odp_timer_set_rel(tim, tick, &ev);
}
- if (ret == ODP_TIMER_TOOEARLY)
- stat->num_tooearly++;
+ if (ret == ODP_TIMER_TOO_NEAR)
+ stat->num_too_near++;
else
break;
}
diff --git a/example/timer/odp_timer_simple.c b/example/timer/odp_timer_simple.c
index 683d6ff8d..4e28807c6 100644
--- a/example/timer/odp_timer_simple.c
+++ b/example/timer/odp_timer_simple.c
@@ -65,7 +65,7 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
/*
* Create pool of timeouts
*/
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)) {
ret += 1;
goto err_tp;
}
@@ -76,7 +76,7 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED)
tparams.max_tmo = 1 * ODP_TIME_SEC_IN_NS;
tparams.num_timers = 1; /* One timer per worker */
tparams.priv = 0; /* Shared */
- tparams.clk_src = ODP_CLOCK_CPU;
+ tparams.clk_src = ODP_CLOCK_DEFAULT;
timer_pool = odp_timer_pool_create("timer_pool", &tparams);
if (timer_pool == ODP_TIMER_POOL_INVALID) {
ret += 1;
diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
index ddb2ccfd5..8bfb99d8f 100644
--- a/example/timer/odp_timer_test.c
+++ b/example/timer/odp_timer_test.c
@@ -56,12 +56,12 @@ static const char *timerset2str(odp_timer_set_t val)
switch (val) {
case ODP_TIMER_SUCCESS:
return "success";
- case ODP_TIMER_TOOEARLY:
- return "too early";
- case ODP_TIMER_TOOLATE:
- return "too late";
- case ODP_TIMER_NOEVENT:
- return "no event";
+ case ODP_TIMER_TOO_NEAR:
+ return "too near";
+ case ODP_TIMER_TOO_FAR:
+ return "too far";
+ case ODP_TIMER_FAIL:
+ return "failure";
default:
return "?";
}
@@ -273,7 +273,7 @@ static int parse_args(int argc, char *argv[], test_args_t *args)
static const char *shortopts = "+c:r:m:x:p:t:h";
/* defaults */
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa))
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa))
return -1;
args->cpu_count = 1;
@@ -444,7 +444,7 @@ int main(int argc, char *argv[])
tparams.max_tmo = gbls->args.max_us * ODP_TIME_USEC_IN_NS;
tparams.num_timers = num_workers; /* One timer per worker */
tparams.priv = 0; /* Shared */
- tparams.clk_src = ODP_CLOCK_CPU;
+ tparams.clk_src = ODP_CLOCK_DEFAULT;
gbls->tp = odp_timer_pool_create("timer_pool", &tparams);
if (gbls->tp == ODP_TIMER_POOL_INVALID) {
err = 1;
diff --git a/example/traffic_mgmt/odp_traffic_mgmt.c b/example/traffic_mgmt/odp_traffic_mgmt.c
index fba494853..521338785 100644
--- a/example/traffic_mgmt/odp_traffic_mgmt.c
+++ b/example/traffic_mgmt/odp_traffic_mgmt.c
@@ -62,8 +62,8 @@ static const odp_init_t ODP_INIT_PARAMS = {
static profile_params_set_t COMPANY_PROFILE_PARAMS = {
.shaper_params = {
- .commit_bps = 50 * MBPS, .commit_burst = 1000000,
- .peak_bps = 0, .peak_burst = 0,
+ .commit_rate = 50 * MBPS, .commit_burst = 1000000,
+ .peak_rate = 0, .peak_burst = 0,
.dual_rate = FALSE, .shaper_len_adjust = 20
},
@@ -95,8 +95,8 @@ static profile_params_set_t COMPANY_PROFILE_PARAMS = {
static profile_params_set_t COS0_PROFILE_PARAMS = {
.shaper_params = {
- .commit_bps = 1 * MBPS, .commit_burst = 100000,
- .peak_bps = 4 * MBPS, .peak_burst = 200000,
+ .commit_rate = 1 * MBPS, .commit_burst = 100000,
+ .peak_rate = 4 * MBPS, .peak_burst = 200000,
.dual_rate = FALSE, .shaper_len_adjust = 20
},
@@ -128,8 +128,8 @@ static profile_params_set_t COS0_PROFILE_PARAMS = {
static profile_params_set_t COS1_PROFILE_PARAMS = {
.shaper_params = {
- .commit_bps = 500 * KBPS, .commit_burst = 50000,
- .peak_bps = 1500 * KBPS, .peak_burst = 150000,
+ .commit_rate = 500 * KBPS, .commit_burst = 50000,
+ .peak_rate = 1500 * KBPS, .peak_burst = 150000,
.dual_rate = FALSE, .shaper_len_adjust = 20
},
@@ -161,8 +161,8 @@ static profile_params_set_t COS1_PROFILE_PARAMS = {
static profile_params_set_t COS2_PROFILE_PARAMS = {
.shaper_params = {
- .commit_bps = 200 * KBPS, .commit_burst = 20000,
- .peak_bps = 400 * KBPS, .peak_burst = 40000,
+ .commit_rate = 200 * KBPS, .commit_burst = 20000,
+ .peak_rate = 400 * KBPS, .peak_burst = 40000,
.dual_rate = FALSE, .shaper_len_adjust = 20
},
@@ -194,8 +194,8 @@ static profile_params_set_t COS2_PROFILE_PARAMS = {
static profile_params_set_t COS3_PROFILE_PARAMS = {
.shaper_params = {
- .commit_bps = 100 * KBPS, .commit_burst = 5000,
- .peak_bps = 0, .peak_burst = 0,
+ .commit_rate = 100 * KBPS, .commit_burst = 5000,
+ .peak_rate = 0, .peak_burst = 0,
.dual_rate = FALSE, .shaper_len_adjust = 20
},
@@ -272,8 +272,8 @@ static uint32_t create_profile_set(profile_params_set_t *profile_params_set,
odp_tm_shaper_params_init(&shaper_params);
shaper = &profile_params_set->shaper_params;
- shaper_params.commit_bps = shaper->commit_bps * shaper_scale;
- shaper_params.peak_bps = shaper->peak_bps * shaper_scale;
+ shaper_params.commit_rate = shaper->commit_rate * shaper_scale;
+ shaper_params.peak_rate = shaper->peak_rate * shaper_scale;
shaper_params.commit_burst = shaper->commit_burst * shaper_scale;
shaper_params.peak_burst = shaper->peak_burst * shaper_scale;
shaper_params.dual_rate = shaper->dual_rate;
@@ -826,6 +826,13 @@ int main(int argc, char *argv[])
create_and_config_tm();
+ /* Start TM */
+ rc = odp_tm_start(odp_tm_test);
+ if (rc != 0) {
+ printf("Error: odp_tm_start() failed, rc=%d\n", rc);
+ return -1;
+ }
+
odp_random_data(random_buf, RANDOM_BUF_LEN, 1);
next_rand_byte = 0;
@@ -841,6 +848,13 @@ int main(int argc, char *argv[])
odp_tm_stats_print(odp_tm_test);
+ /* Stop TM */
+ rc = odp_tm_stop(odp_tm_test);
+ if (rc != 0) {
+ printf("Error: odp_tm_stop() failed, rc = %d\n", rc);
+ return -1;
+ }
+
rc = destroy_tm_queues();
if (rc != 0) {
printf("Error: destroy_tm_queues() failed, rc = %d\n", rc);
diff --git a/helper/cli.c b/helper/cli.c
index dd4b5fe4f..ebc5b01e1 100644
--- a/helper/cli.c
+++ b/helper/cli.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <poll.h>
#include <stdio.h>
+#include <strings.h>
/* Socketpair socket roles. */
enum {
@@ -23,6 +24,15 @@ enum {
SP_WRITE = 1,
};
+#define MAX_NAME_LEN 20
+#define MAX_HELP_LEN 100
+
+typedef struct {
+ odph_cli_user_cmd_func_t fn;
+ char name[MAX_NAME_LEN];
+ char help[MAX_HELP_LEN];
+} user_cmd_t;
+
typedef struct {
volatile int cli_fd;
/* Server thread will exit if this is false. */
@@ -30,9 +40,15 @@ typedef struct {
/* Socketpair descriptors. */
int sp[2];
int listen_fd;
- /* This lock guards cli_fd and run, which must be accessed atomically. */
+ /* Guards cli_fd and run, which must be accessed atomically. */
odp_spinlock_t lock;
+ odp_spinlock_t api_lock;
odph_thread_t thr_server;
+ odp_instance_t instance;
+ struct sockaddr_in addr;
+ uint32_t max_user_commands;
+ uint32_t num_user_commands;
+ user_cmd_t user_cmd[0];
} cli_shm_t;
static const char *shm_name = "_odp_cli";
@@ -40,6 +56,7 @@ static const char *shm_name = "_odp_cli";
static const odph_cli_param_t param_default = {
.address = "127.0.0.1",
.port = 55555,
+ .max_user_commands = 50,
};
void odph_cli_param_init(odph_cli_param_t *param)
@@ -47,28 +64,114 @@ void odph_cli_param_init(odph_cli_param_t *param)
*param = param_default;
}
-static int cmd_show_cpu(struct cli_def *cli, const char *command ODP_UNUSED,
- char *argv[] ODP_UNUSED, int argc ODP_UNUSED)
+static cli_shm_t *shm_lookup(void)
+{
+ cli_shm_t *shm = NULL;
+ odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ return shm;
+}
+
+int odph_cli_init(odp_instance_t instance, const odph_cli_param_t *param)
{
- for (int c = 0; c < odp_cpu_count(); c++) {
- cli_print(cli, "% 4d: %s %.03f / %.03f GHz", c,
- odp_cpu_model_str_id(c),
- (float)odp_cpu_hz_id(c) / 1000000000.0,
- (float)odp_cpu_hz_max_id(c) / 1000000000.0);
+ if (odp_shm_lookup(shm_name) != ODP_SHM_INVALID) {
+ ODPH_ERR("Error: shm %s already exists\n", shm_name);
+ return -1;
}
- return CLI_OK;
+ cli_shm_t *shm = NULL;
+ int shm_size = sizeof(cli_shm_t) +
+ param->max_user_commands * sizeof(user_cmd_t);
+ odp_shm_t shm_hdl =
+ odp_shm_reserve(shm_name, shm_size, 64, ODP_SHM_SW_ONLY);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ if (!shm) {
+ ODPH_ERR("Error: failed to reserve shm %s\n", shm_name);
+ return -1;
+ }
+
+ memset(shm, 0, shm_size);
+ odp_spinlock_init(&shm->lock);
+ odp_spinlock_init(&shm->api_lock);
+ shm->sp[SP_READ] = -1;
+ shm->sp[SP_WRITE] = -1;
+ shm->listen_fd = -1;
+ shm->cli_fd = -1;
+ shm->instance = instance;
+
+ shm->addr.sin_family = AF_INET;
+ shm->addr.sin_port = htons(param->port);
+
+ switch (inet_pton(AF_INET, param->address, &shm->addr.sin_addr)) {
+ case -1:
+ ODPH_ERR("Error: inet_pton(): %s\n", strerror(errno));
+ return -1;
+ case 0:
+ ODPH_ERR("Error: inet_pton(): illegal address format\n");
+ return -1;
+ default:
+ break;
+ }
+
+ shm->max_user_commands = param->max_user_commands;
+
+ return 0;
}
-static int cmd_show_version(struct cli_def *cli, const char *command ODP_UNUSED,
- char *argv[] ODP_UNUSED, int argc ODP_UNUSED)
+int odph_cli_register_command(const char *name, odph_cli_user_cmd_func_t func,
+ const char *help)
{
- cli_print(cli, "ODP API version: %s", odp_version_api_str());
- cli_print(cli, "ODP implementation name: %s", odp_version_impl_name());
- cli_print(cli, "ODP implementation version: %s",
- odp_version_impl_str());
+ cli_shm_t *shm = shm_lookup();
- return CLI_OK;
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return -1;
+ }
+
+ odp_spinlock_lock(&shm->api_lock);
+
+ odp_spinlock_lock(&shm->lock);
+ if (shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ ODPH_ERR("Error: cannot register commands while cli server is running\n");
+ goto error;
+ }
+ odp_spinlock_unlock(&shm->lock);
+
+ if (shm->num_user_commands >= shm->max_user_commands) {
+ ODPH_ERR("Error: maximum number of user commands already registered\n");
+ goto error;
+ }
+
+ user_cmd_t *cmd = &shm->user_cmd[shm->num_user_commands];
+
+ cmd->fn = func;
+
+ if (strlen(name) >= MAX_NAME_LEN - 1) {
+ ODPH_ERR("Error: command name too long\n");
+ goto error;
+ }
+ strcpy(cmd->name, name);
+
+ if (strlen(help) >= MAX_HELP_LEN - 1) {
+ ODPH_ERR("Error: command help too long\n");
+ goto error;
+ }
+ strcpy(cmd->help, help);
+
+ shm->num_user_commands++;
+ odp_spinlock_unlock(&shm->api_lock);
+ return 0;
+
+error:
+ odp_spinlock_unlock(&shm->api_lock);
+ return -1;
}
/*
@@ -91,6 +194,18 @@ static int check_num_args(struct cli_def *cli, int argc, int req_argc)
return 0;
}
+static int cmd_call_odp_cls_print_all(struct cli_def *cli,
+ const char *command ODP_UNUSED,
+ char *argv[] ODP_UNUSED, int argc)
+{
+ if (check_num_args(cli, argc, 0))
+ return CLI_ERROR;
+
+ odp_cls_print_all();
+
+ return CLI_OK;
+}
+
static int cmd_call_odp_ipsec_print(struct cli_def *cli,
const char *command ODP_UNUSED,
char *argv[] ODP_UNUSED, int argc)
@@ -196,6 +311,18 @@ static int cmd_call_odp_queue_print(struct cli_def *cli,
return CLI_OK;
}
+static int cmd_call_odp_queue_print_all(struct cli_def *cli,
+ const char *command ODP_UNUSED,
+ char *argv[] ODP_UNUSED, int argc)
+{
+ if (check_num_args(cli, argc, 0))
+ return CLI_ERROR;
+
+ odp_queue_print_all();
+
+ return CLI_OK;
+}
+
static int cmd_call_odp_shm_print(struct cli_def *cli,
const char *command ODP_UNUSED, char *argv[],
int argc)
@@ -215,7 +342,27 @@ static int cmd_call_odp_shm_print(struct cli_def *cli,
return CLI_OK;
}
-static struct cli_def *create_cli(void)
+static int cmd_user_cmd(struct cli_def *cli ODP_UNUSED, const char *command,
+ char *argv[], int argc)
+{
+ cli_shm_t *shm = shm_lookup();
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return CLI_ERROR;
+ }
+
+ for (uint32_t i = 0; i < shm->num_user_commands; i++) {
+ if (!strcasecmp(command, shm->user_cmd[i].name)) {
+ shm->user_cmd[i].fn(argc, argv);
+ break;
+ }
+ }
+
+ return CLI_OK;
+}
+
+static struct cli_def *create_cli(cli_shm_t *shm)
{
struct cli_command *c;
struct cli_def *cli;
@@ -224,19 +371,12 @@ static struct cli_def *create_cli(void)
cli_set_banner(cli, NULL);
cli_set_hostname(cli, "ODP");
- c = cli_register_command(cli, NULL, "show", NULL,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show information.");
- cli_register_command(cli, c, "cpu", cmd_show_cpu,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show CPU information.");
- cli_register_command(cli, c, "version", cmd_show_version,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show version information.");
-
c = cli_register_command(cli, NULL, "call", NULL,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Call ODP API function.");
+ cli_register_command(cli, c, "odp_cls_print_all",
+ cmd_call_odp_cls_print_all,
+ PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
cli_register_command(cli, c, "odp_ipsec_print",
cmd_call_odp_ipsec_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
@@ -249,6 +389,9 @@ static struct cli_def *create_cli(void)
cli_register_command(cli, c, "odp_queue_print",
cmd_call_odp_queue_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "<name>");
+ cli_register_command(cli, c, "odp_queue_print_all",
+ cmd_call_odp_queue_print_all,
+ PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
cli_register_command(cli, c, "odp_shm_print_all",
cmd_call_odp_shm_print_all,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
@@ -262,6 +405,12 @@ static struct cli_def *create_cli(void)
cmd_call_odp_sys_info_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
+ for (uint32_t i = 0; i < shm->num_user_commands; i++) {
+ cli_register_command(cli, NULL, shm->user_cmd[i].name,
+ cmd_user_cmd, PRIVILEGE_UNPRIVILEGED,
+ MODE_EXEC, shm->user_cmd[i].help);
+ }
+
return cli;
}
@@ -269,8 +418,8 @@ static struct cli_def *create_cli(void)
static struct cli_def *cli;
static char *cli_log_fn_buf;
-ODP_PRINTF_FORMAT(2, 3)
-static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
+ODP_PRINTF_FORMAT(2, 0)
+static int cli_log_va(odp_log_level_t level, const char *fmt, va_list in_args)
{
(void)level;
@@ -289,17 +438,17 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
* If the string does not end in a newline, we keep the part of the
* string after the last newline and use it the next time we're called.
*/
- va_start(args, fmt);
+ va_copy(args, in_args);
len = vsnprintf(NULL, 0, fmt, args) + 1;
va_end(args);
str = malloc(len);
if (!str) {
- ODPH_ERR("malloc failed");
- return 0;
+ ODPH_ERR("malloc failed\n");
+ return -1;
}
- va_start(args, fmt);
+ va_copy(args, in_args);
vsnprintf(str, len, fmt, args);
va_end(args);
p = str;
@@ -323,7 +472,7 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
malloc(strlen(cli_log_fn_buf) + strlen(p) + 1);
if (!buffer_new) {
- ODPH_ERR("malloc failed");
+ ODPH_ERR("malloc failed\n");
goto out;
}
@@ -335,7 +484,7 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
cli_log_fn_buf = malloc(strlen(p) + 1);
if (!cli_log_fn_buf) {
- ODPH_ERR("malloc failed");
+ ODPH_ERR("malloc failed\n");
goto out;
}
@@ -346,23 +495,47 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
out:
free(str);
- return 0;
+ return len;
}
-static int cli_server(void *arg ODP_UNUSED)
+ODP_PRINTF_FORMAT(2, 3)
+static int cli_log(odp_log_level_t level, const char *fmt, ...)
{
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+ (void)level;
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+ int r;
+ va_list args;
+
+ va_start(args, fmt);
+ r = cli_log_va(level, fmt, args);
+ va_end(args);
+
+ return r;
+}
+
+ODP_PRINTF_FORMAT(1, 2)
+int odph_cli_log(const char *fmt, ...)
+{
+ int r;
+ va_list args;
+
+ va_start(args, fmt);
+ r = cli_log_va(ODP_LOG_PRINT, fmt, args);
+ va_end(args);
+
+ return r;
+}
+
+static int cli_server(void *arg ODP_UNUSED)
+{
+ cli_shm_t *shm = shm_lookup();
if (!shm) {
- ODPH_ERR("Error: can't start cli server (shm %s not found)\n", shm_name);
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
- cli = create_cli();
+ cli = create_cli(shm);
while (1) {
struct pollfd pfd[2] = {
@@ -399,26 +572,55 @@ static int cli_server(void *arg ODP_UNUSED)
break;
}
+ /*
+ * The only way to stop cli_loop() is to close the socket, after
+ * which cli_loop() gets an error on the next select() and then
+ * calls close() before returning. This is a problem because the
+ * fd may be reused before the select() or the final close().
+ *
+ * To avoid this problem, switch to a higher fd number
+ * (select() maximum). We will still run into problems if the
+ * descriptor numbers in the process reach FD_SETSIZE - 1 =
+ * 1023.
+ */
+ int newfd = dup2(fd, FD_SETSIZE - 1);
+
+ if (newfd < 0) {
+ ODPH_ERR("Error: dup2(): %s\n", strerror(errno));
+ close(fd);
+ continue;
+ }
+
+ close(fd);
+ fd = newfd;
+
odp_spinlock_lock(&shm->lock);
if (!shm->run) {
+ odp_spinlock_unlock(&shm->lock);
/*
* odph_cli_stop() has been called. Close the
* socket we just accepted and exit.
*/
close(fd);
- odp_spinlock_unlock(&shm->lock);
break;
}
shm->cli_fd = fd;
odp_spinlock_unlock(&shm->lock);
- odp_log_thread_fn_set(cli_log_fn);
+
+ odp_log_thread_fn_set(cli_log);
/*
* cli_loop() returns only when client is disconnected. One
* possible reason for disconnect is odph_cli_stop().
*/
cli_loop(cli, shm->cli_fd);
odp_log_thread_fn_set(NULL);
- close(shm->cli_fd);
+
+ odp_spinlock_lock(&shm->lock);
+ /*
+ * cli_loop() closes the socket before returning (undocumented).
+ */
+ shm->cli_fd = -1;
+ odp_spinlock_unlock(&shm->lock);
/*
* Throw away anything left in the buffer (in case the last
@@ -433,32 +635,30 @@ static int cli_server(void *arg ODP_UNUSED)
return 0;
}
-int odph_cli_start(const odp_instance_t instance,
- const odph_cli_param_t *param_in)
+int odph_cli_start(void)
{
- if (odp_shm_lookup(shm_name) != ODP_SHM_INVALID) {
- ODPH_ERR("Error: cli server already running (shm %s exists)\n", shm_name);
+ cli_shm_t *shm = shm_lookup();
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_reserve(shm_name, sizeof(cli_shm_t), 64,
- ODP_SHM_SW_ONLY);
-
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
-
- if (!shm) {
- ODPH_ERR("Error: failed to reserve shm %s\n", shm_name);
+ odp_spinlock_lock(&shm->api_lock);
+ odp_spinlock_lock(&shm->lock);
+ if (shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ odp_spinlock_unlock(&shm->api_lock);
+ ODPH_ERR("Error: cli server has already been started\n");
return -1;
}
+ shm->run = 1;
+ shm->cli_fd = -1;
+ odp_spinlock_unlock(&shm->lock);
- memset(shm, 0, sizeof(cli_shm_t));
- odp_spinlock_init(&shm->lock);
- shm->sp[SP_READ] = shm->sp[SP_WRITE] = -1;
+ shm->sp[SP_READ] = -1;
+ shm->sp[SP_WRITE] = -1;
shm->listen_fd = -1;
- shm->cli_fd = -1;
- shm->run = 1;
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, shm->sp)) {
ODPH_ERR("Error: socketpair(): %s\n", strerror(errno));
@@ -480,21 +680,8 @@ int odph_cli_start(const odp_instance_t instance,
goto error;
}
- struct sockaddr_in addr;
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(param_in->port);
-
- switch (inet_pton(AF_INET, param_in->address, &addr.sin_addr)) {
- case -1:
- ODPH_ERR("Error: inet_pton(): %s\n", strerror(errno));
- goto error;
- case 0:
- ODPH_ERR("Error: inet_pton(): illegal address format\n");
- goto error;
- }
-
- if (bind(shm->listen_fd, (struct sockaddr *)&addr, sizeof(addr))) {
+ if (bind(shm->listen_fd, (struct sockaddr *)&shm->addr,
+ sizeof(shm->addr))) {
ODPH_ERR("Error: bind(): %s\n", strerror(errno));
goto error;
}
@@ -516,7 +703,7 @@ int odph_cli_start(const odp_instance_t instance,
}
memset(&thr_common, 0, sizeof(thr_common));
- thr_common.instance = instance;
+ thr_common.instance = shm->instance;
thr_common.cpumask = &cpumask;
memset(&thr_param, 0, sizeof(thr_param));
@@ -530,36 +717,50 @@ int odph_cli_start(const odp_instance_t instance,
goto error;
}
+ odp_spinlock_unlock(&shm->api_lock);
return 0;
error:
- close(shm->sp[SP_READ]);
- close(shm->sp[SP_WRITE]);
- close(shm->listen_fd);
- close(shm->cli_fd);
shm->run = 0;
+ if (shm->sp[SP_READ] >= 0)
+ close(shm->sp[SP_READ]);
+ if (shm->sp[SP_WRITE] >= 0)
+ close(shm->sp[SP_WRITE]);
+ if (shm->listen_fd >= 0)
+ close(shm->listen_fd);
+ if (shm->cli_fd >= 0)
+ close(shm->cli_fd);
+ odp_spinlock_unlock(&shm->api_lock);
return -1;
}
int odph_cli_stop(void)
{
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
-
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+ cli_shm_t *shm = shm_lookup();
if (!shm) {
- ODPH_ERR("Error: cli server not running (shm %s not found)\n", shm_name);
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
+ odp_spinlock_lock(&shm->api_lock);
odp_spinlock_lock(&shm->lock);
+ if (!shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ odp_spinlock_unlock(&shm->api_lock);
+ ODPH_ERR("Error: cli server has not been started\n");
+ return -1;
+ }
shm->run = 0;
/*
- * Close the current cli connection. This stops cli_loop().
+ * Close the current cli connection. This stops cli_loop(). If cli
+ * client is disconnecting at the same time, cli_fd may already have
+ * been closed.
*/
- close(shm->cli_fd);
+ if (shm->cli_fd >= 0) {
+ close(shm->cli_fd);
+ shm->cli_fd = -1;
+ }
odp_spinlock_unlock(&shm->lock);
/*
@@ -572,17 +773,37 @@ int odph_cli_stop(void)
if (sent != sizeof(stop)) {
ODPH_ERR("Error: send() = %d: %s\n", sent, strerror(errno));
- return -1;
+ goto error;
}
if (odph_thread_join(&shm->thr_server, 1) != 1) {
ODPH_ERR("Error: odph_thread_join() failed\n");
- return -1;
+ goto error;
}
close(shm->sp[SP_READ]);
close(shm->sp[SP_WRITE]);
close(shm->listen_fd);
+ odp_spinlock_unlock(&shm->api_lock);
+ return 0;
+
+error:
+ odp_spinlock_unlock(&shm->api_lock);
+ return -1;
+}
+
+int odph_cli_term(void)
+{
+ cli_shm_t *shm = NULL;
+ odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return -1;
+ }
if (odp_shm_free(shm_hdl)) {
ODPH_ERR("Error: odp_shm_free() failed\n");
diff --git a/helper/include/odp/helper/cli.h b/helper/include/odp/helper/cli.h
index 41e438857..ef1c24d05 100644
--- a/helper/include/odp/helper/cli.h
+++ b/helper/include/odp/helper/cli.h
@@ -12,9 +12,6 @@
* This API allows control of ODP CLI server, which may be connected to
* using a telnet client. CLI commands may be used to get information
* from an ODP instance, for debugging purposes.
- *
- * Many CLI commands output the information to the console, or wherever
- * ODP logs have been directed to in global init.
*/
#ifndef ODPH_CLI_H_
@@ -33,6 +30,17 @@ extern "C" {
* @{
*/
+/**
+ * User defined command function type. See odph_cli_register_command().
+ *
+ * The arguments (argv) are the arguments to the command given in the CLI
+ * client. For example, having registered a command with the name "my_command",
+ * and given the command "my_command one two" in the CLI client, the user
+ * command function would be called with argc = 2, argv[0] = "one" and argv[1] =
+ * "two".
+ */
+typedef void (*odph_cli_user_cmd_func_t)(int argc, char *argv[]);
+
/** ODP CLI server parameters */
typedef struct {
/**
@@ -42,6 +50,8 @@ typedef struct {
const char *address;
/** TCP port. Default is 55555. */
uint16_t port;
+ /** Maximum number of user defined commands. Default is 50. */
+ uint32_t max_user_commands;
} odph_cli_param_t;
/**
@@ -55,19 +65,56 @@ typedef struct {
void odph_cli_param_init(odph_cli_param_t *param);
/**
+ * Initialize CLI helper
+ *
+ * This function initializes the CLI helper. It must be called before
+ * odph_cli_register_command() and odph_cli_start().
+ *
+ * @param instance ODP instance
+ * @param param CLI server parameters to use
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_init(odp_instance_t instance, const odph_cli_param_t *param);
+
+/**
+ * Register a user defined command
+ *
+ * Register a command with a name, function, and an optional help text. The
+ * registered command is displayed in the output of the "help" command. When the
+ * command is invoked by the CLI client, the registered function is called with
+ * the parameters entered by the CLI client user.
+ *
+ * Command names are case-insensitive. In the CLI client, they are displayed in
+ * the case they were registered in, but they may be invoked using any case.
+ *
+ * This function should be called after odph_cli_init() and before
+ * odph_cli_start().
+ *
+ * @param name Command name (case-insensitive)
+ * @param func Command function
+ * @param help Help or description for the command. This appears in the output
+ * of the "help" command. May be NULL.
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_register_command(const char *name, odph_cli_user_cmd_func_t func,
+ const char *help);
+
+/**
* Start CLI server
*
* Upon successful return from this function, the CLI server will be
* accepting client connections. This function spawns a new thread of
* type ODP_THREAD_CONTROL using odp_cpumask_default_control().
*
- * @param instance ODP instance
- * @param param CLI server parameters to use
+ * This function should be called after odph_cli_init() and after any
+ * odph_cli_register_command() calls.
+ *
* @retval 0 Success
* @retval <0 Failure
*/
-int odph_cli_start(const odp_instance_t instance,
- const odph_cli_param_t *param);
+int odph_cli_start(void);
/**
* Stop CLI server
@@ -82,6 +129,31 @@ int odph_cli_start(const odp_instance_t instance,
int odph_cli_stop(void);
/**
+ * Print to CLI
+ *
+ * A user defined command may call this function to print to the CLI client.
+ * This function should only be called in a user defined command (see
+ * odph_cli_register_command()). If called anywhere else, the behavior is
+ * undefined.
+ *
+ * @param fmt printf-style message format
+ * @return On success, the number of characters printed or buffered, without
+ * accounting for any line feed conversions. If an error is encountered,
+ * a negative value is returned.
+ */
+int odph_cli_log(const char *fmt, ...);
+
+/**
+ * Terminate CLI helper
+ *
+ * Free any resources allocated by the CLI helper.
+ *
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_term(void);
+
+/**
* @}
*/
diff --git a/helper/ipsec.c b/helper/ipsec.c
index e2d24840e..41daefbfb 100644
--- a/helper/ipsec.c
+++ b/helper/ipsec.c
@@ -108,7 +108,7 @@ int odph_ipsec_alg_check(odp_ipsec_capability_t capa,
}
/* Check whether requested cipher key length is supported */
- max_capa = odp_crypto_cipher_capability(cipher_alg, NULL, 0);
+ max_capa = odp_ipsec_cipher_capability(cipher_alg, NULL, 0);
if (max_capa <= 0)
return -1;
@@ -134,7 +134,7 @@ int odph_ipsec_alg_check(odp_ipsec_capability_t capa,
}
/* Check whether requested auth key length is supported */
- max_capa = odp_crypto_auth_capability(auth_alg, NULL, 0);
+ max_capa = odp_ipsec_auth_capability(auth_alg, NULL, 0);
if (max_capa <= 0)
return max_capa;
diff --git a/helper/test/cli.c b/helper/test/cli.c
index ff3ea2f53..e7ed0e06f 100644
--- a/helper/test/cli.c
+++ b/helper/test/cli.c
@@ -38,7 +38,12 @@ int main(int argc, char *argv[])
odph_cli_param_init(&cli_param);
- if (odph_cli_start(instance, &cli_param)) {
+ if (odph_cli_init(instance, &cli_param)) {
+ ODPH_ERR("Error: odph_cli_init() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odph_cli_start()) {
ODPH_ERR("Error: odph_cli_start() failed.\n");
exit(EXIT_FAILURE);
}
@@ -48,6 +53,11 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ if (odph_cli_term()) {
+ ODPH_ERR("Error: odph_cli_term() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
if (odp_term_local()) {
ODPH_ERR("Error: ODP local term failed.\n");
exit(EXIT_FAILURE);
diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h
index 5c4ee03ab..2030b19e8 100644
--- a/include/odp/api/spec/ipsec.h
+++ b/include/odp/api/spec/ipsec.h
@@ -937,6 +937,15 @@ typedef struct odp_ipsec_stats_t {
/** Number of packets with hard lifetime(packets) expired */
uint64_t hard_exp_pkts_err;
+
+ /** Total bytes of packet data processed by IPsec SA in success cases
+ *
+ * The range of packet bytes included in the success_bytes count is
+ * implementation defined but includes at least the bytes input for
+ * encryption or bytes output after decryption in ESP or the bytes
+ * authenticated in AH.
+ */
+ uint64_t success_bytes;
} odp_ipsec_stats_t;
/**
diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h
index fcb0a39c3..1f4ac84f6 100644
--- a/include/odp/api/spec/packet_io.h
+++ b/include/odp/api/spec/packet_io.h
@@ -1074,8 +1074,10 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
* output. If return value (N) is less than 'num', only queues[0 ... N-1] have
* been written.
*
- * Packets (and other events) from these queues are received with
- * odp_queue_deq(), odp_schedule(), etc calls.
+ * In addition to packet input, application and other parts of ODP (e.g. timer)
+ * may enqueue events into these queues. Depending on the queue mode, application
+ * uses either odp_queue_deq() or odp_schedule() (or variants of those) to receive
+ * packets and other events from these queues.
*
* @param pktio Packet IO handle
* @param[out] queues Points to an array of queue handles for output
@@ -1117,7 +1119,7 @@ int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num);
*
* Packets are enqueued to these queues with odp_queue_enq() or
* odp_queue_enq_multi(). Behaviour is undefined if other events than packets
- * are enqueued.
+ * are enqueued. Application cannot dequeue from these queues.
*
* @param pktio Packet IO handle
* @param[out] queues Points to an array of queue handles for output
diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h
index c5756e492..c25338a51 100644
--- a/include/odp/api/spec/time.h
+++ b/include/odp/api/spec/time.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2020, Nokia
+ * Copyright (c) 2020-2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -66,6 +66,35 @@ extern "C" {
odp_time_t odp_time_local(void);
/**
+ * Current local time in nanoseconds
+ *
+ * Like odp_time_local(), but the time stamp value is converted into nanoseconds.
+ *
+ * @return Local time stamp in nanoseconds
+ */
+uint64_t odp_time_local_ns(void);
+
+/**
+ * Current local time (strict)
+ *
+ * Like odp_time_local(), but reads the time stamp value more strictly in the program order.
+ * The function may decrease CPU performance around the call, as it may include additional
+ * barrier instructions or otherwise limit out-of-order execution.
+ *
+ * @return Local time stamp
+ */
+odp_time_t odp_time_local_strict(void);
+
+/**
+ * Current local time in nanoseconds (strict)
+ *
+ * Like odp_time_local_strict(), but the time stamp value is converted into nanoseconds.
+ *
+ * @return Local time stamp in nanoseconds
+ */
+uint64_t odp_time_local_strict_ns(void);
+
+/**
* Current global time
*
* Returns current global time stamp value. The global time source provides high
@@ -78,22 +107,32 @@ odp_time_t odp_time_local(void);
odp_time_t odp_time_global(void);
/**
- * Current local time in nanoseconds
+ * Current global time in nanoseconds
*
- * Like odp_time_local(), but the time stamp value is converted into nanoseconds.
+ * Like odp_time_global(), but the time stamp value is converted into nanoseconds.
*
- * @return Local time stamp in nanoseconds
+ * @return Global time stamp in nanoseconds
*/
-uint64_t odp_time_local_ns(void);
+uint64_t odp_time_global_ns(void);
/**
- * Current global time in nanoseconds
+ * Current global time (strict)
*
- * Like odp_time_global(), but the time stamp value is converted into nanoseconds.
+ * Like odp_time_global(), but reads the time stamp value more strictly (see
+ * odp_time_local_strict() documentation) in the program order.
+ *
+ * @return Global time stamp
+ */
+odp_time_t odp_time_global_strict(void);
+
+/**
+ * Current global time in nanoseconds (strict)
+ *
+ * Like odp_time_global_strict(), but the time stamp value is converted into nanoseconds.
*
* @return Global time stamp in nanoseconds
*/
-uint64_t odp_time_global_ns(void);
+uint64_t odp_time_global_strict_ns(void);
/**
* Time difference
diff --git a/include/odp/api/spec/timer.h b/include/odp/api/spec/timer.h
index 62151e485..a90fb9b07 100644
--- a/include/odp/api/spec/timer.h
+++ b/include/odp/api/spec/timer.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2019-2020, Nokia
+ * Copyright (c) 2019-2021, Nokia
*
* All rights reserved.
*
@@ -36,16 +36,47 @@ extern "C" {
*/
/**
- * Clock sources for timers in timer pool.
+ * Clock sources for timer pools
+ *
+ * ODP_CLOCK_DEFAULT is the default clock source and it is supported always. It is implementation
+ * defined which other clock sources are supported. See from implementation documentation how the
+ * supported clock sources are mapped into these enumerations.
*/
typedef enum {
- /** Use CPU clock as clock source for timers */
- ODP_CLOCK_CPU,
- /** Use external clock as clock source for timers */
- ODP_CLOCK_EXT
- /* Platform dependent which other clock sources exist */
+ /** Clock source number 0 */
+ ODP_CLOCK_SRC_0,
+
+ /** Clock source number 1 */
+ ODP_CLOCK_SRC_1,
+
+ /** Clock source number 2 */
+ ODP_CLOCK_SRC_2,
+
+ /** Clock source number 3 */
+ ODP_CLOCK_SRC_3,
+
+ /** Clock source number 4 */
+ ODP_CLOCK_SRC_4,
+
+ /** Clock source number 5 */
+ ODP_CLOCK_SRC_5,
+
+ /** Number of clock source enumerations */
+ ODP_CLOCK_NUM_SRC
+
} odp_timer_clk_src_t;
+/** The default clock source */
+#define ODP_CLOCK_DEFAULT ODP_CLOCK_SRC_0
+
+/** For backwards compatibility, ODP_CLOCK_CPU is synonym of ODP_CLOCK_DEFAULT.
+ * This will be deprecated in the future. */
+#define ODP_CLOCK_CPU ODP_CLOCK_DEFAULT
+
+/** For backwards compatibility, ODP_CLOCK_EXT is synonym of ODP_CLOCK_SRC_1.
+ * This will be deprecated in the future. */
+#define ODP_CLOCK_EXT ODP_CLOCK_SRC_1
+
/**
* @typedef odp_timer_t
* ODP timer handle
@@ -70,31 +101,34 @@ typedef enum {
* Return values of timer set calls.
*/
typedef enum {
- /**
- * Timer set operation succeeded
- */
+ /** Timer set operation succeeded */
ODP_TIMER_SUCCESS = 0,
- /**
- * Timer set operation failed, expiration too early.
- * Either retry with a later expiration time or process the timeout
- * immediately. */
- ODP_TIMER_TOOEARLY = -1,
+ /** Timer set operation failed because expiration time is too near to
+ * the current time. */
+ ODP_TIMER_TOO_NEAR = -1,
- /**
- * Timer set operation failed, expiration too late.
- * Truncate the expiration time against the maximum timeout for the
- * timer pool. */
- ODP_TIMER_TOOLATE = -2,
+ /** Timer set operation failed because expiration time is too far from
+ * the current time. */
+ ODP_TIMER_TOO_FAR = -2,
- /**
- * Timer set operation failed because no event specified and no event
- * present in the timer (timer inactive/expired).
- */
- ODP_TIMER_NOEVENT = -3
+ /** Timer set operation failed */
+ ODP_TIMER_FAIL = -3
} odp_timer_set_t;
+/** For backwards compatibility, ODP_TIMER_TOOEARLY is synonym of ODP_TIMER_TOO_NEAR.
+ * This will be deprecated in the future. */
+#define ODP_TIMER_TOOEARLY ODP_TIMER_TOO_NEAR
+
+/** For backwards compatibility, ODP_TIMER_TOOLATE is synonym of ODP_TIMER_TOO_FAR.
+ * This will be deprecated in the future. */
+#define ODP_TIMER_TOOLATE ODP_TIMER_TOO_FAR
+
+/** For backwards compatibility, ODP_TIMER_NOEVENT is synonym of ODP_TIMER_FAIL.
+ * This will be deprecated in the future. */
+#define ODP_TIMER_NOEVENT ODP_TIMER_FAIL
+
/**
* @def ODP_TIMER_POOL_NAME_LEN
* Maximum timer pool name length in chars including null char
@@ -240,18 +274,19 @@ typedef struct {
} odp_timer_capability_t;
/**
- * Query timer capabilities
+ * Query timer capabilities per clock source
*
- * Outputs timer capabilities on success.
+ * Outputs timer capabilities on success. Returns -1 if the clock source
+ * is not supported.
*
* @param clk_src Clock source for timers
* @param[out] capa Pointer to capability structure for output
*
- * @retval 0 on success
- * @retval <0 on failure
+ * @retval 0 on success
+ * @retval -1 when the clock source is not supported
+ * @retval <-1 on other failures
*/
-int odp_timer_capability(odp_timer_clk_src_t clk_src,
- odp_timer_capability_t *capa);
+int odp_timer_capability(odp_timer_clk_src_t clk_src, odp_timer_capability_t *capa);
/**
* Timer resolution capability
@@ -423,11 +458,11 @@ odp_event_t odp_timer_free(odp_timer_t timer);
* outputs the old event here.
*
* @retval ODP_TIMER_SUCCESS Success
- * @retval ODP_TIMER_TOOEARLY Failure. Expiration time is too near to
+ * @retval ODP_TIMER_TOO_NEAR Failure. Expiration time is too near to
* the current time.
- * @retval ODP_TIMER_TOOLATE Failure. Expiration time is too far from
+ * @retval ODP_TIMER_TOO_FAR Failure. Expiration time is too far from
* the current time.
- * @retval ODP_TIMER_NOEVENT Failure. Set operation: No event provided.
+ * @retval ODP_TIMER_FAIL Failure. Set operation: No event provided.
* Reset operation: Too late to reset the timer.
*
* @see odp_timer_set_rel(), odp_timer_alloc(), odp_timer_cancel()
@@ -451,11 +486,11 @@ int odp_timer_set_abs(odp_timer_t timer, uint64_t abs_tick,
* outputs the old event here.
*
* @retval ODP_TIMER_SUCCESS Success
- * @retval ODP_TIMER_TOOEARLY Failure. Expiration time is too near to
+ * @retval ODP_TIMER_TOO_NEAR Failure. Expiration time is too near to
* the current time.
- * @retval ODP_TIMER_TOOLATE Failure. Expiration time is too far from
+ * @retval ODP_TIMER_TOO_FAR Failure. Expiration time is too far from
* the current time.
- * @retval ODP_TIMER_NOEVENT Failure. Set operation: No event provided.
+ * @retval ODP_TIMER_FAIL Failure. Set operation: No event provided.
* Reset operation: Too late to reset the timer.
*
* @see odp_timer_set_abs(), odp_timer_alloc(), odp_timer_cancel()
diff --git a/include/odp/api/spec/traffic_mngr.h b/include/odp/api/spec/traffic_mngr.h
index 04848a0ea..699d0bb26 100644
--- a/include/odp/api/spec/traffic_mngr.h
+++ b/include/odp/api/spec/traffic_mngr.h
@@ -224,6 +224,10 @@ typedef struct {
* all support TM shaping, */
odp_bool_t tm_node_shaper_supported;
+ /** tm_node_shaper_packet_mode indicates that tm_nodes at this level
+ * support shaper in packet mode */
+ odp_bool_t tm_node_shaper_packet_mode;
+
/** tm_node_wred_supported indicates that the tm_nodes at this level
* support some form of Random Early Detection. */
odp_bool_t tm_node_wred_supported;
@@ -285,6 +289,10 @@ typedef struct {
* expected to do. */
odp_bool_t tm_queue_shaper_supported;
+ /** tm_queue_shaper_packet_mode indicates that tm_queues support
+ * shaper in packet mode */
+ odp_bool_t tm_queue_shaper_packet_mode;
+
/** tm_queue_wred_supported indicates that the tm_queues support some
* form of Random Early Detection. */
odp_bool_t tm_queue_wred_supported;
@@ -331,6 +339,52 @@ typedef struct {
/** The per_level array specifies the TM system capabilities that
* can vary based upon the tm_node level. */
odp_tm_level_capabilities_t per_level[ODP_TM_MAX_LEVELS];
+
+ /** dynamic_topology_update indicates support for TM system dynamic
+ * topology update. A dynamic topology update is defined as update to
+ * a TM system topology while TM system is not in stopped state.
+ * When TRUE, application can update topology dynamically
+ * without bringing the TM system to stopped state. When FALSE,
+ * application has to call odp_tm_stop() before updating the
+ * topology and odp_tm_start() after completing the update.
+ */
+ odp_bool_t dynamic_topology_update;
+
+ /** dynamic_shaper_update indicates support for TM system's dynamic
+ * shaper profile changes. When TRUE, application can update shaper
+ * profile of a TM queue or TM node dynamically.
+ * When FALSE, it implies that TM system should be brought to
+ * stopped state before changing the shaper profile or updating
+ * the parameters of the shaper profile of any TM node or TM queue.
+ */
+ odp_bool_t dynamic_shaper_update;
+
+ /** dynamic_sched_update indicates support for TM system's dynamic
+ * sched profile changes. When TRUE, application can update sched
+ * profile of a TM queue or TM node dynamically.
+ * When FALSE, it implies that TM system should be brought to
+ * stopped state before changing the sched profile or updating
+ * the parameters of the sched profile of any TM node or TM queue.
+ */
+ odp_bool_t dynamic_sched_update;
+
+ /** dynamic_wred_update indicates support for TM system's dynamic
+ * wred profile changes. When TRUE, application can update wred
+ * profile of a TM queue or TM node dynamically.
+ * When FALSE, it implies that TM system should be brought to
+ * stopped state before changing the wred profile or updating
+ * the parameters of the wred profile of any TM node or TM queue.
+ */
+ odp_bool_t dynamic_wred_update;
+
+ /** dynamic_threshold_update indicates support for TM system's dynamic
+ * threshold profile changes. When TRUE, application can update
+ * threshold profile of a TM queue or TM node dynamically.
+ * When FALSE, it implies that TM system should be brought to
+ * stopped state before changing the threshold profile or updating
+ * the parameters of the threshold profile of any TM node or TM queue.
+ */
+ odp_bool_t dynamic_threshold_update;
} odp_tm_capabilities_t;
/** Per Level Requirements
@@ -605,6 +659,48 @@ odp_tm_t odp_tm_find(const char *name,
*/
int odp_tm_capability(odp_tm_t odp_tm, odp_tm_capabilities_t *capabilities);
+/**
+ * Start a TM system
+ *
+ * odp_tm_start() needs to be used to start an already created or found TM
+ * system. By default, all the TM systems are in stopped state.
+ *
+ * @param tm TM system to be started
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odp_tm_start(odp_tm_t tm);
+
+/**
+ * Stop a TM system
+ *
+ * odp_tm_stop() can to used to stop a TM system that is already started for the
+ * purpose of reconfiguration that cannot be done dynamically.
+ *
+ * When TM is in the stopped state,
+ * - New packets must not be sent to the TM either directly by TM API or indirectly
+ * via IPsec outbound inline API. New packets can only be enqueued after
+ * starting the TM system using odp_tm_start().
+ * - Packets already inflight inside TM or IPSec for transmit may get silently dropped
+ * or may get transmitted with unspecified TM treatment.
+ *
+ * A following call to odp_tm_start() restarts TM system and its scheduling/shaping
+ * on existing and new packets.
+ *
+ * @param tm TM system to be stopped
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ *
+ * @see odp_tm_capabilities_t::dynamic_topology_update
+ * @see odp_tm_capabilities_t::dynamic_shaper_update
+ * @see odp_tm_capabilities_t::dynamic_sched_update
+ * @see odp_tm_capabilities_t::dynamic_wred_update
+ * @see odp_tm_capabilities_t::dynamic_threshold_update
+ */
+int odp_tm_stop(odp_tm_t tm);
+
/** Destroy a TM system.
*
* odp_tm_destroy() may be used to destroy TM systems created via
@@ -746,20 +842,34 @@ typedef enum {
*/
typedef struct {
/** The committed information rate for this shaper profile. The units
- * for this integer are always in bits per second. */
- uint64_t commit_bps;
+ * for this integer is in bits per second when packet_mode is
+ * not TRUE while packets per second when packet mode is TRUE.
+ */
+ union {
+ /**< @deprecated Use commit_rate instead */
+ uint64_t ODP_DEPRECATE(commit_bps);
+ uint64_t commit_rate; /**< Commit information rate */
+ };
/** The peak information rate for this shaper profile. The units for
- * this integer are always in bits per second. */
- uint64_t peak_bps;
+ * this integer is in bits per second when packet_mode is
+ * not TRUE while in packets per second when packet mode is TRUE.
+ */
+ union {
+ /**< @deprecated Use peak_rate instead */
+ uint64_t ODP_DEPRECATE(peak_bps);
+ uint64_t peak_rate; /**< Peak information rate */
+ };
/** The commit burst tolerance for this shaper profile. The units for
- * this field are always bits. This value sets an upper limit for the
+ * this field is bits when packet_mode is not TRUE and packets when
+ * packet_mode is TRUE. This value sets an upper limit for the
* size of the commitCnt. */
uint32_t commit_burst;
/** The peak burst tolerance for this shaper profile. The units for
- * this field are always bits. This value sets an upper limit for the
+ * this field in bits when packet_mode is not TRUE and packets
+ * when packet_mode is TRUE. This value sets an upper limit for the
* size of the peakCnt. */
uint32_t peak_burst;
@@ -771,7 +881,9 @@ typedef struct {
* to a value approximating the "time" (in units of bytes) taken by
* the Ethernet preamble and Inter Frame Gap. Traditionally this
* would be the value 20 (8 + 12), but in same cases can be as low as
- * 9 (4 + 5). */
+ * 9 (4 + 5).
+ * This field is ignored when packet_mode is TRUE.
+ */
int8_t shaper_len_adjust;
/** If dual_rate is TRUE it indicates the desire for the
@@ -780,6 +892,12 @@ typedef struct {
* implementation specific, but in any case require a non-zero set of
* both commit and peak parameters. */
odp_bool_t dual_rate;
+
+ /** If packet_mode is TRUE it indicates that shaper should work
+ * in packet mode ignoring lengths of packet and hence shaping
+ * traffic in packet's per second as opposed to bits per second.
+ */
+ odp_bool_t packet_mode;
} odp_tm_shaper_params_t;
/** odp_tm_shaper_params_init() must be called to initialize any
diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am
index 6967be8cf..8cdb84b15 100644
--- a/platform/linux-dpdk/Makefile.am
+++ b/platform/linux-dpdk/Makefile.am
@@ -259,7 +259,7 @@ __LIB__libodp_dpdk_la_SOURCES += arch/aarch64/odp_atomic.c \
arch/default/odp_hash_crc32.c \
arch/aarch64/odp_sysinfo_parse.c
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_inlines.h \
- arch/default/odp/api/abi/cpu_time.h \
+ arch/aarch64/odp/api/abi/cpu_time.h \
arch/aarch64/odp/api/abi/hash_crc32.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
diff --git a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
index 5032b0fcb..c007c5ce9 100644
--- a/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
+++ b/platform/linux-dpdk/include/odp/api/plat/time_inlines.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2020, Nokia
+ * Copyright (c) 2020-2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -21,11 +21,13 @@
#define _ODP_TIME_GIGA_HZ 1000000000ULL
typedef odp_time_t (*time_cur_fn)(void);
+typedef odp_time_t (*time_cur_strict_fn)(void);
typedef uint64_t (*time_res_fn)(void);
typedef struct time_handler_ {
- time_cur_fn time_cur;
- time_res_fn time_res;
+ time_cur_fn time_cur;
+ time_cur_strict_fn time_cur_strict;
+ time_res_fn time_res;
} time_handler_t;
@@ -58,11 +60,28 @@ static inline odp_time_t _odp_time_cur_gen(void)
return _odp_timespec_cur();
}
+static inline odp_time_t _odp_time_cur_gen_strict(void)
+{
+ if (_odp_time_glob.use_hw) {
+ odp_time_t time;
+
+ time.count = _odp_cpu_global_time_strict() - _odp_time_glob.hw_start;
+ return time;
+ }
+
+ return _odp_timespec_cur();
+}
+
static inline odp_time_t _odp_time_cur(void)
{
return _odp_time_glob.handler.time_cur();
}
+static inline odp_time_t _odp_time_cur_strict(void)
+{
+ return _odp_time_glob.handler.time_cur_strict();
+}
+
static inline uint64_t _odp_time_hw_to_ns(odp_time_t time)
{
uint64_t nsec;
@@ -96,6 +115,12 @@ static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
#define odp_time_to_ns __odp_time_to_ns
#define odp_time_local_ns __odp_time_local_ns
#define odp_time_global_ns __odp_time_global_ns
+
+ #define odp_time_local_strict __odp_time_local_strict
+ #define odp_time_global_strict __odp_time_global_strict
+ #define odp_time_local_strict_ns __odp_time_local_strict_ns
+ #define odp_time_global_strict_ns __odp_time_global_strict_ns
+
#define odp_time_cmp __odp_time_cmp
#define odp_time_diff __odp_time_diff
#define odp_time_sum __odp_time_sum
@@ -114,9 +139,14 @@ _ODP_INLINE odp_time_t odp_time_global(void)
return _odp_time_cur();
}
-_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+_ODP_INLINE odp_time_t odp_time_local_strict(void)
{
- return _odp_time_convert_to_ns(time);
+ return _odp_time_cur_strict();
+}
+
+_ODP_INLINE odp_time_t odp_time_global_strict(void)
+{
+ return _odp_time_cur_strict();
}
_ODP_INLINE uint64_t odp_time_local_ns(void)
@@ -129,6 +159,21 @@ _ODP_INLINE uint64_t odp_time_global_ns(void)
return _odp_time_convert_to_ns(_odp_time_cur());
}
+_ODP_INLINE uint64_t odp_time_local_strict_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur_strict());
+}
+
+_ODP_INLINE uint64_t odp_time_global_strict_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur_strict());
+}
+
+_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+{
+ return _odp_time_convert_to_ns(time);
+}
+
_ODP_INLINE int odp_time_cmp(odp_time_t t2, odp_time_t t1)
{
if (odp_likely(t2.u64 > t1.u64))
diff --git a/platform/linux-dpdk/include/odp_packet_io_internal.h b/platform/linux-dpdk/include/odp_packet_io_internal.h
index e52eb9840..0d2782101 100644
--- a/platform/linux-dpdk/include/odp_packet_io_internal.h
+++ b/platform/linux-dpdk/include/odp_packet_io_internal.h
@@ -32,6 +32,7 @@ extern "C" {
#include <linux/if_ether.h>
#include <sys/select.h>
+#include <inttypes.h>
#define PKTIO_MAX_QUEUES 64
#define PKTIO_LSO_PROFILES 16
@@ -218,7 +219,7 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t pktio)
return NULL;
if (odp_unlikely(_odp_typeval(pktio) > ODP_CONFIG_PKTIO_ENTRIES)) {
- ODP_DBG("pktio limit %d/%d exceed\n",
+ ODP_DBG("pktio limit %" PRIuPTR "/%d exceed\n",
_odp_typeval(pktio), ODP_CONFIG_PKTIO_ENTRIES);
return NULL;
}
@@ -274,6 +275,10 @@ _odp_sock_recv_mq_tmo_try_int_driven(const struct odp_pktin_queue_t queues[],
return 0;
}
+/* Setup PKTOUT with single queue for TM */
+int _odp_pktio_pktout_tm_config(odp_pktio_t pktio_hdl,
+ odp_pktout_queue_t *queue, bool reconf);
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4
index 3d50f2edc..1e6e8306c 100644
--- a/platform/linux-dpdk/m4/configure.m4
+++ b/platform/linux-dpdk/m4/configure.m4
@@ -83,6 +83,8 @@ AC_CONFIG_FILES([platform/linux-dpdk/Makefile
platform/linux-dpdk/test/example/Makefile
platform/linux-dpdk/test/example/classifier/Makefile
platform/linux-dpdk/test/example/generator/Makefile
+ platform/linux-dpdk/test/example/ipsec_api/Makefile
+ platform/linux-dpdk/test/example/ipsec_crypto/Makefile
platform/linux-dpdk/test/example/l2fwd_simple/Makefile
platform/linux-dpdk/test/example/l3fwd/Makefile
platform/linux-dpdk/test/example/packet/Makefile
diff --git a/platform/linux-dpdk/m4/odp_libconfig.m4 b/platform/linux-dpdk/m4/odp_libconfig.m4
index f56946ec5..f2aa36946 100644
--- a/platform/linux-dpdk/m4/odp_libconfig.m4
+++ b/platform/linux-dpdk/m4/odp_libconfig.m4
@@ -3,7 +3,7 @@
##########################################################################
m4_define([_odp_config_version_generation], [0])
m4_define([_odp_config_version_major], [1])
-m4_define([_odp_config_version_minor], [11])
+m4_define([_odp_config_version_minor], [12])
m4_define([_odp_config_version],
[_odp_config_version_generation._odp_config_version_major._odp_config_version_minor])
diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c
index 8030728dd..b0225629d 100644
--- a/platform/linux-dpdk/odp_packet.c
+++ b/platform/linux-dpdk/odp_packet.c
@@ -400,6 +400,7 @@ int odp_packet_trunc_head(odp_packet_t *pkt, uint32_t len, void **data_ptr,
_copy_head_metadata(newhead, mb);
prev->next = NULL;
rte_pktmbuf_free(mb);
+ mb = newhead;
*pkt = (odp_packet_t)newhead;
packet_hdr(*pkt)->buf_hdr.totsize -= totsize_change;
} else {
diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c
index 24c9c2aec..3ac6abd03 100644
--- a/platform/linux-dpdk/odp_pool.c
+++ b/platform/linux-dpdk/odp_pool.c
@@ -679,7 +679,7 @@ odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *params)
event_type = ODP_EVENT_PACKET;
ODP_DBG("type: packet, name: %s, num: %u, len: %u, blk_size: %u, "
- "uarea_size: %d, hdr_size: %d\n", pool_name, num, params->pkt.len,
+ "uarea_size: %d, hdr_size: %zu\n", pool_name, num, params->pkt.len,
blk_size, params->pkt.uarea_size, hdr_size);
break;
case ODP_POOL_TIMEOUT:
diff --git a/platform/linux-dpdk/odp_queue_basic.c b/platform/linux-dpdk/odp_queue_basic.c
index 4a4388b2b..7145fb2ce 100644
--- a/platform/linux-dpdk/odp_queue_basic.c
+++ b/platform/linux-dpdk/odp_queue_basic.c
@@ -166,7 +166,7 @@ static int queue_init_global(void)
queue_capa(&capa, 0);
ODP_DBG("... done.\n");
- ODP_DBG(" queue_entry_t size %u\n", sizeof(queue_entry_t));
+ ODP_DBG(" queue_entry_t size %zu\n", sizeof(queue_entry_t));
ODP_DBG(" max num queues %u\n", capa.max_queues);
ODP_DBG(" max queue size %u\n", capa.plain.max_size);
ODP_DBG(" max num lockfree %u\n", capa.plain.lockfree.max_num);
@@ -697,7 +697,7 @@ static void queue_print(odp_queue_t handle)
if (!odp_pktio_info(queue->s.pktout.pktio, &pktio_info))
ODP_PRINT(" pktout %s\n", pktio_info.name);
}
- ODP_PRINT(" timers %" PRIu32 "\n",
+ ODP_PRINT(" timers %" PRIu64 "\n",
odp_atomic_load_u64(&queue->s.num_timers));
ODP_PRINT(" status %s\n",
queue->s.status == QUEUE_STATUS_READY ? "ready" :
diff --git a/platform/linux-dpdk/odp_queue_eventdev.c b/platform/linux-dpdk/odp_queue_eventdev.c
index 5233031f6..96baffa6f 100644
--- a/platform/linux-dpdk/odp_queue_eventdev.c
+++ b/platform/linux-dpdk/odp_queue_eventdev.c
@@ -558,7 +558,7 @@ static int queue_init_global(void)
queue_capa(&capa, 0);
- ODP_DBG(" queue_entry_t size %u\n", sizeof(queue_entry_t));
+ ODP_DBG(" queue_entry_t size %zu\n", sizeof(queue_entry_t));
ODP_DBG(" max num queues %u\n", capa.max_queues);
ODP_DBG(" max plain queue size %u\n", capa.plain.max_size);
ODP_DBG(" max num lockfree %u\n", capa.plain.lockfree.max_num);
@@ -1048,7 +1048,7 @@ static void queue_print(odp_queue_t handle)
if (!odp_pktio_info(queue->s.pktout.pktio, &pktio_info))
ODP_PRINT(" pktout %s\n", pktio_info.name);
}
- ODP_PRINT(" timers %" PRIu32 "\n",
+ ODP_PRINT(" timers %" PRIu64 "\n",
odp_atomic_load_u64(&queue->s.num_timers));
ODP_PRINT(" status %s\n",
queue->s.status == QUEUE_STATUS_READY ? "ready" :
diff --git a/platform/linux-dpdk/odp_system_info.c b/platform/linux-dpdk/odp_system_info.c
index b48275233..af07f387a 100644
--- a/platform/linux-dpdk/odp_system_info.c
+++ b/platform/linux-dpdk/odp_system_info.c
@@ -95,7 +95,7 @@ static uint64_t default_huge_page_size(void)
while (fgets(str, sizeof(str), file) != NULL) {
if (sscanf(str, "Hugepagesize: %8lu kB", &sz) == 1) {
- ODP_DBG("defaut hp size is %" PRIu64 " kB\n", sz);
+ ODP_DBG("default hp size is %lu kB\n", sz);
fclose(file);
return (uint64_t)sz * 1024;
}
diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c
index 59aaf1c1a..1f3fb2719 100644
--- a/platform/linux-dpdk/odp_time.c
+++ b/platform/linux-dpdk/odp_time.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
+ * Copyright (c) 2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -17,6 +18,7 @@
#include <odp/api/plat/time_inlines.h>
#include <rte_config.h>
+#include <rte_atomic.h>
#include <rte_cycles.h>
ODP_STATIC_ASSERT(_ODP_TIMESPEC_SIZE >= (sizeof(struct timespec)),
@@ -148,6 +150,16 @@ static inline odp_time_t time_cur_dpdk(void)
return time;
}
+static inline odp_time_t time_cur_dpdk_strict(void)
+{
+ odp_time_t time;
+
+ rte_mb();
+ time.u64 = rte_get_timer_cycles() - _odp_time_glob.hw_start;
+
+ return time;
+}
+
static inline uint64_t time_res_dpdk(void)
{
return rte_get_timer_hz();
@@ -259,6 +271,7 @@ int _odp_time_init_global(void)
if (is_dpdk_timer_cycles_support()) {
_odp_time_glob.handler.time_cur = time_cur_dpdk;
+ _odp_time_glob.handler.time_cur_strict = time_cur_dpdk_strict;
_odp_time_glob.handler.time_res = time_res_dpdk;
_odp_time_glob.hw_freq_hz = time_res_dpdk();
_odp_time_glob.use_hw = 1;
@@ -270,6 +283,7 @@ int _odp_time_init_global(void)
}
_odp_time_glob.handler.time_cur = _odp_time_cur_gen;
+ _odp_time_glob.handler.time_cur_strict = _odp_time_cur_gen_strict;
_odp_time_glob.handler.time_res = time_res;
if (_odp_cpu_has_global_time()) {
diff --git a/platform/linux-dpdk/odp_timer.c b/platform/linux-dpdk/odp_timer.c
index 28b4b17a9..b5367b4c2 100644
--- a/platform/linux-dpdk/odp_timer.c
+++ b/platform/linux-dpdk/odp_timer.c
@@ -259,8 +259,8 @@ int odp_timer_capability(odp_timer_clk_src_t clk_src,
{
uint64_t min_tmo = tmo_ticks_to_ns_round_up(MIN_TMO_CYCLES);
- if (clk_src != ODP_CLOCK_CPU) {
- ODP_ERR("Clock source not supported\n");
+ if (clk_src != ODP_CLOCK_DEFAULT) {
+ ODP_ERR("Only ODP_CLOCK_DEFAULT supported. Requested %i.\n", clk_src);
return -1;
}
@@ -289,8 +289,8 @@ int odp_timer_res_capability(odp_timer_clk_src_t clk_src,
{
uint64_t min_tmo = tmo_ticks_to_ns_round_up(MIN_TMO_CYCLES);
- if (clk_src != ODP_CLOCK_CPU) {
- ODP_ERR("Only CPU clock source supported\n");
+ if (clk_src != ODP_CLOCK_DEFAULT) {
+ ODP_ERR("Only ODP_CLOCK_DEFAULT supported. Requested %i.\n", clk_src);
return -1;
}
@@ -655,7 +655,7 @@ retry:
ODP_DBG(" cur_tick %" PRIu64 ", abs_tick %" PRIu64 "\n",
cur_tick, abs_tick);
ODP_DBG(" num_retry %i\n", num_retry);
- return ODP_TIMER_TOOEARLY;
+ return ODP_TIMER_TOO_NEAR;
}
odp_ticketlock_lock(&timer->lock);
@@ -665,7 +665,7 @@ retry:
odp_ticketlock_unlock(&timer->lock);
/* Event missing, or timer already expired and
* enqueued the event. */
- return ODP_TIMER_NOEVENT;
+ return ODP_TIMER_FAIL;
}
if (odp_unlikely(rte_timer_reset(&timer->rte_timer, rel_tick, SINGLE,
@@ -699,7 +699,7 @@ retry:
/* Timer was just about to expire. Too late to reset this timer.
* Return code is NOEVENT, even when application did give
* an event. */
- return ODP_TIMER_NOEVENT;
+ return ODP_TIMER_FAIL;
}
if (event) {
diff --git a/platform/linux-dpdk/test/Makefile.am b/platform/linux-dpdk/test/Makefile.am
index b21fd5314..1496c0558 100644
--- a/platform/linux-dpdk/test/Makefile.am
+++ b/platform/linux-dpdk/test/Makefile.am
@@ -1,10 +1,17 @@
include $(top_srcdir)/test/Makefile.inc
TESTS_ENVIRONMENT += TEST_DIR=${top_builddir}/test/validation
+if WITH_OPENSSL
+TESTS_ENVIRONMENT += WITH_OPENSSL=1
+else
+TESTS_ENVIRONMENT += WITH_OPENSSL=0
+endif
+
SUBDIRS =
+TESTS =
if test_vald
-TESTS = validation/api/pktio/pktio_run.sh
+TESTS += validation/api/pktio/pktio_run.sh
test_SCRIPTS = $(dist_check_SCRIPTS)
@@ -36,25 +43,3 @@ 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
-
-.NOTPARALLEL:
diff --git a/platform/linux-dpdk/test/example/Makefile.am b/platform/linux-dpdk/test/example/Makefile.am
index 22b254cd7..947647cd4 100644
--- a/platform/linux-dpdk/test/example/Makefile.am
+++ b/platform/linux-dpdk/test/example/Makefile.am
@@ -1,6 +1,8 @@
SUBDIRS = \
classifier \
generator \
+ ipsec_api \
+ ipsec_crypto \
l2fwd_simple \
l3fwd \
packet \
diff --git a/platform/linux-dpdk/test/example/ipsec_api/Makefile.am b/platform/linux-dpdk/test/example/ipsec_api/Makefile.am
new file mode 100644
index 000000000..101c97cdf
--- /dev/null
+++ b/platform/linux-dpdk/test/example/ipsec_api/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = pktio_env
+
+# 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
+
+.NOTPARALLEL:
diff --git a/platform/linux-dpdk/test/example/ipsec_api/pktio_env b/platform/linux-dpdk/test/example/ipsec_api/pktio_env
new file mode 100644
index 000000000..c647f6bf2
--- /dev/null
+++ b/platform/linux-dpdk/test/example/ipsec_api/pktio_env
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Copyright (C) 2021, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-dpdk.
+#
+# ipsec_api application uses two loop devices loop0 and loop1.
+#
+
+if [ "$0" == "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+ exit 1
+fi
+
+# Absolute path to the .env file.
+LINUX_ENV_PATH=$PWD/../../platform/linux-dpdk/test
+
+TESTENV="tests-linux-dpdk.env"
+
+if [ -f $LINUX_ENV_PATH/$TESTENV ]; then
+ source $LINUX_ENV_PATH/$TESTENV
+else
+ echo "BUG: unable to find $TESTENV!"
+ echo "$TESTENV has to be in following directory: "
+ echo " $LINUX_ENV_PATH"
+ exit 1
+fi
+
+# Skip IPsec example tests when there's no OpenSSL.
+if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
+ echo "Crypto not supported. Skipping."
+ exit 77
+fi
+
+IF0=p7p1
+IF1=p8p1
+
+NEXT_HOP_MAC0=08:00:27:76:B5:E0
+NEXT_HOP_MAC1=08:00:27:F5:8B:DB
+
+LIF0=loop1
+LIF1=loop2
+
+IF_LIST=$LIF0,$LIF1
+ROUTE_IF_INB=$LIF0
+ROUTE_IF_OUTB=$LIF1
+OUT_IF=$LIF1
+IN_IF=$LIF0
+
+validate_result()
+{
+ return 0
+}
+
+setup_interfaces()
+{
+ return 0
+}
+
+cleanup_interfaces()
+{
+ return 0
+}
diff --git a/platform/linux-dpdk/test/example/ipsec_crypto/Makefile.am b/platform/linux-dpdk/test/example/ipsec_crypto/Makefile.am
new file mode 100644
index 000000000..101c97cdf
--- /dev/null
+++ b/platform/linux-dpdk/test/example/ipsec_crypto/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = pktio_env
+
+# 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
+
+.NOTPARALLEL:
diff --git a/platform/linux-dpdk/test/example/ipsec_crypto/pktio_env b/platform/linux-dpdk/test/example/ipsec_crypto/pktio_env
new file mode 100644
index 000000000..1c6e7d172
--- /dev/null
+++ b/platform/linux-dpdk/test/example/ipsec_crypto/pktio_env
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Copyright (C) 2021, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-dpdk.
+#
+# ipsec_api application uses two loop devices loop0 and loop1.
+#
+
+if [ "$0" == "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+ exit 1
+fi
+
+# Absolute path to the .env file.
+LINUX_ENV_PATH=$PWD/../../platform/linux-dpdk/test
+
+TESTENV="tests-linux-dpdk.env"
+
+if [ -f $LINUX_ENV_PATH/$TESTENV ]; then
+ source $LINUX_ENV_PATH/$TESTENV
+else
+ echo "BUG: unable to find $TESTENV!"
+ echo "$TESTENV has to be in following directory: "
+ echo " $LINUX_ENV_PATH"
+ exit 1
+fi
+
+# Skip IPsec example tests when there's no OpenSSL.
+if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
+ echo "Crypto not supported. Skipping."
+ exit 77
+fi
+
+# Skip live and router mode tests.
+if [ ${IPSEC_APP_MODE} -eq 1 ] || [ ${IPSEC_APP_MODE} -eq 2 ]; then
+ echo "Live / Router mode test. Skipping."
+ exit 77
+fi
+
+IF0=p7p1
+IF1=p8p1
+
+NEXT_HOP_MAC0=08:00:27:76:B5:E0
+NEXT_HOP_MAC1=08:00:27:F5:8B:DB
+
+LIF0=loop1
+LIF1=loop2
+
+IF_LIST=$LIF0,$LIF1
+ROUTE_IF_INB=$LIF0
+ROUTE_IF_OUTB=$LIF1
+OUT_IF=$LIF1
+IN_IF=$LIF0
+
+validate_result()
+{
+ return 0
+}
+
+setup_interfaces()
+{
+ return 0
+}
+
+cleanup_interfaces()
+{
+ return 0
+}
diff --git a/platform/linux-dpdk/test/sched-basic.conf b/platform/linux-dpdk/test/sched-basic.conf
index c54089a0d..8a46a3ccc 100644
--- a/platform/linux-dpdk/test/sched-basic.conf
+++ b/platform/linux-dpdk/test/sched-basic.conf
@@ -1,6 +1,6 @@
# Mandatory fields
odp_implementation = "linux-dpdk"
-config_file_version = "0.1.11"
+config_file_version = "0.1.12"
sched_basic: {
# Test scheduler with an odd spread value
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 2181abd26..e654381e6 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -293,7 +293,7 @@ __LIB__libodp_linux_la_SOURCES += arch/aarch64/odp_atomic.c \
arch/default/odp_hash_crc32.c \
arch/aarch64/odp_sysinfo_parse.c
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_inlines.h \
- arch/default/odp/api/abi/cpu_time.h \
+ arch/aarch64/odp/api/abi/cpu_time.h \
arch/aarch64/odp/api/abi/hash_crc32.h
if !ODP_ABI_COMPAT
odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \
diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h
new file mode 100644
index 000000000..781ee683c
--- /dev/null
+++ b/platform/linux-generic/arch/aarch64/odp/api/abi/cpu_time.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2021, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_API_ABI_CPU_TIME_H_
+#define ODP_API_ABI_CPU_TIME_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+static inline uint64_t _odp_cpu_global_time(void)
+{
+ uint64_t cntvct;
+
+ __asm__ volatile("mrs %0, cntvct_el0" : "=r"(cntvct) : : "memory");
+
+ return cntvct;
+}
+
+static inline uint64_t _odp_cpu_global_time_strict(void)
+{
+ uint64_t cntvct;
+
+ __asm__ volatile("isb" ::: "memory");
+ __asm__ volatile("mrs %0, cntvct_el0" : "=r"(cntvct) : : "memory");
+
+ return cntvct;
+}
+
+static inline uint64_t _odp_cpu_global_time_freq(void)
+{
+ uint64_t cntfrq;
+
+ __asm__ volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq) : : );
+
+ return cntfrq;
+}
+
+int _odp_cpu_has_global_time(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/arch/aarch64/odp_global_time.c b/platform/linux-generic/arch/aarch64/odp_global_time.c
index fa59f5a15..53561b00c 100644
--- a/platform/linux-generic/arch/aarch64/odp_global_time.c
+++ b/platform/linux-generic/arch/aarch64/odp_global_time.c
@@ -4,33 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <odp_posix_extensions.h>
-
-#include <time.h>
-
-#include <odp_debug_internal.h>
#include <odp/api/abi/cpu_time.h>
-#include <odp/visibility_begin.h>
-
-uint64_t _odp_cpu_global_time(void)
-{
- uint64_t cntvct;
-
- /*
- * To be consistent with other architectures, do not issue a
- * serializing instruction, e.g. ISB, before reading this
- * sys reg.
- */
-
- /* Memory clobber to minimize optimization around load from sys reg. */
- __asm__ volatile("mrs %0, cntvct_el0" : "=r"(cntvct) : : "memory");
-
- return cntvct;
-}
-
-#include <odp/visibility_end.h>
-
int _odp_cpu_has_global_time(void)
{
uint64_t hz = _odp_cpu_global_time_freq();
@@ -48,12 +23,3 @@ int _odp_cpu_has_global_time(void)
*/
return hz >= 1000000 && hz <= 6000000000;
}
-
-uint64_t _odp_cpu_global_time_freq(void)
-{
- uint64_t cntfrq;
-
- __asm__ volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq) : : );
-
- return cntfrq;
-}
diff --git a/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h
index 09138e70a..24e1c7d33 100644
--- a/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h
+++ b/platform/linux-generic/arch/default/odp/api/abi/cpu_time.h
@@ -15,6 +15,7 @@ extern "C" {
int _odp_cpu_has_global_time(void);
uint64_t _odp_cpu_global_time(void);
+uint64_t _odp_cpu_global_time_strict(void);
uint64_t _odp_cpu_global_time_freq(void);
#ifdef __cplusplus
diff --git a/platform/linux-generic/arch/default/odp_global_time.c b/platform/linux-generic/arch/default/odp_global_time.c
index facffea7d..ee835413f 100644
--- a/platform/linux-generic/arch/default/odp_global_time.c
+++ b/platform/linux-generic/arch/default/odp_global_time.c
@@ -13,6 +13,11 @@ uint64_t _odp_cpu_global_time(void)
return 0;
}
+uint64_t _odp_cpu_global_time_strict(void)
+{
+ return 0;
+}
+
#include <odp/visibility_end.h>
int _odp_cpu_has_global_time(void)
diff --git a/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h b/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h
index 05ff0db94..c74c4d606 100644
--- a/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h
+++ b/platform/linux-generic/arch/x86/odp/api/abi/cpu_time.h
@@ -19,6 +19,12 @@ static inline uint64_t _odp_cpu_global_time(void)
return _odp_cpu_rdtsc();
}
+static inline uint64_t _odp_cpu_global_time_strict(void)
+{
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
+ return _odp_cpu_rdtsc();
+}
+
int _odp_cpu_has_global_time(void);
uint64_t _odp_cpu_global_time_freq(void);
diff --git a/platform/linux-generic/include/odp/api/plat/time_inlines.h b/platform/linux-generic/include/odp/api/plat/time_inlines.h
index 1ca495065..bb2913532 100644
--- a/platform/linux-generic/include/odp/api/plat/time_inlines.h
+++ b/platform/linux-generic/include/odp/api/plat/time_inlines.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2018, Linaro Limited
- * Copyright (c) 2020, Nokia
+ * Copyright (c) 2020-2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -46,6 +46,18 @@ static inline odp_time_t _odp_time_cur(void)
return _odp_timespec_cur();
}
+static inline odp_time_t _odp_time_cur_strict(void)
+{
+ if (_odp_time_glob.use_hw) {
+ odp_time_t time;
+
+ time.count = _odp_cpu_global_time_strict() - _odp_time_glob.hw_start;
+ return time;
+ }
+
+ return _odp_timespec_cur();
+}
+
static inline uint64_t _odp_time_hw_to_ns(odp_time_t time)
{
uint64_t nsec;
@@ -79,6 +91,12 @@ static inline uint64_t _odp_time_convert_to_ns(odp_time_t time)
#define odp_time_to_ns __odp_time_to_ns
#define odp_time_local_ns __odp_time_local_ns
#define odp_time_global_ns __odp_time_global_ns
+
+ #define odp_time_local_strict __odp_time_local_strict
+ #define odp_time_global_strict __odp_time_global_strict
+ #define odp_time_local_strict_ns __odp_time_local_strict_ns
+ #define odp_time_global_strict_ns __odp_time_global_strict_ns
+
#define odp_time_cmp __odp_time_cmp
#define odp_time_diff __odp_time_diff
#define odp_time_sum __odp_time_sum
@@ -97,9 +115,14 @@ _ODP_INLINE odp_time_t odp_time_global(void)
return _odp_time_cur();
}
-_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+_ODP_INLINE odp_time_t odp_time_local_strict(void)
{
- return _odp_time_convert_to_ns(time);
+ return _odp_time_cur_strict();
+}
+
+_ODP_INLINE odp_time_t odp_time_global_strict(void)
+{
+ return _odp_time_cur_strict();
}
_ODP_INLINE uint64_t odp_time_local_ns(void)
@@ -112,6 +135,21 @@ _ODP_INLINE uint64_t odp_time_global_ns(void)
return _odp_time_convert_to_ns(_odp_time_cur());
}
+_ODP_INLINE uint64_t odp_time_local_strict_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur_strict());
+}
+
+_ODP_INLINE uint64_t odp_time_global_strict_ns(void)
+{
+ return _odp_time_convert_to_ns(_odp_time_cur_strict());
+}
+
+_ODP_INLINE uint64_t odp_time_to_ns(odp_time_t time)
+{
+ return _odp_time_convert_to_ns(time);
+}
+
_ODP_INLINE int odp_time_cmp(odp_time_t t2, odp_time_t t1)
{
if (odp_likely(t2.u64 > t1.u64))
diff --git a/platform/linux-generic/include/odp_debug_internal.h b/platform/linux-generic/include/odp_debug_internal.h
index dfad95b19..5027cfe4a 100644
--- a/platform/linux-generic/include/odp_debug_internal.h
+++ b/platform/linux-generic/include/odp_debug_internal.h
@@ -33,8 +33,15 @@ extern "C" {
* level 0 to N. */
#define CONFIG_DEBUG_LEVEL 0
+ODP_PRINTF_FORMAT(1, 2)
+static inline void check_printf_format(const char *fmt, ...)
+{
+ (void)fmt;
+}
+
#define _ODP_LOG_FN(level, fmt, ...) \
do { \
+ check_printf_format(fmt, ##__VA_ARGS__); \
if (_odp_this_thread && _odp_this_thread->log_fn) \
_odp_this_thread->log_fn(level, fmt, ##__VA_ARGS__); \
else \
diff --git a/platform/linux-generic/include/odp_ipsec_internal.h b/platform/linux-generic/include/odp_ipsec_internal.h
index 2509d22ab..96153007f 100644
--- a/platform/linux-generic/include/odp_ipsec_internal.h
+++ b/platform/linux-generic/include/odp_ipsec_internal.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2017-2018, Linaro Limited
+ * Copyright (c) 2018, 2020-2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -169,7 +170,7 @@ struct ipsec_sa_s {
struct {
odp_ipsec_frag_mode_t frag_mode;
- uint32_t mtu;
+ odp_atomic_u32_t mtu;
union {
struct {
@@ -196,13 +197,15 @@ struct ipsec_sa_s {
odp_atomic_u64_t hard_exp_pkts_err;
/*
- * Track error packets after lifetime check is done.
+ * Track error packets and bytes after lifetime check is done.
* Required since, the stats tracking lifetime is being
* used for SA success packets stats.
*/
odp_atomic_u64_t post_lifetime_err_pkts;
+ odp_atomic_u64_t post_lifetime_err_bytes;
} stats;
+ uint32_t next_sa;
odp_ipsec_sa_param_t param;
};
@@ -302,10 +305,16 @@ uint16_t _odp_ipsec_sa_alloc_ipv4_id(ipsec_sa_t *ipsec_sa);
int _odp_ipsec_try_inline(odp_packet_t *pkt);
/**
- * Get number of packets successfully processed by the SA
+ * Populate number of packets and bytes of data successfully processed by the SA
+ * in the odp_ipsec_stats_t structure passed.
*
*/
-uint64_t _odp_ipsec_sa_stats_pkts(ipsec_sa_t *sa);
+void _odp_ipsec_sa_stats_pkts(ipsec_sa_t *sa, odp_ipsec_stats_t *stats);
+
+/**
+ * Return true if IPsec operates in sync mode in the given direction.
+ */
+odp_bool_t _odp_ipsec_is_sync_mode(odp_ipsec_dir_t dir);
/**
* @}
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 7bbd78ab0..c5a51d11d 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -36,6 +36,7 @@ extern "C" {
#include <net/if.h>
#include <linux/if_ether.h>
#include <sys/select.h>
+#include <inttypes.h>
#define PKTIO_MAX_QUEUES 64
#define PKTIO_LSO_PROFILES 16
@@ -237,7 +238,7 @@ static inline pktio_entry_t *get_pktio_entry(odp_pktio_t pktio)
return NULL;
if (odp_unlikely(_odp_typeval(pktio) > ODP_CONFIG_PKTIO_ENTRIES)) {
- ODP_DBG("pktio limit %d/%d exceed\n",
+ ODP_DBG("pktio limit %" PRIuPTR "/%d exceed\n",
_odp_typeval(pktio), ODP_CONFIG_PKTIO_ENTRIES);
return NULL;
}
@@ -302,6 +303,10 @@ int _odp_sock_recv_mq_tmo_try_int_driven(const struct odp_pktin_queue_t queues[]
uint64_t usecs,
int *trial_successful);
+/* Setup PKTOUT with single queue for TM */
+int _odp_pktio_pktout_tm_config(odp_pktio_t pktio_hdl,
+ odp_pktout_queue_t *queue, bool reconf);
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index 535d43608..01593baea 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -45,6 +45,8 @@ AC_CONFIG_FILES([platform/linux-generic/Makefile
platform/linux-generic/test/example/Makefile
platform/linux-generic/test/example/classifier/Makefile
platform/linux-generic/test/example/generator/Makefile
+ platform/linux-generic/test/example/ipsec_api/Makefile
+ platform/linux-generic/test/example/ipsec_crypto/Makefile
platform/linux-generic/test/example/l2fwd_simple/Makefile
platform/linux-generic/test/example/l3fwd/Makefile
platform/linux-generic/test/example/packet/Makefile
diff --git a/platform/linux-generic/m4/odp_libconfig.m4 b/platform/linux-generic/m4/odp_libconfig.m4
index 7a0b45497..ecfb28b7f 100644
--- a/platform/linux-generic/m4/odp_libconfig.m4
+++ b/platform/linux-generic/m4/odp_libconfig.m4
@@ -3,7 +3,7 @@
##########################################################################
m4_define([_odp_config_version_generation], [0])
m4_define([_odp_config_version_major], [1])
-m4_define([_odp_config_version_minor], [15])
+m4_define([_odp_config_version_minor], [16])
m4_define([_odp_config_version],
[_odp_config_version_generation._odp_config_version_major._odp_config_version_minor])
diff --git a/platform/linux-generic/odp_comp.c b/platform/linux-generic/odp_comp.c
index 8e1de69c2..685c9098a 100644
--- a/platform/linux-generic/odp_comp.c
+++ b/platform/linux-generic/odp_comp.c
@@ -133,7 +133,7 @@ static void process_input(odp_packet_t pkt_out,
do {
out_data =
odp_packet_offset(pkt_out, start, &out_len, &cur_seg);
- ODP_DBG("out_data 0x%x seg_data_ptr 0x%x out_len %d seg 0x%x\n",
+ ODP_DBG("out_data %p seg_data_ptr %p out_len %d seg %p\n",
out_data, odp_packet_seg_data(pkt_out, cur_seg),
out_len, cur_seg);
@@ -258,7 +258,7 @@ static int deflate_comp(odp_packet_t pkt_in,
read,
&in_len,
&in_seg);
- ODP_DBG("data 0x%x in_len %d seg 0x%x len %d\n",
+ ODP_DBG("data %p in_len %d seg %p len %d\n",
data, in_len, in_seg, len);
if (in_len > len)
diff --git a/platform/linux-generic/odp_fdserver.c b/platform/linux-generic/odp_fdserver.c
index 9e0d75de3..3103ddd5c 100644
--- a/platform/linux-generic/odp_fdserver.c
+++ b/platform/linux-generic/odp_fdserver.c
@@ -246,10 +246,14 @@ static int get_socket(void)
int len;
/* construct the named socket path: */
- snprintf(sockpath, FDSERVER_SOCKPATH_MAXLEN, FDSERVER_SOCK_FORMAT,
- odp_global_ro.shm_dir,
- odp_global_ro.uid,
- odp_global_ro.main_pid);
+ len = snprintf(sockpath, FDSERVER_SOCKPATH_MAXLEN, FDSERVER_SOCK_FORMAT,
+ odp_global_ro.shm_dir, odp_global_ro.uid,
+ odp_global_ro.main_pid);
+
+ if (len >= FDSERVER_SOCKPATH_MAXLEN || len >= (int)sizeof(remote.sun_path)) {
+ ODP_ERR("path too long\n");
+ return -1;
+ }
s_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (s_sock == -1) {
@@ -561,7 +565,7 @@ int _odp_fdserver_init_global(void)
int sock;
struct sockaddr_un local;
pid_t server_pid;
- int res;
+ int len, res;
snprintf(sockpath, FDSERVER_SOCKPATH_MAXLEN, FDSERVER_SOCKDIR_FORMAT,
odp_global_ro.shm_dir,
@@ -570,10 +574,14 @@ int _odp_fdserver_init_global(void)
mkdir(sockpath, 0744);
/* construct the server named socket path: */
- snprintf(sockpath, FDSERVER_SOCKPATH_MAXLEN, FDSERVER_SOCK_FORMAT,
- odp_global_ro.shm_dir,
- odp_global_ro.uid,
- odp_global_ro.main_pid);
+ len = snprintf(sockpath, FDSERVER_SOCKPATH_MAXLEN, FDSERVER_SOCK_FORMAT,
+ odp_global_ro.shm_dir, odp_global_ro.uid,
+ odp_global_ro.main_pid);
+
+ if (len >= FDSERVER_SOCKPATH_MAXLEN || len >= (int)sizeof(local.sun_path)) {
+ ODP_ERR("path too long\n");
+ return -1;
+ }
/* create UNIX domain socket: */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c
index 5379a23d0..ed19392c9 100644
--- a/platform/linux-generic/odp_ipsec.c
+++ b/platform/linux-generic/odp_ipsec.c
@@ -19,6 +19,7 @@
#include <odp_ipsec_internal.h>
#include <odp/api/plat/queue_inlines.h>
#include <odp_classification_internal.h>
+#include <odp_libconfig_internal.h>
#include <protocols/eth.h>
#include <protocols/ip.h>
@@ -28,9 +29,42 @@
#include <errno.h>
#include <string.h>
+typedef enum {
+ IPSEC_ORDERING_NONE = 0,
+ IPSEC_ORDERING_SIMPLE,
+} ordering_mode_t;
+
+typedef struct {
+ ordering_mode_t inbound_ordering_mode;
+ ordering_mode_t outbound_ordering_mode;
+ odp_ipsec_config_t ipsec_config;
+} ipsec_global_t;
+
+static ipsec_global_t *ipsec_global;
+
static odp_ipsec_config_t *ipsec_config;
/*
+ * Wait until the ordered scheduling context of this thread corresponds
+ * to the head of its input queue. Do nothing if ordering is not requested
+ * or if not holding an ordered context.
+ */
+static void wait_for_order(ordering_mode_t mode)
+{
+ if (mode == IPSEC_ORDERING_NONE)
+ return;
+ _odp_sched_fn->order_lock();
+ /*
+ * We rely on the unlock being no-op, so let's not even bother
+ * calling it. Unlock cannot really be anything but a no-op since
+ * the scheduler cannot let other threads to continue until at
+ * scheduling context release time.
+ *
+ * _odp_sched_fn->order_unlock();
+ */
+}
+
+/*
* Set cabability bits for algorithms that are defined for use with IPsec
* and for which the IPsec crypto or auth capability function returns
* at least one supported instance.
@@ -240,6 +274,14 @@ int odp_ipsec_config(const odp_ipsec_config_t *config)
return 0;
}
+odp_bool_t _odp_ipsec_is_sync_mode(odp_ipsec_dir_t dir)
+{
+ return ((dir == ODP_IPSEC_DIR_INBOUND &&
+ ipsec_config->inbound_mode == ODP_IPSEC_OP_MODE_SYNC) ||
+ (dir == ODP_IPSEC_DIR_OUTBOUND &&
+ ipsec_config->outbound_mode == ODP_IPSEC_OP_MODE_SYNC));
+}
+
static odp_ipsec_packet_result_t *ipsec_pkt_result(odp_packet_t packet)
{
ODP_ASSERT(ODP_EVENT_PACKET_IPSEC ==
@@ -409,7 +451,7 @@ static inline ipsec_sa_t *ipsec_get_sa(odp_ipsec_sa_t sa,
return NULL;
}
} else {
- ipsec_sa = _odp_ipsec_sa_use(sa);
+ ipsec_sa = _odp_ipsec_sa_entry_from_hdl(sa);
ODP_ASSERT(NULL != ipsec_sa);
if (ipsec_sa->proto != proto ||
ipsec_sa->spi != spi) {
@@ -710,6 +752,7 @@ ipsec_sa_err_stats_update(ipsec_sa_t *sa, odp_ipsec_op_status_t *status)
static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
odp_ipsec_sa_t sa,
odp_packet_t *pkt_out,
+ odp_bool_t enqueue_op,
odp_ipsec_op_status_t *status)
{
ipsec_state_t state;
@@ -796,10 +839,15 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
goto exit;
}
- if (_odp_ipsec_sa_replay_update(ipsec_sa,
- state.in.seq_no,
- status) < 0)
- goto exit;
+ if (ipsec_sa->antireplay) {
+ if (enqueue_op)
+ wait_for_order(ipsec_global->inbound_ordering_mode);
+
+ if (_odp_ipsec_sa_replay_update(ipsec_sa,
+ state.in.seq_no,
+ status) < 0)
+ goto exit;
+ }
if (_odp_ipsec_sa_lifetime_update(ipsec_sa,
state.stats_length,
@@ -908,8 +956,11 @@ static ipsec_sa_t *ipsec_in_single(odp_packet_t pkt,
goto exit;
post_lifetime_err_cnt_update:
- if (ipsec_config->stats_en)
+ if (ipsec_config->stats_en) {
odp_atomic_inc_u64(&ipsec_sa->stats.post_lifetime_err_pkts);
+ odp_atomic_add_u64(&ipsec_sa->stats.post_lifetime_err_bytes,
+ state.stats_length);
+ }
exit:
*pkt_out = pkt;
@@ -1159,6 +1210,7 @@ static int ipsec_out_esp(odp_packet_t *pkt,
odp_crypto_packet_op_param_t *param,
odp_ipsec_op_status_t *status,
uint32_t mtu,
+ odp_bool_t enqueue_op,
const odp_ipsec_out_opt_t *opt)
{
_odp_esphdr_t esp;
@@ -1204,6 +1256,8 @@ static int ipsec_out_esp(odp_packet_t *pkt,
return -1;
}
+ if (enqueue_op)
+ wait_for_order(ipsec_global->outbound_ordering_mode);
seq_no = ipsec_seq_no(ipsec_sa);
if (ipsec_out_iv(state, ipsec_sa, seq_no) < 0) {
@@ -1331,7 +1385,8 @@ static int ipsec_out_ah(odp_packet_t *pkt,
ipsec_sa_t *ipsec_sa,
odp_crypto_packet_op_param_t *param,
odp_ipsec_op_status_t *status,
- uint32_t mtu)
+ uint32_t mtu,
+ odp_bool_t enqueue_op)
{
_odp_ahhdr_t ah;
unsigned hdr_len = _ODP_AHHDR_LEN + ipsec_sa->esp_iv_len +
@@ -1345,6 +1400,8 @@ static int ipsec_out_ah(odp_packet_t *pkt,
return -1;
}
+ if (enqueue_op)
+ wait_for_order(ipsec_global->outbound_ordering_mode);
seq_no = ipsec_seq_no(ipsec_sa);
memset(&ah, 0, sizeof(ah));
@@ -1489,6 +1546,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
odp_ipsec_sa_t sa,
odp_packet_t *pkt_out,
const odp_ipsec_out_opt_t *opt,
+ odp_bool_t enqueue_op,
odp_ipsec_op_status_t *status)
{
ipsec_state_t state;
@@ -1533,7 +1591,7 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
frag_mode = opt->flag.frag_mode ? opt->frag_mode :
ipsec_sa->out.frag_mode;
if (frag_mode == ODP_IPSEC_FRAG_CHECK)
- mtu = ipsec_sa->out.mtu;
+ mtu = odp_atomic_load_u32(&ipsec_sa->out.mtu);
else
mtu = UINT32_MAX;
@@ -1594,9 +1652,10 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
if (ODP_IPSEC_ESP == ipsec_sa->proto) {
rc = ipsec_out_esp(&pkt, &state, ipsec_sa, &param, status, mtu,
- opt);
+ enqueue_op, opt);
} else if (ODP_IPSEC_AH == ipsec_sa->proto) {
- rc = ipsec_out_ah(&pkt, &state, ipsec_sa, &param, status, mtu);
+ rc = ipsec_out_ah(&pkt, &state, ipsec_sa, &param, status, mtu,
+ enqueue_op);
} else {
status->error.alg = 1;
goto exit;
@@ -1652,8 +1711,11 @@ static ipsec_sa_t *ipsec_out_single(odp_packet_t pkt,
goto exit;
post_lifetime_err_cnt_update:
- if (ipsec_config->stats_en)
+ if (ipsec_config->stats_en) {
odp_atomic_inc_u64(&ipsec_sa->stats.post_lifetime_err_pkts);
+ odp_atomic_add_u64(&ipsec_sa->stats.post_lifetime_err_bytes,
+ state.stats_length);
+ }
exit:
*pkt_out = pkt;
@@ -1686,7 +1748,7 @@ int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in,
ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa);
}
- ipsec_sa = ipsec_in_single(pkt, sa, &pkt, &status);
+ ipsec_sa = ipsec_in_single(pkt, sa, &pkt, false, &status);
packet_subtype_set(pkt, ODP_EVENT_PACKET_IPSEC);
result = ipsec_pkt_result(pkt);
@@ -1702,8 +1764,12 @@ int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in,
out_pkt++;
sa_idx += sa_inc;
- /* Last thing */
- if (NULL != ipsec_sa)
+ /*
+ * We need to decrease SA use count only if the SA was not
+ * provided to us by the caller but was found through our own
+ * SA lookup that increased the use count.
+ */
+ if (sa == ODP_IPSEC_SA_INVALID && ipsec_sa)
_odp_ipsec_sa_unuse(ipsec_sa);
}
@@ -1746,7 +1812,7 @@ int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in,
else
opt = &param->opt[opt_idx];
- ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status);
+ ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, false, &status);
ODP_ASSERT(NULL != ipsec_sa);
packet_subtype_set(pkt, ODP_EVENT_PACKET_IPSEC);
@@ -1794,7 +1860,7 @@ int odp_ipsec_in_enq(const odp_packet_t pkt_in[], int num_in,
ODP_ASSERT(ODP_IPSEC_SA_INVALID != sa);
}
- ipsec_sa = ipsec_in_single(pkt, sa, &pkt, &status);
+ ipsec_sa = ipsec_in_single(pkt, sa, &pkt, true, &status);
packet_subtype_set(pkt, ODP_EVENT_PACKET_IPSEC);
result = ipsec_pkt_result(pkt);
@@ -1815,8 +1881,12 @@ int odp_ipsec_in_enq(const odp_packet_t pkt_in[], int num_in,
in_pkt++;
sa_idx += sa_inc;
- /* Last thing */
- if (NULL != ipsec_sa)
+ /*
+ * We need to decrease SA use count only if the SA was not
+ * provided to us by the caller but was found through our own
+ * SA lookup that increased the use count.
+ */
+ if (sa == ODP_IPSEC_SA_INVALID && ipsec_sa)
_odp_ipsec_sa_unuse(ipsec_sa);
}
@@ -1853,7 +1923,7 @@ int odp_ipsec_out_enq(const odp_packet_t pkt_in[], int num_in,
else
opt = &param->opt[opt_idx];
- ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status);
+ ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, true, &status);
ODP_ASSERT(NULL != ipsec_sa);
packet_subtype_set(pkt, ODP_EVENT_PACKET_IPSEC);
@@ -1890,7 +1960,8 @@ int _odp_ipsec_try_inline(odp_packet_t *pkt)
memset(&status, 0, sizeof(status));
- ipsec_sa = ipsec_in_single(*pkt, ODP_IPSEC_SA_INVALID, pkt, &status);
+ ipsec_sa = ipsec_in_single(*pkt, ODP_IPSEC_SA_INVALID, pkt, false,
+ &status);
/*
* Route packet back in case of lookup failure or early error before
* lookup
@@ -1977,7 +2048,7 @@ int odp_ipsec_out_inline(const odp_packet_t pkt_in[], int num_in,
else
opt = &param->opt[opt_idx];
- ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, &status);
+ ipsec_sa = ipsec_out_single(pkt, sa, &pkt, opt, true, &status);
ODP_ASSERT(NULL != ipsec_sa);
offset = odp_packet_l3_offset(pkt);
@@ -2110,7 +2181,7 @@ int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats)
ipsec_sa = _odp_ipsec_sa_entry_from_hdl(sa);
ODP_ASSERT(NULL != ipsec_sa);
- stats->success = _odp_ipsec_sa_stats_pkts(ipsec_sa);
+ _odp_ipsec_sa_stats_pkts(ipsec_sa, stats);
stats->proto_err = odp_atomic_load_u64(&ipsec_sa->stats.proto_err);
stats->auth_err = odp_atomic_load_u64(&ipsec_sa->stats.auth_err);
stats->antireplay_err = odp_atomic_load_u64(&ipsec_sa->stats.antireplay_err);
@@ -2122,6 +2193,27 @@ int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats)
return 0;
}
+static int read_config_file(ipsec_global_t *global)
+{
+ const char *str_i = "ipsec.ordering.async_inbound";
+ const char *str_o = "ipsec.ordering.async_outbound";
+ int val;
+
+ if (!_odp_libconfig_lookup_int(str_i, &val)) {
+ ODP_ERR("Config option '%s' not found.\n", str_i);
+ return -1;
+ }
+ global->inbound_ordering_mode = val;
+
+ if (!_odp_libconfig_lookup_int(str_o, &val)) {
+ ODP_ERR("Config option '%s' not found.\n", str_o);
+ return -1;
+ }
+ global->outbound_ordering_mode = val;
+
+ return 0;
+}
+
int _odp_ipsec_init_global(void)
{
odp_shm_t shm;
@@ -2129,17 +2221,25 @@ int _odp_ipsec_init_global(void)
if (odp_global_ro.disable.ipsec)
return 0;
- shm = odp_shm_reserve("_odp_ipsec", sizeof(odp_ipsec_config_t),
+ shm = odp_shm_reserve("_odp_ipsec", sizeof(*ipsec_global),
ODP_CACHE_LINE_SIZE, 0);
-
- ipsec_config = odp_shm_addr(shm);
-
- if (ipsec_config == NULL) {
+ if (shm == ODP_SHM_INVALID) {
ODP_ERR("Shm reserve failed for odp_ipsec\n");
return -1;
}
+ ipsec_global = odp_shm_addr(shm);
+ if (ipsec_global == NULL) {
+ ODP_ERR("ipsec: odp_shm_addr() failed\n");
+ odp_shm_free(shm);
+ return -1;
+ }
+ memset(ipsec_global, 0, sizeof(*ipsec_global));
+ ipsec_config = &ipsec_global->ipsec_config;
- odp_ipsec_config_init(ipsec_config);
+ if (read_config_file(ipsec_global)) {
+ odp_shm_free(shm);
+ return -1;
+ }
memset(&default_out_opt, 0, sizeof(default_out_opt));
diff --git a/platform/linux-generic/odp_ipsec_sad.c b/platform/linux-generic/odp_ipsec_sad.c
index da8232b01..d0367bf63 100644
--- a/platform/linux-generic/odp_ipsec_sad.c
+++ b/platform/linux-generic/odp_ipsec_sad.c
@@ -22,9 +22,24 @@
#include <string.h>
-#define IPSEC_SA_STATE_DISABLE 0x40000000
-#define IPSEC_SA_STATE_FREE 0xc0000000
-#define IPSEC_SA_STATE_RESERVED 0x80000000
+/*
+ * SA state consists of state value in the high order bits of ipsec_sa_t::state
+ * and use counter in the low order bits.
+ *
+ * An SA cannot be destroyed if its use count is higher than one. Use counter
+ * is needed for the case SA lookup is done by us and not the application.
+ * In the latter case we rely on the fact that the application may not pass
+ * the SA as a parameter to an IPsec operation concurrently with a call
+ * to odp_ipsec_sa_disable().
+ *
+ * SAs that are free or being disabled cannot be found in SA lookup by ODP.
+ */
+#define IPSEC_SA_STATE_ACTIVE 0x00000000 /* SA is in use */
+#define IPSEC_SA_STATE_DISABLE 0x40000000 /* SA is being disabled */
+#define IPSEC_SA_STATE_FREE 0xc0000000 /* SA is unused and free */
+#define IPSEC_SA_STATE_MASK 0xc0000000 /* mask of state bits */
+
+#define SA_IDX_NONE UINT32_MAX
/*
* We do not have global IPv4 ID counter that is accessed for every outbound
@@ -68,7 +83,7 @@ typedef struct sa_thread_local_s {
* Bytes that can be processed in this thread before looking at
* the SA-global byte counter and checking hard and soft limits.
*/
- uint32_t byte_quota;
+ odp_atomic_u32_t byte_quota;
/*
* Life time status when this thread last checked the global
* counter(s).
@@ -88,6 +103,10 @@ typedef struct ipsec_sa_table_t {
ring_mpmc_t ipv4_id_ring;
uint32_t ipv4_id_data[IPV4_ID_RING_SIZE] ODP_ALIGNED_CACHE;
} hot;
+ struct {
+ uint32_t head;
+ odp_spinlock_t lock;
+ } sa_freelist;
uint32_t max_num_sa;
odp_shm_t shm;
ipsec_thread_local_t per_thread[];
@@ -130,7 +149,7 @@ static void init_sa_thread_local(ipsec_sa_t *sa)
for (n = 0; n < thread_count_max; n++) {
sa_tl = &ipsec_sa_tbl->per_thread[n].sa[sa->ipsec_sa_idx];
odp_atomic_init_u32(&sa_tl->packet_quota, 0);
- sa_tl->byte_quota = 0;
+ odp_atomic_init_u32(&sa_tl->byte_quota, 0);
sa_tl->lifetime_status.all = 0;
}
}
@@ -199,10 +218,15 @@ int _odp_ipsec_sad_init_global(void)
ipsec_sa->ipsec_sa_hdl = ipsec_sa_index_to_handle(i);
ipsec_sa->ipsec_sa_idx = i;
+ ipsec_sa->next_sa = i + 1;
+ if (i == ipsec_sa_tbl->max_num_sa - 1)
+ ipsec_sa->next_sa = SA_IDX_NONE;
odp_atomic_init_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE);
odp_atomic_init_u64(&ipsec_sa->hot.bytes, 0);
odp_atomic_init_u64(&ipsec_sa->hot.packets, 0);
}
+ ipsec_sa_tbl->sa_freelist.head = 0;
+ odp_spinlock_init(&ipsec_sa_tbl->sa_freelist.lock);
return 0;
}
@@ -245,31 +269,32 @@ uint32_t _odp_ipsec_max_num_sa(void)
static ipsec_sa_t *ipsec_sa_reserve(void)
{
- uint32_t i;
- ipsec_sa_t *ipsec_sa;
-
- for (i = 0; i < ipsec_sa_tbl->max_num_sa; i++) {
- uint32_t state = IPSEC_SA_STATE_FREE;
-
- ipsec_sa = ipsec_sa_entry(i);
-
- if (odp_atomic_cas_acq_u32(&ipsec_sa->state, &state,
- IPSEC_SA_STATE_RESERVED))
- return ipsec_sa;
+ ipsec_sa_t *ipsec_sa = NULL;
+ uint32_t sa_idx;
+
+ odp_spinlock_lock(&ipsec_sa_tbl->sa_freelist.lock);
+ sa_idx = ipsec_sa_tbl->sa_freelist.head;
+ if (sa_idx != SA_IDX_NONE) {
+ ipsec_sa = ipsec_sa_entry(sa_idx);
+ ipsec_sa_tbl->sa_freelist.head = ipsec_sa->next_sa;
}
-
- return NULL;
+ odp_spinlock_unlock(&ipsec_sa_tbl->sa_freelist.lock);
+ return ipsec_sa;
}
static void ipsec_sa_release(ipsec_sa_t *ipsec_sa)
{
- odp_atomic_store_rel_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE);
+ odp_spinlock_lock(&ipsec_sa_tbl->sa_freelist.lock);
+ ipsec_sa->next_sa = ipsec_sa_tbl->sa_freelist.head;
+ ipsec_sa_tbl->sa_freelist.head = ipsec_sa->ipsec_sa_idx;
+ odp_atomic_store_u32(&ipsec_sa->state, IPSEC_SA_STATE_FREE);
+ odp_spinlock_unlock(&ipsec_sa_tbl->sa_freelist.lock);
}
/* Mark reserved SA as available now */
static void ipsec_sa_publish(ipsec_sa_t *ipsec_sa)
{
- odp_atomic_store_rel_u32(&ipsec_sa->state, 0);
+ odp_atomic_store_rel_u32(&ipsec_sa->state, IPSEC_SA_STATE_ACTIVE);
}
static int ipsec_sa_lock(ipsec_sa_t *ipsec_sa)
@@ -280,11 +305,9 @@ static int ipsec_sa_lock(ipsec_sa_t *ipsec_sa)
while (0 == cas) {
/*
* This can be called from lookup path, so we really need this
- * check. Thanks to the way flags are defined we actually test
- * that the SA is not DISABLED, FREE or RESERVED using just one
- * condition.
+ * check.
*/
- if (state & IPSEC_SA_STATE_FREE)
+ if ((state & IPSEC_SA_STATE_MASK) != IPSEC_SA_STATE_ACTIVE)
return -1;
cas = odp_atomic_cas_acq_u32(&ipsec_sa->state, &state,
@@ -440,6 +463,10 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
ipsec_sa->spi = param->spi;
ipsec_sa->context = param->context;
ipsec_sa->queue = param->dest_queue;
+ if (_odp_ipsec_is_sync_mode(param->dir)) {
+ /* Invalid queue indicates sync mode */
+ ipsec_sa->queue = ODP_QUEUE_INVALID;
+ }
ipsec_sa->mode = param->mode;
ipsec_sa->flags = 0;
if (param->opt.esn) {
@@ -469,7 +496,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
ipsec_sa->lookup_mode = ODP_IPSEC_LOOKUP_DISABLED;
odp_atomic_init_u64(&ipsec_sa->hot.out.seq, 1);
ipsec_sa->out.frag_mode = param->outbound.frag_mode;
- ipsec_sa->out.mtu = param->outbound.mtu;
+ odp_atomic_init_u32(&ipsec_sa->out.mtu, param->outbound.mtu);
}
ipsec_sa->dec_ttl = param->opt.dec_ttl;
ipsec_sa->copy_dscp = param->opt.copy_dscp;
@@ -492,6 +519,7 @@ odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param)
odp_atomic_init_u64(&ipsec_sa->stats.hard_exp_bytes_err, 0);
odp_atomic_init_u64(&ipsec_sa->stats.hard_exp_pkts_err, 0);
odp_atomic_init_u64(&ipsec_sa->stats.post_lifetime_err_pkts, 0);
+ odp_atomic_init_u64(&ipsec_sa->stats.post_lifetime_err_bytes, 0);
/* Copy application provided parameter values. */
ipsec_sa->param = *param;
@@ -770,13 +798,9 @@ int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu)
{
ipsec_sa_t *ipsec_sa;
- ipsec_sa = _odp_ipsec_sa_use(sa);
+ ipsec_sa = ipsec_sa_entry_from_hdl(sa);
ODP_ASSERT(NULL != ipsec_sa);
-
- ipsec_sa->out.mtu = mtu;
-
- _odp_ipsec_sa_unuse(ipsec_sa);
-
+ odp_atomic_store_u32(&ipsec_sa->out.mtu, mtu);
return 0;
}
@@ -835,6 +859,7 @@ int _odp_ipsec_sa_lifetime_update(ipsec_sa_t *ipsec_sa, uint32_t len,
{
sa_thread_local_t *sa_tl = ipsec_sa_thread_local(ipsec_sa);
uint64_t packets, bytes;
+ uint32_t tl_byte_quota;
uint32_t tl_pkt_quota;
tl_pkt_quota = odp_atomic_load_u32(&sa_tl->packet_quota);
@@ -855,11 +880,12 @@ int _odp_ipsec_sa_lifetime_update(ipsec_sa_t *ipsec_sa, uint32_t len,
tl_pkt_quota--;
odp_atomic_store_u32(&sa_tl->packet_quota, tl_pkt_quota);
- if (odp_unlikely(sa_tl->byte_quota < len)) {
+ tl_byte_quota = odp_atomic_load_u32(&sa_tl->byte_quota);
+ if (odp_unlikely(tl_byte_quota < len)) {
bytes = odp_atomic_fetch_add_u64(&ipsec_sa->hot.bytes,
len + SA_LIFE_BYTES_PREALLOC);
bytes += len + SA_LIFE_BYTES_PREALLOC;
- sa_tl->byte_quota += len + SA_LIFE_BYTES_PREALLOC;
+ tl_byte_quota += len + SA_LIFE_BYTES_PREALLOC;
if (ipsec_sa->soft_limit_bytes > 0 &&
bytes >= ipsec_sa->soft_limit_bytes)
@@ -869,7 +895,9 @@ int _odp_ipsec_sa_lifetime_update(ipsec_sa_t *ipsec_sa, uint32_t len,
bytes >= ipsec_sa->hard_limit_bytes)
sa_tl->lifetime_status.error.hard_exp_bytes = 1;
}
- sa_tl->byte_quota -= len;
+ tl_byte_quota -= len;
+ odp_atomic_store_u32(&sa_tl->byte_quota, tl_byte_quota);
+
status->all |= sa_tl->lifetime_status.all;
@@ -909,9 +937,6 @@ int _odp_ipsec_sa_replay_update(ipsec_sa_t *ipsec_sa, uint32_t seq,
int cas = 0;
uint64_t state, new_state;
- if (!ipsec_sa->antireplay)
- return 0;
-
state = odp_atomic_load_u64(&ipsec_sa->hot.in.antireplay);
while (0 == cas) {
@@ -973,9 +998,10 @@ uint16_t _odp_ipsec_sa_alloc_ipv4_id(ipsec_sa_t *ipsec_sa)
return tl->next_ipv4_id++;
}
-uint64_t _odp_ipsec_sa_stats_pkts(ipsec_sa_t *sa)
+void _odp_ipsec_sa_stats_pkts(ipsec_sa_t *sa, odp_ipsec_stats_t *stats)
{
int thread_count_max = odp_thread_count_max();
+ uint64_t tl_byte_quota = 0;
uint64_t tl_pkt_quota = 0;
sa_thread_local_t *sa_tl;
int n;
@@ -994,11 +1020,20 @@ uint64_t _odp_ipsec_sa_stats_pkts(ipsec_sa_t *sa)
for (n = 0; n < thread_count_max; n++) {
sa_tl = &ipsec_sa_tbl->per_thread[n].sa[sa->ipsec_sa_idx];
tl_pkt_quota += odp_atomic_load_u32(&sa_tl->packet_quota);
+ tl_byte_quota += odp_atomic_load_u32(&sa_tl->byte_quota);
}
- return odp_atomic_load_u64(&sa->hot.packets)
+ stats->success =
+ odp_atomic_load_u64(&sa->hot.packets)
- odp_atomic_load_u64(&sa->stats.post_lifetime_err_pkts)
- tl_pkt_quota;
+
+ stats->success_bytes =
+ odp_atomic_load_u64(&sa->hot.bytes)
+ - odp_atomic_load_u64(&sa->stats.post_lifetime_err_bytes)
+ - tl_byte_quota;
+
+ return;
}
static void ipsec_out_sa_info(ipsec_sa_t *ipsec_sa, odp_ipsec_sa_info_t *sa_info)
diff --git a/platform/linux-generic/odp_ishm.c b/platform/linux-generic/odp_ishm.c
index 0014f3c34..7041cd2b5 100644
--- a/platform/linux-generic/odp_ishm.c
+++ b/platform/linux-generic/odp_ishm.c
@@ -1995,7 +1995,7 @@ int _odp_ishm_status(const char *title)
}
ODP_PRINT("%s\n", title);
- ODP_PRINT(" %-*s flag %-29s %-08s %-08s %-3s %-3s %-3s file\n",
+ ODP_PRINT(" %-*s flag %-29s %-8s %-8s %-3s %-3s %-3s file\n",
max_name_len, "name", "range", "user_len", "unused",
"seq", "ref", "fd");
@@ -2045,8 +2045,8 @@ int _odp_ishm_status(const char *title)
entry_fd = ishm_proctable->entry[proc_index].fd;
}
- ODP_PRINT("%2i %-*s %s%c %p-%p %-08" PRIu64 " "
- "%-08" PRIu64 " %-3" PRIu64 " %-3" PRIu64 " "
+ ODP_PRINT("%2i %-*s %s%c %p-%p %-8" PRIu64 " "
+ "%-8" PRIu64 " %-3" PRIu64 " %-3" PRIu64 " "
"%-3d %s\n",
i, max_name_len, ishm_tbl->block[i].name,
flags, huge, start_addr, end_addr,
@@ -2059,7 +2059,7 @@ int _odp_ishm_status(const char *title)
ishm_tbl->block[i].filename :
"(none)");
}
- ODP_PRINT("TOTAL: %58s%-08" PRIu64 " %2s%-08" PRIu64 "\n",
+ ODP_PRINT("TOTAL: %58s%-8" PRIu64 " %2s%-8" PRIu64 "\n",
"", len_total,
"", lost_total);
ODP_PRINT("%65s(%" PRIu64 "MB) %4s(%" PRIu64 "MB)\n",
@@ -2072,15 +2072,15 @@ int _odp_ishm_status(const char *title)
fragmnt; fragmnt = fragmnt->next) {
if (fragmnt->block_index >= 0) {
nb_allocated_frgments++;
- ODP_PRINT(" %08p - %08p: ALLOCATED by block:%d\n",
- (uintptr_t)fragmnt->start,
- (uintptr_t)fragmnt->start + fragmnt->len - 1,
+ ODP_PRINT(" %8p - %8p: ALLOCATED by block:%d\n",
+ fragmnt->start,
+ (void *)((uintptr_t)fragmnt->start + fragmnt->len - 1),
fragmnt->block_index);
consecutive_unallocated = 0;
} else {
- ODP_PRINT(" %08p - %08p: NOT ALLOCATED\n",
- (uintptr_t)fragmnt->start,
- (uintptr_t)fragmnt->start + fragmnt->len - 1);
+ ODP_PRINT(" %8p - %8p: NOT ALLOCATED\n",
+ fragmnt->start,
+ (void *)((uintptr_t)fragmnt->start + fragmnt->len - 1));
if (consecutive_unallocated++)
ODP_ERR("defragmentation error\n");
}
diff --git a/platform/linux-generic/odp_ishmpool.c b/platform/linux-generic/odp_ishmpool.c
index 4b593a4bc..818b0a132 100644
--- a/platform/linux-generic/odp_ishmpool.c
+++ b/platform/linux-generic/odp_ishmpool.c
@@ -280,7 +280,7 @@ static void *_odp_ishmbud_alloc(pool_t *bpool, uint64_t size)
uintptr_t nr;
/* if size is zero or too big reject: */
- if ((!size) && (size > (1U << bpool->ctrl.order))) {
+ if ((!size) && (size > (1ULL << bpool->ctrl.order))) {
ODP_ERR("Invalid alloc size (0 or larger than whole pool)\n");
return NULL;
}
diff --git a/platform/linux-generic/odp_name_table.c b/platform/linux-generic/odp_name_table.c
index 3697bc877..9c1814cae 100644
--- a/platform/linux-generic/odp_name_table.c
+++ b/platform/linux-generic/odp_name_table.c
@@ -376,6 +376,7 @@ static void name_tbl_entry_free(name_tbl_entry_t *name_tbl_entry)
memset(name_tbl_entry, 0, sizeof(name_tbl_entry_t));
name_tbl_entry->next_entry = name_tbl->free_list_head;
name_tbl->free_list_head = name_tbl_entry;
+ name_tbl_entry->name_tbl_id = name_tbl_id;
}
static hash_tbl_entry_t make_hash_tbl_entry(name_tbl_entry_t *name_tbl_entry,
diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 711e5f8a6..694b0a741 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -377,7 +377,7 @@ static const char *driver_name(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_ERR("pktio entry %d does not exist\n", hdl);
+ ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return "bad handle";
}
@@ -1253,7 +1253,7 @@ static inline uint32_t pktio_maxlen(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return 0;
}
@@ -1296,7 +1296,7 @@ int odp_pktio_maxlen_set(odp_pktio_t hdl, uint32_t maxlen_input,
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_ERR("Pktio entry %d does not exist\n", hdl);
+ ODP_ERR("Pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1360,7 +1360,7 @@ int odp_pktio_promisc_mode_set(odp_pktio_t hdl, odp_bool_t enable)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1390,7 +1390,7 @@ int odp_pktio_promisc_mode(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1421,7 +1421,7 @@ int odp_pktio_mac_addr(odp_pktio_t hdl, void *mac_addr, int addr_size)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1456,7 +1456,7 @@ int odp_pktio_mac_addr_set(odp_pktio_t hdl, const void *mac_addr, int addr_size)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1487,7 +1487,7 @@ odp_pktio_link_status_t odp_pktio_link_status(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return ODP_PKTIO_LINK_STATUS_UNKNOWN;
}
@@ -1543,7 +1543,7 @@ int odp_pktio_info(odp_pktio_t hdl, odp_pktio_info_t *info)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1563,7 +1563,7 @@ int odp_pktio_link_info(odp_pktio_t hdl, odp_pktio_link_info_t *info)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
@@ -1579,7 +1579,7 @@ uint64_t odp_pktio_ts_res(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_ERR("pktio entry %d does not exist\n", hdl);
+ ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return 0;
}
@@ -1596,7 +1596,7 @@ odp_time_t odp_pktio_ts_from_ns(odp_pktio_t hdl, uint64_t ns)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_ERR("pktio entry %d does not exist\n", hdl);
+ ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return ODP_TIME_NULL;
}
@@ -1613,7 +1613,7 @@ odp_time_t odp_pktio_time(odp_pktio_t hdl, odp_time_t *global_ts)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_ERR("pktio entry %d does not exist\n", hdl);
+ ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return ODP_TIME_NULL;
}
@@ -1652,7 +1652,7 @@ void odp_pktio_print(odp_pktio_t hdl)
entry = get_pktio_entry(hdl);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", hdl);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return;
}
@@ -1781,7 +1781,7 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -1850,7 +1850,7 @@ int odp_pktio_stats(odp_pktio_t pktio,
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -1880,7 +1880,7 @@ int odp_pktio_stats_reset(odp_pktio_t pktio)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -1920,7 +1920,7 @@ int odp_pktin_queue_config(odp_pktio_t pktio,
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2065,6 +2065,77 @@ int odp_pktin_queue_config(odp_pktio_t pktio,
return 0;
}
+int _odp_pktio_pktout_tm_config(odp_pktio_t pktio_hdl,
+ odp_pktout_queue_t *queue, bool reconf)
+{
+ odp_pktout_queue_param_t param;
+ bool pktio_started = false;
+ odp_pktout_mode_t mode;
+ pktio_entry_t *entry;
+ unsigned int i;
+ int rc = 0;
+
+ odp_pktout_queue_param_init(&param);
+ param.num_queues = 1;
+
+ entry = get_pktio_entry(pktio_hdl);
+ if (entry == NULL) {
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio_hdl);
+ return -1;
+ }
+
+ rc = -ENOTSUP;
+ mode = entry->s.param.out_mode;
+ /* Don't proceed further if mode is not TM */
+ if (mode != ODP_PKTOUT_MODE_TM)
+ return rc;
+
+ /* Don't reconfigure unless requested */
+ if (entry->s.num_out_queue && !reconf) {
+ *queue = entry->s.out_queue[0].pktout;
+ return 0;
+ }
+
+ if (entry->s.state == PKTIO_STATE_STARTED) {
+ pktio_started = true;
+ rc = odp_pktio_stop(pktio_hdl);
+ if (rc) {
+ ODP_ERR("Unable to stop pktio, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* If re-configuring, destroy old queues */
+ if (entry->s.num_out_queue) {
+ destroy_out_queues(entry, entry->s.num_out_queue);
+ entry->s.num_out_queue = 0;
+ }
+
+ init_out_queues(entry);
+ for (i = 0; i < param.num_queues; i++) {
+ entry->s.out_queue[i].pktout.index = i;
+ entry->s.out_queue[i].pktout.pktio = pktio_hdl;
+ }
+
+ entry->s.num_out_queue = param.num_queues;
+
+ rc = 0;
+ if (entry->s.ops->output_queues_config) {
+ rc = entry->s.ops->output_queues_config(entry, &param);
+ if (rc)
+ ODP_ERR("Unable to setup output queues, rc=%d\n", rc);
+ }
+
+ /* Return pktout queue on success */
+ if (!rc)
+ *queue = entry->s.out_queue[0].pktout;
+
+ /* Take pktio back to its previous state */
+ if (pktio_started)
+ rc |= odp_pktio_start(pktio_hdl);
+ return rc;
+}
+
int odp_pktout_queue_config(odp_pktio_t pktio,
const odp_pktout_queue_param_t *param)
{
@@ -2083,7 +2154,7 @@ int odp_pktout_queue_config(odp_pktio_t pktio,
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2189,7 +2260,7 @@ int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2229,7 +2300,7 @@ int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2268,7 +2339,7 @@ int odp_pktout_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2299,7 +2370,7 @@ int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2336,7 +2407,7 @@ int odp_pktin_recv(odp_pktin_queue_t queue, odp_packet_t packets[], int num)
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2365,7 +2436,7 @@ int odp_pktin_recv_tmo(odp_pktin_queue_t queue, odp_packet_t packets[], int num,
entry = get_pktio_entry(queue.pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", queue.pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)queue.pktio);
return -1;
}
@@ -2520,7 +2591,7 @@ int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[],
entry = get_pktio_entry(pktio);
if (entry == NULL) {
- ODP_DBG("pktio entry %d does not exist\n", pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)pktio);
return -1;
}
@@ -2546,7 +2617,7 @@ int odp_pktout_ts_read(odp_pktio_t hdl, odp_time_t *ts)
entry = get_pktio_entry(hdl);
if (odp_unlikely(entry == NULL)) {
- ODP_ERR("pktio entry %d does not exist\n", hdl);
+ ODP_ERR("pktio entry %" PRIuPTR " does not exist\n", (uintptr_t)hdl);
return -1;
}
diff --git a/platform/linux-generic/odp_queue_basic.c b/platform/linux-generic/odp_queue_basic.c
index 8dc10467a..428022ec8 100644
--- a/platform/linux-generic/odp_queue_basic.c
+++ b/platform/linux-generic/odp_queue_basic.c
@@ -180,7 +180,7 @@ static int queue_init_global(void)
queue_capa(&capa, 0);
ODP_DBG("... done.\n");
- ODP_DBG(" queue_entry_t size %u\n", sizeof(queue_entry_t));
+ ODP_DBG(" queue_entry_t size %zu\n", sizeof(queue_entry_t));
ODP_DBG(" max num queues %u\n", capa.max_queues);
ODP_DBG(" max queue size %u\n", capa.plain.max_size);
ODP_DBG(" max num lockfree %u\n", capa.plain.lockfree.max_num);
@@ -740,7 +740,7 @@ static void queue_print(odp_queue_t handle)
if (!odp_pktio_info(queue->s.pktout.pktio, &pktio_info))
ODP_PRINT(" pktout %s\n", pktio_info.name);
}
- ODP_PRINT(" timers %" PRIu32 "\n",
+ ODP_PRINT(" timers %" PRIu64 "\n",
odp_atomic_load_u64(&queue->s.num_timers));
ODP_PRINT(" status %s\n",
queue->s.status == QUEUE_STATUS_READY ? "ready" :
diff --git a/platform/linux-generic/odp_queue_scalable.c b/platform/linux-generic/odp_queue_scalable.c
index 248855be4..ad7807bf9 100644
--- a/platform/linux-generic/odp_queue_scalable.c
+++ b/platform/linux-generic/odp_queue_scalable.c
@@ -1000,7 +1000,7 @@ static void queue_print(odp_queue_t handle)
if (!odp_pktio_info(queue->s.pktout.pktio, &pktio_info))
ODP_PRINT(" pktout %s\n", pktio_info.name);
}
- ODP_PRINT(" timers %" PRIu32 "\n",
+ ODP_PRINT(" timers %" PRIu64 "\n",
odp_atomic_load_u64(&queue->s.num_timers));
ODP_PRINT(" param.size %" PRIu32 "\n", queue->s.param.size);
ODP_PRINT("\n");
diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c
index 9bef6fd7f..27c591a9c 100644
--- a/platform/linux-generic/odp_system_info.c
+++ b/platform/linux-generic/odp_system_info.c
@@ -91,7 +91,7 @@ static uint64_t default_huge_page_size(void)
while (fgets(str, sizeof(str), file) != NULL) {
if (sscanf(str, "Hugepagesize: %8lu kB", &sz) == 1) {
- ODP_DBG("defaut hp size is %" PRIu64 " kB\n", sz);
+ ODP_DBG("defaut hp size is %lu kB\n", sz);
fclose(file);
return (uint64_t)sz * 1024;
}
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 2db5bc7b1..f75fbd522 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2013-2018, Linaro Limited
- * Copyright (c) 2019-2020, Nokia
+ * Copyright (c) 2019-2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -244,7 +244,7 @@ static inline timer_pool_t *handle_to_tp(odp_timer_t hdl)
if (odp_likely(tp != NULL))
return timer_global->timer_pool[tp_idx];
}
- ODP_ABORT("Invalid timer handle %#x\n", hdl);
+ ODP_ABORT("Invalid timer handle %p\n", hdl);
}
static inline uint32_t handle_to_idx(odp_timer_t hdl,
@@ -255,7 +255,7 @@ static inline uint32_t handle_to_idx(odp_timer_t hdl,
__builtin_prefetch(&tp->tick_buf[idx], 0, 0);
if (odp_likely(idx < odp_atomic_load_u32(&tp->high_wm)))
return idx;
- ODP_ABORT("Invalid timer handle %#x\n", hdl);
+ ODP_ABORT("Invalid timer handle %p\n", hdl);
}
static inline odp_timer_t tp_idx_to_handle(timer_pool_t *tp,
@@ -399,7 +399,7 @@ static odp_timer_pool_t timer_pool_new(const char *name,
odp_ticketlock_unlock(&timer_global->lock);
if (!odp_global_rw->inline_timers) {
- if (tp->param.clk_src == ODP_CLOCK_CPU)
+ if (tp->param.clk_src == ODP_CLOCK_DEFAULT)
itimer_init(tp);
} else {
/* Update the highest index for inline timer scan */
@@ -441,7 +441,7 @@ static void odp_timer_pool_del(timer_pool_t *tp)
if (!odp_global_rw->inline_timers) {
/* Stop POSIX itimer signals */
- if (tp->param.clk_src == ODP_CLOCK_CPU)
+ if (tp->param.clk_src == ODP_CLOCK_DEFAULT)
itimer_fini(tp);
stop_timer_thread(tp);
@@ -1220,8 +1220,8 @@ static void itimer_fini(timer_pool_t *tp)
int odp_timer_capability(odp_timer_clk_src_t clk_src,
odp_timer_capability_t *capa)
{
- if (clk_src != ODP_CLOCK_CPU) {
- ODP_ERR("Only CPU clock source supported\n");
+ if (clk_src != ODP_CLOCK_DEFAULT) {
+ ODP_ERR("Only ODP_CLOCK_DEFAULT supported. Requested %i.\n", clk_src);
return -1;
}
@@ -1248,8 +1248,8 @@ int odp_timer_capability(odp_timer_clk_src_t clk_src,
int odp_timer_res_capability(odp_timer_clk_src_t clk_src,
odp_timer_res_capability_t *res_capa)
{
- if (clk_src != ODP_CLOCK_CPU) {
- ODP_ERR("Only CPU clock source supported\n");
+ if (clk_src != ODP_CLOCK_DEFAULT) {
+ ODP_ERR("Only ODP_CLOCK_DEFAULT supported. Requested %i.\n", clk_src);
return -1;
}
@@ -1385,13 +1385,13 @@ int odp_timer_set_abs(odp_timer_t hdl,
uint32_t idx = handle_to_idx(hdl, tp);
if (odp_unlikely(abs_tck < cur_tick + tp->min_rel_tck))
- return ODP_TIMER_TOOEARLY;
+ return ODP_TIMER_TOO_NEAR;
if (odp_unlikely(abs_tck > cur_tick + tp->max_rel_tck))
- return ODP_TIMER_TOOLATE;
+ return ODP_TIMER_TOO_FAR;
if (timer_reset(idx, abs_tck, (odp_buffer_t *)tmo_ev, tp))
return ODP_TIMER_SUCCESS;
else
- return ODP_TIMER_NOEVENT;
+ return ODP_TIMER_FAIL;
}
int odp_timer_set_rel(odp_timer_t hdl,
@@ -1404,13 +1404,13 @@ int odp_timer_set_rel(odp_timer_t hdl,
uint32_t idx = handle_to_idx(hdl, tp);
if (odp_unlikely(rel_tck < tp->min_rel_tck))
- return ODP_TIMER_TOOEARLY;
+ return ODP_TIMER_TOO_NEAR;
if (odp_unlikely(rel_tck > tp->max_rel_tck))
- return ODP_TIMER_TOOLATE;
+ return ODP_TIMER_TOO_FAR;
if (timer_reset(idx, abs_tck, (odp_buffer_t *)tmo_ev, tp))
return ODP_TIMER_SUCCESS;
else
- return ODP_TIMER_NOEVENT;
+ return ODP_TIMER_FAIL;
}
int odp_timer_cancel(odp_timer_t hdl, odp_event_t *tmo_ev)
diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c
index 1633bc454..cd7a9ecd9 100644
--- a/platform/linux-generic/odp_traffic_mngr.c
+++ b/platform/linux-generic/odp_traffic_mngr.c
@@ -22,6 +22,7 @@
#include <odp/api/std_types.h>
#include <protocols/eth.h>
#include <protocols/ip.h>
+#include <odp_packet_io_internal.h>
#include <odp_traffic_mngr_internal.h>
#include <odp/api/plat/packet_inlines.h>
#include <odp/api/plat/byteorder_inlines.h>
@@ -610,8 +611,8 @@ static void tm_shaper_params_cvt_to(const odp_tm_shaper_params_t *shaper_params,
uint32_t min_time_delta;
int64_t commit_burst, peak_burst;
- commit_rate = tm_bps_to_rate(shaper_params->commit_bps);
- if ((shaper_params->commit_bps == 0) || (commit_rate == 0)) {
+ commit_rate = tm_bps_to_rate(shaper_params->commit_rate);
+ if ((shaper_params->commit_rate == 0) || (commit_rate == 0)) {
tm_shaper_params->max_commit_time_delta = 0;
tm_shaper_params->max_peak_time_delta = 0;
tm_shaper_params->commit_rate = 0;
@@ -628,8 +629,8 @@ static void tm_shaper_params_cvt_to(const odp_tm_shaper_params_t *shaper_params,
max_commit_time_delta = tm_max_time_delta(commit_rate);
commit_burst = (int64_t)shaper_params->commit_burst;
- peak_rate = tm_bps_to_rate(shaper_params->peak_bps);
- if ((shaper_params->peak_bps == 0) || (peak_rate == 0)) {
+ peak_rate = tm_bps_to_rate(shaper_params->peak_rate);
+ if ((shaper_params->peak_rate == 0) || (peak_rate == 0)) {
peak_rate = 0;
max_peak_time_delta = 0;
peak_burst = 0;
@@ -669,8 +670,8 @@ static void tm_shaper_params_cvt_from(tm_shaper_params_t *tm_shaper_params,
commit_burst = tm_shaper_params->max_commit >> (26 - 3);
peak_burst = tm_shaper_params->max_peak >> (26 - 3);
- odp_shaper_params->commit_bps = commit_bps;
- odp_shaper_params->peak_bps = peak_bps;
+ odp_shaper_params->commit_rate = commit_bps;
+ odp_shaper_params->peak_rate = peak_bps;
odp_shaper_params->commit_burst = (uint32_t)commit_burst;
odp_shaper_params->peak_burst = (uint32_t)peak_burst;
odp_shaper_params->shaper_len_adjust = tm_shaper_params->len_adjust;
@@ -2565,6 +2566,12 @@ int odp_tm_capabilities(odp_tm_capabilities_t capabilities[] ODP_UNUSED,
cap_ptr->ecn_marking_supported = true;
cap_ptr->drop_prec_marking_supported = true;
+ cap_ptr->dynamic_topology_update = true;
+ cap_ptr->dynamic_shaper_update = true;
+ cap_ptr->dynamic_sched_update = true;
+ cap_ptr->dynamic_wred_update = true;
+ cap_ptr->dynamic_threshold_update = true;
+
for (color = 0; color < ODP_NUM_PACKET_COLORS; color++)
cap_ptr->marking_colors_supported[color] = true;
@@ -2618,6 +2625,12 @@ static void tm_system_capabilities_set(odp_tm_capabilities_t *cap_ptr,
cap_ptr->drop_prec_marking_supported =
req_ptr->drop_prec_marking_needed;
+ cap_ptr->dynamic_topology_update = true;
+ cap_ptr->dynamic_shaper_update = true;
+ cap_ptr->dynamic_sched_update = true;
+ cap_ptr->dynamic_wred_update = true;
+ cap_ptr->dynamic_threshold_update = true;
+
for (color = 0; color < ODP_NUM_PACKET_COLORS; color++)
cap_ptr->marking_colors_supported[color] =
req_ptr->marking_colors_needed[color];
@@ -2919,15 +2932,20 @@ odp_tm_t odp_tm_create(const char *name,
return ODP_TM_INVALID;
}
+ odp_ticketlock_lock(&tm_glb->create_lock);
+
/* If we are using pktio output (usual case) get the first associated
* pktout_queue for this pktio and fail if there isn't one.
*/
- if (egress->egress_kind == ODP_TM_EGRESS_PKT_IO &&
- odp_pktout_queue(egress->pktio, &pktout, 1) != 1)
- return ODP_TM_INVALID;
+ if (egress->egress_kind == ODP_TM_EGRESS_PKT_IO) {
+ rc = _odp_pktio_pktout_tm_config(egress->pktio, &pktout, false);
+ if (rc) {
+ odp_ticketlock_unlock(&tm_glb->create_lock);
+ return ODP_TM_INVALID;
+ }
+ }
/* Allocate tm_system_t record. */
- odp_ticketlock_lock(&tm_glb->create_lock);
tm_system = tm_system_alloc();
if (!tm_system) {
odp_ticketlock_unlock(&tm_glb->create_lock);
@@ -3042,6 +3060,22 @@ int odp_tm_capability(odp_tm_t odp_tm, odp_tm_capabilities_t *capabilities)
return 0;
}
+int odp_tm_start(odp_tm_t odp_tm)
+{
+ (void)odp_tm;
+
+ /* Nothing more to do after TM create */
+ return 0;
+}
+
+int odp_tm_stop(odp_tm_t odp_tm)
+{
+ (void)odp_tm;
+
+ /* Nothing more to do for topology changes */
+ return 0;
+}
+
int odp_tm_destroy(odp_tm_t odp_tm)
{
tm_system_t *tm_system;
@@ -3065,6 +3099,7 @@ int odp_tm_destroy(odp_tm_t odp_tm)
_odp_queue_pool_destroy(tm_system->_odp_int_queue_pool);
_odp_timer_wheel_destroy(tm_system->_odp_int_timer_wheel);
+ _odp_int_name_tbl_delete(tm_system->name_tbl_id);
tm_system_free(tm_system);
return 0;
}
@@ -3204,6 +3239,10 @@ odp_tm_shaper_t odp_tm_shaper_create(const char *name,
odp_tm_shaper_t shaper_handle;
_odp_int_name_t name_tbl_id;
+ /* We don't support shaper in packet mode */
+ if (params->packet_mode)
+ return ODP_TM_INVALID;
+
profile_obj = tm_common_profile_create(name, TM_SHAPER_PROFILE,
&shaper_handle, &name_tbl_id);
if (!profile_obj)
@@ -3573,7 +3612,7 @@ int odp_tm_wred_destroy(odp_tm_wred_t wred_profile)
return -1;
return tm_common_profile_destroy(wred_profile,
- ODP_INVALID_NAME);
+ wred_params->name_tbl_id);
}
int odp_tm_wred_params_read(odp_tm_wred_t wred_profile,
@@ -4685,10 +4724,10 @@ void odp_tm_stats_print(odp_tm_t odp_tm)
ODP_PRINT("odp_tm_stats_print - tm_system=0x%" PRIX64 " tm_idx=%u\n",
odp_tm, tm_system->tm_idx);
- ODP_PRINT(" input_work_queue size=%u current cnt=%u peak cnt=%u\n",
- INPUT_WORK_RING_SIZE, input_work_queue->queue_cnt,
+ ODP_PRINT(" input_work_queue size=%u current cnt=%" PRIu64 " peak cnt=%" PRIu32 "\n",
+ INPUT_WORK_RING_SIZE, odp_atomic_load_u64(&input_work_queue->queue_cnt),
input_work_queue->peak_cnt);
- ODP_PRINT(" input_work_queue enqueues=%" PRIu64 " dequeues=% " PRIu64
+ ODP_PRINT(" input_work_queue enqueues=%" PRIu64 " dequeues=%" PRIu64
" fail_cnt=%" PRIu64 "\n", input_work_queue->total_enqueues,
input_work_queue->total_dequeues,
input_work_queue->enqueue_fail_cnt);
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 6b349293a..5d5fead16 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -1286,7 +1286,7 @@ static int dpdk_pktio_init(void)
masklen = odp_cpumask_to_str(&mask, mask_str, ODP_CPUMASK_STR_SIZE);
if (masklen < 0) {
- ODP_ERR("CPU mask error: d\n", masklen);
+ ODP_ERR("CPU mask error: %" PRId32 "\n", masklen);
return -1;
}
diff --git a/platform/linux-generic/pktio/ipc.c b/platform/linux-generic/pktio/ipc.c
index e0c8cba3b..ad633e231 100644
--- a/platform/linux-generic/pktio/ipc.c
+++ b/platform/linux-generic/pktio/ipc.c
@@ -322,7 +322,7 @@ static int _ipc_init_master(pktio_entry_t *pktio_entry,
pinfo = pktio_ipc->pinfo;
pool_name = _ipc_odp_buffer_pool_shm_name(pool_hdl);
if (strlen(pool_name) > ODP_POOL_NAME_LEN) {
- ODP_ERR("pid %d ipc pool name %s is too big %d\n",
+ ODP_ERR("pid %d ipc pool name %s is too big %zu\n",
getpid(), pool_name, strlen(pool_name));
goto free_s_prod;
}
@@ -742,7 +742,7 @@ static int ipc_pktio_recv_lockless(pktio_entry_t *pktio_entry,
ring_ptr_enq_multi(r_p, ring_mask, ipcbufs_p, pkts);
for (i = 0; i < pkts; i++) {
- IPC_ODP_DBG("%d/%d send to be free packet offset %x\n",
+ IPC_ODP_DBG("%d/%d send to be free packet offset %" PRIuPTR "\n",
i, pkts, offsets[i]);
}
@@ -820,7 +820,7 @@ static int ipc_pktio_send_lockless(pktio_entry_t *pktio_entry,
/* compile all function code even if ipc disabled with config */
IPC_ODP_DBG("%d/%d send packet %" PRIu64 ", pool %" PRIu64 ","
- "phdr = %p, offset %x, sendoff %x, addr %p iaddr "
+ "phdr = %p, offset %td, sendoff %" PRIxPTR ", addr %p iaddr "
"%p\n", i, num,
odp_packet_to_u64(pkt), odp_pool_to_u64(pool_hdl),
pkt_hdr, (uint8_t *)pkt_hdr->seg_data -
diff --git a/platform/linux-generic/pktio/pktio_common.c b/platform/linux-generic/pktio/pktio_common.c
index 4090f8063..d2f4d7219 100644
--- a/platform/linux-generic/pktio/pktio_common.c
+++ b/platform/linux-generic/pktio/pktio_common.c
@@ -7,6 +7,7 @@
#include <odp_packet_io_internal.h>
#include <errno.h>
+#include <inttypes.h>
static int sock_recv_mq_tmo_select(pktio_entry_t * const *entry,
const int index[],
@@ -71,8 +72,8 @@ int _odp_sock_recv_mq_tmo_try_int_driven(const struct odp_pktin_queue_t queues[]
entry[i] = get_pktio_entry(queues[i].pktio);
index[i] = queues[i].index;
if (entry[i] == NULL) {
- ODP_DBG("pktio entry %d does not exist\n",
- queues[i].pktio);
+ ODP_DBG("pktio entry %" PRIuPTR " does not exist\n",
+ (uintptr_t)queues[i].pktio);
*trial_successful = 0;
return -1;
}
diff --git a/platform/linux-generic/test/Makefile.am b/platform/linux-generic/test/Makefile.am
index 1f7ae611e..049ce2187 100644
--- a/platform/linux-generic/test/Makefile.am
+++ b/platform/linux-generic/test/Makefile.am
@@ -8,25 +8,13 @@ TESTS_ENVIRONMENT += WITH_OPENSSL=0
endif
SUBDIRS =
-
-if WITH_EXAMPLES
-TESTS = ipsec/ipsec_api_example.sh \
- ipsec/ipsec_crypto_example.sh
-
-dist_check_SCRIPTS = ipsec/ipsec_api_example.sh \
- ipsec/ipsec_crypto_example.sh
-else
TESTS =
-dist_check_SCRIPTS =
-endif
if test_vald
TESTS += validation/api/pktio/pktio_run.sh \
validation/api/pktio/pktio_run_tap.sh \
validation/api/shmem/shmem_linux$(EXEEXT)
-test_SCRIPTS = $(dist_check_SCRIPTS)
-
SUBDIRS += validation/api/pktio\
validation/api/shmem\
pktio_ipc \
@@ -69,25 +57,3 @@ 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
-
-.NOTPARALLEL:
diff --git a/platform/linux-generic/test/example/Makefile.am b/platform/linux-generic/test/example/Makefile.am
index 22b254cd7..947647cd4 100644
--- a/platform/linux-generic/test/example/Makefile.am
+++ b/platform/linux-generic/test/example/Makefile.am
@@ -1,6 +1,8 @@
SUBDIRS = \
classifier \
generator \
+ ipsec_api \
+ ipsec_crypto \
l2fwd_simple \
l3fwd \
packet \
diff --git a/platform/linux-generic/test/example/ipsec_api/Makefile.am b/platform/linux-generic/test/example/ipsec_api/Makefile.am
new file mode 100644
index 000000000..101c97cdf
--- /dev/null
+++ b/platform/linux-generic/test/example/ipsec_api/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = pktio_env
+
+# 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
+
+.NOTPARALLEL:
diff --git a/platform/linux-generic/test/example/ipsec_api/pktio_env b/platform/linux-generic/test/example/ipsec_api/pktio_env
new file mode 100644
index 000000000..a16002326
--- /dev/null
+++ b/platform/linux-generic/test/example/ipsec_api/pktio_env
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Copyright (C) 2021, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# ipsec_api application uses two loop devices loop0 and loop1.
+#
+
+if [ "$0" == "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+ exit 1
+fi
+
+# Absolute path to the .env file.
+LINUX_ENV_PATH=$PWD/../../platform/linux-generic/test
+
+TESTENV="tests-linux-generic.env"
+
+if [ -f $LINUX_ENV_PATH/$TESTENV ]; then
+ source $LINUX_ENV_PATH/$TESTENV
+else
+ echo "BUG: unable to find $TESTENV!"
+ echo "$TESTENV has to be in following directory: "
+ echo " $LINUX_ENV_PATH"
+ exit 1
+fi
+
+# Skip IPsec example tests when there's no OpenSSL.
+if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
+ echo "Crypto not supported. Skipping."
+ exit 77
+fi
+
+IF0=p7p1
+IF1=p8p1
+
+NEXT_HOP_MAC0=08:00:27:76:B5:E0
+NEXT_HOP_MAC1=08:00:27:F5:8B:DB
+
+LIF0=loop1
+LIF1=loop2
+
+IF_LIST=$LIF0,$LIF1
+ROUTE_IF_INB=$LIF0
+ROUTE_IF_OUTB=$LIF1
+OUT_IF=$LIF1
+IN_IF=$LIF0
+
+validate_result()
+{
+ return 0
+}
+
+setup_interfaces()
+{
+ return 0
+}
+
+cleanup_interfaces()
+{
+ return 0
+}
diff --git a/platform/linux-generic/test/example/ipsec_crypto/Makefile.am b/platform/linux-generic/test/example/ipsec_crypto/Makefile.am
new file mode 100644
index 000000000..101c97cdf
--- /dev/null
+++ b/platform/linux-generic/test/example/ipsec_crypto/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = pktio_env
+
+# 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
+
+.NOTPARALLEL:
diff --git a/platform/linux-generic/test/example/ipsec_crypto/pktio_env b/platform/linux-generic/test/example/ipsec_crypto/pktio_env
new file mode 100644
index 000000000..99a1ac42b
--- /dev/null
+++ b/platform/linux-generic/test/example/ipsec_crypto/pktio_env
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Copyright (C) 2021, Marvell
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Script to setup interfaces used for running application on linux-generic.
+#
+# ipsec_api application uses two loop devices loop0 and loop1.
+#
+
+if [ "$0" == "$BASH_SOURCE" ]; then
+ echo "Error: Platform specific env file has to be sourced."
+ exit 1
+fi
+
+# Absolute path to the .env file.
+LINUX_ENV_PATH=$PWD/../../platform/linux-generic/test
+
+TESTENV="tests-linux-generic.env"
+
+if [ -f $LINUX_ENV_PATH/$TESTENV ]; then
+ source $LINUX_ENV_PATH/$TESTENV
+else
+ echo "BUG: unable to find $TESTENV!"
+ echo "$TESTENV has to be in following directory: "
+ echo " $LINUX_ENV_PATH"
+ exit 1
+fi
+
+# Skip IPsec example tests when there's no OpenSSL.
+if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
+ echo "Crypto not supported. Skipping."
+ exit 77
+fi
+
+# Skip live and router mode tests.
+if [ ${IPSEC_APP_MODE} -eq 1 ] || [ ${IPSEC_APP_MODE} -eq 2 ]; then
+ echo "Live / Router mode test. Skipping."
+ exit 77
+fi
+
+IF0=p7p1
+IF1=p8p1
+
+NEXT_HOP_MAC0=08:00:27:76:B5:E0
+NEXT_HOP_MAC1=08:00:27:F5:8B:DB
+
+LIF0=loop1
+LIF1=loop2
+
+IF_LIST=$LIF0,$LIF1
+ROUTE_IF_INB=$LIF0
+ROUTE_IF_OUTB=$LIF1
+OUT_IF=$LIF1
+IN_IF=$LIF0
+
+validate_result()
+{
+ return 0
+}
+
+setup_interfaces()
+{
+ return 0
+}
+
+cleanup_interfaces()
+{
+ return 0
+}
diff --git a/platform/linux-generic/test/inline-timer.conf b/platform/linux-generic/test/inline-timer.conf
index e4d4af307..93195f5a8 100644
--- a/platform/linux-generic/test/inline-timer.conf
+++ b/platform/linux-generic/test/inline-timer.conf
@@ -1,6 +1,6 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.15"
+config_file_version = "0.1.16"
timer: {
# Enable inline timer implementation
diff --git a/platform/linux-generic/test/ipsec/ipsec_api_example.sh b/platform/linux-generic/test/ipsec/ipsec_api_example.sh
deleted file mode 100755
index 82fd193d9..000000000
--- a/platform/linux-generic/test/ipsec/ipsec_api_example.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2019, Nokia
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Skip IPsec example tests when there's no OpenSSL.
-if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
-echo "Crypto not supported. Skipping."
-exit 77
-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_api
-
-declare -i RESULT=0
-
-pushd $(dirname $0)/../../../../example/ipsec_api
-
-./odp_ipsec_api_run_simple.sh
-RESULT+=$?
-
-./odp_ipsec_api_run_esp_out.sh
-RESULT+=$?
-
-popd
-
-exit ${RESULT}
diff --git a/platform/linux-generic/test/ipsec/ipsec_crypto_example.sh b/platform/linux-generic/test/ipsec/ipsec_crypto_example.sh
deleted file mode 100755
index d99fc3bd2..000000000
--- a/platform/linux-generic/test/ipsec/ipsec_crypto_example.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2019, Nokia
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# Skip IPsec example tests when there's no OpenSSL.
-if [ -n "$WITH_OPENSSL" ] && [ ${WITH_OPENSSL} -eq 0 ]; then
-echo "Crypto not supported. Skipping."
-exit 77
-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_crypto
-
-declare -i RESULT=0
-
-pushd $(dirname $0)/../../../../example/ipsec_crypto
-
-./odp_ipsec_crypto_run_simple.sh
-RESULT+=$?
-
-./odp_ipsec_crypto_run_esp_out.sh
-RESULT+=$?
-
-popd
-
-exit ${RESULT}
diff --git a/platform/linux-generic/test/packet_align.conf b/platform/linux-generic/test/packet_align.conf
index 9b37752ba..58a73f2df 100644
--- a/platform/linux-generic/test/packet_align.conf
+++ b/platform/linux-generic/test/packet_align.conf
@@ -1,6 +1,6 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.15"
+config_file_version = "0.1.16"
pool: {
pkt: {
diff --git a/platform/linux-generic/test/process-mode.conf b/platform/linux-generic/test/process-mode.conf
index 5354cae2f..a6e6080d2 100644
--- a/platform/linux-generic/test/process-mode.conf
+++ b/platform/linux-generic/test/process-mode.conf
@@ -1,6 +1,6 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.15"
+config_file_version = "0.1.16"
# Shared memory options
shm: {
diff --git a/platform/linux-generic/test/sched-basic.conf b/platform/linux-generic/test/sched-basic.conf
index 57a8a772c..79537b454 100644
--- a/platform/linux-generic/test/sched-basic.conf
+++ b/platform/linux-generic/test/sched-basic.conf
@@ -1,6 +1,6 @@
# Mandatory fields
odp_implementation = "linux-generic"
-config_file_version = "0.1.15"
+config_file_version = "0.1.16"
sched_basic: {
# Test scheduler with an odd spread value
diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh
index ae50bf065..38127edc1 100755
--- a/scripts/ci/build.sh
+++ b/scripts/ci/build.sh
@@ -4,7 +4,7 @@ set -e
cd "$(dirname "$0")"/../..
./bootstrap
./configure \
- --host=${TARGET_ARCH} --build=x86_64-linux-gnu \
+ --host=${TARGET_ARCH} --build=${BUILD_ARCH:-x86_64-linux-gnu} \
--prefix=/opt/odp \
${CONF}
@@ -47,7 +47,7 @@ sysctl vm.nr_hugepages=1000
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
-if [ "$TARGET_ARCH" = "x86_64-linux-gnu" ]
+if [ -z "$TARGET_ARCH" ] || [ "$TARGET_ARCH" == "$BUILD_ARCH" ]
then
LD_LIBRARY_PATH="/opt/odp/lib:$LD_LIBRARY_PATH" ./odp_hello_inst_dynamic
fi
diff --git a/scripts/ci/build_arm64.sh b/scripts/ci/build_arm64.sh
index abdc5acb8..ad3b95e75 100755
--- a/scripts/ci/build_arm64.sh
+++ b/scripts/ci/build_arm64.sh
@@ -2,6 +2,10 @@
set -e
export TARGET_ARCH=aarch64-linux-gnu
+if [[ $(uname -m) =~ ^(arm64|aarch64)$ ]]; then
+ export BUILD_ARCH=aarch64-linux-gnu
+fi
+
if [ "${CC#clang}" != "${CC}" ] ; then
export CC="clang --target=${TARGET_ARCH}"
export CXX="clang++ --target=${TARGET_ARCH}"
diff --git a/scripts/ci/check.sh b/scripts/ci/check.sh
index a181a184b..7b22db066 100755
--- a/scripts/ci/check.sh
+++ b/scripts/ci/check.sh
@@ -5,7 +5,7 @@ echo 1500 | tee /proc/sys/vm/nr_hugepages
mkdir -p /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
-"`dirname "$0"`"/build_x86_64.sh
+"`dirname "$0"`"/build_${ARCH}.sh
cd "$(dirname "$0")"/../..
diff --git a/scripts/ci/check_inline_timer.sh b/scripts/ci/check_inline_timer.sh
index d2eff7145..1fa9c21f5 100755
--- a/scripts/ci/check_inline_timer.sh
+++ b/scripts/ci/check_inline_timer.sh
@@ -1,7 +1,7 @@
#!/bin/bash
set -e
-"`dirname "$0"`"/build_x86_64.sh
+"`dirname "$0"`"/build_${ARCH}.sh
cd "$(dirname "$0")"/../..
diff --git a/scripts/ci/check_pktio.sh b/scripts/ci/check_pktio.sh
index d82fe8aad..e61bacc98 100755
--- a/scripts/ci/check_pktio.sh
+++ b/scripts/ci/check_pktio.sh
@@ -1,7 +1,7 @@
#!/bin/bash
set -e
-"`dirname "$0"`"/build_x86_64.sh
+"`dirname "$0"`"/build_${ARCH}.sh
cd "$(dirname "$0")"/../..
diff --git a/scripts/ci/coverage.sh b/scripts/ci/coverage.sh
index e413c28fb..cdcddfe93 100755
--- a/scripts/ci/coverage.sh
+++ b/scripts/ci/coverage.sh
@@ -8,7 +8,7 @@ fi
cd "$(dirname "$0")"/../..
./bootstrap
./configure \
- CFLAGS="-O0 -coverage $CLFAGS" CXXFLAGS="-O0 -coverage $CXXFLAGS" LDFLAGS="--coverage $LDFLAGS" \
+ CFLAGS="-O0 -coverage $CFLAGS" CXXFLAGS="-O0 -coverage $CXXFLAGS" LDFLAGS="--coverage $LDFLAGS" \
--enable-debug=full --enable-helper-linux
export CCACHE_DISABLE=1
make -j $(nproc)
diff --git a/scripts/shippable-post.sh b/scripts/shippable-post.sh
deleted file mode 100755
index 9d59da3f8..000000000
--- a/scripts/shippable-post.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-wget https://raw.githubusercontent.com/shawnliang/cunit-to-junit/master/cunit-to-junit.xsl
-
-mkdir -p "$SHIPPABLE_BUILD_DIR/shippable/testresults"
-
-SCHED=${1:-default}
-echo $SCHED
-
-for FILE in `find ./test ./platform/ -name "*.xml"`; do
- bname="`basename $FILE`";
- echo Processing $FILE as ${SCHED}-${bname}
- xsltproc --novalid cunit-to-junit.xsl "$FILE" > \
- "$SHIPPABLE_BUILD_DIR/shippable/testresults/${SCHED}-${bname}"
-done
diff --git a/test/common/odp_cunit_common.c b/test/common/odp_cunit_common.c
index 62418c356..f5c437344 100644
--- a/test/common/odp_cunit_common.c
+++ b/test/common/odp_cunit_common.c
@@ -259,7 +259,8 @@ int odp_cunit_print_inactive(void)
continue;
if (first) {
- printf("\n\n Inactive tests:\n");
+ printf("\n\nSuite: %s\n", sinfo->name);
+ printf(" Inactive tests:\n");
first = 0;
}
@@ -269,6 +270,34 @@ int odp_cunit_print_inactive(void)
return 0;
}
+int odp_cunit_set_inactive(void)
+{
+ CU_pSuite cur_suite;
+ CU_pTest ptest;
+ odp_suiteinfo_t *sinfo;
+ odp_testinfo_t *tinfo;
+
+ cur_suite = CU_get_current_suite();
+ if (cur_suite == NULL)
+ return -1;
+
+ sinfo = cunit_get_suite_info(cur_suite->pName);
+ if (sinfo == NULL)
+ return -1;
+
+ for (tinfo = sinfo->testinfo_tbl; tinfo->name; tinfo++) {
+ ptest = CU_get_test_by_name(tinfo->name, cur_suite);
+ if (ptest == NULL) {
+ fprintf(stderr, "%s: test not found: %s\n",
+ __func__, tinfo->name);
+ return -1;
+ }
+ CU_set_test_active(ptest, false);
+ }
+
+ return 0;
+}
+
static int default_term_func(void)
{
return odp_cunit_print_inactive();
@@ -526,3 +555,17 @@ int odp_cunit_ret(int val)
{
return allow_skip_result ? 0 : val;
}
+
+int odp_cunit_ci_skip(const char *test_name)
+{
+ const char *ci_skip;
+ const char *found;
+
+ ci_skip = getenv("CI_SKIP");
+ if (ci_skip == NULL)
+ return 0;
+
+ found = strstr(ci_skip, test_name);
+
+ return found != NULL;
+}
diff --git a/test/common/odp_cunit_common.h b/test/common/odp_cunit_common.h
index 55e52ce1c..3e06ba10c 100644
--- a/test/common/odp_cunit_common.h
+++ b/test/common/odp_cunit_common.h
@@ -105,6 +105,10 @@ void odp_cunit_register_global_term(int (*func_term_ptr)(odp_instance_t inst));
int odp_cunit_ret(int val);
int odp_cunit_print_inactive(void);
+int odp_cunit_set_inactive(void);
+
+/* Check from CI_SKIP environment variable if the test case should be skipped by CI */
+int odp_cunit_ci_skip(const char *test_name);
/*
* Wrapper for CU_ASSERT_FATAL implementation to show the compiler that
diff --git a/test/performance/odp_ipsec.c b/test/performance/odp_ipsec.c
index 2e283a63b..05a22ff0d 100644
--- a/test/performance/odp_ipsec.c
+++ b/test/performance/odp_ipsec.c
@@ -866,7 +866,12 @@ run_measure_one_config(ipsec_args_t *cargs,
odp_ipsec_status_t status;
while (1) {
- odp_event_t event = odp_queue_deq(out_queue);
+ odp_event_t event;
+
+ if (cargs->poll)
+ event = odp_queue_deq(out_queue);
+ else
+ event = odp_schedule(NULL, ODP_SCHED_NO_WAIT);
if (event != ODP_EVENT_INVALID &&
odp_event_type(event) == ODP_EVENT_IPSEC_STATUS &&
diff --git a/test/performance/odp_sched_pktio.c b/test/performance/odp_sched_pktio.c
index c752e2a91..cbdbdf4aa 100644
--- a/test/performance/odp_sched_pktio.c
+++ b/test/performance/odp_sched_pktio.c
@@ -490,7 +490,7 @@ static int worker_thread_timers(void *arg)
ret = odp_timer_set_rel(timer, tick, NULL);
if (odp_unlikely(ret != ODP_TIMER_SUCCESS &&
- ret != ODP_TIMER_NOEVENT)) {
+ ret != ODP_TIMER_FAIL)) {
/* Tick period is too short or long. Normally,
* reset either succeeds or fails due to timer
* expiration, in which case timeout event will
@@ -1253,7 +1253,7 @@ static int create_timers(test_global_t *test_global)
if (test_global->opt.timeout_us == 0)
return 0;
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)) {
printf("Timer capa failed\n");
return -1;
}
@@ -1272,7 +1272,7 @@ static int create_timers(test_global_t *test_global)
timer_param.min_tmo = timeout_ns;
timer_param.max_tmo = timeout_ns;
timer_param.num_timers = num_timer;
- timer_param.clk_src = ODP_CLOCK_CPU;
+ timer_param.clk_src = ODP_CLOCK_DEFAULT;
timer_pool = odp_timer_pool_create("sched_pktio_timer", &timer_param);
diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c
index 4b8318557..6989d0d4c 100644
--- a/test/performance/odp_timer_perf.c
+++ b/test/performance/odp_timer_perf.c
@@ -307,14 +307,14 @@ static int create_timer_pools(test_global_t *global)
global->timer[i][j] = ODP_TIMER_INVALID;
}
- if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa)) {
ODPH_ERR("Timer capability failed\n");
return -1;
}
memset(&timer_res_capa, 0, sizeof(odp_timer_res_capability_t));
timer_res_capa.res_ns = res_ns;
- if (odp_timer_res_capability(ODP_CLOCK_CPU, &timer_res_capa)) {
+ if (odp_timer_res_capability(ODP_CLOCK_DEFAULT, &timer_res_capa)) {
ODPH_ERR("Timer resolution capability failed\n");
return -1;
}
@@ -352,7 +352,7 @@ static int create_timer_pools(test_global_t *global)
timer_pool_param.max_tmo = max_tmo_ns;
timer_pool_param.num_timers = num_timer;
timer_pool_param.priv = priv;
- timer_pool_param.clk_src = ODP_CLOCK_CPU;
+ timer_pool_param.clk_src = ODP_CLOCK_DEFAULT;
odp_pool_param_init(&pool_param);
pool_param.type = ODP_POOL_TIMEOUT;
diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c
index a76bac973..981bc9155 100644
--- a/test/validation/api/ipsec/ipsec.c
+++ b/test/validation/api/ipsec/ipsec.c
@@ -217,20 +217,17 @@ int ipsec_check_esp_aes_gcm_256(void)
int ipsec_check_ah_aes_gmac_128(void)
{
- return ipsec_check_esp(ODP_CIPHER_ALG_NULL, 0,
- ODP_AUTH_ALG_AES_GMAC, 128);
+ return ipsec_check_ah(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);
+ return ipsec_check_ah(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);
+ return ipsec_check_ah(ODP_AUTH_ALG_AES_GMAC, 256);
}
int ipsec_check_esp_null_aes_gmac_128(void)
diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h
index 161835a33..b899fce48 100644
--- a/test/validation/api/ipsec/ipsec.h
+++ b/test/validation/api/ipsec/ipsec.h
@@ -16,6 +16,8 @@
((c) << 8) | \
((d) << 0))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
/* test arrays: */
extern odp_testinfo_t ipsec_in_suite[];
extern odp_testinfo_t ipsec_out_suite[];
diff --git a/test/validation/api/ipsec/ipsec_test_in.c b/test/validation/api/ipsec/ipsec_test_in.c
index 4eafed6a9..08512c8fb 100644
--- a/test/validation/api/ipsec/ipsec_test_in.c
+++ b/test/validation/api/ipsec/ipsec_test_in.c
@@ -1,10 +1,13 @@
/* Copyright (c) 2017-2018, Linaro Limited
* Copyright (c) 2020-2021, Marvell
+ * Copyright (c) 2021, Nokia
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <odp/helper/odph_api.h>
+
#include "ipsec.h"
#include "reass_test_vectors.h"
@@ -1764,132 +1767,109 @@ static void test_ipsec_sa_print(void)
ipsec_sa_destroy(in_sa);
}
-static void test_in_ipv4_esp_reass_success_two_frags(odp_ipsec_sa_t out_sa,
- odp_ipsec_sa_t in_sa)
+static void test_multi_out_in(odp_ipsec_sa_t out_sa,
+ odp_ipsec_sa_t in_sa,
+ uint8_t tunnel_ip_ver,
+ int num_input_packets,
+ ipsec_test_packet *input_packets[],
+ ipsec_test_packet *result_packet)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
+ uint8_t ver_ihl = result_packet->data[result_packet->l3_offset];
+ odp_bool_t is_result_ipv6 = (ODPH_IPV4HDR_VER(ver_ihl) == ODPH_IPV6);
int i;
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 2);
-
- part_prep_esp(test_out, 2, false);
-
- test_out[0].pkt_in = &pkt_ipv4_udp_p1_f1;
- test_out[1].pkt_in = &pkt_ipv4_udp_p1_f2;
-
- part_prep_plain(&test_in[1], 1, false, true);
- test_in[1].out[0].pkt_res = &pkt_ipv4_udp_p1;
-
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < num_input_packets; i++) {
+ ipsec_test_part test_out;
+ ipsec_test_part test_in;
ipsec_test_packet test_pkt;
odp_packet_t pkt;
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
+ /*
+ * Convert plain text packet to IPsec packet through
+ * outbound IPsec processing.
+ */
+ part_prep_esp(&test_out, 1, tunnel_ip_ver == ODPH_IPV6);
+ test_out.pkt_in = input_packets[i];
+ CU_ASSERT_EQUAL(ipsec_check_out(&test_out, out_sa, &pkt), 1);
+
+ /*
+ * Perform inbound IPsec processing for the IPsec packet.
+ * Expect result packet only for the last packet.
+ */
+ memset(&test_in, 0, sizeof(test_in));
+ if (i == num_input_packets - 1) {
+ part_prep_plain(&test_in, 1, is_result_ipv6, true);
+ test_in.out[0].pkt_res = result_packet;
+ }
ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ test_in.pkt_in = &test_pkt;
- ipsec_check_in_one(&test_in[i], in_sa);
+ ipsec_check_in_one(&test_in, in_sa);
}
}
-static void test_in_ipv4_esp_reass_success_four_frags(odp_ipsec_sa_t out_sa,
- odp_ipsec_sa_t in_sa)
+static void test_in_ipv4_esp_reass_success_two_frags(odp_ipsec_sa_t out_sa,
+ odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 4);
-
- part_prep_esp(test_out, 4, false);
-
- test_out[0].pkt_in = &pkt_ipv4_udp_p2_f1;
- test_out[1].pkt_in = &pkt_ipv4_udp_p2_f2;
- test_out[2].pkt_in = &pkt_ipv4_udp_p2_f3;
- test_out[3].pkt_in = &pkt_ipv4_udp_p2_f4;
-
- part_prep_plain(&test_in[3], 1, false, true);
- test_in[3].out[0].pkt_res = &pkt_ipv4_udp_p2;
-
- for (i = 0; i < 4; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv4_udp_p1_f1,
+ &pkt_ipv4_udp_p1_f2,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv4_udp_p1;
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV4,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
+}
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+static void test_in_ipv4_esp_reass_success_four_frags(odp_ipsec_sa_t out_sa,
+ odp_ipsec_sa_t in_sa)
+{
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv4_udp_p2_f1,
+ &pkt_ipv4_udp_p2_f2,
+ &pkt_ipv4_udp_p2_f3,
+ &pkt_ipv4_udp_p2_f4,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv4_udp_p2;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV4,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv4_esp_reass_success_two_frags_ooo(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 2);
-
- part_prep_esp(test_out, 2, false);
-
- test_out[0].pkt_in = &pkt_ipv4_udp_p1_f2;
- test_out[1].pkt_in = &pkt_ipv4_udp_p1_f1;
-
- part_prep_plain(&test_in[1], 1, false, true);
- test_in[1].out[0].pkt_res = &pkt_ipv4_udp_p1;
-
- for (i = 0; i < 2; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv4_udp_p1_f2,
+ &pkt_ipv4_udp_p1_f1,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv4_udp_p1;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV4,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv4_esp_reass_success_four_frags_ooo(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 4);
-
- part_prep_esp(test_out, 4, false);
-
- test_out[0].pkt_in = &pkt_ipv4_udp_p2_f4;
- test_out[1].pkt_in = &pkt_ipv4_udp_p2_f1;
- test_out[2].pkt_in = &pkt_ipv4_udp_p2_f2;
- test_out[3].pkt_in = &pkt_ipv4_udp_p2_f3;
-
- part_prep_plain(&test_in[3], 1, false, true);
- test_in[3].out[0].pkt_res = &pkt_ipv4_udp_p2;
-
- for (i = 0; i < 4; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv4_udp_p2_f4,
+ &pkt_ipv4_udp_p2_f1,
+ &pkt_ipv4_udp_p2_f2,
+ &pkt_ipv4_udp_p2_f3,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv4_udp_p2;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV4,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv4_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa,
@@ -2024,129 +2004,65 @@ static void test_in_ipv4_esp_reass_incomp(void)
static void test_in_ipv6_esp_reass_success_two_frags(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 2);
-
- part_prep_esp(test_out, 2, true);
-
- test_out[0].pkt_in = &pkt_ipv6_udp_p1_f1;
- test_out[1].pkt_in = &pkt_ipv6_udp_p1_f2;
-
- part_prep_plain(&test_in[1], 1, true, true);
- test_in[1].out[0].pkt_res = &pkt_ipv6_udp_p1;
-
- for (i = 0; i < 2; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv6_udp_p1_f1,
+ &pkt_ipv6_udp_p1_f2,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv6_udp_p1;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV6,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv6_esp_reass_success_four_frags(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 4);
-
- part_prep_esp(test_out, 4, true);
-
- test_out[0].pkt_in = &pkt_ipv6_udp_p2_f1;
- test_out[1].pkt_in = &pkt_ipv6_udp_p2_f2;
- test_out[2].pkt_in = &pkt_ipv6_udp_p2_f3;
- test_out[3].pkt_in = &pkt_ipv6_udp_p2_f4;
-
- part_prep_plain(&test_in[3], 1, true, true);
- test_in[3].out[0].pkt_res = &pkt_ipv6_udp_p2;
-
- for (i = 0; i < 4; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv6_udp_p2_f1,
+ &pkt_ipv6_udp_p2_f2,
+ &pkt_ipv6_udp_p2_f3,
+ &pkt_ipv6_udp_p2_f4,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv6_udp_p2;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV6,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv6_esp_reass_success_two_frags_ooo(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 2);
-
- part_prep_esp(test_out, 2, true);
-
- test_out[0].pkt_in = &pkt_ipv6_udp_p1_f2;
- test_out[1].pkt_in = &pkt_ipv6_udp_p1_f1;
-
- part_prep_plain(&test_in[1], 1, true, true);
- test_in[1].out[0].pkt_res = &pkt_ipv6_udp_p1;
-
- for (i = 0; i < 2; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv6_udp_p1_f2,
+ &pkt_ipv6_udp_p1_f1,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv6_udp_p1;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV6,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv6_esp_reass_success_four_frags_ooo(odp_ipsec_sa_t out_sa,
odp_ipsec_sa_t in_sa)
{
- ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS];
- int i;
-
- memset(test_in, 0, sizeof(test_in));
-
- CU_ASSERT(MAX_FRAGS >= 4);
-
- part_prep_esp(test_out, 4, true);
-
- test_out[1].pkt_in = &pkt_ipv6_udp_p2_f2;
- test_out[2].pkt_in = &pkt_ipv6_udp_p2_f3;
- test_out[3].pkt_in = &pkt_ipv6_udp_p2_f4;
- test_out[0].pkt_in = &pkt_ipv6_udp_p2_f1;
-
- part_prep_plain(&test_in[3], 1, true, true);
- test_in[3].out[0].pkt_res = &pkt_ipv6_udp_p2;
-
- for (i = 0; i < 4; i++) {
- ipsec_test_packet test_pkt;
- odp_packet_t pkt;
-
- CU_ASSERT_EQUAL(ipsec_check_out(&test_out[i], out_sa, &pkt), 1);
-
- ipsec_test_packet_from_pkt(&test_pkt, &pkt);
- test_in[i].pkt_in = &test_pkt;
+ ipsec_test_packet *input_packets[] = {
+ &pkt_ipv6_udp_p2_f2,
+ &pkt_ipv6_udp_p2_f3,
+ &pkt_ipv6_udp_p2_f4,
+ &pkt_ipv6_udp_p2_f1,
+ };
+ ipsec_test_packet *result_packet = &pkt_ipv6_udp_p2;
- ipsec_check_in_one(&test_in[i], in_sa);
- }
+ test_multi_out_in(out_sa, in_sa, ODPH_IPV6,
+ ARRAY_SIZE(input_packets),
+ input_packets,
+ result_packet);
}
static void test_in_ipv6_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa,
diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c
index b48dd0d6c..7c1121579 100644
--- a/test/validation/api/ipsec/ipsec_test_out.c
+++ b/test/validation/api/ipsec/ipsec_test_out.c
@@ -119,8 +119,6 @@ static struct cipher_auth_comb_param cipher_auth_comb[] = {
},
};
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
static void test_out_ipv4_ah_sha256(void)
{
odp_ipsec_sa_param_t param;
@@ -361,17 +359,19 @@ static void test_ipsec_stats_zero_assert(odp_ipsec_stats_t *stats)
CU_ASSERT_EQUAL(stats->mtu_err, 0);
CU_ASSERT_EQUAL(stats->hard_exp_bytes_err, 0);
CU_ASSERT_EQUAL(stats->hard_exp_pkts_err, 0);
+ CU_ASSERT_EQUAL(stats->success_bytes, 0);
}
static void test_ipsec_stats_test_assert(odp_ipsec_stats_t *stats,
- enum ipsec_test_stats test)
+ enum ipsec_test_stats test,
+ uint64_t succ_bytes)
{
if (test == IPSEC_TEST_STATS_SUCCESS) {
- /* Braces needed by CU macro */
CU_ASSERT_EQUAL(stats->success, 1);
+ CU_ASSERT(stats->success_bytes >= succ_bytes);
} else {
- /* Braces needed by CU macro */
CU_ASSERT_EQUAL(stats->success, 0);
+ CU_ASSERT_EQUAL(stats->success_bytes, 0);
}
if (test == IPSEC_TEST_STATS_PROTO_ERR) {
@@ -608,20 +608,36 @@ static void test_out_in_common(const ipsec_test_flags *flags,
ipsec_check_out_in_one(&test_out, &test_in, sa_out, sa_in, flags);
- if (flags->stats == IPSEC_TEST_STATS_SUCCESS) {
- CU_ASSERT_EQUAL(odp_ipsec_stats(sa_in, &stats), 0);
- test_ipsec_stats_test_assert(&stats, flags->stats);
- }
-
if (flags->stats != IPSEC_TEST_STATS_NONE) {
+ uint64_t succ_bytes = 0;
+
+ /* Minimum bytes to be counted for stats.success_bytes */
+ if (!flags->ah) {
+ succ_bytes = test_out.pkt_in[0].len -
+ test_out.pkt_in[0].l4_offset;
+
+ if (flags->tunnel)
+ succ_bytes += test_out.pkt_in[0].l4_offset -
+ test_out.pkt_in[0].l3_offset;
+ } else {
+ succ_bytes = test_out.pkt_in[0].len -
+ test_out.pkt_in[0].l3_offset;
+
+ if (flags->tunnel)
+ succ_bytes += (flags->tunnel_is_v6 ?
+ ODPH_IPV6HDR_LEN :
+ ODPH_IPV4HDR_LEN);
+ }
+
/* All stats tests have outbound operation success and inbound
* varying.
*/
CU_ASSERT_EQUAL(odp_ipsec_stats(sa_out, &stats), 0);
- test_ipsec_stats_test_assert(&stats, IPSEC_TEST_STATS_SUCCESS);
+ test_ipsec_stats_test_assert(&stats, IPSEC_TEST_STATS_SUCCESS,
+ succ_bytes);
CU_ASSERT_EQUAL(odp_ipsec_stats(sa_in, &stats), 0);
- test_ipsec_stats_test_assert(&stats, flags->stats);
+ test_ipsec_stats_test_assert(&stats, flags->stats, succ_bytes);
}
ipsec_sa_destroy(sa_out);
diff --git a/test/validation/api/packet/packet.c b/test/validation/api/packet/packet.c
index cd3009ce3..e25260b1d 100644
--- a/test/validation/api/packet/packet.c
+++ b/test/validation/api/packet/packet.c
@@ -929,13 +929,7 @@ static void _verify_headroom_shift(odp_packet_t *pkt,
CU_ASSERT_PTR_NOT_NULL(data);
if (extended) {
CU_ASSERT(rc >= 0);
- if (shift >= 0) {
- CU_ASSERT(odp_packet_seg_len(*pkt) == shift - room);
- } else {
- CU_ASSERT(odp_packet_headroom(*pkt) >=
- (uint32_t)abs(shift) - seg_data_len);
- }
- CU_ASSERT(odp_packet_head(*pkt) != head_orig);
+ CU_ASSERT(odp_packet_seg_len(*pkt) == seg_len);
} else {
CU_ASSERT(odp_packet_headroom(*pkt) == room - shift);
CU_ASSERT(odp_packet_seg_len(*pkt) == seg_data_len + shift);
@@ -1032,15 +1026,13 @@ static void _verify_tailroom_shift(odp_packet_t *pkt,
CU_ASSERT_PTR_NOT_NULL(tail);
if (extended) {
CU_ASSERT(rc >= 0);
- CU_ASSERT(odp_packet_last_seg(*pkt) != seg);
- seg = odp_packet_last_seg(*pkt);
- if (shift > 0) {
- CU_ASSERT(odp_packet_seg_data_len(*pkt, seg) ==
- shift - room);
+
+ if (shift >= 0) {
+ if (rc == 0)
+ CU_ASSERT(tail == tail_orig);
} else {
- CU_ASSERT(odp_packet_tailroom(*pkt) >=
- (uint32_t)abs(shift) - seg_data_len);
- CU_ASSERT(seg_len == odp_packet_tailroom(*pkt));
+ CU_ASSERT(odp_packet_tail(*pkt) == tail);
+ CU_ASSERT(odp_packet_tailroom(*pkt) == seg_len);
}
} else {
CU_ASSERT(odp_packet_seg_data_len(*pkt, seg) ==
@@ -1049,19 +1041,15 @@ static void _verify_tailroom_shift(odp_packet_t *pkt,
if (room == 0 || (room - shift) == 0)
return;
if (shift >= 0) {
- CU_ASSERT(odp_packet_tail(*pkt) ==
- tail_orig + shift);
+ CU_ASSERT(odp_packet_tail(*pkt) == tail_orig + shift);
+ CU_ASSERT(tail == tail_orig);
} else {
+ CU_ASSERT(odp_packet_tail(*pkt) == tail);
CU_ASSERT(tail == tail_orig + shift);
}
}
CU_ASSERT(odp_packet_len(*pkt) == pkt_data_len + shift);
- if (shift >= 0) {
- CU_ASSERT(tail == tail_orig);
- } else {
- CU_ASSERT(odp_packet_tail(*pkt) == tail);
- }
}
static void packet_test_tailroom(void)
diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c
index 7549e16ef..9a47dbe8c 100644
--- a/test/validation/api/pktio/pktio.c
+++ b/test/validation/api/pktio/pktio.c
@@ -3810,6 +3810,169 @@ static void pktio_test_pktout_aging_tmo(void)
}
}
+static void pktio_test_pktin_event_queue(odp_pktin_mode_t pktin_mode)
+{
+ odp_pktio_t pktio_tx, pktio_rx;
+ odp_pktin_queue_param_t in_queue_param;
+ odp_pktout_queue_param_t out_queue_param;
+ odp_pktout_queue_t pktout_queue;
+ odp_queue_t queue, from;
+ odp_pool_t buf_pool;
+ odp_pool_param_t pool_param;
+ odp_packet_t pkt_tbl[TX_BATCH_LEN];
+ odp_packet_t pkt;
+ odp_buffer_t buf;
+ odp_event_t ev;
+ uint32_t pkt_seq[TX_BATCH_LEN];
+ int ret, i;
+ odp_time_t t1, t2;
+ int inactive = 0;
+ int num_pkt = 0;
+ int num_buf = 0;
+ int num_bad = 0;
+ odp_pktio_t pktio[MAX_NUM_IFACES] = {0};
+ uint64_t wait_sec = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS);
+
+ CU_ASSERT_FATAL(num_ifaces >= 1);
+
+ odp_pool_param_init(&pool_param);
+ pool_param.type = ODP_POOL_BUFFER;
+ pool_param.buf.num = 2 * TX_BATCH_LEN;
+ pool_param.buf.size = 100;
+
+ buf_pool = odp_pool_create("buffer pool", &pool_param);
+ CU_ASSERT_FATAL(buf_pool != ODP_POOL_INVALID);
+
+ buf = odp_buffer_alloc(buf_pool);
+ CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
+
+ odp_pktin_queue_param_init(&in_queue_param);
+ in_queue_param.num_queues = 1;
+ in_queue_param.hash_enable = 0;
+ in_queue_param.classifier_enable = 0;
+
+ if (pktin_mode == ODP_PKTIN_MODE_SCHED) {
+ in_queue_param.queue_param.type = ODP_QUEUE_TYPE_SCHED;
+ in_queue_param.queue_param.sched.prio = ODP_SCHED_PRIO_DEFAULT;
+ in_queue_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
+ in_queue_param.queue_param.sched.group = ODP_SCHED_GROUP_ALL;
+ }
+
+ odp_pktout_queue_param_init(&out_queue_param);
+ out_queue_param.num_queues = 1;
+
+ /* Open and configure interfaces */
+ for (i = 0; i < num_ifaces; ++i) {
+ pktio[i] = create_pktio(i, pktin_mode, ODP_PKTOUT_MODE_DIRECT);
+ CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID);
+
+ ret = odp_pktin_queue_config(pktio[i], &in_queue_param);
+ CU_ASSERT_FATAL(ret == 0);
+
+ ret = odp_pktout_queue_config(pktio[i], &out_queue_param);
+ CU_ASSERT_FATAL(ret == 0);
+
+ CU_ASSERT_FATAL(odp_pktio_start(pktio[i]) == 0);
+ }
+
+ for (i = 0; i < num_ifaces; ++i)
+ _pktio_wait_linkup(pktio[i]);
+
+ pktio_tx = pktio[0];
+ if (num_ifaces > 1)
+ pktio_rx = pktio[1];
+ else
+ pktio_rx = pktio_tx;
+
+ CU_ASSERT_FATAL(odp_pktin_event_queue(pktio_rx, &queue, 1) == 1);
+ CU_ASSERT_FATAL(odp_pktout_queue(pktio_tx, &pktout_queue, 1) == 1);
+
+ /* Allocate and initialize test packets */
+ ret = create_packets(pkt_tbl, pkt_seq, TX_BATCH_LEN, pktio_tx, pktio_rx);
+ if (ret != TX_BATCH_LEN) {
+ CU_FAIL("Failed to generate test packets");
+ return;
+ }
+
+ /* Send packets */
+ ret = odp_pktout_send(pktout_queue, pkt_tbl, TX_BATCH_LEN);
+ CU_ASSERT_FATAL(ret == TX_BATCH_LEN);
+
+ /* Send buffer event */
+ ret = odp_queue_enq(queue, odp_buffer_to_event(buf));
+ CU_ASSERT_FATAL(ret == 0);
+
+ /* Receive events */
+ while (1) {
+ /* Break after 1 sec of inactivity */
+ if (pktin_mode == ODP_PKTIN_MODE_SCHED) {
+ ev = odp_schedule(&from, wait_sec);
+
+ if (ev == ODP_EVENT_INVALID)
+ break;
+
+ CU_ASSERT(from == queue);
+ } else {
+ ev = odp_queue_deq(queue);
+
+ if (ev == ODP_EVENT_INVALID) {
+ if (inactive == 0) {
+ inactive = 1;
+ t1 = odp_time_local();
+ continue;
+ } else {
+ t2 = odp_time_local();
+ if (odp_time_diff_ns(t2, t1) > ODP_TIME_SEC_IN_NS)
+ break;
+
+ continue;
+ }
+ }
+
+ inactive = 0;
+ }
+
+ if (odp_event_type(ev) == ODP_EVENT_PACKET) {
+ pkt = odp_packet_from_event(ev);
+
+ if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
+ num_pkt++;
+
+ } else if (odp_event_type(ev) == ODP_EVENT_BUFFER) {
+ num_buf++;
+ } else {
+ CU_FAIL("Bad event type");
+ num_bad++;
+ }
+
+ odp_event_free(ev);
+ }
+
+ CU_ASSERT(num_pkt == TX_BATCH_LEN);
+ CU_ASSERT(num_buf == 1);
+ CU_ASSERT(num_bad == 0);
+
+ for (i = 0; i < num_ifaces; i++) {
+ CU_ASSERT_FATAL(odp_pktio_stop(pktio[i]) == 0);
+ CU_ASSERT_FATAL(odp_pktio_close(pktio[i]) == 0);
+ }
+
+ CU_ASSERT_FATAL(odp_pool_destroy(buf_pool) == 0);
+}
+
+static void pktio_test_pktin_event_sched(void)
+{
+ pktio_test_pktin_event_queue(ODP_PKTIN_MODE_SCHED);
+}
+
+static int pktio_check_pktin_event_sched(void)
+{
+ if (odp_cunit_ci_skip("pktio_test_pktin_event_sched"))
+ return ODP_TEST_INACTIVE;
+
+ return ODP_TEST_ACTIVE;
+}
+
static int pktio_suite_init(void)
{
int i;
@@ -3965,6 +4128,8 @@ odp_testinfo_t pktio_suite_unsegmented[] = {
ODP_TEST_INFO(pktio_test_plain_multi_event),
ODP_TEST_INFO(pktio_test_sched_multi_event),
ODP_TEST_INFO(pktio_test_recv_multi_event),
+ ODP_TEST_INFO_CONDITIONAL(pktio_test_pktin_event_sched,
+ pktio_check_pktin_event_sched),
ODP_TEST_INFO_CONDITIONAL(pktio_test_statistics_counters,
pktio_check_statistics_counters),
ODP_TEST_INFO_CONDITIONAL(pktio_test_pktin_ts,
diff --git a/test/validation/api/scheduler/scheduler.c b/test/validation/api/scheduler/scheduler.c
index 8800350f2..37f3b4f0b 100644
--- a/test/validation/api/scheduler/scheduler.c
+++ b/test/validation/api/scheduler/scheduler.c
@@ -59,6 +59,7 @@
#define WAIT_1MS_RETRIES 1000
#define SCHED_AND_PLAIN_ROUNDS 10000
+#define ATOMICITY_ROUNDS 100
/* Test global variables */
typedef struct {
@@ -77,6 +78,10 @@ typedef struct {
odp_spinlock_t atomic_lock;
struct {
odp_queue_t handle;
+ odp_atomic_u32_t state;
+ } atomicity_q;
+ struct {
+ odp_queue_t handle;
char name[ODP_QUEUE_NAME_LEN];
} chaos_q[CHAOS_NUM_QUEUES];
struct {
@@ -145,10 +150,13 @@ static void scheduler_test_init(void)
odp_schedule_config_init(&default_config);
+ CU_ASSERT(default_config.max_flow_id == 0);
+
CU_ASSERT(default_config.sched_group.all);
CU_ASSERT(default_config.sched_group.control);
CU_ASSERT(default_config.sched_group.worker);
}
+
static void scheduler_test_capa(void)
{
odp_schedule_capability_t sched_capa;
@@ -2481,6 +2489,121 @@ static void scheduler_test_ordered_and_plain(void)
scheduler_test_sched_and_plain(ODP_SCHED_SYNC_ORDERED);
}
+static int atomicity_test_run(void *arg)
+{
+ thread_args_t *args = (thread_args_t *)arg;
+ odp_event_t ev;
+ odp_queue_t atomic_queue = args->globals->atomicity_q.handle;
+ odp_queue_t from;
+ odp_atomic_u32_t *state;
+ uint32_t old;
+ uint32_t num_processed = 0;
+
+ if (args->num_workers > 1)
+ odp_barrier_wait(&globals->barrier);
+
+ while (num_processed < ATOMICITY_ROUNDS) {
+ ev = odp_schedule(&from, ODP_SCHED_NO_WAIT);
+ if (ev == ODP_EVENT_INVALID)
+ continue;
+
+ CU_ASSERT(from == atomic_queue);
+ if (from != atomic_queue) {
+ odp_event_free(ev);
+ continue;
+ }
+
+ state = odp_queue_context(from);
+ CU_ASSERT_FATAL(state != NULL);
+
+ old = 0;
+ CU_ASSERT_FATAL(odp_atomic_cas_acq_rel_u32(state, &old, 1));
+
+ /* Hold atomic context a while to better reveal possible atomicity bugs */
+ odp_time_wait_ns(ODP_TIME_MSEC_IN_NS);
+
+ old = 1;
+ CU_ASSERT_FATAL(odp_atomic_cas_acq_rel_u32(state, &old, 0));
+
+ CU_ASSERT_FATAL(odp_queue_enq(from, ev) == 0);
+
+ num_processed++;
+ }
+
+ /* Release atomic context and get rid of possible prescheduled events */
+ odp_schedule_pause();
+ while ((ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT)) != ODP_EVENT_INVALID)
+ CU_ASSERT_FATAL(odp_queue_enq(atomic_queue, ev) == 0);
+
+ if (args->num_workers > 1)
+ odp_barrier_wait(&globals->barrier);
+
+ odp_schedule_resume();
+ drain_queues();
+
+ return 0;
+}
+
+static void scheduler_test_atomicity(void)
+{
+ odp_shm_t shm;
+ test_globals_t *globals;
+ thread_args_t *args;
+ odp_pool_t pool;
+ odp_queue_t queue;
+ odp_queue_param_t queue_param;
+ int i;
+
+ shm = odp_shm_lookup(GLOBALS_SHM_NAME);
+ CU_ASSERT_FATAL(shm != ODP_SHM_INVALID);
+ globals = odp_shm_addr(shm);
+ CU_ASSERT_FATAL(globals != NULL);
+
+ shm = odp_shm_lookup(SHM_THR_ARGS_NAME);
+ CU_ASSERT_FATAL(shm != ODP_SHM_INVALID);
+ args = odp_shm_addr(shm);
+ CU_ASSERT_FATAL(args != NULL);
+
+ pool = odp_pool_lookup(MSG_POOL_NAME);
+ CU_ASSERT_FATAL(pool != ODP_POOL_INVALID);
+
+ odp_queue_param_init(&queue_param);
+ queue_param.type = ODP_QUEUE_TYPE_SCHED;
+ queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;
+ queue_param.sched.group = ODP_SCHED_GROUP_ALL;
+ queue_param.size = globals->max_sched_queue_size;
+ queue_param.context = &globals->atomicity_q.state;
+ queue_param.context_len = sizeof(globals->atomicity_q.state);
+
+ queue = odp_queue_create("atomicity_test", &queue_param);
+ CU_ASSERT_FATAL(queue != ODP_QUEUE_INVALID);
+
+ for (i = 0; i < BUFS_PER_QUEUE; i++) {
+ odp_buffer_t buf = odp_buffer_alloc(pool);
+
+ CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
+
+ CU_ASSERT_FATAL(odp_queue_enq(queue, odp_buffer_to_event(buf)) == 0);
+ }
+ globals->atomicity_q.handle = queue;
+ odp_atomic_init_u32(&globals->atomicity_q.state, 0);
+
+ /* Create and launch worker threads */
+ /* Test runs also on the main thread */
+ args->num_workers = globals->num_workers;
+ args->cu_thr.numthrds = globals->num_workers - 1;
+ if (args->cu_thr.numthrds > 0)
+ odp_cunit_thread_create(atomicity_test_run, &args->cu_thr);
+
+ atomicity_test_run(args);
+
+ /* Wait for worker threads to terminate */
+ if (args->cu_thr.numthrds > 0)
+ odp_cunit_thread_exit(&args->cu_thr);
+
+ odp_queue_destroy(globals->atomicity_q.handle);
+}
+
static int create_queues(test_globals_t *globals)
{
int i, j, prios, rc;
@@ -3048,6 +3171,7 @@ odp_testinfo_t scheduler_basic_suite[] = {
ODP_TEST_INFO(scheduler_test_ordered),
ODP_TEST_INFO(scheduler_test_atomic_and_plain),
ODP_TEST_INFO(scheduler_test_ordered_and_plain),
+ ODP_TEST_INFO(scheduler_test_atomicity),
ODP_TEST_INFO_NULL
};
diff --git a/test/validation/api/time/time.c b/test/validation/api/time/time.c
index 2b1efa8af..4974dcb5d 100644
--- a/test/validation/api/time/time.c
+++ b/test/validation/api/time/time.c
@@ -223,6 +223,16 @@ static void time_test_global_cmp(void)
time_test_cmp(odp_time_global, odp_time_global_from_ns);
}
+static void time_test_local_strict_cmp(void)
+{
+ time_test_cmp(odp_time_local_strict, odp_time_local_from_ns);
+}
+
+static void time_test_global_strict_cmp(void)
+{
+ time_test_cmp(odp_time_global_strict, odp_time_global_from_ns);
+}
+
/* check that a time difference gives a reasonable result */
static void time_test_diff(time_cb time_cur,
time_from_ns_cb time_from_ns,
@@ -318,6 +328,16 @@ static void time_test_global_diff(void)
time_test_diff(odp_time_global, odp_time_global_from_ns, global_res);
}
+static void time_test_local_strict_diff(void)
+{
+ time_test_diff(odp_time_local_strict, odp_time_local_from_ns, local_res);
+}
+
+static void time_test_global_strict_diff(void)
+{
+ time_test_diff(odp_time_global_strict, odp_time_global_from_ns, global_res);
+}
+
/* check that a time sum gives a reasonable result */
static void time_test_sum(time_cb time_cur,
time_from_ns_cb time_from_ns,
@@ -370,6 +390,16 @@ static void time_test_global_sum(void)
time_test_sum(odp_time_global, odp_time_global_from_ns, global_res);
}
+static void time_test_local_strict_sum(void)
+{
+ time_test_sum(odp_time_local_strict, odp_time_local_from_ns, local_res);
+}
+
+static void time_test_global_strict_sum(void)
+{
+ time_test_sum(odp_time_global_strict, odp_time_global_from_ns, global_res);
+}
+
static void time_test_wait_until(time_cb time_cur, time_from_ns_cb time_from_ns)
{
int i;
@@ -488,16 +518,6 @@ static void time_test_accuracy(time_cb time_cur, time_from_ns_cb time_from_ns)
CU_ASSERT(sec_t > sec_c * 0.95);
}
-static void time_test_local_accuracy(void)
-{
- time_test_accuracy(odp_time_local, odp_time_local_from_ns);
-}
-
-static void time_test_global_accuracy(void)
-{
- time_test_accuracy(odp_time_global, odp_time_global_from_ns);
-}
-
static void time_test_accuracy_nsec(time_nsec_cb time_nsec)
{
uint64_t t1, t2, diff;
@@ -533,6 +553,26 @@ static void time_test_accuracy_nsec(time_nsec_cb time_nsec)
CU_ASSERT(sec_t > sec_c * 0.95);
}
+static void time_test_local_accuracy(void)
+{
+ time_test_accuracy(odp_time_local, odp_time_local_from_ns);
+}
+
+static void time_test_global_accuracy(void)
+{
+ time_test_accuracy(odp_time_global, odp_time_global_from_ns);
+}
+
+static void time_test_local_strict_accuracy(void)
+{
+ time_test_accuracy(odp_time_local_strict, odp_time_local_from_ns);
+}
+
+static void time_test_global_strict_accuracy(void)
+{
+ time_test_accuracy(odp_time_global_strict, odp_time_global_from_ns);
+}
+
static void time_test_local_accuracy_nsec(void)
{
time_test_accuracy_nsec(odp_time_local_ns);
@@ -543,26 +583,46 @@ static void time_test_global_accuracy_nsec(void)
time_test_accuracy_nsec(odp_time_global_ns);
}
+static void time_test_local_strict_accuracy_nsec(void)
+{
+ time_test_accuracy_nsec(odp_time_local_strict_ns);
+}
+
+static void time_test_global_strict_accuracy_nsec(void)
+{
+ time_test_accuracy_nsec(odp_time_global_strict_ns);
+}
+
odp_testinfo_t time_suite_time[] = {
ODP_TEST_INFO(time_test_constants),
ODP_TEST_INFO(time_test_local_res),
ODP_TEST_INFO(time_test_local_conversion),
- ODP_TEST_INFO(time_test_monotony),
ODP_TEST_INFO(time_test_local_cmp),
ODP_TEST_INFO(time_test_local_diff),
ODP_TEST_INFO(time_test_local_sum),
- ODP_TEST_INFO(time_test_local_wait_until),
- ODP_TEST_INFO(time_test_wait_ns),
- ODP_TEST_INFO(time_test_local_accuracy),
ODP_TEST_INFO(time_test_global_res),
ODP_TEST_INFO(time_test_global_conversion),
ODP_TEST_INFO(time_test_global_cmp),
ODP_TEST_INFO(time_test_global_diff),
ODP_TEST_INFO(time_test_global_sum),
+ ODP_TEST_INFO(time_test_wait_ns),
+ ODP_TEST_INFO(time_test_monotony),
+ ODP_TEST_INFO(time_test_local_wait_until),
ODP_TEST_INFO(time_test_global_wait_until),
+ ODP_TEST_INFO(time_test_local_accuracy),
ODP_TEST_INFO(time_test_global_accuracy),
ODP_TEST_INFO(time_test_local_accuracy_nsec),
ODP_TEST_INFO(time_test_global_accuracy_nsec),
+ ODP_TEST_INFO(time_test_local_strict_diff),
+ ODP_TEST_INFO(time_test_local_strict_sum),
+ ODP_TEST_INFO(time_test_local_strict_cmp),
+ ODP_TEST_INFO(time_test_global_strict_diff),
+ ODP_TEST_INFO(time_test_global_strict_sum),
+ ODP_TEST_INFO(time_test_global_strict_cmp),
+ ODP_TEST_INFO(time_test_local_strict_accuracy),
+ ODP_TEST_INFO(time_test_global_strict_accuracy),
+ ODP_TEST_INFO(time_test_local_strict_accuracy_nsec),
+ ODP_TEST_INFO(time_test_global_strict_accuracy_nsec),
ODP_TEST_INFO_NULL
};
diff --git a/test/validation/api/timer/timer.c b/test/validation/api/timer/timer.c
index f2cc93cb8..177f6f82b 100644
--- a/test/validation/api/timer/timer.c
+++ b/test/validation/api/timer/timer.c
@@ -47,6 +47,9 @@ struct thread_args {
};
typedef struct {
+ /* Clock source support flags */
+ uint8_t clk_supported[ODP_CLOCK_NUM_SRC];
+
/* Default resolution / timeout parameters */
struct {
uint64_t res_ns;
@@ -88,6 +91,7 @@ static int timer_global_init(odp_instance_t *inst)
odp_timer_res_capability_t res_capa;
uint64_t res_ns, min_tmo, max_tmo;
unsigned int range;
+ int i;
if (odph_options(&helper_options)) {
fprintf(stderr, "error: odph_options() failed.\n");
@@ -121,7 +125,7 @@ static int timer_global_init(odp_instance_t *inst)
odp_schedule_config(NULL);
memset(&capa, 0, sizeof(capa));
- if (odp_timer_capability(ODP_CLOCK_CPU, &capa)) {
+ if (odp_timer_capability(ODP_CLOCK_DEFAULT, &capa)) {
fprintf(stderr, "Timer capability failed\n");
return -1;
}
@@ -134,7 +138,7 @@ static int timer_global_init(odp_instance_t *inst)
memset(&res_capa, 0, sizeof(res_capa));
res_capa.res_ns = res_ns;
- if (odp_timer_res_capability(ODP_CLOCK_CPU, &res_capa)) {
+ if (odp_timer_res_capability(ODP_CLOCK_DEFAULT, &res_capa)) {
fprintf(stderr, "Timer resolution capability failed\n");
return -1;
}
@@ -156,12 +160,19 @@ static int timer_global_init(odp_instance_t *inst)
}
/* Default parameters for test cases */
+ global_mem->clk_supported[0] = 1;
global_mem->param.res_ns = res_ns;
global_mem->param.min_tmo = min_tmo;
global_mem->param.max_tmo = max_tmo;
global_mem->param.queue_type_plain = capa.queue_type_plain;
global_mem->param.queue_type_sched = capa.queue_type_sched;
+ /* Check which other source clocks are supported */
+ for (i = 1; i < ODP_CLOCK_NUM_SRC; i++) {
+ if (odp_timer_capability(ODP_CLOCK_SRC_0 + i, &capa) == 0)
+ global_mem->clk_supported[i] = 1;
+ }
+
return 0;
}
@@ -206,14 +217,14 @@ check_plain_queue_support(void)
return ODP_TEST_INACTIVE;
}
-static void timer_test_capa(void)
+static void timer_test_capa_run(odp_timer_clk_src_t clk_src)
{
odp_timer_capability_t capa;
odp_timer_res_capability_t res_capa;
int ret;
memset(&capa, 0, sizeof(capa));
- ret = odp_timer_capability(ODP_CLOCK_CPU, &capa);
+ ret = odp_timer_capability(clk_src, &capa);
CU_ASSERT_FATAL(ret == 0);
CU_ASSERT(capa.highest_res_ns == capa.max_res.res_ns);
@@ -234,7 +245,7 @@ static void timer_test_capa(void)
memset(&res_capa, 0, sizeof(res_capa));
res_capa.res_ns = capa.max_res.res_ns;
- ret = odp_timer_res_capability(ODP_CLOCK_CPU, &res_capa);
+ ret = odp_timer_res_capability(clk_src, &res_capa);
CU_ASSERT_FATAL(ret == 0);
CU_ASSERT(res_capa.res_ns == capa.max_res.res_ns);
CU_ASSERT(res_capa.min_tmo == capa.max_res.min_tmo);
@@ -244,7 +255,7 @@ static void timer_test_capa(void)
memset(&res_capa, 0, sizeof(res_capa));
res_capa.res_hz = capa.max_res.res_hz;
- ret = odp_timer_res_capability(ODP_CLOCK_CPU, &res_capa);
+ ret = odp_timer_res_capability(clk_src, &res_capa);
CU_ASSERT_FATAL(ret == 0);
CU_ASSERT(res_capa.res_hz == capa.max_res.res_hz);
CU_ASSERT(res_capa.min_tmo == capa.max_res.min_tmo);
@@ -254,7 +265,7 @@ static void timer_test_capa(void)
memset(&res_capa, 0, sizeof(res_capa));
res_capa.max_tmo = capa.max_tmo.max_tmo;
- ret = odp_timer_res_capability(ODP_CLOCK_CPU, &res_capa);
+ ret = odp_timer_res_capability(clk_src, &res_capa);
CU_ASSERT_FATAL(ret == 0);
CU_ASSERT(res_capa.max_tmo == capa.max_tmo.max_tmo);
CU_ASSERT(res_capa.min_tmo == capa.max_tmo.min_tmo);
@@ -262,6 +273,31 @@ static void timer_test_capa(void)
CU_ASSERT(res_capa.res_hz == capa.max_tmo.res_hz);
}
+static void timer_test_capa(void)
+{
+ odp_timer_clk_src_t clk_src;
+ int i;
+
+ /* Check that all API clock source enumeration values exist */
+ CU_ASSERT_FATAL(ODP_CLOCK_DEFAULT == ODP_CLOCK_SRC_0);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 1 == ODP_CLOCK_SRC_1);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 2 == ODP_CLOCK_SRC_2);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 3 == ODP_CLOCK_SRC_3);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 4 == ODP_CLOCK_SRC_4);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_0 + 5 == ODP_CLOCK_SRC_5);
+ CU_ASSERT_FATAL(ODP_CLOCK_SRC_5 + 1 == ODP_CLOCK_NUM_SRC);
+ CU_ASSERT_FATAL(ODP_CLOCK_CPU == ODP_CLOCK_DEFAULT);
+ CU_ASSERT_FATAL(ODP_CLOCK_EXT == ODP_CLOCK_SRC_1);
+
+ for (i = 0; i < ODP_CLOCK_NUM_SRC; i++) {
+ clk_src = ODP_CLOCK_SRC_0 + i;
+ if (global_mem->clk_supported[i]) {
+ ODPH_DBG("\nTesting clock source: %i\n", clk_src);
+ timer_test_capa_run(clk_src);
+ }
+ }
+}
+
static void timer_test_timeout_pool_alloc(void)
{
odp_pool_t pool;
@@ -359,7 +395,7 @@ static void timer_pool_create_destroy(void)
int ret;
memset(&capa, 0, sizeof(capa));
- ret = odp_timer_capability(ODP_CLOCK_CPU, &capa);
+ ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa);
CU_ASSERT_FATAL(ret == 0);
odp_queue_param_init(&queue_param);
@@ -378,7 +414,7 @@ static void timer_pool_create_destroy(void)
tparam.max_tmo = global_mem->param.max_tmo;
tparam.num_timers = 100;
tparam.priv = 0;
- tparam.clk_src = ODP_CLOCK_CPU;
+ tparam.clk_src = ODP_CLOCK_DEFAULT;
tp[0] = odp_timer_pool_create("timer_pool_a", &tparam);
CU_ASSERT(tp[0] != ODP_TIMER_POOL_INVALID);
@@ -444,7 +480,7 @@ static void timer_pool_max_res(void)
int ret, i;
memset(&capa, 0, sizeof(capa));
- ret = odp_timer_capability(ODP_CLOCK_CPU, &capa);
+ ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa);
CU_ASSERT_FATAL(ret == 0);
odp_pool_param_init(&pool_param);
@@ -481,7 +517,7 @@ static void timer_pool_max_res(void)
tp_param.max_tmo = capa.max_res.max_tmo;
tp_param.num_timers = 100;
tp_param.priv = 0;
- tp_param.clk_src = ODP_CLOCK_CPU;
+ tp_param.clk_src = ODP_CLOCK_DEFAULT;
tp = odp_timer_pool_create("high_res_tp", &tp_param);
CU_ASSERT_FATAL(tp != ODP_TIMER_POOL_INVALID);
@@ -545,7 +581,7 @@ static void timer_test_event_type(odp_queue_type_t queue_type,
period_ns = 2 * global_mem->param.min_tmo;
timer_param.max_tmo = global_mem->param.max_tmo;
timer_param.num_timers = num;
- timer_param.clk_src = ODP_CLOCK_CPU;
+ timer_param.clk_src = ODP_CLOCK_DEFAULT;
timer_pool = odp_timer_pool_create("timer_pool", &timer_param);
if (timer_pool == ODP_TIMER_POOL_INVALID)
@@ -614,12 +650,12 @@ static void timer_test_event_type(odp_queue_type_t queue_type,
ret = odp_timer_set_rel(timer[i], (i + 1) * period_tick, &ev);
- if (ret == ODP_TIMER_TOOEARLY)
- ODPH_DBG("Too early %i\n", i);
- else if (ret == ODP_TIMER_TOOLATE)
- ODPH_DBG("Too late %i\n", i);
- else if (ret == ODP_TIMER_NOEVENT)
- ODPH_DBG("No event %i\n", i);
+ if (ret == ODP_TIMER_TOO_NEAR)
+ ODPH_DBG("Timer set failed. Too near %i.\n", i);
+ else if (ret == ODP_TIMER_TOO_FAR)
+ ODPH_DBG("Timer set failed. Too far %i.\n", i);
+ else if (ret == ODP_TIMER_FAIL)
+ ODPH_DBG("Timer set failed %i\n", i);
CU_ASSERT(ret == ODP_TIMER_SUCCESS);
}
@@ -740,7 +776,7 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv)
tparam.max_tmo = global_mem->param.max_tmo;
tparam.num_timers = num + 1;
tparam.priv = priv;
- tparam.clk_src = ODP_CLOCK_CPU;
+ tparam.clk_src = ODP_CLOCK_DEFAULT;
ODPH_DBG("\nTimer pool parameters:\n");
ODPH_DBG(" res_ns %" PRIu64 "\n", tparam.res_ns);
@@ -792,12 +828,12 @@ static void timer_test_queue_type(odp_queue_type_t queue_type, int priv)
target_tick[i] = tick;
ODPH_DBG("abs timer tick %" PRIu64 "\n", tick);
- if (ret == ODP_TIMER_TOOEARLY)
- ODPH_DBG("Too early %" PRIu64 "\n", tick);
- else if (ret == ODP_TIMER_TOOLATE)
- ODPH_DBG("Too late %" PRIu64 "\n", tick);
- else if (ret == ODP_TIMER_NOEVENT)
- ODPH_DBG("No event %" PRIu64 "\n", tick);
+ if (ret == ODP_TIMER_TOO_NEAR)
+ ODPH_DBG("Timer set failed. Too near %" PRIu64 ".\n", tick);
+ else if (ret == ODP_TIMER_TOO_FAR)
+ ODPH_DBG("Timer set failed. Too far %" PRIu64 ".\n", tick);
+ else if (ret == ODP_TIMER_FAIL)
+ ODPH_DBG("Timer set failed %" PRIu64 "\n", tick);
CU_ASSERT(ret == ODP_TIMER_SUCCESS);
}
@@ -902,7 +938,7 @@ static void timer_test_cancel(void)
int ret;
memset(&capa, 0, sizeof(capa));
- ret = odp_timer_capability(ODP_CLOCK_CPU, &capa);
+ ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &capa);
CU_ASSERT_FATAL(ret == 0);
odp_pool_param_init(&params);
@@ -920,7 +956,7 @@ static void timer_test_cancel(void)
tparam.max_tmo = global_mem->param.max_tmo;
tparam.num_timers = 1;
tparam.priv = 0;
- tparam.clk_src = ODP_CLOCK_CPU;
+ tparam.clk_src = ODP_CLOCK_DEFAULT;
tp = odp_timer_pool_create(NULL, &tparam);
if (tp == ODP_TIMER_POOL_INVALID)
CU_FAIL_FATAL("Timer pool create failed");
@@ -1008,7 +1044,7 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type,
odp_timer_t timer[num];
memset(&timer_capa, 0, sizeof(timer_capa));
- ret = odp_timer_capability(ODP_CLOCK_CPU, &timer_capa);
+ ret = odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa);
CU_ASSERT_FATAL(ret == 0);
if (max_res) {
@@ -1028,7 +1064,7 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type,
timer_param.min_tmo = min_tmo;
timer_param.max_tmo = max_tmo;
timer_param.num_timers = num;
- timer_param.clk_src = ODP_CLOCK_CPU;
+ timer_param.clk_src = ODP_CLOCK_DEFAULT;
timer_pool = odp_timer_pool_create("timer_pool", &timer_param);
if (timer_pool == ODP_TIMER_POOL_INVALID)
@@ -1085,12 +1121,12 @@ static void timer_test_tmo_limit(odp_queue_type_t queue_type,
t1 = odp_time_local();
ret = odp_timer_set_rel(timer[i], tmo_tick, &ev);
- if (ret == ODP_TIMER_TOOEARLY)
- ODPH_DBG("Too early %i\n", i);
- else if (ret == ODP_TIMER_TOOLATE)
- ODPH_DBG("Too late %i\n", i);
- else if (ret == ODP_TIMER_NOEVENT)
- ODPH_DBG("No event %i\n", i);
+ if (ret == ODP_TIMER_TOO_NEAR)
+ ODPH_DBG("Timer set failed. Too near %i.\n", i);
+ else if (ret == ODP_TIMER_TOO_FAR)
+ ODPH_DBG("Timer set failed. Too late %i.\n", i);
+ else if (ret == ODP_TIMER_FAIL)
+ ODPH_DBG("Timer set failed %i\n", i);
CU_ASSERT(ret == ODP_TIMER_SUCCESS);
@@ -1364,7 +1400,7 @@ static int worker_entrypoint(void *arg)
tck = odp_timer_current_tick(tp) +
odp_timer_ns_to_tick(tp, nsec);
timer_rc = odp_timer_set_abs(tt[i].tim, tck, &tt[i].ev);
- if (timer_rc == ODP_TIMER_TOOEARLY) {
+ if (timer_rc == ODP_TIMER_TOO_NEAR) {
ODPH_ERR("Missed tick, setting timer\n");
} else if (timer_rc != ODP_TIMER_SUCCESS) {
ODPH_ERR("Failed to set timer: %d\n", timer_rc);
@@ -1431,11 +1467,11 @@ static int worker_entrypoint(void *arg)
cur_tick = odp_timer_current_tick(tp);
rc = odp_timer_set_rel(tt[i].tim, tck, &tt[i].ev);
- if (rc == ODP_TIMER_TOOEARLY) {
- CU_FAIL("Failed to set timer: TOO EARLY");
- } else if (rc == ODP_TIMER_TOOLATE) {
- CU_FAIL("Failed to set timer: TOO LATE");
- } else if (rc == ODP_TIMER_NOEVENT) {
+ if (rc == ODP_TIMER_TOO_NEAR) {
+ CU_FAIL("Failed to set timer: TOO NEAR");
+ } else if (rc == ODP_TIMER_TOO_FAR) {
+ CU_FAIL("Failed to set timer: TOO FAR");
+ } else if (rc == ODP_TIMER_FAIL) {
/* Set/reset failed, timer already expired */
ntoolate++;
} else if (rc == ODP_TIMER_SUCCESS) {
@@ -1561,7 +1597,7 @@ static void timer_test_all(odp_queue_type_t queue_type)
num_workers = 1;
num_timers = num_workers * NTIMERS;
- CU_ASSERT_FATAL(!odp_timer_capability(ODP_CLOCK_CPU, &timer_capa));
+ CU_ASSERT_FATAL(!odp_timer_capability(ODP_CLOCK_DEFAULT, &timer_capa));
if (timer_capa.max_timers && timer_capa.max_timers < num_timers)
num_timers = timer_capa.max_timers;
@@ -1594,7 +1630,7 @@ static void timer_test_all(odp_queue_type_t queue_type)
tparam.max_tmo = max_tmo;
tparam.num_timers = num_timers;
tparam.priv = 0;
- tparam.clk_src = ODP_CLOCK_CPU;
+ tparam.clk_src = ODP_CLOCK_DEFAULT;
global_mem->tp = odp_timer_pool_create(NAME, &tparam);
if (global_mem->tp == ODP_TIMER_POOL_INVALID)
CU_FAIL_FATAL("Timer pool create failed");
diff --git a/test/validation/api/traffic_mngr/traffic_mngr.c b/test/validation/api/traffic_mngr/traffic_mngr.c
index 13f39457d..55004692d 100644
--- a/test/validation/api/traffic_mngr/traffic_mngr.c
+++ b/test/validation/api/traffic_mngr/traffic_mngr.c
@@ -113,6 +113,8 @@
#define TM_PERCENT(percent) ((uint32_t)(100 * percent))
+#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
+
typedef enum {
SHAPER_PROFILE, SCHED_PROFILE, THRESHOLD_PROFILE, WRED_PROFILE
} profile_kind_t;
@@ -281,6 +283,11 @@ static uint32_t num_odp_tm_systems;
static odp_tm_capabilities_t tm_capabilities;
+static bool dynamic_shaper_update = true;
+static bool dynamic_sched_update = true;
+static bool dynamic_threshold_update = true;
+static bool dynamic_wred_update = true;
+
static odp_tm_shaper_t shaper_profiles[NUM_SHAPER_PROFILES];
static odp_tm_sched_t sched_profiles[NUM_SCHED_PROFILES];
static odp_tm_threshold_t threshold_profiles[NUM_THRESHOLD_PROFILES];
@@ -317,8 +324,8 @@ static uint32_t num_ifaces;
static odp_pool_t pools[MAX_NUM_IFACES] = {ODP_POOL_INVALID, ODP_POOL_INVALID};
static odp_pktio_t pktios[MAX_NUM_IFACES];
+static odp_bool_t pktio_started[MAX_NUM_IFACES];
static odp_pktin_queue_t pktins[MAX_NUM_IFACES];
-static odp_pktout_queue_t pktouts[MAX_NUM_IFACES];
static odp_pktin_queue_t rcv_pktin;
static odp_pktio_t xmt_pktio;
@@ -328,6 +335,8 @@ static odph_ethaddr_t dst_mac;
static uint32_t cpu_unique_id;
static uint32_t cpu_tcp_seq_num;
+static int8_t suite_inactive;
+
static void busy_wait(uint64_t nanoseconds)
{
odp_time_t start_time, end_time;
@@ -481,7 +490,6 @@ static int open_pktios(void)
odp_pktio_param_init(&pktio_param);
pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT;
- pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
for (iface = 0; iface < num_ifaces; iface++) {
snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s",
@@ -494,10 +502,37 @@ static int open_pktios(void)
}
pools[iface] = pkt_pool;
- pktio = odp_pktio_open(iface_name[iface], pkt_pool,
- &pktio_param);
- if (pktio == ODP_PKTIO_INVALID)
- pktio = odp_pktio_lookup(iface_name[iface]);
+
+ /* Zero'th device is always PKTOUT TM as we use it from XMIT */
+ if (iface == 0) {
+ pktio_param.out_mode = ODP_PKTOUT_MODE_TM;
+
+ pktio = odp_pktio_open(iface_name[iface], pkt_pool,
+ &pktio_param);
+
+ /* On failure check if pktio can be opened in non-TM mode.
+ * If non-TM mode works, then we can assume that PKTIO
+ * does not support TM
+ */
+ if (pktio == ODP_PKTIO_INVALID) {
+ pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT;
+ pktio = odp_pktio_open(iface_name[iface], pkt_pool,
+ &pktio_param);
+
+ /* Return >0 to indicate no TM support */
+ if (pktio != ODP_PKTIO_INVALID) {
+ odp_pktio_close(pktio);
+ return 1;
+ }
+ }
+ } else {
+ pktio_param.out_mode = ODP_PKTOUT_MODE_DISABLED;
+
+ pktio = odp_pktio_open(iface_name[iface], pkt_pool,
+ &pktio_param);
+ }
+
+ pktios[iface] = pktio;
if (pktio == ODP_PKTIO_INVALID) {
ODPH_ERR("odp_pktio_open() failed\n");
return -1;
@@ -505,25 +540,16 @@ static int open_pktios(void)
/* Set defaults for PktIn and PktOut queues */
(void)odp_pktin_queue_config(pktio, NULL);
- (void)odp_pktout_queue_config(pktio, NULL);
rc = odp_pktio_promisc_mode_set(pktio, true);
if (rc != 0)
printf("****** promisc_mode_set failed ******\n");
- pktios[iface] = pktio;
-
if (odp_pktin_queue(pktio, &pktins[iface], 1) != 1) {
odp_pktio_close(pktio);
ODPH_ERR("odp_pktio_open() failed: no pktin queue\n");
return -1;
}
- if (odp_pktout_queue(pktio, &pktouts[iface], 1) != 1) {
- odp_pktio_close(pktio);
- ODPH_ERR("odp_pktio_open() failed: no pktout queue\n");
- return -1;
- }
-
rc = -1;
if (iface == 0)
rc = odp_pktio_mac_addr(pktio, &src_mac,
@@ -547,6 +573,7 @@ static int open_pktios(void)
ODPH_ERR("odp_pktio_start() failed\n");
return -1;
}
+ pktio_started[1] = true;
} else {
xmt_pktio = pktios[0];
rcv_pktin = pktins[0];
@@ -557,6 +584,7 @@ static int open_pktios(void)
ODPH_ERR("odp_pktio_start() failed\n");
return -1;
}
+ pktio_started[0] = true;
/* Now wait until the link or links are up. */
rc = wait_linkup(pktios[0]);
@@ -1658,12 +1686,26 @@ static int create_tm_system(void)
return -1;
}
+ /* Update dynamic capability flags from created tm system */
+ dynamic_shaper_update = tm_capabilities.dynamic_shaper_update;
+ dynamic_sched_update = tm_capabilities.dynamic_sched_update;
+ dynamic_threshold_update = tm_capabilities.dynamic_threshold_update;
+ dynamic_wred_update = tm_capabilities.dynamic_wred_update;
+
found_odp_tm = odp_tm_find(tm_name, &requirements, &egress);
if ((found_odp_tm == ODP_TM_INVALID) || (found_odp_tm != odp_tm)) {
ODPH_ERR("odp_tm_find() failed\n");
return -1;
}
+ /* Start TM system */
+ CU_ASSERT((rc = odp_tm_start(odp_tm)) == 0);
+ if (rc != 0) {
+ ODPH_ERR("odp_tm_start() failed for tm: %" PRIx64 "\n",
+ odp_tm_to_u64(odp_tm));
+ return -1;
+ }
+
return 0;
}
@@ -2042,11 +2084,16 @@ static int destroy_tm_systems(void)
/* Close/free the TM systems. */
for (idx = 0; idx < num_odp_tm_systems; idx++) {
+ if (odp_tm_stop(odp_tm_systems[idx]) != 0)
+ return -1;
+
if (destroy_tm_subtree(root_node_descs[idx]) != 0)
return -1;
if (odp_tm_destroy(odp_tm_systems[idx]) != 0)
return -1;
+
+ odp_tm_systems[idx] = ODP_TM_INVALID;
}
/* Close/free the TM profiles. */
@@ -2058,7 +2105,9 @@ static int destroy_tm_systems(void)
static int traffic_mngr_suite_init(void)
{
+ odp_tm_capabilities_t capabilities_array[MAX_CAPABILITIES];
uint32_t payload_len, copy_len;
+ int ret, i;
/* Initialize some global variables. */
num_pkts_made = 0;
@@ -2094,9 +2143,45 @@ static int traffic_mngr_suite_init(void)
iface_name[0], iface_name[1]);
}
- if (open_pktios() != 0)
+ pktios[0] = ODP_PKTIO_INVALID;
+ pktios[1] = ODP_PKTIO_INVALID;
+
+ ret = open_pktios();
+ if (ret < 0)
+ return -1;
+
+ /* Positive return indicates, that pktio open failed with out mode as TM
+ * but succeeded with direct mode.
+ */
+ if (ret > 0)
+ goto skip_tests;
+
+ /* Fetch initial dynamic update capabilities, it will be updated
+ * later after TM system is created.
+ */
+ ret = odp_tm_capabilities(capabilities_array, MAX_CAPABILITIES);
+ if (ret <= 0)
return -1;
+ for (i = 0; i < ret; i++) {
+ if (!capabilities_array[i].dynamic_shaper_update)
+ dynamic_shaper_update = false;
+
+ if (!capabilities_array[i].dynamic_sched_update)
+ dynamic_sched_update = false;
+
+ if (!capabilities_array[i].dynamic_threshold_update)
+ dynamic_threshold_update = false;
+
+ if (!capabilities_array[i].dynamic_wred_update)
+ dynamic_wred_update = false;
+ }
+
+ return 0;
+skip_tests:
+ /* Mark all tests as inactive under this suite */
+ odp_cunit_set_inactive();
+ suite_inactive++;
return 0;
}
@@ -2107,14 +2192,22 @@ static int traffic_mngr_suite_term(void)
/* Close the pktios and associated packet pools. */
free_rcvd_pkts();
for (iface = 0; iface < num_ifaces; iface++) {
- if (odp_pktio_stop(pktios[iface]) != 0)
- return -1;
+ /* Skip pktios not initialized */
+ if (pktios[iface] != ODP_PKTIO_INVALID) {
+ if (pktio_started[iface] &&
+ odp_pktio_stop(pktios[iface]) != 0)
+ return -1;
- if (odp_pktio_close(pktios[iface]) != 0)
- return -1;
+ if (odp_pktio_close(pktios[iface]) != 0)
+ return -1;
+ pktios[iface] = ODP_PKTIO_INVALID;
+ pktio_started[iface] = false;
+ }
if (odp_pool_destroy(pools[iface]) != 0)
return -1;
+
+ pools[iface] = ODP_POOL_INVALID;
}
if (odp_cunit_print_inactive())
@@ -2138,9 +2231,9 @@ static void check_shaper_profile(char *shaper_name, uint32_t shaper_idx)
memset(&shaper_params, 0, sizeof(shaper_params));
rc = odp_tm_shaper_params_read(profile, &shaper_params);
CU_ASSERT(rc == 0);
- CU_ASSERT(approx_eq64(shaper_params.commit_bps,
+ CU_ASSERT(approx_eq64(shaper_params.commit_rate,
shaper_idx * MIN_COMMIT_BW));
- CU_ASSERT(approx_eq64(shaper_params.peak_bps,
+ CU_ASSERT(approx_eq64(shaper_params.peak_rate,
shaper_idx * MIN_PEAK_BW));
CU_ASSERT(approx_eq32(shaper_params.commit_burst,
shaper_idx * MIN_COMMIT_BURST));
@@ -2165,8 +2258,8 @@ static void traffic_mngr_test_shaper_profile(void)
for (idx = 1; idx <= NUM_SHAPER_TEST_PROFILES; idx++) {
snprintf(shaper_name, sizeof(shaper_name),
"shaper_profile_%" PRIu32, idx);
- shaper_params.commit_bps = idx * MIN_COMMIT_BW;
- shaper_params.peak_bps = idx * MIN_PEAK_BW;
+ shaper_params.commit_rate = idx * MIN_COMMIT_BW;
+ shaper_params.peak_rate = idx * MIN_PEAK_BW;
shaper_params.commit_burst = idx * MIN_COMMIT_BURST;
shaper_params.peak_burst = idx * MIN_PEAK_BURST;
@@ -2415,6 +2508,7 @@ static int set_shaper(const char *node_name,
odp_tm_shaper_params_t shaper_params;
odp_tm_shaper_t shaper_profile;
odp_tm_node_t tm_node;
+ int rc;
tm_node = find_tm_node(0, node_name);
if (tm_node == ODP_TM_INVALID) {
@@ -2424,13 +2518,20 @@ static int set_shaper(const char *node_name,
}
odp_tm_shaper_params_init(&shaper_params);
- shaper_params.commit_bps = commit_bps;
- shaper_params.peak_bps = 0;
+ shaper_params.commit_rate = commit_bps;
+ shaper_params.peak_rate = 0;
shaper_params.commit_burst = commit_burst_in_bits;
shaper_params.peak_burst = 0;
shaper_params.shaper_len_adjust = 0;
shaper_params.dual_rate = 0;
+ if (!dynamic_shaper_update) {
+ /* Stop TM system before update when dynamic update is not
+ * supported.
+ */
+ CU_ASSERT_FATAL(odp_tm_stop(odp_tm_systems[0]) == 0);
+ }
+
/* First see if a shaper profile already exists with this name, in
* which case we use that profile, else create a new one. */
shaper_profile = odp_tm_shaper_lookup(shaper_name);
@@ -2443,7 +2544,13 @@ static int set_shaper(const char *node_name,
num_shaper_profiles++;
}
- return odp_tm_node_shaper_config(tm_node, shaper_profile);
+ rc = odp_tm_node_shaper_config(tm_node, shaper_profile);
+
+ if (!dynamic_shaper_update) {
+ /* Start TM system, post update */
+ CU_ASSERT_FATAL(odp_tm_start(odp_tm_systems[0]) == 0);
+ }
+ return rc;
}
static int traffic_mngr_check_shaper(void)
@@ -2617,6 +2724,13 @@ static int set_sched_fanin(const char *node_name,
if (node_desc == NULL)
return -1;
+ if (!dynamic_sched_update) {
+ /* Stop TM system before update when dynamic update is not
+ * supported.
+ */
+ CU_ASSERT_FATAL(odp_tm_stop(odp_tm_systems[0]) == 0);
+ }
+
fanin_cnt = MIN(node_desc->num_children, FANIN_RATIO);
for (fanin = 0; fanin < fanin_cnt; fanin++) {
odp_tm_sched_params_init(&sched_params);
@@ -2653,10 +2767,15 @@ static int set_sched_fanin(const char *node_name,
rc = odp_tm_node_sched_config(tm_node, fanin_node,
sched_profile);
if (rc != 0)
- return -1;
+ goto exit;
}
- return 0;
+exit:
+ if (!dynamic_sched_update) {
+ /* Start TM system, post update */
+ CU_ASSERT_FATAL(odp_tm_start(odp_tm_systems[0]) == 0);
+ }
+ return rc;
}
static int test_sched_queue_priority(const char *shaper_name,
@@ -2711,8 +2830,13 @@ static int test_sched_queue_priority(const char *shaper_name,
busy_wait(100 * ODP_TIME_MSEC_IN_NS);
- /* Disable the shaper, so as to get the pkts out quicker. */
- set_shaper(node_name, shaper_name, 0, 0);
+ /* Disable the shaper, so as to get the pkts out quicker.
+ * We cannot do this if dynamic shaper update is not supported. Without
+ * dynamic update support set_shaper() can cause packet drops due to
+ * start/stop.
+ */
+ if (dynamic_shaper_update)
+ set_shaper(node_name, shaper_name, 0, 0);
num_rcv_pkts = receive_pkts(odp_tm_systems[0], rcv_pktin,
pkt_cnt + 4, 64 * 1000);
@@ -2730,6 +2854,8 @@ static int test_sched_queue_priority(const char *shaper_name,
CU_ASSERT(pkts_in_order == pkt_cnt);
+ /* Disable shaper in case it is still enabled */
+ set_shaper(node_name, shaper_name, 0, 0);
flush_leftover_pkts(odp_tm_systems[0], rcv_pktin);
CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0]));
return 0;
@@ -2817,8 +2943,13 @@ static int test_sched_node_priority(const char *shaper_name,
busy_wait(100 * ODP_TIME_MSEC_IN_NS);
- /* Disable the shaper, so as to get the pkts out quicker. */
- set_shaper(node_name, shaper_name, 0, 0);
+ /* Disable the shaper, so as to get the pkts out quicker.
+ * We cannot do this if dynamic shaper update is not supported. Without
+ * dynamic update support set_shaper() can cause packet drops due to
+ * start/stop.
+ */
+ if (dynamic_shaper_update)
+ set_shaper(node_name, shaper_name, 0, 0);
num_rcv_pkts = receive_pkts(odp_tm_systems[0], rcv_pktin,
pkts_sent, 64 * 1000);
@@ -2830,6 +2961,8 @@ static int test_sched_node_priority(const char *shaper_name,
0, false, false);
CU_ASSERT(pkts_in_order == total_pkt_cnt);
+ /* Disable shaper in case it is still enabled */
+ set_shaper(node_name, shaper_name, 0, 0);
flush_leftover_pkts(odp_tm_systems[0], rcv_pktin);
CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0]));
return 0;
@@ -2910,8 +3043,13 @@ static int test_sched_wfq(const char *sched_base_name,
busy_wait(1000000); /* wait 1 millisecond */
- /* Disable the shaper, so as to get the pkts out quicker. */
- set_shaper(node_name, shaper_name, 0, 0);
+ /* Disable the shaper, so as to get the pkts out quicker.
+ * We cannot do this if dynamic shaper update is not supported. Without
+ * dynamic update support set_shaper() can cause packet drops due to
+ * start/stop.
+ */
+ if (dynamic_shaper_update)
+ set_shaper(node_name, shaper_name, 0, 0);
num_rcv_pkts = receive_pkts(odp_tm_systems[0], rcv_pktin,
pkt_cnt + 4, 64 * 1000);
@@ -2923,6 +3061,8 @@ static int test_sched_wfq(const char *sched_base_name,
CU_ASSERT(rcv_rate_stats(&rcv_stats[fanin], pkt_class) == 0);
}
+ /* Disable shaper in case it is still enabled */
+ set_shaper(node_name, shaper_name, 0, 0);
flush_leftover_pkts(odp_tm_systems[0], rcv_pktin);
CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0]));
return 0;
@@ -2935,6 +3075,13 @@ static int set_queue_thresholds(odp_tm_queue_t tm_queue,
odp_tm_threshold_t threshold_profile;
int ret;
+ if (!dynamic_threshold_update) {
+ /* Stop TM system before update when dynamic update is not
+ * supported.
+ */
+ CU_ASSERT_FATAL(odp_tm_stop(odp_tm_systems[0]) == 0);
+ }
+
/* First see if a threshold profile already exists with this name, in
* which case we use that profile, else create a new one. */
threshold_profile = odp_tm_thresholds_lookup(threshold_name);
@@ -2942,17 +3089,25 @@ static int set_queue_thresholds(odp_tm_queue_t tm_queue,
ret = odp_tm_thresholds_params_update(threshold_profile,
threshold_params);
if (ret)
- return ret;
+ goto exit;
} else {
threshold_profile = odp_tm_threshold_create(threshold_name,
threshold_params);
- if (threshold_profile == ODP_TM_INVALID)
- return -1;
+ if (threshold_profile == ODP_TM_INVALID) {
+ ret = -1;
+ goto exit;
+ }
threshold_profiles[num_threshold_profiles] = threshold_profile;
num_threshold_profiles++;
}
- return odp_tm_queue_threshold_config(tm_queue, threshold_profile);
+ ret = odp_tm_queue_threshold_config(tm_queue, threshold_profile);
+exit:
+ if (!dynamic_threshold_update) {
+ /* Start TM system, post update */
+ CU_ASSERT_FATAL(odp_tm_start(odp_tm_systems[0]) == 0);
+ }
+ return ret;
}
static int test_threshold(const char *threshold_name,
@@ -3049,6 +3204,7 @@ static int set_queue_wred(odp_tm_queue_t tm_queue,
{
odp_tm_wred_params_t wred_params;
odp_tm_wred_t wred_profile;
+ int rc;
odp_tm_wred_params_init(&wred_params);
if (use_dual_slope) {
@@ -3066,6 +3222,13 @@ static int set_queue_wred(odp_tm_queue_t tm_queue,
wred_params.enable_wred = true;
wred_params.use_byte_fullness = use_byte_fullness;
+ if (!dynamic_wred_update) {
+ /* Stop TM system before update when dynamic update is not
+ * supported.
+ */
+ CU_ASSERT_FATAL(odp_tm_stop(odp_tm_systems[0]) == 0);
+ }
+
/* First see if a wred profile already exists with this name, in
* which case we use that profile, else create a new one. */
wred_profile = odp_tm_wred_lookup(wred_name);
@@ -3084,7 +3247,14 @@ static int set_queue_wred(odp_tm_queue_t tm_queue,
}
}
- return odp_tm_queue_wred_config(tm_queue, pkt_color, wred_profile);
+ rc = odp_tm_queue_wred_config(tm_queue, pkt_color, wred_profile);
+
+ if (!dynamic_wred_update) {
+ /* Start TM system, post update */
+ CU_ASSERT_FATAL(odp_tm_start(odp_tm_systems[0]) == 0);
+ }
+ return rc;
+
}
static int test_byte_wred(const char *wred_name,
@@ -3149,8 +3319,14 @@ static int test_byte_wred(const char *wred_name,
pkts_sent = send_pkts(tm_queue, num_test_pkts);
- /* Disable the shaper, so as to get the pkts out quicker. */
- set_shaper(node_name, shaper_name, 0, 0);
+ /* Disable the shaper, so as to get the pkts out quicker.
+ * We cannot do this if dynamic shaper update is not supported. Without
+ * dynamic update support set_shaper() can cause packet drops due to
+ * start/stop.
+ */
+ if (dynamic_shaper_update)
+ set_shaper(node_name, shaper_name, 0, 0);
+
num_rcv_pkts = receive_pkts(odp_tm_systems[0], rcv_pktin,
num_fill_pkts + pkts_sent, 64 * 1000);
@@ -3160,6 +3336,8 @@ static int test_byte_wred(const char *wred_name,
if (wred_pkt_cnts == NULL)
return -1;
+ /* Disable shaper in case it is still enabled */
+ set_shaper(node_name, shaper_name, 0, 0);
flush_leftover_pkts(odp_tm_systems[0], rcv_pktin);
CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0]));
@@ -3234,8 +3412,14 @@ static int test_pkt_wred(const char *wred_name,
pkts_sent = send_pkts(tm_queue, num_test_pkts);
- /* Disable the shaper, so as to get the pkts out quicker. */
- set_shaper(node_name, shaper_name, 0, 0);
+ /* Disable the shaper, so as to get the pkts out quicker.
+ * We cannot do this if dynamic shaper update is not supported. Without
+ * dynamic update support set_shaper() can cause packet drops due to
+ * start/stop.
+ */
+ if (dynamic_shaper_update)
+ set_shaper(node_name, shaper_name, 0, 0);
+
ret = receive_pkts(odp_tm_systems[0], rcv_pktin,
num_fill_pkts + pkts_sent, 64 * 1000);
if (ret < 0)
@@ -3249,6 +3433,8 @@ static int test_pkt_wred(const char *wred_name,
if (wred_pkt_cnts == NULL)
return -1;
+ /* Disable shaper in case it is still enabled */
+ set_shaper(node_name, shaper_name, 0, 0);
flush_leftover_pkts(odp_tm_systems[0], rcv_pktin);
CU_ASSERT(odp_tm_is_idle(odp_tm_systems[0]));
@@ -4099,5 +4285,8 @@ int main(int argc, char *argv[])
if (ret == 0)
ret = odp_cunit_run();
+ /* Exit with 77 in order to indicate that test is skipped completely */
+ if (!ret && suite_inactive == (ARRAY_SIZE(traffic_mngr_suites) - 1))
+ return 77;
return ret;
}