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>
... | ... |
@@ -945,16 +945,6 @@ do_ifconfig (struct tuntap *tt, |
945 | 945 |
# define NETBSD_MULTI_AF |
946 | 946 |
#endif |
947 | 947 |
|
948 |
- /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface |
|
949 |
- */ |
|
950 |
- argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual ); |
|
951 |
- argv_msg (M_INFO, &argv); |
|
952 |
- openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed"); |
|
953 |
- |
|
954 |
- argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual ); |
|
955 |
- argv_msg (M_INFO, &argv); |
|
956 |
- openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed"); |
|
957 |
- |
|
958 | 948 |
if (tun) |
959 | 949 |
argv_printf (&argv, |
960 | 950 |
"%s %s %s %s mtu %d netmask 255.255.255.255 up", |
... | ... |
@@ -965,6 +955,19 @@ do_ifconfig (struct tuntap *tt, |
965 | 965 |
tun_mtu |
966 | 966 |
); |
967 | 967 |
else |
968 |
+ if ( tt->topology == TOP_SUBNET ) |
|
969 |
+ { |
|
970 |
+ argv_printf (&argv, |
|
971 |
+ "%s %s %s %s mtu %d netmask %s up", |
|
972 |
+ IFCONFIG_PATH, |
|
973 |
+ actual, |
|
974 |
+ ifconfig_local, |
|
975 |
+ ifconfig_local, |
|
976 |
+ tun_mtu, |
|
977 |
+ ifconfig_remote_netmask |
|
978 |
+ ); |
|
979 |
+ } |
|
980 |
+ else |
|
968 | 981 |
/* |
969 | 982 |
* NetBSD has distinct tun and tap devices |
970 | 983 |
* 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, |
1264 | 1264 |
* explicit unit number. Try opening /dev/[dev]n |
1265 | 1265 |
* where n = [0, 255]. |
1266 | 1266 |
*/ |
1267 |
+#ifdef TARGET_NETBSD |
|
1268 |
+ /* on NetBSD, tap (but not tun) devices are opened by |
|
1269 |
+ * opening /dev/tap and then querying the system about the |
|
1270 |
+ * actual device name (tap0, tap1, ...) assigned |
|
1271 |
+ */ |
|
1272 |
+ if ( dynamic && strcmp( dev, "tap" ) == 0 ) |
|
1273 |
+ { |
|
1274 |
+ struct ifreq ifr; |
|
1275 |
+ if ((tt->fd = open ( "/dev/tap", O_RDWR)) < 0) |
|
1276 |
+ { |
|
1277 |
+ msg (M_FATAL, "Cannot allocate NetBSD TAP dev dynamically"); |
|
1278 |
+ } |
|
1279 |
+ if ( ioctl( tt->fd, TAPGIFNAME, (void*)&ifr ) < 0 ) |
|
1280 |
+ { |
|
1281 |
+ msg (M_FATAL, "Cannot query NetBSD TAP device name"); |
|
1282 |
+ } |
|
1283 |
+ CLEAR(dynamic_name); |
|
1284 |
+ strncpy( dynamic_name, ifr.ifr_name, sizeof(dynamic_name)-1 ); |
|
1285 |
+ dynamic_opened = true; |
|
1286 |
+ openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dynamic_name ); |
|
1287 |
+ } |
|
1288 |
+ else |
|
1289 |
+#endif |
|
1290 |
+ |
|
1267 | 1291 |
if (dynamic && !has_digit((unsigned char *)dev)) |
1268 | 1292 |
{ |
1269 | 1293 |
int i; |
... | ... |
@@ -2084,24 +2111,49 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu |
2084 | 2084 |
ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */ |
2085 | 2085 |
|
2086 | 2086 |
#ifdef NETBSD_MULTI_AF |
2087 |
- i = 1; |
|
2088 |
- if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ |
|
2087 |
+ if ( tt->type == DEV_TYPE_TUN ) |
|
2089 | 2088 |
{ |
2090 |
- msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); |
|
2089 |
+ i = 1; |
|
2090 |
+ if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ |
|
2091 |
+ { |
|
2092 |
+ msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); |
|
2093 |
+ } |
|
2091 | 2094 |
} |
2092 | 2095 |
#endif |
2093 | 2096 |
} |
2094 | 2097 |
} |
2095 | 2098 |
|
2099 |
+/* the current way OpenVPN handles tun devices on NetBSD leads to |
|
2100 |
+ * lingering tunX interfaces after close -> for a full cleanup, they |
|
2101 |
+ * need to be explicitely destroyed |
|
2102 |
+ */ |
|
2096 | 2103 |
void |
2097 | 2104 |
close_tun (struct tuntap *tt) |
2098 | 2105 |
{ |
2099 |
- /* TODO: we really should cleanup non-persistant tunX with |
|
2100 |
- * "ifconfig tunX destroy" here... |
|
2106 |
+ /* only tun devices need destroying, tap devices auto-self-destruct |
|
2101 | 2107 |
*/ |
2102 |
- if (tt) |
|
2108 |
+ if (tt && tt->type != DEV_TYPE_TUN ) |
|
2103 | 2109 |
{ |
2104 | 2110 |
close_tun_generic (tt); |
2111 |
+ free(tt); |
|
2112 |
+ } |
|
2113 |
+ else if (tt) |
|
2114 |
+ { |
|
2115 |
+ struct gc_arena gc = gc_new (); |
|
2116 |
+ struct argv argv; |
|
2117 |
+ |
|
2118 |
+ /* setup command, close tun dev (clears tt->actual_name!), run command |
|
2119 |
+ */ |
|
2120 |
+ |
|
2121 |
+ argv_init (&argv); |
|
2122 |
+ argv_printf (&argv, "%s %s destroy", |
|
2123 |
+ IFCONFIG_PATH, tt->actual_name); |
|
2124 |
+ |
|
2125 |
+ close_tun_generic (tt); |
|
2126 |
+ |
|
2127 |
+ argv_msg (M_INFO, &argv); |
|
2128 |
+ openvpn_execve_check (&argv, NULL, 0, "NetBSD 'destroy tun interface' failed (non-critical)"); |
|
2129 |
+ |
|
2105 | 2130 |
free (tt); |
2106 | 2131 |
} |
2107 | 2132 |
} |