aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2023-03-10 10:16:35 +0200
committerPetri Savolainen <petri.savolainen@nokia.com>2023-03-17 16:17:54 +0200
commit8be77b5634878ffc1bbad16e13938b3d7468fdcb (patch)
treeb42d2fc720af40d4e276e9894a4b3e929a4bafac
parent3f9ab770e1d622c82d3a718a86d1a13d2d4d0603 (diff)
linux-gen: pktio: remove netmap pktio
Remove rarely used Netmap pktio device to ease code maintenance and reduce CI runtime. Netmap pktio can be replaced for example by socket_xdp pktio, which provides better performance with standard Linux APIs. Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-by: Jere Leppänen <jere.leppanen@nokia.com>
-rw-r--r--.github/workflows/ci-pipeline.yml29
-rw-r--r--DEPENDENCIES100
-rw-r--r--config/odp-linux-generic.conf9
-rw-r--r--doc/process-guide/faq.adoc3
-rw-r--r--include/odp/autoheader_internal.h.in3
-rw-r--r--platform/linux-generic/Makefile.am2
-rw-r--r--platform/linux-generic/README4
-rw-r--r--platform/linux-generic/include/odp_packet_io_internal.h5
-rw-r--r--platform/linux-generic/m4/configure.m41
-rw-r--r--platform/linux-generic/m4/odp_netmap.m449
-rw-r--r--platform/linux-generic/pktio/io_ops.c3
-rw-r--r--platform/linux-generic/pktio/netmap.c1347
-rw-r--r--platform/linux-generic/pktio/socket_common.c5
-rw-r--r--platform/linux-generic/test/Makefile.am3
-rw-r--r--platform/linux-generic/test/validation/api/pktio/Makefile.am3
-rwxr-xr-xplatform/linux-generic/test/validation/api/pktio/pktio_run.sh3
-rwxr-xr-xplatform/linux-generic/test/validation/api/pktio/pktio_run_netmap.sh123
17 files changed, 14 insertions, 1678 deletions
diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml
index a51bfc9ae..da09fe020 100644
--- a/.github/workflows/ci-pipeline.yml
+++ b/.github/workflows/ci-pipeline.yml
@@ -462,32 +462,3 @@ jobs:
- name: Failure log
if: ${{ failure() }}
run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
-
- Run_netmap:
- runs-on: ubuntu-20.04
- env:
- NETMAP_TAG: a315cf3f
- strategy:
- fail-fast: false
- matrix:
- cc: [gcc, clang]
- conf: ['--with-netmap-path=/odp/netmap',
- '--with-netmap-path=/odp/netmap --disable-static-applications']
- steps:
- - uses: actions/checkout@v3
- - name: Install dependencies
- run: |
- sudo apt-get install linux-headers-`uname -r`
- CDIR=`pwd`
- git clone --single-branch --branch=master https://github.com/luigirizzo/netmap.git
- pushd netmap/LINUX
- git checkout ${NETMAP_TAG}
- ./configure --drivers=
- make -j $(nproc)
- popd
- sudo insmod ./netmap/LINUX/netmap.ko
- - run: sudo docker run -i -v `pwd`:/odp --privileged --shm-size 8g -e CC="${{matrix.cc}}" -e ARCH="${ARCH}"
- -e CONF="${{matrix.conf}}" $CONTAINER_NAMESPACE/odp-ci-${OS}-${ARCH} /odp/scripts/ci/check.sh
- - name: Failure log
- if: ${{ failure() }}
- run: find . -name "*.trs" | xargs grep -l '^.test-result. FAIL' | while read trs ; do echo FAILURE detected at $trs; cat ${trs%%.trs}.log ; done
diff --git a/DEPENDENCIES b/DEPENDENCIES
index d7af53dff..bb51bc2e0 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -152,86 +152,8 @@ Prerequisites for building the OpenDataPlane (ODP) API
$ ./configure --with-crypto=ipsecmb
$ make
-3.5 Netmap packet I/O support (optional)
- Netmap accelerated ODP packet I/O.
-
-3.5.1 Building netmap kernel modules
-
- ODP works at least with the latest release version of netmap, which is
- currently v13.0. However, if possible one should try to use the latest netmap
- master branch commit for the best performance and the latest bug fixes.
-
- # Checkout netmap code
- $ git clone https://github.com/luigirizzo/netmap.git
- $ cd netmap
- $ git checkout v13.0 (optional)
-
- This is enough to build ODP. If you don't want to build netmap kernel
- modules you can jump to section 3.3.2.
-
- Netmap consists of a core kernel module (netmap.ko), optional modified
- device drivers and user space API headers to access the netmap
- functionality. It is recommended to build both the core module and modified
- device drivers for optimal performance.
-
- Netmap builds as an out-of-tree kernel module, you need matching kernel
- sources to compile it. General build instructions can be found in the packet
- README: https://github.com/luigirizzo/netmap/blob/master/LINUX/README.
-
- If you are running Ubuntu/Debian with the stock kernel and you want to
- compile both netmap.ko and modified drivers, these steps will guide you
- through it.
-
- # Download kernel headers
- $ sudo apt-get install linux-headers-$(uname -r)
-
- # Download kernel source matching to the headers
- $ sudo apt-get install linux-source
- # or
- $ apt-get source linux-image-$(uname -r)
-
- The source archive will be placed in /usr/src/linux-source-<kernel-version>
- (or in the current directory if using apt-get source). You will need to
- locate it and extract it to a convenient place.
-
- # Compile netmap
- $ cd <netmap_dir>/LINUX
- $ ./configure --kernel-sources=<path_to_kernel_src>
- $ make
-
-3.5.2 Building ODP
-
- $ cd <odp_dir>
- $ ./bootstrap
- $ ./configure --with-netmap-path=<netmap_dir>
- $ make
-
-3.5.3 Inserting netmap kernel modules
-
- In order to use netmap I/O you need to insert at least the core netmap
- kernel module.
-
- $ cd <netmap_dir>/LINUX
- $ sudo insmod netmap.ko
-
- To insert the optional modified drivers you first need to remove the
- original drivers, if loaded (and if not linked into the kernel). For
- example, if using ixgbe:
-
- $ cd <netmap_path>/LINUX
- $ sudo rmmod ixgbe
- $ sudo insmod ixgbe/ixgbe.ko
-
- To restore the original drivers you should be able to use modprobe.
-
-3.5.4 Running ODP with netmap I/O
-
- ODP applications will use netmap for packet I/O by default as long as the
- netmap kernel module is loaded. If socket I/O is desired instead, it can be
- activated by setting the environment variable ODP_PKTIO_DISABLE_NETMAP.
-
-3.6 DPDK packet I/O support (optional)
+3.5 DPDK packet I/O support (optional)
Use DPDK for ODP packet I/O. Currently supported DPDK versions are v19.11,
v20.11 (recommended), v21.11, and v22.11.
@@ -240,7 +162,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
https://github.com/OpenDataPlane/odp-dpdk.git
for a full DPDK based ODP implementation.
-3.6.1 DPDK pktio requirements
+3.5.1 DPDK pktio requirements
DPDK pktio adds a dependency to NUMA library.
# Debian/Ubuntu
@@ -249,11 +171,11 @@ Prerequisites for building the OpenDataPlane (ODP) API
# CentOS/RedHat/Fedora
$ sudo yum install numactl-devel
-3.6.2 Native DPDK install
+3.5.2 Native DPDK install
# Debian/Ubuntu starting from 20.04
$ sudo apt-get install dpdk-dev
-3.6.3 Build DPDK v19.11 from source
+3.5.3 Build DPDK v19.11 from source
$ git clone https://dpdk.org/git/dpdk-stable --branch 19.11 --depth 1 ./<dpdk-dir>
# Make and edit DPDK configuration
@@ -271,7 +193,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
# Configure ODP
$ ./configure --with-dpdk-path=<dpdk-dir>
-3.6.4 Build DPDK v20.11 and onwards from source
+3.5.4 Build DPDK v20.11 and onwards from source
$ git clone https://dpdk.org/git/dpdk-stable --branch <version, e.g. 21.11> --depth 1 ./<dpdk-dir>
# Prepare the build directory
@@ -291,7 +213,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
# Or, if DPDK was not installed to the default location, set PKG_CONFIG_PATH:
$ PKG_CONFIG_PATH=<dpdk-dir>/install/lib/x86_64-linux-gnu/pkgconfig ./configure --enable-dpdk
-3.6.5 Setup system
+3.5.5 Setup system
# Load DPDK modules
$ sudo modprobe uio
@@ -303,7 +225,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
512 x 2MB huge pages. All this can be done with the DPDK setup script
(<dpdk-dir>/usertools/dpdk-setup.sh).
-3.6.6 Running ODP with DPDK pktio
+3.5.6 Running ODP with DPDK pktio
ODP applications will try use DPDK for packet I/O by default. If some other
I/O type is desired instead, DPDK I/O can be disabled by setting the
@@ -319,7 +241,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
1024MB of memory:
$ sudo ODP_PKTIO_DPDK_PARAMS="-m 1024" ./test/performance/odp_l2fwd -i 0 -c 1
-3.7 AF_XDP socket based packet I/O support (optional)
+3.6 AF_XDP socket based packet I/O support (optional)
Use AF_XDP socket for packet I/O. At the moment, only zero-copy variant is
supported, requiring a kernel version 5.4 or higher. Additionally, if packet
@@ -336,7 +258,7 @@ Prerequisites for building the OpenDataPlane (ODP) API
Note that, currently, AF_XDP socket packet I/O cannot be instantiated if
DPDK zero-copy is enabled.
-3.7.1 AF_XDP socket packet I/O requirements
+3.6.1 AF_XDP socket packet I/O requirements
AF_XDP socket packet I/O implementation requires libxdp and libbpf libraries.
They can be fetched from XDP-project in GitHub:
@@ -358,14 +280,14 @@ Prerequisites for building the OpenDataPlane (ODP) API
$ cd <path to built libbpf>
$ make install
-3.7.2 Build ODP with AF_XDP socket packet I/O support
+3.6.2 Build ODP with AF_XDP socket packet I/O support
After building and installing libxdp and libbpf, ODP can be configured to be
built with AF_XDP support (pass PKG_CONFIG_PATH if needed).
$ ./configure --enable-xdp
-3.7.3 Running ODP with AF_XDP socket packet I/O
+3.6.3 Running ODP with AF_XDP socket packet I/O
AF_XDP socket packet I/Os bind to TRX-combined queues. Based on the packet
prosessing needs, NIC(s) of the environment should be configured
diff --git a/config/odp-linux-generic.conf b/config/odp-linux-generic.conf
index 142a205d0..89bdecc4b 100644
--- a/config/odp-linux-generic.conf
+++ b/config/odp-linux-generic.conf
@@ -140,15 +140,6 @@ pktio_dpdk: {
}
}
-# netmap pktio options
-pktio_netmap: {
- # Interface specific options
- virt: {
- nr_rx_slots = 0
- nr_tx_slots = 0
- }
-}
-
# XDP pktio options
pktio_xdp: {
# Number of RX and TX descriptors to be reserved for AF_XDP socket
diff --git a/doc/process-guide/faq.adoc b/doc/process-guide/faq.adoc
index cbdd05757..8b3de4de7 100644
--- a/doc/process-guide/faq.adoc
+++ b/doc/process-guide/faq.adoc
@@ -219,9 +219,6 @@ vendors package this capability as a NIC + ODP library. The ODP project also
supports its own ODP-DPDK [1] implementation to help migrations from the lower
level DPDK API to the ODPs abstraction.
-But traditional NICs are supported odp-linux has PKTIO support for Netmap and
-DPDK.
-
== Does ODP support polling mode?
ODP does not dictate a model, although the majority of current contributors see
diff --git a/include/odp/autoheader_internal.h.in b/include/odp/autoheader_internal.h.in
index a42b34ad0..87cefa131 100644
--- a/include/odp/autoheader_internal.h.in
+++ b/include/odp/autoheader_internal.h.in
@@ -17,9 +17,6 @@
/* Define to 1 to enable DPDK zero copy support */
#undef _ODP_DPDK_ZERO_COPY
-/* Define to 1 to enable netmap packet I/O support */
-#undef _ODP_PKTIO_NETMAP
-
/* Define to 1 to enable pcap packet I/O support */
#undef _ODP_PKTIO_PCAP
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index d49a2138b..324507ee5 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -12,7 +12,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/@ARCH_DIR@
AM_CPPFLAGS += -I$(top_srcdir)/platform/$(with_platform)/arch/default
AM_CPPFLAGS += $(OPENSSL_CPPFLAGS)
-AM_CPPFLAGS += $(NETMAP_CPPFLAGS)
AM_CFLAGS += $(AARCH64CRYPTO_CFLAGS)
AM_CFLAGS += $(DPDK_CFLAGS)
@@ -270,7 +269,6 @@ __LIB__libodp_linux_la_SOURCES = \
pktio/io_ops.c \
pktio/ipc.c \
pktio/loop.c \
- pktio/netmap.c \
pktio/null.c \
pktio/pktio_common.c \
pktio/socket.c \
diff --git a/platform/linux-generic/README b/platform/linux-generic/README
index 138e6040c..8fa50c127 100644
--- a/platform/linux-generic/README
+++ b/platform/linux-generic/README
@@ -29,17 +29,17 @@ SPDX-License-Identifier: BSD-3-Clause
E.g.
socket:eth1
- netmap:eth2
+ socket_xdp:eth2
The supported pktio types are:
dpdk
ipc
loop
- netmap
null
pcap
socket
socket_mmap
+ socket_xdp
tap
5. Random data
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 187a3a76f..9caf3c2e9 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -62,9 +62,7 @@ ODP_STATIC_ASSERT(PKTIO_LSO_PROFILES < UINT8_MAX, "PKTIO_LSO_PROFILES_ERROR");
/* Forward declaration */
struct pktio_if_ops;
-#if defined(_ODP_PKTIO_NETMAP)
-#define PKTIO_PRIVATE_SIZE 74752
-#elif defined(_ODP_PKTIO_XDP) && ODP_CACHE_LINE_SIZE == 128
+#if defined(_ODP_PKTIO_XDP) && ODP_CACHE_LINE_SIZE == 128
#define PKTIO_PRIVATE_SIZE 33792
#elif defined(_ODP_PKTIO_XDP)
#define PKTIO_PRIVATE_SIZE 29696
@@ -292,7 +290,6 @@ static inline void _odp_pktio_tx_ts_set(pktio_entry_t *entry)
odp_atomic_store_u64(&entry->tx_ts, ts_val.u64);
}
-extern const pktio_if_ops_t _odp_netmap_pktio_ops;
extern const pktio_if_ops_t _odp_dpdk_pktio_ops;
extern const pktio_if_ops_t _odp_sock_xdp_pktio_ops;
extern const pktio_if_ops_t _odp_sock_mmsg_pktio_ops;
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index f018d2b24..00ee3683b 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -28,7 +28,6 @@ m4_include([platform/linux-generic/m4/odp_openssl.m4])
m4_include([platform/linux-generic/m4/odp_crypto.m4])
m4_include([platform/linux-generic/m4/odp_ipsec_mb.m4])
m4_include([platform/linux-generic/m4/odp_pcapng.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_xdp.m4])
ODP_EVENT_VALIDATION
diff --git a/platform/linux-generic/m4/odp_netmap.m4 b/platform/linux-generic/m4/odp_netmap.m4
deleted file mode 100644
index 7688c080e..000000000
--- a/platform/linux-generic/m4/odp_netmap.m4
+++ /dev/null
@@ -1,49 +0,0 @@
-##########################################################################
-# Enable netmap support
-##########################################################################
-netmap_support=no
-AC_ARG_ENABLE([netmap_support],
- [AS_HELP_STRING([--enable-netmap-support], [include netmap IO support]
- [[default=disabled] (linux-generic)])],
- [if test x$enableval = xyes; then
- netmap_support=yes
- fi])
-
-##########################################################################
-# Set optional netmap path
-##########################################################################
-AC_ARG_WITH([netmap-path],
-AS_HELP_STRING([--with-netmap-path=DIR], [path to netmap root directory]
- [[default=system] (linux-generic)]),
- [NETMAP_PATH=$withval
- NETMAP_CPPFLAGS="-isystem $NETMAP_PATH/sys"
- netmap_support=yes],[])
-
-##########################################################################
-# Save and set temporary compilation flags
-##########################################################################
-OLD_CPPFLAGS=$CPPFLAGS
-CPPFLAGS="$NETMAP_CPPFLAGS $CPPFLAGS"
-
-##########################################################################
-# Check for netmap availability
-##########################################################################
-if test x$netmap_support = xyes
-then
- AC_CHECK_HEADERS([net/netmap_user.h], [],
- [AC_MSG_FAILURE(["can't find netmap header"])])
- AC_DEFINE([_ODP_PKTIO_NETMAP], [1],
- [Define to 1 to enable netmap packet I/O support])
- AC_SUBST([NETMAP_CPPFLAGS])
-else
- netmap_support=no
-fi
-
-##########################################################################
-# Restore old saved variables
-##########################################################################
-CPPFLAGS=$OLD_CPPFLAGS
-
-AC_CONFIG_COMMANDS_PRE([dnl
-AM_CONDITIONAL([netmap_support], [test x$netmap_support = xyes ])
-])
diff --git a/platform/linux-generic/pktio/io_ops.c b/platform/linux-generic/pktio/io_ops.c
index f9ea89f71..141b881e3 100644
--- a/platform/linux-generic/pktio/io_ops.c
+++ b/platform/linux-generic/pktio/io_ops.c
@@ -19,9 +19,6 @@ const pktio_if_ops_t * const _odp_pktio_if_ops[] = {
#ifdef _ODP_PKTIO_XDP
&_odp_sock_xdp_pktio_ops,
#endif
-#ifdef _ODP_PKTIO_NETMAP
- &_odp_netmap_pktio_ops,
-#endif
#ifdef _ODP_PKTIO_PCAP
&_odp_pcap_pktio_ops,
#endif
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
deleted file mode 100644
index 0352e33f7..000000000
--- a/platform/linux-generic/pktio/netmap.c
+++ /dev/null
@@ -1,1347 +0,0 @@
-/* Copyright (c) 2015-2018, Linaro Limited
- * Copyright (c) 2019-2022, Nokia
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <odp/autoheader_internal.h>
-
-#ifdef _ODP_PKTIO_NETMAP
-
-#include <odp_posix_extensions.h>
-
-#include <odp/api/packet.h>
-#include <odp/api/plat/packet_inlines.h>
-#include <odp/api/time.h>
-#include <odp/api/plat/time_inlines.h>
-
-#include <odp_parse_internal.h>
-#include <odp_packet_io_internal.h>
-#include <odp_packet_io_stats.h>
-#include <odp_ethtool_stats.h>
-#include <odp_ethtool_rss.h>
-#include <odp_socket_common.h>
-#include <odp_debug_internal.h>
-#include <odp_errno_define.h>
-#include <odp_classification_datamodel.h>
-#include <odp_classification_internal.h>
-#include <odp_libconfig_internal.h>
-#include <odp_macros_internal.h>
-
-#include <protocols/eth.h>
-#include <sys/ioctl.h>
-#include <sys/syscall.h>
-#include <poll.h>
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
-#include <inttypes.h>
-
-/* Disable netmap debug prints */
-#ifndef ND
-#define ND(_fmt, ...) do {} while (0)
-#define D(_fmt, ...) do {} while (0)
-#define RD(lps, format, ...) do {} while (0)
-#endif
-
-#define NETMAP_WITH_LIBS
-#include <net/netmap_user.h>
-
-#define NM_WAIT_TIMEOUT 10 /* netmap_wait_for_link() timeout in seconds */
-#define NM_INJECT_RETRIES 10
-
-#define NM_MAX_DESC 64
-
-#define NM_BUF_SIZE "/sys/module/netmap/parameters/buf_size"
-
-/** netmap runtime configuration options */
-typedef struct {
- int nr_rx_slots;
- int nr_tx_slots;
-} netmap_opt_t;
-
-/** Ring for mapping pktin/pktout queues to netmap descriptors */
-typedef struct ODP_ALIGNED_CACHE {
- unsigned int first; /**< Index of first netmap descriptor */
- unsigned int last; /**< Index of last netmap descriptor */
- unsigned int num; /**< Number of netmap descriptors */
- /** Netmap metadata for the device */
- struct nm_desc *desc[NM_MAX_DESC];
- unsigned int cur; /**< Index of current netmap descriptor */
- odp_ticketlock_t lock; /**< Queue lock */
-} netmap_ring_t;
-
-/** Netmap ring slot */
-typedef struct {
- char *buf; /**< Slot buffer pointer */
- uint16_t len; /**< Slot length */
-} netmap_slot_t;
-
-/** Packet socket using netmap mmaped rings for both Rx and Tx */
-typedef struct {
- odp_pool_t pool; /**< pool to alloc packets from */
- uint32_t if_flags; /**< interface flags */
- uint32_t mtu; /**< maximum transmission unit */
- uint32_t mtu_max; /**< maximum supported MTU value */
- int sockfd; /**< control socket */
- unsigned char if_mac[ETH_ALEN]; /**< eth mac address */
- char nm_name[IF_NAMESIZE + 7]; /**< netmap:<ifname> */
- char if_name[IF_NAMESIZE]; /**< interface name used in ioctl */
- odp_bool_t is_virtual; /**< nm virtual port (VALE/pipe) */
- uint32_t num_rx_rings; /**< number of nm rx rings */
- uint32_t num_tx_rings; /**< number of nm tx rings */
- unsigned int num_rx_desc_rings; /**< number of rx descriptor rings */
- unsigned int num_tx_desc_rings; /**< number of tx descriptor rings */
- odp_bool_t lockless_rx; /**< no locking for rx */
- odp_bool_t lockless_tx; /**< no locking for tx */
- /** mapping of pktin queues to netmap rx descriptors */
- netmap_ring_t rx_desc_ring[ODP_PKTIN_MAX_QUEUES];
- /** mapping of pktout queues to netmap tx descriptors */
- netmap_ring_t tx_desc_ring[ODP_PKTOUT_MAX_QUEUES];
- netmap_opt_t opt; /**< options */
-} pkt_netmap_t;
-
-ODP_STATIC_ASSERT(PKTIO_PRIVATE_SIZE >= sizeof(pkt_netmap_t),
- "PKTIO_PRIVATE_SIZE too small");
-
-static inline pkt_netmap_t *pkt_priv(pktio_entry_t *pktio_entry)
-{
- return (pkt_netmap_t *)(uintptr_t)(pktio_entry->pkt_priv);
-}
-
-static int disable_pktio; /** !0 this pktio disabled, 0 enabled */
-static int netmap_stats_reset(pktio_entry_t *pktio_entry);
-
-static int read_netmap_buf_size(void)
-{
- FILE *file;
- char str[128];
- int size = 0;
-
- file = fopen(NM_BUF_SIZE, "rt");
- if (file == NULL) {
- /* File not found */
- return 0;
- }
-
- if (fgets(str, sizeof(str), file) != NULL) {
- /* Read netmap buffer size */
- if (sscanf(str, "%i", &size) != 1)
- size = 0;
- }
-
- fclose(file);
-
- return size;
-}
-
-static int lookup_opt(const char *opt_name, const char *drv_name, int *val)
-{
- const char *base = "pktio_netmap";
- int ret;
-
- ret = _odp_libconfig_lookup_ext_int(base, drv_name, opt_name, val);
- if (ret == 0)
- _ODP_ERR("Unable to find netmap configuration option: %s\n", opt_name);
-
- return ret;
-}
-
-static int init_options(pktio_entry_t *pktio_entry)
-{
- netmap_opt_t *opt = &pkt_priv(pktio_entry)->opt;
-
- if (!lookup_opt("nr_rx_slots", "virt",
- &opt->nr_rx_slots))
- return -1;
- if (opt->nr_rx_slots < 0 ||
- opt->nr_rx_slots > 4096) {
- _ODP_ERR("Invalid number of RX slots\n");
- return -1;
- }
-
- if (!lookup_opt("nr_tx_slots", "virt",
- &opt->nr_tx_slots))
- return -1;
- if (opt->nr_tx_slots < 0 ||
- opt->nr_tx_slots > 4096) {
- _ODP_ERR("Invalid number of TX slots\n");
- return -1;
- }
-
- _ODP_DBG("netmap interface: %s\n", pkt_priv(pktio_entry)->if_name);
- _ODP_DBG(" num_rx_desc: %d\n", opt->nr_rx_slots);
- _ODP_DBG(" num_tx_desc: %d\n", opt->nr_tx_slots);
-
- return 0;
-}
-
-static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd,
- int subcmd)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- struct ethtool_value eval;
- struct ifreq ifr;
- int err;
- int fd = pkt_nm->sockfd;
-
- memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s",
- pkt_priv(pktio_entry)->if_name);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- ifr.ifr_flags = pkt_nm->if_flags & 0xffff;
- break;
- case SIOCETHTOOL:
- eval.cmd = subcmd;
- eval.data = 0;
- ifr.ifr_data = (caddr_t)&eval;
- break;
- default:
- break;
- }
- err = ioctl(fd, cmd, &ifr);
- if (err)
- goto done;
-
- switch (cmd) {
- case SIOCGIFFLAGS:
- pkt_nm->if_flags = (ifr.ifr_flags << 16) |
- (0xffff & ifr.ifr_flags);
- break;
- case SIOCETHTOOL:
- if (subcmd == ETHTOOL_GLINK)
- return eval.data;
- break;
- default:
- break;
- }
-done:
- if (err)
- _ODP_ERR("ioctl err %d %lu: %s\n", err, cmd, strerror(errno));
-
- return err;
-}
-
-/**
- * Map netmap rings to pktin/pktout queues
- *
- * @param rings Array of netmap descriptor rings
- * @param num_queues Number of pktin/pktout queues
- * @param num_rings Number of matching netmap rings
- */
-static inline void map_netmap_rings(netmap_ring_t *rings,
- unsigned int num_queues, unsigned int num_rings)
-{
- netmap_ring_t *desc_ring;
- unsigned int rings_per_queue;
- unsigned int remainder;
- unsigned int mapped_rings;
- unsigned int i;
- unsigned int desc_id = 0;
-
- rings_per_queue = num_rings / num_queues;
- remainder = num_rings % num_queues;
-
- if (remainder)
- _ODP_DBG("WARNING: Netmap rings mapped unevenly to queues\n");
-
- for (i = 0; i < num_queues; i++) {
- desc_ring = &rings[i];
- if (i < remainder)
- mapped_rings = rings_per_queue + 1;
- else
- mapped_rings = rings_per_queue;
-
- desc_ring->first = desc_id;
- desc_ring->cur = desc_id;
- desc_ring->last = desc_ring->first + mapped_rings - 1;
- desc_ring->num = mapped_rings;
-
- desc_id = desc_ring->last + 1;
- }
-}
-
-static int netmap_input_queues_config(pktio_entry_t *pktio_entry,
- const odp_pktin_queue_param_t *p)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- odp_pktin_mode_t mode = pktio_entry->param.in_mode;
- unsigned int num_queues = p->num_queues;
- odp_bool_t lockless;
-
- /* Scheduler synchronizes input queue polls. Only single thread
- * at a time polls a queue */
- if (mode == ODP_PKTIN_MODE_SCHED)
- lockless = 1;
- else
- lockless = (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE);
-
- if (p->hash_enable && num_queues > 1) {
- if (_odp_rss_conf_set_fd(pkt_priv(pktio_entry)->sockfd,
- pkt_priv(pktio_entry)->if_name,
- &p->hash_proto)) {
- _ODP_ERR("Failed to configure input hash\n");
- return -1;
- }
- }
-
- pkt_nm->lockless_rx = lockless;
-
- return 0;
-}
-
-static int netmap_output_queues_config(pktio_entry_t *pktio_entry,
- const odp_pktout_queue_param_t *p)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
-
- pkt_nm->lockless_tx = (p->op_mode == ODP_PKTIO_OP_MT_UNSAFE);
-
- return 0;
-}
-
-/**
- * Close netmap descriptors
- *
- * Can be reopened using netmap_start() function.
- *
- * @param pktio_entry Packet IO entry
- */
-static inline void netmap_close_descriptors(pktio_entry_t *pktio_entry)
-{
- int i, j;
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
-
- for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++) {
- for (j = 0; j < NM_MAX_DESC; j++) {
- if (pkt_nm->rx_desc_ring[i].desc[j] != NULL) {
- nm_close(pkt_nm->rx_desc_ring[i].desc[j]);
- pkt_nm->rx_desc_ring[i].desc[j] = NULL;
- }
- }
- }
- for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++) {
- for (j = 0; j < NM_MAX_DESC; j++) {
- if (pkt_nm->tx_desc_ring[i].desc[j] != NULL) {
- nm_close(pkt_nm->tx_desc_ring[i].desc[j]);
- pkt_nm->tx_desc_ring[i].desc[j] = NULL;
- }
- }
- }
-
- pkt_nm->num_rx_desc_rings = 0;
- pkt_nm->num_tx_desc_rings = 0;
-}
-
-static int netmap_close(pktio_entry_t *pktio_entry)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
-
- netmap_close_descriptors(pktio_entry);
-
- if (pkt_nm->sockfd != -1 && close(pkt_nm->sockfd) != 0) {
- _odp_errno = errno;
- _ODP_ERR("close(sockfd): %s\n", strerror(errno));
- return -1;
- }
- return 0;
-}
-
-static int netmap_link_status(pktio_entry_t *pktio_entry)
-{
- if (pkt_priv(pktio_entry)->is_virtual)
- return ODP_PKTIO_LINK_STATUS_UP;
-
- return _odp_link_status_fd(pkt_priv(pktio_entry)->sockfd,
- pkt_priv(pktio_entry)->if_name);
-}
-
-static int netmap_link_info(pktio_entry_t *pktio_entry, odp_pktio_link_info_t *info)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
-
- if (pkt_nm->is_virtual) {
- memset(info, 0, sizeof(odp_pktio_link_info_t));
-
- info->autoneg = ODP_PKTIO_LINK_AUTONEG_OFF;
- info->duplex = ODP_PKTIO_LINK_DUPLEX_FULL;
- info->media = "virtual";
- info->pause_rx = ODP_PKTIO_LINK_PAUSE_OFF;
- info->pause_tx = ODP_PKTIO_LINK_PAUSE_OFF;
- info->speed = ODP_PKTIO_LINK_SPEED_UNKNOWN;
- info->status = ODP_PKTIO_LINK_STATUS_UP;
-
- return 0;
- }
-
- return _odp_link_info_fd(pkt_nm->sockfd, pkt_nm->if_name, info);
-}
-
-/**
- * Wait for netmap link to come up
- *
- * @param pktio_entry Packet IO entry
- *
- * @retval 1 link is up
- * @retval 0 link is down
- * @retval <0 on failure
- */
-static inline int netmap_wait_for_link(pktio_entry_t *pktio_entry)
-{
- int i;
- int ret;
-
- /* Wait for the link to come up */
- for (i = 0; i <= NM_WAIT_TIMEOUT; i++) {
- ret = netmap_link_status(pktio_entry);
- if (ret == -1)
- return -1;
- /* nm_open() causes the physical link to reset. When using a
- * direct attached loopback cable there may be a small delay
- * until the opposing end's interface comes back up again. In
- * this case without the additional sleep pktio validation
- * tests fail. */
- if (!pkt_priv(pktio_entry)->is_virtual)
- sleep(1);
- if (ret == 1)
- return 1;
- }
- _ODP_DBG("%s link is down\n", pkt_priv(pktio_entry)->if_name);
- return 0;
-}
-
-/**
- * Initialize netmap capability values
- *
- * @param pktio_entry Packet IO entry
- */
-static void netmap_init_capability(pktio_entry_t *pktio_entry)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- odp_pktio_capability_t *capa = &pktio_entry->capa;
-
- memset(capa, 0, sizeof(odp_pktio_capability_t));
-
- capa->max_input_queues = ODP_PKTIN_MAX_QUEUES;
- if (pkt_nm->num_rx_rings < ODP_PKTIN_MAX_QUEUES)
- capa->max_input_queues = pkt_nm->num_rx_rings;
- if (capa->max_input_queues > NM_MAX_DESC) {
- /* Have to use a single descriptor to fetch packets from all
- * netmap rings */
- capa->max_input_queues = 1;
- _ODP_DBG("Unable to store all %" PRIu32 " rx rings (max %d)\n"
- " max input queues: %u\n", pkt_nm->num_rx_rings,
- NM_MAX_DESC, capa->max_input_queues);
- }
-
- capa->max_output_queues = ODP_PKTOUT_MAX_QUEUES;
- if (pkt_nm->num_tx_rings < ODP_PKTOUT_MAX_QUEUES)
- capa->max_output_queues = pkt_nm->num_tx_rings;
- if (capa->max_output_queues > NM_MAX_DESC) {
- capa->max_output_queues = NM_MAX_DESC;
- _ODP_DBG("Unable to store all %" PRIu32 " tx rings (max %d)\n"
- " max output queues: %u\n", pkt_nm->num_tx_rings,
- NM_MAX_DESC, capa->max_output_queues);
- }
-
- capa->set_op.op.promisc_mode = 1;
- capa->set_op.op.maxlen = 1;
-
- capa->maxlen.equal = true;
- capa->maxlen.min_input = _ODP_SOCKET_MTU_MIN;
- capa->maxlen.max_input = pkt_nm->mtu_max;
- capa->maxlen.min_output = _ODP_SOCKET_MTU_MIN;
- capa->maxlen.max_output = pkt_nm->mtu_max;
-
- odp_pktio_config_init(&capa->config);
- capa->config.pktin.bit.ts_all = 1;
- capa->config.pktin.bit.ts_ptp = 1;
-
- capa->config.pktout.bit.ts_ena = 1;
-}
-
-/**
- * Open a netmap interface
- *
- * In addition to standard interfaces (with or without modified netmap drivers)
- * virtual VALE and pipe interfaces are also supported. These can be used for
- * example for testing packet IO functionality without any physical interfaces.
- *
- * To use virtual interfaces the 'netdev' device name has to begin with 'vale'
- * prefix. A valid VALE device name would be e.g. 'vale0'. Pipe device names
- * have to include also '{NN' (master) or '}NN' (slave) suffix. A valid pipe
- * master would be e.g. 'vale0{0' and a slave to the same pipe 'vale0}0'.
- *
- * Netmap requires standard interface names to begin with 'netmap:' prefix.
- * netmap_open() adds the prefix if it is missing. Virtual interfaces don't
- * require the 'netmap:' prefix.
- *
- * @param id Packet IO handle
- * @param pktio_entry Packet IO entry
- * @param netdev Packet IO device name
- * @param pool Default pool from which to allocate storage for packets
- *
- * @retval 0 on success
- * @retval <0 on failure
- */
-static int netmap_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
- const char *netdev, odp_pool_t pool)
-{
- int i;
- int err;
- int sockfd;
- const char *prefix;
- uint32_t mtu;
- uint32_t nm_buf_size;
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- struct nm_desc *desc;
- odp_pktin_hash_proto_t hash_proto;
- odp_pktio_stats_t cur_stats;
-
- if (disable_pktio)
- return -1;
-
- if (pool == ODP_POOL_INVALID)
- return -1;
-
- /* Init pktio entry */
- memset(pkt_nm, 0, sizeof(*pkt_nm));
- pkt_nm->sockfd = -1;
- pkt_nm->pool = pool;
-
- /* allow interface to be opened with or without the 'netmap:' prefix */
- prefix = "netmap:";
- if (strncmp(netdev, "netmap:", 7) == 0)
- netdev += 7;
- if (strncmp(netdev, "vale", 4) == 0) {
- pkt_nm->is_virtual = 1;
- prefix = "";
- }
-
- snprintf(pkt_nm->nm_name, sizeof(pkt_nm->nm_name), "%s%s", prefix,
- netdev);
- snprintf(pkt_nm->if_name, sizeof(pkt_nm->if_name), "%s", netdev);
-
- /* Initialize runtime options */
- if (init_options(pktio_entry)) {
- _ODP_ERR("Initializing runtime options failed\n");
- return -1;
- }
-
- /* Read netmap buffer size */
- nm_buf_size = read_netmap_buf_size();
- if (!nm_buf_size) {
- _ODP_ERR("Unable to read netmap buf size\n");
- return -1;
- }
- pkt_nm->mtu_max = _ODP_SOCKET_MTU_MAX;
- if (pkt_nm->mtu_max > nm_buf_size)
- pkt_nm->mtu_max = nm_buf_size;
-
- if (!pkt_nm->is_virtual) {
- sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- if (sockfd == -1) {
- _ODP_ERR("Cannot get device control socket\n");
- return -1;
- }
- pkt_nm->sockfd = sockfd;
-
- /* Use either interface MTU or netmap buffer size as MTU,
- * whichever is smaller. */
- mtu = _odp_mtu_get_fd(pkt_nm->sockfd, pkt_nm->if_name);
- if (mtu == 0) {
- _ODP_ERR("Unable to read interface MTU\n");
- goto error;
- }
- pkt_nm->mtu = (mtu < nm_buf_size) ? mtu : nm_buf_size;
-
- /* Netmap requires that interface MTU size <= nm buf size */
- if (mtu > nm_buf_size) {
- if (_odp_mtu_set_fd(pkt_nm->sockfd, pkt_nm->if_name,
- nm_buf_size)) {
- _ODP_ERR("Unable to set interface MTU\n");
- goto error;
- }
- }
- }
- /* Dummy open here to check if netmap module is available and to read
- * capability info. */
- desc = nm_open(pkt_nm->nm_name, NULL, 0, NULL);
- if (desc == NULL) {
- _ODP_ERR("nm_open(%s) failed\n", pkt_nm->nm_name);
- goto error;
- }
- pkt_nm->num_rx_rings = desc->nifp->ni_rx_rings;
- pkt_nm->num_tx_rings = desc->nifp->ni_tx_rings;
-
- netmap_init_capability(pktio_entry);
-
- nm_close(desc);
-
- for (i = 0; i < ODP_PKTIN_MAX_QUEUES; i++)
- odp_ticketlock_init(&pkt_nm->rx_desc_ring[i].lock);
-
- for (i = 0; i < ODP_PKTOUT_MAX_QUEUES; i++)
- odp_ticketlock_init(&pkt_nm->tx_desc_ring[i].lock);
-
- if (pkt_nm->is_virtual) {
- static unsigned int mac;
- uint32_t tid = syscall(SYS_gettid);
-
- if ((int)tid == -1)
- _ODP_DBG("Unable to fetch thread ID. VALE port MAC "
- "addresses may not be unique.\n");
-
- pktio_entry->capa.max_input_queues = 1;
- pktio_entry->capa.set_op.op.maxlen = 0;
- pktio_entry->capa.set_op.op.promisc_mode = 0;
- pkt_nm->mtu = nm_buf_size;
- pktio_entry->stats_type = STATS_UNSUPPORTED;
- /* Set MAC address for virtual interface */
- pkt_nm->if_mac[0] = 0x2;
- pkt_nm->if_mac[1] = (tid >> 24) & 0xff;
- pkt_nm->if_mac[2] = (tid >> 16) & 0xff;
- pkt_nm->if_mac[3] = (tid >> 8) & 0xff;
- pkt_nm->if_mac[4] = tid & 0xff;
- pkt_nm->if_mac[5] = ++mac;
-
- return 0;
- }
-
- /* Check if RSS is supported. If not, set 'max_input_queues' to 1. */
- if (_odp_rss_conf_get_supported_fd(pkt_nm->sockfd, netdev,
- &hash_proto) == 0) {
- _ODP_DBG("RSS not supported\n");
- pktio_entry->capa.max_input_queues = 1;
- }
-
- err = netmap_do_ioctl(pktio_entry, SIOCGIFFLAGS, 0);
- if (err)
- goto error;
- if ((pkt_nm->if_flags & IFF_UP) == 0)
- _ODP_DBG("%s is down\n", pkt_nm->if_name);
-
- err = _odp_mac_addr_get_fd(pkt_nm->sockfd, netdev, pkt_nm->if_mac);
- if (err)
- goto error;
-
- /* netmap uses only ethtool to get statistics counters */
- err = _odp_ethtool_stats_get_fd(pkt_nm->sockfd, pkt_nm->if_name, &cur_stats);
- if (err) {
- _ODP_DBG("netmap pktio %s does not support statistics counters\n",
- pkt_nm->if_name);
- pktio_entry->stats_type = STATS_UNSUPPORTED;
- } else {
- pktio_entry->stats_type = STATS_ETHTOOL;
- _odp_sock_stats_capa(pktio_entry, &pktio_entry->capa);
- }
-
- (void)netmap_stats_reset(pktio_entry);
-
- return 0;
-
-error:
- netmap_close(pktio_entry);
- return -1;
-}
-
-static int netmap_start(pktio_entry_t *pktio_entry)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- netmap_ring_t *desc_ring;
- struct nm_desc *desc_ptr;
- unsigned int i;
- unsigned int j;
- unsigned int num_rx_desc = 0;
- uint64_t flags;
- odp_pktin_mode_t in_mode = pktio_entry->param.in_mode;
- odp_pktout_mode_t out_mode = pktio_entry->param.out_mode;
-
- /* If no pktin/pktout queues have been configured. Configure one
- * for each direction. */
- if (!pktio_entry->num_in_queue &&
- in_mode != ODP_PKTIN_MODE_DISABLED) {
- odp_pktin_queue_param_t param;
-
- odp_pktin_queue_param_init(&param);
- param.num_queues = 1;
- if (odp_pktin_queue_config(pktio_entry->handle, &param))
- return -1;
- }
- if (!pktio_entry->num_out_queue &&
- out_mode == ODP_PKTOUT_MODE_DIRECT) {
- odp_pktout_queue_param_t param;
-
- odp_pktout_queue_param_init(&param);
- param.num_queues = 1;
- if (odp_pktout_queue_config(pktio_entry->handle, &param))
- return -1;
- }
-
- if (pkt_nm->num_rx_desc_rings == pktio_entry->num_in_queue &&
- pkt_nm->num_tx_desc_rings == pktio_entry->num_out_queue)
- return (netmap_wait_for_link(pktio_entry) == 1) ? 0 : -1;
-
- netmap_close_descriptors(pktio_entry);
-
- /* Map pktin/pktout queues to netmap rings */
- if (pktio_entry->num_in_queue) {
- /* In single queue case only one netmap descriptor is
- * required. */
- num_rx_desc = (pktio_entry->num_in_queue == 1) ? 1 :
- pkt_nm->num_rx_rings;
-
- map_netmap_rings(pkt_nm->rx_desc_ring,
- pktio_entry->num_in_queue, num_rx_desc);
- }
- if (pktio_entry->num_out_queue)
- /* Enough to map only one netmap tx ring per pktout queue */
- map_netmap_rings(pkt_nm->tx_desc_ring,
- pktio_entry->num_out_queue,
- pktio_entry->num_out_queue);
-
- /* Use nm_open() to parse netmap flags from interface name */
- desc_ptr = nm_open(pkt_nm->nm_name, NULL, 0, NULL);
- if (desc_ptr == NULL) {
- _ODP_ERR("nm_start(%s) failed\n", pkt_nm->nm_name);
- goto error;
- }
- struct nm_desc base_desc = *desc_ptr;
-
- nm_close(desc_ptr);
-
- base_desc.self = &base_desc;
- base_desc.mem = NULL;
- if (pkt_priv(pktio_entry)->is_virtual) {
- base_desc.req.nr_rx_slots =
- pkt_priv(pktio_entry)->opt.nr_rx_slots;
- base_desc.req.nr_tx_slots =
- pkt_priv(pktio_entry)->opt.nr_tx_slots;
- }
- base_desc.req.nr_ringid = 0;
- if ((base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ALL_NIC ||
- (base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ONE_NIC) {
- base_desc.req.nr_flags &= ~NR_REG_MASK;
- if (num_rx_desc == 1)
- base_desc.req.nr_flags |= NR_REG_ALL_NIC;
- else
- base_desc.req.nr_flags |= NR_REG_ONE_NIC;
- }
-
- /* Only the first rx descriptor does mmap */
- desc_ring = pkt_nm->rx_desc_ring;
- flags = NM_OPEN_IFNAME | NETMAP_NO_TX_POLL;
- if (pkt_priv(pktio_entry)->is_virtual)
- flags |= NM_OPEN_RING_CFG;
- desc_ring[0].desc[0] = nm_open(pkt_nm->nm_name, NULL, flags,
- &base_desc);
- if (desc_ring[0].desc[0] == NULL) {
- _ODP_ERR("nm_start(%s) failed\n", pkt_nm->nm_name);
- goto error;
- }
- /* Open rest of the rx descriptors (one per netmap ring) */
- flags = NM_OPEN_IFNAME | NETMAP_NO_TX_POLL | NM_OPEN_NO_MMAP;
- if (pkt_priv(pktio_entry)->is_virtual)
- flags |= NM_OPEN_RING_CFG;
- for (i = 0; i < pktio_entry->num_in_queue; i++) {
- for (j = desc_ring[i].first; j <= desc_ring[i].last; j++) {
- if (i == 0 && j == 0) { /* First already opened */
- if (num_rx_desc > 1)
- continue;
- else
- break;
- }
- base_desc.req.nr_ringid = j;
- desc_ring[i].desc[j] = nm_open(pkt_nm->nm_name, NULL,
- flags, &base_desc);
- if (desc_ring[i].desc[j] == NULL) {
- _ODP_ERR("nm_start(%s) failed\n", pkt_nm->nm_name);
- goto error;
- }
- }
- }
- /* Open tx descriptors */
- desc_ring = pkt_nm->tx_desc_ring;
- flags = NM_OPEN_IFNAME | NM_OPEN_NO_MMAP;
- if (pkt_priv(pktio_entry)->is_virtual)
- flags |= NM_OPEN_RING_CFG;
-
- if ((base_desc.req.nr_flags & NR_REG_MASK) == NR_REG_ALL_NIC) {
- base_desc.req.nr_flags &= ~NR_REG_ALL_NIC;
- base_desc.req.nr_flags |= NR_REG_ONE_NIC;
- }
-
- for (i = 0; i < pktio_entry->num_out_queue; i++) {
- for (j = desc_ring[i].first; j <= desc_ring[i].last; j++) {
- base_desc.req.nr_ringid = j;
- desc_ring[i].desc[j] = nm_open(pkt_nm->nm_name, NULL,
- flags, &base_desc);
- if (desc_ring[i].desc[j] == NULL) {
- _ODP_ERR("nm_start(%s) failed\n", pkt_nm->nm_name);
- goto error;
- }
- }
- }
- pkt_nm->num_rx_desc_rings = pktio_entry->num_in_queue;
- pkt_nm->num_tx_desc_rings = pktio_entry->num_out_queue;
- /* Wait for the link to come up */
- return (netmap_wait_for_link(pktio_entry) == 1) ? 0 : -1;
-
-error:
- netmap_close_descriptors(pktio_entry);
- return -1;
-}
-
-static int netmap_stop(pktio_entry_t *pktio_entry ODP_UNUSED)
-{
- return 0;
-}
-
-/**
- * Create ODP packets from netmap packets
- *
- * @param pktio_entry Packet IO entry
- * @param pkt_tbl Array for new ODP packet handles
- * @param slot_tbl Array of netmap ring slots
- * @param slot_num Number of netmap ring slots
- * @param ts Pointer to pktin timestamp
- *
- * @retval Number of created packets
- */
-static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry,
- odp_packet_t pkt_tbl[],
- netmap_slot_t slot_tbl[], int16_t slot_num,
- odp_time_t *ts)
-{
- odp_packet_t pkt;
- odp_pool_t pool = pkt_priv(pktio_entry)->pool;
- odp_packet_hdr_t *pkt_hdr;
- int i;
- int num;
- uint32_t max_len;
- uint16_t frame_offset = pktio_entry->pktin_frame_offset;
- int num_rx = 0;
- const odp_proto_layer_t layer = pktio_entry->parse_layer;
- const odp_pktin_config_opt_t opt = pktio_entry->config.pktin;
-
- /* Allocate maximum sized packets */
- max_len = pkt_priv(pktio_entry)->mtu;
-
- num = _odp_packet_alloc_multi(pool, max_len + frame_offset,
- pkt_tbl, slot_num);
-
- for (i = 0; i < num; i++) {
- netmap_slot_t slot;
- uint16_t len;
- const uint8_t *buf;
-
- slot = slot_tbl[i];
- len = slot.len;
- buf = (const uint8_t *)slot.buf;
-
- odp_prefetch(slot.buf);
-
- pkt = pkt_tbl[i];
- pkt_hdr = packet_hdr(pkt);
-
- pull_tail(pkt_hdr, max_len - len);
- if (frame_offset)
- pull_head(pkt_hdr, frame_offset);
-
- if (odp_packet_copy_from_mem(pkt, 0, len, slot.buf) != 0) {
- odp_packet_free(pkt);
- continue;
- }
-
- if (layer) {
- int ret;
-
- ret = _odp_packet_parse_common(pkt_hdr, buf, len, len,
- layer, opt);
- if (ret)
- odp_atomic_inc_u64(&pktio_entry->stats_extra.in_errors);
-
- if (ret < 0) {
- odp_packet_free(pkt);
- continue;
- }
-
- if (pktio_cls_enabled(pktio_entry)) {
- odp_pool_t new_pool;
-
- ret = _odp_cls_classify_packet(pktio_entry, buf,
- &new_pool, pkt_hdr);
- if (ret < 0)
- odp_atomic_inc_u64(&pktio_entry->stats_extra.in_discards);
-
- if (ret) {
- odp_packet_free(pkt);
- continue;
- }
-
- if (odp_unlikely(_odp_pktio_packet_to_pool(
- &pkt, &pkt_hdr, new_pool))) {
- odp_packet_free(pkt);
- odp_atomic_inc_u64(&pktio_entry->stats_extra.in_discards);
- continue;
- }
- }
- }
-
- pkt_hdr->input = pktio_entry->handle;
- packet_set_ts(pkt_hdr, ts);
-
- pkt_tbl[num_rx++] = pkt;
- }
-
- return num_rx;
-}
-
-static inline int netmap_recv_desc(pktio_entry_t *pktio_entry,
- struct nm_desc *desc,
- odp_packet_t pkt_table[], int num)
-{
- struct netmap_ring *ring;
- odp_time_t ts_val;
- odp_time_t *ts = NULL;
- netmap_slot_t slot_tbl[num];
- char *buf;
- uint32_t slot_id;
- uint32_t mtu = pkt_priv(pktio_entry)->mtu;
- int i;
- int ring_id = desc->cur_rx_ring;
- int num_rx = 0;
- int num_rings = desc->last_rx_ring - desc->first_rx_ring + 1;
-
- if (pktio_entry->config.pktin.bit.ts_all ||
- pktio_entry->config.pktin.bit.ts_ptp)
- ts = &ts_val;
-
- for (i = 0; i < num_rings && num_rx != num; i++) {
- if (ring_id > desc->last_rx_ring)
- ring_id = desc->first_rx_ring;
-
- ring = NETMAP_RXRING(desc->nifp, ring_id);
-
- while (!nm_ring_empty(ring) && num_rx != num) {
- slot_id = ring->cur;
- buf = NETMAP_BUF(ring, ring->slot[slot_id].buf_idx);
-
- if (odp_likely(ring->slot[slot_id].len <= mtu)) {
- slot_tbl[num_rx].buf = buf;
- slot_tbl[num_rx].len = ring->slot[slot_id].len;
- num_rx++;
- } else {
- _ODP_DBG("Dropped oversized packet: %" PRIu16 " "
- "B\n", ring->slot[slot_id].len);
- }
- ring->cur = nm_ring_next(ring, slot_id);
- ring->head = ring->cur;
- }
- ring_id++;
- }
- desc->cur_rx_ring = ring_id;
-
- if (num_rx) {
- if (ts != NULL)
- ts_val = odp_time_global();
- return netmap_pkt_to_odp(pktio_entry, pkt_table, slot_tbl,
- num_rx, ts);
- }
- return 0;
-}
-
-static int netmap_fd_set(pktio_entry_t *pktio_entry, int index, fd_set *readfds)
-{
- struct nm_desc *desc;
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- unsigned int first_desc_id = pkt_nm->rx_desc_ring[index].first;
- unsigned int last_desc_id = pkt_nm->rx_desc_ring[index].last;
- unsigned int desc_id;
- int num_desc = pkt_nm->rx_desc_ring[index].num;
- int i;
- int max_fd = 0;
-
- if (!pkt_nm->lockless_rx)
- odp_ticketlock_lock(&pkt_nm->rx_desc_ring[index].lock);
-
- desc_id = pkt_nm->rx_desc_ring[index].cur;
-
- for (i = 0; i < num_desc; i++) {
- if (desc_id > last_desc_id)
- desc_id = first_desc_id;
-
- desc = pkt_nm->rx_desc_ring[index].desc[desc_id];
-
- FD_SET(desc->fd, readfds);
- if (desc->fd > max_fd)
- max_fd = desc->fd;
- desc_id++;
- }
- pkt_nm->rx_desc_ring[index].cur = desc_id;
-
- if (!pkt_nm->lockless_rx)
- odp_ticketlock_unlock(&pkt_nm->rx_desc_ring[index].lock);
-
- return max_fd;
-}
-
-static int netmap_recv(pktio_entry_t *pktio_entry, int index,
- odp_packet_t pkt_table[], int num)
-{
- struct nm_desc *desc;
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- unsigned int first_desc_id = pkt_nm->rx_desc_ring[index].first;
- unsigned int last_desc_id = pkt_nm->rx_desc_ring[index].last;
- unsigned int desc_id;
- int num_desc = pkt_nm->rx_desc_ring[index].num;
- int i;
- int num_rx = 0;
- int max_fd = 0;
- fd_set empty_rings;
-
- FD_ZERO(&empty_rings);
-
- if (!pkt_nm->lockless_rx)
- odp_ticketlock_lock(&pkt_nm->rx_desc_ring[index].lock);
-
- desc_id = pkt_nm->rx_desc_ring[index].cur;
-
- for (i = 0; i < num_desc && num_rx != num; i++) {
- if (desc_id > last_desc_id)
- desc_id = first_desc_id;
-
- desc = pkt_nm->rx_desc_ring[index].desc[desc_id];
-
- num_rx += netmap_recv_desc(pktio_entry, desc,
- &pkt_table[num_rx], num - num_rx);
-
- if (num_rx != num) {
- FD_SET(desc->fd, &empty_rings);
- if (desc->fd > max_fd)
- max_fd = desc->fd;
- }
- desc_id++;
- }
- pkt_nm->rx_desc_ring[index].cur = desc_id;
-
- if (num_rx != num) {
- struct timeval tout = {.tv_sec = 0, .tv_usec = 0};
-
- if (select(max_fd + 1, &empty_rings, NULL, NULL, &tout) == -1)
- _ODP_ERR("RX: select error\n");
- }
- if (!pkt_nm->lockless_rx)
- odp_ticketlock_unlock(&pkt_nm->rx_desc_ring[index].lock);
-
- return num_rx;
-}
-
-static int netmap_recv_tmo(pktio_entry_t *pktio_entry, int index,
- odp_packet_t pkt_table[], int num, uint64_t usecs)
-{
- struct timeval timeout;
- int ret;
- int maxfd;
- fd_set readfds;
-
- ret = netmap_recv(pktio_entry, index, pkt_table, num);
- if (ret != 0)
- return ret;
-
- timeout.tv_sec = usecs / (1000 * 1000);
- timeout.tv_usec = usecs - timeout.tv_sec * (1000ULL * 1000ULL);
- FD_ZERO(&readfds);
- maxfd = netmap_fd_set(pktio_entry, index, &readfds);
-
- if (select(maxfd + 1, &readfds, NULL, NULL, &timeout) == 0)
- return 0;
-
- return netmap_recv(pktio_entry, index, pkt_table, num);
-}
-
-static int netmap_recv_mq_tmo(pktio_entry_t *pktio_entry[], int index[],
- uint32_t num_q, odp_packet_t pkt_table[], int num,
- uint32_t *from, uint64_t usecs)
-{
- struct timeval timeout;
- uint32_t i;
- int ret;
- int maxfd = -1, maxfd2;
- fd_set readfds;
-
- for (i = 0; i < num_q; i++) {
- ret = netmap_recv(pktio_entry[i], index[i], pkt_table, num);
-
- if (ret > 0 && from)
- *from = i;
-
- if (ret != 0)
- return ret;
- }
-
- FD_ZERO(&readfds);
-
- for (i = 0; i < num_q; i++) {
- maxfd2 = netmap_fd_set(pktio_entry[i], index[i], &readfds);
- if (maxfd2 > maxfd)
- maxfd = maxfd2;
- }
-
- timeout.tv_sec = usecs / (1000 * 1000);
- timeout.tv_usec = usecs - timeout.tv_sec * (1000ULL * 1000ULL);
-
- if (select(maxfd + 1, &readfds, NULL, NULL, &timeout) == 0)
- return 0;
-
- for (i = 0; i < num_q; i++) {
- ret = netmap_recv(pktio_entry[i], index[i], pkt_table, num);
-
- if (ret > 0 && from)
- *from = i;
-
- if (ret != 0)
- return ret;
- }
-
- return 0;
-}
-
-static int netmap_send(pktio_entry_t *pktio_entry, int index,
- const odp_packet_t pkt_table[], int num)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- struct pollfd polld;
- struct nm_desc *desc;
- struct netmap_ring *ring;
- int i;
- int nb_tx;
- int desc_id;
- int tx_ts_idx = 0;
- uint8_t tx_ts_enabled = _odp_pktio_tx_ts_enabled(pktio_entry);
- odp_packet_t pkt;
- uint32_t pkt_len;
- unsigned int slot_id;
- char *buf;
-
- /* Only one netmap tx ring per pktout queue */
- desc_id = pkt_nm->tx_desc_ring[index].cur;
- desc = pkt_nm->tx_desc_ring[index].desc[desc_id];
- ring = NETMAP_TXRING(desc->nifp, desc->cur_tx_ring);
-
- if (!pkt_nm->lockless_tx)
- odp_ticketlock_lock(&pkt_nm->tx_desc_ring[index].lock);
-
- polld.fd = desc->fd;
- polld.events = POLLOUT;
-
- for (nb_tx = 0; nb_tx < num; nb_tx++) {
- pkt = pkt_table[nb_tx];
- pkt_len = odp_packet_len(pkt);
-
- if (pkt_len > pkt_nm->mtu) {
- if (nb_tx == 0)
- _odp_errno = EMSGSIZE;
- break;
- }
- for (i = 0; i < NM_INJECT_RETRIES; i++) {
- if (nm_ring_empty(ring)) {
- poll(&polld, 1, 0);
- continue;
- }
- slot_id = ring->cur;
- ring->slot[slot_id].flags = 0;
- ring->slot[slot_id].len = pkt_len;
-
- buf = NETMAP_BUF(ring, ring->slot[slot_id].buf_idx);
-
- if (odp_packet_copy_to_mem(pkt, 0, pkt_len, buf)) {
- i = NM_INJECT_RETRIES;
- break;
- }
- ring->cur = nm_ring_next(ring, slot_id);
- ring->head = ring->cur;
- break;
- }
- if (i == NM_INJECT_RETRIES)
- break;
-
- if (tx_ts_enabled && tx_ts_idx == 0) {
- if (odp_unlikely(packet_hdr(pkt)->p.flags.ts_set))
- tx_ts_idx = i + 1;
- }
- }
- /* Send pending packets */
- poll(&polld, 1, 0);
-
- if (!pkt_nm->lockless_tx)
- odp_ticketlock_unlock(&pkt_nm->tx_desc_ring[index].lock);
-
- if (odp_unlikely(nb_tx == 0)) {
- if (_odp_errno != 0)
- return -1;
- } else {
- if (odp_unlikely(tx_ts_idx && nb_tx >= tx_ts_idx))
- _odp_pktio_tx_ts_set(pktio_entry);
-
- odp_packet_free_multi(pkt_table, nb_tx);
- }
-
- return nb_tx;
-}
-
-static int netmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
-{
- memcpy(mac_addr, pkt_priv(pktio_entry)->if_mac, ETH_ALEN);
- return ETH_ALEN;
-}
-
-static uint32_t netmap_mtu_get(pktio_entry_t *pktio_entry)
-{
- return pkt_priv(pktio_entry)->mtu;
-}
-
-static int netmap_mtu_set(pktio_entry_t *pktio_entry, uint32_t maxlen_input,
- uint32_t maxlen_output ODP_UNUSED)
-{
- pkt_netmap_t *pkt_nm = pkt_priv(pktio_entry);
- int ret;
-
- ret = _odp_mtu_set_fd(pkt_nm->sockfd, pktio_entry->name, maxlen_input);
- if (ret)
- return ret;
-
- pkt_nm->mtu = maxlen_input;
-
- return 0;
-}
-
-static int netmap_promisc_mode_set(pktio_entry_t *pktio_entry,
- odp_bool_t enable)
-{
- if (pkt_priv(pktio_entry)->is_virtual) {
- _odp_errno = ENOTSUP;
- return -1;
- }
-
- return _odp_promisc_mode_set_fd(pkt_priv(pktio_entry)->sockfd,
- pkt_priv(pktio_entry)->if_name, enable);
-}
-
-static int netmap_promisc_mode_get(pktio_entry_t *pktio_entry)
-{
- if (pkt_priv(pktio_entry)->is_virtual)
- return 0;
-
- return _odp_promisc_mode_get_fd(pkt_priv(pktio_entry)->sockfd,
- pkt_priv(pktio_entry)->if_name);
-}
-
-static int netmap_capability(pktio_entry_t *pktio_entry,
- odp_pktio_capability_t *capa)
-{
- *capa = pktio_entry->capa;
- return 0;
-}
-
-static int netmap_stats(pktio_entry_t *pktio_entry,
- odp_pktio_stats_t *stats)
-{
- return _odp_sock_stats_fd(pktio_entry,
- stats,
- pkt_priv(pktio_entry)->sockfd);
-}
-
-static int netmap_stats_reset(pktio_entry_t *pktio_entry)
-{
- return _odp_sock_stats_reset_fd(pktio_entry,
- pkt_priv(pktio_entry)->sockfd);
-}
-
-static int netmap_extra_stat_info(pktio_entry_t *pktio_entry,
- odp_pktio_extra_stat_info_t info[], int num)
-{
- return _odp_sock_extra_stat_info(pktio_entry, info, num,
- pkt_priv(pktio_entry)->sockfd);
-}
-
-static int netmap_extra_stats(pktio_entry_t *pktio_entry, uint64_t stats[],
- int num)
-{
- return _odp_sock_extra_stats(pktio_entry, stats, num,
- pkt_priv(pktio_entry)->sockfd);
-}
-
-static int netmap_extra_stat_counter(pktio_entry_t *pktio_entry, uint32_t id,
- uint64_t *stat)
-{
- return _odp_sock_extra_stat_counter(pktio_entry, id, stat,
- pkt_priv(pktio_entry)->sockfd);
-}
-
-static void netmap_print(pktio_entry_t *pktio_entry)
-{
- odp_pktin_hash_proto_t hash_proto;
-
- if (_odp_rss_conf_get_fd(pkt_priv(pktio_entry)->sockfd,
- pkt_priv(pktio_entry)->if_name, &hash_proto))
- _odp_rss_conf_print(&hash_proto);
-}
-
-static int netmap_init_global(void)
-{
- if (getenv("ODP_PKTIO_DISABLE_NETMAP")) {
- _ODP_PRINT("PKTIO: netmap pktio skipped,"
- " enabled export ODP_PKTIO_DISABLE_NETMAP=1.\n");
- disable_pktio = 1;
- } else {
- _ODP_PRINT("PKTIO: initialized netmap pktio,"
- " use export ODP_PKTIO_DISABLE_NETMAP=1 to disable.\n"
- " Netmap prefixes are netmap:eth0 or vale:eth0. Refer to"
- " Netmap documentation for usage information.\n");
- }
- return 0;
-}
-
-const pktio_if_ops_t _odp_netmap_pktio_ops = {
- .name = "netmap",
- .print = netmap_print,
- .init_global = netmap_init_global,
- .init_local = NULL,
- .term = NULL,
- .open = netmap_open,
- .close = netmap_close,
- .start = netmap_start,
- .stop = netmap_stop,
- .link_status = netmap_link_status,
- .link_info = netmap_link_info,
- .stats = netmap_stats,
- .stats_reset = netmap_stats_reset,
- .extra_stat_info = netmap_extra_stat_info,
- .extra_stats = netmap_extra_stats,
- .extra_stat_counter = netmap_extra_stat_counter,
- .maxlen_get = netmap_mtu_get,
- .maxlen_set = netmap_mtu_set,
- .promisc_mode_set = netmap_promisc_mode_set,
- .promisc_mode_get = netmap_promisc_mode_get,
- .mac_get = netmap_mac_addr_get,
- .mac_set = NULL,
- .capability = netmap_capability,
- .pktio_ts_res = NULL,
- .pktio_ts_from_ns = NULL,
- .pktio_time = NULL,
- .config = NULL,
- .input_queues_config = netmap_input_queues_config,
- .output_queues_config = netmap_output_queues_config,
- .recv = netmap_recv,
- .recv_tmo = netmap_recv_tmo,
- .recv_mq_tmo = netmap_recv_mq_tmo,
- .send = netmap_send,
- .fd_set = netmap_fd_set
-};
-#else /* _ODP_PKTIO_NETMAP */
-/* Avoid warning about empty translation unit */
-typedef int _odp_dummy;
-#endif
diff --git a/platform/linux-generic/pktio/socket_common.c b/platform/linux-generic/pktio/socket_common.c
index b6ae7b9ae..d7c320a54 100644
--- a/platform/linux-generic/pktio/socket_common.c
+++ b/platform/linux-generic/pktio/socket_common.c
@@ -46,7 +46,6 @@ struct ethtool_link_settings {
/**
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
*/
int _odp_mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[])
{
@@ -70,7 +69,6 @@ int _odp_mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[])
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
* ODP_PACKET_TAP:
*/
uint32_t _odp_mtu_get_fd(int fd, const char *name)
@@ -91,7 +89,6 @@ uint32_t _odp_mtu_get_fd(int fd, const char *name)
/*
* ODP_PACKET_SOCKET_MMAP:
* ODP_PACKET_SOCKET_MMSG:
- * ODP_PACKET_NETMAP:
* ODP_PACKET_TAP:
*/
int _odp_mtu_set_fd(int fd, const char *name, int mtu)
@@ -114,7 +111,6 @@ int _odp_mtu_set_fd(int fd, const char *name, int mtu)
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
*/
int _odp_promisc_mode_set_fd(int fd, const char *name, int enable)
{
@@ -146,7 +142,6 @@ int _odp_promisc_mode_set_fd(int fd, const char *name, int enable)
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
- * ODP_PACKET_NETMAP:
*/
int _odp_promisc_mode_get_fd(int fd, const char *name)
{
diff --git a/platform/linux-generic/test/Makefile.am b/platform/linux-generic/test/Makefile.am
index 06e5a3ba2..99d7199ad 100644
--- a/platform/linux-generic/test/Makefile.am
+++ b/platform/linux-generic/test/Makefile.am
@@ -23,9 +23,6 @@ SUBDIRS += validation/api/pktio\
if ODP_PKTIO_PCAP
TESTS += validation/api/pktio/pktio_run_pcap.sh
endif
-if netmap_support
-TESTS += validation/api/pktio/pktio_run_netmap.sh
-endif
if PKTIO_DPDK
TESTS += validation/api/pktio/pktio_run_dpdk.sh
endif
diff --git a/platform/linux-generic/test/validation/api/pktio/Makefile.am b/platform/linux-generic/test/validation/api/pktio/Makefile.am
index 98b8b233d..1646743fe 100644
--- a/platform/linux-generic/test/validation/api/pktio/Makefile.am
+++ b/platform/linux-generic/test/validation/api/pktio/Makefile.am
@@ -5,9 +5,6 @@ dist_check_SCRIPTS = pktio_env \
if ODP_PKTIO_PCAP
dist_check_SCRIPTS += pktio_run_pcap.sh
endif
-if netmap_support
-dist_check_SCRIPTS += pktio_run_netmap.sh
-endif
if PKTIO_DPDK
dist_check_SCRIPTS += pktio_run_dpdk.sh
endif
diff --git a/platform/linux-generic/test/validation/api/pktio/pktio_run.sh b/platform/linux-generic/test/validation/api/pktio/pktio_run.sh
index 9820ca339..cac297768 100755
--- a/platform/linux-generic/test/validation/api/pktio/pktio_run.sh
+++ b/platform/linux-generic/test/validation/api/pktio/pktio_run.sh
@@ -62,9 +62,6 @@ run_test()
unset ODP_PKTIO_DISABLE_SOCKET_${distype}
done
- # this script doesn't support testing with netmap
- export ODP_PKTIO_DISABLE_NETMAP=y
-
for distype in SKIP MMAP; do
if [ "$disabletype" != "SKIP" ]; then
export ODP_PKTIO_DISABLE_SOCKET_${distype}=y
diff --git a/platform/linux-generic/test/validation/api/pktio/pktio_run_netmap.sh b/platform/linux-generic/test/validation/api/pktio/pktio_run_netmap.sh
deleted file mode 100755
index f4851483b..000000000
--- a/platform/linux-generic/test/validation/api/pktio/pktio_run_netmap.sh
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2016-2018, Linaro Limited
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-# any parameter passed as arguments to this script is passed unchanged to
-# the test itself (pktio_main)
-
-# directories where pktio_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 (./pktio_run) intree.
-# -in the current directory.
-# running stand alone out of tree requires setting PATH
-PATH=${TEST_DIR}/api/pktio:$PATH
-PATH=$(dirname $0):$PATH
-PATH=$(dirname $0)/../../../../../../test/validation/api/pktio:$PATH
-PATH=.:$PATH
-
-pktio_main_path=$(which pktio_main${EXEEXT})
-if [ -x "$pktio_main_path" ] ; then
- echo "running with pktio_main: $pktio_main_path"
-else
- echo "cannot find pktio_main: please set you PATH for it."
-fi
-
-# directory where platform test sources are, including scripts
-TEST_SRC_DIR=$(dirname $0)
-
-# exit codes expected by automake for skipped tests
-TEST_SKIPPED=77
-
-# Use installed pktio env or for make check take it from the test directory
-if [ -f "./pktio_env" ]; then
- . ./pktio_env
-elif [ -f ${TEST_SRC_DIR}/pktio_env ]; then
- . ${TEST_SRC_DIR}/pktio_env
-else
- echo "ERROR: unable to find pktio_env!"
- echo "pktio_env has to be in current directory or in ${TEST_SRC_DIR}"
- exit 1
-fi
-
-run_test()
-{
- local ret=0
-
- pktio_main${EXEEXT} $*
- ret=$?
-
- if [ $ret -ne 0 ]; then
- echo "!!! FAILED !!!"
- fi
-
- return $ret
-}
-
-run_test_vale()
-{
- # use two vale ports on the same switch
- export ODP_PKTIO_IF0=valetest:0
- export ODP_PKTIO_IF1=valetest:1
- run_test
- return $?
-}
-
-run_test_pipe()
-{
- # use a netmap pipe
- export ODP_PKTIO_IF0=valetest:0{0
- export ODP_PKTIO_IF1=valetest:0}0
- run_test
- return $?
-}
-
-run_test_veth()
-{
- if [ "$(lsmod | grep veth)" = "" ]; then
- echo "netmap enabled veth module not loaded, skipping test."
- return 0
- fi
-
- setup_pktio_env clean
- export ODP_PKTIO_IF0=netmap:$IF0
- export ODP_PKTIO_IF1=netmap:$IF1
- run_test
- return $?
-}
-
-run()
-{
- local ret=0
-
- # need to be root to run these tests
- if [ "$(id -u)" != "0" ]; then
- echo "netmap tests must be run as root, skipping test."
- exit $TEST_SKIPPED
- fi
-
- if [ "$(lsmod | grep netmap)" = "" ]; then
- echo "netmap kernel module not loaded, skipping test."
- exit $TEST_SKIPPED
- fi
-
- if [ "$ODP_PKTIO_IF0" != "" ]; then
- run_test
- ret=$?
- else
- run_test_vale
- r=$?; [ $ret = 0 ] && ret=$r
- run_test_pipe
- r=$?; [ $ret = 0 ] && ret=$r
- run_test_veth
- r=$?; [ $ret = 0 ] && ret=$r
- fi
-
- exit $ret
-}
-
-run