90722a32ceb21fb95ae49138e233302abf3af4a7
[librecmc/librecmc.git] /
1 From 4b08d1b6a994dbb593557bd2095ba4f0c3c47819 Mon Sep 17 00:00:00 2001
2 From: Johannes Berg <johannes.berg@intel.com>
3 Date: Fri, 30 Aug 2019 14:24:51 +0300
4 Subject: [PATCH] mac80211: IBSS: send deauth when expiring inactive STAs
5
6 When we expire an inactive station, try to send it a deauth. This
7 helps if it's actually still around, and just has issues with
8 beacon distribution (or we do), and it will not also remove us.
9 Then, if we have shared state, this may not be reset properly,
10 causing problems; for example, we saw a case where aggregation
11 sessions weren't removed properly (due to the TX start being
12 offloaded to firmware and it relying on deauth for stop), causing
13 a lot of traffic to get lost due to the SN reset after remove/add
14 of the peer.
15
16 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
17 Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
18 Link: https://lore.kernel.org/r/20190830112451.21655-9-luca@coelho.fi
19 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
20 ---
21  net/mac80211/ibss.c        |  8 ++++++++
22  net/mac80211/ieee80211_i.h |  3 ++-
23  net/mac80211/mlme.c        | 11 ++++++-----
24  net/mac80211/util.c        |  5 +++--
25  4 files changed, 19 insertions(+), 8 deletions(-)
26
27 --- a/net/mac80211/ibss.c
28 +++ b/net/mac80211/ibss.c
29 @@ -1253,6 +1253,7 @@ void ieee80211_ibss_rx_no_sta(struct iee
30  
31  static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
32  {
33 +       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
34         struct ieee80211_local *local = sdata->local;
35         struct sta_info *sta, *tmp;
36         unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT;
37 @@ -1269,10 +1270,17 @@ static void ieee80211_ibss_sta_expire(st
38                 if (time_is_before_jiffies(last_active + exp_time) ||
39                     (time_is_before_jiffies(last_active + exp_rsn) &&
40                      sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
41 +                       u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
42 +
43                         sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
44                                 sta->sta_state != IEEE80211_STA_AUTHORIZED ?
45                                 "not authorized " : "", sta->sta.addr);
46  
47 +                       ieee80211_send_deauth_disassoc(sdata, sta->sta.addr,
48 +                                                      ifibss->bssid,
49 +                                                      IEEE80211_STYPE_DEAUTH,
50 +                                                      WLAN_REASON_DEAUTH_LEAVING,
51 +                                                      true, frame_buf);
52                         WARN_ON(__sta_info_destroy(sta));
53                 }
54         }
55 --- a/net/mac80211/ieee80211_i.h
56 +++ b/net/mac80211/ieee80211_i.h
57 @@ -2069,7 +2069,8 @@ void ieee80211_send_auth(struct ieee8021
58                          const u8 *da, const u8 *key, u8 key_len, u8 key_idx,
59                          u32 tx_flags);
60  void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
61 -                                   const u8 *bssid, u16 stype, u16 reason,
62 +                                   const u8 *da, const u8 *bssid,
63 +                                   u16 stype, u16 reason,
64                                     bool send_frame, u8 *frame_buf);
65  
66  enum {
67 --- a/net/mac80211/mlme.c
68 +++ b/net/mac80211/mlme.c
69 @@ -2203,8 +2203,9 @@ static void ieee80211_set_disassoc(struc
70                     !ifmgd->have_beacon)
71                         drv_mgd_prepare_tx(sdata->local, sdata, 0);
72  
73 -               ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype,
74 -                                              reason, tx, frame_buf);
75 +               ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid,
76 +                                              ifmgd->bssid, stype, reason,
77 +                                              tx, frame_buf);
78         }
79  
80         /* flush out frame - make sure the deauth was actually sent */
81 @@ -4369,7 +4370,7 @@ void ieee80211_mgd_quiesce(struct ieee80
82                  * cfg80211 won't know and won't actually abort those attempts,
83                  * thus we need to do that ourselves.
84                  */
85 -               ieee80211_send_deauth_disassoc(sdata, bssid,
86 +               ieee80211_send_deauth_disassoc(sdata, bssid, bssid,
87                                                IEEE80211_STYPE_DEAUTH,
88                                                WLAN_REASON_DEAUTH_LEAVING,
89                                                false, frame_buf);
90 @@ -5349,7 +5350,7 @@ int ieee80211_mgd_deauth(struct ieee8021
91                            ieee80211_get_reason_code_string(req->reason_code));
92  
93                 drv_mgd_prepare_tx(sdata->local, sdata, 0);
94 -               ieee80211_send_deauth_disassoc(sdata, req->bssid,
95 +               ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
96                                                IEEE80211_STYPE_DEAUTH,
97                                                req->reason_code, tx,
98                                                frame_buf);
99 @@ -5369,7 +5370,7 @@ int ieee80211_mgd_deauth(struct ieee8021
100                            ieee80211_get_reason_code_string(req->reason_code));
101  
102                 drv_mgd_prepare_tx(sdata->local, sdata, 0);
103 -               ieee80211_send_deauth_disassoc(sdata, req->bssid,
104 +               ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
105                                                IEEE80211_STYPE_DEAUTH,
106                                                req->reason_code, tx,
107                                                frame_buf);
108 --- a/net/mac80211/util.c
109 +++ b/net/mac80211/util.c
110 @@ -1433,7 +1433,8 @@ void ieee80211_send_auth(struct ieee8021
111  }
112  
113  void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
114 -                                   const u8 *bssid, u16 stype, u16 reason,
115 +                                   const u8 *da, const u8 *bssid,
116 +                                   u16 stype, u16 reason,
117                                     bool send_frame, u8 *frame_buf)
118  {
119         struct ieee80211_local *local = sdata->local;
120 @@ -1444,7 +1445,7 @@ void ieee80211_send_deauth_disassoc(stru
121         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
122         mgmt->duration = 0; /* initialize only */
123         mgmt->seq_ctrl = 0; /* initialize only */
124 -       memcpy(mgmt->da, bssid, ETH_ALEN);
125 +       memcpy(mgmt->da, da, ETH_ALEN);
126         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
127         memcpy(mgmt->bssid, bssid, ETH_ALEN);
128         /* u.deauth.reason_code == u.disassoc.reason_code */