diff options
author | Thomas Haller <thaller@redhat.com> | 2016-05-12 15:03:32 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-05-12 15:03:32 +0200 |
commit | 05010747b2818bcf08cf93f52f4ce24dc02d10c2 (patch) | |
tree | a4ddbb83d93eed06de3f17e3c82f6180c24991ed | |
parent | ba90c9601c44a507848359111830ff5d91ad1aa9 (diff) | |
parent | 02e84ba1e8a98de20e4ef718d5069f64ca5398a0 (diff) | |
download | NetworkManager-05010747b2818bcf08cf93f52f4ce24dc02d10c2.tar.gz |
device: merge branch 'th/device-ip-config-on-link-up-rh1309899'
https://bugzilla.redhat.com/show_bug.cgi?id=1309899
-rw-r--r-- | src/devices/nm-device.c | 37 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 9 |
2 files changed, 38 insertions, 8 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 178e02b73e..ee0075956d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -397,6 +397,9 @@ static gboolean nm_device_set_ip6_config (NMDevice *self, gboolean commit, gboolean routes_full_sync, NMDeviceStateReason *reason); +static gboolean ip6_config_merge_and_apply (NMDevice *self, + gboolean commit, + NMDeviceStateReason *out_reason); static void nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); @@ -1561,6 +1564,7 @@ device_link_changed (NMDevice *self) NMPlatformLink info; const NMPlatformLink *pllink; int ifindex; + gboolean was_up; priv->device_link_changed_id = 0; @@ -1633,6 +1637,7 @@ device_link_changed (NMDevice *self) if (ip_ifname_changed) nm_device_update_dynamic_ip_setup (self); + was_up = priv->up; priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP); if ( info.initialized @@ -1665,6 +1670,20 @@ device_link_changed (NMDevice *self) set_unmanaged_external_down (self, FALSE); device_recheck_slave_status (self, &info); + + if (priv->up && !was_up) { + /* the link was down and just came up. That happens for example, while changing MTU. + * We must restore IP configuration. */ + if (priv->ip4_state == IP_DONE) { + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed applying IP4 config after link comes up again"); + } + if (priv->ip6_state == IP_DONE) { + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed applying IP6 config after link comes up again"); + } + } + return G_SOURCE_REMOVE; } @@ -8063,6 +8082,9 @@ nm_device_set_ip4_config (NMDevice *self, g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + _LOGD (LOGD_IP4, "ip4-config: update (commit=%d, routes-full-sync=%d, new-config=%p)", + commit, routes_full_sync, new_config); + priv = NM_DEVICE_GET_PRIVATE (self); ip_ifindex = nm_device_get_ip_ifindex (self); @@ -8096,7 +8118,7 @@ nm_device_set_ip4_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip4_config_replace (old_config, new_config, &has_changes); if (has_changes) { - _LOGD (LOGD_IP4, "update IP4Config instance (%s)", + _LOGD (LOGD_IP4, "ip4-config: update IP4Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); } } else { @@ -8106,13 +8128,13 @@ nm_device_set_ip4_config (NMDevice *self, if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) nm_exported_object_export (NM_EXPORTED_OBJECT (new_config)); - _LOGD (LOGD_IP4, "set IP4Config instance (%s)", + _LOGD (LOGD_IP4, "ip4-config: set IP4Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config))); } } else if (old_config) { has_changes = TRUE; priv->ip4_config = NULL; - _LOGD (LOGD_IP4, "clear IP4Config instance (%s)", + _LOGD (LOGD_IP4, "ip4-config: clear IP4Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); /* Device config is invalid if combined config is invalid */ g_clear_object (&priv->dev_ip4_config); @@ -8231,6 +8253,9 @@ nm_device_set_ip6_config (NMDevice *self, g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + _LOGD (LOGD_IP6, "ip6-config: update (commit=%d, routes-full-sync=%d, new-config=%p)", + commit, routes_full_sync, new_config); + priv = NM_DEVICE_GET_PRIVATE (self); ip_ifindex = nm_device_get_ip_ifindex (self); @@ -8258,7 +8283,7 @@ nm_device_set_ip6_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip6_config_replace (old_config, new_config, &has_changes); if (has_changes) { - _LOGD (LOGD_IP6, "update IP6Config instance (%s)", + _LOGD (LOGD_IP6, "ip6-config: update IP6Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); } } else { @@ -8268,13 +8293,13 @@ nm_device_set_ip6_config (NMDevice *self, if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) nm_exported_object_export (NM_EXPORTED_OBJECT (new_config)); - _LOGD (LOGD_IP6, "set IP6Config instance (%s)", + _LOGD (LOGD_IP6, "ip6-config: set IP6Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config))); } } else if (old_config) { has_changes = TRUE; priv->ip6_config = NULL; - _LOGD (LOGD_IP6, "clear IP6Config instance (%s)", + _LOGD (LOGD_IP6, "ip6-config: clear IP6Config instance (%s)", nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 24a100efa1..82e673a3c1 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3301,9 +3301,14 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP if ( ops_type == NMP_CACHE_OPS_UPDATED && old && new /* <-- nonsensical, make coverity happy */ && old->_link.netlink.is_in_netlink - && NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP) && new->_link.netlink.is_in_netlink - && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP)) { + && ( ( NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_UP) + && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_UP)) + || ( NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP) + && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP)))) { + /* FIXME: I suspect that IFF_LOWER_UP must not be considered, and I + * think kernel does send RTM_DELROUTE events for IPv6 routes, so + * we might not need to refresh IPv6 routes. */ delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, |