diff options
author | Felix Fietkau <nbd@openwrt.org> | 2009-01-25 00:37:41 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2009-01-25 00:37:41 +0000 |
commit | 87db54da68aa2614122a0f2f2d4c79722dad2bb9 (patch) | |
tree | 022b7bd5bc73da3bce22c057ba58b97b4596e5c1 /package/madwifi/patches/392-remove_wds_nodetracking.patch | |
parent | 28abf79c44dc8a464d9573a9dc0c657ad5a35b60 (diff) | |
download | upstream-87db54da68aa2614122a0f2f2d4c79722dad2bb9.tar.gz upstream-87db54da68aa2614122a0f2f2d4c79722dad2bb9.tar.bz2 upstream-87db54da68aa2614122a0f2f2d4c79722dad2bb9.zip |
madwifi: fix the long standing bug that is triggered by nodes getting a timeout on one vap, then moving to another
SVN-Revision: 14171
Diffstat (limited to 'package/madwifi/patches/392-remove_wds_nodetracking.patch')
-rw-r--r-- | package/madwifi/patches/392-remove_wds_nodetracking.patch | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/package/madwifi/patches/392-remove_wds_nodetracking.patch b/package/madwifi/patches/392-remove_wds_nodetracking.patch new file mode 100644 index 0000000000..d035fd6158 --- /dev/null +++ b/package/madwifi/patches/392-remove_wds_nodetracking.patch @@ -0,0 +1,388 @@ +--- a/net80211/ieee80211_input.c ++++ b/net80211/ieee80211_input.c +@@ -572,36 +572,6 @@ ieee80211_input(struct ieee80211vap * va + } + } + +- /* XXX: Useless node mgmt API; make better */ +- if ((dir == IEEE80211_FC1_DIR_DSTODS) && !vap->iv_wdsnode && +- !ni_wds && !ni->ni_subif) { +- struct ieee80211_node_table *nt = &ic->ic_sta; +- struct ieee80211_frame_addr4 *wh4; +- +- if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) { +- IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, +- wh, "data", "%s", "4 addr not allowed"); +- goto err; +- } +- wh4 = (struct ieee80211_frame_addr4 *)skb->data; +- ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4); +- /* Last call increments ref count if !NULL */ +- if ((ni_wds != NULL) && (ni_wds != ni)) { +- /* +- * node with source address (addr4) moved +- * to another WDS capable station. remove the +- * reference to the previous station and add +- * reference to the new one +- */ +- (void) ieee80211_remove_wds_addr(nt, wh4->i_addr4); +- ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0); +- } +- if (ni_wds == NULL) +- ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0); +- else +- ieee80211_unref_node(&ni_wds); +- } +- + /* + * Check for power save state change. + */ +--- a/net80211/ieee80211_node.c ++++ b/net80211/ieee80211_node.c +@@ -122,7 +122,6 @@ static void ieee80211_node_table_init(st + static void ieee80211_node_table_cleanup(struct ieee80211_node_table *); + static void ieee80211_node_table_reset(struct ieee80211_node_table *, + struct ieee80211vap *); +-static void ieee80211_node_wds_ageout(unsigned long); + + MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state"); + +@@ -785,10 +784,6 @@ ieee80211_node_table_init(struct ieee802 + nt->nt_name = name; + nt->nt_scangen = 1; + nt->nt_inact_init = inact; +- init_timer(&nt->nt_wds_aging_timer); +- nt->nt_wds_aging_timer.function = ieee80211_node_wds_ageout; +- nt->nt_wds_aging_timer.data = (unsigned long) nt; +- mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); + } + + static __inline +@@ -1201,142 +1196,6 @@ void ieee80211_wds_addif(struct ieee8021 + schedule_work(&ni->ni_create); + } + +-/* Add wds address to the node table */ +-int +-#ifdef IEEE80211_DEBUG_REFCNT +-ieee80211_add_wds_addr_debug(struct ieee80211_node_table *nt, +- struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static, +- const char* func, int line) +-#else +-ieee80211_add_wds_addr(struct ieee80211_node_table *nt, +- struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static) +-#endif +-{ +- int hash; +- struct ieee80211_wds_addr *wds; +- +- MALLOC(wds, struct ieee80211_wds_addr *, sizeof(struct ieee80211_wds_addr), +- M_80211_WDS, M_NOWAIT | M_ZERO); +- if (wds == NULL) { +- /* XXX msg */ +- return 1; +- } +- if (wds_static) +- wds->wds_agingcount = WDS_AGING_STATIC; +- else +- wds->wds_agingcount = WDS_AGING_COUNT; +- hash = IEEE80211_NODE_HASH(macaddr); +- IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr); +- +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +-#ifdef IEEE80211_DEBUG_REFCNT +- wds->wds_ni = ieee80211_ref_node_debug(ni, func, line); +-#else +- wds->wds_ni = ieee80211_ref_node(ni); +-#endif +- LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash); +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +- return 0; +-} +-#ifdef IEEE80211_DEBUG_REFCNT +-EXPORT_SYMBOL(ieee80211_add_wds_addr_debug); +-#else +-EXPORT_SYMBOL(ieee80211_add_wds_addr); +-#endif +- +-/* remove wds address from the wds hash table */ +-void +-#ifdef IEEE80211_DEBUG_REFCNT +-ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr, +- const char* func, int line) +-#else +-ieee80211_remove_wds_addr(struct ieee80211_node_table *nt, const u_int8_t *macaddr) +-#endif +-{ +- int hash; +- struct ieee80211_wds_addr *wds, *twds; +- +- hash = IEEE80211_NODE_HASH(macaddr); +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) { +- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { +- LIST_REMOVE(wds, wds_hash); +-#ifdef IEEE80211_DEBUG_REFCNT +- ieee80211_unref_node_debug(&wds->wds_ni, func, line); +-#else +- ieee80211_unref_node(&wds->wds_ni); +-#endif +- FREE(wds, M_80211_WDS); +- break; +- } +- } +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +-} +-#ifdef IEEE80211_DEBUG_REFCNT +-EXPORT_SYMBOL(ieee80211_remove_wds_addr_debug); +-#else +-EXPORT_SYMBOL(ieee80211_remove_wds_addr); +-#endif +- +-/* Remove node references from wds table */ +-void +-#ifdef IEEE80211_DEBUG_REFCNT +-ieee80211_del_wds_node_debug(struct ieee80211_node_table *nt, struct ieee80211_node *ni, +- const char* func, int line) +-#else +-ieee80211_del_wds_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) +-#endif +-{ +- int hash; +- struct ieee80211_wds_addr *wds, *twds; +- +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +- for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { +- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) { +- if (wds->wds_ni == ni) { +- LIST_REMOVE(wds, wds_hash); +-#ifdef IEEE80211_DEBUG_REFCNT +- ieee80211_unref_node_debug(&wds->wds_ni, func, line); +-#else +- ieee80211_unref_node(&wds->wds_ni); +-#endif +- FREE(wds, M_80211_WDS); +- } +- } +- } +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +-} +-#ifdef IEEE80211_DEBUG_REFCNT +-EXPORT_SYMBOL(ieee80211_del_wds_node_debug); +-#else +-EXPORT_SYMBOL(ieee80211_del_wds_node); +-#endif +- +-static void +-ieee80211_node_wds_ageout(unsigned long data) +-{ +- struct ieee80211_node_table *nt = (struct ieee80211_node_table *)data; +- int hash; +- struct ieee80211_wds_addr *wds, *twds; +- +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +- for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) { +- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) { +- if (wds->wds_agingcount != WDS_AGING_STATIC) { +- if (!wds->wds_agingcount) { +- LIST_REMOVE(wds, wds_hash); +- ieee80211_unref_node(&wds->wds_ni); +- FREE(wds, M_80211_WDS); +- } else +- wds->wds_agingcount--; +- } +- } +- } +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +- mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL); +-} +- +- + /* Add the specified station to the station table. + * Allocates a new ieee80211_node* that has a reference count of one + * If tmp is 0, it is added to the node table and the reference is used. +@@ -1382,34 +1241,6 @@ ieee80211_dup_bss(struct ieee80211vap *v + return ni; + } + +-static struct ieee80211_node * +-#ifdef IEEE80211_DEBUG_REFCNT +-ieee80211_find_wds_node_locked_debug(struct ieee80211_node_table *nt, +- const u_int8_t *macaddr, const char* func, int line) +-#else +-ieee80211_find_wds_node_locked(struct ieee80211_node_table *nt, +- const u_int8_t *macaddr) +-#endif +-{ +- struct ieee80211_wds_addr *wds; +- int hash; +- IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); +- +- hash = IEEE80211_NODE_HASH(macaddr); +- LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { +- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { +- if (wds->wds_agingcount != WDS_AGING_STATIC) +- wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */ +-#ifdef IEEE80211_DEBUG_REFCNT +- return ieee80211_ref_node_debug(wds->wds_ni, func, line); +-#else +- return ieee80211_ref_node(wds->wds_ni); +-#endif +- } +- } +- return NULL; +-} +- + /* NB: A node reference is acquired here; the caller MUST release it. */ + #ifdef IEEE80211_DEBUG_REFCNT + #define ieee80211_find_node_locked(nt, mac) \ +@@ -1427,7 +1258,6 @@ ieee80211_find_node_locked(struct ieee80 + { + struct ieee80211_node *ni; + int hash; +- struct ieee80211_wds_addr *wds; + + IEEE80211_NODE_TABLE_LOCK_ASSERT(nt); + +@@ -1442,48 +1272,11 @@ ieee80211_find_node_locked(struct ieee80 + return ni; + } + } +- +- /* Now, we look for the desired mac address in the 4 address +- nodes. */ +- LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) { +- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) { +-#ifdef IEEE80211_DEBUG_REFCNT +- return ieee80211_ref_node_debug(wds->wds_ni, func, line); +-#else +- return ieee80211_ref_node(wds->wds_ni); +-#endif +- } +- } + return NULL; + } + + struct ieee80211_node * + #ifdef IEEE80211_DEBUG_REFCNT +-ieee80211_find_wds_node_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr, +- const char* func, int line) +-#else +-ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr) +-#endif +-{ +- struct ieee80211_node *ni; +- +- IEEE80211_NODE_TABLE_LOCK_IRQ(nt); +-#ifdef IEEE80211_DEBUG_REFCNT +- ni = ieee80211_find_wds_node_locked_debug(nt, macaddr, func, line); +-#else +- ni = ieee80211_find_wds_node_locked(nt, macaddr); +-#endif +- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +- return ni; +-} +-#ifdef IEEE80211_DEBUG_REFCNT +-EXPORT_SYMBOL(ieee80211_find_wds_node_debug); +-#else +-EXPORT_SYMBOL(ieee80211_find_wds_node); +-#endif +- +-struct ieee80211_node * +-#ifdef IEEE80211_DEBUG_REFCNT + ieee80211_find_node_debug(struct ieee80211_node_table *nt, + const u_int8_t *macaddr, const char *func, int line) + #else +@@ -1835,7 +1628,6 @@ ieee80211_node_table_cleanup(struct ieee + ic->ic_node_cleanup(ni); + #endif + } +- del_timer(&nt->nt_wds_aging_timer); + IEEE80211_SCAN_LOCK_DESTROY(nt); + IEEE80211_NODE_TABLE_LOCK_DESTROY(nt); + } +@@ -2402,8 +2194,6 @@ ieee80211_node_leave(struct ieee80211_no + * so no more references are generated + */ + if (nt) { +- ieee80211_remove_wds_addr(nt, ni->ni_macaddr); +- ieee80211_del_wds_node(nt, ni); + IEEE80211_NODE_TABLE_LOCK_IRQ(nt); + node_table_leave_locked(nt, ni); + IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt); +--- a/net80211/ieee80211_node.h ++++ b/net80211/ieee80211_node.h +@@ -231,13 +231,6 @@ void ieee80211_sta_leave(struct ieee8021 + #define WDS_AGING_STATIC 0xffff + #define WDS_AGING_TIMER_VAL (WDS_AGING_TIME / 2) + +-struct ieee80211_wds_addr { +- LIST_ENTRY(ieee80211_wds_addr) wds_hash; +- u_int8_t wds_macaddr[IEEE80211_ADDR_LEN]; +- struct ieee80211_node *wds_ni; +- u_int16_t wds_agingcount; +-}; +- + /* + * Table of ieee80211_node instances. Each ieee80211com + * has at least one for holding the scan candidates. +@@ -250,11 +243,9 @@ struct ieee80211_node_table { + ieee80211_node_table_lock_t nt_nodelock; /* on node table */ + TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */ + ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE]; +- ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE]; + ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */ + u_int nt_scangen; /* gen# for timeout scan */ + int nt_inact_init; /* initial node inact setting */ +- struct timer_list nt_wds_aging_timer; /* timer to age out wds entries */ + }; + + /* Allocates a new ieee80211_node* that has a reference count of one, and +@@ -363,47 +354,6 @@ void + ieee80211_unref_node(struct ieee80211_node **pni); + #endif /* #ifdef IEEE80211_DEBUG_REFCNT */ + +-/* Increments reference count of ieee80211_node *ni */ +-#ifdef IEEE80211_DEBUG_REFCNT +-#define ieee80211_add_wds_addr(_table, _node, _mac, _static) \ +- ieee80211_add_wds_addr_debug(_table, _node, _mac, _static, __func__, __LINE__) +-int ieee80211_add_wds_addr_debug(struct ieee80211_node_table *, struct ieee80211_node *, +- const u_int8_t *, u_int8_t, const char* func, int line); +-#else +-int ieee80211_add_wds_addr(struct ieee80211_node_table *, struct ieee80211_node *, +- const u_int8_t *, u_int8_t); +-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */ +- +-/* Decrements reference count of ieee80211_node *ni */ +-#ifdef IEEE80211_DEBUG_REFCNT +-#define ieee80211_remove_wds_addr(_table, _mac) \ +- ieee80211_remove_wds_addr_debug(_table, _mac, __func__, __LINE__) +-void ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *, const u_int8_t *, +- const char* func, int line); +-#else +-void ieee80211_remove_wds_addr(struct ieee80211_node_table *, const u_int8_t *); +-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */ +- +-/* Decrements reference count of node, if found */ +-#ifdef IEEE80211_DEBUG_REFCNT +-#define ieee80211_del_wds_node(_table, _node) \ +- ieee80211_del_wds_node_debug(_table, _node, __func__, __LINE__) +-void ieee80211_del_wds_node_debug(struct ieee80211_node_table *, struct ieee80211_node *, +- const char* func, int line); +-#else +-void ieee80211_del_wds_node(struct ieee80211_node_table *, struct ieee80211_node *); +-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */ +- +-/* Increments reference count of node, if found */ +-#ifdef IEEE80211_DEBUG_REFCNT +-#define ieee80211_find_wds_node(_table, _mac) \ +- ieee80211_find_wds_node_debug(_table, _mac, __func__, __LINE__) +-struct ieee80211_node *ieee80211_find_wds_node_debug(struct ieee80211_node_table *, +- const u_int8_t *, const char* func, int line); +-#else +-struct ieee80211_node *ieee80211_find_wds_node(struct ieee80211_node_table *, +- const u_int8_t *); +-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */ + typedef void ieee80211_iter_func(void *, struct ieee80211_node *); + void ieee80211_iterate_nodes(struct ieee80211_node_table *, + ieee80211_iter_func *, void *); |