New upstream version 18.11.1
[deb_dpdk.git] / drivers / net / tap / rte_eth_tap.c
index 49afd38..a934299 100644 (file)
@@ -78,9 +78,6 @@ static const char *valid_arguments[] = {
        NULL
 };
 
-static unsigned int tap_unit;
-static unsigned int tun_unit;
-
 static char tuntap_name[8];
 
 static volatile uint32_t tap_trigger;  /* Rx trigger */
@@ -150,8 +147,6 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive)
                IFF_TAP : IFF_TUN | IFF_POINTOPOINT;
        snprintf(ifr.ifr_name, IFNAMSIZ, "%s", pmd->name);
 
-       TAP_LOG(DEBUG, "ifr_name '%s'", ifr.ifr_name);
-
        fd = open(TUN_TAP_DEV_PATH, O_RDWR);
        if (fd < 0) {
                TAP_LOG(ERR, "Unable to create %s interface", tuntap_name);
@@ -185,6 +180,13 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive)
                goto error;
        }
 
+       /*
+        * Name passed to kernel might be wildcard like dtun%d
+        * and need to find the resulting device.
+        */
+       TAP_LOG(DEBUG, "Device name is '%s'", ifr.ifr_name);
+       strlcpy(pmd->name, ifr.ifr_name, RTE_ETH_NAME_MAX_LEN);
+
        if (is_keepalive) {
                /*
                 * Detach the TUN/TAP keep-alive queue
@@ -281,13 +283,27 @@ tap_verify_csum(struct rte_mbuf *mbuf)
                l3_len = 4 * (iph->version_ihl & 0xf);
                if (unlikely(l2_len + l3_len > rte_pktmbuf_data_len(mbuf)))
                        return;
+               /* check that the total length reported by header is not
+                * greater than the total received size
+                */
+               if (l2_len + rte_be_to_cpu_16(iph->total_length) >
+                               rte_pktmbuf_data_len(mbuf))
+                       return;
 
                cksum = ~rte_raw_cksum(iph, l3_len);
                mbuf->ol_flags |= cksum ?
                        PKT_RX_IP_CKSUM_BAD :
                        PKT_RX_IP_CKSUM_GOOD;
        } else if (l3 == RTE_PTYPE_L3_IPV6) {
+               struct ipv6_hdr *iph = l3_hdr;
+
                l3_len = sizeof(struct ipv6_hdr);
+               /* check that the total length reported by header is not
+                * greater than the total received size
+                */
+               if (l2_len + l3_len + rte_be_to_cpu_16(iph->payload_len) >
+                               rte_pktmbuf_data_len(mbuf))
+                       return;
        } else {
                /* IPv6 extensions are not supported */
                return;
@@ -1741,6 +1757,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name,
                TAP_LOG(ERR, "Unable to create %s interface", tuntap_name);
                goto error_exit;
        }
+       TAP_LOG(DEBUG, "allocated %s", pmd->name);
 
        ifr.ifr_mtu = dev->data->mtu;
        if (tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1, LOCAL_AND_REMOTE) < 0)
@@ -1878,10 +1895,10 @@ set_interface_name(const char *key __rte_unused,
        char *name = (char *)extra_args;
 
        if (value)
-               strlcpy(name, value, RTE_ETH_NAME_MAX_LEN - 1);
+               strlcpy(name, value, RTE_ETH_NAME_MAX_LEN);
        else
-               snprintf(name, RTE_ETH_NAME_MAX_LEN - 1, "%s%d",
-                        DEFAULT_TAP_NAME, (tap_unit - 1));
+               /* use tap%d which causes kernel to choose next available */
+               strlcpy(name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN);
 
        return 0;
 }
@@ -1988,8 +2005,8 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev)
                return 0;
        }
 
-       snprintf(tun_name, sizeof(tun_name), "%s%u",
-                DEFAULT_TUN_NAME, tun_unit++);
+       /* use tun%d which causes kernel to choose next available */
+       strlcpy(tun_name, DEFAULT_TUN_NAME "%d", RTE_ETH_NAME_MAX_LEN);
 
        if (params && (params[0] != '\0')) {
                TAP_LOG(DEBUG, "parameters (%s)", params);
@@ -2009,17 +2026,15 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev)
        }
        pmd_link.link_speed = ETH_SPEED_NUM_10G;
 
-       TAP_LOG(NOTICE, "Initializing pmd_tun for %s as %s",
-               name, tun_name);
+       TAP_LOG(NOTICE, "Initializing pmd_tun for %s", name);
 
        ret = eth_dev_tap_create(dev, tun_name, remote_iface, 0,
-               ETH_TUNTAP_TYPE_TUN);
+                                ETH_TUNTAP_TYPE_TUN);
 
 leave:
        if (ret == -1) {
                TAP_LOG(ERR, "Failed to create pmd for %s as %s",
                        name, tun_name);
-               tun_unit--; /* Restore the unit number */
        }
        rte_kvargs_free(kvlist);
 
@@ -2175,8 +2190,9 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)
        }
 
        speed = ETH_SPEED_NUM_10G;
-       snprintf(tap_name, sizeof(tap_name), "%s%u",
-                DEFAULT_TAP_NAME, tap_unit++);
+
+       /* use tap%d which causes kernel to choose next available */
+       strlcpy(tap_name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN);
        memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN);
 
        if (params && (params[0] != '\0')) {
@@ -2240,7 +2256,6 @@ leave:
                                rte_mp_action_unregister(TAP_MP_KEY);
                        tap_devices_count--;
                }
-               tap_unit--;             /* Restore the unit number */
        }
        rte_kvargs_free(kvlist);