madwifi: make STA mode interfaces disassociate if transmission of assoc/auth critical...
authorFelix Fietkau <nbd@openwrt.org>
Sat, 12 Jul 2008 22:23:36 +0000 (22:23 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 12 Jul 2008 22:23:36 +0000 (22:23 +0000)
SVN-Revision: 11792

package/madwifi/patches/355-eap_auth_disassoc.patch [new file with mode: 0644]

diff --git a/package/madwifi/patches/355-eap_auth_disassoc.patch b/package/madwifi/patches/355-eap_auth_disassoc.patch
new file mode 100644 (file)
index 0000000..e85d93a
--- /dev/null
@@ -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
+@@ -8315,6 +8315,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
+@@ -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)