Browse code

Platform cleanup for FreeBSD

- 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>

Gert Doering authored on 2012/01/23 06:21:22
Showing 1 changed files
... ...
@@ -1098,6 +1098,18 @@ do_ifconfig (struct tuntap *tt,
1098 1098
 			  ifconfig_remote_netmask,
1099 1099
 			  tun_mtu
1100 1100
 			  );
1101
+      else if ( tt->topology == TOP_SUBNET )
1102
+	{
1103
+	    argv_printf (&argv,
1104
+			  "%s %s %s %s mtu %d netmask %s up",
1105
+			  IFCONFIG_PATH,
1106
+			  actual,
1107
+			  ifconfig_local,
1108
+			  ifconfig_local,
1109
+			  tun_mtu,
1110
+			  ifconfig_remote_netmask
1111
+			  );
1112
+	}
1101 1113
       else
1102 1114
 	argv_printf (&argv,
1103 1115
 		      "%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
2246 2246
 
2247 2247
   if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2248 2248
     {
2249
-      int i = 0;
2249
+      int i = IFF_POINTOPOINT | IFF_MULTICAST;
2250 2250
 
2251
-      i = tt->topology == TOP_SUBNET ? IFF_BROADCAST : IFF_POINTOPOINT;
2252
-      i |= IFF_MULTICAST;
2253 2251
       if (ioctl (tt->fd, TUNSIFMODE, &i) < 0) {
2254 2252
 	msg (M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno));
2255 2253
       }
... ...
@@ -2260,12 +2270,33 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
2260 2260
     }
2261 2261
 }
2262 2262
 
2263
+/* tun(4): "These network interfaces persist until the if_tun.ko module is
2264
+ *          unloaded, or until removed with the ifconfig(8) command."
2265
+ *          (verified for FreeBSD 6.3, 7.4, 8.2 and 9, same for tap(4))
2266
+ *
2267
+ * so, to avoid lingering tun/tap interfaces after OpenVPN quits,
2268
+ * we need to call "ifconfig ... destroy" for cleanup
2269
+ */
2263 2270
 void
2264 2271
 close_tun (struct tuntap *tt)
2265 2272
 {
2266 2273
   if (tt)
2267 2274
     {
2275
+      struct gc_arena gc = gc_new ();
2276
+      struct argv argv;
2277
+
2278
+      /* setup command, close tun dev (clears tt->actual_name!), run command
2279
+       */
2280
+
2281
+      argv_init (&argv);
2282
+      argv_printf (&argv, "%s %s destroy",
2283
+                          IFCONFIG_PATH, tt->actual_name);
2284
+
2268 2285
       close_tun_generic (tt);
2286
+
2287
+      argv_msg (M_INFO, &argv);
2288
+      openvpn_execve_check (&argv, NULL, 0, "FreeBSD 'destroy tun interface' failed (non-critical)");
2289
+
2269 2290
       free (tt);
2270 2291
     }
2271 2292
 }