summaryrefslogtreecommitdiffstats
path: root/tun.c
diff options
context:
space:
mode:
authorGert Doering <gert@greenie.muc.de>2011-09-16 19:51:09 +0200
committerDavid Sommerseth <davids@redhat.com>2011-09-21 15:21:25 +0200
commit8ca19c014c149cf69257798afa6c75d1ff8f11a7 (patch)
tree6836b292510e3a96c48773e92a93c72079e41579 /tun.c
parentc02a84051297d97ba5955b93cdf479393b1dc1f8 (diff)
downloadopenvpn-8ca19c014c149cf69257798afa6c75d1ff8f11a7.tar.gz
openvpn-8ca19c014c149cf69257798afa6c75d1ff8f11a7.tar.xz
openvpn-8ca19c014c149cf69257798afa6c75d1ff8f11a7.zip
Platform cleanup for NetBSD
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>
Diffstat (limited to 'tun.c')
-rw-r--r--tun.c84
1 files changed, 68 insertions, 16 deletions
diff --git a/tun.c b/tun.c
index d121fc1..c8ac394 100644
--- 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",
@@ -965,6 +955,19 @@ do_ifconfig (struct tuntap *tt,
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
* so we don't need the "link0" extra parameter to specify we want to do
@@ -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);
}
}