summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-02-03 11:15:47 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2019-02-04 09:43:12 +0100
commit266b226dbaa99ad9e1dcf5a9d603f9161999323e (patch)
tree9d01049943d145f829a34c1b536f8de561936315
parent027ef98cd4b44937d07c331868f1efa01b8e8e7c (diff)
downloadNetworkManager-bg/issue93.tar.gz
vpn: add route to vpn gw when parent has a default device routebg/issue93
When the parent device has a device default route (i.e. without gateway) and we establish a VPN on top of it, 'ip route get' for the VPN gateway returns a device route, which is the same result we get for an unreachable VPN gateway. However it is necessary to add the route to the gateway or otherwise it will possibly become unreachable once the VPN gets activated. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/93
-rw-r--r--src/vpn/nm-vpn-connection.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index 6626f64a04..c7cfcdcdfd 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -729,15 +729,23 @@ add_ip4_vpn_gateway_route (NMIP4Config *config,
const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (route_resolved);
if (r->ifindex == ifindex) {
+ const NMPObject *obj;
+
/* `ip route get` always resolves the route, even if the destination is unreachable.
* In which case, it pretends the destination is directly reachable.
*
- * So, only accept direct routes, if @vpn_gw is a private network. */
- if ( nm_platform_route_table_is_main (r->table_coerced)
- && ( r->gateway
- || nm_utils_ip_is_site_local (AF_INET, &vpn_gw))) {
- parent_gw = r->gateway;
- has_parent_gw = TRUE;
+ * So, only accept direct routes if @vpn_gw is a private network
+ * or if the parent device also has a direct default route */
+ if (nm_platform_route_table_is_main (r->table_coerced)) {
+ if (r->gateway) {
+ parent_gw = r->gateway;
+ has_parent_gw = TRUE;
+ } else if (nm_utils_ip_is_site_local (AF_INET, &vpn_gw)) {
+ has_parent_gw = TRUE;
+ } else if ( (obj = nm_device_get_best_default_route (parent_device, AF_INET))
+ && !NMP_OBJECT_CAST_IP4_ROUTE (obj)->gateway) {
+ has_parent_gw = TRUE;
+ }
}
}
}
@@ -803,15 +811,23 @@ add_ip6_vpn_gateway_route (NMIP6Config *config,
const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (route_resolved);
if (r->ifindex == ifindex) {
+ const NMPObject *obj;
+
/* `ip route get` always resolves the route, even if the destination is unreachable.
* In which case, it pretends the destination is directly reachable.
*
- * So, only accept direct routes, if @vpn_gw is a private network. */
- if ( nm_platform_route_table_is_main (r->table_coerced)
- && ( !IN6_IS_ADDR_UNSPECIFIED (&r->gateway)
- || nm_utils_ip_is_site_local (AF_INET6, &vpn_gw))) {
- parent_gw = &r->gateway;
- has_parent_gw = TRUE;
+ * So, only accept direct routes if @vpn_gw is a private network
+ * or if the parent device also has a direct default route */
+ if (nm_platform_route_table_is_main (r->table_coerced)) {
+ if (!IN6_IS_ADDR_UNSPECIFIED (&r->gateway)) {
+ parent_gw = &r->gateway;
+ has_parent_gw = TRUE;
+ } else if (nm_utils_ip_is_site_local (AF_INET6, &vpn_gw)) {
+ has_parent_gw = TRUE;
+ } else if ( (obj = nm_device_get_best_default_route (parent_device, AF_INET6))
+ && IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (obj)->gateway)) {
+ has_parent_gw = TRUE;
+ }
}
}
}