summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2019-08-30 07:24:51 -0400
committerJohannes Berg <johannes.berg@intel.com>2019-09-11 03:33:29 -0400
commit4b08d1b6a994dbb593557bd2095ba4f0c3c47819 (patch)
tree3d44a28ca9693a078946f93cb96785da93921468 /net/mac80211
parent753a9a729f84e22b3726f5bf61e1a9b59712d04f (diff)
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>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ibss.c8
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c11
-rw-r--r--net/mac80211/util.c5
4 files changed, 19 insertions, 8 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f00dca056295..0a6ff01c68a9 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1252,6 +1252,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
1252 1252
1253static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) 1253static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
1254{ 1254{
1255 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
1255 struct ieee80211_local *local = sdata->local; 1256 struct ieee80211_local *local = sdata->local;
1256 struct sta_info *sta, *tmp; 1257 struct sta_info *sta, *tmp;
1257 unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT; 1258 unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT;
@@ -1268,10 +1269,17 @@ static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
1268 if (time_is_before_jiffies(last_active + exp_time) || 1269 if (time_is_before_jiffies(last_active + exp_time) ||
1269 (time_is_before_jiffies(last_active + exp_rsn) && 1270 (time_is_before_jiffies(last_active + exp_rsn) &&
1270 sta->sta_state != IEEE80211_STA_AUTHORIZED)) { 1271 sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
1272 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
1273
1271 sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n", 1274 sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
1272 sta->sta_state != IEEE80211_STA_AUTHORIZED ? 1275 sta->sta_state != IEEE80211_STA_AUTHORIZED ?
1273 "not authorized " : "", sta->sta.addr); 1276 "not authorized " : "", sta->sta.addr);
1274 1277
1278 ieee80211_send_deauth_disassoc(sdata, sta->sta.addr,
1279 ifibss->bssid,
1280 IEEE80211_STYPE_DEAUTH,
1281 WLAN_REASON_DEAUTH_LEAVING,
1282 true, frame_buf);
1275 WARN_ON(__sta_info_destroy(sta)); 1283 WARN_ON(__sta_info_destroy(sta));
1276 } 1284 }
1277 } 1285 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 791ce58d0f09..05406e9c05b3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2099,7 +2099,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
2099 const u8 *da, const u8 *key, u8 key_len, u8 key_idx, 2099 const u8 *da, const u8 *key, u8 key_len, u8 key_idx,
2100 u32 tx_flags); 2100 u32 tx_flags);
2101void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 2101void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
2102 const u8 *bssid, u16 stype, u16 reason, 2102 const u8 *da, const u8 *bssid,
2103 u16 stype, u16 reason,
2103 bool send_frame, u8 *frame_buf); 2104 bool send_frame, u8 *frame_buf);
2104 2105
2105enum { 2106enum {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 31f0bae28dcc..26a2f49208b6 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2278,8 +2278,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2278 !ifmgd->have_beacon) 2278 !ifmgd->have_beacon)
2279 drv_mgd_prepare_tx(sdata->local, sdata, 0); 2279 drv_mgd_prepare_tx(sdata->local, sdata, 0);
2280 2280
2281 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, 2281 ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
2282 reason, tx, frame_buf); 2282 ifmgd->bssid, stype, reason,
2283 tx, frame_buf);
2283 } 2284 }
2284 2285
2285 /* flush out frame - make sure the deauth was actually sent */ 2286 /* flush out frame - make sure the deauth was actually sent */
@@ -4509,7 +4510,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
4509 * cfg80211 won't know and won't actually abort those attempts, 4510 * cfg80211 won't know and won't actually abort those attempts,
4510 * thus we need to do that ourselves. 4511 * thus we need to do that ourselves.
4511 */ 4512 */
4512 ieee80211_send_deauth_disassoc(sdata, bssid, 4513 ieee80211_send_deauth_disassoc(sdata, bssid, bssid,
4513 IEEE80211_STYPE_DEAUTH, 4514 IEEE80211_STYPE_DEAUTH,
4514 WLAN_REASON_DEAUTH_LEAVING, 4515 WLAN_REASON_DEAUTH_LEAVING,
4515 false, frame_buf); 4516 false, frame_buf);
@@ -5550,7 +5551,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
5550 ieee80211_get_reason_code_string(req->reason_code)); 5551 ieee80211_get_reason_code_string(req->reason_code));
5551 5552
5552 drv_mgd_prepare_tx(sdata->local, sdata, 0); 5553 drv_mgd_prepare_tx(sdata->local, sdata, 0);
5553 ieee80211_send_deauth_disassoc(sdata, req->bssid, 5554 ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
5554 IEEE80211_STYPE_DEAUTH, 5555 IEEE80211_STYPE_DEAUTH,
5555 req->reason_code, tx, 5556 req->reason_code, tx,
5556 frame_buf); 5557 frame_buf);
@@ -5570,7 +5571,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
5570 ieee80211_get_reason_code_string(req->reason_code)); 5571 ieee80211_get_reason_code_string(req->reason_code));
5571 5572
5572 drv_mgd_prepare_tx(sdata->local, sdata, 0); 5573 drv_mgd_prepare_tx(sdata->local, sdata, 0);
5573 ieee80211_send_deauth_disassoc(sdata, req->bssid, 5574 ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
5574 IEEE80211_STYPE_DEAUTH, 5575 IEEE80211_STYPE_DEAUTH,
5575 req->reason_code, tx, 5576 req->reason_code, tx,
5576 frame_buf); 5577 frame_buf);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 92bfedfd3fd2..051a02ddcb85 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1583,7 +1583,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1583} 1583}
1584 1584
1585void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 1585void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1586 const u8 *bssid, u16 stype, u16 reason, 1586 const u8 *da, const u8 *bssid,
1587 u16 stype, u16 reason,
1587 bool send_frame, u8 *frame_buf) 1588 bool send_frame, u8 *frame_buf)
1588{ 1589{
1589 struct ieee80211_local *local = sdata->local; 1590 struct ieee80211_local *local = sdata->local;
@@ -1594,7 +1595,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1594 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype); 1595 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
1595 mgmt->duration = 0; /* initialize only */ 1596 mgmt->duration = 0; /* initialize only */
1596 mgmt->seq_ctrl = 0; /* initialize only */ 1597 mgmt->seq_ctrl = 0; /* initialize only */
1597 memcpy(mgmt->da, bssid, ETH_ALEN); 1598 memcpy(mgmt->da, da, ETH_ALEN);
1598 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 1599 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
1599 memcpy(mgmt->bssid, bssid, ETH_ALEN); 1600 memcpy(mgmt->bssid, bssid, ETH_ALEN);
1600 /* u.deauth.reason_code == u.disassoc.reason_code */ 1601 /* u.deauth.reason_code == u.disassoc.reason_code */