device: don't allways set assumed reason when platform init is done
authorLubomir Rintel <lkundrak@v3.sk>
Thu, 18 Feb 2016 15:13:23 +0000 (16:13 +0100)
committerLubomir Rintel <lkundrak@v3.sk>
Fri, 19 Feb 2016 13:40:16 +0000 (14:40 +0100)
When the device is transitioning from unmanaged to disconnected for "assumed"
reason, bring_up is not called. This is not a good thing in numerous
instances, e.g.:

1.) vlans that we've created need that to set IFF_UP and read carrier
otherwise they won't be available for connections.

2.) veths that are being managed need to start the deferred carrier check
so that the behavior matches real Ethernet.

3.) Hardware devices that were plugged in while NetworkManager is running
that need the IFF_UP for a carrier check, possibly enqueueing a deferred one.

Fixes: 5637d72af2d51b6f2b8dbe70553754f1828fdb66.

src/devices/nm-device.c

index 8d930b1..9b0cdfe 100644 (file)
@@ -1505,9 +1505,26 @@ device_link_changed (NMDevice *self)
        if (   priv->ifindex > 0
            && info.initialized
            && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
+               NMDeviceStateReason reason;
+
                nm_device_set_unmanaged_by_user_udev (self);
 
-               nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
+               /* If the devices that need an external IFF_UP go managed below,
+                * it means they're already up. In that case we should use an "assumed"
+                * reason to prevent the cleanup sequence from being run on transition
+                * from "unmanaged" to "unavailable". */
+               if (   priv->up
+                   && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)
+                   && NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self)) {
+                       /* Ensure the assume check is queued before any queued state changes
+                        * from the transition to UNAVAILABLE.
+                        */
+                       nm_device_queue_recheck_assume (self);
+                       reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
+               } else
+                       reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
+
+               nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
        }
 
        if (   priv->ifindex > 0