summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-05-12 15:03:32 +0200
committerThomas Haller <thaller@redhat.com>2016-05-12 15:03:32 +0200
commit05010747b2818bcf08cf93f52f4ce24dc02d10c2 (patch)
treea4ddbb83d93eed06de3f17e3c82f6180c24991ed
parentba90c9601c44a507848359111830ff5d91ad1aa9 (diff)
parent02e84ba1e8a98de20e4ef718d5069f64ca5398a0 (diff)
downloadNetworkManager-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.c37
-rw-r--r--src/platform/nm-linux-platform.c9
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,