mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-07 14:28:50 +00:00
e30ca0d90a
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
129 lines
5.1 KiB
Diff
129 lines
5.1 KiB
Diff
From 4b08d1b6a994dbb593557bd2095ba4f0c3c47819 Mon Sep 17 00:00:00 2001
|
|
From: Johannes Berg <johannes.berg@intel.com>
|
|
Date: Fri, 30 Aug 2019 14:24:51 +0300
|
|
Subject: [PATCH] mac80211: IBSS: send deauth when expiring inactive STAs
|
|
|
|
When we expire an inactive station, try to send it a deauth. This
|
|
helps if it's actually still around, and just has issues with
|
|
beacon distribution (or we do), and it will not also remove us.
|
|
Then, if we have shared state, this may not be reset properly,
|
|
causing problems; for example, we saw a case where aggregation
|
|
sessions weren't removed properly (due to the TX start being
|
|
offloaded to firmware and it relying on deauth for stop), causing
|
|
a lot of traffic to get lost due to the SN reset after remove/add
|
|
of the peer.
|
|
|
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
|
Link: https://lore.kernel.org/r/20190830112451.21655-9-luca@coelho.fi
|
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
---
|
|
net/mac80211/ibss.c | 8 ++++++++
|
|
net/mac80211/ieee80211_i.h | 3 ++-
|
|
net/mac80211/mlme.c | 11 ++++++-----
|
|
net/mac80211/util.c | 5 +++--
|
|
4 files changed, 19 insertions(+), 8 deletions(-)
|
|
|
|
--- a/net/mac80211/ibss.c
|
|
+++ b/net/mac80211/ibss.c
|
|
@@ -1253,6 +1253,7 @@ void ieee80211_ibss_rx_no_sta(struct iee
|
|
|
|
static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
|
|
{
|
|
+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
|
struct ieee80211_local *local = sdata->local;
|
|
struct sta_info *sta, *tmp;
|
|
unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT;
|
|
@@ -1269,10 +1270,17 @@ static void ieee80211_ibss_sta_expire(st
|
|
if (time_is_before_jiffies(last_active + exp_time) ||
|
|
(time_is_before_jiffies(last_active + exp_rsn) &&
|
|
sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
|
|
+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
|
+
|
|
sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
|
|
sta->sta_state != IEEE80211_STA_AUTHORIZED ?
|
|
"not authorized " : "", sta->sta.addr);
|
|
|
|
+ ieee80211_send_deauth_disassoc(sdata, sta->sta.addr,
|
|
+ ifibss->bssid,
|
|
+ IEEE80211_STYPE_DEAUTH,
|
|
+ WLAN_REASON_DEAUTH_LEAVING,
|
|
+ true, frame_buf);
|
|
WARN_ON(__sta_info_destroy(sta));
|
|
}
|
|
}
|
|
--- a/net/mac80211/ieee80211_i.h
|
|
+++ b/net/mac80211/ieee80211_i.h
|
|
@@ -2070,7 +2070,8 @@ void ieee80211_send_auth(struct ieee8021
|
|
const u8 *da, const u8 *key, u8 key_len, u8 key_idx,
|
|
u32 tx_flags);
|
|
void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
|
|
- const u8 *bssid, u16 stype, u16 reason,
|
|
+ const u8 *da, const u8 *bssid,
|
|
+ u16 stype, u16 reason,
|
|
bool send_frame, u8 *frame_buf);
|
|
|
|
enum {
|
|
--- a/net/mac80211/mlme.c
|
|
+++ b/net/mac80211/mlme.c
|
|
@@ -2203,8 +2203,9 @@ static void ieee80211_set_disassoc(struc
|
|
!ifmgd->have_beacon)
|
|
drv_mgd_prepare_tx(sdata->local, sdata, 0);
|
|
|
|
- ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
|
|
- reason, tx, frame_buf);
|
|
+ ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
|
|
+ ifmgd->bssid, stype, reason,
|
|
+ tx, frame_buf);
|
|
}
|
|
|
|
/* flush out frame - make sure the deauth was actually sent */
|
|
@@ -4369,7 +4370,7 @@ void ieee80211_mgd_quiesce(struct ieee80
|
|
* cfg80211 won't know and won't actually abort those attempts,
|
|
* thus we need to do that ourselves.
|
|
*/
|
|
- ieee80211_send_deauth_disassoc(sdata, bssid,
|
|
+ ieee80211_send_deauth_disassoc(sdata, bssid, bssid,
|
|
IEEE80211_STYPE_DEAUTH,
|
|
WLAN_REASON_DEAUTH_LEAVING,
|
|
false, frame_buf);
|
|
@@ -5349,7 +5350,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
|
ieee80211_get_reason_code_string(req->reason_code));
|
|
|
|
drv_mgd_prepare_tx(sdata->local, sdata, 0);
|
|
- ieee80211_send_deauth_disassoc(sdata, req->bssid,
|
|
+ ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
|
|
IEEE80211_STYPE_DEAUTH,
|
|
req->reason_code, tx,
|
|
frame_buf);
|
|
@@ -5369,7 +5370,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
|
ieee80211_get_reason_code_string(req->reason_code));
|
|
|
|
drv_mgd_prepare_tx(sdata->local, sdata, 0);
|
|
- ieee80211_send_deauth_disassoc(sdata, req->bssid,
|
|
+ ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
|
|
IEEE80211_STYPE_DEAUTH,
|
|
req->reason_code, tx,
|
|
frame_buf);
|
|
--- a/net/mac80211/util.c
|
|
+++ b/net/mac80211/util.c
|
|
@@ -1427,7 +1427,8 @@ void ieee80211_send_auth(struct ieee8021
|
|
}
|
|
|
|
void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
|
|
- const u8 *bssid, u16 stype, u16 reason,
|
|
+ const u8 *da, const u8 *bssid,
|
|
+ u16 stype, u16 reason,
|
|
bool send_frame, u8 *frame_buf)
|
|
{
|
|
struct ieee80211_local *local = sdata->local;
|
|
@@ -1438,7 +1439,7 @@ void ieee80211_send_deauth_disassoc(stru
|
|
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
|
|
mgmt->duration = 0; /* initialize only */
|
|
mgmt->seq_ctrl = 0; /* initialize only */
|
|
- memcpy(mgmt->da, bssid, ETH_ALEN);
|
|
+ memcpy(mgmt->da, da, ETH_ALEN);
|
|
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
|
memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
|
/* u.deauth.reason_code == u.disassoc.reason_code */
|