X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Ftap%2Frte_eth_tap.c;h=71be763d66e8b4bc4d7a831766a2d67cba7357ba;hb=6d13ea8e8e49ab957deae2bba5ecf4a4bfe747d1;hp=ed8483cb96bcdb1290f9f0730af1fd23999ec575;hpb=b5235d61f3b7d2b1c2b9ee2601f3aca2b151b508;p=dpdk.git diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index ed8483cb96..71be763d66 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -68,6 +68,8 @@ /* IPC key for queue fds sync */ #define TAP_MP_KEY "tap_mp_sync_queues" +#define TAP_IOV_DEFAULT_MAX 1024 + static int tap_devices_count; static struct rte_vdev_driver pmd_tap_drv; static struct rte_vdev_driver pmd_tun_drv; @@ -79,8 +81,6 @@ static const char *valid_arguments[] = { NULL }; -static char tuntap_name[8]; - static volatile uint32_t tap_trigger; /* Rx trigger */ static struct rte_eth_link pmd_link = { @@ -150,18 +150,17 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive) fd = open(TUN_TAP_DEV_PATH, O_RDWR); if (fd < 0) { - TAP_LOG(ERR, "Unable to create %s interface", tuntap_name); + TAP_LOG(ERR, "Unable to open %s interface", TUN_TAP_DEV_PATH); goto error; } #ifdef IFF_MULTI_QUEUE /* Grab the TUN features to verify we can work multi-queue */ if (ioctl(fd, TUNGETFEATURES, &features) < 0) { - TAP_LOG(ERR, "%s unable to get TUN/TAP features", - tuntap_name); + TAP_LOG(ERR, "unable to get TUN/TAP features"); goto error; } - TAP_LOG(DEBUG, "%s Features %08x", tuntap_name, features); + TAP_LOG(DEBUG, "%s Features %08x", TUN_TAP_DEV_PATH, features); if (features & IFF_MULTI_QUEUE) { TAP_LOG(DEBUG, " Multi-queue support for %d queues", @@ -262,7 +261,7 @@ tap_verify_csum(struct rte_mbuf *mbuf) uint32_t l2 = mbuf->packet_type & RTE_PTYPE_L2_MASK; uint32_t l3 = mbuf->packet_type & RTE_PTYPE_L3_MASK; uint32_t l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK; - unsigned int l2_len = sizeof(struct ether_hdr); + unsigned int l2_len = sizeof(struct rte_ether_hdr); unsigned int l3_len; uint16_t cksum = 0; void *l3_hdr; @@ -761,9 +760,9 @@ tap_ioctl(struct pmd_internals *pmd, unsigned long request, */ apply: if (remote) - snprintf(ifr->ifr_name, IFNAMSIZ, "%s", pmd->remote_iface); + strlcpy(ifr->ifr_name, pmd->remote_iface, IFNAMSIZ); else if (mode == LOCAL_ONLY || mode == LOCAL_AND_REMOTE) - snprintf(ifr->ifr_name, IFNAMSIZ, "%s", pmd->name); + strlcpy(ifr->ifr_name, pmd->name, IFNAMSIZ); switch (request) { case SIOCSIFFLAGS: /* fetch current flags to leave other flags untouched */ @@ -856,6 +855,8 @@ tap_dev_stop(struct rte_eth_dev *dev) static int tap_dev_configure(struct rte_eth_dev *dev) { + struct pmd_internals *pmd = dev->data->dev_private; + if (dev->data->nb_rx_queues > RTE_PMD_TAP_MAX_QUEUES) { TAP_LOG(ERR, "%s: number of rx queues %d exceeds max num of queues %d", @@ -873,11 +874,11 @@ tap_dev_configure(struct rte_eth_dev *dev) return -1; } - TAP_LOG(INFO, "%s: %p: TX configured queues number: %u", - dev->device->name, (void *)dev, dev->data->nb_tx_queues); + TAP_LOG(INFO, "%s: %s: TX configured queues number: %u", + dev->device->name, pmd->name, dev->data->nb_tx_queues); - TAP_LOG(INFO, "%s: %p: RX configured queues number: %u", - dev->device->name, (void *)dev, dev->data->nb_rx_queues); + TAP_LOG(INFO, "%s: %s: RX configured queues number: %u", + dev->device->name, pmd->name, dev->data->nb_rx_queues); return 0; } @@ -1149,7 +1150,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev) } static int -tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) +tap_mac_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) { struct pmd_internals *pmd = dev->data->dev_private; enum ioctl_mode mode = LOCAL_ONLY; @@ -1171,15 +1172,16 @@ tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr) ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY); if (ret < 0) return ret; - if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data, + if (is_same_ether_addr((struct rte_ether_addr *)&ifr.ifr_hwaddr.sa_data, mac_addr)) return 0; /* Check the current MAC address on the remote */ ret = tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY); if (ret < 0) return ret; - if (!is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data, - mac_addr)) + if (!is_same_ether_addr( + (struct rte_ether_addr *)&ifr.ifr_hwaddr.sa_data, + mac_addr)) mode = LOCAL_AND_REMOTE; ifr.ifr_hwaddr.sa_family = AF_LOCAL; rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN); @@ -1327,6 +1329,13 @@ tap_rx_queue_setup(struct rte_eth_dev *dev, struct rx_queue *rxq = &internals->rxq[rx_queue_id]; struct rte_mbuf **tmp = &rxq->pool; long iov_max = sysconf(_SC_IOV_MAX); + + if (iov_max <= 0) { + TAP_LOG(WARNING, + "_SC_IOV_MAX is not defined. Using %d as default", + TAP_IOV_DEFAULT_MAX); + iov_max = TAP_IOV_DEFAULT_MAX; + } uint16_t nb_desc = RTE_MIN(nb_rx_desc, iov_max - 1); struct iovec (*iovecs)[nb_desc + 1]; int data_off = RTE_PKTMBUF_HEADROOM; @@ -1450,7 +1459,7 @@ tap_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) static int tap_set_mc_addr_list(struct rte_eth_dev *dev __rte_unused, - struct ether_addr *mc_addr_set __rte_unused, + struct rte_ether_addr *mc_addr_set __rte_unused, uint32_t nb_mc_addr __rte_unused) { /* @@ -1668,21 +1677,25 @@ static const struct eth_dev_ops ops = { .filter_ctrl = tap_dev_filter_ctrl, }; +static const char *tuntap_types[ETH_TUNTAP_TYPE_MAX] = { + "UNKNOWN", "TUN", "TAP" +}; + static int -eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name, - char *remote_iface, struct ether_addr *mac_addr, +eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, + char *remote_iface, struct rte_ether_addr *mac_addr, enum rte_tuntap_type type) { int numa_node = rte_socket_id(); struct rte_eth_dev *dev; struct pmd_internals *pmd; struct pmd_process_private *process_private; + const char *tuntap_name = tuntap_types[type]; struct rte_eth_dev_data *data; struct ifreq ifr; int i; - TAP_LOG(DEBUG, "%s device on numa %u", - tuntap_name, rte_socket_id()); + TAP_LOG(DEBUG, "%s device on numa %u", tuntap_name, rte_socket_id()); dev = rte_eth_vdev_allocate(vdev, sizeof(*pmd)); if (!dev) { @@ -1702,7 +1715,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name, pmd = dev->data->dev_private; dev->process_private = process_private; pmd->dev = dev; - snprintf(pmd->name, sizeof(pmd->name), "%s", tap_name); + strlcpy(pmd->name, tap_name, sizeof(pmd->name)); pmd->type = type; pmd->ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0); @@ -1811,8 +1824,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name, pmd->name, remote_iface); goto error_remote; } - snprintf(pmd->remote_iface, RTE_ETH_NAME_MAX_LEN, - "%s", remote_iface); + strlcpy(pmd->remote_iface, remote_iface, RTE_ETH_NAME_MAX_LEN); /* Save state of remote device */ tap_ioctl(pmd, SIOCGIFFLAGS, &pmd->remote_initial_flags, 0, REMOTE_ONLY); @@ -1946,7 +1958,7 @@ set_remote_iface(const char *key __rte_unused, return 0; } -static int parse_user_mac(struct ether_addr *user_mac, +static int parse_user_mac(struct rte_ether_addr *user_mac, const char *value) { unsigned int index = 0; @@ -1974,7 +1986,7 @@ set_mac_type(const char *key __rte_unused, const char *value, void *extra_args) { - struct ether_addr *user_mac = extra_args; + struct rte_ether_addr *user_mac = extra_args; if (!value) return 0; @@ -2016,8 +2028,6 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) char remote_iface[RTE_ETH_NAME_MAX_LEN]; struct rte_eth_dev *eth_dev; - strcpy(tuntap_name, "TUN"); - name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); @@ -2085,13 +2095,14 @@ tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev) int queue, fd_iterator; /* Prepare the request */ + memset(&request, 0, sizeof(request)); strlcpy(request.name, TAP_MP_KEY, sizeof(request.name)); strlcpy(request_param->port_name, port_name, sizeof(request_param->port_name)); request.len_param = sizeof(*request_param); /* Send request and receive reply */ ret = rte_mp_request_sync(&request, &replies, &timeout); - if (ret < 0) { + if (ret < 0 || replies.nb_received != 1) { TAP_LOG(ERR, "Failed to request queues from primary: %d", rte_errno); return -1; @@ -2101,6 +2112,11 @@ tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev) TAP_LOG(DEBUG, "Received IPC reply for %s", reply_param->port_name); /* Attach the queues from received file descriptors */ + if (reply_param->rxq_count + reply_param->txq_count != reply->num_fds) { + TAP_LOG(ERR, "Unexpected number of fds received"); + return -1; + } + dev->data->nb_rx_queues = reply_param->rxq_count; dev->data->nb_tx_queues = reply_param->txq_count; fd_iterator = 0; @@ -2108,7 +2124,7 @@ tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev) process_private->rxq_fds[queue] = reply->fds[fd_iterator++]; for (queue = 0; queue < reply_param->txq_count; queue++) process_private->txq_fds[queue] = reply->fds[fd_iterator++]; - + free(reply); return 0; } @@ -2141,19 +2157,24 @@ tap_mp_sync_queues(const struct rte_mp_msg *request, const void *peer) /* Fill file descriptors for all queues */ reply.num_fds = 0; reply_param->rxq_count = 0; + if (dev->data->nb_rx_queues + dev->data->nb_tx_queues > + RTE_MP_MAX_FD_NUM){ + TAP_LOG(ERR, "Number of rx/tx queues exceeds max number of fds"); + return -1; + } + for (queue = 0; queue < dev->data->nb_rx_queues; queue++) { reply.fds[reply.num_fds++] = process_private->rxq_fds[queue]; reply_param->rxq_count++; } RTE_ASSERT(reply_param->rxq_count == dev->data->nb_rx_queues); - RTE_ASSERT(reply_param->txq_count == dev->data->nb_tx_queues); - RTE_ASSERT(reply.num_fds <= RTE_MP_MAX_FD_NUM); reply_param->txq_count = 0; for (queue = 0; queue < dev->data->nb_tx_queues; queue++) { reply.fds[reply.num_fds++] = process_private->txq_fds[queue]; reply_param->txq_count++; } + RTE_ASSERT(reply_param->txq_count == dev->data->nb_tx_queues); /* Send reply */ strlcpy(reply.name, request->name, sizeof(reply.name)); @@ -2178,12 +2199,10 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) int speed; char tap_name[RTE_ETH_NAME_MAX_LEN]; char remote_iface[RTE_ETH_NAME_MAX_LEN]; - struct ether_addr user_mac = { .addr_bytes = {0} }; + struct rte_ether_addr user_mac = { .addr_bytes = {0} }; struct rte_eth_dev *eth_dev; int tap_devices_count_increased = 0; - strcpy(tuntap_name, "TAP"); - name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); @@ -2266,8 +2285,8 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) if (!tap_devices_count) { ret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues); if (ret < 0) { - TAP_LOG(ERR, "%s: Failed to register IPC callback: %s", - tuntap_name, strerror(rte_errno)); + TAP_LOG(ERR, "tap: Failed to register IPC callback: %s", + strerror(rte_errno)); goto leave; } } @@ -2316,8 +2335,7 @@ rte_pmd_tap_remove(struct rte_vdev_device *dev) process_private = eth_dev->process_private; TAP_LOG(DEBUG, "Closing %s Ethernet device on numa %u", - (internals->type == ETH_TUNTAP_TYPE_TAP) ? "TAP" : "TUN", - rte_socket_id()); + tuntap_types[internals->type], rte_socket_id()); if (internals->nlsk_fd) { tap_flow_flush(eth_dev, NULL);