device: refactor setting unmanaged flag EXTERNAL_DOWN
authorThomas Haller <thaller@redhat.com>
Mon, 21 Mar 2016 13:56:15 +0000 (14:56 +0100)
committerThomas Haller <thaller@redhat.com>
Thu, 31 Mar 2016 08:38:38 +0000 (10:38 +0200)
This should not actually change how we handle EXTERNAL_DOWN
unmanaged devices.

src/devices/nm-device.c

index 3816a1a..980b6e7 100644 (file)
@@ -1199,6 +1199,23 @@ can_unmanaged_external_down (NMDevice *self)
               && nm_device_is_software (self);
 }
 
+static NMUnmanFlagOp
+is_unmanaged_external_down (NMDevice *self, gboolean consider_can)
+{
+       NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+
+       if (   consider_can
+           && !NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self))
+               return NM_UNMAN_FLAG_OP_FORGET;
+
+       /* Manage externally-created software interfaces only when they are IFF_UP */
+       if (   priv->ifindex <= 0
+           || !priv->up)
+               return NM_UNMAN_FLAG_OP_SET_UNMANAGED;
+
+       return NM_UNMAN_FLAG_OP_SET_MANAGED;
+}
+
 static void
 update_dynamic_ip_setup (NMDevice *self)
 {
@@ -1423,7 +1440,6 @@ device_link_changed (NMDevice *self)
        NMPlatformLink info;
        const NMPlatformLink *pllink;
        int ifindex;
-       gboolean was_up;
 
        priv->device_link_changed_id = 0;
 
@@ -1496,23 +1512,19 @@ device_link_changed (NMDevice *self)
        if (ip_ifname_changed)
                update_dynamic_ip_setup (self);
 
-       was_up = priv->up;
        priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
 
-       if (   priv->ifindex > 0
-           && info.initialized
+       if (   info.initialized
            && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
                NMDeviceStateReason reason;
 
                nm_device_set_unmanaged_by_user_udev (self);
 
-               /* 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)) {
+               /* If the device is a external-down candidated but no longer has external
+                * down set, we must clear the platform-unmanaged flag with reason
+                * "assumed". */
+               if (    nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)
+                   && !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
                        /* Ensure the assume check is queued before any queued state changes
                         * from the transition to UNAVAILABLE.
                         */
@@ -1524,33 +1536,20 @@ device_link_changed (NMDevice *self)
                nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason);
        }
 
-       if (   priv->ifindex > 0
-           && priv->up != was_up
-           && NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self)) {
-               /* Manage externally-created software interfaces only when they are IFF_UP */
-               if (   priv->up
-                   && nm_device_get_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
+       if (nm_device_get_unmanaged_mask (self, NM_UNMANAGED_EXTERNAL_DOWN)) {
+               NMUnmanFlagOp ext_flags;
+
+               ext_flags = is_unmanaged_external_down (self, FALSE);
+               if (ext_flags != NM_UNMAN_FLAG_OP_SET_UNMANAGED) {
                        /* Ensure the assume check is queued before any queued state changes
                         * from the transition to UNAVAILABLE.
                         */
                        nm_device_queue_recheck_assume (self);
                }
 
-               /* In case of @priv->up, resetting the EXTERNAL_DOWN flag may change the device's
-                * state to UNAVAILABLE. To ensure that the state change doesn't touch
-                * the device before assumption occurs, pass NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED
-                * as the reason.
-                *
-                * In case of !@priv->up, and the device is already unmanaged for other reasons, the
-                * state-change-reason has no effect.
-                * If the device is managed for an explict user-request, the state-change-reason
-                * also has no effect, because the device stays managed.
-                *
-                * The state-change-reason only has effect if the device was assumed
-                * and is now to be unmanaged. */
                nm_device_set_unmanaged_by_flags (self,
                                                  NM_UNMANAGED_EXTERNAL_DOWN,
-                                                 !priv->up,
+                                                 ext_flags,
                                                  NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
        }
 
@@ -1922,12 +1921,11 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
 
        klass->realize_start_notify (self, plink);
 
-       /* Do not manage externally created software devices until they are IFF_UP */
-       if (   priv->ifindex > 0
-           && plink
-           && !priv->up
-           && NM_DEVICE_GET_CLASS (self)->can_unmanaged_external_down (self))
-               nm_device_set_unmanaged_flags (self, NM_UNMANAGED_EXTERNAL_DOWN, TRUE);
+       /* Do not manage externally created software devices until they are IFF_UP
+        * or have IP addressing */
+       nm_device_set_unmanaged_flags (self,
+                                      NM_UNMANAGED_EXTERNAL_DOWN,
+                                      is_unmanaged_external_down (self, TRUE));
 
        /* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK flag.
         * Later we might want to manage 'lo' too. Currently that doesn't work because