Browse code

Platform cleanup for NetBSD

make TAP devices work (need to go via multiplex device /dev/tap)
cleanup TUN devices at program end ("ifconfig tunX destroy")
correctly setup TUN devices for "topology subnet"
don't try to put TAP devices into TUNSIFHEAD mode (get rid of error message)

Tested on NetBSD 5.1_STABLE / Sparc64

Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>

Gert Doering authored on 2011/09/17 02:51:09
Showing 2 changed files
... ...
@@ -213,6 +213,10 @@
213 213
 #include <net/if.h>
214 214
 #endif
215 215
 
216
+#ifdef TARGET_NETBSD
217
+#include <net/if_tap.h>
218
+#endif
219
+
216 220
 #ifdef TARGET_LINUX
217 221
 
218 222
 #if defined(HAVE_NETINET_IF_ETHER_H)
... ...
@@ -945,16 +945,6 @@ do_ifconfig (struct tuntap *tt,
945 945
 # define NETBSD_MULTI_AF
946 946
 #endif
947 947
 
948
-      /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface
949
-       */
950
-      argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual );
951
-      argv_msg (M_INFO, &argv);
952
-      openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed");
953
-
954
-      argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual );
955
-      argv_msg (M_INFO, &argv);
956
-      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed");
957
-
958 948
       if (tun)
959 949
 	argv_printf (&argv,
960 950
 			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
... ...
@@ -965,6 +955,19 @@ do_ifconfig (struct tuntap *tt,
965 965
 			  tun_mtu
966 966
 			  );
967 967
       else
968
+	if ( tt->topology == TOP_SUBNET )
969
+	{
970
+	    argv_printf (&argv,
971
+			  "%s %s %s %s mtu %d netmask %s up",
972
+			  IFCONFIG_PATH,
973
+			  actual,
974
+			  ifconfig_local,
975
+			  ifconfig_local,
976
+			  tun_mtu,
977
+			  ifconfig_remote_netmask
978
+			  );
979
+	}
980
+      else
968 981
       /*
969 982
        * NetBSD has distinct tun and tap devices
970 983
        * so we don't need the "link0" extra parameter to specify we want to do 
... ...
@@ -1264,6 +1267,30 @@ open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
1264 1264
 	   * explicit unit number.  Try opening /dev/[dev]n
1265 1265
 	   * where n = [0, 255].
1266 1266
 	   */
1267
+#ifdef TARGET_NETBSD
1268
+	  /* on NetBSD, tap (but not tun) devices are opened by
1269
+           * opening /dev/tap and then querying the system about the
1270
+	   * actual device name (tap0, tap1, ...) assigned
1271
+           */
1272
+	  if ( dynamic && strcmp( dev, "tap" ) == 0 )
1273
+	    {
1274
+	      struct ifreq ifr;
1275
+	      if ((tt->fd = open ( "/dev/tap", O_RDWR)) < 0)
1276
+		{
1277
+		  msg (M_FATAL, "Cannot allocate NetBSD TAP dev dynamically");
1278
+		}
1279
+	      if ( ioctl( tt->fd, TAPGIFNAME, (void*)&ifr ) < 0 )
1280
+		{
1281
+		  msg (M_FATAL, "Cannot query NetBSD TAP device name");
1282
+		}
1283
+	      CLEAR(dynamic_name);
1284
+	      strncpy( dynamic_name, ifr.ifr_name, sizeof(dynamic_name)-1 );
1285
+	      dynamic_opened = true;
1286
+	      openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dynamic_name );
1287
+	    }
1288
+	  else
1289
+#endif
1290
+
1267 1291
 	  if (dynamic && !has_digit((unsigned char *)dev))
1268 1292
 	    {
1269 1293
 	      int i;
... ...
@@ -2084,24 +2111,49 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
2084 2084
         ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
2085 2085
 
2086 2086
 #ifdef NETBSD_MULTI_AF
2087
-        i = 1;
2088
-        if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) 	/* multi-af mode on */
2087
+	if ( tt->type == DEV_TYPE_TUN )
2089 2088
 	  {
2090
-	    msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2089
+	    i = 1;
2090
+	    if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) 	/* multi-af mode on */
2091
+	      {
2092
+		msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2093
+	      }
2091 2094
 	  }
2092 2095
 #endif
2093 2096
       }
2094 2097
 }
2095 2098
 
2099
+/* the current way OpenVPN handles tun devices on NetBSD leads to
2100
+ * lingering tunX interfaces after close -> for a full cleanup, they
2101
+ * need to be explicitely destroyed
2102
+ */
2096 2103
 void
2097 2104
 close_tun (struct tuntap *tt)
2098 2105
 {
2099
-  /* TODO: we really should cleanup non-persistant tunX with 
2100
-   * "ifconfig tunX destroy" here...
2106
+  /* only tun devices need destroying, tap devices auto-self-destruct
2101 2107
    */
2102
-  if (tt)
2108
+  if (tt && tt->type != DEV_TYPE_TUN )
2103 2109
     {
2104 2110
       close_tun_generic (tt);
2111
+      free(tt);
2112
+    }
2113
+  else if (tt)
2114
+    {
2115
+      struct gc_arena gc = gc_new ();
2116
+      struct argv argv;
2117
+
2118
+      /* setup command, close tun dev (clears tt->actual_name!), run command
2119
+       */
2120
+
2121
+      argv_init (&argv);
2122
+      argv_printf (&argv, "%s %s destroy",
2123
+                          IFCONFIG_PATH, tt->actual_name);
2124
+
2125
+      close_tun_generic (tt);
2126
+
2127
+      argv_msg (M_INFO, &argv);
2128
+      openvpn_execve_check (&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)");
2129
+
2105 2130
       free (tt);
2106 2131
     }
2107 2132
 }