]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Platform cleanup for NetBSD
authorGert Doering <gert@greenie.muc.de>
Fri, 16 Sep 2011 17:51:09 +0000 (19:51 +0200)
committerDavid Sommerseth <davids@redhat.com>
Wed, 21 Sep 2011 13:21:25 +0000 (15:21 +0200)
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>
syshead.h
tun.c

index 66a25386d4307b57ccd2a681b6300cd9b5f5e1a8..bb8e180dc9a5c7d15a668283ec79b9956b74b0f6 100644 (file)
--- a/syshead.h
+++ b/syshead.h
 #include <net/if.h>
 #endif
 
+#ifdef TARGET_NETBSD
+#include <net/if_tap.h>
+#endif
+
 #ifdef TARGET_LINUX
 
 #if defined(HAVE_NETINET_IF_ETHER_H)
diff --git a/tun.c b/tun.c
index d121fc1f6870761ac018fbb0ef25b429e96341bd..c8ac394ebfba625fcb92ca9645418fa5f6feb355 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -945,16 +945,6 @@ do_ifconfig (struct tuntap *tt,
 # define NETBSD_MULTI_AF
 #endif
 
-      /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface
-       */
-      argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual );
-      argv_msg (M_INFO, &argv);
-      openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed");
-
-      argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual );
-      argv_msg (M_INFO, &argv);
-      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed");
-
       if (tun)
        argv_printf (&argv,
                          "%s %s %s %s mtu %d netmask 255.255.255.255 up",
@@ -964,6 +954,19 @@ do_ifconfig (struct tuntap *tt,
                          ifconfig_remote_netmask,
                          tun_mtu
                          );
+      else
+       if ( tt->topology == TOP_SUBNET )
+       {
+           argv_printf (&argv,
+                         "%s %s %s %s mtu %d netmask %s up",
+                         IFCONFIG_PATH,
+                         actual,
+                         ifconfig_local,
+                         ifconfig_local,
+                         tun_mtu,
+                         ifconfig_remote_netmask
+                         );
+       }
       else
       /*
        * NetBSD has distinct tun and tap devices
@@ -1264,6 +1267,30 @@ open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
           * explicit unit number.  Try opening /dev/[dev]n
           * where n = [0, 255].
           */
+#ifdef TARGET_NETBSD
+         /* on NetBSD, tap (but not tun) devices are opened by
+           * opening /dev/tap and then querying the system about the
+          * actual device name (tap0, tap1, ...) assigned
+           */
+         if ( dynamic && strcmp( dev, "tap" ) == 0 )
+           {
+             struct ifreq ifr;
+             if ((tt->fd = open ( "/dev/tap", O_RDWR)) < 0)
+               {
+                 msg (M_FATAL, "Cannot allocate NetBSD TAP dev dynamically");
+               }
+             if ( ioctl( tt->fd, TAPGIFNAME, (void*)&ifr ) < 0 )
+               {
+                 msg (M_FATAL, "Cannot query NetBSD TAP device name");
+               }
+             CLEAR(dynamic_name);
+             strncpy( dynamic_name, ifr.ifr_name, sizeof(dynamic_name)-1 );
+             dynamic_opened = true;
+             openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dynamic_name );
+           }
+         else
+#endif
+
          if (dynamic && !has_digit((unsigned char *)dev))
            {
              int i;
@@ -2084,24 +2111,49 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
         ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
 
 #ifdef NETBSD_MULTI_AF
-        i = 1;
-        if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0)        /* multi-af mode on */
+       if ( tt->type == DEV_TYPE_TUN )
          {
-           msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
+           i = 1;
+           if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0)     /* multi-af mode on */
+             {
+               msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
+             }
          }
 #endif
       }
 }
 
+/* the current way OpenVPN handles tun devices on NetBSD leads to
+ * lingering tunX interfaces after close -> for a full cleanup, they
+ * need to be explicitely destroyed
+ */
 void
 close_tun (struct tuntap *tt)
 {
-  /* TODO: we really should cleanup non-persistant tunX with 
-   * "ifconfig tunX destroy" here...
+  /* only tun devices need destroying, tap devices auto-self-destruct
    */
-  if (tt)
+  if (tt && tt->type != DEV_TYPE_TUN )
     {
       close_tun_generic (tt);
+      free(tt);
+    }
+  else if (tt)
+    {
+      struct gc_arena gc = gc_new ();
+      struct argv argv;
+
+      /* setup command, close tun dev (clears tt->actual_name!), run command
+       */
+
+      argv_init (&argv);
+      argv_printf (&argv, "%s %s destroy",
+                          IFCONFIG_PATH, tt->actual_name);
+
+      close_tun_generic (tt);
+
+      argv_msg (M_INFO, &argv);
+      openvpn_execve_check (&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)");
+
       free (tt);
     }
 }