diff options
90 files changed, 3841 insertions, 1143 deletions
diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index f21f85a03..c3109ff2c 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -29,7 +29,7 @@ jobs: run: | AFTER=${{ github.event.after }} BEFORE=${{ github.event.before }} - if [ -z "${BEFORE}" ] || [ -z "${AFTER}" ]; then + if [ -z "${BEFORE//0}" ] || [ -z "${AFTER//0}" ]; then COMMIT_RANGE="" else COMMIT_RANGE="${BEFORE}..${AFTER}" @@ -66,12 +66,12 @@ jobs: fail-fast: false matrix: cc: [gcc, clang] - conf: ['', 'CFLAGS=-O3', 'CFLAGS=-O1', 'CFLAGS=-O0 --enable-debug=full', '--enable-lto', '--enable-lto --disable-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' - cc: clang - conf: '--enable-lto --disable-abi-compat' + conf: '--enable-lto --enable-abi-compat' steps: - uses: actions/checkout@v2 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" @@ -92,9 +92,9 @@ jobs: run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh - - name: --disable-abi-compat + - name: --enable-abi-compat env: - CONF: "--disable-abi-compat" + CONF: "--enable-abi-compat" run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e CONF="${CONF}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh @@ -112,7 +112,8 @@ jobs: strategy: fail-fast: false matrix: - conf: ['', '--disable-abi-compat'] + cc: [gcc, clang] + conf: ['', '--enable-abi-compat'] steps: - uses: actions/checkout@v2 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${CC}" @@ -126,7 +127,7 @@ jobs: fail-fast: false matrix: cc: [gcc, clang] - conf: ['', '--disable-abi-compat'] + conf: ['', '--enable-abi-compat'] steps: - uses: actions/checkout@v2 - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" @@ -141,10 +142,11 @@ jobs: matrix: cc: [gcc, clang] os: ['centos_7', 'centos_8', 'ubuntu_16.04'] + conf: ['--enable-abi-compat'] steps: - 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} /odp/scripts/ci/build_${ARCH}.sh + -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${{matrix.os}}-${ARCH} /odp/scripts/ci/build_${ARCH}.sh Build_gcc-10: runs-on: ubuntu-18.04 @@ -202,7 +204,7 @@ jobs: strategy: fail-fast: false matrix: - conf: ['--enable-user-guides', '--enable-user-guides --disable-abi-compat'] + conf: ['--enable-user-guides', '--enable-user-guides --enable-abi-compat'] steps: - uses: actions/checkout@v2 # Ignore distcheck failure (caused by the first 'make check' run unmounting huge pages) @@ -220,7 +222,7 @@ jobs: fail-fast: false matrix: cc: [gcc, clang] - conf: ['', '--disable-abi-compat', '--enable-deprecated', '--disable-static-applications', '--disable-host-optimization', '--disable-host-optimization --disable-abi-compat', '--without-openssl --without-pcap'] + conf: ['', '--enable-abi-compat', '--enable-deprecated', '--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}}" @@ -1,21 +1,47 @@ +== OpenDataPlane (1.29.0.0) +=== API +==== Packet IO +* Modified statistics counters (`odp_pktio_stats_t`) definitions +* Deprecated statistics counter `odp_pktio_stats_t.in_unknown_protos` +* New `odp_pktio_stats_t.in_packets` and `odp_pktio_stats_t.out_packets` +statistics counters +* New APIs for packet input inline IP reassembly offload + +==== Packet +* New `odp_packet_reass_status()` function added for checking packet reassembly +status +* New `odp_packet_reass_partial_state()` function added for reading packet +partial reassembly state + +==== IPsec +* New APIs for inline IP reassembly offload + +==== Init +* New `odp_log_thread_fn_set()` function added for setting a thread specific log +function + +=== Implementation +* ABI compatibility default value has been changed to disabled. User can enable +ABI compatibility with `--enable-abi-compat` configure option. + == OpenDataPlane (1.28.0.0) === API ==== Crypto * New crypto capabilities for defining if a queue type (scheduled/plain) can be used as a crypto completion event destination -=== Event +==== Event * New packet TX completion event type and related functions -=== Packet +==== Packet * New packet APIs for requesting packet TX completion events -* New packet APIS for requesting packet TX drop based on packet age +* New packet APIs for requesting packet TX drop based on packet age -=== Classifier +==== Classifier * New `odp_cls_print_all()` function for printing implementation specific debug information about all classifier rules -=== System +==== System * New enumerations for ARMv8.7-A, ARMv9.0-A, ARMv9.1-A, and ARMv9.2-A ISA versions diff --git a/configure.ac b/configure.ac index f92195772..e84cb3297 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], [28]) +m4_define([odpapi_major_version], [29]) m4_define([odpapi_minor_version], [0]) m4_define([odpapi_point_version], [0]) m4_define([odpapi_version], @@ -226,27 +226,28 @@ AC_SUBST(PKGCONFIG_VERSION) ########################################################################## # Enable/disable ABI compatible build ########################################################################## -ODP_ABI_COMPAT=1 -abi_compat=yes +ODP_ABI_COMPAT=0 +abi_compat=no AC_ARG_ENABLE([abi-compat], - [AS_HELP_STRING([--disable-abi-compat], - [disables ABI compatible mode, enables inline code in header files] - [[default=enabled]])], - [if test "x$enableval" = "xno"; then - ODP_ABI_COMPAT=0 - abi_compat=no - - #if there is no ABI compatibility the .so numbers are meaningless + [AS_HELP_STRING([--enable-abi-compat], + [enables ABI compatible mode, disables inline code in header files] + [[default=disabled]])], + [if test "x$enableval" = "xyes"; then + ODP_ABI_COMPAT=1 + abi_compat=yes + fi]) +if test "x$abi_compat" = "xno" ; then + # If there is no ABI compatibility the .so numbers are meaningless ODP_LIBSO_VERSION=0:0:0 - # do not use -march=native with clang (due to possible failures on + # Do not use -march=native with clang (due to possible failures on # clang optimizations). $CC --version | grep -q clang if test $? -ne 0; then ODP_CHECK_CFLAG([-march=native]) fi - fi]) +fi AM_CONDITIONAL(ODP_ABI_COMPAT, [test "x$ODP_ABI_COMPAT" = "x1"]) ########################################################################## diff --git a/doc/implementers-guide/implementers-guide.adoc b/doc/implementers-guide/implementers-guide.adoc index 6e1130b1a..9bc8d8b13 100644 --- a/doc/implementers-guide/implementers-guide.adoc +++ b/doc/implementers-guide/implementers-guide.adoc @@ -760,8 +760,8 @@ debugging easier. By default, building ODP only builds the code. When this option is specified, the supporting user documentation (including this file) is also built. -`--disable-abi-compat`:: -By default ODP builds with support for the ODP ABI, which permits application +`--enable-abi-compat`:: +Enable ABI compatible ODP build, which permits application binary portability across different ODP implementations targeting the same Instruction Set Architecture (ISA). While this is useful in cloud/host environments, it does involve some performance cost to provide binary diff --git a/doc/users-guide/users-guide.adoc b/doc/users-guide/users-guide.adoc index 56ce3a624..ecaf70022 100644 --- a/doc/users-guide/users-guide.adoc +++ b/doc/users-guide/users-guide.adoc @@ -704,7 +704,7 @@ Embedded applications will typically work with a copy of ODP downloaded from a git repository so that it can be configured for the application's precise needs. To specify that the application wishes to use the embedded profile: -`./configure --enable-abi-compat=no ...` +`./configure --disable-abi-compat ...` should be used as part of the ODP configuration options. This allows applications to use inline forms of ODP APIs to give optimal performance @@ -724,11 +724,7 @@ that is installed via `sudo apt-get install` or equivalent command). When using a copy of ODP downloaded from a repository, the cloud profile is selected at configure time: -`./configure --enable-abi-compat=yes ...` - -Note that `--enable-abi-compat=yes` is the default, so this need not be -specified. Unless `no` is specified for this option, the result will be -applications designed to run in the cloud profile. +`./configure --enable-abi-compat ...` === ABI Characteristics An ABI consists of several conventions that ensure that a program compiled diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index a6c8dc73f..ddb2ccfd5 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -253,7 +253,7 @@ static void print_usage(void) * @param argv Argument vector * @param args Test arguments */ -static void parse_args(int argc, char *argv[], test_args_t *args) +static int parse_args(int argc, char *argv[], test_args_t *args) { int opt; int long_index; @@ -273,7 +273,8 @@ static void parse_args(int argc, char *argv[], test_args_t *args) static const char *shortopts = "+c:r:m:x:p:t:h"; /* defaults */ - odp_timer_capability(ODP_CLOCK_CPU, &timer_capa); + if (odp_timer_capability(ODP_CLOCK_CPU, &timer_capa)) + return -1; args->cpu_count = 1; args->resolution_us = MAX(10000, @@ -321,8 +322,9 @@ static void parse_args(int argc, char *argv[], test_args_t *args) if (args->period_us < args->resolution_us) printf("\n\tWarn: timeout is set less then resolution\n"); -} + return 0; +} /** * Test main function @@ -394,7 +396,10 @@ int main(int argc, char *argv[]) gbls->pool = ODP_POOL_INVALID; gbls->tp = ODP_TIMER_POOL_INVALID; - parse_args(argc, argv, &gbls->args); + if (parse_args(argc, argv, &gbls->args)) { + ODPH_ERR("Parse args failed.\n"); + goto err; + } memset(thread_tbl, 0, sizeof(thread_tbl)); diff --git a/helper/cli.c b/helper/cli.c index 3aee88aaa..dd4b5fe4f 100644 --- a/helper/cli.c +++ b/helper/cli.c @@ -15,6 +15,7 @@ #include <unistd.h> #include <errno.h> #include <poll.h> +#include <stdio.h> /* Socketpair socket roles. */ enum { @@ -264,6 +265,90 @@ static struct cli_def *create_cli(void) return cli; } +/* Not shared, used only in the server thread. */ +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, ...) +{ + (void)level; + + va_list args; + char *str, *p, *last; + int len; + + /* + * This function should be just a simple call to cli_vabufprint(). + * Unfortunately libcli (at least versions 1.9.7 - 1.10.4) has a few + * bugs. cli_print() prints a newline at the end even if the string + * doesn't end in a newline. cli_*bufprint() on the other hand just + * throws away everything after the last newline. + * + * The following code ensures that each cli_*print() ends in a newline. + * 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); + len = vsnprintf(NULL, 0, fmt, args) + 1; + va_end(args); + str = malloc(len); + + if (!str) { + ODPH_ERR("malloc failed"); + return 0; + } + + va_start(args, fmt); + vsnprintf(str, len, fmt, args); + va_end(args); + p = str; + last = strrchr(p, '\n'); + + if (last) { + *last++ = 0; + if (cli_log_fn_buf) { + cli_bufprint(cli, "%s%s\n", cli_log_fn_buf, p); + free(cli_log_fn_buf); + cli_log_fn_buf = NULL; + } else { + cli_bufprint(cli, "%s\n", p); + } + p = last; + } + + if (*p) { + if (cli_log_fn_buf) { + char *buffer_new = + malloc(strlen(cli_log_fn_buf) + strlen(p) + 1); + + if (!buffer_new) { + ODPH_ERR("malloc failed"); + goto out; + } + + strcpy(buffer_new, cli_log_fn_buf); + strcat(buffer_new, p); + free(cli_log_fn_buf); + cli_log_fn_buf = buffer_new; + } else { + cli_log_fn_buf = malloc(strlen(p) + 1); + + if (!cli_log_fn_buf) { + ODPH_ERR("malloc failed"); + goto out; + } + + strcpy(cli_log_fn_buf, p); + } + } + +out: + free(str); + + return 0; +} + static int cli_server(void *arg ODP_UNUSED) { cli_shm_t *shm = NULL; @@ -277,7 +362,7 @@ static int cli_server(void *arg ODP_UNUSED) return -1; } - struct cli_def *cli = create_cli(); + cli = create_cli(); while (1) { struct pollfd pfd[2] = { @@ -326,12 +411,21 @@ static int cli_server(void *arg ODP_UNUSED) } shm->cli_fd = fd; odp_spinlock_unlock(&shm->lock); + odp_log_thread_fn_set(cli_log_fn); /* * 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); + + /* + * Throw away anything left in the buffer (in case the last + * print didn't end in a newline). + */ + free(cli_log_fn_buf); + cli_log_fn_buf = NULL; } cli_done(cli); diff --git a/helper/test/linux/process.c b/helper/test/linux/process.c index f57b5ab8a..8d3f31af0 100644 --- a/helper/test/linux/process.c +++ b/helper/test/linux/process.c @@ -82,10 +82,20 @@ int main(int argc ODP_UNUSED, char *argv[] ODP_UNUSED) if (ret == 0) { /* Child process */ worker_fn(NULL); + + if (odp_term_local() < 0) { + ODPH_ERR("Error: ODP local term failed.\n"); + exit(EXIT_FAILURE); + } } else { /* Parent process */ odph_linux_process_wait_n(proc, num_workers); + if (odp_term_local()) { + ODPH_ERR("Error: ODP local term failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_global(instance)) { ODPH_ERR("Error: ODP global term failed.\n"); exit(EXIT_FAILURE); diff --git a/include/Makefile.am b/include/Makefile.am index 911cd92f9..98cb9117f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -38,6 +38,7 @@ odpapiinclude_HEADERS = \ odp/api/pool.h \ odp/api/queue.h \ odp/api/random.h \ + odp/api/reassembly.h \ odp/api/rwlock.h \ odp/api/rwlock_recursive.h \ odp/api/schedule.h \ @@ -90,6 +91,7 @@ odpapispecinclude_HEADERS = \ odp/api/spec/queue.h \ odp/api/spec/queue_types.h \ odp/api/spec/random.h \ + odp/api/spec/reassembly.h \ odp/api/spec/rwlock.h \ odp/api/spec/rwlock_recursive.h \ odp/api/spec/schedule.h \ diff --git a/include/odp/api/reassembly.h b/include/odp/api/reassembly.h new file mode 100644 index 000000000..153fd6a12 --- /dev/null +++ b/include/odp/api/reassembly.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2021, Marvell + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP REASSEMBLY API - platform specific header + */ + +#ifndef ODP_API_REASSEMBLY_H_ +#define ODP_API_REASSEMBLY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/api/spec/reassembly.h> + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spec/init.h b/include/odp/api/spec/init.h index 73fd3e2b3..d52ac50b6 100644 --- a/include/odp/api/spec/init.h +++ b/include/odp/api/spec/init.h @@ -20,7 +20,7 @@ extern "C" { #include <odp/api/std_types.h> #include <odp/api/hints.h> #include <odp/api/feature.h> -#include <odp/api/thread.h> +#include <odp/api/spec/thread_types.h> #include <odp/api/cpumask.h> /** @defgroup odp_initialization ODP INITIALIZATION @@ -333,6 +333,20 @@ int odp_term_local(void); int odp_term_global(odp_instance_t instance); /** + * Set thread specific log function + * + * By default, all ODP log writes use the global log function, which may be set + * as part of odp_init_t. Using this operation, an alternative ODP log function + * may be set for the calling thread. When set, ODP uses the thread specific log + * function for all log writes originating from ODP API calls made by the + * calling thread. Setting the log function to NULL causes the calling thread to + * use the global log function. + * + * @param func Log function + */ +void odp_log_thread_fn_set(odp_log_func_t func); + +/** * @} */ diff --git a/include/odp/api/spec/ipsec.h b/include/odp/api/spec/ipsec.h index d1856432b..5c4ee03ab 100644 --- a/include/odp/api/spec/ipsec.h +++ b/include/odp/api/spec/ipsec.h @@ -191,6 +191,25 @@ typedef struct odp_ipsec_inbound_config_t { */ odp_proto_chksums_t chksums; + /** Post-IPsec reassembly configuration + * + * This field provides global IPsec configuration parameters for + * fragment reassembly. The enable flag does not turn on reassembly + * but tells if reassembly may be enabled in SA parameters. + * + * The enable flag may be set only if retain_outer is + * ODP_PROTO_LAYER_NONE. + */ + odp_reass_config_t reassembly; + + /** Attempt reassembly after inbound IPsec processing in + * odp_ipsec_in_enq(). + */ + odp_bool_t reass_async; + + /** Attempt reassembly after inline inbound IPsec processing. */ + odp_bool_t reass_inline; + } odp_ipsec_inbound_config_t; /** @@ -343,6 +362,16 @@ typedef struct odp_ipsec_capability_t { * @see odp_ipsec_test_sa_update() */ odp_ipsec_test_capability_t test; + + /** Post-IPsec reassembly capability */ + odp_reass_capability_t reassembly; + + /** Support of reassembly after inbound processing in odp_ipsec_in_enq() */ + odp_bool_t reass_async; + + /** Support of reassembly after inline inbound IPsec processing */ + odp_bool_t reass_inline; + } odp_ipsec_capability_t; /** @@ -832,6 +861,30 @@ typedef struct odp_ipsec_sa_param_t { */ odp_cos_t dest_cos; + /** Enable reassembly of IPsec tunneled fragments + * + * Attempt reassembly of fragments after IPsec tunnel + * decapsulation. + * + * Reassembly is attempted for inline or asynchronously + * processed packets, not for packets processed using + * the synchronous API function. + * + * Fragments received through different SAs will not be + * reassembled into the same packet. + * + * IPsec statistics reflect IPsec processing before + * reassembly and thus count all individual fragments. + * + * Reassembly may be enabled for an SA only if + * reassembly was enabled in the global IPsec + * configuration. + * + * @see odp_ipsec_config() + * + */ + odp_bool_t reassembly_en; + } inbound; /** Outbound specific parameters */ @@ -1664,6 +1717,14 @@ int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in, * once before packet data or metadata (other than packet type and subtype) * may be accessed. * + * If reassembly is attempted but fails, the result packet delivered to the + * application will have reassembly status as ODP_PACKET_REASS_INCOMPLETE and + * will not have ODP_EVENT_PACKET_IPSEC subtype. In that case, the application + * can call odp_packet_reass_partial_state() to get fragments of the packet. The + * fragments will have subtype as ODP_EVENT_PACKET_IPSEC and the application + * must call odp_ipsec_result() for such a fragment before accessing its packet + * data. + * * @param pkt Packets to be processed * @param num Number of packets to be processed * @param param Inbound operation parameters diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index d973b26a5..eef7bae8a 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -249,6 +249,37 @@ typedef struct odp_packet_data_range { } odp_packet_data_range_t; /** + * Reassembly status of a packet + */ +typedef enum odp_packet_reass_status_t { + /** Reassembly was not attempted */ + ODP_PACKET_REASS_NONE = 0, + + /** Reassembly was attempted but is incomplete. Partial reassembly + * result can be accessed using ``odp_packet_reass_partial_state()``. + * + * The packet does not contain valid packet data and cannot be used + * in normal packet operations. + */ + ODP_PACKET_REASS_INCOMPLETE, + + /** Reassembly was successfully done. The packet has been + * reassembled from multiple received fragments. */ + ODP_PACKET_REASS_COMPLETE, +} odp_packet_reass_status_t; + +/** + * Result from odp_packet_reass_partial_state() + */ +typedef struct odp_packet_reass_partial_state_t { + /** Number of fragments returned */ + uint16_t num_frags; + + /** Time, in ns, since the reception of the first received fragment */ + uint64_t elapsed_time; +} odp_packet_reass_partial_state_t; + +/** * Event subtype of a packet * * Returns the subtype of a packet event. Subtype tells if the packet contains @@ -399,6 +430,29 @@ odp_event_t odp_packet_to_event(odp_packet_t pkt); void odp_packet_to_event_multi(const odp_packet_t pkt[], odp_event_t ev[], int num); +/** + * Get partial reassembly state from a packet + * + * In case of incomplete reassembly, a packet carries information on + * the time already used for the reassembly attempt and one or more + * fragments. The fragments are not necessarily the original received + * fragments but may be partially reassembled parts of the packet. + * + * This function may be called only if the reassembly status of a packet + * is ODP_PACKET_REASS_INCOMPLETE. + * + * @param pkt Incompletely reassembled packet. The packet will + * be consumed if the function succeeds. + * @param[out] frags Packet handle array for output. The size of this array must + * be at least `odp_reass_config_t::max_num_frags`. + * @param[out] res Pointer to result structure + * + * @retval 0 on success + * @retval <0 on failure + */ +int odp_packet_reass_partial_state(odp_packet_t pkt, odp_packet_t frags[], + odp_packet_reass_partial_state_t *res); + /* * * Pointers and lengths @@ -2411,6 +2465,15 @@ void odp_packet_vector_print(odp_packet_vector_t pktv); */ uint64_t odp_packet_vector_to_u64(odp_packet_vector_t hdl); +/** + * Check reassembly status of the packet + * + * @param pkt Packet handle + * @return Reassembly status + * + */ +odp_packet_reass_status_t odp_packet_reass_status(odp_packet_t pkt); + /* * * Packet Tx completion event handling routines diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index 03b7d094a..fcb0a39c3 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -22,6 +22,7 @@ extern "C" { #include <odp/api/deprecated.h> #include <odp/api/packet_io_stats.h> #include <odp/api/queue.h> +#include <odp/api/reassembly.h> #include <odp/api/time.h> #include <odp/api/packet.h> @@ -633,6 +634,9 @@ typedef struct odp_pktio_config_t { */ odp_bool_t enable_lso; + /** Packet input reassembly configuration */ + odp_reass_config_t reassembly; + } odp_pktio_config_t; /** @@ -901,6 +905,9 @@ typedef struct odp_pktio_capability_t { } tx_compl; + /** Packet input reassembly capability */ + odp_reass_capability_t reassembly; + } odp_pktio_capability_t; /** diff --git a/include/odp/api/spec/packet_io_stats.h b/include/odp/api/spec/packet_io_stats.h index ea41e3a3a..10e74e52f 100644 --- a/include/odp/api/spec/packet_io_stats.h +++ b/include/odp/api/spec/packet_io_stats.h @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2018, Linaro Limited + * Copyright (c) 2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,7 +8,7 @@ /** * @file * - * ODP Packet IO + * ODP Packet IO statistics */ #ifndef ODP_API_SPEC_PACKET_IO_STATS_H_ @@ -18,47 +19,38 @@ extern "C" { #endif +#include <odp/api/deprecated.h> + /** @addtogroup odp_packet_io * @{ */ /** - * Packet IO statistics + * Packet IO statistics counters * - * Packet IO statistics counters follow RFCs for Management Information Base - * (MIB)for use with network management protocols in the Internet community: - * https://tools.ietf.org/html/rfc3635 - * https://tools.ietf.org/html/rfc2863 - * https://tools.ietf.org/html/rfc2819 + * In the counter definitions the term successfully refers to packets which were + * not discarded or detected to contain errors by the packet IO interface. In + * case of Ethernet, it's implementation specific whether valid pause frames are + * included in the counters or not. */ typedef struct odp_pktio_stats_t { - /** - * The number of octets in valid MAC frames received on this interface, - * including the MAC header and FCS. See ifHCInOctets counter - * description in RFC 3635 for details. - */ + /** Number of octets in successfully received packets. In case of + * Ethernet, packet size includes MAC header and FCS. */ uint64_t in_octets; - /** - * The number of packets, delivered by this sub-layer to a higher - * (sub-)layer, which were not addressed to a multicast or broadcast - * address at this sub-layer. See ifHCInUcastPkts in RFC 2863, RFC 3635. - */ + /** Number of successfully received packets. */ + uint64_t in_packets; + + /** Number of successfully received Ethernet packets with a unicast + * destination MAC address. */ uint64_t in_ucast_pkts; - /** - * The number of inbound packets which were chosen to be discarded - * even though no errors had been detected to prevent their being - * deliverable to a higher-layer protocol. One possible reason for - * discarding such a packet could be to free up buffer space. - * See ifInDiscards in RFC 2863. - */ + /** Number of inbound packets which were discarded due to a lack of free + * resources (e.g. buffers) or other reasons than packet errors. */ uint64_t in_discards; - /** - * The sum for this interface of AlignmentErrors, FCSErrors, - * FrameTooLongs, InternalMacReceiveErrors. See ifInErrors in RFC 3635. - */ + /** Number of inbound packets with errors. Depending on packet input + * configuration, packets with errors may be dropped or not. */ uint64_t in_errors; /** @@ -70,64 +62,52 @@ typedef struct odp_pktio_stats_t { * because of an unknown or unsupported protocol. For any interface * that does not support protocol multiplexing, this counter will always * be 0. See ifInUnknownProtos in RFC 2863, RFC 3635. + * + * @deprecated This counter has been deprecated. */ - uint64_t in_unknown_protos; + uint64_t ODP_DEPRECATE(in_unknown_protos); - /** - * The number of octets transmitted in valid MAC frames on this - * interface, including the MAC header and FCS. This does include - * the number of octets in valid MAC Control frames transmitted on - * this interface. See ifHCOutOctets in RFC 3635. - */ + /** Number of octets in successfully transmitted packets. In case of + * Ethernet, packet size includes MAC header and FCS. */ uint64_t out_octets; - /** - * The total number of packets that higher-level protocols requested - * be transmitted, and which were not addressed to a multicast or - * broadcast address at this sub-layer, including those that were - * discarded or not sent. does not include MAC Control frames. - * See ifHCOutUcastPkts RFC 2863, 3635. - */ + /** Number of successfully transmitted packets. */ + uint64_t out_packets; + + /** Number of successfully transmitted Ethernet packets with a unicast + * destination MAC address. */ uint64_t out_ucast_pkts; - /** - * The number of outbound packets which were chosen to be discarded - * even though no errors had been detected to prevent their being - * transmitted. One possible reason for discarding such a packet could - * be to free up buffer space. See OutDiscards in RFC 2863. - */ + /** Number of outbound packets which were discarded due to a lack of + * free resources (e.g. buffers) or other reasons than errors. */ uint64_t out_discards; - /** - * The sum for this interface of SQETestErrors, LateCollisions, - * ExcessiveCollisions, InternalMacTransmitErrors and - * CarrierSenseErrors. See ifOutErrors in RFC 3635. - */ + /** Number of packets with transmission errors. */ uint64_t out_errors; } odp_pktio_stats_t; /** * Get statistics for pktio handle * - * @param pktio Packet IO handle - * @param[out] stats Output buffer for counters + * Counters not supported by the interface are set to zero. + * + * @param pktio Packet IO handle + * @param[out] stats Output buffer for counters + * * @retval 0 on success * @retval <0 on failure - * - * @note: If counter is not supported by platform it has - * to be set to 0. */ -int odp_pktio_stats(odp_pktio_t pktio, - odp_pktio_stats_t *stats); +int odp_pktio_stats(odp_pktio_t pktio, odp_pktio_stats_t *stats); /** * Reset statistics for pktio handle * - * Reset all pktio counters to 0. - * @param pktio Packet IO handle + * Reset all statistics counters to zero. + * + * @param pktio Packet IO handle + * * @retval 0 on success * @retval <0 on failure - * */ int odp_pktio_stats_reset(odp_pktio_t pktio); diff --git a/include/odp/api/spec/reassembly.h b/include/odp/api/spec/reassembly.h new file mode 100644 index 000000000..2609158f5 --- /dev/null +++ b/include/odp/api/spec/reassembly.h @@ -0,0 +1,130 @@ +/* Copyright (c) 2021, Marvell + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP REASSEMBLY API + */ + +#ifndef ODP_API_SPEC_REASSEMBLY_H_ +#define ODP_API_SPEC_REASSEMBLY_H_ +#include <odp/visibility_begin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup odp_reassembly ODP REASSEMBLY + * Reassembly + * @{ + */ + +/** + * Reassembly capabilities + * + */ +typedef struct odp_reass_capability_t { + /** Reassembly offload for both IPv4 and IPv6 packets. This capability + * does not allow enabling reassembly for only IPv4 or only IPv6. + */ + odp_bool_t ip; + + /** Reassembly offload for IPv4 packets */ + odp_bool_t ipv4; + + /** Reassembly offload for IPv6 packets */ + odp_bool_t ipv6; + + /** Maximum time in ns that a fragment can wait in the reassembly + * offload for the arrival of further fragments. + */ + uint64_t max_wait_time; + + /** Maximum number of fragments that can be reassembled */ + uint16_t max_num_frags; + +} odp_reass_capability_t; + +/** + * Fragment reassembly configuration + * + * Configure inline fragment reassembly offload support. Fragment + * reassembly offload can be enabled in IPSEC and PKTIN operations. + * + * When the offload is enabled, fragments will be delayed for a specified time + * period to allow reassembly. + * + * Reassembly result will be delivered to the application through an ODP packet + * with reassembly metadata. odp_packet_reass_status() can be used to query if + * reassembly has been attempted and if reassembly was successfully completed. + * + * In case of successful reassembly, the reassembled packet is delivered + * to the receiver as a regular ODP packet as if the reassembled packet + * was received as such. When reassembly is enabled in pktio, it will be + * attempted before other offloads such as packet parsing, inline IPsec and + * classification. + * + * In case of failed reassembly, the result is delivered to the application + * as a special packet that does not contain valid packet data. Such a + * packet can be used to get information of the incomplete reassembly + * so that the application can try to retry or continue the reassembly. + * See odp_packet_reass_partial_state(). + * + * Reassembly may not complete if not all fragments were received in time but + * also for packet parsing difficulty, fragment overlap, resource shortage or + * other reasons. In such cases, application may receive packets with reassembly + * status as either ``ODP_PACKET_REASS_NONE`` or ``ODP_PACKET_REASS_INCOMPLETE``. + * + * This structure is used only for configuration, not for capability + * query even though it is indirectly contained in odp_pktio_capability_t. + * The content of odp_pktio_capability_t.config.reassembly written by + * odp_pktio_capability() is undefined. Reassembly capabilities of a pktio + * can be checked through odp_pktio_capability_t.reassembly. + * + * @see odp_packet_reass_status(), odp_packet_reass_partial_state() + */ +typedef struct odp_reass_config_t { + /** Attempt inline reassembly of IPv4 packets. Disabled by default. + * This may be set if the relevant odp_reass_capability_t::ipv4 + * capability is present or if odp_reass_capability_t::ip capability + * is present and en_ipv6 is also set. + */ + odp_bool_t en_ipv4; + + /** Attempt inline reassembly of IPv6 packets. Disabled by default. + * This may be set if the relevant odp_reass_capability_t::ipv6 + * capability is present or if odp_reass_capability_t::ip capability + * is present and en_ipv4 is also set. + */ + odp_bool_t en_ipv6; + + /** Maximum time in ns that a fragment may wait in the reassembly + * offload for the arrival of further fragments. The value may + * not exceed the max_wait_time capability. Zero value means + * implementation defined maximum wait time. + * + * Default value is 0. + */ + uint64_t max_wait_time; + + /** Maximum number of fragments that can be reassembled + * + * Minimum allowed value is 2. Default value is 2. + */ + uint16_t max_num_frags; +} odp_reass_config_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include <odp/visibility_end.h> +#endif diff --git a/include/odp/autoheader_external.h.in b/include/odp/autoheader_external.h.in index 978bc1f2b..dd60fa0b2 100644 --- a/include/odp/autoheader_external.h.in +++ b/include/odp/autoheader_external.h.in @@ -8,4 +8,7 @@ /* Define to 1 to display debug information */ #undef ODP_DEBUG_PRINT +/* Define cache line size */ +#undef _ODP_CACHE_LINE_SIZE + #endif diff --git a/include/odp_api.h b/include/odp_api.h index fe2e31a20..763c9ed7d 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -63,6 +63,7 @@ extern "C" { #include <odp/api/support.h> #include <odp/api/ipsec.h> #include <odp/api/stash.h> +#include <odp/api/reassembly.h> #ifdef __cplusplus } diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index e8c2531f0..6967be8cf 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -336,7 +336,7 @@ __LIB__libodp_dpdk_la_SOURCES += arch/default/odp_atomic.c \ odpapiabiarchinclude_HEADERS += arch/x86/odp/api/abi/cpu_inlines.h \ arch/x86/odp/api/abi/cpu_rdtsc.h \ arch/x86/odp/api/abi/cpu_time.h \ - arch/default/odp/api/abi/hash_crc32.h + arch/x86/odp/api/abi/hash_crc32.h if !ODP_ABI_COMPAT odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/atomic_inlines.h \ diff --git a/platform/linux-dpdk/include/odp_packet_io_internal.h b/platform/linux-dpdk/include/odp_packet_io_internal.h index fe8d4770c..e52eb9840 100644 --- a/platform/linux-dpdk/include/odp_packet_io_internal.h +++ b/platform/linux-dpdk/include/odp_packet_io_internal.h @@ -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 @@ -35,8 +35,12 @@ extern "C" { #define PKTIO_MAX_QUEUES 64 #define PKTIO_LSO_PROFILES 16 +/* Assume at least Ethernet header per each segment */ +#define PKTIO_LSO_MIN_PAYLOAD_OFFSET 14 #define PKTIO_LSO_MAX_PAYLOAD_OFFSET 128 -#define PKTIO_LSO_MAX_SEGMENTS 8 +/* Allow 64 kB packet to be split into about 1kB segments */ +#define PKTIO_LSO_MAX_SEGMENTS 64 + ODP_STATIC_ASSERT(PKTIO_LSO_PROFILES < UINT8_MAX, "PKTIO_LSO_PROFILES_ERROR"); #define PKTIO_NAME_LEN 256 diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4 index 2006c0834..3d50f2edc 100644 --- a/platform/linux-dpdk/m4/configure.m4 +++ b/platform/linux-dpdk/m4/configure.m4 @@ -4,6 +4,7 @@ ODP_LIB_NAME="odp-dpdk" ODP_VISIBILITY ODP_ATOMIC +m4_include([platform/linux-dpdk/m4/odp_cpu.m4]) m4_include([platform/linux-dpdk/m4/odp_libconfig.m4]) m4_include([platform/linux-dpdk/m4/odp_pcapng.m4]) m4_include([platform/linux-dpdk/m4/odp_scheduler.m4]) diff --git a/platform/linux-dpdk/m4/odp_cpu.m4 b/platform/linux-dpdk/m4/odp_cpu.m4 new file mode 120000 index 000000000..effd70d56 --- /dev/null +++ b/platform/linux-dpdk/m4/odp_cpu.m4 @@ -0,0 +1 @@ +../../linux-generic/m4/odp_cpu.m4
\ No newline at end of file diff --git a/platform/linux-dpdk/odp_init.c b/platform/linux-dpdk/odp_init.c index 1f39c4377..e8df33fae 100644 --- a/platform/linux-dpdk/odp_init.c +++ b/platform/linux-dpdk/odp_init.c @@ -13,6 +13,7 @@ #include <odp_init_internal.h> #include <odp_schedule_if.h> #include <odp_libconfig_internal.h> +#include <odp/api/plat/thread_inlines.h> #include <odp_shm_internal.h> #include <string.h> #include <stdio.h> @@ -247,9 +248,6 @@ static int term_global(enum init_stage stage) } /* Fall through */ - case RANDOM_INIT: - /* Fall through */ - case TIMER_INIT: if (_odp_timer_term_global()) { ODP_ERR("ODP timer term failed.\n"); @@ -352,8 +350,8 @@ static int term_global(enum init_stage stage) } /* Fall through */ - case NO_INIT: - ; + default: + break; } return rc; @@ -480,9 +478,6 @@ int odp_init_global(odp_instance_t *instance, } stage = TIMER_INIT; - /* No init needed */ - stage = RANDOM_INIT; - if (_odp_crypto_init_global()) { ODP_ERR("ODP crypto init failed.\n"); goto init_failed; @@ -607,7 +602,7 @@ static int term_local(enum init_stage stage) rc = -1; } else { if (!rc) - rc = rc_thd; + rc = (rc_thd == 0) ? 0 : 1; } /* Fall through */ @@ -699,3 +694,8 @@ int odp_term_local(void) { return term_local(ALL_INIT); } + +void odp_log_thread_fn_set(odp_log_func_t func) +{ + _odp_this_thread->log_fn = func; +} diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index d1b7558e5..8030728dd 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -2374,3 +2374,18 @@ void *odp_packet_tx_compl_user_ptr(odp_packet_tx_compl_t tx_compl) return NULL; } + +odp_packet_reass_status_t odp_packet_reass_status(odp_packet_t pkt) +{ + (void)pkt; + return ODP_PACKET_REASS_NONE; +} + +int odp_packet_reass_partial_state(odp_packet_t pkt, odp_packet_t frags[], + odp_packet_reass_partial_state_t *res) +{ + (void)pkt; + (void)frags; + (void)res; + return -ENOTSUP; +} diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c index 7fd4de06d..44a2d39a3 100644 --- a/platform/linux-dpdk/odp_packet_dpdk.c +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -1419,11 +1419,12 @@ static void stats_convert(struct rte_eth_stats *rte_stats, odp_pktio_stats_t *stats) { stats->in_octets = rte_stats->ibytes; + stats->in_packets = rte_stats->ipackets; stats->in_ucast_pkts = 0; stats->in_discards = rte_stats->imissed; stats->in_errors = rte_stats->ierrors; - stats->in_unknown_protos = 0; stats->out_octets = rte_stats->obytes; + stats->out_packets = rte_stats->opackets; stats->out_ucast_pkts = 0; stats->out_discards = 0; stats->out_errors = rte_stats->oerrors; diff --git a/platform/linux-dpdk/odp_schedule_if.c b/platform/linux-dpdk/odp_schedule_if.c index b8ba33725..2ccadf285 100644 --- a/platform/linux-dpdk/odp_schedule_if.c +++ b/platform/linux-dpdk/odp_schedule_if.c @@ -9,6 +9,7 @@ #include <odp_schedule_if.h> #include <odp_init_internal.h> #include <odp_debug_internal.h> +#include <odp_global_data.h> #include <stdlib.h> #include <string.h> @@ -25,8 +26,6 @@ extern const schedule_api_t _odp_schedule_eventdev_api; const schedule_fn_t *_odp_sched_fn; const schedule_api_t *_odp_sched_api; -int _odp_schedule_configured; - uint64_t odp_schedule_wait_time(uint64_t ns) { return _odp_sched_api->schedule_wait_time(ns); @@ -49,7 +48,7 @@ int odp_schedule_config(const odp_schedule_config_t *config) int ret; odp_schedule_config_t defconfig; - if (_odp_schedule_configured) { + if (odp_global_rw->schedule_configured) { ODP_ERR("Scheduler has been configured already\n"); return -1; } @@ -62,14 +61,14 @@ int odp_schedule_config(const odp_schedule_config_t *config) ret = _odp_sched_api->schedule_config(config); if (ret >= 0) - _odp_schedule_configured = 1; + odp_global_rw->schedule_configured = 1; return ret; } odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait) { - ODP_ASSERT(_odp_schedule_configured); + ODP_ASSERT(odp_global_rw->schedule_configured); return _odp_sched_api->schedule(from, wait); } @@ -77,7 +76,7 @@ odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait) int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int num) { - ODP_ASSERT(_odp_schedule_configured); + ODP_ASSERT(odp_global_rw->schedule_configured); return _odp_sched_api->schedule_multi(from, wait, events, num); } diff --git a/platform/linux-dpdk/odp_system_info.c b/platform/linux-dpdk/odp_system_info.c index 42c502fda..b48275233 100644 --- a/platform/linux-dpdk/odp_system_info.c +++ b/platform/linux-dpdk/odp_system_info.c @@ -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 @@ -55,7 +55,6 @@ static int sysconf_cpu_count(void) return odp_global_ro.num_cpus_installed; } -#if defined __x86_64__ || defined __i386__ || defined __OCTEON__ || defined __powerpc__ /* * Analysis of /sys/devices/system/cpu/ files */ @@ -68,7 +67,9 @@ static int systemcpu_cache_line_size(void) file = fopen(CACHE_LNSZ_FILE, "rt"); if (file == NULL) { /* File not found */ - return 0; + ODP_PRINT("WARN: unable to read host CPU cache line size. " + "Using ODP_CACHE_LINE_SIZE instead.\n"); + return ODP_CACHE_LINE_SIZE; } if (fgets(str, sizeof(str), file) != NULL) { @@ -82,16 +83,6 @@ static int systemcpu_cache_line_size(void) return size; } -#else -/* - * Use dummy data if not available from /sys/devices/system/cpu/ - */ -static int systemcpu_cache_line_size(void) -{ - return 64; -} -#endif - static uint64_t default_huge_page_size(void) { char str[1024]; @@ -234,10 +225,8 @@ static int systemcpu(system_info_t *sysinfo) sysinfo->cache_line_size = ret; - if (ret != ODP_CACHE_LINE_SIZE) { - ODP_ERR("Cache line sizes definitions don't match.\n"); - return -1; - } + if (ret != ODP_CACHE_LINE_SIZE) + ODP_PRINT("WARN: host CPU cache line size and ODP_CACHE_LINE_SIZE don't match.\n"); return 0; } diff --git a/platform/linux-dpdk/odp_thread.c b/platform/linux-dpdk/odp_thread.c index f03be1d75..39ff1b28b 100644 --- a/platform/linux-dpdk/odp_thread.c +++ b/platform/linux-dpdk/odp_thread.c @@ -96,7 +96,14 @@ int _odp_thread_init_global(void) int _odp_thread_term_global(void) { - int ret; + int ret, num; + + odp_spinlock_lock(&thread_globals->lock); + num = thread_globals->num; + odp_spinlock_unlock(&thread_globals->lock); + + if (num) + ODP_ERR("%u threads have not called odp_term_local().\n", num); ret = odp_shm_free(thread_globals->shm); if (ret < 0) @@ -240,6 +247,8 @@ int _odp_thread_term_local(void) if (type == ODP_THREAD_CONTROL && group_control) _odp_sched_fn->thr_rem(ODP_SCHED_GROUP_CONTROL, id); + _odp_this_thread = NULL; + odp_spinlock_lock(&thread_globals->lock); num = free_id(id); odp_spinlock_unlock(&thread_globals->lock); diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 495ff1c88..2181abd26 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -370,7 +370,7 @@ __LIB__libodp_linux_la_SOURCES += arch/default/odp_atomic.c \ odpapiabiarchinclude_HEADERS += arch/x86/odp/api/abi/cpu_inlines.h \ arch/x86/odp/api/abi/cpu_rdtsc.h \ arch/x86/odp/api/abi/cpu_time.h \ - arch/default/odp/api/abi/hash_crc32.h + arch/x86/odp/api/abi/hash_crc32.h if !ODP_ABI_COMPAT odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/atomic_generic.h \ arch/default/odp/api/abi/atomic_inlines.h \ diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/cpu.h b/platform/linux-generic/arch/aarch64/odp/api/abi/cpu.h index 0ab5b8e14..97a2861c5 100644 --- a/platform/linux-generic/arch/aarch64/odp/api/abi/cpu.h +++ b/platform/linux-generic/arch/aarch64/odp/api/abi/cpu.h @@ -11,7 +11,11 @@ extern "C" { #endif -#define ODP_CACHE_LINE_SIZE 64 +#include <odp/autoheader_external.h> + +#ifndef ODP_CACHE_LINE_SIZE + #define ODP_CACHE_LINE_SIZE _ODP_CACHE_LINE_SIZE +#endif static inline void odp_cpu_pause(void) { diff --git a/platform/linux-generic/arch/x86/odp/api/abi/hash_crc32.h b/platform/linux-generic/arch/x86/odp/api/abi/hash_crc32.h new file mode 100644 index 000000000..c2c71bcb7 --- /dev/null +++ b/platform/linux-generic/arch/x86/odp/api/abi/hash_crc32.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_API_ABI_HASH_CRC32_H_ +#define ODP_API_ABI_HASH_CRC32_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +uint32_t _odp_hash_crc32_generic(const void *data, uint32_t data_len, + uint32_t init_val); +uint32_t _odp_hash_crc32c_generic(const void *data, uint32_t data_len, + uint32_t init_val); + +static inline uint32_t _odp_hash_crc32(const void *data, uint32_t data_len, + uint32_t init_val) +{ + return _odp_hash_crc32_generic(data, data_len, init_val); +} + +#ifdef __SSE4_2__ + +static inline uint32_t _odp_hash_crc32c(const void *data, uint32_t data_len, + uint32_t init_val) +{ + uint32_t i; + uintptr_t pd = (uintptr_t)data; + +#ifdef __x86_64__ + for (i = 0; i < data_len / 8; i++) { + init_val = (uint32_t)__builtin_ia32_crc32di(init_val, *(const uint64_t *)pd); + pd += 8; + } + + if (data_len & 0x4) { + init_val = __builtin_ia32_crc32si(init_val, *(const uint32_t *)pd); + pd += 4; + } +#else + for (i = 0; i < data_len / 4; i++) { + init_val = __builtin_ia32_crc32si(init_val, *(const uint32_t *)pd); + pd += 4; + } +#endif + + if (data_len & 0x2) { + init_val = __builtin_ia32_crc32hi(init_val, *(const uint16_t *)pd); + pd += 2; + } + + if (data_len & 0x1) + init_val = __builtin_ia32_crc32qi(init_val, *(const uint8_t *)pd); + + return init_val; +} + +#else + +static inline uint32_t _odp_hash_crc32c(const void *data, uint32_t data_len, + uint32_t init_val) +{ + return _odp_hash_crc32c_generic(data, data_len, init_val); +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp/api/plat/thread_inlines.h b/platform/linux-generic/include/odp/api/plat/thread_inlines.h index ecab29e54..fc9275209 100644 --- a/platform/linux-generic/include/odp/api/plat/thread_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/thread_inlines.h @@ -7,6 +7,8 @@ #ifndef ODP_PLAT_THREAD_INLINES_H_ #define ODP_PLAT_THREAD_INLINES_H_ +#include <odp/api/init.h> + #ifdef __cplusplus extern "C" { #endif @@ -17,6 +19,7 @@ typedef struct { int thr; int cpu; odp_thread_type_t type; + odp_log_func_t log_fn; } _odp_thread_state_t; diff --git a/platform/linux-generic/include/odp_debug_internal.h b/platform/linux-generic/include/odp_debug_internal.h index fbc8f165c..dfad95b19 100644 --- a/platform/linux-generic/include/odp_debug_internal.h +++ b/platform/linux-generic/include/odp_debug_internal.h @@ -20,6 +20,7 @@ #include <odp/autoheader_external.h> #include <odp/api/debug.h> #include <odp_global_data.h> +#include <odp/api/plat/thread_inlines.h> #include <stdio.h> #include <stdlib.h> @@ -32,6 +33,14 @@ extern "C" { * level 0 to N. */ #define CONFIG_DEBUG_LEVEL 0 +#define _ODP_LOG_FN(level, fmt, ...) \ + do { \ + if (_odp_this_thread && _odp_this_thread->log_fn) \ + _odp_this_thread->log_fn(level, fmt, ##__VA_ARGS__); \ + else \ + odp_global_ro.log_fn(level, fmt, ##__VA_ARGS__); \ + } while (0) + /** * Runtime assertion-macro - aborts if 'cond' is false. */ @@ -45,7 +54,7 @@ extern "C" { * This macro is used to indicate when a given function is not implemented */ #define ODP_UNIMPLEMENTED() \ - odp_global_ro.log_fn(ODP_LOG_UNIMPLEMENTED, \ + _ODP_LOG_FN(ODP_LOG_UNIMPLEMENTED, \ "%s:%d:The function %s() is not implemented\n", \ __FILE__, __LINE__, __func__) /* @@ -72,7 +81,7 @@ extern "C" { #define ODP_DBG_RAW(level, fmt, ...) \ do { \ if (ODP_DEBUG_PRINT == 1 && CONFIG_DEBUG_LEVEL >= (level)) \ - odp_global_ro.log_fn(ODP_LOG_DBG, fmt, ##__VA_ARGS__);\ + _ODP_LOG_FN(ODP_LOG_DBG, fmt, ##__VA_ARGS__);\ } while (0) /** @@ -95,7 +104,7 @@ extern "C" { * ODP LOG macro. */ #define ODP_LOG(level, fmt, ...) \ - odp_global_ro.log_fn(level, "%s:%d:%s():" fmt, __FILE__, \ + _ODP_LOG_FN(level, "%s:%d:%s():" fmt, __FILE__, \ __LINE__, __func__, ##__VA_ARGS__) /** @@ -103,7 +112,7 @@ extern "C" { * specifically for dumping internal data. */ #define ODP_PRINT(fmt, ...) \ - odp_global_ro.log_fn(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) + _ODP_LOG_FN(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) #ifdef __cplusplus } diff --git a/platform/linux-generic/include/odp_global_data.h b/platform/linux-generic/include/odp_global_data.h index 237385ada..a907f87be 100644 --- a/platform/linux-generic/include/odp_global_data.h +++ b/platform/linux-generic/include/odp_global_data.h @@ -85,6 +85,7 @@ typedef struct odp_global_data_ro_t { typedef struct odp_global_data_rw_t { odp_bool_t dpdk_initialized; odp_bool_t inline_timers; + odp_bool_t schedule_configured; } odp_global_data_rw_t; diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h index 07b0b4b69..7bbd78ab0 100644 --- a/platform/linux-generic/include/odp_packet_io_internal.h +++ b/platform/linux-generic/include/odp_packet_io_internal.h @@ -39,8 +39,12 @@ extern "C" { #define PKTIO_MAX_QUEUES 64 #define PKTIO_LSO_PROFILES 16 +/* Assume at least Ethernet header per each segment */ +#define PKTIO_LSO_MIN_PAYLOAD_OFFSET 14 #define PKTIO_LSO_MAX_PAYLOAD_OFFSET 128 -#define PKTIO_LSO_MAX_SEGMENTS 8 +/* Allow 64 kB packet to be split into about 1kB segments */ +#define PKTIO_LSO_MAX_SEGMENTS 64 + ODP_STATIC_ASSERT(PKTIO_LSO_PROFILES < UINT8_MAX, "PKTIO_LSO_PROFILES_ERROR"); #define PKTIO_NAME_LEN 256 diff --git a/platform/linux-generic/include/odp_schedule_if.h b/platform/linux-generic/include/odp_schedule_if.h index da240dca3..db0f5c264 100644 --- a/platform/linux-generic/include/odp_schedule_if.h +++ b/platform/linux-generic/include/odp_schedule_if.h @@ -86,9 +86,6 @@ int _odp_sched_cb_pktin_poll(int pktio_index, int pktin_index, int _odp_sched_cb_pktin_poll_one(int pktio_index, int rx_queue, odp_event_t evts[]); void _odp_sched_cb_pktio_stop_finalize(int pktio_index); -/* For debugging */ -extern int _odp_schedule_configured; - /* API functions */ typedef struct { uint64_t (*schedule_wait_time)(uint64_t ns); diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index 2ebc23174..535d43608 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -6,6 +6,7 @@ ODP_ATOMIC ODP_PTHREAD ODP_TIMER +m4_include([platform/linux-generic/m4/odp_cpu.m4]) m4_include([platform/linux-generic/m4/odp_pcap.m4]) m4_include([platform/linux-generic/m4/odp_scheduler.m4]) diff --git a/platform/linux-generic/m4/odp_cpu.m4 b/platform/linux-generic/m4/odp_cpu.m4 new file mode 100644 index 000000000..35a83faf6 --- /dev/null +++ b/platform/linux-generic/m4/odp_cpu.m4 @@ -0,0 +1,35 @@ +########################################################################## +# Set ODP_CACHE_LINE_SIZE define +########################################################################## +# Currently used only for aarch64 +if test "${ARCH_DIR}" = "aarch64"; then + cache_line_size=64 + # Use default cache size if cross-compiling + if test $build = $host; then + cpu_implementer="" + cpu_part="" + + AC_PROG_GREP + AC_PROG_SED + while read line; do + if echo $line | $GREP -q "CPU implementer"; then + cpu_implementer=`echo $line | $SED 's/.*\:\s*//'` + fi + if echo $line | $GREP -q "CPU part"; then + cpu_part=`echo $line | $SED 's/.*\:\s*//'` + fi + done < /proc/cpuinfo + + # Cavium + if test "$cpu_implementer" == "0x43"; then + # ThunderX2 (0x0af) 64B, others 128B + if test "$cpu_part" == "0x0af"; then + cache_line_size=64; + else + cache_line_size=128; + fi + fi + fi + AC_DEFINE_UNQUOTED([_ODP_CACHE_LINE_SIZE], [$cache_line_size], + [Define cache line size]) +fi diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c index 9e734f1a6..0cb60cdfa 100644 --- a/platform/linux-generic/odp_init.c +++ b/platform/linux-generic/odp_init.c @@ -12,6 +12,7 @@ #include <odp_init_internal.h> #include <odp_schedule_if.h> #include <odp_libconfig_internal.h> +#include <odp/api/plat/thread_inlines.h> #include <string.h> #include <stdio.h> #include <unistd.h> @@ -173,9 +174,6 @@ static int term_global(enum init_stage stage) } /* Fall through */ - case RANDOM_INIT: - /* Fall through */ - case TIMER_INIT: if (_odp_timer_term_global()) { ODP_ERR("ODP timer term failed.\n"); @@ -283,8 +281,8 @@ static int term_global(enum init_stage stage) } /* Fall through */ - case NO_INIT: - ; + default: + break; } return rc; @@ -411,9 +409,6 @@ int odp_init_global(odp_instance_t *instance, } stage = TIMER_INIT; - /* No init neeeded */ - stage = RANDOM_INIT; - if (_odp_crypto_init_global()) { ODP_ERR("ODP crypto init failed.\n"); goto init_failed; @@ -537,7 +532,7 @@ static int term_local(enum init_stage stage) rc = -1; } else { if (!rc) - rc = rc_thd; + rc = (rc_thd == 0) ? 0 : 1; } /* Fall through */ @@ -629,3 +624,8 @@ int odp_term_local(void) { return term_local(ALL_INIT); } + +void odp_log_thread_fn_set(odp_log_func_t func) +{ + _odp_this_thread->log_fn = func; +} diff --git a/platform/linux-generic/odp_ipsec.c b/platform/linux-generic/odp_ipsec.c index 766fd10b7..5379a23d0 100644 --- a/platform/linux-generic/odp_ipsec.c +++ b/platform/linux-generic/odp_ipsec.c @@ -138,6 +138,13 @@ int odp_ipsec_capability(odp_ipsec_capability_t *capa) capa->inline_ipsec_tm = ODP_SUPPORT_NO; capa->test.sa_operations.seq_num = 1; + + capa->reassembly.ip = false; + capa->reassembly.ipv4 = false; + capa->reassembly.ipv6 = false; + capa->reass_async = false; + capa->reass_inline = false; + return 0; } @@ -1016,8 +1023,6 @@ static int ipsec_out_tunnel_ipv4(odp_packet_t *pkt, odp_packet_copy_from_mem(*pkt, state->ip_offset, _ODP_IPV4HDR_LEN, &out_ip); - odp_packet_l4_offset_set(*pkt, state->ip_offset + _ODP_IPV4HDR_LEN); - state->ip = odp_packet_l3_ptr(*pkt, NULL); state->ip_hdr_len = _ODP_IPV4HDR_LEN; if (state->is_ipv4) @@ -1077,8 +1082,6 @@ static int ipsec_out_tunnel_ipv6(odp_packet_t *pkt, odp_packet_copy_from_mem(*pkt, state->ip_offset, sizeof(out_ip), &out_ip); - odp_packet_l4_offset_set(*pkt, state->ip_offset + _ODP_IPV6HDR_LEN); - state->ip = odp_packet_l3_ptr(*pkt, NULL); state->ip_hdr_len = _ODP_IPV6HDR_LEN; if (state->is_ipv4) @@ -2082,6 +2085,8 @@ int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet) odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev) { + ODP_ASSERT(odp_event_type(ev) == ODP_EVENT_PACKET); + ODP_ASSERT(odp_event_subtype(ev) == ODP_EVENT_PACKET_IPSEC); return odp_packet_from_event(ev); } diff --git a/platform/linux-generic/odp_libconfig.c b/platform/linux-generic/odp_libconfig.c index aeee319ce..93095ed1a 100644 --- a/platform/linux-generic/odp_libconfig.c +++ b/platform/linux-generic/odp_libconfig.c @@ -191,7 +191,8 @@ int _odp_libconfig_lookup_ext_int(const char *base_path, int _odp_libconfig_print(void) { int c; - /* Temp file for config_write() output */ + /* Temp file for config_write() output. Suppress Coverity warning about tmpfile() usage. */ + /* coverity[secure_temp] */ FILE *file = tmpfile(); if (file == NULL) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 99b0b3ae2..fdf711735 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2932,3 +2932,20 @@ void *odp_packet_tx_compl_user_ptr(odp_packet_tx_compl_t tx_compl) return NULL; } + +odp_packet_reass_status_t +odp_packet_reass_status(odp_packet_t pkt) +{ + (void)pkt; + return ODP_PACKET_REASS_NONE; +} + +int +odp_packet_reass_partial_state(odp_packet_t pkt, odp_packet_t frags[], + odp_packet_reass_partial_state_t *res) +{ + (void)pkt; + (void)frags; + (void)res; + return -ENOTSUP; +} diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 369c319c2..711e5f8a6 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -1812,7 +1812,7 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) capa->lso.max_profiles_per_pktio = PKTIO_LSO_PROFILES; capa->lso.max_packet_segments = PKT_MAX_SEGS; capa->lso.max_segments = PKTIO_LSO_MAX_SEGMENTS; - capa->lso.max_payload_len = mtu - PKTIO_LSO_MAX_PAYLOAD_OFFSET; + capa->lso.max_payload_len = mtu - PKTIO_LSO_MIN_PAYLOAD_OFFSET; capa->lso.max_payload_offset = PKTIO_LSO_MAX_PAYLOAD_OFFSET; capa->lso.max_num_custom = ODP_LSO_MAX_CUSTOM; capa->lso.proto.ipv4 = 1; @@ -1830,6 +1830,10 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) capa->vector.min_tmo_ns = 0; } + capa->reassembly.ip = false; + capa->reassembly.ipv4 = false; + capa->reassembly.ipv6 = false; + return ret; } @@ -2685,10 +2689,14 @@ int odp_packet_lso_request(odp_packet_t pkt, const odp_packet_lso_opt_t *lso_opt return -1; } + if (odp_packet_payload_offset_set(pkt, payload_offset)) { + ODP_ERR("Payload offset set failed\n"); + return -1; + } + pkt_hdr->p.flags.lso = 1; pkt_hdr->lso_max_payload = lso_opt->max_payload_len; pkt_hdr->lso_profile_idx = lso_prof->index; - odp_packet_payload_offset_set(pkt, payload_offset); return 0; } @@ -2829,6 +2837,12 @@ static int pktout_send_lso(odp_pktout_queue_t queue, odp_packet_t packet, num_pkt++; } + if (num_pkt > PKTIO_LSO_MAX_SEGMENTS) { + ODP_ERR("Too many LSO segments %i. Maximum is %i\n", num_pkt, + PKTIO_LSO_MAX_SEGMENTS); + return -1; + } + /* Alloc packets */ odp_packet_t pkt_out[num_pkt]; diff --git a/platform/linux-generic/odp_schedule_basic.c b/platform/linux-generic/odp_schedule_basic.c index 21f707be7..3c3810dfc 100644 --- a/platform/linux-generic/odp_schedule_basic.c +++ b/platform/linux-generic/odp_schedule_basic.c @@ -35,6 +35,7 @@ #include <odp_queue_basic_internal.h> #include <odp_libconfig_internal.h> #include <odp/api/plat/queue_inlines.h> +#include <odp_global_data.h> #include <string.h> @@ -591,7 +592,7 @@ static int schedule_create_queue(uint32_t queue_index, int prio = prio_level_from_api(sched_param->prio); uint8_t spread = spread_index(queue_index); - if (_odp_schedule_configured == 0) { + if (odp_global_rw->schedule_configured == 0) { ODP_ERR("Scheduler has not been configured\n"); return -1; } diff --git a/platform/linux-generic/odp_schedule_if.c b/platform/linux-generic/odp_schedule_if.c index 92d70d0f8..01359543c 100644 --- a/platform/linux-generic/odp_schedule_if.c +++ b/platform/linux-generic/odp_schedule_if.c @@ -9,6 +9,7 @@ #include <odp_schedule_if.h> #include <odp_init_internal.h> #include <odp_debug_internal.h> +#include <odp_global_data.h> #include <stdlib.h> #include <string.h> @@ -24,7 +25,6 @@ extern const schedule_api_t _odp_schedule_scalable_api; const schedule_fn_t *_odp_sched_fn; const schedule_api_t *_odp_sched_api; -int _odp_schedule_configured; uint64_t odp_schedule_wait_time(uint64_t ns) { @@ -48,7 +48,7 @@ int odp_schedule_config(const odp_schedule_config_t *config) int ret; odp_schedule_config_t defconfig; - if (_odp_schedule_configured) { + if (odp_global_rw->schedule_configured) { ODP_ERR("Scheduler has been configured already\n"); return -1; } @@ -61,14 +61,14 @@ int odp_schedule_config(const odp_schedule_config_t *config) ret = _odp_sched_api->schedule_config(config); if (ret >= 0) - _odp_schedule_configured = 1; + odp_global_rw->schedule_configured = 1; return ret; } odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait) { - ODP_ASSERT(_odp_schedule_configured); + ODP_ASSERT(odp_global_rw->schedule_configured); return _odp_sched_api->schedule(from, wait); } @@ -76,7 +76,7 @@ odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait) int odp_schedule_multi(odp_queue_t *from, uint64_t wait, odp_event_t events[], int num) { - ODP_ASSERT(_odp_schedule_configured); + ODP_ASSERT(odp_global_rw->schedule_configured); return _odp_sched_api->schedule_multi(from, wait, events, num); } diff --git a/platform/linux-generic/odp_schedule_sp.c b/platform/linux-generic/odp_schedule_sp.c index a91b9fbca..a401ba884 100644 --- a/platform/linux-generic/odp_schedule_sp.c +++ b/platform/linux-generic/odp_schedule_sp.c @@ -27,6 +27,7 @@ #include <odp_ring_u32_internal.h> #include <odp_timer_internal.h> #include <odp_queue_basic_internal.h> +#include <odp_global_data.h> #include <string.h> @@ -437,7 +438,7 @@ static int create_queue(uint32_t qi, const odp_schedule_param_t *sched_param) odp_schedule_group_t group = sched_param->group; int prio = 0; - if (_odp_schedule_configured == 0) { + if (odp_global_rw->schedule_configured == 0) { ODP_ERR("Scheduler has not been configured\n"); return -1; } diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 079210652..9bef6fd7f 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -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 @@ -51,8 +51,6 @@ static int sysconf_cpu_count(void) return odp_global_ro.num_cpus_installed; } -#if defined __x86_64__ || defined __i386__ || defined __OCTEON__ || \ -defined __powerpc__ /* * Analysis of /sys/devices/system/cpu/ files */ @@ -65,7 +63,9 @@ static int systemcpu_cache_line_size(void) file = fopen(CACHE_LNSZ_FILE, "rt"); if (file == NULL) { /* File not found */ - return 0; + ODP_PRINT("WARN: unable to read host CPU cache line size. " + "Using ODP_CACHE_LINE_SIZE instead.\n"); + return ODP_CACHE_LINE_SIZE; } if (fgets(str, sizeof(str), file) != NULL) { @@ -79,16 +79,6 @@ static int systemcpu_cache_line_size(void) return size; } -#else -/* - * Use dummy data if not available from /sys/devices/system/cpu/ - */ -static int systemcpu_cache_line_size(void) -{ - return 64; -} -#endif - static uint64_t default_huge_page_size(void) { char str[1024]; @@ -309,10 +299,8 @@ static int systemcpu(system_info_t *sysinfo) sysinfo->cache_line_size = ret; - if (ret != ODP_CACHE_LINE_SIZE) { - ODP_ERR("Cache line sizes definitions don't match.\n"); - return -1; - } + if (ret != ODP_CACHE_LINE_SIZE) + ODP_PRINT("WARN: host CPU cache line size and ODP_CACHE_LINE_SIZE don't match.\n"); return 0; } diff --git a/platform/linux-generic/odp_thread.c b/platform/linux-generic/odp_thread.c index 170bf82b7..af891bce8 100644 --- a/platform/linux-generic/odp_thread.c +++ b/platform/linux-generic/odp_thread.c @@ -88,7 +88,14 @@ int _odp_thread_init_global(void) int _odp_thread_term_global(void) { - int ret; + int ret, num; + + odp_spinlock_lock(&thread_globals->lock); + num = thread_globals->num; + odp_spinlock_unlock(&thread_globals->lock); + + if (num) + ODP_ERR("%u threads have not called odp_term_local().\n", num); ret = odp_shm_free(odp_shm_lookup("_odp_thread_globals")); if (ret < 0) @@ -231,6 +238,8 @@ int _odp_thread_term_local(void) if (type == ODP_THREAD_CONTROL && group_control) _odp_sched_fn->thr_rem(ODP_SCHED_GROUP_CONTROL, id); + _odp_this_thread = NULL; + odp_spinlock_lock(&thread_globals->lock); num = free_id(id); odp_spinlock_unlock(&thread_globals->lock); diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c index 0ae107509..1633bc454 100644 --- a/platform/linux-generic/odp_traffic_mngr.c +++ b/platform/linux-generic/odp_traffic_mngr.c @@ -2246,12 +2246,14 @@ static void tm_send_pkt(tm_system_t *tm_system, uint32_t max_sends) tm_egress_marking(tm_system, odp_pkt); tm_system->egress_pkt_desc = EMPTY_PKT_DESC; - if (tm_system->egress.egress_kind == ODP_TM_EGRESS_PKT_IO) - odp_pktout_send(tm_system->pktout, &odp_pkt, 1); - else if (tm_system->egress.egress_kind == ODP_TM_EGRESS_FN) + if (tm_system->egress.egress_kind == ODP_TM_EGRESS_PKT_IO) { + if (odp_pktout_send(tm_system->pktout, &odp_pkt, 1) != 1) + odp_packet_free(odp_pkt); + } else if (tm_system->egress.egress_kind == ODP_TM_EGRESS_FN) { tm_system->egress.egress_fcn(odp_pkt); - else + } else { return; + } tm_queue_obj->sent_pkt = tm_queue_obj->pkt; tm_queue_obj->sent_pkt_desc = tm_queue_obj->in_pkt_desc; @@ -2515,7 +2517,9 @@ static void *tm_system_thread(void *arg) } odp_barrier_wait(&tm_system->tm_system_destroy_barrier); - odp_term_local(); + if (odp_term_local() < 0) + ODP_ERR("Term local failed\n"); + return NULL; } @@ -3966,7 +3970,15 @@ odp_tm_queue_t odp_tm_queue_create(odp_tm_t odp_tm, } queue_obj->queue = queue; - odp_queue_context_set(queue, queue_obj, sizeof(tm_queue_obj_t)); + if (odp_queue_context_set(queue, queue_obj, sizeof(tm_queue_obj_t))) { + ODP_ERR("Queue context set failed\n"); + if (odp_queue_destroy(queue)) + ODP_ERR("Queue destroy failed\n"); + + odp_tm_queue = ODP_TM_INVALID; + break; + } + _odp_queue_fn->set_enq_deq_fn(queue, queue_tm_reenq, queue_tm_reenq_multi, NULL, NULL); diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index fb99d8ed5..6b349293a 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -2201,9 +2201,11 @@ static void stats_convert(const struct rte_eth_stats *rte_stats, memset(stats, 0, sizeof(odp_pktio_stats_t)); stats->in_octets = rte_stats->ibytes; + stats->in_packets = rte_stats->ipackets; stats->in_discards = rte_stats->imissed; stats->in_errors = rte_stats->ierrors; stats->out_octets = rte_stats->obytes; + stats->out_packets = rte_stats->opackets; stats->out_errors = rte_stats->oerrors; } diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index d58c9a55c..dd321511a 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -191,7 +191,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, } pktio_entry->s.stats.in_errors += failed; - pktio_entry->s.stats.in_ucast_pkts += num_rx - failed; + pktio_entry->s.stats.in_packets += num_rx - failed; odp_ticketlock_unlock(&pktio_entry->s.rxl); @@ -355,7 +355,7 @@ static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED, if (odp_unlikely(tx_ts_idx) && ret >= tx_ts_idx) _odp_pktio_tx_ts_set(pktio_entry); - pktio_entry->s.stats.out_ucast_pkts += ret; + pktio_entry->s.stats.out_packets += ret; pktio_entry->s.stats.out_octets += out_octets_tbl[ret - 1]; } else { ODP_DBG("queue enqueue failed %i\n", ret); diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index 82635e59c..d4858903b 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -318,7 +318,7 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED, i++; } - pktio_entry->s.stats.in_ucast_pkts += i; + pktio_entry->s.stats.in_packets += i; odp_ticketlock_unlock(&pktio_entry->s.rxl); @@ -377,7 +377,7 @@ static int pcapif_send_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED, odp_packet_free(pkts[i]); } - pktio_entry->s.stats.out_ucast_pkts += i; + pktio_entry->s.stats.out_packets += i; odp_ticketlock_unlock(&pktio_entry->s.txl); diff --git a/platform/linux-generic/pktio/stats/ethtool_stats.c b/platform/linux-generic/pktio/stats/ethtool_stats.c index 8e94e03e7..e4f99e331 100644 --- a/platform/linux-generic/pktio/stats/ethtool_stats.c +++ b/platform/linux-generic/pktio/stats/ethtool_stats.c @@ -128,6 +128,9 @@ static int ethtool_stats(int fd, struct ifreq *ifr, odp_pktio_stats_t *stats) if (!strcmp(cnt, "rx_octets")) { stats->in_octets = val; cnts++; + } else if (!strcmp(cnt, "rx_packets")) { + stats->in_packets = val; + cnts++; } else if (!strcmp(cnt, "rx_ucast_packets")) { stats->in_ucast_pkts = val; cnts++; @@ -140,6 +143,9 @@ static int ethtool_stats(int fd, struct ifreq *ifr, odp_pktio_stats_t *stats) } else if (!strcmp(cnt, "tx_octets")) { stats->out_octets = val; cnts++; + } else if (!strcmp(cnt, "tx_packets")) { + stats->out_packets = val; + cnts++; } else if (!strcmp(cnt, "tx_ucast_packets")) { stats->out_ucast_pkts = val; cnts++; diff --git a/platform/linux-generic/pktio/stats/packet_io_stats.c b/platform/linux-generic/pktio/stats/packet_io_stats.c index b79cf17aa..e8d4d9a62 100644 --- a/platform/linux-generic/pktio/stats/packet_io_stats.c +++ b/platform/linux-generic/pktio/stats/packet_io_stats.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <odp/api/deprecated.h> #include <odp_packet_io_stats.h> #include <odp_ethtool_stats.h> #include <odp_sysfs_stats.h> @@ -61,17 +62,22 @@ int _odp_sock_stats_fd(pktio_entry_t *pktio_entry, stats->in_octets = cur_stats.in_octets - pktio_entry->s.stats.in_octets; + stats->in_packets = cur_stats.in_packets - + pktio_entry->s.stats.in_packets; stats->in_ucast_pkts = cur_stats.in_ucast_pkts - pktio_entry->s.stats.in_ucast_pkts; stats->in_discards = cur_stats.in_discards - pktio_entry->s.stats.in_discards; stats->in_errors = cur_stats.in_errors - pktio_entry->s.stats.in_errors; +#if ODP_DEPRECATED_API stats->in_unknown_protos = cur_stats.in_unknown_protos - pktio_entry->s.stats.in_unknown_protos; - +#endif stats->out_octets = cur_stats.out_octets - pktio_entry->s.stats.out_octets; + stats->out_packets = cur_stats.out_packets - + pktio_entry->s.stats.out_packets; stats->out_ucast_pkts = cur_stats.out_ucast_pkts - pktio_entry->s.stats.out_ucast_pkts; stats->out_discards = cur_stats.out_discards - diff --git a/platform/linux-generic/pktio/stats/sysfs_stats.c b/platform/linux-generic/pktio/stats/sysfs_stats.c index 45e005c74..1150f9d72 100644 --- a/platform/linux-generic/pktio/stats/sysfs_stats.c +++ b/platform/linux-generic/pktio/stats/sysfs_stats.c @@ -52,6 +52,9 @@ int _odp_sysfs_stats(pktio_entry_t *pktio_entry, ret -= sysfs_get_val(fname, &stats->in_octets); sprintf(fname, "/sys/class/net/%s/statistics/rx_packets", dev); + ret -= sysfs_get_val(fname, &stats->in_packets); + + sprintf(fname, "/sys/class/net/%s/statistics/rx_packets", dev); ret -= sysfs_get_val(fname, &stats->in_ucast_pkts); sprintf(fname, "/sys/class/net/%s/statistics/rx_droppped", dev); @@ -60,12 +63,13 @@ int _odp_sysfs_stats(pktio_entry_t *pktio_entry, sprintf(fname, "/sys/class/net/%s/statistics/rx_errors", dev); ret -= sysfs_get_val(fname, &stats->in_errors); - /* stats->in_unknown_protos is not supported in sysfs */ - sprintf(fname, "/sys/class/net/%s/statistics/tx_bytes", dev); ret -= sysfs_get_val(fname, &stats->out_octets); sprintf(fname, "/sys/class/net/%s/statistics/tx_packets", dev); + ret -= sysfs_get_val(fname, &stats->out_packets); + + sprintf(fname, "/sys/class/net/%s/statistics/tx_packets", dev); ret -= sysfs_get_val(fname, &stats->out_ucast_pkts); sprintf(fname, "/sys/class/net/%s/statistics/tx_dropped", dev); diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index 8126773ea..ae50bf065 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -28,7 +28,15 @@ ODP_LIB_NAME=libodp-dpdk fi # Additional warning checks -EXTRA_CHECKS="-Werror -Wall -Wextra -Wconversion -Wundef -Wpointer-arith -Wfloat-equal -Wpacked" +EXTRA_CHECKS="-Werror -Wall -Wextra -Wconversion -Wfloat-equal -Wpacked" +# Ignore clang warning about large atomic operations causing significant performance penalty +if [ "${CC#clang}" != "${CC}" ] ; then + EXTRA_CHECKS="${EXTRA_CHECKS} -Wno-unknown-warning-option -Wno-atomic-alignment" +fi +# Ignore warnings from aarch64 DPDK internals +if [ "${TARGET_ARCH}" == "aarch64-linux-gnu" ] ; then + EXTRA_CHECKS="${EXTRA_CHECKS} -Wno-conversion -Wno-packed" +fi CC="${CC:-${TARGET_ARCH}-gcc}" ${CC} ${CFLAGS} ${EXTRA_CHECKS} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst_dynamic \ diff --git a/test/common/Makefile.am b/test/common/Makefile.am index 79146e01c..37582d55a 100644 --- a/test/common/Makefile.am +++ b/test/common/Makefile.am @@ -14,5 +14,10 @@ libthrmask_common_la_CFLAGS = $(AM_CFLAGS) -DTEST_THRMASK endif -noinst_HEADERS = test_packet_parser.h +noinst_HEADERS = test_packet_custom.h \ + test_packet_ipsec.h \ + test_packet_ipv4.h \ + test_packet_ipv4_with_crc.h \ + test_packet_ipv6.h + dist_test_SCRIPTS = run-test.sh diff --git a/test/common/test_packet_custom.h b/test/common/test_packet_custom.h new file mode 100644 index 000000000..7ff652bd8 --- /dev/null +++ b/test/common/test_packet_custom.h @@ -0,0 +1,124 @@ +/* Copyright (c) 2020-2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_PACKET_CUSTOM_H_ +#define TEST_PACKET_CUSTOM_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Test packets without CRC */ + +/* Ethernet type 0x88B5: EthernetIEEE Std 802 - Local Experimental Ethertype 1 + * + * Imaginary, custom protocol on top of Ethernet. + */ +static const uint8_t test_packet_custom_eth_1[] = { + /* Ethernet */ + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x04, 0x00, 0x88, 0xB5, + /* Header fields (16 bit): + * packet length, segment number, segment offset, port number */ + 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x05, 0x67, + /* Payload 701 bytes */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, + 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, + 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, + 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, + 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, + 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, + 0x00, 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, + 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, + 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, + 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, + 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, + 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, + 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, + 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, + 0x00, 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, + 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, + 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, + 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, + 0x00, 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, + 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, + 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, + 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, + 0x00, 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, + 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, + 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, + 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, + 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, + 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, + 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, + 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, + 0x00, 0x78, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B, + 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, + 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, + 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, + 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, + 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, + 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, + 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, + 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, + 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, + 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, + 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, + 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, + 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, + 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, + 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, + 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, + 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, + 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, + 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, + 0xDC, 0x00, 0xDD, 0x00, 0xDE +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/common/test_packet_ipsec.h b/test/common/test_packet_ipsec.h new file mode 100644 index 000000000..918870c99 --- /dev/null +++ b/test/common/test_packet_ipsec.h @@ -0,0 +1,188 @@ +/* Copyright (c) 2017-2018, Linaro Limited + * Copyright (c) 2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_PACKET_IPSEC_H_ +#define TEST_PACKET_IPSEC_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Test packets without CRC */ + +static const uint8_t test_packet_ipv4_ipsec_ah[] = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IPv4 */ + 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* AH */ + 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3, + 0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b +}; + +static const uint8_t test_packet_ipv4_ipsec_esp[] = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IPv4 */ + 0x45, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x32, 0x19, 0x18, 0x0a, 0x00, 0x6f, 0x02, + 0x0a, 0x00, 0xde, 0x02, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* IPv4 */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + + /* ESP TRL */ + 0x01, 0x02, 0x02, 0x04, + + /* ICV */ + 0x73, 0x8d, 0xf6, 0x9a, 0x26, 0x06, 0x4d, 0xa1, + 0x88, 0x37, 0x65, 0xab, 0x0d, 0xe9, 0x95, 0x3b +}; + +static const uint8_t test_packet_ipv6_ipsec_ah[] = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IPv6 */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x33, 0x40, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + + /* AH */ + 0x29, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x01, + 0x62, 0x96, 0x2b, 0x40, 0x3e, 0x53, 0x76, 0x4a, + 0x4d, 0x7f, 0xf6, 0x22, 0x35, 0x3c, 0x74, 0xe2, + 0x00, 0x00, 0x00, 0x00, + + /* IPv6 */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x40, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + + /* Hop-by-Hop */ + 0x3a, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b +}; + +static const uint8_t test_packet_ipv6_ipsec_esp[] = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IPv6 */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x32, 0x40, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + + /* ESP */ + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, + + /* IPv4 */ + 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, + 0xc0, 0xa8, 0xde, 0x02, + + /* ICMP */ + 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, + 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + + /* ESP TRL */ + 0x01, 0x02, 0x02, 0x04, + + /* ICV */ + 0x73, 0x8d, 0xf6, 0x9a, 0x26, 0x06, 0x4d, 0xa1, + 0x88, 0x37, 0x65, 0xab, 0x0d, 0xe9, 0x95, 0x3b +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/common/test_packet_parser.h b/test/common/test_packet_ipv4.h index 07e2cfe0a..2bccf7b5f 100644 --- a/test/common/test_packet_parser.h +++ b/test/common/test_packet_ipv4.h @@ -1,11 +1,12 @@ /* Copyright (c) 2017-2018, Linaro Limited + * Copyright (c) 2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef TEST_PACKET_PARSER_H_ -#define TEST_PACKET_PARSER_H_ +#ifndef TEST_PACKET_IPV4_H_ +#define TEST_PACKET_IPV4_H_ #include <stdint.h> @@ -15,108 +16,6 @@ extern "C" { /* Test packets without CRC */ -/* Ethernet type 0x88B5: EthernetIEEE Std 802 - Local Experimental Ethertype 1 - * - * Imaginary, custom protocol on top of Ethernet. - */ -static const uint8_t test_packet_custom_eth_1[] = { - /* Ethernet */ - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x09, 0x00, 0x04, 0x00, 0x88, 0xB5, - /* Header fields (16 bit): - * packet length, segment number, segment offset, port number */ - 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x05, 0x67, - /* Payload 701 bytes */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, - 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, - 0x00, 0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, - 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, - 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, - 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, - 0x00, 0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, - 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, - 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, - 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, - 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, - 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, - 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, - 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, - 0x00, 0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, - 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, - 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, - 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, - 0x00, 0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, - 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, - 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, - 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, - 0x00, 0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, - 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, - 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, - 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, - 0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, - 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, - 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, - 0x00, 0x78, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B, - 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, - 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, - 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, - 0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, - 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00, - 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, - 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, - 0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, - 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00, - 0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, - 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00, - 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, - 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00, - 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, - 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00, - 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, - 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00, - 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, - 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00, - 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, - 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00, - 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, - 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00, - 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, - 0xDC, 0x00, 0xDD, 0x00, 0xDE -}; - /* ARP request */ static const uint8_t test_packet_arp[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, @@ -207,59 +106,6 @@ static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { 0x06, 0x07, 0x08, 0x09 }; -/* ICMPv6 echo request */ -static const uint8_t test_packet_ipv6_icmp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, - 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02 -}; - -/* IPv6 TCP */ -static const uint8_t test_packet_ipv6_tcp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, - 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x50, 0x02, 0x00, 0x00, 0x36, 0x35, - 0x00, 0x00 -}; - -/* IPv6 UDP */ -static const uint8_t test_packet_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68 -}; - -/* VLAN IPv6 - * - type 0x8100, tag 23 - */ -static const uint8_t test_packet_vlan_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, - 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, - 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, - 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, - 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, - 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, - 0x9B, 0x68 -}; - /* IPv4 SCTP * - chunk type: payload data */ @@ -283,197 +129,6 @@ static const uint8_t test_packet_ipv4_sctp[] = { 0x79, 0x74, 0x65, 0x73, 0x2E }; -/* IPv6 SCTP - * - chunk type: payload data - */ -static const uint8_t test_packet_ipv6_sctp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x63, 0x84, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, - 0x16, 0x2E, 0xDE, 0xAD, 0xBE, 0xEF, 0x31, 0x44, - 0xE3, 0xFE, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, - 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, - 0x73, 0x20, 0x6D, 0x79, 0x20, 0x64, 0x75, 0x6D, - 0x6D, 0x79, 0x20, 0x70, 0x61, 0x79, 0x6C, 0x6F, - 0x61, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, - 0x67, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6C, - 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x6F, 0x66, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6E, 0x67, 0x20, 0x69, 0x73, 0x20, - 0x37, 0x31, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x2E -}; - -static const uint8_t test_packet_ipv4_ipsec_ah[] = { - /* ETH */ - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, - - /* IPv4 */ - 0x45, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x33, 0xab, 0xd9, 0xc0, 0xa8, 0x6f, 0x02, - 0xc0, 0xa8, 0xde, 0x02, - - /* AH */ - 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x01, - 0x6c, 0x2e, 0xf7, 0x1f, 0x7c, 0x70, 0x39, 0xa3, - 0x4a, 0x77, 0x01, 0x47, 0x9e, 0x45, 0x73, 0x51, - - /* ICMP */ - 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, - 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b -}; - -static const uint8_t test_packet_ipv4_ipsec_esp[] = { - /* ETH */ - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, - - /* IPv4 */ - 0x45, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x32, 0x19, 0x18, 0x0a, 0x00, 0x6f, 0x02, - 0x0a, 0x00, 0xde, 0x02, - - /* ESP */ - 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - - /* IPv4 */ - 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, - 0xc0, 0xa8, 0xde, 0x02, - - /* ICMP */ - 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, - 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, - - /* ESP TRL */ - 0x01, 0x02, 0x02, 0x04, - - /* ICV */ - 0x73, 0x8d, 0xf6, 0x9a, 0x26, 0x06, 0x4d, 0xa1, - 0x88, 0x37, 0x65, 0xab, 0x0d, 0xe9, 0x95, 0x3b -}; - -static const uint8_t test_packet_ipv6_ipsec_ah[] = { - /* ETH */ - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, - - /* IPv6 */ - 0x60, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x33, 0x40, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, - - /* AH */ - 0x29, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - 0x00, 0x00, 0x00, 0x01, - 0x62, 0x96, 0x2b, 0x40, 0x3e, 0x53, 0x76, 0x4a, - 0x4d, 0x7f, 0xf6, 0x22, 0x35, 0x3c, 0x74, 0xe2, - 0x00, 0x00, 0x00, 0x00, - - /* IPv6 */ - 0x60, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x40, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, - - /* Hop-by-Hop */ - 0x3a, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, - - /* ICMP */ - 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, - 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b -}; - -static const uint8_t test_packet_ipv6_ipsec_esp[] = { - /* ETH */ - 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, - - /* IPv6 */ - 0x60, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x32, 0x40, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, - - /* ESP */ - 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x01, - - /* IPv4 */ - 0x45, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x01, 0xac, 0x27, 0xc0, 0xa8, 0x6f, 0x02, - 0xc0, 0xa8, 0xde, 0x02, - - /* ICMP */ - 0x08, 0x00, 0xfb, 0x37, 0x12, 0x34, 0x00, 0x00, - 0xba, 0xbe, 0x01, 0x23, 0x45, 0x67, 0xca, 0xfe, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, - - /* ESP TRL */ - 0x01, 0x02, 0x02, 0x04, - - /* ICV */ - 0x73, 0x8d, 0xf6, 0x9a, 0x26, 0x06, 0x4d, 0xa1, - 0x88, 0x37, 0x65, 0xab, 0x0d, 0xe9, 0x95, 0x3b -}; - static const uint8_t test_packet_mcast_eth_ipv4_udp[] = { 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x02, 0x00, 0x00, 0x03, 0x04, 0x05, 0x08, 0x00, 0x45, 0x00, @@ -510,26 +165,6 @@ static const uint8_t test_packet_bcast_eth_ipv4_udp[] = { 0x2E }; -static const uint8_t test_packet_mcast_eth_ipv6_udp[] = { - 0x33, 0x33, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00, - 0x00, 0x03, 0x04, 0x05, 0x86, 0xDD, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x4F, 0x11, 0x40, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xFF, 0xFE, 0x03, 0x04, 0x05, 0xFF, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x04, 0xD2, - 0x16, 0x2E, 0x00, 0x4F, 0xD6, 0x79, 0x54, 0x68, - 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, - 0x20, 0x64, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x70, - 0x61, 0x79, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x6C, 0x65, 0x6E, 0x67, 0x74, - 0x68, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, - 0x20, 0x69, 0x73, 0x20, 0x37, 0x31, 0x20, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x2E -}; - static const uint8_t test_packet_ipv4_udp_first_frag[] = { 0x02, 0x00, 0x00, 0x04, 0x05, 0x06, 0x02, 0x00, 0x00, 0x01, 0x02, 0x03, 0x08, 0x00, 0x45, 0x00, diff --git a/test/common/test_packet_ipv4_with_crc.h b/test/common/test_packet_ipv4_with_crc.h new file mode 100644 index 000000000..f10c405e1 --- /dev/null +++ b/test/common/test_packet_ipv4_with_crc.h @@ -0,0 +1,234 @@ +/* Copyright (c) 2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_PACKET_IPV4_WITH_CRC_H_ +#define TEST_PACKET_IPV4_WITH_CRC_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Ethernet/IPv4/UDP test packets with CRC. Last 4 bytes are the Ethernet FCS. */ + +/* Frame length is 64 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_64_crc[] = { + 0x12, 0xA8, 0x87, 0x93, 0x25, 0x39, 0x1A, 0x29, + 0x92, 0x49, 0x00, 0x32, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAB, 0x8D, 0xC0, 0xA8, 0xDE, 0xC7, 0xC0, 0xA8, + 0x6F, 0x19, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, + 0xA8, 0x69, 0xD3, 0xFA, 0x53, 0xCD, 0xFF, 0xF7, + 0x11, 0xB0, 0x3B, 0xD1, 0x1F, 0xF4, 0x64, 0xBB, + 0x70, 0x11, 0x1D, 0x9E, 0x00, 0xA8, 0xC6, 0xBA +}; + +/* Frame length is 68 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_68_crc[] = { + 0x12, 0x69, 0x5C, 0xDF, 0xB0, 0xDB, 0x1A, 0x38, + 0xC8, 0x96, 0x1E, 0x5A, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAA, 0xBA, 0xC0, 0xA8, 0xDE, 0xF8, 0xC0, 0xA8, + 0x6F, 0xB7, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1E, + 0x06, 0xFC, 0x73, 0x90, 0xFC, 0x24, 0x58, 0xE6, + 0x2F, 0x29, 0xA7, 0x18, 0x77, 0xF8, 0x8D, 0xB6, + 0xF5, 0xB6, 0xE4, 0x3A, 0x09, 0xD8, 0x9F, 0xE0, + 0x88, 0xEB, 0x77, 0x75 +}; + +/* Frame length is 70 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_70_crc[] = { + 0x12, 0x7F, 0x60, 0x61, 0x5F, 0x98, 0x1A, 0x18, + 0x74, 0x06, 0x52, 0x94, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAB, 0xDD, 0xC0, 0xA8, 0xDE, 0x89, 0xC0, 0xA8, + 0x6F, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x20, + 0xDC, 0xBC, 0xC2, 0x76, 0xB8, 0x05, 0x50, 0x86, + 0x90, 0xA3, 0x46, 0x76, 0x89, 0x9B, 0xF8, 0xD9, + 0x3A, 0x36, 0x58, 0x64, 0xD5, 0xF2, 0xBE, 0xA2, + 0x07, 0xD5, 0x80, 0x25, 0x82, 0x94 +}; + +/* Frame length is 71 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_71_crc[] = { + 0x12, 0x37, 0x9F, 0x5A, 0x81, 0x77, 0x1A, 0xB2, + 0x2F, 0x2F, 0xF8, 0xAE, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAB, 0x6B, 0xC0, 0xA8, 0xDE, 0xA2, 0xC0, 0xA8, + 0x6F, 0x59, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x21, + 0xAA, 0x78, 0x09, 0xE6, 0xC7, 0x2B, 0x99, 0x6D, + 0xC7, 0xA9, 0xE2, 0x8E, 0xB7, 0x21, 0xE0, 0x9C, + 0xAC, 0x23, 0x77, 0x44, 0xB0, 0x61, 0x1C, 0x70, + 0x15, 0xB7, 0xD3, 0x4D, 0x8E, 0xB3, 0xA4 +}; + +/* Frame length is 287 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_287_crc[] = { + 0x12, 0x16, 0xB7, 0x09, 0x63, 0x96, 0x1A, 0xDE, + 0xBE, 0x52, 0xEC, 0x53, 0x08, 0x00, 0x45, 0x00, + 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAA, 0x5F, 0xC0, 0xA8, 0xDE, 0xB6, 0xC0, 0xA8, + 0x6F, 0x79, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0xF9, + 0x99, 0x92, 0xA3, 0x3E, 0x1A, 0xAA, 0xFF, 0xA6, + 0xAB, 0xDD, 0xF5, 0x55, 0x28, 0x08, 0xCA, 0x0E, + 0x99, 0x27, 0x61, 0xB5, 0x9D, 0x65, 0x01, 0x07, + 0x55, 0x79, 0x57, 0x89, 0x7D, 0x35, 0xBF, 0xBE, + 0xDC, 0x5C, 0xBF, 0x9D, 0xDF, 0xB5, 0xD4, 0x42, + 0x81, 0x5D, 0x72, 0xE4, 0x6D, 0x61, 0x46, 0x07, + 0x67, 0x8C, 0xBE, 0xF3, 0xE8, 0x7E, 0xCB, 0x64, + 0x08, 0xFE, 0xE6, 0x83, 0xA1, 0x92, 0x51, 0x15, + 0xB2, 0x4C, 0x9F, 0xF3, 0x01, 0xE6, 0x76, 0xBA, + 0x05, 0x12, 0x94, 0xC3, 0x02, 0x0B, 0x10, 0x56, + 0x76, 0x70, 0xE2, 0x1A, 0xB4, 0x52, 0xA6, 0xD0, + 0xCF, 0x8C, 0x9D, 0x41, 0xB9, 0x52, 0xF5, 0x75, + 0xAC, 0x0D, 0x4A, 0x26, 0xC9, 0x66, 0x6C, 0x74, + 0x00, 0xA1, 0x63, 0xDB, 0x2F, 0x2D, 0xB0, 0x61, + 0x8E, 0x79, 0xD6, 0x14, 0x4A, 0x09, 0x19, 0xB3, + 0x70, 0xC8, 0x86, 0xAC, 0x0D, 0xA0, 0x33, 0x46, + 0x94, 0x48, 0xC8, 0x20, 0x7F, 0x5D, 0x3E, 0xDA, + 0x39, 0xB5, 0xE7, 0x12, 0x3C, 0xF0, 0xAF, 0x92, + 0x76, 0x4F, 0xA1, 0xC7, 0xF2, 0xCA, 0xAD, 0x76, + 0xB4, 0x5C, 0xA8, 0xAA, 0xE5, 0xA2, 0x94, 0xF1, + 0x30, 0xA4, 0x22, 0xC7, 0x6B, 0xF3, 0x75, 0x53, + 0x7A, 0xF4, 0x29, 0x51, 0x70, 0x7B, 0x94, 0x50, + 0xF8, 0x9B, 0x4B, 0x1D, 0xF4, 0xBD, 0xE8, 0x7F, + 0x63, 0xF0, 0x0B, 0x24, 0x88, 0x80, 0x9F, 0xDC, + 0x49, 0xCA, 0x5F, 0x05, 0xD5, 0x4E, 0x98, 0x46, + 0x89, 0x06, 0x30, 0x81, 0x15, 0xF7, 0xE7, 0x02, + 0xDA, 0x05, 0xDD, 0xFD, 0x97, 0x0B, 0x55, 0x37, + 0x45, 0x2B, 0xB8, 0x03, 0x3F, 0x63, 0xDD, 0x70, + 0xA6, 0x61, 0x87, 0xC1, 0x04, 0x99, 0x2F, 0x1D, + 0x2F, 0x94, 0x04, 0x88, 0x71, 0x8B, 0x31, 0x12, + 0xE5, 0x34, 0x5E, 0x01, 0x24, 0x62, 0x28 +}; + +/* Frame length is 400 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_400_crc[] = { + 0x12, 0x61, 0x73, 0x60, 0x9D, 0x86, 0x1A, 0x85, + 0x0E, 0xF2, 0x3B, 0x2E, 0x08, 0x00, 0x45, 0x00, + 0x01, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAA, 0xB3, 0xC0, 0xA8, 0xDE, 0x0B, 0xC0, 0xA8, + 0x6F, 0x5F, 0x00, 0x3F, 0x00, 0x3F, 0x01, 0x6A, + 0x16, 0x66, 0xE1, 0xC0, 0xC1, 0x8E, 0xA5, 0x1A, + 0x01, 0x2A, 0x00, 0xBB, 0x41, 0x3B, 0x9C, 0xB8, + 0x18, 0x8A, 0x70, 0x3C, 0xD6, 0xBA, 0xE3, 0x1C, + 0xC6, 0x7B, 0x34, 0xB1, 0xB0, 0x00, 0x19, 0xE6, + 0xA2, 0xB2, 0xA6, 0x90, 0xF0, 0x26, 0x71, 0xFE, + 0x7A, 0x4C, 0xF4, 0xD1, 0x2D, 0xEA, 0x32, 0x0E, + 0xCD, 0x49, 0x9E, 0x72, 0xF1, 0x2F, 0x38, 0x06, + 0x4F, 0x0C, 0xF9, 0xF3, 0x39, 0x78, 0x71, 0x96, + 0x68, 0xDD, 0xAF, 0xD7, 0xF9, 0x71, 0x61, 0xB7, + 0xB5, 0x68, 0x3C, 0x29, 0x95, 0x67, 0x9E, 0x23, + 0x85, 0x3B, 0x72, 0xF4, 0x69, 0xCB, 0x55, 0xD8, + 0x5E, 0x4B, 0xF6, 0xCA, 0x42, 0xB3, 0xC3, 0x99, + 0x76, 0x70, 0xC2, 0x3E, 0xE2, 0x59, 0xBC, 0x6D, + 0x3A, 0xE4, 0xA1, 0x6A, 0x80, 0x9A, 0x28, 0x1E, + 0xCB, 0xC8, 0xB6, 0x6A, 0x46, 0x78, 0x81, 0xBB, + 0x7B, 0x9F, 0xF5, 0xDF, 0xD2, 0x98, 0x57, 0x17, + 0x54, 0xD1, 0xA8, 0x6D, 0xB5, 0xC5, 0xCC, 0x47, + 0x92, 0x2A, 0xEB, 0x3D, 0xF7, 0x6B, 0x18, 0x28, + 0x24, 0x58, 0x30, 0x7B, 0x91, 0x1D, 0x05, 0xD7, + 0x2F, 0x70, 0xBC, 0xD9, 0xF1, 0x0F, 0x74, 0x37, + 0x8B, 0x6A, 0x29, 0x0B, 0x7A, 0x9C, 0xD7, 0x6E, + 0x44, 0xA0, 0xE2, 0x49, 0x01, 0xC2, 0xB5, 0x68, + 0x1A, 0x53, 0xA9, 0xD0, 0x51, 0xA1, 0x29, 0x53, + 0x01, 0x27, 0x15, 0x61, 0xA7, 0x00, 0x63, 0x21, + 0xA2, 0xA2, 0x0C, 0xC0, 0x37, 0xC8, 0x26, 0x0A, + 0xD8, 0xB0, 0x4D, 0x37, 0xA6, 0x87, 0x48, 0x07, + 0x34, 0x22, 0xEA, 0x11, 0x8E, 0xEE, 0x35, 0x57, + 0x7A, 0x2A, 0xC6, 0x1F, 0xFD, 0x53, 0x6D, 0xFE, + 0x21, 0xE0, 0x1B, 0x36, 0xF6, 0x30, 0x01, 0x42, + 0xD7, 0xC1, 0xF6, 0xAE, 0xEE, 0xA2, 0x19, 0x2C, + 0xFB, 0x2B, 0xB8, 0xE5, 0x50, 0xEB, 0x71, 0x0D, + 0x20, 0xE2, 0x97, 0xBA, 0xFA, 0xF0, 0xD8, 0xF6, + 0x91, 0x8E, 0x1C, 0x12, 0xBE, 0xBC, 0xAF, 0x3E, + 0xC8, 0x3A, 0xA3, 0x57, 0xE2, 0xFB, 0x70, 0x00, + 0xF5, 0xD7, 0xDE, 0xF4, 0xA0, 0x80, 0x25, 0x9B, + 0x7E, 0xB7, 0x52, 0xDB, 0xA7, 0xC0, 0xEC, 0x30, + 0x79, 0x13, 0xD8, 0xFF, 0x98, 0x54, 0x7A, 0x27, + 0x33, 0x85, 0x1D, 0xDA, 0x89, 0x7B, 0x95, 0xAB, + 0xAC, 0x8E, 0x22, 0xE7, 0x85, 0x95, 0x98, 0x29, + 0x19, 0x12, 0xBD, 0x29, 0x0A, 0xA9, 0xF3, 0xD5, + 0x61, 0xD7, 0x17, 0xA3, 0x8A, 0xE0, 0xA8, 0x25, + 0xA0, 0x09, 0x2C, 0xDE, 0xEC, 0x08, 0xCF, 0x54, + 0xA8, 0xB9, 0x4E, 0x66, 0x08, 0x12, 0x13, 0xE0, + 0x7B, 0x59, 0xA2, 0x4D, 0x2E, 0x94, 0x33, 0x0C, + 0xD1, 0x42, 0xA0, 0xA6, 0xCC, 0x80, 0x7F, 0xA8 +}; + +/* Frame length is 503 bytes with CRC. */ +static const uint8_t test_packet_ipv4_udp_503_crc[] = { + 0x12, 0xA5, 0xD4, 0xC0, 0xC6, 0xC4, 0x1A, 0xCA, + 0xB9, 0x97, 0x2B, 0x57, 0x08, 0x00, 0x45, 0x00, + 0x01, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xAA, 0x01, 0xC0, 0xA8, 0xDE, 0x34, 0xC0, 0xA8, + 0x6F, 0x81, 0x00, 0x3F, 0x00, 0x3F, 0x01, 0xD1, + 0xD3, 0xC9, 0x46, 0x40, 0x04, 0x0F, 0x98, 0xEF, + 0x43, 0xB0, 0xDC, 0xEC, 0x33, 0x67, 0x66, 0x85, + 0xFD, 0x87, 0xC9, 0x58, 0xD7, 0x41, 0x02, 0xB8, + 0xD7, 0x24, 0xF2, 0x53, 0x04, 0xE5, 0x12, 0x11, + 0xB3, 0x5C, 0x62, 0x3F, 0x11, 0xD0, 0xA2, 0xEC, + 0xFC, 0x74, 0xC5, 0x93, 0x17, 0x31, 0xA3, 0xFB, + 0x1D, 0xA6, 0xEE, 0x5C, 0x75, 0x6E, 0x67, 0xC3, + 0x07, 0xA1, 0x51, 0xB7, 0x4F, 0x9D, 0x26, 0x1D, + 0xAF, 0x06, 0x8A, 0x59, 0x0A, 0x0B, 0x7D, 0xB6, + 0x8E, 0xEB, 0xD4, 0x08, 0xD1, 0xB8, 0xEA, 0x90, + 0x20, 0x5C, 0x93, 0x1F, 0x14, 0xD9, 0x51, 0x7E, + 0x65, 0xD5, 0xCB, 0x0E, 0x03, 0x55, 0x7A, 0xAC, + 0x63, 0xC9, 0xA6, 0xD7, 0x17, 0x49, 0x91, 0x15, + 0xA2, 0x1E, 0xF2, 0x92, 0x8A, 0x84, 0xA4, 0x0B, + 0xAF, 0xAE, 0xA0, 0xEA, 0xDA, 0x0B, 0x29, 0xB3, + 0x99, 0xC8, 0x46, 0x9E, 0x4B, 0x96, 0x75, 0x86, + 0x77, 0xAD, 0x9E, 0x01, 0x62, 0x10, 0x46, 0xD1, + 0xE0, 0x13, 0x05, 0x7B, 0x6A, 0x1B, 0x3A, 0x35, + 0x71, 0xA6, 0xFD, 0x05, 0xF2, 0x8B, 0x55, 0x28, + 0x4B, 0x82, 0xAB, 0xB1, 0x4D, 0xE6, 0x7F, 0x72, + 0x92, 0xBA, 0x5A, 0x1F, 0x10, 0xEB, 0x04, 0xB1, + 0xEF, 0xD4, 0xF6, 0x09, 0x98, 0x07, 0x12, 0xD6, + 0x0F, 0x4B, 0x92, 0xB8, 0x82, 0xE1, 0x3F, 0xA6, + 0x22, 0x0C, 0xE3, 0x8D, 0x31, 0xD0, 0x00, 0x39, + 0x5C, 0xF9, 0xC2, 0x79, 0x4C, 0x5F, 0x33, 0x7E, + 0x78, 0x69, 0xAE, 0x85, 0x3D, 0xD0, 0x96, 0xB6, + 0x30, 0xA5, 0x47, 0x4B, 0xB3, 0x96, 0x4D, 0xF4, + 0xC6, 0x6D, 0xD5, 0x7A, 0x20, 0xD9, 0x60, 0xA3, + 0x7F, 0x71, 0xBF, 0x57, 0x3C, 0xF6, 0x3B, 0x00, + 0x22, 0xD8, 0x14, 0x37, 0x80, 0xFC, 0x2D, 0x9C, + 0x7D, 0xBD, 0x05, 0x05, 0xAC, 0x31, 0xE9, 0xDC, + 0xE0, 0xAD, 0x68, 0xC2, 0x42, 0x8B, 0x08, 0x78, + 0xA0, 0x2A, 0x37, 0x00, 0x08, 0x37, 0x84, 0xFF, + 0x96, 0x2B, 0x0F, 0x66, 0x8A, 0x15, 0x3E, 0x51, + 0x9D, 0x9A, 0xB2, 0x30, 0x96, 0x3A, 0x7A, 0x24, + 0x18, 0xD5, 0x86, 0xAC, 0xBE, 0x6D, 0x5E, 0x80, + 0x6A, 0x2D, 0x14, 0xBD, 0xD9, 0xAA, 0x76, 0x43, + 0x7B, 0x6A, 0x89, 0x5B, 0x82, 0xA3, 0x33, 0x9E, + 0x39, 0x44, 0x38, 0x12, 0x98, 0x39, 0x68, 0x95, + 0x15, 0xEB, 0x16, 0x7F, 0xBC, 0x07, 0xCB, 0x83, + 0x82, 0x81, 0x3C, 0xD6, 0xD7, 0xD8, 0x7A, 0x93, + 0x7A, 0x9B, 0x69, 0x5F, 0x91, 0x2C, 0x73, 0x49, + 0xF9, 0xC4, 0x7D, 0xF3, 0xDB, 0xB7, 0x1A, 0xF7, + 0x80, 0xFA, 0xFF, 0x84, 0x66, 0xE2, 0xB8, 0x48, + 0x93, 0x2E, 0x99, 0x93, 0x29, 0x48, 0xF6, 0xB9, + 0x3B, 0xC8, 0x97, 0xB8, 0xDF, 0x3A, 0x66, 0x1A, + 0x84, 0x21, 0x6B, 0x1D, 0x86, 0x3C, 0xFA, 0x12, + 0x00, 0x07, 0x2B, 0x03, 0xE2, 0x85, 0x8B, 0x98, + 0x43, 0x3D, 0x11, 0x3B, 0xF8, 0x82, 0x54, 0x7B, + 0x65, 0xF8, 0xFA, 0xAE, 0x93, 0x54, 0x74, 0xDB, + 0x83, 0x63, 0xE9, 0xD7, 0xC2, 0x4E, 0x6F, 0xAD, + 0x3E, 0x1C, 0x81, 0x43, 0x58, 0x78, 0xAE, 0x3B, + 0x3A, 0xB5, 0x8E, 0x18, 0x6B, 0x0F, 0xFA, 0xA2, + 0xA0, 0x34, 0x7C, 0x8B, 0xD6, 0x03, 0x05, 0x52, + 0x9D, 0x93, 0xDE, 0x68, 0xB7, 0x77, 0xE1, 0x92, + 0xE1, 0x40, 0xE9, 0x8E, 0xF1, 0x44, 0x87, 0xF9, + 0x21, 0x9E, 0xF7, 0x70, 0xAB, 0x76, 0x52, 0xF6, + 0x96, 0x83, 0x04, 0x4C, 0x80, 0xEF, 0x86 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/common/test_packet_ipv6.h b/test/common/test_packet_ipv6.h new file mode 100644 index 000000000..8703aab34 --- /dev/null +++ b/test/common/test_packet_ipv6.h @@ -0,0 +1,123 @@ +/* Copyright (c) 2017-2018, Linaro Limited + * Copyright (c) 2021, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_PACKET_IPV6_H_ +#define TEST_PACKET_IPV6_H_ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Test packets without CRC */ + +/* ICMPv6 echo request */ +static const uint8_t test_packet_ipv6_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02 +}; + +/* IPv6 TCP */ +static const uint8_t test_packet_ipv6_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x50, 0x02, 0x00, 0x00, 0x36, 0x35, + 0x00, 0x00 +}; + +/* IPv6 UDP */ +static const uint8_t test_packet_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68 +}; + +/* VLAN IPv6 + * - type 0x8100, tag 23 + */ +static const uint8_t test_packet_vlan_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, + 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, + 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, + 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, + 0x9B, 0x68 +}; + +/* IPv6 SCTP + * - chunk type: payload data + */ +static const uint8_t test_packet_ipv6_sctp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x63, 0x84, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x16, 0x2E, 0xDE, 0xAD, 0xBE, 0xEF, 0x31, 0x44, + 0xE3, 0xFE, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, + 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, + 0x73, 0x20, 0x6D, 0x79, 0x20, 0x64, 0x75, 0x6D, + 0x6D, 0x79, 0x20, 0x70, 0x61, 0x79, 0x6C, 0x6F, + 0x61, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, + 0x67, 0x2E, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6C, + 0x65, 0x6E, 0x67, 0x74, 0x68, 0x20, 0x6F, 0x66, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6E, 0x67, 0x20, 0x69, 0x73, 0x20, + 0x37, 0x31, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x2E +}; + +/* Multi-cast Ethernet, IPv6 UDP */ +static const uint8_t test_packet_mcast_eth_ipv6_udp[] = { + 0x33, 0x33, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00, + 0x00, 0x03, 0x04, 0x05, 0x86, 0xDD, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x4F, 0x11, 0x40, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFE, 0x03, 0x04, 0x05, 0xFF, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x04, 0xD2, + 0x16, 0x2E, 0x00, 0x4F, 0xD6, 0x79, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6D, 0x79, + 0x20, 0x64, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x70, + 0x61, 0x79, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E, 0x20, 0x54, + 0x68, 0x65, 0x20, 0x6C, 0x65, 0x6E, 0x67, 0x74, + 0x68, 0x20, 0x6F, 0x66, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, + 0x20, 0x69, 0x73, 0x20, 0x37, 0x31, 0x20, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x2E +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/miscellaneous/odp_api_from_cpp.cpp b/test/miscellaneous/odp_api_from_cpp.cpp index f3297093a..c5aae0c3f 100644 --- a/test/miscellaneous/odp_api_from_cpp.cpp +++ b/test/miscellaneous/odp_api_from_cpp.cpp @@ -1,3 +1,4 @@ +#include <stdlib.h> #include <iostream> #include <odp_api.h> #include <odp/helper/odph_api.h> @@ -6,14 +7,20 @@ int main(int argc ODP_UNUSED, const char *argv[] ODP_UNUSED) { odp_instance_t inst; - odp_init_global(&inst, NULL, NULL); - odp_init_local(inst, ODP_THREAD_WORKER); + if (odp_init_global(&inst, NULL, NULL)) + exit(EXIT_FAILURE); + + if (odp_init_local(inst, ODP_THREAD_WORKER)) + exit(EXIT_FAILURE); std::cout << "\tODP API version: " << odp_version_api_str() << std::endl; std::cout << "\tODP implementation version: " << odp_version_impl_str() << std::endl; - odp_term_local(); - odp_term_global(inst); + if (odp_term_local()) + exit(EXIT_FAILURE); + + if (odp_term_global(inst)) + exit(EXIT_FAILURE); return 0; } diff --git a/test/performance/.gitignore b/test/performance/.gitignore index 0e6d9ef57..0d70a025b 100644 --- a/test/performance/.gitignore +++ b/test/performance/.gitignore @@ -4,6 +4,7 @@ odp_atomic odp_atomic_perf odp_bench_packet odp_cpu_bench +odp_crc odp_crypto odp_ipsec odp_l2fwd diff --git a/test/performance/Makefile.am b/test/performance/Makefile.am index 06866ae39..15c6f46e0 100644 --- a/test/performance/Makefile.am +++ b/test/performance/Makefile.am @@ -5,6 +5,7 @@ TESTS_ENVIRONMENT += TEST_DIR=${builddir} EXECUTABLES = odp_atomic_perf \ odp_bench_packet \ odp_cpu_bench \ + odp_crc \ odp_crypto \ odp_ipsec \ odp_mem_perf \ @@ -43,6 +44,7 @@ bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY) odp_atomic_perf_SOURCES = odp_atomic_perf.c odp_bench_packet_SOURCES = odp_bench_packet.c odp_cpu_bench_SOURCES = odp_cpu_bench.c +odp_crc_SOURCES = odp_crc.c odp_crypto_SOURCES = odp_crypto.c odp_ipsec_SOURCES = odp_ipsec.c odp_mem_perf_SOURCES = odp_mem_perf.c diff --git a/test/performance/odp_atomic_perf.c b/test/performance/odp_atomic_perf.c index 887525f50..b56135c35 100644 --- a/test/performance/odp_atomic_perf.c +++ b/test/performance/odp_atomic_perf.c @@ -1286,12 +1286,20 @@ static test_case_t test_suite[] = { int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; odp_shm_t shm; test_options_t test_options; int num_tests, i; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } + if (parse_options(argc, argv, &test_options)) exit(EXIT_FAILURE); @@ -1306,6 +1314,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { ODPH_ERR("Global init failed.\n"); diff --git a/test/performance/odp_bench_packet.c b/test/performance/odp_bench_packet.c index cf79b9618..e80e823f6 100644 --- a/test/performance/odp_bench_packet.c +++ b/test/performance/odp_bench_packet.c @@ -17,7 +17,8 @@ #include <inttypes.h> #include <signal.h> -#include <test_packet_parser.h> +#include <test_packet_ipv4.h> +#include <test_packet_ipv6.h> #include <odp_api.h> #include <odp/helper/odph_api.h> diff --git a/test/performance/odp_crc.c b/test/performance/odp_crc.c new file mode 100644 index 000000000..89e8af837 --- /dev/null +++ b/test/performance/odp_crc.c @@ -0,0 +1,300 @@ +/* Copyright (c) 2021, Nokia + * + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <inttypes.h> +#include <getopt.h> + +#include <odp_api.h> +#include <odp/helper/odph_api.h> + +#define KB 1024ull +#define MB (1024ull * 1024ull) + +/* Command line options */ +typedef struct { + uint32_t size; + uint32_t rounds; + uint32_t offset; + uint32_t test; +} options_t; + +static options_t options; +static const options_t options_def = { + .size = 16, + .rounds = 10000, + .offset = 0, + .test = 0, +}; + +static void print_usage(void) +{ + printf("\n" + "CRC performance test\n" + "\n" + "Usage: odp_crc_perf [options]\n" + "\n" + " -s, --size Size of buffer in KB (default %u)\n" + " -r, --rounds Number of test rounds (default %u)\n" + " Rounded down to nearest multiple of 8\n" + " -o, --offset Offset of data (default %u)\n" + " -t, --test Which API to test (default %u)\n" + " 0: both\n" + " 1: odp_hash_crc32c\n" + " 2: odp_hash_crc32\n" + " -h, --help This help\n" + "\n", + options_def.size, options_def.rounds, options_def.offset, + options.test); +} + +static int parse_options(int argc, char *argv[]) +{ + int opt; + int long_index; + int ret = 0; + + static const struct option longopts[] = { + { "size", required_argument, NULL, 's' }, + { "rounds", required_argument, NULL, 'r' }, + { "offset", required_argument, NULL, 'o' }, + { "test", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } + }; + + static const char *shortopts = "+s:r:o:t:h"; + + options = options_def; + + while (1) { + opt = getopt_long(argc, argv, shortopts, longopts, &long_index); + + if (opt == -1) + break; + + switch (opt) { + case 's': + options.size = atol(optarg); + break; + case 'r': + options.rounds = atol(optarg); + break; + case 'o': + options.offset = atol(optarg); + break; + case 't': + options.test = atol(optarg); + break; + case 'h': + /* fall through */ + default: + print_usage(); + ret = -1; + break; + } + } + + if (options.size < 1) { + ODPH_ERR("Invalid size: %" PRIu32 "\n", options.size); + return -1; + } + + if (options.offset > 4 * KB) { + ODPH_ERR("Invalid offset: %" PRIu32 "\n", options.offset); + return -1; + } + + if (options.test > 2) { + ODPH_ERR("Invalid API to test: %" PRIu32 "\n", options.test); + return -1; + } + + return ret; +} + +static void report(uint64_t nsec) +{ + uint64_t size = (uint64_t)options.size * KB; + uint32_t rounds = options.rounds & ~7ul; + double mb, seconds; + + printf("size: %d KB rounds: %d offset: %d ", + options.size, rounds, options.offset); + mb = (double)(size * (uint64_t)rounds) / (double)MB; + seconds = (double)nsec / (double)ODP_TIME_SEC_IN_NS; + printf("MB: %.3f seconds: %.3f ", mb, seconds); + printf("MB/s: %.3f", mb / seconds); + printf("\n\n"); +} + +static uint64_t measure_crc32c(uint8_t *data, uint32_t size) +{ + void *p = data + options.offset; + uint32_t crc = 1; + volatile uint32_t v; + odp_time_t start = odp_time_local(); + + for (uint32_t i = 0; i < options.rounds / 8; i++) { + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + crc ^= odp_hash_crc32c(p, size, crc); + } + + /* Make sure that crc is not optimized out. */ + v = crc; + + /* Quell "unused" warning. */ + (void)v; + + return odp_time_diff_ns(odp_time_local(), start); +} + +static void test_odp_hash_crc32c(uint8_t *data) +{ + uint64_t size = (uint64_t)options.size * KB; + uint64_t nsec; + + /* Warm-up. */ + measure_crc32c(data, size); + + /* Actual measurement. */ + nsec = measure_crc32c(data, size); + + report(nsec); +} + +static uint64_t measure_crc32(uint8_t *data, uint32_t size) +{ + void *p = data + options.offset; + uint32_t crc = 1; + volatile uint32_t v; + odp_time_t start = odp_time_local(); + + for (uint32_t i = 0; i < options.rounds / 8; i++) { + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + crc ^= odp_hash_crc32(p, size, crc); + } + + /* Make sure that crc is not optimized out. */ + v = crc; + + /* Quell "unused" warning. */ + (void)v; + + return odp_time_diff_ns(odp_time_local(), start); +} + +static void test_odp_hash_crc32(uint8_t *data) +{ + uint64_t size = (uint64_t)options.size * KB; + uint64_t nsec; + + /* Warm-up. */ + measure_crc32(data, size); + + /* Actual measurement. */ + nsec = measure_crc32(data, size); + + report(nsec); +} + +int main(int argc, char **argv) +{ + odp_instance_t instance; + odp_init_t init; + + if (parse_options(argc, argv)) + exit(EXIT_FAILURE); + + /* List features not to be used */ + odp_init_param_init(&init); + init.not_used.feat.cls = 1; + init.not_used.feat.compress = 1; + init.not_used.feat.crypto = 1; + init.not_used.feat.ipsec = 1; + init.not_used.feat.schedule = 1; + init.not_used.feat.stash = 1; + init.not_used.feat.timer = 1; + init.not_used.feat.tm = 1; + + /* Init ODP before calling anything else */ + if (odp_init_global(&instance, &init, NULL)) { + ODPH_ERR("Global init failed.\n"); + exit(EXIT_FAILURE); + } + + /* Init this thread */ + if (odp_init_local(instance, ODP_THREAD_CONTROL)) { + ODPH_ERR("Local init failed.\n"); + exit(EXIT_FAILURE); + } + + odp_sys_info_print(); + + uint8_t *buf, *data; + uint32_t size = options.size * KB; + uint64_t seed = 1; + const unsigned long page = 4 * KB; + + /* One extra page for alignment, another one for offset. */ + buf = (uint8_t *)malloc(size + page * 2); + + if (!buf) { + ODPH_ERR("Memory allocation failed.\n"); + exit(EXIT_FAILURE); + } + + /* Align to start of page. */ + data = (uint8_t *)(((uintptr_t)buf + (page - 1)) & ~(page - 1)); + + if (odp_random_test_data(data, size, &seed) != (int32_t)size) { + ODPH_ERR("odp_random_test_data() failed.\n"); + exit(EXIT_FAILURE); + } + + if (options.test == 0 || options.test == 1) { + printf("odp_hash_crc32c\n" + "---------------\n"); + test_odp_hash_crc32c(data); + } + + if (options.test == 0 || options.test == 2) { + printf("odp_hash_crc32\n" + "--------------\n"); + test_odp_hash_crc32(data); + } + + free(buf); + + if (odp_term_local()) { + ODPH_ERR("Local terminate failed.\n"); + exit(EXIT_FAILURE); + } + + if (odp_term_global(instance)) { + ODPH_ERR("Global terminate failed.\n"); + exit(EXIT_FAILURE); + } + + return 0; +} diff --git a/test/performance/odp_mem_perf.c b/test/performance/odp_mem_perf.c index 0470d337a..1348eaaa2 100644 --- a/test/performance/odp_mem_perf.c +++ b/test/performance/odp_mem_perf.c @@ -47,8 +47,6 @@ struct test_global_t { }; -static test_global_t test_global; - static void print_usage(void) { printf("\n" @@ -388,15 +386,18 @@ static void print_stat(test_global_t *global) int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; + odp_shm_t shm; test_global_t *global; - global = &test_global; - memset(global, 0, sizeof(test_global_t)); - - if (parse_options(argc, argv, &global->test_options)) - return -1; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } /* List features not to be used */ odp_init_param_init(&init); @@ -408,6 +409,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { ODPH_ERR("Global init failed.\n"); @@ -420,6 +423,23 @@ int main(int argc, char **argv) return -1; } + shm = odp_shm_reserve("mem_perf_global", sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Shared mem reserve failed.\n"); + exit(EXIT_FAILURE); + } + + global = odp_shm_addr(shm); + if (global == NULL) { + ODPH_ERR("Shared mem alloc failed\n"); + exit(EXIT_FAILURE); + } + + memset(global, 0, sizeof(test_global_t)); + + if (parse_options(argc, argv, &global->test_options)) + return -1; + odp_sys_info_print(); if (set_num_cpu(global)) @@ -440,6 +460,11 @@ int main(int argc, char **argv) if (free_shm(global)) return -1; + if (odp_shm_free(shm)) { + ODPH_ERR("Shared mem free failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_local()) { ODPH_ERR("term local failed.\n"); return -1; diff --git a/test/performance/odp_packet_gen.c b/test/performance/odp_packet_gen.c index b903eb200..f3919ebac 100644 --- a/test/performance/odp_packet_gen.c +++ b/test/performance/odp_packet_gen.c @@ -279,8 +279,14 @@ static int parse_options(int argc, char *argv[], test_global_t *global) sizeof(test_options->ipv4_src_s) - 1); strncpy(test_options->ipv4_dst_s, "192.168.0.2", sizeof(test_options->ipv4_dst_s) - 1); - odph_ipv4_addr_parse(&test_options->ipv4_src, test_options->ipv4_src_s); - odph_ipv4_addr_parse(&test_options->ipv4_dst, test_options->ipv4_dst_s); + if (odph_ipv4_addr_parse(&test_options->ipv4_src, test_options->ipv4_src_s)) { + ODPH_ERR("Address parse failed\n"); + return -1; + } + if (odph_ipv4_addr_parse(&test_options->ipv4_dst, test_options->ipv4_dst_s)) { + ODPH_ERR("Address parse failed\n"); + return -1; + } test_options->udp_src = 10000; test_options->udp_dst = 20000; test_options->c_mode.udp_src = 0; @@ -1729,6 +1735,7 @@ static void sig_handler(int signo) int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; test_global_t *global; @@ -1738,6 +1745,13 @@ int main(int argc, char **argv) signal(SIGINT, sig_handler); + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } + /* List features not to be used */ odp_init_param_init(&init); init.not_used.feat.cls = 1; @@ -1747,6 +1761,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { printf("Error: Global init failed.\n"); diff --git a/test/performance/odp_pool_perf.c b/test/performance/odp_pool_perf.c index 28471875c..ee97af519 100644 --- a/test/performance/odp_pool_perf.c +++ b/test/performance/odp_pool_perf.c @@ -1,5 +1,5 @@ /* Copyright (c) 2018, Linaro Limited - * Copyright (c) 2019, Nokia + * Copyright (c) 2019-2021, Nokia * * All rights reserved. * @@ -23,6 +23,7 @@ typedef struct test_options_t { uint32_t max_burst; uint32_t num_burst; uint32_t data_size; + uint32_t cache_size; int pool_type; } test_options_t; @@ -47,8 +48,6 @@ typedef struct test_global_t { } test_global_t; -test_global_t test_global; - static void print_usage(void) { printf("\n" @@ -64,6 +63,7 @@ static void print_usage(void) " -s, --data_size Data size in bytes\n" " -t, --pool_type 0: Buffer pool (default)\n" " 1: Packet pool\n" + " -C, --cache_size Pool cache size (per thread)\n" " -h, --help This help\n" "\n"); } @@ -75,26 +75,28 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options) int ret = 0; static const struct option longopts[] = { - {"num_cpu", required_argument, NULL, 'c'}, - {"num_event", required_argument, NULL, 'e'}, - {"num_round", required_argument, NULL, 'r'}, - {"burst", required_argument, NULL, 'b'}, - {"num_burst", required_argument, NULL, 'n'}, - {"data_size", required_argument, NULL, 's'}, - {"pool_type", required_argument, NULL, 't'}, - {"help", no_argument, NULL, 'h'}, + {"num_cpu", required_argument, NULL, 'c'}, + {"num_event", required_argument, NULL, 'e'}, + {"num_round", required_argument, NULL, 'r'}, + {"burst", required_argument, NULL, 'b'}, + {"num_burst", required_argument, NULL, 'n'}, + {"data_size", required_argument, NULL, 's'}, + {"pool_type", required_argument, NULL, 't'}, + {"cache_size", required_argument, NULL, 'C'}, + {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; - static const char *shortopts = "+c:e:r:b:n:s:t:h"; + static const char *shortopts = "+c:e:r:b:n:s:t:C:h"; - test_options->num_cpu = 1; - test_options->num_event = 1000; - test_options->num_round = 100000; - test_options->max_burst = 100; - test_options->num_burst = 1; - test_options->data_size = 64; - test_options->pool_type = 0; + test_options->num_cpu = 1; + test_options->num_event = 1000; + test_options->num_round = 100000; + test_options->max_burst = 100; + test_options->num_burst = 1; + test_options->data_size = 64; + test_options->pool_type = 0; + test_options->cache_size = UINT32_MAX; while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); @@ -124,6 +126,9 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options) case 't': test_options->pool_type = atoi(optarg); break; + case 'C': + test_options->cache_size = atoi(optarg); + break; case 'h': /* fall through */ default: @@ -181,16 +186,23 @@ static int create_pool(test_global_t *global) odp_pool_capability_t pool_capa; odp_pool_param_t pool_param; odp_pool_t pool; - uint32_t max_num, max_size; + uint32_t max_num, max_size, min_cache_size, max_cache_size; test_options_t *test_options = &global->test_options; - uint32_t num_event = test_options->num_event; - uint32_t num_round = test_options->num_round; - uint32_t max_burst = test_options->max_burst; - uint32_t num_burst = test_options->num_burst; - uint32_t num_cpu = test_options->num_cpu; - uint32_t data_size = test_options->data_size; + uint32_t num_event = test_options->num_event; + uint32_t num_round = test_options->num_round; + uint32_t max_burst = test_options->max_burst; + uint32_t num_burst = test_options->num_burst; + uint32_t num_cpu = test_options->num_cpu; + uint32_t data_size = test_options->data_size; + uint32_t cache_size = test_options->cache_size; int packet_pool = test_options->pool_type; + odp_pool_param_init(&pool_param); + + if (cache_size == UINT32_MAX) + cache_size = packet_pool ? pool_param.pkt.cache_size : + pool_param.buf.cache_size; + printf("\nPool performance test\n"); printf(" num cpu %u\n", num_cpu); printf(" num rounds %u\n", num_round); @@ -198,6 +210,7 @@ static int create_pool(test_global_t *global) printf(" max burst %u\n", max_burst); printf(" num bursts %u\n", num_burst); printf(" data size %u\n", data_size); + printf(" cache size %u\n", cache_size); printf(" pool type %s\n\n", packet_pool ? "packet" : "buffer"); if (odp_pool_capability(&pool_capa)) { @@ -206,11 +219,25 @@ static int create_pool(test_global_t *global) } if (packet_pool) { - max_num = pool_capa.pkt.max_num; - max_size = pool_capa.pkt.max_len; + max_num = pool_capa.pkt.max_num; + max_size = pool_capa.pkt.max_len; + max_cache_size = pool_capa.pkt.max_cache_size; + min_cache_size = pool_capa.pkt.min_cache_size; } else { - max_num = pool_capa.buf.max_num; - max_size = pool_capa.buf.max_size; + max_num = pool_capa.buf.max_num; + max_size = pool_capa.buf.max_size; + max_cache_size = pool_capa.buf.max_cache_size; + min_cache_size = pool_capa.buf.min_cache_size; + } + + if (cache_size < min_cache_size) { + printf("Error: min cache size supported %u\n", min_cache_size); + return -1; + } + + if (cache_size > max_cache_size) { + printf("Error: max cache size supported %u\n", max_cache_size); + return -1; } if (max_num && num_event > max_num) { @@ -223,19 +250,19 @@ static int create_pool(test_global_t *global) return -1; } - odp_pool_param_init(&pool_param); - if (packet_pool) { - pool_param.type = ODP_POOL_PACKET; - pool_param.pkt.num = num_event; - pool_param.pkt.len = data_size; - pool_param.pkt.max_num = num_event; - pool_param.pkt.max_len = data_size; + pool_param.type = ODP_POOL_PACKET; + pool_param.pkt.num = num_event; + pool_param.pkt.len = data_size; + pool_param.pkt.max_num = num_event; + pool_param.pkt.max_len = data_size; + pool_param.pkt.cache_size = cache_size; } else { - pool_param.type = ODP_POOL_BUFFER; - pool_param.buf.num = num_event; - pool_param.buf.size = data_size; + pool_param.type = ODP_POOL_BUFFER; + pool_param.buf.num = num_event; + pool_param.buf.size = data_size; + pool_param.buf.cache_size = cache_size; } pool = odp_pool_create("pool perf", &pool_param); @@ -514,16 +541,18 @@ static void print_stat(test_global_t *global) int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; + odp_shm_t shm; test_global_t *global; - global = &test_global; - memset(global, 0, sizeof(test_global_t)); - global->pool = ODP_POOL_INVALID; - - if (parse_options(argc, argv, &global->test_options)) - return -1; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: Reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } /* List features not to be used */ odp_init_param_init(&init); @@ -535,6 +564,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { printf("Error: Global init failed.\n"); @@ -547,6 +578,24 @@ int main(int argc, char **argv) return -1; } + shm = odp_shm_reserve("pool_perf_global", sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Error: Shared mem reserve failed.\n"); + exit(EXIT_FAILURE); + } + + global = odp_shm_addr(shm); + if (global == NULL) { + ODPH_ERR("Error: Shared mem alloc failed\n"); + exit(EXIT_FAILURE); + } + + memset(global, 0, sizeof(test_global_t)); + global->pool = ODP_POOL_INVALID; + + if (parse_options(argc, argv, &global->test_options)) + return -1; + odp_sys_info_print(); if (set_num_cpu(global)) @@ -568,6 +617,11 @@ int main(int argc, char **argv) return -1; } + if (odp_shm_free(shm)) { + ODPH_ERR("Error: Shared mem free failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_local()) { printf("Error: term local failed.\n"); return -1; diff --git a/test/performance/odp_queue_perf.c b/test/performance/odp_queue_perf.c index 036cfc1ea..33284d312 100644 --- a/test/performance/odp_queue_perf.c +++ b/test/performance/odp_queue_perf.c @@ -1,4 +1,5 @@ /* Copyright (c) 2018, Linaro Limited + * Copyright (c) 2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -48,8 +49,6 @@ typedef struct test_global_t { } test_global_t; -static test_global_t test_global; - static void print_usage(void) { printf("\n" @@ -528,10 +527,19 @@ static void print_stat(test_global_t *global) int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; + odp_shm_t shm; test_global_t *global; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: Reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } + /* List features not to be used */ odp_init_param_init(&init); init.not_used.feat.cls = 1; @@ -542,6 +550,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { printf("Error: Global init failed.\n"); @@ -554,7 +564,18 @@ int main(int argc, char **argv) return -1; } - global = &test_global; + shm = odp_shm_reserve("queue_perf_global", sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Error: Shared mem reserve failed.\n"); + exit(EXIT_FAILURE); + } + + global = odp_shm_addr(shm); + if (global == NULL) { + ODPH_ERR("Error: Shared mem alloc failed\n"); + exit(EXIT_FAILURE); + } + memset(global, 0, sizeof(test_global_t)); if (parse_options(argc, argv, &global->options)) @@ -585,6 +606,11 @@ destroy: return -1; } + if (odp_shm_free(shm)) { + ODPH_ERR("Error: Shared mem free failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_local()) { printf("Error: term local failed.\n"); return -1; diff --git a/test/performance/odp_sched_perf.c b/test/performance/odp_sched_perf.c index fa93aa18d..148bf11d5 100644 --- a/test/performance/odp_sched_perf.c +++ b/test/performance/odp_sched_perf.c @@ -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 @@ -84,8 +84,6 @@ typedef struct test_global_t { } test_global_t; -test_global_t test_global; - static void print_usage(void) { printf("\n" @@ -906,7 +904,11 @@ static int test_sched(void *arg) queue = *next; } - odp_queue_enq(queue, ev[0]); + if (odp_queue_enq(queue, ev[0])) { + printf("Error: Queue enqueue failed\n"); + odp_event_free(ev[0]); + ret = -1; + } } return ret; @@ -1081,17 +1083,18 @@ static void print_stat(test_global_t *global) int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; + odp_shm_t shm; test_global_t *global; - global = &test_global; - memset(global, 0, sizeof(test_global_t)); - global->pool = ODP_POOL_INVALID; - global->ctx_shm = ODP_SHM_INVALID; - - if (parse_options(argc, argv, &global->test_options)) - return -1; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Error: Reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } /* List features not to be used */ odp_init_param_init(&init); @@ -1102,6 +1105,8 @@ int main(int argc, char **argv) init.not_used.feat.timer = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { printf("Error: Global init failed.\n"); @@ -1114,6 +1119,25 @@ int main(int argc, char **argv) return -1; } + shm = odp_shm_reserve("sched_perf_global", sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Error: SHM reserve failed.\n"); + exit(EXIT_FAILURE); + } + + global = odp_shm_addr(shm); + if (global == NULL) { + ODPH_ERR("Error: SHM alloc failed\n"); + exit(EXIT_FAILURE); + } + + memset(global, 0, sizeof(test_global_t)); + global->pool = ODP_POOL_INVALID; + global->ctx_shm = ODP_SHM_INVALID; + + if (parse_options(argc, argv, &global->test_options)) + return -1; + odp_sys_info_print(); if (global->test_options.ctx_size) { @@ -1166,6 +1190,11 @@ int main(int argc, char **argv) if (global->ctx_shm != ODP_SHM_INVALID) odp_shm_free(global->ctx_shm); + if (odp_shm_free(shm)) { + ODPH_ERR("Error: SHM free failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_local()) { printf("Error: term local failed.\n"); return -1; diff --git a/test/performance/odp_timer_perf.c b/test/performance/odp_timer_perf.c index be0fc363a..4b8318557 100644 --- a/test/performance/odp_timer_perf.c +++ b/test/performance/odp_timer_perf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2020, Nokia +/* Copyright (c) 2019-2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -110,7 +110,7 @@ typedef struct test_global_t { } test_global_t; -test_global_t test_global; +test_global_t *test_global; static void print_usage(void) { @@ -946,35 +946,29 @@ static void sig_handler(int signo) { (void)signo; - odp_atomic_add_u32(&test_global.exit_test, MAX_TIMER_POOLS); + if (test_global == NULL) + return; + odp_atomic_add_u32(&test_global->exit_test, MAX_TIMER_POOLS); } int main(int argc, char **argv) { + odph_helper_options_t helper_options; odp_instance_t instance; odp_init_t init; + odp_shm_t shm; test_global_t *global; test_options_t *test_options; int i, shared, mode; - global = &test_global; - memset(global, 0, sizeof(test_global_t)); - odp_atomic_init_u32(&global->exit_test, 0); - odp_atomic_init_u32(&global->timers_started, 0); - - for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { - global->thread_arg[i].global = global; - global->thread_arg[i].worker_idx = i; - } - signal(SIGINT, sig_handler); - if (parse_options(argc, argv, &global->test_options)) - return -1; - - test_options = &global->test_options; - shared = test_options->shared; - mode = test_options->mode; + /* Let helper collect its own arguments (e.g. --odph_proc) */ + argc = odph_parse_options(argc, argv); + if (odph_options(&helper_options)) { + ODPH_ERR("Reading ODP helper options failed.\n"); + exit(EXIT_FAILURE); + } /* List features not to be used */ odp_init_param_init(&init); @@ -984,6 +978,8 @@ int main(int argc, char **argv) init.not_used.feat.ipsec = 1; init.not_used.feat.tm = 1; + init.mem_model = helper_options.mem_model; + /* Init ODP before calling anything else */ if (odp_init_global(&instance, &init, NULL)) { ODPH_ERR("Global init failed.\n"); @@ -996,6 +992,35 @@ int main(int argc, char **argv) return -1; } + shm = odp_shm_reserve("timer_perf_global", sizeof(test_global_t), ODP_CACHE_LINE_SIZE, 0); + if (shm == ODP_SHM_INVALID) { + ODPH_ERR("Shared mem reserve failed.\n"); + exit(EXIT_FAILURE); + } + + global = odp_shm_addr(shm); + if (global == NULL) { + ODPH_ERR("Shared mem alloc failed\n"); + exit(EXIT_FAILURE); + } + test_global = global; + + memset(global, 0, sizeof(test_global_t)); + odp_atomic_init_u32(&global->exit_test, 0); + odp_atomic_init_u32(&global->timers_started, 0); + + for (i = 0; i < ODP_THREAD_COUNT_MAX; i++) { + global->thread_arg[i].global = global; + global->thread_arg[i].worker_idx = i; + } + + if (parse_options(argc, argv, &global->test_options)) + return -1; + + test_options = &global->test_options; + shared = test_options->shared; + mode = test_options->mode; + odp_sys_info_print(); odp_schedule_config(NULL); @@ -1052,6 +1077,11 @@ int main(int argc, char **argv) destroy_timer_pool(global); + if (odp_shm_free(shm)) { + ODPH_ERR("Shared mem free failed.\n"); + exit(EXIT_FAILURE); + } + if (odp_term_local()) { ODPH_ERR("Term local failed.\n"); return -1; diff --git a/test/validation/api/Makefile.am b/test/validation/api/Makefile.am index 9fb77bcf7..ce29781d6 100644 --- a/test/validation/api/Makefile.am +++ b/test/validation/api/Makefile.am @@ -47,6 +47,7 @@ TESTS = \ init/init_defaults$(EXEEXT) \ init/init_abort$(EXEEXT) \ init/init_log$(EXEEXT) \ + init/init_log_thread$(EXEEXT) \ init/init_num_thr$(EXEEXT) \ init/init_feature_enabled$(EXEEXT) \ init/init_feature_disabled$(EXEEXT) \ diff --git a/test/validation/api/hash/hash.c b/test/validation/api/hash/hash.c index b4f22d609..a5dc2e286 100644 --- a/test/validation/api/hash/hash.c +++ b/test/validation/api/hash/hash.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2018, Linaro Limited + * Copyright (c) 2021, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -6,6 +7,7 @@ #include <odp_api.h> #include <odp_cunit_common.h> +#include <test_packet_ipv4_with_crc.h> /* Commonly used CRC check string */ #define CHECK_STR "123456789" @@ -16,6 +18,10 @@ #define CRC32_INIT 0xffffffff #define CRC32_XOR 0xffffffff +/* When Ethernet frame CRC is included into the CRC32 calculation, + * the result should match this value. */ +#define ETHCRC_CHECK_VAL 0xdebb20e3 + typedef struct hash_test_vector_t { const uint8_t *data; uint32_t len; @@ -238,6 +244,83 @@ static void hash_test_crc32(void) } } +static void hash_test_ethernet_crc32(void) +{ + uint32_t ret; + + ret = odp_hash_crc32(test_packet_ipv4_udp_64_crc, + sizeof(test_packet_ipv4_udp_64_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_68_crc, + sizeof(test_packet_ipv4_udp_68_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_70_crc, + sizeof(test_packet_ipv4_udp_70_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_71_crc, + sizeof(test_packet_ipv4_udp_71_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_287_crc, + sizeof(test_packet_ipv4_udp_287_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_400_crc, + sizeof(test_packet_ipv4_udp_400_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + ret = odp_hash_crc32(test_packet_ipv4_udp_503_crc, + sizeof(test_packet_ipv4_udp_503_crc), CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); +} + +static void hash_test_ethernet_crc32_odd_align(void) +{ + uint32_t ret, size; + const uint32_t max_size = sizeof(test_packet_ipv4_udp_503_crc); + uint8_t buf[max_size + 1] ODP_ALIGNED(8); + + memset(buf, 0, sizeof(buf)); + + size = sizeof(test_packet_ipv4_udp_64_crc); + memcpy(&buf[1], test_packet_ipv4_udp_64_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_68_crc); + memcpy(&buf[1], test_packet_ipv4_udp_68_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_70_crc); + memcpy(&buf[1], test_packet_ipv4_udp_70_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_71_crc); + memcpy(&buf[1], test_packet_ipv4_udp_71_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_287_crc); + memcpy(&buf[1], test_packet_ipv4_udp_287_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_400_crc); + memcpy(&buf[1], test_packet_ipv4_udp_400_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); + + size = sizeof(test_packet_ipv4_udp_503_crc); + memcpy(&buf[1], test_packet_ipv4_udp_503_crc, size); + ret = odp_hash_crc32(&buf[1], size, CRC32_INIT); + CU_ASSERT(ret == ETHCRC_CHECK_VAL); +} + /* * Test various commonly used 32 bit CRCs. Used CRC names, parameters and * check values can be found e.g. here: @@ -650,6 +733,8 @@ static void hash_test_crc16_generic(void) odp_testinfo_t hash_suite[] = { ODP_TEST_INFO(hash_test_crc32c), ODP_TEST_INFO(hash_test_crc32), + ODP_TEST_INFO(hash_test_ethernet_crc32), + ODP_TEST_INFO(hash_test_ethernet_crc32_odd_align), ODP_TEST_INFO(hash_test_crc32_generic), ODP_TEST_INFO(hash_test_crc24_generic), ODP_TEST_INFO(hash_test_crc16_generic), diff --git a/test/validation/api/init/.gitignore b/test/validation/api/init/.gitignore index 05301baac..5001771bf 100644 --- a/test/validation/api/init/.gitignore +++ b/test/validation/api/init/.gitignore @@ -1,6 +1,7 @@ init_defaults init_abort init_log +init_log_thread init_num_thr init_feature_enabled init_feature_disabled diff --git a/test/validation/api/init/Makefile.am b/test/validation/api/init/Makefile.am index 297f33dc4..479e3a71b 100644 --- a/test/validation/api/init/Makefile.am +++ b/test/validation/api/init/Makefile.am @@ -3,7 +3,7 @@ include ../Makefile.inc # Keep init test cases in separate binaries. Some implementations may not allow # the same application process to call odp_init_global() multiple times. test_PROGRAMS = init_defaults init_abort init_log init_num_thr \ - init_feature_enabled init_feature_disabled + init_feature_enabled init_feature_disabled init_log_thread init_defaults_CPPFLAGS = -DINIT_TEST=0 $(AM_CPPFLAGS) init_abort_CPPFLAGS = -DINIT_TEST=1 $(AM_CPPFLAGS) @@ -11,6 +11,7 @@ init_log_CPPFLAGS = -DINIT_TEST=2 $(AM_CPPFLAGS) init_num_thr_CPPFLAGS = -DINIT_TEST=3 $(AM_CPPFLAGS) init_feature_enabled_CPPFLAGS = -DINIT_TEST=4 $(AM_CPPFLAGS) init_feature_disabled_CPPFLAGS = -DINIT_TEST=5 $(AM_CPPFLAGS) +init_log_thread_CPPFLAGS = -DINIT_TEST=6 $(AM_CPPFLAGS) init_defaults_SOURCES = init_main.c init_abort_SOURCES = init_main.c @@ -18,3 +19,4 @@ init_log_SOURCES = init_main.c init_num_thr_SOURCES = init_main.c init_feature_enabled_SOURCES = init_main.c init_feature_disabled_SOURCES = init_main.c +init_log_thread_SOURCES = init_main.c diff --git a/test/validation/api/init/init_main.c b/test/validation/api/init/init_main.c index baf6a5458..c335e10a3 100644 --- a/test/validation/api/init/init_main.c +++ b/test/validation/api/init/init_main.c @@ -10,6 +10,7 @@ #include <stdarg.h> #include <stdlib.h> +#include <stdio.h> /* Replacement abort function */ static void ODP_NORETURN my_abort_func(void) @@ -32,6 +33,20 @@ static int my_log_func(odp_log_level_t level __attribute__((unused)), return r; } +static uint32_t my_log_thread_func_count; + +/* Thread specific log function */ +ODP_PRINTF_FORMAT(2, 3) +static int my_log_thread_func(odp_log_level_t level, const char *fmt, ...) +{ + (void)level; + (void)fmt; + + my_log_thread_func_count++; + + return 0; +} + static void init_test_defaults(void) { int ret; @@ -97,6 +112,39 @@ static void init_test_log(void) CU_ASSERT(ret == 0); } +static void init_test_log_thread(void) +{ + int ret; + odp_instance_t instance; + odp_init_t param; + + odp_init_param_init(¶m); + + ret = odp_init_global(&instance, ¶m, NULL); + CU_ASSERT_FATAL(ret == 0); + + ret = odp_init_local(instance, ODP_THREAD_WORKER); + CU_ASSERT_FATAL(ret == 0); + + /* Test that our print function is called when set. */ + odp_log_thread_fn_set(my_log_thread_func); + my_log_thread_func_count = 0; + odp_sys_info_print(); + CU_ASSERT(my_log_thread_func_count != 0); + + /* Test that our print function is not called when not set. */ + odp_log_thread_fn_set(NULL); + my_log_thread_func_count = 0; + odp_sys_info_print(); + CU_ASSERT(my_log_thread_func_count == 0); + + ret = odp_term_local(); + CU_ASSERT_FATAL(ret == 0); + + ret = odp_term_global(instance); + CU_ASSERT(ret == 0); +} + static void init_test_num_thr(void) { int ret; @@ -178,7 +226,8 @@ odp_testinfo_t testinfo[] = { ODP_TEST_INFO(init_test_log), ODP_TEST_INFO(init_test_num_thr), ODP_TEST_INFO(init_test_feature_enabled), - ODP_TEST_INFO(init_test_feature_disabled) + ODP_TEST_INFO(init_test_feature_disabled), + ODP_TEST_INFO(init_test_log_thread), }; odp_testinfo_t init_suite[] = { diff --git a/test/validation/api/ipsec/Makefile.am b/test/validation/api/ipsec/Makefile.am index e2c633e0d..8417a5776 100644 --- a/test/validation/api/ipsec/Makefile.am +++ b/test/validation/api/ipsec/Makefile.am @@ -3,6 +3,7 @@ include ../Makefile.inc noinst_LTLIBRARIES = libtestipsec.la libtestipsec_la_SOURCES = \ test_vectors.h \ + reass_test_vectors.h \ ipsec_test_in.c \ ipsec_test_out.c \ ipsec.h \ diff --git a/test/validation/api/ipsec/ipsec.c b/test/validation/api/ipsec/ipsec.c index f36ca5769..a76bac973 100644 --- a/test/validation/api/ipsec/ipsec.c +++ b/test/validation/api/ipsec/ipsec.c @@ -1,6 +1,6 @@ /* Copyright (c) 2017-2018, Linaro Limited * Copyright (c) 2018-2021, Nokia - * Copyright (c) 2020, Marvell + * Copyright (c) 2020-2021, Marvell * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -14,6 +14,7 @@ #include "ipsec.h" #include "test_vectors.h" +#include "reass_test_vectors.h" struct suite_context_s suite_context; static odp_ipsec_capability_t capa; @@ -268,6 +269,22 @@ int ipsec_check_test_sa_update_seq_num(void) return ODP_TEST_ACTIVE; } +int ipsec_check_esp_aes_gcm_128_reass_ipv4(void) +{ + if (suite_context.reass_ipv4) + return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 128, + ODP_AUTH_ALG_AES_GCM, 0); + return ODP_TEST_INACTIVE; +} + +int ipsec_check_esp_aes_gcm_128_reass_ipv6(void) +{ + if (suite_context.reass_ipv6) + return ipsec_check_esp(ODP_CIPHER_ALG_AES_GCM, 128, + ODP_AUTH_ALG_AES_GCM, 0); + return ODP_TEST_INACTIVE; +} + void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, odp_bool_t in, odp_bool_t ah, @@ -423,28 +440,10 @@ static void ipsec_check_packet(const ipsec_test_packet *itp, odp_packet_t pkt, uint8_t data[len]; const odph_ipv4hdr_t *itp_ip; odph_ipv4hdr_t *ip; - int inline_mode = 0; if (NULL == itp) return; - CU_ASSERT_NOT_EQUAL(ODP_PACKET_INVALID, pkt); - if (ODP_PACKET_INVALID == pkt) - return; - - if ((!is_outbound && - suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) || - (is_outbound && - suite_context.outbound_op_mode == ODP_IPSEC_OP_MODE_INLINE)) - inline_mode = 1; - - if (inline_mode) { - /* User pointer is reset during inline mode (packet IO) */ - CU_ASSERT(odp_packet_user_ptr(pkt) == NULL); - } else { - CU_ASSERT(odp_packet_user_ptr(pkt) == PACKET_USER_PTR); - } - l3 = odp_packet_l3_offset(pkt); l4 = odp_packet_l4_offset(pkt); odp_packet_copy_to_mem(pkt, 0, len, data); @@ -501,17 +500,104 @@ static void ipsec_check_packet(const ipsec_test_packet *itp, odp_packet_t pkt, len - l3)); } -static int ipsec_send_in_one(const ipsec_test_part *part, - odp_ipsec_sa_t sa, - odp_packet_t *pkto) +static int send_pkts(const ipsec_test_part part[], int num_part) +{ + odp_packet_t pkt[num_part]; + odp_pktout_queue_t pktout; + int i; + + if (odp_pktout_queue(suite_context.pktio, &pktout, 1) != 1) { + CU_FAIL_FATAL("No pktout queue"); + return 0; + } + + for (i = 0; i < num_part; i++) + pkt[i] = ipsec_packet(part[i].pkt_in); + + CU_ASSERT_EQUAL(num_part, odp_pktout_send(pktout, pkt, num_part)); + + return num_part; +} + +/* Receive inline processed packets */ +static int recv_pkts_inline(const ipsec_test_part *part, + odp_packet_t *pkto) +{ + odp_packet_reass_partial_state_t reass_state; + odp_packet_reass_status_t reass_status; + odp_queue_t queue = ODP_QUEUE_INVALID; + int i; + + CU_ASSERT_EQUAL_FATAL(1, odp_pktin_event_queue(suite_context.pktio, + &queue, 1)); + + for (i = 0; i < part->num_pkt;) { + odp_event_t ev; + odp_event_subtype_t subtype; + + ev = odp_queue_deq(queue); + if (ODP_EVENT_INVALID != ev) { + CU_ASSERT(odp_event_is_valid(ev) == 1); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, + odp_event_types(ev, &subtype)); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET_BASIC, + subtype); + CU_ASSERT(part->out[i].status.error.sa_lookup); + + pkto[i] = odp_packet_from_event(ev); + CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); + i++; + continue; + } + + ev = odp_queue_deq(suite_context.queue); + if (ODP_EVENT_INVALID != ev) { + odp_packet_t pkt; + int num_pkts = 0; + + CU_ASSERT(odp_event_is_valid(ev) == 1); + CU_ASSERT_EQUAL(ODP_EVENT_PACKET, odp_event_type(ev)); + pkt = odp_packet_from_event(ev); + + CU_ASSERT(!part->out[i].status.error.sa_lookup); + + reass_status = odp_packet_reass_status(pkt); + if (ODP_PACKET_REASS_INCOMPLETE != reass_status) { + pkto[i] = pkt; + num_pkts = 1; + } else { + odp_packet_t frags[MAX_FRAGS]; + int j; + + CU_ASSERT(0 == + odp_packet_reass_partial_state(pkt, frags, &reass_state)); + num_pkts = reass_state.num_frags; + + CU_ASSERT_FATAL(i + num_pkts <= part->num_pkt); + for (j = 0; j < num_pkts; j++) + pkto[i + j] = frags[j]; + } + + for (; num_pkts > 0; num_pkts--) + CU_ASSERT(odp_packet_subtype(pkto[i++]) == + ODP_EVENT_PACKET_IPSEC); + + continue; + } + } + + return i; +} + +static int ipsec_process_in(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_packet_t *pkto) { odp_ipsec_in_param_t param; int num_out = part->num_pkt; odp_packet_t pkt; int i; - pkt = ipsec_packet(part->pkt_in); - memset(¶m, 0, sizeof(param)); if (!part->flags.lookup) { param.num_sa = 1; @@ -522,16 +608,21 @@ static int ipsec_send_in_one(const ipsec_test_part *part, } if (ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode) { + pkt = ipsec_packet(part->pkt_in); CU_ASSERT_EQUAL(part->num_pkt, odp_ipsec_in(&pkt, 1, pkto, &num_out, ¶m)); CU_ASSERT_EQUAL(num_out, part->num_pkt); + CU_ASSERT_FATAL(*pkto != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_subtype(*pkto) == ODP_EVENT_PACKET_IPSEC); } else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode) { - num_out = odp_ipsec_in_enq(&pkt, 1, ¶m); - CU_ASSERT_EQUAL(1, num_out); + int consumed; - num_out = (num_out == 1) ? 1 : 0; + pkt = ipsec_packet(part->pkt_in); + consumed = odp_ipsec_in_enq(&pkt, 1, ¶m); + CU_ASSERT_EQUAL(1, consumed); + if (consumed <= 0) + num_out = 0; for (i = 0; i < num_out; i++) { odp_event_t event; @@ -546,57 +637,14 @@ static int ipsec_send_in_one(const ipsec_test_part *part, odp_event_types(event, &subtype)); CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, subtype); pkto[i] = odp_ipsec_packet_from_event(event); + CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_subtype(pkto[i]) == ODP_EVENT_PACKET_IPSEC); } } else { - odp_pktout_queue_t pktout; - odp_queue_t queue = ODP_QUEUE_INVALID; - - if (odp_pktout_queue(suite_context.pktio, &pktout, 1) != 1) { - CU_FAIL_FATAL("No pktout queue"); - return 0; - } - - CU_ASSERT_EQUAL(1, odp_pktout_send(pktout, &pkt, 1)); - CU_ASSERT_EQUAL_FATAL(1, - odp_pktin_event_queue(suite_context. - pktio, - &queue, 1)); - - for (i = 0; i < num_out;) { - odp_event_t ev; - odp_event_subtype_t subtype; - - ev = odp_queue_deq(queue); - if (ODP_EVENT_INVALID != ev) { - CU_ASSERT(odp_event_is_valid(ev) == 1); - CU_ASSERT_EQUAL(ODP_EVENT_PACKET, - odp_event_types(ev, &subtype)); - CU_ASSERT_EQUAL(ODP_EVENT_PACKET_BASIC, - subtype); - CU_ASSERT(part->in[i].status.error.sa_lookup); - - pkto[i++] = odp_ipsec_packet_from_event(ev); - continue; - } - - ev = odp_queue_deq(suite_context.queue); - if (ODP_EVENT_INVALID != ev) { - CU_ASSERT(odp_event_is_valid(ev) == 1); - CU_ASSERT_EQUAL(ODP_EVENT_PACKET, - odp_event_types(ev, &subtype)); - CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, - subtype); - CU_ASSERT(!part->in[i].status.error.sa_lookup); - - pkto[i] = odp_ipsec_packet_from_event(ev); - CU_ASSERT(odp_packet_subtype(pkto[i]) == - ODP_EVENT_PACKET_IPSEC); - i++; - continue; - } - } + CU_ASSERT_EQUAL(1, send_pkts(part, 1)); + if (part->num_pkt) + CU_ASSERT_EQUAL(part->num_pkt, recv_pkts_inline(part, pkto)); } return num_out; @@ -622,11 +670,9 @@ static int ipsec_send_out_one(const ipsec_test_part *part, if (ODP_IPSEC_OP_MODE_SYNC == suite_context.outbound_op_mode) { CU_ASSERT_EQUAL(1, odp_ipsec_out(&pkt, 1, pkto, &num_out, ¶m)); - CU_ASSERT_EQUAL(num_out, 1); - if (num_out == 1) { - CU_ASSERT(odp_packet_subtype(*pkto) == - ODP_EVENT_PACKET_IPSEC); - } + CU_ASSERT_FATAL(num_out == 1); + CU_ASSERT_FATAL(*pkto != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_subtype(*pkto) == ODP_EVENT_PACKET_IPSEC); } else if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.outbound_op_mode) { num_out = odp_ipsec_out_enq(&pkt, 1, ¶m); CU_ASSERT_EQUAL(1, num_out); @@ -646,13 +692,14 @@ static int ipsec_send_out_one(const ipsec_test_part *part, odp_event_types(event, &subtype)); CU_ASSERT_EQUAL(ODP_EVENT_PACKET_IPSEC, subtype); pkto[i] = odp_ipsec_packet_from_event(event); + CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_subtype(pkto[i]) == ODP_EVENT_PACKET_IPSEC); } } else { struct odp_ipsec_out_inline_param_t inline_param; uint32_t hdr_len; - uint8_t hdr[32]; + odph_ethhdr_t hdr; odp_queue_t queue = ODP_QUEUE_INVALID; if (NULL != part->out[0].pkt_res) { @@ -663,16 +710,16 @@ static int ipsec_send_out_one(const ipsec_test_part *part, */ hdr_len = part->out[0].pkt_res->l3_offset; CU_ASSERT_FATAL(hdr_len <= sizeof(hdr)); - memcpy(hdr, part->out[0].pkt_res->data, hdr_len); - } else if (part->pkt_in->l3_offset != - ODP_PACKET_OFFSET_INVALID) { - hdr_len = part->pkt_in->l3_offset; - CU_ASSERT_FATAL(hdr_len <= sizeof(hdr)); - memcpy(hdr, part->pkt_in->data, hdr_len); + memcpy(&hdr, part->out[0].pkt_res->data, hdr_len); } else { - /* Dummy header */ hdr_len = 14; - memset(hdr, 0xff, hdr_len); + memset(&hdr, 0xff, hdr_len); + + if (part->out[0].l3_type == ODP_PROTO_L3_TYPE_IPV6) { + hdr.type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV6); + } else { + hdr.type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); + } } if (part->flags.inline_hdr_in_packet) { @@ -695,14 +742,14 @@ static int ipsec_send_out_one(const ipsec_test_part *part, CU_ASSERT_FATAL(ret >= 0); odp_packet_l2_offset_set(pkt, new_l2_offset); odp_packet_l3_offset_set(pkt, new_l3_offset); - odp_packet_copy_from_mem(pkt, new_l2_offset, hdr_len, hdr); + odp_packet_copy_from_mem(pkt, new_l2_offset, hdr_len, &hdr); if (l4_offset != ODP_PACKET_OFFSET_INVALID) odp_packet_l4_offset_set(pkt, new_l3_offset + l4_offset - l3_offset); inline_param.outer_hdr.ptr = NULL; } else { - inline_param.outer_hdr.ptr = hdr; + inline_param.outer_hdr.ptr = (void *)&hdr; } inline_param.pktio = suite_context.pktio; @@ -729,7 +776,9 @@ static int ipsec_send_out_one(const ipsec_test_part *part, subtype); CU_ASSERT(!part->out[i].status.error.all); - pkto[i++] = odp_ipsec_packet_from_event(ev); + pkto[i] = odp_packet_from_event(ev); + CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); + i++; continue; } @@ -743,6 +792,7 @@ static int ipsec_send_out_one(const ipsec_test_part *part, CU_ASSERT(part->out[i].status.error.all); pkto[i] = odp_ipsec_packet_from_event(ev); + CU_ASSERT_FATAL(pkto[i] != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_subtype(pkto[i]) == ODP_EVENT_PACKET_IPSEC); i++; @@ -796,90 +846,27 @@ static void ipsec_pkt_seq_num_check(odp_packet_t pkt, uint32_t seq_num) } } -static void ipsec_pkt_proto_err_set(odp_packet_t pkt) -{ - uint32_t l3_off = odp_packet_l3_offset(pkt); - odph_ipv4hdr_t ip; - - /* Simulate proto error by corrupting protocol field */ - - odp_packet_copy_to_mem(pkt, l3_off, sizeof(ip), &ip); - - if (ip.proto == ODPH_IPPROTO_ESP) - ip.proto = ODPH_IPPROTO_AH; - else - ip.proto = ODPH_IPPROTO_ESP; - - odp_packet_copy_from_mem(pkt, l3_off, sizeof(ip), &ip); -} - -static void ipsec_pkt_auth_err_set(odp_packet_t pkt) -{ - uint32_t data, len; - - /* Simulate auth error by corrupting ICV */ - - len = odp_packet_len(pkt); - odp_packet_copy_to_mem(pkt, len - sizeof(data), sizeof(data), &data); - data = ~data; - odp_packet_copy_from_mem(pkt, len - sizeof(data), sizeof(data), &data); -} - -static void ipsec_pkt_v4_check_udp_encap(odp_packet_t pkt) -{ - uint32_t l3_off = odp_packet_l3_offset(pkt); - odph_ipv4hdr_t ip; - - odp_packet_copy_to_mem(pkt, l3_off, sizeof(ip), &ip); - - CU_ASSERT(ip.proto == ODPH_IPPROTO_UDP); -} - -static void ipsec_pkt_v6_check_udp_encap(odp_packet_t pkt) -{ - uint32_t l3_off = odp_packet_l3_offset(pkt); - odph_ipv6hdr_ext_t ext; - odph_ipv6hdr_t ip; - uint8_t next_hdr; - - odp_packet_copy_to_mem(pkt, l3_off, sizeof(ip), &ip); - - next_hdr = ip.next_hdr; - - if (ip.next_hdr == ODPH_IPPROTO_HOPOPTS) { - odp_packet_copy_to_mem(pkt, l3_off + sizeof(ip), sizeof(ext), &ext); - next_hdr = ext.next_hdr; - } - - CU_ASSERT(next_hdr == ODPH_IPPROTO_UDP); -} - -void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) +/* Verify inbound processed one part */ +static void verify_in(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_packet_t *pkto) { - int num_out = part->num_pkt; - odp_packet_t pkto[num_out]; int i; - num_out = ipsec_send_in_one(part, sa, pkto); - - for (i = 0; i < num_out; i++) { + for (i = 0; i < part->num_pkt; i++) { odp_ipsec_packet_result_t result; - - if (ODP_PACKET_INVALID == pkto[i]) { - CU_FAIL("ODP_PACKET_INVALID received"); - continue; - } + void *expected_user_ptr = PACKET_USER_PTR; if (ODP_EVENT_PACKET_IPSEC != odp_event_subtype(odp_packet_to_event(pkto[i]))) { - /* Inline packet went through loop */ - CU_ASSERT_EQUAL(1, part->in[i].status.error.sa_lookup); + /* Inline packet failed SA lookup */ + CU_ASSERT_EQUAL(1, part->out[i].status.error.sa_lookup); } else { CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); - CU_ASSERT_EQUAL(part->in[i].status.error.all, + CU_ASSERT_EQUAL(part->out[i].status.error.all, result.status.error.all); - if (part->in[i].status.error.all != 0) { + if (part->out[i].status.error.all != 0) { odp_packet_free(pkto[i]); return; } @@ -895,41 +882,66 @@ void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) CU_ASSERT_EQUAL(IPSEC_SA_CTX, odp_ipsec_sa_context(sa)); } - ipsec_check_packet(part->in[i].pkt_res, + ipsec_check_packet(part->out[i].pkt_res, pkto[i], false); - if (part->in[i].pkt_res != NULL && - part->in[i].l3_type != _ODP_PROTO_L3_TYPE_UNDEF) - CU_ASSERT_EQUAL(part->in[i].l3_type, + if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) + expected_user_ptr = NULL; + CU_ASSERT(odp_packet_user_ptr(pkto[i]) == expected_user_ptr); + + if (part->out[i].pkt_res != NULL && + part->out[i].l3_type != _ODP_PROTO_L3_TYPE_UNDEF) + CU_ASSERT_EQUAL(part->out[i].l3_type, odp_packet_l3_type(pkto[i])); - if (part->in[i].pkt_res != NULL && - part->in[i].l4_type != _ODP_PROTO_L4_TYPE_UNDEF) - CU_ASSERT_EQUAL(part->in[i].l4_type, + if (part->out[i].pkt_res != NULL && + part->out[i].l4_type != _ODP_PROTO_L4_TYPE_UNDEF) + CU_ASSERT_EQUAL(part->out[i].l4_type, odp_packet_l4_type(pkto[i])); odp_packet_free(pkto[i]); } } -void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) +static void parse_ip(odp_packet_t pkt) +{ + uint8_t *ver_ihl; + odp_proto_t proto = ODP_PROTO_NONE; + uint32_t l3 = odp_packet_l3_offset(pkt); + + ver_ihl = odp_packet_l3_ptr(pkt, NULL); + if ((*ver_ihl >> 4) == 4) + proto = ODP_PROTO_IPV4; + else if ((*ver_ihl >> 4) == 6) + proto = ODP_PROTO_IPV6; + else + CU_FAIL("Invalid IP version"); + + odp_packet_parse_param_t param = { + .proto = proto, + .last_layer = ODP_PROTO_LAYER_L4, + }; + /* + * odp_packet_parse() is buggy in linux generic ODP. Intentionally + * ignore the return value until the bug has been fixed. + */ + (void)odp_packet_parse(pkt, l3, ¶m); +} + +int ipsec_check_out(const ipsec_test_part *part, odp_ipsec_sa_t sa, + odp_packet_t *pkto) { - int num_out = part->num_pkt; - odp_packet_t pkto[num_out]; int i; + int num_out; num_out = ipsec_send_out_one(part, sa, pkto); for (i = 0; i < num_out; i++) { odp_ipsec_packet_result_t result; - if (ODP_PACKET_INVALID == pkto[i]) { - CU_FAIL("ODP_PACKET_INVALID received"); - continue; - } - if (ODP_EVENT_PACKET_IPSEC != odp_event_subtype(odp_packet_to_event(pkto[i]))) { /* Inline packet went through loop */ CU_ASSERT_EQUAL(0, part->out[i].status.error.all); + CU_ASSERT(odp_packet_user_ptr(pkto[i]) == NULL); /* L2 header must match the requested one */ check_l2_header(part->out[i].pkt_res, pkto[i]); } else { @@ -943,80 +955,57 @@ void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) CU_ASSERT_EQUAL(sa, result.sa); CU_ASSERT_EQUAL(IPSEC_SA_CTX, odp_ipsec_sa_context(sa)); + CU_ASSERT(odp_packet_user_ptr(pkto[i]) == PACKET_USER_PTR); + + /* Parse the packet to set L4 offset and type */ + parse_ip(pkto[i]); } + + if (part->flags.test_sa_seq_num) + ipsec_pkt_seq_num_check(pkto[i], part->out[i].seq_num); + ipsec_check_packet(part->out[i].pkt_res, pkto[i], true); - odp_packet_free(pkto[i]); + + /* + * If we did not have an expected packet to compare the + * result packet with, we will check the l3 and l4 types + * against the expected ones. + */ + if (part->out[i].pkt_res == NULL) { + if (part->out[i].l3_type != _ODP_PROTO_L3_TYPE_UNDEF) + CU_ASSERT(part->out[i].l3_type == + odp_packet_l3_type(pkto[i])); + if (part->out[i].l4_type != _ODP_PROTO_L4_TYPE_UNDEF) + CU_ASSERT(part->out[i].l4_type == + odp_packet_l4_type(pkto[i])); + } } + return num_out; } -void ipsec_check_out_in_one(const ipsec_test_part *part, - odp_ipsec_sa_t sa, - odp_ipsec_sa_t sa_in) +void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) { - int num_out = part->num_pkt; - odp_packet_t pkto[num_out]; - int i; + odp_packet_t pkto[MAX_FRAGS] = {0}; + int num_out; - num_out = ipsec_send_out_one(part, sa, pkto); + num_out = ipsec_process_in(part, sa, pkto); + CU_ASSERT_EQUAL(num_out, part->num_pkt); - for (i = 0; i < num_out; i++) { - ipsec_test_part part_in = *part; - ipsec_test_packet pkt_in; - odp_ipsec_packet_result_t result; - - if (ODP_PACKET_INVALID == pkto[i]) { - CU_FAIL("ODP_PACKET_INVALID received"); - continue; - } - - if (ODP_EVENT_PACKET_IPSEC != - odp_event_subtype(odp_packet_to_event(pkto[i]))) { - /* Inline packet went through loop */ - CU_ASSERT_EQUAL(0, part->out[i].status.error.all); - /* L2 header must match that of input packet */ - check_l2_header(part->out[i].pkt_res, pkto[i]); - } else { - /* IPsec packet */ - CU_ASSERT_EQUAL(0, odp_ipsec_result(&result, pkto[i])); - CU_ASSERT_EQUAL(part->out[i].status.error.all, - result.status.error.all); - CU_ASSERT_EQUAL(sa, result.sa); - CU_ASSERT_EQUAL(IPSEC_SA_CTX, - odp_ipsec_sa_context(sa)); - } - CU_ASSERT_FATAL(odp_packet_len(pkto[i]) <= - sizeof(pkt_in.data)); - - if (part->flags.test_sa_seq_num) - ipsec_pkt_seq_num_check(pkto[i], part->out[i].seq_num); - - if (part->flags.stats == IPSEC_TEST_STATS_PROTO_ERR) - ipsec_pkt_proto_err_set(pkto[i]); + verify_in(part, sa, pkto); +} - if (part->flags.stats == IPSEC_TEST_STATS_AUTH_ERR) - ipsec_pkt_auth_err_set(pkto[i]); +void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa) +{ + int num_out = part->num_pkt; + odp_packet_t pkto[num_out]; + int i; - if (part->flags.udp_encap) { - if ((!part->flags.tunnel && part->flags.v6) || - (part->flags.tunnel && part->flags.tunnel_is_v6)) - ipsec_pkt_v6_check_udp_encap(pkto[i]); - else - ipsec_pkt_v4_check_udp_encap(pkto[i]); - } + num_out = ipsec_check_out(part, sa, pkto); - pkt_in.len = odp_packet_len(pkto[i]); - pkt_in.l2_offset = odp_packet_l2_offset(pkto[i]); - pkt_in.l3_offset = odp_packet_l3_offset(pkto[i]); - pkt_in.l4_offset = odp_packet_l4_offset(pkto[i]); - odp_packet_copy_to_mem(pkto[i], 0, - pkt_in.len, - pkt_in.data); - part_in.pkt_in = &pkt_in; - ipsec_check_in_one(&part_in, sa_in); + for (i = 0; i < num_out; i++) odp_packet_free(pkto[i]); - } } int ipsec_suite_init(void) @@ -1035,6 +1024,18 @@ int ipsec_suite_init(void) return rc < 0 ? -1 : 0; } +void ipsec_test_packet_from_pkt(ipsec_test_packet *test_pkt, odp_packet_t *pkt) +{ + CU_ASSERT_FATAL(odp_packet_len(*pkt) <= sizeof(test_pkt->data)); + + test_pkt->len = odp_packet_len(*pkt); + test_pkt->l2_offset = odp_packet_l2_offset(*pkt); + test_pkt->l3_offset = odp_packet_l3_offset(*pkt); + test_pkt->l4_offset = odp_packet_l4_offset(*pkt); + odp_packet_copy_to_mem(*pkt, 0, test_pkt->len, test_pkt->data); + odp_packet_free(*pkt); +} + static int ipsec_suite_term(void) { if (suite_context.pktio != ODP_PKTIO_INVALID) @@ -1161,6 +1162,8 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst) ODP_SUPPORT_NO == capa.op_mode_inline_out)) return 0; + reass_test_vectors_init(); + odp_ipsec_config_init(&ipsec_config); ipsec_config.max_num_sa = capa.max_num_sa; ipsec_config.inbound_mode = suite_context.inbound_op_mode; @@ -1171,6 +1174,68 @@ int ipsec_config(odp_instance_t ODP_UNUSED inst) ipsec_config.inbound.chksums.all_chksum = ~0; ipsec_config.stats_en = true; + ipsec_config.inbound.reassembly.max_wait_time = 100 * ODP_TIME_MSEC_IN_NS; + if (ipsec_config.inbound.reassembly.max_wait_time > capa.reassembly.max_wait_time) + ipsec_config.inbound.reassembly.max_wait_time = capa.reassembly.max_wait_time; + + ipsec_config.inbound.reassembly.max_num_frags = capa.reassembly.max_num_frags; + + if (capa.reassembly.ip) { + ipsec_config.inbound.reassembly.en_ipv4 = true; + ipsec_config.inbound.reassembly.en_ipv6 = true; + } + + if (capa.reassembly.ipv4) + ipsec_config.inbound.reassembly.en_ipv4 = true; + + if (capa.reassembly.ipv6) + ipsec_config.inbound.reassembly.en_ipv6 = true; + + if (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode && + !capa.reass_inline) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode && + !capa.reass_async) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ODP_IPSEC_OP_MODE_SYNC == suite_context.inbound_op_mode) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ipsec_config.inbound.reassembly.max_num_frags > MAX_FRAGS) { + ipsec_config.inbound.reassembly.en_ipv4 = false; + ipsec_config.inbound.reassembly.en_ipv6 = false; + } + + if (ipsec_config.inbound.reassembly.en_ipv4) + suite_context.reass_ipv4 = true; + else + suite_context.reass_ipv4 = false; + + if (ipsec_config.inbound.reassembly.en_ipv6) + suite_context.reass_ipv6 = true; + else + suite_context.reass_ipv6 = false; + + if (suite_context.reass_ipv4 || suite_context.reass_ipv6) { + if (ODP_IPSEC_OP_MODE_INLINE == suite_context.inbound_op_mode) + ipsec_config.inbound.reass_inline = true; + + if (ODP_IPSEC_OP_MODE_ASYNC == suite_context.inbound_op_mode) { + ipsec_config.inbound.reass_async = true; + + /* Reassembly with ASYNC not supported */ + suite_context.reass_ipv4 = false; + suite_context.reass_ipv6 = false; + } + } + if (ODP_IPSEC_OK != odp_ipsec_config(&ipsec_config)) return -1; diff --git a/test/validation/api/ipsec/ipsec.h b/test/validation/api/ipsec/ipsec.h index 8b332b2f7..161835a33 100644 --- a/test/validation/api/ipsec/ipsec.h +++ b/test/validation/api/ipsec/ipsec.h @@ -11,6 +11,11 @@ #include <odp_cunit_common.h> +#define IPV4ADDR(a, b, c, d) odp_cpu_to_be_32(((a) << 24) | \ + ((b) << 16) | \ + ((c) << 8) | \ + ((d) << 0)) + /* test arrays: */ extern odp_testinfo_t ipsec_in_suite[]; extern odp_testinfo_t ipsec_out_suite[]; @@ -27,6 +32,8 @@ int ipsec_in_term(void); int ipsec_out_term(void); struct suite_context_s { + odp_bool_t reass_ipv4; + odp_bool_t reass_ipv6; odp_ipsec_op_mode_t inbound_op_mode; odp_ipsec_op_mode_t outbound_op_mode; odp_pool_t pool; @@ -36,7 +43,9 @@ struct suite_context_s { extern struct suite_context_s suite_context; -#define MAX_PKT_LEN 1024 +#define MAX_FRAG_LEN 1500 +#define MAX_FRAGS 4 +#define MAX_PKT_LEN (MAX_FRAG_LEN * MAX_FRAGS) typedef struct { uint32_t len; @@ -57,23 +66,20 @@ enum ipsec_test_stats { }; typedef struct { - odp_bool_t display_algo; odp_bool_t lookup; - odp_bool_t ah; odp_bool_t inline_hdr_in_packet; odp_bool_t test_sa_seq_num; - odp_bool_t v6; - odp_bool_t tunnel; - odp_bool_t tunnel_is_v6; - odp_bool_t udp_encap; - enum ipsec_test_stats stats; -} ipsec_test_flags; +} ipsec_test_part_flags_t; typedef struct { + ipsec_test_part_flags_t flags; + + /* Input for the inbound or outbound IPsec operation */ const ipsec_test_packet *pkt_in; - ipsec_test_flags flags; int num_opt; odp_ipsec_out_opt_t opt; + + /* Expected output */ int num_pkt; struct { odp_ipsec_op_status_t status; @@ -81,13 +87,7 @@ typedef struct { odp_proto_l3_type_t l3_type; odp_proto_l4_type_t l4_type; uint32_t seq_num; - } out[1]; - struct { - odp_ipsec_op_status_t status; - const ipsec_test_packet *pkt_res; - odp_proto_l3_type_t l3_type; - odp_proto_l4_type_t l4_type; - } in[1]; + } out[MAX_FRAGS]; } ipsec_test_part; void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, @@ -105,12 +105,12 @@ void ipsec_sa_param_fill(odp_ipsec_sa_param_t *param, void ipsec_sa_destroy(odp_ipsec_sa_t sa); odp_packet_t ipsec_packet(const ipsec_test_packet *itp); void ipsec_check_in_one(const ipsec_test_part *part, odp_ipsec_sa_t sa); +int ipsec_check_out(const ipsec_test_part *part, + odp_ipsec_sa_t sa, + odp_packet_t *pkto); void ipsec_check_out_one(const ipsec_test_part *part, odp_ipsec_sa_t sa); -void ipsec_check_out_in_one(const ipsec_test_part *part, - odp_ipsec_sa_t sa, - odp_ipsec_sa_t sa_in); int ipsec_test_sa_update_seq_num(odp_ipsec_sa_t sa, uint32_t seq_num); - +void ipsec_test_packet_from_pkt(ipsec_test_packet *test_pkt, odp_packet_t *pkt); int ipsec_check(odp_bool_t ah, odp_cipher_alg_t cipher, uint32_t cipher_bits, @@ -138,5 +138,7 @@ int ipsec_check_esp_null_aes_gmac_192(void); int ipsec_check_esp_null_aes_gmac_256(void); int ipsec_check_esp_chacha20_poly1305(void); int ipsec_check_test_sa_update_seq_num(void); +int ipsec_check_esp_aes_gcm_128_reass_ipv4(void); +int ipsec_check_esp_aes_gcm_128_reass_ipv6(void); #endif diff --git a/test/validation/api/ipsec/ipsec_test_in.c b/test/validation/api/ipsec/ipsec_test_in.c index f31f77244..4eafed6a9 100644 --- a/test/validation/api/ipsec/ipsec_test_in.c +++ b/test/validation/api/ipsec/ipsec_test_in.c @@ -1,5 +1,5 @@ /* Copyright (c) 2017-2018, Linaro Limited - * Copyright (c) 2020, Marvell + * Copyright (c) 2020-2021, Marvell * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -7,8 +7,45 @@ #include "ipsec.h" +#include "reass_test_vectors.h" #include "test_vectors.h" +static void part_prep_esp(ipsec_test_part part[], int num_part, bool v6_tunnel) +{ + int i; + + memset(part, 0, sizeof(ipsec_test_part) * num_part); + + for (i = 0; i < num_part; i++) { + part[i].num_pkt = 1; + + if (v6_tunnel) + part[i].out[0].l3_type = ODP_PROTO_L3_TYPE_IPV6; + else + part[i].out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + + part[i].out[0].l4_type = ODP_PROTO_L4_TYPE_ESP; + } +} + +static void part_prep_plain(ipsec_test_part *part, int num_pkt, bool v6, bool udp) +{ + int i; + + part->num_pkt = num_pkt; + for (i = 0; i < num_pkt; i++) { + part->out[i].l4_type = _ODP_PROTO_L4_TYPE_UNDEF; + + if (v6) + part->out[i].l3_type = ODP_PROTO_L3_TYPE_IPV6; + else + part->out[i].l3_type = ODP_PROTO_L3_TYPE_IPV4; + + if (udp) + part->out[i].l4_type = ODP_PROTO_L4_TYPE_UDP; + } +} + static void test_in_ipv4_ah_sha256(void) { odp_ipsec_sa_param_t param; @@ -27,7 +64,7 @@ static void test_in_ipv4_ah_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -62,7 +99,7 @@ static void test_in_ipv4_ah_sha256_tun_ipv4(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_tun_ipv4_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -97,7 +134,7 @@ static void test_in_ipv4_ah_sha256_tun_ipv6(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_tun_ipv6_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -129,7 +166,7 @@ static void test_in_ipv4_ah_sha256_tun_ipv4_notun(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_tun_ipv4_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -162,7 +199,7 @@ static void test_in_ipv4_esp_null_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -194,7 +231,7 @@ static void test_in_ipv4_esp_aes_cbc_null(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_cbc_null_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -226,7 +263,7 @@ static void test_in_ipv4_esp_aes_cbc_sha1(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_cbc_sha1_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -258,7 +295,7 @@ static void test_in_ipv4_esp_aes_cbc_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_cbc_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -290,7 +327,7 @@ static void test_in_ipv4_esp_aes_cbc_sha384(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_cbc_sha384_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -322,7 +359,7 @@ static void test_in_ipv4_esp_aes_cbc_sha512(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_cbc_sha512_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -354,7 +391,7 @@ static void test_in_ipv4_esp_aes_ctr_null(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_aes_ctr_null_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -389,7 +426,7 @@ static void test_in_ipv4_ah_sha256_lookup(void) .lookup = 1, }, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -424,7 +461,7 @@ static void test_in_ipv4_esp_null_sha256_lookup(void) .lookup = 1, }, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -459,7 +496,7 @@ static void test_in_ipv4_esp_null_sha256_tun_ipv4(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_tun_ipv4_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -494,7 +531,7 @@ static void test_in_ipv4_esp_null_sha256_tun_ipv6(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_tun_ipv6_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -527,7 +564,7 @@ static void test_in_ipv4_esp_udp_null_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_udp_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -563,7 +600,7 @@ static void test_in_ipv4_esp_udp_null_sha256_lookup(void) .lookup = 1, }, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -596,7 +633,7 @@ static void test_in_ipv4_ah_sha256_noreplay(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -608,7 +645,7 @@ static void test_in_ipv4_ah_sha256_noreplay(void) ipsec_test_part test_1235 = { .pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1235, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -647,7 +684,7 @@ static void test_in_ipv4_ah_sha256_replay(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -658,12 +695,12 @@ static void test_in_ipv4_ah_sha256_replay(void) test_repl.pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1; test_repl.num_pkt = 1; - test_repl.in[0].status.error.antireplay = 1; + test_repl.out[0].status.error.antireplay = 1; ipsec_test_part test_1235 = { .pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1235, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -699,7 +736,7 @@ static void test_in_ipv4_esp_null_sha256_noreplay(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -711,7 +748,7 @@ static void test_in_ipv4_esp_null_sha256_noreplay(void) ipsec_test_part test_1235 = { .pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1235, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -757,18 +794,11 @@ static void test_in_ipv4_esp_null_sha256_replay(void) .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, .pkt_res = &pkt_ipv4_icmp_0 }, }, - .in = { - { .status.warn.all = 0, - .status.error.all = 0, - .l3_type = ODP_PROTO_L3_TYPE_IPV4, - .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, - .pkt_res = &pkt_ipv4_icmp_0 }, - }, }; test_repl.pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1; test_repl.num_pkt = 1; - test_repl.in[0].status.error.antireplay = 1; + test_repl.out[0].status.error.antireplay = 1; ipsec_test_part test_1235 = { .pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1235, @@ -780,13 +810,6 @@ static void test_in_ipv4_esp_null_sha256_replay(void) .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, .pkt_res = &pkt_ipv4_icmp_0 }, }, - .in = { - { .status.warn.all = 0, - .status.error.all = 0, - .l3_type = ODP_PROTO_L3_TYPE_IPV4, - .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, - .pkt_res = &pkt_ipv4_icmp_0 }, - }, }; ipsec_check_in_one(&test, sa); @@ -822,7 +845,7 @@ static void test_in_ipv4_ah_esp_pkt(void) test.pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1; test.num_pkt = 1; - test.in[0].status.error.proto = 1; + test.out[0].status.error.proto = 1; ipsec_check_in_one(&test, sa); @@ -854,7 +877,7 @@ static void test_in_ipv4_esp_ah_pkt(void) test.pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1; test.num_pkt = 1; - test.in[0].status.error.proto = 1; + test.out[0].status.error.proto = 1; ipsec_check_in_one(&test, sa); @@ -882,7 +905,7 @@ static void test_in_ipv4_ah_esp_pkt_lookup(void) test.pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1; test.flags.lookup = 1; test.num_pkt = 1; - test.in[0].status.error.sa_lookup = 1; + test.out[0].status.error.sa_lookup = 1; ipsec_check_in_one(&test, ODP_IPSEC_SA_INVALID); @@ -910,7 +933,7 @@ static void test_in_ipv4_esp_ah_pkt_lookup(void) test.pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1; test.flags.lookup = 1; test.num_pkt = 1; - test.in[0].status.error.sa_lookup = 1; + test.out[0].status.error.sa_lookup = 1; ipsec_check_in_one(&test, ODP_IPSEC_SA_INVALID); @@ -937,7 +960,7 @@ static void test_in_ipv4_ah_sha256_bad1(void) test.pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1_bad1; test.num_pkt = 1; - test.in[0].status.error.auth = 1; + test.out[0].status.error.auth = 1; ipsec_check_in_one(&test, sa); @@ -964,7 +987,7 @@ static void test_in_ipv4_ah_sha256_bad2(void) test.pkt_in = &pkt_ipv4_icmp_0_ah_sha256_1_bad2; test.num_pkt = 1; - test.in[0].status.error.auth = 1; + test.out[0].status.error.auth = 1; ipsec_check_in_one(&test, sa); @@ -991,7 +1014,7 @@ static void test_in_ipv4_esp_null_sha256_bad1(void) test.pkt_in = &pkt_ipv4_icmp_0_esp_null_sha256_1_bad1; test.num_pkt = 1; - test.in[0].status.error.auth = 1; + test.out[0].status.error.auth = 1; ipsec_check_in_one(&test, sa); @@ -1016,7 +1039,7 @@ static void test_in_ipv4_rfc3602_5_esp(void) ipsec_test_part test = { .pkt_in = &pkt_rfc3602_5_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1048,7 +1071,7 @@ static void test_in_ipv4_rfc3602_6_esp(void) ipsec_test_part test = { .pkt_in = &pkt_rfc3602_6_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1083,7 +1106,7 @@ static void test_in_ipv4_rfc3602_7_esp(void) ipsec_test_part test = { .pkt_in = &pkt_rfc3602_7_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1118,7 +1141,7 @@ static void test_in_ipv4_rfc3602_8_esp(void) ipsec_test_part test = { .pkt_in = &pkt_rfc3602_8_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1153,7 +1176,7 @@ static void test_in_ipv4_mcgrew_gcm_2_esp(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_2_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1188,7 +1211,7 @@ static void test_in_ipv4_mcgrew_gcm_3_esp(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_3_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1223,7 +1246,7 @@ static void test_in_ipv4_mcgrew_gcm_4_esp(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_4_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1263,7 +1286,7 @@ static void test_in_ipv4_mcgrew_gcm_12_esp(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_12_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_NONE, @@ -1295,7 +1318,7 @@ static void test_in_ipv4_mcgrew_gcm_12_esp_notun(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_12_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1330,7 +1353,7 @@ static void test_in_ipv4_mcgrew_gcm_15_esp(void) ipsec_test_part test = { .pkt_in = &pkt_mcgrew_gcm_test_15_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1365,7 +1388,7 @@ static void test_in_ipv4_rfc7634_chacha(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_rfc7634_esp, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1397,7 +1420,7 @@ static void test_in_ipv4_ah_aes_gmac_128(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_ah_aes_gmac_128_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1429,7 +1452,7 @@ static void test_in_ipv4_esp_null_aes_gmac_128(void) ipsec_test_part test = { .pkt_in = &pkt_ipv4_icmp_0_esp_null_aes_gmac_128_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1461,7 +1484,7 @@ static void test_in_ipv6_ah_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_ah_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1496,7 +1519,7 @@ static void test_in_ipv6_ah_sha256_tun_ipv4(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_ah_tun_ipv4_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1531,7 +1554,7 @@ static void test_in_ipv6_ah_sha256_tun_ipv6(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_ah_tun_ipv6_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1563,7 +1586,7 @@ static void test_in_ipv6_esp_null_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_esp_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1598,7 +1621,7 @@ static void test_in_ipv6_esp_null_sha256_tun_ipv4(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_esp_tun_ipv4_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1633,7 +1656,7 @@ static void test_in_ipv6_esp_null_sha256_tun_ipv6(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_esp_tun_ipv6_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1666,7 +1689,7 @@ static void test_in_ipv6_esp_udp_null_sha256(void) ipsec_test_part test = { .pkt_in = &pkt_ipv6_icmp_0_esp_udp_null_sha256_1, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1702,7 +1725,7 @@ static void test_in_ipv6_esp_udp_null_sha256_lookup(void) .lookup = 1, }, .num_pkt = 1, - .in = { + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV6, @@ -1741,6 +1764,529 @@ 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) +{ + 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_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++) { + 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_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_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, 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; + + 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_check_in_one(&test_in[i], in_sa); + } +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv4_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 1); + + part_prep_esp(test_out, 1, false); + + test_out[0].pkt_in = &pkt_ipv4_udp_p1_f1; + + part_prep_plain(&test_in[0], 1, false, true); + test_in[0].out[0].pkt_res = &pkt_ipv4_udp_p1_f1; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[0], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[0].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[0], in_sa); +} + +static void test_in_ipv4_esp_reass_success(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + uint32_t src = IPV4ADDR(10, 0, 11, 2); + uint32_t dst = IPV4ADDR(10, 0, 22, 2); + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + memset(&out_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + + out_tunnel.type = ODP_IPSEC_TUNNEL_IPV4; + out_tunnel.ipv4.src_addr = &src; + out_tunnel.ipv4.dst_addr = &dst; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv4 two frags"); + test_in_ipv4_esp_reass_success_two_frags(out_sa, in_sa); + + printf("\n IPv4 four frags"); + test_in_ipv4_esp_reass_success_four_frags(out_sa, in_sa); + + printf("\n IPv4 two frags out of order"); + test_in_ipv4_esp_reass_success_two_frags_ooo(out_sa, in_sa); + + printf("\n IPv4 four frags out of order"); + test_in_ipv4_esp_reass_success_four_frags_ooo(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + +static void test_in_ipv4_esp_reass_incomp(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + uint32_t src = IPV4ADDR(10, 0, 11, 2); + uint32_t dst = IPV4ADDR(10, 0, 22, 2); + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + memset(&out_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + + out_tunnel.type = ODP_IPSEC_TUNNEL_IPV4; + out_tunnel.ipv4.src_addr = &src; + out_tunnel.ipv4.dst_addr = &dst; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv4 missing frag"); + test_in_ipv4_esp_reass_incomp_missing(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +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_check_in_one(&test_in[i], in_sa); + } +} + +static void test_in_ipv6_esp_reass_incomp_missing(odp_ipsec_sa_t out_sa, + odp_ipsec_sa_t in_sa) +{ + ipsec_test_part test_out[MAX_FRAGS], test_in[MAX_FRAGS]; + ipsec_test_packet test_pkt; + odp_packet_t pkt; + + memset(test_in, 0, sizeof(test_in)); + + CU_ASSERT(MAX_FRAGS >= 1); + + part_prep_esp(test_out, 1, true); + + test_out[0].pkt_in = &pkt_ipv6_udp_p1_f1; + + part_prep_plain(&test_in[0], 1, true, true); + test_in[0].out[0].pkt_res = &pkt_ipv6_udp_p1_f1; + + CU_ASSERT_EQUAL(ipsec_check_out(&test_out[0], out_sa, &pkt), 1); + + ipsec_test_packet_from_pkt(&test_pkt, &pkt); + test_in[0].pkt_in = &test_pkt; + + ipsec_check_in_one(&test_in[0], in_sa); +} + +static void test_in_ipv6_esp_reass_success(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + uint8_t src[16] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, + }; + uint8_t dst[16] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + }; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + memset(&out_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + out_tunnel.type = ODP_IPSEC_TUNNEL_IPV6; + out_tunnel.ipv6.src_addr = &src; + out_tunnel.ipv6.dst_addr = &dst; + out_tunnel.ipv6.hlimit = 64; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv6 two frags"); + test_in_ipv6_esp_reass_success_two_frags(out_sa, in_sa); + + printf("\n IPv6 four frags"); + test_in_ipv6_esp_reass_success_four_frags(out_sa, in_sa); + + printf("\n IPv6 two frags out of order"); + test_in_ipv6_esp_reass_success_two_frags_ooo(out_sa, in_sa); + + printf("\n IPv6 four frags out of order"); + test_in_ipv6_esp_reass_success_four_frags_ooo(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + +static void test_in_ipv6_esp_reass_incomp(void) +{ + odp_ipsec_tunnel_param_t in_tunnel, out_tunnel; + odp_ipsec_sa_param_t param_in, param_out; + odp_ipsec_sa_t out_sa, in_sa; + odp_ipsec_capability_t capa; + uint8_t src[16] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, + }; + uint8_t dst[16] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + }; + + memset(&in_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + memset(&out_tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + out_tunnel.type = ODP_IPSEC_TUNNEL_IPV6; + out_tunnel.ipv6.src_addr = &src; + out_tunnel.ipv6.dst_addr = &dst; + + CU_ASSERT(odp_ipsec_capability(&capa) == 0); + + ipsec_sa_param_fill(¶m_out, + false, false, 0x4a2cbfe7, &out_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + + ipsec_sa_param_fill(¶m_in, + true, false, 0x4a2cbfe7, &in_tunnel, + ODP_CIPHER_ALG_AES_GCM, &key_mcgrew_gcm_4, + ODP_AUTH_ALG_AES_GCM, NULL, + &key_mcgrew_gcm_salt_4, NULL); + param_in.inbound.reassembly_en = 1; + + out_sa = odp_ipsec_sa_create(¶m_out); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, out_sa); + + in_sa = odp_ipsec_sa_create(¶m_in); + CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, in_sa); + + printf("\n IPv6 missing frag"); + test_in_ipv6_esp_reass_incomp_missing(out_sa, in_sa); + + printf("\n"); + + ipsec_sa_destroy(in_sa); + ipsec_sa_destroy(out_sa); +} + static void ipsec_test_capability(void) { odp_ipsec_capability_t capa; @@ -1853,5 +2399,13 @@ odp_testinfo_t ipsec_in_suite[] = { ODP_TEST_INFO(test_ipsec_print), ODP_TEST_INFO_CONDITIONAL(test_ipsec_sa_print, ipsec_check_esp_aes_cbc_128_sha1), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_esp_reass_success, + ipsec_check_esp_aes_gcm_128_reass_ipv4), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv4_esp_reass_incomp, + ipsec_check_esp_aes_gcm_128_reass_ipv4), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv6_esp_reass_success, + ipsec_check_esp_aes_gcm_128_reass_ipv6), + ODP_TEST_INFO_CONDITIONAL(test_in_ipv6_esp_reass_incomp, + ipsec_check_esp_aes_gcm_128_reass_ipv6), ODP_TEST_INFO_NULL, }; diff --git a/test/validation/api/ipsec/ipsec_test_out.c b/test/validation/api/ipsec/ipsec_test_out.c index 5bc6b7a16..b48dd0d6c 100644 --- a/test/validation/api/ipsec/ipsec_test_out.c +++ b/test/validation/api/ipsec/ipsec_test_out.c @@ -6,10 +6,25 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "ipsec.h" +#include <odp/helper/odph_api.h> +#include "ipsec.h" #include "test_vectors.h" +/* + * Miscellaneous parameters for combined out+in tests + */ +typedef struct { + ipsec_test_part_flags_t part_flags; + odp_bool_t display_algo; + odp_bool_t ah; + odp_bool_t v6; + odp_bool_t tunnel; + odp_bool_t tunnel_is_v6; + odp_bool_t udp_encap; + enum ipsec_test_stats stats; +} ipsec_test_flags; + struct cipher_param { const char *name; odp_cipher_alg_t algo; @@ -136,11 +151,6 @@ static void test_out_ipv4_ah_sha256(void) ipsec_sa_destroy(sa); } -#define IPV4ADDR(a, b, c, d) odp_cpu_to_be_32((a << 24) | \ - (b << 16) | \ - (c << 8) | \ - (d << 0)) - static void test_out_ipv4_ah_sha256_tun_ipv4(void) { odp_ipsec_tunnel_param_t tunnel; @@ -387,7 +397,70 @@ static void test_ipsec_stats_test_assert(odp_ipsec_stats_t *stats, CU_ASSERT_EQUAL(stats->hard_exp_pkts_err, 0); } -static void test_out_in_common(ipsec_test_flags *flags, +static void ipsec_pkt_proto_err_set(odp_packet_t pkt) +{ + uint32_t l3_off = odp_packet_l3_offset(pkt); + odph_ipv4hdr_t ip; + + /* Simulate proto error by corrupting protocol field */ + + odp_packet_copy_to_mem(pkt, l3_off, sizeof(ip), &ip); + + if (ip.proto == ODPH_IPPROTO_ESP) + ip.proto = ODPH_IPPROTO_AH; + else + ip.proto = ODPH_IPPROTO_ESP; + + odp_packet_copy_from_mem(pkt, l3_off, sizeof(ip), &ip); +} + +static void ipsec_pkt_auth_err_set(odp_packet_t pkt) +{ + uint32_t data, len; + + /* Simulate auth error by corrupting ICV */ + + len = odp_packet_len(pkt); + odp_packet_copy_to_mem(pkt, len - sizeof(data), sizeof(data), &data); + data = ~data; + odp_packet_copy_from_mem(pkt, len - sizeof(data), sizeof(data), &data); +} + +static void ipsec_pkt_update(odp_packet_t pkt, const ipsec_test_flags *flags) +{ + if (flags && flags->stats == IPSEC_TEST_STATS_PROTO_ERR) + ipsec_pkt_proto_err_set(pkt); + + if (flags && flags->stats == IPSEC_TEST_STATS_AUTH_ERR) + ipsec_pkt_auth_err_set(pkt); +} + +static void ipsec_check_out_in_one(const ipsec_test_part *part_outbound, + const ipsec_test_part *part_inbound, + odp_ipsec_sa_t sa, + odp_ipsec_sa_t sa_in, + const ipsec_test_flags *flags) +{ + int num_out = part_outbound->num_pkt; + odp_packet_t pkto[num_out]; + int i; + + num_out = ipsec_check_out(part_outbound, sa, pkto); + + for (i = 0; i < num_out; i++) { + ipsec_test_part part_in = *part_inbound; + ipsec_test_packet pkt_in; + + ipsec_pkt_update(pkto[i], flags); + + ipsec_test_packet_from_pkt(&pkt_in, &pkto[i]); + part_in.pkt_in = &pkt_in; + + ipsec_check_in_one(&part_in, sa_in); + } +} + +static void test_out_in_common(const ipsec_test_flags *flags, odp_cipher_alg_t cipher, const odp_crypto_key_t *cipher_key, odp_auth_alg_t auth, @@ -411,6 +484,8 @@ static void test_out_in_common(ipsec_test_flags *flags, odp_ipsec_stats_t stats; odp_ipsec_sa_t sa_out; odp_ipsec_sa_t sa_in; + odp_proto_l3_type_t out_l3_type = ODP_PROTO_L3_TYPE_IPV4; + odp_proto_l4_type_t out_l4_type = ODP_PROTO_L4_TYPE_ESP; CU_ASSERT_NOT_EQUAL_FATAL(flags, NULL); @@ -463,17 +538,28 @@ static void test_out_in_common(ipsec_test_flags *flags, CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa_in); - ipsec_test_part test = { + if ((flags->tunnel && flags->tunnel_is_v6) || + (!flags->tunnel && flags->v6)) + out_l3_type = ODP_PROTO_L3_TYPE_IPV6; + if (flags->ah) + out_l4_type = ODP_PROTO_L4_TYPE_AH; + if (flags->udp_encap) + out_l4_type = ODP_PROTO_L4_TYPE_UDP; + + ipsec_test_part test_out = { .pkt_in = &pkt_ipv4_icmp_0, .num_pkt = 1, .out = { { .status.warn.all = 0, .status.error.all = 0, - .l3_type = ODP_PROTO_L3_TYPE_IPV4, - .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, - .pkt_res = &pkt_ipv4_icmp_0 }, + .l3_type = out_l3_type, + .l4_type = out_l4_type, + }, }, - .in = { + }; + ipsec_test_part test_in = { + .num_pkt = 1, + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -483,21 +569,19 @@ static void test_out_in_common(ipsec_test_flags *flags, }; if (flags->v6) { - test.pkt_in = &pkt_ipv6_icmp_0; - test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV6; - test.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV6; - test.out[0].pkt_res = &pkt_ipv6_icmp_0; - test.in[0].l3_type = ODP_PROTO_L3_TYPE_IPV6; - test.in[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV6; - test.in[0].pkt_res = &pkt_ipv6_icmp_0; + test_out.pkt_in = &pkt_ipv6_icmp_0; + test_in.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV6; + test_in.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV6; + test_in.out[0].pkt_res = &pkt_ipv6_icmp_0; } - test.flags = *flags; + test_out.flags = flags->part_flags; + test_in.flags = flags->part_flags; if (flags->stats == IPSEC_TEST_STATS_PROTO_ERR) - test.in[0].status.error.proto = 1; + test_in.out[0].status.error.proto = 1; if (flags->stats == IPSEC_TEST_STATS_AUTH_ERR) - test.in[0].status.error.auth = 1; + test_in.out[0].status.error.auth = 1; if (flags->stats != IPSEC_TEST_STATS_NONE) { CU_ASSERT_EQUAL(odp_ipsec_stats(sa_out, &stats), 0); @@ -506,22 +590,23 @@ static void test_out_in_common(ipsec_test_flags *flags, test_ipsec_stats_zero_assert(&stats); } - if (flags->test_sa_seq_num) { + if (flags->part_flags.test_sa_seq_num) { int rc; - test.out[0].seq_num = 0x1235; - rc = ipsec_test_sa_update_seq_num(sa_out, test.out[0].seq_num); + test_out.out[0].seq_num = 0x1235; + rc = ipsec_test_sa_update_seq_num(sa_out, + test_out.out[0].seq_num); /* Skip further checks related to this specific test if the * SA update call was not successful. */ if (rc < 0) { printf("\t >> skipped"); - test.flags.test_sa_seq_num = false; + test_out.flags.test_sa_seq_num = false; } } - ipsec_check_out_in_one(&test, sa_out, sa_in); + 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); @@ -545,7 +630,7 @@ static void test_out_in_common(ipsec_test_flags *flags, static void test_esp_out_in(struct cipher_param *cipher, struct auth_param *auth, - ipsec_test_flags *flags) + const ipsec_test_flags *flags) { int cipher_keylen = cipher->key ? 8 * cipher->key->length : 0; int auth_keylen = auth->key ? 8 * auth->key->length : 0; @@ -604,7 +689,7 @@ static int is_out_mode_inline(void) static void test_esp_out_in_all_hdr_in_packet(void) { ipsec_test_flags flags = { - .inline_hdr_in_packet = true, + .part_flags.inline_hdr_in_packet = true, }; test_esp_out_in_all(&flags); } @@ -728,6 +813,8 @@ static void test_out_ipv4_ah_sha256_frag_check(void) test.pkt_in = &pkt_ipv4_icmp_0; test.num_pkt = 1; test.out[0].status.error.mtu = 1; + test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + test.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV4; test2.pkt_in = &pkt_ipv4_icmp_0; test2.num_opt = 1; @@ -766,6 +853,8 @@ static void test_out_ipv4_ah_sha256_frag_check_2(void) test.pkt_in = &pkt_ipv4_icmp_0; test.num_pkt = 1; test.out[0].status.error.mtu = 1; + test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + test.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV4; ipsec_test_part test2 = { .pkt_in = &pkt_ipv4_icmp_0, @@ -812,6 +901,8 @@ static void test_out_ipv4_esp_null_sha256_frag_check(void) test.pkt_in = &pkt_ipv4_icmp_0; test.num_pkt = 1; test.out[0].status.error.mtu = 1; + test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + test.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV4; test2.pkt_in = &pkt_ipv4_icmp_0; test2.num_opt = 1; @@ -851,6 +942,8 @@ static void test_out_ipv4_esp_null_sha256_frag_check_2(void) test.pkt_in = &pkt_ipv4_icmp_0; test.num_pkt = 1; test.out[0].status.error.mtu = 1; + test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + test.out[0].l4_type = ODP_PROTO_L4_TYPE_ICMPV4; ipsec_test_part test2 = { .pkt_in = &pkt_ipv4_icmp_0, @@ -1132,27 +1225,24 @@ static void test_out_ipv6_esp_udp_null_sha256(void) ipsec_sa_destroy(sa); } -static void test_out_dummy_esp_null_sha256_tun_ipv4(void) +static void test_out_dummy_esp_null_sha256_tun(odp_ipsec_tunnel_param_t tunnel) { - odp_ipsec_tunnel_param_t tunnel; odp_ipsec_sa_param_t param; odp_ipsec_sa_t sa; odp_ipsec_sa_t sa2; - uint32_t src = IPV4ADDR(10, 0, 111, 2); - uint32_t dst = IPV4ADDR(10, 0, 222, 2); ipsec_test_part test; + ipsec_test_part test_in; ipsec_test_part test_empty; + odp_proto_l3_type_t out_l3_type = ODP_PROTO_L3_TYPE_IPV4; + + if (tunnel.type == ODP_IPSEC_TUNNEL_IPV6) + out_l3_type = ODP_PROTO_L3_TYPE_IPV6; memset(&test, 0, sizeof(ipsec_test_part)); + memset(&test_in, 0, sizeof(ipsec_test_part)); memset(&test_empty, 0, sizeof(ipsec_test_part)); - memset(&tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); - tunnel.type = ODP_IPSEC_TUNNEL_IPV4; - tunnel.ipv4.src_addr = &src; - tunnel.ipv4.dst_addr = &dst; - tunnel.ipv4.ttl = 64; - - /* This test will not work properly inbound inline mode. + /* This test will not work properly in inbound inline mode. * Packet might be dropped and we will not check for that. */ if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) return; @@ -1179,35 +1269,49 @@ static void test_out_dummy_esp_null_sha256_tun_ipv4(void) test.pkt_in = &pkt_test_nodata; test.num_opt = 1; - test.opt .flag.tfc_dummy = 1; + test.opt.flag.tfc_dummy = 1; test.opt.tfc_pad_len = 16; test.num_pkt = 1; - test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; - test.out[0].l4_type = ODP_PROTO_L4_TYPE_NO_NEXT; + test.out[0].l3_type = out_l3_type; + test.out[0].l4_type = ODP_PROTO_L4_TYPE_ESP; + + test_in.num_pkt = 1; + test_in.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; + test_in.out[0].l4_type = ODP_PROTO_L4_TYPE_NO_NEXT; test_empty.pkt_in = &pkt_test_empty; test_empty.num_opt = 1; test_empty.opt.flag.tfc_dummy = 1; test_empty.opt.tfc_pad_len = 16; test_empty.num_pkt = 1; - test_empty.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; - test_empty.out[0].l4_type = ODP_PROTO_L4_TYPE_NO_NEXT; + test_empty.out[0].l3_type = out_l3_type; + test_empty.out[0].l4_type = ODP_PROTO_L4_TYPE_ESP; - ipsec_check_out_in_one(&test, sa, sa2); - ipsec_check_out_in_one(&test_empty, sa, sa2); + ipsec_check_out_in_one(&test, &test_in, sa, sa2, NULL); + ipsec_check_out_in_one(&test_empty, &test_in, sa, sa2, NULL); ipsec_sa_destroy(sa2); ipsec_sa_destroy(sa); } +static void test_out_dummy_esp_null_sha256_tun_ipv4(void) +{ + odp_ipsec_tunnel_param_t tunnel; + uint32_t src = IPV4ADDR(10, 0, 111, 2); + uint32_t dst = IPV4ADDR(10, 0, 222, 2); + + memset(&tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); + tunnel.type = ODP_IPSEC_TUNNEL_IPV4; + tunnel.ipv4.src_addr = &src; + tunnel.ipv4.dst_addr = &dst; + tunnel.ipv4.ttl = 64; + + test_out_dummy_esp_null_sha256_tun(tunnel); +} + static void test_out_dummy_esp_null_sha256_tun_ipv6(void) { odp_ipsec_tunnel_param_t tunnel; - odp_ipsec_sa_param_t param; - odp_ipsec_sa_t sa; - odp_ipsec_sa_t sa2; - ipsec_test_part test; - ipsec_test_part test_empty; uint8_t src[16] = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x43, 0xff, 0xfe, 0x4a, 0xd7, 0x0a, @@ -1217,61 +1321,13 @@ static void test_out_dummy_esp_null_sha256_tun_ipv6(void) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, }; - memset(&test, 0, sizeof(ipsec_test_part)); - memset(&test_empty, 0, sizeof(ipsec_test_part)); - memset(&tunnel, 0, sizeof(odp_ipsec_tunnel_param_t)); tunnel.type = ODP_IPSEC_TUNNEL_IPV6; tunnel.ipv6.src_addr = src; tunnel.ipv6.dst_addr = dst; tunnel.ipv6.hlimit = 64; - /* This test will not work properly inbound inline mode. - * Packet might be dropped and we will not check for that. */ - if (suite_context.inbound_op_mode == ODP_IPSEC_OP_MODE_INLINE) - return; - - ipsec_sa_param_fill(¶m, - false, false, 123, &tunnel, - ODP_CIPHER_ALG_NULL, NULL, - ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, - NULL, NULL); - - sa = odp_ipsec_sa_create(¶m); - - CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa); - - ipsec_sa_param_fill(¶m, - true, false, 123, &tunnel, - ODP_CIPHER_ALG_NULL, NULL, - ODP_AUTH_ALG_SHA256_HMAC, &key_5a_256, - NULL, NULL); - - sa2 = odp_ipsec_sa_create(¶m); - - CU_ASSERT_NOT_EQUAL_FATAL(ODP_IPSEC_SA_INVALID, sa2); - - test.pkt_in = &pkt_test_nodata; - test.num_opt = 1; - test.opt .flag.tfc_dummy = 1; - test.opt.tfc_pad_len = 16; - test.num_pkt = 1; - test.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; - test.out[0].l4_type = ODP_PROTO_L4_TYPE_NO_NEXT; - - test_empty.pkt_in = &pkt_test_empty; - test_empty.num_opt = 1; - test_empty.opt.flag.tfc_dummy = 1; - test_empty.opt.tfc_pad_len = 16; - test_empty.num_pkt = 1; - test_empty.out[0].l3_type = ODP_PROTO_L3_TYPE_IPV4; - test_empty.out[0].l4_type = ODP_PROTO_L4_TYPE_NO_NEXT; - - ipsec_check_out_in_one(&test, sa, sa2); - ipsec_check_out_in_one(&test_empty, sa, sa2); - - ipsec_sa_destroy(sa2); - ipsec_sa_destroy(sa); + test_out_dummy_esp_null_sha256_tun(tunnel); } static void test_out_ipv4_udp_esp_null_sha256(void) @@ -1400,19 +1456,29 @@ static void test_sa_info(void) CU_ASSERT_EQUAL_FATAL(0, odp_ipsec_sa_info(sa_in, &info_in)); CU_ASSERT_EQUAL(0, info_in.inbound.antireplay_window_top); - ipsec_test_part test = { + ipsec_test_part test_out = { .pkt_in = &pkt_ipv4_icmp_0, .num_pkt = 1, .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, + .l4_type = ODP_PROTO_L4_TYPE_ESP, + }, + }, + }; + ipsec_test_part test_in = { + .num_pkt = 1, + .out = { + { .status.warn.all = 0, + .status.error.all = 0, + .l3_type = ODP_PROTO_L3_TYPE_IPV4, .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, - .pkt_res = &pkt_ipv4_icmp_0 }, + }, }, }; - ipsec_check_out_in_one(&test, sa_out, sa_in); + ipsec_check_out_in_one(&test_out, &test_in, sa_out, sa_in, NULL); memset(&info_out, 0, sizeof(info_out)); CU_ASSERT_EQUAL_FATAL(0, odp_ipsec_sa_info(sa_out, &info_out)); @@ -1459,7 +1525,7 @@ static void test_test_sa_update_seq_num(void) memset(&flags, 0, sizeof(flags)); flags.display_algo = true; - flags.test_sa_seq_num = true; + flags.part_flags.test_sa_seq_num = true; test_esp_out_in_all(&flags); @@ -1603,21 +1669,24 @@ static void test_max_num_sa(void) odp_ipsec_sa_param_t param; const uint32_t spi_start = 256; odp_ipsec_sa_t sa_odd = ODP_IPSEC_SA_INVALID; - ipsec_test_part test = { + ipsec_test_part test_out = { .pkt_in = &pkt_ipv4_icmp_0, - .flags = { - /* Test lookup now that we have lots of SAs */ - .lookup = 1, - }, .num_pkt = 1, .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, - .l4_type = ODP_PROTO_L4_TYPE_ICMPV4, - .pkt_res = &pkt_ipv4_icmp_0 }, + .l4_type = ODP_PROTO_L4_TYPE_ESP, + }, + }, + }; + ipsec_test_part test_in = { + .flags = { + /* Test lookup now that we have lots of SAs */ + .lookup = 1, }, - .in = { + .num_pkt = 1, + .out = { { .status.warn.all = 0, .status.error.all = 0, .l3_type = ODP_PROTO_L3_TYPE_IPV4, @@ -1688,11 +1757,13 @@ static void test_max_num_sa(void) sa_odd = odp_ipsec_sa_create(¶m); CU_ASSERT_FATAL(sa_odd != ODP_IPSEC_SA_INVALID); - ipsec_check_out_in_one(&test, sa_odd, sa_in[n]); + ipsec_check_out_in_one(&test_out, &test_in, + sa_odd, sa_in[n], NULL); } for (n = 0; n < sa_pairs; n++) - ipsec_check_out_in_one(&test, sa_out[n], sa_in[n]); + ipsec_check_out_in_one(&test_out, &test_in, + sa_out[n], sa_in[n], NULL); for (n = 0; n < sa_pairs; n++) { ipsec_sa_destroy(sa_out[n]); diff --git a/test/validation/api/ipsec/reass_test_vectors.h b/test/validation/api/ipsec/reass_test_vectors.h new file mode 100644 index 000000000..4fbb1ebaf --- /dev/null +++ b/test/validation/api/ipsec/reass_test_vectors.h @@ -0,0 +1,395 @@ + /* Copyright (c) 2021, Marvell + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_REASS_TEST_VECTORS_H_ +#define _ODP_REASS_TEST_VECTORS_H_ + +/* The header file includes below test vectors */ + +/* IPv6: + * + * 1) pkt_ipv6_udp_p1 + * pkt_ipv6_udp_p1_f1 + * pkt_ipv6_udp_p1_f2 + * + * 2) pkt_ipv6_udp_p2 + * pkt_ipv6_udp_p2_f1 + * pkt_ipv6_udp_p2_f2 + * pkt_ipv6_udp_p2_f3 + * pkt_ipv6_udp_p2_f4 + */ + +/* IPv4: + * + * 1) pkt_ipv4_udp_p1 + * pkt_ipv4_udp_p1_f1 + * pkt_ipv4_udp_p1_f2 + * + * 2) pkt_ipv4_udp_p2 + * pkt_ipv4_udp_p2_f1 + * pkt_ipv4_udp_p2_f2 + * pkt_ipv4_udp_p2_f3 + * pkt_ipv4_udp_p2_f4 + */ + +static ipsec_test_packet pkt_ipv6_udp_p1 = { + .len = 1514, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 54, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x05, 0xb4, 0x11, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x05, 0xb4, 0x2b, 0xe8, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p1_f1 = { + .len = 1398, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x05, 0x40, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x00, 0x01, 0x5c, 0x92, 0xac, 0xf1, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x05, 0xb4, 0x2b, 0xe8, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p1_f2 = { + .len = 186, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x84, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x05, 0x38, 0x5c, 0x92, 0xac, 0xf1, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p2 = { + .len = 4496, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 54, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x11, 0x5a, 0x11, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x11, 0x5a, 0x8a, 0x11, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p2_f1 = { + .len = 1398, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x05, 0x40, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x00, 0x01, 0x64, 0x6c, 0x68, 0x9f, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x11, 0x5a, 0x8a, 0x11, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p2_f2 = { + .len = 1398, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x05, 0x40, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x05, 0x39, 0x64, 0x6c, 0x68, 0x9f, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p2_f3 = { + .len = 1398, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x05, 0x40, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x0a, 0x71, 0x64, 0x6c, 0x68, 0x9f, + }, +}; + +static ipsec_test_packet pkt_ipv6_udp_p2_f4 = { + .len = 496, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 62, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x86, 0xdd, + + /* IP */ + 0x60, 0x00, 0x00, 0x00, 0x01, 0xba, 0x2c, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x02, + 0x11, 0x00, 0x0f, 0xa8, 0x64, 0x6c, 0x68, 0x9f, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p1 = { + .len = 1514, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x05, 0xdc, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x11, 0x66, 0x0d, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x05, 0xc8, 0xb8, 0x4c, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p1_f1 = { + .len = 1434, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x05, 0x8c, 0x00, 0x01, 0x20, 0x00, + 0x40, 0x11, 0x46, 0x5d, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x05, 0xc8, 0xb8, 0x4c, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p1_f2 = { + .len = 114, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0xaf, + 0x40, 0x11, 0x6a, 0xd6, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p2 = { + .len = 4496, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x11, 0x82, 0x00, 0x02, 0x00, 0x00, + 0x40, 0x11, 0x5a, 0x66, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x11, 0x6e, 0x16, 0x76, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p2_f1 = { + .len = 1434, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x05, 0x8c, 0x00, 0x02, 0x20, 0x00, + 0x40, 0x11, 0x46, 0x5c, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + + /* UDP */ + 0x08, 0x00, 0x27, 0x10, 0x11, 0x6e, 0x16, 0x76, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p2_f2 = { + .len = 1434, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x05, 0x8c, 0x00, 0x02, 0x20, 0xaf, + 0x40, 0x11, 0x45, 0xad, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p2_f3 = { + .len = 1434, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x05, 0x8c, 0x00, 0x02, 0x21, 0x5e, + 0x40, 0x11, 0x44, 0xfe, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + }, +}; + +static ipsec_test_packet pkt_ipv4_udp_p2_f4 = { + .len = 296, + .l2_offset = 0, + .l3_offset = 14, + .l4_offset = 34, + .data = { + /* ETH */ + 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0x08, 0x00, + + /* IP */ + 0x45, 0x00, 0x01, 0x1a, 0x00, 0x02, 0x02, 0x0d, + 0x40, 0x11, 0x68, 0xc1, 0x0d, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, + }, +}; + +static inline void +test_vector_payload_populate(ipsec_test_packet *pkt, odp_bool_t first_frag) +{ + uint32_t i = pkt->l4_offset; + + /* For non-fragmented packets and first frag, skip 8 bytes from + * l4_offset for UDP header */ + + if (first_frag) + i += 8; + + for (; i < pkt->len; i++) + pkt->data[i] = 0x58; +} + +static inline void +reass_test_vectors_init(void) +{ + test_vector_payload_populate(&pkt_ipv6_udp_p1, true); + test_vector_payload_populate(&pkt_ipv6_udp_p1_f1, true); + test_vector_payload_populate(&pkt_ipv6_udp_p1_f2, false); + + test_vector_payload_populate(&pkt_ipv6_udp_p2, true); + test_vector_payload_populate(&pkt_ipv6_udp_p2_f1, true); + test_vector_payload_populate(&pkt_ipv6_udp_p2_f2, false); + test_vector_payload_populate(&pkt_ipv6_udp_p2_f3, false); + test_vector_payload_populate(&pkt_ipv6_udp_p2_f4, false); + + test_vector_payload_populate(&pkt_ipv4_udp_p1, true); + test_vector_payload_populate(&pkt_ipv4_udp_p1_f1, true); + test_vector_payload_populate(&pkt_ipv4_udp_p1_f2, false); + + test_vector_payload_populate(&pkt_ipv4_udp_p2, true); + test_vector_payload_populate(&pkt_ipv4_udp_p2_f1, true); + test_vector_payload_populate(&pkt_ipv4_udp_p2_f2, false); + test_vector_payload_populate(&pkt_ipv4_udp_p2_f3, false); + test_vector_payload_populate(&pkt_ipv4_udp_p2_f4, false); +} + +#endif diff --git a/test/validation/api/packet/packet.c b/test/validation/api/packet/packet.c index 2054eb95f..cd3009ce3 100644 --- a/test/validation/api/packet/packet.c +++ b/test/validation/api/packet/packet.c @@ -10,7 +10,9 @@ #include <odp_api.h> #include <odp_cunit_common.h> -#include <test_packet_parser.h> +#include <test_packet_ipv4.h> +#include <test_packet_ipsec.h> +#include <test_packet_ipv6.h> #include <odp/helper/odph_api.h> @@ -914,7 +916,7 @@ static void _verify_headroom_shift(odp_packet_t *pkt, extended = 1; } } else { - if ((uint32_t)abs(shift) <= seg_data_len) { + if ((uint32_t)abs(shift) < seg_data_len) { data = odp_packet_pull_head(*pkt, -shift); extended = 0; } else { @@ -1017,7 +1019,7 @@ static void _verify_tailroom_shift(odp_packet_t *pkt, CU_ASSERT(l3_off == odp_packet_l3_offset(*pkt)); CU_ASSERT(l4_off == odp_packet_l4_offset(*pkt)); } else { - if ((uint32_t)abs(shift) <= seg_data_len) { + if ((uint32_t)abs(shift) < seg_data_len) { tail = odp_packet_pull_tail(*pkt, -shift); extended = 0; } else { diff --git a/test/validation/api/pktio/lso.c b/test/validation/api/pktio/lso.c index 5d0596861..bde94816e 100644 --- a/test/validation/api/pktio/lso.c +++ b/test/validation/api/pktio/lso.c @@ -6,7 +6,8 @@ #include <odp_api.h> #include <odp_cunit_common.h> -#include <test_packet_parser.h> +#include <test_packet_ipv4.h> +#include <test_packet_custom.h> #include <odp/helper/odph_api.h> diff --git a/test/validation/api/pktio/parser.c b/test/validation/api/pktio/parser.c index 9c493b45e..2b5042724 100644 --- a/test/validation/api/pktio/parser.c +++ b/test/validation/api/pktio/parser.c @@ -6,7 +6,8 @@ #include <odp_api.h> #include <odp_cunit_common.h> -#include <test_packet_parser.h> +#include <test_packet_ipv4.h> +#include <test_packet_ipv6.h> #include <odp/helper/odph_api.h> diff --git a/test/validation/api/pktio/pktio.c b/test/validation/api/pktio/pktio.c index da87c7ebc..7549e16ef 100644 --- a/test/validation/api/pktio/pktio.c +++ b/test/validation/api/pktio/pktio.c @@ -1942,21 +1942,23 @@ static void _print_pktio_stats(odp_pktio_stats_t *s, const char *name) { ODPH_ERR("\n%s:\n" " in_octets %" PRIu64 "\n" + " in_packets %" PRIu64 "\n" " in_ucast_pkts %" PRIu64 "\n" " in_discards %" PRIu64 "\n" " in_errors %" PRIu64 "\n" - " in_unknown_protos %" PRIu64 "\n" " out_octets %" PRIu64 "\n" + " out_packets %" PRIu64 "\n" " out_ucast_pkts %" PRIu64 "\n" " out_discards %" PRIu64 "\n" " out_errors %" PRIu64 "\n", name, s->in_octets, + s->in_packets, s->in_ucast_pkts, s->in_discards, s->in_errors, - s->in_unknown_protos, s->out_octets, + s->out_packets, s->out_ucast_pkts, s->out_discards, s->out_errors); @@ -2005,6 +2007,7 @@ static void pktio_test_statistics_counters(void) odp_pktout_queue_t pktout; uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS); odp_pktio_stats_t stats[2]; + odp_pktio_stats_t *rx_stats, *tx_stats; for (i = 0; i < num_ifaces; i++) { pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED, @@ -2061,28 +2064,31 @@ static void pktio_test_statistics_counters(void) ret = odp_pktio_stats(pktio_tx, &stats[0]); CU_ASSERT(ret == 0); - + tx_stats = &stats[0]; + + CU_ASSERT((tx_stats->out_octets == 0) || + (tx_stats->out_octets >= (PKT_LEN_NORMAL * (uint64_t)pkts))); + CU_ASSERT((tx_stats->out_packets == 0) || + (tx_stats->out_packets >= (uint64_t)pkts)); + CU_ASSERT((tx_stats->out_ucast_pkts == 0) || + (tx_stats->out_ucast_pkts >= (uint64_t)pkts)); + CU_ASSERT(tx_stats->out_discards == 0); + CU_ASSERT(tx_stats->out_errors == 0); + + rx_stats = &stats[0]; if (num_ifaces > 1) { - ret = odp_pktio_stats(pktio_rx, &stats[1]); + rx_stats = &stats[1]; + ret = odp_pktio_stats(pktio_rx, rx_stats); CU_ASSERT(ret == 0); - CU_ASSERT((stats[1].in_ucast_pkts == 0) || - (stats[1].in_ucast_pkts >= (uint64_t)pkts)); - CU_ASSERT((stats[0].out_octets == 0) || - (stats[0].out_octets >= - (PKT_LEN_NORMAL * (uint64_t)pkts))); - } else { - CU_ASSERT((stats[0].in_ucast_pkts == 0) || - (stats[0].in_ucast_pkts == (uint64_t)pkts)); - CU_ASSERT((stats[0].in_octets == 0) || - (stats[0].in_octets == - (PKT_LEN_NORMAL * (uint64_t)pkts))); - } - - CU_ASSERT(0 == stats[0].in_discards); - CU_ASSERT(0 == stats[0].in_errors); - CU_ASSERT(0 == stats[0].in_unknown_protos); - CU_ASSERT(0 == stats[0].out_discards); - CU_ASSERT(0 == stats[0].out_errors); + } + CU_ASSERT((rx_stats->in_octets == 0) || + (rx_stats->in_octets >= (PKT_LEN_NORMAL * (uint64_t)pkts))); + CU_ASSERT((rx_stats->in_packets == 0) || + (rx_stats->in_packets >= (uint64_t)pkts)); + CU_ASSERT((rx_stats->in_ucast_pkts == 0) || + (rx_stats->in_ucast_pkts >= (uint64_t)pkts)); + CU_ASSERT(rx_stats->in_discards == 0); + CU_ASSERT(rx_stats->in_errors == 0); for (i = 0; i < num_ifaces; i++) { CU_ASSERT(odp_pktio_stop(pktio[i]) == 0); diff --git a/test/validation/api/system/system.c b/test/validation/api/system/system.c index 9beb89cf2..e511582dc 100644 --- a/test/validation/api/system/system.c +++ b/test/validation/api/system/system.c @@ -20,6 +20,9 @@ /* 10 usec wait time assumes >100kHz resolution on CPU cycles counter */ #define WAIT_TIME (10 * ODP_TIME_USEC_IN_NS) +/* Check if value is power of two */ +#define IS_POW2(x) ((((x) - 1) & (x)) == 0) + static void test_version_api_str(void) { int char_ok = 0; @@ -248,7 +251,11 @@ static void system_test_odp_sys_cache_line_size(void) cache_size = odp_sys_cache_line_size(); CU_ASSERT(0 < cache_size); - CU_ASSERT(ODP_CACHE_LINE_SIZE == cache_size); + CU_ASSERT(0 < ODP_CACHE_LINE_SIZE); + CU_ASSERT(IS_POW2(cache_size)); + CU_ASSERT(IS_POW2(ODP_CACHE_LINE_SIZE)); + if (ODP_CACHE_LINE_SIZE != cache_size) + printf("WARNING: ODP_CACHE_LINE_SIZE and odp_sys_cache_line_size() not matching\n"); CU_ASSERT(ODP_CACHE_LINE_ROUNDUP(0) == 0); CU_ASSERT(ODP_CACHE_LINE_ROUNDUP(1) == ODP_CACHE_LINE_SIZE); |