Hi, the current "master" code on FreeBSD has two problems:
- tun or tap devices are not removed at program end, so a "dead" interface is left behind - not critical, but we should not do that -> call "ifconfig destroy" in tun_close(). - "topology subnet" for IPv4 causes failure for IPv6 (because the interface is ioctl()'ed to IFF_BROADCAST mode, which changes the IPv6 behaviour to "use neighbour discovery", which would have to be implemented by the OpenVPN server - and isn't, as of today). With my change, the interface is left as "point to point" interface (which it really is), but routing and ifconfig is setup with the proper netmask, so all interesting packets are still sent down the tun if to OpenVPN. Patch below, auto-tested for tun and tap devices on FreeBSD 7.4 and FreeBSD 8.2 on amd64. (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. I'm just mentioning it here for the sake of the archives, in case someone else falls over it) gert -- USENET is *not* the non-clickable part of WWW! //www.muc.de/~gert/ Gert Doering - Munich, Germany g...@greenie.muc.de fax: +49-89-35655025 g...@net.informatik.tu-muenchen.de
From 1b9e8c58bebde6be369859078d41ef48001a35d5 Mon Sep 17 00:00:00 2001 From: Gert Doering <g...@fbsd74.ov.greenie.net> List-Post: openvpn-devel@lists.sourceforge.net Date: Sun, 22 Jan 2012 23:21:22 +0200 Subject: [PATCH] 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) Tested with IPv4 and IPv6 on 7.4-RELEASE/amd64 and 8.2-RELEASE/amd64 Signed-off-by: Gert Doering <g...@greenie.muc.de> --- tun.c | 37 ++++++++++++++++++++++++++++++++++--- 1 files changed, 34 insertions(+), 3 deletions(-) diff --git a/tun.c b/tun.c index ea0e226..5285b86 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); } } -- 1.7.3.5
pgpXZrpKLxUXw.pgp
Description: PGP signature