From 227aebf4b6d1cdf764f2eb75d2d1970038d80a91 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 4 Nov 2014 11:51:03 +0100 Subject: policy: fix updating the default route for VPN When adding a default route fails, the most common reason is that we don't have a direct route to the gateway. In that case, NMPolicy tries to add a direct route to the gateway and then retries adding the default route. For VPN however, previously NMPolicy would not added a direct route to the gateway via the VPN device. Instead it would add a direct route to the external gateway via the parent interface. That is wrong. Indeed the external gateway must be reachable directly not via the VPN interface itself. But for that the vpn connection already sets a route via nm_device_set_vpn4_config(). Signed-off-by: Thomas Haller --- src/nm-policy.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 480364e9b9..3394fc7e8a 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -675,27 +675,26 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) } if (vpn) { - NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - int parent_ifindex = nm_device_get_ip_ifindex (parent); - NMIP4Config *parent_ip4 = nm_device_get_ip4_config (parent); - guint32 parent_mss = parent_ip4 ? nm_ip4_config_get_mss (parent_ip4) : 0; in_addr_t int_gw = nm_vpn_connection_get_ip4_internal_gateway (vpn); int mss = nm_ip4_config_get_mss (ip4_config); /* If no VPN interface, use the parent interface */ if (ip_ifindex <= 0) - ip_ifindex = parent_ifindex; + ip_ifindex = nm_device_get_ip_ifindex (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn))); if (!nm_platform_ip4_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, 0, 0, int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip4_route_add (parent_ifindex, NM_IP_CONFIG_SOURCE_VPN, - gw_addr, 32, 0, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip4_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, - 0, 0, int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) - nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set default route."); + if (int_gw) { + (void) nm_platform_ip4_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, + int_gw, 32, 0, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); + if (!nm_platform_ip4_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, + 0, 0, int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) + nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set IPv4 default route via VPN."); + } else + nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set IPv4 default route via VPN."); } default_device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); @@ -892,10 +891,6 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) } if (vpn) { - NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - int parent_ifindex = nm_device_get_ip_ifindex (parent); - NMIP6Config *parent_ip6 = nm_device_get_ip6_config (parent); - guint32 parent_mss = parent_ip6 ? nm_ip6_config_get_mss (parent_ip6) : 0; const struct in6_addr *int_gw = nm_vpn_connection_get_ip6_internal_gateway (vpn); int mss = nm_ip6_config_get_mss (ip6_config); @@ -904,19 +899,21 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) /* If no VPN interface, use the parent interface */ if (ip_ifindex <= 0) - ip_ifindex = parent_ifindex; + ip_ifindex = nm_device_get_ip_ifindex (nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn))); if (!nm_platform_ip6_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, in6addr_any, 0, *int_gw, NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip6_route_add (parent_ifindex, NM_IP_CONFIG_SOURCE_VPN, - *gw_addr, 128, in6addr_any, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip6_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, - in6addr_any, 0, *int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set default route."); - } + if (!IN6_IS_ADDR_UNSPECIFIED (int_gw)) { + (void) nm_platform_ip6_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, + *int_gw, 128, in6addr_any, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); + if (!nm_platform_ip6_route_add (ip_ifindex, NM_IP_CONFIG_SOURCE_VPN, + in6addr_any, 0, *int_gw, + NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) + nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set IPv6 default route via VPN."); + } else + nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set IPv6 default route via VPN."); } default_device6 = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); -- cgit v1.2.1