|
@@ -0,0 +1,83 @@
|
|
|
|
+From: Jouni Malinen <[email protected]>
|
|
|
|
+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 <[email protected]>
|
|
|
|
+---
|
|
|
|
+
|
|
|
|
+--- 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;
|
|
|
|
+
|