summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-11-08 08:36:41 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2019-11-08 23:26:41 +0100
commit7bba7a6036866a853069548fb24fe103cbd3abf0 (patch)
tree8e1dfe96b9a91e12ab0e9cd99c83bfbe4366a4a7
parent649be3ae7d6e3aee02d881cfd3cfc07f3f68b120 (diff)
downloadNetworkManager-bg/802-1x-wait-carrier-rh1765490.tar.gz
ethernet: wait for carrier before starting supplicantbg/802-1x-wait-carrier-rh1765490
After we set link parameters (auto-negotiation, speed, duplex) in stage1, the carrier can go down for several seconds because the Ethernet PHY needs to renegotiate the link. Wait that carrier goes up before starting the supplicant or the EAPoL start packet can be lost causing an authentication failure. https://bugzilla.redhat.com/show_bug.cgi?id=1759797
-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);
}