From 965c7906f61e6de30adc1cc2d24ec73e345e0007 Mon Sep 17 00:00:00 2001 From: Selva Nair Date: Wed, 24 Jan 2018 12:31:45 -0500 Subject: [PATCH] Use lowest metric interface when multiple interfaces match a route Currently a route addition using IPAPI or service is skipped if the route gateway is reachable by multiple interfaces. This changes that to use the interface with lowest metric. Implemented by (i) Do not over-write the return value with TUN_ADAPTER_INDEX_INVALID in windows_route_find_if_index() if multiple interfaces match a route. (ii) Select the interface with lowest metric in adapter_index_of_ip() instead of the first one found when multiple interfaces match. Reported by Jan Just Keijser Signed-off-by: Selva Nair Tested-by: Jan Just Keijser Acked-by: Gert Doering Message-Id: <1516815105-17882-1-git-send-email-selva.nair@gmail.com> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16347.html Signed-off-by: Gert Doering (cherry picked from commit 3854d4040e0d6fd2a58292e8bb1c1fbae5c17bb1) --- src/openvpn/route.c | 1 - src/openvpn/tun.c | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 553008bea..d4625794c 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -2780,7 +2780,6 @@ windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt) msg(M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)", print_in_addr_t(r->gateway, 0, &gc), count); - ret = TUN_ADAPTER_INDEX_INVALID; } dmsg(D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d", diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 90050a8d9..ebb15bd3c 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -45,6 +45,7 @@ #include "manage.h" #include "route.h" #include "win32.h" +#include "block_dns.h" #include "memdbg.h" @@ -4480,6 +4481,7 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, struct gc_arena gc = gc_new(); DWORD ret = TUN_ADAPTER_INDEX_INVALID; in_addr_t highest_netmask = 0; + int lowest_metric = INT_MAX; bool first = true; if (count) @@ -4493,9 +4495,14 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, if (is_ip_in_adapter_subnet(list, ip, &hn)) { + int metric = get_interface_metric(list->Index, AF_INET, NULL); if (first || hn > highest_netmask) { highest_netmask = hn; + if (metric >= 0) + { + lowest_metric = metric; + } if (count) { *count = 1; @@ -4509,16 +4516,22 @@ adapter_index_of_ip(const IP_ADAPTER_INFO *list, { ++*count; } + if (metric >= 0 && metric < lowest_metric) + { + ret = list->Index; + lowest_metric = metric; + } } } list = list->Next; } - dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d", + dmsg(D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d", print_in_addr_t(ip, 0, &gc), print_in_addr_t(highest_netmask, 0, &gc), (int)ret, - count ? *count : -1); + count ? *count : -1, + lowest_metric); if (ret == TUN_ADAPTER_INDEX_INVALID && count) { -- 2.47.2