From 2a5fb5b868d0bfe416c80559a751b23b424daa30 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 15 Jun 2012 10:04:40 -0500 Subject: [PATCH] vpn: fix resetting parent device routing on disconnect 1fd11bd8d1bcbff5fe11aaea01d944b0084cd774 consolidated VPN connection state handling, but that had the effect of making vpn_cleanup() be called after all other handlers had processed the VPN connection state change. This meant that the code in vpn_cleanup() that reapplies the parent device's IP configs ran last, and that code flushes routes on the device before reapplying them. Since the policy is a listener on the VPN state change signals, it was running the default routing updates before vpn_cleanup() got run, resulting in vpn_cleanup()'s calls to nm_system_apply_ip4_config() and nm_system_apply_ip6_config() blowing the default route away which the policy had just set. Fix that by moving the VPN routing cleanups into the policy, where most of the routing decisions currently live, causing them to be run before the default route is fixed up. --- src/nm-policy.c | 46 +++++++++++++++++++++++++---- src/vpn-manager/nm-vpn-connection.c | 30 ------------------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 92fabe1a6c..bce37cc926 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -968,25 +968,59 @@ vpn_connection_deactivated (NMVPNManager *manager, gpointer user_data) { NMDnsManager *mgr; - NMIP4Config *ip4_config; - NMIP6Config *ip6_config; + NMIP4Config *ip4_config, *parent_ip4 = NULL; + NMIP6Config *ip6_config, *parent_ip6 = NULL; const char *ip_iface; + NMDevice *parent; mgr = nm_dns_manager_get (NULL); nm_dns_manager_begin_updates (mgr, __func__); ip_iface = nm_vpn_connection_get_ip_iface (vpn); - - /* Remove the VPN connection's IP configs from DNS */ + parent = nm_vpn_connection_get_parent_device (vpn); ip4_config = nm_vpn_connection_get_ip4_config (vpn); - if (ip4_config) + if (ip4_config) { + /* Remove the VPN connection's IP4 config from DNS */ nm_dns_manager_remove_ip4_config (mgr, ip_iface, ip4_config); + /* Re-apply routes and addresses of the VPN connection's parent interface, + * which the VPN might have overridden. + */ + if (parent) { + parent_ip4 = nm_device_get_ip4_config (parent); + if (parent_ip4) { + if (!nm_system_apply_ip4_config (nm_device_get_ip_ifindex (parent), + parent_ip4, + nm_device_get_priority (parent), + NM_IP4_COMPARE_FLAG_ADDRESSES | NM_IP4_COMPARE_FLAG_ROUTES)) { + nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device IPv4 addresses and routes."); + } + } + } + } + ip6_config = nm_vpn_connection_get_ip6_config (vpn); - if (ip6_config) + if (ip6_config) { + /* Remove the VPN connection's IP6 config from DNS */ nm_dns_manager_remove_ip6_config (mgr, ip_iface, ip6_config); + /* Re-apply routes and addresses of the VPN connection's parent interface, + * which the VPN might have overridden. + */ + if (parent) { + parent_ip6 = nm_device_get_ip6_config (parent); + if (parent_ip6) { + if (!nm_system_apply_ip6_config (nm_device_get_ip_ifindex (parent), + parent_ip6, + nm_device_get_priority (parent), + NM_IP6_COMPARE_FLAG_ADDRESSES | NM_IP6_COMPARE_FLAG_ROUTES)) { + nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device IPv6 addresses and routes."); + } + } + } + } + update_routing_and_dns ((NMPolicy *) user_data, TRUE); nm_dns_manager_end_updates (mgr, __func__); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index d06287e352..1d6c6c2a33 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -168,36 +168,6 @@ vpn_cleanup (NMVPNConnection *connection) nm_system_iface_flush_addresses (priv->ip_ifindex, AF_UNSPEC); } - if (priv->ip4_config) { - NMIP4Config *parent_config; - - /* Reset routes and addresses of the currently active device */ - parent_config = nm_device_get_ip4_config (priv->parent_dev); - if (parent_config) { - if (!nm_system_apply_ip4_config (nm_device_get_ip_ifindex (priv->parent_dev), - nm_device_get_ip4_config (priv->parent_dev), - nm_device_get_priority (priv->parent_dev), - NM_IP4_COMPARE_FLAG_ADDRESSES | NM_IP4_COMPARE_FLAG_ROUTES)) { - nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device addresses and routes."); - } - } - } - - if (priv->ip6_config) { - NMIP6Config *parent_config; - - /* Reset routes and addresses of the currently active device */ - parent_config = nm_device_get_ip6_config (priv->parent_dev); - if (parent_config) { - if (!nm_system_apply_ip6_config (nm_device_get_ip_ifindex (priv->parent_dev), - nm_device_get_ip6_config (priv->parent_dev), - nm_device_get_priority (priv->parent_dev), - NM_IP6_COMPARE_FLAG_ADDRESSES | NM_IP6_COMPARE_FLAG_ROUTES)) { - nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device addresses and routes."); - } - } - } - if (priv->gw_route) { nm_netlink_route_delete (priv->gw_route); rtnl_route_put (priv->gw_route);