Thread: [Madwifi-cvs] revision 1819 committed
Status: Beta
Brought to you by:
otaku
From: Kel M. <svn...@ma...> - 2006-11-22 09:17:42
|
Project : madwifi Revision : 1819 Author : kelmo (Kel Modderman) Date : 2006-11-22 10:17:27 +0100 (Wed, 22 Nov 2006) Log Message : In a multi-vap scenario (for example, a STA or WDS-REPEATER vap on the same device as an AP vap) an IEEE80211_MLME_DISASSOC/DEAUTH (for example, from hostapd upon startup) will call ieee80211_node_leave for all nodes in the node table, regardless of what vap they are associated with. Instead, ieee80211_node_leave should only be called for nodes that are on the specified vap (Note that this same mis-behavior of iterating over all nodes regardless of vap may be alsmo present elsewhere in madwifi) This can cause a number of issues, including driver crash when nodes get dropped that shouldn't be. See #969 for details about how to reliably reproduce this problem. Signed-off-by: Tim Harvey <tim...@ya...> Affected Files: * trunk/net80211/ieee80211_node.c updated * trunk/net80211/ieee80211_node.h updated * trunk/net80211/ieee80211_wireless.c updated Modified: trunk/net80211/ieee80211_node.c =================================================================== --- trunk/net80211/ieee80211_node.c 2006-11-22 09:03:30 UTC (rev 1818) +++ trunk/net80211/ieee80211_node.c 2006-11-22 09:17:27 UTC (rev 1819) @@ -1662,6 +1662,13 @@ void ieee80211_iterate_nodes(struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg) { + ieee80211_iterate_dev_nodes(NULL, nt, f, arg); +} +EXPORT_SYMBOL(ieee80211_iterate_nodes); + +void +ieee80211_iterate_dev_nodes(struct net_device *dev, struct ieee80211_node_table *nt, ieee80211_iter_func *f, void *arg) +{ struct ieee80211_node *ni; u_int gen; @@ -1670,7 +1677,9 @@ restart: IEEE80211_NODE_LOCK(nt); TAILQ_FOREACH(ni, &nt->nt_node, ni_list) { - if (ni->ni_scangen != gen) { + if (dev != NULL && ni->ni_vap->iv_dev != dev) + continue; /* skip node not for this vap */ + if (ni->ni_scangen) { ni->ni_scangen = gen; (void) ieee80211_ref_node(ni); IEEE80211_NODE_UNLOCK(nt); @@ -1683,7 +1692,7 @@ IEEE80211_SCAN_UNLOCK_IRQ(nt); } -EXPORT_SYMBOL(ieee80211_iterate_nodes); +EXPORT_SYMBOL(ieee80211_iterate_dev_nodes); void ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) Modified: trunk/net80211/ieee80211_node.h =================================================================== --- trunk/net80211/ieee80211_node.h 2006-11-22 09:03:30 UTC (rev 1818) +++ trunk/net80211/ieee80211_node.h 2006-11-22 09:17:27 UTC (rev 1819) @@ -298,6 +298,8 @@ typedef void ieee80211_iter_func(void *, struct ieee80211_node *); void ieee80211_iterate_nodes(struct ieee80211_node_table *, ieee80211_iter_func *, void *); +void ieee80211_iterate_dev_nodes(struct net_device *, + struct ieee80211_node_table *, ieee80211_iter_func *, void *); void ieee80211_dump_node(struct ieee80211_node_table *, struct ieee80211_node *); Modified: trunk/net80211/ieee80211_wireless.c =================================================================== --- trunk/net80211/ieee80211_wireless.c 2006-11-22 09:03:30 UTC (rev 1818) +++ trunk/net80211/ieee80211_wireless.c 2006-11-22 09:17:27 UTC (rev 1819) @@ -3321,12 +3321,15 @@ if (!IEEE80211_ADDR_EQ(mlme->im_macaddr, vap->iv_dev->broadcast)) { ni = ieee80211_find_node(&ic->ic_sta, mlme->im_macaddr); - if (ni == NULL) + if (ni == NULL) { + ieee80211_free_node(ni); return -EINVAL; - domlme(mlme, ni); + } + if (dev == ni->ni_vap->iv_dev) + domlme(mlme, ni); ieee80211_free_node(ni); } else - ieee80211_iterate_nodes(&ic->ic_sta, domlme, mlme); + ieee80211_iterate_dev_nodes(dev, &ic->ic_sta, domlme, mlme); break; default: return -EINVAL; |