From 39f85bc6cab329b4ae41ba2ec922370c24254325 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 21 Feb 2017 14:51:32 +0200 Subject: helper: linux: add common linux helper file Added common helper file for backwards compatibility. This file includes all headers under helper/linux directory. It's installed only with --enable-helper-linux configuration option. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- helper/Makefile.am | 3 +++ helper/include/odp/helper/linux.h | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 helper/include/odp/helper/linux.h diff --git a/helper/Makefile.am b/helper/Makefile.am index 5757c7c81..b478dcdda 100644 --- a/helper/Makefile.am +++ b/helper/Makefile.am @@ -32,6 +32,9 @@ helperinclude_HEADERS = \ $(srcdir)/include/odp/helper/udp.h if helper_linux +helperinclude_HEADERS += \ + $(srcdir)/include/odp/helper/linux.h + helperlinuxincludedir = $(includedir)/odp/helper/linux helperlinuxinclude_HEADERS = \ $(srcdir)/include/odp/helper/linux/pthread.h \ diff --git a/helper/include/odp/helper/linux.h b/helper/include/odp/helper/linux.h new file mode 100644 index 000000000..396203a27 --- /dev/null +++ b/helper/include/odp/helper/linux.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * All ODP Linux helpers + * + */ + +#ifndef ODP_HELPER_LINUX_H_ +#define ODP_HELPER_LINUX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#ifdef __cplusplus +} +#endif +#endif -- cgit v1.2.3 From e93df7d7b3b278dfadba4a9b7c01afc0dd411f13 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 21 Feb 2017 14:51:33 +0200 Subject: helper: pkgconfig: remove linux-generic from helper lib name Helper library should be built ABI compatible when it's part of a distro. There's no need to have implementation specific helper libs. Those would be needed only if non-ABI compat helper libraries need to be distributed. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- configure.ac | 2 +- helper/Makefile.am | 2 +- pkgconfig/libodphelper-linux-generic.pc.in | 11 ----------- pkgconfig/libodphelper.pc.in | 11 +++++++++++ 4 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 pkgconfig/libodphelper-linux-generic.pc.in create mode 100644 pkgconfig/libodphelper.pc.in diff --git a/configure.ac b/configure.ac index 1f9e5cfaa..8be06debd 100644 --- a/configure.ac +++ b/configure.ac @@ -328,7 +328,7 @@ AM_CXXFLAGS="-std=c++11" AC_CONFIG_FILES([Makefile pkgconfig/libodp-linux.pc - pkgconfig/libodphelper-linux-generic.pc + pkgconfig/libodphelper.pc ]) AC_SEARCH_LIBS([timer_create],[rt posix4]) diff --git a/helper/Makefile.am b/helper/Makefile.am index b478dcdda..2c5452dcc 100644 --- a/helper/Makefile.am +++ b/helper/Makefile.am @@ -1,7 +1,7 @@ include $(top_srcdir)/platform/@with_platform@/Makefile.inc pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(top_builddir)/pkgconfig/libodphelper-linux-generic.pc +pkgconfig_DATA = $(top_builddir)/pkgconfig/libodphelper.pc LIB = $(top_builddir)/lib AM_CFLAGS += -I$(srcdir)/include diff --git a/pkgconfig/libodphelper-linux-generic.pc.in b/pkgconfig/libodphelper-linux-generic.pc.in deleted file mode 100644 index cab7be2dd..000000000 --- a/pkgconfig/libodphelper-linux-generic.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libodphelper-linux-generic -Description: Helper for the ODP packet processing engine -Version: @PKGCONFIG_VERSION@ -Libs: -L${libdir} -lodphelper-linux-generic -Libs.private: -Cflags: -I${includedir} diff --git a/pkgconfig/libodphelper.pc.in b/pkgconfig/libodphelper.pc.in new file mode 100644 index 000000000..b14335e5c --- /dev/null +++ b/pkgconfig/libodphelper.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libodphelper +Description: Helper for the ODP packet processing engine +Version: @PKGCONFIG_VERSION@ +Libs: -L${libdir} -lodphelper +Libs.private: +Cflags: -I${includedir} -- cgit v1.2.3 From 2bac2dbfd7a7c55e588a6b72af22ae7b810558f7 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Tue, 21 Feb 2017 14:51:34 +0200 Subject: linux-gen: dependencies: update cunit install instructions Add missing commands and update instructions for installing into default location for 'make distcheck'. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- DEPENDENCIES | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 574859ce5..6b69bd97b 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -215,8 +215,22 @@ Prerequisites for building the OpenDataPlane (ODP) API tar -jxf *.bz2 cd CUnit* ./bootstrap + + # Install CUnit into the default location (/usr/local). This is needed for + # 'make distcheck'. + ./configure + make + sudo make install + + # ... OR ... Install CUnit into user defined location. The same path is + # used in step 4.4 --with-cunit-path=/home/ + ./configure --prefix=/home/ + make make install - #In Step 4.4 use --with-cunit-path=/home/${USER}/CUnitHome + + # Also (in Ubuntu at least) run ldconfig to update shared lib cache or + # reboot, before trying to run e.g. 'make distcheck'. + sudo ldconfig 4.3 Cross compile of Cunit @@ -227,8 +241,11 @@ Prerequisites for building the OpenDataPlane (ODP) API 4.4 Using Cunit with ODP $ Add the configuration option to the regular configuration options - ./configure --enable-cunit #if cunit is in the PATH - ./configure --with-cunit-path=DIR #only if you need a path to Cunit libs and headers + # Use the default path ... + ./configure --enable-cunit + + # ... OR the user defined path. + ./configure --with-cunit-path=/home/ 5.0 Documentation Images & Doxygen -- cgit v1.2.3 From 88dbb00623102878f2e0e1dd720a942fdd980ca3 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Wed, 18 Jan 2017 16:05:16 -0600 Subject: linux-generic: pool: add odp_pool_capability() rc check Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2826 by adding an explicit check of the rc from odp_pool_capability() for consistency with other code that calls this routine. Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_pool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index cf7c2c415..145002d96 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -445,7 +445,8 @@ static int check_params(odp_pool_param_t *params) { odp_pool_capability_t capa; - odp_pool_capability(&capa); + if (odp_pool_capability(&capa) < 0) + return -1; switch (params->type) { case ODP_POOL_BUFFER: -- cgit v1.2.3 From a347c91412f0db5c25141b709a93eaf040a77730 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 27 Feb 2017 14:38:56 +0200 Subject: linux-gen: dpdk: improve pmd driver linking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously each dpdk pmd driver had to be individually referred in the odp code to ensure proper gcc constructor linking. Using the -—whole-archive option when linking the drivers removes this need. After this patch new dpdk pmd drivers are automatically linked. Signed-off-by: Matias Elo Signed-off-by: Maxim Uvarov --- platform/linux-generic/m4/odp_dpdk.m4 | 33 +++++--- platform/linux-generic/pktio/dpdk.c | 152 +--------------------------------- 2 files changed, 22 insertions(+), 163 deletions(-) diff --git a/platform/linux-generic/m4/odp_dpdk.m4 b/platform/linux-generic/m4/odp_dpdk.m4 index 30347dce8..58d14727b 100644 --- a/platform/linux-generic/m4/odp_dpdk.m4 +++ b/platform/linux-generic/m4/odp_dpdk.m4 @@ -2,22 +2,10 @@ # Enable DPDK support ########################################################################## pktio_dpdk_support=no -AC_ARG_ENABLE([dpdk_support], - [ --enable-dpdk-support include dpdk IO support], - [if test x$enableval = xyes; then - pktio_dpdk_support=yes - fi]) - -########################################################################## -# Set optional DPDK path -########################################################################## AC_ARG_WITH([dpdk-path], -AC_HELP_STRING([--with-dpdk-path=DIR path to dpdk build directory], - [(or in the default path if not specified).]), +AC_HELP_STRING([--with-dpdk-path=DIR path to dpdk build directory]), [DPDK_PATH=$withval AM_CPPFLAGS="$AM_CPPFLAGS -msse4.2 -isystem $DPDK_PATH/include" - AM_LDFLAGS="$AM_LDFLAGS -L$DPDK_PATH/lib" - LIBS="$LIBS -ldpdk -ldl -lpcap" pktio_dpdk_support=yes],[]) ########################################################################## @@ -28,12 +16,31 @@ CPPFLAGS="$AM_CPPFLAGS $CPPFLAGS" ########################################################################## # Check for DPDK availability +# +# DPDK pmd drivers are not linked unless the --whole-archive option is +# used. No spaces are allowed between the --whole-arhive flags. ########################################################################## if test x$pktio_dpdk_support = xyes then AC_CHECK_HEADERS([rte_config.h], [], [AC_MSG_FAILURE(["can't find DPDK header"])]) + + DPDK_PMD=--whole-archive, + for filename in $with_dpdk_path/lib/*.a; do + cur_driver=`echo $(basename "$filename" .a) | \ + sed -n 's/^\(librte_pmd_\)/-lrte_pmd_/p' | sed -n 's/$/,/p'` + # rte_pmd_nfp has external dependencies which break linking + if test "$cur_driver" = "-lrte_pmd_nfp,"; then + echo "skip linking rte_pmd_nfp" + else + DPDK_PMD+=$cur_driver + fi + done + DPDK_PMD+=--no-whole-archive + ODP_CFLAGS="$ODP_CFLAGS -DODP_PKTIO_DPDK" + AM_LDFLAGS="$AM_LDFLAGS -L$DPDK_PATH/lib -Wl,$DPDK_PMD" + LIBS="$LIBS -ldpdk -ldl -lpcap" else pktio_dpdk_support=no fi diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 1922109a7..6ac89bd5d 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -34,49 +34,6 @@ static int disable_pktio; /** !0 this pktio disabled, 0 enabled */ /* Has dpdk_pktio_init() been called */ static odp_bool_t dpdk_initialized; -#define PMD_EXT(drv) \ -extern void devinitfn_##drv(void) - -PMD_EXT(aesni_gcm_pmd_drv); -PMD_EXT(cryptodev_aesni_mb_pmd_drv); -PMD_EXT(cryptodev_kasumi_pmd_drv); -PMD_EXT(cryptodev_null_pmd_drv); -PMD_EXT(cryptodev_snow3g_pmd_drv); -PMD_EXT(pmd_qat_drv); -PMD_EXT(pmd_af_packet_drv); -PMD_EXT(rte_bnx2x_driver); -PMD_EXT(rte_bnx2xvf_driver); -PMD_EXT(bnxt_pmd_drv); -PMD_EXT(bond_drv); -PMD_EXT(rte_cxgbe_driver); -PMD_EXT(em_pmd_drv); -PMD_EXT(pmd_igb_drv); -PMD_EXT(pmd_igbvf_drv); -PMD_EXT(ena_pmd_drv); -PMD_EXT(rte_enic_driver); -PMD_EXT(rte_fm10k_driver); -PMD_EXT(rte_i40e_driver); -PMD_EXT(rte_i40evf_driver); -PMD_EXT(rte_ixgbe_driver); -PMD_EXT(rte_ixgbevf_driver); -PMD_EXT(rte_mlx4_driver); -PMD_EXT(rte_mlx5_driver); -PMD_EXT(pmd_mpipe_xgbe_drv); -PMD_EXT(pmd_mpipe_gbe_drv); -PMD_EXT(rte_nfp_net_driver); -PMD_EXT(pmd_null_drv); -PMD_EXT(pmd_pcap_drv); -PMD_EXT(rte_qede_driver); -PMD_EXT(rte_qedevf_driver); -PMD_EXT(pmd_ring_drv); -PMD_EXT(pmd_szedata2_drv); -PMD_EXT(rte_nicvf_driver); -PMD_EXT(pmd_vhost_drv); -PMD_EXT(rte_virtio_driver); -PMD_EXT(virtio_user_driver); -PMD_EXT(rte_vmxnet3_driver); -PMD_EXT(pmd_xenvirt_drv); - #define MEMPOOL_OPS(hdl) \ extern void mp_hdlr_init_##hdl(void) @@ -89,116 +46,11 @@ MEMPOOL_OPS(ops_stack); /* * This function is not called from anywhere, it's only purpose is to make sure * that if ODP and DPDK are statically linked to an application, the GCC - * constructors of the PMDs are linked as well. Otherwise the linker would omit - * them. It's not an issue with dynamic linking. */ + * constructors of mempool handlers are linked as well. Otherwise the linker + * would omit them. It's not an issue with dynamic linking. */ void refer_constructors(void); void refer_constructors(void) { -#ifdef RTE_LIBRTE_PMD_AESNI_GCM - devinitfn_aesni_gcm_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_AESNI_MB - devinitfn_cryptodev_aesni_mb_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_KASUMI - devinitfn_cryptodev_kasumi_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_NULL_CRYPTO - devinitfn_cryptodev_null_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_SNOW3G - devinitfn_cryptodev_snow3g_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_QAT - devinitfn_pmd_qat_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_AF_PACKET - devinitfn_pmd_af_packet_drv(); -#endif -#ifdef RTE_LIBRTE_BNX2X_PMD - devinitfn_rte_bnx2x_driver(); - devinitfn_rte_bnx2xvf_driver(); -#endif -#ifdef RTE_LIBRTE_BNXT_PMD - devinitfn_bnxt_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_BOND - devinitfn_bond_drv(); -#endif -#ifdef RTE_LIBRTE_CXGBE_PMD - devinitfn_rte_cxgbe_driver(); -#endif -#ifdef RTE_LIBRTE_EM_PMD - devinitfn_em_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_IGB_PMD - devinitfn_pmd_igb_drv(); - devinitfn_pmd_igbvf_drv(); -#endif -#ifdef RTE_LIBRTE_ENA_PMD - devinitfn_ena_pmd_drv(); -#endif -#ifdef RTE_LIBRTE_ENIC_PMD - devinitfn_rte_enic_driver(); -#endif -#ifdef RTE_LIBRTE_FM10K_PMD - devinitfn_rte_fm10k_driver(); -#endif -#ifdef RTE_LIBRTE_I40E_PMD - devinitfn_rte_i40e_driver(); - devinitfn_rte_i40evf_driver(); -#endif -#ifdef RTE_LIBRTE_IXGBE_PMD - devinitfn_rte_ixgbe_driver(); - devinitfn_rte_ixgbevf_driver(); -#endif -#ifdef RTE_LIBRTE_MLX4_PMD - devinitfn_rte_mlx4_driver(); -#endif -#ifdef RTE_LIBRTE_MLX5_PMD - devinitfn_rte_mlx5_driver(); -#endif -#ifdef RTE_LIBRTE_MPIPE_PMD - devinitfn_pmd_mpipe_xgbe_drv() - devinitfn_pmd_mpipe_gbe_drv() -#endif -#ifdef RTE_LIBRTE_NFP_PMD - devinitfn_rte_nfp_net_driver(); -#endif -#ifdef RTE_LIBRTE_PMD_NULL - devinitfn_pmd_null_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_PCAP - devinitfn_pmd_pcap_drv(); -#endif -#ifdef RTE_LIBRTE_QEDE_PMD - devinitfn_rte_qede_driver(); - devinitfn_rte_qedevf_driver(); -#endif -#ifdef RTE_LIBRTE_PMD_RING - devinitfn_pmd_ring_drv(); -#endif -#ifdef RTE_LIBRTE_PMD_SZEDATA2 - devinitfn_pmd_szedata2_drv(); -#endif -#ifdef RTE_LIBRTE_THUNDERX_NICVF_PMD - devinitfn_rte_nicvf_driver(); -#endif -#ifdef RTE_LIBRTE_PMD_VHOST - devinitfn_pmd_vhost_drv(); -#endif -#ifdef RTE_LIBRTE_VIRTIO_PMD - devinitfn_rte_virtio_driver(); -#endif -#ifdef RTE_VIRTIO_USER - devinitfn_rte_virtio_driver(); -#endif -#ifdef RTE_LIBRTE_VMXNET3_PMD - devinitfn_rte_vmxnet3_driver(); -#endif -#ifdef RTE_LIBRTE_PMD_XENVIRT - devinitfn_pmd_xenvirt_drv(); -#endif mp_hdlr_init_ops_mp_mc(); mp_hdlr_init_ops_sp_sc(); mp_hdlr_init_ops_mp_sc(); -- cgit v1.2.3 From e6a635ac73e99a9a7a6b499685a72139e87044ea Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 27 Feb 2017 14:38:57 +0200 Subject: linux-gen: dpdk: disable pci devices when running make check Disable pci devices during DPDK pktio validation test. If the system has pci devices mapped to DPDK pmd drivers they may overlap with the test vdev device indices, which will cause the validation test to fail. Signed-off-by: Matias Elo Signed-off-by: Maxim Uvarov --- test/linux-generic/validation/api/pktio/pktio_run_dpdk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/linux-generic/validation/api/pktio/pktio_run_dpdk.sh b/test/linux-generic/validation/api/pktio/pktio_run_dpdk.sh index fa46fa430..3060dc003 100755 --- a/test/linux-generic/validation/api/pktio/pktio_run_dpdk.sh +++ b/test/linux-generic/validation/api/pktio/pktio_run_dpdk.sh @@ -74,7 +74,7 @@ run() if [ "$ODP_PKTIO_IF0" = "" ]; then setup_pktio_env clean - export ODP_PKTIO_DPDK_PARAMS="--vdev eth_pcap0,iface=$IF0 --vdev eth_pcap1,iface=$IF1" + export ODP_PKTIO_DPDK_PARAMS="--no-pci --vdev eth_pcap0,iface=$IF0 --vdev eth_pcap1,iface=$IF1" export ODP_PKTIO_IF0=0 export ODP_PKTIO_IF1=1 fi -- cgit v1.2.3 From 37db76d04174f90f86c8103e6a1ca9d1e9518098 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 27 Feb 2017 14:38:58 +0200 Subject: linux-gen: dpdk: bump target dpdk version to 17.02 Signed-off-by: Matias Elo Signed-off-by: Maxim Uvarov --- .travis.yml | 2 +- DEPENDENCIES | 2 +- scripts/build-pktio-dpdk | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 83ec65f89..aa7ea0107 100644 --- a/.travis.yml +++ b/.travis.yml @@ -80,7 +80,7 @@ before_install: # DPDK pktio - TARGET=${TARGET:-"x86_64-native-linuxapp-gcc"} - - git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v16.07 http://dpdk.org/git/dpdk dpdk + - git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v17.02 http://dpdk.org/git/dpdk dpdk - pushd dpdk - git log --oneline --decorate - make config T=${TARGET} O=${TARGET} diff --git a/DEPENDENCIES b/DEPENDENCIES index 6b69bd97b..a194cad1c 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -165,7 +165,7 @@ Prerequisites for building the OpenDataPlane (ODP) API 3.4.1 Building DPDK and ODP with DPDK pktio support - DPDK packet I/O has been tested to work with DPDK v16.07. + DPDK packet I/O has been tested to work with DPDK v17.02. Follow steps in ./scripts/build-pktio-dpdk diff --git a/scripts/build-pktio-dpdk b/scripts/build-pktio-dpdk index 36727dd7b..6c6830ac0 100755 --- a/scripts/build-pktio-dpdk +++ b/scripts/build-pktio-dpdk @@ -10,7 +10,7 @@ if [ "$?" != "0" ]; then echo "Error: pcap is not installed. You may need to install libpcap-dev" fi -git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v16.07 http://dpdk.org/git/dpdk dpdk +git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v17.02 http://dpdk.org/git/dpdk dpdk pushd dpdk git log --oneline --decorate -- cgit v1.2.3 From ec8a54c9236925ea97ee154eb70093d6effb1311 Mon Sep 17 00:00:00 2001 From: Janne Peltonen Date: Tue, 7 Mar 2017 11:16:32 +0200 Subject: linux-gen: abi: fix include/odp/api/abi symlink creation Fix the ABI symlink creation that went broken in 3d6cbd2. Signed-off-by: Janne Peltonen Signed-off-by: Maxim Uvarov --- platform/linux-generic/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 682bac6c1..056ba67d6 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -225,7 +225,7 @@ endif # specific include path for installed files. install-data-hook: if [ -h $(prefix)/include/odp/api/abi ]; then \ - : \ + : ; \ else \ $(LN_S) -rf $(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ $(prefix)/include/odp/api/abi; \ -- cgit v1.2.3 From 746455fcdf279fcef7ec6a3eb6c5f1b465588554 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 13 Mar 2017 17:14:57 +0200 Subject: linux-gen: packet: make inline table visible Add visibility markers to make inline offset table visible applications linking against an installed copy of the library. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_packet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 60eef3a64..b8aac6bfe 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -24,6 +24,8 @@ /* Initial packet segment data length */ #define BASE_LEN CONFIG_PACKET_MAX_SEG_LEN +#include + /* Fill in packet header field offsets for inline functions */ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { .data = offsetof(odp_packet_hdr_t, buf_hdr.seg[0].data), @@ -43,6 +45,8 @@ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { }; +#include + static inline odp_packet_hdr_t *packet_hdr(odp_packet_t pkt) { return (odp_packet_hdr_t *)(uintptr_t)pkt; -- cgit v1.2.3 From b056efea2b416831e4d0ecf6494ee10c8da4b117 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 14 Mar 2017 09:30:05 +0200 Subject: test: bench_packet: add tests for reference functions Add microbenchmarks for the new packet reference functions. Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_bench_packet.c | 86 +++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/test/common_plat/performance/odp_bench_packet.c b/test/common_plat/performance/odp_bench_packet.c index 1aa9d819d..7a3a00429 100644 --- a/test/common_plat/performance/odp_bench_packet.c +++ b/test/common_plat/performance/odp_bench_packet.c @@ -338,6 +338,21 @@ static void alloc_concat_packets(void) TEST_REPEAT_COUNT); } +static void alloc_ref_packets(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *ref_tbl = gbl_args->pkt2_tbl; + + allocate_test_packets(gbl_args->pkt.len, pkt_tbl, TEST_REPEAT_COUNT); + + for (i = 0; i < TEST_REPEAT_COUNT; i++) { + ref_tbl[i] = odp_packet_ref(pkt_tbl[i], TEST_MIN_PKT_SIZE / 2); + if (ref_tbl[i] == ODP_PACKET_INVALID) + LOG_ABORT("Allocating packet reference failed\n"); + } +} + static void alloc_packets_twice(void) { allocate_test_packets(gbl_args->pkt.len, gbl_args->pkt_tbl, @@ -1212,6 +1227,67 @@ static int bench_packet_ts_set(void) return i; } +static int bench_packet_ref_static(void) +{ + int i; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *ref_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ref_tbl[i] = odp_packet_ref_static(pkt_tbl[i]); + + return i; +} + +static int bench_packet_ref(void) +{ + int i; + uint32_t offset = TEST_MIN_PKT_SIZE / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *ref_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ref_tbl[i] = odp_packet_ref(pkt_tbl[i], offset); + + return i; +} + +static int bench_packet_ref_pkt(void) +{ + int i; + uint32_t offset = TEST_MIN_PKT_SIZE / 2; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + odp_packet_t *hdr_tbl = gbl_args->pkt2_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + hdr_tbl[i] = odp_packet_ref_pkt(pkt_tbl[i], offset, hdr_tbl[i]); + + return i; +} + +static int bench_packet_unshared_len(void) +{ + int i; + uint32_t ret = 0; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_unshared_len(gbl_args->pkt_tbl[i]); + + return ret; +} + +static int bench_packet_has_ref(void) +{ + int i; + uint32_t ret = 0; + odp_packet_t *pkt_tbl = gbl_args->pkt_tbl; + + for (i = 0; i < TEST_REPEAT_COUNT; i++) + ret += odp_packet_has_ref(pkt_tbl[i]); + + return i; +} + /** * Prinf usage information */ @@ -1445,6 +1521,16 @@ bench_info_t test_suite[] = { BENCH_INFO(bench_packet_ts, create_packets, free_packets, NULL), BENCH_INFO(bench_packet_ts_set, create_packets, free_packets, NULL), + BENCH_INFO(bench_packet_ref_static, create_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_ref, create_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_ref_pkt, alloc_packets_twice, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_unshared_len, alloc_ref_packets, + free_packets_twice, NULL), + BENCH_INFO(bench_packet_has_ref, alloc_ref_packets, + free_packets_twice, NULL), }; /** -- cgit v1.2.3 From 97b7d50af6b7239db03d941e4816f4da98ab9449 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 10 Mar 2017 13:14:55 +0300 Subject: linux-generic: pool: don't allocate buffers from invalid pool Add ODP_ASSERT checking that passed pool is not ODP_POOL_INVALID before tring to allocate buffers from that pool. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_pool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/odp_pool.c index 145002d96..9dba73413 100644 --- a/platform/linux-generic/odp_pool.c +++ b/platform/linux-generic/odp_pool.c @@ -769,6 +769,8 @@ odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) pool_t *pool; int ret; + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool = pool_entry_from_hdl(pool_hdl); ret = buffer_alloc_multi(pool, &buf, NULL, 1); @@ -782,6 +784,8 @@ int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num) { pool_t *pool; + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool = pool_entry_from_hdl(pool_hdl); return buffer_alloc_multi(pool, buf, NULL, num); -- cgit v1.2.3 From 7ba232f77c60f707d279478a798f6ea14fe9c143 Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Tue, 21 Mar 2017 23:54:17 -0500 Subject: linux-gen: ring: fix memory ordering in ring dequeue Acquire ordering is needed to maintain proper release consistency with the ring enqueue operation. This issue presented itself as deadlock when running on an ARM-based chip. Signed-off-by: Brian Brooks Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp_ring_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/include/odp_ring_internal.h b/platform/linux-generic/include/odp_ring_internal.h index 55fedeb3a..44b83c603 100644 --- a/platform/linux-generic/include/odp_ring_internal.h +++ b/platform/linux-generic/include/odp_ring_internal.h @@ -57,7 +57,7 @@ static inline uint32_t ring_deq(ring_t *ring, uint32_t mask) /* Move reader head. This thread owns data at the new head. */ do { - tail = odp_atomic_load_u32(&ring->w_tail); + tail = odp_atomic_load_acq_u32(&ring->w_tail); if (head == tail) return RING_EMPTY; @@ -90,7 +90,7 @@ static inline uint32_t ring_deq_multi(ring_t *ring, uint32_t mask, /* Move reader head. This thread owns data at the new head. */ do { - tail = odp_atomic_load_u32(&ring->w_tail); + tail = odp_atomic_load_acq_u32(&ring->w_tail); /* Ring is empty */ if (head == tail) -- cgit v1.2.3 From 5876b4f36fbbaf10f5242915a1b29dee37cfb005 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Thu, 23 Mar 2017 16:56:50 -0500 Subject: validation: packet: do not require a max packet length Address bug https://bugs.linaro.org/show_bug.cgi?id=2908 by adding appropriate pool capability checks to the packet, pktio, and crypto tests to account for pkt.max_len, pkt.max_seg_len, or pkt.max_segs_per_pkt being zero, indicating these limits are bound only by available memory. Signed-off-by: Bill Fischofer Reviewed-by: Balakrishna Garapati Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.c | 6 ++++-- test/common_plat/validation/api/packet/packet.c | 13 +++++++++++-- test/common_plat/validation/api/pktio/pktio.c | 11 +++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/test/common_plat/validation/api/crypto/crypto.c b/test/common_plat/validation/api/crypto/crypto.c index e7c2bf320..94beb2f12 100644 --- a/test/common_plat/validation/api/crypto/crypto.c +++ b/test/common_plat/validation/api/crypto/crypto.c @@ -48,12 +48,14 @@ int crypto_init(odp_instance_t *inst) params.pkt.num = PKT_POOL_NUM; params.type = ODP_POOL_PACKET; - if (PKT_POOL_LEN > pool_capa.pkt.max_seg_len) { + if (pool_capa.pkt.max_seg_len && + PKT_POOL_LEN > pool_capa.pkt.max_seg_len) { fprintf(stderr, "Warning: small packet segment length\n"); params.pkt.seg_len = pool_capa.pkt.max_seg_len; } - if (PKT_POOL_LEN > pool_capa.pkt.max_len) { + if (pool_capa.pkt.max_len && + PKT_POOL_LEN > pool_capa.pkt.max_len) { fprintf(stderr, "Pool max packet length too small\n"); return -1; } diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index 900c42637..669122a70 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -114,6 +114,8 @@ int packet_suite_init(void) printf("pool_capability failed\n"); return -1; } + if (capa.pkt.max_segs_per_pkt == 0) + capa.pkt.max_segs_per_pkt = 10; /* Pick a typical packet size and decrement it to the single segment * limit if needed (min_seg_len maybe equal to max_len @@ -366,6 +368,8 @@ void packet_test_alloc_segmented(void) int ret, i, num_alloc; CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); + if (capa.pkt.max_segs_per_pkt == 0) + capa.pkt.max_segs_per_pkt = 10; if (capa.pkt.max_len) max_len = capa.pkt.max_len; @@ -1847,6 +1851,9 @@ void packet_test_extend_ref(void) { odp_packet_t max_pkt, ref; uint32_t hr, tr, max_len; + odp_pool_capability_t capa; + + CU_ASSERT_FATAL(odp_pool_capability(&capa) == 0); max_pkt = odp_packet_copy(segmented_test_packet, odp_packet_pool(segmented_test_packet)); @@ -1860,8 +1867,10 @@ void packet_test_extend_ref(void) odp_packet_push_tail(max_pkt, tr); /* Max packet should not be extendable at either end */ - CU_ASSERT(odp_packet_extend_tail(&max_pkt, 1, NULL, NULL) < 0); - CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) < 0); + if (max_len == capa.pkt.max_len) { + CU_ASSERT(odp_packet_extend_tail(&max_pkt, 1, NULL, NULL) < 0); + CU_ASSERT(odp_packet_extend_head(&max_pkt, 1, NULL, NULL) < 0); + } /* See if we can trunc and extend anyway */ CU_ASSERT(odp_packet_trunc_tail(&max_pkt, hr + tr + 1, diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 4f3c0c0f7..54f206efc 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -124,7 +124,7 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) { uint32_t seg_len; - seg_len = capa->pkt.max_seg_len; + seg_len = capa->pkt.max_seg_len ? capa->pkt.max_seg_len : PKT_BUF_SIZE; switch (pool_segmentation) { case PKT_POOL_SEGMENTED: @@ -620,7 +620,8 @@ static void pktio_txrx_multi(pktio_info_t *pktio_a, pktio_info_t *pktio_b, CU_ASSERT_FATAL(odp_pool_capability(&pool_capa) == 0); - if (packet_len > pool_capa.pkt.max_len) + if (pool_capa.pkt.max_len && + packet_len > pool_capa.pkt.max_len) packet_len = pool_capa.pkt.max_len; } @@ -1689,7 +1690,8 @@ int pktio_check_send_failure(void) odp_pktio_close(pktio_tx); /* Failure test supports only single segment */ - if (pool_capa.pkt.max_seg_len < mtu + 32) + if (pool_capa.pkt.max_seg_len && + pool_capa.pkt.max_seg_len < mtu + 32) return ODP_TEST_INACTIVE; return ODP_TEST_ACTIVE; @@ -1728,7 +1730,8 @@ void pktio_test_send_failure(void) CU_ASSERT_FATAL(odp_pool_capability(&pool_capa) == 0); - if (pool_capa.pkt.max_seg_len < mtu + 32) { + if (pool_capa.pkt.max_seg_len && + pool_capa.pkt.max_seg_len < mtu + 32) { CU_FAIL("Max packet seg length is too small."); return; } -- cgit v1.2.3 From 39b3a1681097638f5ba99666447553293abdef20 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Mon, 27 Feb 2017 18:21:19 +0300 Subject: linux-gen: remove pktio ipc option from configure Options becomes stable and not need any entry in main configure for platform specific pktio. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- configure.ac | 1 - platform/linux-generic/Makefile.am | 1 + platform/linux-generic/m4/configure.m4 | 1 - platform/linux-generic/m4/odp_ipc.m4 | 9 --------- test/linux-generic/Makefile.am | 3 --- 5 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 platform/linux-generic/m4/odp_ipc.m4 diff --git a/configure.ac b/configure.ac index 8be06debd..9320f360b 100644 --- a/configure.ac +++ b/configure.ac @@ -209,7 +209,6 @@ AC_SUBST([testdir]) # Set conditionals as computed within platform specific files ########################################################################## AM_CONDITIONAL([netmap_support], [test x$netmap_support = xyes ]) -AM_CONDITIONAL([PKTIO_IPC], [test x$pktio_ipc_support = xyes]) AM_CONDITIONAL([PKTIO_DPDK], [test x$pktio_dpdk_support = xyes ]) AM_CONDITIONAL([HAVE_PCAP], [test $have_pcap = yes]) AM_CONDITIONAL([SDK_INSTALL_PATH_], [test "x${SDK_INSTALL_PATH_}" = "x1"]) diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 056ba67d6..37835c394 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -9,6 +9,7 @@ AM_CFLAGS += -I$(top_srcdir)/include AM_CFLAGS += -I$(top_srcdir)/include/odp/arch/@ARCH_ABI@ AM_CFLAGS += -I$(top_builddir)/include AM_CFLAGS += -Iinclude +AM_CFLAGS += -D_ODP_PKTIO_IPC include_HEADERS = \ $(top_srcdir)/include/odp.h \ diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index d3e5528c1..a2a25408d 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -33,7 +33,6 @@ m4_include([platform/linux-generic/m4/odp_openssl.m4]) m4_include([platform/linux-generic/m4/odp_pcap.m4]) m4_include([platform/linux-generic/m4/odp_netmap.m4]) m4_include([platform/linux-generic/m4/odp_dpdk.m4]) -m4_include([platform/linux-generic/m4/odp_ipc.m4]) m4_include([platform/linux-generic/m4/odp_schedule.m4]) AC_CONFIG_FILES([platform/linux-generic/Makefile diff --git a/platform/linux-generic/m4/odp_ipc.m4 b/platform/linux-generic/m4/odp_ipc.m4 deleted file mode 100644 index 78217e221..000000000 --- a/platform/linux-generic/m4/odp_ipc.m4 +++ /dev/null @@ -1,9 +0,0 @@ -########################################################################## -# Enable IPC pktio support -########################################################################## -AC_ARG_ENABLE([pktio_ipc_support], - [ --enable-pktio_ipc-support include ipc IO support], - [if test x$enableval = xyes; then - pktio_ipc_support=yes - ODP_CFLAGS="$ODP_CFLAGS -D_ODP_PKTIO_IPC" - fi]) diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index 998ee5617..0522550ad 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -53,11 +53,8 @@ endif if PKTIO_DPDK TESTS += validation/api/pktio/pktio_run_dpdk.sh endif - -if PKTIO_IPC TESTS += pktio_ipc/pktio_ipc_run.sh SUBDIRS += pktio_ipc -endif else #performance tests refer to pktio_env if test_perf -- cgit v1.2.3 From fd980722c2a99d57ece3ec878d82dd94d03a5e76 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 21 Mar 2017 20:08:38 +0300 Subject: linux-gen: pktio: socket mmap: check unmap return code Check unmap return code https://bugs.linaro.org/show_bug.cgi?id=2831 Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- platform/linux-generic/pktio/socket_mmap.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index 666aae6af..fdf8cca54 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -454,11 +454,11 @@ static int mmap_sock(pkt_sock_mmap_t *pkt_sock) return 0; } -static void mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock) +static int mmap_unmap_sock(pkt_sock_mmap_t *pkt_sock) { - munmap(pkt_sock->mmap_base, pkt_sock->mmap_len); free(pkt_sock->rx_ring.rd); free(pkt_sock->tx_ring.rd); + return munmap(pkt_sock->mmap_base, pkt_sock->mmap_len); } static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, const char *netdev) @@ -486,8 +486,14 @@ static int mmap_bind_sock(pkt_sock_mmap_t *pkt_sock, const char *netdev) static int sock_mmap_close(pktio_entry_t *entry) { pkt_sock_mmap_t *const pkt_sock = &entry->s.pkt_sock_mmap; + int ret; + + ret = mmap_unmap_sock(pkt_sock); + if (ret != 0) { + ODP_ERR("mmap_unmap_sock() %s\n", strerror(errno)); + return -1; + } - mmap_unmap_sock(pkt_sock); if (pkt_sock->sockfd != -1 && close(pkt_sock->sockfd) != 0) { __odp_errno = errno; ODP_ERR("close(sockfd): %s\n", strerror(errno)); -- cgit v1.2.3 From 07bf459919d968674741fe9be6120124221ee62e Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 28 Mar 2017 14:03:23 +0300 Subject: test: generator: compose sending packets from reference packet plus differences Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 130 +++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 17 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 8062d8733..816db8808 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -170,21 +170,20 @@ static int scan_ip(char *buf, unsigned int *paddr) } /** - * set up an udp packet + * set up an udp packet reference * * @param pool Buffer pool to create packet in * * @return Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created */ -static odp_packet_t pack_udp_pkt(odp_pool_t pool) +static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool) { odp_packet_t pkt; char *buf; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_udphdr_t *udp; - unsigned short seq; pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); @@ -200,8 +199,10 @@ static odp_packet_t pack_udp_pkt(odp_pool_t pool) memcpy((char *)eth->src.addr, args->appl.srcmac.addr, ODPH_ETHADDR_LEN); memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, ODPH_ETHADDR_LEN); eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); + /* ip */ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); + odp_packet_has_ipv4_set(pkt, 1); ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); @@ -209,12 +210,13 @@ static odp_packet_t pack_udp_pkt(odp_pool_t pool) ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN + ODPH_IPV4HDR_LEN); ip->proto = ODPH_IPPROTO_UDP; - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; - ip->id = odp_cpu_to_be_16(seq); + ip->id = 0; + ip->ttl = 64; ip->chksum = 0; - odph_ipv4_csum_update(pkt); + /* udp */ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); + odp_packet_has_udp_set(pkt, 1); udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); udp->src_port = 0; udp->dst_port = 0; @@ -226,27 +228,60 @@ static odp_packet_t pack_udp_pkt(odp_pool_t pool) } /** - * Set up an icmp packet + * set up an udp packet + * + * @param pool Buffer pool to create packet in + * @param pkt_ref Reference UDP packet + * + * @return Handle of created packet + * @retval ODP_PACKET_INVALID Packet could not be created + */ +static odp_packet_t pack_udp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) +{ + odp_packet_t pkt; + char *buf; + odph_ipv4hdr_t *ip; + unsigned short seq; + + pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_UDPHDR_LEN + + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); + + if (pkt == ODP_PACKET_INVALID) + return pkt; + + buf = (char *)odp_packet_data(pkt); + odp_memcpy(buf, odp_packet_data(pkt_ref), + args->appl.payload + ODPH_UDPHDR_LEN + + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); + + /*Update IP ID and checksum*/ + ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); + seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; + ip->id = odp_cpu_to_be_16(seq); + ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + + return pkt; +} + +/** + * Set up an icmp packet reference * * @param pool Buffer pool to create packet in * * @return Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created */ -static odp_packet_t pack_icmp_pkt(odp_pool_t pool) +static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) { odp_packet_t pkt; char *buf; odph_ethhdr_t *eth; odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; - struct timeval tval; - uint8_t *tval_d; - unsigned short seq; args->appl.payload = 56; pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN + - ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); if (pkt == ODP_PACKET_INVALID) return pkt; @@ -265,18 +300,62 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool) ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; + ip->ttl = 64; ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN); ip->proto = ODPH_IPPROTO_ICMP; - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; - ip->id = odp_cpu_to_be_16(seq); + ip->id = 0; ip->chksum = 0; - odph_ipv4_csum_update(pkt); + /* icmp */ icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); icmp->type = ICMP_ECHO; icmp->code = 0; icmp->un.echo.id = 0; + icmp->un.echo.sequence = 0; + icmp->chksum = 0; + + return pkt; +} + +/** + * Set up an icmp packet + * + * @param pool Buffer pool to create packet in + * @param pkt_ref Reference ICMP packet + * + * @return Handle of created packet + * @retval ODP_PACKET_INVALID Packet could not be created + */ +static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) +{ + odp_packet_t pkt; + char *buf; + odph_ipv4hdr_t *ip; + odph_icmphdr_t *icmp; + struct timeval tval; + uint8_t *tval_d; + unsigned short seq; + + pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN + + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); + + if (pkt == ODP_PACKET_INVALID) + return pkt; + + buf = (char *)odp_packet_data(pkt); + odp_memcpy(buf, odp_packet_data(pkt_ref), + args->appl.payload + ODPH_ICMPHDR_LEN + + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); + + /* ip */ + ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); + seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; + ip->id = odp_cpu_to_be_16(seq); + ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + + /* icmp */ + icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); icmp->un.echo.sequence = ip->id; tval_d = (uint8_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ICMPHDR_LEN); @@ -357,6 +436,7 @@ static int gen_send_thread(void *arg) thread_args_t *thr_args; odp_pktout_queue_t pktout; odp_packet_t pkt; + odp_packet_t pkt_ref = ODP_PACKET_INVALID; thr = odp_thread_id(); thr_args = arg; @@ -373,6 +453,21 @@ static int gen_send_thread(void *arg) return -1; } + if (args->appl.mode == APPL_MODE_UDP) { + pkt_ref = setup_udp_pkt_ref(thr_args->pool); + } else if (args->appl.mode == APPL_MODE_PING) { + pkt_ref = setup_icmp_pkt_ref(thr_args->pool); + } else { + EXAMPLE_ERR(" [%02i] Error: invalid processing mode %d\n", + thr, args->appl.mode); + return -1; + } + if (pkt_ref == ODP_PACKET_INVALID) { + EXAMPLE_ERR(" [%2i] Error: reference packet creation failed\n", + thr); + return -1; + } + printf(" [%02i] created mode: SEND\n", thr); odp_barrier_wait(&barrier); @@ -386,9 +481,9 @@ static int gen_send_thread(void *arg) pkt = ODP_PACKET_INVALID; if (args->appl.mode == APPL_MODE_UDP) - pkt = pack_udp_pkt(thr_args->pool); + pkt = pack_udp_pkt(thr_args->pool, pkt_ref); else if (args->appl.mode == APPL_MODE_PING) - pkt = pack_icmp_pkt(thr_args->pool); + pkt = pack_icmp_pkt(thr_args->pool, pkt_ref); if (pkt == ODP_PACKET_INVALID) { /* Thread gives up as soon as it sees the pool empty. @@ -440,6 +535,7 @@ static int gen_send_thread(void *arg) args->appl.timeout--; } } + odp_packet_free(pkt_ref); return 0; } -- cgit v1.2.3 From 62298f0a5a25f3f3d0b2289b004dfc79246d7dbc Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 28 Mar 2017 14:03:24 +0300 Subject: test: generator: send UDP packets in bursts Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 74 ++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 816db8808..a9b07e5cb 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -26,6 +26,7 @@ #define POOL_NUM_PKT 2048 /* Number of packets in packet pool */ #define POOL_PKT_LEN 1856 /* Max packet length */ #define DEFAULT_PKT_INTERVAL 1000 /* Interval between each packet */ +#define MAX_UDP_TX_BURST 32 #define APPL_MODE_UDP 0 /**< UDP mode */ #define APPL_MODE_PING 1 /**< ping mode */ @@ -57,6 +58,8 @@ typedef struct { int timeout; /**< wait time */ int interval; /**< wait interval ms between sending each packet */ + int udp_tx_burst; /**< number of udp packets to send with one + API call */ } appl_args_t; /** @@ -431,11 +434,13 @@ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) static int gen_send_thread(void *arg) { int thr; - int ret; + int ret, i; odp_pktio_t pktio; thread_args_t *thr_args; odp_pktout_queue_t pktout; - odp_packet_t pkt; + odp_packet_t pkt_array[MAX_UDP_TX_BURST]; + int pkt_array_size; + int burst_start, burst_size; odp_packet_t pkt_ref = ODP_PACKET_INVALID; thr = odp_thread_id(); @@ -455,8 +460,10 @@ static int gen_send_thread(void *arg) if (args->appl.mode == APPL_MODE_UDP) { pkt_ref = setup_udp_pkt_ref(thr_args->pool); + pkt_array_size = args->appl.udp_tx_burst; } else if (args->appl.mode == APPL_MODE_PING) { pkt_ref = setup_icmp_pkt_ref(thr_args->pool); + pkt_array_size = 1; } else { EXAMPLE_ERR(" [%02i] Error: invalid processing mode %d\n", thr, args->appl.mode); @@ -478,32 +485,46 @@ static int gen_send_thread(void *arg) (unsigned int)args->appl.number) break; - pkt = ODP_PACKET_INVALID; - - if (args->appl.mode == APPL_MODE_UDP) - pkt = pack_udp_pkt(thr_args->pool, pkt_ref); - else if (args->appl.mode == APPL_MODE_PING) - pkt = pack_icmp_pkt(thr_args->pool, pkt_ref); - - if (pkt == ODP_PACKET_INVALID) { - /* Thread gives up as soon as it sees the pool empty. - * Depending on pool size and transmit latency, it may - * be normal that pool gets empty sometimes. */ - EXAMPLE_ERR(" [%2i] alloc_single failed\n", thr); + if (args->appl.mode == APPL_MODE_UDP) { + for (i = 0; i < pkt_array_size; i++) { + pkt_array[i] = pack_udp_pkt(thr_args->pool, + pkt_ref); + if (!odp_packet_is_valid(pkt_array[i])) + break; + } + if (i != pkt_array_size) { + EXAMPLE_ERR(" [%2i] alloc_multi failed\n", + thr); + odp_packet_free_multi(pkt_array, i); + break; + } + } else if (args->appl.mode == APPL_MODE_PING) { + pkt_array[0] = pack_icmp_pkt(thr_args->pool, pkt_ref); + if (!odp_packet_is_valid(pkt_array[0])) { + EXAMPLE_ERR(" [%2i] alloc_single failed\n", + thr); + break; + } + } else { break; } - for (;;) { - ret = odp_pktout_send(pktout, &pkt, 1); - if (ret == 1) { + for (burst_start = 0, burst_size = pkt_array_size;;) { + ret = odp_pktout_send(pktout, &pkt_array[burst_start], + burst_size); + if (ret == burst_size) { break; - } else if (ret == 0) { - odp_atomic_add_u64(&counters.tx_drops, 1); + } else if (ret >= 0 && ret < burst_size) { + odp_atomic_add_u64(&counters.tx_drops, + burst_size - ret); + burst_start += ret; + burst_size -= ret; odp_time_wait_ns(ODP_TIME_MSEC_IN_NS); continue; } EXAMPLE_ERR(" [%02i] packet send failed\n", thr); - odp_packet_free(pkt); + odp_packet_free_multi(&pkt_array[burst_start], + burst_size); break; } @@ -1053,10 +1074,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {"timeout", required_argument, NULL, 't'}, {"interval", required_argument, NULL, 'i'}, {"help", no_argument, NULL, 'h'}, + {"udp_tx_burst", required_argument, NULL, 'x'}, {NULL, 0, NULL, 0} }; - static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:h"; + static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ odph_parse_options(argc, argv, shortopts, longopts); @@ -1066,6 +1088,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->payload = 56; appl_args->timeout = -1; appl_args->interval = DEFAULT_PKT_INTERVAL; + appl_args->udp_tx_burst = 16; opterr = 0; /* do not issue errors on helper options */ @@ -1191,6 +1214,14 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) exit(EXIT_FAILURE); } break; + case 'x': + appl_args->udp_tx_burst = atoi(optarg); + if (appl_args->udp_tx_burst > MAX_UDP_TX_BURST) { + EXAMPLE_ERR("wrong UDP Tx burst size (max %d)\n", + MAX_UDP_TX_BURST); + exit(EXIT_FAILURE); + } + break; case 'h': usage(argv[0]); @@ -1285,6 +1316,7 @@ static void usage(char *progname) " default is to assign all\n" " -n, --count the number of packets to be send\n" " -c, --cpumask to set on cores\n" + " -x, --udp_tx_burst size of UDP TX burst\n" "\n", NO_PATH(progname), NO_PATH(progname) ); } -- cgit v1.2.3 From 6b417e477b0a7b743c7b68a840c4ac19f08f8dbd Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 28 Mar 2017 14:03:25 +0300 Subject: test: generator: receive packets in bursts Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index a9b07e5cb..452fa8b98 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -27,6 +27,7 @@ #define POOL_PKT_LEN 1856 /* Max packet length */ #define DEFAULT_PKT_INTERVAL 1000 /* Interval between each packet */ #define MAX_UDP_TX_BURST 32 +#define MAX_RX_BURST 32 #define APPL_MODE_UDP 0 /**< UDP mode */ #define APPL_MODE_PING 1 /**< ping mode */ @@ -637,8 +638,9 @@ static int gen_recv_thread(void *arg) int thr; odp_pktio_t pktio; thread_args_t *thr_args; - odp_packet_t pkt; - odp_event_t ev; + odp_packet_t pkts[MAX_RX_BURST], pkt; + odp_event_t events[MAX_RX_BURST]; + int pkt_cnt, ev_cnt, i; thr = odp_thread_id(); thr_args = arg; @@ -661,18 +663,24 @@ static int gen_recv_thread(void *arg) } /* Use schedule to get buf from any input queue */ - ev = odp_schedule(NULL, ODP_SCHED_WAIT); - - pkt = odp_packet_from_event(ev); - /* Drop packets with errors */ - if (odp_unlikely(odp_packet_has_error(pkt))) { - odp_packet_free(pkt); + ev_cnt = odp_schedule_multi(NULL, ODP_SCHED_WAIT, + events, MAX_RX_BURST); + if (ev_cnt == 0) continue; + for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) { + pkt = odp_packet_from_event(events[i]); + + /* Drop packets with errors */ + if (odp_unlikely(odp_packet_has_error(pkt))) { + odp_packet_free(pkt); + continue; + } + pkts[pkt_cnt++] = pkt; } - print_pkts(thr, &pkt, 1); + print_pkts(thr, pkts, pkt_cnt); - odp_packet_free(pkt); + odp_packet_free_multi(pkts, pkt_cnt); } return 0; -- cgit v1.2.3 From 3a8d28128480b75c2e5039b6c53db05fc8b6aa74 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 28 Mar 2017 14:03:26 +0300 Subject: test: generator: use multiple RX queue in receiving mode Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 452fa8b98..9305aa9b4 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -382,9 +382,11 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) * @return The handle of the created pktio object. * @warning This routine aborts if the create is unsuccessful. */ -static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) +static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool, + unsigned num_rx_queues) { odp_pktio_t pktio; + odp_pktio_capability_t capa; int ret; odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; @@ -400,7 +402,16 @@ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) exit(EXIT_FAILURE); } + if (odp_pktio_capability(pktio, &capa)) { + EXAMPLE_ERR("Error: Failed to get interface capabilities %s\n", + dev); + exit(EXIT_FAILURE); + } + if (num_rx_queues > capa.max_input_queues) + num_rx_queues = capa.max_input_queues; + odp_pktin_queue_param_init(&pktin_param); + pktin_param.num_queues = num_rx_queues; pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; if (odp_pktin_queue_config(pktio, &pktin_param)) { @@ -749,6 +760,7 @@ int main(int argc, char *argv[]) odph_odpthread_t thread_tbl[MAX_WORKERS]; odp_pool_t pool; int num_workers; + unsigned num_rx_queues; int i; odp_shm_t shm; odp_cpumask_t cpumask; @@ -872,8 +884,15 @@ int main(int argc, char *argv[]) pktio = malloc(sizeof(odp_pktio_t) * args->appl.if_count); + if (args->appl.mode == APPL_MODE_PING || + args->appl.mode == APPL_MODE_UDP) + num_rx_queues = 1; + else + num_rx_queues = num_workers; + for (i = 0; i < args->appl.if_count; ++i) - pktio[i] = create_pktio(args->appl.if_names[i], pool); + pktio[i] = create_pktio(args->appl.if_names[i], pool, + num_rx_queues); /* Create and init worker threads */ memset(thread_tbl, 0, sizeof(thread_tbl)); -- cgit v1.2.3 From 539b12c997b213c687249669b4ed4dc058d957ee Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 28 Mar 2017 14:03:27 +0300 Subject: test: generator: use multiple TX queues in send UDP mode Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 136 +++++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 52 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 9305aa9b4..d4184a493 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -39,6 +39,17 @@ /** Get rid of path in filename - only for unix-type paths using '/' */ #define NO_PATH(file_name) (strrchr((file_name), '/') ? \ strrchr((file_name), '/') + 1 : (file_name)) + +/** + * Interfaces + */ + +typedef struct { + odp_pktio_t pktio; + odp_pktout_queue_t pktout[MAX_WORKERS]; + unsigned pktout_count; +} interface_t; + /** * Parsed command line application arguments */ @@ -78,7 +89,7 @@ static struct { /** * Thread specific arguments */ typedef struct { - char *pktio_dev; /**< Interface name to use */ + odp_pktout_queue_t pktout; /**< Packet output queue to use*/ odp_pool_t pool; /**< Pool for packet IO */ odp_timer_pool_t tp; /**< Timer pool handle */ odp_queue_t tq; /**< Queue for timeouts */ @@ -382,30 +393,33 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) * @return The handle of the created pktio object. * @warning This routine aborts if the create is unsuccessful. */ -static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool, - unsigned num_rx_queues) +static int create_pktio(const char *dev, odp_pool_t pool, + unsigned num_rx_queues, + unsigned num_tx_queues, + interface_t *itf) { - odp_pktio_t pktio; odp_pktio_capability_t capa; int ret; odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; + odp_pktout_queue_param_t pktout_param; + odp_pktio_op_mode_t pktout_mode; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; /* Open a packet IO instance */ - pktio = odp_pktio_open(dev, pool, &pktio_param); + itf->pktio = odp_pktio_open(dev, pool, &pktio_param); - if (pktio == ODP_PKTIO_INVALID) { + if (itf->pktio == ODP_PKTIO_INVALID) { EXAMPLE_ERR("Error: pktio create failed for %s\n", dev); - exit(EXIT_FAILURE); + return -1; } - if (odp_pktio_capability(pktio, &capa)) { + if (odp_pktio_capability(itf->pktio, &capa)) { EXAMPLE_ERR("Error: Failed to get interface capabilities %s\n", dev); - exit(EXIT_FAILURE); + return -1; } if (num_rx_queues > capa.max_input_queues) num_rx_queues = capa.max_input_queues; @@ -414,27 +428,44 @@ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool, pktin_param.num_queues = num_rx_queues; pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; - if (odp_pktin_queue_config(pktio, &pktin_param)) { + if (odp_pktin_queue_config(itf->pktio, &pktin_param)) { EXAMPLE_ERR("Error: pktin queue config failed for %s\n", dev); - exit(EXIT_FAILURE); + return -1; + } + + pktout_mode = ODP_PKTIO_OP_MT_UNSAFE; + if (num_tx_queues > capa.max_output_queues) { + num_tx_queues = capa.max_output_queues; + pktout_mode = ODP_PKTIO_OP_MT; } - if (odp_pktout_queue_config(pktio, NULL)) { + odp_pktout_queue_param_init(&pktout_param); + pktout_param.num_queues = num_tx_queues; + pktout_param.op_mode = pktout_mode; + + if (odp_pktout_queue_config(itf->pktio, &pktout_param)) { EXAMPLE_ERR("Error: pktout queue config failed for %s\n", dev); - exit(EXIT_FAILURE); + return -1; } - ret = odp_pktio_start(pktio); + ret = odp_pktio_start(itf->pktio); if (ret) EXAMPLE_ABORT("Error: unable to start %s\n", dev); + itf->pktout_count = num_tx_queues; + if (odp_pktout_queue(itf->pktio, itf->pktout, itf->pktout_count) != + (int)itf->pktout_count) { + EXAMPLE_ERR("Error: failed to get output queues for %s\n", dev); + return -1; + } + printf(" created pktio:%02" PRIu64 ", dev:%s, queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "\n", - odp_pktio_to_u64(pktio), dev, - odp_pktio_to_u64(pktio)); + odp_pktio_to_u64(itf->pktio), dev, + odp_pktio_to_u64(itf->pktio)); - return pktio; + return 0; } /** @@ -447,7 +478,6 @@ static int gen_send_thread(void *arg) { int thr; int ret, i; - odp_pktio_t pktio; thread_args_t *thr_args; odp_pktout_queue_t pktout; odp_packet_t pkt_array[MAX_UDP_TX_BURST]; @@ -458,17 +488,7 @@ static int gen_send_thread(void *arg) thr = odp_thread_id(); thr_args = arg; - pktio = odp_pktio_lookup(thr_args->pktio_dev); - if (pktio == ODP_PKTIO_INVALID) { - EXAMPLE_ERR(" [%02i] Error: lookup of pktio %s failed\n", - thr, thr_args->pktio_dev); - return -1; - } - - if (odp_pktout_queue(pktio, &pktout, 1) != 1) { - EXAMPLE_ERR(" [%02i] Error: no output queue\n", thr); - return -1; - } + pktout = thr_args->pktout; if (args->appl.mode == APPL_MODE_UDP) { pkt_ref = setup_udp_pkt_ref(thr_args->pool); @@ -647,21 +667,12 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) static int gen_recv_thread(void *arg) { int thr; - odp_pktio_t pktio; - thread_args_t *thr_args; odp_packet_t pkts[MAX_RX_BURST], pkt; odp_event_t events[MAX_RX_BURST]; int pkt_cnt, ev_cnt, i; thr = odp_thread_id(); - thr_args = arg; - - pktio = odp_pktio_lookup(thr_args->pktio_dev); - if (pktio == ODP_PKTIO_INVALID) { - EXAMPLE_ERR(" [%02i] Error: lookup of pktio %s failed\n", - thr, thr_args->pktio_dev); - return -1; - } + (void)arg; printf(" [%02i] created mode: RECEIVE\n", thr); odp_barrier_wait(&barrier); @@ -760,7 +771,7 @@ int main(int argc, char *argv[]) odph_odpthread_t thread_tbl[MAX_WORKERS]; odp_pool_t pool; int num_workers; - unsigned num_rx_queues; + unsigned num_rx_queues, num_tx_queues; int i; odp_shm_t shm; odp_cpumask_t cpumask; @@ -771,7 +782,7 @@ int main(int argc, char *argv[]) odp_pool_t tmop; odp_queue_t tq; odp_event_t ev; - odp_pktio_t *pktio; + interface_t *ifs; odp_instance_t instance; odph_odpthread_params_t thr_params; @@ -882,7 +893,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - pktio = malloc(sizeof(odp_pktio_t) * args->appl.if_count); + ifs = malloc(sizeof(interface_t) * args->appl.if_count); if (args->appl.mode == APPL_MODE_PING || args->appl.mode == APPL_MODE_UDP) @@ -890,9 +901,22 @@ int main(int argc, char *argv[]) else num_rx_queues = num_workers; + if (args->appl.mode == APPL_MODE_PING || + args->appl.mode == APPL_MODE_RCV) + num_tx_queues = 1; + else { + num_tx_queues = num_workers / args->appl.if_count; + if (num_workers % args->appl.if_count) + num_tx_queues++; + } + for (i = 0; i < args->appl.if_count; ++i) - pktio[i] = create_pktio(args->appl.if_names[i], pool, - num_rx_queues); + if (create_pktio(args->appl.if_names[i], pool, num_rx_queues, + num_tx_queues, &ifs[i])) { + EXAMPLE_ERR("Error: create interface %s failed.\n", + args->appl.if_names[i]); + exit(EXIT_FAILURE); + } /* Create and init worker threads */ memset(thread_tbl, 0, sizeof(thread_tbl)); @@ -918,7 +942,7 @@ int main(int argc, char *argv[]) EXAMPLE_ERR("queue_create failed\n"); abort(); } - args->thread[1].pktio_dev = args->appl.if_names[0]; + (void)args->thread[1].pktout; /* Not used*/ args->thread[1].pool = pool; args->thread[1].tp = tp; args->thread[1].tq = tq; @@ -947,7 +971,7 @@ int main(int argc, char *argv[]) EXAMPLE_ERR("queue_create failed\n"); abort(); } - args->thread[0].pktio_dev = args->appl.if_names[0]; + args->thread[0].pktout = ifs[0].pktout[0]; args->thread[0].pool = pool; args->thread[0].tp = tp; args->thread[0].tq = tq; @@ -973,14 +997,22 @@ int main(int argc, char *argv[]) } else { int cpu = odp_cpumask_first(&cpumask); + for (i = 0; i < num_workers; ++i) { odp_cpumask_t thd_mask; int (*thr_run_func)(void *); - int if_idx; + int if_idx, pktout_idx; - if_idx = i % args->appl.if_count; + if (args->appl.mode == APPL_MODE_RCV) + (void)args->thread[i].pktout; /*not used*/ + else { + if_idx = i % args->appl.if_count; + pktout_idx = (i / args->appl.if_count) % + ifs[if_idx].pktout_count; - args->thread[i].pktio_dev = args->appl.if_names[if_idx]; + args->thread[i].pktout = + ifs[if_idx].pktout[pktout_idx]; + } tq = odp_queue_create("", NULL); if (tq == ODP_QUEUE_INVALID) { EXAMPLE_ERR("queue_create failed\n"); @@ -1034,7 +1066,7 @@ int main(int argc, char *argv[]) odph_odpthreads_join(&thread_tbl[i]); for (i = 0; i < args->appl.if_count; ++i) - odp_pktio_stop(pktio[i]); + odp_pktio_stop(ifs[i].pktio); for (i = 0; i < num_workers; ++i) { odp_timer_cancel(args->thread[i].tim, &ev); @@ -1053,8 +1085,8 @@ int main(int argc, char *argv[]) } for (i = 0; i < args->appl.if_count; ++i) - odp_pktio_close(pktio[i]); - free(pktio); + odp_pktio_close(ifs[i].pktio); + free(ifs); free(args->appl.if_names); free(args->appl.if_str); if (0 != odp_pool_destroy(pool)) -- cgit v1.2.3 From 138a4a92b0bbf5bcc713a62747644276ada8d05d Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 30 Mar 2017 10:41:02 +0300 Subject: test: bench_packet: fix headroom/tailroom test return values Zero is a valid return value from the packet headroom/tailroom functions. Signed-off-by: Matias Elo Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_bench_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common_plat/performance/odp_bench_packet.c b/test/common_plat/performance/odp_bench_packet.c index 7a3a00429..c4cd6139b 100644 --- a/test/common_plat/performance/odp_bench_packet.c +++ b/test/common_plat/performance/odp_bench_packet.c @@ -618,7 +618,7 @@ static int bench_packet_headroom(void) for (i = 0; i < TEST_REPEAT_COUNT; i++) ret += odp_packet_headroom(gbl_args->pkt_tbl[i]); - return ret; + return i; } static int bench_packet_tailroom(void) @@ -629,7 +629,7 @@ static int bench_packet_tailroom(void) for (i = 0; i < TEST_REPEAT_COUNT; i++) ret += odp_packet_tailroom(gbl_args->pkt_tbl[i]); - return ret; + return i; } static int bench_packet_tail(void) -- cgit v1.2.3 From 8286cff9c5bb890d169b58857e3ab6cd118a2af4 Mon Sep 17 00:00:00 2001 From: Ola Liljedahl Date: Tue, 28 Mar 2017 14:23:28 -0500 Subject: linux-generic: ring.c: use required memory orderings Signed-off-by: Ola Liljedahl Reviewed-by: Brian Brooks Signed-off-by: Maxim Uvarov --- platform/linux-generic/pktio/ring.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/platform/linux-generic/pktio/ring.c b/platform/linux-generic/pktio/ring.c index aeda04b26..e3c73d1cb 100644 --- a/platform/linux-generic/pktio/ring.c +++ b/platform/linux-generic/pktio/ring.c @@ -263,8 +263,8 @@ int ___ring_mp_do_enqueue(_ring_t *r, void * const *obj_table, /* Reset n to the initial burst count */ n = max; - prod_head = r->prod.head; - cons_tail = r->cons.tail; + prod_head = __atomic_load_n(&r->prod.head, __ATOMIC_RELAXED); + cons_tail = __atomic_load_n(&r->cons.tail, __ATOMIC_ACQUIRE); /* The subtraction is done between two unsigned 32bits value * (the result is always modulo 32 bits even if we have * prod_head > cons_tail). So 'free_entries' is always between 0 @@ -306,12 +306,12 @@ int ___ring_mp_do_enqueue(_ring_t *r, void * const *obj_table, * If there are other enqueues in progress that preceded us, * we need to wait for them to complete */ - while (odp_unlikely(r->prod.tail != prod_head)) + while (odp_unlikely(__atomic_load_n(&r->prod.tail, __ATOMIC_RELAXED) != + prod_head)) odp_cpu_pause(); /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->prod.tail = prod_next; + __atomic_store_n(&r->prod.tail, prod_next, __ATOMIC_RELEASE); return ret; } @@ -328,7 +328,7 @@ int ___ring_sp_do_enqueue(_ring_t *r, void * const *obj_table, int ret; prod_head = r->prod.head; - cons_tail = r->cons.tail; + cons_tail = __atomic_load_n(&r->cons.tail, __ATOMIC_ACQUIRE); /* The subtraction is done between two unsigned 32bits value * (the result is always modulo 32 bits even if we have * prod_head > cons_tail). So 'free_entries' is always between 0 @@ -361,8 +361,7 @@ int ___ring_sp_do_enqueue(_ring_t *r, void * const *obj_table, } /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->prod.tail = prod_next; + __atomic_store_n(&r->prod.tail, prod_next, __ATOMIC_RELEASE); return ret; } @@ -385,8 +384,8 @@ int ___ring_mc_do_dequeue(_ring_t *r, void **obj_table, /* Restore n as it may change every loop */ n = max; - cons_head = r->cons.head; - prod_tail = r->prod.tail; + cons_head = __atomic_load_n(&r->cons.head, __ATOMIC_RELAXED); + prod_tail = __atomic_load_n(&r->prod.tail, __ATOMIC_ACQUIRE); /* The subtraction is done between two unsigned 32bits value * (the result is always modulo 32 bits even if we have * cons_head > prod_tail). So 'entries' is always between 0 @@ -419,12 +418,12 @@ int ___ring_mc_do_dequeue(_ring_t *r, void **obj_table, * If there are other dequeues in progress that preceded us, * we need to wait for them to complete */ - while (odp_unlikely(r->cons.tail != cons_head)) + while (odp_unlikely(__atomic_load_n(&r->cons.tail, __ATOMIC_RELAXED) != + cons_head)) odp_cpu_pause(); /* Release our entries and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_RELEASE); - r->cons.tail = cons_next; + __atomic_store_n(&r->cons.tail, cons_next, __ATOMIC_RELEASE); return behavior == _RING_QUEUE_FIXED ? 0 : n; } @@ -441,7 +440,7 @@ int ___ring_sc_do_dequeue(_ring_t *r, void **obj_table, uint32_t mask = r->prod.mask; cons_head = r->cons.head; - prod_tail = r->prod.tail; + prod_tail = __atomic_load_n(&r->prod.tail, __ATOMIC_ACQUIRE); /* The subtraction is done between two unsigned 32bits value * (the result is always modulo 32 bits even if we have * cons_head > prod_tail). So 'entries' is always between 0 @@ -461,11 +460,10 @@ int ___ring_sc_do_dequeue(_ring_t *r, void **obj_table, r->cons.head = cons_next; /* Acquire the pointers and the memory they refer to */ - __atomic_thread_fence(__ATOMIC_ACQUIRE); /* copy in table */ DEQUEUE_PTRS(); - r->cons.tail = cons_next; + __atomic_store_n(&r->cons.tail, cons_next, __ATOMIC_RELEASE); return behavior == _RING_QUEUE_FIXED ? 0 : n; } -- cgit v1.2.3 From 4eebb3ada12ab8815b26ba0800f7cf830e4ee6ad Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Wed, 15 Mar 2017 09:48:33 +0200 Subject: test: generator: update global statistics calculation Update global statistics calculation to provide useful/easy-to-parse information. Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 57 ++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index d4184a493..95fb54327 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -715,7 +715,10 @@ static int gen_recv_thread(void *arg) static void print_global_stats(int num_workers) { odp_time_t cur, wait, next; - uint64_t pkts, pkts_prev = 0, pps, maximum_pps = 0; + uint64_t pkts_snd = 0, pkts_snd_prev = 0; + uint64_t pps_snd = 0, maximum_pps_snd = 0; + uint64_t pkts_rcv = 0, pkts_rcv_prev = 0; + uint64_t pps_rcv = 0, maximum_pps_rcv = 0; int verbose_interval = 20; odp_thrmask_t thrd_mask; @@ -736,30 +739,40 @@ static void print_global_stats(int num_workers) continue; next = odp_time_sum(cur, wait); - - if (args->appl.mode == APPL_MODE_RCV) { - pkts = odp_atomic_load_u64(&counters.udp); - printf(" total receive(UDP: %" PRIu64 ")\n", pkts); + switch (args->appl.mode) { + case APPL_MODE_RCV: + pkts_rcv = odp_atomic_load_u64(&counters.ip); + break; + case APPL_MODE_PING: + pkts_snd = odp_atomic_load_u64(&counters.seq); + pkts_rcv = odp_atomic_load_u64(&counters.icmp); + break; + case APPL_MODE_UDP: + pkts_snd = odp_atomic_load_u64(&counters.seq); + break; + default: continue; } - if (args->appl.mode == APPL_MODE_PING) { - pkts = odp_atomic_load_u64(&counters.icmp); - printf(" total receive(ICMP: %" PRIu64 ")\n", pkts); - } - - pkts = odp_atomic_load_u64(&counters.seq); - printf(" total sent: %" PRIu64 ", drops: %" PRIu64 "\n", pkts, - odp_atomic_load_u64(&counters.tx_drops)); - - if (args->appl.mode == APPL_MODE_UDP) { - pps = (pkts - pkts_prev) / verbose_interval; - if (pps > maximum_pps) - maximum_pps = pps; - printf(" %" PRIu64 " pps, %" PRIu64 " max pps\n", - pps, maximum_pps); - pkts_prev = pkts; - } + pps_snd = (pkts_snd - pkts_snd_prev) / verbose_interval; + pkts_snd_prev = pkts_snd; + if (pps_snd > maximum_pps_snd) + maximum_pps_snd = pps_snd; + + pps_rcv = (pkts_rcv - pkts_rcv_prev) / verbose_interval; + pkts_rcv_prev = pkts_rcv; + if (pps_rcv > maximum_pps_rcv) + maximum_pps_rcv = pps_rcv; + + printf("sent: %" PRIu64 ", drops: %" PRIu64 ", " + "send rate: %" PRIu64 " pps, " + "max send rate: %" PRIu64 " pps, " + "rcv: %" PRIu64 ", " + "recv rate: %" PRIu64 " pps, " + "max recv rate: %" PRIu64 " pps\n", + pkts_snd, odp_atomic_load_u64(&counters.tx_drops), + pps_snd, maximum_pps_snd, + pkts_rcv, pps_rcv, maximum_pps_rcv); } } -- cgit v1.2.3 From 503708078bf6ab9228d23ad65660b42248600c2d Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 30 Mar 2017 19:20:57 +0300 Subject: test: perf: fix bash syntax in odp_pktio_ordered_run.sh bash -lt syntax expects 2 integer values, not strings. Also return code of piped command needs to be get in a little bit different way. https://bugs.linaro.org/show_bug.cgi?id=2872 Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- test/common_plat/performance/Makefile.am | 2 ++ .../performance/odp_pktio_ordered_run.sh | 36 ++++++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/test/common_plat/performance/Makefile.am b/test/common_plat/performance/Makefile.am index 9111c0c2d..3299f03f8 100644 --- a/test/common_plat/performance/Makefile.am +++ b/test/common_plat/performance/Makefile.am @@ -51,3 +51,5 @@ dist_odp_scheduling_SOURCES = odp_scheduling.c dist_odp_pktio_perf_SOURCES = odp_pktio_perf.c EXTRA_DIST = $(TESTSCRIPTS) + +dist_check_SCRIPTS = udp64.pcap diff --git a/test/common_plat/performance/odp_pktio_ordered_run.sh b/test/common_plat/performance/odp_pktio_ordered_run.sh index d91211c0c..d6c2be526 100755 --- a/test/common_plat/performance/odp_pktio_ordered_run.sh +++ b/test/common_plat/performance/odp_pktio_ordered_run.sh @@ -5,14 +5,21 @@ # # SPDX-License-Identifier: BSD-3-Clause # +TEST_SRC_DIR=$(dirname $0) +TEST_DIR="${TEST_DIR:-$(dirname $0)}" DURATION=5 LOG=odp_pktio_ordered.log LOOPS=100000000 PASS_PPS=5000 -PCAP_IN=`find . ${TEST_DIR} $(dirname $0) -name udp64.pcap -print -quit` +PCAP_IN=`find . ${TEST_SRC_DIR} $(dirname $0) -name udp64.pcap -print -quit` PCAP_OUT=/dev/null +if [ ! -f ${PCAP_IN} ]; then + echo "FAIL: no udp64.pcap" + exit 1 +fi + # This just turns off output buffering so that you still get periodic # output while piping to tee, as long as stdbuf is available. if [ "$(which stdbuf)" != "" ]; then @@ -21,20 +28,29 @@ else STDBUF= fi -$STDBUF ./odp_pktio_ordered${EXEEXT} -i pcap:in=${PCAP_IN}:loops=$LOOPS,\ -pcap:out=${PCAP_OUT} -t $DURATION | tee $LOG +$STDBUF ${TEST_DIR}/odp_pktio_ordered${EXEEXT} \ + -i pcap:in=${PCAP_IN}:loops=$LOOPS,pcap:out=${PCAP_OUT} \ + -t $DURATION | tee $LOG -ret=$? +ret=${PIPESTATUS[0]} + +if [ $ret -ne 0 ]; then + echo "FAIL: no odp_pktio_ordered${EXEEXT}" + rm -f $LOG + exit $ret +fi if [ ! -f $LOG ]; then echo "FAIL: $LOG not found" ret=1 -elif [ $ret -eq 0 ]; then - MAX_PPS=$(awk '/TEST RESULT/ {print $3}' $LOG) - if [ "$MAX_PPS" -lt "$PASS_PPS" ]; then - echo "FAIL: pps below threshold $MAX_PPS < $PASS_PPS" - ret=1 - fi + exit $ret +fi + +MAX_PPS=$(awk '/TEST RESULT/ {print $3}' $LOG) +echo "MAX_PPS=$MAX_PPS" +if [ $MAX_PPS -lt $PASS_PPS ]; then + echo "FAIL: pps below threshold $MAX_PPS < $PASS_PPS" + ret=1 fi rm -f $LOG -- cgit v1.2.3 From c7014b4848c276c17dcdddab103ce88b3eb29235 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 31 Mar 2017 17:40:13 +0300 Subject: helper: iplookuptable: fix prefix_entry_t member order Depending on the alignment/padding odph_iplookup_table_put_value() could end up overwriting the wrong fields in prefix_entry_t. Fix this by reverting the order of prefix_entry_t members. Fixes https://bugs.linaro.org/show_bug.cgi?id=2910 Signed-off-by: Matias Elo Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- helper/iplookuptable.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/helper/iplookuptable.c b/helper/iplookuptable.c index aae219945..37d31e368 100644 --- a/helper/iplookuptable.c +++ b/helper/iplookuptable.c @@ -41,6 +41,10 @@ * address of the buffer. */ typedef struct { + union { + odp_buffer_t nexthop; + void *ptr; + }; union { uint8_t u8; struct { @@ -53,10 +57,6 @@ typedef struct { #endif }; }; - union { - odp_buffer_t nexthop; - void *ptr; - }; } prefix_entry_t; #define ENTRY_SIZE (sizeof(prefix_entry_t) + sizeof(odp_buffer_t)) -- cgit v1.2.3 From ce61337e6a7e955913fa64412c75d2066e0f121c Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 29 Mar 2017 10:15:17 +0200 Subject: validation: packet: do assert on newly created pkt reference Signed-off-by: Balakrishna Garapati Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/packet/packet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index 669122a70..2ffd9247d 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -2234,12 +2234,15 @@ void packet_test_ref(void) /* Create references */ ref_pkt[0] = odp_packet_ref(segmented_base_pkt, offset[0]); + CU_ASSERT_FATAL(ref_pkt[0] != ODP_PACKET_INVALID); + if (odp_packet_has_ref(ref_pkt[0]) == 1) { /* CU_ASSERT needs braces */ CU_ASSERT(odp_packet_has_ref(segmented_base_pkt) == 1); } ref_pkt[1] = odp_packet_ref(segmented_base_pkt, offset[1]); + CU_ASSERT_FATAL(ref_pkt[1] != ODP_PACKET_INVALID); if (odp_packet_has_ref(ref_pkt[1]) == 1) { /* CU_ASSERT needs braces */ -- cgit v1.2.3 From 0955fbb395dc1651a8bcd473beae2154d39f4a69 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Thu, 6 Apr 2017 08:48:56 +0200 Subject: linux-generic: decouple odp_errno define from odp-linux makes it easy to define odp_errno to dpdk rteerrno and fixes linking issues. Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/Makefile.am | 1 + platform/linux-generic/include/odp_errno_define.h | 26 +++++++++++++++++++++++ platform/linux-generic/include/odp_internal.h | 3 +-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 platform/linux-generic/include/odp_errno_define.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 37835c394..545291518 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -125,6 +125,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_config_internal.h \ ${srcdir}/include/odp_crypto_internal.h \ ${srcdir}/include/odp_debug_internal.h \ + ${srcdir}/include/odp_errno_define.h \ ${srcdir}/include/odp_forward_typedefs_internal.h \ ${srcdir}/include/odp_internal.h \ ${srcdir}/include/odp_name_table_internal.h \ diff --git a/platform/linux-generic/include/odp_errno_define.h b/platform/linux-generic/include/odp_errno_define.h new file mode 100644 index 000000000..94c30e793 --- /dev/null +++ b/platform/linux-generic/include/odp_errno_define.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP error number define + */ + +#ifndef ODP_ERRNO_DEFINE_H_ +#define ODP_ERRNO_DEFINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern __thread int __odp_errno; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index b313b1fef..e1267cff7 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -20,11 +20,10 @@ extern "C" { #include #include #include +#include #include #include -extern __thread int __odp_errno; - #define MAX_CPU_NUMBER 128 typedef struct { -- cgit v1.2.3 From c9417b862f7df0213b5135f0aa364761cb23cec6 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 31 Mar 2017 15:18:47 +0300 Subject: validation: packet: increase test pool size Previously packet_test_concatsplit() could fail on some pool implementations as the pool ran out of buffers. Increase default pools size and use capability to make sure the value is valid. Signed-off-by: Matias Elo Reviewed-by: Balakrishna Garapati Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/packet/packet.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index 2ffd9247d..619f99a65 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -13,6 +13,8 @@ #define PACKET_BUF_LEN ODP_CONFIG_PACKET_SEG_LEN_MIN /* Reserve some tailroom for tests */ #define PACKET_TAILROOM_RESERVE 4 +/* Number of packets in the test packet pool */ +#define PACKET_POOL_NUM 300 static odp_pool_t packet_pool, packet_pool_no_uarea, packet_pool_double_uarea; static uint32_t packet_len; @@ -109,6 +111,7 @@ int packet_suite_init(void) uint32_t udat_size; uint8_t data = 0; uint32_t i; + uint32_t num = PACKET_POOL_NUM; if (odp_pool_capability(&capa) < 0) { printf("pool_capability failed\n"); @@ -130,13 +133,15 @@ int packet_suite_init(void) segmented_packet_len = capa.pkt.min_seg_len * capa.pkt.max_segs_per_pkt; } + if (capa.pkt.max_num != 0 && capa.pkt.max_num < num) + num = capa.pkt.max_num; odp_pool_param_init(¶ms); params.type = ODP_POOL_PACKET; params.pkt.seg_len = capa.pkt.min_seg_len; params.pkt.len = capa.pkt.min_seg_len; - params.pkt.num = 100; + params.pkt.num = num; params.pkt.uarea_size = sizeof(struct udata_struct); packet_pool = odp_pool_create("packet_pool", ¶ms); -- cgit v1.2.3 From 66869dae3b8cce7ed020d6922bd68ed30542f753 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 31 Mar 2017 15:18:48 +0300 Subject: validation: packet: remove invalid check from packet_test_alloc_segmented() One can't assume that the packet should be segmented as this test is using a different pool with different parameters than the default test pool. Signed-off-by: Matias Elo Reviewed-by: Balakrishna Garapati Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/packet/packet.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index 619f99a65..af9a667ec 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -422,9 +422,6 @@ void packet_test_alloc_segmented(void) CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); CU_ASSERT(odp_packet_len(pkt) == max_len); - if (segmentation_supported) - CU_ASSERT(odp_packet_is_segmented(pkt) == 1); - odp_packet_free(pkt); num_alloc = 0; -- cgit v1.2.3 From 077b6c427cac9687349a56ebf5602bb953348440 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 31 Mar 2017 15:18:49 +0300 Subject: validation: packet: use common define for test pool sizes Signed-off-by: Matias Elo Reviewed-by: Balakrishna Garapati Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/packet/packet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/common_plat/validation/api/packet/packet.c b/test/common_plat/validation/api/packet/packet.c index af9a667ec..284aaeb5a 100644 --- a/test/common_plat/validation/api/packet/packet.c +++ b/test/common_plat/validation/api/packet/packet.c @@ -1386,7 +1386,7 @@ void packet_test_concat_small(void) param.type = ODP_POOL_PACKET; param.pkt.len = len; - param.pkt.num = 100; + param.pkt.num = PACKET_POOL_NUM; pool = odp_pool_create("packet_pool_concat", ¶m); CU_ASSERT(packet_pool != ODP_POOL_INVALID); @@ -1451,7 +1451,7 @@ void packet_test_concat_extend_trunc(void) param.type = ODP_POOL_PACKET; param.pkt.len = len; - param.pkt.num = 100; + param.pkt.num = PACKET_POOL_NUM; pool = odp_pool_create("packet_pool_concat", ¶m); CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID); @@ -1544,7 +1544,7 @@ void packet_test_extend_small(void) param.type = ODP_POOL_PACKET; param.pkt.len = len; - param.pkt.num = 100; + param.pkt.num = PACKET_POOL_NUM; pool = odp_pool_create("packet_pool_extend", ¶m); CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID); @@ -1639,7 +1639,7 @@ void packet_test_extend_large(void) param.type = ODP_POOL_PACKET; param.pkt.len = len; - param.pkt.num = 100; + param.pkt.num = PACKET_POOL_NUM; pool = odp_pool_create("packet_pool_extend", ¶m); CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID); @@ -1758,7 +1758,7 @@ void packet_test_extend_mix(void) param.type = ODP_POOL_PACKET; param.pkt.len = len; - param.pkt.num = 100; + param.pkt.num = PACKET_POOL_NUM; pool = odp_pool_create("packet_pool_extend", ¶m); CU_ASSERT_FATAL(packet_pool != ODP_POOL_INVALID); -- cgit v1.2.3 From 8c0df898b6f90564037fba43b1e9e6224e4ee740 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Thu, 13 Apr 2017 06:48:33 -0500 Subject: abi: packet: restore abi compatibility for odp_packet_seg_t type When running in --enable-abi-compat=yes mode, all ODP types need to be of pointer width in the default ABI definition. The optimization of the odp_packet_seg_t type to uint8_t can only be supported when running in --enable-abi-compate=no mode. Change the ODP packet routines to use type converter routines that have varying definitions based on whether we're running in ABI compatibility mode and provide these variant definitions to enable proper ABI compatibility while still supporting an optimized typedef for non-ABI mode. This resolves Bug https://bugs.linaro.org/show_bug.cgi?id=2940 Reported-by: Krishna Garapati Reviewed-by: Balakrishna Garapati Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/arch/default/api/abi/packet.h | 7 +++++-- .../include/odp/api/plat/packet_inlines.h | 21 ++++++++++++++++++--- .../include/odp/api/plat/packet_types.h | 10 ++++++++++ platform/linux-generic/odp_packet.c | 12 +++++++----- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/include/odp/arch/default/api/abi/packet.h b/include/odp/arch/default/api/abi/packet.h index 60a41b80b..4aac75b9e 100644 --- a/include/odp/arch/default/api/abi/packet.h +++ b/include/odp/arch/default/api/abi/packet.h @@ -16,15 +16,18 @@ extern "C" { /** @internal Dummy type for strong typing */ typedef struct { char dummy; /**< @internal Dummy */ } _odp_abi_packet_t; +/** @internal Dummy type for strong typing */ +typedef struct { char dummy; /**< *internal Dummy */ } _odp_abi_packet_seg_t; + /** @ingroup odp_packet * @{ */ typedef _odp_abi_packet_t *odp_packet_t; -typedef uint8_t odp_packet_seg_t; +typedef _odp_abi_packet_seg_t *odp_packet_seg_t; #define ODP_PACKET_INVALID ((odp_packet_t)0xffffffff) -#define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)-1) +#define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)0xffffffff) #define ODP_PACKET_OFFSET_INVALID (0x0fffffff) typedef enum { diff --git a/platform/linux-generic/include/odp/api/plat/packet_inlines.h b/platform/linux-generic/include/odp/api/plat/packet_inlines.h index eb36aa96d..3dd643fe2 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_inlines.h +++ b/platform/linux-generic/include/odp/api/plat/packet_inlines.h @@ -21,6 +21,20 @@ /** @internal Inline function offsets */ extern const _odp_packet_inline_offset_t _odp_packet_inline; +#if ODP_ABI_COMPAT == 1 +/** @internal Inline function @param seg @return */ +static inline uint32_t _odp_packet_seg_to_ndx(odp_packet_seg_t seg) +{ + return _odp_typeval(seg); +} + +/** @internal Inline function @param ndx @return */ +static inline odp_packet_seg_t _odp_packet_seg_from_ndx(uint32_t ndx) +{ + return _odp_cast_scalar(odp_packet_seg_t, ndx); +} +#endif + /** @internal Inline function @param pkt @return */ static inline void *_odp_packet_data(odp_packet_t pkt) { @@ -128,20 +142,21 @@ static inline odp_packet_seg_t _odp_packet_first_seg(odp_packet_t pkt) { (void)pkt; - return 0; + return _odp_packet_seg_from_ndx(0); } /** @internal Inline function @param pkt @return */ static inline odp_packet_seg_t _odp_packet_last_seg(odp_packet_t pkt) { - return _odp_packet_num_segs(pkt) - 1; + return _odp_packet_seg_from_ndx(_odp_packet_num_segs(pkt) - 1); } /** @internal Inline function @param pkt @param seg @return */ static inline odp_packet_seg_t _odp_packet_next_seg(odp_packet_t pkt, odp_packet_seg_t seg) { - if (odp_unlikely(seg >= _odp_packet_last_seg(pkt))) + if (odp_unlikely(_odp_packet_seg_to_ndx(seg) >= + _odp_packet_seg_to_ndx(_odp_packet_last_seg(pkt)))) return ODP_PACKET_SEG_INVALID; return seg + 1; diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h index b8f665d28..7e3c51e6c 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h @@ -40,6 +40,16 @@ typedef ODP_HANDLE_T(odp_packet_t); typedef uint8_t odp_packet_seg_t; +static inline uint8_t _odp_packet_seg_to_ndx(odp_packet_seg_t seg) +{ + return (uint8_t)seg; +} + +static inline odp_packet_seg_t _odp_packet_seg_from_ndx(uint8_t ndx) +{ + return (odp_packet_seg_t)ndx; +} + #define ODP_PACKET_SEG_INVALID ((odp_packet_seg_t)-1) typedef enum { diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index b8aac6bfe..e99e8b837 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1185,7 +1185,7 @@ void *odp_packet_offset(odp_packet_t pkt, uint32_t offset, uint32_t *len, void *addr = packet_map(pkt_hdr, offset, len, &seg_idx); if (addr != NULL && seg != NULL) - *seg = seg_idx; + *seg = _odp_packet_seg_from_ndx(seg_idx); return addr; } @@ -1326,20 +1326,22 @@ void *odp_packet_seg_data(odp_packet_t pkt, odp_packet_seg_t seg) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (odp_unlikely(seg >= pkt_hdr->buf_hdr.segcount)) + if (odp_unlikely(_odp_packet_seg_to_ndx(seg) >= + pkt_hdr->buf_hdr.segcount)) return NULL; - return packet_seg_data(pkt_hdr, seg); + return packet_seg_data(pkt_hdr, _odp_packet_seg_to_ndx(seg)); } uint32_t odp_packet_seg_data_len(odp_packet_t pkt, odp_packet_seg_t seg) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (odp_unlikely(seg >= pkt_hdr->buf_hdr.segcount)) + if (odp_unlikely(_odp_packet_seg_to_ndx(seg) >= + pkt_hdr->buf_hdr.segcount)) return 0; - return packet_seg_len(pkt_hdr, seg); + return packet_seg_len(pkt_hdr, _odp_packet_seg_to_ndx(seg)); } /* -- cgit v1.2.3 From 3e5a07edf190614e739c8dba76cf165330e1b035 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Sun, 2 Apr 2017 17:55:20 -0500 Subject: linux-generic: debug: enable helper use from c++ programs The ODP_STATIC_ASSERT() macro expands to _Static_assert(), however when used in C++ programs this needs to expand to static_assert(). This resolves Bug https://bugs.linaro.org/show_bug.cgi?id=2852 Reported-by: Moshe Tubul Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp/api/debug.h | 41 ++++++++++++++++------ .../common_plat/miscellaneous/odp_api_from_cpp.cpp | 3 +- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/platform/linux-generic/include/odp/api/debug.h b/platform/linux-generic/include/odp/api/debug.h index 7db143395..b0f91b1c9 100644 --- a/platform/linux-generic/include/odp/api/debug.h +++ b/platform/linux-generic/include/odp/api/debug.h @@ -19,17 +19,36 @@ extern "C" { #include -#if defined(__GNUC__) && !defined(__clang__) - -#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 6)) - /** - * @internal _Static_assert was only added in GCC 4.6. Provide a weak replacement - * for previous versions. + * @internal _Static_assert was only added in GCC 4.6 and the C++ version + * static_assert for g++ 6 and above. Provide a weak replacement for previous + * versions. */ -#define _Static_assert(e, s) (extern int (*static_assert_checker(void)) \ - [sizeof(struct { unsigned int error_if_negative:(e) ? 1 : -1; })]) +#define _odp_merge(a, b) a##b +#define _odp_label(a) _odp_merge(_ODP_SASSERT_, a) +#define _ODP_SASSERT _odp_label(__COUNTER__) +#define _ODP_SASSERT_ENUM(e) { _ODP_SASSERT = 1 / !!(e) } +#define _odp_static_assert(e, s) enum _ODP_SASSERT_ENUM(e) + +#if defined(__clang__) +#if defined(__cplusplus) +#if !__has_feature(cxx_static_assert) && !defined(static_assert) +#define static_assert(e, s) _odp_static_assert(e, s) +#endif +#elif !__has_feature(c_static_assert) && !defined(_Static_assert) +#define _Static_assert(e, s) _odp_static_assert(e, s) +#endif +#elif defined(__GNUC__) +#if __GNUC__ < 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ < 6)) || \ + (__GNUC__ < 6 && defined(__cplusplus)) +#if defined(__cplusplus) +#if !defined(static_assert) +#define static_assert(e, s) _odp_static_assert(e, s) +#endif +#elif !defined(_Static_assert) +#define _Static_assert(e, s) _odp_static_assert(e, s) +#endif #endif #endif @@ -39,9 +58,11 @@ extern "C" { * if condition 'cond' is false. Macro definition is empty when compiler is not * supported or the compiler does not support static assertion. */ -#define ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) +#ifndef __cplusplus +#define ODP_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg) -#ifdef __cplusplus +#else +#define ODP_STATIC_ASSERT(cond, msg) static_assert(cond, msg) } #endif diff --git a/test/common_plat/miscellaneous/odp_api_from_cpp.cpp b/test/common_plat/miscellaneous/odp_api_from_cpp.cpp index 2b3078642..4578ae4be 100644 --- a/test/common_plat/miscellaneous/odp_api_from_cpp.cpp +++ b/test/common_plat/miscellaneous/odp_api_from_cpp.cpp @@ -1,10 +1,9 @@ #include #include -#include +#include int main(int argc ODP_UNUSED, const char *argv[] ODP_UNUSED) { - printf("\tODP API version: %s\n", odp_version_api_str()); printf("\tODP implementation version: %s\n", odp_version_impl_str()); -- cgit v1.2.3 From 39be9572056ee715468214ad6d2d5c01054456d7 Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Wed, 12 Apr 2017 13:30:04 -0500 Subject: configure.ac: fix native Clang build on ARMv8 The build is broken when using clang on ARM. -mcx16 is being passed to clang when building natively on ARM. This combined with -Werror causes the breakage. Fix it by skipping anything related to -mcx16 when not building for x86-based architectures. See [1] for details. Signed-off-by: Brian Brooks Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- configure.ac | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 9320f360b..d364b8ddf 100644 --- a/configure.ac +++ b/configure.ac @@ -303,20 +303,22 @@ ODP_CFLAGS="$ODP_CFLAGS -std=c99" # Extra flags for example to suppress certain warning types ODP_CFLAGS="$ODP_CFLAGS $ODP_CFLAGS_EXTRA" -######################################################################### -# Check if compiler supports cmpxchng16 -########################################################################## -if test "${CC}" != "gcc" -o ${CC_VERSION_MAJOR} -ge 5; then - my_save_cflags="$CFLAGS" - - CFLAGS=-mcx16 - AC_MSG_CHECKING([whether CC supports -mcx16]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], - [AC_MSG_RESULT([yes])] - [ODP_CFLAGS="$ODP_CFLAGS $CFLAGS"], - [AC_MSG_RESULT([no])] - ) - CFLAGS="$my_save_cflags" +########################################################################## +# Check if compiler supports cmpxchng16 on x86-based architectures +########################################################################## +if "${host}" == i?86* -o "${host}" == x86*; then + if test "${CC}" != "gcc" -o ${CC_VERSION_MAJOR} -ge 5; then + my_save_cflags="$CFLAGS" + + CFLAGS=-mcx16 + AC_MSG_CHECKING([whether CC supports -mcx16]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])] + [ODP_CFLAGS="$ODP_CFLAGS $CFLAGS"], + [AC_MSG_RESULT([no])] + ) + CFLAGS="$my_save_cflags" + fi fi ########################################################################## -- cgit v1.2.3 From 8eba3e76f32bb2d17b88ba13f633606fef61efe8 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 10 Apr 2017 13:43:05 +0800 Subject: linux-gen: pktio: miss an unlock operation before exit if error happens Just set the return value, and remove the return() function at the failure branch. https://bugs.linaro.org/show_bug.cgi?id=2933 Signed-off-by: Kevin Wang Reviewed-by: Ola Liljedahl Reviewed-by: Brian Brooks Signed-off-by: Maxim Uvarov --- platform/linux-generic/pktio/loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 70962839f..61e98ad8c 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -176,7 +176,7 @@ static int loopback_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED, pktio_entry->s.stats.out_octets += bytes; } else { ODP_DBG("queue enqueue failed %i\n", ret); - return -1; + ret = -1; } odp_ticketlock_unlock(&pktio_entry->s.txl); -- cgit v1.2.3 From d20f3a639d236066cbd76514df5c4faaa0ae17e9 Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Tue, 4 Apr 2017 13:47:59 -0500 Subject: test: odp_scheduling: handle dequeueing from a concurrent queue Signed-off-by: Ola Liljedahl Reviewed-by: Brian Brooks Reviewed-by: Honnappa Nagarahalli Reviewed-by: Kevin Wang Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_scheduling.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/common_plat/performance/odp_scheduling.c b/test/common_plat/performance/odp_scheduling.c index c74a07133..38e76257b 100644 --- a/test/common_plat/performance/odp_scheduling.c +++ b/test/common_plat/performance/odp_scheduling.c @@ -273,7 +273,7 @@ static int test_plain_queue(int thr, test_globals_t *globals) test_message_t *t_msg; odp_queue_t queue; uint64_t c1, c2, cycles; - int i; + int i, j; /* Alloc test message */ buf = odp_buffer_alloc(globals->pool); @@ -307,7 +307,15 @@ static int test_plain_queue(int thr, test_globals_t *globals) return -1; } - ev = odp_queue_deq(queue); + /* When enqueue and dequeue are decoupled (e.g. not using a + * common lock), an enqueued event may not be immediately + * visible to dequeue. So we just try again for a while. */ + for (j = 0; j < 100; j++) { + ev = odp_queue_deq(queue); + if (ev != ODP_EVENT_INVALID) + break; + odp_cpu_pause(); + } buf = odp_buffer_from_event(ev); -- cgit v1.2.3 From 51e3b8776b78180741fa57a621f9d13b9ae8bbfb Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Fri, 31 Mar 2017 23:39:39 +0300 Subject: test: tm: skip tm result under travis run tm test fails time to time in Travis environment. Because of we can not control that machine we can not do things like taskset and core isolation there. So simple run test and ignore it's result. Threat only segfault as actual error. Linaro CI will still do full test. https://bugs.linaro.org/show_bug.cgi?id=2881 Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- .../validation/api/traffic_mngr/Makefile.am | 12 +++++++++-- .../validation/api/traffic_mngr/traffic_mngr.sh | 25 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100755 test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh diff --git a/test/common_plat/validation/api/traffic_mngr/Makefile.am b/test/common_plat/validation/api/traffic_mngr/Makefile.am index 35e689a02..a012c1b3c 100644 --- a/test/common_plat/validation/api/traffic_mngr/Makefile.am +++ b/test/common_plat/validation/api/traffic_mngr/Makefile.am @@ -1,10 +1,18 @@ include ../Makefile.inc +TESTS_ENVIRONMENT += TEST_DIR=${builddir} + +TESTSCRIPTS = traffic_mngr.sh +TEST_EXTENSIONS = .sh + +TESTS = $(TESTSCRIPTS) + noinst_LTLIBRARIES = libtesttraffic_mngr.la libtesttraffic_mngr_la_SOURCES = traffic_mngr.c -test_PROGRAMS = traffic_mngr_main$(EXEEXT) +bin_PROGRAMS = traffic_mngr_main$(EXEEXT) dist_traffic_mngr_main_SOURCES = traffic_mngr_main.c traffic_mngr_main_LDADD = libtesttraffic_mngr.la -lm $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = traffic_mngr.h +EXTRA_DIST = traffic_mngr.h $(TESTSCRIPTS) +dist_check_SCRIPTS = $(TESTSCRIPTS) diff --git a/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh new file mode 100755 index 000000000..a7d541624 --- /dev/null +++ b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2017, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# directory where test binaries have been built +TEST_DIR="${TEST_DIR:-$(dirname $0)}" + +# exit codes expected by automake for skipped tests +TEST_SKIPPED=77 + +${TEST_DIR}/traffic_mngr_main${EXEEXT} +ret=$? + +SIGSEGV=139 + +if [ "${TRAVIS}" = "true" ] && [ $ret -ne 0 ] && [ $ret -ne ${SIGSEGV} ]; then + echo "SKIP: skip due to not isolated environment" + exit ${TEST_SKIPPED} +fi + +exit $ret -- cgit v1.2.3 From 2e8f024440a1e770068b1e9a9d50770ab166e40d Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 11 Apr 2017 14:25:55 +0300 Subject: example: generator: fix stop criteria - number of packets sent Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 95fb54327..63e3f2b5c 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -513,8 +513,8 @@ static int gen_send_thread(void *arg) for (;;) { if (args->appl.number != -1 && - odp_atomic_fetch_add_u64(&counters.cnt, 1) >= - (unsigned int)args->appl.number) + odp_atomic_fetch_add_u64(&counters.cnt, pkt_array_size) >= + (unsigned int)args->appl.number) break; if (args->appl.mode == APPL_MODE_UDP) { -- cgit v1.2.3 From 5622f689653013b317842386a1aed81dd81fe749 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Tue, 11 Apr 2017 14:25:56 +0300 Subject: example: generator: flush output messages Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 63e3f2b5c..ede1cdf29 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -464,6 +464,7 @@ static int create_pktio(const char *dev, odp_pool_t pool, " default pktio%02" PRIu64 "\n", odp_pktio_to_u64(itf->pktio), dev, odp_pktio_to_u64(itf->pktio)); + fflush(NULL); return 0; } @@ -773,6 +774,7 @@ static void print_global_stats(int num_workers) pkts_snd, odp_atomic_load_u64(&counters.tx_drops), pps_snd, maximum_pps_snd, pkts_rcv, pps_rcv, maximum_pps_rcv); + fflush(NULL); } } @@ -855,6 +857,7 @@ int main(int argc, char *argv[]) printf("num worker threads: %i\n", num_workers); printf("first CPU: %i\n", odp_cpumask_first(&cpumask)); printf("cpu mask: %s\n", cpumaskstr); + fflush(NULL); /* ping mode need two workers */ if (args->appl.mode == APPL_MODE_PING) { -- cgit v1.2.3 From 8ddca7c5d2d1f6b4311501e3ce6eef6d22e40591 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 20 Apr 2017 03:00:05 +0300 Subject: test: tm: use script instead of binary when calling traffic manager test Since 51e3b8776b78180741fa57a621f9d13b9ae8bbfb tm test received wrapper script checking if it is run under Travis CI. However linux-generic testsuite was not updated to call script instead of binary, resulting in test failures. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/linux-generic/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index 0522550ad..38516a432 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -30,7 +30,7 @@ TESTS = validation/api/pktio/pktio_run.sh \ $(ALL_API_VALIDATION_DIR)/thread/thread_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/time/time_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/timer/timer_main$(EXEEXT) \ - $(ALL_API_VALIDATION_DIR)/traffic_mngr/traffic_mngr_main$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/traffic_mngr/traffic_mngr.sh \ $(ALL_API_VALIDATION_DIR)/shmem/shmem_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/system/system_main$(EXEEXT) \ ring/ring_main$(EXEEXT) -- cgit v1.2.3 From 43de90c46e321f00ed7bf3f66c0c3c2ad41b5afd Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 6 Apr 2017 14:59:02 +0300 Subject: test: l2fwd: add group option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User may give number of scheduling groups to test scheduler performance with other that the default (all threads) group. Both pktios and threads are allocated into these groups with round robin. The number of groups may not exceed number of pktios or worker threads. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Carl Wallén Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_l2fwd.c | 148 ++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 32 deletions(-) diff --git a/test/common_plat/performance/odp_l2fwd.c b/test/common_plat/performance/odp_l2fwd.c index 8f5c5e152..33efc0223 100644 --- a/test/common_plat/performance/odp_l2fwd.c +++ b/test/common_plat/performance/odp_l2fwd.c @@ -104,6 +104,7 @@ typedef struct { int src_change; /**< Change source eth addresses */ int error_check; /**< Check packet errors */ int sched_mode; /**< Scheduler mode */ + int num_groups; /**< Number of scheduling groups */ } appl_args_t; static int exit_threads; /**< Break workers loop if set to 1 */ @@ -130,6 +131,7 @@ typedef union { typedef struct thread_args_t { int thr_idx; int num_pktio; + int num_groups; struct { odp_pktin_queue_t pktin; @@ -142,7 +144,12 @@ typedef struct thread_args_t { int tx_queue_idx; } pktio[MAX_PKTIOS]; - stats_t *stats; /**< Pointer to per thread stats */ + /* Groups to join */ + odp_schedule_group_t group[MAX_PKTIOS]; + + /* Pointer to per thread stats */ + stats_t *stats; + } thread_args_t; /** @@ -297,6 +304,22 @@ static int run_worker_sched_mode(void *arg) thr = odp_thread_id(); + if (gbl_args->appl.num_groups) { + odp_thrmask_t mask; + + odp_thrmask_zero(&mask); + odp_thrmask_set(&mask, thr); + + /* Join non-default groups */ + for (i = 0; i < thr_args->num_groups; i++) { + if (odp_schedule_group_join(thr_args->group[i], + &mask)) { + LOG_ERR("Join failed\n"); + return -1; + } + } + } + num_pktio = thr_args->num_pktio; if (num_pktio > MAX_PKTIOS) { @@ -590,7 +613,7 @@ static int run_worker_direct_mode(void *arg) * @retval -1 on failure */ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, - odp_pool_t pool) + odp_pool_t pool, odp_schedule_group_t group) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; @@ -650,7 +673,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, pktin_param.queue_param.sched.prio = ODP_SCHED_PRIO_DEFAULT; pktin_param.queue_param.sched.sync = sync_mode; - pktin_param.queue_param.sched.group = ODP_SCHED_GROUP_ALL; + pktin_param.queue_param.sched.group = group; } if (num_rx > (int)capa.max_input_queues) { @@ -1016,39 +1039,46 @@ static void usage(char *progname) printf("\n" "OpenDataPlane L2 forwarding application.\n" "\n" - "Usage: %s OPTIONS\n" + "Usage: %s [options]\n" + "\n" " E.g. %s -i eth0,eth1,eth2,eth3 -m 0 -t 1\n" - " In the above example,\n" - " eth0 will send pkts to eth1 and vice versa\n" - " eth2 will send pkts to eth3 and vice versa\n" + " In the above example,\n" + " eth0 will send pkts to eth1 and vice versa\n" + " eth2 will send pkts to eth3 and vice versa\n" "\n" "Mandatory OPTIONS:\n" - " -i, --interface Eth interfaces (comma-separated, no spaces)\n" - " Interface count min 1, max %i\n" + " -i, --interface Eth interfaces (comma-separated, no spaces)\n" + " Interface count min 1, max %i\n" "\n" "Optional OPTIONS:\n" - " -m, --mode Packet input mode\n" - " 0: Direct mode: PKTIN_MODE_DIRECT (default)\n" - " 1: Scheduler mode with parallel queues: PKTIN_MODE_SCHED + SCHED_SYNC_PARALLEL\n" - " 2: Scheduler mode with atomic queues: PKTIN_MODE_SCHED + SCHED_SYNC_ATOMIC\n" - " 3: Scheduler mode with ordered queues: PKTIN_MODE_SCHED + SCHED_SYNC_ORDERED\n" - " 4: Plain queue mode: ODP_PKTIN_MODE_QUEUE\n" - " -o, --out_mode Packet output mode\n" - " 0: Direct mode: PKTOUT_MODE_DIRECT (default)\n" - " 1: Queue mode: PKTOUT_MODE_QUEUE\n" - " -c, --count CPU count.\n" - " -t, --time Time in seconds to run.\n" - " -a, --accuracy Time in seconds get print statistics\n" + " -m, --mode Packet input mode\n" + " 0: Direct mode: PKTIN_MODE_DIRECT (default)\n" + " 1: Scheduler mode with parallel queues:\n" + " PKTIN_MODE_SCHED + SCHED_SYNC_PARALLEL\n" + " 2: Scheduler mode with atomic queues:\n" + " PKTIN_MODE_SCHED + SCHED_SYNC_ATOMIC\n" + " 3: Scheduler mode with ordered queues:\n" + " PKTIN_MODE_SCHED + SCHED_SYNC_ORDERED\n" + " 4: Plain queue mode: PKTIN_MODE_QUEUE\n" + " -o, --out_mode Packet output mode\n" + " 0: Direct mode: PKTOUT_MODE_DIRECT (default)\n" + " 1: Queue mode: PKTOUT_MODE_QUEUE\n" + " -c, --count CPU count.\n" + " -t, --time Time in seconds to run.\n" + " -a, --accuracy Time in seconds get print statistics\n" " (default is 1 second).\n" - " -d, --dst_change 0: Don't change packets' dst eth addresses\n" - " 1: Change packets' dst eth addresses (default)\n" - " -s, --src_change 0: Don't change packets' src eth addresses\n" - " 1: Change packets' src eth addresses (default)\n" - " -r, --dst_addr Destination addresses (comma-separated, no spaces)\n" - " Requires also the -d flag to be set\n" - " -e, --error_check 0: Don't check packet errors (default)\n" - " 1: Check packet errors\n" - " -h, --help Display help and exit.\n\n" + " -d, --dst_change 0: Don't change packets' dst eth addresses\n" + " 1: Change packets' dst eth addresses (default)\n" + " -s, --src_change 0: Don't change packets' src eth addresses\n" + " 1: Change packets' src eth addresses (default)\n" + " -r, --dst_addr Destination addresses (comma-separated, no spaces)\n" + " Requires also the -d flag to be set\n" + " -e, --error_check 0: Don't check packet errors (default)\n" + " 1: Check packet errors\n" + " -g, --groups Number of groups to use: 0 ... num\n" + " 0: SCHED_GROUP_ALL (default)\n" + " num: must not exceed number of interfaces or workers\n" + " -h, --help Display help and exit.\n\n" "\n", NO_PATH(progname), NO_PATH(progname), MAX_PKTIOS ); } @@ -1079,11 +1109,12 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {"dst_change", required_argument, NULL, 'd'}, {"src_change", required_argument, NULL, 's'}, {"error_check", required_argument, NULL, 'e'}, + {"groups", required_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; - static const char *shortopts = "+c:+t:+a:i:m:o:r:d:s:e:h"; + static const char *shortopts = "+c:+t:+a:i:m:o:r:d:s:e:g:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ odph_parse_options(argc, argv, shortopts, longopts); @@ -1092,6 +1123,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->accuracy = 1; /* get and print pps stats second */ appl_args->dst_change = 1; /* change eth dst address by default */ appl_args->src_change = 1; /* change eth src address by default */ + appl_args->num_groups = 0; /* use default group */ appl_args->error_check = 0; /* don't check packet errors by default */ opterr = 0; /* do not issue errors on helper options */ @@ -1217,6 +1249,9 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) case 'e': appl_args->error_check = atoi(optarg); break; + case 'g': + appl_args->num_groups = atoi(optarg); + break; case 'h': usage(argv[0]); exit(EXIT_SUCCESS); @@ -1305,6 +1340,24 @@ static void gbl_args_init(args_t *args) } } +static void create_groups(int num, odp_schedule_group_t *group) +{ + int i; + odp_thrmask_t zero; + + odp_thrmask_zero(&zero); + + /* Create groups */ + for (i = 0; i < num; i++) { + group[i] = odp_schedule_group_create(NULL, &zero); + + if (group[i] == ODP_SCHED_GROUP_INVALID) { + LOG_ERR("Group create failed\n"); + exit(EXIT_FAILURE); + } + } +} + /** * ODP L2 forwarding main function */ @@ -1325,6 +1378,8 @@ int main(int argc, char *argv[]) int if_count; int (*thr_run_func)(void *); odp_instance_t instance; + int num_groups; + odp_schedule_group_t group[MAX_PKTIOS]; /* Init ODP before calling anything else */ if (odp_init_global(&instance, NULL, NULL)) { @@ -1374,10 +1429,23 @@ int main(int argc, char *argv[]) if_count = gbl_args->appl.if_count; + num_groups = gbl_args->appl.num_groups; + printf("num worker threads: %i\n", num_workers); printf("first CPU: %i\n", odp_cpumask_first(&cpumask)); printf("cpu mask: %s\n", cpumaskstr); + if (num_groups) + printf("num groups: %i\n", num_groups); + + printf("\n"); + + if (num_groups > if_count || num_groups > num_workers) { + LOG_ERR("Too many groups. Number of groups may not exceed " + "number of interfaces or workers.\n"); + exit(EXIT_FAILURE); + } + /* Create packet pool */ odp_pool_param_init(¶ms); params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE; @@ -1399,9 +1467,18 @@ int main(int argc, char *argv[]) bind_workers(); + /* Default */ + if (num_groups == 0) { + group[0] = ODP_SCHED_GROUP_ALL; + num_groups = 1; + } else { + create_groups(num_groups, group); + } + for (i = 0; i < if_count; ++i) { const char *dev = gbl_args->appl.if_names[i]; int num_rx, num_tx; + odp_schedule_group_t grp; /* A queue per worker in scheduled mode */ num_rx = num_workers; @@ -1413,7 +1490,10 @@ int main(int argc, char *argv[]) num_tx = gbl_args->pktios[i].num_tx_thr; } - if (create_pktio(dev, i, num_rx, num_tx, pool)) + /* Round robin pktios to groups */ + grp = group[i % num_groups]; + + if (create_pktio(dev, i, num_rx, num_tx, pool, grp)) exit(EXIT_FAILURE); /* Save interface ethernet address */ @@ -1473,6 +1553,10 @@ int main(int argc, char *argv[]) thr_params.thr_type = ODP_THREAD_WORKER; thr_params.instance = instance; + /* Round robin threads to groups */ + gbl_args->thread[i].num_groups = 1; + gbl_args->thread[i].group[0] = group[i % num_groups]; + gbl_args->thread[i].stats = &stats[i]; odp_cpumask_zero(&thd_mask); -- cgit v1.2.3 From b12bfc6ebd9e7785d069ebea2861d7ac6ca237dd Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 6 Apr 2017 14:59:03 +0300 Subject: linux-gen: sched: use weight table for preferences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A precalculated table is more flexible for tunning weights than hard coding. As future development, the table may be updated with different weights at init or run time. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Carl Wallén Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_schedule.c | 51 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index cd5bf21bd..e7079b957 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -39,6 +39,13 @@ ODP_STATIC_ASSERT((ODP_SCHED_PRIO_NORMAL > 0) && /* Priority queues per priority */ #define QUEUES_PER_PRIO 4 +/* A thread polls a non preferred sched queue every this many polls + * of the prefer queue. */ +#define PREFER_RATIO 64 + +/* Size of poll weight table */ +#define WEIGHT_TBL_SIZE ((QUEUES_PER_PRIO - 1) * PREFER_RATIO) + /* Packet input poll cmd queues */ #define PKTIO_CMD_QUEUES 4 @@ -142,7 +149,6 @@ typedef struct { int index; int pause; uint16_t round; - uint16_t prefer_offset; uint16_t pktin_polls; uint32_t queue_index; odp_queue_t queue; @@ -157,6 +163,8 @@ typedef struct { ordered_stash_t stash[MAX_ORDERED_STASH]; } ordered; + uint8_t weight_tbl[WEIGHT_TBL_SIZE]; + } sched_local_t; /* Priority queue */ @@ -237,11 +245,29 @@ static inline void schedule_release_context(void); static void sched_local_init(void) { + int i; + uint8_t id; + uint8_t offset = 0; + memset(&sched_local, 0, sizeof(sched_local_t)); sched_local.thr = odp_thread_id(); sched_local.queue = ODP_QUEUE_INVALID; sched_local.queue_index = PRIO_QUEUE_EMPTY; + + id = sched_local.thr & (QUEUES_PER_PRIO - 1); + + for (i = 0; i < WEIGHT_TBL_SIZE; i++) { + sched_local.weight_tbl[i] = id; + + if (i % PREFER_RATIO == 0) { + offset++; + sched_local.weight_tbl[i] = (id + offset) & + (QUEUES_PER_PRIO - 1); + if (offset == QUEUES_PER_PRIO - 1) + offset = 0; + } + } } static int schedule_init_global(void) @@ -670,10 +696,10 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], { int prio, i; int ret; - int id; - int offset = 0; + int id, first; unsigned int max_deq = MAX_DEQ; uint32_t qi; + uint16_t round; if (sched_local.num) { ret = copy_events(out_ev, max_num); @@ -689,15 +715,15 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], if (odp_unlikely(sched_local.pause)) return 0; - /* Each thread prefers a priority queue. This offset avoids starvation - * of other priority queues on low thread counts. */ - if (odp_unlikely((sched_local.round & 0x3f) == 0)) { - offset = sched_local.prefer_offset; - sched_local.prefer_offset = (offset + 1) & - (QUEUES_PER_PRIO - 1); - } + /* Each thread prefers a priority queue. Poll weight table avoids + * starvation of other priority queues on low thread counts. */ + round = sched_local.round + 1; + + if (odp_unlikely(round == WEIGHT_TBL_SIZE)) + round = 0; - sched_local.round++; + sched_local.round = round; + first = sched_local.weight_tbl[round]; /* Schedule events */ for (prio = 0; prio < NUM_PRIO; prio++) { @@ -705,7 +731,8 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], if (sched->pri_mask[prio] == 0) continue; - id = (sched_local.thr + offset) & (QUEUES_PER_PRIO - 1); + /* Select the first ring based on weights */ + id = first; for (i = 0; i < QUEUES_PER_PRIO;) { int num; -- cgit v1.2.3 From 0a94dd3322dcbbd791e45647b238997553bfd1bc Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 6 Apr 2017 14:59:04 +0300 Subject: linux-gen: sched: optimize group scheduling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use separate priority queues for different groups. Sharing the same priority queue over multiple groups caused multiple issues: * latency and ordering issues when threads push back events (from wrong groups) to the tail of the priority queue * unnecessary contention (scaling issues) when threads belong to different groups Lowered the maximum number of groups from 256 to 32 (in the default configuration) to limit memory usage of priority queues. This should be enough for the most users. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Carl Wallén Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_schedule.c | 284 +++++++++++++++++++++++----------- 1 file changed, 195 insertions(+), 89 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index e7079b957..f366e7ed9 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -34,7 +34,7 @@ ODP_STATIC_ASSERT((ODP_SCHED_PRIO_NORMAL > 0) && "normal_prio_is_not_between_highest_and_lowest"); /* Number of scheduling groups */ -#define NUM_SCHED_GRPS 256 +#define NUM_SCHED_GRPS 32 /* Priority queues per priority */ #define QUEUES_PER_PRIO 4 @@ -163,7 +163,11 @@ typedef struct { ordered_stash_t stash[MAX_ORDERED_STASH]; } ordered; + uint32_t grp_epoch; + int num_grp; + uint8_t grp[NUM_SCHED_GRPS]; uint8_t weight_tbl[WEIGHT_TBL_SIZE]; + uint8_t grp_weight[WEIGHT_TBL_SIZE]; } sched_local_t; @@ -199,7 +203,7 @@ typedef struct { pri_mask_t pri_mask[NUM_PRIO]; odp_spinlock_t mask_lock; - prio_queue_t prio_q[NUM_PRIO][QUEUES_PER_PRIO]; + prio_queue_t prio_q[NUM_SCHED_GRPS][NUM_PRIO][QUEUES_PER_PRIO]; odp_spinlock_t poll_cmd_lock; /* Number of commands in a command queue */ @@ -214,8 +218,10 @@ typedef struct { odp_shm_t shm; uint32_t pri_count[NUM_PRIO][QUEUES_PER_PRIO]; - odp_spinlock_t grp_lock; - odp_thrmask_t mask_all; + odp_thrmask_t mask_all; + odp_spinlock_t grp_lock; + odp_atomic_u32_t grp_epoch; + struct { char name[ODP_SCHED_GROUP_NAME_LEN]; odp_thrmask_t mask; @@ -223,6 +229,7 @@ typedef struct { } sched_grp[NUM_SCHED_GRPS]; struct { + int grp; int prio; int queue_per_prio; } queue[ODP_CONFIG_QUEUES]; @@ -273,7 +280,7 @@ static void sched_local_init(void) static int schedule_init_global(void) { odp_shm_t shm; - int i, j; + int i, j, grp; ODP_DBG("Schedule init ... "); @@ -293,15 +300,20 @@ static int schedule_init_global(void) sched->shm = shm; odp_spinlock_init(&sched->mask_lock); - for (i = 0; i < NUM_PRIO; i++) { - for (j = 0; j < QUEUES_PER_PRIO; j++) { - int k; + for (grp = 0; grp < NUM_SCHED_GRPS; grp++) { + for (i = 0; i < NUM_PRIO; i++) { + for (j = 0; j < QUEUES_PER_PRIO; j++) { + prio_queue_t *prio_q; + int k; - ring_init(&sched->prio_q[i][j].ring); + prio_q = &sched->prio_q[grp][i][j]; + ring_init(&prio_q->ring); - for (k = 0; k < PRIO_QUEUE_RING_SIZE; k++) - sched->prio_q[i][j].queue_index[k] = - PRIO_QUEUE_EMPTY; + for (k = 0; k < PRIO_QUEUE_RING_SIZE; k++) { + prio_q->queue_index[k] = + PRIO_QUEUE_EMPTY; + } + } } } @@ -317,12 +329,17 @@ static int schedule_init_global(void) sched->pktio_cmd[i].cmd_index = PKTIO_CMD_FREE; odp_spinlock_init(&sched->grp_lock); + odp_atomic_init_u32(&sched->grp_epoch, 0); for (i = 0; i < NUM_SCHED_GRPS; i++) { memset(sched->sched_grp[i].name, 0, ODP_SCHED_GROUP_NAME_LEN); odp_thrmask_zero(&sched->sched_grp[i].mask); } + sched->sched_grp[ODP_SCHED_GROUP_ALL].allocated = 1; + sched->sched_grp[ODP_SCHED_GROUP_WORKER].allocated = 1; + sched->sched_grp[ODP_SCHED_GROUP_CONTROL].allocated = 1; + odp_thrmask_setall(&sched->mask_all); ODP_DBG("done\n"); @@ -330,29 +347,38 @@ static int schedule_init_global(void) return 0; } +static inline void queue_destroy_finalize(uint32_t qi) +{ + sched_cb_queue_destroy_finalize(qi); +} + static int schedule_term_global(void) { int ret = 0; int rc = 0; - int i, j; + int i, j, grp; - for (i = 0; i < NUM_PRIO; i++) { - for (j = 0; j < QUEUES_PER_PRIO; j++) { - ring_t *ring = &sched->prio_q[i][j].ring; - uint32_t qi; + for (grp = 0; grp < NUM_SCHED_GRPS; grp++) { + for (i = 0; i < NUM_PRIO; i++) { + for (j = 0; j < QUEUES_PER_PRIO; j++) { + ring_t *ring = &sched->prio_q[grp][i][j].ring; + uint32_t qi; - while ((qi = ring_deq(ring, PRIO_QUEUE_MASK)) != - RING_EMPTY) { - odp_event_t events[1]; - int num; + while ((qi = ring_deq(ring, PRIO_QUEUE_MASK)) != + RING_EMPTY) { + odp_event_t events[1]; + int num; - num = sched_cb_queue_deq_multi(qi, events, 1); + num = sched_cb_queue_deq_multi(qi, + events, + 1); - if (num < 0) - sched_cb_queue_destroy_finalize(qi); + if (num < 0) + queue_destroy_finalize(qi); - if (num > 0) - ODP_ERR("Queue not empty\n"); + if (num > 0) + ODP_ERR("Queue not empty\n"); + } } } } @@ -383,6 +409,40 @@ static int schedule_term_local(void) return 0; } +static inline void grp_update_mask(int grp, const odp_thrmask_t *new_mask) +{ + odp_thrmask_copy(&sched->sched_grp[grp].mask, new_mask); + odp_atomic_add_rel_u32(&sched->grp_epoch, 1); +} + +static inline int grp_update_tbl(void) +{ + int i; + int num = 0; + int thr = sched_local.thr; + + odp_spinlock_lock(&sched->grp_lock); + + for (i = 0; i < NUM_SCHED_GRPS; i++) { + if (sched->sched_grp[i].allocated == 0) + continue; + + if (odp_thrmask_isset(&sched->sched_grp[i].mask, thr)) { + sched_local.grp[num] = i; + num++; + } + } + + odp_spinlock_unlock(&sched->grp_lock); + + /* Update group weights. Round robin over all thread's groups. */ + for (i = 0; i < WEIGHT_TBL_SIZE; i++) + sched_local.grp_weight[i] = i % num; + + sched_local.num_grp = num; + return num; +} + static unsigned schedule_max_ordered_locks(void) { return MAX_ORDERED_LOCKS_PER_QUEUE; @@ -433,6 +493,7 @@ static int schedule_init_queue(uint32_t queue_index, int prio = sched_param->prio; pri_set_queue(queue_index, prio); + sched->queue[queue_index].grp = sched_param->group; sched->queue[queue_index].prio = prio; sched->queue[queue_index].queue_per_prio = queue_per_prio(queue_index); @@ -444,6 +505,7 @@ static void schedule_destroy_queue(uint32_t queue_index) int prio = sched->queue[queue_index].prio; pri_clr_queue(queue_index, prio); + sched->queue[queue_index].grp = 0; sched->queue[queue_index].prio = 0; sched->queue[queue_index].queue_per_prio = 0; } @@ -535,9 +597,10 @@ static void schedule_release_atomic(void) uint32_t qi = sched_local.queue_index; if (qi != PRIO_QUEUE_EMPTY && sched_local.num == 0) { - int prio = sched->queue[qi].prio; + int grp = sched->queue[qi].grp; + int prio = sched->queue[qi].prio; int queue_per_prio = sched->queue[qi].queue_per_prio; - ring_t *ring = &sched->prio_q[prio][queue_per_prio].ring; + ring_t *ring = &sched->prio_q[grp][prio][queue_per_prio].ring; /* Release current atomic queue */ ring_enq(ring, PRIO_QUEUE_MASK, qi); @@ -688,42 +751,14 @@ static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[], return 1; } -/* - * Schedule queues - */ -static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], - unsigned int max_num) +static inline int do_schedule_grp(odp_queue_t *out_queue, odp_event_t out_ev[], + unsigned int max_num, int grp, int first) { int prio, i; int ret; - int id, first; + int id; unsigned int max_deq = MAX_DEQ; uint32_t qi; - uint16_t round; - - if (sched_local.num) { - ret = copy_events(out_ev, max_num); - - if (out_queue) - *out_queue = sched_local.queue; - - return ret; - } - - schedule_release_context(); - - if (odp_unlikely(sched_local.pause)) - return 0; - - /* Each thread prefers a priority queue. Poll weight table avoids - * starvation of other priority queues on low thread counts. */ - round = sched_local.round + 1; - - if (odp_unlikely(round == WEIGHT_TBL_SIZE)) - round = 0; - - sched_local.round = round; - first = sched_local.weight_tbl[round]; /* Schedule events */ for (prio = 0; prio < NUM_PRIO; prio++) { @@ -736,7 +771,6 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], for (i = 0; i < QUEUES_PER_PRIO;) { int num; - int grp; int ordered; odp_queue_t handle; ring_t *ring; @@ -753,7 +787,7 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], } /* Get queue index from the priority queue */ - ring = &sched->prio_q[prio][id].ring; + ring = &sched->prio_q[grp][prio][id].ring; qi = ring_deq(ring, PRIO_QUEUE_MASK); /* Priority queue empty */ @@ -763,21 +797,6 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], continue; } - grp = sched_cb_queue_grp(qi); - - if (grp > ODP_SCHED_GROUP_ALL && - !odp_thrmask_isset(&sched->sched_grp[grp].mask, - sched_local.thr)) { - /* This thread is not eligible for work from - * this queue, so continue scheduling it. - */ - ring_enq(ring, PRIO_QUEUE_MASK, qi); - - i++; - id++; - continue; - } - /* Low priorities have smaller batch size to limit * head of line blocking latency. */ if (odp_unlikely(prio > ODP_SCHED_PRIO_DEFAULT)) @@ -845,6 +864,70 @@ static int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], } } + return 0; +} + +/* + * Schedule queues + */ +static inline int do_schedule(odp_queue_t *out_queue, odp_event_t out_ev[], + unsigned int max_num) +{ + int i, num_grp; + int ret; + int id, first, grp_id; + uint16_t round; + uint32_t epoch; + + if (sched_local.num) { + ret = copy_events(out_ev, max_num); + + if (out_queue) + *out_queue = sched_local.queue; + + return ret; + } + + schedule_release_context(); + + if (odp_unlikely(sched_local.pause)) + return 0; + + /* Each thread prefers a priority queue. Poll weight table avoids + * starvation of other priority queues on low thread counts. */ + round = sched_local.round + 1; + + if (odp_unlikely(round == WEIGHT_TBL_SIZE)) + round = 0; + + sched_local.round = round; + first = sched_local.weight_tbl[round]; + + epoch = odp_atomic_load_acq_u32(&sched->grp_epoch); + num_grp = sched_local.num_grp; + + if (odp_unlikely(sched_local.grp_epoch != epoch)) { + num_grp = grp_update_tbl(); + sched_local.grp_epoch = epoch; + } + + grp_id = sched_local.grp_weight[round]; + + /* Schedule queues per group and priority */ + for (i = 0; i < num_grp; i++) { + int grp; + + grp = sched_local.grp[grp_id]; + ret = do_schedule_grp(out_queue, out_ev, max_num, grp, first); + + if (odp_likely(ret)) + return ret; + + grp_id++; + if (odp_unlikely(grp_id >= num_grp)) + grp_id = 0; + } + /* * Poll packet input when there are no events * * Each thread starts the search for a poll command from its @@ -1050,7 +1133,8 @@ static odp_schedule_group_t schedule_group_create(const char *name, ODP_SCHED_GROUP_NAME_LEN - 1); grp_name[ODP_SCHED_GROUP_NAME_LEN - 1] = 0; } - odp_thrmask_copy(&sched->sched_grp[i].mask, mask); + + grp_update_mask(i, mask); group = (odp_schedule_group_t)i; sched->sched_grp[i].allocated = 1; break; @@ -1063,13 +1147,16 @@ static odp_schedule_group_t schedule_group_create(const char *name, static int schedule_group_destroy(odp_schedule_group_t group) { + odp_thrmask_t zero; int ret; + odp_thrmask_zero(&zero); + odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && sched->sched_grp[group].allocated) { - odp_thrmask_zero(&sched->sched_grp[group].mask); + grp_update_mask(group, &zero); memset(sched->sched_grp[group].name, 0, ODP_SCHED_GROUP_NAME_LEN); sched->sched_grp[group].allocated = 0; @@ -1109,9 +1196,11 @@ static int schedule_group_join(odp_schedule_group_t group, if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && sched->sched_grp[group].allocated) { - odp_thrmask_or(&sched->sched_grp[group].mask, - &sched->sched_grp[group].mask, - mask); + odp_thrmask_t new_mask; + + odp_thrmask_or(&new_mask, &sched->sched_grp[group].mask, mask); + grp_update_mask(group, &new_mask); + ret = 0; } else { ret = -1; @@ -1124,18 +1213,19 @@ static int schedule_group_join(odp_schedule_group_t group, static int schedule_group_leave(odp_schedule_group_t group, const odp_thrmask_t *mask) { + odp_thrmask_t new_mask; int ret; + odp_thrmask_xor(&new_mask, mask, &sched->mask_all); + odp_spinlock_lock(&sched->grp_lock); if (group < NUM_SCHED_GRPS && group >= SCHED_GROUP_NAMED && sched->sched_grp[group].allocated) { - odp_thrmask_t leavemask; + odp_thrmask_and(&new_mask, &sched->sched_grp[group].mask, + &new_mask); + grp_update_mask(group, &new_mask); - odp_thrmask_xor(&leavemask, mask, &sched->mask_all); - odp_thrmask_and(&sched->sched_grp[group].mask, - &sched->sched_grp[group].mask, - &leavemask); ret = 0; } else { ret = -1; @@ -1186,12 +1276,19 @@ static int schedule_group_info(odp_schedule_group_t group, static int schedule_thr_add(odp_schedule_group_t group, int thr) { + odp_thrmask_t mask; + odp_thrmask_t new_mask; + if (group < 0 || group >= SCHED_GROUP_NAMED) return -1; + odp_thrmask_zero(&mask); + odp_thrmask_set(&mask, thr); + odp_spinlock_lock(&sched->grp_lock); - odp_thrmask_set(&sched->sched_grp[group].mask, thr); + odp_thrmask_or(&new_mask, &sched->sched_grp[group].mask, &mask); + grp_update_mask(group, &new_mask); odp_spinlock_unlock(&sched->grp_lock); @@ -1200,12 +1297,20 @@ static int schedule_thr_add(odp_schedule_group_t group, int thr) static int schedule_thr_rem(odp_schedule_group_t group, int thr) { + odp_thrmask_t mask; + odp_thrmask_t new_mask; + if (group < 0 || group >= SCHED_GROUP_NAMED) return -1; + odp_thrmask_zero(&mask); + odp_thrmask_set(&mask, thr); + odp_thrmask_xor(&new_mask, &mask, &sched->mask_all); + odp_spinlock_lock(&sched->grp_lock); - odp_thrmask_clr(&sched->sched_grp[group].mask, thr); + odp_thrmask_and(&new_mask, &sched->sched_grp[group].mask, &new_mask); + grp_update_mask(group, &new_mask); odp_spinlock_unlock(&sched->grp_lock); @@ -1219,9 +1324,10 @@ static void schedule_prefetch(int num ODP_UNUSED) static int schedule_sched_queue(uint32_t queue_index) { + int grp = sched->queue[queue_index].grp; int prio = sched->queue[queue_index].prio; int queue_per_prio = sched->queue[queue_index].queue_per_prio; - ring_t *ring = &sched->prio_q[prio][queue_per_prio].ring; + ring_t *ring = &sched->prio_q[grp][prio][queue_per_prio].ring; ring_enq(ring, PRIO_QUEUE_MASK, queue_index); return 0; -- cgit v1.2.3 From 9b993a1531c94782b48292adff54a95de9d2be5c Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 15:03:06 -0500 Subject: bug: linux-generic: add syntax to allow newer clang to compile odp Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2942 by adding casts needed to avoid compilation failures when using clang 4.0.0 included in Ubuntu 17.04, which is stricter than clang 3.8.1 which is in Ubuntu 16.10. Signed-off-by: Bill Fischofer Reviewed-by: Brian Brooks Signed-off-by: Maxim Uvarov --- helper/chksum.c | 6 +++--- platform/linux-generic/odp_packet_flags.c | 2 +- .../validation/api/classification/odp_classification_common.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/helper/chksum.c b/helper/chksum.c index f740618d3..ae70d97e6 100644 --- a/helper/chksum.c +++ b/helper/chksum.c @@ -128,7 +128,7 @@ static inline int odph_process_l4_hdr(odp_packet_t odp_pkt, * should come from the udp header, unlike for TCP where is * derived. */ l4_len = odp_be_to_cpu_16(udp_hdr_ptr->length); - pkt_chksum_ptr = &udp_hdr_ptr->chksum; + pkt_chksum_ptr = (uint16_t *)(void *)&udp_hdr_ptr->chksum; pkt_chksum_offset = l4_offset + offsetof(odph_udphdr_t, chksum); } else if (odp_packet_has_tcp(odp_pkt)) { tcp_hdr_ptr = (odph_tcphdr_t *)l4_ptr; @@ -139,7 +139,7 @@ static inline int odph_process_l4_hdr(odp_packet_t odp_pkt, ODPH_TCPHDR_LEN, tcp_hdr_ptr); } - pkt_chksum_ptr = &tcp_hdr_ptr->cksm; + pkt_chksum_ptr = (uint16_t *)(void *)&tcp_hdr_ptr->cksm; pkt_chksum_offset = l4_offset + offsetof(odph_tcphdr_t, cksm); is_tcp = true; } else { @@ -203,7 +203,7 @@ static inline int odph_process_l3_hdr(odp_packet_t odp_pkt, ipv4_hdr_ptr = &ipv4_hdr; } - addrs_ptr = (uint16_t *)&ipv4_hdr_ptr->src_addr; + addrs_ptr = (uint16_t *)(void *)&ipv4_hdr_ptr->src_addr; addrs_len = 2 * ODPH_IPV4ADDR_LEN; protocol = ipv4_hdr_ptr->proto; l3_len = odp_be_to_cpu_16(ipv4_hdr_ptr->tot_len); diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c index ea9a22710..c2e8b9cf7 100644 --- a/platform/linux-generic/odp_packet_flags.c +++ b/platform/linux-generic/odp_packet_flags.c @@ -19,7 +19,7 @@ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ if (pkt_hdr->p.parsed_layers < layer) \ packet_parse_layer(pkt_hdr, layer); \ - pkt_hdr->p.x = v & 1; \ + pkt_hdr->p.x = (v) & 1; \ } while (0) int odp_packet_has_error(odp_packet_t pkt) diff --git a/test/common_plat/validation/api/classification/odp_classification_common.c b/test/common_plat/validation/api/classification/odp_classification_common.c index 3b379c14c..eca30b87f 100644 --- a/test/common_plat/validation/api/classification/odp_classification_common.c +++ b/test/common_plat/validation/api/classification/odp_classification_common.c @@ -278,14 +278,14 @@ odp_packet_t create_packet(cls_packet_info_t pkt_info) ethhdr = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL); memcpy(ethhdr->src.addr, &src_mac, ODPH_ETHADDR_LEN); memcpy(ethhdr->dst.addr, &dst_mac_be, ODPH_ETHADDR_LEN); - vlan_type = (odp_u16be_t *)ðhdr->type; + vlan_type = (odp_u16be_t *)(void *)ðhdr->type; vlan_hdr = (odph_vlanhdr_t *)(ethhdr + 1); if (pkt_info.vlan_qinq) { odp_packet_has_vlan_qinq_set(pkt, 1); *vlan_type = odp_cpu_to_be_16(ODPH_ETHTYPE_VLAN_OUTER); vlan_hdr->tci = odp_cpu_to_be_16(0); - vlan_type = (uint16_t *)&vlan_hdr->type; + vlan_type = (uint16_t *)(void *)&vlan_hdr->type; vlan_hdr++; } if (pkt_info.vlan) { -- cgit v1.2.3 From de52bbc9058604745e443195fbd9f4504d700d8d Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 24 Apr 2017 17:46:08 +0300 Subject: linux-generic: crypto: properly handle errors in packet copy Add proper handling for errors returned by odp_packet_copy_from_pkt(). Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Balasubramanian Manoharan Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 54b222fd2..831228008 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -871,14 +871,17 @@ odp_crypto_operation(odp_crypto_op_param_t *param, odp_crypto_alg_err_t rc_auth = ODP_CRYPTO_ALG_ERR_NONE; odp_crypto_generic_session_t *session; odp_crypto_op_result_t local_result; + odp_bool_t allocated = false; session = (odp_crypto_generic_session_t *)(intptr_t)param->session; /* Resolve output buffer */ if (ODP_PACKET_INVALID == param->out_pkt && - ODP_POOL_INVALID != session->p.output_pool) + ODP_POOL_INVALID != session->p.output_pool) { param->out_pkt = odp_packet_alloc(session->p.output_pool, odp_packet_len(param->pkt)); + allocated = true; + } if (odp_unlikely(ODP_PACKET_INVALID == param->out_pkt)) { ODP_DBG("Alloc failed.\n"); @@ -886,11 +889,16 @@ odp_crypto_operation(odp_crypto_op_param_t *param, } if (param->pkt != param->out_pkt) { - (void)odp_packet_copy_from_pkt(param->out_pkt, + int ret; + + ret = odp_packet_copy_from_pkt(param->out_pkt, 0, param->pkt, 0, odp_packet_len(param->pkt)); + if (odp_unlikely(ret < 0)) + goto err; + _odp_packet_copy_md_to_packet(param->pkt, param->out_pkt); odp_packet_free(param->pkt); param->pkt = ODP_PACKET_INVALID; @@ -932,7 +940,7 @@ odp_crypto_operation(odp_crypto_op_param_t *param, op_result->result = local_result; if (odp_queue_enq(session->p.compl_queue, completion_event)) { odp_event_free(completion_event); - return -1; + goto err; } /* Indicate to caller operation was async */ @@ -940,13 +948,21 @@ odp_crypto_operation(odp_crypto_op_param_t *param, } else { /* Synchronous, simply return results */ if (!result) - return -1; + goto err; *result = local_result; /* Indicate to caller operation was sync */ *posted = 0; } return 0; + +err: + if (allocated) { + odp_packet_free(param->out_pkt); + param->out_pkt = ODP_PACKET_INVALID; + } + + return -1; } static void ODP_UNUSED openssl_thread_id(CRYPTO_THREADID ODP_UNUSED *id) -- cgit v1.2.3 From 8c35a494023c7e5de127ed6de8ed8562b36f3cac Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Tue, 25 Apr 2017 16:27:11 -0500 Subject: test: odp_sched_latency: robust draining of queues In order to robustly drain all queues when the benchmark has ended, we enqueue a special event on every queue and invoke the scheduler until all such events have been received. Signed-off-by: Ola Liljedahl Reviewed-by: Brian Brooks Reviewed-by: Honnappa Nagarahalli Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_sched_latency.c | 59 ++++++++++++++++++------ 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/test/common_plat/performance/odp_sched_latency.c b/test/common_plat/performance/odp_sched_latency.c index 2b28cd7bc..b40186872 100644 --- a/test/common_plat/performance/odp_sched_latency.c +++ b/test/common_plat/performance/odp_sched_latency.c @@ -57,9 +57,10 @@ ODP_STATIC_ASSERT(LO_PRIO_QUEUES <= MAX_QUEUES, "Too many LO priority queues"); /** Test event types */ typedef enum { - WARM_UP, /**< Warm up event */ - TRAFFIC, /**< Event used only as traffic load */ - SAMPLE /**< Event used to measure latency */ + WARM_UP, /**< Warm up event */ + COOL_DOWN,/**< Last event on queue */ + TRAFFIC, /**< Event used only as traffic load */ + SAMPLE /**< Event used to measure latency */ } event_type_t; /** Test event */ @@ -112,20 +113,52 @@ typedef struct { /** * Clear all scheduled queues. * - * Retry to be sure that all buffers have been scheduled. + * Use special cool_down event to guarantee that queue is drained. */ -static void clear_sched_queues(void) +static void clear_sched_queues(test_globals_t *globals) { odp_event_t ev; + odp_buffer_t buf; + test_event_t *event; + int i, j; + odp_queue_t fromq; - while (1) { - ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); + /* Allocate the cool_down event. */ + buf = odp_buffer_alloc(globals->pool); + if (buf == ODP_BUFFER_INVALID) + LOG_ABORT("Buffer alloc failed.\n"); - if (ev == ODP_EVENT_INVALID) - break; + event = odp_buffer_addr(buf); + event->type = COOL_DOWN; + ev = odp_buffer_to_event(buf); - odp_event_free(ev); + for (i = 0; i < NUM_PRIOS; i++) { + for (j = 0; j < globals->args.prio[i].queues; j++) { + /* Enqueue cool_down event on each queue. */ + if (odp_queue_enq(globals->queue[i][j], ev)) + LOG_ABORT("Queue enqueue failed.\n"); + + /* Invoke scheduler until cool_down event has been + * received. */ + while (1) { + ev = odp_schedule(NULL, ODP_SCHED_WAIT); + buf = odp_buffer_from_event(ev); + event = odp_buffer_addr(buf); + if (event->type == COOL_DOWN) + break; + odp_event_free(ev); + } + } } + + /* Free the cool_down event. */ + odp_event_free(ev); + + /* Call odp_schedule() to trigger a release of any scheduler context. */ + ev = odp_schedule(&fromq, ODP_SCHED_NO_WAIT); + if (ev != ODP_EVENT_INVALID) + LOG_ABORT("Queue %" PRIu64 " not empty.\n", + odp_queue_to_u64(fromq)); } /** @@ -394,10 +427,10 @@ static int test_schedule(int thr, test_globals_t *globals) odp_barrier_wait(&globals->barrier); - clear_sched_queues(); - - if (thr == MAIN_THREAD) + if (thr == MAIN_THREAD) { + clear_sched_queues(globals); print_results(globals); + } return 0; } -- cgit v1.2.3 From 6028f9d4b9ec4c770d8fc5c09f1ccbb33b22f8b2 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 25 Apr 2017 04:41:49 +0300 Subject: validation: crypto: add tests for checking message digests Currently ODP testsuite only verifies generation of digests. Let's also verify that checking the digest actually works. Test that check function will accept valid digest and that it will reject wrong digests. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.h | 6 +- .../validation/api/crypto/odp_crypto_test_inp.c | 150 ++++++++++++++++++++- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h index 9b909aa04..661fe5df9 100644 --- a/test/common_plat/validation/api/crypto/crypto.h +++ b/test/common_plat/validation/api/crypto/crypto.h @@ -22,8 +22,10 @@ void crypto_test_enc_alg_aes128_gcm(void); void crypto_test_enc_alg_aes128_gcm_ovr_iv(void); void crypto_test_dec_alg_aes128_gcm(void); void crypto_test_dec_alg_aes128_gcm_ovr_iv(void); -void crypto_test_alg_hmac_md5(void); -void crypto_test_alg_hmac_sha256(void); +void crypto_test_gen_alg_hmac_md5(void); +void crypto_test_check_alg_hmac_md5(void); +void crypto_test_gen_alg_hmac_sha256(void); +void crypto_test_check_alg_hmac_sha256(void); /* test arrays: */ extern odp_testinfo_t crypto_suite[]; diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 43ddb2ffd..0909741dc 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -65,6 +65,7 @@ static const char *cipher_alg_name(odp_cipher_alg_t cipher) * buffer can be used. * */ static void alg_test(odp_crypto_op_t op, + odp_bool_t should_fail, odp_cipher_alg_t cipher_alg, odp_crypto_iv_t ses_iv, uint8_t *op_iv_ptr, @@ -239,6 +240,10 @@ static void alg_test(odp_crypto_op_t op, op_params.override_iv_ptr = op_iv_ptr; op_params.hash_result_offset = plaintext_len; + if (0 != digest_len) { + memcpy(data_addr + op_params.hash_result_offset, + digest, digest_len); + } rc = odp_crypto_operation(&op_params, &posted, &result); if (rc < 0) { @@ -259,8 +264,15 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_compl_free(compl_event); } - CU_ASSERT(result.ok); CU_ASSERT(result.pkt == pkt); + CU_ASSERT(result.ctx == (void *)0xdeadbeef); + + if (should_fail) { + CU_ASSERT(!result.ok); + goto cleanup; + } + + CU_ASSERT(result.ok); if (cipher_alg != ODP_CIPHER_ALG_NULL) CU_ASSERT(!memcmp(data_addr, ciphertext, ciphertext_len)); @@ -268,8 +280,6 @@ static void alg_test(odp_crypto_op_t op, if (op == ODP_CRYPTO_OP_ENCODE && auth_alg != ODP_AUTH_ALG_NULL) CU_ASSERT(!memcmp(data_addr + op_params.hash_result_offset, digest, digest_len)); - - CU_ASSERT(result.ctx == (void *)0xdeadbeef); cleanup: rc = odp_crypto_session_destroy(session); CU_ASSERT(!rc); @@ -445,6 +455,7 @@ void crypto_test_enc_alg_3des_cbc(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_3DES_CBC, iv, NULL, @@ -480,6 +491,7 @@ void crypto_test_enc_alg_3des_cbc_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_3DES_CBC, iv, tdes_cbc_reference_iv[i], @@ -519,6 +531,7 @@ void crypto_test_dec_alg_3des_cbc(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_3DES_CBC, iv, NULL, @@ -556,6 +569,7 @@ void crypto_test_dec_alg_3des_cbc_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_3DES_CBC, iv, tdes_cbc_reference_iv[i], @@ -602,6 +616,7 @@ void crypto_test_enc_alg_aes128_gcm(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_AES_GCM, iv, NULL, @@ -645,6 +660,7 @@ void crypto_test_enc_alg_aes128_gcm_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_AES_GCM, iv, aes128_gcm_reference_iv[i], @@ -691,6 +707,7 @@ void crypto_test_dec_alg_aes128_gcm(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_AES_GCM, iv, NULL, @@ -735,6 +752,7 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_AES_GCM, iv, aes128_gcm_reference_iv[i], @@ -782,6 +800,7 @@ void crypto_test_enc_alg_aes128_cbc(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_AES_CBC, iv, NULL, @@ -817,6 +836,7 @@ void crypto_test_enc_alg_aes128_cbc_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, ODP_CIPHER_ALG_AES_CBC, iv, aes128_cbc_reference_iv[i], @@ -856,6 +876,7 @@ void crypto_test_dec_alg_aes128_cbc(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_AES_CBC, iv, NULL, @@ -893,6 +914,7 @@ void crypto_test_dec_alg_aes128_cbc_ovr_iv(void) continue; alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_AES_CBC, iv, aes128_cbc_reference_iv[i], @@ -919,7 +941,7 @@ static int check_alg_hmac_md5(void) * In addition the test verifies if the implementation can use the * packet buffer as completion event buffer. * */ -void crypto_test_alg_hmac_md5(void) +void crypto_test_gen_alg_hmac_md5(void) { odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; @@ -938,6 +960,45 @@ void crypto_test_alg_hmac_md5(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_MD5_HMAC, + auth_key, + NULL, NULL, + hmac_md5_reference_plaintext[i], + hmac_md5_reference_length[i], + NULL, 0, + hmac_md5_reference_digest[i], + HMAC_MD5_96_CHECK_LEN); + } +} + +void crypto_test_check_alg_hmac_md5(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + uint8_t wrong_digest[HMAC_MD5_DIGEST_LEN]; + + unsigned int test_vec_num = (sizeof(hmac_md5_reference_length) / + sizeof(hmac_md5_reference_length[0])); + unsigned int i; + + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_md5_reference_key[i]; + auth_key.length = sizeof(hmac_md5_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_MD5_HMAC, auth_key.length, + HMAC_MD5_96_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_NULL, iv, iv.data, @@ -950,6 +1011,21 @@ void crypto_test_alg_hmac_md5(void) NULL, 0, hmac_md5_reference_digest[i], HMAC_MD5_96_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_MD5_HMAC, + auth_key, + NULL, NULL, + hmac_md5_reference_plaintext[i], + hmac_md5_reference_length[i], + NULL, 0, + wrong_digest, + HMAC_MD5_96_CHECK_LEN); } } @@ -965,7 +1041,7 @@ static int check_alg_hmac_sha256(void) * In addition the test verifies if the implementation can use the * packet buffer as completion event buffer. * */ -void crypto_test_alg_hmac_sha256(void) +void crypto_test_gen_alg_hmac_sha256(void) { odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; @@ -986,6 +1062,47 @@ void crypto_test_alg_hmac_sha256(void) continue; alg_test(ODP_CRYPTO_OP_ENCODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA256_HMAC, + auth_key, + NULL, NULL, + hmac_sha256_reference_plaintext[i], + hmac_sha256_reference_length[i], + NULL, 0, + hmac_sha256_reference_digest[i], + HMAC_SHA256_128_CHECK_LEN); + } +} + +void crypto_test_check_alg_hmac_sha256(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + uint8_t wrong_digest[HMAC_SHA256_DIGEST_LEN]; + + unsigned int test_vec_num = (sizeof(hmac_sha256_reference_length) / + sizeof(hmac_sha256_reference_length[0])); + + unsigned int i; + + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_sha256_reference_key[i]; + auth_key.length = sizeof(hmac_sha256_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_SHA256_HMAC, + auth_key.length, + HMAC_SHA256_128_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_DECODE, + 0, ODP_CIPHER_ALG_NULL, iv, iv.data, @@ -998,6 +1115,21 @@ void crypto_test_alg_hmac_sha256(void) NULL, 0, hmac_sha256_reference_digest[i], HMAC_SHA256_128_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA256_HMAC, + auth_key, + NULL, NULL, + hmac_sha256_reference_plaintext[i], + hmac_sha256_reference_length[i], + NULL, 0, + wrong_digest, + HMAC_SHA256_128_CHECK_LEN); } } @@ -1050,9 +1182,13 @@ odp_testinfo_t crypto_suite[] = { check_alg_aes_gcm), ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_aes128_gcm_ovr_iv, check_alg_aes_gcm), - ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_md5, + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_md5, + check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, check_alg_hmac_md5), - ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha256, + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, + check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, check_alg_hmac_sha256), ODP_TEST_INFO_NULL, }; -- cgit v1.2.3 From 24c00c16869cf0863b5592c9e2eeeef5daf9684c Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 25 Apr 2017 04:41:50 +0300 Subject: validation: crypto: correct comment for HMAC-SHA-256 tests Comment for HMAC-SHA-256 tests talks about HMAC-MD5 and respective lengths. Correct it to mention SHA-256 and proper digest lengths. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/odp_crypto_test_inp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 0909741dc..a415f5c1c 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -1034,8 +1034,8 @@ static int check_alg_hmac_sha256(void) return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC); } -/* This test verifies the correctness of HMAC_MD5 digest operation. - * The output check length is truncated to 12 bytes (96 bits) as +/* This test verifies the correctness of HMAC_SHA256 digest operation. + * The output check length is truncated to 16 bytes (128 bits) as * returned by the crypto operation API call. * Note that hash digest is a one-way operation. * In addition the test verifies if the implementation can use the -- cgit v1.2.3 From de644d068b0a6d4658770044191db7f96f716600 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Tue, 25 Apr 2017 04:41:51 +0300 Subject: linux-generic: crypto: unify auth code Authentication code contains similar functions. Instead of replicating them further (e.g. for SHA-1 or SHA-3) factor out common code blocks, moving all difference to session data. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_crypto_internal.h | 14 +-- platform/linux-generic/odp_crypto.c | 126 ++++----------------- 2 files changed, 28 insertions(+), 112 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index f85b76eaa..515cefaa0 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -60,16 +60,10 @@ struct odp_crypto_generic_session { } cipher; struct { - union { - struct { - uint8_t key[16]; - uint32_t bytes; - } md5; - struct { - uint8_t key[32]; - uint32_t bytes; - } sha256; - } data; + uint8_t key[EVP_MAX_KEY_LENGTH]; + uint32_t key_length; + uint32_t bytes; + const EVP_MD *evp_md; crypto_func_t func; } auth; }; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 831228008..b432f84af 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -110,8 +110,8 @@ null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED, } static -odp_crypto_alg_err_t md5_gen(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param, + odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(param->out_pkt); uint8_t *icv = data; @@ -123,94 +123,28 @@ odp_crypto_alg_err_t md5_gen(odp_crypto_op_param_t *param, icv += param->hash_result_offset; /* Hash it */ - HMAC(EVP_md5(), - session->auth.data.md5.key, - 16, + HMAC(session->auth.evp_md, + session->auth.key, + session->auth.key_length, data, len, hash, NULL); /* Copy to the output location */ - memcpy(icv, hash, session->auth.data.md5.bytes); + memcpy(icv, hash, session->auth.bytes); return ODP_CRYPTO_ALG_ERR_NONE; } static -odp_crypto_alg_err_t md5_check(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - uint8_t *data = odp_packet_data(param->out_pkt); - uint8_t *icv = data; - uint32_t len = param->auth_range.length; - uint32_t bytes = session->auth.data.md5.bytes; - uint8_t hash_in[EVP_MAX_MD_SIZE]; - uint8_t hash_out[EVP_MAX_MD_SIZE]; - - /* Adjust pointer for beginning of area to auth */ - data += param->auth_range.offset; - icv += param->hash_result_offset; - - /* Copy current value out and clear it before authentication */ - memset(hash_in, 0, sizeof(hash_in)); - memcpy(hash_in, icv, bytes); - memset(icv, 0, bytes); - memset(hash_out, 0, sizeof(hash_out)); - - /* Hash it */ - HMAC(EVP_md5(), - session->auth.data.md5.key, - 16, - data, - len, - hash_out, - NULL); - - /* Verify match */ - if (0 != memcmp(hash_in, hash_out, bytes)) - return ODP_CRYPTO_ALG_ERR_ICV_CHECK; - - /* Matched */ - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static -odp_crypto_alg_err_t sha256_gen(odp_crypto_op_param_t *param, +odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { uint8_t *data = odp_packet_data(param->out_pkt); uint8_t *icv = data; uint32_t len = param->auth_range.length; - uint8_t hash[EVP_MAX_MD_SIZE]; - - /* Adjust pointer for beginning of area to auth */ - data += param->auth_range.offset; - icv += param->hash_result_offset; - - /* Hash it */ - HMAC(EVP_sha256(), - session->auth.data.sha256.key, - 32, - data, - len, - hash, - NULL); - - /* Copy to the output location */ - memcpy(icv, hash, session->auth.data.sha256.bytes); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static -odp_crypto_alg_err_t sha256_check(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - uint8_t *data = odp_packet_data(param->out_pkt); - uint8_t *icv = data; - uint32_t len = param->auth_range.length; - uint32_t bytes = session->auth.data.sha256.bytes; + uint32_t bytes = session->auth.bytes; uint8_t hash_in[EVP_MAX_MD_SIZE]; uint8_t hash_out[EVP_MAX_MD_SIZE]; @@ -225,9 +159,9 @@ odp_crypto_alg_err_t sha256_check(odp_crypto_op_param_t *param, memset(hash_out, 0, sizeof(hash_out)); /* Hash it */ - HMAC(EVP_sha256(), - session->auth.data.sha256.key, - 32, + HMAC(session->auth.evp_md, + session->auth.key, + session->auth.key_length, data, len, hash_out, @@ -587,38 +521,26 @@ static int process_des_param(odp_crypto_generic_session_t *session) return 0; } -static int process_md5_param(odp_crypto_generic_session_t *session, - uint32_t bits) +static int process_auth_param(odp_crypto_generic_session_t *session, + uint32_t bits, + uint32_t key_length, + const EVP_MD *evp_md) { /* Set function */ if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->auth.func = md5_gen; + session->auth.func = auth_gen; else - session->auth.func = md5_check; - - /* Number of valid bytes */ - session->auth.data.md5.bytes = bits / 8; - - /* Convert keys */ - memcpy(session->auth.data.md5.key, session->p.auth_key.data, 16); - - return 0; -} + session->auth.func = auth_check; -static int process_sha256_param(odp_crypto_generic_session_t *session, - uint32_t bits) -{ - /* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->auth.func = sha256_gen; - else - session->auth.func = sha256_check; + session->auth.evp_md = evp_md; /* Number of valid bytes */ - session->auth.data.sha256.bytes = bits / 8; + session->auth.bytes = bits / 8; /* Convert keys */ - memcpy(session->auth.data.sha256.key, session->p.auth_key.data, 32); + session->auth.key_length = key_length; + memcpy(session->auth.key, session->p.auth_key.data, + session->auth.key_length); return 0; } @@ -814,12 +736,12 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, case ODP_AUTH_ALG_MD5_HMAC: /* deprecated */ case ODP_AUTH_ALG_MD5_96: - rc = process_md5_param(session, 96); + rc = process_auth_param(session, 96, 16, EVP_md5()); break; case ODP_AUTH_ALG_SHA256_HMAC: /* deprecated */ case ODP_AUTH_ALG_SHA256_128: - rc = process_sha256_param(session, 128); + rc = process_auth_param(session, 128, 32, EVP_sha256()); break; case ODP_AUTH_ALG_AES_GCM: /* deprecated */ -- cgit v1.2.3 From cf4a8144d8a8fcbbc3a9d6d43cbaa479f5e2dbfb Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 27 Apr 2017 17:26:42 +0300 Subject: test: tm: add paths to find tm binary Use the same algorithm as pktio_run.sh to find paths in different cases (in tree build, out of tree build, distcheck and etc). Fixes: https://bugs.linaro.org/show_bug.cgi?id=2969 Signed-off-by: Maxim Uvarov Reviewed-and-tested-by: Bill Fischofer --- .../validation/api/traffic_mngr/traffic_mngr.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh index a7d541624..4db7ea384 100755 --- a/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh +++ b/test/common_plat/validation/api/traffic_mngr/traffic_mngr.sh @@ -6,13 +6,29 @@ # SPDX-License-Identifier: BSD-3-Clause # -# directory where test binaries have been built -TEST_DIR="${TEST_DIR:-$(dirname $0)}" +# directories where traffic_mngr_main binary can be found: +# -in the validation dir when running make check (intree or out of tree) +# -in the script directory, when running after 'make install', or +# -in the validation when running standalone (./traffic_mngr) intree. +# -in the current directory. +# running stand alone out of tree requires setting PATH +PATH=${TEST_DIR}/api/traffic_mngr:$PATH +PATH=$(dirname $0)/../../../../common_plat/validation/api/traffic_mngr:$PATH +PATH=$(dirname $0):$PATH +PATH=`pwd`:$PATH + +traffic_mngr_main_path=$(which traffic_mngr_main${EXEEXT}) +if [ -x "$traffic_mngr_main_path" ] ; then + echo "running with traffic_mngr_main: $traffic_mngr_run_path" +else + echo "cannot find traffic_mngr_main: please set you PATH for it." + exit 1 +fi # exit codes expected by automake for skipped tests TEST_SKIPPED=77 -${TEST_DIR}/traffic_mngr_main${EXEEXT} +traffic_mngr_main${EXEEXT} ret=$? SIGSEGV=139 -- cgit v1.2.3 From b33b8ed7ca7c0f66f9c63155dd7e59ecaf7ea75e Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 27 Apr 2017 17:26:43 +0300 Subject: test: pktio_run: exit if binary was not found No need to continue run if binary was not found in paths. Signed-off-by: Maxim Uvarov Reviewed-and-tested-by: Bill Fischofer --- test/linux-generic/validation/api/pktio/pktio_run.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/linux-generic/validation/api/pktio/pktio_run.sh b/test/linux-generic/validation/api/pktio/pktio_run.sh index e8b0f936f..19def8c5a 100755 --- a/test/linux-generic/validation/api/pktio/pktio_run.sh +++ b/test/linux-generic/validation/api/pktio/pktio_run.sh @@ -31,6 +31,7 @@ if [ -x "$pktio_main_path" ] ; then echo "running with pktio_main: $pktio_run_path" else echo "cannot find pktio_main: please set you PATH for it." + exit 1 fi # directory where platform test sources are, including scripts -- cgit v1.2.3 From 2520efadae74322d9a61c7e306246518a8396b6f Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 27 Apr 2017 14:29:54 +0300 Subject: linux-gen: pktio: fix valgrind warnings Fix valgrind warnings about syscall params pointing to uninitialised bytes. Signed-off-by: Matias Elo Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/pktio/ethtool.c | 1 + platform/linux-generic/pktio/socket.c | 1 + 2 files changed, 2 insertions(+) diff --git a/platform/linux-generic/pktio/ethtool.c b/platform/linux-generic/pktio/ethtool.c index 1b0f25b2c..d8f9e12cb 100644 --- a/platform/linux-generic/pktio/ethtool.c +++ b/platform/linux-generic/pktio/ethtool.c @@ -158,6 +158,7 @@ int ethtool_stats_get_fd(int fd, const char *name, odp_pktio_stats_t *stats) { struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", name); return ethtool_stats(fd, &ifr, stats); diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index 7d2396866..a08b0104a 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -234,6 +234,7 @@ static inline int get_rss_hash_options(int fd, const char *name, struct ifreq ifr; struct ethtool_rxnfc rsscmd; + memset(&ifr, 0, sizeof(ifr)); memset(&rsscmd, 0, sizeof(rsscmd)); *options = 0; -- cgit v1.2.3 From f05a0abd5386dc953b8a3eb30b6f6b8937be08cc Mon Sep 17 00:00:00 2001 From: Janne Kajovuori Date: Fri, 28 Apr 2017 10:29:39 +0300 Subject: linux-generic: makefile: fix staged install support install-data-hook tries to create the symlink with incorrect paths when a staged install is performed with "make DESTDIR= install". This issue can be fixed by prepending the paths with $(DESTDIR), which provides correct path to the staging area. Signed-off-by: Janne Kajovuori Signed-off-by: Maxim Uvarov --- platform/linux-generic/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 545291518..69fdf8b91 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -226,9 +226,9 @@ endif # Create symlink for ABI header files. Application does not need to use the arch # specific include path for installed files. install-data-hook: - if [ -h $(prefix)/include/odp/api/abi ]; then \ + if [ -h $(DESTDIR)$(prefix)/include/odp/api/abi ]; then \ : ; \ else \ - $(LN_S) -rf $(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ - $(prefix)/include/odp/api/abi; \ + $(LN_S) -rf $(DESTDIR)$(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ + $(DESTDIR)$(prefix)/include/odp/api/abi; \ fi -- cgit v1.2.3 From a6ce9a4b1c70506a9d178d53b9c5daff92477d46 Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Fri, 21 Apr 2017 13:52:41 -0500 Subject: .gitignore: add perf.data Signed-off-by: Brian Brooks Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fbc0eab96..cce24282a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ libtool ltmain.sh m4/*.m4 missing +perf.data* pkgconfig/libodp*.pc tags test-driver -- cgit v1.2.3 From 79ba737a404d2833ad33d8f84ed6ce82c9a8c18e Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Wed, 12 Apr 2017 14:41:14 -0500 Subject: example: l3fwd: check rc from odph_eth_addr_parse() Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2779 by checking the return code from odph_eth_addr_parse() and failing the call if dst_mac is unparseable. Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- example/l3fwd/odp_l3fwd_db.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/example/l3fwd/odp_l3fwd_db.c b/example/l3fwd/odp_l3fwd_db.c index 082b2c276..0670aa455 100644 --- a/example/l3fwd/odp_l3fwd_db.c +++ b/example/l3fwd/odp_l3fwd_db.c @@ -394,7 +394,10 @@ int create_fwd_db_entry(char *input, char **oif, uint8_t **dst_mac) *oif = entry->oif; break; case 2: - odph_eth_addr_parse(&entry->dst_mac, token); + if (odph_eth_addr_parse(&entry->dst_mac, token) < 0) { + free(local); + return -1; + } *dst_mac = entry->dst_mac.addr; break; -- cgit v1.2.3 From bd583923b29e5dddc4d1b9c6d0e0a513edb69496 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Fri, 5 May 2017 15:49:56 +0300 Subject: helper: tables: avoid invalid odp_shm_addr() calls odp_shm_lookup() return value can be used to detect name conflicts. Signed-off-by: Matias Elo Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- helper/hashtable.c | 3 +-- helper/lineartable.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/helper/hashtable.c b/helper/hashtable.c index 9d4114445..f26b18b27 100644 --- a/helper/hashtable.c +++ b/helper/hashtable.c @@ -76,8 +76,7 @@ odph_table_t odph_hash_table_create(const char *name, uint32_t capacity, ODPH_DBG("create para input error!\n"); return NULL; } - tbl = (odph_hash_table_imp *)odp_shm_addr(odp_shm_lookup(name)); - if (tbl != NULL) { + if (odp_shm_lookup(name) != ODP_SHM_INVALID) { ODPH_DBG("name already exist\n"); return NULL; } diff --git a/helper/lineartable.c b/helper/lineartable.c index 32c4956ee..dd4a59958 100644 --- a/helper/lineartable.c +++ b/helper/lineartable.c @@ -55,8 +55,7 @@ odph_table_t odph_linear_table_create(const char *name, uint32_t capacity, return NULL; } /* check name confict in shm*/ - tbl = (odph_linear_table_imp *)odp_shm_addr(odp_shm_lookup(name)); - if (tbl != NULL) { + if (odp_shm_lookup(name) != ODP_SHM_INVALID) { ODPH_DBG("name already exist\n"); return NULL; } -- cgit v1.2.3 From c1e962548f5082554bb52137765a258b3a29283c Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 11 May 2017 14:48:38 +0300 Subject: linux-gen: sched: fix one at a time low priority event scheduling If CONFIG_BURST_SIZE was set to one low priority events were never scheduled. Signed-off-by: Matias Elo Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_schedule.c | 3 ++- platform/linux-generic/odp_schedule_iquery.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index f366e7ed9..f680ac47e 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -799,7 +799,8 @@ static inline int do_schedule_grp(odp_queue_t *out_queue, odp_event_t out_ev[], /* Low priorities have smaller batch size to limit * head of line blocking latency. */ - if (odp_unlikely(prio > ODP_SCHED_PRIO_DEFAULT)) + if (odp_unlikely(MAX_DEQ > 1 && + prio > ODP_SCHED_PRIO_DEFAULT)) max_deq = MAX_DEQ / 2; ordered = sched_cb_queue_is_ordered(qi); diff --git a/platform/linux-generic/odp_schedule_iquery.c b/platform/linux-generic/odp_schedule_iquery.c index b69245788..b8a400117 100644 --- a/platform/linux-generic/odp_schedule_iquery.c +++ b/platform/linux-generic/odp_schedule_iquery.c @@ -1457,7 +1457,7 @@ static inline int consume_queue(int prio, unsigned int queue_index) /* Low priorities have smaller batch size to limit * head of line blocking latency. */ - if (odp_unlikely(prio > ODP_SCHED_PRIO_DEFAULT)) + if (odp_unlikely(MAX_DEQ > 1 && prio > ODP_SCHED_PRIO_DEFAULT)) max = MAX_DEQ / 2; /* For ordered queues we want consecutive events to -- cgit v1.2.3 From 86e5b478325a0f5422fc6edff9db168d44852d2e Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 5 May 2017 01:00:08 +0300 Subject: linux-generic: rwlock: fix odp_rwlock_read_trylock() odp_rwlock_read_trylock() currently works only if there are no readers (and writers) as it compares counter with 0. Make it actually work in case there are other active readers. Fixes: https://bugs.linaro.org/show_bug.cgi?id=2974 Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_rwlock.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c index 13c17a2c7..5bef13a45 100644 --- a/platform/linux-generic/odp_rwlock.c +++ b/platform/linux-generic/odp_rwlock.c @@ -33,9 +33,14 @@ void odp_rwlock_read_lock(odp_rwlock_t *rwlock) int odp_rwlock_read_trylock(odp_rwlock_t *rwlock) { - uint32_t zero = 0; + uint32_t cnt = odp_atomic_load_u32(&rwlock->cnt); + + while (cnt != (uint32_t)-1) { + if (odp_atomic_cas_acq_u32(&rwlock->cnt, &cnt, cnt + 1)) + return 1; + } - return odp_atomic_cas_acq_u32(&rwlock->cnt, &zero, (uint32_t)1); + return 0; } void odp_rwlock_read_unlock(odp_rwlock_t *rwlock) -- cgit v1.2.3 From 91f92891554b9c335e9f51f8ef574b74a37a11fb Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 5 May 2017 01:00:07 +0300 Subject: test: lock: expand rwlock tests Expand testsuite for rwlocks: - always verify _trylock return code - always unlock after successful _trylock return - try calling _trylock when holding write lock Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/lock/lock.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/test/common_plat/validation/api/lock/lock.c b/test/common_plat/validation/api/lock/lock.c index bd9a2aad2..f8a1d8c01 100644 --- a/test/common_plat/validation/api/lock/lock.c +++ b/test/common_plat/validation/api/lock/lock.c @@ -257,7 +257,7 @@ static int ticketlock_api_tests(void *arg UNUSED) static void rwlock_api_test(odp_rwlock_t *rw_lock) { - int rc; + int rc = 0; odp_rwlock_init(rw_lock); /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 0); */ @@ -265,23 +265,40 @@ static void rwlock_api_test(odp_rwlock_t *rw_lock) odp_rwlock_read_lock(rw_lock); rc = odp_rwlock_read_trylock(rw_lock); - CU_ASSERT(rc == 0); + CU_ASSERT(rc != 0); + if (rc == 1) + odp_rwlock_read_unlock(rw_lock); + rc = odp_rwlock_write_trylock(rw_lock); CU_ASSERT(rc == 0); + if (rc == 1) + odp_rwlock_write_unlock(rw_lock); odp_rwlock_read_unlock(rw_lock); rc = odp_rwlock_read_trylock(rw_lock); + CU_ASSERT(rc != 0); if (rc == 1) odp_rwlock_read_unlock(rw_lock); odp_rwlock_write_lock(rw_lock); /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 1); */ + rc = odp_rwlock_read_trylock(rw_lock); + CU_ASSERT(rc == 0); + if (rc == 1) + odp_rwlock_read_unlock(rw_lock); + + rc = odp_rwlock_write_trylock(rw_lock); + CU_ASSERT(rc == 0); + if (rc == 1) + odp_rwlock_write_unlock(rw_lock); + odp_rwlock_write_unlock(rw_lock); /* CU_ASSERT(odp_rwlock_is_locked(rw_lock) == 0); */ rc = odp_rwlock_write_trylock(rw_lock); + CU_ASSERT(rc != 0); if (rc == 1) odp_rwlock_write_unlock(rw_lock); } -- cgit v1.2.3 From 036f1d33b5d186a68748a5465713370b1c602545 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 12 May 2017 03:00:05 +0300 Subject: configure.ac: fix mcx16 vs clang check Currently configure script outputs the following error on my sistem, because the syntax is far from being standard. Use standard case/esac instead. ./configure: line 23507: x86_64-pc-linux-gnu: command not found Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d364b8ddf..7569ebe07 100644 --- a/configure.ac +++ b/configure.ac @@ -306,7 +306,8 @@ ODP_CFLAGS="$ODP_CFLAGS $ODP_CFLAGS_EXTRA" ########################################################################## # Check if compiler supports cmpxchng16 on x86-based architectures ########################################################################## -if "${host}" == i?86* -o "${host}" == x86*; then +case "${host}" in + i?86? | x86*) if test "${CC}" != "gcc" -o ${CC_VERSION_MAJOR} -ge 5; then my_save_cflags="$CFLAGS" @@ -319,7 +320,8 @@ if "${host}" == i?86* -o "${host}" == x86*; then ) CFLAGS="$my_save_cflags" fi -fi + ;; +esac ########################################################################## # Default include setup -- cgit v1.2.3 From 8b9783b7f5667b3a37f039222e06448af2eec070 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 10 May 2017 02:47:11 +0300 Subject: linux-generic: crypto: don't leak sessions if creation fails We should free allocated session in odp_crypto_session_create() error paths, so that the session is not leaked. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index b432f84af..c5473d959 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -678,6 +678,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, if (session->p.iv.data) { if (session->p.iv.length > MAX_IV_LEN) { ODP_DBG("Maximum IV length exceeded\n"); + free_session(session); return -1; } @@ -724,6 +725,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, /* Check result */ if (rc) { *status = ODP_CRYPTO_SES_CREATE_ERR_INV_CIPHER; + free_session(session); return -1; } @@ -763,6 +765,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, /* Check result */ if (rc) { *status = ODP_CRYPTO_SES_CREATE_ERR_INV_AUTH; + free_session(session); return -1; } -- cgit v1.2.3 From 160f71a48b5891b49a84cc849f08c1ff99d26b3f Mon Sep 17 00:00:00 2001 From: Dmitriy Krot Date: Fri, 12 May 2017 03:00:13 +0300 Subject: linux-gen: tm: fix wrr/wfq bug when weight=1 Usage of 0x10000 in the inverted weight calculation causes overflow of uint16_t if weight=1. As a result of this bug, frame len used for virtual finish time calculation is always zero, despite of packet size, so packets from input with weight=1 always pass first. Signed-off-by: Dmitriy Krot Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_traffic_mngr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_traffic_mngr.c b/platform/linux-generic/odp_traffic_mngr.c index 4e9358b96..a93b3ba90 100644 --- a/platform/linux-generic/odp_traffic_mngr.c +++ b/platform/linux-generic/odp_traffic_mngr.c @@ -3238,7 +3238,7 @@ static void tm_sched_params_cvt_to(odp_tm_sched_params_t *odp_sched_params, if (weight == 0) inv_weight = 0; else - inv_weight = 0x10000 / weight; + inv_weight = 0xFFFF / weight; tm_sched_params->sched_modes[priority] = sched_mode; tm_sched_params->inverted_weights[priority] = inv_weight; @@ -3254,7 +3254,7 @@ static void tm_sched_params_cvt_from(tm_sched_params_t *tm_sched_params, for (priority = 0; priority < ODP_TM_MAX_PRIORITIES; priority++) { sched_mode = tm_sched_params->sched_modes[priority]; inv_weight = tm_sched_params->inverted_weights[priority]; - weight = 0x10000 / inv_weight; + weight = 0xFFFF / inv_weight; odp_sched_params->sched_modes[priority] = sched_mode; odp_sched_params->sched_weights[priority] = weight; -- cgit v1.2.3 From 3a8ba69bff8052cbe35dcca71ebda9b669dbf807 Mon Sep 17 00:00:00 2001 From: Yi He Date: Tue, 16 May 2017 06:00:06 +0300 Subject: checkpatch.conf: ignore PREFER_PRINTF, PREFER_SCANF This is not the kernel, ignore these preferences Signed-off-by: Yi He Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .checkpatch.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.checkpatch.conf b/.checkpatch.conf index 1e7d6638a..043551a4c 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -6,5 +6,7 @@ --ignore=DEPRECATED_VARIABLE --ignore=COMPARISON_TO_NULL --ignore=BIT_MACRO +--ignore=PREFER_PRINTF +--ignore=PREFER_SCANF --codespell --codespellfile=/usr/share/codespell/dictionary.txt -- cgit v1.2.3 From b50cf14202528e986ae9a41721fae1e746078646 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 11 May 2017 01:14:29 +0300 Subject: codecov: enable threshold for patches thresholds for individual patches and for project set in different places. Also drop status for not visible diff changes. Test only patch and project. https://github.com/codecov/support/wiki/Codecov-Yaml Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- .codecov.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 36270d618..327f65496 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -8,10 +8,16 @@ coverage: range: "50...75" status: project: - target: 70% - threshold: 5% - patch: yes - changes: yes + default: + enabled: yes + target: 70% + threshold: 5% + patch: + default: + enabled: yes + target: 70% + threshold: 5% + changes: no parsers: gcov: -- cgit v1.2.3 From 3ca26420f0e06fdb1b2cb9192461dbc32a421de5 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Wed, 3 May 2017 10:42:25 +0300 Subject: examples: generator: UDP ports configuration Signed-off-by: Bogdan Pricope Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index ede1cdf29..79efe5bb0 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -64,6 +64,8 @@ typedef struct { odph_ethaddr_t dstmac; /**< dest mac addr */ unsigned int srcip; /**< src ip addr */ unsigned int dstip; /**< dest ip addr */ + uint16_t srcport; /**< src udp port */ + uint16_t dstport; /**< dest udp port */ int mode; /**< work mode */ int number; /**< packets number to be sent */ int payload; /**< data len */ @@ -233,8 +235,8 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool) odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); odp_packet_has_udp_set(pkt, 1); udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); - udp->src_port = 0; - udp->dst_port = 0; + udp->src_port = odp_cpu_to_be_16(args->appl.srcport); + udp->dst_port = odp_cpu_to_be_16(args->appl.dstport); udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN); udp->chksum = 0; udp->chksum = odph_ipv4_udp_chksum(pkt); @@ -1143,6 +1145,8 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {"dstmac", required_argument, NULL, 'b'}, {"srcip", required_argument, NULL, 's'}, {"dstip", required_argument, NULL, 'd'}, + {"srcport", required_argument, NULL, 'e'}, + {"dstport", required_argument, NULL, 'f'}, {"packetsize", required_argument, NULL, 'p'}, {"mode", required_argument, NULL, 'm'}, {"count", required_argument, NULL, 'n'}, @@ -1153,7 +1157,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) {NULL, 0, NULL, 0} }; - static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:h"; + static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:"; /* let helper collect its own arguments (e.g. --odph_proc) */ odph_parse_options(argc, argv, shortopts, longopts); @@ -1164,6 +1168,8 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->timeout = -1; appl_args->interval = DEFAULT_PKT_INTERVAL; appl_args->udp_tx_burst = 16; + appl_args->srcport = 0; + appl_args->dstport = 0; opterr = 0; /* do not issue errors on helper options */ @@ -1270,6 +1276,12 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) } break; + case 'e': + appl_args->srcport = (unsigned short)atoi(optarg); + break; + case 'f': + appl_args->dstport = (unsigned short)atoi(optarg); + break; case 'p': appl_args->payload = atoi(optarg); break; @@ -1383,6 +1395,8 @@ static void usage(char *progname) "\n" "Optional OPTIONS\n" " -h, --help Display help and exit.\n" + " -e, --srcport src udp port\n" + " -f, --dstport dst udp port\n" " -p, --packetsize payload length of the packets\n" " -t, --timeout only for ping mode, wait ICMP reply timeout seconds\n" " -i, --interval wait interval ms between sending each packet\n" -- cgit v1.2.3 From f4386378e466a519d8f97923ba43ea22dec1e933 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Thu, 4 May 2017 14:33:14 -0500 Subject: scripts: checkpatch: update to allow additional exceptions Update checkpatch.pl to avoid issuing warnings for use of externs, volatile, or camelCase. Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 16316b928..1c27ac60c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4273,7 +4273,7 @@ sub process { $camelcase_file_seeded = 1; } } - if (!defined $camelcase{$word}) { + if (!defined $camelcase{$word} && 0) { $camelcase{$word} = 1; CHK("CAMELCASE", "Avoid CamelCase: <$word>\n" . $herecurr); @@ -4620,7 +4620,7 @@ sub process { # no volatiles please my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; - if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { + if ($line =~ /\bvolatile\b/ && 0 && $line !~ /$asm_volatile/) { WARN("VOLATILE", "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); } @@ -5134,7 +5134,7 @@ sub process { if (defined $cond) { substr($s, 0, length($cond), ''); } - if ($s =~ /^\s*;/ && + if ($s =~ /^\s*;/ && 0 && $function_name ne 'uninitialized_var') { WARN("AVOID_EXTERNS", -- cgit v1.2.3 From d2562fb0cb2c2b21b628b265ef24a6c8cbac9608 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 16 May 2017 16:09:27 +0300 Subject: travis: move code style check to separate job Move this check to separate job to better see which exactly task was failed. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- .travis.yml | 31 ++++++++++++++++--------------- scripts/ci-checkpatches.sh | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 15 deletions(-) create mode 100755 scripts/ci-checkpatches.sh diff --git a/.travis.yml b/.travis.yml index aa7ea0107..e792af06b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,12 +51,28 @@ matrix: - llvm-toolchain-precise-3.8 packages: - clang-3.8 + - compiler: gcc + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc + env: TEST="CHECKPATCH" before_install: - echo 1000 | sudo tee /proc/sys/vm/nr_hugepages - sudo mkdir -p /mnt/huge - sudo mount -t hugetlbfs nodev /mnt/huge + - if [ "$TEST" = "CHECKPATCH" ]; then + echo ${TRAVIS_COMMIT_RANGE}; + ODP_PATCHES=`echo ${TRAVIS_COMMIT_RANGE} | sed 's/\.//'`; + if [ -z "${ODP_PATCHES}" ]; then env; exit 1; fi; + ./scripts/ci-checkpatches.sh ${ODP_PATCHES}; + exit $?; + fi + - sudo apt-get -qq update - sudo apt-get install automake autoconf libtool libssl-dev graphviz mscgen doxygen - sudo apt-get install libpcap-dev linux-headers-`uname -r` @@ -101,21 +117,6 @@ before_install: - popd script: - - echo $TRAVIS_COMMIT_RANGE - - ODP_PACHES=`echo $TRAVIS_COMMIT_RANGE | sed 's/\.//'` -# Generate patches provided with $TRAVIS_COMMIT_RANGE. -# In case of force push and range is broken validate only the latest commit if it's not merge commit. - - git format-patch $ODP_PACHES; - if [ $? -ne 0 ]; then - git show --summary HEAD| grep -q '^Merge:'; - if [ $? -ne 0 ]; then - git format-patch HEAD^; - perl ./scripts/checkpatch.pl *.patch; - fi; - else - perl ./scripts/checkpatch.pl *.patch; - fi - - ./bootstrap - ./configure # doxygen does not trap on warnings, check for them here. diff --git a/scripts/ci-checkpatches.sh b/scripts/ci-checkpatches.sh new file mode 100755 index 000000000..cb1c4e65d --- /dev/null +++ b/scripts/ci-checkpatches.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +PATCHES=$1 +echo "Run checkpatch for ${PATCHES}" +# Generate patches provided with $1. +# In case of force push and range is broken +# validate only the latest commit if it's not merge commit. +git format-patch ${PATCHES} +if [ $? -ne 0 ]; then + git show --summary HEAD| grep -q '^Merge:'; + if [ $? -ne 0 ]; then + git format-patch HEAD^; + perl ./scripts/checkpatch.pl *.patch; + fi; +else + perl ./scripts/checkpatch.pl *.patch; +fi -- cgit v1.2.3 From 599ac6802352c9c56eca33a6004824783becaa6e Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 16 May 2017 22:01:33 +0300 Subject: travis: check compile and run from install Verify that odp app can be compiled and run from installed odp library and includes. Signed-off-by: Maxim Uvarov eviewed-by: Bill Fischofer --- .travis.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e792af06b..65edfbb3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -125,9 +125,21 @@ script: - make distcheck - ./bootstrap - - ./configure --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="$MY_CF" CXXFLAGS="$MY_CF" LDFLAGS="$MY_LDF" + - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="$MY_CF" CXXFLAGS="$MY_CF" LDFLAGS="$MY_LDF" - make -j 4 - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" make check + - make install + + - echo "Checking linking and run from install..." + - pushd $HOME + - echo "Dynamic link.." + - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap $MY_CF $MY_LDF -ldl + - LD_LIBRARY_PATH="${HOME}/odp-install/lib:$LD_LIBRARY_PATH" ./odp_hello_inst + - echo "Static link.." + - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap $MY_CF $MY_LDF -ldl -static + - ./odp_hello_inst + - popd + - sudo rm -rf dpdk - sudo rm -rf netmap - sudo rm -rf $KSRC -- cgit v1.2.3 From 60b9dd435bf1be55794e5be6ee24714d28a5b587 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 23 May 2017 15:38:54 +0300 Subject: linux-gen: sched: fix ordered enqueue to pktout queue Make sure packet order is maintained if enqueueing packets from an ordered queue. Fixes https://bugs.linaro.org/show_bug.cgi?id=3002 Signed-off-by: Matias Elo Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_packet_io.c | 8 ++++++++ platform/linux-generic/odp_queue.c | 1 + platform/linux-generic/odp_schedule.c | 5 ++++- platform/linux-generic/odp_schedule_iquery.c | 5 ++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 98460a566..50a000e5b 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -586,6 +586,10 @@ int pktout_enqueue(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr) int len = 1; int nbr; + if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, len, + &nbr)) + return (nbr == len ? 0 : -1); + nbr = odp_pktout_send(qentry->s.pktout, &pkt, len); return (nbr == len ? 0 : -1); } @@ -603,6 +607,10 @@ int pktout_enq_multi(queue_entry_t *qentry, odp_buffer_hdr_t *buf_hdr[], int nbr; int i; + if (sched_fn->ord_enq_multi(qentry->s.index, (void **)buf_hdr, num, + &nbr)) + return nbr; + for (i = 0; i < num; ++i) pkt_tbl[i] = _odp_packet_from_buffer(buf_hdr[i]->handle.handle); diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index fcf4bf5bb..a96f9225f 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -95,6 +95,7 @@ static int queue_init(queue_entry_t *queue, const char *name, queue->s.dequeue_multi = queue_deq_multi; queue->s.pktin = PKTIN_INVALID; + queue->s.pktout = PKTOUT_INVALID; queue->s.head = NULL; queue->s.tail = NULL; diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c index f680ac47e..c4567d810 100644 --- a/platform/linux-generic/odp_schedule.c +++ b/platform/linux-generic/odp_schedule.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -729,7 +730,9 @@ static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[], return 0; } - if (odp_unlikely(stash_num >= MAX_ORDERED_STASH)) { + /* Pktout may drop packets, so the operation cannot be stashed. */ + if (dst_queue->s.pktout.pktio != ODP_PKTIO_INVALID || + odp_unlikely(stash_num >= MAX_ORDERED_STASH)) { /* If the local stash is full, wait until it is our turn and * then release the stash and do enqueue directly. */ wait_for_order(src_queue); diff --git a/platform/linux-generic/odp_schedule_iquery.c b/platform/linux-generic/odp_schedule_iquery.c index b8a400117..75470aff8 100644 --- a/platform/linux-generic/odp_schedule_iquery.c +++ b/platform/linux-generic/odp_schedule_iquery.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* Number of priority levels */ @@ -1176,7 +1177,9 @@ static int schedule_ord_enq_multi(uint32_t queue_index, void *buf_hdr[], return 0; } - if (odp_unlikely(stash_num >= MAX_ORDERED_STASH)) { + /* Pktout may drop packets, so the operation cannot be stashed. */ + if (dst_queue->s.pktout.pktio != ODP_PKTIO_INVALID || + odp_unlikely(stash_num >= MAX_ORDERED_STASH)) { /* If the local stash is full, wait until it is our turn and * then release the stash and do enqueue directly. */ wait_for_order(src_queue); -- cgit v1.2.3 From ea134fe159c0d249e4bed12b7269e8236afa0262 Mon Sep 17 00:00:00 2001 From: Bogdan Pricope Date: Mon, 3 Apr 2017 13:00:57 +0300 Subject: test: generator: replace gettimeofday with ODP API calls Fixes: https://bugs.linaro.org/show_bug.cgi?id=2416 Signed-off-by: Bogdan Pricope Reviewed-and-tested-by: Yi He Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 89 ++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 79efe5bb0..3ec7d8d12 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -121,7 +121,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args); static void print_info(char *progname, appl_args_t *appl_args); static void usage(char *progname); static int scan_ip(char *buf, unsigned int *paddr); -static void tv_sub(struct timeval *recvtime, struct timeval *sendtime); static void print_global_stats(int num_workers); /** @@ -350,7 +349,7 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) char *buf; odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; - struct timeval tval; + uint64_t tval; uint8_t *tval_d; unsigned short seq; @@ -374,12 +373,12 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref) /* icmp */ icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); icmp->un.echo.sequence = ip->id; + tval_d = (uint8_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ICMPHDR_LEN); - /* TODO This should be changed to use an - * ODP timer API once one exists. */ - gettimeofday(&tval, NULL); - memcpy(tval_d, &tval, sizeof(struct timeval)); + tval = odp_time_to_ns(odp_time_local()); + memcpy(tval_d, &tval, sizeof(uint64_t)); + icmp->chksum = 0; icmp->chksum = odph_chksum(icmp, args->appl.payload + ODPH_ICMPHDR_LEN); @@ -596,6 +595,40 @@ static int gen_send_thread(void *arg) return 0; } +/** + * Process icmp packets + * + * @param icmp icmp header address + * @param msg output buffer + */ + +static void process_icmp_pkt(odph_icmphdr_t *icmp, char *msg) +{ + uint64_t trecv; + uint64_t tsend; + uint64_t rtt_ms, rtt_us; + + msg[0] = 0; + + if (icmp->type == ICMP_ECHOREPLY) { + odp_atomic_inc_u64(&counters.icmp); + + memcpy(&tsend, (uint8_t *)icmp + ODPH_ICMPHDR_LEN, + sizeof(uint64_t)); + trecv = odp_time_to_ns(odp_time_local()); + rtt_ms = (trecv - tsend) / ODP_TIME_MSEC_IN_NS; + rtt_us = (trecv - tsend) / ODP_TIME_USEC_IN_NS - + 1000 * rtt_ms; + sprintf(msg, + "ICMP Echo Reply seq %d time %" + PRIu64 ".%.03" PRIu64" ms", + odp_be_to_cpu_16(icmp->un.echo.sequence), + rtt_ms, rtt_us); + } else if (icmp->type == ICMP_ECHO) { + sprintf(msg, "Icmp Echo Request"); + } +} + /** * Print odp packets * @@ -609,16 +642,12 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) char *buf; odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; - struct timeval tvrecv; - struct timeval tvsend; - double rtt; unsigned i; size_t offset; char msg[1024]; - int rlen; + for (i = 0; i < len; ++i) { pkt = pkt_tbl[i]; - rlen = 0; /* only ip pkts */ if (!odp_packet_has_ipv4(pkt)) @@ -637,26 +666,8 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) /* icmp */ if (ip->proto == ODPH_IPPROTO_ICMP) { icmp = (odph_icmphdr_t *)(buf + offset); - /* echo reply */ - if (icmp->type == ICMP_ECHOREPLY) { - odp_atomic_inc_u64(&counters.icmp); - memcpy(&tvsend, buf + offset + ODPH_ICMPHDR_LEN, - sizeof(struct timeval)); - /* TODO This should be changed to use an - * ODP timer API once one exists. */ - gettimeofday(&tvrecv, NULL); - tv_sub(&tvrecv, &tvsend); - rtt = tvrecv.tv_sec*1000 + tvrecv.tv_usec/1000; - rlen += sprintf(msg + rlen, - "ICMP Echo Reply seq %d time %.1f ", - odp_be_to_cpu_16(icmp->un.echo.sequence) - , rtt); - } else if (icmp->type == ICMP_ECHO) { - rlen += sprintf(msg + rlen, - "Icmp Echo Request"); - } - msg[rlen] = '\0'; + process_icmp_pkt(icmp, msg); printf(" [%02i] %s\n", thr, msg); } } @@ -1409,21 +1420,3 @@ static void usage(char *progname) "\n", NO_PATH(progname), NO_PATH(progname) ); } -/** - * calc time period - * - *@param recvtime start time - *@param sendtime end time -*/ -static void tv_sub(struct timeval *recvtime, struct timeval *sendtime) -{ - long sec = recvtime->tv_sec - sendtime->tv_sec; - long usec = recvtime->tv_usec - sendtime->tv_usec; - if (usec >= 0) { - recvtime->tv_sec = sec; - recvtime->tv_usec = usec; - } else { - recvtime->tv_sec = sec - 1; - recvtime->tv_usec = -usec; - } -} -- cgit v1.2.3 From c5eb1703fe9e7529ae12ecf1799b757e1a992afd Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 25 May 2017 07:59:44 +0300 Subject: test: linux-generic: stop dropping other ODP files in pktio_ipc test Prevent pktio_ipc test from removing sockets and SHM files used by other applications. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/linux-generic/pktio_ipc/pktio_ipc_run.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh index 52e8d42a0..331ecdc98 100755 --- a/test/linux-generic/pktio_ipc/pktio_ipc_run.sh +++ b/test/linux-generic/pktio_ipc/pktio_ipc_run.sh @@ -20,9 +20,6 @@ PATH=.:$PATH run() { local ret=0 - #if test was interrupted with CTRL+c than files - #might remain in shm. Needed cleanely delete them. - rm -rf /tmp/odp-* 2>&1 > /dev/null echo "==== run pktio_ipc1 then pktio_ipc2 ====" pktio_ipc1${EXEEXT} -t 10 & -- cgit v1.2.3 From ba6cad6319b917c078dd0c20cd6b011637195898 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 24 May 2017 17:35:19 +0300 Subject: linux-gen: packet: fix odp_packet_free_multi() with single segment pool Previously the implementation would use wrong handles and crash if CONFIG_PACKET_MAX_SEGS was set to one. https://bugs.linaro.org/show_bug.cgi?id=3013 Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_packet.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index e99e8b837..3e7c07a35 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -594,11 +594,16 @@ void odp_packet_free(odp_packet_t pkt) void odp_packet_free_multi(const odp_packet_t pkt[], int num) { + odp_buffer_t buf[num * CONFIG_PACKET_MAX_SEGS]; + int i; + if (CONFIG_PACKET_MAX_SEGS == 1) { - buffer_free_multi((const odp_buffer_t * const)pkt, num); + for (i = 0; i < num; i++) + buf[i] = buffer_handle(packet_hdr(pkt[i])); + + buffer_free_multi(buf, num); } else { - odp_buffer_t buf[num * CONFIG_PACKET_MAX_SEGS]; - int i, j; + int j; int bufs = 0; for (i = 0; i < num; i++) { -- cgit v1.2.3 From 148a700fb9af847a64d732bf7ed9975aa03fefa9 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 24 May 2017 17:35:20 +0300 Subject: linux-gen: packet: fix gcc errors with single segment pool Fix (invalid) gcc errors when CONFIG_PACKET_MAX_SEGS is set to one. https://bugs.linaro.org/show_bug.cgi?id=3013 Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_packet.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 3e7c07a35..e2bb8426a 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -804,7 +804,8 @@ static inline int move_data_to_head(odp_packet_hdr_t *pkt_hdr, int segs) free_len = BASE_LEN - len; - for (src_seg = dst_seg + 1; src_seg < segs; src_seg++) { + for (src_seg = dst_seg + 1; CONFIG_PACKET_MAX_SEGS > 1 && + src_seg < segs; src_seg++) { len = fill_seg_head(pkt_hdr, dst_seg, src_seg, free_len); moved += len; @@ -928,7 +929,7 @@ int odp_packet_extend_head(odp_packet_t *pkt, uint32_t len, pkt_hdr = new_hdr; *pkt = packet_handle(pkt_hdr); - } else if (free_segs) { + } else if (CONFIG_PACKET_MAX_SEGS > 1 && free_segs) { new_hdr = pkt_hdr->buf_hdr.seg[free_segs].hdr; packet_seg_copy_md(new_hdr, pkt_hdr); -- cgit v1.2.3 From 472d34cc0fd2b5f96277b1799583ab6c45375d40 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 24 May 2017 17:35:21 +0300 Subject: test: pktio: use capability to set test pool packet length Test used to fail if odp_pool_capability_t.pkt.max_len < PKT_BUF_SIZE. https://bugs.linaro.org/show_bug.cgi?id=3013 Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/pktio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 54f206efc..11fe974fe 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -122,20 +122,23 @@ static inline void _pktio_wait_linkup(odp_pktio_t pktio) static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) { + uint32_t len; uint32_t seg_len; + len = (capa->pkt.max_len && capa->pkt.max_len < PKT_BUF_SIZE) ? + capa->pkt.max_len : PKT_BUF_SIZE; seg_len = capa->pkt.max_seg_len ? capa->pkt.max_seg_len : PKT_BUF_SIZE; switch (pool_segmentation) { case PKT_POOL_SEGMENTED: /* Force segment to minimum size */ params->pkt.seg_len = 0; - params->pkt.len = PKT_BUF_SIZE; + params->pkt.len = len; break; case PKT_POOL_UNSEGMENTED: default: params->pkt.seg_len = seg_len; - params->pkt.len = PKT_BUF_SIZE; + params->pkt.len = len; break; } } -- cgit v1.2.3 From fc815dec86d080ca7d1b8fadddcab1e7c8e4b11b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Wed, 24 May 2017 19:30:04 +0300 Subject: travis: split build into separate stages Introduce separate parallel builds for checkpatch, doxygen, distcheck and plain checks. Signed-off-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- .travis.yml | 136 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 65 insertions(+), 71 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65edfbb3c..2ae788eb0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,65 +33,50 @@ env: # you need generated new one at https://codecov.io specific for your repo. - CODECOV_TOKEN=8e1c0fd8-62ff-411e-a79f-5839f6662c11 -matrix: - include: - - compiler: gcc - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc - env: MY_CF="-O0 -coverage" MY_LDF="--coverage" DOCOV=1 - - compiler: clang - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.8 - packages: - - clang-3.8 - - compiler: gcc - addons: +addons: apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc - env: TEST="CHECKPATCH" + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.8 + packages: + - gcc + - clang-3.8 + - automake autoconf libtool libssl-dev graphviz mscgen doxygen + - libpcap-dev +# coverity_scan: +# project: +# name: "$TRAVIS_REPO_SLUG" +# notification_email: xxxx +# build_command_prepend: "./bootstrap && ./configure --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example" +# build_command: "make" +# branch_pattern: coverity_scan + +compiler: + - gcc + - clang-3.8 -before_install: +install: - echo 1000 | sudo tee /proc/sys/vm/nr_hugepages - sudo mkdir -p /mnt/huge - sudo mount -t hugetlbfs nodev /mnt/huge - - if [ "$TEST" = "CHECKPATCH" ]; then - echo ${TRAVIS_COMMIT_RANGE}; - ODP_PATCHES=`echo ${TRAVIS_COMMIT_RANGE} | sed 's/\.//'`; - if [ -z "${ODP_PATCHES}" ]; then env; exit 1; fi; - ./scripts/ci-checkpatches.sh ${ODP_PATCHES}; - exit $?; - fi - - sudo apt-get -qq update - - sudo apt-get install automake autoconf libtool libssl-dev graphviz mscgen doxygen - - sudo apt-get install libpcap-dev linux-headers-`uname -r` + - sudo apt-get install linux-headers-`uname -r` - sudo pip install coverage - gem install asciidoctor - PATH=${PATH//:\.\/node_modules\/\.bin/} - - if [ "$CC" = "clang" ]; then export CXX="clang++-3.8" CC="clang-3.8" LD="clang-3.8"; fi # Install cunit for the validation tests because distro version is too old and fails C99 compile - sudo apt-get remove libcunit1-dev libcunit1 - export CUNIT_VERSION=2.1-3 - curl -sSOL https://github.com/Linaro/libcunit/releases/download/${CUNIT_VERSION}/CUnit-${CUNIT_VERSION}.tar.bz2 - tar -jxf *.bz2 - - cd CUnit* + - pushd CUnit* - ./bootstrap - ./configure --enable-debug --enable-automated --enable-basic --enable-console --enable-examples --enable-test - make - sudo make install - - cd .. + - popd - export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" # DPDK pktio @@ -103,55 +88,64 @@ before_install: - pushd ${TARGET} - sed -ri 's,(CONFIG_RTE_LIBRTE_PMD_PCAP=).*,\1y,' .config - popd - - make install T=${TARGET} EXTRA_CFLAGS="-fPIC" > /dev/null + - make install T=${TARGET} EXTRA_CFLAGS="-fPIC" - popd # Netmap pktio - - sudo apt-get source linux-image-$(uname -r) > /dev/null - - KSRC="$PWD/`find . -name kernel-parameters.txt | cut -d / -f 2 `" - git -c advice.detachedHead=false clone -q --depth=1 --single-branch --branch=v11.2 https://github.com/luigirizzo/netmap.git - pushd netmap/LINUX - - ./configure --kernel-sources=$KSRC - - make > /dev/null + - ./configure + - make - sudo insmod ./netmap.ko - popd script: - ./bootstrap - - ./configure -# doxygen does not trap on warnings, check for them here. - - make doxygen-doc |tee doxygen.log - - fgrep -rvq warning ./doxygen.log - - make distcheck - - - ./bootstrap - - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="$MY_CF" CXXFLAGS="$MY_CF" LDFLAGS="$MY_LDF" - - make -j 4 + - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap + - make -j $(nproc) - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" make check - make install - echo "Checking linking and run from install..." - pushd $HOME - echo "Dynamic link.." - - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap $MY_CF $MY_LDF -ldl + - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap -ldl - LD_LIBRARY_PATH="${HOME}/odp-install/lib:$LD_LIBRARY_PATH" ./odp_hello_inst - echo "Static link.." - - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap $MY_CF $MY_LDF -ldl -static + - ${CC} ${OLDPWD}/example/hello/odp_hello.c -o odp_hello_inst -I${HOME}/odp-install/include -L${HOME}/odp-install/lib -lodp-linux -L${OLDPWD}/dpdk/x86_64-native-linuxapp-gcc/lib -lrt -ldpdk -lpthread -lcrypto -lpcap -ldl -static - ./odp_hello_inst - - popd - - sudo rm -rf dpdk - - sudo rm -rf netmap - - sudo rm -rf $KSRC - -after_success: - - if [ -n "$DOCOV" ]; then find . -type f -iname '*.[ch]' -not -path ".git/*" -execdir gcov {} \; ; bash <(curl -s https://codecov.io/bash) -X coveragepy; fi - -addons: - coverity_scan: - project: - name: "$TRAVIS_REPO_SLUG" - notification_email: xxxx - build_command_prepend: "./bootstrap && ./configure --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example" - build_command: "make" - branch_pattern: coverity_scan +jobs: + include: + - stage: test + env: TEST=coverage + compiler: gcc + script: + - ./bootstrap + - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="-O0 -coverage" CXXFLAGS="-O0 -coverage" LDFLAGS="--coverage" + - make check -j $(nproc) + - find . -type f -iname '*.[ch]' -not -path ".git/*" -execdir gcov {} \; ; bash <(curl -s https://codecov.io/bash) -X coveragepy + - stage: test + env: TEST=distcheck + compiler: gcc + script: + - ./bootstrap + - ./configure + - make distcheck + - stage: test + env: TEST=doxygen + compiler: gcc + script: + # doxygen does not trap on warnings, check for them here. + - ./bootstrap + - ./configure + - make doxygen-doc |tee doxygen.log + - fgrep -rvq warning ./doxygen.log + - stage: test + env: TEST=checkpatch + compiler: gcc + script: + - echo ${TRAVIS_COMMIT_RANGE}; + - ODP_PATCHES=`echo ${TRAVIS_COMMIT_RANGE} | sed 's/\.//'`; + - if [ -z "${ODP_PATCHES}" ]; then env; exit 1; fi; + - ./scripts/ci-checkpatches.sh ${ODP_PATCHES}; -- cgit v1.2.3 From 0f47f4c4b48fb08326d6be9c0b1019f738d57911 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 23 May 2017 22:29:43 +0300 Subject: travis: expand testing with varios configure options [DES: check all compiler vs options combinations] Signed-off-by: Maxim Uvarov Signed-off-by: Dmitry Eremin-Solenikov --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2ae788eb0..af47ed179 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,6 +55,12 @@ compiler: - gcc - clang-3.8 +env: + - CONF="" + - CONF="--disable-abi-compat" + - CONF="--enable-schedule-sp" + - CONF="--enable-schedule-iquery" + install: - echo 1000 | sudo tee /proc/sys/vm/nr_hugepages - sudo mkdir -p /mnt/huge @@ -101,7 +107,7 @@ install: script: - ./bootstrap - - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap + - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap $CONF - make -j $(nproc) - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" make check - make install -- cgit v1.2.3 From 87bba414b4444d8247adf3411e8bbefd35899f1b Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 23 May 2017 22:58:14 +0300 Subject: travis: print failed test logs to screen If some test failed try to find them and print log. Signed-off-by: Maxim Uvarov Signed-off-by: Dmitry Eremin-Solenikov --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index af47ed179..a7ad2a743 100644 --- a/.travis.yml +++ b/.travis.yml @@ -155,3 +155,6 @@ jobs: - ODP_PATCHES=`echo ${TRAVIS_COMMIT_RANGE} | sed 's/\.//'`; - if [ -z "${ODP_PATCHES}" ]; then env; exit 1; fi; - ./scripts/ci-checkpatches.sh ${ODP_PATCHES}; + +after_failure: + - find . -name 'test-suite.log' -execdir grep -il "FAILED" {} \; -exec echo {} \; -exec cat {} \; -- cgit v1.2.3 From 7a7e3ff9d50d67b7c79058db98ba27ab5a806437 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Wed, 31 May 2017 18:33:25 +0300 Subject: test: time: do not fail under gcov code coverage gcov make test very slow and it does not pass accepted boundaries. Test if env TEST=coverage variable is set and do no generate fail result if some boundaries are missing. https://bugs.linaro.org/show_bug.cgi?id=3017 Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- test/common_plat/validation/api/time/Makefile.am | 10 +++++- test/common_plat/validation/api/time/time.sh | 42 ++++++++++++++++++++++++ test/linux-generic/Makefile.am | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100755 test/common_plat/validation/api/time/time.sh diff --git a/test/common_plat/validation/api/time/Makefile.am b/test/common_plat/validation/api/time/Makefile.am index bf2d0268c..72e6b7b2a 100644 --- a/test/common_plat/validation/api/time/Makefile.am +++ b/test/common_plat/validation/api/time/Makefile.am @@ -1,5 +1,12 @@ include ../Makefile.inc +TESTS_ENVIRONMENT += TEST_DIR=${builddir} + +TESTSCRIPTS = time.sh +TEST_EXTENSIONS = .sh + +TESTS = $(TESTSCRIPTS) + noinst_LTLIBRARIES = libtesttime.la libtesttime_la_SOURCES = time.c @@ -7,4 +14,5 @@ test_PROGRAMS = time_main$(EXEEXT) dist_time_main_SOURCES = time_main.c time_main_LDADD = libtesttime.la $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = time.h +EXTRA_DIST = time.h $(TESTSCRIPTS) +dist_check_SCRIPTS = $(TESTSCRIPTS) diff --git a/test/common_plat/validation/api/time/time.sh b/test/common_plat/validation/api/time/time.sh new file mode 100755 index 000000000..02bf75a76 --- /dev/null +++ b/test/common_plat/validation/api/time/time.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (c) 2017, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# directories where time_main binary can be found: +# -in the validation dir when running make check (intree or out of tree) +# -in the script directory, when running after 'make install', or +# -in the validation when running standalone (./time) intree. +# -in the current directory. +# running stand alone out of tree requires setting PATH +PATH=${TEST_DIR}/api/time:$PATH +PATH=$(dirname $0)/../../../../common_plat/validation/api/time:$PATH +PATH=$(dirname $0):$PATH +PATH=`pwd`:$PATH + +time_main_path=$(which time_main${EXEEXT}) +if [ -x "$time_main_path" ] ; then + echo "running with time_main: $time_run_path" +else + echo "cannot find time_main: please set you PATH for it." + exit 1 +fi + +# exit codes expected by automake for skipped tests +TEST_SKIPPED=77 + +time_main${EXEEXT} +ret=$? + +SIGSEGV=139 + +if [ "${TRAVIS}" = "true" ] && [ $ret -ne 0 ] && + [ ${TEST} = "coverage" ] && [ $ret -ne ${SIGSEGV} ]; then + echo "SKIP: skip due significant slowdown under code coverage" + exit ${TEST_SKIPPED} +fi + +exit $ret diff --git a/test/linux-generic/Makefile.am b/test/linux-generic/Makefile.am index 38516a432..f92083d73 100644 --- a/test/linux-generic/Makefile.am +++ b/test/linux-generic/Makefile.am @@ -28,7 +28,7 @@ TESTS = validation/api/pktio/pktio_run.sh \ $(ALL_API_VALIDATION_DIR)/scheduler/scheduler_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/std_clib/std_clib_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/thread/thread_main$(EXEEXT) \ - $(ALL_API_VALIDATION_DIR)/time/time_main$(EXEEXT) \ + $(ALL_API_VALIDATION_DIR)/time/time.sh \ $(ALL_API_VALIDATION_DIR)/timer/timer_main$(EXEEXT) \ $(ALL_API_VALIDATION_DIR)/traffic_mngr/traffic_mngr.sh \ $(ALL_API_VALIDATION_DIR)/shmem/shmem_main$(EXEEXT) \ -- cgit v1.2.3 From a48979af5b36c11fb5c7f8d2c6029c12bb191b51 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 1 Jun 2017 10:18:22 +0300 Subject: scripts: checkpatch: revert code modification Checkpatch code should not be modified directly. When the code is updated to a next version, any local modifications would be lost and needed to be done again. Camelcase check is enabled again. Exceptions to camelcase are allowed e.g. when calling an external library interface. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- scripts/checkpatch.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 1c27ac60c..16316b928 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -4273,7 +4273,7 @@ sub process { $camelcase_file_seeded = 1; } } - if (!defined $camelcase{$word} && 0) { + if (!defined $camelcase{$word}) { $camelcase{$word} = 1; CHK("CAMELCASE", "Avoid CamelCase: <$word>\n" . $herecurr); @@ -4620,7 +4620,7 @@ sub process { # no volatiles please my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; - if ($line =~ /\bvolatile\b/ && 0 && $line !~ /$asm_volatile/) { + if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { WARN("VOLATILE", "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); } @@ -5134,7 +5134,7 @@ sub process { if (defined $cond) { substr($s, 0, length($cond), ''); } - if ($s =~ /^\s*;/ && 0 && + if ($s =~ /^\s*;/ && $function_name ne 'uninitialized_var') { WARN("AVOID_EXTERNS", -- cgit v1.2.3 From 15ea6562d284bd5f2bd20e9b79bd102db106555c Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 1 Jun 2017 10:18:23 +0300 Subject: scripts: checkpatch: ignore volatile and extern warnings These warnings were disabled with code modification. Use checkpatch config file to ignore those. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .checkpatch.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.checkpatch.conf b/.checkpatch.conf index 043551a4c..990a54d2d 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -8,5 +8,7 @@ --ignore=BIT_MACRO --ignore=PREFER_PRINTF --ignore=PREFER_SCANF +--ignore=VOLATILE +--ignore=AVOID_EXTERNS --codespell --codespellfile=/usr/share/codespell/dictionary.txt -- cgit v1.2.3 From e6be64e01589f1aa335ea178e8314bf35ad34847 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 1 Jun 2017 14:00:47 +0300 Subject: scripts: spelling: update to latest version Updated Linux spelling file to it's latest version. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- scripts/spelling.txt | 151 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/scripts/spelling.txt b/scripts/spelling.txt index bb8e4d0a1..eb38f49d4 100644 --- a/scripts/spelling.txt +++ b/scripts/spelling.txt @@ -16,6 +16,7 @@ absense||absence absolut||absolute absoulte||absolute acccess||access +acceess||access acceleratoin||acceleration accelleration||acceleration accesing||accessing @@ -32,19 +33,23 @@ accoring||according accout||account accquire||acquire accquired||acquired +accross||across acessable||accessible acess||access achitecture||architecture acient||ancient acitions||actions acitve||active -acknowldegement||acknowldegement +acknowldegement||acknowledgment acknowledgement||acknowledgment ackowledge||acknowledge ackowledged||acknowledged acording||according activete||activate +actived||activated +actualy||actually acumulating||accumulating +acumulator||accumulator adapater||adapter addional||additional additionaly||additionally @@ -59,16 +64,22 @@ adress||address adresses||addresses adviced||advised afecting||affecting +againt||against agaist||against albumns||albums alegorical||allegorical +algined||aligned algorith||algorithm algorithmical||algorithmically algoritm||algorithm algoritms||algorithms algorrithm||algorithm algorritm||algorithm +aligment||alignment +alignement||alignment allign||align +alligned||aligned +allocatote||allocate allocatrd||allocated allocte||allocate allpication||application @@ -83,6 +94,10 @@ alue||value ambigious||ambiguous amoung||among amout||amount +an union||a union +an user||a user +an userspace||a userspace +an one||a one analysator||analyzer ang||and anniversery||anniversary @@ -95,13 +110,16 @@ appearence||appearance applicaion||application appliction||application applictions||applications +applys||applies appplications||applications appropiate||appropriate appropriatly||appropriately approriate||appropriate approriately||appropriately +apropriate||appropriate aquainted||acquainted aquired||acquired +aquisition||acquisition arbitary||arbitrary architechture||architecture arguement||argument @@ -111,6 +129,8 @@ arne't||aren't arraival||arrival artifical||artificial artillary||artillery +asign||assign +assertation||assertion assiged||assigned assigment||assignment assigments||assignments @@ -125,6 +145,7 @@ asycronous||asynchronous asynchnous||asynchronous atomatically||automatically atomicly||atomically +atempt||attempt attachement||attachment attched||attached attemps||attempts @@ -136,6 +157,7 @@ automatize||automate automatized||automated automatizes||automates autonymous||autonomous +auxillary||auxiliary auxilliary||auxiliary avaiable||available avaible||available @@ -157,6 +179,7 @@ bakup||backup baloon||balloon baloons||balloons bandwith||bandwidth +banlance||balance batery||battery beacuse||because becasue||because @@ -178,6 +201,7 @@ cacluated||calculated caculation||calculation calender||calendar calle||called +callibration||calibration calucate||calculate calulate||calculate cancelation||cancellation @@ -187,6 +211,7 @@ capatibilities||capabilities carefuly||carefully cariage||carriage catagory||category +cehck||check challange||challenge challanges||challenges chanell||channel @@ -199,6 +224,8 @@ charactor||character charater||character charaters||characters charcter||character +chcek||check +chck||check checksuming||checksumming childern||children childs||children @@ -225,14 +252,20 @@ commited||committed commiting||committing committ||commit commoditiy||commodity +comsume||consume +comsumer||consumer +comsuming||consuming compability||compatibility compaibility||compatibility compatability||compatibility compatable||compatible compatibiliy||compatibility compatibilty||compatibility +compatiblity||compatibility +competion||completion compilant||compliant compleatly||completely +completition||completion completly||completely complient||compliant componnents||components @@ -243,9 +276,12 @@ comunication||communication conbination||combination conditionaly||conditionally conected||connected +connecetd||connected +configuartion||configuration configuratoin||configuration configuraton||configuration configuretion||configuration +configutation||configuration conider||consider conjuction||conjunction connectinos||connections @@ -262,11 +298,14 @@ continous||continuous continously||continuously continueing||continuing contraints||constraints +contol||control +contoller||controller controled||controlled controler||controller controll||control contruction||construction contry||country +conuntry||country convertion||conversion convertor||converter convienient||convenient @@ -281,6 +320,7 @@ coutner||counter cryptocraphic||cryptographic cunter||counter curently||currently +cylic||cyclic dafault||default deafult||default deamon||daemon @@ -291,8 +331,12 @@ defferred||deferred definate||definite definately||definitely defintion||definition +defintions||definitions defualt||default defult||default +deintializing||deinitializing +deintialize||deinitialize +deintialized||deinitialized deivce||device delared||declared delare||declare @@ -305,7 +349,9 @@ dependant||dependent depreacted||deprecated depreacte||deprecate desactivate||deactivate +desciptor||descriptor desciptors||descriptors +descripton||description descrition||description descritptor||descriptor desctiptor||descriptor @@ -327,14 +373,20 @@ devided||divided deviece||device diable||disable dictionnary||dictionary +didnt||didn't diferent||different differrence||difference +diffrent||different +diffrentiate||differentiate difinition||definition diplay||display direectly||directly +disassocation||disassociation disapear||disappear disapeared||disappeared disappared||disappeared +disble||disable +disbled||disabled disconnet||disconnect discontinous||discontinuous dispertion||dispersion @@ -344,6 +396,7 @@ docuentation||documentation documantation||documentation documentaion||documentation documment||document +doesnt||doesn't dorp||drop dosen||doesn downlad||download @@ -354,10 +407,13 @@ easilly||easily ecspecially||especially edditable||editable editting||editing +efective||effective efficently||efficiently ehther||ether eigth||eight +elementry||elementary eletronic||electronic +embeded||embedded enabledi||enabled enchanced||enhanced encorporating||incorporating @@ -393,6 +449,7 @@ expecially||especially explicite||explicit explicitely||explicitly explict||explicit +explictely||explicitly explictly||explicitly expresion||expression exprimental||experimental @@ -400,11 +457,15 @@ extened||extended extensability||extensibility extention||extension extracter||extractor +falied||failed faild||failed faill||fail +failied||failed +faillure||failure failue||failure failuer||failure faireness||fairness +falied||failed faliure||failure familar||familiar fatser||faster @@ -413,6 +474,7 @@ feautures||features fetaure||feature fetaures||features fileystem||filesystem +fimware||firmware finanize||finalize findn||find finilizes||finalizes @@ -420,11 +482,13 @@ finsih||finish flusing||flushing folloing||following followign||following +followings||following follwing||following forseeable||foreseeable forse||force fortan||fortran forwardig||forwarding +framming||framing framwork||framework frequncy||frequency frome||from @@ -443,6 +507,7 @@ futhermore||furthermore futrue||future gaurenteed||guaranteed generiously||generously +genereate||generate genric||generic globel||global grabing||grabbing @@ -450,11 +515,13 @@ grahical||graphical grahpical||graphical grapic||graphic guage||gauge +guarenteed||guaranteed guarentee||guarantee halfs||halves hander||handler handfull||handful hanled||handled +happend||happened harware||hardware heirarchically||hierarchically helpfull||helpful @@ -462,8 +529,11 @@ hierachy||hierarchy hierarchie||hierarchy howver||however hsould||should +hypervior||hypervisor hypter||hyper identidier||identifier +iligal||illegal +illigal||illegal imblance||imbalance immeadiately||immediately immedaite||immediate @@ -502,17 +572,21 @@ informtion||information infromation||information ingore||ignore inital||initial +initalized||initialized initalised||initialized initalise||initialize initalize||initialize initation||initiation initators||initiators +initialiazation||initialization initializiation||initialization initialzed||initialized initilization||initialization initilize||initialize inofficial||unofficial +insititute||institute instal||install +instanciated||instantiated inteface||interface integreated||integrated integrety||integrity @@ -534,19 +608,28 @@ interruptted||interrupted interupted||interrupted interupt||interrupt intial||initial +intialisation||initialisation +intialised||initialised +intialise||initialise +intialization||initialization intialized||initialized intialize||initialize intregral||integral intrrupt||interrupt +intterrupt||interrupt intuative||intuitive invaid||invalid -invalde||invald +invalde||invalid invalide||invalid +invalud||invalid invididual||individual invokation||invocation invokations||invocations irrelevent||irrelevant +isnt||isn't isssue||issue +iternations||iterations +itertation||iteration itslef||itself jave||java jeffies||jiffies @@ -558,6 +641,7 @@ langauage||language langauge||language langugage||language lauch||launch +layed||laid leightweight||lightweight lengh||length lenght||length @@ -600,16 +684,20 @@ messsage||message messsages||messages microprocesspr||microprocessor milliseonds||milliseconds +minium||minimum +minimam||minimum minumum||minimum +misalinged||misaligned miscelleneous||miscellaneous misformed||malformed mispelled||misspelled mispelt||misspelt +mising||missing miximum||maximum mmnemonic||mnemonic mnay||many -modeled||modelled modulues||modules +momery||memory monochorome||monochrome monochromo||monochrome monocrome||monochrome @@ -629,6 +717,7 @@ neccecary||necessary neccesary||necessary neccessary||necessary necesary||necessary +neded||needed negaive||negative negoitation||negotiation negotation||negotiation @@ -648,8 +737,11 @@ occurances||occurrences occured||occurred occurence||occurrence occure||occurred +occured||occurred occuring||occurring offet||offset +omited||omitted +omiting||omitting omitt||omit ommiting||omitting ommitted||omitted @@ -661,13 +753,19 @@ optionnal||optional optmizations||optimizations orientatied||orientated orientied||oriented +orignal||original otherise||otherwise ouput||output +oustanding||outstanding overaall||overall overhread||overhead overlaping||overlapping +overide||override +overrided||overridden overriden||overridden overun||overrun +overwritting||overwriting +overwriten||overwritten pacakge||package pachage||package packacge||package @@ -678,6 +776,7 @@ pakage||package pallette||palette paln||plan paramameters||parameters +paramaters||parameters paramater||parameter parametes||parameters parametised||parametrised @@ -685,6 +784,7 @@ paramter||parameter paramters||parameters particuarly||particularly particularily||particularly +partiton||partition pased||passed passin||passing pathes||paths @@ -704,6 +804,7 @@ pleaes||please ploting||plotting plugable||pluggable poinnter||pointer +pointeur||pointer poiter||pointer posible||possible positon||position @@ -714,6 +815,7 @@ preceeding||preceding preceed||precede precendence||precedence precission||precision +preemptable||preemptible prefered||preferred prefferably||preferably premption||preemption @@ -731,6 +833,7 @@ procceed||proceed proccesors||processors procesed||processed proces||process +procesing||processing processessing||processing processess||processes processpr||processor @@ -744,6 +847,7 @@ programers||programmers programm||program programms||programs progresss||progress +promiscous||promiscuous promps||prompts pronnounced||pronounced prononciation||pronunciation @@ -758,6 +862,7 @@ protable||portable protcol||protocol protecion||protection protocoll||protocol +promixity||proximity psudo||pseudo psuedo||pseudo psychadelic||psychedelic @@ -779,6 +884,7 @@ recommanded||recommended recyle||recycle redircet||redirect redirectrion||redirection +reename||rename refcounf||refcount refence||reference refered||referred @@ -791,6 +897,7 @@ registerd||registered registeresd||registered registes||registers registraration||registration +regsiter||register regster||register regualar||regular reguator||regulator @@ -808,6 +915,7 @@ replys||replies reponse||response representaion||representation reqeust||request +requestied||requested requiere||require requirment||requirement requred||required @@ -817,6 +925,7 @@ reseting||resetting resizeable||resizable resouces||resources resoures||resources +responce||response ressizes||resizes ressource||resource ressources||resources @@ -869,6 +978,7 @@ setts||sets settting||setting shotdown||shutdown shoud||should +shouldnt||shouldn't shoule||should shrinked||shrunk siginificantly||significantly @@ -899,6 +1009,7 @@ spinlcok||spinlock spinock||spinlock splitted||split spreaded||spread +spurrious||spurious sructure||structure stablilization||stabilization staically||statically @@ -913,12 +1024,17 @@ straming||streaming struc||struct structres||structures stuct||struct +strucuture||structure +stucture||structure sturcture||structure subdirectoires||subdirectories suble||subtle +substract||subtract succesfully||successfully succesful||successful +successed||succeeded successfull||successful +successfuly||successfully sucessfully||successfully sucess||success superflous||superfluous @@ -926,6 +1042,7 @@ superseeded||superseded suplied||supplied suported||supported suport||support +supportet||supported suppored||supported supportin||supporting suppoted||supported @@ -934,13 +1051,22 @@ suppport||support supress||suppress surpresses||suppresses susbsystem||subsystem +suspeneded||suspended suspicously||suspiciously swaping||swapping switchs||switches +swith||switch +swithable||switchable +swithc||switch +swithced||switched +swithcing||switching +swithed||switched +swithing||switching symetric||symmetric synax||syntax synchonized||synchronized syncronize||synchronize +syncronized||synchronized syncronizing||synchronizing syncronus||synchronous syste||system @@ -952,6 +1078,7 @@ targetting||targeting teh||the temorary||temporary temproarily||temporarily +therfore||therefore thier||their threds||threads threshhold||threshold @@ -959,13 +1086,14 @@ throught||through thses||these tiggered||triggered tipically||typically +timout||timeout tmis||this torerable||tolerable tramsmitted||transmitted tramsmit||transmit tranfer||transfer transciever||transceiver -transferd||transferrd +transferd||transferred transfered||transferred transfering||transferring transision||transition @@ -979,21 +1107,33 @@ ture||true tyep||type udpate||update uesd||used +uncommited||uncommitted unconditionaly||unconditionally underun||underrun unecessary||unnecessary unexecpted||unexpected +unexepected||unexpected +unexpcted||unexpected unexpectd||unexpected unexpeted||unexpected +unexpexted||unexpected unfortunatelly||unfortunately unifiy||unify +unintialized||uninitialized +unkmown||unknown unknonw||unknown unknow||unknown unkown||unknown +unneded||unneeded unneedingly||unnecessarily +unnsupported||unsupported +unmached||unmatched +unregester||unregister unresgister||unregister +unrgesiter||unregister unsinged||unsigned unstabel||unstable +unsolicitied||unsolicited unsuccessfull||unsuccessful unsuported||unsupported untill||until @@ -1014,6 +1154,7 @@ vaid||valid vaild||valid valide||valid variantions||variations +varible||variable varient||variant vaule||value verbse||verbose @@ -1027,7 +1168,9 @@ virtiual||virtual visiters||visitors vitual||virtual wating||waiting +wether||whether whataver||whatever +whcih||which whenver||whenever wheter||whether whe||when -- cgit v1.2.3 From 8d19f94fd96eb5a411eafb75c487dc3f972297bd Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Thu, 8 Jun 2017 15:42:05 -0500 Subject: build: GCC 7 fixes The GCC 7 series introduces changes that expose ODP compilation issues. These include case statement fall through warnings, and stricter checks on potential string overflows and other semantic analysis. Fixes: https://bugs.linaro.org/show_bug.cgi?id=3027 Signed-off-by: Brian Brooks Reviewed-by: Ola Liljedahl Reviewed-by: Honnappa Nagarahalli Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- DEPENDENCIES | 5 ++-- configure.ac | 13 ++++++++++ pkgconfig/libodp-linux.pc.in | 2 +- platform/linux-generic/Makefile.am | 2 ++ platform/linux-generic/m4/configure.m4 | 45 ++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index a194cad1c..7bcbd5ebc 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -8,13 +8,14 @@ Prerequisites for building the OpenDataPlane (ODP) API automake autoconf + autoconf-archive libtool On Debian/Ubuntu systems: - $ sudo apt-get install automake autoconf libtool + $ sudo apt-get install automake autoconf autoconf-archive libtool On CentOS/RedHat/Fedora systems: - $ sudo yum install automake autoconf libtool + $ sudo yum install automake autoconf autoconf-archive libtool 3. Required libraries diff --git a/configure.ac b/configure.ac index 7569ebe07..6351878ab 100644 --- a/configure.ac +++ b/configure.ac @@ -300,6 +300,19 @@ ODP_CFLAGS="$ODP_CFLAGS -Wmissing-declarations -Wold-style-definition -Wpointer- ODP_CFLAGS="$ODP_CFLAGS -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral" ODP_CFLAGS="$ODP_CFLAGS -Wformat-security -Wundef -Wwrite-strings" ODP_CFLAGS="$ODP_CFLAGS -std=c99" + +dnl Use -Werror in the checks below since Clang emits a warning instead of +dnl an error when it encounters an unknown warning option. +AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=0], + [ODP_CFLAGS="$ODP_CFLAGS -Wimplicit-fallthrough=0"], + [], [-Werror]) +AX_CHECK_COMPILE_FLAG([-Wformat-truncation=0], + [ODP_CFLAGS="$ODP_CFLAGS -Wformat-truncation=0"], + [], [-Werror]) +AX_CHECK_COMPILE_FLAG([-Wformat-overflow=0], + [ODP_CFLAGS="$ODP_CFLAGS -Wformat-overflow=0"], + [], [-Werror]) + # Extra flags for example to suppress certain warning types ODP_CFLAGS="$ODP_CFLAGS $ODP_CFLAGS_EXTRA" diff --git a/pkgconfig/libodp-linux.pc.in b/pkgconfig/libodp-linux.pc.in index 0769b2145..61770175a 100644 --- a/pkgconfig/libodp-linux.pc.in +++ b/pkgconfig/libodp-linux.pc.in @@ -7,5 +7,5 @@ Name: libodp-linux Description: The ODP packet processing engine Version: @PKGCONFIG_VERSION@ Libs: -L${libdir} -lodp-linux -Libs.private: +Libs.private: @ATOMIC_LIBS@ Cflags: -I${includedir} diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 69fdf8b91..00ce80d74 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -219,6 +219,8 @@ __LIB__libodp_linux_la_SOURCES = \ arch/@ARCH_DIR@/odp_cpu_arch.c \ arch/@ARCH_DIR@/odp_sysinfo_parse.c +__LIB__libodp_linux_la_LIBADD = $(ATOMIC_LIBS) + if HAVE_PCAP __LIB__libodp_linux_la_SOURCES += pktio/pcap.c endif diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index a2a25408d..6a429f1d6 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -28,6 +28,51 @@ AC_LINK_IFELSE( echo "Use newer version. For gcc > 4.7.0" exit -1) +dnl Check whether -latomic is needed +use_libatomic=no + +AC_MSG_CHECKING(whether -latomic is needed for 64-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static int loc; + int main(void) + { + int prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_8], + [use_libatomic=yes], + [AC_MSG_FAILURE([__atomic_exchange_8 is not available])]) + ]) + +AC_MSG_CHECKING(whether -latomic is needed for 128-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static __int128 loc; + int main(void) + { + __int128 prev; + prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_16], + [use_libatomic=yes], + [AC_MSG_FAILURE([cannot detect support for 128-bit atomics])]) + ]) + +if test "x$use_libatomic" = "xyes"; then + ATOMIC_LIBS="-latomic" +fi +AC_SUBST([ATOMIC_LIBS]) + m4_include([platform/linux-generic/m4/odp_pthread.m4]) m4_include([platform/linux-generic/m4/odp_openssl.m4]) m4_include([platform/linux-generic/m4/odp_pcap.m4]) -- cgit v1.2.3 From 61a5edca59780fc2a4a0e656e09738145892a3a0 Mon Sep 17 00:00:00 2001 From: Brian Brooks Date: Thu, 8 Jun 2017 15:42:06 -0500 Subject: pktio: GCC 7 fixes The GCC 7 series introduces changes that expose ODP compilation issues. These include case statement fall through warnings, and stricter checks on potential string overflows and other semantic analysis. Fixes: https://bugs.linaro.org/show_bug.cgi?id=3027 Signed-off-by: Brian Brooks Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/pktio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 11fe974fe..4d8d2cc75 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -1429,7 +1429,9 @@ int pktio_check_statistics_counters(void) void pktio_test_statistics_counters(void) { odp_pktio_t pktio_rx, pktio_tx; - odp_pktio_t pktio[MAX_NUM_IFACES]; + odp_pktio_t pktio[MAX_NUM_IFACES] = { + ODP_PKTIO_INVALID, ODP_PKTIO_INVALID + }; odp_packet_t pkt; odp_packet_t tx_pkt[1000]; uint32_t pkt_seq[1000]; -- cgit v1.2.3 From 7cf390d11e69f6b677e6fbfd6414944737406fc3 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 13 Jun 2017 18:09:45 +0300 Subject: travis: add dependency of autoconf-archive autoconf-archive dependency was added with gcc 7 req. This also need to be in .travis. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer Reviewed-by: Brian Brooks --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7ad2a743..669695d89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ addons: packages: - gcc - clang-3.8 - - automake autoconf libtool libssl-dev graphviz mscgen doxygen + - automake autoconf autoconf-archive libtool libssl-dev graphviz mscgen doxygen - libpcap-dev # coverity_scan: # project: -- cgit v1.2.3 From 373f97f88d327ca0e211df33d6fcaad0b9188a1c Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 13 Jun 2017 13:05:37 +0300 Subject: linux-gen: socket: remove limits for maximum RX/TX burst size Remove unnecessary limits for maximum RX/TX burst size. Fixes: https://bugs.linaro.org/show_bug.cgi?id=3039 Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp_packet_socket.h | 7 ----- platform/linux-generic/pktio/socket.c | 36 ++++------------------ 2 files changed, 6 insertions(+), 37 deletions(-) diff --git a/platform/linux-generic/include/odp_packet_socket.h b/platform/linux-generic/include/odp_packet_socket.h index dbfc9f1f8..0e61f6f0c 100644 --- a/platform/linux-generic/include/odp_packet_socket.h +++ b/platform/linux-generic/include/odp_packet_socket.h @@ -27,11 +27,6 @@ * Packet socket config: */ -/** Max receive (Rx) burst size*/ -#define ODP_PACKET_SOCKET_MAX_BURST_RX 32 -/** Max transmit (Tx) burst size*/ -#define ODP_PACKET_SOCKET_MAX_BURST_TX 32 - /* * This makes sure that building for kernels older than 3.1 works * and a fanout requests fails (for invalid packet socket option) @@ -47,8 +42,6 @@ typedef struct { odp_pool_t pool; /**< pool to alloc packets from */ uint32_t mtu; /**< maximum transmission unit */ unsigned char if_mac[ETH_ALEN]; /**< IF eth mac addr */ - uint8_t *cache_ptr[ODP_PACKET_SOCKET_MAX_BURST_RX]; - odp_shm_t shm; } pkt_sock_t; /** packet mmap ring */ diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index a08b0104a..c4d786037 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -462,8 +462,6 @@ static int sock_close(pktio_entry_t *pktio_entry) return -1; } - odp_shm_free(pkt_sock->shm); - return 0; } @@ -475,13 +473,11 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev, { int sockfd; int err; - int i; unsigned int if_idx; struct ifreq ethreq; struct sockaddr_ll sa_ll; char shm_name[ODP_SHM_NAME_LEN]; pkt_sock_t *pkt_sock = &pktio_entry->s.pkt_sock; - uint8_t *addr; odp_pktio_stats_t cur_stats; /* Init pktio entry */ @@ -495,18 +491,6 @@ static int sock_setup_pkt(pktio_entry_t *pktio_entry, const char *netdev, snprintf(shm_name, ODP_SHM_NAME_LEN, "%s-%s", "pktio", netdev); shm_name[ODP_SHM_NAME_LEN - 1] = '\0'; - pkt_sock->shm = odp_shm_reserve(shm_name, PACKET_JUMBO_LEN, - PACKET_JUMBO_LEN * - ODP_PACKET_SOCKET_MAX_BURST_RX, 0); - if (pkt_sock->shm == ODP_SHM_INVALID) - return -1; - - addr = odp_shm_addr(pkt_sock->shm); - for (i = 0; i < ODP_PACKET_SOCKET_MAX_BURST_RX; i++) { - pkt_sock->cache_ptr[i] = addr; - addr += PACKET_JUMBO_LEN; - } - sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sockfd == -1) { __odp_errno = errno; @@ -622,15 +606,11 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, odp_time_t *ts = NULL; const int sockfd = pkt_sock->sockfd; int msgvec_len; - struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_RX]; + struct mmsghdr msgvec[len]; int nb_rx = 0; int recv_msgs; - uint8_t **recv_cache; int i; - if (odp_unlikely(len > ODP_PACKET_SOCKET_MAX_BURST_RX)) - return -1; - odp_ticketlock_lock(&pktio_entry->s.rxl); if (pktio_entry->s.config.pktin.bit.ts_all || @@ -638,10 +618,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, ts = &ts_val; memset(msgvec, 0, sizeof(msgvec)); - recv_cache = pkt_sock->cache_ptr; if (pktio_cls_enabled(pktio_entry)) { - struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_RX]; + struct iovec iovecs[len]; + uint8_t recv_cache[len][PACKET_JUMBO_LEN]; for (i = 0; i < (int)len; i++) { msgvec[i].msg_hdr.msg_iovlen = 1; @@ -694,8 +674,7 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, pkt_table[nb_rx++] = pkt; } } else { - struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_RX] - [MAX_SEGS]; + struct iovec iovecs[len][MAX_SEGS]; for (i = 0; i < (int)len; i++) { int num; @@ -794,15 +773,12 @@ static int sock_mmsg_send(pktio_entry_t *pktio_entry, int index ODP_UNUSED, const odp_packet_t pkt_table[], int len) { pkt_sock_t *pkt_sock = &pktio_entry->s.pkt_sock; - struct mmsghdr msgvec[ODP_PACKET_SOCKET_MAX_BURST_TX]; - struct iovec iovecs[ODP_PACKET_SOCKET_MAX_BURST_TX][MAX_SEGS]; + struct mmsghdr msgvec[len]; + struct iovec iovecs[len][MAX_SEGS]; int ret; int sockfd; int n, i; - if (odp_unlikely(len > ODP_PACKET_SOCKET_MAX_BURST_TX)) - return -1; - odp_ticketlock_lock(&pktio_entry->s.txl); sockfd = pkt_sock->sockfd; -- cgit v1.2.3 From 248ebf35eaf51d962e9d14a4e2c541d3cbc96268 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 13 Jun 2017 13:05:38 +0300 Subject: linux-gen: socket: streamline sock_mmsg_recv() function Use the same main code path when operating with or without classifier. Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/pktio/socket.c | 154 +++++++++++----------------------- 1 file changed, 48 insertions(+), 106 deletions(-) diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index c4d786037..2e94a3882 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -602,12 +602,14 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, odp_packet_t pkt_table[], int len) { pkt_sock_t *pkt_sock = &pktio_entry->s.pkt_sock; + odp_pool_t pool = pkt_sock->pool; odp_time_t ts_val; odp_time_t *ts = NULL; const int sockfd = pkt_sock->sockfd; - int msgvec_len; struct mmsghdr msgvec[len]; + struct iovec iovecs[len][MAX_SEGS]; int nb_rx = 0; + int nb_pkts; int recv_msgs; int i; @@ -619,129 +621,69 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, memset(msgvec, 0, sizeof(msgvec)); - if (pktio_cls_enabled(pktio_entry)) { - struct iovec iovecs[len]; - uint8_t recv_cache[len][PACKET_JUMBO_LEN]; + nb_pkts = packet_alloc_multi(pool, pkt_sock->mtu, pkt_table, len); + for (i = 0; i < nb_pkts; i++) { + msgvec[i].msg_hdr.msg_iovlen = + _rx_pkt_to_iovec(pkt_table[i], iovecs[i]); + msgvec[i].msg_hdr.msg_iov = iovecs[i]; + } - for (i = 0; i < (int)len; i++) { - msgvec[i].msg_hdr.msg_iovlen = 1; - iovecs[i].iov_base = recv_cache[i]; - iovecs[i].iov_len = PACKET_JUMBO_LEN; - msgvec[i].msg_hdr.msg_iov = &iovecs[i]; - } - msgvec_len = i; - - recv_msgs = recvmmsg(sockfd, msgvec, msgvec_len, - MSG_DONTWAIT, NULL); - - if (ts != NULL) - ts_val = odp_time_global(); - - for (i = 0; i < recv_msgs; i++) { - odp_packet_hdr_t *pkt_hdr; - odp_packet_t pkt; - odp_pool_t pool = pkt_sock->pool; - odp_packet_hdr_t parsed_hdr; - void *base = msgvec[i].msg_hdr.msg_iov->iov_base; - struct ethhdr *eth_hdr = base; - uint16_t pkt_len = msgvec[i].msg_len; - int num; - - /* Don't receive packets sent by ourselves */ - if (odp_unlikely(ethaddrs_equal(pkt_sock->if_mac, - eth_hdr->h_source))) - continue; + recv_msgs = recvmmsg(sockfd, msgvec, nb_pkts, MSG_DONTWAIT, NULL); - if (cls_classify_packet(pktio_entry, base, pkt_len, - pkt_len, &pool, &parsed_hdr)) - continue; + if (ts != NULL) + ts_val = odp_time_global(); - num = packet_alloc_multi(pool, pkt_len, &pkt, 1); - if (num != 1) - continue; + for (i = 0; i < recv_msgs; i++) { + void *base = msgvec[i].msg_hdr.msg_iov->iov_base; + struct ethhdr *eth_hdr = base; + odp_packet_t pkt = pkt_table[i]; + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); + uint16_t pkt_len = msgvec[i].msg_len; + int ret; - pkt_hdr = odp_packet_hdr(pkt); + if (pktio_cls_enabled(pktio_entry)) { + uint16_t seg_len = pkt_len; - if (odp_packet_copy_from_mem(pkt, 0, pkt_len, - base) != 0) { + if (msgvec[i].msg_hdr.msg_iov->iov_len < pkt_len) + seg_len = msgvec[i].msg_hdr.msg_iov->iov_len; + + if (cls_classify_packet(pktio_entry, base, pkt_len, + seg_len, &pool, pkt_hdr)) { + ODP_ERR("cls_classify_packet failed"); odp_packet_free(pkt); continue; } - pkt_hdr->input = pktio_entry->s.handle; - copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); - packet_set_ts(pkt_hdr, ts); - - pkt_table[nb_rx++] = pkt; } - } else { - struct iovec iovecs[len][MAX_SEGS]; - - for (i = 0; i < (int)len; i++) { - int num; - - num = packet_alloc_multi(pkt_sock->pool, pkt_sock->mtu, - &pkt_table[i], 1); - - if (odp_unlikely(num != 1)) { - pkt_table[i] = ODP_PACKET_INVALID; - break; - } - msgvec[i].msg_hdr.msg_iovlen = - _rx_pkt_to_iovec(pkt_table[i], iovecs[i]); - - msgvec[i].msg_hdr.msg_iov = iovecs[i]; + /* Don't receive packets sent by ourselves */ + if (odp_unlikely(ethaddrs_equal(pkt_sock->if_mac, + eth_hdr->h_source))) { + odp_packet_free(pkt); + continue; } - /* number of successfully allocated pkt buffers */ - msgvec_len = i; - - recv_msgs = recvmmsg(sockfd, msgvec, msgvec_len, - MSG_DONTWAIT, NULL); - - if (ts != NULL) - ts_val = odp_time_global(); - - for (i = 0; i < recv_msgs; i++) { - void *base = msgvec[i].msg_hdr.msg_iov->iov_base; - struct ethhdr *eth_hdr = base; - odp_packet_hdr_t *pkt_hdr; - odp_packet_t pkt; - int ret; - - pkt = pkt_table[i]; - - /* Don't receive packets sent by ourselves */ - if (odp_unlikely(ethaddrs_equal(pkt_sock->if_mac, - eth_hdr->h_source))) { - odp_packet_free(pkt); - continue; - } + ret = odp_packet_trunc_tail(&pkt, odp_packet_len(pkt) - pkt_len, + NULL, NULL); + if (ret < 0) { + ODP_ERR("trunk_tail failed"); + odp_packet_free(pkt); + continue; + } - /* Parse and set packet header data */ - ret = odp_packet_trunc_tail(&pkt, odp_packet_len(pkt) - - msgvec[i].msg_len, - NULL, NULL); - if (ret < 0) { - ODP_ERR("trunk_tail failed"); - odp_packet_free(pkt); - continue; - } + pkt_hdr->input = pktio_entry->s.handle; - pkt_hdr = odp_packet_hdr(pkt); - packet_parse_l2(&pkt_hdr->p, pkt_hdr->frame_len); - packet_set_ts(pkt_hdr, ts); - pkt_hdr->input = pktio_entry->s.handle; + if (!pktio_cls_enabled(pktio_entry)) + packet_parse_l2(&pkt_hdr->p, pkt_len); - pkt_table[nb_rx] = pkt; - nb_rx++; - } + packet_set_ts(pkt_hdr, ts); - /* Free unused pkt buffers */ - for (; i < msgvec_len; i++) - odp_packet_free(pkt_table[i]); + pkt_table[nb_rx++] = pkt; } + /* Free unused pkt buffers */ + for (; i < nb_pkts; i++) + odp_packet_free(pkt_table[i]); + odp_ticketlock_unlock(&pktio_entry->s.rxl); return nb_rx; -- cgit v1.2.3 From aadd1d62084191bf2fb909a7dbedee628b197929 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 15 Jun 2017 18:56:06 +0300 Subject: configure.ac: do not trap if libatomic is not found Idea if check was to detect if libatomic is needed or not, not trap configure on not case Fixes Linaro CI compilation for: gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabih Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- platform/linux-generic/m4/configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4 index 6a429f1d6..e1197f606 100644 --- a/platform/linux-generic/m4/configure.m4 +++ b/platform/linux-generic/m4/configure.m4 @@ -65,7 +65,7 @@ AC_LINK_IFELSE( AC_CHECK_LIB( [atomic], [__atomic_exchange_16], [use_libatomic=yes], - [AC_MSG_FAILURE([cannot detect support for 128-bit atomics])]) + [AC_MSG_CHECKING([cannot detect support for 128-bit atomics])]) ]) if test "x$use_libatomic" = "xyes"; then -- cgit v1.2.3 From b8de7dfbadb10da65a0a675db5f588cc3998508a Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 09:25:20 -0500 Subject: api: classification: add additional doxygen documentation Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher. Signed-off-by: Bill Fischofer Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- include/odp/api/spec/classification.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/odp/api/spec/classification.h b/include/odp/api/spec/classification.h index 0e1addd6e..39831b240 100644 --- a/include/odp/api/spec/classification.h +++ b/include/odp/api/spec/classification.h @@ -366,7 +366,9 @@ typedef struct odp_pmr_param_t { /** True if the value is range and false if match */ odp_bool_t range_term; + /** Variant mappings for types of matches */ union { + /** Parameters for single-valued matches */ struct { /** Value to be matched */ const void *value; @@ -374,6 +376,8 @@ typedef struct odp_pmr_param_t { /** Masked set of bits to be matched */ const void *mask; } match; + + /** Parameter for range value matches */ struct { /** Start and End values are included in the range */ /** start value of range */ -- cgit v1.2.3 From 658f6f27ed62c651d8555a4de0ef103191c491b1 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Feb 2017 17:08:23 +0200 Subject: api: crypto: add sha-1 and sha-512 enumerations Added enumerations for HMAC-SHA-1 and HMAC-SHA-256 authentication algorithms. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 9855bf989..d30f050f8 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -102,12 +102,24 @@ typedef enum { */ ODP_AUTH_ALG_MD5_HMAC, + /** HMAC-SHA-1 + * + * SHA-1 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA1_HMAC, + /** HMAC-SHA-256 * * SHA-256 algorithm in HMAC mode */ ODP_AUTH_ALG_SHA256_HMAC, + /** HMAC-SHA-512 + * + * SHA-512 algorithm in HMAC mode + */ + ODP_AUTH_ALG_SHA512_HMAC, + /** AES in Galois/Counter Mode * * @note Must be paired with cipher ODP_CIPHER_ALG_AES_GCM @@ -171,9 +183,15 @@ typedef union odp_crypto_auth_algos_t { /** ODP_AUTH_ALG_MD5_HMAC */ uint32_t md5_hmac : 1; + /** ODP_AUTH_ALG_SHA1_HMAC */ + uint32_t sha1_hmac : 1; + /** ODP_AUTH_ALG_SHA256_HMAC */ uint32_t sha256_hmac : 1; + /** ODP_AUTH_ALG_SHA512_HMAC */ + uint32_t sha512_hmac : 1; + /** ODP_AUTH_ALG_AES_GCM */ uint32_t aes_gcm : 1; -- cgit v1.2.3 From 0ee227d51cdb1cc29853dac0376e6e02b6e585de Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Feb 2017 17:08:24 +0200 Subject: linux-gen: crypto: sha-1 and sha-512 not implemented yet Explicitly set capabilities to zero. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index c5473d959..de67ad363 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -561,7 +561,9 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.null = 1; capa->auths.bit.md5_hmac = 1; + capa->auths.bit.sha1_hmac = 0; capa->auths.bit.sha256_hmac = 1; + capa->auths.bit.sha512_hmac = 0; capa->auths.bit.aes_gcm = 1; /* Deprecated */ -- cgit v1.2.3 From 8184de8ef8492a739d30c354628aada2e2bab366 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 30 Mar 2017 16:58:56 +0300 Subject: api: crypto: enforce deprecated API status Used ODP_DEPRECATE() to control if deprecated API definitions are visible in the API or not. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 29 ++++++++++++++---------- platform/linux-generic/odp_crypto.c | 45 +++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index d30f050f8..181c0cc46 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -15,6 +15,8 @@ #define ODP_API_CRYPTO_H_ #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -82,10 +84,10 @@ typedef enum { ODP_CIPHER_ALG_AES_GCM, /** @deprecated Use ODP_CIPHER_ALG_AES_CBC instead */ - ODP_CIPHER_ALG_AES128_CBC, + ODP_DEPRECATE(ODP_CIPHER_ALG_AES128_CBC), /** @deprecated Use ODP_CIPHER_ALG_AES_GCM instead */ - ODP_CIPHER_ALG_AES128_GCM + ODP_DEPRECATE(ODP_CIPHER_ALG_AES128_GCM) } odp_cipher_alg_t; @@ -127,13 +129,14 @@ typedef enum { ODP_AUTH_ALG_AES_GCM, /** @deprecated Use ODP_AUTH_ALG_MD5_HMAC instead */ - ODP_AUTH_ALG_MD5_96, + ODP_DEPRECATE(ODP_AUTH_ALG_MD5_96), /** @deprecated Use ODP_AUTH_ALG_SHA256_HMAC instead */ - ODP_AUTH_ALG_SHA256_128, + ODP_DEPRECATE(ODP_AUTH_ALG_SHA256_128), /** @deprecated Use ODP_AUTH_ALG_AES_GCM instead */ - ODP_AUTH_ALG_AES128_GCM + ODP_DEPRECATE(ODP_AUTH_ALG_AES128_GCM) + } odp_auth_alg_t; /** @@ -158,10 +161,11 @@ typedef union odp_crypto_cipher_algos_t { uint32_t aes_gcm : 1; /** @deprecated Use aes_cbc instead */ - uint32_t aes128_cbc : 1; + uint32_t ODP_DEPRECATE(aes128_cbc) : 1; /** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; + uint32_t ODP_DEPRECATE(aes128_gcm) : 1; + } bit; /** All bits of the bit field structure @@ -196,13 +200,14 @@ typedef union odp_crypto_auth_algos_t { uint32_t aes_gcm : 1; /** @deprecated Use md5_hmac instead */ - uint32_t md5_96 : 1; + uint32_t ODP_DEPRECATE(md5_96) : 1; /** @deprecated Use sha256_hmac instead */ - uint32_t sha256_128 : 1; + uint32_t ODP_DEPRECATE(sha256_128) : 1; /** @deprecated Use aes_gcm instead */ - uint32_t aes128_gcm : 1; + uint32_t ODP_DEPRECATE(aes128_gcm) : 1; + } bit; /** All bits of the bit field structure @@ -317,7 +322,7 @@ typedef struct odp_crypto_session_param_t { } odp_crypto_session_param_t; /** @deprecated Use odp_crypto_session_param_t instead */ -typedef odp_crypto_session_param_t odp_crypto_session_params_t; +typedef odp_crypto_session_param_t ODP_DEPRECATE(odp_crypto_session_params_t); /** * Crypto API per packet operation parameters @@ -373,7 +378,7 @@ typedef struct odp_crypto_op_param_t { } odp_crypto_op_param_t; /** @deprecated Use odp_crypto_op_param_t instead */ -typedef odp_crypto_op_param_t odp_crypto_op_params_t; +typedef odp_crypto_op_param_t ODP_DEPRECATE(odp_crypto_op_params_t); /** * Crypto API session creation return code diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index de67ad363..dfeb9f3f2 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -566,12 +566,13 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.sha512_hmac = 0; capa->auths.bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API capa->ciphers.bit.aes128_cbc = 1; capa->ciphers.bit.aes128_gcm = 1; capa->auths.bit.md5_96 = 1; capa->auths.bit.sha256_128 = 1; capa->auths.bit.aes128_gcm = 1; +#endif capa->max_sessions = MAX_SESSIONS; @@ -662,6 +663,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, { int rc; odp_crypto_generic_session_t *session; + int aes_gcm = 0; /* Default to successful result */ *status = ODP_CRYPTO_SES_CREATE_ERR_NONE; @@ -705,17 +707,21 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, rc = process_des_param(session); break; case ODP_CIPHER_ALG_AES_CBC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_CBC: +#endif rc = process_aes_param(session); break; - case ODP_CIPHER_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_GCM: + if (param->auth_alg == ODP_AUTH_ALG_AES128_GCM) + aes_gcm = 1; + /* Fallthrough */ +#endif + case ODP_CIPHER_ALG_AES_GCM: /* AES-GCM requires to do both auth and * cipher at the same time */ - if (param->auth_alg == ODP_AUTH_ALG_AES_GCM || - param->auth_alg == ODP_AUTH_ALG_AES128_GCM) + if (param->auth_alg == ODP_AUTH_ALG_AES_GCM || aes_gcm) rc = process_aes_gcm_param(session); else rc = -1; @@ -731,6 +737,8 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, return -1; } + aes_gcm = 0; + /* Process based on auth */ switch (param->auth_alg) { case ODP_AUTH_ALG_NULL: @@ -738,22 +746,27 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, rc = 0; break; case ODP_AUTH_ALG_MD5_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_MD5_96: +#endif rc = process_auth_param(session, 96, 16, EVP_md5()); break; case ODP_AUTH_ALG_SHA256_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: +#endif rc = process_auth_param(session, 128, 32, EVP_sha256()); break; - case ODP_AUTH_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: + if (param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) + aes_gcm = 1; + /* Fallthrough */ +#endif + case ODP_AUTH_ALG_AES_GCM: /* AES-GCM requires to do both auth and * cipher at the same time */ - if (param->cipher_alg == ODP_CIPHER_ALG_AES_GCM || - param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) { + if (param->cipher_alg == ODP_CIPHER_ALG_AES_GCM || aes_gcm) { session->auth.func = null_crypto_routine; rc = 0; } else { @@ -779,10 +792,14 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, int odp_crypto_session_destroy(odp_crypto_session_t session) { odp_crypto_generic_session_t *generic; + int aes_gcm = 0; generic = (odp_crypto_generic_session_t *)(intptr_t)session; - if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM || - generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM) +#if ODP_DEPRECATED_API + if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM) + aes_gcm = 1; +#endif + if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM || aes_gcm) EVP_CIPHER_CTX_free(generic->cipher.data.aes_gcm.ctx); memset(generic, 0, sizeof(*generic)); free_session(generic); -- cgit v1.2.3 From e6e666d533615de703993836b958514208de942a Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 4 May 2017 15:55:56 +0300 Subject: api: crypto: add digest length session parameter Authentication capabilities list supported digest lengths per algorithm, but application did not have means to select which length is used. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 181c0cc46..769772049 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -299,10 +299,16 @@ typedef struct odp_crypto_session_param_t { /** Authentication key * - * Use odp_crypto_auth_capa() for supported digest and key lengths. + * Use odp_crypto_auth_capa() for supported key lengths. */ odp_crypto_key_t auth_key; + /** Authentication digest length in bytes + * + * Use odp_crypto_auth_capa() for supported digest lengths. + */ + uint32_t auth_digest_len; + /** Async mode completion event queue * * When odp_crypto_operation() is asynchronous, the completion queue is -- cgit v1.2.3 From e149fb058c6ea718e22c77c6fc930141004dcba2 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 4 May 2017 15:55:57 +0300 Subject: api: crypto: add AAD operation parameters Authentication capabilities list supported AAD lengths per algorithm, but application did not have means to select which length is used. Also pointer to AAD is added, since it may be constructed also outside of packet data. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 769772049..1f83e819e 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -375,6 +375,16 @@ typedef struct odp_crypto_op_param_t { */ uint32_t hash_result_offset; + /** Additional Authenticated Data (AAD) */ + struct { + /** Pointer to ADD */ + uint8_t *ptr; + + /** AAD length in bytes. Use odp_crypto_auth_capa() for + * supported AAD lengths. */ + uint32_t length; + } aad; + /** Data range to apply cipher */ odp_crypto_data_range_t cipher_range; -- cgit v1.2.3 From 166e4e6a7f2e289f305203e75c68cea56d015c08 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 4 May 2017 14:30:50 +0300 Subject: api: packet: introduce odp_packet_data_range_t Rename odp_crypto_data_range_t to odp_packet_data_range_t, as it is relevant not only to the crypto interface. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 17 +++++++---------- include/odp/api/spec/packet.h | 12 ++++++++++++ .../validation/api/crypto/odp_crypto_test_inp.c | 4 ++-- test/common_plat/validation/api/crypto/test_vectors.h | 4 ++-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index 1f83e819e..c47d31492 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -21,6 +21,8 @@ extern "C" { #endif +#include + /** @defgroup odp_crypto ODP CRYPTO * Macros, enums, types and operations to utilise crypto. * @{ @@ -243,15 +245,10 @@ typedef struct odp_crypto_iv { /** * Crypto API data range specifier + * + * @deprecated Use odp_packet_data_range_t instead */ -typedef struct odp_crypto_data_range { - /** Offset from beginning of packet */ - uint32_t offset; - - /** Length of data to operate on */ - uint32_t length; - -} odp_crypto_data_range_t; +typedef odp_packet_data_range_t ODP_DEPRECATE(odp_crypto_data_range_t); /** * Crypto API session creation parameters @@ -386,10 +383,10 @@ typedef struct odp_crypto_op_param_t { } aad; /** Data range to apply cipher */ - odp_crypto_data_range_t cipher_range; + odp_packet_data_range_t cipher_range; /** Data range to authenticate */ - odp_crypto_data_range_t auth_range; + odp_packet_data_range_t auth_range; } odp_crypto_op_param_t; diff --git a/include/odp/api/spec/packet.h b/include/odp/api/spec/packet.h index 92c35ae6d..79d8773e9 100644 --- a/include/odp/api/spec/packet.h +++ b/include/odp/api/spec/packet.h @@ -71,6 +71,18 @@ extern "C" { * Packet is red */ +/** + * Packet API data range specifier + */ +typedef struct odp_packet_data_range { + /** Offset from beginning of packet */ + uint32_t offset; + + /** Length of data to operate on */ + uint32_t length; + +} odp_packet_data_range_t; + /* * * Alloc and free diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index a415f5c1c..57e7c0e05 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -72,8 +72,8 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_key_t cipher_key, odp_auth_alg_t auth_alg, odp_crypto_key_t auth_key, - odp_crypto_data_range_t *cipher_range, - odp_crypto_data_range_t *auth_range, + odp_packet_data_range_t *cipher_range, + odp_packet_data_range_t *auth_range, const uint8_t *plaintext, unsigned int plaintext_len, const uint8_t *ciphertext, diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index da4610f33..a1cf4faf3 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -139,14 +139,14 @@ static uint8_t aes128_gcm_reference_iv[][AES128_GCM_IV_LEN] = { static uint32_t aes128_gcm_reference_length[] = { 84, 72, 72, 40}; -static odp_crypto_data_range_t aes128_gcm_cipher_range[] = { +static odp_packet_data_range_t aes128_gcm_cipher_range[] = { { .offset = 12, .length = 72 }, { .offset = 8, .length = 64 }, { .offset = 8, .length = 64 }, { .offset = 12, .length = 28 }, }; -static odp_crypto_data_range_t aes128_gcm_auth_range[] = { +static odp_packet_data_range_t aes128_gcm_auth_range[] = { { .offset = 0, .length = 84 }, { .offset = 0, .length = 72 }, { .offset = 0, .length = 72 }, -- cgit v1.2.3 From 2b34cda253fd28f3b373dc3ee66753d47a0c9b33 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 30 Mar 2017 16:58:54 +0300 Subject: api: deprecated: add configure option and macros Added configuration option --enable-deprecated to control if deprecated APIs are enabled or disabled. Added ODP_DEPRECATED_API macro into the API. Its value can be used to check if deprecated API definitions are enabled or disabled. Deprecated APIs are disabled by default. Deprecated APIs are meant to be removed completely in a later API version. Added ODP_DEPRECATE() macro to enforce deprecation of API definitions. When deprecated APIs are disabled, the macro renames API definitions so that application cannot use those any more, but a single implementation library can serve applications built with both options. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- configure.ac | 19 +++++++- doc/application-api-guide/api_guide_lines.dox | 6 +-- doc/platform-api-guide/Doxyfile | 1 + doc/process-guide/release-guide.adoc | 6 +-- include/odp/api/spec/.gitignore | 1 + include/odp/api/spec/deprecated.h.in | 50 ++++++++++++++++++++++ include/odp_api.h | 1 + platform/Makefile.inc | 1 + platform/linux-generic/Makefile.am | 1 + .../linux-generic/include/odp/api/deprecated.h | 26 +++++++++++ 10 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 include/odp/api/spec/deprecated.h.in create mode 100644 platform/linux-generic/include/odp/api/deprecated.h diff --git a/configure.ac b/configure.ac index 6351878ab..f6b20cb20 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,8 @@ ODP_VERSION_API_MAJOR=odpapi_major_version AC_SUBST(ODP_VERSION_API_MAJOR) ODP_VERSION_API_MINOR=odpapi_minor_version AC_SUBST(ODP_VERSION_API_MINOR) -AC_CONFIG_FILES([include/odp/api/spec/version.h]) +AC_CONFIG_FILES([include/odp/api/spec/version.h + include/odp/api/spec/deprecated.h]) AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) AC_CONFIG_SRCDIR([helper/config.h.in]) @@ -283,7 +284,7 @@ ODP_CFLAGS="$ODP_CFLAGS -DODP_DEBUG=$ODP_DEBUG" ODP_ABI_COMPAT=1 abi_compat=yes AC_ARG_ENABLE([abi-compat], - [ --disable-abi-compat disables ABI compatible mode, enables inline code in header files], + [ --disable-abi-compat disables ABI compatible mode, enables inline code in header files], [if test "x$enableval" = "xno"; then ODP_ABI_COMPAT=0 abi_compat=no @@ -292,6 +293,19 @@ AC_ARG_ENABLE([abi-compat], fi]) AC_SUBST(ODP_ABI_COMPAT) +########################################################################## +# Enable/disable deprecated API definitions +########################################################################## +ODP_DEPRECATED_API=0 +deprecated=no +AC_ARG_ENABLE([deprecated], + [ --enable-deprecated enable deprecated API definitions], + [if test "x$enableval" = "xyes"; then + ODP_DEPRECATED_API=1 + deprecated=yes + fi]) +AC_SUBST(ODP_DEPRECATED_API) + ########################################################################## # Default warning setup ########################################################################## @@ -395,6 +409,7 @@ AC_MSG_RESULT([ static libraries: ${enable_static} shared libraries: ${enable_shared} ABI compatible: ${abi_compat} + Deprecated APIs: ${deprecated} cunit: ${cunit_support} test_vald: ${test_vald} test_perf: ${test_perf} diff --git a/doc/application-api-guide/api_guide_lines.dox b/doc/application-api-guide/api_guide_lines.dox index 394e95829..a6488c322 100644 --- a/doc/application-api-guide/api_guide_lines.dox +++ b/doc/application-api-guide/api_guide_lines.dox @@ -75,7 +75,7 @@ The former is a compile-time assertion and hence adds no additional path length. The latter is controlled by the ODP_NO_DEBUG compile-time switch and so is suitable for use in development/debug builds that can be compiled out for production use. Other mechanisms available to the implementer are: - ODP_ABORT() is provided for situations where further execution of the code must not occur and a level of tracing information should be left in the log. - - ODP_DEPRECATED() is used to signify that a call is planned for obsolescence. + - ODP_DEPRECATE() is used to signify that a call is planned for obsolescence. - ODP_LOG() is used to direct implementation messages to the application. @@ -197,8 +197,8 @@ This is one of the reasons why some features MAY be defined as OPTIONAL. While allowed, the proliferation of OPTIONAL features SHOULD be avoided to enable broad application portability across many implementations. At the same time, a "least common denominator" approach MUST NOT be taken as that defeats the purpose of providing higher-level abstractions in APIs. -@subsection odp_deprecated ODP DEPRECATED -A deprecated API will remain marked as such in the public API using #ODP_DEPRECATED for two release cycles for the #ODP_VERSION_API_MAJOR number. +@subsection odp_deprecate ODP DEPRECATE +A deprecated API will remain marked as such in the public API using #ODP_DEPRECATE() for two release cycles for the #ODP_VERSION_API_MAJOR number. For example an API marked as deprecated in 1.1.0 will still be present in 1.2.0 and removed in 1.3.0. A deprecated API will contain the doxygen tag \@deprecated with a description of the reason for the change. diff --git a/doc/platform-api-guide/Doxyfile b/doc/platform-api-guide/Doxyfile index 93f6edfe3..12d356e3a 100644 --- a/doc/platform-api-guide/Doxyfile +++ b/doc/platform-api-guide/Doxyfile @@ -17,4 +17,5 @@ PREDEFINED = __GNUC__ \ __LITTLE_ENDIAN_BITFIELD \ __x86_64__ \ ODP_PACKED \ + ODP_DEPRECATE(x)=x \ "ODP_HANDLE_T(type)=odp_handle_t type" diff --git a/doc/process-guide/release-guide.adoc b/doc/process-guide/release-guide.adoc index 8ea147af8..595af91a4 100644 --- a/doc/process-guide/release-guide.adoc +++ b/doc/process-guide/release-guide.adoc @@ -251,7 +251,7 @@ Deleting or changing the published API follows the normal <>, * A deprecated indication is applied to the old API using the @deprecated doxygen syntax. * For a function change the old API it is additionally marked using the -ODP_DEPRECATED preprocessor macro. +ODP_DEPRECATE() preprocessor macro. * The CHANGELOG will have an entry in the API change section. * The Release Manager will resolve the duration for which the deprecated API. will be supported, and determine which future release it will be applied to. + @@ -275,7 +275,7 @@ The new API must have comparable coverage to the old API. * * @param name ... */ -odp_foo_t odp_foo_create(const char *name) ODP_DEPRECATED; +odp_foo_t ODP_DEPRECATE(odp_foo_create)(const char *name); /** * Create a bar @@ -298,7 +298,7 @@ compiler warning. * * @param name ... */ -odp_foo_t odp_foo_create(const char *name) ODP_DEPRECATED; +odp_foo_t ODP_DEPRECATE(odp_foo_create)(const char *name); ---- === Changing a struct member diff --git a/include/odp/api/spec/.gitignore b/include/odp/api/spec/.gitignore index 67020331b..df9c87d90 100644 --- a/include/odp/api/spec/.gitignore +++ b/include/odp/api/spec/.gitignore @@ -1 +1,2 @@ +deprecated.h version.h diff --git a/include/odp/api/spec/deprecated.h.in b/include/odp/api/spec/deprecated.h.in new file mode 100644 index 000000000..224f60ff3 --- /dev/null +++ b/include/odp/api/spec/deprecated.h.in @@ -0,0 +1,50 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Macro for deprecated API definitions + */ + +#ifndef ODP_API_DEPRECATED_H_ +#define ODP_API_DEPRECATED_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Deprecated API definitions + * + * Some API definitions may be deprecated by this or a previous API version. + * This macro controls if those are enabled (and visible to the application) + * or disabled. + * + * * 0: Deprecated API definitions are disabled (default) + * * 1: Deprecated API definitions are enabled + */ +#define ODP_DEPRECATED_API @ODP_DEPRECATED_API@ + +/** + * @def ODP_DEPRECATE + * + * Macro to deprecate API definitions + */ + +#if ODP_DEPRECATED_API +#define ODP_DEPRECATE(x) x +#else +#define ODP_DEPRECATE(x) _deprecated_ ## x +#endif + +#ifdef __cplusplus +} +#endif + +#include +#endif diff --git a/include/odp_api.h b/include/odp_api.h index ec7fcd2e7..060ec888b 100644 --- a/include/odp_api.h +++ b/include/odp_api.h @@ -18,6 +18,7 @@ extern "C" { #endif +#include #include #include #include diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 7059d9103..59a577241 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -29,6 +29,7 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/cpumask.h \ $(top_srcdir)/include/odp/api/spec/crypto.h \ $(top_srcdir)/include/odp/api/spec/debug.h \ + $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 00ce80d74..eb7bea8f3 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -33,6 +33,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/cpumask.h \ $(srcdir)/include/odp/api/crypto.h \ $(srcdir)/include/odp/api/debug.h \ + $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ $(srcdir)/include/odp/api/hash.h \ diff --git a/platform/linux-generic/include/odp/api/deprecated.h b/platform/linux-generic/include/odp/api/deprecated.h new file mode 100644 index 000000000..82797ebc4 --- /dev/null +++ b/platform/linux-generic/include/odp/api/deprecated.h @@ -0,0 +1,26 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * Control deprecated API definitions + */ + +#ifndef ODP_PLAT_DEPRECATED_H_ +#define ODP_PLAT_DEPRECATED_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3 From be9ca86f431d5eaab0702f7d76db60cd75982e15 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 30 Mar 2017 16:58:55 +0300 Subject: test: crypto: remove references to deprecated crypto apis Remove last remaining references to deprecated API definitions. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- example/ipsec/odp_ipsec_misc.h | 4 ++-- example/ipsec/odp_ipsec_sa_db.c | 4 ++-- example/ipsec/odp_ipsec_stream.c | 6 +++--- test/common_plat/performance/odp_crypto.c | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/example/ipsec/odp_ipsec_misc.h b/example/ipsec/odp_ipsec_misc.h index e0320eb4e..45cb022eb 100644 --- a/example/ipsec/odp_ipsec_misc.h +++ b/example/ipsec/odp_ipsec_misc.h @@ -98,10 +98,10 @@ int parse_key_string(char *keystring, key->length = key_bits_in / 8; } else { - if ((alg->u.auth == ODP_AUTH_ALG_MD5_96) && + if ((alg->u.auth == ODP_AUTH_ALG_MD5_HMAC) && (KEY_BITS_MD5_96 == key_bits_in)) key->length = key_bits_in / 8; - else if ((alg->u.auth == ODP_AUTH_ALG_SHA256_128) && + else if ((alg->u.auth == ODP_AUTH_ALG_SHA256_HMAC) && (KEY_BITS_SHA256_128 == key_bits_in)) key->length = key_bits_in / 8; } diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c index 28215b5b7..10bbcb8f2 100644 --- a/example/ipsec/odp_ipsec_sa_db.c +++ b/example/ipsec/odp_ipsec_sa_db.c @@ -111,11 +111,11 @@ int create_sa_db_entry(char *input, odp_bool_t cipher) } else { if (0 == strcmp(token, "md5")) { entry->alg.u.auth = - ODP_AUTH_ALG_MD5_96; + ODP_AUTH_ALG_MD5_HMAC; entry->icv_len = 12; } else if (!strcmp(token, "sha256")) { entry->alg.u.auth = - ODP_AUTH_ALG_SHA256_128; + ODP_AUTH_ALG_SHA256_HMAC; entry->icv_len = 16; } else { entry->alg.u.auth = ODP_AUTH_ALG_NULL; diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index 428ec04da..15087cbe1 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -227,8 +227,8 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, /* AH (if specified) */ if (entry && (entry == stream->input.entry) && (ODP_AUTH_ALG_NULL != entry->ah.alg)) { - if (entry->ah.alg != ODP_AUTH_ALG_MD5_96 && - entry->ah.alg != ODP_AUTH_ALG_SHA256_128) + if (entry->ah.alg != ODP_AUTH_ALG_MD5_HMAC && + entry->ah.alg != ODP_AUTH_ALG_SHA256_HMAC) abort(); ah = (odph_ahhdr_t *)data; @@ -424,7 +424,7 @@ odp_bool_t verify_ipv4_packet(stream_db_entry_t *stream, return FALSE; if (odp_be_to_cpu_32(ah->spi) != entry->ah.spi) return FALSE; - if (ODP_AUTH_ALG_MD5_96 != entry->ah.alg) + if (ODP_AUTH_ALG_MD5_HMAC != entry->ah.alg) abort(); } else { if (entry && (ODP_AUTH_ALG_NULL != entry->ah.alg)) diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c index 954bdb794..b3857973e 100644 --- a/test/common_plat/performance/odp_crypto.c +++ b/test/common_plat/performance/odp_crypto.c @@ -205,7 +205,7 @@ static crypto_alg_config_t algs_config[] = { .data = test_iv, .length = 8, }, - .auth_alg = ODP_AUTH_ALG_MD5_96, + .auth_alg = ODP_AUTH_ALG_MD5_HMAC, .auth_key = { .data = test_key16, .length = sizeof(test_key16) @@ -217,7 +217,7 @@ static crypto_alg_config_t algs_config[] = { .name = "null-hmac-md5-96", .session = { .cipher_alg = ODP_CIPHER_ALG_NULL, - .auth_alg = ODP_AUTH_ALG_MD5_96, + .auth_alg = ODP_AUTH_ALG_MD5_HMAC, .auth_key = { .data = test_key16, .length = sizeof(test_key16) -- cgit v1.2.3 From 99478ee923dfd8279a7a5149769aee49df315dde Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 30 Mar 2017 16:58:53 +0300 Subject: api: hints: remove ODP_DEPRECATED from API Remove ODP_DEPRECATED macro as it depends on (GCC) compiler type attribute, which may not be supported (the same way) by all compilers. Also the attribute works only for types, but not e.g. for fields of structure. A new configuration option will be added to control deprecated definitions. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/api/spec/hints.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/odp/api/spec/hints.h b/include/odp/api/spec/hints.h index 82400f073..7434c6a5c 100644 --- a/include/odp/api/spec/hints.h +++ b/include/odp/api/spec/hints.h @@ -51,11 +51,6 @@ extern "C" { */ #define ODP_PRINTF_FORMAT(x, y) __attribute__((format(printf, (x), (y)))) -/** - * Indicate deprecated variables, functions or types - */ -#define ODP_DEPRECATED __attribute__((__deprecated__)) - /** * Intentionally unused variables of functions */ @@ -96,7 +91,6 @@ extern "C" { #define ODP_WEAK_SYMBOL #define ODP_HOT_CODE #define ODP_COLD_CODE -#define ODP_DEPRECATED #define ODP_UNUSED #define odp_likely(x) #define odp_unlikely(x) -- cgit v1.2.3 From 966c1c956a21f4e70c873a3c3546e65299837457 Mon Sep 17 00:00:00 2001 From: Christophe Milard Date: Fri, 19 Aug 2016 17:10:12 +0200 Subject: doc: application-api-guide: excluding drv interface The input files parsed to generate the ODP platform specific API doc included (wrongly) part of the drv interface specification. This led to warning on undefined symbols. Fixed by restricting imput files to API only. Signed-off-by: Christophe Milard Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- doc/platform-api-guide/Doxyfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/platform-api-guide/Doxyfile b/doc/platform-api-guide/Doxyfile index 12d356e3a..1f2d49a4b 100644 --- a/doc/platform-api-guide/Doxyfile +++ b/doc/platform-api-guide/Doxyfile @@ -5,9 +5,9 @@ PROJECT_NUMBER = $(VERSION) PROJECT_LOGO = $(SRCDIR)/doc/images/ODP-Logo-HQ.svg INPUT = $(SRCDIR)/doc/application-api-guide \ $(SRCDIR)/doc/platform-api-guide \ - $(SRCDIR)/include \ + $(SRCDIR)/include/odp/api \ $(SRCDIR)/platform/$(WITH_PLATFORM)/doc \ - $(SRCDIR)/platform/$(WITH_PLATFORM)/include/odp \ + $(SRCDIR)/platform/$(WITH_PLATFORM)/include/odp/api \ $(SRCDIR)/platform/$(WITH_PLATFORM)/arch/$(WITH_ARCH) EXAMPLE_PATH = $(SRCDIR)/example $(SRCDIR)/platform $(SRCDIR) PREDEFINED = __GNUC__ \ -- cgit v1.2.3 From 19c488fdd9f9868cbe60f1ff8558f48c7bba6f04 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 8 Dec 2016 16:25:58 +0200 Subject: linux-gen: crypto: add algo capability functions Implemented cipher and authentication algorithm capability functions. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Reviewed-by: Balasubramanian Manoharan Reviewed-by: Nikhil Agarwal Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 77 +++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index dfeb9f3f2..6963ee625 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -656,6 +656,83 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, return num; } +int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, + odp_crypto_cipher_capability_t dst[], + int num_copy) +{ + const odp_crypto_cipher_capability_t *src; + int num; + int size = sizeof(odp_crypto_cipher_capability_t); + + switch (cipher) { + case ODP_CIPHER_ALG_NULL: + src = NULL; + num = 0; + break; + case ODP_CIPHER_ALG_DES: + src = cipher_capa_des; + num = sizeof(cipher_capa_des) / size; + break; + case ODP_CIPHER_ALG_3DES_CBC: + src = cipher_capa_trides_cbc; + num = sizeof(cipher_capa_trides_cbc) / size; + break; + case ODP_CIPHER_ALG_AES_CBC: + src = cipher_capa_aes_cbc; + num = sizeof(cipher_capa_aes_cbc) / size; + break; + case ODP_CIPHER_ALG_AES_GCM: + src = cipher_capa_aes_gcm; + num = sizeof(cipher_capa_aes_gcm) / size; + break; + default: + return -1; + } + + if (num < num_copy) + num_copy = num; + + memcpy(dst, src, num_copy * size); + + return num; +} + +int odp_crypto_auth_capability(odp_auth_alg_t auth, + odp_crypto_auth_capability_t dst[], int num_copy) +{ + const odp_crypto_auth_capability_t *src; + int num; + int size = sizeof(odp_crypto_auth_capability_t); + + switch (auth) { + case ODP_AUTH_ALG_NULL: + src = NULL; + num = 0; + break; + case ODP_AUTH_ALG_MD5_HMAC: + src = auth_capa_md5_hmac; + num = sizeof(auth_capa_md5_hmac) / size; + break; + case ODP_AUTH_ALG_SHA256_HMAC: + src = auth_capa_sha256_hmac; + num = sizeof(auth_capa_sha256_hmac) / size; + break; + case ODP_AUTH_ALG_AES_GCM: + src = auth_capa_aes_gcm; + num = sizeof(auth_capa_aes_gcm) / size; + break; + default: + return -1; + } + + if (num < num_copy) + num_copy = num; + + memcpy(dst, src, num_copy * size); + + return num; +} + int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out, -- cgit v1.2.3 From 8c6ca3886ae4ffb111d3a81d09d21b68e0e11349 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 17 Feb 2017 16:20:06 +0200 Subject: api: pktio: add parser configuration Packet input parsing level configuration is added. An application may express the maximum layer it is interested about. Implementations may optimize packet input performance as parsing can be stopped on the application required level. Implementations are free to parse more layers than application requests. Lazy parsing (e.g. in current odp-linux) does not work in practice. The implementation cannot continue parsing after the application has got access to packet data, since application may overwrite some packet headers. Parse results must reflect the format of the received packet. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/api/spec/packet_io.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/include/odp/api/spec/packet_io.h b/include/odp/api/spec/packet_io.h index 85cd6d184..cec1f22af 100644 --- a/include/odp/api/spec/packet_io.h +++ b/include/odp/api/spec/packet_io.h @@ -345,6 +345,39 @@ typedef union odp_pktout_config_opt_t { uint64_t all_bits; } odp_pktout_config_opt_t; +/** + * Parser layers + */ +typedef enum odp_pktio_parser_layer_t { + /** No layers */ + ODP_PKTIO_PARSER_LAYER_NONE = 0, + + /** Layer L2 protocols (Ethernet, VLAN, ARP, etc) */ + ODP_PKTIO_PARSER_LAYER_L2, + + /** Layer L3 protocols (IPv4, IPv6, ICMP, IPsec, etc) */ + ODP_PKTIO_PARSER_LAYER_L3, + + /** Layer L4 protocols (UDP, TCP, SCTP) */ + ODP_PKTIO_PARSER_LAYER_L4, + + /** All layers */ + ODP_PKTIO_PARSER_LAYER_ALL + +} odp_pktio_parser_layer_t; + +/** + * Parser configuration + */ +typedef struct odp_pktio_parser_config_t { + /** Protocol parsing level in packet input + * + * Parse protocol layers in minimum up to this level during packet + * input. The default value is ODP_PKTIO_PARSER_LAYER_ALL. */ + odp_pktio_parser_layer_t layer; + +} odp_pktio_parser_config_t; + /** * Packet IO configuration options * @@ -363,6 +396,9 @@ typedef struct odp_pktio_config_t { * Default value for all bits is zero. */ odp_pktout_config_opt_t pktout; + /** Packet input parser configuration */ + odp_pktio_parser_config_t parser; + /** Interface loopback mode * * In this mode the packets sent out through the interface is -- cgit v1.2.3 From 29b29677ed7d5d396f4aec1d0f3197efbf119113 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 17 Feb 2017 16:20:07 +0200 Subject: linux-gen: pktio: parser default config Fill default parser configuration and capability. All pktios use same parser code, so the capability is the same (all layers). Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_packet_io.c | 13 +++++++++++-- test/common_plat/validation/api/pktio/pktio.c | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index 50a000e5b..ea9f2a756 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -931,6 +931,8 @@ void odp_pktout_queue_param_init(odp_pktout_queue_param_t *param) void odp_pktio_config_init(odp_pktio_config_t *config) { memset(config, 0, sizeof(odp_pktio_config_t)); + + config->parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; } int odp_pktio_info(odp_pktio_t hdl, odp_pktio_info_t *info) @@ -1106,6 +1108,7 @@ int odp_pktio_term_global(void) int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) { pktio_entry_t *entry; + int ret; entry = get_pktio_entry(pktio); if (entry == NULL) { @@ -1114,9 +1117,15 @@ int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa) } if (entry->s.ops->capability) - return entry->s.ops->capability(entry, capa); + ret = entry->s.ops->capability(entry, capa); + else + ret = single_capability(capa); - return single_capability(capa); + /* The same parser is used for all pktios */ + if (ret == 0) + capa->config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + + return ret; } unsigned odp_pktio_max_index(void) diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 4d8d2cc75..0e2a9f390 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -1182,6 +1182,8 @@ void pktio_test_pktio_config(void) odp_pktio_config_init(&config); + CU_ASSERT(config.parser.layer == ODP_PKTIO_PARSER_LAYER_ALL); + CU_ASSERT(odp_pktio_config(pktio, NULL) == 0); CU_ASSERT(odp_pktio_config(pktio, &config) == 0); -- cgit v1.2.3 From fdddf685fcad06f05f3788705968622b23a569ac Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 4 Apr 2017 09:28:18 +0300 Subject: linux-gen: packet: recognize ICMPv6 packets Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- example/generator/odp_generator.c | 4 ++-- example/ipsec/odp_ipsec_stream.c | 6 +++--- helper/include/odp/helper/ip.h | 3 ++- platform/linux-generic/include/protocols/ip.h | 3 ++- platform/linux-generic/odp_packet.c | 5 ++++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 3ec7d8d12..9336cec16 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -319,7 +319,7 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) ip->ttl = 64; ip->tot_len = odp_cpu_to_be_16(args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN); - ip->proto = ODPH_IPPROTO_ICMP; + ip->proto = ODPH_IPPROTO_ICMPv4; ip->id = 0; ip->chksum = 0; @@ -664,7 +664,7 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) } /* icmp */ - if (ip->proto == ODPH_IPPROTO_ICMP) { + if (ip->proto == ODPH_IPPROTO_ICMPv4) { icmp = (odph_icmphdr_t *)(buf + offset); process_icmp_pkt(icmp, msg); diff --git a/example/ipsec/odp_ipsec_stream.c b/example/ipsec/odp_ipsec_stream.c index 15087cbe1..e37fbee29 100644 --- a/example/ipsec/odp_ipsec_stream.c +++ b/example/ipsec/odp_ipsec_stream.c @@ -219,7 +219,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, ip->src_addr = odp_cpu_to_be_32(entry->tun_src_ip); ip->dst_addr = odp_cpu_to_be_32(entry->tun_dst_ip); } else { - ip->proto = ODPH_IPPROTO_ICMP; + ip->proto = ODPH_IPPROTO_ICMPv4; ip->src_addr = odp_cpu_to_be_32(stream->src_ip); ip->dst_addr = odp_cpu_to_be_32(stream->dst_ip); } @@ -262,7 +262,7 @@ odp_packet_t create_ipv4_packet(stream_db_entry_t *stream, inner_ip = (odph_ipv4hdr_t *)data; memset((char *)inner_ip, 0, sizeof(*inner_ip)); inner_ip->ver_ihl = 0x45; - inner_ip->proto = ODPH_IPPROTO_ICMP; + inner_ip->proto = ODPH_IPPROTO_ICMPv4; inner_ip->id = odp_cpu_to_be_16(stream->id); inner_ip->ttl = 64; inner_ip->tos = 0; @@ -519,7 +519,7 @@ clear_packet: icmp = (odph_icmphdr_t *)(inner_ip + 1); data = (uint8_t *)icmp; } else { - if (ODPH_IPPROTO_ICMP != ip->proto) + if (ODPH_IPPROTO_ICMPv4 != ip->proto) return FALSE; icmp = (odph_icmphdr_t *)data; } diff --git a/helper/include/odp/helper/ip.h b/helper/include/odp/helper/ip.h index ba6e675f4..91776fad6 100644 --- a/helper/include/odp/helper/ip.h +++ b/helper/include/odp/helper/ip.h @@ -205,13 +205,14 @@ typedef struct ODP_PACKED { * IP protocol values (IPv4:'proto' or IPv6:'next_hdr') * @{*/ #define ODPH_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */ -#define ODPH_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol (1) */ +#define ODPH_IPPROTO_ICMPv4 0x01 /**< Internet Control Message Protocol (1) */ #define ODPH_IPPROTO_TCP 0x06 /**< Transmission Control Protocol (6) */ #define ODPH_IPPROTO_UDP 0x11 /**< User Datagram Protocol (17) */ #define ODPH_IPPROTO_ROUTE 0x2B /**< IPv6 Routing header (43) */ #define ODPH_IPPROTO_FRAG 0x2C /**< IPv6 Fragment (44) */ #define ODPH_IPPROTO_AH 0x33 /**< Authentication Header (51) */ #define ODPH_IPPROTO_ESP 0x32 /**< Encapsulating Security Payload (50) */ +#define ODPH_IPPROTO_ICMPv6 0x3A /**< Internet Control Message Protocol (58) */ #define ODPH_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */ /**@}*/ diff --git a/platform/linux-generic/include/protocols/ip.h b/platform/linux-generic/include/protocols/ip.h index 20041f1c0..2b34a753f 100644 --- a/platform/linux-generic/include/protocols/ip.h +++ b/platform/linux-generic/include/protocols/ip.h @@ -157,13 +157,14 @@ typedef struct ODP_PACKED { * IP protocol values (IPv4:'proto' or IPv6:'next_hdr') * @{*/ #define _ODP_IPPROTO_HOPOPTS 0x00 /**< IPv6 hop-by-hop options */ -#define _ODP_IPPROTO_ICMP 0x01 /**< Internet Control Message Protocol (1) */ +#define _ODP_IPPROTO_ICMPv4 0x01 /**< Internet Control Message Protocol (1) */ #define _ODP_IPPROTO_TCP 0x06 /**< Transmission Control Protocol (6) */ #define _ODP_IPPROTO_UDP 0x11 /**< User Datagram Protocol (17) */ #define _ODP_IPPROTO_ROUTE 0x2B /**< IPv6 Routing header (43) */ #define _ODP_IPPROTO_FRAG 0x2C /**< IPv6 Fragment (44) */ #define _ODP_IPPROTO_AH 0x33 /**< Authentication Header (51) */ #define _ODP_IPPROTO_ESP 0x32 /**< Encapsulating Security Payload (50) */ +#define _ODP_IPPROTO_ICMPv6 0x3A /**< Internet Control Message Protocol (58) */ #define _ODP_IPPROTO_SCTP 0x84 /**< Stream Control Transmission protocol (132) */ #define _ODP_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */ diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index e2bb8426a..c6962ce97 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -2078,7 +2078,10 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, /* Parse Layer 4 headers */ switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMP: + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ + + case _ODP_IPPROTO_ICMPv6: prs->input_flags.icmp = 1; break; -- cgit v1.2.3 From 93afeeaf4e3dee3099830fccbb53bb32e64e3090 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 4 Apr 2017 09:28:20 +0300 Subject: examples: use odp_pktio_config() to select required packet parsing level Select required packet parsing level when full packet parsing is not required. Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- example/l2fwd_simple/odp_l2fwd_simple.c | 5 +++++ example/l3fwd/odp_l3fwd.c | 7 +++++++ example/switch/odp_switch.c | 5 +++++ test/common_plat/performance/odp_l2fwd.c | 7 +++++++ test/common_plat/performance/odp_pktio_ordered.c | 5 +++++ 5 files changed, 29 insertions(+) diff --git a/example/l2fwd_simple/odp_l2fwd_simple.c b/example/l2fwd_simple/odp_l2fwd_simple.c index b97808f4b..e63814555 100644 --- a/example/l2fwd_simple/odp_l2fwd_simple.c +++ b/example/l2fwd_simple/odp_l2fwd_simple.c @@ -41,6 +41,7 @@ static odp_pktio_t create_pktio(const char *name, odp_pool_t pool, odp_pktin_queue_param_t in_queue_param; odp_pktout_queue_param_t out_queue_param; odp_pktio_t pktio; + odp_pktio_config_t config; odp_pktio_param_init(&pktio_param); @@ -50,6 +51,10 @@ static odp_pktio_t create_pktio(const char *name, odp_pool_t pool, exit(1); } + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&in_queue_param); odp_pktout_queue_param_init(&out_queue_param); diff --git a/example/l3fwd/odp_l3fwd.c b/example/l3fwd/odp_l3fwd.c index ba0697201..f579d36d3 100644 --- a/example/l3fwd/odp_l3fwd.c +++ b/example/l3fwd/odp_l3fwd.c @@ -101,6 +101,7 @@ static int create_pktio(const char *name, odp_pool_t pool, odp_pktio_param_t pktio_param; odp_pktio_t pktio; odp_pktio_capability_t capa; + odp_pktio_config_t config; int rc; odp_pktio_param_init(&pktio_param); @@ -120,6 +121,12 @@ static int create_pktio(const char *name, odp_pool_t pool, return -1; } + odp_pktio_config_init(&config); + config.parser.layer = global.cmd_args.error_check ? + ODP_PKTIO_PARSER_LAYER_ALL : + ODP_PKTIO_PARSER_LAYER_L4; + odp_pktio_config(pktio, &config); + fwd_pktio->nb_rxq = (int)capa.max_input_queues; fwd_pktio->nb_txq = (int)capa.max_output_queues; diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index 561c2934b..5bec6a043 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -217,6 +217,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -238,6 +239,10 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; } + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param); diff --git a/test/common_plat/performance/odp_l2fwd.c b/test/common_plat/performance/odp_l2fwd.c index 33efc0223..78b3633bd 100644 --- a/test/common_plat/performance/odp_l2fwd.c +++ b/test/common_plat/performance/odp_l2fwd.c @@ -619,6 +619,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_param_t pktio_param; odp_schedule_sync_t sync_mode; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -655,6 +656,12 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; } + odp_pktio_config_init(&config); + config.parser.layer = gbl_args->appl.error_check ? + ODP_PKTIO_PARSER_LAYER_ALL : + ODP_PKTIO_PARSER_LAYER_NONE; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param); diff --git a/test/common_plat/performance/odp_pktio_ordered.c b/test/common_plat/performance/odp_pktio_ordered.c index bff4586e5..4bb0bef93 100644 --- a/test/common_plat/performance/odp_pktio_ordered.c +++ b/test/common_plat/performance/odp_pktio_ordered.c @@ -586,6 +586,7 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; + odp_pktio_config_t config; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; @@ -611,6 +612,10 @@ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, return -1; } + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; + odp_pktio_config(pktio, &config); + odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param); -- cgit v1.2.3 From 7394a5c8dead5edcfa5bda571aceba5945c91d16 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 4 Apr 2017 09:28:21 +0300 Subject: validation: pktio: add tests for packet parsing Test packet parsing using predefined test packets (byte arrays). Test packets are looped through tested pktio interfaces to force packet parsing. Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/Makefile.am | 4 +- test/common_plat/validation/api/pktio/parser.c | 545 ++++++++++++++++++++++ test/common_plat/validation/api/pktio/parser.h | 180 +++++++ test/common_plat/validation/api/pktio/pktio.c | 5 +- test/common_plat/validation/api/pktio/pktio.h | 3 + 5 files changed, 733 insertions(+), 4 deletions(-) create mode 100644 test/common_plat/validation/api/pktio/parser.c create mode 100644 test/common_plat/validation/api/pktio/parser.h diff --git a/test/common_plat/validation/api/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index 466d690dc..c6368fba3 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c +dist_pktio_main_SOURCES = pktio_main.c parser.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = pktio.h +EXTRA_DIST = pktio.h parser.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c new file mode 100644 index 000000000..ad7101d08 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.c @@ -0,0 +1,545 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include + +#include +#include "parser.h" +#include "pktio.h" + +#define MAX_NUM_IFACES 2 +#define PKT_POOL_NUM 256 +#define PKT_POOL_BUF_LEN (2 * 1024) + +/** + * local container for pktio attributes + */ +typedef struct { + const char *name; + odp_pktio_t hdl; + odp_pktout_queue_t pktout; + odp_pktin_queue_t pktin; +} pktio_info_t; + +/** Interface names used for testing */ +static const char *iface_name[MAX_NUM_IFACES]; + +/** Test interfaces */ +pktio_info_t pktios[MAX_NUM_IFACES]; +pktio_info_t *pktio_a; +pktio_info_t *pktio_b; + +/** Number of interfaces being used (1=loopback, 2=pair) */ +static int num_ifaces; + +/** While testing real-world interfaces additional time may be needed for + * external network to enable link to pktio interface that just become up. + */ +static bool wait_for_network; + +/** Parser packet pool */ +odp_pool_t parser_pool = ODP_POOL_INVALID; + +static inline void wait_linkup(odp_pktio_t pktio) +{ + /* wait 1 second for link up */ + uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); + int wait_num = 100; + int i; + int ret = -1; + + for (i = 0; i < wait_num; i++) { + ret = odp_pktio_link_status(pktio); + if (ret < 0 || ret == 1) + break; + /* link is down, call status again after delay */ + odp_time_wait_ns(wait_ns); + } +} + +static int pkt_pool_create(void) +{ + odp_pool_capability_t capa; + odp_pool_param_t params; + + if (odp_pool_capability(&capa) != 0) { + printf("Error: unable to query pool capability.\n"); + return -1; + } + + if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { + printf("Error: packet pool size not supported.\n"); + printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); + return -1; + } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { + printf("Error: packet length not supported.\n"); + return -1; + } else if (capa.pkt.max_seg_len && + capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { + printf("Error: segment length not supported.\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_BUF_LEN; + params.pkt.len = PKT_POOL_BUF_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + parser_pool = odp_pool_create("pkt_pool_default", ¶ms); + if (parser_pool == ODP_POOL_INVALID) { + printf("Error: packet pool create failed.\n"); + return -1; + } + + return 0; +} + +static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_config_t config; + odp_pktio_param_t pktio_param; + const char *iface = iface_name[iface_idx]; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; + pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; + + pktio = odp_pktio_open(iface, pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) { + printf("Error: failed to open %s\n", iface); + return ODP_PKTIO_INVALID; + } + + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + if (odp_pktio_config(pktio, &config)) { + printf("Error: failed to configure %s\n", iface); + return ODP_PKTIO_INVALID; + } + + /* By default, single input and output queue is used */ + if (odp_pktin_queue_config(pktio, NULL)) { + printf("Error: failed to config input queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + if (odp_pktout_queue_config(pktio, NULL)) { + printf("Error: failed to config output queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + + if (wait_for_network) + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); + + return pktio; +} + +static odp_packet_t create_packet(const uint8_t *data, uint32_t len) +{ + odp_packet_t pkt; + + pkt = odp_packet_alloc(parser_pool, len); + if (pkt == ODP_PACKET_INVALID) + return ODP_PACKET_INVALID; + + if (odp_packet_copy_from_mem(pkt, 0, len, data)) { + printf("Error: failed to copy test packet data\n"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + odp_packet_l2_offset_set(pkt, 0); + + return pkt; +} + +/** + * Receive incoming packets and compare them to the original. Function returns + * a valid packet handle only when the received packet matches to the original + * packet. + */ +static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, + odp_packet_t orig_pkt, uint64_t ns) +{ + odp_packet_t pkt = ODP_PACKET_INVALID; + odp_time_t wait_time, end; + uint32_t orig_len; + uint8_t *orig_data; + + orig_len = odp_packet_len(orig_pkt); + orig_data = odp_packet_data(orig_pkt); + wait_time = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait_time); + + do { + int ret; + odp_packet_t tmp_pkt; + + ret = odp_pktin_recv(pktin, &tmp_pkt, 1); + if (ret < 0) + break; + + if (ret == 1) { + uint32_t len; + uint8_t *data; + + len = odp_packet_len(tmp_pkt); + data = odp_packet_data(tmp_pkt); + + if (len == orig_len && + memcmp(data, orig_data, len) == 0) { + pkt = tmp_pkt; + break; + } + odp_packet_free(tmp_pkt); + } + } while (odp_time_cmp(end, odp_time_local()) > 0); + + return pkt; +} + +/** + * Creates a test packet from data array and loops it through the test pktio + * interfaces forcing packet parsing. + */ +static odp_packet_t loopback_packet(pktio_info_t *pktio_a, + pktio_info_t *pktio_b, const uint8_t *data, + uint32_t len) +{ + odp_packet_t pkt; + odp_packet_t sent_pkt; + + pkt = create_packet(data, len); + if (pkt == ODP_PACKET_INVALID) { + CU_FAIL("failed to generate test packet"); + return ODP_PACKET_INVALID; + } + + pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); + + sent_pkt = odp_packet_copy(pkt, parser_pool); + if (sent_pkt == ODP_PACKET_INVALID) { + CU_FAIL_FATAL("failed to copy test packet"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + while (1) { + int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); + + if (ret < 0) { + CU_FAIL_FATAL("failed to send test packet"); + odp_packet_free(pkt); + odp_packet_free(sent_pkt); + return ODP_PACKET_INVALID; + } + if (ret == 1) + break; + } + + /* and wait for them to arrive back */ + pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); + odp_packet_free(sent_pkt); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); + CU_ASSERT(odp_packet_has_error(pkt) == 0); + + return pkt; +} + +void parser_test_arp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, + sizeof(test_packet_arp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_arp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, + sizeof(test_packet_ipv4_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, + sizeof(test_packet_ipv4_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, + sizeof(test_packet_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, + sizeof(test_packet_vlan_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_qinq_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, + sizeof(test_packet_vlan_qinq_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, + sizeof(test_packet_ipv6_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, + sizeof(test_packet_ipv6_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, + sizeof(test_packet_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, + sizeof(test_packet_vlan_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +int parser_suite_init(void) +{ + int i; + + if (getenv("ODP_WAIT_FOR_NETWORK")) + wait_for_network = true; + + iface_name[0] = getenv("ODP_PKTIO_IF0"); + iface_name[1] = getenv("ODP_PKTIO_IF1"); + num_ifaces = 1; + + if (!iface_name[0]) { + printf("No interfaces specified, using default \"loop\".\n"); + iface_name[0] = "loop"; + } else if (!iface_name[1]) { + printf("Using loopback interface: %s\n", iface_name[0]); + } else { + num_ifaces = 2; + printf("Using paired interfaces: %s %s\n", + iface_name[0], iface_name[1]); + } + + if (pkt_pool_create() != 0) { + printf("Error: failed to create parser pool\n"); + return -1; + } + + /* Create pktios and associate input/output queues */ + for (i = 0; i < num_ifaces; ++i) { + pktio_info_t *io; + + io = &pktios[i]; + io->name = iface_name[i]; + io->hdl = create_pktio(i, parser_pool); + if (io->hdl == ODP_PKTIO_INVALID) { + printf("Error: failed to open iface"); + return -1; + } + + if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktio_start(io->hdl)) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + wait_linkup(io->hdl); + } + + pktio_a = &pktios[0]; + pktio_b = &pktios[1]; + if (num_ifaces == 1) + pktio_b = pktio_a; + + return 0; +} + +int parser_suite_term(void) +{ + int i; + int ret = 0; + + for (i = 0; i < num_ifaces; ++i) { + if (odp_pktio_stop(pktios[i].hdl)) { + printf("Error: failed to stop pktio: %s\n", + pktios[i].name); + ret = -1; + } + if (odp_pktio_close(pktios[i].hdl)) { + printf("Error: failed to close pktio: %s\n", + pktios[i].name); + ret = -1; + } + } + + if (odp_pool_destroy(parser_pool) != 0) { + printf("Error: failed to destroy packet pool\n"); + ret = -1; + } + + return ret; +} + +/** + * Certain tests can only be run with 'loop' pktio. + */ +static int loop_pktio(void) +{ + if (strcmp(iface_name[0], "loop") == 0) + return ODP_TEST_ACTIVE; + else + return ODP_TEST_INACTIVE; +} + +odp_testinfo_t parser_suite[] = { + ODP_TEST_INFO(parser_test_arp), + ODP_TEST_INFO(parser_test_ipv4_icmp), + ODP_TEST_INFO(parser_test_ipv4_tcp), + ODP_TEST_INFO(parser_test_ipv4_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), + ODP_TEST_INFO(parser_test_ipv6_icmp), + ODP_TEST_INFO(parser_test_ipv6_tcp), + ODP_TEST_INFO(parser_test_ipv6_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), + ODP_TEST_INFO_NULL +}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h new file mode 100644 index 000000000..57c623884 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_PARSER_H_ +#define _ODP_TEST_PARSER_H_ + +#include + +/* test functions: */ +void parser_test_arp(void); +void parser_test_ipv4_icmp(void); +void parser_test_ipv4_tcp(void); +void parser_test_ipv4_udp(void); +void parser_test_vlan_ipv4_udp(void); +void parser_test_vlan_qinq_ipv4_udp(void); +void parser_test_ipv6_icmp(void); +void parser_test_ipv6_tcp(void); +void parser_test_ipv6_udp(void); +void parser_test_vlan_ipv6_udp(void); + +/* test array init/term functions: */ +int parser_suite_term(void); +int parser_suite_init(void); + +/* test arrays: */ +extern odp_testinfo_t parser_suite[]; + +/** + * ARP request + */ +static const uint8_t test_packet_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, + 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, + 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, +}; + +/** + * ICMPv4 echo reply + */ +static const uint8_t test_packet_ipv4_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, + 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, +}; + +/** + * IPv4 TCP + */ +static const uint8_t test_packet_ipv4_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, + 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, + 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, +}; + +/** + * IPv4 UDP + */ +static const uint8_t test_packet_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, + 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, +}; + +/** + * VLAN IPv4 UDP + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, + 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, +}; + +/** + * VLAN Q-in-Q IPv4 UDP + * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 + * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 + */ +static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, + 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, + 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, +}; + +/** + * ICMPv6 echo request + */ +static const uint8_t test_packet_ipv6_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, + 0x0E, 0xBA, +}; + +/** + * IPv6 TCP + */ +static const uint8_t test_packet_ipv6_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, + 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, +}; + +/** + * IPv6 UDP + */ +static const uint8_t test_packet_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, + 0x64, 0x49, +}; + +/** + * VLAN IPv6 + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, + 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, + 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, + 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, + 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, +}; + +#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 0e2a9f390..c476a7126 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,6 +10,7 @@ #include #include "pktio.h" +#include "parser.h" #define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -143,8 +144,7 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } } -static void pktio_pkt_set_macs(odp_packet_t pkt, - odp_pktio_t src, odp_pktio_t dst) +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2192,6 +2192,7 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, + {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL }; diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index 8131d05fe..b8799d9eb 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,4 +61,7 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]); +/* functions shared by parser test suite */ +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); + #endif -- cgit v1.2.3 From 464fdc4efb4148dd8d1ec1aeaa2a7ffcb58d7faf Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 11 Apr 2017 16:31:14 +0300 Subject: Revert "validation: pktio: add tests for packet parsing" This reverts commit 5a770508ecf (validation: pktio: add tests for packet parsing) This commit breaks tap pktio test on Travis CI and some over envs. That needs to be fixed before restoring it back. Suite: Packet parser Test: parser_test_arp ...passed Test: parser_test_ipv4_icmp ...received pkt 0x7fec7ea00000, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv4_tcp ...received pkt 0x7fec7ea425c0, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv4_udp ...received pkt 0x7fec7ea00000, len == 60, orig_len = 64 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_icmp ...received pkt 0x7fec7ea425c0, len == 62, orig_len = 66 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_tcp ...received pkt 0x7fec7ea00000, len == 74, orig_len = 78 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Test: parser_test_ipv6_udp ...received pkt 0x7fec7ea425c0, len == 62, orig_len = 66 FAILED 1. parser.c:251 - pkt != ODP_PACKET_INVALID Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/Makefile.am | 4 +- test/common_plat/validation/api/pktio/parser.c | 545 ---------------------- test/common_plat/validation/api/pktio/parser.h | 180 ------- test/common_plat/validation/api/pktio/pktio.c | 5 +- test/common_plat/validation/api/pktio/pktio.h | 3 - 5 files changed, 4 insertions(+), 733 deletions(-) delete mode 100644 test/common_plat/validation/api/pktio/parser.c delete mode 100644 test/common_plat/validation/api/pktio/parser.h diff --git a/test/common_plat/validation/api/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index c6368fba3..466d690dc 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c parser.c +dist_pktio_main_SOURCES = pktio_main.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = pktio.h parser.h +EXTRA_DIST = pktio.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c deleted file mode 100644 index ad7101d08..000000000 --- a/test/common_plat/validation/api/pktio/parser.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include -#include - -#include - -#include -#include "parser.h" -#include "pktio.h" - -#define MAX_NUM_IFACES 2 -#define PKT_POOL_NUM 256 -#define PKT_POOL_BUF_LEN (2 * 1024) - -/** - * local container for pktio attributes - */ -typedef struct { - const char *name; - odp_pktio_t hdl; - odp_pktout_queue_t pktout; - odp_pktin_queue_t pktin; -} pktio_info_t; - -/** Interface names used for testing */ -static const char *iface_name[MAX_NUM_IFACES]; - -/** Test interfaces */ -pktio_info_t pktios[MAX_NUM_IFACES]; -pktio_info_t *pktio_a; -pktio_info_t *pktio_b; - -/** Number of interfaces being used (1=loopback, 2=pair) */ -static int num_ifaces; - -/** While testing real-world interfaces additional time may be needed for - * external network to enable link to pktio interface that just become up. - */ -static bool wait_for_network; - -/** Parser packet pool */ -odp_pool_t parser_pool = ODP_POOL_INVALID; - -static inline void wait_linkup(odp_pktio_t pktio) -{ - /* wait 1 second for link up */ - uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); - int wait_num = 100; - int i; - int ret = -1; - - for (i = 0; i < wait_num; i++) { - ret = odp_pktio_link_status(pktio); - if (ret < 0 || ret == 1) - break; - /* link is down, call status again after delay */ - odp_time_wait_ns(wait_ns); - } -} - -static int pkt_pool_create(void) -{ - odp_pool_capability_t capa; - odp_pool_param_t params; - - if (odp_pool_capability(&capa) != 0) { - printf("Error: unable to query pool capability.\n"); - return -1; - } - - if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { - printf("Error: packet pool size not supported.\n"); - printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); - return -1; - } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { - printf("Error: packet length not supported.\n"); - return -1; - } else if (capa.pkt.max_seg_len && - capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { - printf("Error: segment length not supported.\n"); - return -1; - } - - odp_pool_param_init(¶ms); - params.pkt.seg_len = PKT_POOL_BUF_LEN; - params.pkt.len = PKT_POOL_BUF_LEN; - params.pkt.num = PKT_POOL_NUM; - params.type = ODP_POOL_PACKET; - - parser_pool = odp_pool_create("pkt_pool_default", ¶ms); - if (parser_pool == ODP_POOL_INVALID) { - printf("Error: packet pool create failed.\n"); - return -1; - } - - return 0; -} - -static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) -{ - odp_pktio_t pktio; - odp_pktio_config_t config; - odp_pktio_param_t pktio_param; - const char *iface = iface_name[iface_idx]; - - odp_pktio_param_init(&pktio_param); - pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; - pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; - - pktio = odp_pktio_open(iface, pool, &pktio_param); - if (pktio == ODP_PKTIO_INVALID) { - printf("Error: failed to open %s\n", iface); - return ODP_PKTIO_INVALID; - } - - odp_pktio_config_init(&config); - config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; - if (odp_pktio_config(pktio, &config)) { - printf("Error: failed to configure %s\n", iface); - return ODP_PKTIO_INVALID; - } - - /* By default, single input and output queue is used */ - if (odp_pktin_queue_config(pktio, NULL)) { - printf("Error: failed to config input queue for %s\n", iface); - return ODP_PKTIO_INVALID; - } - if (odp_pktout_queue_config(pktio, NULL)) { - printf("Error: failed to config output queue for %s\n", iface); - return ODP_PKTIO_INVALID; - } - - if (wait_for_network) - odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); - - return pktio; -} - -static odp_packet_t create_packet(const uint8_t *data, uint32_t len) -{ - odp_packet_t pkt; - - pkt = odp_packet_alloc(parser_pool, len); - if (pkt == ODP_PACKET_INVALID) - return ODP_PACKET_INVALID; - - if (odp_packet_copy_from_mem(pkt, 0, len, data)) { - printf("Error: failed to copy test packet data\n"); - odp_packet_free(pkt); - return ODP_PACKET_INVALID; - } - - odp_packet_l2_offset_set(pkt, 0); - - return pkt; -} - -/** - * Receive incoming packets and compare them to the original. Function returns - * a valid packet handle only when the received packet matches to the original - * packet. - */ -static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, - odp_packet_t orig_pkt, uint64_t ns) -{ - odp_packet_t pkt = ODP_PACKET_INVALID; - odp_time_t wait_time, end; - uint32_t orig_len; - uint8_t *orig_data; - - orig_len = odp_packet_len(orig_pkt); - orig_data = odp_packet_data(orig_pkt); - wait_time = odp_time_local_from_ns(ns); - end = odp_time_sum(odp_time_local(), wait_time); - - do { - int ret; - odp_packet_t tmp_pkt; - - ret = odp_pktin_recv(pktin, &tmp_pkt, 1); - if (ret < 0) - break; - - if (ret == 1) { - uint32_t len; - uint8_t *data; - - len = odp_packet_len(tmp_pkt); - data = odp_packet_data(tmp_pkt); - - if (len == orig_len && - memcmp(data, orig_data, len) == 0) { - pkt = tmp_pkt; - break; - } - odp_packet_free(tmp_pkt); - } - } while (odp_time_cmp(end, odp_time_local()) > 0); - - return pkt; -} - -/** - * Creates a test packet from data array and loops it through the test pktio - * interfaces forcing packet parsing. - */ -static odp_packet_t loopback_packet(pktio_info_t *pktio_a, - pktio_info_t *pktio_b, const uint8_t *data, - uint32_t len) -{ - odp_packet_t pkt; - odp_packet_t sent_pkt; - - pkt = create_packet(data, len); - if (pkt == ODP_PACKET_INVALID) { - CU_FAIL("failed to generate test packet"); - return ODP_PACKET_INVALID; - } - - pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); - - sent_pkt = odp_packet_copy(pkt, parser_pool); - if (sent_pkt == ODP_PACKET_INVALID) { - CU_FAIL_FATAL("failed to copy test packet"); - odp_packet_free(pkt); - return ODP_PACKET_INVALID; - } - - while (1) { - int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); - - if (ret < 0) { - CU_FAIL_FATAL("failed to send test packet"); - odp_packet_free(pkt); - odp_packet_free(sent_pkt); - return ODP_PACKET_INVALID; - } - if (ret == 1) - break; - } - - /* and wait for them to arrive back */ - pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); - odp_packet_free(sent_pkt); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); - CU_ASSERT(odp_packet_has_error(pkt) == 0); - - return pkt; -} - -void parser_test_arp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, - sizeof(test_packet_arp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_arp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_icmp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, - sizeof(test_packet_ipv4_icmp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_icmp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_tcp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, - sizeof(test_packet_ipv4_tcp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_tcp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, - sizeof(test_packet_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, - sizeof(test_packet_vlan_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_qinq_ipv4_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, - sizeof(test_packet_vlan_qinq_ipv4_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); - CU_ASSERT(odp_packet_has_ipv4(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv6(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_icmp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, - sizeof(test_packet_ipv6_icmp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_icmp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_tcp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, - sizeof(test_packet_ipv6_tcp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_tcp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_udp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_ipv6_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, - sizeof(test_packet_ipv6_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -void parser_test_vlan_ipv6_udp(void) -{ - odp_packet_t pkt; - - pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, - sizeof(test_packet_vlan_ipv6_udp)); - CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); - CU_ASSERT(odp_packet_has_eth(pkt)); - CU_ASSERT(odp_packet_has_vlan(pkt)); - CU_ASSERT(odp_packet_has_ipv6(pkt)); - CU_ASSERT(odp_packet_has_udp(pkt)); - - CU_ASSERT(!odp_packet_has_ipv4(pkt)); - CU_ASSERT(!odp_packet_has_tcp(pkt)); - - odp_packet_free(pkt); -} - -int parser_suite_init(void) -{ - int i; - - if (getenv("ODP_WAIT_FOR_NETWORK")) - wait_for_network = true; - - iface_name[0] = getenv("ODP_PKTIO_IF0"); - iface_name[1] = getenv("ODP_PKTIO_IF1"); - num_ifaces = 1; - - if (!iface_name[0]) { - printf("No interfaces specified, using default \"loop\".\n"); - iface_name[0] = "loop"; - } else if (!iface_name[1]) { - printf("Using loopback interface: %s\n", iface_name[0]); - } else { - num_ifaces = 2; - printf("Using paired interfaces: %s %s\n", - iface_name[0], iface_name[1]); - } - - if (pkt_pool_create() != 0) { - printf("Error: failed to create parser pool\n"); - return -1; - } - - /* Create pktios and associate input/output queues */ - for (i = 0; i < num_ifaces; ++i) { - pktio_info_t *io; - - io = &pktios[i]; - io->name = iface_name[i]; - io->hdl = create_pktio(i, parser_pool); - if (io->hdl == ODP_PKTIO_INVALID) { - printf("Error: failed to open iface"); - return -1; - } - - if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - if (odp_pktio_start(io->hdl)) { - printf("Error: failed to start iface: %s\n", io->name); - return -1; - } - - wait_linkup(io->hdl); - } - - pktio_a = &pktios[0]; - pktio_b = &pktios[1]; - if (num_ifaces == 1) - pktio_b = pktio_a; - - return 0; -} - -int parser_suite_term(void) -{ - int i; - int ret = 0; - - for (i = 0; i < num_ifaces; ++i) { - if (odp_pktio_stop(pktios[i].hdl)) { - printf("Error: failed to stop pktio: %s\n", - pktios[i].name); - ret = -1; - } - if (odp_pktio_close(pktios[i].hdl)) { - printf("Error: failed to close pktio: %s\n", - pktios[i].name); - ret = -1; - } - } - - if (odp_pool_destroy(parser_pool) != 0) { - printf("Error: failed to destroy packet pool\n"); - ret = -1; - } - - return ret; -} - -/** - * Certain tests can only be run with 'loop' pktio. - */ -static int loop_pktio(void) -{ - if (strcmp(iface_name[0], "loop") == 0) - return ODP_TEST_ACTIVE; - else - return ODP_TEST_INACTIVE; -} - -odp_testinfo_t parser_suite[] = { - ODP_TEST_INFO(parser_test_arp), - ODP_TEST_INFO(parser_test_ipv4_icmp), - ODP_TEST_INFO(parser_test_ipv4_tcp), - ODP_TEST_INFO(parser_test_ipv4_udp), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), - ODP_TEST_INFO(parser_test_ipv6_icmp), - ODP_TEST_INFO(parser_test_ipv6_tcp), - ODP_TEST_INFO(parser_test_ipv6_udp), - ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), - ODP_TEST_INFO_NULL -}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h deleted file mode 100644 index 57c623884..000000000 --- a/test/common_plat/validation/api/pktio/parser.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2017, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _ODP_TEST_PARSER_H_ -#define _ODP_TEST_PARSER_H_ - -#include - -/* test functions: */ -void parser_test_arp(void); -void parser_test_ipv4_icmp(void); -void parser_test_ipv4_tcp(void); -void parser_test_ipv4_udp(void); -void parser_test_vlan_ipv4_udp(void); -void parser_test_vlan_qinq_ipv4_udp(void); -void parser_test_ipv6_icmp(void); -void parser_test_ipv6_tcp(void); -void parser_test_ipv6_udp(void); -void parser_test_vlan_ipv6_udp(void); - -/* test array init/term functions: */ -int parser_suite_term(void); -int parser_suite_init(void); - -/* test arrays: */ -extern odp_testinfo_t parser_suite[]; - -/** - * ARP request - */ -static const uint8_t test_packet_arp[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, - 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, - 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, -}; - -/** - * ICMPv4 echo reply - */ -static const uint8_t test_packet_ipv4_icmp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, - 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, - 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, -}; - -/** - * IPv4 TCP - */ -static const uint8_t test_packet_ipv4_tcp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, - 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, - 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, -}; - -/** - * IPv4 UDP - */ -static const uint8_t test_packet_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, - 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, -}; - -/** - * VLAN IPv4 UDP - * - ID: 23 - */ -static const uint8_t test_packet_vlan_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, - 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, - 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, -}; - -/** - * VLAN Q-in-Q IPv4 UDP - * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 - * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 - */ -static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, - 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, - 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, - 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, - 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, -}; - -/** - * ICMPv6 echo request - */ -static const uint8_t test_packet_ipv6_icmp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, - 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, - 0x0E, 0xBA, -}; - -/** - * IPv6 TCP - */ -static const uint8_t test_packet_ipv6_tcp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, - 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, - 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, -}; - -/** - * IPv6 UDP - */ -static const uint8_t test_packet_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, - 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, - 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, - 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, - 0x64, 0x49, -}; - -/** - * VLAN IPv6 - * - ID: 23 - */ -static const uint8_t test_packet_vlan_ipv6_udp[] = { - 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, - 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, - 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, - 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, - 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, - 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, - 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, -}; - -#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index c476a7126..0e2a9f390 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,7 +10,6 @@ #include #include "pktio.h" -#include "parser.h" #define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -144,7 +143,8 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } } -void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) +static void pktio_pkt_set_macs(odp_packet_t pkt, + odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2192,7 +2192,6 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, - {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL }; diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index b8799d9eb..8131d05fe 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,7 +61,4 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]); -/* functions shared by parser test suite */ -void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); - #endif -- cgit v1.2.3 From 4418eef8a7b7f621047101f284ce5e5df44f0239 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 4 Apr 2017 09:28:21 +0300 Subject: validation: pktio: add tests for packet parsing Test packet parsing using predefined test packets (byte arrays). Test packets are looped through tested pktio interfaces to force packet parsing. Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/Makefile.am | 4 +- test/common_plat/validation/api/pktio/parser.c | 545 ++++++++++++++++++++++ test/common_plat/validation/api/pktio/parser.h | 180 +++++++ test/common_plat/validation/api/pktio/pktio.c | 5 +- test/common_plat/validation/api/pktio/pktio.h | 3 + 5 files changed, 733 insertions(+), 4 deletions(-) create mode 100644 test/common_plat/validation/api/pktio/parser.c create mode 100644 test/common_plat/validation/api/pktio/parser.h diff --git a/test/common_plat/validation/api/pktio/Makefile.am b/test/common_plat/validation/api/pktio/Makefile.am index 466d690dc..c6368fba3 100644 --- a/test/common_plat/validation/api/pktio/Makefile.am +++ b/test/common_plat/validation/api/pktio/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libtestpktio.la libtestpktio_la_SOURCES = pktio.c test_PROGRAMS = pktio_main$(EXEEXT) -dist_pktio_main_SOURCES = pktio_main.c +dist_pktio_main_SOURCES = pktio_main.c parser.c pktio_main_LDADD = libtestpktio.la $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = pktio.h +EXTRA_DIST = pktio.h parser.h diff --git a/test/common_plat/validation/api/pktio/parser.c b/test/common_plat/validation/api/pktio/parser.c new file mode 100644 index 000000000..ad7101d08 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.c @@ -0,0 +1,545 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include + +#include +#include "parser.h" +#include "pktio.h" + +#define MAX_NUM_IFACES 2 +#define PKT_POOL_NUM 256 +#define PKT_POOL_BUF_LEN (2 * 1024) + +/** + * local container for pktio attributes + */ +typedef struct { + const char *name; + odp_pktio_t hdl; + odp_pktout_queue_t pktout; + odp_pktin_queue_t pktin; +} pktio_info_t; + +/** Interface names used for testing */ +static const char *iface_name[MAX_NUM_IFACES]; + +/** Test interfaces */ +pktio_info_t pktios[MAX_NUM_IFACES]; +pktio_info_t *pktio_a; +pktio_info_t *pktio_b; + +/** Number of interfaces being used (1=loopback, 2=pair) */ +static int num_ifaces; + +/** While testing real-world interfaces additional time may be needed for + * external network to enable link to pktio interface that just become up. + */ +static bool wait_for_network; + +/** Parser packet pool */ +odp_pool_t parser_pool = ODP_POOL_INVALID; + +static inline void wait_linkup(odp_pktio_t pktio) +{ + /* wait 1 second for link up */ + uint64_t wait_ns = (10 * ODP_TIME_MSEC_IN_NS); + int wait_num = 100; + int i; + int ret = -1; + + for (i = 0; i < wait_num; i++) { + ret = odp_pktio_link_status(pktio); + if (ret < 0 || ret == 1) + break; + /* link is down, call status again after delay */ + odp_time_wait_ns(wait_ns); + } +} + +static int pkt_pool_create(void) +{ + odp_pool_capability_t capa; + odp_pool_param_t params; + + if (odp_pool_capability(&capa) != 0) { + printf("Error: unable to query pool capability.\n"); + return -1; + } + + if (capa.pkt.max_num && capa.pkt.max_num < PKT_POOL_NUM) { + printf("Error: packet pool size not supported.\n"); + printf("MAX: %" PRIu32 "\n", capa.pkt.max_num); + return -1; + } else if (capa.pkt.max_len && capa.pkt.max_len < PKT_POOL_BUF_LEN) { + printf("Error: packet length not supported.\n"); + return -1; + } else if (capa.pkt.max_seg_len && + capa.pkt.max_seg_len < PKT_POOL_BUF_LEN) { + printf("Error: segment length not supported.\n"); + return -1; + } + + odp_pool_param_init(¶ms); + params.pkt.seg_len = PKT_POOL_BUF_LEN; + params.pkt.len = PKT_POOL_BUF_LEN; + params.pkt.num = PKT_POOL_NUM; + params.type = ODP_POOL_PACKET; + + parser_pool = odp_pool_create("pkt_pool_default", ¶ms); + if (parser_pool == ODP_POOL_INVALID) { + printf("Error: packet pool create failed.\n"); + return -1; + } + + return 0; +} + +static odp_pktio_t create_pktio(int iface_idx, odp_pool_t pool) +{ + odp_pktio_t pktio; + odp_pktio_config_t config; + odp_pktio_param_t pktio_param; + const char *iface = iface_name[iface_idx]; + + odp_pktio_param_init(&pktio_param); + pktio_param.in_mode = ODP_PKTIN_MODE_DIRECT; + pktio_param.out_mode = ODP_PKTOUT_MODE_DIRECT; + + pktio = odp_pktio_open(iface, pool, &pktio_param); + if (pktio == ODP_PKTIO_INVALID) { + printf("Error: failed to open %s\n", iface); + return ODP_PKTIO_INVALID; + } + + odp_pktio_config_init(&config); + config.parser.layer = ODP_PKTIO_PARSER_LAYER_ALL; + if (odp_pktio_config(pktio, &config)) { + printf("Error: failed to configure %s\n", iface); + return ODP_PKTIO_INVALID; + } + + /* By default, single input and output queue is used */ + if (odp_pktin_queue_config(pktio, NULL)) { + printf("Error: failed to config input queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + if (odp_pktout_queue_config(pktio, NULL)) { + printf("Error: failed to config output queue for %s\n", iface); + return ODP_PKTIO_INVALID; + } + + if (wait_for_network) + odp_time_wait_ns(ODP_TIME_SEC_IN_NS / 4); + + return pktio; +} + +static odp_packet_t create_packet(const uint8_t *data, uint32_t len) +{ + odp_packet_t pkt; + + pkt = odp_packet_alloc(parser_pool, len); + if (pkt == ODP_PACKET_INVALID) + return ODP_PACKET_INVALID; + + if (odp_packet_copy_from_mem(pkt, 0, len, data)) { + printf("Error: failed to copy test packet data\n"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + odp_packet_l2_offset_set(pkt, 0); + + return pkt; +} + +/** + * Receive incoming packets and compare them to the original. Function returns + * a valid packet handle only when the received packet matches to the original + * packet. + */ +static odp_packet_t recv_and_cmp_packet(odp_pktin_queue_t pktin, + odp_packet_t orig_pkt, uint64_t ns) +{ + odp_packet_t pkt = ODP_PACKET_INVALID; + odp_time_t wait_time, end; + uint32_t orig_len; + uint8_t *orig_data; + + orig_len = odp_packet_len(orig_pkt); + orig_data = odp_packet_data(orig_pkt); + wait_time = odp_time_local_from_ns(ns); + end = odp_time_sum(odp_time_local(), wait_time); + + do { + int ret; + odp_packet_t tmp_pkt; + + ret = odp_pktin_recv(pktin, &tmp_pkt, 1); + if (ret < 0) + break; + + if (ret == 1) { + uint32_t len; + uint8_t *data; + + len = odp_packet_len(tmp_pkt); + data = odp_packet_data(tmp_pkt); + + if (len == orig_len && + memcmp(data, orig_data, len) == 0) { + pkt = tmp_pkt; + break; + } + odp_packet_free(tmp_pkt); + } + } while (odp_time_cmp(end, odp_time_local()) > 0); + + return pkt; +} + +/** + * Creates a test packet from data array and loops it through the test pktio + * interfaces forcing packet parsing. + */ +static odp_packet_t loopback_packet(pktio_info_t *pktio_a, + pktio_info_t *pktio_b, const uint8_t *data, + uint32_t len) +{ + odp_packet_t pkt; + odp_packet_t sent_pkt; + + pkt = create_packet(data, len); + if (pkt == ODP_PACKET_INVALID) { + CU_FAIL("failed to generate test packet"); + return ODP_PACKET_INVALID; + } + + pktio_pkt_set_macs(pkt, pktio_a->hdl, pktio_b->hdl); + + sent_pkt = odp_packet_copy(pkt, parser_pool); + if (sent_pkt == ODP_PACKET_INVALID) { + CU_FAIL_FATAL("failed to copy test packet"); + odp_packet_free(pkt); + return ODP_PACKET_INVALID; + } + + while (1) { + int ret = odp_pktout_send(pktio_a->pktout, &pkt, 1); + + if (ret < 0) { + CU_FAIL_FATAL("failed to send test packet"); + odp_packet_free(pkt); + odp_packet_free(sent_pkt); + return ODP_PACKET_INVALID; + } + if (ret == 1) + break; + } + + /* and wait for them to arrive back */ + pkt = recv_and_cmp_packet(pktio_b->pktin, sent_pkt, ODP_TIME_SEC_IN_NS); + odp_packet_free(sent_pkt); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_input(pkt) == pktio_b->hdl); + CU_ASSERT(odp_packet_has_error(pkt) == 0); + + return pkt; +} + +void parser_test_arp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_arp, + sizeof(test_packet_arp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_arp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_icmp, + sizeof(test_packet_ipv4_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_tcp, + sizeof(test_packet_ipv4_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv4_udp, + sizeof(test_packet_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv4_udp, + sizeof(test_packet_vlan_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_qinq_ipv4_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_qinq_ipv4_udp, + sizeof(test_packet_vlan_qinq_ipv4_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_vlan_qinq(pkt)); + CU_ASSERT(odp_packet_has_ipv4(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv6(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_icmp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_icmp, + sizeof(test_packet_ipv6_icmp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_icmp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_tcp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_tcp, + sizeof(test_packet_ipv6_tcp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_tcp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_udp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_ipv6_udp, + sizeof(test_packet_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +void parser_test_vlan_ipv6_udp(void) +{ + odp_packet_t pkt; + + pkt = loopback_packet(pktio_a, pktio_b, test_packet_vlan_ipv6_udp, + sizeof(test_packet_vlan_ipv6_udp)); + CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID); + CU_ASSERT(odp_packet_has_eth(pkt)); + CU_ASSERT(odp_packet_has_vlan(pkt)); + CU_ASSERT(odp_packet_has_ipv6(pkt)); + CU_ASSERT(odp_packet_has_udp(pkt)); + + CU_ASSERT(!odp_packet_has_ipv4(pkt)); + CU_ASSERT(!odp_packet_has_tcp(pkt)); + + odp_packet_free(pkt); +} + +int parser_suite_init(void) +{ + int i; + + if (getenv("ODP_WAIT_FOR_NETWORK")) + wait_for_network = true; + + iface_name[0] = getenv("ODP_PKTIO_IF0"); + iface_name[1] = getenv("ODP_PKTIO_IF1"); + num_ifaces = 1; + + if (!iface_name[0]) { + printf("No interfaces specified, using default \"loop\".\n"); + iface_name[0] = "loop"; + } else if (!iface_name[1]) { + printf("Using loopback interface: %s\n", iface_name[0]); + } else { + num_ifaces = 2; + printf("Using paired interfaces: %s %s\n", + iface_name[0], iface_name[1]); + } + + if (pkt_pool_create() != 0) { + printf("Error: failed to create parser pool\n"); + return -1; + } + + /* Create pktios and associate input/output queues */ + for (i = 0; i < num_ifaces; ++i) { + pktio_info_t *io; + + io = &pktios[i]; + io->name = iface_name[i]; + io->hdl = create_pktio(i, parser_pool); + if (io->hdl == ODP_PKTIO_INVALID) { + printf("Error: failed to open iface"); + return -1; + } + + if (odp_pktout_queue(io->hdl, &io->pktout, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktin_queue(io->hdl, &io->pktin, 1) != 1) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + if (odp_pktio_start(io->hdl)) { + printf("Error: failed to start iface: %s\n", io->name); + return -1; + } + + wait_linkup(io->hdl); + } + + pktio_a = &pktios[0]; + pktio_b = &pktios[1]; + if (num_ifaces == 1) + pktio_b = pktio_a; + + return 0; +} + +int parser_suite_term(void) +{ + int i; + int ret = 0; + + for (i = 0; i < num_ifaces; ++i) { + if (odp_pktio_stop(pktios[i].hdl)) { + printf("Error: failed to stop pktio: %s\n", + pktios[i].name); + ret = -1; + } + if (odp_pktio_close(pktios[i].hdl)) { + printf("Error: failed to close pktio: %s\n", + pktios[i].name); + ret = -1; + } + } + + if (odp_pool_destroy(parser_pool) != 0) { + printf("Error: failed to destroy packet pool\n"); + ret = -1; + } + + return ret; +} + +/** + * Certain tests can only be run with 'loop' pktio. + */ +static int loop_pktio(void) +{ + if (strcmp(iface_name[0], "loop") == 0) + return ODP_TEST_ACTIVE; + else + return ODP_TEST_INACTIVE; +} + +odp_testinfo_t parser_suite[] = { + ODP_TEST_INFO(parser_test_arp), + ODP_TEST_INFO(parser_test_ipv4_icmp), + ODP_TEST_INFO(parser_test_ipv4_tcp), + ODP_TEST_INFO(parser_test_ipv4_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv4_udp, loop_pktio), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_qinq_ipv4_udp, loop_pktio), + ODP_TEST_INFO(parser_test_ipv6_icmp), + ODP_TEST_INFO(parser_test_ipv6_tcp), + ODP_TEST_INFO(parser_test_ipv6_udp), + ODP_TEST_INFO_CONDITIONAL(parser_test_vlan_ipv6_udp, loop_pktio), + ODP_TEST_INFO_NULL +}; diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h new file mode 100644 index 000000000..57c623884 --- /dev/null +++ b/test/common_plat/validation/api/pktio/parser.h @@ -0,0 +1,180 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_PARSER_H_ +#define _ODP_TEST_PARSER_H_ + +#include + +/* test functions: */ +void parser_test_arp(void); +void parser_test_ipv4_icmp(void); +void parser_test_ipv4_tcp(void); +void parser_test_ipv4_udp(void); +void parser_test_vlan_ipv4_udp(void); +void parser_test_vlan_qinq_ipv4_udp(void); +void parser_test_ipv6_icmp(void); +void parser_test_ipv6_tcp(void); +void parser_test_ipv6_udp(void); +void parser_test_vlan_ipv6_udp(void); + +/* test array init/term functions: */ +int parser_suite_term(void); +int parser_suite_init(void); + +/* test arrays: */ +extern odp_testinfo_t parser_suite[]; + +/** + * ARP request + */ +static const uint8_t test_packet_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x06, 0x00, 0x01, + 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0xC0, 0xA8, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, + 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, +}; + +/** + * ICMPv4 echo reply + */ +static const uint8_t test_packet_ipv4_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0xF3, 0x7B, 0xC0, 0xA8, 0x01, 0x01, 0xC4, 0xA8, + 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, +}; + +/** + * IPv4 TCP + */ +static const uint8_t test_packet_ipv4_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, + 0xF3, 0x76, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, + 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, +}; + +/** + * IPv4 UDP + */ +static const uint8_t test_packet_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x6B, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, + 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, +}; + +/** + * VLAN IPv4 UDP + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x08, 0x00, 0x45, 0x00, 0x00, 0x2A, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x11, 0xF3, 0x6F, 0xC0, 0xA8, + 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, +}; + +/** + * VLAN Q-in-Q IPv4 UDP + * - Outer: Tag Protocol ID 0x88a8, VLAN ID 1 + * - Inner: Tag Protocol ID 0x8100, VLAN ID 2 + */ +static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x88, 0xA8, 0x00, 0x01, + 0x81, 0x00, 0x00, 0x02, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, + 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, + 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, + 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, +}; + +/** + * ICMPv6 echo request + */ +static const uint8_t test_packet_ipv6_icmp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x3A, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, + 0x0E, 0xBA, +}; + +/** + * IPv6 TCP + */ +static const uint8_t test_packet_ipv6_tcp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x14, 0x06, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, + 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, + 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, +}; + +/** + * IPv6 UDP + */ +static const uint8_t test_packet_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x86, 0xDD, 0x60, 0x30, + 0x00, 0x00, 0x00, 0x08, 0x11, 0xFF, 0xFE, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, + 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, + 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, + 0x64, 0x49, +}; + +/** + * VLAN IPv6 + * - ID: 23 + */ +static const uint8_t test_packet_vlan_ipv6_udp[] = { + 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x04, 0x00, 0x81, 0x00, 0x00, 0x17, + 0x86, 0xDD, 0x60, 0x30, 0x00, 0x00, 0x00, 0x08, + 0x11, 0xFF, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x09, 0xFF, 0xFE, 0x00, + 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, + 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, + 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, + 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, +}; + +#endif diff --git a/test/common_plat/validation/api/pktio/pktio.c b/test/common_plat/validation/api/pktio/pktio.c index 0e2a9f390..c476a7126 100644 --- a/test/common_plat/validation/api/pktio/pktio.c +++ b/test/common_plat/validation/api/pktio/pktio.c @@ -10,6 +10,7 @@ #include #include "pktio.h" +#include "parser.h" #define PKT_BUF_NUM 32 #define PKT_BUF_SIZE (9 * 1024) @@ -143,8 +144,7 @@ static void set_pool_len(odp_pool_param_t *params, odp_pool_capability_t *capa) } } -static void pktio_pkt_set_macs(odp_packet_t pkt, - odp_pktio_t src, odp_pktio_t dst) +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); @@ -2192,6 +2192,7 @@ odp_suiteinfo_t pktio_suites[] = { pktio_suite_term, pktio_suite_unsegmented}, {"Packet I/O Segmented", pktio_suite_init_segmented, pktio_suite_term, pktio_suite_segmented}, + {"Packet parser", parser_suite_init, parser_suite_term, parser_suite}, ODP_SUITE_INFO_NULL }; diff --git a/test/common_plat/validation/api/pktio/pktio.h b/test/common_plat/validation/api/pktio/pktio.h index 8131d05fe..b8799d9eb 100644 --- a/test/common_plat/validation/api/pktio/pktio.h +++ b/test/common_plat/validation/api/pktio/pktio.h @@ -61,4 +61,7 @@ extern odp_suiteinfo_t pktio_suites[]; /* main test program: */ int pktio_main(int argc, char *argv[]); +/* functions shared by parser test suite */ +void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst); + #endif -- cgit v1.2.3 From a074bc12f6a960c195daf3ceb28e3f717cfc3aa2 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Thu, 6 Apr 2017 17:41:17 +0300 Subject: validation: pktio: remove CRCs from parser test packets Remove precalculated CRCs from test packets. Some pktio devices may drop CRCs causing the tests to fail. Signed-off-by: Matias Elo Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/pktio/parser.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/common_plat/validation/api/pktio/parser.h b/test/common_plat/validation/api/pktio/parser.h index 57c623884..5cc2b988c 100644 --- a/test/common_plat/validation/api/pktio/parser.h +++ b/test/common_plat/validation/api/pktio/parser.h @@ -28,6 +28,8 @@ int parser_suite_init(void); /* test arrays: */ extern odp_testinfo_t parser_suite[]; +/* Test packets without CRC */ + /** * ARP request */ @@ -39,7 +41,7 @@ static const uint8_t test_packet_arp[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xA1, 0xA8, 0x27, 0x43, + 0x0E, 0x0F, 0x10, 0x11 }; /** @@ -53,7 +55,7 @@ static const uint8_t test_packet_ipv4_icmp[] = { 0x01, 0x02, 0x00, 0x00, 0xB7, 0xAB, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0xD9, 0x7F, 0xE8, 0x02, + 0x0E, 0x0F, 0x10, 0x11 }; /** @@ -67,7 +69,7 @@ static const uint8_t test_packet_ipv4_tcp[] = { 0x01, 0x01, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x0C, 0xCC, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x2E, 0xDE, 0x5E, 0x48, + 0x02, 0x03, 0x04, 0x05 }; /** @@ -81,7 +83,7 @@ static const uint8_t test_packet_ipv4_udp[] = { 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1A, 0x2F, 0x97, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, 0x10, 0x11, 0x64, 0xF4, 0xE4, 0xB6, + 0x0E, 0x0F, 0x10, 0x11 }; /** @@ -96,7 +98,7 @@ static const uint8_t test_packet_vlan_ipv4_udp[] = { 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x16, 0x4D, 0xBF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x0C, 0x0D, 0xCB, 0xBF, 0xD0, 0x29, + 0x0A, 0x0B, 0x0C, 0x0D }; /** @@ -112,7 +114,7 @@ static const uint8_t test_packet_vlan_qinq_ipv4_udp[] = { 0xF3, 0x73, 0xC0, 0xA8, 0x01, 0x02, 0xC4, 0xA8, 0x01, 0x01, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x12, 0x63, 0xDF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x80, 0x98, 0xB8, 0x18, + 0x06, 0x07, 0x08, 0x09 }; /** @@ -126,8 +128,7 @@ static const uint8_t test_packet_ipv6_icmp[] = { 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, - 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02, 0xE0, 0x68, - 0x0E, 0xBA, + 0x1B, 0xC2, 0x00, 0x01, 0x00, 0x02 }; /** @@ -143,7 +144,7 @@ static const uint8_t test_packet_ipv6_tcp[] = { 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x04, 0xD2, 0x10, 0xE1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x00, 0x36, 0x37, - 0x00, 0x00, 0x28, 0x67, 0xD2, 0xAF, + 0x00, 0x00 }; /** @@ -157,8 +158,7 @@ static const uint8_t test_packet_ipv6_udp[] = { 0x09, 0xFF, 0xFE, 0x00, 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, - 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68, 0x35, 0xD3, - 0x64, 0x49, + 0x00, 0x3F, 0x00, 0x08, 0x9B, 0x68 }; /** @@ -174,7 +174,7 @@ static const uint8_t test_packet_vlan_ipv6_udp[] = { 0x04, 0x00, 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x08, - 0x9B, 0x68, 0xC5, 0xD8, 0x2F, 0x5C, + 0x9B, 0x68 }; #endif -- cgit v1.2.3 From 48ad38ac169c48ac67e0758d3d45eb146255ed09 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 13 Apr 2017 17:40:50 +0300 Subject: api: queue: added queue size param Added capability information about maximum number of queues and queue sizes. Both are defined per queue type, since plain and scheduled queues may have different implementations (e.g. one uses HW while the other is SW). Added queue size parameter, which specifies how large storage size application requires in minimum. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Reviewed-by: Honnappa Nagarahalli Reviewed-by: Balasubramanian Manoharan Signed-off-by: Maxim Uvarov --- include/odp/api/spec/queue.h | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/include/odp/api/spec/queue.h b/include/odp/api/spec/queue.h index 7972feacb..9dd0a5618 100644 --- a/include/odp/api/spec/queue.h +++ b/include/odp/api/spec/queue.h @@ -100,7 +100,9 @@ typedef enum odp_queue_op_mode_t { * Queue capabilities */ typedef struct odp_queue_capability_t { - /** Maximum number of event queues */ + /** Maximum number of event queues of any type (default size). Use + * this in addition to queue type specific 'max_num', if both queue + * types are used simultaneously. */ uint32_t max_queues; /** Maximum number of ordered locks per queue */ @@ -112,6 +114,32 @@ typedef struct odp_queue_capability_t { /** Number of scheduling priorities */ unsigned sched_prios; + /** Plain queue capabilities */ + struct { + /** Maximum number of plain queues of the default size. */ + uint32_t max_num; + + /** Maximum number of events a plain queue can store + * simultaneously. The value of zero means that plain + * queues do not have a size limit, but a single queue can + * store all available events. */ + uint32_t max_size; + + } plain; + + /** Scheduled queue capabilities */ + struct { + /** Maximum number of scheduled queues of the default size. */ + uint32_t max_num; + + /** Maximum number of events a scheduled queue can store + * simultaneously. The value of zero means that scheduled + * queues do not have a size limit, but a single queue can + * store all available events. */ + uint32_t max_size; + + } sched; + } odp_queue_capability_t; /** @@ -165,6 +193,15 @@ typedef struct odp_queue_param_t { * The implementation may use this value as a hint for the number of * context data bytes to prefetch. Default value is zero (no hint). */ uint32_t context_len; + + /** Queue size + * + * The queue must be able to store at minimum this many events + * simultaneously. The value must not exceed 'max_size' queue + * capability. The value of zero means implementation specific + * default size. */ + uint32_t size; + } odp_queue_param_t; /** -- cgit v1.2.3 From 8367530231e7cd4c33c63b789a5ed8322b51e58f Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Thu, 13 Apr 2017 17:40:51 +0300 Subject: validation: queue: test queue max_num per type Updated implementation and test with type specific number of queues. Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Reviewed-by: Honnappa Nagarahalli Reviewed-by: Balasubramanian Manoharan Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_queue.c | 2 ++ test/common_plat/validation/api/queue/queue.c | 49 +++++++++++++++++---------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index a96f9225f..dd430cd12 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -176,6 +176,8 @@ int odp_queue_capability(odp_queue_capability_t *capa) capa->max_ordered_locks = sched_fn->max_ordered_locks(); capa->max_sched_groups = sched_fn->num_grps(); capa->sched_prios = odp_schedule_num_prio(); + capa->plain.max_num = capa->max_queues; + capa->sched.max_num = capa->max_queues; return 0; } diff --git a/test/common_plat/validation/api/queue/queue.c b/test/common_plat/validation/api/queue/queue.c index 1f7913a12..6a13c0062 100644 --- a/test/common_plat/validation/api/queue/queue.c +++ b/test/common_plat/validation/api/queue/queue.c @@ -56,7 +56,7 @@ void queue_test_capa(void) odp_queue_param_t qparams; char name[ODP_QUEUE_NAME_LEN]; odp_queue_t queue[MAX_QUEUES]; - uint32_t num_queues, i; + uint32_t num_queues, min, i, j; memset(&capa, 0, sizeof(odp_queue_capability_t)); CU_ASSERT(odp_queue_capability(&capa) == 0); @@ -65,34 +65,49 @@ void queue_test_capa(void) CU_ASSERT(capa.max_ordered_locks != 0); CU_ASSERT(capa.max_sched_groups != 0); CU_ASSERT(capa.sched_prios != 0); + CU_ASSERT(capa.plain.max_num != 0); + CU_ASSERT(capa.sched.max_num != 0); + + min = capa.plain.max_num; + if (min > capa.sched.max_num) + min = capa.sched.max_num; + + CU_ASSERT(capa.max_queues >= min); for (i = 0; i < ODP_QUEUE_NAME_LEN; i++) name[i] = 'A' + (i % 26); name[ODP_QUEUE_NAME_LEN - 1] = 0; - if (capa.max_queues > MAX_QUEUES) - num_queues = MAX_QUEUES; - else - num_queues = capa.max_queues; - odp_queue_param_init(&qparams); - for (i = 0; i < num_queues; i++) { - generate_name(name, i); - queue[i] = odp_queue_create(name, &qparams); + for (j = 0; j < 2; j++) { + if (j == 0) { + num_queues = capa.plain.max_num; + } else { + num_queues = capa.sched.max_num; + qparams.type = ODP_QUEUE_TYPE_SCHED; + } + + if (num_queues > MAX_QUEUES) + num_queues = MAX_QUEUES; - if (queue[i] == ODP_QUEUE_INVALID) { - CU_FAIL("Queue create failed"); - num_queues = i; - break; + for (i = 0; i < num_queues; i++) { + generate_name(name, i); + queue[i] = odp_queue_create(name, &qparams); + + if (queue[i] == ODP_QUEUE_INVALID) { + CU_FAIL("Queue create failed"); + num_queues = i; + break; + } + + CU_ASSERT(odp_queue_lookup(name) != ODP_QUEUE_INVALID); } - CU_ASSERT(odp_queue_lookup(name) != ODP_QUEUE_INVALID); + for (i = 0; i < num_queues; i++) + CU_ASSERT(odp_queue_destroy(queue[i]) == 0); } - - for (i = 0; i < num_queues; i++) - CU_ASSERT(odp_queue_destroy(queue[i]) == 0); } void queue_test_mode(void) -- cgit v1.2.3 From 20d0d4d1a34725dec053ecd7cd46979345f7d625 Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Tue, 11 Apr 2017 10:38:06 +0800 Subject: validation: scheduler: modify the queue size for atomic queue Signed-off-by: Kevin Wang Reviewed-by: Honnappa Nagarahalli Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/scheduler/scheduler.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c index 952561cd3..f46d3910f 100644 --- a/test/common_plat/validation/api/scheduler/scheduler.c +++ b/test/common_plat/validation/api/scheduler/scheduler.c @@ -1388,6 +1388,7 @@ static int create_queues(void) snprintf(name, sizeof(name), "sched_%d_%d_a", i, j); p.sched.sync = ODP_SCHED_SYNC_ATOMIC; + p.size = BUFS_PER_QUEUE_EXCL; q = odp_queue_create(name, &p); if (q == ODP_QUEUE_INVALID) { @@ -1423,6 +1424,7 @@ static int create_queues(void) snprintf(name, sizeof(name), "sched_%d_%d_o", i, j); p.sched.sync = ODP_SCHED_SYNC_ORDERED; p.sched.lock_count = capa.max_ordered_locks; + p.size = 0; q = odp_queue_create(name, &p); if (q == ODP_QUEUE_INVALID) { -- cgit v1.2.3 From 87b108d54a697b0c3704342ec7b4d484d04dfdbb Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Fri, 14 Apr 2017 10:57:21 +0800 Subject: validation: scheduler: release context according to scheduler sync type For different scheduler sync type, need to call different release function. Signed-off-by: Kevin Wang Reviewed-by: Honnappa Nagarahalli Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/scheduler/scheduler.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/common_plat/validation/api/scheduler/scheduler.c b/test/common_plat/validation/api/scheduler/scheduler.c index f46d3910f..4f99435c9 100644 --- a/test/common_plat/validation/api/scheduler/scheduler.c +++ b/test/common_plat/validation/api/scheduler/scheduler.c @@ -129,6 +129,14 @@ static int exit_schedule_loop(void) return ret; } +static void release_context(odp_schedule_sync_t sync) +{ + if (sync == ODP_SCHED_SYNC_ATOMIC) + odp_schedule_release_atomic(); + else if (sync == ODP_SCHED_SYNC_ORDERED) + odp_schedule_release_ordered(); +} + void scheduler_test_wait_time(void) { int i; @@ -251,8 +259,7 @@ void scheduler_test_queue_destroy(void) CU_ASSERT_FATAL(u32[0] == MAGIC); odp_buffer_free(buf); - odp_schedule_release_ordered(); - + release_context(qp.sched.sync); CU_ASSERT_FATAL(odp_queue_destroy(queue) == 0); } @@ -820,12 +827,7 @@ static int schedule_common_(void *arg) } } - if (sync == ODP_SCHED_SYNC_ATOMIC) - odp_schedule_release_atomic(); - - if (sync == ODP_SCHED_SYNC_ORDERED) - odp_schedule_release_ordered(); - + release_context(sync); odp_ticketlock_lock(&globals->lock); globals->buf_count -= num; -- cgit v1.2.3 From 867d8fc93d074005b52375995b9beed4a896c1ed Mon Sep 17 00:00:00 2001 From: Honnappa Nagarahalli Date: Thu, 6 Apr 2017 23:07:04 -0500 Subject: helper: cuckoo: add queue size config to cuckoo table Some queue implementations in ODP take queue size input. Cuckoo table is modified to provide the queue size input while creating the queue. Signed-off-by: Honnappa Nagarahalli Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- helper/cuckootable.c | 1 + 1 file changed, 1 insertion(+) diff --git a/helper/cuckootable.c b/helper/cuckootable.c index 80ff49893..0d46300e0 100644 --- a/helper/cuckootable.c +++ b/helper/cuckootable.c @@ -256,6 +256,7 @@ odph_cuckoo_table_create( /* initialize free_slots queue */ odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_PLAIN; + qparam.size = capacity; snprintf(queue_name, sizeof(queue_name), "fs_%s", name); queue = odp_queue_create(queue_name, &qparam); -- cgit v1.2.3 From 583dbc9adab460c926339353cc882095594b5b60 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 09:25:22 -0500 Subject: api: pool: add additional doxygen documentation Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher. Signed-off-by: Bill Fischofer Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- include/odp/api/spec/pool.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/odp/api/spec/pool.h b/include/odp/api/spec/pool.h index c0de195a7..6fc5b6b4a 100644 --- a/include/odp/api/spec/pool.h +++ b/include/odp/api/spec/pool.h @@ -166,7 +166,9 @@ typedef struct odp_pool_param_t { /** Pool type */ int type; + /** Variant parameters for different pool types */ union { + /** Parameters for buffer pools */ struct { /** Number of buffers in the pool */ uint32_t num; @@ -180,6 +182,8 @@ typedef struct odp_pool_param_t { Default will always be a multiple of 8. */ uint32_t align; } buf; + + /** Parameters for packet pools */ struct { /** The number of packets that the pool must provide that are packet length 'len' bytes or smaller. @@ -211,6 +215,8 @@ typedef struct odp_pool_param_t { Specify as 0 if no user area is needed. */ uint32_t uarea_size; } pkt; + + /** Parameters for timeout pools */ struct { /** Number of timeouts in the pool */ uint32_t num; -- cgit v1.2.3 From b9676fc5ba51d0f26a9c8c40f0b65a003113f1b5 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 09:25:23 -0500 Subject: api: tm: add additional doxygen documentation Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher. Signed-off-by: Bill Fischofer Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- include/odp/api/spec/traffic_mngr.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/odp/api/spec/traffic_mngr.h b/include/odp/api/spec/traffic_mngr.h index 71198bbdd..3a748cef7 100644 --- a/include/odp/api/spec/traffic_mngr.h +++ b/include/odp/api/spec/traffic_mngr.h @@ -471,9 +471,10 @@ typedef enum { typedef struct { odp_tm_egress_kind_t egress_kind; /**< Union discriminator */ + /** Variant parameters for different TM outputs */ union { - odp_pktio_t pktio; - odp_tm_egress_fcn_t egress_fcn; + odp_pktio_t pktio; /**< Output to PktIO */ + odp_tm_egress_fcn_t egress_fcn; /**< Output to user func */ }; } odp_tm_egress_t; -- cgit v1.2.3 From af05215e26c99693c000981fddfaf3cdd2225e3f Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 09:25:24 -0500 Subject: linux-generic: types: add additional doxygen documentation Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher. Signed-off-by: Bill Fischofer Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp/api/debug.h | 8 ++++++++ platform/linux-generic/include/odp/api/plat/packet_types.h | 1 + platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/include/odp/api/debug.h b/platform/linux-generic/include/odp/api/debug.h index b0f91b1c9..bef2fd0eb 100644 --- a/platform/linux-generic/include/odp/api/debug.h +++ b/platform/linux-generic/include/odp/api/debug.h @@ -25,17 +25,23 @@ extern "C" { * versions. */ #define _odp_merge(a, b) a##b +/** @internal */ #define _odp_label(a) _odp_merge(_ODP_SASSERT_, a) +/** @internal */ #define _ODP_SASSERT _odp_label(__COUNTER__) +/** @internal */ #define _ODP_SASSERT_ENUM(e) { _ODP_SASSERT = 1 / !!(e) } +/** @internal */ #define _odp_static_assert(e, s) enum _ODP_SASSERT_ENUM(e) #if defined(__clang__) #if defined(__cplusplus) #if !__has_feature(cxx_static_assert) && !defined(static_assert) +/** @internal */ #define static_assert(e, s) _odp_static_assert(e, s) #endif #elif !__has_feature(c_static_assert) && !defined(_Static_assert) +/** @internal */ #define _Static_assert(e, s) _odp_static_assert(e, s) #endif @@ -44,9 +50,11 @@ extern "C" { (__GNUC__ < 6 && defined(__cplusplus)) #if defined(__cplusplus) #if !defined(static_assert) +/** @intenral */ #define static_assert(e, s) _odp_static_assert(e, s) #endif #elif !defined(_Static_assert) +/** @internal */ #define _Static_assert(e, s) _odp_static_assert(e, s) #endif #endif diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h index 7e3c51e6c..95cba5eb6 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h @@ -105,6 +105,7 @@ typedef union { /** All input flags */ uint64_t all; + /** Individual input flags */ struct { uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ diff --git a/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h b/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h index b766afecd..f47a13f6f 100644 --- a/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h +++ b/platform/linux-generic/include/odp/api/plat/traffic_mngr_types.h @@ -168,7 +168,7 @@ typedef odp_tm_handle_t odp_tm_wred_t; */ #define ODP_TM_ROOT ((odp_tm_handle_t)-1) -/** Get printable format of odp_queue_t */ +/** @internal Get printable format of odp_tm_handle_t @param hdl @return */ static inline uint64_t odp_tm_handle_to_u64(odp_tm_handle_t hdl) { return hdl; -- cgit v1.2.3 From 629be2dd2d166ed1246b8c1982af3a55a7035657 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 21 Apr 2017 09:25:25 -0500 Subject: helper: add additional doxygen documentation Resolve Bug https://bugs.linaro.org/show_bug.cgi?id=2952 by adding additional field documentation to avoid problems with doxygen 1.8.13 and higher. Signed-off-by: Bill Fischofer Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- helper/include/odp/helper/icmp.h | 11 ++++++---- helper/include/odp/helper/strong_types.h | 3 ++- helper/include/odp/helper/table.h | 2 +- helper/include/odp/helper/tcp.h | 35 ++++++++++++++++---------------- helper/include/odp/helper/threads.h | 7 +++++-- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/helper/include/odp/helper/icmp.h b/helper/include/odp/helper/icmp.h index e25646ad0..bef967842 100644 --- a/helper/include/odp/helper/icmp.h +++ b/helper/include/odp/helper/icmp.h @@ -32,15 +32,18 @@ typedef struct ODP_PACKED { uint8_t type; /**< message type */ uint8_t code; /**< type sub-code */ odp_u16sum_t chksum; /**< checksum of icmp header */ + /** Variant mappings of ICMP fields */ union { + /** Fields used for ICMP echo msgs */ struct { - odp_u16be_t id; - odp_u16be_t sequence; + odp_u16be_t id; /**< id */ + odp_u16be_t sequence; /**< sequence */ } echo; /**< echo datagram */ odp_u32be_t gateway; /**< gateway address */ + /** Fields used for ICMP frag msgs */ struct { - odp_u16be_t __unused; - odp_u16be_t mtu; + odp_u16be_t __unused; /**< @internal */ + odp_u16be_t mtu; /**< mtu */ } frag; /**< path mtu discovery */ } un; /**< icmp sub header */ } odph_icmphdr_t; diff --git a/helper/include/odp/helper/strong_types.h b/helper/include/odp/helper/strong_types.h index 13e35a438..501d0f28f 100644 --- a/helper/include/odp/helper/strong_types.h +++ b/helper/include/odp/helper/strong_types.h @@ -20,10 +20,11 @@ /** Use strong typing for ODP types */ #ifdef __cplusplus +/** @internal C++ helper macro for strong typing @param type @return */ #define ODPH_HANDLE_T(type) struct _##type { uint8_t unused_dummy_var; } *type #else #define odph_handle_t struct { uint8_t unused_dummy_var; } * -/** C/C++ helper macro for strong typing */ +/** @internal C helper macro for strong typing @param type @return */ #define ODPH_HANDLE_T(type) odph_handle_t type #endif diff --git a/helper/include/odp/helper/table.h b/helper/include/odp/helper/table.h index b3440ef53..96c9c5fe7 100644 --- a/helper/include/odp/helper/table.h +++ b/helper/include/odp/helper/table.h @@ -94,7 +94,7 @@ extern "C" { #define ODPH_TABLE_NAME_LEN 32 #include -/** ODP table handle */ +/** @internal ODPH table handle @return */ typedef ODPH_HANDLE_T(odph_table_t); /** diff --git a/helper/include/odp/helper/tcp.h b/helper/include/odp/helper/tcp.h index fd234e583..e91b52e24 100644 --- a/helper/include/odp/helper/tcp.h +++ b/helper/include/odp/helper/tcp.h @@ -32,8 +32,9 @@ typedef struct ODP_PACKED { odp_u16be_t dst_port; /**< Destination port */ odp_u32be_t seq_no; /**< Sequence number */ odp_u32be_t ack_no; /**< Acknowledgment number */ + /** Variant maps for TCP header fields */ union { - odp_u16be_t doffset_flags; + odp_u16be_t doffset_flags; /**< TCP Flags aggregate */ #if ODP_BIG_ENDIAN_BITFIELD struct { odp_u16be_t rsvd1:8; @@ -42,14 +43,14 @@ typedef struct ODP_PACKED { struct { odp_u16be_t hl:4; /**< Hdr len, in words */ odp_u16be_t rsvd3:4; /**< Reserved */ - odp_u16be_t cwr:1; - odp_u16be_t ece:1; - odp_u16be_t urg:1; - odp_u16be_t ack:1; - odp_u16be_t psh:1; - odp_u16be_t rst:1; - odp_u16be_t syn:1; - odp_u16be_t fin:1; + odp_u16be_t cwr:1; /**< cwr bit */ + odp_u16be_t ece:1; /**< ece bit */ + odp_u16be_t urg:1; /**< urg bit */ + odp_u16be_t ack:1; /**< ack bit */ + odp_u16be_t psh:1; /**< psh bit */ + odp_u16be_t rst:1; /**< rst bit */ + odp_u16be_t syn:1; /**< syn bit */ + odp_u16be_t fin:1; /**< fin bit */ }; #elif ODP_LITTLE_ENDIAN_BITFIELD struct { @@ -59,14 +60,14 @@ typedef struct ODP_PACKED { struct { odp_u16be_t rsvd3:4; /**< Reserved */ odp_u16be_t hl:4; /**< Hdr len, in words */ - odp_u16be_t fin:1; - odp_u16be_t syn:1; - odp_u16be_t rst:1; - odp_u16be_t psh:1; - odp_u16be_t ack:1; - odp_u16be_t urg:1; - odp_u16be_t ece:1; - odp_u16be_t cwr:1; + odp_u16be_t fin:1; /**< fin bit */ + odp_u16be_t syn:1; /**< syn bit */ + odp_u16be_t rst:1; /**< rst bit */ + odp_u16be_t psh:1; /**< psh bit */ + odp_u16be_t ack:1; /**< ack bit */ + odp_u16be_t urg:1; /**< urg bit */ + odp_u16be_t ece:1; /**< ece bit */ + odp_u16be_t cwr:1; /**< cwr bit */ }; #else diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h index 5682bab99..526f0d489 100644 --- a/helper/include/odp/helper/threads.h +++ b/helper/include/odp/helper/threads.h @@ -80,12 +80,15 @@ typedef struct { odph_odpthread_start_args_t start_args; /**< start arguments */ int cpu; /**< CPU ID */ int last; /**< true if last table entry */ + /** Variant field mappings for thread/process modes */ union { - struct { /* for thread implementation */ + /** For thread implementation */ + struct { pthread_t thread_id; /**< Pthread ID */ pthread_attr_t attr; /**< Pthread attributes */ } thread; - struct { /* for process implementation */ + /** For process implementation */ + struct { pid_t pid; /**< Process ID */ int status; /**< Process state chge status*/ } proc; -- cgit v1.2.3 From 4bb3025e76a81130e8e80cd582ae2433d3450e2b Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:48 +0300 Subject: api: time: remove odp_time_to_u64 from API Debug function that converts odp_time_t to u64 is unnecessary since odp_time_to_ns() returns time as a u64 (nsec) value. Application can always use that as the 64 bit representation of an odp_time_t value. Also validation tests for odp_time_to_u64() were erroneous since those compared returned u64 values and expected greater/lesser than relation. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/api/spec/time.h | 13 ---------- platform/linux-generic/odp_time.c | 15 ------------ test/common_plat/validation/api/time/time.c | 37 ----------------------------- test/common_plat/validation/api/time/time.h | 2 -- 4 files changed, 67 deletions(-) diff --git a/include/odp/api/spec/time.h b/include/odp/api/spec/time.h index fcc94c98e..29175eb5a 100644 --- a/include/odp/api/spec/time.h +++ b/include/odp/api/spec/time.h @@ -157,19 +157,6 @@ void odp_time_wait_until(odp_time_t time); */ void odp_time_wait_ns(uint64_t ns); -/** - * Get printable value for an odp_time_t - * - * @param time time to be printed - * - * @return uint64_t value that can be used to print/display this time - * - * @note This routine is intended to be used for diagnostic purposes - * to enable applications to generate a printable value that represents - * an odp_time_t time. - */ -uint64_t odp_time_to_u64(odp_time_t time); - /** * @} */ diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 81e05224c..0e5966c07 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -176,21 +176,6 @@ void odp_time_wait_until(odp_time_t time) return time_wait_until(time); } -uint64_t odp_time_to_u64(odp_time_t time) -{ - int ret; - struct timespec tres; - uint64_t resolution; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - resolution = (uint64_t)tres.tv_nsec; - - return time_to_ns(time) / resolution; -} - int odp_time_init_global(void) { int ret; diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c index 530d5c07a..df65c7195 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -398,41 +398,6 @@ void time_test_wait_ns(void) } } -static void time_test_to_u64(time_cb time) -{ - volatile int count = 0; - uint64_t val1, val2; - odp_time_t t1, t2; - - t1 = time(); - - val1 = odp_time_to_u64(t1); - CU_ASSERT(val1 > 0); - - while (count < BUSY_LOOP_CNT) { - count++; - }; - - t2 = time(); - val2 = odp_time_to_u64(t2); - CU_ASSERT(val2 > 0); - - CU_ASSERT(val2 > val1); - - val1 = odp_time_to_u64(ODP_TIME_NULL); - CU_ASSERT(val1 == 0); -} - -void time_test_local_to_u64(void) -{ - time_test_to_u64(odp_time_local); -} - -void time_test_global_to_u64(void) -{ - time_test_to_u64(odp_time_global); -} - odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), @@ -443,14 +408,12 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_sum), ODP_TEST_INFO(time_test_local_wait_until), ODP_TEST_INFO(time_test_wait_ns), - ODP_TEST_INFO(time_test_local_to_u64), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), - ODP_TEST_INFO(time_test_global_to_u64), ODP_TEST_INFO_NULL }; diff --git a/test/common_plat/validation/api/time/time.h b/test/common_plat/validation/api/time/time.h index e5132a494..109562944 100644 --- a/test/common_plat/validation/api/time/time.h +++ b/test/common_plat/validation/api/time/time.h @@ -24,8 +24,6 @@ void time_test_global_sum(void); void time_test_local_wait_until(void); void time_test_global_wait_until(void); void time_test_wait_ns(void); -void time_test_local_to_u64(void); -void time_test_global_to_u64(void); void time_test_monotony(void); /* test arrays: */ -- cgit v1.2.3 From 8f07f3de3da7961cd29046d2107f27a0f7391703 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:49 +0300 Subject: api: system: added system info print This information specifies the system where ODP application is running for debugging purposes. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- include/odp/api/spec/system_info.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/odp/api/spec/system_info.h b/include/odp/api/spec/system_info.h index 0bb4f1f12..ca4dcdc7a 100644 --- a/include/odp/api/spec/system_info.h +++ b/include/odp/api/spec/system_info.h @@ -44,6 +44,15 @@ uint64_t odp_sys_page_size(void); */ int odp_sys_cache_line_size(void); +/** + * Print system info + * + * Print out implementation defined information about the system. This + * information is intended for debugging purposes and may contain e.g. + * information about CPUs, memory and other HW configuration. + */ +void odp_sys_info_print(void); + /** * @} */ -- cgit v1.2.3 From 89a00a2ed43a99e0d2d78a5baeff1292e41ecd34 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:50 +0300 Subject: linux-gen: cpu_flags: added x86 cpu flag read functions When building on x86 CPU flags can be used to determine which CPU features are supported. CPU flag definitions and the code to read the flags is from DPDK. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- configure.ac | 1 + platform/Makefile.inc | 4 +- platform/linux-generic/Makefile.am | 4 + platform/linux-generic/arch/x86/cpu_flags.c | 359 ++++++++++++++++++++++++++++ platform/linux-generic/arch/x86/cpu_flags.h | 20 ++ 5 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 platform/linux-generic/arch/x86/cpu_flags.c create mode 100644 platform/linux-generic/arch/x86/cpu_flags.h diff --git a/configure.ac b/configure.ac index f6b20cb20..4f44f8f68 100644 --- a/configure.ac +++ b/configure.ac @@ -225,6 +225,7 @@ AM_CONDITIONAL([HAVE_DOXYGEN], [test "x${DOXYGEN}" = "xdoxygen"]) AM_CONDITIONAL([user_guide], [test "x${user_guides}" = "xyes" ]) AM_CONDITIONAL([HAVE_MSCGEN], [test "x${MSCGEN}" = "xmscgen"]) AM_CONDITIONAL([helper_linux], [test x$helper_linux = xyes ]) +AM_CONDITIONAL([ARCH_IS_X86], [test "x${ARCH_DIR}" = "xx86"]) ########################################################################## # Setup doxygen documentation diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 59a577241..9844a58a2 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -98,4 +98,6 @@ EXTRA_DIST = \ arch/powerpc/odp_sysinfo_parse.c \ arch/x86/odp/api/cpu_arch.h \ arch/x86/odp_cpu_arch.c \ - arch/x86/odp_sysinfo_parse.c + arch/x86/odp_sysinfo_parse.c \ + arch/x86/cpu_flags.c \ + arch/x86/cpu_flags.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index eb7bea8f3..15b8894d3 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -222,6 +222,10 @@ __LIB__libodp_linux_la_SOURCES = \ __LIB__libodp_linux_la_LIBADD = $(ATOMIC_LIBS) +if ARCH_IS_X86 +__LIB__libodp_linux_la_SOURCES += arch/@ARCH_DIR@/cpu_flags.c +endif + if HAVE_PCAP __LIB__libodp_linux_la_SOURCES += pktio/pcap.c endif diff --git a/platform/linux-generic/arch/x86/cpu_flags.c b/platform/linux-generic/arch/x86/cpu_flags.c new file mode 100644 index 000000000..954dac272 --- /dev/null +++ b/platform/linux-generic/arch/x86/cpu_flags.c @@ -0,0 +1,359 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +enum rte_cpu_flag_t { + /* (EAX 01h) ECX features*/ + RTE_CPUFLAG_SSE3 = 0, /**< SSE3 */ + RTE_CPUFLAG_PCLMULQDQ, /**< PCLMULQDQ */ + RTE_CPUFLAG_DTES64, /**< DTES64 */ + RTE_CPUFLAG_MONITOR, /**< MONITOR */ + RTE_CPUFLAG_DS_CPL, /**< DS_CPL */ + RTE_CPUFLAG_VMX, /**< VMX */ + RTE_CPUFLAG_SMX, /**< SMX */ + RTE_CPUFLAG_EIST, /**< EIST */ + RTE_CPUFLAG_TM2, /**< TM2 */ + RTE_CPUFLAG_SSSE3, /**< SSSE3 */ + RTE_CPUFLAG_CNXT_ID, /**< CNXT_ID */ + RTE_CPUFLAG_FMA, /**< FMA */ + RTE_CPUFLAG_CMPXCHG16B, /**< CMPXCHG16B */ + RTE_CPUFLAG_XTPR, /**< XTPR */ + RTE_CPUFLAG_PDCM, /**< PDCM */ + RTE_CPUFLAG_PCID, /**< PCID */ + RTE_CPUFLAG_DCA, /**< DCA */ + RTE_CPUFLAG_SSE4_1, /**< SSE4_1 */ + RTE_CPUFLAG_SSE4_2, /**< SSE4_2 */ + RTE_CPUFLAG_X2APIC, /**< X2APIC */ + RTE_CPUFLAG_MOVBE, /**< MOVBE */ + RTE_CPUFLAG_POPCNT, /**< POPCNT */ + RTE_CPUFLAG_TSC_DEADLINE, /**< TSC_DEADLINE */ + RTE_CPUFLAG_AES, /**< AES */ + RTE_CPUFLAG_XSAVE, /**< XSAVE */ + RTE_CPUFLAG_OSXSAVE, /**< OSXSAVE */ + RTE_CPUFLAG_AVX, /**< AVX */ + RTE_CPUFLAG_F16C, /**< F16C */ + RTE_CPUFLAG_RDRAND, /**< RDRAND */ + + /* (EAX 01h) EDX features */ + RTE_CPUFLAG_FPU, /**< FPU */ + RTE_CPUFLAG_VME, /**< VME */ + RTE_CPUFLAG_DE, /**< DE */ + RTE_CPUFLAG_PSE, /**< PSE */ + RTE_CPUFLAG_TSC, /**< TSC */ + RTE_CPUFLAG_MSR, /**< MSR */ + RTE_CPUFLAG_PAE, /**< PAE */ + RTE_CPUFLAG_MCE, /**< MCE */ + RTE_CPUFLAG_CX8, /**< CX8 */ + RTE_CPUFLAG_APIC, /**< APIC */ + RTE_CPUFLAG_SEP, /**< SEP */ + RTE_CPUFLAG_MTRR, /**< MTRR */ + RTE_CPUFLAG_PGE, /**< PGE */ + RTE_CPUFLAG_MCA, /**< MCA */ + RTE_CPUFLAG_CMOV, /**< CMOV */ + RTE_CPUFLAG_PAT, /**< PAT */ + RTE_CPUFLAG_PSE36, /**< PSE36 */ + RTE_CPUFLAG_PSN, /**< PSN */ + RTE_CPUFLAG_CLFSH, /**< CLFSH */ + RTE_CPUFLAG_DS, /**< DS */ + RTE_CPUFLAG_ACPI, /**< ACPI */ + RTE_CPUFLAG_MMX, /**< MMX */ + RTE_CPUFLAG_FXSR, /**< FXSR */ + RTE_CPUFLAG_SSE, /**< SSE */ + RTE_CPUFLAG_SSE2, /**< SSE2 */ + RTE_CPUFLAG_SS, /**< SS */ + RTE_CPUFLAG_HTT, /**< HTT */ + RTE_CPUFLAG_TM, /**< TM */ + RTE_CPUFLAG_PBE, /**< PBE */ + + /* (EAX 06h) EAX features */ + RTE_CPUFLAG_DIGTEMP, /**< DIGTEMP */ + RTE_CPUFLAG_TRBOBST, /**< TRBOBST */ + RTE_CPUFLAG_ARAT, /**< ARAT */ + RTE_CPUFLAG_PLN, /**< PLN */ + RTE_CPUFLAG_ECMD, /**< ECMD */ + RTE_CPUFLAG_PTM, /**< PTM */ + + /* (EAX 06h) ECX features */ + RTE_CPUFLAG_MPERF_APERF_MSR, /**< MPERF_APERF_MSR */ + RTE_CPUFLAG_ACNT2, /**< ACNT2 */ + RTE_CPUFLAG_ENERGY_EFF, /**< ENERGY_EFF */ + + /* (EAX 07h, ECX 0h) EBX features */ + RTE_CPUFLAG_FSGSBASE, /**< FSGSBASE */ + RTE_CPUFLAG_BMI1, /**< BMI1 */ + RTE_CPUFLAG_HLE, /**< Hardware Lock elision */ + RTE_CPUFLAG_AVX2, /**< AVX2 */ + RTE_CPUFLAG_SMEP, /**< SMEP */ + RTE_CPUFLAG_BMI2, /**< BMI2 */ + RTE_CPUFLAG_ERMS, /**< ERMS */ + RTE_CPUFLAG_INVPCID, /**< INVPCID */ + RTE_CPUFLAG_RTM, /**< Transactional memory */ + RTE_CPUFLAG_AVX512F, /**< AVX512F */ + + /* (EAX 80000001h) ECX features */ + RTE_CPUFLAG_LAHF_SAHF, /**< LAHF_SAHF */ + RTE_CPUFLAG_LZCNT, /**< LZCNT */ + + /* (EAX 80000001h) EDX features */ + RTE_CPUFLAG_SYSCALL, /**< SYSCALL */ + RTE_CPUFLAG_XD, /**< XD */ + RTE_CPUFLAG_1GB_PG, /**< 1GB_PG */ + RTE_CPUFLAG_RDTSCP, /**< RDTSCP */ + RTE_CPUFLAG_EM64T, /**< EM64T */ + + /* (EAX 80000007h) EDX features */ + RTE_CPUFLAG_INVTSC, /**< INVTSC */ + + /* The last item */ + RTE_CPUFLAG_NUMFLAGS, /**< This should always be the last! */ +}; + +enum cpu_register_t { + RTE_REG_EAX = 0, + RTE_REG_EBX, + RTE_REG_ECX, + RTE_REG_EDX, +}; + +typedef uint32_t cpuid_registers_t[4]; + +/** + * Struct to hold a processor feature entry + */ +struct feature_entry { + uint32_t leaf; /**< cpuid leaf */ + uint32_t subleaf; /**< cpuid subleaf */ + uint32_t reg; /**< cpuid register */ + uint32_t bit; /**< cpuid register bit */ +#define CPU_FLAG_NAME_MAX_LEN 64 + char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ +}; + +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ + [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, + +static const struct feature_entry cpu_feature_table[] = { + FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX, 0) + FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX, 1) + FEAT_DEF(DTES64, 0x00000001, 0, RTE_REG_ECX, 2) + FEAT_DEF(MONITOR, 0x00000001, 0, RTE_REG_ECX, 3) + FEAT_DEF(DS_CPL, 0x00000001, 0, RTE_REG_ECX, 4) + FEAT_DEF(VMX, 0x00000001, 0, RTE_REG_ECX, 5) + FEAT_DEF(SMX, 0x00000001, 0, RTE_REG_ECX, 6) + FEAT_DEF(EIST, 0x00000001, 0, RTE_REG_ECX, 7) + FEAT_DEF(TM2, 0x00000001, 0, RTE_REG_ECX, 8) + FEAT_DEF(SSSE3, 0x00000001, 0, RTE_REG_ECX, 9) + FEAT_DEF(CNXT_ID, 0x00000001, 0, RTE_REG_ECX, 10) + FEAT_DEF(FMA, 0x00000001, 0, RTE_REG_ECX, 12) + FEAT_DEF(CMPXCHG16B, 0x00000001, 0, RTE_REG_ECX, 13) + FEAT_DEF(XTPR, 0x00000001, 0, RTE_REG_ECX, 14) + FEAT_DEF(PDCM, 0x00000001, 0, RTE_REG_ECX, 15) + FEAT_DEF(PCID, 0x00000001, 0, RTE_REG_ECX, 17) + FEAT_DEF(DCA, 0x00000001, 0, RTE_REG_ECX, 18) + FEAT_DEF(SSE4_1, 0x00000001, 0, RTE_REG_ECX, 19) + FEAT_DEF(SSE4_2, 0x00000001, 0, RTE_REG_ECX, 20) + FEAT_DEF(X2APIC, 0x00000001, 0, RTE_REG_ECX, 21) + FEAT_DEF(MOVBE, 0x00000001, 0, RTE_REG_ECX, 22) + FEAT_DEF(POPCNT, 0x00000001, 0, RTE_REG_ECX, 23) + FEAT_DEF(TSC_DEADLINE, 0x00000001, 0, RTE_REG_ECX, 24) + FEAT_DEF(AES, 0x00000001, 0, RTE_REG_ECX, 25) + FEAT_DEF(XSAVE, 0x00000001, 0, RTE_REG_ECX, 26) + FEAT_DEF(OSXSAVE, 0x00000001, 0, RTE_REG_ECX, 27) + FEAT_DEF(AVX, 0x00000001, 0, RTE_REG_ECX, 28) + FEAT_DEF(F16C, 0x00000001, 0, RTE_REG_ECX, 29) + FEAT_DEF(RDRAND, 0x00000001, 0, RTE_REG_ECX, 30) + + FEAT_DEF(FPU, 0x00000001, 0, RTE_REG_EDX, 0) + FEAT_DEF(VME, 0x00000001, 0, RTE_REG_EDX, 1) + FEAT_DEF(DE, 0x00000001, 0, RTE_REG_EDX, 2) + FEAT_DEF(PSE, 0x00000001, 0, RTE_REG_EDX, 3) + FEAT_DEF(TSC, 0x00000001, 0, RTE_REG_EDX, 4) + FEAT_DEF(MSR, 0x00000001, 0, RTE_REG_EDX, 5) + FEAT_DEF(PAE, 0x00000001, 0, RTE_REG_EDX, 6) + FEAT_DEF(MCE, 0x00000001, 0, RTE_REG_EDX, 7) + FEAT_DEF(CX8, 0x00000001, 0, RTE_REG_EDX, 8) + FEAT_DEF(APIC, 0x00000001, 0, RTE_REG_EDX, 9) + FEAT_DEF(SEP, 0x00000001, 0, RTE_REG_EDX, 11) + FEAT_DEF(MTRR, 0x00000001, 0, RTE_REG_EDX, 12) + FEAT_DEF(PGE, 0x00000001, 0, RTE_REG_EDX, 13) + FEAT_DEF(MCA, 0x00000001, 0, RTE_REG_EDX, 14) + FEAT_DEF(CMOV, 0x00000001, 0, RTE_REG_EDX, 15) + FEAT_DEF(PAT, 0x00000001, 0, RTE_REG_EDX, 16) + FEAT_DEF(PSE36, 0x00000001, 0, RTE_REG_EDX, 17) + FEAT_DEF(PSN, 0x00000001, 0, RTE_REG_EDX, 18) + FEAT_DEF(CLFSH, 0x00000001, 0, RTE_REG_EDX, 19) + FEAT_DEF(DS, 0x00000001, 0, RTE_REG_EDX, 21) + FEAT_DEF(ACPI, 0x00000001, 0, RTE_REG_EDX, 22) + FEAT_DEF(MMX, 0x00000001, 0, RTE_REG_EDX, 23) + FEAT_DEF(FXSR, 0x00000001, 0, RTE_REG_EDX, 24) + FEAT_DEF(SSE, 0x00000001, 0, RTE_REG_EDX, 25) + FEAT_DEF(SSE2, 0x00000001, 0, RTE_REG_EDX, 26) + FEAT_DEF(SS, 0x00000001, 0, RTE_REG_EDX, 27) + FEAT_DEF(HTT, 0x00000001, 0, RTE_REG_EDX, 28) + FEAT_DEF(TM, 0x00000001, 0, RTE_REG_EDX, 29) + FEAT_DEF(PBE, 0x00000001, 0, RTE_REG_EDX, 31) + + FEAT_DEF(DIGTEMP, 0x00000006, 0, RTE_REG_EAX, 0) + FEAT_DEF(TRBOBST, 0x00000006, 0, RTE_REG_EAX, 1) + FEAT_DEF(ARAT, 0x00000006, 0, RTE_REG_EAX, 2) + FEAT_DEF(PLN, 0x00000006, 0, RTE_REG_EAX, 4) + FEAT_DEF(ECMD, 0x00000006, 0, RTE_REG_EAX, 5) + FEAT_DEF(PTM, 0x00000006, 0, RTE_REG_EAX, 6) + + FEAT_DEF(MPERF_APERF_MSR, 0x00000006, 0, RTE_REG_ECX, 0) + FEAT_DEF(ACNT2, 0x00000006, 0, RTE_REG_ECX, 1) + FEAT_DEF(ENERGY_EFF, 0x00000006, 0, RTE_REG_ECX, 3) + + FEAT_DEF(FSGSBASE, 0x00000007, 0, RTE_REG_EBX, 0) + FEAT_DEF(BMI1, 0x00000007, 0, RTE_REG_EBX, 2) + FEAT_DEF(HLE, 0x00000007, 0, RTE_REG_EBX, 4) + FEAT_DEF(AVX2, 0x00000007, 0, RTE_REG_EBX, 5) + FEAT_DEF(SMEP, 0x00000007, 0, RTE_REG_EBX, 6) + FEAT_DEF(BMI2, 0x00000007, 0, RTE_REG_EBX, 7) + FEAT_DEF(ERMS, 0x00000007, 0, RTE_REG_EBX, 8) + FEAT_DEF(INVPCID, 0x00000007, 0, RTE_REG_EBX, 10) + FEAT_DEF(RTM, 0x00000007, 0, RTE_REG_EBX, 11) + FEAT_DEF(AVX512F, 0x00000007, 0, RTE_REG_EBX, 16) + + FEAT_DEF(LAHF_SAHF, 0x80000001, 0, RTE_REG_ECX, 0) + FEAT_DEF(LZCNT, 0x80000001, 0, RTE_REG_ECX, 4) + + FEAT_DEF(SYSCALL, 0x80000001, 0, RTE_REG_EDX, 11) + FEAT_DEF(XD, 0x80000001, 0, RTE_REG_EDX, 20) + FEAT_DEF(1GB_PG, 0x80000001, 0, RTE_REG_EDX, 26) + FEAT_DEF(RDTSCP, 0x80000001, 0, RTE_REG_EDX, 27) + FEAT_DEF(EM64T, 0x80000001, 0, RTE_REG_EDX, 29) + + FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX, 8) +}; + +/* + * Execute CPUID instruction and get contents of a specific register + * + * This function, when compiled with GCC, will generate architecture-neutral + * code, as per GCC manual. + */ +static void cpu_get_features(uint32_t leaf, uint32_t subleaf, + cpuid_registers_t out) +{ +#if defined(__i386__) && defined(__PIC__) + /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */ + __asm__ __volatile__("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0" + : "=r" (out[RTE_REG_EBX]), + "=a" (out[RTE_REG_EAX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#else + __asm__ __volatile__("cpuid" + : "=a" (out[RTE_REG_EAX]), + "=b" (out[RTE_REG_EBX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#endif +} + +static int cpu_get_flag_enabled(enum rte_cpu_flag_t feature) +{ + const struct feature_entry *feat; + cpuid_registers_t regs; + + if (feature >= RTE_CPUFLAG_NUMFLAGS) + /* Flag does not match anything in the feature tables */ + return -1; + + feat = &cpu_feature_table[feature]; + + if (!feat->leaf) + /* This entry in the table wasn't filled out! */ + return -1; + + cpu_get_features(feat->leaf & 0xffff0000, 0, regs); + if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) || + regs[RTE_REG_EAX] < feat->leaf) + return 0; + + /* get the cpuid leaf containing the desired feature */ + cpu_get_features(feat->leaf, feat->subleaf, regs); + + /* check if the feature is enabled */ + return (regs[feat->reg] >> feat->bit) & 1; +} + +static const char *cpu_get_flag_name(enum rte_cpu_flag_t feature) +{ + if (feature >= RTE_CPUFLAG_NUMFLAGS) + return NULL; + return cpu_feature_table[feature].name; +} + +void cpu_flags_print_all(void) +{ + int len, i; + int max_str = 1024; + int max_len = max_str - 1; + char str[max_str]; + + len = snprintf(str, max_len, "\nCPU features supported:\n"); + + for (i = 0; i < RTE_CPUFLAG_NUMFLAGS; i++) { + if (cpu_get_flag_enabled(i) > 0) + len += snprintf(&str[len], max_len - len, "%s ", + cpu_get_flag_name(i)); + } + + len += snprintf(&str[len], max_len - len, + "\n\nCPU features NOT supported:\n"); + + for (i = 0; i < RTE_CPUFLAG_NUMFLAGS; i++) { + if (cpu_get_flag_enabled(i) <= 0) + len += snprintf(&str[len], max_len - len, "%s ", + cpu_get_flag_name(i)); + } + + len += snprintf(&str[len], max_len - len, "\n\n"); + + str[len] = '\0'; + ODP_PRINT("%s", str); +} diff --git a/platform/linux-generic/arch/x86/cpu_flags.h b/platform/linux-generic/arch/x86/cpu_flags.h new file mode 100644 index 000000000..f709ca08b --- /dev/null +++ b/platform/linux-generic/arch/x86/cpu_flags.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_PLAT_CPU_FLAGS_H_ +#define ODP_PLAT_CPU_FLAGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void cpu_flags_print_all(void); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3 From 73954b9142d1ddc2dde7c0f9b6596e2d8bac3caf Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:51 +0300 Subject: linux-gen: system: implement system info print Print API, impl name, CPU model/freq, cache line size and CPU count by default. Print CPU flags in case of x86. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .../linux-generic/arch/arm/odp_sysinfo_parse.c | 4 +++ .../linux-generic/arch/default/odp_sysinfo_parse.c | 4 +++ .../linux-generic/arch/mips64/odp_sysinfo_parse.c | 4 +++ .../linux-generic/arch/powerpc/odp_sysinfo_parse.c | 4 +++ .../linux-generic/arch/x86/odp_sysinfo_parse.c | 6 +++++ platform/linux-generic/include/odp_internal.h | 1 + platform/linux-generic/odp_system_info.c | 30 ++++++++++++++++++++++ 7 files changed, 53 insertions(+) diff --git a/platform/linux-generic/arch/arm/odp_sysinfo_parse.c b/platform/linux-generic/arch/arm/odp_sysinfo_parse.c index 53e2aaeaf..8ae2022ac 100644 --- a/platform/linux-generic/arch/arm/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/arm/odp_sysinfo_parse.c @@ -25,3 +25,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/default/odp_sysinfo_parse.c b/platform/linux-generic/arch/default/odp_sysinfo_parse.c index 53e2aaeaf..8ae2022ac 100644 --- a/platform/linux-generic/arch/default/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/default/odp_sysinfo_parse.c @@ -25,3 +25,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c b/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c index 407264b7f..d6f75f283 100644 --- a/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/mips64/odp_sysinfo_parse.c @@ -62,3 +62,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c b/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c index 3b88d55b6..bd4b9b429 100644 --- a/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/powerpc/odp_sysinfo_parse.c @@ -61,3 +61,7 @@ uint64_t odp_cpu_hz_current(int id ODP_UNUSED) { return 0; } + +void sys_info_print_arch(void) +{ +} diff --git a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c index 96127ec67..d77165a41 100644 --- a/platform/linux-generic/arch/x86/odp_sysinfo_parse.c +++ b/platform/linux-generic/arch/x86/odp_sysinfo_parse.c @@ -5,6 +5,7 @@ */ #include +#include #include int cpuinfo_parser(FILE *file, system_info_t *sysinfo) @@ -73,3 +74,8 @@ uint64_t odp_cpu_hz_current(int id) return 0; } + +void sys_info_print_arch(void) +{ + cpu_flags_print_all(); +} diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h index e1267cff7..8bae028d9 100644 --- a/platform/linux-generic/include/odp_internal.h +++ b/platform/linux-generic/include/odp_internal.h @@ -128,6 +128,7 @@ int _odp_ishm_term_local(void); int cpuinfo_parser(FILE *file, system_info_t *sysinfo); uint64_t odp_cpu_hz_current(int id); +void sys_info_print_arch(void); #ifdef __cplusplus } diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c index 18c61dbe7..40ffca078 100644 --- a/platform/linux-generic/odp_system_info.c +++ b/platform/linux-generic/odp_system_info.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -405,3 +406,32 @@ int odp_cpu_count(void) { return odp_global_data.system_info.cpu_count; } + +void odp_sys_info_print(void) +{ + int len; + int max_len = 512; + char str[max_len]; + + len = snprintf(str, max_len, "\n" + "ODP system info\n" + "---------------\n" + "ODP API version: %s\n" + "ODP impl name: %s\n" + "CPU model: %s\n" + "CPU freq (hz): %" PRIu64 "\n" + "Cache line size: %i\n" + "CPU count: %i\n" + "\n", + odp_version_api_str(), + odp_version_impl_name(), + odp_cpu_model_str(), + odp_cpu_hz_max(), + odp_sys_cache_line_size(), + odp_cpu_count()); + + str[len] = '\0'; + ODP_PRINT("%s", str); + + sys_info_print_arch(); +} -- cgit v1.2.3 From a5116e42abf0452f5ad9fd1920d5377aa0ef36b6 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:52 +0300 Subject: test: validation: add odp_sys_info_print test Added validation test for the new system info print call. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/system/system.c | 8 ++++++++ test/common_plat/validation/api/system/system.h | 1 + 2 files changed, 9 insertions(+) diff --git a/test/common_plat/validation/api/system/system.c b/test/common_plat/validation/api/system/system.c index 57ff34eb9..5b7ca01ae 100644 --- a/test/common_plat/validation/api/system/system.c +++ b/test/common_plat/validation/api/system/system.c @@ -301,6 +301,13 @@ void system_test_odp_cpu_hz_max_id(void) } } +void system_test_info_print(void) +{ + printf("\n\nCalling system info print...\n"); + odp_sys_info_print(); + printf("...done. "); +} + odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_version_numbers), ODP_TEST_INFO(system_test_odp_cpu_count), @@ -319,6 +326,7 @@ odp_testinfo_t system_suite[] = { ODP_TEST_INFO(system_test_odp_cpu_cycles_max), ODP_TEST_INFO(system_test_odp_cpu_cycles_resolution), ODP_TEST_INFO(system_test_odp_cpu_cycles_diff), + ODP_TEST_INFO(system_test_info_print), ODP_TEST_INFO_NULL, }; diff --git a/test/common_plat/validation/api/system/system.h b/test/common_plat/validation/api/system/system.h index cbb994eb0..c33729b94 100644 --- a/test/common_plat/validation/api/system/system.h +++ b/test/common_plat/validation/api/system/system.h @@ -30,6 +30,7 @@ void system_test_odp_cpu_cycles_max(void); void system_test_odp_cpu_cycles(void); void system_test_odp_cpu_cycles_diff(void); void system_test_odp_cpu_cycles_resolution(void); +void system_test_info_print(void); /* test arrays: */ extern odp_testinfo_t system_suite[]; -- cgit v1.2.3 From f54860c628c16c4f76d555b9d20c28e04af13751 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:53 +0300 Subject: test: sched_latency: use sys_info_print Use the new system info print function. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_sched_latency.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/test/common_plat/performance/odp_sched_latency.c b/test/common_plat/performance/odp_sched_latency.c index b40186872..026f2f6c7 100644 --- a/test/common_plat/performance/odp_sched_latency.c +++ b/test/common_plat/performance/odp_sched_latency.c @@ -667,16 +667,7 @@ int main(int argc, char *argv[]) return -1; } - printf("\n"); - printf("ODP system info\n"); - printf("---------------\n"); - printf("ODP API version: %s\n", odp_version_api_str()); - printf("ODP impl name: %s\n", odp_version_impl_name()); - printf("ODP impl details: %s\n", odp_version_impl_str()); - printf("CPU model: %s\n", odp_cpu_model_str()); - printf("CPU freq (hz): %" PRIu64 "\n", odp_cpu_hz_max()); - printf("Cache line size: %i\n", odp_sys_cache_line_size()); - printf("Max CPU count: %i\n", odp_cpu_count()); + odp_sys_info_print(); /* Get default worker cpumask */ if (args.cpu_count) @@ -687,9 +678,10 @@ int main(int argc, char *argv[]) (void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr)); - printf("Worker threads: %i\n", num_workers); - printf("First CPU: %i\n", odp_cpumask_first(&cpumask)); - printf("CPU mask: %s\n\n", cpumaskstr); + printf("CPU mask info:\n"); + printf(" Worker threads: %i\n", num_workers); + printf(" First CPU: %i\n", odp_cpumask_first(&cpumask)); + printf(" CPU mask: %s\n", cpumaskstr); thread_tbl = calloc(sizeof(odph_odpthread_t), num_workers); if (!thread_tbl) { -- cgit v1.2.3 From 17f4cddfcbf47f73761cb869ace264cc8444dc08 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:54 +0300 Subject: test: validation: rename time test header file Header file name time.h is ambiguos since C has a library header file with the same name. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/time/Makefile.am | 2 +- test/common_plat/validation/api/time/time.c | 2 +- test/common_plat/validation/api/time/time.h | 38 ------------------------ test/common_plat/validation/api/time/time_main.c | 2 +- test/common_plat/validation/api/time/time_test.h | 38 ++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 41 deletions(-) delete mode 100644 test/common_plat/validation/api/time/time.h create mode 100644 test/common_plat/validation/api/time/time_test.h diff --git a/test/common_plat/validation/api/time/Makefile.am b/test/common_plat/validation/api/time/Makefile.am index 72e6b7b2a..82682dfc3 100644 --- a/test/common_plat/validation/api/time/Makefile.am +++ b/test/common_plat/validation/api/time/Makefile.am @@ -14,5 +14,5 @@ test_PROGRAMS = time_main$(EXEEXT) dist_time_main_SOURCES = time_main.c time_main_LDADD = libtesttime.la $(LIBCUNIT_COMMON) $(LIBODP) -EXTRA_DIST = time.h $(TESTSCRIPTS) +EXTRA_DIST = time_test.h $(TESTSCRIPTS) dist_check_SCRIPTS = $(TESTSCRIPTS) diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c index df65c7195..36c419cb7 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -6,7 +6,7 @@ #include #include "odp_cunit_common.h" -#include "time.h" +#include "time_test.h" #define BUSY_LOOP_CNT 30000000 /* used for t > min resolution */ #define BUSY_LOOP_CNT_LONG 6000000000 /* used for t > 4 sec */ diff --git a/test/common_plat/validation/api/time/time.h b/test/common_plat/validation/api/time/time.h deleted file mode 100644 index 109562944..000000000 --- a/test/common_plat/validation/api/time/time.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2015, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _ODP_TEST_TIME_H_ -#define _ODP_TEST_TIME_H_ - -#include - -/* test functions: */ -void time_test_constants(void); -void time_test_local_res(void); -void time_test_global_res(void); -void time_test_local_conversion(void); -void time_test_global_conversion(void); -void time_test_local_cmp(void); -void time_test_global_cmp(void); -void time_test_local_diff(void); -void time_test_global_diff(void); -void time_test_local_sum(void); -void time_test_global_sum(void); -void time_test_local_wait_until(void); -void time_test_global_wait_until(void); -void time_test_wait_ns(void); -void time_test_monotony(void); - -/* test arrays: */ -extern odp_testinfo_t time_suite_time[]; - -/* test registry: */ -extern odp_suiteinfo_t time_suites[]; - -/* main test program: */ -int time_main(int argc, char *argv[]); - -#endif diff --git a/test/common_plat/validation/api/time/time_main.c b/test/common_plat/validation/api/time/time_main.c index f86d638a5..bf1cfe7bd 100644 --- a/test/common_plat/validation/api/time/time_main.c +++ b/test/common_plat/validation/api/time/time_main.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "time.h" +#include "time_test.h" int main(int argc, char *argv[]) { diff --git a/test/common_plat/validation/api/time/time_test.h b/test/common_plat/validation/api/time/time_test.h new file mode 100644 index 000000000..109562944 --- /dev/null +++ b/test/common_plat/validation/api/time/time_test.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ODP_TEST_TIME_H_ +#define _ODP_TEST_TIME_H_ + +#include + +/* test functions: */ +void time_test_constants(void); +void time_test_local_res(void); +void time_test_global_res(void); +void time_test_local_conversion(void); +void time_test_global_conversion(void); +void time_test_local_cmp(void); +void time_test_global_cmp(void); +void time_test_local_diff(void); +void time_test_global_diff(void); +void time_test_local_sum(void); +void time_test_global_sum(void); +void time_test_local_wait_until(void); +void time_test_global_wait_until(void); +void time_test_wait_ns(void); +void time_test_monotony(void); + +/* test arrays: */ +extern odp_testinfo_t time_suite_time[]; + +/* test registry: */ +extern odp_suiteinfo_t time_suites[]; + +/* main test program: */ +int time_main(int argc, char *argv[]); + +#endif -- cgit v1.2.3 From 62f95a564b7b3e08a32e6e72d234eb86292021d0 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:55 +0300 Subject: test: validation: add time accuracy test Test ODP time keeping accuracy against system time. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/time/time.c | 66 +++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/test/common_plat/validation/api/time/time.c b/test/common_plat/validation/api/time/time.c index 36c419cb7..e2ca2e17c 100644 --- a/test/common_plat/validation/api/time/time.c +++ b/test/common_plat/validation/api/time/time.c @@ -7,6 +7,7 @@ #include #include "odp_cunit_common.h" #include "time_test.h" +#include #define BUSY_LOOP_CNT 30000000 /* used for t > min resolution */ #define BUSY_LOOP_CNT_LONG 6000000000 /* used for t > 4 sec */ @@ -140,25 +141,25 @@ void time_test_monotony(void) CU_ASSERT(ns3 > ns2); } -static void time_test_cmp(time_cb time, time_from_ns_cb time_from_ns) +static void time_test_cmp(time_cb time_cur, time_from_ns_cb time_from_ns) { /* volatile to stop optimization of busy loop */ volatile int count = 0; odp_time_t t1, t2, t3; - t1 = time(); + t1 = time_cur(); while (count < BUSY_LOOP_CNT) { count++; }; - t2 = time(); + t2 = time_cur(); while (count < BUSY_LOOP_CNT * 2) { count++; }; - t3 = time(); + t3 = time_cur(); CU_ASSERT(odp_time_cmp(t2, t1) > 0); CU_ASSERT(odp_time_cmp(t3, t2) > 0); @@ -191,7 +192,7 @@ void time_test_global_cmp(void) } /* check that a time difference gives a reasonable result */ -static void time_test_diff(time_cb time, +static void time_test_diff(time_cb time_cur, time_from_ns_cb time_from_ns, uint64_t res) { @@ -202,13 +203,13 @@ static void time_test_diff(time_cb time, uint64_t upper_limit, lower_limit; /* test timestamp diff */ - t1 = time(); + t1 = time_cur(); while (count < BUSY_LOOP_CNT) { count++; }; - t2 = time(); + t2 = time_cur(); CU_ASSERT(odp_time_cmp(t2, t1) > 0); diff = odp_time_diff(t2, t1); @@ -268,7 +269,7 @@ void time_test_global_diff(void) } /* check that a time sum gives a reasonable result */ -static void time_test_sum(time_cb time, +static void time_test_sum(time_cb time_cur, time_from_ns_cb time_from_ns, uint64_t res) { @@ -277,7 +278,7 @@ static void time_test_sum(time_cb time, uint64_t upper_limit, lower_limit; /* sum timestamp and interval */ - t1 = time(); + t1 = time_cur(); ns2 = 103; t2 = time_from_ns(ns2); ns1 = odp_time_to_ns(t1); @@ -319,20 +320,20 @@ void time_test_global_sum(void) time_test_sum(odp_time_global, odp_time_global_from_ns, global_res); } -static void time_test_wait_until(time_cb time, time_from_ns_cb time_from_ns) +static void time_test_wait_until(time_cb time_cur, time_from_ns_cb time_from_ns) { int i; odp_time_t lower_limit, upper_limit; odp_time_t start_time, end_time, wait; odp_time_t second = time_from_ns(ODP_TIME_SEC_IN_NS); - start_time = time(); + start_time = time_cur(); wait = start_time; for (i = 0; i < WAIT_SECONDS; i++) { wait = odp_time_sum(wait, second); odp_time_wait_until(wait); } - end_time = time(); + end_time = time_cur(); wait = odp_time_diff(end_time, start_time); lower_limit = time_from_ns(WAIT_SECONDS * ODP_TIME_SEC_IN_NS - @@ -398,6 +399,45 @@ void time_test_wait_ns(void) } } +static void time_test_accuracy(time_cb time_cur, time_from_ns_cb time_from_ns) +{ + int i; + odp_time_t t1, t2, wait, diff; + clock_t c1, c2; + double sec_t, sec_c; + odp_time_t sec = time_from_ns(ODP_TIME_SEC_IN_NS); + + c1 = clock(); + t1 = time_cur(); + + wait = odp_time_sum(t1, sec); + for (i = 0; i < 5; i++) { + odp_time_wait_until(wait); + wait = odp_time_sum(wait, sec); + } + + t2 = time_cur(); + c2 = clock(); + + diff = odp_time_diff(t2, t1); + sec_t = ((double)odp_time_to_ns(diff)) / ODP_TIME_SEC_IN_NS; + sec_c = ((double)(c2 - c1)) / CLOCKS_PER_SEC; + + /* Check that ODP time is within +-5% of system time */ + CU_ASSERT(sec_t < sec_c * 1.05); + CU_ASSERT(sec_t > sec_c * 0.95); +} + +static void time_test_local_accuracy(void) +{ + time_test_accuracy(odp_time_local, odp_time_local_from_ns); +} + +static void time_test_global_accuracy(void) +{ + time_test_accuracy(odp_time_global, odp_time_global_from_ns); +} + odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_constants), ODP_TEST_INFO(time_test_local_res), @@ -408,12 +448,14 @@ odp_testinfo_t time_suite_time[] = { ODP_TEST_INFO(time_test_local_sum), ODP_TEST_INFO(time_test_local_wait_until), ODP_TEST_INFO(time_test_wait_ns), + ODP_TEST_INFO(time_test_local_accuracy), ODP_TEST_INFO(time_test_global_res), ODP_TEST_INFO(time_test_global_conversion), ODP_TEST_INFO(time_test_global_cmp), ODP_TEST_INFO(time_test_global_diff), ODP_TEST_INFO(time_test_global_sum), ODP_TEST_INFO(time_test_global_wait_until), + ODP_TEST_INFO(time_test_global_accuracy), ODP_TEST_INFO_NULL }; -- cgit v1.2.3 From fbe34c754b7abe15100779ce9833a7f200517d9f Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:56 +0300 Subject: linux-gen: time: use hw time counter when available Use 64 bit HW time counter when available. It is used on x86 when invariant TSC CPU flag indicates that TSC frequency is constant. Otherwise, the system time is used as before. Direct HW time counter usage avoids system call, and related latency and performance issues. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/Makefile.am | 1 + platform/linux-generic/arch/arm/odp_cpu_arch.c | 16 ++ platform/linux-generic/arch/default/odp_cpu_arch.c | 16 ++ platform/linux-generic/arch/mips64/odp_cpu_arch.c | 16 ++ platform/linux-generic/arch/powerpc/odp_cpu_arch.c | 16 ++ platform/linux-generic/arch/x86/cpu_flags.c | 9 + platform/linux-generic/arch/x86/odp_cpu_arch.c | 59 ++++ .../include/odp/api/plat/time_types.h | 23 +- platform/linux-generic/include/odp_time_internal.h | 24 ++ platform/linux-generic/odp_time.c | 300 ++++++++++++++++----- 10 files changed, 415 insertions(+), 65 deletions(-) create mode 100644 platform/linux-generic/include/odp_time_internal.h diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 15b8894d3..8dcdebd29 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -147,6 +147,7 @@ noinst_HEADERS = \ ${srcdir}/include/odp_schedule_if.h \ ${srcdir}/include/odp_sorted_list_internal.h \ ${srcdir}/include/odp_shm_internal.h \ + ${srcdir}/include/odp_time_internal.h \ ${srcdir}/include/odp_timer_internal.h \ ${srcdir}/include/odp_timer_wheel_internal.h \ ${srcdir}/include/odp_traffic_mngr_internal.h \ diff --git a/platform/linux-generic/arch/arm/odp_cpu_arch.c b/platform/linux-generic/arch/arm/odp_cpu_arch.c index 2ac223e07..c31f90844 100644 --- a/platform/linux-generic/arch/arm/odp_cpu_arch.c +++ b/platform/linux-generic/arch/arm/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include #include #include +#include #define GIGA 1000000000 @@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/default/odp_cpu_arch.c b/platform/linux-generic/arch/default/odp_cpu_arch.c index 2ac223e07..c31f90844 100644 --- a/platform/linux-generic/arch/default/odp_cpu_arch.c +++ b/platform/linux-generic/arch/default/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include #include #include +#include #define GIGA 1000000000 @@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/mips64/odp_cpu_arch.c b/platform/linux-generic/arch/mips64/odp_cpu_arch.c index 646acf9c1..f7eafa0fb 100644 --- a/platform/linux-generic/arch/mips64/odp_cpu_arch.c +++ b/platform/linux-generic/arch/mips64/odp_cpu_arch.c @@ -7,6 +7,7 @@ #include #include #include +#include uint64_t odp_cpu_cycles(void) { @@ -29,3 +30,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/powerpc/odp_cpu_arch.c b/platform/linux-generic/arch/powerpc/odp_cpu_arch.c index 2ac223e07..c31f90844 100644 --- a/platform/linux-generic/arch/powerpc/odp_cpu_arch.c +++ b/platform/linux-generic/arch/powerpc/odp_cpu_arch.c @@ -13,6 +13,7 @@ #include #include #include +#include #define GIGA 1000000000 @@ -46,3 +47,18 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +int cpu_has_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time(void) +{ + return 0; +} + +uint64_t cpu_global_time_freq(void) +{ + return 0; +} diff --git a/platform/linux-generic/arch/x86/cpu_flags.c b/platform/linux-generic/arch/x86/cpu_flags.c index 954dac272..a492a35bf 100644 --- a/platform/linux-generic/arch/x86/cpu_flags.c +++ b/platform/linux-generic/arch/x86/cpu_flags.c @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -357,3 +358,11 @@ void cpu_flags_print_all(void) str[len] = '\0'; ODP_PRINT("%s", str); } + +int cpu_has_global_time(void) +{ + if (cpu_get_flag_enabled(RTE_CPUFLAG_INVTSC) > 0) + return 1; + + return 0; +} diff --git a/platform/linux-generic/arch/x86/odp_cpu_arch.c b/platform/linux-generic/arch/x86/odp_cpu_arch.c index c8cf27b65..9ba601a32 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_arch.c +++ b/platform/linux-generic/arch/x86/odp_cpu_arch.c @@ -3,7 +3,14 @@ * * SPDX-License-Identifier: BSD-3-Clause */ + +#include + #include +#include +#include + +#include uint64_t odp_cpu_cycles(void) { @@ -31,3 +38,55 @@ uint64_t odp_cpu_cycles_resolution(void) { return 1; } + +uint64_t cpu_global_time(void) +{ + return odp_cpu_cycles(); +} + +#define SEC_IN_NS 1000000000ULL + +/* Measure TSC frequency. Frequency information registers are defined for x86, + * but those are often not enumerated. */ +uint64_t cpu_global_time_freq(void) +{ + struct timespec sleep, ts1, ts2; + uint64_t t1, t2, ts_nsec, cycles, hz; + int i; + uint64_t avg = 0; + int rounds = 4; + + for (i = 0; i < rounds; i++) { + sleep.tv_sec = 0; + sleep.tv_nsec = SEC_IN_NS / 10; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts1)) { + ODP_DBG("clock_gettime failed\n"); + return 0; + } + + t1 = cpu_global_time(); + + if (nanosleep(&sleep, NULL) < 0) { + ODP_DBG("nanosleep failed\n"); + return 0; + } + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts2)) { + ODP_DBG("clock_gettime failed\n"); + return 0; + } + + t2 = cpu_global_time(); + + ts_nsec = (ts2.tv_sec - ts1.tv_sec) * SEC_IN_NS; + ts_nsec += ts2.tv_nsec - ts1.tv_nsec; + + cycles = t2 - t1; + + hz = (cycles * SEC_IN_NS) / ts_nsec; + avg += hz; + } + + return avg / rounds; +} diff --git a/platform/linux-generic/include/odp/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h index 4847f3b1f..1cafb1f7c 100644 --- a/platform/linux-generic/include/odp/api/plat/time_types.h +++ b/platform/linux-generic/include/odp/api/plat/time_types.h @@ -26,11 +26,28 @@ extern "C" { * the linux timespec structure, which is dependent on POSIX extension level. */ typedef struct odp_time_t { - int64_t tv_sec; /**< @internal Seconds */ - int64_t tv_nsec; /**< @internal Nanoseconds */ + union { + /** @internal Posix timespec */ + struct { + /** @internal Seconds */ + int64_t tv_sec; + + /** @internal Nanoseconds */ + int64_t tv_nsec; + } spec; + + /** @internal HW time counter */ + struct { + /** @internal Counter value */ + uint64_t count; + + /** @internal Reserved */ + uint64_t reserved; + } hw; + }; } odp_time_t; -#define ODP_TIME_NULL ((odp_time_t){0, 0}) +#define ODP_TIME_NULL ((odp_time_t){.spec = {0, 0} }) /** * @} diff --git a/platform/linux-generic/include/odp_time_internal.h b/platform/linux-generic/include/odp_time_internal.h new file mode 100644 index 000000000..99ac79772 --- /dev/null +++ b/platform/linux-generic/include/odp_time_internal.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2017, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_TIME_INTERNAL_H_ +#define ODP_TIME_INTERNAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int cpu_has_global_time(void); +uint64_t cpu_global_time(void); +uint64_t cpu_global_time_freq(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index 0e5966c07..ac82175dd 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -10,36 +10,39 @@ #include #include #include +#include +#include +#include -static odp_time_t start_time; +typedef struct time_global_t { + odp_time_t start_time; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; +} time_global_t; -static inline -uint64_t time_to_ns(odp_time_t time) -{ - uint64_t ns; - - ns = time.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.tv_nsec; +static time_global_t global; - return ns; -} +/* + * Posix timespec based functions + */ -static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +static inline odp_time_t time_spec_diff(odp_time_t t2, odp_time_t t1) { odp_time_t time; - time.tv_sec = t2.tv_sec - t1.tv_sec; - time.tv_nsec = t2.tv_nsec - t1.tv_nsec; + time.spec.tv_sec = t2.spec.tv_sec - t1.spec.tv_sec; + time.spec.tv_nsec = t2.spec.tv_nsec - t1.spec.tv_nsec; - if (time.tv_nsec < 0) { - time.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.tv_sec; + if (time.spec.tv_nsec < 0) { + time.spec.tv_nsec += ODP_TIME_SEC_IN_NS; + --time.spec.tv_sec; } return time; } -static inline odp_time_t time_local(void) +static inline odp_time_t time_spec_cur(void) { int ret; odp_time_t time; @@ -49,77 +52,234 @@ static inline odp_time_t time_local(void) if (odp_unlikely(ret != 0)) ODP_ABORT("clock_gettime failed\n"); - time.tv_sec = sys_time.tv_sec; - time.tv_nsec = sys_time.tv_nsec; + time.spec.tv_sec = sys_time.tv_sec; + time.spec.tv_nsec = sys_time.tv_nsec; - return time_diff(time, start_time); + return time_spec_diff(time, global.start_time); } -static inline int time_cmp(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_spec_res(void) { - if (t2.tv_sec < t1.tv_sec) + int ret; + struct timespec tres; + + ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_getres failed\n"); + + return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; +} + +static inline int time_spec_cmp(odp_time_t t2, odp_time_t t1) +{ + if (t2.spec.tv_sec < t1.spec.tv_sec) return -1; - if (t2.tv_sec > t1.tv_sec) + if (t2.spec.tv_sec > t1.spec.tv_sec) return 1; - return t2.tv_nsec - t1.tv_nsec; + return t2.spec.tv_nsec - t1.spec.tv_nsec; } -static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) +static inline odp_time_t time_spec_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time; - time.tv_sec = t2.tv_sec + t1.tv_sec; - time.tv_nsec = t2.tv_nsec + t1.tv_nsec; + time.spec.tv_sec = t2.spec.tv_sec + t1.spec.tv_sec; + time.spec.tv_nsec = t2.spec.tv_nsec + t1.spec.tv_nsec; - if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.tv_sec; + if (time.spec.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { + time.spec.tv_nsec -= ODP_TIME_SEC_IN_NS; + ++time.spec.tv_sec; } return time; } -static inline odp_time_t time_local_from_ns(uint64_t ns) +static inline uint64_t time_spec_to_ns(odp_time_t time) +{ + uint64_t ns; + + ns = time.spec.tv_sec * ODP_TIME_SEC_IN_NS; + ns += time.spec.tv_nsec; + + return ns; +} + +static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time; - time.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.tv_nsec = ns - time.tv_sec * ODP_TIME_SEC_IN_NS; + time.spec.tv_sec = ns / ODP_TIME_SEC_IN_NS; + time.spec.tv_nsec = ns - time.spec.tv_sec * ODP_TIME_SEC_IN_NS; return time; } -static inline void time_wait_until(odp_time_t time) +/* + * HW time counter based functions + */ + +static inline odp_time_t time_hw_cur(void) { - odp_time_t cur; + odp_time_t time; - do { - cur = time_local(); - } while (time_cmp(time, cur) > 0); + time.hw.count = cpu_global_time() - global.hw_start; + + return time; } -static inline uint64_t time_local_res(void) +static inline uint64_t time_hw_res(void) { - int ret; - struct timespec tres; + /* Promise a bit lower resolution than average cycle counter + * frequency */ + return global.hw_freq_hz / 10; +} - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); +static inline int time_hw_cmp(odp_time_t t2, odp_time_t t1) +{ + if (odp_likely(t2.hw.count > t1.hw.count)) + return 1; - return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; + if (t2.hw.count < t1.hw.count) + return -1; + + return 0; +} + +static inline odp_time_t time_hw_diff(odp_time_t t2, odp_time_t t1) +{ + odp_time_t time; + + time.hw.count = t2.hw.count - t1.hw.count; + + return time; +} + +static inline odp_time_t time_hw_sum(odp_time_t t1, odp_time_t t2) +{ + odp_time_t time; + + time.hw.count = t1.hw.count + t2.hw.count; + + return time; +} + +static inline uint64_t time_hw_to_ns(odp_time_t time) +{ + uint64_t nsec; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t count = time.hw.count; + uint64_t sec = 0; + + if (count >= freq_hz) { + sec = count / freq_hz; + count = count - sec * freq_hz; + } + + nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz; + + return (sec * ODP_TIME_SEC_IN_NS) + nsec; +} + +static inline odp_time_t time_hw_from_ns(uint64_t ns) +{ + odp_time_t time; + uint64_t count; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t sec = 0; + + if (ns >= ODP_TIME_SEC_IN_NS) { + sec = ns / ODP_TIME_SEC_IN_NS; + ns = ns - sec * ODP_TIME_SEC_IN_NS; + } + + count = sec * freq_hz; + count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; + + time.hw.reserved = 0; + time.hw.count = count; + + return time; +} + +/* + * Common functions + */ + +static inline odp_time_t time_cur(void) +{ + if (global.use_hw) + return time_hw_cur(); + + return time_spec_cur(); +} + +static inline uint64_t time_res(void) +{ + if (global.use_hw) + return time_hw_res(); + + return time_spec_res(); +} + +static inline int time_cmp(odp_time_t t2, odp_time_t t1) +{ + if (global.use_hw) + return time_hw_cmp(t2, t1); + + return time_spec_cmp(t2, t1); +} + +static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +{ + if (global.use_hw) + return time_hw_diff(t2, t1); + + return time_spec_diff(t2, t1); +} + +static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) +{ + if (global.use_hw) + return time_hw_sum(t1, t2); + + return time_spec_sum(t1, t2); +} + +static inline uint64_t time_to_ns(odp_time_t time) +{ + if (global.use_hw) + return time_hw_to_ns(time); + + return time_spec_to_ns(time); +} + +static inline odp_time_t time_from_ns(uint64_t ns) +{ + if (global.use_hw) + return time_hw_from_ns(ns); + + return time_spec_from_ns(ns); +} + +static inline void time_wait_until(odp_time_t time) +{ + odp_time_t cur; + + do { + cur = time_cur(); + } while (time_cmp(time, cur) > 0); } odp_time_t odp_time_local(void) { - return time_local(); + return time_cur(); } odp_time_t odp_time_global(void) { - return time_local(); + return time_cur(); } odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) @@ -134,12 +294,12 @@ uint64_t odp_time_to_ns(odp_time_t time) odp_time_t odp_time_local_from_ns(uint64_t ns) { - return time_local_from_ns(ns); + return time_from_ns(ns); } odp_time_t odp_time_global_from_ns(uint64_t ns) { - return time_local_from_ns(ns); + return time_from_ns(ns); } int odp_time_cmp(odp_time_t t2, odp_time_t t1) @@ -154,18 +314,18 @@ odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) uint64_t odp_time_local_res(void) { - return time_local_res(); + return time_res(); } uint64_t odp_time_global_res(void) { - return time_local_res(); + return time_res(); } void odp_time_wait_ns(uint64_t ns) { - odp_time_t cur = time_local(); - odp_time_t wait = time_local_from_ns(ns); + odp_time_t cur = time_cur(); + odp_time_t wait = time_from_ns(ns); odp_time_t end_time = time_sum(cur, wait); time_wait_until(end_time); @@ -178,15 +338,31 @@ void odp_time_wait_until(odp_time_t time) int odp_time_init_global(void) { - int ret; - struct timespec time; - - ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time); - if (ret) { - start_time = ODP_TIME_NULL; - } else { - start_time.tv_sec = time.tv_sec; - start_time.tv_nsec = time.tv_nsec; + struct timespec sys_time; + int ret = 0; + + memset(&global, 0, sizeof(time_global_t)); + + if (cpu_has_global_time()) { + global.use_hw = 1; + global.hw_freq_hz = cpu_global_time_freq(); + + if (global.hw_freq_hz == 0) + return -1; + + printf("HW time counter freq: %" PRIu64 " hz\n\n", + global.hw_freq_hz); + + global.hw_start = cpu_global_time(); + return 0; + } + + global.start_time = ODP_TIME_NULL; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); + if (ret == 0) { + global.start_time.spec.tv_sec = sys_time.tv_sec; + global.start_time.spec.tv_nsec = sys_time.tv_nsec; } return ret; -- cgit v1.2.3 From 60150bba495711e6fdfc948ffb4ad405878fbcbc Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:57 +0300 Subject: linux-gen: time: improve x86 TSC freq measurement accuracy Add short warm up round and measure over a longer period of time (250ms vs 100ms). Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/arch/x86/odp_cpu_arch.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/platform/linux-generic/arch/x86/odp_cpu_arch.c b/platform/linux-generic/arch/x86/odp_cpu_arch.c index 9ba601a32..b1da428b9 100644 --- a/platform/linux-generic/arch/x86/odp_cpu_arch.c +++ b/platform/linux-generic/arch/x86/odp_cpu_arch.c @@ -54,11 +54,16 @@ uint64_t cpu_global_time_freq(void) uint64_t t1, t2, ts_nsec, cycles, hz; int i; uint64_t avg = 0; - int rounds = 4; + int rounds = 3; + int warm_up = 1; for (i = 0; i < rounds; i++) { - sleep.tv_sec = 0; - sleep.tv_nsec = SEC_IN_NS / 10; + sleep.tv_sec = 0; + + if (warm_up) + sleep.tv_nsec = SEC_IN_NS / 1000; + else + sleep.tv_nsec = SEC_IN_NS / 4; if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts1)) { ODP_DBG("clock_gettime failed\n"); @@ -85,8 +90,12 @@ uint64_t cpu_global_time_freq(void) cycles = t2 - t1; hz = (cycles * SEC_IN_NS) / ts_nsec; - avg += hz; + + if (warm_up) + warm_up = 0; + else + avg += hz; } - return avg / rounds; + return avg / (rounds - 1); } -- cgit v1.2.3 From dfbab7438c8404d5f4af20086e2100d40a5ffc0c Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Fri, 28 Apr 2017 15:09:58 +0300 Subject: linux-gen: time: store timespec as nsec Use single 64 bit nanosecond value to store time when using posix time. Posix time stamp is converted directly from timespec (sec + nsec) to nsec time. Storage space for odp_time_t is halved as both posix and HW time use single u64. Some functions (sum, diff, cmp) are generic for both time sources. Signed-off-by: Petri Savolainen Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .../include/odp/api/plat/time_types.h | 32 ++--- platform/linux-generic/odp_time.c | 143 ++++++--------------- 2 files changed, 52 insertions(+), 123 deletions(-) diff --git a/platform/linux-generic/include/odp/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h index 1cafb1f7c..71e354e6e 100644 --- a/platform/linux-generic/include/odp/api/plat/time_types.h +++ b/platform/linux-generic/include/odp/api/plat/time_types.h @@ -22,32 +22,24 @@ extern "C" { **/ /** - * @internal Time structure used to isolate odp-linux implementation from - * the linux timespec structure, which is dependent on POSIX extension level. + * @internal Time structure used for both POSIX timespec and HW counter + * implementations. */ typedef struct odp_time_t { union { - /** @internal Posix timespec */ - struct { - /** @internal Seconds */ - int64_t tv_sec; - - /** @internal Nanoseconds */ - int64_t tv_nsec; - } spec; - - /** @internal HW time counter */ - struct { - /** @internal Counter value */ - uint64_t count; - - /** @internal Reserved */ - uint64_t reserved; - } hw; + /** @internal Used with generic 64 bit operations */ + uint64_t u64; + + /** @internal Nanoseconds */ + uint64_t nsec; + + /** @internal HW timer counter value */ + uint64_t count; + }; } odp_time_t; -#define ODP_TIME_NULL ((odp_time_t){.spec = {0, 0} }) +#define ODP_TIME_NULL ((odp_time_t){.u64 = 0}) /** * @} diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c index ac82175dd..2bbe56664 100644 --- a/platform/linux-generic/odp_time.c +++ b/platform/linux-generic/odp_time.c @@ -15,10 +15,10 @@ #include typedef struct time_global_t { - odp_time_t start_time; - int use_hw; - uint64_t hw_start; - uint64_t hw_freq_hz; + struct timespec spec_start; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; } time_global_t; static time_global_t global; @@ -27,19 +27,23 @@ static time_global_t global; * Posix timespec based functions */ -static inline odp_time_t time_spec_diff(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_spec_diff_nsec(struct timespec *t2, + struct timespec *t1) { - odp_time_t time; + struct timespec diff; + uint64_t nsec; - time.spec.tv_sec = t2.spec.tv_sec - t1.spec.tv_sec; - time.spec.tv_nsec = t2.spec.tv_nsec - t1.spec.tv_nsec; + diff.tv_sec = t2->tv_sec - t1->tv_sec; + diff.tv_nsec = t2->tv_nsec - t1->tv_nsec; - if (time.spec.tv_nsec < 0) { - time.spec.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.spec.tv_sec; + if (diff.tv_nsec < 0) { + diff.tv_nsec += ODP_TIME_SEC_IN_NS; + diff.tv_sec -= 1; } - return time; + nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec; + + return nsec; } static inline odp_time_t time_spec_cur(void) @@ -52,10 +56,9 @@ static inline odp_time_t time_spec_cur(void) if (odp_unlikely(ret != 0)) ODP_ABORT("clock_gettime failed\n"); - time.spec.tv_sec = sys_time.tv_sec; - time.spec.tv_nsec = sys_time.tv_nsec; + time.nsec = time_spec_diff_nsec(&sys_time, &global.spec_start); - return time_spec_diff(time, global.start_time); + return time; } static inline uint64_t time_spec_res(void) @@ -70,48 +73,16 @@ static inline uint64_t time_spec_res(void) return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; } -static inline int time_spec_cmp(odp_time_t t2, odp_time_t t1) -{ - if (t2.spec.tv_sec < t1.spec.tv_sec) - return -1; - - if (t2.spec.tv_sec > t1.spec.tv_sec) - return 1; - - return t2.spec.tv_nsec - t1.spec.tv_nsec; -} - -static inline odp_time_t time_spec_sum(odp_time_t t1, odp_time_t t2) -{ - odp_time_t time; - - time.spec.tv_sec = t2.spec.tv_sec + t1.spec.tv_sec; - time.spec.tv_nsec = t2.spec.tv_nsec + t1.spec.tv_nsec; - - if (time.spec.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.spec.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.spec.tv_sec; - } - - return time; -} - static inline uint64_t time_spec_to_ns(odp_time_t time) { - uint64_t ns; - - ns = time.spec.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.spec.tv_nsec; - - return ns; + return time.nsec; } static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time; - time.spec.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.spec.tv_nsec = ns - time.spec.tv_sec * ODP_TIME_SEC_IN_NS; + time.nsec = ns; return time; } @@ -124,7 +95,7 @@ static inline odp_time_t time_hw_cur(void) { odp_time_t time; - time.hw.count = cpu_global_time() - global.hw_start; + time.count = cpu_global_time() - global.hw_start; return time; } @@ -136,40 +107,11 @@ static inline uint64_t time_hw_res(void) return global.hw_freq_hz / 10; } -static inline int time_hw_cmp(odp_time_t t2, odp_time_t t1) -{ - if (odp_likely(t2.hw.count > t1.hw.count)) - return 1; - - if (t2.hw.count < t1.hw.count) - return -1; - - return 0; -} - -static inline odp_time_t time_hw_diff(odp_time_t t2, odp_time_t t1) -{ - odp_time_t time; - - time.hw.count = t2.hw.count - t1.hw.count; - - return time; -} - -static inline odp_time_t time_hw_sum(odp_time_t t1, odp_time_t t2) -{ - odp_time_t time; - - time.hw.count = t1.hw.count + t2.hw.count; - - return time; -} - static inline uint64_t time_hw_to_ns(odp_time_t time) { uint64_t nsec; uint64_t freq_hz = global.hw_freq_hz; - uint64_t count = time.hw.count; + uint64_t count = time.count; uint64_t sec = 0; if (count >= freq_hz) { @@ -197,8 +139,7 @@ static inline odp_time_t time_hw_from_ns(uint64_t ns) count = sec * freq_hz; count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; - time.hw.reserved = 0; - time.hw.count = count; + time.count = count; return time; } @@ -225,26 +166,22 @@ static inline uint64_t time_res(void) static inline int time_cmp(odp_time_t t2, odp_time_t t1) { - if (global.use_hw) - return time_hw_cmp(t2, t1); - - return time_spec_cmp(t2, t1); -} + if (odp_likely(t2.u64 > t1.u64)) + return 1; -static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) -{ - if (global.use_hw) - return time_hw_diff(t2, t1); + if (t2.u64 < t1.u64) + return -1; - return time_spec_diff(t2, t1); + return 0; } static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) { - if (global.use_hw) - return time_hw_sum(t1, t2); + odp_time_t time; + + time.u64 = t1.u64 + t2.u64; - return time_spec_sum(t1, t2); + return time; } static inline uint64_t time_to_ns(odp_time_t time) @@ -284,7 +221,11 @@ odp_time_t odp_time_global(void) odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) { - return time_diff(t2, t1); + odp_time_t time; + + time.u64 = t2.u64 - t1.u64; + + return time; } uint64_t odp_time_to_ns(odp_time_t time) @@ -338,7 +279,6 @@ void odp_time_wait_until(odp_time_t time) int odp_time_init_global(void) { - struct timespec sys_time; int ret = 0; memset(&global, 0, sizeof(time_global_t)); @@ -357,13 +297,10 @@ int odp_time_init_global(void) return 0; } - global.start_time = ODP_TIME_NULL; + global.spec_start.tv_sec = 0; + global.spec_start.tv_nsec = 0; - ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); - if (ret == 0) { - global.start_time.spec.tv_sec = sys_time.tv_sec; - global.start_time.spec.tv_nsec = sys_time.tv_nsec; - } + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &global.spec_start); return ret; } -- cgit v1.2.3 From 2ffff0bc3e07678214a413b5eb89da13e7624055 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 5 May 2017 04:13:15 +0300 Subject: test: crypto: add AES-GCM tests with wrong tag value Signed-off-by: Dmitry Eremin-Solenikov Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .../validation/api/crypto/odp_crypto_test_inp.c | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 57e7c0e05..9defdbfab 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -689,10 +689,13 @@ void crypto_test_dec_alg_aes128_gcm(void) odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + uint8_t wrong_digest[AES128_GCM_DIGEST_LEN]; unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / sizeof(aes128_gcm_reference_length[0])); unsigned int i; + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + for (i = 0; i < test_vec_num; i++) { cipher_key.data = aes128_gcm_reference_key[i]; cipher_key.length = sizeof(aes128_gcm_reference_key[i]); @@ -723,6 +726,23 @@ void crypto_test_dec_alg_aes128_gcm(void) aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], AES128_GCM_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_AES_GCM, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_AES_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + wrong_digest, + AES128_GCM_CHECK_LEN); } } @@ -736,10 +756,13 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, auth_key = { .data = NULL, .length = 0 }; odp_crypto_iv_t iv = { .data = NULL, .length = AES128_GCM_IV_LEN }; + uint8_t wrong_digest[AES128_GCM_DIGEST_LEN]; unsigned int test_vec_num = (sizeof(aes128_gcm_reference_length) / sizeof(aes128_gcm_reference_length[0])); unsigned int i; + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + for (i = 0; i < test_vec_num; i++) { cipher_key.data = aes128_gcm_reference_key[i]; cipher_key.length = sizeof(aes128_gcm_reference_key[i]); @@ -768,6 +791,23 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], AES128_GCM_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_AES_GCM, + iv, + aes128_gcm_reference_iv[i], + cipher_key, + ODP_AUTH_ALG_AES_GCM, + auth_key, + &aes128_gcm_cipher_range[i], + &aes128_gcm_auth_range[i], + aes128_gcm_reference_ciphertext[i], + aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_plaintext[i], + aes128_gcm_reference_length[i], + wrong_digest, + AES128_GCM_CHECK_LEN); } } -- cgit v1.2.3 From 697c3be9b2155379dee458d66335442375a9354d Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Fri, 5 May 2017 04:14:34 +0300 Subject: linux: crypto: fix checking of GCM tags Currently odp_crypto code will happily accept wrong tags, because the check for EVP_DecryptFinal_ex return code is incorrect. This function returns 0 if tag is incorrect, not < 0. https://bugs.linaro.org/show_bug.cgi?id=3003 Signed-off-by: Dmitry Eremin-Solenikov Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 6963ee625..157a41520 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -384,7 +384,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, auth_len - (aad_tail - aad_head)); } - if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len) < 0) + if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len) <= 0) return ODP_CRYPTO_ALG_ERR_ICV_CHECK; return ODP_CRYPTO_ALG_ERR_NONE; -- cgit v1.2.3 From 0344270a085f78d9f6d4fbef3c497750bbcee071 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Mon, 15 May 2017 23:24:38 +0300 Subject: linux-generic: packet: add functions to optimize memset and memcmp paths Add function implementing memset and memcmp on packet object. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_packet_internal.h | 6 +++ platform/linux-generic/odp_packet.c | 48 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 0a9f17799..4c8d7515c 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -268,6 +268,12 @@ int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr); +int _odp_packet_set_data(odp_packet_t pkt, uint32_t offset, + uint8_t c, uint32_t len); + +int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset, + const void *s, uint32_t len); + #ifdef __cplusplus } #endif diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index c6962ce97..69098624d 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1665,6 +1665,54 @@ int odp_packet_move_data(odp_packet_t pkt, uint32_t dst_offset, pkt, src_offset, len); } +int _odp_packet_set_data(odp_packet_t pkt, uint32_t offset, + uint8_t c, uint32_t len) +{ + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t setlen; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + if (offset + len > pkt_hdr->frame_len) + return -1; + + while (len > 0) { + mapaddr = packet_map(pkt_hdr, offset, &seglen, NULL); + setlen = len > seglen ? seglen : len; + memset(mapaddr, c, setlen); + offset += setlen; + len -= setlen; + } + + return 0; +} + +int _odp_packet_cmp_data(odp_packet_t pkt, uint32_t offset, + const void *s, uint32_t len) +{ + const uint8_t *ptr = s; + void *mapaddr; + uint32_t seglen = 0; /* GCC */ + uint32_t cmplen; + int ret; + odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); + + ODP_ASSERT(offset + len <= pkt_hdr->frame_len); + + while (len > 0) { + mapaddr = packet_map(pkt_hdr, offset, &seglen, NULL); + cmplen = len > seglen ? seglen : len; + ret = memcmp(mapaddr, ptr, cmplen); + if (ret != 0) + return ret; + offset += cmplen; + len -= cmplen; + ptr += cmplen; + } + + return 0; +} + /* * * Debugging -- cgit v1.2.3 From 8e9242391f79ed54430b5fdc37e992addf9a26b8 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Tue, 30 May 2017 16:14:57 +0300 Subject: mergefix: remove duplicate declaration Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 77 ------------------------------------- 1 file changed, 77 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 157a41520..a993542f5 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -656,83 +656,6 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, return num; } -int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, - odp_crypto_cipher_capability_t dst[], - int num_copy) -{ - const odp_crypto_cipher_capability_t *src; - int num; - int size = sizeof(odp_crypto_cipher_capability_t); - - switch (cipher) { - case ODP_CIPHER_ALG_NULL: - src = NULL; - num = 0; - break; - case ODP_CIPHER_ALG_DES: - src = cipher_capa_des; - num = sizeof(cipher_capa_des) / size; - break; - case ODP_CIPHER_ALG_3DES_CBC: - src = cipher_capa_trides_cbc; - num = sizeof(cipher_capa_trides_cbc) / size; - break; - case ODP_CIPHER_ALG_AES_CBC: - src = cipher_capa_aes_cbc; - num = sizeof(cipher_capa_aes_cbc) / size; - break; - case ODP_CIPHER_ALG_AES_GCM: - src = cipher_capa_aes_gcm; - num = sizeof(cipher_capa_aes_gcm) / size; - break; - default: - return -1; - } - - if (num < num_copy) - num_copy = num; - - memcpy(dst, src, num_copy * size); - - return num; -} - -int odp_crypto_auth_capability(odp_auth_alg_t auth, - odp_crypto_auth_capability_t dst[], int num_copy) -{ - const odp_crypto_auth_capability_t *src; - int num; - int size = sizeof(odp_crypto_auth_capability_t); - - switch (auth) { - case ODP_AUTH_ALG_NULL: - src = NULL; - num = 0; - break; - case ODP_AUTH_ALG_MD5_HMAC: - src = auth_capa_md5_hmac; - num = sizeof(auth_capa_md5_hmac) / size; - break; - case ODP_AUTH_ALG_SHA256_HMAC: - src = auth_capa_sha256_hmac; - num = sizeof(auth_capa_sha256_hmac) / size; - break; - case ODP_AUTH_ALG_AES_GCM: - src = auth_capa_aes_gcm; - num = sizeof(auth_capa_aes_gcm) / size; - break; - default: - return -1; - } - - if (num < num_copy) - num_copy = num; - - memcpy(dst, src, num_copy * size); - - return num; -} - int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out, -- cgit v1.2.3 From ce8bebad45c590ad5b06d31d8be9fae8182f944a Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Tue, 4 Apr 2017 09:28:19 +0300 Subject: linux-gen: packet: remove lazy parsing Replace old lazy parsing code with a new packet parsing implementation which follows the latest API (parsing level is selected using odp_pktio_config()). Signed-off-by: Matias Elo Reviewed-and-tested-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- .../include/odp/api/plat/packet_types.h | 1 - .../linux-generic/include/odp_packet_internal.h | 39 +-- platform/linux-generic/odp_classification.c | 7 +- platform/linux-generic/odp_packet.c | 362 ++++++++------------- platform/linux-generic/odp_packet_flags.c | 111 +++---- platform/linux-generic/odp_packet_io.c | 2 + platform/linux-generic/pktio/dpdk.c | 3 +- platform/linux-generic/pktio/loop.c | 3 +- platform/linux-generic/pktio/netmap.c | 3 +- platform/linux-generic/pktio/pcap.c | 3 +- platform/linux-generic/pktio/socket.c | 4 +- platform/linux-generic/pktio/socket_mmap.c | 3 +- platform/linux-generic/pktio/tap.c | 3 +- 13 files changed, 208 insertions(+), 336 deletions(-) diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h b/platform/linux-generic/include/odp/api/plat/packet_types.h index 95cba5eb6..a209c759f 100644 --- a/platform/linux-generic/include/odp/api/plat/packet_types.h +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h @@ -107,7 +107,6 @@ typedef union { /** Individual input flags */ struct { - uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ uint64_t flow_hash:1; /**< Flow hash present */ diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 4c8d7515c..a480a7484 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -79,18 +79,6 @@ typedef union { ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR"); -/** - * Protocol stack layers - */ -typedef enum { - LAYER_NONE = 0, - LAYER_L1, - LAYER_L2, - LAYER_L3, - LAYER_L4, - LAYER_ALL -} layer_t; - /** * Packet parser metadata */ @@ -102,14 +90,6 @@ typedef struct { uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */ - - uint32_t l3_len; /**< Layer 3 length */ - uint32_t l4_len; /**< Layer 4 length */ - - uint16_t ethtype; /**< EtherType */ - uint8_t ip_proto; /**< IP protocol */ - uint8_t parsed_layers; /**< Highest parsed protocol stack layer */ - } packet_parser_t; /** @@ -203,16 +183,6 @@ static inline void packet_set_len(odp_packet_hdr_t *pkt_hdr, uint32_t len) pkt_hdr->frame_len = len; } -static inline int packet_parse_l2_not_done(packet_parser_t *prs) -{ - return !prs->input_flags.parsed_l2; -} - -static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) -{ - return pkt_hdr->p.parsed_layers != LAYER_ALL; -} - /* Forward declarations */ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt); @@ -220,11 +190,9 @@ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt); int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, odp_packet_t pkt[], int max_num); -/* Fill in parser metadata for L2 */ -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len); - /* Perform packet parse up to a given protocol layer */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer); /* Reset parser metadata for a new parse */ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); @@ -264,7 +232,8 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) } int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len, layer_t layer); + uint32_t pkt_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer); int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr); diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 5d96b00b3..7ebc47d7d 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -790,10 +790,6 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry, cls = &entry->s.cls; default_cos = cls->default_cos; - /* Check for lazy parse needed */ - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - /* Return error cos for error packet */ if (pkt_hdr->p.error_flags.all) return cls->error_cos; @@ -838,7 +834,8 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, packet_parse_reset(pkt_hdr); packet_set_len(pkt_hdr, pkt_len); - packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, LAYER_ALL); + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, + ODP_PKTIO_PARSER_LAYER_ALL); cos = cls_select_cos(entry, base, pkt_hdr); if (cos == NULL) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 69098624d..eb66af2d3 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -220,16 +220,9 @@ static inline void *packet_map(odp_packet_hdr_t *pkt_hdr, return addr; } -static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) -{ - pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.parsed_layers = LAYER_ALL; -} - void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { /* Reset parser metadata before new parse */ - pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.error_flags.all = 0; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; @@ -241,8 +234,7 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) /** * Initialize packet */ -static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, - int parse) +static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len) { uint32_t seg_len; int num = pkt_hdr->buf_hdr.segcount; @@ -257,7 +249,6 @@ static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, pkt_hdr->buf_hdr.seg[num - 1].len = seg_len; } - pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -266,10 +257,6 @@ static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; - /* Disable lazy parsing on user allocated packets */ - if (!parse) - packet_parse_disable(pkt_hdr); - /* * Packet headroom is set from the pool's headroom * Packet tailroom is rounded up to fill the last @@ -485,7 +472,7 @@ static inline odp_packet_hdr_t *free_segments(odp_packet_hdr_t *pkt_hdr, } static inline int packet_alloc(pool_t *pool, uint32_t len, int max_pkt, - int num_seg, odp_packet_t *pkt, int parse) + int num_seg, odp_packet_t *pkt) { int num_buf, i; int num = max_pkt; @@ -518,7 +505,7 @@ static inline int packet_alloc(pool_t *pool, uint32_t len, int max_pkt, pkt[i] = packet_handle(hdr); init_segments(&pkt_hdr[i * num_seg], num_seg); - packet_init(hdr, len, parse); + packet_init(hdr, len); } return num; @@ -531,7 +518,7 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, int num, num_seg; num_seg = num_segments(len); - num = packet_alloc(pool, len, max_num, num_seg, pkt, 1); + num = packet_alloc(pool, len, max_num, num_seg, pkt); return num; } @@ -551,7 +538,7 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, uint32_t len) return ODP_PACKET_INVALID; num_seg = num_segments(len); - num = packet_alloc(pool, len, 1, num_seg, &pkt, 0); + num = packet_alloc(pool, len, 1, num_seg, &pkt); if (odp_unlikely(num == 0)) return ODP_PACKET_INVALID; @@ -574,7 +561,7 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, return -1; num_seg = num_segments(len); - num = packet_alloc(pool, len, max_num, num_seg, pkt, 0); + num = packet_alloc(pool, len, max_num, num_seg, pkt); return num; } @@ -635,7 +622,7 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) if (len > pool->headroom + pool->data_size + pool->tailroom) return -1; - packet_init(pkt_hdr, len, 0); + packet_init(pkt_hdr, len); return 0; } @@ -1247,8 +1234,6 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len, NULL); } @@ -1256,8 +1241,6 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return pkt_hdr->p.l3_offset; } @@ -1268,8 +1251,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); pkt_hdr->p.l3_offset = offset; return 0; } @@ -1278,8 +1259,6 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len, NULL); } @@ -1287,8 +1266,6 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return pkt_hdr->p.l4_offset; } @@ -1299,8 +1276,6 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); pkt_hdr->p.l4_offset = offset; return 0; } @@ -1829,12 +1804,11 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); uint16_t frag_offset; uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); - - prs->l3_len = odp_be_to_cpu_16(ipv4->tot_len); + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || odp_unlikely(ver != 4) || - (prs->l3_len > frame_len - *offset)) { + (l3_len > frame_len - *offset)) { prs->error_flags.ip_err = 1; return 0; } @@ -1871,13 +1845,12 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; const _odp_ipv6hdr_ext_t *ipv6ext; uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); - - prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + - _ODP_IPV6HDR_LEN; + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN; /* Basic sanity checks on IPv6 header */ if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || - prs->l3_len > frame_len - *offset) { + l3_len > frame_len - *offset) { prs->error_flags.ip_err = 1; return 0; } @@ -1938,9 +1911,6 @@ static inline void parse_tcp(packet_parser_t *prs, else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) prs->input_flags.tcpopt = 1; - prs->l4_len = prs->l3_len + - prs->l3_offset - prs->l4_offset; - if (offset) *offset += (uint32_t)tcp->hl * 4; *parseptr += (uint32_t)tcp->hl * 4; @@ -1955,39 +1925,14 @@ static inline void parse_udp(packet_parser_t *prs, const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; uint32_t udplen = odp_be_to_cpu_16(udp->length); - if (udplen < sizeof(_odp_udphdr_t) || - udplen > (prs->l3_len + - prs->l4_offset - prs->l3_offset)) { + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) prs->error_flags.udp_err = 1; - } - - prs->l4_len = udplen; if (offset) *offset += sizeof(_odp_udphdr_t); *parseptr += sizeof(_odp_udphdr_t); } -/** - * Initialize L2 related parser flags and metadata - */ -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) -{ - /* Packet alloc or reset have already init other offsets and flags */ - - /* We only support Ethernet for now */ - prs->input_flags.eth = 1; - - /* Detect jumbo frames */ - if (frame_len > _ODP_ETH_LEN_MAX) - prs->input_flags.jumbo = 1; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->input_flags.l2 = 1; - - prs->input_flags.parsed_l2 = 1; -} - /** * Parse common packet headers up to given layer * @@ -1995,192 +1940,164 @@ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) * available from the ptr. */ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, layer_t layer) + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) { uint32_t offset; + uint16_t ethtype; const uint8_t *parseptr; + uint8_t ip_proto; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; - switch (prs->parsed_layers) { - case LAYER_NONE: - /* Fall through */ - - case LAYER_L2: - { - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0; - /* Get Ethertype */ - prs->ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->input_flags.l2 = 1; + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1; - /* Check for SNAP vs. DIX */ - if (prs->ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (prs->ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; - } - prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t) - (parseptr + 6))); - offset += 8; - parseptr += 8; - } + offset = sizeof(_odp_ethhdr_t); + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + } - /* Parse the VLAN header(s), if present */ - if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + } - if (prs->ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; - prs->l3_offset = offset; - prs->parsed_layers = LAYER_L2; - if (layer == LAYER_L2) - return prs->error_flags.all != 0; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); } - /* Fall through */ - case LAYER_L3: - { - offset = prs->l3_offset; - parseptr = (const uint8_t *)(ptr + offset); - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - - /* Parse Layer 3 headers */ - switch (prs->ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, - frame_len); - break; + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } - case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, - frame_len, seg_len); - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L2) + return prs->error_flags.all != 0; - case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - break; + /* Set l3_offset+flag only for known ethtypes */ + prs->l3_offset = offset; + prs->input_flags.l3 = 1; - default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - } + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); + break; - /* Set l4_offset+flag only for known ip_proto */ - prs->l4_offset = offset; - prs->parsed_layers = LAYER_L3; - if (layer == LAYER_L3) - return prs->error_flags.all != 0; - } - /* Fall through */ + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len); + break; - case LAYER_L4: - { - offset = prs->l4_offset; - parseptr = (const uint8_t *)(ptr + offset); - prs->input_flags.l4 = 1; + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break; - /* Parse Layer 4 headers */ - switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMPv4: - /* Fall through */ + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + ip_proto = 255; /* Reserved invalid by IANA */ + } - case _ODP_IPPROTO_ICMPv6: - prs->input_flags.icmp = 1; - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L3) + return prs->error_flags.all != 0; - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->input_flags.l4 = 1; - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ - case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; - break; + case _ODP_IPPROTO_ICMPv6: + prs->input_flags.icmp = 1; + break; - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; - break; + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; - case _ODP_IPPROTO_SCTP: - prs->input_flags.sctp = 1; - break; + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; - default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; - } + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; - prs->parsed_layers = LAYER_L4; + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; break; - } - case LAYER_ALL: + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; break; default: - ODP_ERR("Invalid parse layer: %d\n", (int)layer); - return -1; + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; } - - prs->parsed_layers = LAYER_ALL; - parse_exit: return prs->error_flags.all != 0; } @@ -2188,7 +2105,8 @@ parse_exit: /** * Simple packet parser */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer) { uint32_t seg_len = packet_first_seg_len(pkt_hdr); void *base = packet_data(pkt_hdr); diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c index c2e8b9cf7..72df1ecfe 100644 --- a/platform/linux-generic/odp_packet_flags.c +++ b/platform/linux-generic/odp_packet_flags.c @@ -8,17 +8,13 @@ #include #include -#define retflag(pkt, x, layer) do { \ +#define retflag(pkt, x) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ return pkt_hdr->p.x; \ } while (0) -#define setflag(pkt, x, v, layer) do { \ +#define setflag(pkt, x, v) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ pkt_hdr->p.x = (v) & 1; \ } while (0) @@ -26,9 +22,7 @@ int odp_packet_has_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return odp_packet_hdr(pkt)->p.error_flags.all != 0; + return pkt_hdr->p.error_flags.all != 0; } /* Get Input Flags */ @@ -45,126 +39,117 @@ int odp_packet_has_l2_error(odp_packet_t pkt) int odp_packet_has_l3(odp_packet_t pkt) { - retflag(pkt, input_flags.l3, LAYER_L3); + retflag(pkt, input_flags.l3); } int odp_packet_has_l3_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); - return pkt_hdr->p.error_flags.ip_err; } int odp_packet_has_l4(odp_packet_t pkt) { - retflag(pkt, input_flags.l4, LAYER_L4); + retflag(pkt, input_flags.l4); } int odp_packet_has_l4_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); - return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err; } int odp_packet_has_eth_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_bcast, LAYER_L2); + retflag(pkt, input_flags.eth_bcast); } int odp_packet_has_eth_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_mcast, LAYER_L2); + retflag(pkt, input_flags.eth_mcast); } int odp_packet_has_vlan(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan, LAYER_L2); + retflag(pkt, input_flags.vlan); } int odp_packet_has_vlan_qinq(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan_qinq, LAYER_L2); + retflag(pkt, input_flags.vlan_qinq); } int odp_packet_has_arp(odp_packet_t pkt) { - retflag(pkt, input_flags.arp, LAYER_L3); + retflag(pkt, input_flags.arp); } int odp_packet_has_ipv4(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv4, LAYER_L3); + retflag(pkt, input_flags.ipv4); } int odp_packet_has_ipv6(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv6, LAYER_L3); + retflag(pkt, input_flags.ipv6); } int odp_packet_has_ip_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_bcast, LAYER_L3); + retflag(pkt, input_flags.ip_bcast); } int odp_packet_has_ip_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_mcast, LAYER_L3); + retflag(pkt, input_flags.ip_mcast); } int odp_packet_has_ipfrag(odp_packet_t pkt) { - retflag(pkt, input_flags.ipfrag, LAYER_L3); + retflag(pkt, input_flags.ipfrag); } int odp_packet_has_ipopt(odp_packet_t pkt) { - retflag(pkt, input_flags.ipopt, LAYER_L3); + retflag(pkt, input_flags.ipopt); } int odp_packet_has_ipsec(odp_packet_t pkt) { - retflag(pkt, input_flags.ipsec, LAYER_L4); + retflag(pkt, input_flags.ipsec); } int odp_packet_has_udp(odp_packet_t pkt) { - retflag(pkt, input_flags.udp, LAYER_L4); + retflag(pkt, input_flags.udp); } int odp_packet_has_tcp(odp_packet_t pkt) { - retflag(pkt, input_flags.tcp, LAYER_L4); + retflag(pkt, input_flags.tcp); } int odp_packet_has_sctp(odp_packet_t pkt) { - retflag(pkt, input_flags.sctp, LAYER_L4); + retflag(pkt, input_flags.sctp); } int odp_packet_has_icmp(odp_packet_t pkt) { - retflag(pkt, input_flags.icmp, LAYER_L4); + retflag(pkt, input_flags.icmp); } odp_packet_color_t odp_packet_color(odp_packet_t pkt) { - retflag(pkt, input_flags.color, LAYER_ALL); + retflag(pkt, input_flags.color); } void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.input_flags.color = color; } @@ -172,29 +157,23 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return !pkt_hdr->p.input_flags.nodrop; } void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop) { - setflag(pkt, input_flags.nodrop, !drop, LAYER_ALL); + setflag(pkt, input_flags.nodrop, !drop); } int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) { - retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); + retflag(pkt, output_flags.shaper_len_adj); } void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.output_flags.shaper_len_adj = adj; } @@ -202,107 +181,107 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) void odp_packet_has_l2_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l2, val, LAYER_L2); + setflag(pkt, input_flags.l2, val); } void odp_packet_has_l3_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l3, val, LAYER_L3); + setflag(pkt, input_flags.l3, val); } void odp_packet_has_l4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l4, val, LAYER_L4); + setflag(pkt, input_flags.l4, val); } void odp_packet_has_eth_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth, val, LAYER_L2); + setflag(pkt, input_flags.eth, val); } void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_bcast, val); } void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_mcast, val); } void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.jumbo, val, LAYER_L2); + setflag(pkt, input_flags.jumbo, val); } void odp_packet_has_vlan_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan, val, LAYER_L2); + setflag(pkt, input_flags.vlan, val); } void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); + setflag(pkt, input_flags.vlan_qinq, val); } void odp_packet_has_arp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.arp, val, LAYER_L3); + setflag(pkt, input_flags.arp, val); } void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv4, val, LAYER_L3); + setflag(pkt, input_flags.ipv4, val); } void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv6, val, LAYER_L3); + setflag(pkt, input_flags.ipv6, val); } void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_bcast, val); } void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_mcast, val); } void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipfrag, val, LAYER_L3); + setflag(pkt, input_flags.ipfrag, val); } void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipopt, val, LAYER_L3); + setflag(pkt, input_flags.ipopt, val); } void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipsec, val, LAYER_L4); + setflag(pkt, input_flags.ipsec, val); } void odp_packet_has_udp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.udp, val, LAYER_L4); + setflag(pkt, input_flags.udp, val); } void odp_packet_has_tcp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.tcp, val, LAYER_L4); + setflag(pkt, input_flags.tcp, val); } void odp_packet_has_sctp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.sctp, val, LAYER_L4); + setflag(pkt, input_flags.sctp, val); } void odp_packet_has_icmp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.icmp, val, LAYER_L4); + setflag(pkt, input_flags.icmp, val); } void odp_packet_has_flow_hash_clr(odp_packet_t pkt) diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index ea9f2a756..877978ba2 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -206,6 +206,8 @@ static odp_pktio_t setup_pktio_entry(const char *name, odp_pool_t pool, memcpy(&pktio_entry->s.param, param, sizeof(odp_pktio_param_t)); pktio_entry->s.handle = hdl; + odp_pktio_config_init(&pktio_entry->s.config); + for (pktio_if = 0; pktio_if_ops[pktio_if]; ++pktio_if) { ret = pktio_if_ops[pktio_if]->open(hdl, pktio_entry, name, pool); diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 6ac89bd5d..c52cd09d1 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -653,7 +653,8 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); if (mbuf->ol_flags & PKT_RX_RSS_HASH) odp_packet_flow_hash_set(pkt, mbuf->hash.rss); diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index 61e98ad8c..e9ad22ba2 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -132,7 +132,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); packet_set_ts(pkt_hdr, ts); diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index ae3db34d9..928bb00af 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -663,7 +663,8 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); packet_set_ts(pkt_hdr, ts); } diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/pktio/pcap.c index e54a56f5f..a467b6402 100644 --- a/platform/linux-generic/pktio/pcap.c +++ b/platform/linux-generic/pktio/pcap.c @@ -252,7 +252,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED, break; } - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); pktio_entry->s.stats.in_octets += pkt_hdr->frame_len; packet_set_ts(pkt_hdr, ts); diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index 2e94a3882..a383adc6a 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -673,8 +673,10 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, pkt_hdr->input = pktio_entry->s.handle; if (!pktio_cls_enabled(pktio_entry)) - packet_parse_l2(&pkt_hdr->p, pkt_len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); + pkt_hdr->input = pktio_entry->s.handle; packet_set_ts(pkt_hdr, ts); pkt_table[nb_rx++] = pkt; diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index fdf8cca54..2dba7b08f 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -231,7 +231,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, hdr); else - packet_parse_l2(&hdr->p, pkt_len); + packet_parse_layer(hdr, + pktio_entry->s.config.parser.layer); packet_set_ts(hdr, ts); diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c index ac2045606..650c12a77 100644 --- a/platform/linux-generic/pktio/tap.c +++ b/platform/linux-generic/pktio/tap.c @@ -213,7 +213,8 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else - packet_parse_l2(&pkt_hdr->p, len); + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); packet_set_ts(pkt_hdr, ts); pkt_hdr->input = pktio_entry->s.handle; -- cgit v1.2.3 From ad5d48fe658927a7b946533d50fd907e306ec184 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Wed, 22 Feb 2017 17:08:25 +0200 Subject: validation: crypto: add stubs for sha-1 and sha-512 tests API enumerations are tested but functional tests are missing still. Signed-off-by: Petri Savolainen Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.h | 2 ++ .../validation/api/crypto/odp_crypto_test_inp.c | 32 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h index 661fe5df9..4d810f62b 100644 --- a/test/common_plat/validation/api/crypto/crypto.h +++ b/test/common_plat/validation/api/crypto/crypto.h @@ -24,8 +24,10 @@ void crypto_test_dec_alg_aes128_gcm(void); void crypto_test_dec_alg_aes128_gcm_ovr_iv(void); void crypto_test_gen_alg_hmac_md5(void); void crypto_test_check_alg_hmac_md5(void); +void crypto_test_alg_hmac_sha1(void); void crypto_test_gen_alg_hmac_sha256(void); void crypto_test_check_alg_hmac_sha256(void); +void crypto_test_alg_hmac_sha512(void); /* test arrays: */ extern odp_testinfo_t crypto_suite[]; diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 9defdbfab..bfc9da3c6 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -340,10 +340,18 @@ static int check_alg_support(odp_cipher_alg_t cipher, odp_auth_alg_t auth) if (!capability.auths.bit.md5_hmac) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_SHA1_HMAC: + if (!capability.auths.bit.sha1_hmac) + return ODP_TEST_INACTIVE; + break; case ODP_AUTH_ALG_SHA256_HMAC: if (!capability.auths.bit.sha256_hmac) return ODP_TEST_INACTIVE; break; + case ODP_AUTH_ALG_SHA512_HMAC: + if (!capability.auths.bit.sha512_hmac) + return ODP_TEST_INACTIVE; + break; case ODP_AUTH_ALG_AES_GCM: if (!capability.auths.bit.aes_gcm) return ODP_TEST_INACTIVE; @@ -1173,6 +1181,26 @@ void crypto_test_check_alg_hmac_sha256(void) } } +static int check_alg_hmac_sha1(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); +} + +void crypto_test_alg_hmac_sha1(void) +{ + printf(" TEST NOT IMPLEMENTED YET "); +} + +static int check_alg_hmac_sha512(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); +} + +void crypto_test_alg_hmac_sha512(void) +{ + printf(" TEST NOT IMPLEMENTED YET "); +} + int crypto_suite_sync_init(void) { suite_context.pool = odp_pool_lookup("packet_pool"); @@ -1226,10 +1254,14 @@ odp_testinfo_t crypto_suite[] = { check_alg_hmac_md5), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, check_alg_hmac_md5), + ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha1, + check_alg_hmac_sha1), ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, check_alg_hmac_sha256), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, check_alg_hmac_sha256), + ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha512, + check_alg_hmac_sha512), ODP_TEST_INFO_NULL, }; -- cgit v1.2.3 From 1adf94727a92a260f3145c3c777cc8cf3ecb419b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:17 +0300 Subject: validation: crypto: explicitly pass auth_digest_len to crypto subsystem Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../validation/api/crypto/odp_crypto_test_inp.c | 57 +++++++++++++--------- .../validation/api/crypto/test_vectors.h | 10 ++++ .../validation/api/crypto/test_vectors_len.h | 3 -- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index bfc9da3c6..3d09e3745 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -201,6 +201,7 @@ static void alg_test(odp_crypto_op_t op, ses_params.cipher_key = cipher_key; ses_params.iv = ses_iv; ses_params.auth_key = auth_key; + ses_params.auth_digest_len = digest_len; rc = odp_crypto_session_create(&ses_params, &session, &status); CU_ASSERT_FATAL(!rc); @@ -620,7 +621,8 @@ void crypto_test_enc_alg_aes128_gcm(void) cipher_key.length, iv.length)) continue; if (!check_auth_options(ODP_AUTH_ALG_AES_GCM, - auth_key.length, AES128_GCM_CHECK_LEN)) + auth_key.length, + aes128_gcm_reference_tag_length[i])) continue; alg_test(ODP_CRYPTO_OP_ENCODE, @@ -639,7 +641,7 @@ void crypto_test_enc_alg_aes128_gcm(void) aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); } } @@ -664,7 +666,8 @@ void crypto_test_enc_alg_aes128_gcm_ovr_iv(void) cipher_key.length, iv.length)) continue; if (!check_auth_options(ODP_AUTH_ALG_AES_GCM, - auth_key.length, AES128_GCM_CHECK_LEN)) + auth_key.length, + aes128_gcm_reference_tag_length[i])) continue; alg_test(ODP_CRYPTO_OP_ENCODE, @@ -683,7 +686,7 @@ void crypto_test_enc_alg_aes128_gcm_ovr_iv(void) aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); } } @@ -714,7 +717,8 @@ void crypto_test_dec_alg_aes128_gcm(void) cipher_key.length, iv.length)) continue; if (!check_auth_options(ODP_AUTH_ALG_AES_GCM, - auth_key.length, AES128_GCM_CHECK_LEN)) + auth_key.length, + aes128_gcm_reference_tag_length[i])) continue; alg_test(ODP_CRYPTO_OP_DECODE, @@ -728,12 +732,13 @@ void crypto_test_dec_alg_aes128_gcm(void) &aes128_gcm_cipher_range[i], &aes128_gcm_auth_range[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_length[i] + + aes128_gcm_reference_tag_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); alg_test(ODP_CRYPTO_OP_DECODE, 1, @@ -746,11 +751,12 @@ void crypto_test_dec_alg_aes128_gcm(void) &aes128_gcm_cipher_range[i], &aes128_gcm_auth_range[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_length[i] + + aes128_gcm_reference_tag_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], wrong_digest, - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); } } @@ -779,7 +785,8 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) cipher_key.length, iv.length)) continue; if (!check_auth_options(ODP_AUTH_ALG_AES_GCM, - auth_key.length, AES128_GCM_CHECK_LEN)) + auth_key.length, + aes128_gcm_reference_tag_length[i])) continue; alg_test(ODP_CRYPTO_OP_DECODE, @@ -793,12 +800,13 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) &aes128_gcm_cipher_range[i], &aes128_gcm_auth_range[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_length[i] + + aes128_gcm_reference_tag_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + aes128_gcm_reference_length[i], - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); alg_test(ODP_CRYPTO_OP_DECODE, 1, @@ -811,11 +819,12 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) &aes128_gcm_cipher_range[i], &aes128_gcm_auth_range[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + AES128_GCM_CHECK_LEN, + aes128_gcm_reference_length[i] + + aes128_gcm_reference_tag_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], wrong_digest, - AES128_GCM_CHECK_LEN); + aes128_gcm_reference_tag_length[i]); } } @@ -1004,7 +1013,7 @@ void crypto_test_gen_alg_hmac_md5(void) auth_key.length = sizeof(hmac_md5_reference_key[i]); if (!check_auth_options(ODP_AUTH_ALG_MD5_HMAC, auth_key.length, - HMAC_MD5_96_CHECK_LEN)) + hmac_md5_reference_digest_length[i])) continue; alg_test(ODP_CRYPTO_OP_ENCODE, @@ -1020,7 +1029,7 @@ void crypto_test_gen_alg_hmac_md5(void) hmac_md5_reference_length[i], NULL, 0, hmac_md5_reference_digest[i], - HMAC_MD5_96_CHECK_LEN); + hmac_md5_reference_digest_length[i]); } } @@ -1042,7 +1051,7 @@ void crypto_test_check_alg_hmac_md5(void) auth_key.length = sizeof(hmac_md5_reference_key[i]); if (!check_auth_options(ODP_AUTH_ALG_MD5_HMAC, auth_key.length, - HMAC_MD5_96_CHECK_LEN)) + hmac_md5_reference_digest_length[i])) continue; alg_test(ODP_CRYPTO_OP_DECODE, @@ -1058,7 +1067,7 @@ void crypto_test_check_alg_hmac_md5(void) hmac_md5_reference_length[i], NULL, 0, hmac_md5_reference_digest[i], - HMAC_MD5_96_CHECK_LEN); + hmac_md5_reference_digest_length[i]); alg_test(ODP_CRYPTO_OP_DECODE, 1, @@ -1073,7 +1082,7 @@ void crypto_test_check_alg_hmac_md5(void) hmac_md5_reference_length[i], NULL, 0, wrong_digest, - HMAC_MD5_96_CHECK_LEN); + hmac_md5_reference_digest_length[i]); } } @@ -1106,7 +1115,7 @@ void crypto_test_gen_alg_hmac_sha256(void) if (!check_auth_options(ODP_AUTH_ALG_SHA256_HMAC, auth_key.length, - HMAC_SHA256_128_CHECK_LEN)) + hmac_sha256_reference_digest_length[i])) continue; alg_test(ODP_CRYPTO_OP_ENCODE, @@ -1122,7 +1131,7 @@ void crypto_test_gen_alg_hmac_sha256(void) hmac_sha256_reference_length[i], NULL, 0, hmac_sha256_reference_digest[i], - HMAC_SHA256_128_CHECK_LEN); + hmac_sha256_reference_digest_length[i]); } } @@ -1146,7 +1155,7 @@ void crypto_test_check_alg_hmac_sha256(void) if (!check_auth_options(ODP_AUTH_ALG_SHA256_HMAC, auth_key.length, - HMAC_SHA256_128_CHECK_LEN)) + hmac_sha256_reference_digest_length[i])) continue; alg_test(ODP_CRYPTO_OP_DECODE, @@ -1162,7 +1171,7 @@ void crypto_test_check_alg_hmac_sha256(void) hmac_sha256_reference_length[i], NULL, 0, hmac_sha256_reference_digest[i], - HMAC_SHA256_128_CHECK_LEN); + hmac_sha256_reference_digest_length[i]); alg_test(ODP_CRYPTO_OP_DECODE, 1, @@ -1177,7 +1186,7 @@ void crypto_test_check_alg_hmac_sha256(void) hmac_sha256_reference_length[i], NULL, 0, wrong_digest, - HMAC_SHA256_128_CHECK_LEN); + hmac_sha256_reference_digest_length[i]); } } diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index a1cf4faf3..defbda45a 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -139,6 +139,8 @@ static uint8_t aes128_gcm_reference_iv[][AES128_GCM_IV_LEN] = { static uint32_t aes128_gcm_reference_length[] = { 84, 72, 72, 40}; +static uint32_t aes128_gcm_reference_tag_length[] = { 16, 16, 16, 16}; + static odp_packet_data_range_t aes128_gcm_cipher_range[] = { { .offset = 12, .length = 72 }, { .offset = 8, .length = 64 }, @@ -306,6 +308,10 @@ static uint8_t hmac_md5_reference_digest[][HMAC_MD5_DIGEST_LEN] = { 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 } }; +static uint32_t hmac_md5_reference_digest_length[] = { + 12, 12, 12 +}; + static uint8_t hmac_sha256_reference_key[][HMAC_SHA256_KEY_LEN] = { { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, @@ -350,4 +356,8 @@ static uint8_t hmac_sha256_reference_digest[][HMAC_SHA256_DIGEST_LEN] = { 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7 } }; +static uint32_t hmac_sha256_reference_digest_length[] = { + 16, 16, 16 +}; + #endif diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h index 4fbb5cd70..80fd927b7 100644 --- a/test/common_plat/validation/api/crypto/test_vectors_len.h +++ b/test/common_plat/validation/api/crypto/test_vectors_len.h @@ -21,18 +21,15 @@ #define AES128_GCM_IV_LEN 12 #define AES128_GCM_MAX_DATA_LEN 106 #define AES128_GCM_DIGEST_LEN 16 -#define AES128_GCM_CHECK_LEN 16 /* HMAC-MD5 */ #define HMAC_MD5_KEY_LEN 16 #define HMAC_MD5_MAX_DATA_LEN 128 #define HMAC_MD5_DIGEST_LEN 16 -#define HMAC_MD5_96_CHECK_LEN 12 /* HMAC-SHA256 */ #define HMAC_SHA256_KEY_LEN 32 #define HMAC_SHA256_MAX_DATA_LEN 128 #define HMAC_SHA256_DIGEST_LEN 32 -#define HMAC_SHA256_128_CHECK_LEN 16 #endif -- cgit v1.2.3 From 1ebbb8f882ae6506fc9fa2cb02dadae3d35eaf58 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:18 +0300 Subject: validation: crypto: explicitly pass AAD to crypto subsystem Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../validation/api/crypto/odp_crypto_test_inp.c | 55 +++++++++++++----- .../validation/api/crypto/test_vectors.h | 65 ++++++++-------------- 2 files changed, 64 insertions(+), 56 deletions(-) diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 3d09e3745..c89d04f9c 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -74,6 +74,8 @@ static void alg_test(odp_crypto_op_t op, odp_crypto_key_t auth_key, odp_packet_data_range_t *cipher_range, odp_packet_data_range_t *auth_range, + uint8_t *aad, + uint32_t aad_len, const uint8_t *plaintext, unsigned int plaintext_len, const uint8_t *ciphertext, @@ -240,6 +242,9 @@ static void alg_test(odp_crypto_op_t op, if (op_iv_ptr) op_params.override_iv_ptr = op_iv_ptr; + op_params.aad.ptr = aad; + op_params.aad.length = aad_len; + op_params.hash_result_offset = plaintext_len; if (0 != digest_len) { memcpy(data_addr + op_params.hash_result_offset, @@ -472,6 +477,7 @@ void crypto_test_enc_alg_3des_cbc(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, tdes_cbc_reference_plaintext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_ciphertext[i], @@ -508,6 +514,7 @@ void crypto_test_enc_alg_3des_cbc_ovr_iv(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, tdes_cbc_reference_plaintext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_ciphertext[i], @@ -548,6 +555,7 @@ void crypto_test_dec_alg_3des_cbc(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, tdes_cbc_reference_ciphertext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_plaintext[i], @@ -586,6 +594,7 @@ void crypto_test_dec_alg_3des_cbc_ovr_iv(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, tdes_cbc_reference_ciphertext[i], tdes_cbc_reference_length[i], tdes_cbc_reference_plaintext[i], @@ -634,7 +643,9 @@ void crypto_test_enc_alg_aes128_gcm(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i], @@ -679,7 +690,9 @@ void crypto_test_enc_alg_aes128_gcm_ovr_iv(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i], @@ -730,10 +743,11 @@ void crypto_test_dec_alg_aes128_gcm(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + - aes128_gcm_reference_tag_length[i], + aes128_gcm_reference_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + @@ -749,10 +763,11 @@ void crypto_test_dec_alg_aes128_gcm(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + - aes128_gcm_reference_tag_length[i], + aes128_gcm_reference_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], wrong_digest, @@ -798,10 +813,11 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + - aes128_gcm_reference_tag_length[i], + aes128_gcm_reference_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], aes128_gcm_reference_ciphertext[i] + @@ -817,10 +833,11 @@ void crypto_test_dec_alg_aes128_gcm_ovr_iv(void) ODP_AUTH_ALG_AES_GCM, auth_key, &aes128_gcm_cipher_range[i], - &aes128_gcm_auth_range[i], + &aes128_gcm_cipher_range[i], + aes128_gcm_reference_aad[i], + aes128_gcm_reference_aad_length[i], aes128_gcm_reference_ciphertext[i], - aes128_gcm_reference_length[i] + - aes128_gcm_reference_tag_length[i], + aes128_gcm_reference_length[i], aes128_gcm_reference_plaintext[i], aes128_gcm_reference_length[i], wrong_digest, @@ -865,6 +882,7 @@ void crypto_test_enc_alg_aes128_cbc(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, aes128_cbc_reference_plaintext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_ciphertext[i], @@ -901,6 +919,7 @@ void crypto_test_enc_alg_aes128_cbc_ovr_iv(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, aes128_cbc_reference_plaintext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_ciphertext[i], @@ -941,6 +960,7 @@ void crypto_test_dec_alg_aes128_cbc(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, aes128_cbc_reference_ciphertext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_plaintext[i], @@ -979,6 +999,7 @@ void crypto_test_dec_alg_aes128_cbc_ovr_iv(void) ODP_AUTH_ALG_NULL, auth_key, NULL, NULL, + NULL, 0, aes128_cbc_reference_ciphertext[i], aes128_cbc_reference_length[i], aes128_cbc_reference_plaintext[i], @@ -1025,6 +1046,7 @@ void crypto_test_gen_alg_hmac_md5(void) ODP_AUTH_ALG_MD5_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_md5_reference_plaintext[i], hmac_md5_reference_length[i], NULL, 0, @@ -1063,6 +1085,7 @@ void crypto_test_check_alg_hmac_md5(void) ODP_AUTH_ALG_MD5_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_md5_reference_plaintext[i], hmac_md5_reference_length[i], NULL, 0, @@ -1078,6 +1101,7 @@ void crypto_test_check_alg_hmac_md5(void) ODP_AUTH_ALG_MD5_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_md5_reference_plaintext[i], hmac_md5_reference_length[i], NULL, 0, @@ -1127,6 +1151,7 @@ void crypto_test_gen_alg_hmac_sha256(void) ODP_AUTH_ALG_SHA256_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_sha256_reference_plaintext[i], hmac_sha256_reference_length[i], NULL, 0, @@ -1167,6 +1192,7 @@ void crypto_test_check_alg_hmac_sha256(void) ODP_AUTH_ALG_SHA256_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_sha256_reference_plaintext[i], hmac_sha256_reference_length[i], NULL, 0, @@ -1182,6 +1208,7 @@ void crypto_test_check_alg_hmac_sha256(void) ODP_AUTH_ALG_SHA256_HMAC, auth_key, NULL, NULL, + NULL, 0, hmac_sha256_reference_plaintext[i], hmac_sha256_reference_length[i], NULL, 0, diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index defbda45a..0d36c2498 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -137,31 +137,31 @@ static uint8_t aes128_gcm_reference_iv[][AES128_GCM_IV_LEN] = { 0xa2, 0xfc, 0xa1, 0xa3 } }; -static uint32_t aes128_gcm_reference_length[] = { 84, 72, 72, 40}; +static uint32_t aes128_gcm_reference_length[] = { 72, 64, 64, 28}; static uint32_t aes128_gcm_reference_tag_length[] = { 16, 16, 16, 16}; +static uint32_t aes128_gcm_reference_aad_length[] = { 12, 8, 8, 12}; + static odp_packet_data_range_t aes128_gcm_cipher_range[] = { - { .offset = 12, .length = 72 }, - { .offset = 8, .length = 64 }, - { .offset = 8, .length = 64 }, - { .offset = 12, .length = 28 }, + { .offset = 0, .length = 72 }, + { .offset = 0, .length = 64 }, + { .offset = 0, .length = 64 }, + { .offset = 0, .length = 28 }, }; -static odp_packet_data_range_t aes128_gcm_auth_range[] = { - { .offset = 0, .length = 84 }, - { .offset = 0, .length = 72 }, - { .offset = 0, .length = 72 }, - { .offset = 0, .length = 40 }, +static uint8_t aes128_gcm_reference_aad[][AES128_GCM_MAX_DATA_LEN] = { + { 0x00, 0x00, 0x43, 0x21, 0x87, 0x65, 0x43, 0x21, + 0x00, 0x00, 0x00, 0x00, }, + { 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }, + { 0x42, 0xf6, 0x7e, 0x3f, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, }, }; static uint8_t aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { - { /* Aad */ - 0x00, 0x00, 0x43, 0x21, 0x87, 0x65, 0x43, 0x21, - 0x00, 0x00, 0x00, 0x00, - /* Plain */ - 0x45, 0x00, 0x00, 0x48, 0x69, 0x9a, 0x00, 0x00, + { 0x45, 0x00, 0x00, 0x48, 0x69, 0x9a, 0x00, 0x00, 0x80, 0x11, 0x4d, 0xb7, 0xc0, 0xa8, 0x01, 0x02, 0xc0, 0xa8, 0x01, 0x01, 0x0a, 0x9b, 0xf1, 0x56, 0x38, 0xd3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, @@ -171,10 +171,7 @@ aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { 0x63, 0x69, 0x74, 0x79, 0x02, 0x64, 0x6b, 0x00, 0x00, 0x21, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01 }, - { /* Aad */ - 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, - /* Plain */ - 0x45, 0x00, 0x00, 0x3e, 0x69, 0x8f, 0x00, 0x00, + { 0x45, 0x00, 0x00, 0x3e, 0x69, 0x8f, 0x00, 0x00, 0x80, 0x11, 0x4d, 0xcc, 0xc0, 0xa8, 0x01, 0x02, 0xc0, 0xa8, 0x01, 0x01, 0x0a, 0x98, 0x00, 0x35, 0x00, 0x2a, 0x23, 0x43, 0xb2, 0xd0, 0x01, 0x00, @@ -183,10 +180,7 @@ aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { 0x65, 0x72, 0x63, 0x69, 0x74, 0x79, 0x02, 0x64, 0x6b, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01 }, - { /* Aad */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* Plain */ - 0x45, 0x00, 0x00, 0x3c, 0x99, 0xc5, 0x00, 0x00, + { 0x45, 0x00, 0x00, 0x3c, 0x99, 0xc5, 0x00, 0x00, 0x80, 0x01, 0xcb, 0x7a, 0x40, 0x67, 0x93, 0x18, 0x01, 0x01, 0x01, 0x01, 0x08, 0x00, 0x07, 0x5c, 0x02, 0x00, 0x44, 0x00, 0x61, 0x62, 0x63, 0x64, @@ -195,11 +189,7 @@ aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x01, 0x02, 0x02, 0x01 }, - { /* Aad */ - 0x42, 0xf6, 0x7e, 0x3f, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, - /* Plain */ - 0x45, 0x00, 0x00, 0x1c, 0x42, 0xa2, 0x00, 0x00, + { 0x45, 0x00, 0x00, 0x1c, 0x42, 0xa2, 0x00, 0x00, 0x80, 0x01, 0x44, 0x1f, 0x40, 0x67, 0x93, 0xb6, 0xe0, 0x00, 0x00, 0x02, 0x0a, 0x00, 0xf5, 0xff, 0x01, 0x02, 0x02, 0x01 } @@ -207,10 +197,7 @@ aes128_gcm_reference_plaintext[][AES128_GCM_MAX_DATA_LEN] = { static uint8_t aes128_gcm_reference_ciphertext[][AES128_GCM_MAX_DATA_LEN] = { - { /* Aad */ - 0x00, 0x00, 0x43, 0x21, 0x87, 0x65, 0x43, 0x21, - 0x00, 0x00, 0x00, 0x00, - /* Plain */ + { /* Plain */ 0xfe, 0xcf, 0x53, 0x7e, 0x72, 0x9d, 0x5b, 0x07, 0xdc, 0x30, 0xdf, 0x52, 0x8d, 0xd2, 0x2b, 0x76, 0x8d, 0x1b, 0x98, 0x73, 0x66, 0x96, 0xa6, 0xfd, @@ -224,9 +211,7 @@ aes128_gcm_reference_ciphertext[][AES128_GCM_MAX_DATA_LEN] = { 0x45, 0x90, 0x18, 0x14, 0x8f, 0x6c, 0xbe, 0x72, 0x2f, 0xd0, 0x47, 0x96, 0x56, 0x2d, 0xfd, 0xb4 }, - { /* Aad */ - 0x00, 0x00, 0xa5, 0xf8, 0x00, 0x00, 0x00, 0x0a, - /* Plain */ + { /* Plain */ 0xde, 0xb2, 0x2c, 0xd9, 0xb0, 0x7c, 0x72, 0xc1, 0x6e, 0x3a, 0x65, 0xbe, 0xeb, 0x8d, 0xf3, 0x04, 0xa5, 0xa5, 0x89, 0x7d, 0x33, 0xae, 0x53, 0x0f, @@ -238,9 +223,8 @@ aes128_gcm_reference_ciphertext[][AES128_GCM_MAX_DATA_LEN] = { /* Digest */ 0x83, 0xb7, 0x0d, 0x3a, 0xa8, 0xbc, 0x6e, 0xe4, 0xc3, 0x09, 0xe9, 0xd8, 0x5a, 0x41, 0xad, 0x4a }, - { /* Aad */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* Plain */ + + { /* Plain */ 0x46, 0x88, 0xda, 0xf2, 0xf9, 0x73, 0xa3, 0x92, 0x73, 0x29, 0x09, 0xc3, 0x31, 0xd5, 0x6d, 0x60, 0xf6, 0x94, 0xab, 0xaa, 0x41, 0x4b, 0x5e, 0x7f, @@ -253,10 +237,7 @@ aes128_gcm_reference_ciphertext[][AES128_GCM_MAX_DATA_LEN] = { 0xf8, 0x21, 0xd4, 0x96, 0xee, 0xb0, 0x96, 0xe9, 0x8a, 0xd2, 0xb6, 0x9e, 0x47, 0x99, 0xc7, 0x1d }, - { /* Aad */ - 0x42, 0xf6, 0x7e, 0x3f, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, - /* Plain */ + { /* Plain */ 0xfb, 0xa2, 0xca, 0x84, 0x5e, 0x5d, 0xf9, 0xf0, 0xf2, 0x2c, 0x3e, 0x6e, 0x86, 0xdd, 0x83, 0x1e, 0x1f, 0xc6, 0x57, 0x92, 0xcd, 0x1a, 0xf9, 0x13, -- cgit v1.2.3 From 93ee286c21a576c265463ca5dcd17b39ef80962b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:19 +0300 Subject: test: odp_crypto: update performance test to set auth_digest_length Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_crypto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c index b3857973e..6a58294a2 100644 --- a/test/common_plat/performance/odp_crypto.c +++ b/test/common_plat/performance/odp_crypto.c @@ -50,7 +50,6 @@ static uint8_t test_key24[24] = { 0x01, 0x02, 0x03, 0x04, 0x05, typedef struct { const char *name; /**< Algorithm name */ odp_crypto_session_param_t session; /**< Prefilled crypto session params */ - unsigned int hash_adjust; /**< Size of hash */ } crypto_alg_config_t; /** @@ -209,9 +208,9 @@ static crypto_alg_config_t algs_config[] = { .auth_key = { .data = test_key16, .length = sizeof(test_key16) - } + }, + .auth_digest_len = 12, }, - .hash_adjust = 12 }, { .name = "null-hmac-md5-96", @@ -221,9 +220,9 @@ static crypto_alg_config_t algs_config[] = { .auth_key = { .data = test_key16, .length = sizeof(test_key16) - } + }, + .auth_digest_len = 12, }, - .hash_adjust = 12 }, }; @@ -578,7 +577,7 @@ run_measure_one(crypto_args_t *cargs, mem = odp_packet_data(params.out_pkt); print_mem("Immediately encrypted packet", mem, payload_length + - config->hash_adjust); + config->session.auth_digest_len); } if (!cargs->in_place) { if (cargs->reuse_packet) { @@ -611,7 +610,8 @@ run_measure_one(crypto_args_t *cargs, print_mem("Receieved encrypted packet", mem, payload_length + - config->hash_adjust); + config-> + session.auth_digest_len); } if (cargs->reuse_packet) { params.pkt = out_pkt; -- cgit v1.2.3 From ab3003c87e4cc25e3b26c7bddbfbce61525a94ad Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:20 +0300 Subject: example: ipsec: set auth_digest_len Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- example/ipsec/odp_ipsec_cache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c index b2a91c242..dba0ea0ab 100644 --- a/example/ipsec/odp_ipsec_cache.c +++ b/example/ipsec/odp_ipsec_cache.c @@ -100,6 +100,7 @@ int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa, params.auth_alg = auth_sa->alg.u.auth; params.auth_key.data = auth_sa->key.data; params.auth_key.length = auth_sa->key.length; + params.auth_digest_len = auth_sa->icv_len; mode = auth_sa->mode; } else { params.auth_alg = ODP_AUTH_ALG_NULL; -- cgit v1.2.3 From 93e9e20c17426d3262aa96a589106e635b755090 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:21 +0300 Subject: linux-generic: crypto: use auth_digest_len when calculating HMACs Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index a993542f5..472ee3107 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -522,7 +522,6 @@ static int process_des_param(odp_crypto_generic_session_t *session) } static int process_auth_param(odp_crypto_generic_session_t *session, - uint32_t bits, uint32_t key_length, const EVP_MD *evp_md) { @@ -535,7 +534,9 @@ static int process_auth_param(odp_crypto_generic_session_t *session, session->auth.evp_md = evp_md; /* Number of valid bytes */ - session->auth.bytes = bits / 8; + session->auth.bytes = session->p.auth_digest_len; + if (session->auth.bytes < (unsigned)EVP_MD_size(evp_md) / 2) + return -1; /* Convert keys */ session->auth.key_length = key_length; @@ -745,17 +746,23 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, session->auth.func = null_crypto_routine; rc = 0; break; - case ODP_AUTH_ALG_MD5_HMAC: #if ODP_DEPRECATED_API case ODP_AUTH_ALG_MD5_96: + /* Fixed digest tag length with deprecated algo */ + session->p.auth_digest_len = 96 / 8; + /* Fallthrough */ #endif - rc = process_auth_param(session, 96, 16, EVP_md5()); + case ODP_AUTH_ALG_MD5_HMAC: + rc = process_auth_param(session, 16, EVP_md5()); break; - case ODP_AUTH_ALG_SHA256_HMAC: #if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: + /* Fixed digest tag length with deprecated algo */ + session->p.auth_digest_len = 128 / 8; + /* Fallthrough */ #endif - rc = process_auth_param(session, 128, 32, EVP_sha256()); + case ODP_AUTH_ALG_SHA256_HMAC: + rc = process_auth_param(session, 32, EVP_sha256()); break; #if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: -- cgit v1.2.3 From e3a92c5bf48f2279cd4ef5c8d22eafc523445626 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:22 +0300 Subject: linux-generic: crypto: add SHA* capabilities for full length digests In addition to truncated digests (used by IPsec) add full-length capabilities to SHA* algos. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 472ee3107..91ef05aeb 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -52,10 +52,12 @@ static const odp_crypto_cipher_capability_t cipher_capa_aes_gcm[] = { * Keep sorted: first by digest length, then by key length */ static const odp_crypto_auth_capability_t auth_capa_md5_hmac[] = { -{.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; +{.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; static const odp_crypto_auth_capability_t auth_capa_sha256_hmac[] = { -{.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; +{.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 32, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = { {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } }; -- cgit v1.2.3 From a28dab7edeeee74db65349231ec400d92d491a22 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:23 +0300 Subject: linux-generic: crypto: update AES-GCM support to reflect aad and auth_digest_len Make AES-GCM use recently introduced aad and auth_digest_len fields. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 58 ++++++++++--------------------------- 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 91ef05aeb..352cfa536 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -267,10 +267,8 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, { uint8_t *data = odp_packet_data(param->out_pkt); uint32_t plain_len = param->cipher_range.length; - uint8_t *aad_head = data + param->auth_range.offset; - uint8_t *aad_tail = data + param->cipher_range.offset + - param->cipher_range.length; - uint32_t auth_len = param->auth_range.length; + const uint8_t *aad_head = param->aad.ptr; + uint32_t aad_len = param->aad.length; unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -282,12 +280,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* All cipher data must be part of the authentication */ - if (param->auth_range.offset > param->cipher_range.offset || - param->auth_range.offset + auth_len < - param->cipher_range.offset + plain_len) - return ODP_CRYPTO_ALG_ERR_DATA_SIZE; - /* * Create a copy of the IV. The DES library modifies IV * and if we are processing packets on parallel threads @@ -305,23 +297,16 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); /* Authenticate header data (if any) without encrypting them */ - if (aad_head < plaindata) { + if (aad_len > 0) EVP_EncryptUpdate(ctx, NULL, &cipher_len, - aad_head, plaindata - aad_head); - } + aad_head, aad_len); EVP_EncryptUpdate(ctx, plaindata, &cipher_len, plaindata, plain_len); - cipher_len = plain_len; - - /* Authenticate footer data (if any) without encrypting them */ - if (aad_head + auth_len > plaindata + plain_len) { - EVP_EncryptUpdate(ctx, NULL, NULL, aad_tail, - auth_len - (aad_tail - aad_head)); - } EVP_EncryptFinal_ex(ctx, plaindata + cipher_len, &cipher_len); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, + session->p.auth_digest_len, tag); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -332,10 +317,8 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, { uint8_t *data = odp_packet_data(param->out_pkt); uint32_t cipher_len = param->cipher_range.length; - uint8_t *aad_head = data + param->auth_range.offset; - uint8_t *aad_tail = data + param->cipher_range.offset + - param->cipher_range.length; - uint32_t auth_len = param->auth_range.length; + const uint8_t *aad_head = param->aad.ptr; + uint32_t aad_len = param->aad.length; unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -347,12 +330,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* All cipher data must be part of the authentication */ - if (param->auth_range.offset > param->cipher_range.offset || - param->auth_range.offset + auth_len < - param->cipher_range.offset + cipher_len) - return ODP_CRYPTO_ALG_ERR_DATA_SIZE; - /* * Create a copy of the IV. The DES library modifies IV * and if we are processing packets on parallel threads @@ -368,25 +345,18 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, + session->p.auth_digest_len, tag); /* Authenticate header data (if any) without encrypting them */ - if (aad_head < cipherdata) { + if (aad_len > 0) EVP_DecryptUpdate(ctx, NULL, &plain_len, - aad_head, cipherdata - aad_head); - } + aad_head, aad_len); EVP_DecryptUpdate(ctx, cipherdata, &plain_len, cipherdata, cipher_len); - plain_len = cipher_len; - - /* Authenticate footer data (if any) without encrypting them */ - if (aad_head + auth_len > cipherdata + cipher_len) { - EVP_DecryptUpdate(ctx, NULL, NULL, aad_tail, - auth_len - (aad_tail - aad_head)); - } - if (EVP_DecryptFinal_ex(ctx, cipherdata + cipher_len, &plain_len) <= 0) + if (EVP_DecryptFinal_ex(ctx, cipherdata + plain_len, &plain_len) <= 0) return ODP_CRYPTO_ALG_ERR_ICV_CHECK; return ODP_CRYPTO_ALG_ERR_NONE; @@ -770,6 +740,8 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, case ODP_AUTH_ALG_AES128_GCM: if (param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) aes_gcm = 1; + /* Fixed digest tag length with deprecated algo */ + session->p.auth_digest_len = 16; /* Fallthrough */ #endif case ODP_AUTH_ALG_AES_GCM: -- cgit v1.2.3 From 2239b759ad0cb09e3a2ec3d132580123ed92ab03 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:24 +0300 Subject: linux-generic: crypto: remote extra memcpy in AES-GCM There is no need to memcpy IV if it gets passed to EVP functions. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 352cfa536..3f298485c 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -269,7 +269,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, uint32_t plain_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -280,13 +279,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - /* Adjust pointer for beginning of area to cipher/auth */ uint8_t *plaindata = data + param->cipher_range.offset; @@ -294,7 +286,7 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; int cipher_len = 0; - EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); + EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); /* Authenticate header data (if any) without encrypting them */ if (aad_len > 0) @@ -319,7 +311,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, uint32_t cipher_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -330,20 +321,13 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - /* Adjust pointer for beginning of area to cipher/auth */ uint8_t *cipherdata = data + param->cipher_range.offset; /* Encrypt it */ EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; int plain_len = 0; - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_enc); + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, session->p.auth_digest_len, tag); -- cgit v1.2.3 From 3362bb0eea7b4cdeb97cd2558e9bc5e4ee176852 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:25 +0300 Subject: linux-generic: crypto: make AES-GCM thread safe Using single context for all operations is not thread safe: multiple threads can access the same context in parallel, affecting its internal state. Make AES-GCM functions use local context for en/decryption operations. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_crypto_internal.h | 2 +- platform/linux-generic/odp_crypto.c | 84 ++++++++++------------ 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index 515cefaa0..d1020dba3 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -53,7 +53,7 @@ struct odp_crypto_generic_session { AES_KEY key; } aes; struct { - EVP_CIPHER_CTX *ctx; + uint8_t key[EVP_MAX_KEY_LENGTH]; } aes_gcm; } data; crypto_func_t func; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 3f298485c..3deec7de3 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -265,11 +265,13 @@ static odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); uint32_t plain_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; void *iv_ptr; + int cipher_len = 0; uint8_t *tag = data + param->hash_result_offset; if (param->override_iv_ptr) @@ -280,12 +282,14 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, return ODP_CRYPTO_ALG_ERR_IV_INVALID; /* Adjust pointer for beginning of area to cipher/auth */ - uint8_t *plaindata = data + param->cipher_range.offset; + data += param->cipher_range.offset; /* Encrypt it */ - EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; - int cipher_len = 0; - + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, + session->cipher.data.aes_gcm.key, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, + session->p.iv.length, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); /* Authenticate header data (if any) without encrypting them */ @@ -293,13 +297,14 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, EVP_EncryptUpdate(ctx, NULL, &cipher_len, aad_head, aad_len); - EVP_EncryptUpdate(ctx, plaindata, &cipher_len, - plaindata, plain_len); + EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); - EVP_EncryptFinal_ex(ctx, plaindata + cipher_len, &cipher_len); + EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, session->p.auth_digest_len, tag); + EVP_CIPHER_CTX_free(ctx); + return ODP_CRYPTO_ALG_ERR_NONE; } @@ -307,10 +312,12 @@ static odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); uint32_t cipher_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; + int plain_len = 0; void *iv_ptr; uint8_t *tag = data + param->hash_result_offset; @@ -322,11 +329,14 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, return ODP_CRYPTO_ALG_ERR_IV_INVALID; /* Adjust pointer for beginning of area to cipher/auth */ - uint8_t *cipherdata = data + param->cipher_range.offset; - /* Encrypt it */ - EVP_CIPHER_CTX *ctx = session->cipher.data.aes_gcm.ctx; - int plain_len = 0; + data += param->cipher_range.offset; + /* Decrypt it */ + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, + session->cipher.data.aes_gcm.key, NULL); + EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, + session->p.iv.length, NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, @@ -337,12 +347,13 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, EVP_DecryptUpdate(ctx, NULL, &plain_len, aad_head, aad_len); - EVP_DecryptUpdate(ctx, cipherdata, &plain_len, - cipherdata, cipher_len); + EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); - if (EVP_DecryptFinal_ex(ctx, cipherdata + plain_len, &plain_len) <= 0) + if (EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len) <= 0) return ODP_CRYPTO_ALG_ERR_ICV_CHECK; + EVP_CIPHER_CTX_free(ctx); + return ODP_CRYPTO_ALG_ERR_NONE; } @@ -352,27 +363,14 @@ static int process_aes_gcm_param(odp_crypto_generic_session_t *session) if (session->p.cipher_key.length != 16) return -1; - /* Set function */ - EVP_CIPHER_CTX *ctx = - session->cipher.data.aes_gcm.ctx = EVP_CIPHER_CTX_new(); + memcpy(session->cipher.data.aes_gcm.key, session->p.cipher_key.data, + session->p.cipher_key.length); - if (ODP_CRYPTO_OP_ENCODE == session->p.op) { + /* Set function */ + if (ODP_CRYPTO_OP_ENCODE == session->p.op) session->cipher.func = aes_gcm_encrypt; - EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); - } else { + else session->cipher.func = aes_gcm_decrypt; - EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); - } - - EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, - session->p.iv.length, NULL); - if (ODP_CRYPTO_OP_ENCODE == session->p.op) { - EVP_EncryptInit_ex(ctx, NULL, NULL, - session->p.cipher_key.data, NULL); - } else { - EVP_DecryptInit_ex(ctx, NULL, NULL, - session->p.cipher_key.data, NULL); - } return 0; } @@ -635,17 +633,16 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, /* Copy parameters */ session->p = *param; - /* Copy IV data */ - if (session->p.iv.data) { - if (session->p.iv.length > MAX_IV_LEN) { - ODP_DBG("Maximum IV length exceeded\n"); - free_session(session); - return -1; - } + if (session->p.iv.length > MAX_IV_LEN) { + ODP_DBG("Maximum IV length exceeded\n"); + free_session(session); + return -1; + } + /* Copy IV data */ + if (session->p.iv.data) memcpy(session->cipher.iv_data, session->p.iv.data, session->p.iv.length); - } /* Derive order */ if (ODP_CRYPTO_OP_ENCODE == param->op) @@ -757,15 +754,8 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, int odp_crypto_session_destroy(odp_crypto_session_t session) { odp_crypto_generic_session_t *generic; - int aes_gcm = 0; generic = (odp_crypto_generic_session_t *)(intptr_t)session; -#if ODP_DEPRECATED_API - if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES128_GCM) - aes_gcm = 1; -#endif - if (generic->p.cipher_alg == ODP_CIPHER_ALG_AES_GCM || aes_gcm) - EVP_CIPHER_CTX_free(generic->cipher.data.aes_gcm.ctx); memset(generic, 0, sizeof(*generic)); free_session(generic); return 0; -- cgit v1.2.3 From dcd53771432aeb838f2584458589b3430104abcf Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:26 +0300 Subject: linux-generic: crypto: explicitly disable padding for AES-GCM Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 3deec7de3..ff3f1ac76 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -291,6 +291,7 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, session->p.iv.length, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); /* Authenticate header data (if any) without encrypting them */ if (aad_len > 0) @@ -338,6 +339,7 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, session->p.iv.length, NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, session->p.auth_digest_len, tag); -- cgit v1.2.3 From 14df663ba9534101305ea4f5201fc2a5e55a974f Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:27 +0300 Subject: linux-generic: crypto: rewrite AES-CBC support using EVP functions Rewrite AES-CBC to use generic EVP interface following AES-GCM implementation. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_crypto_internal.h | 3 +- platform/linux-generic/odp_crypto.c | 70 ++++++++++++---------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index d1020dba3..d6fd04003 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -12,7 +12,6 @@ extern "C" { #endif #include -#include #include #define MAX_IV_LEN 64 @@ -50,7 +49,7 @@ struct odp_crypto_generic_session { DES_key_schedule ks3; } des; struct { - AES_KEY key; + uint8_t key[EVP_MAX_KEY_LENGTH]; } aes; struct { uint8_t key[EVP_MAX_KEY_LENGTH]; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index ff3f1ac76..f503bd983 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -181,10 +181,11 @@ static odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; + uint32_t plain_len = param->cipher_range.length; void *iv_ptr; + int cipher_len = 0; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -193,18 +194,21 @@ odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - - /* Adjust pointer for beginning of area to cipher */ + /* Adjust pointer for beginning of area to cipher/auth */ data += param->cipher_range.offset; + /* Encrypt it */ - AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, - iv_enc, AES_ENCRYPT); + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, + session->cipher.data.aes.key, NULL); + EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); + + EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); + + EVP_CIPHER_CTX_free(ctx); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -213,9 +217,10 @@ static odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - unsigned char iv_enc[AES_BLOCK_SIZE]; + uint32_t cipher_len = param->cipher_range.length; + int plain_len = 0; void *iv_ptr; if (param->override_iv_ptr) @@ -225,18 +230,21 @@ odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv_enc, iv_ptr, AES_BLOCK_SIZE); - - /* Adjust pointer for beginning of area to cipher */ + /* Adjust pointer for beginning of area to cipher/auth */ data += param->cipher_range.offset; - /* Encrypt it */ - AES_cbc_encrypt(data, data, len, &session->cipher.data.aes.key, - iv_enc, AES_DECRYPT); + + /* Decrypt it */ + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, + session->cipher.data.aes.key, NULL); + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); + + EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len); + + EVP_CIPHER_CTX_free(ctx); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -247,16 +255,14 @@ static int process_aes_param(odp_crypto_generic_session_t *session) if (!((0 == session->p.iv.length) || (16 == session->p.iv.length))) return -1; + memcpy(session->cipher.data.aes.key, session->p.cipher_key.data, + session->p.cipher_key.length); + /* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) { + if (ODP_CRYPTO_OP_ENCODE == session->p.op) session->cipher.func = aes_encrypt; - AES_set_encrypt_key(session->p.cipher_key.data, 128, - &session->cipher.data.aes.key); - } else { + else session->cipher.func = aes_decrypt; - AES_set_decrypt_key(session->p.cipher_key.data, 128, - &session->cipher.data.aes.key); - } return 0; } -- cgit v1.2.3 From c3d3787ae527291e969a60bc54dd4e2ab220251d Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:28 +0300 Subject: linux-generic: crypto: rewrite 3DES-CBC support using EVP functions Rewrite 3DES-CBC to use generic EVP interface following AES-GCM implementation. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_crypto_internal.h | 5 +- platform/linux-generic/odp_crypto.c | 78 ++++++++++------------ 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index d6fd04003..f4f1948f8 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -11,7 +11,6 @@ extern "C" { #endif -#include #include #define MAX_IV_LEN 64 @@ -44,9 +43,7 @@ struct odp_crypto_generic_session { union { struct { - DES_key_schedule ks1; - DES_key_schedule ks2; - DES_key_schedule ks3; + uint8_t key[EVP_MAX_KEY_LENGTH]; } des; struct { uint8_t key[EVP_MAX_KEY_LENGTH]; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index f503bd983..bff712d18 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -387,10 +387,11 @@ static odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - DES_cblock iv; + uint32_t plain_len = param->cipher_range.length; void *iv_ptr; + int cipher_len = 0; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -399,24 +400,21 @@ odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv, iv_ptr, sizeof(iv)); - - /* Adjust pointer for beginning of area to cipher */ + /* Adjust pointer for beginning of area to cipher/auth */ data += param->cipher_range.offset; + /* Encrypt it */ - DES_ede3_cbc_encrypt(data, - data, - len, - &session->cipher.data.des.ks1, - &session->cipher.data.des.ks2, - &session->cipher.data.des.ks3, - &iv, - 1); + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, + session->cipher.data.des.key, NULL); + EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); + + EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); + + EVP_CIPHER_CTX_cleanup(ctx); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -425,9 +423,10 @@ static odp_crypto_alg_err_t des_decrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { + EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t len = param->cipher_range.length; - DES_cblock iv; + uint32_t cipher_len = param->cipher_range.length; + int plain_len = 0; void *iv_ptr; if (param->override_iv_ptr) @@ -437,25 +436,21 @@ odp_crypto_alg_err_t des_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* - * Create a copy of the IV. The DES library modifies IV - * and if we are processing packets on parallel threads - * we could get corruption. - */ - memcpy(iv, iv_ptr, sizeof(iv)); - - /* Adjust pointer for beginning of area to cipher */ + /* Adjust pointer for beginning of area to cipher/auth */ data += param->cipher_range.offset; /* Decrypt it */ - DES_ede3_cbc_encrypt(data, - data, - len, - &session->cipher.data.des.ks1, - &session->cipher.data.des.ks2, - &session->cipher.data.des.ks3, - &iv, - 0); + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, + session->cipher.data.des.key, NULL); + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); + EVP_CIPHER_CTX_set_padding(ctx, 0); + + EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); + + EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len); + + EVP_CIPHER_CTX_cleanup(ctx); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -466,20 +461,15 @@ static int process_des_param(odp_crypto_generic_session_t *session) if (!((0 == session->p.iv.length) || (8 == session->p.iv.length))) return -1; + memcpy(session->cipher.data.des.key, session->p.cipher_key.data, + session->p.cipher_key.length); + /* Set function */ if (ODP_CRYPTO_OP_ENCODE == session->p.op) session->cipher.func = des_encrypt; else session->cipher.func = des_decrypt; - /* Convert keys */ - DES_set_key((DES_cblock *)&session->p.cipher_key.data[0], - &session->cipher.data.des.ks1); - DES_set_key((DES_cblock *)&session->p.cipher_key.data[8], - &session->cipher.data.des.ks2); - DES_set_key((DES_cblock *)&session->p.cipher_key.data[16], - &session->cipher.data.des.ks3); - return 0; } -- cgit v1.2.3 From 2210dc7d26125ac9b8b51fa4de7b2b72e4e8f13e Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:29 +0300 Subject: linux-generic: crypto: merge AES-CBC and 3DES-CBC support There is now nearly no difference between AES-CBC and 3DES-CBC code. Merge it into generic 'cipher' support, easing adding support for other ciphers in future. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- .../linux-generic/include/odp_crypto_internal.h | 13 +- platform/linux-generic/odp_crypto.c | 153 +++++---------------- 2 files changed, 40 insertions(+), 126 deletions(-) diff --git a/platform/linux-generic/include/odp_crypto_internal.h b/platform/linux-generic/include/odp_crypto_internal.h index f4f1948f8..c3b70b231 100644 --- a/platform/linux-generic/include/odp_crypto_internal.h +++ b/platform/linux-generic/include/odp_crypto_internal.h @@ -40,18 +40,9 @@ struct odp_crypto_generic_session { struct { /* Copy of session IV data */ uint8_t iv_data[MAX_IV_LEN]; + uint8_t key_data[EVP_MAX_KEY_LENGTH]; - union { - struct { - uint8_t key[EVP_MAX_KEY_LENGTH]; - } des; - struct { - uint8_t key[EVP_MAX_KEY_LENGTH]; - } aes; - struct { - uint8_t key[EVP_MAX_KEY_LENGTH]; - } aes_gcm; - } data; + const EVP_CIPHER *evp_cipher; crypto_func_t func; } cipher; diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index bff712d18..2ba077f9d 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -178,8 +178,8 @@ odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param, } static -odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param, + odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); @@ -199,8 +199,8 @@ odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, /* Encrypt it */ ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, - session->cipher.data.aes.key, NULL); + EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + session->cipher.key_data, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_set_padding(ctx, 0); @@ -214,8 +214,8 @@ odp_crypto_alg_err_t aes_encrypt(odp_crypto_op_param_t *param, } static -odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) +odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param, + odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; uint8_t *data = odp_packet_data(param->out_pkt); @@ -235,8 +235,8 @@ odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, /* Decrypt it */ ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, - session->cipher.data.aes.key, NULL); + EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + session->cipher.key_data, NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_set_padding(ctx, 0); @@ -249,20 +249,29 @@ odp_crypto_alg_err_t aes_decrypt(odp_crypto_op_param_t *param, return ODP_CRYPTO_ALG_ERR_NONE; } -static int process_aes_param(odp_crypto_generic_session_t *session) +static int process_cipher_param(odp_crypto_generic_session_t *session, + const EVP_CIPHER *cipher) { - /* Verify IV len is either 0 or 16 */ - if (!((0 == session->p.iv.length) || (16 == session->p.iv.length))) + /* Verify Key len is valid */ + if ((uint32_t)EVP_CIPHER_key_length(cipher) != + session->p.cipher_key.length) return -1; - memcpy(session->cipher.data.aes.key, session->p.cipher_key.data, + /* Verify IV len is correct */ + if (!((0 == session->p.iv.length) || + ((uint32_t)EVP_CIPHER_iv_length(cipher) == session->p.iv.length))) + return -1; + + session->cipher.evp_cipher = cipher; + + memcpy(session->cipher.key_data, session->p.cipher_key.data, session->p.cipher_key.length); /* Set function */ if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->cipher.func = aes_encrypt; + session->cipher.func = cipher_encrypt; else - session->cipher.func = aes_decrypt; + session->cipher.func = cipher_decrypt; return 0; } @@ -292,8 +301,8 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, /* Encrypt it */ ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, - session->cipher.data.aes_gcm.key, NULL); + EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + session->cipher.key_data, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, session->p.iv.length, NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); @@ -340,8 +349,8 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, /* Decrypt it */ ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, - session->cipher.data.aes_gcm.key, NULL); + EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, + session->cipher.key_data, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, session->p.iv.length, NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); @@ -365,15 +374,19 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, return ODP_CRYPTO_ALG_ERR_NONE; } -static int process_aes_gcm_param(odp_crypto_generic_session_t *session) +static int process_aes_gcm_param(odp_crypto_generic_session_t *session, + const EVP_CIPHER *cipher) { - /* Verify Key len is 16 */ - if (session->p.cipher_key.length != 16) + /* Verify Key len is valid */ + if ((uint32_t)EVP_CIPHER_key_length(cipher) != + session->p.cipher_key.length) return -1; - memcpy(session->cipher.data.aes_gcm.key, session->p.cipher_key.data, + memcpy(session->cipher.key_data, session->p.cipher_key.data, session->p.cipher_key.length); + session->cipher.evp_cipher = cipher; + /* Set function */ if (ODP_CRYPTO_OP_ENCODE == session->p.op) session->cipher.func = aes_gcm_encrypt; @@ -383,96 +396,6 @@ static int process_aes_gcm_param(odp_crypto_generic_session_t *session) return 0; } -static -odp_crypto_alg_err_t des_encrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t plain_len = param->cipher_range.length; - void *iv_ptr; - int cipher_len = 0; - - if (param->override_iv_ptr) - iv_ptr = param->override_iv_ptr; - else if (session->p.iv.data) - iv_ptr = session->cipher.iv_data; - else - return ODP_CRYPTO_ALG_ERR_IV_INVALID; - - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - - /* Encrypt it */ - ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, - session->cipher.data.des.key, NULL); - EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); - EVP_CIPHER_CTX_set_padding(ctx, 0); - - EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); - - EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); - - EVP_CIPHER_CTX_cleanup(ctx); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static -odp_crypto_alg_err_t des_decrypt(odp_crypto_op_param_t *param, - odp_crypto_generic_session_t *session) -{ - EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t cipher_len = param->cipher_range.length; - int plain_len = 0; - void *iv_ptr; - - if (param->override_iv_ptr) - iv_ptr = param->override_iv_ptr; - else if (session->p.iv.data) - iv_ptr = session->cipher.iv_data; - else - return ODP_CRYPTO_ALG_ERR_IV_INVALID; - - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - - /* Decrypt it */ - ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(ctx, EVP_des_ede3_cbc(), NULL, - session->cipher.data.des.key, NULL); - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); - EVP_CIPHER_CTX_set_padding(ctx, 0); - - EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); - - EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len); - - EVP_CIPHER_CTX_cleanup(ctx); - - return ODP_CRYPTO_ALG_ERR_NONE; -} - -static int process_des_param(odp_crypto_generic_session_t *session) -{ - /* Verify IV len is either 0 or 8 */ - if (!((0 == session->p.iv.length) || (8 == session->p.iv.length))) - return -1; - - memcpy(session->cipher.data.des.key, session->p.cipher_key.data, - session->p.cipher_key.length); - - /* Set function */ - if (ODP_CRYPTO_OP_ENCODE == session->p.op) - session->cipher.func = des_encrypt; - else - session->cipher.func = des_decrypt; - - return 0; -} - static int process_auth_param(odp_crypto_generic_session_t *session, uint32_t key_length, const EVP_MD *evp_md) @@ -656,13 +579,13 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, break; case ODP_CIPHER_ALG_DES: case ODP_CIPHER_ALG_3DES_CBC: - rc = process_des_param(session); + rc = process_cipher_param(session, EVP_des_ede3_cbc()); break; case ODP_CIPHER_ALG_AES_CBC: #if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_CBC: #endif - rc = process_aes_param(session); + rc = process_cipher_param(session, EVP_aes_128_cbc()); break; #if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_GCM: @@ -674,7 +597,7 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, /* AES-GCM requires to do both auth and * cipher at the same time */ if (param->auth_alg == ODP_AUTH_ALG_AES_GCM || aes_gcm) - rc = process_aes_gcm_param(session); + rc = process_aes_gcm_param(session, EVP_aes_128_gcm()); else rc = -1; break; -- cgit v1.2.3 From fec16fd81d4084340f0f9a6893c9772000608031 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:30 +0300 Subject: linux-generic: crypto: make HMAC work across segmented packets Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 78 +++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 2ba077f9d..7ea90fb92 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -111,30 +111,54 @@ null_crypto_routine(odp_crypto_op_param_t *param ODP_UNUSED, return ODP_CRYPTO_ALG_ERR_NONE; } +static +void packet_hmac(odp_crypto_op_param_t *param, + odp_crypto_generic_session_t *session, + uint8_t *hash) +{ + odp_packet_t pkt = param->out_pkt; + uint32_t offset = param->auth_range.offset; + uint32_t len = param->auth_range.length; + HMAC_CTX ctx; + + ODP_ASSERT(offset + len <= odp_packet_len(pkt)); + + /* Hash it */ + HMAC_CTX_init(&ctx); + HMAC_Init_ex(&ctx, + session->auth.key, + session->auth.key_length, + session->auth.evp_md, + NULL); + + while (len > 0) { + uint32_t seglen = 0; /* GCC */ + void *mapaddr = odp_packet_offset(pkt, offset, &seglen, NULL); + uint32_t maclen = len > seglen ? seglen : len; + + HMAC_Update(&ctx, mapaddr, maclen); + offset += maclen; + len -= maclen; + } + + HMAC_Final(&ctx, hash, NULL); + HMAC_CTX_cleanup(&ctx); +} + static odp_crypto_alg_err_t auth_gen(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { - uint8_t *data = odp_packet_data(param->out_pkt); - uint8_t *icv = data; - uint32_t len = param->auth_range.length; uint8_t hash[EVP_MAX_MD_SIZE]; - /* Adjust pointer for beginning of area to auth */ - data += param->auth_range.offset; - icv += param->hash_result_offset; - /* Hash it */ - HMAC(session->auth.evp_md, - session->auth.key, - session->auth.key_length, - data, - len, - hash, - NULL); + packet_hmac(param, session, hash); /* Copy to the output location */ - memcpy(icv, hash, session->auth.bytes); + odp_packet_copy_from_mem(param->out_pkt, + param->hash_result_offset, + session->auth.bytes, + hash); return ODP_CRYPTO_ALG_ERR_NONE; } @@ -143,31 +167,19 @@ static odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { - uint8_t *data = odp_packet_data(param->out_pkt); - uint8_t *icv = data; - uint32_t len = param->auth_range.length; uint32_t bytes = session->auth.bytes; uint8_t hash_in[EVP_MAX_MD_SIZE]; uint8_t hash_out[EVP_MAX_MD_SIZE]; - /* Adjust pointer for beginning of area to auth */ - data += param->auth_range.offset; - icv += param->hash_result_offset; - /* Copy current value out and clear it before authentication */ - memset(hash_in, 0, sizeof(hash_in)); - memcpy(hash_in, icv, bytes); - memset(icv, 0, bytes); - memset(hash_out, 0, sizeof(hash_out)); + odp_packet_copy_to_mem(param->out_pkt, param->hash_result_offset, + bytes, hash_in); + + _odp_packet_set_data(param->out_pkt, param->hash_result_offset, + 0, bytes); /* Hash it */ - HMAC(session->auth.evp_md, - session->auth.key, - session->auth.key_length, - data, - len, - hash_out, - NULL); + packet_hmac(param, session, hash_out); /* Verify match */ if (0 != memcmp(hash_in, hash_out, bytes)) -- cgit v1.2.3 From b93c17b30d051b114a099ed5219fb2a82f5a864c Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:31 +0300 Subject: linux-generic: crypto: make en/decryption work across packet segments Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 184 +++++++++++++++++++++++++++--------- 1 file changed, 138 insertions(+), 46 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 7ea90fb92..ea7c70265 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -189,15 +189,123 @@ odp_crypto_alg_err_t auth_check(odp_crypto_op_param_t *param, return ODP_CRYPTO_ALG_ERR_NONE; } +static +int internal_encrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param) +{ + odp_packet_t pkt = param->out_pkt; + unsigned in_pos = param->cipher_range.offset; + unsigned out_pos = param->cipher_range.offset; + unsigned in_len = param->cipher_range.length; + uint8_t block[2 * EVP_MAX_BLOCK_LENGTH]; + unsigned block_len = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ctx)); + int cipher_len; + int ret; + + while (in_len > 0) { + uint32_t seglen = 0; /* GCC */ + uint8_t *insegaddr = odp_packet_offset(pkt, in_pos, + &seglen, NULL); + unsigned inseglen = in_len < seglen ? in_len : seglen; + + /* There should be at least 1 additional block in out buffer */ + if (inseglen > block_len) { + unsigned part = inseglen - block_len; + + EVP_EncryptUpdate(ctx, insegaddr, &cipher_len, + insegaddr, part); + in_pos += part; + in_len -= part; + insegaddr += part; + inseglen -= part; + + out_pos += cipher_len; + } + + /* Use temporal storage */ + if (inseglen > 0) { + unsigned part = inseglen; + + EVP_EncryptUpdate(ctx, block, &cipher_len, + insegaddr, part); + in_pos += part; + in_len -= part; + insegaddr += part; + inseglen -= part; + + odp_packet_copy_from_mem(pkt, out_pos, + cipher_len, block); + out_pos += cipher_len; + } + } + + ret = EVP_EncryptFinal_ex(ctx, block, &cipher_len); + odp_packet_copy_from_mem(pkt, out_pos, cipher_len, block); + + return ret; +} + +static +int internal_decrypt(EVP_CIPHER_CTX *ctx, odp_crypto_op_param_t *param) +{ + odp_packet_t pkt = param->out_pkt; + unsigned in_pos = param->cipher_range.offset; + unsigned out_pos = param->cipher_range.offset; + unsigned in_len = param->cipher_range.length; + uint8_t block[2 * EVP_MAX_BLOCK_LENGTH]; + unsigned block_len = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ctx)); + int cipher_len; + int ret; + + while (in_len > 0) { + uint32_t seglen = 0; /* GCC */ + uint8_t *insegaddr = odp_packet_offset(pkt, in_pos, + &seglen, NULL); + unsigned inseglen = in_len < seglen ? in_len : seglen; + + /* There should be at least 1 additional block in out buffer */ + if (inseglen > block_len) { + unsigned part = inseglen - block_len; + + EVP_DecryptUpdate(ctx, insegaddr, &cipher_len, + insegaddr, part); + in_pos += part; + in_len -= part; + insegaddr += part; + inseglen -= part; + + out_pos += cipher_len; + } + + /* Use temporal storage */ + if (inseglen > 0) { + unsigned part = inseglen; + + EVP_DecryptUpdate(ctx, block, &cipher_len, + insegaddr, part); + in_pos += part; + in_len -= part; + insegaddr += part; + inseglen -= part; + + odp_packet_copy_from_mem(pkt, out_pos, + cipher_len, block); + out_pos += cipher_len; + } + } + + ret = EVP_DecryptFinal_ex(ctx, block, &cipher_len); + odp_packet_copy_from_mem(pkt, out_pos, cipher_len, block); + + return ret; +} + static odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t plain_len = param->cipher_range.length; void *iv_ptr; - int cipher_len = 0; + int ret; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -206,9 +314,6 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - /* Encrypt it */ ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, @@ -216,13 +321,12 @@ odp_crypto_alg_err_t cipher_encrypt(odp_crypto_op_param_t *param, EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_set_padding(ctx, 0); - EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); - - EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); + ret = internal_encrypt(ctx, param); EVP_CIPHER_CTX_free(ctx); - return ODP_CRYPTO_ALG_ERR_NONE; + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE : + ODP_CRYPTO_ALG_ERR_NONE; } static @@ -230,10 +334,8 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t cipher_len = param->cipher_range.length; - int plain_len = 0; void *iv_ptr; + int ret; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -242,9 +344,6 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - /* Decrypt it */ ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, @@ -252,13 +351,12 @@ odp_crypto_alg_err_t cipher_decrypt(odp_crypto_op_param_t *param, EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_set_padding(ctx, 0); - EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); - - EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len); + ret = internal_decrypt(ctx, param); EVP_CIPHER_CTX_free(ctx); - return ODP_CRYPTO_ALG_ERR_NONE; + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE : + ODP_CRYPTO_ALG_ERR_NONE; } static int process_cipher_param(odp_crypto_generic_session_t *session, @@ -293,13 +391,12 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t plain_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; void *iv_ptr; - int cipher_len = 0; - uint8_t *tag = data + param->hash_result_offset; + int dummy_len = 0; + uint8_t block[EVP_MAX_MD_SIZE]; + int ret; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -308,9 +405,6 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - /* Encrypt it */ ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, session->cipher.evp_cipher, NULL, @@ -322,18 +416,20 @@ odp_crypto_alg_err_t aes_gcm_encrypt(odp_crypto_op_param_t *param, /* Authenticate header data (if any) without encrypting them */ if (aad_len > 0) - EVP_EncryptUpdate(ctx, NULL, &cipher_len, + EVP_EncryptUpdate(ctx, NULL, &dummy_len, aad_head, aad_len); - EVP_EncryptUpdate(ctx, data, &cipher_len, data, plain_len); + ret = internal_encrypt(ctx, param); - EVP_EncryptFinal_ex(ctx, data + cipher_len, &cipher_len); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, - session->p.auth_digest_len, tag); + session->p.auth_digest_len, block); + odp_packet_copy_from_mem(param->out_pkt, param->hash_result_offset, + session->p.auth_digest_len, block); EVP_CIPHER_CTX_free(ctx); - return ODP_CRYPTO_ALG_ERR_NONE; + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_DATA_SIZE : + ODP_CRYPTO_ALG_ERR_NONE; } static @@ -341,13 +437,12 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, odp_crypto_generic_session_t *session) { EVP_CIPHER_CTX *ctx; - uint8_t *data = odp_packet_data(param->out_pkt); - uint32_t cipher_len = param->cipher_range.length; const uint8_t *aad_head = param->aad.ptr; uint32_t aad_len = param->aad.length; - int plain_len = 0; + int dummy_len = 0; void *iv_ptr; - uint8_t *tag = data + param->hash_result_offset; + uint8_t block[EVP_MAX_MD_SIZE]; + int ret; if (param->override_iv_ptr) iv_ptr = param->override_iv_ptr; @@ -356,9 +451,6 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, else return ODP_CRYPTO_ALG_ERR_IV_INVALID; - /* Adjust pointer for beginning of area to cipher/auth */ - data += param->cipher_range.offset; - /* Decrypt it */ ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, session->cipher.evp_cipher, NULL, @@ -368,22 +460,22 @@ odp_crypto_alg_err_t aes_gcm_decrypt(odp_crypto_op_param_t *param, EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv_ptr); EVP_CIPHER_CTX_set_padding(ctx, 0); + odp_packet_copy_to_mem(param->out_pkt, param->hash_result_offset, + session->p.auth_digest_len, block); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, - session->p.auth_digest_len, tag); + session->p.auth_digest_len, block); /* Authenticate header data (if any) without encrypting them */ if (aad_len > 0) - EVP_DecryptUpdate(ctx, NULL, &plain_len, + EVP_DecryptUpdate(ctx, NULL, &dummy_len, aad_head, aad_len); - EVP_DecryptUpdate(ctx, data, &plain_len, data, cipher_len); - - if (EVP_DecryptFinal_ex(ctx, data + plain_len, &plain_len) <= 0) - return ODP_CRYPTO_ALG_ERR_ICV_CHECK; + ret = internal_decrypt(ctx, param); EVP_CIPHER_CTX_free(ctx); - return ODP_CRYPTO_ALG_ERR_NONE; + return ret <= 0 ? ODP_CRYPTO_ALG_ERR_ICV_CHECK : + ODP_CRYPTO_ALG_ERR_NONE; } static int process_aes_gcm_param(odp_crypto_generic_session_t *session, -- cgit v1.2.3 From 8d4ecf491a0af45c499d38c6e72853e756d69f0e Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:32 +0300 Subject: linux-generic: crypto: NULL session->next pointer on session allocation Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index ea7c70265..32fece308 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -88,8 +88,10 @@ odp_crypto_generic_session_t *alloc_session(void) odp_spinlock_lock(&global->lock); session = global->free; - if (session) + if (session) { global->free = session->next; + session->next = NULL; + } odp_spinlock_unlock(&global->lock); return session; -- cgit v1.2.3 From ca1ebaa8319604d4f5fe303be7150b7278fe9d94 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:33 +0300 Subject: test: odp_crypto: bail out if odp_crypto_session_create failed If odp_crypto_session_create() failed, there is no point in checking/freeing session, as it might not have been updated. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- test/common_plat/performance/odp_crypto.c | 44 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/test/common_plat/performance/odp_crypto.c b/test/common_plat/performance/odp_crypto.c index 6a58294a2..c3dd6d38f 100644 --- a/test/common_plat/performance/odp_crypto.c +++ b/test/common_plat/performance/odp_crypto.c @@ -665,34 +665,32 @@ run_measure_one_config(crypto_args_t *cargs, int rc = 0; if (create_session_from_config(&session, config, cargs)) - rc = -1; - - if (!rc) { - if (cargs->payload_length) { - rc = run_measure_one(cargs, config, &session, - cargs->payload_length, &result); - if (!rc) { - print_result_header(); - print_result(cargs, cargs->payload_length, - config, &result); - } - } else { - unsigned i; + return -1; + if (cargs->payload_length) { + rc = run_measure_one(cargs, config, &session, + cargs->payload_length, &result); + if (!rc) { print_result_header(); - for (i = 0; i < num_payloads; i++) { - rc = run_measure_one(cargs, config, &session, - payloads[i], &result); - if (rc) - break; - print_result(cargs, payloads[i], - config, &result); - } + print_result(cargs, cargs->payload_length, + config, &result); + } + } else { + unsigned i; + + print_result_header(); + for (i = 0; i < num_payloads; i++) { + rc = run_measure_one(cargs, config, &session, + payloads[i], &result); + if (rc) + break; + print_result(cargs, payloads[i], + config, &result); } } - if (session != ODP_CRYPTO_SESSION_INVALID) - odp_crypto_session_destroy(session); + odp_crypto_session_destroy(session); + return rc; } -- cgit v1.2.3 From 2156eaa076fe0ca0aaa910c8902d5b60aa3bbed6 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:34 +0300 Subject: crypto: linux-generic: add capabilities for CIPHER_NULL and AUTH_NULL There is no point in having separate cases for NULL algorithms. Add capabilities returning 0 key/digest/iv length. Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 14 ++++++++++---- .../validation/api/crypto/odp_crypto_test_inp.c | 18 ++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 32fece308..9e5a11900 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -34,6 +34,9 @@ * * Keep sorted: first by key length, then by IV length */ +static const odp_crypto_cipher_capability_t cipher_capa_null[] = { +{.key_len = 0, .iv_len = 0} }; + static const odp_crypto_cipher_capability_t cipher_capa_des[] = { {.key_len = 24, .iv_len = 8} }; @@ -51,6 +54,9 @@ static const odp_crypto_cipher_capability_t cipher_capa_aes_gcm[] = { * * Keep sorted: first by digest length, then by key length */ +static const odp_crypto_auth_capability_t auth_capa_null[] = { +{.digest_len = 0, .key_len = 0, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; + static const odp_crypto_auth_capability_t auth_capa_md5_hmac[] = { {.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} }, {.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; @@ -571,8 +577,8 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, switch (cipher) { case ODP_CIPHER_ALG_NULL: - src = NULL; - num = 0; + src = cipher_capa_null; + num = sizeof(cipher_capa_null) / size; break; case ODP_CIPHER_ALG_DES: src = cipher_capa_des; @@ -611,8 +617,8 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, switch (auth) { case ODP_AUTH_ALG_NULL: - src = NULL; - num = 0; + src = auth_capa_null; + num = sizeof(auth_capa_null) / size; break; case ODP_AUTH_ALG_MD5_HMAC: src = auth_capa_md5_hmac; diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index c89d04f9c..470c5bc5e 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -141,13 +141,8 @@ static void alg_test(odp_crypto_op_t op, num = odp_crypto_cipher_capability(cipher_alg, cipher_capa, MAX_ALG_CAPA); - if (cipher_alg != ODP_CIPHER_ALG_NULL) { - CU_ASSERT(num > 0); - found = 0; - } else { - CU_ASSERT(num == 0); - found = 1; - } + CU_ASSERT(num > 0); + found = 0; CU_ASSERT(num <= MAX_ALG_CAPA); @@ -167,13 +162,8 @@ static void alg_test(odp_crypto_op_t op, num = odp_crypto_auth_capability(auth_alg, auth_capa, MAX_ALG_CAPA); - if (auth_alg != ODP_AUTH_ALG_NULL) { - CU_ASSERT(num > 0); - found = 0; - } else { - CU_ASSERT(num == 0); - found = 1; - } + CU_ASSERT(num > 0); + found = 0; CU_ASSERT(num <= MAX_ALG_CAPA); -- cgit v1.2.3 From bddd9fb0a5353c611bb9de78f3355d30147f8efc Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:35 +0300 Subject: validation: crypto: add tests for NULL cipher Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.h | 2 + .../validation/api/crypto/odp_crypto_test_inp.c | 71 ++++++++++++++++++++++ .../validation/api/crypto/test_vectors.h | 12 ++++ .../validation/api/crypto/test_vectors_len.h | 3 + 4 files changed, 88 insertions(+) diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h index 4d810f62b..2a491c3c9 100644 --- a/test/common_plat/validation/api/crypto/crypto.h +++ b/test/common_plat/validation/api/crypto/crypto.h @@ -10,6 +10,8 @@ #include "odp_cunit_common.h" /* test functions: */ +void crypto_test_enc_alg_null(void); +void crypto_test_dec_alg_null(void); void crypto_test_enc_alg_3des_cbc(void); void crypto_test_enc_alg_3des_cbc_ovr_iv(void); void crypto_test_dec_alg_3des_cbc(void); diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 470c5bc5e..4d8f7b54a 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -430,6 +430,73 @@ static int check_auth_options(odp_auth_alg_t auth, uint32_t key_len, return 1; } +static int check_alg_null(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_NULL); +} + +void crypto_test_enc_alg_null(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0}; + unsigned int test_vec_num = (sizeof(null_reference_length) / + sizeof(null_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + if (!check_cipher_options(ODP_CIPHER_ALG_NULL, + cipher_key.length, iv.length)) + continue; + + alg_test(ODP_CRYPTO_OP_ENCODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_NULL, + auth_key, + NULL, NULL, + NULL, 0, + null_reference_plaintext[i], + null_reference_length[i], + null_reference_plaintext[i], + null_reference_length[i], NULL, 0); + } +} + +void crypto_test_dec_alg_null(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + unsigned int test_vec_num = (sizeof(null_reference_length) / + sizeof(null_reference_length[0])); + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + if (!check_cipher_options(ODP_CIPHER_ALG_NULL, + cipher_key.length, iv.length)) + continue; + + alg_test(ODP_CRYPTO_OP_DECODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + NULL, + cipher_key, + ODP_AUTH_ALG_NULL, + auth_key, + NULL, NULL, + NULL, 0, + null_reference_plaintext[i], + null_reference_length[i], + null_reference_plaintext[i], + null_reference_length[i], NULL, 0); + } +} + static int check_alg_3des_cbc(void) { return check_alg_support(ODP_CIPHER_ALG_3DES_CBC, ODP_AUTH_ALG_NULL); @@ -1252,6 +1319,10 @@ int crypto_suite_async_init(void) } odp_testinfo_t crypto_suite[] = { + ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_null, + check_alg_null), + ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_null, + check_alg_null), ODP_TEST_INFO_CONDITIONAL(crypto_test_enc_alg_3des_cbc, check_alg_3des_cbc), ODP_TEST_INFO_CONDITIONAL(crypto_test_dec_alg_3des_cbc, diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index 0d36c2498..6d568b918 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -8,6 +8,18 @@ #define _ODP_TEST_CRYPTO_VECTORS_H_ #include "test_vectors_len.h" + +/** length in bytes */ +static uint32_t null_reference_length[] = { 8, 16 }; + +static uint8_t +null_reference_plaintext[][NULL_MAX_DATA_LEN] = { + {0x32, 0x6a, 0x49, 0x4c, 0xd3, 0x3f, 0xe7, 0x56}, + + {0x84, 0x40, 0x1f, 0x78, 0xfe, 0x6c, 0x10, 0x87, 0x6d, 0x8e, 0xa2, 0x30, + 0x94, 0xea, 0x53, 0x09} +}; + /* TDES-CBC reference vectors, according to * "http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf" */ diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h index 80fd927b7..c1521dd76 100644 --- a/test/common_plat/validation/api/crypto/test_vectors_len.h +++ b/test/common_plat/validation/api/crypto/test_vectors_len.h @@ -6,6 +6,9 @@ #ifndef TEST_VECTORS_LEN_ #define TEST_VECTORS_LEN_ +/* NULL */ +#define NULL_MAX_DATA_LEN 16 + /* TDES-CBC */ #define TDES_CBC_KEY_LEN 24 #define TDES_CBC_IV_LEN 8 -- cgit v1.2.3 From ff6d71903cdfdd68246e3daabedd645bf30640cc Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:36 +0300 Subject: validation: crypto: add HMAC-SHA-1 test cases Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.h | 3 +- .../validation/api/crypto/odp_crypto_test_inp.c | 126 +++++++++++++++++++-- .../validation/api/crypto/test_vectors.h | 44 +++++++ .../validation/api/crypto/test_vectors_len.h | 6 + 4 files changed, 167 insertions(+), 12 deletions(-) diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h index 2a491c3c9..84e673791 100644 --- a/test/common_plat/validation/api/crypto/crypto.h +++ b/test/common_plat/validation/api/crypto/crypto.h @@ -26,7 +26,8 @@ void crypto_test_dec_alg_aes128_gcm(void); void crypto_test_dec_alg_aes128_gcm_ovr_iv(void); void crypto_test_gen_alg_hmac_md5(void); void crypto_test_check_alg_hmac_md5(void); -void crypto_test_alg_hmac_sha1(void); +void crypto_test_gen_alg_hmac_sha1(void); +void crypto_test_check_alg_hmac_sha1(void); void crypto_test_gen_alg_hmac_sha256(void); void crypto_test_check_alg_hmac_sha256(void); void crypto_test_alg_hmac_sha512(void); diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 4d8f7b54a..6129d82d9 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -28,6 +28,8 @@ static const char *auth_alg_name(odp_auth_alg_t auth) return "ODP_AUTH_ALG_NULL"; case ODP_AUTH_ALG_MD5_HMAC: return "ODP_AUTH_ALG_MD5_HMAC"; + case ODP_AUTH_ALG_SHA1_HMAC: + return "ODP_AUTH_ALG_SHA1_HMAC"; case ODP_AUTH_ALG_SHA256_HMAC: return "ODP_AUTH_ALG_SHA256_HMAC"; case ODP_AUTH_ALG_AES_GCM: @@ -131,6 +133,9 @@ static void alg_test(odp_crypto_op_t op, if (auth_alg == ODP_AUTH_ALG_NULL && !(capa.auths.bit.null)) rc = -1; + if (auth_alg == ODP_AUTH_ALG_SHA1_HMAC && + !(capa.auths.bit.sha1_hmac)) + rc = -1; if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC && !(capa.auths.bit.sha256_hmac)) rc = -1; @@ -1167,6 +1172,113 @@ void crypto_test_check_alg_hmac_md5(void) } } +static int check_alg_hmac_sha1(void) +{ + return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); +} + +/* This test verifies the correctness of HMAC_SHA1 digest operation. + * The output check length is truncated to 12 bytes (96 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +void crypto_test_gen_alg_hmac_sha1(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + + unsigned int test_vec_num = (sizeof(hmac_sha1_reference_length) / + sizeof(hmac_sha1_reference_length[0])); + + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_sha1_reference_key[i]; + auth_key.length = sizeof(hmac_sha1_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_SHA1_HMAC, + auth_key.length, + HMAC_SHA1_96_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_ENCODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA1_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha1_reference_plaintext[i], + hmac_sha1_reference_length[i], + NULL, 0, + hmac_sha1_reference_digest[i], + HMAC_SHA1_96_CHECK_LEN); + } +} + +void crypto_test_check_alg_hmac_sha1(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + uint8_t wrong_digest[HMAC_SHA1_DIGEST_LEN]; + + unsigned int test_vec_num = (sizeof(hmac_sha1_reference_length) / + sizeof(hmac_sha1_reference_length[0])); + + unsigned int i; + + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_sha1_reference_key[i]; + auth_key.length = sizeof(hmac_sha1_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_SHA1_HMAC, + auth_key.length, + HMAC_SHA1_96_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_DECODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA1_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha1_reference_plaintext[i], + hmac_sha1_reference_length[i], + NULL, 0, + hmac_sha1_reference_digest[i], + HMAC_SHA1_96_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA1_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha1_reference_plaintext[i], + hmac_sha1_reference_length[i], + NULL, 0, + wrong_digest, + HMAC_SHA1_96_CHECK_LEN); + } +} + static int check_alg_hmac_sha256(void) { return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA256_HMAC); @@ -1274,16 +1386,6 @@ void crypto_test_check_alg_hmac_sha256(void) } } -static int check_alg_hmac_sha1(void) -{ - return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA1_HMAC); -} - -void crypto_test_alg_hmac_sha1(void) -{ - printf(" TEST NOT IMPLEMENTED YET "); -} - static int check_alg_hmac_sha512(void) { return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); @@ -1351,7 +1453,9 @@ odp_testinfo_t crypto_suite[] = { check_alg_hmac_md5), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_md5, check_alg_hmac_md5), - ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha1, + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha1, + check_alg_hmac_sha1), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha1, check_alg_hmac_sha1), ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha256, check_alg_hmac_sha256), diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index 6d568b918..1de54964d 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -353,4 +353,48 @@ static uint32_t hmac_sha256_reference_digest_length[] = { 16, 16, 16 }; +static uint8_t hmac_sha1_reference_key[][HMAC_SHA1_KEY_LEN] = { + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b }, + + /* "Jefe" */ + { 0x4a, 0x65, 0x66, 0x65 }, + + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa } +}; + +static uint32_t hmac_sha1_reference_length[] = { 8, 28, 50 }; + +static uint8_t +hmac_sha1_reference_plaintext[][HMAC_SHA1_MAX_DATA_LEN] = { + /* "Hi There" */ + { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65}, + + /* what do ya want for nothing?*/ + { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, + 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x3f }, + + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd } +}; + +static uint8_t hmac_sha1_reference_digest[][HMAC_SHA1_DIGEST_LEN] = { + { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, + 0x72, 0x64, 0xe2, 0x8b, 0xc0, 0xb6 }, + + { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, + 0x2f, 0xa2, 0xd2, 0x74, 0x16, 0xd5 }, + + { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, + 0x11, 0xcd, 0x91, 0xa3, 0x9a, 0xf4 }, +}; + #endif diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h index c1521dd76..5c3ddcee5 100644 --- a/test/common_plat/validation/api/crypto/test_vectors_len.h +++ b/test/common_plat/validation/api/crypto/test_vectors_len.h @@ -35,4 +35,10 @@ #define HMAC_SHA256_MAX_DATA_LEN 128 #define HMAC_SHA256_DIGEST_LEN 32 +/* HMAC-SHA1 */ +#define HMAC_SHA1_KEY_LEN 20 +#define HMAC_SHA1_MAX_DATA_LEN 128 +#define HMAC_SHA1_DIGEST_LEN 20 +#define HMAC_SHA1_96_CHECK_LEN 12 + #endif -- cgit v1.2.3 From e248b708ff31467591fb99f7cc8652ab9e3081b2 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:37 +0300 Subject: validation: crypto: add HMAC-SHA-512 test cases Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- test/common_plat/validation/api/crypto/crypto.h | 3 +- .../validation/api/crypto/odp_crypto_test_inp.c | 110 ++++++++++++++++++++- .../validation/api/crypto/test_vectors.h | 50 ++++++++++ .../validation/api/crypto/test_vectors_len.h | 6 ++ 4 files changed, 165 insertions(+), 4 deletions(-) diff --git a/test/common_plat/validation/api/crypto/crypto.h b/test/common_plat/validation/api/crypto/crypto.h index 84e673791..dd15b448f 100644 --- a/test/common_plat/validation/api/crypto/crypto.h +++ b/test/common_plat/validation/api/crypto/crypto.h @@ -30,7 +30,8 @@ void crypto_test_gen_alg_hmac_sha1(void); void crypto_test_check_alg_hmac_sha1(void); void crypto_test_gen_alg_hmac_sha256(void); void crypto_test_check_alg_hmac_sha256(void); -void crypto_test_alg_hmac_sha512(void); +void crypto_test_gen_alg_hmac_sha512(void); +void crypto_test_check_alg_hmac_sha512(void); /* test arrays: */ extern odp_testinfo_t crypto_suite[]; diff --git a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c index 6129d82d9..ae600e230 100644 --- a/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c +++ b/test/common_plat/validation/api/crypto/odp_crypto_test_inp.c @@ -32,6 +32,8 @@ static const char *auth_alg_name(odp_auth_alg_t auth) return "ODP_AUTH_ALG_SHA1_HMAC"; case ODP_AUTH_ALG_SHA256_HMAC: return "ODP_AUTH_ALG_SHA256_HMAC"; + case ODP_AUTH_ALG_SHA512_HMAC: + return "ODP_AUTH_ALG_SHA512_HMAC"; case ODP_AUTH_ALG_AES_GCM: return "ODP_AUTH_ALG_AES_GCM"; default: @@ -139,6 +141,9 @@ static void alg_test(odp_crypto_op_t op, if (auth_alg == ODP_AUTH_ALG_SHA256_HMAC && !(capa.auths.bit.sha256_hmac)) rc = -1; + if (auth_alg == ODP_AUTH_ALG_SHA512_HMAC && + !(capa.auths.bit.sha512_hmac)) + rc = -1; CU_ASSERT(!rc); CU_ASSERT((~capa.auths.all_bits & capa.hw_auths.all_bits) == 0); @@ -1391,9 +1396,106 @@ static int check_alg_hmac_sha512(void) return check_alg_support(ODP_CIPHER_ALG_NULL, ODP_AUTH_ALG_SHA512_HMAC); } -void crypto_test_alg_hmac_sha512(void) +/* This test verifies the correctness of HMAC_SHA512 digest operation. + * The output check length is truncated to 32 bytes (256 bits) as + * returned by the crypto operation API call. + * Note that hash digest is a one-way operation. + * In addition the test verifies if the implementation can use the + * packet buffer as completion event buffer. + * */ +void crypto_test_gen_alg_hmac_sha512(void) { - printf(" TEST NOT IMPLEMENTED YET "); + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + + unsigned int test_vec_num = (sizeof(hmac_sha512_reference_length) / + sizeof(hmac_sha512_reference_length[0])); + + unsigned int i; + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_sha512_reference_key[i]; + auth_key.length = sizeof(hmac_sha512_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_SHA512_HMAC, + auth_key.length, + HMAC_SHA512_256_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_ENCODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA512_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha512_reference_plaintext[i], + hmac_sha512_reference_length[i], + NULL, 0, + hmac_sha512_reference_digest[i], + HMAC_SHA512_256_CHECK_LEN); + } +} + +void crypto_test_check_alg_hmac_sha512(void) +{ + odp_crypto_key_t cipher_key = { .data = NULL, .length = 0 }, + auth_key = { .data = NULL, .length = 0 }; + odp_crypto_iv_t iv = { .data = NULL, .length = 0 }; + uint8_t wrong_digest[HMAC_SHA512_DIGEST_LEN]; + + unsigned int test_vec_num = (sizeof(hmac_sha512_reference_length) / + sizeof(hmac_sha512_reference_length[0])); + + unsigned int i; + + memset(wrong_digest, 0xa5, sizeof(wrong_digest)); + + for (i = 0; i < test_vec_num; i++) { + auth_key.data = hmac_sha512_reference_key[i]; + auth_key.length = sizeof(hmac_sha512_reference_key[i]); + + if (!check_auth_options(ODP_AUTH_ALG_SHA512_HMAC, + auth_key.length, + HMAC_SHA512_256_CHECK_LEN)) + continue; + + alg_test(ODP_CRYPTO_OP_DECODE, + 0, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA512_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha512_reference_plaintext[i], + hmac_sha512_reference_length[i], + NULL, 0, + hmac_sha512_reference_digest[i], + HMAC_SHA512_256_CHECK_LEN); + + alg_test(ODP_CRYPTO_OP_DECODE, + 1, + ODP_CIPHER_ALG_NULL, + iv, + iv.data, + cipher_key, + ODP_AUTH_ALG_SHA512_HMAC, + auth_key, + NULL, NULL, + NULL, 0, + hmac_sha512_reference_plaintext[i], + hmac_sha512_reference_length[i], + NULL, 0, + wrong_digest, + HMAC_SHA512_256_CHECK_LEN); + } } int crypto_suite_sync_init(void) @@ -1461,7 +1563,9 @@ odp_testinfo_t crypto_suite[] = { check_alg_hmac_sha256), ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha256, check_alg_hmac_sha256), - ODP_TEST_INFO_CONDITIONAL(crypto_test_alg_hmac_sha512, + ODP_TEST_INFO_CONDITIONAL(crypto_test_gen_alg_hmac_sha512, + check_alg_hmac_sha512), + ODP_TEST_INFO_CONDITIONAL(crypto_test_check_alg_hmac_sha512, check_alg_hmac_sha512), ODP_TEST_INFO_NULL, }; diff --git a/test/common_plat/validation/api/crypto/test_vectors.h b/test/common_plat/validation/api/crypto/test_vectors.h index 1de54964d..bd8bf347d 100644 --- a/test/common_plat/validation/api/crypto/test_vectors.h +++ b/test/common_plat/validation/api/crypto/test_vectors.h @@ -397,4 +397,54 @@ static uint8_t hmac_sha1_reference_digest[][HMAC_SHA1_DIGEST_LEN] = { 0x11, 0xcd, 0x91, 0xa3, 0x9a, 0xf4 }, }; +static uint8_t hmac_sha512_reference_key[][HMAC_SHA512_KEY_LEN] = { + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b }, + + /* "Jefe" */ + { 0x4a, 0x65, 0x66, 0x65 }, + + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa } +}; + +static uint32_t hmac_sha512_reference_length[] = { 8, 28, 50 }; + +static uint8_t +hmac_sha512_reference_plaintext[][HMAC_SHA512_MAX_DATA_LEN] = { + /* "Hi There" */ + { 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65}, + + /* what do ya want for nothing?*/ + { 0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, + 0x79, 0x61, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x3f }, + + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd } +}; + +static uint8_t hmac_sha512_reference_digest[][HMAC_SHA512_DIGEST_LEN] = { + { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, + 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, + 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, + 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde }, + + { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, + 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, + 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, + 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54 }, + + { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, + 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9, + 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, + 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39 } +}; + #endif diff --git a/test/common_plat/validation/api/crypto/test_vectors_len.h b/test/common_plat/validation/api/crypto/test_vectors_len.h index 5c3ddcee5..20a7ddbad 100644 --- a/test/common_plat/validation/api/crypto/test_vectors_len.h +++ b/test/common_plat/validation/api/crypto/test_vectors_len.h @@ -41,4 +41,10 @@ #define HMAC_SHA1_DIGEST_LEN 20 #define HMAC_SHA1_96_CHECK_LEN 12 +/* HMAC-SHA512 */ +#define HMAC_SHA512_KEY_LEN 64 +#define HMAC_SHA512_MAX_DATA_LEN 128 +#define HMAC_SHA512_DIGEST_LEN 64 +#define HMAC_SHA512_256_CHECK_LEN 32 + #endif -- cgit v1.2.3 From e5faf09d8dfa9631caa7ccf1461fd4bc9f69d4c0 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:38 +0300 Subject: linux-generic: crypto: add SHA-1 authentication support Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 9e5a11900..3117f65d5 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -61,6 +61,10 @@ static const odp_crypto_auth_capability_t auth_capa_md5_hmac[] = { {.digest_len = 12, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} }, {.digest_len = 16, .key_len = 16, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; +static const odp_crypto_auth_capability_t auth_capa_sha1_hmac[] = { +{.digest_len = 12, .key_len = 20, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 20, .key_len = 20, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; + static const odp_crypto_auth_capability_t auth_capa_sha256_hmac[] = { {.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} }, {.digest_len = 32, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; @@ -549,7 +553,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.null = 1; capa->auths.bit.md5_hmac = 1; - capa->auths.bit.sha1_hmac = 0; + capa->auths.bit.sha1_hmac = 1; capa->auths.bit.sha256_hmac = 1; capa->auths.bit.sha512_hmac = 0; capa->auths.bit.aes_gcm = 1; @@ -624,6 +628,10 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, src = auth_capa_md5_hmac; num = sizeof(auth_capa_md5_hmac) / size; break; + case ODP_AUTH_ALG_SHA1_HMAC: + src = auth_capa_sha1_hmac; + num = sizeof(auth_capa_sha1_hmac) / size; + break; case ODP_AUTH_ALG_SHA256_HMAC: src = auth_capa_sha256_hmac; num = sizeof(auth_capa_sha256_hmac) / size; @@ -741,6 +749,9 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, case ODP_AUTH_ALG_MD5_HMAC: rc = process_auth_param(session, 16, EVP_md5()); break; + case ODP_AUTH_ALG_SHA1_HMAC: + rc = process_auth_param(session, 20, EVP_sha1()); + break; #if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: /* Fixed digest tag length with deprecated algo */ -- cgit v1.2.3 From 9815336c6c7c64df3b40a1fb0c1c668a36d5550b Mon Sep 17 00:00:00 2001 From: Dmitry Eremin-Solenikov Date: Thu, 1 Jun 2017 12:03:39 +0300 Subject: linux-generic: crypto: add HMAC-SHA-512 authentication support Signed-off-by: Dmitry Eremin-Solenikov Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- platform/linux-generic/odp_crypto.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/platform/linux-generic/odp_crypto.c b/platform/linux-generic/odp_crypto.c index 3117f65d5..6fc1907d9 100644 --- a/platform/linux-generic/odp_crypto.c +++ b/platform/linux-generic/odp_crypto.c @@ -69,6 +69,10 @@ static const odp_crypto_auth_capability_t auth_capa_sha256_hmac[] = { {.digest_len = 16, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} }, {.digest_len = 32, .key_len = 32, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; +static const odp_crypto_auth_capability_t auth_capa_sha512_hmac[] = { +{.digest_len = 32, .key_len = 64, .aad_len = {.min = 0, .max = 0, .inc = 0} }, +{.digest_len = 64, .key_len = 64, .aad_len = {.min = 0, .max = 0, .inc = 0} } }; + static const odp_crypto_auth_capability_t auth_capa_aes_gcm[] = { {.digest_len = 16, .key_len = 0, .aad_len = {.min = 8, .max = 12, .inc = 4} } }; @@ -555,7 +559,7 @@ int odp_crypto_capability(odp_crypto_capability_t *capa) capa->auths.bit.md5_hmac = 1; capa->auths.bit.sha1_hmac = 1; capa->auths.bit.sha256_hmac = 1; - capa->auths.bit.sha512_hmac = 0; + capa->auths.bit.sha512_hmac = 1; capa->auths.bit.aes_gcm = 1; #if ODP_DEPRECATED_API @@ -636,6 +640,10 @@ int odp_crypto_auth_capability(odp_auth_alg_t auth, src = auth_capa_sha256_hmac; num = sizeof(auth_capa_sha256_hmac) / size; break; + case ODP_AUTH_ALG_SHA512_HMAC: + src = auth_capa_sha512_hmac; + num = sizeof(auth_capa_sha512_hmac) / size; + break; case ODP_AUTH_ALG_AES_GCM: src = auth_capa_aes_gcm; num = sizeof(auth_capa_aes_gcm) / size; @@ -761,6 +769,9 @@ odp_crypto_session_create(odp_crypto_session_param_t *param, case ODP_AUTH_ALG_SHA256_HMAC: rc = process_auth_param(session, 32, EVP_sha256()); break; + case ODP_AUTH_ALG_SHA512_HMAC: + rc = process_auth_param(session, 64, EVP_sha512()); + break; #if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: if (param->cipher_alg == ODP_CIPHER_ALG_AES128_GCM) -- cgit v1.2.3 From e24f6b3d0c130af3838ba49661d4bc9cb83e940f Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Fri, 2 Jun 2017 16:24:49 -0500 Subject: linux-generic: time: add additional doxygen doc for time type Latest doxygen requires all items to be documented so add doxygen for enclosing union around variant time types. Signed-off-by: Bill Fischofer Reviewed-by: Dmitry Eremin-Solenikov Signed-off-by: Maxim Uvarov --- platform/linux-generic/include/odp/api/plat/time_types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/linux-generic/include/odp/api/plat/time_types.h b/platform/linux-generic/include/odp/api/plat/time_types.h index 71e354e6e..e7111c8c5 100644 --- a/platform/linux-generic/include/odp/api/plat/time_types.h +++ b/platform/linux-generic/include/odp/api/plat/time_types.h @@ -26,6 +26,7 @@ extern "C" { * implementations. */ typedef struct odp_time_t { + /** @internal Variant mappings for time type */ union { /** @internal Used with generic 64 bit operations */ uint64_t u64; -- cgit v1.2.3 From 1b8c663ecd3b8a7c34ae52163961cdb442383d31 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Mon, 5 Jun 2017 22:22:19 -0500 Subject: api: crypto: correct documentation typos Correct odp_crypto_auth_capa() to odp_crypto_auth_capability() in several places in the spec doxygen. Signed-off-by: Bill Fischofer Reviewed-by: Yi He Reviewed-by: Petri Savolainen Signed-off-by: Maxim Uvarov --- include/odp/api/spec/crypto.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/odp/api/spec/crypto.h b/include/odp/api/spec/crypto.h index c47d31492..470cba050 100644 --- a/include/odp/api/spec/crypto.h +++ b/include/odp/api/spec/crypto.h @@ -296,13 +296,13 @@ typedef struct odp_crypto_session_param_t { /** Authentication key * - * Use odp_crypto_auth_capa() for supported key lengths. + * Use odp_crypto_auth_capability() for supported key lengths. */ odp_crypto_key_t auth_key; /** Authentication digest length in bytes * - * Use odp_crypto_auth_capa() for supported digest lengths. + * Use odp_crypto_auth_capability() for supported digest lengths. */ uint32_t auth_digest_len; @@ -377,7 +377,7 @@ typedef struct odp_crypto_op_param_t { /** Pointer to ADD */ uint8_t *ptr; - /** AAD length in bytes. Use odp_crypto_auth_capa() for + /** AAD length in bytes. Use odp_crypto_auth_capability() for * supported AAD lengths. */ uint32_t length; } aad; -- cgit v1.2.3 From 40c06707ed485e5e957a413d697f4f1370f98837 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Fri, 2 Jun 2017 15:58:52 +0300 Subject: update API version number from v1.14.0.0 to v1.15.0.0 Signed-off-by: Maxim Uvarov --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 4f44f8f68..46c7bbd24 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.5]) # Set correct API version ########################################################################## m4_define([odpapi_generation_version], [1]) -m4_define([odpapi_major_version], [14]) +m4_define([odpapi_major_version], [15]) m4_define([odpapi_minor_version], [0]) m4_define([odpapi_point_version], [0]) m4_define([odpapi_version], @@ -39,10 +39,10 @@ AM_SILENT_RULES([yes]) # 3. if interfaces were removed, then use C+1:0:0 ########################################################################## -ODP_LIBSO_VERSION=114:0:1 +ODP_LIBSO_VERSION=115:0:2 AC_SUBST(ODP_LIBSO_VERSION) -ODPHELPER_LIBSO_VERSION=112:0:0 +ODPHELPER_LIBSO_VERSION=112:1:0 AC_SUBST(ODPHELPER_LIBSO_VERSION) # Checks for programs. -- cgit v1.2.3 From 11a1d56876d14cd715a1906a95a7c3734999bdc0 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Sat, 10 Jun 2017 10:03:40 -0500 Subject: changelog: updates for odp v1.15.0.0 Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- CHANGELOG | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index a550a723e..25e903478 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,267 @@ +== OpenDataPlane (1.15.0.0) +=== New Features +ODP v1.15.0.0 continues the preview of Tiger Moth, introducing new APIs and +extensions, as well as numerous bug fixes and functional improvements. + +==== Deprecation Framework +To permit smoother evolution of the ODP API specification, a deprecation +framework is introduced to permit controlled deprecation. + +When an ODP API or defined struct parameter is deprecated, ODP validation +tests will be updated to no longer use that API and instead use the +replacement API. By default, attempts to compile with the older API/feature +will fail and applications wishing to move to the new ODP release should be +updated to use the replacement API. To permit evaluation of new ODP +releases in advance of such updating, however, ODP supports the `configure` +option `--enable-deprecated`, which makes the obsolete APIs visible again. + +This feature will be used on a case-by-case basis and documented in the +release notes for each release that introduces replacement API(s). In general +the deprecated forms will not be maintained for more than a single release +cycle. After that they will no longer be present in the API specification and +the replacement forms must be used to compile with that level of the API +specification. + +==== APIs +A number of new and refined APIs are introduced in crypto, packet parsing, +and queue configuration: + +===== Crypto Enhancements +The ODP crypto APIs receive several enhancements in this release: + +====== New Authentication Algorithms +Additional enumerations added for HMAC-SHA-1 and HMAC-SHA-512 authentication. + +====== Deprecated Cipher/Authentication Algorithms +The following cipher/authentication algorithms have been deprecated in favor +of newer replacement algorithms: + +* `ODP_CIPHER_ALG_AES128_CBC` is replaced by `ODP_CIPHER_ALG_AES_CBC` +* `ODP_CIPHER_ALG_AES128_GCM` is replaced by `ODP_CIPHER_ALG_AES_GCM` +* `ODP_AUTH_ALG_MD5_96` is replaced by `ODP_AUTH_ALG_MD5_HMAC` +* `ODP_AUTH_ALG_SHA256_128` is replaced by `ODP_AUTH_ALG_SHA256_HMAC` +* `ODP_AUTH_ALG_AES128_GCM1 is replaced by `ODP_AUTH_ALG_AES_GCM` + +====== Deprecated Name for Crypto Parameter struct +`odp_crypto_op_params_t` is deprecated in favor of `odp_crypto_op_param_t` +for consistency with other ODP `param` structs. + +====== Digest Length Session Parameter +`odp_crypto_session_param_t` adds the field `auth_digest_len` to permit +specification of the authentication digest length to be used for this +session. The `odp_crypto_auth_capability()` API returns the list of +supported digest lengths. + +====== Additional Authentication Data (AAD) +The `odp_crypto_op_param_t` struct adds an optional pointer and length for +AAD information. This allows applications to specify AAD information from +the list of supported lengths provided by `odp_crypto_auth_capability()`. + +===== Packet Range Data +The former `odp_crypto_data_range_t` type is deprecated and renamed to +`odp_packet_data_range_t` since it can be used to specify ranges for other +than crypto purposes. + +===== Parser Configuration +Applications may now specify the maximum packet layer of interest. For +example, a router may not care about anything beyond ISO Layer 3 in packets. +This can be used by ODP implementations to control the depth of packet +parsing needed by the application and may allow greater efficiency, +especially in software implementations. + +This is controlled by a new `odp_pktio_parser_layer_t` enum that is +part of the new `odp_pktio_parser_config_t` struct that is added to the +`odp_pktio_config_t` struct used by the `odp_pktio_config()` API. The +supported parser layers are also returned in this struct as part of the +`odp_pktio_capability_t` struct returned by the `odp_pktio_capability()` API. + +===== Queue Size Parameter +The `odp_queue_capability_t` struct returned by the `odp_queue_capability()` +API is enhanced as follows: +* The `max_queues` field is now defined to return the maximum number of event +queues of any type. +* New sub-structs (`plain` and `sched`) are added that detail the `max_num` of +queues of that type supported as well as the new field `max_size` that +specifies the maximum number of elements that each queue of this type can +store. A value of zero for `max_num` indicates no fixed limit. + +In addition, the `odp_queue_param_t` passed to `odp_queue_create()` now adds +a `size` field to allow applications to specify the minimum number of events +that this queue should be able to store. A value of zero specified requests that +the implementation default limits be used. + +The ODP examples have been updated to show this configuration, for example, +the `l2fwd_simple` example does Layer 2 forwarding and hence doesn't need +packets to be parsed beyond Layer 2. So prior to opening an interface via +`odp_pktio_open()` the configuration processing now includes code of the form: +[source,c] +----- +odp_pktio_config_init(&config); +config.parser.layer = ODP_PKTIO_PARSER_LAYER_L2; +odp_pktio_config(pktio, &config); +----- +This serves as a hint to the ODP implementation that parsing beyond Layer 2 +is not required on this interface. + +===== Removal of `odp_time_to_u64()` API +The `odp_time_to_u64()` API is removed without deprecation in this release. +This is redundant since the `odp_time_to_ns()` API already returns a `uint64_t` +value for `odp_time_t` and can be used for the same purpose. + +===== New `odp_sys_info_print()` API +For debugging / diagnostic use, the `odp_sys_info_print()` API is added. +This prints implementation defined information about the system and ODP +environment and may contain information about CPUs, memory, and other +hardware configuration. + +=== Helpers +==== Linux Helpers +ODP helper functions fall into two categories: system-independent, and those +that rely on Linux. For backwards compatibility, these have been +reorganized into a new `helper/linux` directory that is installed only when +the `--enable-helper-linux` `configure` option is specified. + +=== `odp-linux` Performance +==== Scheduler Improvements +The default scheduler is streamlined by using precomputed weight tables and +separated priority queues for different scheduling groups. This improves +both latency and scalability. + +Also included in this change, the default number of scheduling groups is +lowered from 256 to 32, which experience has shown is sufficient for most +applications. + +The scheduler fairness checks are also enhanced to avoid low priority event +starvation if `CONFIG_BURST_SIZE` is set to 1. + +=== `odp_linux` Crypto Improvements +* Errors in implicit packet copy operations performed during crypto operation +are now handled properly. +* If `odp_crypto_session_create()` fails, proper cleanup is now performed to +avoid memory leaks. +* The auth digest len is now used when calculating HMACs, and full-length +digests are now added to supported SHA capabilities. +* Numerous crypto functions have been rewritten to use the OpenSSL `EVP_` +functions for improved efficiency and accuracy. + +=== `odp-linux` Packet Improvements +* The packet parser now recognizes ICMPv6 packets in addition to ICMPv4. + +=== `odp-linux` PktIO Improvements +* The `ethtool` and `socket` drivers add additional initializations to avoid +valgrind warnings. +* The `dpdk` driver is upgraded to DPDK 17.02 and is now also built with the +`--whole-archive` option, which means that PMDs no longer need to be linked +individually but are automatically included in builds that make use of DPDK +pktio support. + +=== `odp-linux` Time Improvements +* The ODP Time APIs are now more efficiently handled by replacing the previous +Linux timespec with simple nanoseconds (ns) and using native hardware time +counters in x86 and ARM environments, when available. + +=== `odp-linux` Traffic Manager Improvements +* Weighting is now handled properly when weight=1 is specified. Previously +this caused an overflow that distorted packet priorities. + +=== Miscellaneous Fixes and Improvements +==== Native Clang build on ARMv8 +ARMv8 compilation now works properly when using the clang compiler. + +==== Test Improvements +* The `odp_scheduling` performance test now handles dequeueing from +potentially concurrent queues properly. +* The traffic manager and time tests are now invoked via scripts to better +account for load-sensitivity when running regressions in CI environments. +* The l2fwd test now supports an additional parameter to specify the number +of scheduling groups to use in the test. +* The `odp_sched_latency` performance test now handles queue draining in +a robust manner. +* The crypto validation tests now properly check and validate message digests, +and include negative tests to verify that incorrect digests are properly +flagged. Note that this may expose omissions in other ODP implementations that +had previously passed this validation test. +* The crypto validation test now adds an explicit test for the NULL cipher, +as well as HMAC-SHA-1 and HMAC-SHA-512. +* The pktio_ipc test now properly cleans up only its own temp files. + +==== Examples Improvements +* The `odp_generator` example now properly honors stop criteria based on +number of packets sent. +* The `odp_generator` example now properly flushes output messages +* The `odp_generator` example now supports port configuration. + +=== Bug Fixes +==== https://bugs.linaro.org/show_bug.cgi?id=2416[Bug 2416] +example/generator/odp_generator.c contains todo items + +==== https://bugs.linaro.org/show_bug.cgi?id=2779[Bug 2779] +Error handling issues (CHECKED_RETURN) + +==== https://bugs.linaro.org/show_bug.cgi?id=2826[Bug 2826] +Unchecked return in pool.c + +==== https://bugs.linaro.org/show_bug.cgi?id=2831[Bug 2831] +Unchecked return in mmap_unmap_sock() + +==== https://bugs.linaro.org/show_bug.cgi?id=2852[Bug 2852] +ODP_STATIC_ASSERT() fails when used by C++ + +==== https://bugs.linaro.org/show_bug.cgi?id=2872[Bug 2872] +odp_pktio_ordered_run.sh: line 34: integer expression expected + +==== https://bugs.linaro.org/show_bug.cgi?id=2881[Bug 2881] +load sensitive tests fail on CI + +==== https://bugs.linaro.org/show_bug.cgi?id=2895[Bug 2895] +The `odp_crypto_operation()` routine does not work with multi-segment packets. + +==== https://bugs.linaro.org/show_bug.cgi?id=2908[Bug 2908] +Packet validation test fails if implementation does not limit packet length + +==== https://bugs.linaro.org/show_bug.cgi?id=2910[Bug 2910] +odph_iplookup_table_put_value() uses overlapping pointer addresses + +==== https://bugs.linaro.org/show_bug.cgi?id=2933[Bug 2933] +Miss to call unlock if there are some errors happen in loopback_send() function + +==== https://bugs.linaro.org/show_bug.cgi?id=2940[Bug 2940] +`odp_packet_seg_t` fails ABI compatibility between odp-linux and odp-dpdk + +==== https://bugs.linaro.org/show_bug.cgi?id=2942[Bug 2942] +Compilation fails using clang 4.0.0 + +==== https://bugs.linaro.org/show_bug.cgi?id=2952[Bug 2952] +doxygen errors and travis does not catch them + +==== https://bugs.linaro.org/show_bug.cgi?id=2969[Bug 2969] +TM validation test does find traffic_mngr_main + +==== https://bugs.linaro.org/show_bug.cgi?id=2974[Bug 2974] +`odp_rwlock_read_trylock()` fails if lock is already held for read access + +==== https://bugs.linaro.org/show_bug.cgi?id=3002[Bug 3002] +Packet order lost when enqueuing to pktout queue + +==== https://bugs.linaro.org/show_bug.cgi?id=3003[Bug 3003] +AES-GCM returns 'valid' tag when checking invalid tag + +==== https://bugs.linaro.org/show_bug.cgi?id=3013[Bug 3013] +Various failures if CONFIG_PACKET_MAX_SEGS is set to 1 + +==== https://bugs.linaro.org/show_bug.cgi?id=3017[Bug 3017] +Travis: time main test out of boundaries + +==== https://bugs.linaro.org/show_bug.cgi?id=3027[Bug 3027] +Compilation failures using GCC 7 series + +=== Known Issues +==== https://bugs.linaro.org/show_bug.cgi?id=3024[Bug 3024] +odp_traffic_mngr example is broken + +==== https://bugs.linaro.org/show_bug.cgi?id=3026[Bug 3026] +pktio_ips_run test can fail due to segfault + == OpenDataPlane (1.14.0.0) === New Features ==== APIs -- cgit v1.2.3 From 79ed8c746ba13233c111a61d2d4f17e360dd8023 Mon Sep 17 00:00:00 2001 From: Bill Fischofer Date: Wed, 14 Jun 2017 12:12:25 -0500 Subject: changelog: add bug 3039 to list of bug fixes for v1.15 Signed-off-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 25e903478..866e51e95 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -255,6 +255,9 @@ Travis: time main test out of boundaries ==== https://bugs.linaro.org/show_bug.cgi?id=3027[Bug 3027] Compilation failures using GCC 7 series +==== https://bugs.linaro.org/show_bug.cgi?id=3039[Bug 3039] +Socket pktio recv fails on large number of packet + === Known Issues ==== https://bugs.linaro.org/show_bug.cgi?id=3024[Bug 3024] odp_traffic_mngr example is broken -- cgit v1.2.3 From b5f5510a9751ad60915f5b9fcf8763a97f77b5ab Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Wed, 14 Jun 2017 16:50:13 +0300 Subject: test: l2fwd pass under coverage env variable TEST=coverage is set, use it to not fail under gcov run which is really slow. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- test/common_plat/performance/odp_l2fwd_run.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/common_plat/performance/odp_l2fwd_run.sh b/test/common_plat/performance/odp_l2fwd_run.sh index dd42ede97..6871e4b07 100755 --- a/test/common_plat/performance/odp_l2fwd_run.sh +++ b/test/common_plat/performance/odp_l2fwd_run.sh @@ -96,6 +96,9 @@ run_l2fwd() ret=1 elif [ $ret -eq 0 ]; then PASS_PPS=5000 + if [ "${TEST}" = "coverage" ]; then + PASS_PPS=10 + fi MAX_PPS=$(awk '/TEST RESULT/ {print $3}' $LOG) if [ "$MAX_PPS" -lt "$PASS_PPS" ]; then echo "FAIL: pps below threshold $MAX_PPS < $PASS_PPS" -- cgit v1.2.3 From 0b5e8c6870b959ad9db426aa067326f4baad5d58 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Wed, 14 Jun 2017 23:45:31 +0300 Subject: build: fix order of test execution l2fwd perf test requires odp_generator from examples. Make sure that examples already build when make check is run. https://bugs.linaro.org/show_bug.cgi?id=2938 Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2a9a658df..daa497886 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,10 +8,10 @@ AM_DISTCHECK_CONFIGURE_FLAGS = --enable-test-cpp \ #@with_platform@ works alone in subdir but not as part of a path??? SUBDIRS = @platform_with_platform@ \ helper \ - test \ helper/test \ doc \ - example + example . \ + test @DX_RULES@ -- cgit v1.2.3 From 452c37072103864d7117e31f521b5e620e4937b5 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 15 Jun 2017 16:04:55 +0300 Subject: travis: add sudo run make check make check has to be under root to validate pktio like raw sockets. Also odp temporary files can overlap with previous root run and permission to overwrite that files is needed. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 669695d89..7783f13af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,7 +129,7 @@ jobs: script: - ./bootstrap - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="-O0 -coverage" CXXFLAGS="-O0 -coverage" LDFLAGS="--coverage" - - make check -j $(nproc) + - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" PATH=${PATH//:\.\/node_modules\/\.bin/} make check -j ${nproc} - find . -type f -iname '*.[ch]' -not -path ".git/*" -execdir gcov {} \; ; bash <(curl -s https://codecov.io/bash) -X coveragepy - stage: test env: TEST=distcheck @@ -137,7 +137,7 @@ jobs: script: - ./bootstrap - ./configure - - make distcheck + - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" make distcheck - stage: test env: TEST=doxygen compiler: gcc -- cgit v1.2.3 From 4bda102286cf55b0bc93fdf8f8f276d5528fdf14 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 15 Jun 2017 17:02:43 +0300 Subject: travis: do not run performance test in parallel under coverage Performance tests have some limits to detect if they pass or fail but under coverage execution is slow, running tests in parallel is also very slow. Without that patch scheduler test simetimes fails. Signed-off-by: Maxim Uvarov Reviewed-by: Bill Fischofer --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7783f13af..50b3b9c27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,7 +129,7 @@ jobs: script: - ./bootstrap - ./configure --prefix=$HOME/odp-install --enable-test-cpp --enable-test-vald --enable-test-helper --enable-test-perf --enable-user-guides --enable-test-perf-proc --enable-test-example --with-dpdk-path=`pwd`/dpdk/${TARGET} --with-netmap-path=`pwd`/netmap CFLAGS="-O0 -coverage" CXXFLAGS="-O0 -coverage" LDFLAGS="--coverage" - - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" PATH=${PATH//:\.\/node_modules\/\.bin/} make check -j ${nproc} + - sudo LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" PATH=${PATH//:\.\/node_modules\/\.bin/} make check - find . -type f -iname '*.[ch]' -not -path ".git/*" -execdir gcov {} \; ; bash <(curl -s https://codecov.io/bash) -X coveragepy - stage: test env: TEST=distcheck -- cgit v1.2.3 From 5dd7d9ed05ee228406cc3c0ae6cd9caa20a71f08 Mon Sep 17 00:00:00 2001 From: Petri Savolainen Date: Mon, 19 Jun 2017 11:25:19 +0300 Subject: linux-gen: makefile: fix out of tree build Generated files need $(top_builddir) instead of $(top_srcdir) Fixes bug https://bugs.linaro.org/show_bug.cgi?id=3052 Signed-off-by: Petri Savolainen Reviewed-by: Bill Fischofer Signed-off-by: Maxim Uvarov --- platform/Makefile.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/Makefile.inc b/platform/Makefile.inc index 9844a58a2..1903d92d2 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -29,7 +29,6 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/cpumask.h \ $(top_srcdir)/include/odp/api/spec/crypto.h \ $(top_srcdir)/include/odp/api/spec/debug.h \ - $(top_srcdir)/include/odp/api/spec/deprecated.h \ $(top_srcdir)/include/odp/api/spec/errno.h \ $(top_srcdir)/include/odp/api/spec/event.h \ $(top_srcdir)/include/odp/api/spec/hash.h \ @@ -58,8 +57,9 @@ odpapispecinclude_HEADERS = \ $(top_srcdir)/include/odp/api/spec/ticketlock.h \ $(top_srcdir)/include/odp/api/spec/time.h \ $(top_srcdir)/include/odp/api/spec/timer.h \ - $(top_builddir)/include/odp/api/spec/version.h \ - $(top_srcdir)/include/odp/api/spec/traffic_mngr.h + $(top_srcdir)/include/odp/api/spec/traffic_mngr.h \ + $(top_builddir)/include/odp/api/spec/deprecated.h \ + $(top_builddir)/include/odp/api/spec/version.h odpapiabidefaultincludedir= $(includedir)/odp/arch/default/api/abi odpapiabidefaultinclude_HEADERS = \ -- cgit v1.2.3 From fac3d65908a081764413656bfc7f2bc7bfb5a648 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:24:48 +0200 Subject: linux-dpdk: port "pool: add odp_pool_capability() rc check" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_pool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c index e6d415954..8acd9b995 100644 --- a/platform/linux-dpdk/odp_pool.c +++ b/platform/linux-dpdk/odp_pool.c @@ -240,7 +240,8 @@ static int check_params(odp_pool_param_t *params) { odp_pool_capability_t capa; - odp_pool_capability(&capa); + if (odp_pool_capability(&capa) < 0) + return -1; switch (params->type) { case ODP_POOL_BUFFER: -- cgit v1.2.3 From 03d11d06e8329f5e5575a50fb9e6b22e280e8396 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:28:02 +0200 Subject: linux-dpdk: port "abi: fix include/odp/api/abi symlink creation" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index dfbc57619..fc12a91a0 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -221,7 +221,7 @@ __LIB__libodp_dpdk_la_SOURCES = \ # specific include path for installed files. install-data-hook: if [ -h $(prefix)/include/odp/api/abi ]; then \ - : \ + : ; \ else \ $(LN_S) -rf $(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ $(prefix)/include/odp/api/abi; \ -- cgit v1.2.3 From a29e079bb362a84e3c821dfef1cb60b2eb1a758d Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:30:58 +0200 Subject: linux-dpdk: porting "packet: make inline table visible" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_packet.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index 68ad26b29..2243948c9 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -21,6 +21,8 @@ #include #include +#include + /* Fill in packet header field offsets for inline functions */ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { @@ -49,6 +51,8 @@ const _odp_packet_inline_offset_t _odp_packet_inline ODP_ALIGNED_CACHE = { .rss_flag = PKT_RX_RSS_HASH }; +#include + struct rte_mbuf dummy; ODP_STATIC_ASSERT(sizeof(dummy.data_off) == sizeof(uint16_t), "data_off should be uint16_t"); -- cgit v1.2.3 From 7783e68c8c72c75ce331ed06cedc2f2a8e1674a1 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:36:12 +0200 Subject: linux-dpdk: porting "pool: don't allocate buffers from invalid pool" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_pool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/linux-dpdk/odp_pool.c b/platform/linux-dpdk/odp_pool.c index 8acd9b995..0821cdcac 100644 --- a/platform/linux-dpdk/odp_pool.c +++ b/platform/linux-dpdk/odp_pool.c @@ -553,6 +553,8 @@ static odp_buffer_t buffer_alloc(pool_entry_t *pool) odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) { + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); return buffer_alloc(pool); @@ -561,6 +563,9 @@ odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl) int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num) { int i; + + ODP_ASSERT(ODP_POOL_INVALID != pool_hdl); + pool_entry_t *pool = odp_pool_to_entry(pool_hdl); for (i = 0; i < num; i++) { -- cgit v1.2.3 From e8926e29cb4c66b76bf171d404ed1ed9246374a4 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:45:32 +0200 Subject: linux-dpdk: porting "add syntax to allow newer clang to compile odp" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_packet_flags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_packet_flags.c b/platform/linux-dpdk/odp_packet_flags.c index 20517e164..ebe567e78 100644 --- a/platform/linux-dpdk/odp_packet_flags.c +++ b/platform/linux-dpdk/odp_packet_flags.c @@ -19,7 +19,7 @@ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ if (pkt_hdr->p.parsed_layers < layer) \ packet_parse_layer(pkt_hdr, layer); \ - pkt_hdr->p.x = v & 1; \ + pkt_hdr->p.x = (v) & 1; \ } while (0) int odp_packet_has_error(odp_packet_t pkt) -- cgit v1.2.3 From 5ca377b73201924be54b748e52f56aee94ee564c Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 15:57:41 +0200 Subject: linux-dpdk: porting "crypto: properly handle errors in packet copy" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_crypto.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index e1f7026ed..7a77f83ae 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -918,7 +918,7 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, struct rte_crypto_op *op; uint16_t rc; uint32_t plain_len, aad_len; - odp_bool_t pkt_allocated = 0; + odp_bool_t allocated = false; entry = (crypto_session_entry_t *)(intptr_t)params->session; if (entry == NULL) @@ -939,17 +939,22 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, ODP_POOL_INVALID != entry->output_pool) { params->out_pkt = odp_packet_alloc(entry->output_pool, odp_packet_len(params->pkt)); - pkt_allocated = 1; + allocated = true; } if (params->pkt != params->out_pkt) { if (odp_unlikely(ODP_PACKET_INVALID == params->out_pkt)) ODP_ABORT(); - (void)odp_packet_copy_from_pkt(params->out_pkt, + int ret; + + ret = odp_packet_copy_from_pkt(params->out_pkt, 0, params->pkt, 0, odp_packet_len(params->pkt)); + if (odp_unlikely(ret < 0)) + goto err; + _odp_packet_copy_md_to_packet(params->pkt, params->out_pkt); odp_packet_free(params->pkt); params->pkt = ODP_PACKET_INVALID; @@ -962,10 +967,8 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, op = rte_crypto_op_alloc(global->crypto_op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC); if (op == NULL) { - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate crypto operation"); - return -1; + goto err; } odp_spinlock_unlock(&global->lock); @@ -996,10 +999,8 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, op->sym->auth.aad.data = rte_malloc("aad", aad_len, 0); if (op->sym->auth.aad.data == NULL) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate memory for AAD"); - return -1; + goto err; } memcpy(op->sym->auth.aad.data, aad_head, aad_len); @@ -1010,19 +1011,15 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, if (entry->iv.length == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Wrong IV length"); - return -1; + goto err; } op->sym->cipher.iv.data = rte_malloc("iv", entry->iv.length, 0); if (op->sym->cipher.iv.data == NULL) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to allocate memory for IV"); - return -1; + goto err; } if (params->override_iv_ptr) { @@ -1060,10 +1057,8 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, queue_pair, &op, 1); if (rc == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to enqueue packet"); - return -1; + goto err; } rc = rte_cryptodev_dequeue_burst(rte_session->dev_id, @@ -1071,10 +1066,8 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, if (rc == 0) { rte_crypto_op_free(op); - if (pkt_allocated) - odp_packet_free(params->out_pkt); ODP_ERR("Failed to dequeue packet"); - return -1; + goto err; } params->out_pkt = (odp_packet_t)op->sym->m_src; @@ -1108,7 +1101,7 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, op_result->result = local_result; if (odp_queue_enq(entry->compl_queue, completion_event)) { odp_event_free(completion_event); - return -1; + goto err; } /* Indicate to caller operation was async */ @@ -1116,14 +1109,21 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, } else { /* Synchronous, simply return results */ if (!result) - return -1; + goto err; *result = local_result; /* Indicate to caller operation was sync */ *posted = 0; } - return 0; + +err: + if (allocated) { + odp_packet_free(param->out_pkt); + param->out_pkt = ODP_PACKET_INVALID; + } + + return -1; } int odp_crypto_term_global(void) -- cgit v1.2.3 From c62c615e3358c4f7018788af1e88bbda38db2d36 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 16:05:33 +0200 Subject: linux-dpdk: porting "makefile: fix staged install support" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index fc12a91a0..32a9b7dbb 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -220,9 +220,9 @@ __LIB__libodp_dpdk_la_SOURCES = \ # Create symlink for ABI header files. Application does not need to use the arch # specific include path for installed files. install-data-hook: - if [ -h $(prefix)/include/odp/api/abi ]; then \ + if [ -h $(DESTDIR)$(prefix)/include/odp/api/abi ]; then \ : ; \ else \ - $(LN_S) -rf $(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ - $(prefix)/include/odp/api/abi; \ + $(LN_S) -rf $(DESTDIR)$(prefix)/include/odp/arch/@ARCH_ABI@/odp/api/abi \ + $(DESTDIR)$(prefix)/include/odp/api/abi; \ fi -- cgit v1.2.3 From 3d30a4d26953f3823588a0443226651b745b119c Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 16:39:53 +0200 Subject: linux-dpdk: porting "build: GCC 7 fixes" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- pkgconfig/libodp-dpdk.pc.in | 2 +- platform/linux-dpdk/Makefile.am | 2 ++ platform/linux-dpdk/m4/configure.m4 | 45 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/pkgconfig/libodp-dpdk.pc.in b/pkgconfig/libodp-dpdk.pc.in index 6497c796d..23804b0f7 100644 --- a/pkgconfig/libodp-dpdk.pc.in +++ b/pkgconfig/libodp-dpdk.pc.in @@ -7,5 +7,5 @@ Name: libodp-dpdk Description: The ODP packet processing engine Version: @PKGCONFIG_VERSION@ Libs: -L${libdir} -lodp-dpdk -Libs.private: +Libs.private: @ATOMIC_LIBS@ Cflags: -I${includedir} diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index 32a9b7dbb..e6d99cfac 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -217,6 +217,8 @@ __LIB__libodp_dpdk_la_SOURCES = \ arch/@ARCH_DIR@/odp_cpu_arch.c \ arch/@ARCH_DIR@/odp_sysinfo_parse.c +__LIB__libodp_dpdk_la_LIBADD = $(ATOMIC_LIBS) + # Create symlink for ABI header files. Application does not need to use the arch # specific include path for installed files. install-data-hook: diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4 index fb9a91399..6d7c73072 100644 --- a/platform/linux-dpdk/m4/configure.m4 +++ b/platform/linux-dpdk/m4/configure.m4 @@ -28,6 +28,51 @@ AC_LINK_IFELSE( echo "Use newer version. For gcc > 4.7.0" exit -1) +dnl Check whether -latomic is needed +use_libatomic=no + +AC_MSG_CHECKING(whether -latomic is needed for 64-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static int loc; + int main(void) + { + int prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_8], + [use_libatomic=yes], + [AC_MSG_FAILURE([__atomic_exchange_8 is not available])]) + ]) + +AC_MSG_CHECKING(whether -latomic is needed for 128-bit atomic built-ins) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ + static __int128 loc; + int main(void) + { + __int128 prev; + prev = __atomic_exchange_n(&loc, 7, __ATOMIC_RELAXED); + return 0; + } + ]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_CHECK_LIB( + [atomic], [__atomic_exchange_16], + [use_libatomic=yes], + [AC_MSG_CHECKING([cannot detect support for 128-bit atomics])]) + ]) + +if test "x$use_libatomic" = "xyes"; then + ATOMIC_LIBS="-latomic" +fi +AC_SUBST([ATOMIC_LIBS]) + # linux-generic PCAP support is not relevant as the code doesn't use # linux-generic pktio at all. And DPDK has its own PCAP support anyway AM_CONDITIONAL([HAVE_PCAP], [false]) -- cgit v1.2.3 From 22187ee507099a0b7c03e9f96b6399dc6a43eb68 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 16:42:39 +0200 Subject: linux-dpdk: porting "do not trap if libatomic is not found" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/m4/configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linux-dpdk/m4/configure.m4 b/platform/linux-dpdk/m4/configure.m4 index 6d7c73072..230ef6eff 100644 --- a/platform/linux-dpdk/m4/configure.m4 +++ b/platform/linux-dpdk/m4/configure.m4 @@ -46,7 +46,7 @@ AC_LINK_IFELSE( AC_CHECK_LIB( [atomic], [__atomic_exchange_8], [use_libatomic=yes], - [AC_MSG_FAILURE([__atomic_exchange_8 is not available])]) + [AC_MSG_CHECKING([__atomic_exchange_8 is not available])]) ]) AC_MSG_CHECKING(whether -latomic is needed for 128-bit atomic built-ins) -- cgit v1.2.3 From 165f61d03a751374f55729257560e1435c34eb0d Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:10:19 +0200 Subject: linux-dpdk: porting "crypto: enforce deprecated API status" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_crypto.c | 45 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index 7a77f83ae..9533d18b0 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -94,13 +94,15 @@ static int cipher_alg_odp_to_rte(odp_cipher_alg_t cipher_alg, cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_3DES_CBC; break; case ODP_CIPHER_ALG_AES_CBC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_CBC: +#endif cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC; break; case ODP_CIPHER_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_CIPHER_ALG_AES128_GCM: +#endif cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM; break; default: @@ -121,20 +123,23 @@ static int auth_alg_odp_to_rte(odp_auth_alg_t auth_alg, auth_xform->auth.algo = RTE_CRYPTO_AUTH_NULL; break; case ODP_AUTH_ALG_MD5_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_MD5_96: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_MD5_HMAC; auth_xform->auth.digest_length = 12; break; case ODP_AUTH_ALG_SHA256_HMAC: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_SHA256_128: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; auth_xform->auth.digest_length = 16; break; case ODP_AUTH_ALG_AES_GCM: - /* deprecated */ +#if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: +#endif auth_xform->auth.algo = RTE_CRYPTO_AUTH_AES_GCM; auth_xform->auth.digest_length = 16; break; @@ -349,14 +354,16 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) { hw_ciphers->bit.aes_cbc = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_ciphers->bit.aes128_cbc = 1; +#endif } if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) { hw_ciphers->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_ciphers->bit.aes128_gcm = 1; +#endif } } @@ -373,20 +380,23 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_auth_algo == RTE_CRYPTO_AUTH_AES_GCM) { hw_auths->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.aes128_gcm = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_MD5_HMAC) { hw_auths->bit.md5_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.md5_96 = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { hw_auths->bit.sha256_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API hw_auths->bit.sha256_128 = 1; +#endif } } cap = &dev_info.capabilities[++i]; @@ -411,14 +421,16 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC) { ciphers->bit.aes_cbc = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API ciphers->bit.aes128_cbc = 1; +#endif } if (cap_cipher_algo == RTE_CRYPTO_CIPHER_AES_GCM) { ciphers->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API ciphers->bit.aes128_gcm = 1; +#endif } } @@ -435,20 +447,23 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) if (cap_auth_algo == RTE_CRYPTO_AUTH_AES_GCM) { auths->bit.aes_gcm = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.aes128_gcm = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_MD5_HMAC) { auths->bit.md5_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.md5_96 = 1; +#endif } if (cap_auth_algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { auths->bit.sha256_hmac = 1; - /* Deprecated */ +#if ODP_DEPRECATED_API auths->bit.sha256_128 = 1; +#endif } } cap = &dev_info.capabilities[++i]; -- cgit v1.2.3 From 4e1a38d1f75dac1fefd255083a605952c211a4df Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:17:45 +0200 Subject: linux-dpdk: porting "deprecated: add configure option and macros" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/Makefile.am | 1 + platform/linux-dpdk/include/odp/api/deprecated.h | 1 + 2 files changed, 2 insertions(+) create mode 120000 platform/linux-dpdk/include/odp/api/deprecated.h diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index e6d99cfac..2495f39f2 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -42,6 +42,7 @@ odpapiinclude_HEADERS = \ $(srcdir)/include/odp/api/cpumask.h \ $(srcdir)/include/odp/api/crypto.h \ $(srcdir)/include/odp/api/debug.h \ + $(srcdir)/include/odp/api/deprecated.h \ $(srcdir)/include/odp/api/errno.h \ $(srcdir)/include/odp/api/event.h \ $(srcdir)/include/odp/api/hash.h \ diff --git a/platform/linux-dpdk/include/odp/api/deprecated.h b/platform/linux-dpdk/include/odp/api/deprecated.h new file mode 120000 index 000000000..42bc7ef16 --- /dev/null +++ b/platform/linux-dpdk/include/odp/api/deprecated.h @@ -0,0 +1 @@ +../../../../linux-generic/include/odp/api/deprecated.h \ No newline at end of file -- cgit v1.2.3 From 773ff75a304bbdd4362a8a8064be84e9d76d1a46 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:24:46 +0200 Subject: linux-dpdk:porting "packet: recognize ICMPv6 packets" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_packet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index 2243948c9..06f5a19cb 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -1429,7 +1429,10 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, /* Parse Layer 4 headers */ switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMP: + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ + + case _ODP_IPPROTO_ICMPv6: prs->input_flags.icmp = 1; break; -- cgit v1.2.3 From df1b969c806659be3c37ee16d58325f54ee8c6f7 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:28:49 +0200 Subject: linux-dpdk:porting "types: add additional doxygen documentation" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/include/odp/api/plat/packet_types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_types.h b/platform/linux-dpdk/include/odp/api/plat/packet_types.h index c6ee3966f..795ee0c16 100644 --- a/platform/linux-dpdk/include/odp/api/plat/packet_types.h +++ b/platform/linux-dpdk/include/odp/api/plat/packet_types.h @@ -99,6 +99,7 @@ typedef union { /** All input flags */ uint64_t all; + /** Individual input flags */ struct { uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ -- cgit v1.2.3 From 2f144ba129628bd0e38b9804f9f7326380d70b2b Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:31:25 +0200 Subject: linux-dpdk:porting "time: remove odp_time_to_u64 from API" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_time.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c index c1ad973cc..9ca3109f1 100644 --- a/platform/linux-dpdk/odp_time.c +++ b/platform/linux-dpdk/odp_time.c @@ -240,31 +240,11 @@ void odp_time_wait_until(odp_time_t time) return time_wait_until(time); } -static uint64_t time_to_u64(odp_time_t time) -{ - int ret; - struct timespec tres; - uint64_t resolution; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - resolution = (uint64_t)tres.tv_nsec; - - return time_handler.time_to_ns(time) / resolution; -} - static uint64_t time_to_u64_dpdk(odp_time_t time) { return time.tv_sec; } -uint64_t odp_time_to_u64(odp_time_t time) -{ - return time_handler.time_to_u64(time); -} - static odp_bool_t is_invariant_tsc_supported(void) { FILE *file; -- cgit v1.2.3 From d0eb8f2e9610cd61131f9e2e9e3f78ca68c8706f Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Wed, 12 Jul 2017 17:35:03 +0200 Subject: linux-dpdk:porting "cpu_flags: added x86 cpu flag read functions" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index 2495f39f2..1482f1bc2 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -220,6 +220,10 @@ __LIB__libodp_dpdk_la_SOURCES = \ __LIB__libodp_dpdk_la_LIBADD = $(ATOMIC_LIBS) +if ARCH_IS_X86 +__LIB__libodp_dpdk_la_SOURCES += arch/@ARCH_DIR@/cpu_flags.c +endif + # Create symlink for ABI header files. Application does not need to use the arch # specific include path for installed files. install-data-hook: -- cgit v1.2.3 From c2c3ed55057e1a8032da4cff3ef0b61d38b33d58 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Thu, 13 Jul 2017 07:55:57 +0200 Subject: linux-dpdk:porting "update AES-GCM support to reflect aad and auth_digest_len" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_crypto.c | 113 ++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index 9533d18b0..443314a35 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -156,8 +156,10 @@ static crypto_session_entry_t *alloc_session(void) odp_spinlock_lock(&global->lock); session = global->free; - if (session) + if (session) { global->free = session->next; + session->next = NULL; + } odp_spinlock_unlock(&global->lock); return session; @@ -755,7 +757,7 @@ static int get_crypto_dev(struct rte_crypto_sym_xform *cipher_xform, return -1; } -int odp_crypto_session_create(odp_crypto_session_params_t *params, +int odp_crypto_session_create(odp_crypto_session_param_t *param, odp_crypto_session_t *session_out, odp_crypto_ses_create_err_t *status) { @@ -786,7 +788,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, /* Cipher Data */ cipher_xform.cipher.key.data = rte_malloc("crypto key", - params->cipher_key.length, 0); + param->cipher_key.length, 0); if (cipher_xform.cipher.key.data == NULL) { ODP_ERR("Failed to allocate memory for cipher key\n"); /* remove the crypto_session_entry_t */ @@ -797,14 +799,14 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER; cipher_xform.next = NULL; - cipher_xform.cipher.key.length = params->cipher_key.length; + cipher_xform.cipher.key.length = param->cipher_key.length; memcpy(cipher_xform.cipher.key.data, - params->cipher_key.data, - params->cipher_key.length); + param->cipher_key.data, + param->cipher_key.length); /* Authentication Data */ auth_xform.auth.key.data = rte_malloc("auth key", - params->auth_key.length, 0); + param->auth_key.length, 0); if (auth_xform.auth.key.data == NULL) { ODP_ERR("Failed to allocate memory for auth key\n"); /* remove the crypto_session_entry_t */ @@ -814,16 +816,16 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, } auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH; auth_xform.next = NULL; - auth_xform.auth.key.length = params->auth_key.length; + auth_xform.auth.key.length = param->auth_key.length; memcpy(auth_xform.auth.key.data, - params->auth_key.data, - params->auth_key.length); + param->auth_key.data, + param->auth_key.length); /* Derive order */ - if (ODP_CRYPTO_OP_ENCODE == params->op) - entry->do_cipher_first = params->auth_cipher_text; + if (ODP_CRYPTO_OP_ENCODE == param->op) + entry->do_cipher_first = param->auth_cipher_text; else - entry->do_cipher_first = !params->auth_cipher_text; + entry->do_cipher_first = !param->auth_cipher_text; /* Process based on cipher */ /* Derive order */ @@ -839,7 +841,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, first_xform->next = &cipher_xform; } - rc = cipher_alg_odp_to_rte(params->cipher_alg, &cipher_xform); + rc = cipher_alg_odp_to_rte(param->cipher_alg, &cipher_xform); /* Check result */ if (rc) { @@ -847,7 +849,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, return -1; } - rc = auth_alg_odp_to_rte(params->auth_alg, &auth_xform); + rc = auth_alg_odp_to_rte(param->auth_alg, &auth_xform); /* Check result */ if (rc) { @@ -860,7 +862,7 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, rc = get_crypto_dev(&cipher_xform, &auth_xform, - params->iv.length, + param->iv.length, &cdev_id); if (rc) { @@ -883,10 +885,10 @@ int odp_crypto_session_create(odp_crypto_session_params_t *params, entry->rte_session = (intptr_t)session; entry->cipher_xform = cipher_xform; entry->auth_xform = auth_xform; - entry->iv.length = params->iv.length; - entry->iv.data = params->iv.data; - entry->output_pool = params->output_pool; - entry->compl_queue = params->compl_queue; + entry->iv.length = param->iv.length; + entry->iv.data = param->iv.data; + entry->output_pool = param->output_pool; + entry->compl_queue = param->compl_queue; /* We're happy */ *session_out = (intptr_t)entry; @@ -918,7 +920,7 @@ int odp_crypto_session_destroy(odp_crypto_session_t session) return 0; } -int odp_crypto_operation(odp_crypto_op_params_t *params, +int odp_crypto_operation(odp_crypto_op_param_t *param, odp_bool_t *posted, odp_crypto_op_result_t *result) { @@ -932,10 +934,10 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, uint8_t *data_addr, *aad_head; struct rte_crypto_op *op; uint16_t rc; - uint32_t plain_len, aad_len; + uint32_t aad_len; odp_bool_t allocated = false; - entry = (crypto_session_entry_t *)(intptr_t)params->session; + entry = (crypto_session_entry_t *)(intptr_t)param->session; if (entry == NULL) return -1; @@ -950,32 +952,32 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, auth_xform = entry->auth_xform; /* Resolve output buffer */ - if (ODP_PACKET_INVALID == params->out_pkt && + if (ODP_PACKET_INVALID == param->out_pkt && ODP_POOL_INVALID != entry->output_pool) { - params->out_pkt = odp_packet_alloc(entry->output_pool, - odp_packet_len(params->pkt)); + param->out_pkt = odp_packet_alloc(entry->output_pool, + odp_packet_len(param->pkt)); allocated = true; } - if (params->pkt != params->out_pkt) { - if (odp_unlikely(ODP_PACKET_INVALID == params->out_pkt)) + if (param->pkt != param->out_pkt) { + if (odp_unlikely(ODP_PACKET_INVALID == param->out_pkt)) ODP_ABORT(); int ret; - ret = odp_packet_copy_from_pkt(params->out_pkt, + ret = odp_packet_copy_from_pkt(param->out_pkt, 0, - params->pkt, + param->pkt, 0, - odp_packet_len(params->pkt)); + odp_packet_len(param->pkt)); if (odp_unlikely(ret < 0)) goto err; - _odp_packet_copy_md_to_packet(params->pkt, params->out_pkt); - odp_packet_free(params->pkt); - params->pkt = ODP_PACKET_INVALID; + _odp_packet_copy_md_to_packet(param->pkt, param->out_pkt); + odp_packet_free(param->pkt); + param->pkt = ODP_PACKET_INVALID; } - data_addr = odp_packet_data(params->out_pkt); + data_addr = odp_packet_data(param->out_pkt); odp_spinlock_init(&global->lock); odp_spinlock_lock(&global->lock); @@ -990,25 +992,24 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, /* Set crypto operation data parameters */ rte_crypto_op_attach_sym_session(op, rte_session); - op->sym->auth.digest.data = data_addr + params->hash_result_offset; + op->sym->auth.digest.data = data_addr + param->hash_result_offset; op->sym->auth.digest.phys_addr = - rte_pktmbuf_mtophys_offset((struct rte_mbuf *)params->out_pkt, - odp_packet_len(params->out_pkt) - + rte_pktmbuf_mtophys_offset((struct rte_mbuf *)param->out_pkt, + odp_packet_len(param->out_pkt) - auth_xform.auth.digest_length); op->sym->auth.digest.length = auth_xform.auth.digest_length; /* For SNOW3G algorithms, offset/length must be in bits */ if (auth_xform.auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) { - op->sym->auth.data.offset = params->auth_range.offset << 3; - op->sym->auth.data.length = params->auth_range.length << 3; + op->sym->auth.data.offset = param->auth_range.offset << 3; + op->sym->auth.data.length = param->auth_range.length << 3; } else { - op->sym->auth.data.offset = params->auth_range.offset; - op->sym->auth.data.length = params->auth_range.length; + op->sym->auth.data.offset = param->auth_range.offset; + op->sym->auth.data.length = param->auth_range.length; } - aad_head = data_addr + params->auth_range.offset; - plain_len = params->cipher_range.length; - aad_len = params->auth_range.length - plain_len; + aad_head = param->aad.ptr; + aad_len = param->aad.length; if (aad_len > 0) { op->sym->auth.aad.data = rte_malloc("aad", aad_len, 0); @@ -1037,9 +1038,9 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, goto err; } - if (params->override_iv_ptr) { + if (param->override_iv_ptr) { memcpy(op->sym->cipher.iv.data, - params->override_iv_ptr, + param->override_iv_ptr, entry->iv.length); } else if (entry->iv.data) { memcpy(op->sym->cipher.iv.data, @@ -1055,19 +1056,19 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, /* For SNOW3G algorithms, offset/length must be in bits */ if (cipher_xform.cipher.algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2) { - op->sym->cipher.data.offset = params->cipher_range.offset << 3; - op->sym->cipher.data.length = params->cipher_range.length << 3; + op->sym->cipher.data.offset = param->cipher_range.offset << 3; + op->sym->cipher.data.length = param->cipher_range.length << 3; } else { - op->sym->cipher.data.offset = params->cipher_range.offset; - op->sym->cipher.data.length = params->cipher_range.length; + op->sym->cipher.data.offset = param->cipher_range.offset; + op->sym->cipher.data.length = param->cipher_range.length; } if (rc_cipher == ODP_CRYPTO_ALG_ERR_NONE && rc_auth == ODP_CRYPTO_ALG_ERR_NONE) { int queue_pair = odp_cpu_id(); - op->sym->m_src = (struct rte_mbuf *)params->out_pkt; + op->sym->m_src = (struct rte_mbuf *)param->out_pkt; rc = rte_cryptodev_enqueue_burst(rte_session->dev_id, queue_pair, &op, 1); if (rc == 0) { @@ -1085,12 +1086,12 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, goto err; } - params->out_pkt = (odp_packet_t)op->sym->m_src; + param->out_pkt = (odp_packet_t)op->sym->m_src; } /* Fill in result */ - local_result.ctx = params->ctx; - local_result.pkt = params->out_pkt; + local_result.ctx = param->ctx; + local_result.pkt = param->out_pkt; local_result.cipher_status.alg_err = rc_cipher; local_result.cipher_status.hw_err = ODP_CRYPTO_HW_ERR_NONE; local_result.auth_status.alg_err = rc_auth; @@ -1106,7 +1107,7 @@ int odp_crypto_operation(odp_crypto_op_params_t *params, odp_event_t completion_event; odp_crypto_generic_op_result_t *op_result; - completion_event = odp_packet_to_event(params->out_pkt); + completion_event = odp_packet_to_event(param->out_pkt); _odp_buffer_event_type_set( odp_buffer_from_event(completion_event), ODP_EVENT_CRYPTO_COMPL); -- cgit v1.2.3 From 48ad99f7b4acca7577a17e259f1489cf4c7816d9 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Thu, 13 Jul 2017 14:13:28 +0200 Subject: linux-dpdk:porting "crypto: add SHA-1 authentication support" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_crypto.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index 443314a35..a869262bf 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -136,6 +136,10 @@ static int auth_alg_odp_to_rte(odp_auth_alg_t auth_alg, auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC; auth_xform->auth.digest_length = 16; break; + case ODP_AUTH_ALG_SHA1_HMAC: + auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; + auth_xform->auth.digest_length = 20; + break; case ODP_AUTH_ALG_AES_GCM: #if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: @@ -400,6 +404,10 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) hw_auths->bit.sha256_128 = 1; #endif } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA1_HMAC) { + hw_auths->bit.sha1_hmac = 1; + } } cap = &dev_info.capabilities[++i]; } @@ -467,6 +475,10 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) auths->bit.sha256_128 = 1; #endif } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA1_HMAC) { + auths->bit.sha1_hmac = 1; + } } cap = &dev_info.capabilities[++i]; } @@ -564,7 +576,7 @@ int odp_crypto_cipher_capability(odp_cipher_alg_t cipher, int odp_crypto_auth_capability(odp_auth_alg_t auth, odp_crypto_auth_capability_t dst[], - int num_copy) + int num_copy) { odp_crypto_auth_capability_t src[num_copy]; int idx = 0, rc = 0; -- cgit v1.2.3 From 27cfa741e4d80919fd352f3660351ac4fb631031 Mon Sep 17 00:00:00 2001 From: Balakrishna Garapati Date: Thu, 13 Jul 2017 14:18:25 +0200 Subject: linux-dpdk:porting "crypto: add HMAC-SHA-512 authentication support" Signed-off-by: Balakrishna Garapati Reviewed-and-tested-by: Matias Elo --- platform/linux-dpdk/odp_crypto.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform/linux-dpdk/odp_crypto.c b/platform/linux-dpdk/odp_crypto.c index a869262bf..d95b15780 100644 --- a/platform/linux-dpdk/odp_crypto.c +++ b/platform/linux-dpdk/odp_crypto.c @@ -140,6 +140,10 @@ static int auth_alg_odp_to_rte(odp_auth_alg_t auth_alg, auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC; auth_xform->auth.digest_length = 20; break; + case ODP_AUTH_ALG_SHA512_HMAC: + auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC; + auth_xform->auth.digest_length = 64; + break; case ODP_AUTH_ALG_AES_GCM: #if ODP_DEPRECATED_API case ODP_AUTH_ALG_AES128_GCM: @@ -408,6 +412,10 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) RTE_CRYPTO_AUTH_SHA1_HMAC) { hw_auths->bit.sha1_hmac = 1; } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA512_HMAC) { + hw_auths->bit.sha512_hmac = 1; + } } cap = &dev_info.capabilities[++i]; } @@ -479,6 +487,10 @@ int odp_crypto_capability(odp_crypto_capability_t *capability) RTE_CRYPTO_AUTH_SHA1_HMAC) { auths->bit.sha1_hmac = 1; } + if (cap_auth_algo == + RTE_CRYPTO_AUTH_SHA512_HMAC) { + auths->bit.sha512_hmac = 1; + } } cap = &dev_info.capabilities[++i]; } -- cgit v1.2.3 From 923550217b3800b2826965b1e7e964d799af7d94 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Mon, 17 Jul 2017 15:31:18 +0300 Subject: linux-dpdk: port time implementation changes dfbab74 linux-gen: time: store timespec as nsec fbe34c7 linux-gen: time: use hw time counter when available 08fe6f0 fix invalid casting on a 32-bit host Signed-off-by: Matias Elo Reviewed-by: Kevin Wang --- platform/linux-dpdk/Makefile.am | 2 +- .../linux-dpdk/include/odp/api/plat/time_types.h | 44 +-- platform/linux-dpdk/include/odp_time_internal.h | 44 --- platform/linux-dpdk/odp_time.c | 339 +++++++++++++-------- 4 files changed, 220 insertions(+), 209 deletions(-) mode change 100644 => 120000 platform/linux-dpdk/include/odp/api/plat/time_types.h delete mode 100644 platform/linux-dpdk/include/odp_time_internal.h diff --git a/platform/linux-dpdk/Makefile.am b/platform/linux-dpdk/Makefile.am index 1482f1bc2..c1497f0f6 100644 --- a/platform/linux-dpdk/Makefile.am +++ b/platform/linux-dpdk/Makefile.am @@ -155,7 +155,7 @@ noinst_HEADERS = \ ${top_srcdir}/platform/linux-generic/include/odp_schedule_if.h \ ${top_srcdir}/platform/linux-generic/include/odp_sorted_list_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_shm_internal.h \ - ${srcdir}/include/odp_time_internal.h \ + ${top_srcdir}/platform/linux-generic/include/odp_time_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_timer_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_timer_wheel_internal.h \ ${top_srcdir}/platform/linux-generic/include/odp_traffic_mngr_internal.h \ diff --git a/platform/linux-dpdk/include/odp/api/plat/time_types.h b/platform/linux-dpdk/include/odp/api/plat/time_types.h deleted file mode 100644 index e53ad2f97..000000000 --- a/platform/linux-dpdk/include/odp/api/plat/time_types.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP time service - */ - -#ifndef ODP_TIME_TYPES_H_ -#define ODP_TIME_TYPES_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup odp_time - * @{ - **/ - -/** - * @internal Time structure used to isolate odp-linux implementation from - * the linux timespec structure, which is dependent on POSIX extension level. - */ -typedef struct odp_time_t { - int64_t tv_sec; /**< @internal Seconds or DPDK ticks */ - int64_t tv_nsec; /**< @internal Nanoseconds */ -} odp_time_t; - -#define ODP_TIME_NULL ((odp_time_t){0, 0}) - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-dpdk/include/odp/api/plat/time_types.h b/platform/linux-dpdk/include/odp/api/plat/time_types.h new file mode 120000 index 000000000..b42bc83c2 --- /dev/null +++ b/platform/linux-dpdk/include/odp/api/plat/time_types.h @@ -0,0 +1 @@ +../../../../../linux-generic/include/odp/api/plat/time_types.h \ No newline at end of file diff --git a/platform/linux-dpdk/include/odp_time_internal.h b/platform/linux-dpdk/include/odp_time_internal.h deleted file mode 100644 index 8cbf81419..000000000 --- a/platform/linux-dpdk/include/odp_time_internal.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2016, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/** - * @file - * - * ODP time service - */ - -#ifndef ODP_TIME_INTERNAL_H_ -#define ODP_TIME_INTERNAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint64_t (*time_to_ns_fn) (odp_time_t time); -typedef odp_time_t (*time_diff_fn) (odp_time_t t2, odp_time_t t1); -typedef odp_time_t (*time_curr_fn)(void); -typedef int (*time_cmp_fn) (odp_time_t t2, odp_time_t t1); -typedef odp_time_t (*time_sum_fn) (odp_time_t t1, odp_time_t t2); -typedef odp_time_t (*time_local_from_ns_fn) (uint64_t ns); -typedef uint64_t (*time_local_res_fn)(void); -typedef uint64_t (*time_to_u64_fn) (odp_time_t time); - -typedef struct time_handler_ { - time_to_ns_fn time_to_ns; - time_diff_fn time_diff; - time_curr_fn time_curr; - time_cmp_fn time_cmp; - time_sum_fn time_sum; - time_local_from_ns_fn time_local_from_ns; - time_local_res_fn time_local_res; - time_to_u64_fn time_to_u64; -} time_handler_t; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/linux-dpdk/odp_time.c b/platform/linux-dpdk/odp_time.c index 9ca3109f1..6c066a5b5 100644 --- a/platform/linux-dpdk/odp_time.c +++ b/platform/linux-dpdk/odp_time.c @@ -13,105 +13,182 @@ #include #include #include +#include + +typedef uint64_t (*time_to_ns_fn) (odp_time_t time); +typedef odp_time_t (*time_cur_fn)(void); +typedef odp_time_t (*time_from_ns_fn) (uint64_t ns); +typedef uint64_t (*time_res_fn)(void); + +typedef struct time_handler_ { + time_to_ns_fn time_to_ns; + time_cur_fn time_cur; + time_from_ns_fn time_from_ns; + time_res_fn time_res; +} time_handler_t; + +typedef struct time_global_t { + struct timespec spec_start; + int use_hw; + uint64_t hw_start; + uint64_t hw_freq_hz; + /* DPDK specific */ + time_handler_t handler; + double tick_per_nsec; + double nsec_per_tick; +} time_global_t; + +static time_global_t global; + +/* + * Posix timespec based functions + */ + +static inline uint64_t time_spec_diff_nsec(struct timespec *t2, + struct timespec *t1) +{ + struct timespec diff; + uint64_t nsec; -typedef union { - odp_time_t ex; - struct timespec in; -} _odp_time_t; + diff.tv_sec = t2->tv_sec - t1->tv_sec; + diff.tv_nsec = t2->tv_nsec - t1->tv_nsec; -static odp_time_t start_time; -static time_handler_t time_handler; -double tick_per_nsec; -double nsec_per_tick; + if (diff.tv_nsec < 0) { + diff.tv_nsec += ODP_TIME_SEC_IN_NS; + diff.tv_sec -= 1; + } + + nsec = (diff.tv_sec * ODP_TIME_SEC_IN_NS) + diff.tv_nsec; + + return nsec; +} -static inline uint64_t time_local_res_dpdk(void) +static inline odp_time_t time_spec_cur(void) { - return rte_get_timer_hz(); + int ret; + odp_time_t time; + struct timespec sys_time; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &sys_time); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_gettime failed\n"); + + time.nsec = time_spec_diff_nsec(&sys_time, &global.spec_start); + + return time; } -static inline -uint64_t time_to_ns(odp_time_t time) +static inline uint64_t time_spec_res(void) { - uint64_t ns; + int ret; + struct timespec tres; - ns = time.tv_sec * ODP_TIME_SEC_IN_NS; - ns += time.tv_nsec; + ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); + if (odp_unlikely(ret != 0)) + ODP_ABORT("clock_getres failed\n"); - return ns; + return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; } -static inline uint64_t time_to_ns_dpdk(odp_time_t time) +static inline uint64_t time_spec_to_ns(odp_time_t time) { - return (time.tv_sec * nsec_per_tick); + return time.nsec; } -static inline odp_time_t time_diff(odp_time_t t2, odp_time_t t1) +static inline odp_time_t time_spec_from_ns(uint64_t ns) { odp_time_t time; - time.tv_sec = t2.tv_sec - t1.tv_sec; - time.tv_nsec = t2.tv_nsec - t1.tv_nsec; - - if (time.tv_nsec < 0) { - time.tv_nsec += ODP_TIME_SEC_IN_NS; - --time.tv_sec; - } + time.nsec = ns; return time; } -static inline odp_time_t time_diff_dpdk(odp_time_t t2, odp_time_t t1) +/* + * HW time counter based functions + */ + +static inline odp_time_t time_hw_cur(void) { odp_time_t time; - time.tv_sec = t2.tv_sec - t1.tv_sec; + time.count = cpu_global_time() - global.hw_start; + return time; } -static inline odp_time_t time_curr(void) +static inline uint64_t time_hw_res(void) { - int ret; - _odp_time_t time; + /* Promise a bit lower resolution than average cycle counter + * frequency */ + return global.hw_freq_hz / 10; +} - ret = clock_gettime(CLOCK_MONOTONIC_RAW, &time.in); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_gettime failed\n"); - return time.ex; +static inline uint64_t time_hw_to_ns(odp_time_t time) +{ + uint64_t nsec; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t count = time.count; + uint64_t sec = 0; + + if (count >= freq_hz) { + sec = count / freq_hz; + count = count - sec * freq_hz; + } + + nsec = (ODP_TIME_SEC_IN_NS * count) / freq_hz; + + return (sec * ODP_TIME_SEC_IN_NS) + nsec; } -static inline odp_time_t time_curr_dpdk(void) +static inline odp_time_t time_hw_from_ns(uint64_t ns) { odp_time_t time; + uint64_t count; + uint64_t freq_hz = global.hw_freq_hz; + uint64_t sec = 0; + + if (ns >= ODP_TIME_SEC_IN_NS) { + sec = ns / ODP_TIME_SEC_IN_NS; + ns = ns - sec * ODP_TIME_SEC_IN_NS; + } + + count = sec * freq_hz; + count += (ns * freq_hz) / ODP_TIME_SEC_IN_NS; + + time.count = count; - time.tv_sec = rte_get_timer_cycles(); return time; } -static inline odp_time_t time_local(void) +/* + * Common functions + */ + +static inline odp_time_t time_cur(void) { - odp_time_t time; + if (global.use_hw) + return time_hw_cur(); - time = time_handler.time_curr(); - return time_handler.time_diff(time, start_time); + return time_spec_cur(); } -static inline int time_cmp(odp_time_t t2, odp_time_t t1) +static inline uint64_t time_res(void) { - if (t2.tv_sec < t1.tv_sec) - return -1; + if (global.use_hw) + return time_hw_res(); - if (t2.tv_sec > t1.tv_sec) - return 1; - - return t2.tv_nsec - t1.tv_nsec; + return time_spec_res(); } -static inline int time_cmp_dpdk(odp_time_t t2, odp_time_t t1) +static inline int time_cmp(odp_time_t t2, odp_time_t t1) { - if (t2.tv_sec < t1.tv_sec) - return -1; - if (t2.tv_sec > t1.tv_sec) + if (odp_likely(t2.u64 > t1.u64)) return 1; + + if (t2.u64 < t1.u64) + return -1; + return 0; } @@ -119,61 +196,67 @@ static inline odp_time_t time_sum(odp_time_t t1, odp_time_t t2) { odp_time_t time; - time.tv_sec = t2.tv_sec + t1.tv_sec; - time.tv_nsec = t2.tv_nsec + t1.tv_nsec; - - if (time.tv_nsec >= (long)ODP_TIME_SEC_IN_NS) { - time.tv_nsec -= ODP_TIME_SEC_IN_NS; - ++time.tv_sec; - } + time.u64 = t1.u64 + t2.u64; return time; } -static inline odp_time_t time_sum_dpdk(odp_time_t t1, odp_time_t t2) +static inline uint64_t time_to_ns(odp_time_t time) { - odp_time_t time; + if (global.use_hw) + return time_hw_to_ns(time); - time.tv_sec = t2.tv_sec + t1.tv_sec; - return time; + return time_spec_to_ns(time); +} + +static inline odp_time_t time_from_ns(uint64_t ns) +{ + if (global.use_hw) + return time_hw_from_ns(ns); + + return time_spec_from_ns(ns); } -static inline odp_time_t time_local_from_ns(uint64_t ns) +static inline uint64_t time_res_dpdk(void) +{ + return rte_get_timer_hz(); +} + +static inline uint64_t time_to_ns_dpdk(odp_time_t time) +{ + return (time.u64 * global.nsec_per_tick); +} + +static inline odp_time_t time_cur_dpdk(void) { odp_time_t time; - time.tv_sec = ns / ODP_TIME_SEC_IN_NS; - time.tv_nsec = ns - time.tv_sec * ODP_TIME_SEC_IN_NS; + time.u64 = rte_get_timer_cycles() - global.hw_start; return time; } -static inline odp_time_t time_local_from_ns_dpdk(uint64_t ns) +static inline odp_time_t time_from_ns_dpdk(uint64_t ns) { odp_time_t time; - time.tv_sec = ns * tick_per_nsec; + + time.u64 = ns * global.tick_per_nsec; + return time; } +static inline odp_time_t time_local(void) +{ + return global.handler.time_cur(); +} + static inline void time_wait_until(odp_time_t time) { odp_time_t cur; do { cur = time_local(); - } while (time_handler.time_cmp(time, cur) > 0); -} - -static inline uint64_t time_local_res(void) -{ - int ret; - struct timespec tres; - - ret = clock_getres(CLOCK_MONOTONIC_RAW, &tres); - if (odp_unlikely(ret != 0)) - ODP_ABORT("clock_getres failed\n"); - - return ODP_TIME_SEC_IN_NS / (uint64_t)tres.tv_nsec; + } while (time_cmp(time, cur) > 0); } odp_time_t odp_time_local(void) @@ -188,49 +271,53 @@ odp_time_t odp_time_global(void) odp_time_t odp_time_diff(odp_time_t t2, odp_time_t t1) { - return time_handler.time_diff(t2, t1); + odp_time_t time; + + time.u64 = t2.u64 - t1.u64; + + return time; } uint64_t odp_time_to_ns(odp_time_t time) { - return time_handler.time_to_ns(time); + return global.handler.time_to_ns(time); } odp_time_t odp_time_local_from_ns(uint64_t ns) { - return time_handler.time_local_from_ns(ns); + return global.handler.time_from_ns(ns); } odp_time_t odp_time_global_from_ns(uint64_t ns) { - return time_handler.time_local_from_ns(ns); + return global.handler.time_from_ns(ns); } int odp_time_cmp(odp_time_t t2, odp_time_t t1) { - return time_handler.time_cmp(t2, t1); + return time_cmp(t2, t1); } odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2) { - return time_handler.time_sum(t1, t2); + return time_sum(t1, t2); } uint64_t odp_time_local_res(void) { - return time_handler.time_local_res(); + return global.handler.time_res(); } uint64_t odp_time_global_res(void) { - return time_handler.time_local_res(); + return global.handler.time_res(); } void odp_time_wait_ns(uint64_t ns) { odp_time_t cur = time_local(); - odp_time_t wait = time_handler.time_local_from_ns(ns); - odp_time_t end_time = time_handler.time_sum(cur, wait); + odp_time_t wait = global.handler.time_from_ns(ns); + odp_time_t end_time = time_sum(cur, wait); time_wait_until(end_time); } @@ -240,11 +327,6 @@ void odp_time_wait_until(odp_time_t time) return time_wait_until(time); } -static uint64_t time_to_u64_dpdk(odp_time_t time) -{ - return time.tv_sec; -} - static odp_bool_t is_invariant_tsc_supported(void) { FILE *file; @@ -291,37 +373,52 @@ static inline odp_bool_t is_dpdk_timer_cycles_support(void) int odp_time_init_global(void) { + int ret = 0; + + memset(&global, 0, sizeof(time_global_t)); + if (is_dpdk_timer_cycles_support()) { - time_handler.time_to_ns = time_to_ns_dpdk; - time_handler.time_diff = time_diff_dpdk; - time_handler.time_curr = time_curr_dpdk; - time_handler.time_cmp = time_cmp_dpdk; - time_handler.time_sum = time_sum_dpdk; - time_handler.time_local_from_ns = time_local_from_ns_dpdk; - time_handler.time_local_res = time_local_res_dpdk; - time_handler.time_to_u64 = time_to_u64_dpdk; - tick_per_nsec = (double)time_local_res_dpdk() / + global.handler.time_to_ns = time_to_ns_dpdk; + global.handler.time_cur = time_cur_dpdk; + global.handler.time_from_ns = time_from_ns_dpdk; + global.handler.time_res = time_res_dpdk; + global.tick_per_nsec = (double)time_res_dpdk() / (double)ODP_TIME_SEC_IN_NS; - nsec_per_tick = (double)ODP_TIME_SEC_IN_NS / - (double)time_local_res_dpdk(); - } else { - time_handler.time_to_ns = time_to_ns; - time_handler.time_diff = time_diff; - time_handler.time_curr = time_curr; - time_handler.time_cmp = time_cmp; - time_handler.time_sum = time_sum; - time_handler.time_local_from_ns = time_local_from_ns; - time_handler.time_local_res = time_local_res; - time_handler.time_to_u64 = time_to_u64; + global.nsec_per_tick = (double)ODP_TIME_SEC_IN_NS / + (double)time_res_dpdk(); + + global.hw_start = rte_get_timer_cycles(); + if (global.hw_start == 0) + return -1; + else + return 0; } - start_time = time_handler.time_curr(); - if (time_handler.time_cmp(start_time, ODP_TIME_NULL) == 0) { - ODP_ABORT("initiate odp time failed\n"); - return -1; - } else { + global.handler.time_to_ns = time_to_ns; + global.handler.time_cur = time_cur; + global.handler.time_from_ns = time_from_ns; + global.handler.time_res = time_res; + + if (cpu_has_global_time()) { + global.use_hw = 1; + global.hw_freq_hz = cpu_global_time_freq(); + + if (global.hw_freq_hz == 0) + return -1; + + printf("HW time counter freq: %" PRIu64 " hz\n\n", + global.hw_freq_hz); + + global.hw_start = cpu_global_time(); return 0; } + + global.spec_start.tv_sec = 0; + global.spec_start.tv_nsec = 0; + + ret = clock_gettime(CLOCK_MONOTONIC_RAW, &global.spec_start); + + return ret; } int odp_time_term_global(void) -- cgit v1.2.3 From 107b9411e85aad0a48d759fbf0572a631e189a02 Mon Sep 17 00:00:00 2001 From: Matias Elo Date: Wed, 19 Jul 2017 12:29:48 +0300 Subject: linux-dpdk: porting "linux-gen: packet: remove lazy parsing" Signed-off-by: Matias Elo Reviewed-by: Kevin Wang --- .../linux-dpdk/include/odp/api/plat/packet_types.h | 1 - platform/linux-dpdk/include/odp_packet_internal.h | 79 +---- platform/linux-dpdk/odp_packet.c | 340 ++++++++------------- platform/linux-dpdk/odp_packet_dpdk.c | 22 +- platform/linux-dpdk/odp_packet_flags.c | 114 +++---- 5 files changed, 210 insertions(+), 346 deletions(-) diff --git a/platform/linux-dpdk/include/odp/api/plat/packet_types.h b/platform/linux-dpdk/include/odp/api/plat/packet_types.h index 795ee0c16..5df0a41ec 100644 --- a/platform/linux-dpdk/include/odp/api/plat/packet_types.h +++ b/platform/linux-dpdk/include/odp/api/plat/packet_types.h @@ -101,7 +101,6 @@ typedef union { /** Individual input flags */ struct { - uint64_t parsed_l2:1; /**< L2 parsed */ uint64_t dst_queue:1; /**< Dst queue present */ uint64_t timestamp:1; /**< Timestamp present */ diff --git a/platform/linux-dpdk/include/odp_packet_internal.h b/platform/linux-dpdk/include/odp_packet_internal.h index d3f00847e..481e4afb1 100644 --- a/platform/linux-dpdk/include/odp_packet_internal.h +++ b/platform/linux-dpdk/include/odp_packet_internal.h @@ -83,18 +83,6 @@ typedef union { ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR"); -/** - * Protocol stack layers - */ -typedef enum { - LAYER_NONE = 0, - LAYER_L1, - LAYER_L2, - LAYER_L3, - LAYER_L4, - LAYER_ALL -} layer_t; - /** * Packet parser metadata */ @@ -106,14 +94,6 @@ typedef struct { uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also ICMP) */ - - uint32_t l3_len; /**< Layer 3 length */ - uint32_t l4_len; /**< Layer 4 length */ - - uint16_t ethtype; /**< EtherType */ - uint8_t ip_proto; /**< IP protocol */ - uint8_t parsed_layers; /**< Highest parsed protocol stack layer */ - } packet_parser_t; /** @@ -190,58 +170,25 @@ static inline void packet_set_len(odp_packet_hdr_t *pkt_hdr, uint32_t len) rte_pktmbuf_pkt_len(&pkt_hdr->buf_hdr.mb) = len; } -static inline int packet_parse_l2_not_done(packet_parser_t *prs) -{ - return !prs->input_flags.parsed_l2; -} - -static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) -{ - return pkt_hdr->p.parsed_layers != LAYER_ALL; -} - /* Forward declarations */ int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt); -/* Fill in parser metadata for L2 */ -static inline void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) -{ - /* Packet alloc or reset have already init other offsets and flags */ - - /* We only support Ethernet for now */ - prs->input_flags.eth = 1; - - /* Detect jumbo frames */ - if (frame_len > _ODP_ETH_LEN_MAX) - prs->input_flags.jumbo = 1; - - /* Assume valid L2 header, no CRC/FCS check in SW */ - prs->input_flags.l2 = 1; - - prs->input_flags.parsed_l2 = 1; -} +/* Perform packet parse up to a given protocol layer */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer); -static inline void _odp_packet_reset_parse(odp_packet_t pkt) +/* Reset parser metadata for a new parse */ +static inline void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { - odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - - uint32_t frame_len = rte_pktmbuf_pkt_len(&pkt_hdr->buf_hdr.mb); - - pkt_hdr->p.parsed_layers = LAYER_NONE; - pkt_hdr->p.input_flags.all = 0; + /* Reset parser metadata before new parse */ + pkt_hdr->p.error_flags.all = 0; + pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; - pkt_hdr->p.error_flags.all = 0; - pkt_hdr->p.l2_offset = 0; - - packet_parse_l2(&pkt_hdr->p, frame_len); + pkt_hdr->p.l2_offset = 0; + pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; + pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; } -/* Perform packet parse up to a given protocol layer */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); - -/* Reset parser metadata for a new parse */ -void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); - /* Convert a packet handle to a buffer handle */ odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt); @@ -277,7 +224,9 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) } int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len, layer_t layer); + uint32_t pkt_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer); + /* We can't enforce tailroom reservation for received packets */ ODP_STATIC_ASSERT(CONFIG_PACKET_TAILROOM == 0, diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c index 06f5a19cb..0d05e23f2 100644 --- a/platform/linux-dpdk/odp_packet.c +++ b/platform/linux-dpdk/odp_packet.c @@ -81,24 +81,6 @@ static inline odp_packet_hdr_t *buf_to_packet_hdr(odp_buffer_t buf) return (odp_packet_hdr_t *)buf_hdl_to_hdr(buf); } -static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) -{ - pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.parsed_layers = LAYER_ALL; -} - -void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) -{ - /* Reset parser metadata before new parse */ - pkt_hdr->p.parsed_layers = LAYER_NONE; - pkt_hdr->p.error_flags.all = 0; - pkt_hdr->p.input_flags.all = 0; - pkt_hdr->p.output_flags.all = 0; - pkt_hdr->p.l2_offset = 0; - pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; - pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; -} - static odp_packet_t packet_alloc(pool_entry_t* pool, uint32_t len) { odp_packet_t pkt; @@ -198,7 +180,6 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) return -1; } - pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -211,9 +192,6 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) pkt_hdr->input = ODP_PKTIO_INVALID; - /* Disable lazy parsing on user allocated packets */ - packet_parse_disable(pkt_hdr); - mb->port = 0xff; mb->pkt_len = len; mb->data_off = RTE_PKTMBUF_HEADROOM; @@ -627,8 +605,6 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l3_offset); } @@ -636,8 +612,6 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); return pkt_hdr->p.l3_offset; } @@ -648,8 +622,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L3) - packet_parse_layer(pkt_hdr, LAYER_L3); pkt_hdr->p.l3_offset = offset; return 0; } @@ -658,8 +630,6 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return packet_offset_to_ptr(pkt, len, pkt_hdr->p.l4_offset); } @@ -667,8 +637,6 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); return pkt_hdr->p.l4_offset; } @@ -679,8 +647,6 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1))) return -1; - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); pkt_hdr->p.l4_offset = offset; return 0; } @@ -1152,12 +1118,11 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr, uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); uint16_t frag_offset; uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); - - prs->l3_len = odp_be_to_cpu_16(ipv4->tot_len); + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || odp_unlikely(ver != 4) || - (prs->l3_len > frame_len - *offset)) { + (l3_len > frame_len - *offset)) { prs->error_flags.ip_err = 1; return 0; } @@ -1194,13 +1159,12 @@ static inline uint8_t parse_ipv6(packet_parser_t *prs, const uint8_t **parseptr, const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; const _odp_ipv6hdr_ext_t *ipv6ext; uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); - - prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + - _ODP_IPV6HDR_LEN; + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN; /* Basic sanity checks on IPv6 header */ if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || - prs->l3_len > frame_len - *offset) { + l3_len > frame_len - *offset) { prs->error_flags.ip_err = 1; return 0; } @@ -1261,9 +1225,6 @@ static inline void parse_tcp(packet_parser_t *prs, else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) prs->input_flags.tcpopt = 1; - prs->l4_len = prs->l3_len + - prs->l3_offset - prs->l4_offset; - if (offset) *offset += (uint32_t)tcp->hl * 4; *parseptr += (uint32_t)tcp->hl * 4; @@ -1278,13 +1239,8 @@ static inline void parse_udp(packet_parser_t *prs, const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; uint32_t udplen = odp_be_to_cpu_16(udp->length); - if (udplen < sizeof(_odp_udphdr_t) || - udplen > (prs->l3_len + - prs->l4_offset - prs->l3_offset)) { + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) prs->error_flags.udp_err = 1; - } - - prs->l4_len = udplen; if (offset) *offset += sizeof(_odp_udphdr_t); @@ -1298,200 +1254,172 @@ static inline void parse_udp(packet_parser_t *prs, * available from the ptr. */ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, - uint32_t frame_len, uint32_t seg_len, layer_t layer) + uint32_t frame_len, uint32_t seg_len, + odp_pktio_parser_layer_t layer) { uint32_t offset; + uint16_t ethtype; const uint8_t *parseptr; + uint8_t ip_proto; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; - switch (prs->parsed_layers) { - case LAYER_NONE: - /* Fall through */ - - case LAYER_L2: - { - const _odp_ethhdr_t *eth; - uint16_t macaddr0, macaddr2, macaddr4; - const _odp_vlanhdr_t *vlan; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - } - - /* Get Ethertype */ - prs->ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); + if (layer == ODP_PKTIO_PARSER_LAYER_NONE) + return 0; - /* Check for SNAP vs. DIX */ - if (prs->ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (prs->ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; - } - prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t) - (parseptr + 6))); - offset += 8; - parseptr += 8; - } + /* We only support Ethernet for now */ + prs->input_flags.eth = 1; + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->input_flags.l2 = 1; + /* Detect jumbo frames */ + if (frame_len > _ODP_ETH_LEN_MAX) + prs->input_flags.jumbo = 1; + + offset = sizeof(_odp_ethhdr_t); + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; + } - /* Parse the VLAN header(s), if present */ - if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1; + /* Get Ethertype */ + ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); + /* Check for SNAP vs. DIX */ + if (ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; } + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + } - if (prs->ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - prs->ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } + /* Parse the VLAN header(s), if present */ + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1; - prs->l3_offset = offset; - prs->parsed_layers = LAYER_L2; - if (layer == LAYER_L2) - return prs->error_flags.all != 0; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); } - /* Fall through */ - case LAYER_L3: - { - offset = prs->l3_offset; - parseptr = (const uint8_t *)(ptr + offset); - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - - /* Parse Layer 3 headers */ - switch (prs->ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, - frame_len); - break; + if (ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + } - case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, - frame_len, seg_len); - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L2) + return prs->error_flags.all != 0; - case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - break; + /* Set l3_offset+flag only for known ethtypes */ + prs->l3_offset = offset; + prs->input_flags.l3 = 1; - default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - prs->ip_proto = 255; /* Reserved invalid by IANA */ - } + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); + break; - /* Set l4_offset+flag only for known ip_proto */ - prs->l4_offset = offset; - prs->parsed_layers = LAYER_L3; - if (layer == LAYER_L3) - return prs->error_flags.all != 0; - } - /* Fall through */ + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len); + break; - case LAYER_L4: - { - offset = prs->l4_offset; - parseptr = (const uint8_t *)(ptr + offset); - prs->input_flags.l4 = 1; + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break; - /* Parse Layer 4 headers */ - switch (prs->ip_proto) { - case _ODP_IPPROTO_ICMPv4: - /* Fall through */ + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + ip_proto = 255; /* Reserved invalid by IANA */ + } - case _ODP_IPPROTO_ICMPv6: - prs->input_flags.icmp = 1; - break; + if (layer == ODP_PKTIO_PARSER_LAYER_L3) + return prs->error_flags.all != 0; - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->input_flags.l4 = 1; - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPv4: + /* Fall through */ - case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; - break; + case _ODP_IPPROTO_ICMPv6: + prs->input_flags.icmp = 1; + break; - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; - break; + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; - case _ODP_IPPROTO_SCTP: - prs->input_flags.sctp = 1; - break; + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; - default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; - } + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; - prs->parsed_layers = LAYER_L4; + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; break; - } - case LAYER_ALL: + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; break; default: - ODP_ERR("Invalid parse layer: %d\n", (int)layer); - return -1; + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; } - - prs->parsed_layers = LAYER_ALL; - parse_exit: return prs->error_flags.all != 0; } - /** * Simple packet parser */ -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + odp_pktio_parser_layer_t layer) { uint32_t seg_len = odp_packet_seg_len((odp_packet_t)pkt_hdr); uint32_t len = packet_len(pkt_hdr); diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c index 26d32370b..d056a8242 100644 --- a/platform/linux-dpdk/odp_packet_dpdk.c +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -369,6 +369,12 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index, (struct rte_mbuf **)pkt_table, (uint16_t)RTE_MAX(len, min)); + if (pktio_entry->s.config.pktin.bit.ts_all || + pktio_entry->s.config.pktin.bit.ts_ptp) { + ts_val = odp_time_global(); + ts = &ts_val; + } + if (nb_rx == 0 && !pkt_dpdk->lockless_tx) { pool_entry_t *pool_entry = get_pool_entry(_odp_typeval(pktio_entry->s.pool)); @@ -382,14 +388,16 @@ static int recv_pkt_dpdk(pktio_entry_t *pktio_entry, int index, odp_ticketlock_unlock(&pkt_dpdk->rx_lock[index]); for (i = 0; i < nb_rx; ++i) { - _odp_packet_reset_parse(pkt_table[i]); - odp_packet_hdr(pkt_table[i])->input = pktio_entry->s.handle; - } + odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt_table[i]); - if (pktio_entry->s.config.pktin.bit.ts_all || - pktio_entry->s.config.pktin.bit.ts_ptp) { - ts_val = odp_time_global(); - ts = &ts_val; + packet_parse_reset(pkt_hdr); + pkt_hdr->input = pktio_entry->s.handle; + + if (!pktio_cls_enabled(pktio_entry) && + pktio_entry->s.config.parser.layer) + packet_parse_layer(pkt_hdr, + pktio_entry->s.config.parser.layer); + packet_set_ts(pkt_hdr, ts); } if (odp_unlikely(min > len)) { diff --git a/platform/linux-dpdk/odp_packet_flags.c b/platform/linux-dpdk/odp_packet_flags.c index ebe567e78..d8c68f021 100644 --- a/platform/linux-dpdk/odp_packet_flags.c +++ b/platform/linux-dpdk/odp_packet_flags.c @@ -8,26 +8,21 @@ #include #include -#define retflag(pkt, x, layer) do { \ +#define retflag(pkt, x) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ return pkt_hdr->p.x; \ } while (0) -#define setflag(pkt, x, v, layer) do { \ +#define setflag(pkt, x, v) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (pkt_hdr->p.parsed_layers < layer) \ - packet_parse_layer(pkt_hdr, layer); \ - pkt_hdr->p.x = (v) & 1; \ + pkt_hdr->p.x = (v) & 1; \ } while (0) int odp_packet_has_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return odp_packet_hdr(pkt)->p.error_flags.all != 0; + + return pkt_hdr->p.error_flags.all != 0; } /* Get Input Flags */ @@ -44,126 +39,117 @@ int odp_packet_has_l2_error(odp_packet_t pkt) int odp_packet_has_l3(odp_packet_t pkt) { - retflag(pkt, input_flags.l3, LAYER_L3); + retflag(pkt, input_flags.l3); } int odp_packet_has_l3_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return pkt_hdr->p.error_flags.ip_err; } int odp_packet_has_l4(odp_packet_t pkt) { - retflag(pkt, input_flags.l4, LAYER_L4); + retflag(pkt, input_flags.l4); } int odp_packet_has_l4_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (pkt_hdr->p.parsed_layers < LAYER_L4) - packet_parse_layer(pkt_hdr, LAYER_L4); - return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err; } int odp_packet_has_eth_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_bcast, LAYER_L2); + retflag(pkt, input_flags.eth_bcast); } int odp_packet_has_eth_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_mcast, LAYER_L2); + retflag(pkt, input_flags.eth_mcast); } int odp_packet_has_vlan(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan, LAYER_L2); + retflag(pkt, input_flags.vlan); } int odp_packet_has_vlan_qinq(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan_qinq, LAYER_L2); + retflag(pkt, input_flags.vlan_qinq); } int odp_packet_has_arp(odp_packet_t pkt) { - retflag(pkt, input_flags.arp, LAYER_L3); + retflag(pkt, input_flags.arp); } int odp_packet_has_ipv4(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv4, LAYER_L3); + retflag(pkt, input_flags.ipv4); } int odp_packet_has_ipv6(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv6, LAYER_L3); + retflag(pkt, input_flags.ipv6); } int odp_packet_has_ip_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_bcast, LAYER_L3); + retflag(pkt, input_flags.ip_bcast); } int odp_packet_has_ip_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_mcast, LAYER_L3); + retflag(pkt, input_flags.ip_mcast); } int odp_packet_has_ipfrag(odp_packet_t pkt) { - retflag(pkt, input_flags.ipfrag, LAYER_L3); + retflag(pkt, input_flags.ipfrag); } int odp_packet_has_ipopt(odp_packet_t pkt) { - retflag(pkt, input_flags.ipopt, LAYER_L3); + retflag(pkt, input_flags.ipopt); } int odp_packet_has_ipsec(odp_packet_t pkt) { - retflag(pkt, input_flags.ipsec, LAYER_L4); + retflag(pkt, input_flags.ipsec); } int odp_packet_has_udp(odp_packet_t pkt) { - retflag(pkt, input_flags.udp, LAYER_L4); + retflag(pkt, input_flags.udp); } int odp_packet_has_tcp(odp_packet_t pkt) { - retflag(pkt, input_flags.tcp, LAYER_L4); + retflag(pkt, input_flags.tcp); } int odp_packet_has_sctp(odp_packet_t pkt) { - retflag(pkt, input_flags.sctp, LAYER_L4); + retflag(pkt, input_flags.sctp); } int odp_packet_has_icmp(odp_packet_t pkt) { - retflag(pkt, input_flags.icmp, LAYER_L4); + retflag(pkt, input_flags.icmp); } odp_packet_color_t odp_packet_color(odp_packet_t pkt) { - retflag(pkt, input_flags.color, LAYER_ALL); + retflag(pkt, input_flags.color); } void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.input_flags.color = color; } @@ -171,29 +157,23 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - return !pkt_hdr->p.input_flags.nodrop; } void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop) { - setflag(pkt, input_flags.nodrop, !drop, LAYER_ALL); + setflag(pkt, input_flags.nodrop, !drop); } int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) { - retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); + retflag(pkt, output_flags.shaper_len_adj); } void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); - if (packet_parse_not_complete(pkt_hdr)) - packet_parse_layer(pkt_hdr, LAYER_ALL); - pkt_hdr->p.output_flags.shaper_len_adj = adj; } @@ -201,107 +181,107 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) void odp_packet_has_l2_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l2, val, LAYER_L2); + setflag(pkt, input_flags.l2, val); } void odp_packet_has_l3_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l3, val, LAYER_L3); + setflag(pkt, input_flags.l3, val); } void odp_packet_has_l4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l4, val, LAYER_L4); + setflag(pkt, input_flags.l4, val); } void odp_packet_has_eth_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth, val, LAYER_L2); + setflag(pkt, input_flags.eth, val); } void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_bcast, val); } void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); + setflag(pkt, input_flags.eth_mcast, val); } void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.jumbo, val, LAYER_L2); + setflag(pkt, input_flags.jumbo, val); } void odp_packet_has_vlan_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan, val, LAYER_L2); + setflag(pkt, input_flags.vlan, val); } void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); + setflag(pkt, input_flags.vlan_qinq, val); } void odp_packet_has_arp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.arp, val, LAYER_L3); + setflag(pkt, input_flags.arp, val); } void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv4, val, LAYER_L3); + setflag(pkt, input_flags.ipv4, val); } void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv6, val, LAYER_L3); + setflag(pkt, input_flags.ipv6, val); } void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_bcast, val); } void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); + setflag(pkt, input_flags.ip_mcast, val); } void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipfrag, val, LAYER_L3); + setflag(pkt, input_flags.ipfrag, val); } void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipopt, val, LAYER_L3); + setflag(pkt, input_flags.ipopt, val); } void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipsec, val, LAYER_L4); + setflag(pkt, input_flags.ipsec, val); } void odp_packet_has_udp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.udp, val, LAYER_L4); + setflag(pkt, input_flags.udp, val); } void odp_packet_has_tcp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.tcp, val, LAYER_L4); + setflag(pkt, input_flags.tcp, val); } void odp_packet_has_sctp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.sctp, val, LAYER_L4); + setflag(pkt, input_flags.sctp, val); } void odp_packet_has_icmp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.icmp, val, LAYER_L4); + setflag(pkt, input_flags.icmp, val); } void odp_packet_has_ts_clr(odp_packet_t pkt) -- cgit v1.2.3