aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2015-10-05 18:12:19 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-10-08 13:43:07 +0300
commit7082b5fb21c944afa3bac54106001eca714d0058 (patch)
treecf1b016b2d2b12cb827c55b32e03a9cd5955b5e3
parentac20026ffdbbb07b46bf81bb2449e83301284145 (diff)
linux-generic: pktio: add netmap pktio support
Added new netmap pktio interface type which operates in the same manner as the existing socket io interfaces. The code is based on the odp-netmap branch. Using netmap io requires netmap headers and loaded netmap kernel module. Netmap can be installed from https://github.com/luigirizzo/netmap. ODP netmap support is enabled using --with-netmap-path=<netmap_dir> configuration option. If netmap kernel module is loaded when starting ODP application netmap io will be used by default. If the module is not found standard socket io is used. Netmap io can be disabled with ODP_PKTIO_DISABLE_NETMAP environment variable. Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-and-tested by: Petri Savolainen <petri.savolainen@nokia.com> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
-rw-r--r--configure.ac2
-rw-r--r--example/generator/odp_generator.c3
-rw-r--r--example/ipsec/odp_ipsec.c3
-rw-r--r--example/packet/odp_pktio.c3
-rw-r--r--platform/linux-generic/Makefile.am2
-rw-r--r--platform/linux-generic/include/odp_packet_io_internal.h3
-rw-r--r--platform/linux-generic/include/odp_packet_netmap.h24
-rw-r--r--platform/linux-generic/m4/configure.m41
-rw-r--r--platform/linux-generic/m4/odp_netmap.m450
-rw-r--r--platform/linux-generic/pktio/io_ops.c3
-rw-r--r--platform/linux-generic/pktio/netmap.c303
-rw-r--r--platform/linux-generic/pktio/socket.c4
-rw-r--r--test/performance/odp_l2fwd.c3
13 files changed, 400 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 15dc6cf..92f9d39 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,8 @@ 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"
+# Extra flags for example to suppress certain warning types
+ODP_CFLAGS="$ODP_CFLAGS $ODP_CFLAGS_EXTRA"
##########################################################################
# Default include setup
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index f4f6038..085902b 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -1114,7 +1114,8 @@ static void usage(char *progname)
"\n"
"Optional OPTIONS\n"
" -h, --help Display help and exit.\n"
- " environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
+ " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
+ " ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
" ODP_PKTIO_DISABLE_SOCKET_MMSG\n"
" can be used to advanced pkt I/O selection for linux-generic\n"
" -p, --packetsize payload length of the packets\n"
diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c
index 564d65e..6f5aae8 100644
--- a/example/ipsec/odp_ipsec.c
+++ b/example/ipsec/odp_ipsec.c
@@ -1577,7 +1577,8 @@ static void usage(char *progname)
"Optional OPTIONS\n"
" -c, --count <number> CPU count.\n"
" -h, --help Display help and exit.\n"
- " environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
+ " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
+ " ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
" ODP_PKTIO_DISABLE_SOCKET_MMSG\n"
" can be used to advanced pkt I/O selection for linux-generic\n"
" ODP_IPSEC_USE_POLL_QUEUES\n"
diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c
index 16d4533..de6e42b 100644
--- a/example/packet/odp_pktio.c
+++ b/example/packet/odp_pktio.c
@@ -700,7 +700,8 @@ static void usage(char *progname)
" 1: Receive and send via queues.\n"
" 2: Receive via scheduler, send via queues.\n"
" -h, --help Display help and exit.\n"
- " environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
+ " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
+ " ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
" ODP_PKTIO_DISABLE_SOCKET_MMSG\n"
" can be used to advanced pkt I/O selection for linux-generic\n"
"\n", NO_PATH(progname), NO_PATH(progname)
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 4c79730..2a71d32 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -127,6 +127,7 @@ noinst_HEADERS = \
${srcdir}/include/odp_packet_internal.h \
${srcdir}/include/odp_packet_io_internal.h \
${srcdir}/include/odp_packet_io_queue.h \
+ ${srcdir}/include/odp_packet_netmap.h \
${srcdir}/include/odp_packet_socket.h \
${srcdir}/include/odp_pool_internal.h \
${srcdir}/include/odp_queue_internal.h \
@@ -151,6 +152,7 @@ __LIB__libodp_la_SOURCES = \
odp_packet_io.c \
pktio/io_ops.c \
pktio/loop.c \
+ pktio/netmap.c \
pktio/socket.c \
pktio/socket_mmap.c \
odp_pool.c \
diff --git a/platform/linux-generic/include/odp_packet_io_internal.h b/platform/linux-generic/include/odp_packet_io_internal.h
index 60aca1c..353b40d 100644
--- a/platform/linux-generic/include/odp_packet_io_internal.h
+++ b/platform/linux-generic/include/odp_packet_io_internal.h
@@ -21,6 +21,7 @@ extern "C" {
#include <odp/spinlock.h>
#include <odp/ticketlock.h>
#include <odp_packet_socket.h>
+#include <odp_packet_netmap.h>
#include <odp_classification_datamodel.h>
#include <odp_align_internal.h>
#include <odp_debug_internal.h>
@@ -50,6 +51,7 @@ struct pktio_entry {
pkt_sock_t pkt_sock; /**< using socket API for IO */
pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap
* API for IO */
+ pkt_netmap_t pkt_nm; /**< using netmap API for IO */
};
enum {
STATE_START = 0,
@@ -122,6 +124,7 @@ static inline void pktio_cls_enabled_set(pktio_entry_t *entry, int ena)
int pktin_poll(pktio_entry_t *entry);
+extern const pktio_if_ops_t netmap_pktio_ops;
extern const pktio_if_ops_t sock_mmsg_pktio_ops;
extern const pktio_if_ops_t sock_mmap_pktio_ops;
extern const pktio_if_ops_t loopback_pktio_ops;
diff --git a/platform/linux-generic/include/odp_packet_netmap.h b/platform/linux-generic/include/odp_packet_netmap.h
new file mode 100644
index 0000000..23aea5b
--- /dev/null
+++ b/platform/linux-generic/include/odp_packet_netmap.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_PACKET_NETMAP_H
+#define ODP_PACKET_NETMAP_H
+
+#include <odp/pool.h>
+
+#include <linux/if_ether.h>
+
+/** Packet socket using netmap mmaped rings for both Rx and Tx */
+typedef struct {
+ odp_pool_t pool; /**< pool to alloc packets from */
+ size_t max_frame_len; /**< buf_size - sizeof(pkt_hdr) */
+ struct nm_desc *desc; /**< netmap meta-data for the device */
+ uint32_t if_flags; /**< interface flags */
+ int sockfd; /**< control socket */
+ unsigned char if_mac[ETH_ALEN]; /**< eth mac address */
+} pkt_netmap_t;
+
+#endif
diff --git a/platform/linux-generic/m4/configure.m4 b/platform/linux-generic/m4/configure.m4
index 9658274..f2d42f1 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -18,6 +18,7 @@ AC_LINK_IFELSE(
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_netmap.m4])
AC_CONFIG_FILES([platform/linux-generic/Makefile
platform/linux-generic/test/Makefile
diff --git a/platform/linux-generic/m4/odp_netmap.m4 b/platform/linux-generic/m4/odp_netmap.m4
new file mode 100644
index 0000000..02cd3d3
--- /dev/null
+++ b/platform/linux-generic/m4/odp_netmap.m4
@@ -0,0 +1,50 @@
+##########################################################################
+# Enable netmap support
+##########################################################################
+netmap_support=no
+AC_ARG_ENABLE([netmap_support],
+ [ --enable-netmap-support include netmap IO support],
+ [if test x$enableval = xyes; then
+ netmap_support=yes
+ fi])
+
+##########################################################################
+# Set optional netmap path
+##########################################################################
+AC_ARG_WITH([netmap-path],
+AC_HELP_STRING([--with-netmap-path=DIR path to netmap root directory],
+ [(or in the default path if not specified).]),
+ [NETMAP_PATH=$withval
+ AM_CPPFLAGS="$AM_CPPFLAGS -I$NETMAP_PATH/sys"
+ netmap_support=yes],[])
+
+##########################################################################
+# Save and set temporary compilation flags
+##########################################################################
+OLD_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$AM_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"])])
+ ODP_CFLAGS="$ODP_CFLAGS -DODP_NETMAP"
+else
+ netmap_support=no
+fi
+
+AM_CONDITIONAL([netmap_support], [test x$netmap_support = xyes ])
+
+# Disable cast errors until the problem in netmap_user.h is fixed upstream
+if test x$netmap_support = xyes
+then
+ODP_CFLAGS_EXTRA="$ODP_CFLAGS_EXTRA -Wno-cast-qual"
+fi
+
+##########################################################################
+# Restore old saved variables
+##########################################################################
+CPPFLAGS=$OLD_CPPFLAGS \ No newline at end of file
diff --git a/platform/linux-generic/pktio/io_ops.c b/platform/linux-generic/pktio/io_ops.c
index 1d47e74..bd4cc48 100644
--- a/platform/linux-generic/pktio/io_ops.c
+++ b/platform/linux-generic/pktio/io_ops.c
@@ -12,6 +12,9 @@
* Array must be NULL terminated */
const pktio_if_ops_t * const pktio_if_ops[] = {
&loopback_pktio_ops,
+#ifdef ODP_NETMAP
+ &netmap_pktio_ops,
+#endif
&sock_mmap_pktio_ops,
&sock_mmsg_pktio_ops,
NULL
diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
new file mode 100644
index 0000000..54e7043
--- /dev/null
+++ b/platform/linux-generic/pktio/netmap.c
@@ -0,0 +1,303 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef ODP_NETMAP
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <odp_packet_netmap.h>
+#include <odp_packet_socket.h>
+#include <odp_packet_io_internal.h>
+#include <odp_debug_internal.h>
+#include <odp/helper/eth.h>
+
+#include <sys/ioctl.h>
+#include <poll.h>
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+static struct nm_desc mmap_desc; /** Used to store the mmap address;
+ filled in first time, used for
+ subsequent calls to nm_open */
+
+#define NM_INJECT_RETRIES 10
+
+struct dispatch_args {
+ odp_packet_t *pkt_table;
+ unsigned nb_rx;
+ pktio_entry_t *pktio_entry;
+};
+
+static int netmap_do_ioctl(pktio_entry_t *pktio_entry, unsigned long cmd,
+ int subcmd)
+{
+ pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm;
+ 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",
+ pktio_entry->s.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;
+ default:
+ break;
+ }
+done:
+ if (err)
+ ODP_ERR("ioctl err %d %lu: %s\n", err, cmd, strerror(errno));
+
+ return err;
+}
+
+static int netmap_close(pktio_entry_t *pktio_entry)
+{
+ pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm;
+
+ if (pkt_nm->desc != NULL)
+ nm_close(pkt_nm->desc);
+
+ 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_open(odp_pktio_t id ODP_UNUSED, pktio_entry_t *pktio_entry,
+ const char *netdev, odp_pool_t pool)
+{
+ char ifname[IFNAMSIZ + 7]; /* netmap:<ifname> */
+ int err;
+ int sockfd;
+ pkt_netmap_t *pkt_nm = &pktio_entry->s.pkt_nm;
+
+ if (getenv("ODP_PKTIO_DISABLE_NETMAP"))
+ 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;
+
+ /* max frame len taking into account the l2-offset */
+ pkt_nm->max_frame_len = ODP_CONFIG_PACKET_BUF_LEN_MAX -
+ odp_buffer_pool_headroom(pool) -
+ odp_buffer_pool_tailroom(pool);
+
+ snprintf(pktio_entry->s.name, sizeof(pktio_entry->s.name), "%s",
+ netdev);
+ snprintf(ifname, sizeof(ifname), "netmap:%s", netdev);
+
+ if (mmap_desc.mem == NULL)
+ pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL, NULL);
+ else
+ pkt_nm->desc = nm_open(ifname, NULL, NETMAP_NO_TX_POLL |
+ NM_OPEN_NO_MMAP, &mmap_desc);
+ if (pkt_nm->desc == NULL) {
+ ODP_ERR("nm_open(%s) failed\n", ifname);
+ goto error;
+ }
+
+ if (mmap_desc.mem == NULL) {
+ mmap_desc.mem = pkt_nm->desc->mem;
+ mmap_desc.memsize = pkt_nm->desc->memsize;
+ }
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd == -1) {
+ ODP_ERR("Cannot get device control socket\n");
+ goto error;
+ }
+ pkt_nm->sockfd = sockfd;
+
+ 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", pktio_entry->s.name);
+
+ err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL, ETHTOOL_SGSO);
+ if (err)
+ ODP_DBG("ETHTOOL_SGSO not supported\n");
+
+ err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL, ETHTOOL_STSO);
+ if (err)
+ ODP_DBG("ETHTOOL_STSO not supported\n");
+
+ err = mac_addr_get_fd(sockfd, netdev, pkt_nm->if_mac);
+ if (err)
+ goto error;
+
+ err = netmap_do_ioctl(pktio_entry, SIOCETHTOOL, ETHTOOL_STXCSUM);
+ if (err)
+ ODP_DBG("ETHTOOL_STXCSUM not supported\n");
+
+ return 0;
+
+error:
+ netmap_close(pktio_entry);
+ return -1;
+}
+
+static void netmap_recv_cb(u_char *arg, const struct nm_pkthdr *hdr,
+ const u_char *buf)
+{
+ struct dispatch_args *args = (struct dispatch_args *)arg;
+ pkt_netmap_t *pkt_nm = &args->pktio_entry->s.pkt_nm;
+ odp_packet_t pkt;
+ size_t frame_len = (size_t)hdr->len;
+
+ if (odp_unlikely(frame_len > pkt_nm->max_frame_len)) {
+ ODP_ERR("RX: frame too big %u %lu!\n", (unsigned)frame_len,
+ pkt_nm->max_frame_len);
+ return;
+ }
+
+ if (odp_unlikely(frame_len < ODPH_ETH_LEN_MIN)) {
+ ODP_ERR("RX: Frame truncated: %u\n", (unsigned)frame_len);
+ return;
+ }
+
+ pkt = odp_packet_alloc(pkt_nm->pool, frame_len);
+ if (pkt == ODP_PACKET_INVALID)
+ return;
+
+ /* For now copy the data in the mbuf,
+ worry about zero-copy later */
+ if (odp_packet_copydata_in(pkt, 0, frame_len, buf) != 0) {
+ odp_packet_free(pkt);
+ return;
+ }
+
+ _odp_packet_reset_parse(pkt);
+
+ args->pkt_table[args->nb_rx++] = pkt;
+}
+
+static int netmap_recv(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
+ unsigned num)
+{
+ struct dispatch_args args;
+ struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.desc;
+ struct pollfd polld;
+
+ polld.fd = nm_desc->fd;
+ polld.events = POLLIN;
+
+ args.pkt_table = pkt_table;
+ args.nb_rx = 0;
+ args.pktio_entry = pktio_entry;
+
+ nm_dispatch(nm_desc, num, netmap_recv_cb, (u_char *)&args);
+ if (args.nb_rx == 0) {
+ if (odp_unlikely(poll(&polld, 1, 0) < 0))
+ ODP_ERR("RX: poll error\n");
+ }
+ return args.nb_rx;
+}
+
+static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
+ unsigned num)
+{
+ struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.desc;
+ struct pollfd polld;
+ unsigned i, nb_tx;
+ uint8_t *frame;
+ uint32_t frame_len;
+
+ polld.fd = nm_desc->fd;
+ polld.events = POLLOUT;
+
+ for (nb_tx = 0; nb_tx < num; nb_tx++) {
+ frame_len = 0;
+ frame = odp_packet_l2_ptr(pkt_table[nb_tx], &frame_len);
+ for (i = 0; i < NM_INJECT_RETRIES; i++) {
+ if (nm_inject(nm_desc, frame, frame_len) == 0)
+ poll(&polld, 1, 0);
+ else
+ break;
+ }
+ if (odp_unlikely(i == NM_INJECT_RETRIES))
+ break;
+ }
+ for (i = 0; i < nb_tx; i++)
+ odp_packet_free(pkt_table[i]);
+
+ return nb_tx;
+}
+
+static int netmap_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
+{
+ memcpy(mac_addr, pktio_entry->s.pkt_nm.if_mac, ETH_ALEN);
+ return ETH_ALEN;
+}
+
+static int netmap_mtu_get(pktio_entry_t *pktio_entry)
+{
+ return mtu_get_fd(pktio_entry->s.pkt_nm.sockfd, pktio_entry->s.name);
+}
+
+static int netmap_promisc_mode_set(pktio_entry_t *pktio_entry,
+ odp_bool_t enable)
+{
+ return promisc_mode_set_fd(pktio_entry->s.pkt_nm.sockfd,
+ pktio_entry->s.name, enable);
+}
+
+static int netmap_promisc_mode_get(pktio_entry_t *pktio_entry)
+{
+ return promisc_mode_get_fd(pktio_entry->s.pkt_nm.sockfd,
+ pktio_entry->s.name);
+}
+
+const pktio_if_ops_t netmap_pktio_ops = {
+ .init = NULL,
+ .term = NULL,
+ .open = netmap_open,
+ .close = netmap_close,
+ .start = NULL,
+ .stop = NULL,
+ .recv = netmap_recv,
+ .send = netmap_send,
+ .mtu_get = netmap_mtu_get,
+ .promisc_mode_set = netmap_promisc_mode_set,
+ .promisc_mode_get = netmap_promisc_mode_get,
+ .mac_get = netmap_mac_addr_get
+};
+
+#endif /* ODP_NETMAP */
diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c
index 1ced69a..a95b9a8 100644
--- a/platform/linux-generic/pktio/socket.c
+++ b/platform/linux-generic/pktio/socket.c
@@ -91,6 +91,7 @@ int sendmmsg(int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
/**
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
*/
int mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[])
{
@@ -115,6 +116,7 @@ int mac_addr_get_fd(int fd, const char *name, unsigned char mac_dst[])
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
*/
int mtu_get_fd(int fd, const char *name)
{
@@ -133,6 +135,7 @@ int mtu_get_fd(int fd, const char *name)
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
*/
int promisc_mode_set_fd(int fd, const char *name, int enable)
{
@@ -162,6 +165,7 @@ int promisc_mode_set_fd(int fd, const char *name, int enable)
/*
* ODP_PACKET_SOCKET_MMSG:
* ODP_PACKET_SOCKET_MMAP:
+ * ODP_PACKET_NETMAP:
*/
int promisc_mode_get_fd(int fd, const char *name)
{
diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index cb31544..812d47f 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -758,7 +758,8 @@ static void usage(char *progname)
" -a, --accuracy <number> Time in seconds get print statistics\n"
" (default is 1 second).\n"
" -h, --help Display help and exit.\n\n"
- " environment variables: ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
+ " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
+ " ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
" ODP_PKTIO_DISABLE_SOCKET_MMSG\n"
" can be used to advanced pkt I/O selection for linux-generic\n"
"\n", NO_PATH(progname), NO_PATH(progname)