device: merge branch 'th/device-ip-config-on-link-up-rh1309899'

https://bugzilla.redhat.com/show_bug.cgi?id=1309899
This commit is contained in:
Thomas Haller
2016-05-12 15:03:32 +02:00
2 changed files with 38 additions and 8 deletions

View File

@@ -397,6 +397,9 @@ static gboolean nm_device_set_ip6_config (NMDevice *self,
gboolean commit, gboolean commit,
gboolean routes_full_sync, gboolean routes_full_sync,
NMDeviceStateReason *reason); 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_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure);
static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success);
@@ -1561,6 +1564,7 @@ device_link_changed (NMDevice *self)
NMPlatformLink info; NMPlatformLink info;
const NMPlatformLink *pllink; const NMPlatformLink *pllink;
int ifindex; int ifindex;
gboolean was_up;
priv->device_link_changed_id = 0; priv->device_link_changed_id = 0;
@@ -1633,6 +1637,7 @@ device_link_changed (NMDevice *self)
if (ip_ifname_changed) if (ip_ifname_changed)
nm_device_update_dynamic_ip_setup (self); nm_device_update_dynamic_ip_setup (self);
was_up = priv->up;
priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP); priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
if ( info.initialized if ( info.initialized
@@ -1665,6 +1670,20 @@ device_link_changed (NMDevice *self)
set_unmanaged_external_down (self, FALSE); set_unmanaged_external_down (self, FALSE);
device_recheck_slave_status (self, &info); 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; 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); 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); priv = NM_DEVICE_GET_PRIVATE (self);
ip_ifindex = nm_device_get_ip_ifindex (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 */ * this causes a re-read and reset. This should only happen for relevant changes */
nm_ip4_config_replace (old_config, new_config, &has_changes); nm_ip4_config_replace (old_config, new_config, &has_changes);
if (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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
} }
} else { } else {
@@ -8106,13 +8128,13 @@ nm_device_set_ip4_config (NMDevice *self,
if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
nm_exported_object_export (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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
} }
} else if (old_config) { } else if (old_config) {
has_changes = TRUE; has_changes = TRUE;
priv->ip4_config = NULL; 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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
/* Device config is invalid if combined config is invalid */ /* Device config is invalid if combined config is invalid */
g_clear_object (&priv->dev_ip4_config); 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); 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); priv = NM_DEVICE_GET_PRIVATE (self);
ip_ifindex = nm_device_get_ip_ifindex (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 */ * this causes a re-read and reset. This should only happen for relevant changes */
nm_ip6_config_replace (old_config, new_config, &has_changes); nm_ip6_config_replace (old_config, new_config, &has_changes);
if (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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
} }
} else { } else {
@@ -8268,13 +8293,13 @@ nm_device_set_ip6_config (NMDevice *self,
if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config)))
nm_exported_object_export (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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config)));
} }
} else if (old_config) { } else if (old_config) {
has_changes = TRUE; has_changes = TRUE;
priv->ip6_config = NULL; 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))); nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config)));
} }

View File

@@ -3301,9 +3301,14 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
if ( ops_type == NMP_CACHE_OPS_UPDATED if ( ops_type == NMP_CACHE_OPS_UPDATED
&& old && new /* <-- nonsensical, make coverity happy */ && old && new /* <-- nonsensical, make coverity happy */
&& old->_link.netlink.is_in_netlink && old->_link.netlink.is_in_netlink
&& NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP)
&& new->_link.netlink.is_in_netlink && 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_schedule (platform,
DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES |
DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES,