aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2016-12-19 23:30:09 (GMT)
committerJouni Malinen <j@w1.fi>2016-12-19 23:30:09 (GMT)
commit1f0fdaf0e45fac76fcd6d2382e28e0298e1edef0 (patch)
tree0259df6d97feaa0b16123106bcaf60800bcc5f92
parentad02e79d12fd70ed6bd5fbaf64001a2851e5bb7b (diff)
downloadhostap-1f0fdaf0e45fac76fcd6d2382e28e0298e1edef0.zip
hostap-1f0fdaf0e45fac76fcd6d2382e28e0298e1edef0.tar.gz
hostap-1f0fdaf0e45fac76fcd6d2382e28e0298e1edef0.tar.bz2
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>
-rw-r--r--src/ap/ieee802_11.c24
-rw-r--r--src/ap/sta_info.h1
2 files changed, 24 insertions, 1 deletions
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 1cecc80..f3d8c96 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2634,6 +2634,8 @@ static void handle_assoc(struct hostapd_data *hapd,
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 hostapd_data *hapd,
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 hostapd_data *hapd, const u8 *src,
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];
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index 980afed..0b44f7b 100644
--- 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;