While at it, small Solaris cleanup - use CLEAR() to zero-out "ifr" struct.
Tested on Windows XP SP3 and Win7 by Gert Doering and Tony Lim.
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -392,3 +392,49 @@ So 24. Apr 16:51:45 CEST 2011 |
392 | 392 |
|
393 | 393 |
* TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6 |
394 | 394 |
|
395 |
+Thu Apr 28 19:10:01 CEST 2011 |
|
396 |
+ |
|
397 |
+ * rebase to "origin/release/2.2" branch (at v2.2.0 tag) |
|
398 |
+ |
|
399 |
+Thu May 19 20:51:12 CEST 2011 |
|
400 |
+ |
|
401 |
+ * include Windows "netsh add" -> "netsh set ... store=active" patch from |
|
402 |
+ Seth Mos, to fix restart problems on Windows due to persistant addresses |
|
403 |
+ |
|
404 |
+ * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6 |
|
405 |
+ |
|
406 |
+Sat May 21 17:03:20 CEST 2011 |
|
407 |
+ |
|
408 |
+ * tun.c: Solaris cleanup (use CLEAR() to zero-out "ifr") |
|
409 |
+ |
|
410 |
+ * tun.c: Windows cleanup: remove route and IPv6 address on disconnect |
|
411 |
+ |
|
412 |
+ * route.c, route.h: remove "static" from delete_route_ipv6(), needed |
|
413 |
+ for ipv6-route cleanup on disconnect |
|
414 |
+ |
|
415 |
+ * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6 |
|
416 |
+ |
|
417 |
+ * TEST SUCCESS: Windows 7 Home Premium: client-tun/net30, v4+v6 |
|
418 |
+ |
|
419 |
+So 22. Mai 14:46:12 CEST 2011 |
|
420 |
+ |
|
421 |
+ * Tony Lim: removing routes fails on windows if certain bits are set |
|
422 |
+ in the "host part" (others are silently ignored) --> |
|
423 |
+ |
|
424 |
+ * route.c: create print_in6_addr_netbits_only() helper, call from |
|
425 |
+ add_route_ipv6() and delete_route_ipv6() to get only network part |
|
426 |
+ of route-to-be-modified |
|
427 |
+ |
|
428 |
+ * route.c: set 'store=active' on adding routes on WIN32 as well (Tony Lim) |
|
429 |
+ |
|
430 |
+ * options.c: bump IPv6 release to 20110522-1 |
|
431 |
+ |
|
432 |
+ * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6 |
|
433 |
+ |
|
434 |
+ * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6 |
|
435 |
+ |
|
436 |
+ * TEST SUCCESS: Windows 7 Home Premium: client-tun/net30, v4+v6 |
|
437 |
+ |
|
438 |
+ * TEST SUCCESS: OpenBSD 4.7: client-tun/net30, v4+v6 |
|
439 |
+ TEST FAIL: OpenBSD 4.7: client-tun/subnet, v4 |
|
440 |
+ (seems to be due to "topology subnet has just not been implemented yet") |
... | ... |
@@ -40,7 +40,6 @@ |
40 | 40 |
#include "memdbg.h" |
41 | 41 |
|
42 | 42 |
static void delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
43 |
-static void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
|
44 | 43 |
static void get_bypass_addresses (struct route_bypass *rb, const unsigned int flags); |
45 | 44 |
|
46 | 45 |
#ifdef ENABLE_DEBUG |
... | ... |
@@ -1264,6 +1263,29 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s |
1264 | 1264 |
gc_free (&gc); |
1265 | 1265 |
} |
1266 | 1266 |
|
1267 |
+ |
|
1268 |
+static const char * |
|
1269 |
+print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits, |
|
1270 |
+ struct gc_arena * gc) |
|
1271 |
+{ |
|
1272 |
+ /* clear host bit parts of route |
|
1273 |
+ * (needed if routes are specified improperly, or if we need to |
|
1274 |
+ * explicitely setup/clear the "connected" network routes on some OSes) |
|
1275 |
+ */ |
|
1276 |
+ int byte = 15; |
|
1277 |
+ int bits_to_clear = 128 - netbits; |
|
1278 |
+ |
|
1279 |
+ while( byte >= 0 && bits_to_clear > 0 ) |
|
1280 |
+ { |
|
1281 |
+ if ( bits_to_clear >= 8 ) |
|
1282 |
+ { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; } |
|
1283 |
+ else |
|
1284 |
+ { network_copy.s6_addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; } |
|
1285 |
+ } |
|
1286 |
+ |
|
1287 |
+ return print_in6_addr( network_copy, 0, gc); |
|
1288 |
+} |
|
1289 |
+ |
|
1267 | 1290 |
void |
1268 | 1291 |
add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es) |
1269 | 1292 |
{ |
... | ... |
@@ -1274,8 +1296,6 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla |
1274 | 1274 |
const char *gateway; |
1275 | 1275 |
bool status = false; |
1276 | 1276 |
const char *device = tt->actual_name; |
1277 |
- int byte, bits_to_clear; |
|
1278 |
- struct in6_addr network_copy = r6->network; |
|
1279 | 1277 |
|
1280 | 1278 |
if (!r6->defined) |
1281 | 1279 |
return; |
... | ... |
@@ -1283,22 +1303,7 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla |
1283 | 1283 |
gc_init (&gc); |
1284 | 1284 |
argv_init (&argv); |
1285 | 1285 |
|
1286 |
- /* clear host bit parts of route |
|
1287 |
- * (needed if routes are specified improperly, or if we need to |
|
1288 |
- * explicitely setup the "connected" network routes on some OSes) |
|
1289 |
- */ |
|
1290 |
- byte = 15; |
|
1291 |
- bits_to_clear = 128 - r6->netbits; |
|
1292 |
- |
|
1293 |
- while( byte >= 0 && bits_to_clear > 0 ) |
|
1294 |
- { |
|
1295 |
- if ( bits_to_clear >= 8 ) |
|
1296 |
- { network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; } |
|
1297 |
- else |
|
1298 |
- { network_copy.s6_addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; } |
|
1299 |
- } |
|
1300 |
- |
|
1301 |
- network = print_in6_addr( network_copy, 0, &gc); |
|
1286 |
+ network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc); |
|
1302 | 1287 |
gateway = print_in6_addr( r6->gateway, 0, &gc); |
1303 | 1288 |
|
1304 | 1289 |
if ( !tt->ipv6 ) |
... | ... |
@@ -1363,6 +1368,11 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla |
1363 | 1363 |
argv_printf_cat (&argv, " METRIC %d", r->metric); |
1364 | 1364 |
#endif |
1365 | 1365 |
|
1366 |
+ /* in some versions of Windows, routes are persistent across reboots by |
|
1367 |
+ * default, unless "store=active" is set (pointed out by Tony Lim, thanks) |
|
1368 |
+ */ |
|
1369 |
+ argv_printf_cat( &argv, " store=active" ); |
|
1370 |
+ |
|
1366 | 1371 |
argv_msg (D_ROUTE, &argv); |
1367 | 1372 |
|
1368 | 1373 |
netcmd_semaphore_lock (); |
... | ... |
@@ -1573,7 +1583,7 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags |
1573 | 1573 |
gc_free (&gc); |
1574 | 1574 |
} |
1575 | 1575 |
|
1576 |
-static void |
|
1576 |
+void |
|
1577 | 1577 |
delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es) |
1578 | 1578 |
{ |
1579 | 1579 |
struct gc_arena gc; |
... | ... |
@@ -1588,7 +1598,7 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne |
1588 | 1588 |
gc_init (&gc); |
1589 | 1589 |
argv_init (&argv); |
1590 | 1590 |
|
1591 |
- network = print_in6_addr( r6->network, 0, &gc); |
|
1591 |
+ network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc); |
|
1592 | 1592 |
gateway = print_in6_addr( r6->gateway, 0, &gc); |
1593 | 1593 |
|
1594 | 1594 |
if ( !tt->ipv6 ) |
... | ... |
@@ -176,6 +176,7 @@ struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_are |
176 | 176 |
|
177 | 177 |
void add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
178 | 178 |
void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
179 |
+void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es); |
|
179 | 180 |
|
180 | 181 |
void add_route_to_option_list (struct route_option_list *l, |
181 | 182 |
const char *network, |
... | ... |
@@ -591,6 +591,18 @@ void add_route_connected_v6_net(struct tuntap * tt, |
591 | 591 |
r6.gateway = tt->local_ipv6; |
592 | 592 |
add_route_ipv6 (&r6, tt, 0, es); |
593 | 593 |
} |
594 |
+ |
|
595 |
+void delete_route_connected_v6_net(struct tuntap * tt, |
|
596 |
+ const struct env_set *es) |
|
597 |
+{ |
|
598 |
+ struct route_ipv6 r6; |
|
599 |
+ |
|
600 |
+ r6.defined = true; |
|
601 |
+ r6.network = tt->local_ipv6; |
|
602 |
+ r6.netbits = tt->netbits_ipv6; |
|
603 |
+ r6.gateway = tt->local_ipv6; |
|
604 |
+ delete_route_ipv6 (&r6, tt, 0, es); |
|
605 |
+} |
|
594 | 606 |
#endif |
595 | 607 |
|
596 | 608 |
|
... | ... |
@@ -1649,7 +1661,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu |
1649 | 1649 |
* http://www.whiteboard.ne.jp/~admin2/tuntap/ |
1650 | 1650 |
* has IPv6 support |
1651 | 1651 |
*/ |
1652 |
- memset(&ifr, 0x0, sizeof(ifr)); |
|
1652 |
+ CLEAR(ifr); |
|
1653 | 1653 |
|
1654 | 1654 |
if (tt->type == DEV_TYPE_NULL) |
1655 | 1655 |
{ |
... | ... |
@@ -4851,9 +4863,23 @@ close_tun (struct tuntap *tt) |
4851 | 4851 |
{ |
4852 | 4852 |
if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) |
4853 | 4853 |
{ |
4854 |
+ struct argv argv; |
|
4855 |
+ argv_init (&argv); |
|
4856 |
+ |
|
4857 |
+ /* remove route pointing to interface */ |
|
4858 |
+ delete_route_connected_v6_net(tt, NULL); |
|
4859 |
+ |
|
4854 | 4860 |
/* netsh interface ipv6 delete address \"%s\" %s */ |
4855 | 4861 |
const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc); |
4856 |
- msg( M_WARN, "TODO: remove IPv6 address %s", ifconfig_ipv6_local ); |
|
4862 |
+ argv_printf (&argv, |
|
4863 |
+ "%s%sc interface ipv6 delete address %s %s", |
|
4864 |
+ get_win_sys_path(), |
|
4865 |
+ NETSH_PATH_SUFFIX, |
|
4866 |
+ tt->actual_name, |
|
4867 |
+ ifconfig_ipv6_local ); |
|
4868 |
+ |
|
4869 |
+ netsh_command (&argv, 1); |
|
4870 |
+ argv_reset (&argv); |
|
4857 | 4871 |
} |
4858 | 4872 |
#if 1 |
4859 | 4873 |
if (tt->ipapi_context_defined) |