diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index c448f0481..279d7e327 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3362,7 +3362,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave static gboolean nm_device_can_assume_connections (NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (self)->update_connection; + return !!NM_DEVICE_GET_CLASS (self)->update_connection; } /** @@ -3378,7 +3378,7 @@ nm_device_can_assume_connections (NMDevice *self) * if there is no active connection or the active connection cannot be * assumed. */ -gboolean +static gboolean nm_device_can_assume_active_connection (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -3425,6 +3425,45 @@ nm_device_can_assume_active_connection (NMDevice *self) return TRUE; } +static gboolean +unmanaged_on_quit (NMDevice *self) +{ + /* Leave certain devices alone when quitting so their configuration + * can be taken over when NM restarts. This ensures connectivity while + * NM is stopped. + */ + if (nm_device_uses_assumed_connection (self)) { + /* An assume connection must be left alone */ + return FALSE; + } + + if (!nm_device_get_act_request (self)) { + /* a device without any active connection is either UNAVAILABLE or DISCONNECTED + * state. Since we don't know whether the device was upped by NetworkManager, + * we must leave it up on exit. + */ + return FALSE; + } + + if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (self))) { + /* The device has no layer 3 configuration. Leave it up. */ + return FALSE; + } + + if (nm_device_can_assume_active_connection (self)) + return FALSE; + + return TRUE; +} + +gboolean +nm_device_unmanage_on_quit (NMDevice *self) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + return NM_DEVICE_GET_CLASS (self)->unmanaged_on_quit (self); +} + static gboolean nm_device_emit_recheck_assume (gpointer user_data) { @@ -12357,6 +12396,7 @@ nm_device_class_init (NMDeviceClass *klass) klass->take_down = take_down; klass->carrier_changed = carrier_changed; klass->get_ip_iface_identifier = get_ip_iface_identifier; + klass->unmanaged_on_quit = unmanaged_on_quit; /* Properties */ obj_properties[PROP_UDI] = diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 181ad8e1c..8383ea250 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -328,6 +328,8 @@ typedef struct { gboolean (* owns_iface) (NMDevice *self, const char *iface); NMConnection * (* new_default_connection) (NMDevice *self); + + gboolean (* unmanaged_on_quit) (NMDevice *self); } NMDeviceClass; typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device, @@ -417,7 +419,7 @@ gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnec gboolean nm_device_uses_assumed_connection (NMDevice *device); -gboolean nm_device_can_assume_active_connection (NMDevice *device); +gboolean nm_device_unmanage_on_quit (NMDevice *self); gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 60f6f99f2..ebbd34fb4 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -193,6 +193,18 @@ constructed (GObject *object) priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ()); } +static gboolean +unmanaged_on_quit (NMDevice *self) +{ + /* Wi-Fi devices cannot be assumed and are always taken down. + * However, also when being disconnected, we scan and thus + * set the MAC address to a random value. + * + * We must restore the original MAC address when quitting, thus + * signal to unmanage the device. */ + return TRUE; +} + static gboolean supplicant_interface_acquire (NMDeviceWifi *self) { @@ -3097,6 +3109,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout; parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout; parent_class->deactivate = deactivate; + parent_class->unmanaged_on_quit = unmanaged_on_quit; parent_class->state_changed = device_state_changed; diff --git a/src/nm-manager.c b/src/nm-manager.c index 1ab140fd3..e7ca81219 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -945,28 +945,12 @@ remove_device (NMManager *self, nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device, FALSE)); if (allow_unmanage && nm_device_get_managed (device, FALSE)) { - unmanage = TRUE; - if (!quitting) { + if (quitting) + unmanage = nm_device_unmanage_on_quit (device); + else { /* the device is already gone. Unmanage it. */ - } else { - /* Leave certain devices alone when quitting so their configuration - * can be taken over when NM restarts. This ensures connectivity while - * NM is stopped. - */ - if (nm_device_uses_assumed_connection (device)) { - /* An assume connection must be left alone */ - unmanage = FALSE; - } else if (!nm_device_get_act_request (device)) { - /* a device without any active connection is either UNAVAILABLE or DISCONNECTED - * state. Since we don't know whether the device was upped by NetworkManager, - * we must leave it up on exit. */ - unmanage = FALSE; - } else if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (device))) { - /* The device has no layer 3 configuration. Leave it up. */ - unmanage = FALSE; - } else if (nm_device_can_assume_active_connection (device)) - unmanage = FALSE; + unmanage = TRUE; } if (unmanage) {