net/virtio: fix interrupt handle leak
[dpdk.git] / drivers / net / virtio / virtio_user / vhost_kernel_tap.c
index 2fbfecb..99096bd 100644 (file)
 
 #include "vhost_kernel_tap.h"
 #include "../virtio_logs.h"
-#include "../virtio_pci.h"
+#include "../virtio.h"
+
+
+int
+tap_support_features(unsigned int *tap_features)
+{
+       int tapfd;
+
+       tapfd = open(PATH_NET_TUN, O_RDWR);
+       if (tapfd < 0) {
+               PMD_DRV_LOG(ERR, "fail to open %s: %s",
+                           PATH_NET_TUN, strerror(errno));
+               return -1;
+       }
+
+       if (ioctl(tapfd, TUNGETFEATURES, tap_features) == -1) {
+               PMD_DRV_LOG(ERR, "TUNGETFEATURES failed: %s", strerror(errno));
+               close(tapfd);
+               return -1;
+       }
+
+       close(tapfd);
+       return 0;
+}
 
 int
 vhost_kernel_tap_set_offload(int fd, uint64_t features)
@@ -39,7 +62,7 @@ vhost_kernel_tap_set_offload(int fd, uint64_t features)
 
        /* Check if our kernel supports TUNSETOFFLOAD */
        if (ioctl(fd, TUNSETOFFLOAD, 0) != 0 && errno == EINVAL) {
-               PMD_DRV_LOG(ERR, "Kernel does't support TUNSETOFFLOAD\n");
+               PMD_DRV_LOG(ERR, "Kernel doesn't support TUNSETOFFLOAD\n");
                return -ENOTSUP;
        }
 
@@ -74,6 +97,7 @@ vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
        int sndbuf = INT_MAX;
        struct ifreq ifr;
        int tapfd;
+       int ret;
 
        /* TODO:
         * 1. verify we can get/set vnet_hdr_len, tap_probe_vnet_hdr_len
@@ -127,7 +151,10 @@ vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
                goto error;
        }
 
-       fcntl(tapfd, F_SETFL, O_NONBLOCK);
+       if (fcntl(tapfd, F_SETFL, O_NONBLOCK) < 0) {
+               PMD_DRV_LOG(ERR, "fcntl tapfd failed: %s", strerror(errno));
+               goto error;
+       }
 
        if (ioctl(tapfd, TUNSETVNETHDRSZ, &hdr_size) < 0) {
                PMD_DRV_LOG(ERR, "TUNSETVNETHDRSZ failed: %s", strerror(errno));
@@ -139,7 +166,9 @@ vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq,
                goto error;
        }
 
-       vhost_kernel_tap_set_offload(tapfd, features);
+       ret = vhost_kernel_tap_set_offload(tapfd, features);
+       if (ret < 0 && ret != -ENOTSUP)
+               goto error;
 
        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;