123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- From: Emmanuel Grumbach <[email protected]>
- Date: Fri, 31 Aug 2018 11:31:12 +0300
- Subject: [PATCH] mac80211: don't Tx a deauth frame if the AP forbade Tx
- If the driver fails to properly prepare for the channel
- switch, mac80211 will disconnect. If the CSA IE had mode
- set to 1, it means that the clients are not allowed to send
- any Tx on the current channel, and that includes the
- deauthentication frame.
- Make sure that we don't send the deauthentication frame in
- this case.
- In iwlwifi, this caused a failure to flush queues since the
- firmware already closed the queues after having parsed the
- CSA IE. Then mac80211 would wait until the deauthentication
- frame would go out (drv_flush(drop=false)) and that would
- never happen.
- Signed-off-by: Emmanuel Grumbach <[email protected]>
- Signed-off-by: Luca Coelho <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- ---
- --- a/net/mac80211/mlme.c
- +++ b/net/mac80211/mlme.c
- @@ -1267,6 +1267,16 @@ ieee80211_sta_process_chanswitch(struct
- cbss->beacon_interval));
- return;
- drop_connection:
- + /*
- + * This is just so that the disconnect flow will know that
- + * we were trying to switch channel and failed. In case the
- + * mode is 1 (we are not allowed to Tx), we will know not to
- + * send a deauthentication frame. Those two fields will be
- + * reset when the disconnection worker runs.
- + */
- + sdata->vif.csa_active = true;
- + sdata->csa_block_tx = csa_ie.mode;
- +
- ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
- mutex_unlock(&local->chanctx_mtx);
- mutex_unlock(&local->mtx);
- @@ -2437,6 +2447,7 @@ static void __ieee80211_disconnect(struc
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
- u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
- + bool tx;
-
- sdata_lock(sdata);
- if (!ifmgd->associated) {
- @@ -2444,6 +2455,8 @@ static void __ieee80211_disconnect(struc
- return;
- }
-
- + tx = !sdata->csa_block_tx;
- +
- /* AP is probably out of range (or not reachable for another reason) so
- * remove the bss struct for that AP.
- */
- @@ -2451,7 +2464,7 @@ static void __ieee80211_disconnect(struc
-
- ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
- - true, frame_buf);
- + tx, frame_buf);
- mutex_lock(&local->mtx);
- sdata->vif.csa_active = false;
- ifmgd->csa_waiting_bcn = false;
- @@ -2462,7 +2475,7 @@ static void __ieee80211_disconnect(struc
- }
- mutex_unlock(&local->mtx);
-
- - ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
- + ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
-
- sdata_unlock(sdata);
|