Browse code

Implement search for "first free" tun/tap device on Solaris

Without this patch, Solaris will do "--dev tun3" just fine, but "--dev tun"
will either use "tun0" if that is available, or fail. With the patch, the
first available device is searched if "--dev tun" or "--dev tap" (without
a number) is specified.

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: David Sommerseth <davids@redhat.com>
Message-Id: 20120607174638.GW1059@greenie.muc.de
URL: http://article.gmane.org/gmane.network.openvpn.devel/6705
Signed-off-by: David Sommerseth <davids@redhat.com>

Gert Doering authored on 2012/06/08 00:38:17
Showing 1 changed files
... ...
@@ -1711,6 +1711,12 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
1711 1711
       msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1712 1712
 	   dev);
1713 1713
     }
1714
+
1715
+  if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
1716
+    msg (M_ERR, "Can't open %s", ip_node);
1717
+
1718
+  if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
1719
+    msg (M_ERR, "Can't open %s", dev_node);
1714 1720
   
1715 1721
   /* get unit number */
1716 1722
   if (*dev)
... ...
@@ -1721,19 +1727,37 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
1721 1721
       ppa = atoi (ptr);
1722 1722
     }
1723 1723
 
1724
-  if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
1725
-    msg (M_ERR, "Can't open %s", ip_node);
1726
-
1727
-  if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
1728
-    msg (M_ERR, "Can't open %s", dev_node);
1729
-
1730 1724
   /* Assign a new PPA and get its unit number. */
1731 1725
   strioc_ppa.ic_cmd = TUNNEWPPA;
1732 1726
   strioc_ppa.ic_timout = 0;
1733 1727
   strioc_ppa.ic_len = sizeof(ppa);
1734 1728
   strioc_ppa.ic_dp = (char *)&ppa;
1735
-  if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
1736
-    msg (M_ERR, "Can't assign new interface");
1729
+
1730
+  if ( *ptr == '\0' )		/* no number given, try dynamic */
1731
+    {
1732
+      bool found_one = false;
1733
+      while( ! found_one && ppa < 64 )
1734
+	{
1735
+	  int new_ppa = ioctl (tt->fd, I_STR, &strioc_ppa);
1736
+	  if ( new_ppa >= 0 )
1737
+	    {
1738
+	      msg( M_INFO, "open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
1739
+	      ppa = new_ppa;
1740
+	      found_one = true;
1741
+	      break;
1742
+	    }
1743
+	  if ( errno != EEXIST )
1744
+	    msg (M_ERR, "open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
1745
+	  ppa++;
1746
+	}
1747
+      if ( !found_one )
1748
+	msg (M_ERR, "open_tun: could not find free %s interface, give up.", dev_tuntap_type );
1749
+    }
1750
+  else				/* try this particular one */
1751
+    {
1752
+      if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
1753
+        msg (M_ERR, "Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
1754
+    }
1737 1755
 
1738 1756
   if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
1739 1757
     msg (M_ERR, "Can't open %s (2)", dev_node);