if (ns->threads_auto) {
/* As NetmapGetRSSCount used to be broken on Linux,
* fall back to GetIfaceRSSQueuesNum if needed. */
- ns->threads = NetmapGetRSSCount(ns->iface);
+ ns->threads = NetmapGetRSSCount(base_name);
if (ns->threads == 0) {
/* need to use base_name of interface here */
ns->threads = GetIfaceRSSQueuesNum(base_name);
LiveRegisterDevice(live_buf);
}
+ /* we need the base interface name with any trailing software
+ * ring marker stripped for HW offloading checks */
+ char base_name[sizeof(aconf->in.iface)];
+ strlcpy(base_name, aconf->in.iface, sizeof(base_name));
+ /* for a sw_ring enabled device name, strip the trailing char */
+ if (aconf->in.sw_ring) {
+ base_name[strlen(base_name) - 1] = '\0';
+ }
+
/* netmap needs all offloading to be disabled */
if (aconf->in.real) {
- char base_name[sizeof(aconf->in.iface)];
- strlcpy(base_name, aconf->in.iface, sizeof(base_name));
- /* for a sw_ring enabled device name, strip the trailing char */
- if (aconf->in.sw_ring) {
- base_name[strlen(base_name) - 1] = '\0';
- }
-
if (LiveGetOffload() == 0) {
(void)GetIfaceOffloading(base_name, 1, 1);
} else {
goto error_open;
}
- /* query netmap interface info */
+ /* query netmap interface info for ring count */
memset(&req, 0, sizeof(req));
memset(&hdr, 0, sizeof(hdr));
hdr.nr_version = NETMAP_API;
strlcpy(hdr.nr_name, base_name, sizeof(hdr.nr_name));
if (ioctl(fd, NIOCCTRL, &hdr) != 0) {
- SCLogError("%s: failed to query netmap for device info: %s", ifname, strerror(errno));
+ SCLogError(
+ "Query of netmap HW rings count on %s failed; error: %s", ifname, strerror(errno));
goto error_fd;
};
SCMutexLock(&ntv->ifdst->netmap_dev_lock);
}
+ int write_tries = 0;
+try_write:
/* attempt to write the packet into the netmap ring buffer(s) */
if (nmport_inject(ntv->ifdst->nmd, GET_PKT_DATA(p), GET_PKT_LEN(p)) == 0) {
+
+ /* writing the packet failed, but ask kernel to sync TX rings
+ * for us as the ring buffers may simply be full */
+ (void)ioctl(ntv->ifdst->nmd->fd, NIOCTXSYNC, 0);
+
+ /* Try write up to 2 more times before giving up */
+ if (write_tries < 3) {
+ write_tries++;
+ goto try_write;
+ }
+
if (ntv->flags & NETMAP_FLAG_EXCL_RING_ACCESS) {
SCMutexUnlock(&ntv->ifdst->netmap_dev_lock);
}
ntv->ifdst->ifname, ntv->ifdst->ring, GET_PKT_LEN(p));
/* Instruct netmap to push the data on the TX ring on the destination port */
- ioctl(ntv->ifdst->nmd->fd, NIOCTXSYNC, 0);
+ (void)ioctl(ntv->ifdst->nmd->fd, NIOCTXSYNC, 0);
if (ntv->flags & NETMAP_FLAG_EXCL_RING_ACCESS) {
SCMutexUnlock(&ntv->ifdst->netmap_dev_lock);
}