mac80211: backport upstream fixes
authorKoen Vandeputte <koen.vandeputte@ncentric.com>
Wed, 6 Nov 2019 12:38:51 +0000 (13:38 +0100)
committerKoen Vandeputte <koen.vandeputte@ncentric.com>
Tue, 19 Nov 2019 14:02:22 +0000 (15:02 +0100)
This potentially fixes some issues seen on IBSS
when interfaces go out of range and then re-appear.

Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
package/kernel/mac80211/patches/subsys/365-mac80211-IBSS-send-deauth-when-expiring-inactive-STA.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/366-mac80211-accept-deauth-frames-in-IBSS-mode.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/367-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/subsys/365-mac80211-IBSS-send-deauth-when-expiring-inactive-STA.patch b/package/kernel/mac80211/patches/subsys/365-mac80211-IBSS-send-deauth-when-expiring-inactive-STA.patch
new file mode 100644 (file)
index 0000000..5b5acde
--- /dev/null
@@ -0,0 +1,128 @@
+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 */
+@@ -4371,7 +4372,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);
+@@ -5351,7 +5352,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);
+@@ -5371,7 +5372,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 */
diff --git a/package/kernel/mac80211/patches/subsys/366-mac80211-accept-deauth-frames-in-IBSS-mode.patch b/package/kernel/mac80211/patches/subsys/366-mac80211-accept-deauth-frames-in-IBSS-mode.patch
new file mode 100644 (file)
index 0000000..292cf55
--- /dev/null
@@ -0,0 +1,39 @@
+From 95697f9907bfe3eab0ef20265a766b22e27dde64 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 4 Oct 2019 15:37:05 +0300
+Subject: [PATCH] mac80211: accept deauth frames in IBSS mode
+
+We can process deauth frames and all, but we drop them very
+early in the RX path today - this could never have worked.
+
+Fixes: 2cc59e784b54 ("mac80211: reply to AUTH with DEAUTH if sta allocation fails in IBSS")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Link: https://lore.kernel.org/r/20191004123706.15768-2-luca@coelho.fi
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ net/mac80211/rx.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -3407,9 +3407,18 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
+       case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+               /* process for all: mesh, mlme, ibss */
+               break;
++      case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
++              if (is_multicast_ether_addr(mgmt->da) &&
++                  !is_broadcast_ether_addr(mgmt->da))
++                      return RX_DROP_MONITOR;
++
++              /* process only for station/IBSS */
++              if (sdata->vif.type != NL80211_IFTYPE_STATION &&
++                  sdata->vif.type != NL80211_IFTYPE_ADHOC)
++                      return RX_DROP_MONITOR;
++              break;
+       case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+       case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+-      case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+       case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+               if (is_multicast_ether_addr(mgmt->da) &&
+                   !is_broadcast_ether_addr(mgmt->da))
diff --git a/package/kernel/mac80211/patches/subsys/367-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/package/kernel/mac80211/patches/subsys/367-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch
new file mode 100644 (file)
index 0000000..58158b5
--- /dev/null
@@ -0,0 +1,38 @@
+From b478e06a16a8baa00c5ecc87c1d636981f2206d5 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 29 Oct 2019 10:25:25 +0100
+Subject: [PATCH] mac80211: sta: randomize BA session dialog token allocator
+
+We currently always start the dialog token generator at zero,
+so the first dialog token we use is always 1. This would be
+OK if we had a perfect guarantee that we always do a proper
+deauth/re-auth handshake, but in IBSS mode this doesn't always
+happen properly.
+
+To make problems with block ack (aggregation) sessions getting
+stuck less likely, randomize the dialog token so if we start a
+new session but the peer still has old state for us, it can
+better detect this.
+
+This is really just a workaround to make things a bit more
+robust than they are now - a better fix would be to do a full
+authentication handshake in IBSS mode upon having discovered a
+new station, and on the receiver resetting the state (removing
+and re-adding the station) on receiving the authentication
+packet.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ net/mac80211/sta_info.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -322,6 +322,7 @@ struct sta_info *sta_info_alloc(struct i
+       INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
+       INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
+       mutex_init(&sta->ampdu_mlme.mtx);
++      sta->ampdu_mlme.dialog_token_allocator = prandom_u32_max(U8_MAX);
+ #ifdef CPTCFG_MAC80211_MESH
+       if (ieee80211_vif_is_mesh(&sdata->vif)) {
+               sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);