Skip to content

Commit

Permalink
mac80211: don't Tx a deauth frame if the AP forbade Tx
Browse files Browse the repository at this point in the history
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 <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
  • Loading branch information
Emmanuel Grumbach authored and Johannes Berg committed Sep 3, 2018
1 parent 0007e94 commit 6c18b27
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,16 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
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);
Expand Down Expand Up @@ -2453,21 +2463,24 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
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) {
sdata_unlock(sdata);
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.
*/
cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);

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;
Expand All @@ -2478,7 +2491,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
}
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);
Expand Down

0 comments on commit 6c18b27

Please sign in to comment.