summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-11-08 12:32:44 +0100
committerThomas Haller <thaller@redhat.com>2017-11-08 12:33:24 +0100
commit0e4405e9247e588ce89434de8eb61ce6ac094710 (patch)
tree7af8d9004775cba8cddaf25fdfeffe777d5af6c1
parent80687ed0cedf3d4eeb32459eb6350d5e4e3428ae (diff)
parent146fbfab33c109026be82bc76c2bc8a9dcd1717d (diff)
downloadNetworkManager-0e4405e9247e588ce89434de8eb61ce6ac094710.tar.gz
core: merge branch 'th/autoconnect-rh1401515-3'
https://bugzilla.redhat.com/show_bug.cgi?id=1401515
-rw-r--r--src/devices/bluetooth/nm-device-bt.c3
-rw-r--r--src/devices/nm-device.c150
-rw-r--r--src/devices/nm-device.h33
-rw-r--r--src/devices/wifi/nm-device-olpc-mesh.c8
-rw-r--r--src/devices/wifi/nm-device-wifi.c3
-rw-r--r--src/devices/wwan/nm-device-modem.c3
-rw-r--r--src/nm-manager.c2
-rw-r--r--src/nm-policy.c131
8 files changed, 162 insertions, 171 deletions
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 0d46be8fe7..977c1e1ae6 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -491,8 +491,7 @@ modem_prepare_result (NMModem *modem,
* the device to be auto-activated anymore, which would risk locking
* the SIM if the incorrect PIN continues to be used.
*/
- _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN");
- nm_device_set_autoconnect_intern (device, FALSE);
+ nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN);
}
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index e979b87541..e587567504 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -354,6 +354,8 @@ typedef struct _NMDevicePrivate {
bool v4_route_table_initalized:1;
bool v6_route_table_initalized:1;
+ NMDeviceAutoconnectBlockedFlags autoconnect_blocked_flags:4;
+
/* Generic DHCP stuff */
char * dhcp_anycast_address;
@@ -466,10 +468,6 @@ typedef struct _NMDevicePrivate {
gboolean needs_ip6_subnet;
- /* allow autoconnect feature */
- bool autoconnect_intern:1;
- bool autoconnect_user:1;
-
/* master interface for bridge/bond/team slave */
NMDevice * master;
bool is_enslaved;
@@ -533,9 +531,6 @@ static NMActStageReturn linklocal6_start (NMDevice *self);
static void _carrier_wait_check_queued_act_request (NMDevice *self);
-static void nm_device_set_autoconnect_both (NMDevice *self, gboolean autoconnect);
-static void nm_device_set_autoconnect_full (NMDevice *self, int autoconnect_intern, int autoconnect_user);
-
static const char *_activation_func_to_string (ActivationHandleFunc func);
static void activation_source_handle_cb (NMDevice *self, int addr_family);
@@ -3392,8 +3387,6 @@ realize_start_setup (NMDevice *self,
if (real_rate)
priv->stats.timeout_id = g_timeout_add (real_rate, _stats_timeout_cb, self);
- nm_device_set_autoconnect_full (self, !!DEFAULT_AUTOCONNECT, TRUE);
-
klass->realize_start_notify (self, plink);
nm_assert (!nm_device_get_unmanaged_mask (self, NM_UNMANAGED_USER_EXPLICIT));
@@ -3593,8 +3586,6 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
priv->real = FALSE;
_notify (self, PROP_REAL);
- nm_device_set_autoconnect_both (self, FALSE);
-
g_object_thaw_notify (G_OBJECT (self));
nm_device_set_unmanaged_flags (self,
@@ -4219,62 +4210,55 @@ nm_device_set_enabled (NMDevice *self, gboolean enabled)
NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled);
}
-/**
- * nm_device_get_autoconnect:
- * @self: the #NMDevice
- *
- * Returns: %TRUE if the device allows autoconnect connections, or %FALSE if the
- * device is explicitly blocking all autoconnect connections. Does not take
- * into account transient conditions like companion devices that may wish to
- * block the device.
- */
-gboolean
-nm_device_get_autoconnect (NMDevice *self)
+NM_UTILS_FLAGS2STR_DEFINE_STATIC (_autoconnect_blocked_flags_to_string, NMDeviceAutoconnectBlockedFlags,
+ NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_NONE, "none"),
+ NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_USER, "user"),
+ NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN, "wrong-pin"),
+ NM_UTILS_FLAGS2STR (NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT, "manual-disconnect"),
+);
+
+NMDeviceAutoconnectBlockedFlags
+nm_device_autoconnect_blocked_get (NMDevice *self, NMDeviceAutoconnectBlockedFlags mask)
{
NMDevicePrivate *priv;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+ if (mask == 0)
+ mask = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL;
+
priv = NM_DEVICE_GET_PRIVATE (self);
- return priv->autoconnect_intern && priv->autoconnect_user;
+ return priv->autoconnect_blocked_flags & mask;
}
-static void
-nm_device_set_autoconnect_full (NMDevice *self, int autoconnect_intern, int autoconnect_user)
+void
+nm_device_autoconnect_blocked_set_full (NMDevice *self, NMDeviceAutoconnectBlockedFlags mask, NMDeviceAutoconnectBlockedFlags value)
{
NMDevicePrivate *priv;
- gboolean old_value;
+ gboolean changed;
+ char buf1[128], buf2[128];
g_return_if_fail (NM_IS_DEVICE (self));
+ nm_assert (mask);
+ nm_assert (!NM_FLAGS_ANY (mask, ~NM_DEVICE_AUTOCONNECT_BLOCKED_ALL));
+ nm_assert (!NM_FLAGS_ANY (value, ~mask));
priv = NM_DEVICE_GET_PRIVATE (self);
- old_value = nm_device_get_autoconnect (self);
- if (autoconnect_intern != -1)
- priv->autoconnect_intern = autoconnect_intern;
- if (autoconnect_user != -1)
- priv->autoconnect_user = autoconnect_user;
- if (old_value != nm_device_get_autoconnect (self))
- _notify (self, PROP_AUTOCONNECT);
-}
+ value = (priv->autoconnect_blocked_flags & ~mask) | (mask & value);
+ if (value == priv->autoconnect_blocked_flags)
+ return;
-void
-nm_device_set_autoconnect_intern (NMDevice *self, gboolean autoconnect)
-{
- nm_device_set_autoconnect_full (self, !!autoconnect, -1);
-}
+ changed = ((!value) != (!priv->autoconnect_blocked_flags));
-static void
-nm_device_set_autoconnect_both (NMDevice *self, gboolean autoconnect)
-{
- autoconnect = !!autoconnect;
- nm_device_set_autoconnect_full (self, autoconnect, autoconnect);
-}
+ _LOGT (LOGD_DEVICE, "autoconnect-blocked: set \"%s\" (was \"%s\")",
+ _autoconnect_blocked_flags_to_string (value, buf1, sizeof (buf1)),
+ _autoconnect_blocked_flags_to_string (priv->autoconnect_blocked_flags, buf2, sizeof (buf2)));
-static gboolean
-get_autoconnect_allowed (NMDevice *self)
-{
- return TRUE;
+ priv->autoconnect_blocked_flags = value;
+ nm_assert (priv->autoconnect_blocked_flags == value);
+ if (changed)
+ _notify (self, PROP_AUTOCONNECT);
}
static gboolean
@@ -4303,14 +4287,23 @@ nm_device_autoconnect_allowed (NMDevice *self)
GValue instance = G_VALUE_INIT;
GValue retval = G_VALUE_INIT;
- if ( !nm_device_get_autoconnect (self)
- || !klass->get_autoconnect_allowed (self))
+ if (nm_device_autoconnect_blocked_get (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL))
return FALSE;
- /* Unrealized devices can always autoconnect. */
- if (nm_device_is_real (self) && priv->state < NM_DEVICE_STATE_DISCONNECTED)
+ if ( klass->get_autoconnect_allowed
+ && !klass->get_autoconnect_allowed (self))
return FALSE;
+ if (!nm_device_get_enabled (self))
+ return FALSE;
+
+ if (nm_device_is_real (self)) {
+ if (priv->state < NM_DEVICE_STATE_DISCONNECTED)
+ return FALSE;
+ } else {
+ /* Unrealized devices can always autoconnect. */
+ }
+
/* The 'autoconnect-allowed' signal is emitted on a device to allow
* other listeners to block autoconnect on the device if they wish.
* This is mainly used by the OLPC Mesh devices to block autoconnect
@@ -4337,15 +4330,8 @@ can_auto_connect (NMDevice *self,
NMConnection *connection,
char **specific_object)
{
- NMSettingConnection *s_con;
-
nm_assert (!specific_object || !*specific_object);
-
- s_con = nm_connection_get_setting_connection (connection);
- if (!nm_setting_connection_get_autoconnect (s_con))
- return FALSE;
-
- return nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL);
+ return TRUE;
}
/**
@@ -4372,11 +4358,24 @@ nm_device_can_auto_connect (NMDevice *self,
{
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
- g_return_val_if_fail (specific_object && !*specific_object, FALSE);
+ g_return_val_if_fail (!specific_object || !*specific_object, FALSE);
- if (nm_device_autoconnect_allowed (self))
- return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object);
- return FALSE;
+ /* the caller must ensure that nm_device_autoconnect_allowed() returns
+ * TRUE as well. This is done, because nm_device_can_auto_connect()
+ * has only one caller, and it iterates over a list of available
+ * connections.
+ *
+ * Hence, we don't need to re-check nm_device_autoconnect_allowed()
+ * over and over again. The caller is supposed to do that. */
+ nm_assert (nm_device_autoconnect_allowed (self));
+
+ if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL))
+ return FALSE;
+
+ if (!NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object))
+ return FALSE;
+
+ return TRUE;
}
static gboolean
@@ -9732,7 +9731,7 @@ disconnect_cb (NMDevice *self,
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_DISCONNECT, self, FALSE, NULL, subject, local->message);
g_dbus_method_invocation_take_error (context, local);
} else {
- nm_device_set_autoconnect_intern (self, FALSE);
+ nm_device_autoconnect_blocked_set (self, NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT);
nm_device_state_changed (self,
NM_DEVICE_STATE_DEACTIVATING,
@@ -12988,10 +12987,10 @@ _set_state_full (NMDevice *self,
break;
}
- /* Reset autoconnect flag when the device is activating or connected. */
+ /* Reset intern autoconnect flags when the device is activating or connected. */
if ( state >= NM_DEVICE_STATE_PREPARE
&& state <= NM_DEVICE_STATE_ACTIVATED)
- nm_device_set_autoconnect_intern (self, TRUE);
+ nm_device_autoconnect_blocked_unset (self, NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL);
_notify (self, PROP_STATE);
_notify (self, PROP_STATE_REASON);
@@ -14116,6 +14115,10 @@ nm_device_init (NMDevice *self)
priv->netns = g_object_ref (NM_NETNS_GET);
+ priv->autoconnect_blocked_flags = DEFAULT_AUTOCONNECT
+ ? NM_DEVICE_AUTOCONNECT_BLOCKED_NONE
+ : NM_DEVICE_AUTOCONNECT_BLOCKED_USER;
+
priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET;
priv->type = NM_DEVICE_TYPE_UNKNOWN;
priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
@@ -14402,7 +14405,10 @@ set_property (GObject *object, guint prop_id,
}
break;
case PROP_AUTOCONNECT:
- nm_device_set_autoconnect_both (self, g_value_get_boolean (value));
+ if (g_value_get_boolean (value))
+ nm_device_autoconnect_blocked_unset (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL);
+ else
+ nm_device_autoconnect_blocked_set (self, NM_DEVICE_AUTOCONNECT_BLOCKED_USER);
break;
case PROP_FIRMWARE_MISSING:
/* construct-only */
@@ -14539,7 +14545,10 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, nm_device_get_state (self) > NM_DEVICE_STATE_UNMANAGED);
break;
case PROP_AUTOCONNECT:
- g_value_set_boolean (value, nm_device_get_autoconnect (self));
+ g_value_set_boolean (value,
+ nm_device_autoconnect_blocked_get (self, NM_DEVICE_AUTOCONNECT_BLOCKED_ALL)
+ ? FALSE
+ : TRUE);
break;
case PROP_FIRMWARE_MISSING:
g_value_set_boolean (value, priv->firmware_missing);
@@ -14668,7 +14677,6 @@ nm_device_class_init (NMDeviceClass *klass)
klass->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout;
klass->get_type_description = get_type_description;
- klass->get_autoconnect_allowed = get_autoconnect_allowed;
klass->can_auto_connect = can_auto_connect;
klass->check_connection_compatible = check_connection_compatible;
klass->check_connection_available = check_connection_available;
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 350a17b2c1..bd8104b4bf 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -663,8 +663,37 @@ gboolean nm_device_unrealize (NMDevice *device,
void nm_device_update_from_platform_link (NMDevice *self,
const NMPlatformLink *plink);
-gboolean nm_device_get_autoconnect (NMDevice *device);
-void nm_device_set_autoconnect_intern (NMDevice *device, gboolean autoconnect);
+typedef enum {
+ NM_DEVICE_AUTOCONNECT_BLOCKED_NONE = 0,
+
+ NM_DEVICE_AUTOCONNECT_BLOCKED_USER = (1LL << 0),
+
+ NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN = (1LL << 1),
+ NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT = (1LL << 2),
+
+ _NM_DEVICE_AUTOCONNECT_BLOCKED_LAST,
+
+ NM_DEVICE_AUTOCONNECT_BLOCKED_ALL = (((_NM_DEVICE_AUTOCONNECT_BLOCKED_LAST - 1) << 1) - 1),
+
+ NM_DEVICE_AUTOCONNECT_BLOCKED_INTERNAL = NM_DEVICE_AUTOCONNECT_BLOCKED_ALL & ~NM_DEVICE_AUTOCONNECT_BLOCKED_USER,
+} NMDeviceAutoconnectBlockedFlags;
+
+NMDeviceAutoconnectBlockedFlags nm_device_autoconnect_blocked_get (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask);
+
+void nm_device_autoconnect_blocked_set_full (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask, NMDeviceAutoconnectBlockedFlags values);
+
+static inline void
+nm_device_autoconnect_blocked_set (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask)
+{
+ nm_device_autoconnect_blocked_set_full (device, mask, mask);
+}
+
+static inline void
+nm_device_autoconnect_blocked_unset (NMDevice *device, NMDeviceAutoconnectBlockedFlags mask)
+{
+ nm_device_autoconnect_blocked_set_full (device, mask, NM_DEVICE_AUTOCONNECT_BLOCKED_NONE);
+}
+
void nm_device_emit_recheck_auto_activate (NMDevice *device);
NMDeviceSysIfaceState nm_device_sys_iface_state_get (NMDevice *device);
diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c
index ac78757d9d..3a4a027afa 100644
--- a/src/devices/wifi/nm-device-olpc-mesh.c
+++ b/src/devices/wifi/nm-device-olpc-mesh.c
@@ -107,12 +107,8 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
}
static gboolean
-can_auto_connect (NMDevice *device,
- NMConnection *connection,
- char **specific_object)
+get_autoconnect_allowed (NMDevice *device)
{
- nm_assert (!specific_object || !*specific_object);
-
return FALSE;
}
@@ -517,7 +513,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
object_class->dispose = dispose;
parent_class->check_connection_compatible = check_connection_compatible;
- parent_class->can_auto_connect = can_auto_connect;
+ parent_class->get_autoconnect_allowed = get_autoconnect_allowed;
parent_class->complete_connection = complete_connection;
parent_class->is_available = is_available;
parent_class->act_stage1_prepare = act_stage1_prepare;
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 8bfddbd924..5e92f47b76 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -997,9 +997,6 @@ get_autoconnect_allowed (NMDevice *device)
{
NMDeviceWifiPrivate *priv;
- if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->get_autoconnect_allowed (device))
- return FALSE;
-
priv = NM_DEVICE_WIFI_GET_PRIVATE (NM_DEVICE_WIFI (device));
return !priv->requested_scan;
}
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index 22fb8c673d..b79d145d1f 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -132,8 +132,7 @@ modem_prepare_result (NMModem *modem,
* the device to be auto-activated anymore, which would risk locking
* the SIM if the incorrect PIN continues to be used.
*/
- nm_device_set_autoconnect_intern (device, FALSE);
- _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN");
+ nm_device_autoconnect_blocked_set (device, NM_DEVICE_AUTOCONNECT_BLOCKED_WRONG_PIN);
}
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 3b2b4861e9..45afc7f131 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -4623,8 +4623,6 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed)
nm_device_set_enabled (device, enabled);
}
- nm_device_set_autoconnect_intern (device, TRUE);
-
nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, FALSE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
}
}
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 3cfb1f7c4a..e56fce0b26 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1159,8 +1159,7 @@ activate_data_free (ActivateData *data)
nm_device_remove_pending_action (data->device, NM_PENDING_ACTION_AUTOACTIVATE, TRUE);
priv->pending_activation_checks = g_slist_remove (priv->pending_activation_checks, data);
- if (data->autoactivate_id)
- g_source_remove (data->autoactivate_id);
+ nm_clear_g_source (&data->autoactivate_id);
g_object_unref (data->device);
g_slice_free (ActivateData, data);
@@ -1214,6 +1213,9 @@ auto_activate_device (NMPolicy *self,
gs_free char *specific_object = NULL;
gs_free NMSettingsConnection **connections = NULL;
guint i, len;
+ GError *error = NULL;
+ NMAuthSubject *subject;
+ NMActiveConnection *ac;
nm_assert (NM_IS_POLICY (self));
nm_assert (NM_IS_DEVICE (device));
@@ -1227,6 +1229,9 @@ auto_activate_device (NMPolicy *self,
if (nm_device_get_act_request (device))
return;
+ if (!nm_device_autoconnect_allowed (device))
+ return;
+
connections = nm_manager_get_activatable_connections (priv->manager, &len, TRUE);
if (!connections[0])
return;
@@ -1258,46 +1263,43 @@ auto_activate_device (NMPolicy *self,
}
}
- if (best_connection) {
- GError *error = NULL;
- NMAuthSubject *subject;
- NMActiveConnection *ac;
-
- _LOGI (LOGD_DEVICE, "auto-activating connection '%s'",
- nm_settings_connection_get_id (best_connection));
- subject = nm_auth_subject_new_internal ();
- ac = nm_manager_activate_connection (priv->manager,
- best_connection,
- NULL,
- specific_object,
- device,
- subject,
- NM_ACTIVATION_TYPE_MANAGED,
- &error);
- if (!ac) {
- _LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: (%d) %s",
- nm_settings_connection_get_id (best_connection),
- error->code,
- error->message);
- g_error_free (error);
- nm_settings_connection_autoconnect_blocked_reason_set (best_connection,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
- schedule_activate_check (self, device);
- return;
- }
+ if (!best_connection)
+ return;
- /* Subscribe to AC state-changed signal to detect when the
- * activation fails in early stages without changing device
- * state.
- */
- if (nm_g_hash_table_add (priv->pending_active_connections, ac)) {
- g_signal_connect (ac, NM_ACTIVE_CONNECTION_STATE_CHANGED,
- G_CALLBACK (pending_ac_state_changed), g_object_ref (self));
- g_object_weak_ref (G_OBJECT (ac), (GWeakNotify) pending_ac_gone, self);
- }
+ _LOGI (LOGD_DEVICE, "auto-activating connection '%s'",
+ nm_settings_connection_get_id (best_connection));
+ subject = nm_auth_subject_new_internal ();
+ ac = nm_manager_activate_connection (priv->manager,
+ best_connection,
+ NULL,
+ specific_object,
+ device,
+ subject,
+ NM_ACTIVATION_TYPE_MANAGED,
+ &error);
+ if (!ac) {
+ _LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: (%d) %s",
+ nm_settings_connection_get_id (best_connection),
+ error->code,
+ error->message);
+ g_error_free (error);
+ nm_settings_connection_autoconnect_blocked_reason_set (best_connection,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED);
+ schedule_activate_check (self, device);
+ return;
+ }
- g_object_unref (subject);
+ /* Subscribe to AC state-changed signal to detect when the
+ * activation fails in early stages without changing device
+ * state.
+ */
+ if (nm_g_hash_table_add (priv->pending_active_connections, ac)) {
+ g_signal_connect (ac, NM_ACTIVE_CONNECTION_STATE_CHANGED,
+ G_CALLBACK (pending_ac_state_changed), g_object_ref (self));
+ g_object_weak_ref (G_OBJECT (ac), (GWeakNotify) pending_ac_gone, self);
}
+
+ g_object_unref (subject);
}
static gboolean
@@ -1465,34 +1467,6 @@ reset_autoconnect_for_failed_secrets (NMPolicy *self)
}
static void
-block_autoconnect_for_device (NMPolicy *self, NMDevice *device)
-{
- NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- gs_free NMSettingsConnection **connections = NULL;
- guint i;
-
- _LOGD (LOGD_DEVICE, "blocking autoconnect for all connections on %s",
- nm_device_get_iface (device));
-
- /* 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_sorted (priv->settings, NULL);
- for (i = 0; connections[i]; i++) {
- NMSettingsConnection *connection = connections[i];
-
- if (nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) {
- nm_settings_connection_autoconnect_blocked_reason_set (connection,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST);
- }
- }
-}
-
-static void
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
{
NMPolicyPrivate *priv = user_data;
@@ -1517,9 +1491,6 @@ schedule_activate_check (NMPolicy *self, NMDevice *device)
if (nm_manager_get_state (priv->manager) == NM_STATE_ASLEEP)
return;
- if (!nm_device_get_enabled (device))
- return;
-
if (!nm_device_autoconnect_allowed (device))
return;
@@ -1845,17 +1816,12 @@ device_state_changed (NMDevice *device,
break;
case NM_DEVICE_STATE_DEACTIVATING:
if (nm_device_state_reason_check (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 (self, device);
- } else {
- if (connection) {
- /* The connection was deactivated, so block just this connection */
- _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s' by user request",
- nm_settings_connection_get_id (connection));
- nm_settings_connection_autoconnect_blocked_reason_set (connection,
- NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST);
- }
+ if (connection) {
+ /* The connection was deactivated, so block just this connection */
+ _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s' by user request",
+ nm_settings_connection_get_id (connection));
+ nm_settings_connection_autoconnect_blocked_reason_set (connection,
+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST);
}
}
ip6_remove_device_prefix_delegations (self, device);
@@ -1999,8 +1965,7 @@ device_autoconnect_changed (NMDevice *device,
NMPolicyPrivate *priv = user_data;
NMPolicy *self = _PRIV_TO_SELF (priv);
- if (nm_device_autoconnect_allowed (device))
- schedule_activate_check (self, device);
+ schedule_activate_check (self, device);
}
static void