diff --git a/net/tap-linux.c b/net/tap-linux.c
index 0f621a2..21f0167 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -36,10 +36,20 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
 {
     struct ifreq ifr;
     int fd, ret;
+    int open_named;
+    char *devname;
+
+    if (ifname_size >= 1 && *ifname == "/") {
+	open_named = 1;
+	devname = ifname;
+    } else {
+	open_named = 0;
+	devname = "/dev/net/tun";
+    }
 
-    TFR(fd = open("/dev/net/tun", O_RDWR));
+    TFR(fd = open(devname, O_RDWR));
     if (fd < 0) {
-        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
+        fprintf(stderr, "warning: could not open %s: no virtual network emulation\n", devname);
         return -1;
     }
     memset(&ifr, 0, sizeof(ifr));
@@ -62,17 +72,20 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
         }
     }
 
-    if (ifname[0] != '\0')
-        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
-    else
-        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
-    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
-    if (ret != 0) {
-        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
-        close(fd);
-        return -1;
+    if (!open_named) {
+	if (ifname[0] != '\0')
+	    pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
+	else
+	    pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
+	ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
+	if (ret != 0) {
+	    fprintf(stderr, "warning: could not configure %s: no virtual "
+		    "network emulation\n", devname);
+	    close(fd);
+	    return -1;
+	}
+	pstrcpy(ifname, ifname_size, ifr.ifr_name);
     }
-    pstrcpy(ifname, ifname_size, ifr.ifr_name);
     fcntl(fd, F_SETFL, O_NONBLOCK);
     return fd;
 }
