From 710406e74635ec03776dc49aa2de6d2bc0f6ff5f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 20 Dec 2018 09:35:34 +0100 Subject: [PATCH] device: ensure IP configuration is restored when link goes up When the link is up and goes down link_changed_cb() schedules device_link_changed() to be run later. If the function is dispatched when the link is already up again, it does not detect that the link was down. Fix this by storing in the device state that we saw the link down so that device_link_changed() can properly restore the IP configuration. https://bugzilla.redhat.com/show_bug.cgi?id=1636715 https://github.com/NetworkManager/NetworkManager/pull/264 (cherry picked from commit 7bd193ef30fb2a1d4c328bb61412e35a5bccfced) --- src/devices/nm-device.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 186f184554..42457f7135 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -392,6 +392,7 @@ typedef struct _NMDevicePrivate { bool ipv6ll_handle:1; /* TRUE if NM handles the device's IPv6LL address */ bool ipv6ll_has:1; + bool device_link_changed_down:1; /* Generic DHCP stuff */ char * dhcp_anycast_address; @@ -3592,8 +3593,10 @@ device_link_changed (NMDevice *self) gboolean was_up; gboolean update_unmanaged_specs = FALSE; gboolean got_hw_addr = FALSE, had_hw_addr; + gboolean seen_down = priv->device_link_changed_down; priv->device_link_changed_id = 0; + priv->device_link_changed_down = FALSE; ifindex = nm_device_get_ifindex (self); pllink = nm_platform_link_get (nm_device_get_platform (self), ifindex); @@ -3703,7 +3706,7 @@ device_link_changed (NMDevice *self) device_recheck_slave_status (self, pllink); - if (priv->up && !was_up) { + if (priv->up && (!was_up || seen_down)) { /* 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) { @@ -3779,6 +3782,8 @@ link_changed_cb (NMPlatform *platform, priv = NM_DEVICE_GET_PRIVATE (self); if (ifindex == nm_device_get_ifindex (self)) { + if (!(info->n_ifi_flags & IFF_UP)) + priv->device_link_changed_down = TRUE; if (!priv->device_link_changed_id) { priv->device_link_changed_id = g_idle_add ((GSourceFunc) device_link_changed, self); _LOGD (LOGD_DEVICE, "queued link change for ifindex %d", ifindex);