]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
mac80211: IBSS: send deauth when expiring inactive STAs
authorJohannes Berg <johannes.berg@intel.com>
Fri, 30 Aug 2019 11:24:51 +0000 (14:24 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 11 Sep 2019 07:33:29 +0000 (09:33 +0200)
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
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/util.c

index f00dca05629596b4f0bf4a03880249b082066137..0a6ff01c68a9659b71bb0823ccc089a0cc4964cb 100644 (file)
@@ -1252,6 +1252,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
 
 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;
@@ -1268,10 +1269,17 @@ static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
                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));
                }
        }
index 791ce58d0f09f0ef58e5fd8d42d23e26afeef3e4..05406e9c05b3214dba881b36975eb7ecf5f1a615 100644 (file)
@@ -2099,7 +2099,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         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 {
index 31f0bae28dcc0a639f3e9ed546136f18cfb66296..26a2f49208b6a30623667f21dfb0b18fd7aba2d2 100644 (file)
@@ -2278,8 +2278,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
                    !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 */
@@ -4509,7 +4510,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
                 * 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);
@@ -5550,7 +5551,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                           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);
@@ -5570,7 +5571,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                           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);
index 92bfedfd3fd2803a6de1b06b2c1228ce3542a51a..051a02ddcb854d5dae0eb33e742129ffcf203848 100644 (file)
@@ -1583,7 +1583,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 }
 
 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;
@@ -1594,7 +1595,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
        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 */