aboutsummaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches-testing/319-eap_auth_disassoc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/madwifi/patches-testing/319-eap_auth_disassoc.patch')
-rw-r--r--package/madwifi/patches-testing/319-eap_auth_disassoc.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/package/madwifi/patches-testing/319-eap_auth_disassoc.patch b/package/madwifi/patches-testing/319-eap_auth_disassoc.patch
new file mode 100644
index 0000000000..a1d9b0ba4e
--- /dev/null
+++ b/package/madwifi/patches-testing/319-eap_auth_disassoc.patch
@@ -0,0 +1,81 @@
+This patch causes STA mode interfaces to disassociate if transmission of assoc/auth
+critical packets failed.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+--- a/ath/if_ath.c
++++ b/ath/if_ath.c
+@@ -8273,6 +8273,18 @@
+ #endif
+ if (ts->ts_status & HAL_TXERR_XRETRY) {
+ sc->sc_stats.ast_tx_xretries++;
++ if (SKB_CB(bf->bf_skb)->auth_pkt && (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) {
++ struct ieee80211com *ic = &sc->sc_ic;
++
++ /* if roaming is enabled, try reassociating, otherwise
++ * disassociate and go back to the scan state */
++ IEEE80211_VAPS_LOCK_BH(ic);
++ if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
++ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_ASSOC, 1);
++ else
++ ni->ni_vap->iv_newstate(ni->ni_vap, IEEE80211_S_SCAN, 0);
++ IEEE80211_VAPS_UNLOCK_BH(ic);
++ }
+ if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) {
+ ni->ni_stats.ns_tx_eosplost++;
+ DPRINTF(sc, ATH_DEBUG_UAPSD,
+--- a/net80211/ieee80211_linux.c
++++ b/net80211/ieee80211_linux.c
+@@ -158,6 +158,7 @@
+
+ SKB_NI(skb) = NULL;
+ SKB_CB(skb)->flags = 0;
++ SKB_CB(skb)->auth_pkt = 0;
+
+ skb_reserve(skb, sizeof(struct ieee80211_frame));
+ *frm = skb_put(skb, pktlen);
+--- a/net80211/ieee80211_linux.h
++++ b/net80211/ieee80211_linux.h
+@@ -411,6 +411,7 @@
+ #define M_SKB_TRACKED 0x20
+ void (*next_destructor)(struct sk_buff *skb);
+ #endif
++ u_int8_t auth_pkt;
+ };
+
+ struct __assert {
+--- a/net80211/ieee80211_output.c
++++ b/net80211/ieee80211_output.c
+@@ -773,6 +773,8 @@
+ else
+ hdrsize = sizeof(struct ieee80211_frame);
+
++ SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
++
+ switch (vap->iv_opmode) {
+ case IEEE80211_M_IBSS:
+ case IEEE80211_M_AHDEMO:
+@@ -1617,6 +1619,7 @@
+ ie->param_len = frm - &ie->param_oui[0];
+ return frm;
+ }
++
+ #endif
+ /*
+ * Send a probe request frame with the specified ssid
+@@ -1881,6 +1884,7 @@
+ sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0));
+ if (skb == NULL)
+ senderr(ENOMEM, is_tx_nobuf);
++ SKB_CB(skb)->auth_pkt = 1;
+
+ ((__le16 *)frm)[0] =
+ (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
+@@ -1955,6 +1959,7 @@
+ vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length);
+ if (skb == NULL)
+ senderr(ENOMEM, is_tx_nobuf);
++ SKB_CB(skb)->auth_pkt = 1;
+
+ capinfo = 0;
+ if (vap->iv_opmode == IEEE80211_M_IBSS)