net/tap: add debug messages
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index d9ec14d..3d08ef2 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@
 #include <rte_vdev.h>
 #include <rte_kvargs.h>
 #include <rte_net.h>
+#include <rte_debug.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -72,6 +73,8 @@
 #define ETH_TAP_IFACE_ARG       "iface"
 #define ETH_TAP_SPEED_ARG       "speed"
 #define ETH_TAP_REMOTE_ARG      "remote"
+#define ETH_TAP_MAC_ARG         "mac"
+#define ETH_TAP_MAC_FIXED       "fixed"
 
 #define FLOWER_KERNEL_VERSION KERNEL_VERSION(4, 2, 0)
 #define FLOWER_VLAN_KERNEL_VERSION KERNEL_VERSION(4, 9, 0)
@@ -82,6 +85,7 @@ static const char *valid_arguments[] = {
        ETH_TAP_IFACE_ARG,
        ETH_TAP_SPEED_ARG,
        ETH_TAP_REMOTE_ARG,
+       ETH_TAP_MAC_ARG,
        NULL
 };
 
@@ -442,6 +446,24 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
        return num_tx;
 }
 
+static const char *
+tap_ioctl_req2str(unsigned long request)
+{
+       switch (request) {
+       case SIOCSIFFLAGS:
+               return "SIOCSIFFLAGS";
+       case SIOCGIFFLAGS:
+               return "SIOCGIFFLAGS";
+       case SIOCGIFHWADDR:
+               return "SIOCGIFHWADDR";
+       case SIOCSIFHWADDR:
+               return "SIOCSIFHWADDR";
+       case SIOCSIFMTU:
+               return "SIOCSIFMTU";
+       }
+       return "UNKNOWN";
+}
+
 static int
 tap_ioctl(struct pmd_internals *pmd, unsigned long request,
          struct ifreq *ifr, int set, enum ioctl_mode mode)
@@ -477,9 +499,7 @@ apply:
        case SIOCSIFMTU:
                break;
        default:
-               RTE_LOG(WARNING, PMD, "%s: ioctl() called with wrong arg\n",
-                       pmd->name);
-               return -EINVAL;
+               RTE_ASSERT(!"unsupported request type: must not happen");
        }
        if (ioctl(pmd->ioctl_sock, request, ifr) < 0)
                goto error;
@@ -488,8 +508,8 @@ apply:
        return 0;
 
 error:
-       RTE_LOG(ERR, PMD, "%s: ioctl(%lu) failed with error: %s\n",
-               ifr->ifr_name, request, strerror(errno));
+       RTE_LOG(DEBUG, PMD, "%s: %s(%s) failed: %s(%d)\n", ifr->ifr_name,
+               __func__, tap_ioctl_req2str(request), strerror(errno), errno);
        return -errno;
 }
 
@@ -771,12 +791,8 @@ tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
                return;
        }
        /* Check the actual current MAC address on the tap netdevice */
-       if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) != 0) {
-               RTE_LOG(ERR, PMD,
-                       "%s: couldn't check current tap MAC address\n",
-                       dev->data->name);
+       if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, LOCAL_ONLY) != 0)
                return;
-       }
        if (is_same_ether_addr((struct ether_addr *)&ifr.ifr_hwaddr.sa_data,
                               mac_addr))
                return;
@@ -875,7 +891,9 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
        struct pmd_internals *internals = dev->data->dev_private;
        struct rx_queue *rxq = &internals->rxq[rx_queue_id];
        struct rte_mbuf **tmp = &rxq->pool;
-       struct iovec (*iovecs)[nb_rx_desc + 1];
+       long iov_max = sysconf(_SC_IOV_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;
        int ret = 0;
        int fd;
@@ -891,13 +909,13 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
        rxq->mp = mp;
        rxq->trigger_seen = 1; /* force initial burst */
        rxq->in_port = dev->data->port_id;
-       rxq->nb_rx_desc = nb_rx_desc;
+       rxq->nb_rx_desc = nb_desc;
        iovecs = rte_zmalloc_socket(dev->data->name, sizeof(*iovecs), 0,
                                    socket_id);
        if (!iovecs) {
                RTE_LOG(WARNING, PMD,
                        "%s: Couldn't allocate %d RX descriptors\n",
-                       dev->data->name, nb_rx_desc);
+                       dev->data->name, nb_desc);
                return -ENOMEM;
        }
        rxq->iovecs = iovecs;
@@ -911,7 +929,7 @@ tap_rx_queue_setup(struct rte_eth_dev *dev,
        (*rxq->iovecs)[0].iov_len = sizeof(struct tun_pi);
        (*rxq->iovecs)[0].iov_base = &rxq->pi;
 
-       for (i = 1; i <= nb_rx_desc; i++) {
+       for (i = 1; i <= nb_desc; i++) {
                *tmp = rte_pktmbuf_alloc(rxq->mp);
                if (!*tmp) {
                        RTE_LOG(WARNING, PMD,
@@ -1133,7 +1151,7 @@ tap_kernel_support(struct pmd_internals *pmd)
 
 static int
 eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
-                  char *remote_iface)
+                  char *remote_iface, int fixed_mac_type)
 {
        int numa_node = rte_socket_id();
        struct rte_eth_dev *dev;
@@ -1193,6 +1211,17 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
                pmd->txq[i].fd = -1;
        }
 
+       if (fixed_mac_type) {
+               /* fixed mac = 00:64:74:61:70:<iface_idx> */
+               static int iface_idx;
+               char mac[ETHER_ADDR_LEN] = "\0dtap";
+
+               mac[ETHER_ADDR_LEN - 1] = iface_idx++;
+               rte_memcpy(&pmd->eth_addr, mac, ETHER_ADDR_LEN);
+       } else {
+               eth_random_addr((uint8_t *)&pmd->eth_addr);
+       }
+
        tap_kernel_support(pmd);
        if (!pmd->flower_support)
                return 0;
@@ -1214,14 +1243,10 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
                                remote_iface);
                        return 0;
                }
-               if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0) {
-                       RTE_LOG(ERR, PMD, "Could not get remote MAC address\n");
+               if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0)
                        goto error_exit;
-               }
                rte_memcpy(&pmd->eth_addr, ifr.ifr_hwaddr.sa_data,
                           ETHER_ADDR_LEN);
-       } else {
-               eth_random_addr((uint8_t *)&pmd->eth_addr);
        }
 
        return 0;
@@ -1273,6 +1298,17 @@ set_remote_iface(const char *key __rte_unused,
        return 0;
 }
 
+static int
+set_mac_type(const char *key __rte_unused,
+            const char *value,
+            void *extra_args)
+{
+       if (value &&
+           !strncasecmp(ETH_TAP_MAC_FIXED, value, strlen(ETH_TAP_MAC_FIXED)))
+               *(int *)extra_args = 1;
+       return 0;
+}
+
 /* Open a TAP interface device.
  */
 static int
@@ -1284,6 +1320,7 @@ 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];
+       int fixed_mac_type = 0;
 
        name = rte_vdev_device_name(dev);
        params = rte_vdev_device_args(dev);
@@ -1324,6 +1361,15 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
                                if (ret == -1)
                                        goto leave;
                        }
+
+                       if (rte_kvargs_count(kvlist, ETH_TAP_MAC_ARG) == 1) {
+                               ret = rte_kvargs_process(kvlist,
+                                                        ETH_TAP_MAC_ARG,
+                                                        &set_mac_type,
+                                                        &fixed_mac_type);
+                               if (ret == -1)
+                                       goto leave;
+                       }
                }
        }
        pmd_link.link_speed = speed;
@@ -1331,7 +1377,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
        RTE_LOG(NOTICE, PMD, "Initializing pmd_tap for %s as %s\n",
                name, tap_name);
 
-       ret = eth_dev_tap_create(dev, tap_name, remote_iface);
+       ret = eth_dev_tap_create(dev, tap_name, remote_iface, fixed_mac_type);
 
 leave:
        if (ret == -1) {
@@ -1389,4 +1435,5 @@ RTE_PMD_REGISTER_ALIAS(net_tap, eth_tap);
 RTE_PMD_REGISTER_PARAM_STRING(net_tap,
                              ETH_TAP_IFACE_ARG "=<string> "
                              ETH_TAP_SPEED_ARG "=<int> "
+                             ETH_TAP_MAC_ARG "=" ETH_TAP_MAC_FIXED " "
                              ETH_TAP_REMOTE_ARG "=<string>");