[PATCH] mac80211: Send deauth to STA's upon AP stop

Shay Bar
2020-06-18T09:36:30Z

In current code, AP is not informing STA when its going down.
So STA keep looking the AP (Null function etc.) and can't find it (it is down).

Fix is to send deauth to all associated STA's upon AP stop.
__sta_info_flush() with a true bool is only called from ieee80211_stop_ap().
Rename "vlans" -> "ap_stop".

Signed-off-by: Shay Bar <shay.bar@celeno.com>
---
net/mac80211/sta_info.c | 20 ++++++++++++++++----
net/mac80211/sta_info.h | 5 +++--
2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index cd8487bc6fc2..46b26e66430a 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1179,7 +1179,7 @@ void sta_info_stop(struct ieee80211_local *local)
}

-int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
+int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool ap_stop)
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta, *tmp;
@@ -1188,13 +1188,25 @@ int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)

might_sleep();

- WARN_ON(vlans && sdata->vif.type != NL80211_IFTYPE_AP);
- WARN_ON(vlans && !sdata->bss);
+ WARN_ON(ap_stop && sdata->vif.type != NL80211_IFTYPE_AP);
+ WARN_ON(ap_stop && !sdata->bss);

mutex_lock(&local->sta_mtx);
list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
if (sdata == sta->sdata ||
- (vlans && sdata->bss == sta->sdata->bss)) {
+ (ap_stop && sdata->bss == sta->sdata->bss)) {
+ if (ap_stop) {
+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
+ u16 stype = IEEE80211_STYPE_DEAUTH;
+ u16 reason = WLAN_REASON_DEAUTH_LEAVING;
+ ieee80211_send_deauth_disassoc(sdata,
+ sta->sta.addr,
+ sdata->vif.addr,
+ stype,
+ reason,
+ true,
+ frame_buf);
+ }
if (!WARN_ON(__sta_info_destroy_part1(sta)))
list_add(&sta->free_list, &free_list);
ret++;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 49728047dfad..f0aedfa221c2 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -789,9 +789,10 @@ void sta_info_stop(struct ieee80211_local *local);
* Returns the number of removed STA entries.
*
* @sdata: sdata to remove all stations from
- * @vlans: if the given interface is an AP interface, also flush VLANs
+ * @ap_stop: if the given interface is an AP being stopped, we should send
+ * deauth to STA's and flush VLANs
*/
-int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
+int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool ap_stop);

static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
{
--
2.17.1