]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Platform cleanup for FreeBSD
authorGert Doering <gert@fbsd74.ov.greenie.net>
Sun, 22 Jan 2012 21:21:22 +0000 (23:21 +0200)
committerDavid Sommerseth <davids@redhat.com>
Mon, 23 Jan 2012 09:04:10 +0000 (10:04 +0100)
- cleanup TUN/TAP devices at program end ("ifconfig ... destroy")
- make TUN device setup for "topology subnet" work together with IPv6
  (setup correct netmask and route, but do not use IFF_BROADCAST)

There's one catch for FreeBSD 8.2 if you use pf(4): it will block IPv6
fragments by default, so the standard t_client.sh test sets fail unless
you specifically add "pass in on tun1 fragment" rules - but there's
nothing OpenVPN can do about it.

Tested with IPv4 and IPv6 on 7.4-RELEASE/amd64 and 8.2-RELEASE/amd64

Signed-off-by: Gert Doering <gert@greenie.muc.de>
URL: http://thread.gmane.org/gmane.network.openvpn.devel/5303
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
tun.c

diff --git a/tun.c b/tun.c
index ea0e2268bfbf498894e66027142d6e5aff20945d..c9af168da24350ce2cbd3e949e6537ea54be82a9 100644 (file)
--- a/tun.c
+++ b/tun.c
@@ -1098,6 +1098,18 @@ 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
        argv_printf (&argv,
                      "%s %s %s netmask %s mtu %d up",
@@ -2246,10 +2258,8 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
 
   if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
     {
-      int i = 0;
+      int i = IFF_POINTOPOINT | IFF_MULTICAST;
 
-      i = tt->topology == TOP_SUBNET ? IFF_BROADCAST : IFF_POINTOPOINT;
-      i |= IFF_MULTICAST;
       if (ioctl (tt->fd, TUNSIFMODE, &i) < 0) {
        msg (M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno));
       }
@@ -2260,12 +2270,33 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
     }
 }
 
+/* tun(4): "These network interfaces persist until the if_tun.ko module is
+ *          unloaded, or until removed with the ifconfig(8) command."
+ *          (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4))
+ *
+ * so, to avoid lingering tun/tap interfaces after OpenVPN quits,
+ * we need to call "ifconfig ... destroy" for cleanup
+ */
 void
 close_tun (struct tuntap *tt)
 {
   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, "FreeBSD 'destroy tun interface' failed (non-critical)");
+
       free (tt);
     }
 }