From 6466b5da6aca2ba29adeaf1ae1641cd6083d878c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 16 Mar 2017 14:54:16 +0100 Subject: [PATCH] device: force restart of IP method during reapply Scenario: Have a connection with DHCPv4 and a default-route. When externally removing the default route (`ip route delete 0.0.0.0/0`) and issuing `nmcli device reapply $IF`, the default route was not restored. That was because when externally removing the default route, we would remove the gateway from priv->con_ip4_config (see update_ip4_config()). Later, when reapplying the connection, the IP method doesn't actually change. So we would not restart DHCP and thus there is no gateway around to add the default route. The default route would only be restored after receiving a DHCP lease in the far future. Fix that, by always restarting the IP method. --- src/devices/nm-device-vlan.c | 2 +- src/devices/nm-device.c | 44 +++++++++++++++++++++--------------- src/devices/nm-device.h | 6 +++-- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 2680353ca0..54d0440960 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -121,7 +121,7 @@ parent_hwaddr_maybe_changed (NMDevice *parent, */ s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - nm_device_reactivate_ip6_config (NM_DEVICE (self), s_ip6, s_ip6); + nm_device_reactivate_ip6_config (NM_DEVICE (self), s_ip6, s_ip6, FALSE); } } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 88fbe78692..cb1cc63707 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -8418,7 +8418,8 @@ _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, void nm_device_reactivate_ip4_config (NMDevice *self, NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new) + NMSettingIPConfig *s_ip4_new, + gboolean force_restart) { NMDevicePrivate *priv; const char *method_old, *method_new; @@ -8434,14 +8435,17 @@ nm_device_reactivate_ip4_config (NMDevice *self, s_ip4_new, nm_device_get_ip4_route_metric (self)); - method_old = s_ip4_old ? - nm_setting_ip_config_get_method (s_ip4_old) : - NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - method_new = s_ip4_new ? - nm_setting_ip_config_get_method (s_ip4_new) : - NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + if (!force_restart) { + method_old = s_ip4_old + ? nm_setting_ip_config_get_method (s_ip4_old) + : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + method_new = s_ip4_new + ? nm_setting_ip_config_get_method (s_ip4_new) + : NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + force_restart = !nm_streq0 (method_old, method_new); + } - if (!nm_streq0 (method_old, method_new)) { + if (force_restart) { _cleanup_ip4_pre (self, CLEANUP_TYPE_DECONFIGURE); _set_ip_state (self, AF_INET, IP_WAIT); if (!nm_device_activate_stage3_ip4_start (self)) @@ -8456,7 +8460,8 @@ nm_device_reactivate_ip4_config (NMDevice *self, void nm_device_reactivate_ip6_config (NMDevice *self, NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new) + NMSettingIPConfig *s_ip6_new, + gboolean force_restart) { NMDevicePrivate *priv; const char *method_old, *method_new; @@ -8472,14 +8477,17 @@ nm_device_reactivate_ip6_config (NMDevice *self, s_ip6_new, nm_device_get_ip6_route_metric (self)); - method_old = s_ip6_old ? - nm_setting_ip_config_get_method (s_ip6_old) : - NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - method_new = s_ip6_new ? - nm_setting_ip_config_get_method (s_ip6_new) : - NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + if (!force_restart) { + method_old = s_ip6_old + ? nm_setting_ip_config_get_method (s_ip6_old) + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + method_new = s_ip6_new + ? nm_setting_ip_config_get_method (s_ip6_new) + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + force_restart = !nm_streq0 (method_old, method_new); + } - if (!nm_streq0 (method_old, method_new)) { + if (force_restart) { _cleanup_ip6_pre (self, CLEANUP_TYPE_DECONFIGURE); _set_ip_state (self, AF_INET6, IP_WAIT); if (!nm_device_activate_stage3_ip6_start (self)) @@ -8693,8 +8701,8 @@ check_and_reapply_connection (NMDevice *self, s_ip6_old = nm_connection_get_setting_ip6_config (con_old); s_ip6_new = nm_connection_get_setting_ip6_config (con_new); - nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new); - nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new); + nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new, TRUE); + nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new, TRUE); reactivate_proxy_config (self); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index d1e9a9455a..f98978bdc0 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -657,10 +657,12 @@ void nm_device_update_firewall_zone (NMDevice *self); void nm_device_update_metered (NMDevice *self); void nm_device_reactivate_ip4_config (NMDevice *device, NMSettingIPConfig *s_ip4_old, - NMSettingIPConfig *s_ip4_new); + NMSettingIPConfig *s_ip4_new, + gboolean force_restart); void nm_device_reactivate_ip6_config (NMDevice *device, NMSettingIPConfig *s_ip6_old, - NMSettingIPConfig *s_ip6_new); + NMSettingIPConfig *s_ip6_new, + gboolean force_restart); gboolean nm_device_update_hw_address (NMDevice *self); void nm_device_update_initial_hw_address (NMDevice *self);