madwifi: fix a race condition in the wds sta separation, which is triggered by using wpa authentication on the ap

SVN-Revision: 14193
This commit is contained in:
Felix Fietkau 2009-01-26 00:27:49 +00:00
parent 727ab9ce8d
commit f561b910e8
5 changed files with 17 additions and 17 deletions

View File

@ -680,14 +680,10 @@
} }
break; break;
case IEEE80211_M_IBSS: case IEEE80211_M_IBSS:
@@ -540,16 +548,32 @@ ieee80211_input(struct ieee80211vap * va @@ -540,16 +548,28 @@ ieee80211_input(struct ieee80211vap * va
vap->iv_stats.is_rx_notassoc++; vap->iv_stats.is_rx_notassoc++;
goto err; goto err;
} }
+
+ /* subif isn't fully set up yet, drop the frame */
+ if (ni->ni_subif == ni->ni_vap)
+ goto err;
+ +
/* /*
* If we're a 4 address packet, make sure we have an entry in * If we're a 4 address packet, make sure we have an entry in
@ -716,7 +712,7 @@
if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) { if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
@@ -557,7 +581,6 @@ ieee80211_input(struct ieee80211vap * va @@ -557,7 +577,6 @@ ieee80211_input(struct ieee80211vap * va
goto err; goto err;
} }
wh4 = (struct ieee80211_frame_addr4 *)skb->data; wh4 = (struct ieee80211_frame_addr4 *)skb->data;
@ -724,7 +720,7 @@
ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4); ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4);
/* Last call increments ref count if !NULL */ /* Last call increments ref count if !NULL */
if ((ni_wds != NULL) && (ni_wds != ni)) { if ((ni_wds != NULL) && (ni_wds != ni)) {
@@ -608,6 +631,11 @@ ieee80211_input(struct ieee80211vap * va @@ -608,6 +627,11 @@ ieee80211_input(struct ieee80211vap * va
goto out; goto out;
} }
@ -736,7 +732,7 @@
/* /*
* Handle privacy requirements. Note that we * Handle privacy requirements. Note that we
* must not be preempted from here until after * must not be preempted from here until after
@@ -680,8 +708,12 @@ ieee80211_input(struct ieee80211vap * va @@ -680,8 +704,12 @@ ieee80211_input(struct ieee80211vap * va
if (! accept_data_frame(vap, ni, key, skb, eh)) if (! accept_data_frame(vap, ni, key, skb, eh))
goto out; goto out;
@ -751,16 +747,20 @@
IEEE80211_NODE_STAT(ni, rx_data); IEEE80211_NODE_STAT(ni, rx_data);
IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len); IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len);
ic->ic_lastdata = jiffies; ic->ic_lastdata = jiffies;
@@ -1114,6 +1146,13 @@ ieee80211_deliver_data(struct ieee80211_ @@ -1114,6 +1142,17 @@ ieee80211_deliver_data(struct ieee80211_
dev = vap->iv_xrvap->iv_dev; dev = vap->iv_xrvap->iv_dev;
#endif #endif
+ /* if the node has a wds subif, move data frames there, + /* if the node has a wds subif, move data frames there,
+ * but keep EAP traffic on the master */ + * but keep EAP traffic on the master */
+ if (ni->ni_subif && ((eh)->ether_type != __constant_htons(ETHERTYPE_PAE))) { + if (ni->ni_subif && ((eh)->ether_type != __constant_htons(ETHERTYPE_PAE))) {
+ if (ni->ni_vap == ni->ni_subif) {
+ ieee80211_dev_kfree_skb(&skb);
+ } else {
+ vap = ni->ni_subif; + vap = ni->ni_subif;
+ dev = vap->iv_dev; + dev = vap->iv_dev;
+ } + }
+ }
+ +
/* perform as a bridge within the vap */ /* perform as a bridge within the vap */
/* XXX intra-vap bridging only */ /* XXX intra-vap bridging only */

View File

@ -1,6 +1,6 @@
--- a/net80211/ieee80211_input.c --- a/net80211/ieee80211_input.c
+++ b/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c
@@ -572,36 +572,6 @@ ieee80211_input(struct ieee80211vap * va @@ -568,36 +568,6 @@ ieee80211_input(struct ieee80211vap * va
} }
} }

View File

@ -249,7 +249,7 @@
KASSERT(skb->len >= sizeof(struct ieee80211_frame_min), KASSERT(skb->len >= sizeof(struct ieee80211_frame_min),
("frame length too short: %u", skb->len)); ("frame length too short: %u", skb->len));
@@ -848,10 +847,11 @@ ieee80211_input(struct ieee80211vap * va @@ -844,10 +843,11 @@ ieee80211_input(struct ieee80211vap * va
err: err:
vap->iv_devstats.rx_errors++; vap->iv_devstats.rx_errors++;
out: out:
@ -263,7 +263,7 @@
return type; return type;
#undef HAS_SEQ #undef HAS_SEQ
} }
@@ -933,16 +933,23 @@ int @@ -929,16 +929,23 @@ int
ieee80211_input_all(struct ieee80211com *ic, ieee80211_input_all(struct ieee80211com *ic,
struct sk_buff *skb, int rssi, u_int64_t rtsf) struct sk_buff *skb, int rssi, u_int64_t rtsf)
{ {
@ -287,7 +287,7 @@
if (TAILQ_NEXT(vap, iv_next) != NULL) { if (TAILQ_NEXT(vap, iv_next) != NULL) {
skb1 = skb_copy(skb, GFP_ATOMIC); skb1 = skb_copy(skb, GFP_ATOMIC);
if (skb1 == NULL) { if (skb1 == NULL) {
@@ -954,8 +961,10 @@ ieee80211_input_all(struct ieee80211com @@ -950,8 +957,10 @@ ieee80211_input_all(struct ieee80211com
skb1 = skb; skb1 = skb;
skb = NULL; skb = NULL;
} }

View File

@ -1,6 +1,6 @@
--- a/net80211/ieee80211_input.c --- a/net80211/ieee80211_input.c
+++ b/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c
@@ -3618,6 +3618,8 @@ ieee80211_recv_mgmt(struct ieee80211vap @@ -3611,6 +3611,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
vap->iv_stats.is_rx_mgtdiscard++; vap->iv_stats.is_rx_mgtdiscard++;
return; return;
} }

View File

@ -11,7 +11,7 @@
#define IEEE80211_QOS_TXOP 0x00ff #define IEEE80211_QOS_TXOP 0x00ff
--- a/net80211/ieee80211_input.c --- a/net80211/ieee80211_input.c
+++ b/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c
@@ -436,7 +436,7 @@ ieee80211_input(struct ieee80211vap * va @@ -428,7 +428,7 @@ ieee80211_input(struct ieee80211vap * va
tid = 0; tid = 0;
rxseq = le16toh(*(__le16 *)wh->i_seq); rxseq = le16toh(*(__le16 *)wh->i_seq);
if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&