This allows us to control whether the PMD will attempt to use the PACKET_FANOUT socket option, and allows the binary compiled against newer kernel headers to run on an older kernel, which lacks support for it.
Signed-off-by: Tudor Cornea <tudor.cor...@gmail.com> --- doc/guides/nics/af_packet.rst | 4 ++- drivers/net/af_packet/rte_eth_af_packet.c | 32 ++++++++++++++++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/doc/guides/nics/af_packet.rst b/doc/guides/nics/af_packet.rst index a343d3a961..42837031de 100644 --- a/doc/guides/nics/af_packet.rst +++ b/doc/guides/nics/af_packet.rst @@ -25,6 +25,8 @@ Some of these, in turn, will be used to configure the PACKET_MMAP settings. * ``qpairs`` - number of Rx and Tx queues (optional, default 1); * ``qdisc_bypass`` - set PACKET_QDISC_BYPASS option in AF_PACKET (optional, disabled by default); +* ``packet_fanout`` - set PACKET_FANOUT option in AF_PACKET (optional, + enabled by default); * ``blocksz`` - PACKET_MMAP block size (optional, default 4096); * ``framesz`` - PACKET_MMAP frame size (optional, default 2048B; Note: multiple of 16B); @@ -64,7 +66,7 @@ framecnt=512): .. code-block:: console - --vdev=eth_af_packet0,iface=tap0,blocksz=4096,framesz=2048,framecnt=512,qpairs=1,qdisc_bypass=0 + --vdev=eth_af_packet0,iface=tap0,blocksz=4096,framesz=2048,framecnt=512,qpairs=1,qdisc_bypass=0,packet_fanout=0 Features and Limitations ------------------------ diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index ceb8d9356a..521dbef317 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -36,6 +36,7 @@ #define ETH_AF_PACKET_FRAMESIZE_ARG "framesz" #define ETH_AF_PACKET_FRAMECOUNT_ARG "framecnt" #define ETH_AF_PACKET_QDISC_BYPASS_ARG "qdisc_bypass" +#define ETH_AF_PACKET_PACKET_FANOUT_ARG "packet_fanout" #define DFLT_FRAME_SIZE (1 << 11) #define DFLT_FRAME_COUNT (1 << 9) @@ -96,6 +97,7 @@ static const char *valid_arguments[] = { ETH_AF_PACKET_FRAMESIZE_ARG, ETH_AF_PACKET_FRAMECOUNT_ARG, ETH_AF_PACKET_QDISC_BYPASS_ARG, + ETH_AF_PACKET_PACKET_FANOUT_ARG, NULL }; @@ -709,6 +711,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, unsigned int framesize, unsigned int framecnt, unsigned int qdisc_bypass, + unsigned int packet_fanout, struct pmd_internals **internals, struct rte_eth_dev **eth_dev, struct rte_kvargs *kvlist) @@ -926,14 +929,17 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, goto error; } + if (packet_fanout) { #if defined(PACKET_FANOUT) - rc = setsockopt(qsockfd, SOL_PACKET, PACKET_FANOUT, - &fanout_arg, sizeof(fanout_arg)); - if (rc == -1) { - PMD_LOG_ERRNO(ERR, - "%s: could not set PACKET_FANOUT on AF_PACKET socket for %s", - name, pair->value); - goto error; + rc = setsockopt(qsockfd, SOL_PACKET, PACKET_FANOUT, + &fanout_arg, sizeof(fanout_arg)); + if (rc == -1) { + PMD_LOG_ERRNO(ERR, + "%s: could not set PACKET_FANOUT " + "on AF_PACKET socket for %s", + name, pair->value); + goto error; + } } #endif } @@ -1003,6 +1009,7 @@ rte_eth_from_packet(struct rte_vdev_device *dev, unsigned int framecount = DFLT_FRAME_COUNT; unsigned int qpairs = 1; unsigned int qdisc_bypass = 1; + unsigned int packet_fanout = 1; /* do some parameter checking */ if (*sockfd < 0) @@ -1065,6 +1072,16 @@ rte_eth_from_packet(struct rte_vdev_device *dev, } continue; } + if (strstr(pair->key, ETH_AF_PACKET_PACKET_FANOUT_ARG) != NULL) { + packet_fanout = atoi(pair->value); + if (packet_fanout > 1) { + PMD_LOG(ERR, + "%s: invalid packet fanout value", + name); + return -1; + } + continue; + } } if (framesize > blocksize) { @@ -1091,6 +1108,7 @@ rte_eth_from_packet(struct rte_vdev_device *dev, blocksize, blockcount, framesize, framecount, qdisc_bypass, + packet_fanout, &internals, ð_dev, kvlist) < 0) return -1; -- 2.34.1