[PATCH] wpa_supplicant: Use nl80211_send_eapol_data for station

Ben Greear greearb at candelatech.com
Fri Jun 9 06:33:18 PDT 2017



On 06/09/2017 02:21 AM, Wojciech Dubowik wrote:
> Supplicant is using generic L2 send function for EAPOL
> messages which doesn't give back status whether frame has been
> acked or not. It can lead to wrong wpa states when EAPOL 4/4
> is lost i.e. client is in connected state but keys aren't
> established on AP side.
> Fix that by using nl80211_send_eapol_data as for AP side
> and check in conneced state that 4/4 EAPOL has been acked.

This seems like it could help my case where keys are set before the 4/4 is
transmitted.  Maybe only set the keys once we get the txstatus back?

Thanks,
Ben

>
> Signed-off-by: Wojciech Dubowik <Wojciech.Dubowik at neratec.com>
> ---
>  src/drivers/driver.h         | 12 ++++++++++++
>  src/drivers/driver_nl80211.c | 11 +++++++++++
>  wpa_supplicant/driver_i.h    | 10 ++++++++++
>  wpa_supplicant/events.c      | 17 ++++++++++++++++-
>  wpa_supplicant/wpas_glue.c   |  6 ++++++
>  5 files changed, 55 insertions(+), 1 deletion(-)
>
> diff --git a/src/drivers/driver.h b/src/drivers/driver.h
> index 9587d06..b73679d 100644
> --- a/src/drivers/driver.h
> +++ b/src/drivers/driver.h
> @@ -2665,6 +2665,18 @@ struct wpa_driver_ops {
>  			       const u8 *own_addr, u32 flags);
>
>  	/**
> +	 * send_eapol - Send an EAPOL packet (STA only)
> +	 * @priv: private driver interface data
> +	 * @addr: Destination MAC address
> +	 * @data: EAPOL packet starting with IEEE 802.1X header
> +	 * @data_len: Length of the EAPOL packet in octets
> +	 *
> +	 * Returns: 0 on success, -1 on failure
> +	 */
> +	int (*send_eapol)(void *priv, const u8 *addr, const u8 *data,
> +			       size_t data_len);
> +
> +	/**
>  	 * sta_deauth - Deauthenticate a station (AP only)
>  	 * @priv: Private driver interface data
>  	 * @own_addr: Source address and BSSID for the Deauthentication frame
> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> index 1b7be39..60185dd 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -4844,6 +4844,16 @@ static int wpa_driver_nl80211_hapd_send_eapol(
>  	return res;
>  }
>
> +static int wpa_driver_nl80211_send_eapol(
> +	void *priv, const u8 *addr, const u8 *data,
> +	size_t data_len)
> +{
> +	struct i802_bss *bss = priv;
> +
> +	return nl80211_send_eapol_data(bss, addr, data, data_len);
> +}
> +
> +
>
>  static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
>  					    unsigned int total_flags,
> @@ -10186,6 +10196,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
>  	.sta_add = wpa_driver_nl80211_sta_add,
>  	.sta_remove = driver_nl80211_sta_remove,
>  	.hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
> +	.send_eapol = wpa_driver_nl80211_send_eapol,
>  	.sta_set_flags = wpa_driver_nl80211_sta_set_flags,
>  	.hapd_init = i802_init,
>  	.hapd_deinit = i802_deinit,
> diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
> index fa2296b..e0a177c 100644
> --- a/wpa_supplicant/driver_i.h
> +++ b/wpa_supplicant/driver_i.h
> @@ -349,6 +349,16 @@ static inline int wpa_drv_hapd_send_eapol(struct wpa_supplicant *wpa_s,
>  	return -1;
>  }
>
> +static inline int wpa_drv_send_eapol(struct wpa_supplicant *wpa_s,
> +					  const u8 *addr, const u8 *data,
> +					  size_t data_len)
> +{
> +	if (wpa_s->driver->hapd_send_eapol)
> +		return wpa_s->driver->send_eapol(wpa_s->drv_priv, addr,
> +						      data, data_len);
> +	return -1;
> +}
> +
>  static inline int wpa_drv_sta_set_flags(struct wpa_supplicant *wpa_s,
>  					const u8 *addr, int total_flags,
>  					int flags_or, int flags_and)
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 3a2ec64..af9bf2a 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -3966,13 +3966,28 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
>  		}
>  #endif /* CONFIG_AP */
>  		break;
> -#ifdef CONFIG_AP
>  	case EVENT_EAPOL_TX_STATUS:
> +#ifdef CONFIG_AP
>  		ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
>  				   data->eapol_tx_status.data,
>  				   data->eapol_tx_status.data_len,
>  				   data->eapol_tx_status.ack);
> +#else
> +		wpa_dbg(wpa_s, MSG_DEBUG,
> +				"EAPOL_TX_STATUS: ACK(%d)",
> +				   data->eapol_tx_status.ack);
> +		if (!data->eapol_tx_status.ack &&
> +		   wpa_s->wpa_state == WPA_COMPLETED) {
> +			wpa_dbg(wpa_s, MSG_DEBUG,
> +				"EAPOL 4/4 Not acked, disconnecting");
> +			wpa_s->own_disconnect_req = 1;
> +			wpa_supplicant_deauthenticate(
> +				wpa_s, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
> +
> +		}
> +#endif
>  		break;
> +#ifdef CONFIG_AP
>  	case EVENT_DRIVER_CLIENT_POLL_OK:
>  		ap_client_poll_ok(wpa_s, data->client_poll.addr);
>  		break;
> diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
> index ae246f9..da81ac0 100644
> --- a/wpa_supplicant/wpas_glue.c
> +++ b/wpa_supplicant/wpas_glue.c
> @@ -97,6 +97,7 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
>  static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
>  			  u16 proto, const u8 *buf, size_t len)
>  {
> +	int ret;
>  #ifdef CONFIG_TESTING_OPTIONS
>  	if (wpa_s->ext_eapol_frame_io && proto == ETH_P_EAPOL) {
>  		size_t hex_len = 2 * len + 1;
> @@ -111,6 +112,11 @@ static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
>  		return 0;
>  	}
>  #endif /* CONFIG_TESTING_OPTIONS */
> +	ret = wpa_drv_send_eapol(wpa_s, dest, buf, len);
> +	if (ret < 0)
> +		wpa_printf(MSG_DEBUG, " (%d)", ret);
> +	else
> +		return ret;
>
>  	if (wpa_s->l2) {
>  		return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
>

-- 
Ben Greear <greearb at candelatech.com>
Candela Technologies Inc  http://www.candelatech.com



More information about the Hostap mailing list