diff -aur openvpn-2.3.2/src/openvpn/init.c src/src/openvpn/init.c
--- openvpn-2.3.2/src/openvpn/init.c	2013-05-31 14:00:25.000000000 +0200
+++ src/src/openvpn/init.c	2014-02-21 20:11:26.526011030 +0100
@@ -839,7 +839,7 @@
 void
 init_options_dev (struct options *options)
 {
-  if (!options->dev && options->dev_node) {
+  if (!options->dev && options->dev_from_fd == -1 && options->dev_node) {
     char *dev_node = strdup(options->dev_node); /* POSIX basename() implementaions may modify its arguments */
     options->dev = basename (dev_node);
   }
@@ -924,7 +924,8 @@
 	)
 	msg (M_FATAL|M_OPTERR,
 	     "options --mktun or --rmtun should only be used together with --dev");
-      tuncfg (options->dev, options->dev_type, options->dev_node,
+      tuncfg (options->dev, options->dev_from_fd,
+	      options->dev_type, options->dev_node,
 	      options->persist_mode,
 	      options->username, options->groupname, &options->tuntap_options);
       if (options->persist_mode && options->lladdr)
@@ -1431,7 +1487,8 @@
 	}
 
       /* open the tun device */
-      open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
+      open_tun (c->options.dev, c->options.dev_from_fd,
+		c->options.dev_type, c->options.dev_node,
 		c->c1.tuntap);
 
       /* set the hardware address */
diff -aur openvpn-2.3.2/src/openvpn/options.c src/src/openvpn/options.c
--- openvpn-2.3.2/src/openvpn/options.c	2013-05-31 14:00:25.000000000 +0200
+++ src/src/openvpn/options.c	2014-02-21 20:07:25.613699779 +0100
@@ -765,6 +765,7 @@
       gc_init (&o->gc);
       o->gc_owned = true;
     }
+  o->dev_from_fd = -1;
   o->mode = MODE_POINT_TO_POINT;
   o->topology = TOP_NET30;
   o->ce.proto = PROTO_UDPv4;
@@ -4268,6 +4269,11 @@
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->dev = p[1];
     }
+  else if (streq (p[0], "dev-from-fd") && p[1])
+    {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->dev_from_fd = positive_atoi(p[1]);
+    }
   else if (streq (p[0], "dev-type") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
diff -aur openvpn-2.3.2/src/openvpn/options.h src/src/openvpn/options.h
--- openvpn-2.3.2/src/openvpn/options.h	2013-05-31 14:00:25.000000000 +0200
+++ src/src/openvpn/options.h	2014-02-21 20:00:47.250347434 +0100
@@ -218,6 +218,7 @@
   bool remote_random;
   const char *ipchange;
   const char *dev;
+  int dev_from_fd;
   const char *dev_type;
   const char *dev_node;
   const char *lladdr;
diff -aur openvpn-2.3.2/src/openvpn/tun.c src/src/openvpn/tun.c
--- openvpn-2.3.2/src/openvpn/tun.c	2013-05-31 14:00:25.000000000 +0200
+++ src/src/openvpn/tun.c	2014-02-21 20:47:42.121330194 +0100
@@ -1379,7 +1379,7 @@
 #if !PEDANTIC
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   struct ifreq ifr;
 
@@ -1402,10 +1402,16 @@
       /*
        * Open the interface
        */
-      if ((tt->fd = open (node, O_RDWR)) < 0)
-	{
-	  msg (M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node);
-	}
+      if (dev_from_fd >= 0) {
+	      tt->fd = dup(dev_from_fd);
+	      strncpynt (ifr.ifr_name, dev, IFNAMSIZ);
+	      goto done;
+      } else {
+	      if ((tt->fd = open (node, O_RDWR)) < 0)
+	      {
+		      msg (M_ERR, "ERROR: Cannot open TUN/TAP dev %s", node);
+	      }
+      }
 
       /*
        * Process --tun-ipv6
@@ -1478,6 +1484,7 @@
       }
 #endif
 
+    done:
       set_nonblock (tt->fd);
       set_cloexec (tt->fd);
       tt->actual_name = string_alloc (ifr.ifr_name, NULL);
@@ -1488,7 +1495,7 @@
 #else
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   ASSERT (0);
 }
@@ -1498,7 +1505,7 @@
 #else
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, false, true, tt);
 }
@@ -1520,7 +1527,7 @@
 #endif
 
 void
-tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
+tuncfg (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
 {
   struct tuntap *tt;
 
@@ -1528,7 +1535,7 @@
   clear_tuntap (tt);
   tt->type = dev_type_enum (dev, dev_type);
   tt->options = *options;
-  open_tun (dev, dev_type, dev_node, tt);
+  open_tun (dev, dev_from_fd, dev_type, dev_node, tt);
   if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
     msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
   if (username != NULL)
@@ -1667,7 +1676,7 @@
 #endif
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
   struct lifreq ifr;
@@ -1990,7 +1999,7 @@
  */
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, true, true, tt);
 
@@ -2127,7 +2136,7 @@
  */
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
 #ifdef NETBSD_MULTI_AF
     open_tun_generic (dev, dev_type, dev_node, true, true, tt);
@@ -2274,7 +2283,7 @@
 }
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, true, true, tt);
 
@@ -2386,7 +2395,7 @@
 }
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, true, true, tt);
 
@@ -2468,7 +2477,7 @@
  */
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, true, true, tt);
 }
@@ -4518,7 +4527,7 @@
 }
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   struct gc_arena gc = gc_new ();
   char device_path[256];
@@ -5102,7 +5111,7 @@
 #else /* generic */
 
 void
-open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
+open_tun (const char *dev, int dev_from_fd, const char *dev_type, const char *dev_node, struct tuntap *tt)
 {
   open_tun_generic (dev, dev_type, dev_node, false, true, tt);
 }
diff -aur openvpn-2.3.2/src/openvpn/tun.h src/src/openvpn/tun.h
--- openvpn-2.3.2/src/openvpn/tun.h	2013-05-31 14:00:25.000000000 +0200
+++ src/src/openvpn/tun.h	2014-02-21 20:10:50.389363582 +0100
@@ -203,7 +203,8 @@
  * Function prototypes
  */
 
-void open_tun (const char *dev, const char *dev_type, const char *dev_node,
+void open_tun (const char *dev,
+	       int dev_from_fd, const char *dev_type, const char *dev_node,
 	       struct tuntap *tt);
 
 void close_tun (struct tuntap *tt);
@@ -212,7 +213,8 @@
 
 int read_tun (struct tuntap* tt, uint8_t *buf, int len);
 
-void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
+void tuncfg (const char *dev, int dev_from_fd,
+	     const char *dev_type, const char *dev_node,
 	     int persist_mode, const char *username,
 	     const char *groupname, const struct tuntap_options *options);
 
