@@ -29,6 +29,8 @@ Some of these, in turn, will be used to configure the PACKET_MMAP settings.
* ``framesz`` - PACKET_MMAP frame size (optional, default 2048B; Note: multiple
of 16B);
* ``framecnt`` - PACKET_MMAP frame count (optional, default 512).
+* ``rollover`` - disable(0)/enable(1) PACKET_FANOUT_ROLLOVER (optional, default 1).
+* ``defrag`` - disable(0)/enable(1) PACKET_FANOUT_FLAG_DEFRAG (optional, default 1).
Because this implementation is based on PACKET_MMAP, and PACKET_MMAP has its
own pre-requisites, it should be noted that the inner workings of PACKET_MMAP
@@ -47,6 +49,8 @@ For the full details behind PACKET_MMAP's structures and settings, consider
reading the `PACKET_MMAP documentation in the Kernel
<https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt>`_.
+For details of ``rollover`` anb ``defrag`` refer to the *packet(7)* man page.
+
Prerequisites
-------------
@@ -36,6 +36,8 @@
#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_ROLLOVER "rollover"
+#define ETH_AF_PACKET_DEFRAG "defrag"
#define DFLT_FRAME_SIZE (1 << 11)
#define DFLT_FRAME_COUNT (1 << 9)
@@ -91,6 +93,8 @@ static const char *valid_arguments[] = {
ETH_AF_PACKET_FRAMESIZE_ARG,
ETH_AF_PACKET_FRAMECOUNT_ARG,
ETH_AF_PACKET_QDISC_BYPASS_ARG,
+ ETH_AF_PACKET_ROLLOVER,
+ ETH_AF_PACKET_DEFRAG,
NULL
};
@@ -676,6 +680,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
const unsigned int numa_node = dev->device.numa_node;
struct rte_eth_dev_data *data = NULL;
struct rte_kvargs_pair *pair = NULL;
+ const char *ifname = NULL;
struct ifreq ifr;
size_t ifnamelen;
unsigned k_idx;
@@ -686,6 +691,8 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
int rc, tpver, discard;
int qsockfd = -1;
unsigned int i, q, rdsize;
+ unsigned int rollover = 1;
+ unsigned int defrag = 1;
#if defined(PACKET_FANOUT)
int fanout_arg;
#endif
@@ -693,9 +700,30 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
pair = &kvlist->pairs[k_idx];
if (strstr(pair->key, ETH_AF_PACKET_IFACE_ARG) != NULL)
- break;
+ ifname = pair->value;
+ if (strstr(pair->key, ETH_AF_PACKET_ROLLOVER) != NULL) {
+ rollover = atoi(pair->value);
+ if (rollover != 0 && rollover != 1) {
+ PMD_LOG(ERR,
+ "%s: invalid rollover value",
+ name);
+ return -1;
+ }
+ continue;
+ }
+ if (strstr(pair->key, ETH_AF_PACKET_DEFRAG) != NULL) {
+ defrag = atoi(pair->value);
+ if (defrag != 0 && defrag != 1) {
+ PMD_LOG(ERR,
+ "%s: invalid defrag value",
+ name);
+ return -1;
+ }
+ continue;
+ }
}
- if (pair == NULL) {
+
+ if (ifname == NULL) {
PMD_LOG(ERR,
"%s: no interface specified for AF_PACKET ethdev",
name);
@@ -738,21 +766,21 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
req->tp_frame_size = framesize;
req->tp_frame_nr = framecnt;
- ifnamelen = strlen(pair->value);
+ ifnamelen = strlen(ifname);
if (ifnamelen < sizeof(ifr.ifr_name)) {
- memcpy(ifr.ifr_name, pair->value, ifnamelen);
+ memcpy(ifr.ifr_name, ifname, ifnamelen);
ifr.ifr_name[ifnamelen] = '\0';
} else {
PMD_LOG(ERR,
"%s: I/F name too long (%s)",
- name, pair->value);
+ name, ifname);
goto free_internals;
}
if (ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1) {
PMD_LOG_ERRNO(ERR, "%s: ioctl failed (SIOCGIFINDEX)", name);
goto free_internals;
}
- (*internals)->if_name = strdup(pair->value);
+ (*internals)->if_name = strdup(ifname);
if ((*internals)->if_name == NULL)
goto free_internals;
(*internals)->if_index = ifr.ifr_ifindex;
@@ -770,9 +798,12 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
#if defined(PACKET_FANOUT)
fanout_arg = (getpid() ^ (*internals)->if_index) & 0xffff;
- fanout_arg |= (PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_DEFRAG) << 16;
+ fanout_arg |= PACKET_FANOUT_HASH << 16;
+ if (defrag)
+ fanout_arg |= PACKET_FANOUT_FLAG_DEFRAG << 16;
#if defined(PACKET_FANOUT_FLAG_ROLLOVER)
- fanout_arg |= PACKET_FANOUT_FLAG_ROLLOVER << 16;
+ if (rollover)
+ fanout_arg |= PACKET_FANOUT_FLAG_ROLLOVER << 16;
#endif
#endif
@@ -792,7 +823,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_VERSION on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
@@ -802,7 +833,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_LOSS on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
@@ -813,7 +844,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_QDISC_BYPASS on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
#endif
@@ -823,7 +854,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_RX_RING on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
@@ -831,7 +862,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_TX_RING on AF_PACKET "
- "socket for %s", name, pair->value);
+ "socket for %s", name, ifname);
goto error;
}
@@ -844,7 +875,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rx_queue->map == MAP_FAILED) {
PMD_LOG_ERRNO(ERR,
"%s: call to mmap failed on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
@@ -881,7 +912,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not bind AF_PACKET socket to %s",
- name, pair->value);
+ name, ifname);
goto error;
}
@@ -891,7 +922,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
if (rc == -1) {
PMD_LOG_ERRNO(ERR,
"%s: could not set PACKET_FANOUT on AF_PACKET socket for %s",
- name, pair->value);
+ name, ifname);
goto error;
}
#endif