summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2014-10-23 14:57:22 -0500
committerDan Williams <dcbw@redhat.com>2014-10-23 15:36:59 -0500
commite8a4dc00cb5e42dd498ce6362710d6cdf0850fe0 (patch)
tree6811db6aa5316a569f61ba4a519fe43ff913cb1f
parent32b09b4a60b53e6082134a7969ce776b2a3f8c1d (diff)
downloadNetworkManager-dcbw/unmanaged-available.tar.gz
core: autoconnect fixes for default-unmanaged devices and property notificationdcbw/unmanaged-available
Previously the only thing preventing default-unmanaged devices from being auto-activated was luck and the fact that they didn't have any available connections when in the UNMANAGED state. That's no longer true, so we must be more explicit about their behavior. Furthermore it makes no sense to allow default-unmanaged devices to set priv->autoconnect=TRUE since that is never supposed to happen, so enforce that both in NM itself and if the change request comes in over the D-Bus interface. Lastly, internal priv->autoconnect=TRUE changes never emitted a property change notification, meaning the NMPolicy would never schedule an autoconnect check if the device's priv->autoconnect was set to TRUE as a result of re-activating or waking from sleep.
-rw-r--r--introspection/nm-device.xml3
-rw-r--r--src/devices/nm-device.c68
-rw-r--r--src/nm-policy.c2
3 files changed, 64 insertions, 9 deletions
diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml
index 0dca23c37d..0c2a330c00 100644
--- a/introspection/nm-device.xml
+++ b/introspection/nm-device.xml
@@ -106,7 +106,8 @@
If TRUE, indicates the device is allowed to autoconnect. If FALSE,
manual intervention is required before the device will automatically
connect to a known network, such as activating a connection using the
- device, or setting this property to TRUE.
+ device, or setting this property to TRUE. This property cannot be
+ set to TRUE for default-unmanaged devices, since they never autoconnect.
</tp:docstring>
</property>
<property name="FirmwareMissing" type="b" access="read">
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 87bebdb1eb..4f8e86c07a 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1573,6 +1573,14 @@ 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 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)
{
@@ -1581,6 +1589,29 @@ nm_device_get_autoconnect (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->autoconnect;
}
+static void
+nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect)
+{
+ NMDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE (self));
+
+ priv = NM_DEVICE_GET_PRIVATE (self);
+ if (priv->autoconnect == autoconnect)
+ return;
+
+ if (autoconnect) {
+ /* Default-unmanaged devices never autoconnect */
+ if (!nm_device_get_default_unmanaged (self)) {
+ priv->autoconnect = TRUE;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT);
+ }
+ } else {
+ priv->autoconnect = FALSE;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT);
+ }
+}
+
static gboolean
autoconnect_allowed_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
@@ -1591,6 +1622,14 @@ autoconnect_allowed_accumulator (GSignalInvocationHint *ihint,
return TRUE;
}
+/**
+ * nm_device_autoconnect_allowed:
+ * @self: the #NMDevice
+ *
+ * Returns: %TRUE if the device can be auto-connected immediately, taking
+ * transient conditions into account (like companion devices that may wish to
+ * block autoconnect for a time).
+ */
gboolean
nm_device_autoconnect_allowed (NMDevice *self)
{
@@ -1598,6 +1637,16 @@ nm_device_autoconnect_allowed (NMDevice *self)
GValue instance = G_VALUE_INIT;
GValue retval = G_VALUE_INIT;
+ if (priv->state < NM_DEVICE_STATE_DISCONNECTED || !priv->autoconnect)
+ return FALSE;
+
+ /* 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
+ * on their companion WiFi device as they share radio resources and
+ * cannot be connected at the same time.
+ */
+
g_value_init (&instance, G_TYPE_OBJECT);
g_value_set_object (&instance, self);
@@ -1639,8 +1688,9 @@ can_auto_connect (NMDevice *self,
* Checks if @connection can be auto-activated on @self right now.
* This requires, at a minimum, that the connection be compatible with
* @self, and that it have the #NMSettingConnection:autoconnect property
- * set. Some devices impose additional requirements. (Eg, a Wi-Fi connection
- * can only be activated if its SSID was seen in the last scan.)
+ * set, and that the device allow auto connections. Some devices impose
+ * additional requirements. (Eg, a Wi-Fi connection can only be activated
+ * if its SSID was seen in the last scan.)
*
* Returns: %TRUE, if the @connection can be auto-activated.
**/
@@ -1653,7 +1703,9 @@ nm_device_can_auto_connect (NMDevice *self,
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
g_return_val_if_fail (specific_object && !*specific_object, FALSE);
- return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object);
+ if (nm_device_autoconnect_allowed (self))
+ return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object);
+ return FALSE;
}
static gboolean
@@ -5076,7 +5128,7 @@ disconnect_cb (NMDevice *self,
dbus_g_method_return_error (context, local);
g_error_free (local);
} else {
- priv->autoconnect = FALSE;
+ nm_device_set_autoconnect (self, FALSE);
nm_device_state_changed (self,
NM_DEVICE_STATE_DEACTIVATING,
@@ -6856,7 +6908,7 @@ _set_state_full (NMDevice *self,
/* Reset autoconnect flag when the device is activating or connected. */
if ( state >= NM_DEVICE_STATE_PREPARE
&& state <= NM_DEVICE_STATE_ACTIVATED)
- priv->autoconnect = TRUE;
+ nm_device_set_autoconnect (self, TRUE);
g_object_notify (G_OBJECT (self), NM_DEVICE_STATE);
g_object_notify (G_OBJECT (self), NM_DEVICE_STATE_REASON);
@@ -7412,8 +7464,10 @@ constructed (GObject *object)
* since they don't transition from UNMANAGED (and thus the state handler
* doesn't run and update them) until something external happens.
*/
- if (nm_device_get_default_unmanaged (self))
+ if (nm_device_get_default_unmanaged (self)) {
+ nm_device_set_autoconnect (self, FALSE);
nm_device_recheck_available_connections (self);
+ }
G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
}
@@ -7561,7 +7615,7 @@ set_property (GObject *object, guint prop_id,
priv->ip4_address = g_value_get_uint (value);
break;
case PROP_AUTOCONNECT:
- priv->autoconnect = g_value_get_boolean (value);
+ nm_device_set_autoconnect (self, g_value_get_boolean (value));
break;
case PROP_FIRMWARE_MISSING:
priv->firmware_missing = g_value_get_boolean (value);
diff --git a/src/nm-policy.c b/src/nm-policy.c
index ff100d069d..ddb85bd96b 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -1658,7 +1658,7 @@ device_autoconnect_changed (NMDevice *device,
GParamSpec *pspec,
gpointer user_data)
{
- if (nm_device_get_autoconnect (device))
+ if (nm_device_autoconnect_allowed (device))
schedule_activate_check ((NMPolicy *) user_data, device);
}