summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/devices/nm-device-ethernet.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index a9e57afb66..6b80c4ed49 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -73,6 +73,7 @@ typedef enum {
typedef struct _NMDeviceEthernetPrivate {
guint32 speed;
+ gulong carrier_id;
Supplicant supplicant;
guint supplicant_timeout_id;
@@ -940,7 +941,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
}
static NMActStageReturn
-nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
+supplicant_check_secrets_needed (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMConnection *connection;
@@ -949,7 +950,6 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *out_failure
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
connection = nm_device_get_applied_connection (NM_DEVICE (self));
-
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
security = nm_connection_get_setting_802_1x (connection);
@@ -988,6 +988,44 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *out_failure
return ret;
}
+static void
+carrier_changed (NMSupplicantInterface *iface,
+ GParamSpec *pspec,
+ NMDeviceEthernet *self)
+{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+ NMDeviceStateReason reason;
+ NMActStageReturn ret;
+
+ if (nm_device_has_carrier (NM_DEVICE (self))) {
+ _LOGD (LOGD_DEVICE | LOGD_ETHER, "got carrier, initializing supplicant");
+ nm_clear_g_signal_handler (self, &priv->carrier_id);
+ ret = supplicant_check_secrets_needed (self, &reason);
+ if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ reason);
+ }
+ }
+}
+
+static NMActStageReturn
+nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
+{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+
+ if (!nm_device_has_carrier (NM_DEVICE (self))) {
+ _LOGD (LOGD_DEVICE | LOGD_ETHER, "delay supplicant initialization until carrier goes up");
+ priv->carrier_id = g_signal_connect (self,
+ "notify::" NM_DEVICE_CARRIER,
+ G_CALLBACK (carrier_changed),
+ self);
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+ }
+
+ return supplicant_check_secrets_needed (self, out_failure_reason);
+}
+
/*****************************************************************************/
/* PPPoE */
@@ -1405,6 +1443,7 @@ deactivate (NMDevice *device)
GError *error = NULL;
nm_clear_g_source (&priv->pppoe_wait_id);
+ nm_clear_g_signal_handler (self, &priv->carrier_id);
if (priv->ppp_manager) {
nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL);
@@ -1724,6 +1763,8 @@ dispose (GObject *object)
nm_clear_g_source (&priv->dcb_timeout_id);
+ nm_clear_g_signal_handler (self, &priv->carrier_id);
+
G_OBJECT_CLASS (nm_device_ethernet_parent_class)->dispose (object);
}