diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2a459bb64f..6d1d5cd7ee 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -4610,13 +4610,6 @@ disconnect_cb (NMDevice *device, } else { priv->autoconnect = FALSE; - /* Software devices are removed when manually disconnected and thus - * we need to track the autoconnect flag outside the device. - */ - nm_manager_prevent_device_auto_connect (nm_manager_get (), - nm_device_get_ip_iface (device), - TRUE); - nm_device_state_changed (device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_USER_REQUESTED); diff --git a/src/nm-manager.c b/src/nm-manager.c index d3fa52436e..1edcda1622 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -249,9 +249,6 @@ typedef struct { guint timestamp_update_id; - /* Track auto-activation for software devices */ - GHashTable *noauto_sw_devices; - gboolean startup; gboolean disposed; } NMManagerPrivate; @@ -1214,21 +1211,11 @@ system_create_virtual_devices (NMManager *self) connections = nm_settings_get_connections (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *connection = iter->data; - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - if (connection_needs_virtual_device (connection)) { - char *iface = get_virtual_iface_name (self, connection, NULL); - - /* We only create a virtual interface if the connection can autoconnect - * and the interface was not manually disconnected before. - */ - if ( nm_setting_connection_get_autoconnect (s_con) - && iface - && nm_manager_can_device_auto_connect (self, iface)) - system_create_virtual_device (self, connection); - g_free (iface); - } + /* We only create a virtual interface if the connection can autoconnect */ + if ( connection_needs_virtual_device (connection) + && nm_settings_connection_can_autoconnect (NM_SETTINGS_CONNECTION (connection))) + system_create_virtual_device (self, connection); } g_slist_free (connections); } @@ -2720,31 +2707,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * device = nm_active_connection_get_device (active); if (!device) { - char *iface; - g_assert (connection_needs_virtual_device (connection)); - iface = get_virtual_iface_name (self, connection, NULL); - g_assert (iface); - - /* Create the software device. Only exception is when: - * - this is an auto-activation *and* the device denies auto-activation - * at this time (the device was manually disconnected/deleted before) - */ - if (!nm_manager_can_device_auto_connect (self, iface)) { - if (nm_active_connection_get_user_requested (active)) { - /* Manual activation - allow device auto-activation again */ - nm_manager_prevent_device_auto_connect (self, iface, FALSE); - } else { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED, - "Automatic activation of '%s' not allowed for connection '%s'", - iface, nm_connection_get_id (connection)); - g_free (iface); - return FALSE; - } - } - g_free (iface); - device = system_create_virtual_device (self, connection); if (!device) { g_set_error_literal (error, @@ -3617,33 +3581,6 @@ done: g_clear_error (&error); } -/* - * Track (software) devices that cannot auto activate. - * It is needed especially for software devices, that can be removed and added - * again. So we can't simply use a flag inside the device. - */ -void -nm_manager_prevent_device_auto_connect (NMManager *manager, const char *ifname, gboolean prevent) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - - if (prevent) - g_hash_table_add (priv->noauto_sw_devices, g_strdup (ifname)); - else - g_hash_table_remove (priv->noauto_sw_devices, ifname); -} - -gboolean -nm_manager_can_device_auto_connect (NMManager *manager, const char *ifname) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - - if (!ifname) - return FALSE; - - return !g_hash_table_contains (priv->noauto_sw_devices, ifname); -} - static void do_sleep_wake (NMManager *self) { @@ -4719,8 +4656,6 @@ dispose (GObject *object) g_object_unref (priv->fw_monitor); } - g_hash_table_unref (priv->noauto_sw_devices); - g_slist_free (priv->factories); if (priv->timestamp_update_id) { @@ -5085,9 +5020,6 @@ nm_manager_init (NMManager *manager) KERNEL_FIRMWARE_DIR); } - /* Hash table storing software devices that should not auto activate */ - priv->noauto_sw_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - load_device_factories (manager); /* Update timestamps in active connections */ diff --git a/src/nm-manager.h b/src/nm-manager.h index 4d84db5d26..25e30f3352 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -128,12 +128,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager, NMDeviceStateReason reason, GError **error); -void nm_manager_prevent_device_auto_connect (NMManager *manager, - const char *ifname, - gboolean prevent); -gboolean nm_manager_can_device_auto_connect (NMManager *manager, - const char *ifname); - /* State handling */ NMState nm_manager_get_state (NMManager *manager); diff --git a/src/nm-policy.c b/src/nm-policy.c index 01ddc15436..dee85d678b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1160,6 +1160,28 @@ reset_autoconnect_for_failed_secrets (NMPolicy *policy) g_slist_free (connections); } +static void +block_autoconnect_for_device (NMPolicy *policy, NMDevice *device) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); + GSList *connections, *iter; + + /* NMDevice keeps its own autoconnect-able-ness state; we only need to + * explicitly block connections for software devices, where the NMDevice + * might be destroyed and recreated later. + */ + if (!nm_device_is_software (device)) + return; + + connections = nm_settings_get_connections (priv->settings); + for (iter = connections; iter; iter = g_slist_next (iter)) { + if (nm_device_check_connection_compatible (device, iter->data, NULL)) { + nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data), + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } +} + static void sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) { @@ -1432,8 +1454,15 @@ device_state_changed (NMDevice *device, update_routing_and_dns (policy, FALSE); break; case NM_DEVICE_STATE_DEACTIVATING: - if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) - nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED); + if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) { + if (!nm_device_get_autoconnect (device)) { + /* The device was disconnected; block all connections on it */ + block_autoconnect_for_device (policy, device); + } else { + /* The connection was deactivated, so block just this connection */ + nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } break; case NM_DEVICE_STATE_DISCONNECTED: /* Reset retry counts for a device's connections when carrier on; if cable diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 63bc8aa083..2a23396759 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1955,6 +1955,7 @@ gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connection) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + NMSettingConnection *s_con; const char *permission; if ( !priv->visible @@ -1962,6 +1963,10 @@ nm_settings_connection_can_autoconnect (NMSettingsConnection *connection) || priv->autoconnect_blocked_reason != NM_DEVICE_STATE_REASON_NONE) return FALSE; + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); + if (!nm_setting_connection_get_autoconnect (s_con)) + return FALSE; + permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (connection)); if (permission) { if (nm_settings_connection_check_permission (connection, permission) == FALSE)