aboutsummaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/392-remove_wds_nodetracking.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-01-25 00:37:41 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-01-25 00:37:41 +0000
commit87db54da68aa2614122a0f2f2d4c79722dad2bb9 (patch)
tree022b7bd5bc73da3bce22c057ba58b97b4596e5c1 /package/madwifi/patches/392-remove_wds_nodetracking.patch
parent28abf79c44dc8a464d9573a9dc0c657ad5a35b60 (diff)
downloadupstream-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.patch388
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 *);