1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
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
@@ -8332,6 +8332,14 @@
#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 ieee80211vap *vap = ni->ni_vap;
+
+ /* if roaming is enabled, try reassociating, otherwise
+ * disassociate and go back to the scan state */
+ vap->iv_mgtsend.function(vap->iv_mgtsend.data);
+ }
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
@@ -156,6 +156,7 @@
if (off != 0)
skb_reserve(skb, align - off);
+ SKB_CB(skb)->auth_pkt = 0;
SKB_CB(skb)->ni = NULL;
SKB_CB(skb)->flags = 0;
SKB_CB(skb)->next = NULL;
--- a/net80211/ieee80211_linux.h
+++ b/net80211/ieee80211_linux.h
@@ -393,6 +393,7 @@
void (*next_destructor)(struct sk_buff *skb);
#endif
struct sk_buff *next; /* fast frame sk_buf chain */
+ u_int8_t auth_pkt;
};
--- a/net80211/ieee80211_output.c
+++ b/net80211/ieee80211_output.c
@@ -778,6 +778,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:
@@ -1622,6 +1624,7 @@
ie->param_len = frm - &ie->param_oui[0];
return frm;
}
+
#endif
/*
* Send a probe request frame with the specified ssid
@@ -1886,6 +1889,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)
@@ -1960,6 +1964,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)
|