From 94ea292a7d81edcfbb88004f0c0aa3718adf1f6b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 20:07:02 +0200 Subject: [PATCH 1/4] device: improve logging when changing IP configuration nm_device_set_ip4_config() is called during cleanup and from ip4_config_merge_and_apply(). The latter, has several call sites. It's not easy to track whether we called set_ip4_config with or without commit (and if we call it without commit, we might not see a logging line at all). (same for nm_device_set_ip6_config()/ip6_config_merge_and_apply()). (cherry picked from commit f50e39fc9852865ab6bb984d2db9b34d83263426) (cherry picked from commit a3b3e17bf91485b692a8de19d92b2ba9d7fadb8e) (cherry picked from commit c3946c3d2975015473d9552b537ed02b5f89be63) --- src/devices/nm-device.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 39977c6..aea1695 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6515,6 +6515,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_iface = nm_device_get_ip_iface (self); ip_ifindex = nm_device_get_ip_ifindex (self); @@ -6543,7 +6546,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_ip4_config_get_dbus_path (old_config)); } } else { @@ -6555,13 +6558,13 @@ nm_device_set_ip4_config (NMDevice *self, nm_ip4_config_export (new_config); } - _LOGD (LOGD_IP4, "set IP4Config instance (%s)", + _LOGD (LOGD_IP4, "ip4-config: set IP4Config instance (%s)", nm_ip4_config_get_dbus_path (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_ip4_config_get_dbus_path (old_config)); /* Device config is invalid if combined config is invalid */ g_clear_object (&priv->dev_ip4_config); @@ -6650,6 +6653,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_iface = nm_device_get_ip_iface (self); ip_ifindex = nm_device_get_ip_ifindex (self); @@ -6672,7 +6678,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_ip6_config_get_dbus_path (old_config)); } } else { @@ -6684,13 +6690,13 @@ nm_device_set_ip6_config (NMDevice *self, nm_ip6_config_export (new_config); } - _LOGD (LOGD_IP6, "set IP6Config instance (%s)", + _LOGD (LOGD_IP6, "ip6-config: set IP6Config instance (%s)", nm_ip6_config_get_dbus_path (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_ip6_config_get_dbus_path (old_config)); } -- 2.5.5 From 3ae0dce013f159884706ec5622276f54602c9be4 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 20:01:36 +0200 Subject: [PATCH 2/4] device: restore IP configuration when link comes up This is especially important, because changing MTU takes the link down for a moment. Taking a link down deletes IP routes and IPv6 addresses. Thus, when the link comes up again, we must restore them. Otherwise, we don't call merge_and_apply() until the next DHCP lease (or possibly never in case of static addressing). https://bugzilla.redhat.com/show_bug.cgi?id=1309899 (cherry picked from commit 35a7ea77b0dc5cddb8d8f0854499715ccf57287c) (cherry picked from commit 5367eac8146ef47f07f1bcfe1e3e74d381080706) (cherry picked from commit 6fa2405997d8399c3af64dcbde02e31dc59cc1e8) --- src/devices/nm-device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index aea1695..d35f8e9 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -370,6 +370,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 gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); @@ -1512,6 +1515,19 @@ device_link_changed (NMDevice *self) } } + 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; } -- 2.5.5 From d5c01bccd30e3fce6bd970950e1ecca57b07c519 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 15 Apr 2016 20:53:15 +0200 Subject: [PATCH 3/4] platform: ensure refetching routes when link goes down It's not enough to consider IF_LOWER_UP flag. Instead, the important flag is actually IF_UP. Actually, I suspect that IF_LOWER_UP is not needed. But for now leave it, in order not to break something. (cherry picked from commit 02e84ba1e8a98de20e4ef718d5069f64ca5398a0) (cherry picked from commit 11bfe8a88146b4ad8f05d2ea3c01f6e5b901c8dc) (cherry picked from commit 8d9e033ecd39e82a2dcc2500f75d92cf3c023da3) --- src/platform/nm-linux-platform.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index a218edb..62de84b 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1931,9 +1931,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.flags, IFF_LOWER_UP) && new->_link.netlink.is_in_netlink - && !NM_FLAGS_HAS (new->link.flags, IFF_LOWER_UP)) { + && ( ( NM_FLAGS_HAS (old->link.flags, IFF_UP) + && !NM_FLAGS_HAS (new->link.flags, IFF_UP)) + || ( NM_FLAGS_HAS (old->link.flags, IFF_LOWER_UP) + && !NM_FLAGS_HAS (new->link.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, -- 2.5.5 From eeb7f20b4104888306c5fa4973ce65cda30596ad Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sun, 29 May 2016 17:54:36 +0200 Subject: [PATCH 4/4] device: reconfigure IP addressing after bringing up device For changing the hardware address, we must bring the device down. When doing that, IP addressing is lost and it must be re-configured after bringing the device up again. We already do something similar in device_link_changed(), but that might not be sufficient, because device_link_changed() is run on an idle handler, thus, while changing the hardware address it has no chance to run (or notice that the device was shortly down). https://bugzilla.redhat.com/show_bug.cgi?id=1309899 (cherry picked from commit 63571b266634c6d8bbbb37f26e502c2df759fc65) (cherry picked from commit 951013d1e1182510366fb0de088179a3303ea65d) (cherry picked from commit e0805fc686bfdc01f2026dfb02263a4351f8f301) --- src/devices/nm-device.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index d35f8e9..98d50b2 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -7138,6 +7138,17 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) nm_device_update_hw_address (self); _update_ip4_address (self); + + /* when the link comes up, we must restore IP configuration if necessary. */ + if (priv->ip4_state == IP_DONE) { + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed applying IP4 config after bringing link up"); + } + if (priv->ip6_state == IP_DONE) { + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed applying IP6 config after bringing link up"); + } + return TRUE; } -- 2.5.5