| 1 | This patch causes STA mode interfaces to disassociate if transmission of assoc/auth |
| 2 | critical packets failed. |
| 3 | |
| 4 | Signed-off-by: Felix Fietkau <nbd@openwrt.org> |
| 5 | |
| 6 | --- a/ath/if_ath.c |
| 7 | +++ b/ath/if_ath.c |
| 8 | @@ -8334,6 +8334,14 @@ ath_tx_processq(struct ath_softc *sc, st |
| 9 | #endif |
| 10 | if (ts->ts_status & HAL_TXERR_XRETRY) { |
| 11 | sc->sc_stats.ast_tx_xretries++; |
| 12 | + if (SKB_CB(bf->bf_skb)->auth_pkt && |
| 13 | + (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) { |
| 14 | + struct ieee80211vap *vap = ni->ni_vap; |
| 15 | + |
| 16 | + /* if roaming is enabled, try reassociating, otherwise |
| 17 | + * disassociate and go back to the scan state */ |
| 18 | + vap->iv_mgtsend.function(vap->iv_mgtsend.data); |
| 19 | + } |
| 20 | if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) { |
| 21 | ni->ni_stats.ns_tx_eosplost++; |
| 22 | DPRINTF(sc, ATH_DEBUG_UAPSD, |
| 23 | --- a/net80211/ieee80211_linux.c |
| 24 | +++ b/net80211/ieee80211_linux.c |
| 25 | @@ -156,6 +156,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_ |
| 26 | if (off != 0) |
| 27 | skb_reserve(skb, align - off); |
| 28 | |
| 29 | + SKB_CB(skb)->auth_pkt = 0; |
| 30 | SKB_CB(skb)->ni = NULL; |
| 31 | SKB_CB(skb)->flags = 0; |
| 32 | SKB_CB(skb)->next = NULL; |
| 33 | --- a/net80211/ieee80211_linux.h |
| 34 | +++ b/net80211/ieee80211_linux.h |
| 35 | @@ -393,6 +393,7 @@ typedef spinlock_t acl_lock_t; |
| 36 | void (*next_destructor)(struct sk_buff *skb); |
| 37 | #endif |
| 38 | struct sk_buff *next; /* fast frame sk_buf chain */ |
| 39 | + u_int8_t auth_pkt; |
| 40 | }; |
| 41 | |
| 42 | |
| 43 | --- a/net80211/ieee80211_output.c |
| 44 | +++ b/net80211/ieee80211_output.c |
| 45 | @@ -778,6 +778,8 @@ ieee80211_encap(struct ieee80211_node *n |
| 46 | else |
| 47 | hdrsize = sizeof(struct ieee80211_frame); |
| 48 | |
| 49 | + SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE)); |
| 50 | + |
| 51 | switch (vap->iv_opmode) { |
| 52 | case IEEE80211_M_IBSS: |
| 53 | case IEEE80211_M_AHDEMO: |
| 54 | @@ -1622,6 +1624,7 @@ ieee80211_add_xr_param(u_int8_t *frm, st |
| 55 | ie->param_len = frm - &ie->param_oui[0]; |
| 56 | return frm; |
| 57 | } |
| 58 | + |
| 59 | #endif |
| 60 | /* |
| 61 | * Send a probe request frame with the specified ssid |
| 62 | @@ -1886,6 +1889,7 @@ ieee80211_send_mgmt(struct ieee80211_nod |
| 63 | sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)); |
| 64 | if (skb == NULL) |
| 65 | senderr(ENOMEM, is_tx_nobuf); |
| 66 | + SKB_CB(skb)->auth_pkt = 1; |
| 67 | |
| 68 | ((__le16 *)frm)[0] = |
| 69 | (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED) |
| 70 | @@ -1960,6 +1964,7 @@ ieee80211_send_mgmt(struct ieee80211_nod |
| 71 | vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length); |
| 72 | if (skb == NULL) |
| 73 | senderr(ENOMEM, is_tx_nobuf); |
| 74 | + SKB_CB(skb)->auth_pkt = 1; |
| 75 | |
| 76 | capinfo = 0; |
| 77 | if (vap->iv_opmode == IEEE80211_M_IBSS) |
| 78 | |