From: Gert Doering Date: Sun, 22 Jan 2012 21:21:22 +0000 (+0200) Subject: Platform cleanup for FreeBSD X-Git-Tag: v2.3-alpha1~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62c613d46dc495d747074ca030d2cbdfd255c386;p=thirdparty%2Fopenvpn.git 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 URL: http://thread.gmane.org/gmane.network.openvpn.devel/5303 Acked-by: David Sommerseth Signed-off-by: David Sommerseth --- diff --git a/tun.c b/tun.c index ea0e2268b..c9af168da 100644 --- 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); } }