/** * Simulate a Netmap NIOCTXSYNC ioctl: */ static inline int ioctl_nioctxsync(int fd) { uint32_t idx, port; idx = FD_TO_IDX(fd); if ((port = fd_port[idx].port) < RTE_DIM(ports) && ports[port].fd == idx) { return (tx_sync_if(fd_port[idx].port)); } else { return (-EINVAL); } }
/** * Doesn't support timeout other than 0 or infinite (negative) timeout */ int rte_netmap_poll(struct pollfd *fds, nfds_t nfds, int timeout) { int32_t count_it, ret; uint32_t i, idx, port; uint32_t want_rx, want_tx; if (timeout > 0) return -1; ret = 0; do { for (i = 0; i < nfds; i++) { count_it = 0; if (!FD_VALID(fds[i].fd) || fds[i].events == 0) { fds[i].revents = 0; continue; } idx = FD_TO_IDX(fds[i].fd); if ((port = fd_port[idx].port) >= RTE_DIM(ports) || ports[port].fd != idx) { fds[i].revents |= POLLERR; ret++; continue; } want_rx = fds[i].events & (POLLIN | POLLRDNORM); want_tx = fds[i].events & (POLLOUT | POLLWRNORM); if (want_rx && rx_sync_if(port) > 0) { fds[i].revents = (uint16_t) (fds[i].revents | want_rx); count_it = 1; } if (want_tx && tx_sync_if(port) > 0) { fds[i].revents = (uint16_t) (fds[i].revents | want_tx); count_it = 1; } ret += count_it; } } while ((ret == 0 && timeout < 0) || timeout); return ret; }
static int32_t fd_release(int32_t fd) { uint32_t idx, port; idx = FD_TO_IDX(fd); if (!FD_VALID(fd) || (port = fd_port[idx].port) == FD_PORT_FREE) return (-EINVAL); /* if we still have a valid port attached, release the port */ if (port < RTE_DIM(ports) && ports[port].fd == idx) { netmap_unregif(idx, port); } fd_port[idx].port = FD_PORT_FREE; return (0); }
/** * Simulate a Netmap NIOCREGIF ioctl: */ static int ioctl_niocregif(int32_t fd, void * param) { uint8_t portid; int32_t rc; uint32_t idx; struct nmreq *req; req = (struct nmreq *)param; if ((rc = check_nmreq(req, &portid)) != 0) return (rc); idx = FD_TO_IDX(fd); rte_spinlock_lock(&netmap_lock); rc = netmap_regif(req, idx, portid); rte_spinlock_unlock(&netmap_lock); return (rc); }
/** * Simulate a Netmap NIOCUNREGIF ioctl: put an interface running in Netmap * mode back in "normal" mode. In our case, we just stop the port associated * with this file descriptor. */ static int ioctl_niocunregif(int fd) { uint32_t idx, port; int32_t rc; idx = FD_TO_IDX(fd); rte_spinlock_lock(&netmap_lock); port = fd_port[idx].port; if (port < RTE_DIM(ports) && ports[port].fd == idx) { netmap_unregif(idx, port); rc = 0; } else { RTE_LOG(ERR, USER1, "%s: %d is not associated with valid port\n", __func__, fd); rc = -EINVAL; } rte_spinlock_unlock(&netmap_lock); return (rc); }