diff options
Diffstat (limited to 'package/madwifi/patches/393-mbss_vap_auth.patch')
-rw-r--r-- | package/madwifi/patches/393-mbss_vap_auth.patch | 491 |
1 files changed, 0 insertions, 491 deletions
diff --git a/package/madwifi/patches/393-mbss_vap_auth.patch b/package/madwifi/patches/393-mbss_vap_auth.patch deleted file mode 100644 index a2637cccbb..0000000000 --- a/package/madwifi/patches/393-mbss_vap_auth.patch +++ /dev/null @@ -1,491 +0,0 @@ ---- a/net80211/ieee80211_node.c -+++ b/net80211/ieee80211_node.c -@@ -123,6 +123,9 @@ static void ieee80211_node_table_cleanup - static void ieee80211_node_table_reset(struct ieee80211_node_table *, - struct ieee80211vap *); - -+static struct ieee80211_node * -+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, const u_int8_t *addr); -+ - MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state"); - - void -@@ -697,7 +700,7 @@ ieee80211_sta_join(struct ieee80211vap * - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node *ni; - -- ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr); -+ ni = lookup_rxnode(ic, vap, se->se_macaddr); - if (ni == NULL) { - ni = ieee80211_alloc_node_table(vap, se->se_macaddr); - IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC, -@@ -1394,6 +1397,53 @@ ieee80211_add_neighbor(struct ieee80211v - return ni; - } - -+struct ieee80211vap * -+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac) -+{ -+ struct ieee80211vap *vap; -+ -+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { -+ if (IEEE80211_ADDR_EQ(vap->iv_myaddr, mac)) -+ return vap; -+ } -+ return NULL; -+} -+EXPORT_SYMBOL(ieee80211_find_rxvap); -+ -+static struct ieee80211_node * -+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, -+ const u_int8_t *addr) -+{ -+ struct ieee80211_node_table *nt; -+ struct ieee80211_node *ni = NULL; -+ int use_bss = 0; -+ int hash; -+ -+ nt = &ic->ic_sta; -+ IEEE80211_NODE_TABLE_LOCK_IRQ(nt); -+ hash = IEEE80211_NODE_HASH(addr); -+ LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { -+ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, addr)) { -+ /* allow multiple nodes on different vaps */ -+ if (vap && (ni->ni_vap != vap)) -+ continue; -+ -+ ieee80211_ref_node(ni); -+ goto out; -+ } -+ } -+ -+ /* no match found */ -+ ni = NULL; -+ -+out: -+ IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); -+ return ni; -+#undef IS_PSPOLL -+#undef IS_CTL -+} -+ -+ - /* - * Return the node for the sender of a frame; if the sender is unknown return - * NULL. The caller is expected to deal with this. (The frame is sent to all -@@ -1403,10 +1453,10 @@ ieee80211_add_neighbor(struct ieee80211v - */ - struct ieee80211_node * - #ifdef IEEE80211_DEBUG_REFCNT --ieee80211_find_rxnode_debug(struct ieee80211com *ic, -+ieee80211_find_rxnode_debug(struct ieee80211com *ic, struct ieee80211vap *vap, - const struct ieee80211_frame_min *wh, const char *func, int line) - #else --ieee80211_find_rxnode(struct ieee80211com *ic, -+ieee80211_find_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, - const struct ieee80211_frame_min *wh) - #endif - { -@@ -1414,9 +1464,8 @@ ieee80211_find_rxnode(struct ieee80211co - ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) - #define IS_PSPOLL(wh) \ - ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) -- struct ieee80211_node_table *nt; -- struct ieee80211_node *ni; -- struct ieee80211vap *vap, *avp; -+ struct ieee80211_node *ni = NULL; -+ struct ieee80211vap *avp; - const u_int8_t *addr; - - if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/) -@@ -1429,32 +1478,25 @@ ieee80211_find_rxnode(struct ieee80211co - - /* XXX check ic_bss first in station mode */ - /* XXX 4-address frames? */ -- nt = &ic->ic_sta; -- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); - if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) { -- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { -+ if (vap) { /* assume unicast if vap is set, mcast not supported for wds */ - TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) { -- if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac)) -+ if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac) || -+ !IEEE80211_ADDR_EQ(wh->i_addr1, avp->iv_myaddr)) - continue; - - if (avp->iv_wdsnode) -- return ieee80211_ref_node(avp->iv_wdsnode); -- else -- return NULL; -+ ni = ieee80211_ref_node(avp->iv_wdsnode); -+ return ni; - } -+ if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) -+ return NULL; -+ } else { -+ return NULL; - } - } - --#ifdef IEEE80211_DEBUG_REFCNT -- ni = ieee80211_find_node_locked_debug(nt, addr, func, line); --#else -- ni = ieee80211_find_node_locked(nt, addr); --#endif -- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); -- -- return ni; --#undef IS_PSPOLL --#undef IS_CTL -+ return lookup_rxnode(ic, vap, addr); - } - #ifdef IEEE80211_DEBUG_REFCNT - EXPORT_SYMBOL(ieee80211_find_rxnode_debug); -@@ -1479,15 +1521,14 @@ ieee80211_find_txnode(struct ieee80211va - struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_node_table *nt; - struct ieee80211_node *ni = NULL; -+ int hash; - -- IEEE80211_LOCK_IRQ(ic); - if (vap->iv_opmode == IEEE80211_M_WDS) { - if (vap->iv_wdsnode && (vap->iv_state == IEEE80211_S_RUN)) - return ieee80211_ref_node(vap->iv_wdsnode); - else - return NULL; - } -- IEEE80211_UNLOCK_IRQ(ic); - - /* - * The destination address should be in the node table -@@ -1505,11 +1546,22 @@ ieee80211_find_txnode(struct ieee80211va - /* XXX: Can't hold lock across dup_bss due to recursive locking. */ - nt = &vap->iv_ic->ic_sta; - IEEE80211_NODE_TABLE_LOCK_IRQ(nt); -+ hash = IEEE80211_NODE_HASH(mac); -+ LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) { -+ if (ni->ni_vap != vap) -+ continue; -+ -+ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, mac)) { - #ifdef IEEE80211_DEBUG_REFCNT -- ni = ieee80211_find_node_locked_debug(nt, mac, func, line); -+ ieee80211_ref_node_debug(ni, func, line); - #else -- ni = ieee80211_find_node_locked(nt, mac); -+ ieee80211_ref_node(ni); - #endif -+ goto found; -+ } -+ } -+ ni = NULL; -+found: - IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); - - if (ni == NULL) { -@@ -1964,13 +2016,32 @@ remove_worse_nodes(void *arg, struct iee - } - } - -+static void -+remove_duplicate_nodes(void *arg, struct ieee80211_node *ni) -+{ -+ struct ieee80211_node *rni = arg; -+ -+ if (ni == rni) -+ return; -+ -+ if (ni->ni_vap == rni->ni_vap) -+ return; -+ -+ if (!IEEE80211_ADDR_EQ(rni->ni_macaddr, ni->ni_macaddr)) -+ return; -+ -+ ieee80211_node_leave(ni); -+} -+ - void - ieee80211_node_join(struct ieee80211_node *ni, int resp) - { - struct ieee80211com *ic = ni->ni_ic; - struct ieee80211vap *vap = ni->ni_vap; -+ struct ieee80211_node *tni; - int newassoc; - -+ ieee80211_iterate_nodes(&ic->ic_sta, remove_duplicate_nodes, ni); - if (ni->ni_associd == 0) { - u_int16_t aid; - ---- a/net80211/ieee80211_input.c -+++ b/net80211/ieee80211_input.c -@@ -216,16 +216,14 @@ ieee80211_input(struct ieee80211vap * va - - type = -1; /* undefined */ - -- if (!vap) -- goto out; -+ if (!vap || !vap->iv_bss || !vap->iv_dev || !vap->iv_ic) -+ goto discard; - - ic = vap->iv_ic; -- if (!ic) -- goto out; -- - dev = vap->iv_dev; -- if (!dev) -- goto out; -+ -+ if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) -+ goto discard; - - /* initialize ni as in the previous API */ - if (ni_or_null == NULL) { -@@ -233,9 +231,10 @@ ieee80211_input(struct ieee80211vap * va - * guarantee its existence during the following call, hence - * briefly grab our own reference. */ - ni = ieee80211_ref_node(vap->iv_bss); -+ KASSERT(ni != NULL, ("null node")); -+ } else { -+ ni->ni_inact = ni->ni_inact_reload; - } -- KASSERT(ni != NULL, ("null node")); -- ni->ni_inact = ni->ni_inact_reload; - - KASSERT(skb->len >= sizeof(struct ieee80211_frame_min), - ("frame length too short: %u", skb->len)); -@@ -844,10 +843,11 @@ ieee80211_input(struct ieee80211vap * va - err: - vap->iv_devstats.rx_errors++; - out: -- if (skb != NULL) -- ieee80211_dev_kfree_skb(&skb); - if (ni_or_null == NULL) - ieee80211_unref_node(&ni); -+discard: -+ if (skb != NULL) -+ ieee80211_dev_kfree_skb(&skb); - return type; - #undef HAS_SEQ - } -@@ -929,16 +929,23 @@ int - ieee80211_input_all(struct ieee80211com *ic, - struct sk_buff *skb, int rssi, u_int64_t rtsf) - { -+ struct ieee80211_frame_min *wh = (struct ieee80211_frame_min *) skb->data; - struct ieee80211vap *vap; - int type = -1; - - /* XXX locking */ - TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { -+ struct ieee80211_node *ni = NULL; - struct sk_buff *skb1; - - if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) - continue; - -+ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) && -+ !IEEE80211_IS_MULTICAST(wh->i_addr1)) -+ continue; -+ -+ ni = ieee80211_find_rxnode(ic, vap, wh); - if (TAILQ_NEXT(vap, iv_next) != NULL) { - skb1 = skb_copy(skb, GFP_ATOMIC); - if (skb1 == NULL) { -@@ -950,8 +957,12 @@ ieee80211_input_all(struct ieee80211com - skb1 = skb; - skb = NULL; - } -- type = ieee80211_input(vap, NULL, skb1, rssi, rtsf); -+ type = ieee80211_input(vap, ni, skb1, rssi, rtsf); -+ if (ni) -+ ieee80211_unref_node(&ni); - } -+ -+out: - if (skb != NULL) /* no vaps, reclaim skb */ - ieee80211_dev_kfree_skb(&skb); - return type; -@@ -1147,11 +1158,9 @@ ieee80211_deliver_data(struct ieee80211_ - * sending it will not work; just let it be - * delivered normally. - */ -- struct ieee80211_node *ni1 = ieee80211_find_node( -- &vap->iv_ic->ic_sta, eh->ether_dhost); -+ struct ieee80211_node *ni1 = ieee80211_find_txnode(vap, eh->ether_dhost); - if (ni1 != NULL) { -- if (ni1->ni_vap == vap && -- ieee80211_node_is_authorized(ni1) && -+ if (ieee80211_node_is_authorized(ni1) && - !ni1->ni_subif && - ni1 != vap->iv_bss) { - -@@ -3520,6 +3529,7 @@ ieee80211_recv_mgmt(struct ieee80211vap - (vap->iv_opmode == IEEE80211_M_WDS)) && - (scan.capinfo & IEEE80211_CAPINFO_ESS))) { - struct ieee80211vap *avp = NULL; -+ int do_unref = 0; - int found = 0; - - IEEE80211_LOCK_IRQ(vap->iv_ic); -@@ -3553,10 +3563,12 @@ ieee80211_recv_mgmt(struct ieee80211vap - ni->ni_associd |= 0xc000; - avp->iv_wdsnode = ieee80211_ref_node(ni); - IEEE80211_UNLOCK_IRQ(ic); -- } else if (vap->iv_opmode == IEEE80211_M_IBSS) { -+ } else if ((vap->iv_opmode == IEEE80211_M_IBSS) && -+ IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) { - /* Create a new entry in the neighbor table. */ - ni = ieee80211_add_neighbor(vap, wh, &scan); - } -+ do_unref = 1; - } else { - /* - * Copy data from beacon to neighbor table. -@@ -3595,6 +3607,8 @@ ieee80211_recv_mgmt(struct ieee80211vap - ni->ni_rssi = rssi; - ni->ni_rtsf = rtsf; - ni->ni_last_rx = jiffies; -+ if (do_unref) -+ ieee80211_unref_node(&ni); - } - } - break; ---- a/ath/if_ath.c -+++ b/ath/if_ath.c -@@ -6589,9 +6589,8 @@ ath_recv_mgmt(struct ieee80211vap * vap, - - sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf); - -- - /* Lookup the new node if any (this grabs a reference to it) */ -- ni = ieee80211_find_rxnode(vap->iv_ic, -+ ni = ieee80211_find_rxnode(vap->iv_ic, vap, - (const struct ieee80211_frame_min *)skb->data); - if (ni == NULL) { - DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n"); -@@ -6746,7 +6745,9 @@ ath_rx_poll(struct net_device *dev, int - struct ath_desc *ds; - struct ath_rx_status *rs; - struct sk_buff *skb = NULL; -+ struct ieee80211vap *vap; - struct ieee80211_node *ni; -+ const struct ieee80211_frame_min *wh; - unsigned int len; - int type; - u_int phyerr; -@@ -6901,12 +6902,15 @@ rx_accept: - skb_trim(skb, skb->len - IEEE80211_CRC_LEN); - - if (mic_fail) { -+ wh = (const struct ieee80211_frame_min *) skb->data; -+ - /* Ignore control frames which are reported with mic error */ -- if ((((struct ieee80211_frame *)skb->data)->i_fc[0] & -+ if ((wh->i_fc[0] & - IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) - goto drop_micfail; - -- ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data); -+ vap = ieee80211_find_rxvap(ic, wh->i_addr1); -+ ni = ieee80211_find_rxnode(ic, vap, wh); - - if (ni && ni->ni_table) { - ieee80211_check_mic(ni, skb); -@@ -6968,11 +6972,24 @@ drop_micfail: - * for its use. If the sender is unknown spam the - * frame; it'll be dropped where it's not wanted. - */ -- if (rs->rs_keyix != HAL_RXKEYIX_INVALID && -+ wh = (const struct ieee80211_frame_min *) skb->data; -+ if ((rs->rs_keyix != HAL_RXKEYIX_INVALID) && - (ni = sc->sc_keyixmap[rs->rs_keyix]) != NULL) { - /* Fast path: node is present in the key map; - * grab a reference for processing the frame. */ -- ni = ieee80211_ref_node(ni); -+ ieee80211_ref_node(ni); -+ if ((ATH_GET_VAP_ID(wh->i_addr1) != -+ ATH_GET_VAP_ID(ni->ni_vap->iv_myaddr)) || -+ ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == -+ IEEE80211_FC1_DIR_DSTODS)) { -+ /* key cache node lookup is fast, but it can -+ * lead to problems in multi-bss (foreign vap -+ * node reference) or wds (wdsap node ref instead -+ * of base ap node ref). -+ * use slowpath lookup in both cases -+ */ -+ goto lookup_slowpath; -+ } - ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi); - type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf); - ieee80211_unref_node(&ni); -@@ -6981,24 +6998,39 @@ drop_micfail: - * No key index or no entry, do a lookup and - * add the node to the mapping table if possible. - */ -- ni = ieee80211_find_rxnode(ic, -- (const struct ieee80211_frame_min *)skb->data); -+ -+lookup_slowpath: -+ if (IEEE80211_IS_MULTICAST(wh->i_addr1)) -+ vap = NULL; -+ else -+ vap = ieee80211_find_rxvap(ic, wh->i_addr1); -+ -+ if (vap) -+ ni = ieee80211_find_rxnode(ic, vap, wh); -+ else -+ ni = NULL; -+ - if (ni != NULL) { - ieee80211_keyix_t keyix; - - ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi); -- type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf); -+ type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf); - /* - * If the station has a key cache slot assigned - * update the key->node mapping table. - */ - keyix = ni->ni_ucastkey.wk_keyix; - if (keyix != IEEE80211_KEYIX_NONE && -- sc->sc_keyixmap[keyix] == NULL) -+ sc->sc_keyixmap[keyix] == NULL) { - sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni); -+ } - ieee80211_unref_node(&ni); -- } else -- type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf); -+ } else { -+ if (vap) -+ type = ieee80211_input(vap, NULL, skb, rs->rs_rssi, bf->bf_tsf); -+ else -+ type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf); -+ } - } - - if (sc->sc_diversity) { ---- a/net80211/ieee80211_node.h -+++ b/net80211/ieee80211_node.h -@@ -286,15 +286,18 @@ struct ieee80211_node *ieee80211_find_no - const u_int8_t *); - #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ - -+struct ieee80211vap * -+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac); -+ - /* Returns a ieee80211_node* with refcount incremented, if found */ - #ifdef IEEE80211_DEBUG_REFCNT --#define ieee80211_find_rxnode(_nt, _wh) \ -- ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__) -+#define ieee80211_find_rxnode(_nt, _vap, _wh) \ -+ ieee80211_find_rxnode_debug(_nt, _vap, _wh, __func__, __LINE__) - struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *, -- const struct ieee80211_frame_min *, const char *, int); -+ struct ieee80211vap *, const struct ieee80211_frame_min *, const char *, int); - #else - struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *, -- const struct ieee80211_frame_min *); -+ struct ieee80211vap *, const struct ieee80211_frame_min *); - #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ - - /* Returns a ieee80211_node* with refcount incremented, if found */ |