From 75d11f665c3fb28d2c0fe90e236632d211ec41ea Mon Sep 17 00:00:00 2001 From: Koen Vandeputte Date: Wed, 6 Nov 2019 13:38:51 +0100 Subject: [PATCH] mac80211: backport upstream fixes This potentially fixes some issues seen on IBSS when interfaces go out of range and then re-appear. Signed-off-by: Koen Vandeputte --- ...nd-deauth-when-expiring-inactive-STA.patch | 128 ++++++++++++++++++ ...11-accept-deauth-frames-in-IBSS-mode.patch | 39 ++++++ ...domize-BA-session-dialog-token-alloc.patch | 38 ++++++ 3 files changed, 205 insertions(+) create mode 100644 package/kernel/mac80211/patches/subsys/365-mac80211-IBSS-send-deauth-when-expiring-inactive-STA.patch create mode 100644 package/kernel/mac80211/patches/subsys/366-mac80211-accept-deauth-frames-in-IBSS-mode.patch create mode 100644 package/kernel/mac80211/patches/subsys/367-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch 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 index 0000000000..5b5acded9a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/365-mac80211-IBSS-send-deauth-when-expiring-inactive-STA.patch @@ -0,0 +1,128 @@ +From 4b08d1b6a994dbb593557bd2095ba4f0c3c47819 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +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 +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/20190830112451.21655-9-luca@coelho.fi +Signed-off-by: Johannes Berg +--- + 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 index 0000000000..292cf55843 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/366-mac80211-accept-deauth-frames-in-IBSS-mode.patch @@ -0,0 +1,39 @@ +From 95697f9907bfe3eab0ef20265a766b22e27dde64 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +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 +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/20191004123706.15768-2-luca@coelho.fi +Signed-off-by: Johannes Berg +--- + 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 index 0000000000..58158b58e6 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/367-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch @@ -0,0 +1,38 @@ +From b478e06a16a8baa00c5ecc87c1d636981f2206d5 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +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 +--- + 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); -- 2.30.2