diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-11-08 08:36:41 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2019-11-08 23:26:41 +0100 |
commit | 7bba7a6036866a853069548fb24fe103cbd3abf0 (patch) | |
tree | 8e1dfe96b9a91e12ab0e9cd99c83bfbe4366a4a7 | |
parent | 649be3ae7d6e3aee02d881cfd3cfc07f3f68b120 (diff) | |
download | NetworkManager-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.c | 45 |
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); } |