1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- 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;
-
|