From: Selva Nair <selva.n...@gmail.com> Currently we use netsh for this. The new code closely follows what interactive service does.
Signed-off-by: Selva Nair <selva.n...@gmail.com> --- src/openvpn/route.c | 175 ++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 104 deletions(-) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index ded8fec8..eabfe0a5 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -65,6 +65,8 @@ static bool add_route_ipv6_service(const struct route_ipv6 *, const struct tunta static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *); +static bool route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *); + #endif static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx); @@ -1975,58 +1977,8 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, } else { - DWORD adapter_index; - if (r6->adapter_index) /* vpn server special route */ - { - adapter_index = r6->adapter_index; - gateway_needed = true; - } - else - { - adapter_index = tt->adapter_index; - } - - /* netsh interface ipv6 add route 2001:db8::/32 42 */ - argv_printf(&argv, "%s%s interface ipv6 add route %s/%d %lu", - get_win_sys_path(), - NETSH_PATH_SUFFIX, - network, - r6->netbits, - adapter_index); - - /* next-hop depends on TUN or TAP mode: - * - in TAP mode, we use the "real" next-hop - * - in TUN mode we use a special-case link-local address that the tapdrvr - * knows about and will answer ND (neighbor discovery) packets for - */ - if (tt->type == DEV_TYPE_TUN && !gateway_needed) - { - argv_printf_cat( &argv, " %s", "fe80::8" ); - } - else if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) ) - { - argv_printf_cat( &argv, " %s", gateway ); - } - -#if 0 - if (r6->flags & RT_METRIC_DEFINED) - { - argv_printf_cat(&argv, " METRIC %d", r->metric); - } -#endif - - /* in some versions of Windows, routes are persistent across reboots by - * default, unless "store=active" is set (pointed out by Tony Lim, thanks) - */ - argv_printf_cat( &argv, " store=active" ); - - argv_msg(D_ROUTE, &argv); - - netcmd_semaphore_lock(); - status = openvpn_execve_check(&argv, es, 0, "ERROR: Windows route add ipv6 command failed"); - netcmd_semaphore_release(); + status = route_ipv6_ipapi(true, r6, tt); } - #elif defined (TARGET_SOLARIS) /* example: route add -inet6 2001:db8::/32 somegateway 0 */ @@ -2416,60 +2368,8 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, } else { - DWORD adapter_index; - if (r6->adapter_index) /* vpn server special route */ - { - adapter_index = r6->adapter_index; - gateway_needed = true; - } - else - { - adapter_index = tt->adapter_index; - } - - /* netsh interface ipv6 delete route 2001:db8::/32 42 */ - argv_printf(&argv, "%s%s interface ipv6 delete route %s/%d %lu", - get_win_sys_path(), - NETSH_PATH_SUFFIX, - network, - r6->netbits, - adapter_index); - - /* next-hop depends on TUN or TAP mode: - * - in TAP mode, we use the "real" next-hop - * - in TUN mode we use a special-case link-local address that the tapdrvr - * knows about and will answer ND (neighbor discovery) packets for - * (and "route deletion without specifying next-hop" does not work...) - */ - if (tt->type == DEV_TYPE_TUN && !gateway_needed) - { - argv_printf_cat( &argv, " %s", "fe80::8" ); - } - else if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) ) - { - argv_printf_cat( &argv, " %s", gateway ); - } - -#if 0 - if (r6->flags & RT_METRIC_DEFINED) - { - argv_printf_cat(&argv, "METRIC %d", r->metric); - } -#endif - - /* Windows XP to 7 "just delete" routes, wherever they came from, but - * in Windows 8(.1?), if you create them with "store=active", this is - * how you should delete them as well (pointed out by Cedric Tabary) - */ - argv_printf_cat( &argv, " store=active" ); - - argv_msg(D_ROUTE, &argv); - - netcmd_semaphore_lock(); - openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete ipv6 command failed"); - netcmd_semaphore_release(); + route_ipv6_ipapi(false, r6, tt); } - #elif defined (TARGET_SOLARIS) /* example: route delete -inet6 2001:db8::/32 somegateway */ @@ -3049,6 +2949,73 @@ do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct t return do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel); } +/* Add or delete an ipv6 route */ +static bool +route_ipv6_ipapi(const bool add, const struct route_ipv6 *r, const struct tuntap *tt) +{ + DWORD err; + PMIB_IPFORWARD_ROW2 fwd_row; + struct gc_arena gc = gc_new(); + + fwd_row = gc_malloc(sizeof(*fwd_row), true, &gc); + + fwd_row->ValidLifetime = 0xffffffff; + fwd_row->PreferredLifetime = 0xffffffff; + fwd_row->Protocol = MIB_IPPROTO_NETMGMT; + fwd_row->Metric = ((r->flags & RT_METRIC_DEFINED) ? r->metric : -1); + fwd_row->DestinationPrefix.Prefix.si_family = AF_INET6; + fwd_row->DestinationPrefix.Prefix.Ipv6.sin6_addr = r->network; + fwd_row->DestinationPrefix.PrefixLength = (UINT8) r->netbits; + fwd_row->NextHop.si_family = AF_INET6; + fwd_row->NextHop.Ipv6.sin6_addr = r->gateway; + fwd_row->InterfaceIndex = r->adapter_index ? r->adapter_index : tt->adapter_index; + + /* In TUN mode we use a special link-local address as the next hop. + * The tapdrvr knows about it and will answer neighbor discovery packets. + * (only do this for routes actually using the tun/tap device) + */ + if (tt->type == DEV_TYPE_TUN && !r->adapter_index) + { + inet_pton(AF_INET6, "fe80::8", &fwd_row->NextHop.Ipv6.sin6_addr); + } + + /* Use LUID if interface index not available */ + if (fwd_row->InterfaceIndex == TUN_ADAPTER_INDEX_INVALID && strlen(tt->actual_name)) + { + NET_LUID luid; + err = ConvertInterfaceAliasToLuid(wide_string(tt->actual_name, &gc), &luid); + if (err != NO_ERROR) + { + goto out; + } + fwd_row->InterfaceLuid = luid; + fwd_row->InterfaceIndex = 0; + } + + if (add) + { + err = CreateIpForwardEntry2(fwd_row); + } + else + { + err = DeleteIpForwardEntry2(fwd_row); + } + +out: + if (err != NO_ERROR) + { + msg(M_WARN, "ROUTE: route %s failed using ipapi: %s [status=%lu if_index=%lu]", + (add ? "addition" : "deletion"), strerror_win32(err, &gc), err, fwd_row->InterfaceIndex); + } + else + { + msg(D_ROUTE, "IPv6 route %s using ipapi", add ? "added" : "deleted"); + } + gc_free(&gc); + + return (err == NO_ERROR); +} + static bool do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt) { -- 2.34.1 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel