84 lines
2.8 KiB
Diff
84 lines
2.8 KiB
Diff
|
From: Jouni Malinen <jouni@qca.qualcomm.com>
|
||
|
Date: Tue, 20 Dec 2016 01:30:09 +0200
|
||
|
Subject: [PATCH] Fix race condition between AssocResp callback and 4addr event
|
||
|
|
||
|
It is apparently possible for the NL80211_CMD_UNEXPECTED_4ADDR_FRAME
|
||
|
event to be delivered to hostapd before the NL80211_CMD_FRAME_TX_STATUS
|
||
|
event for (Re)Association Response frame. This resulted in the 4-address
|
||
|
WDS mode not getting enabled for a STA. This could occur in particular
|
||
|
when operating under heavy load and the STA is reconnecting to the same
|
||
|
AP in a sequence where Deauthentication frame is followed immediately by
|
||
|
Authentication frame and the driver event processing gets delayed due to
|
||
|
removal of the previous netdev taking time in the middle of this
|
||
|
sequence.
|
||
|
|
||
|
Fix this by recording a pending item for 4-address WDS enabling if the
|
||
|
NL80211_CMD_UNEXPECTED_4ADDR_FRAME event would have been dropped due to
|
||
|
incompleted association and then process this pending item if the TX
|
||
|
status for the (Re)Association Response frame is received and it shows
|
||
|
that the frame was acknowledged.
|
||
|
|
||
|
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
|
||
|
---
|
||
|
|
||
|
--- a/src/ap/ieee802_11.c
|
||
|
+++ b/src/ap/ieee802_11.c
|
||
|
@@ -2634,6 +2634,8 @@ static void handle_assoc(struct hostapd_
|
||
|
taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
|
||
|
#endif /* CONFIG_TAXONOMY */
|
||
|
|
||
|
+ sta->pending_wds_enable = 0;
|
||
|
+
|
||
|
fail:
|
||
|
/*
|
||
|
* In case of a successful response, add the station to the driver.
|
||
|
@@ -3248,6 +3250,14 @@ static void handle_assoc_cb(struct hosta
|
||
|
|
||
|
hostapd_set_sta_flags(hapd, sta);
|
||
|
|
||
|
+ if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
|
||
|
+ wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
|
||
|
+ MACSTR " based on pending request",
|
||
|
+ MAC2STR(sta->addr));
|
||
|
+ sta->pending_wds_enable = 0;
|
||
|
+ sta->flags |= WLAN_STA_WDS;
|
||
|
+ }
|
||
|
+
|
||
|
if (sta->flags & WLAN_STA_WDS) {
|
||
|
int ret;
|
||
|
char ifname_wds[IFNAMSIZ + 1];
|
||
|
@@ -3512,10 +3522,22 @@ void ieee802_11_rx_from_unknown(struct h
|
||
|
struct sta_info *sta;
|
||
|
|
||
|
sta = ap_get_sta(hapd, src);
|
||
|
- if (sta && (sta->flags & WLAN_STA_ASSOC)) {
|
||
|
+ if (sta &&
|
||
|
+ ((sta->flags & WLAN_STA_ASSOC) ||
|
||
|
+ ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
|
||
|
if (!hapd->conf->wds_sta)
|
||
|
return;
|
||
|
|
||
|
+ if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
|
||
|
+ WLAN_STA_ASSOC_REQ_OK) {
|
||
|
+ wpa_printf(MSG_DEBUG,
|
||
|
+ "Postpone 4-address WDS mode enabling for STA "
|
||
|
+ MACSTR " since TX status for AssocResp is not yet known",
|
||
|
+ MAC2STR(sta->addr));
|
||
|
+ sta->pending_wds_enable = 1;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
if (wds && !(sta->flags & WLAN_STA_WDS)) {
|
||
|
int ret;
|
||
|
char ifname_wds[IFNAMSIZ + 1];
|
||
|
--- a/src/ap/sta_info.h
|
||
|
+++ b/src/ap/sta_info.h
|
||
|
@@ -115,6 +115,7 @@ struct sta_info {
|
||
|
unsigned int radius_das_match:1;
|
||
|
unsigned int ecsa_supported:1;
|
||
|
unsigned int added_unassoc:1;
|
||
|
+ unsigned int pending_wds_enable:1;
|
||
|
|
||
|
u16 auth_alg;
|
||
|
|