svn commit: r282372 - head/sys/net80211
Adrian Chadd
adrian at FreeBSD.org
Sun May 3 22:28:43 UTC 2015
Author: adrian
Date: Sun May 3 22:28:42 2015
New Revision: 282372
URL: https://svnweb.freebsd.org/changeset/base/282372
Log:
Remove old iv_bss entry from the node table
This may happen on RUN -> SCAN -> RUN -> SCAN state transition:
1. RUN -> SCAN: in ieee80211_sta_join1(): iv_bss will be moved to obss,
refcnt will be reduced by 2 (default minimum).
Now, if old iv_bss have some extra references (for example, from
unacknowledged probe responses), it will not be freed and will stay
in the node table.
2. SCAN -> RUN.
3. If old iv_bss will not be deleted by the time when the next RUN -> SCAN
state transition occurs, then sta_leave() will reduce it's reference
counter once more. As a result, two last users will free it -> this will
lead to kernel panic.
In this patch old iv_bss entry is explicitly removed from the node table in
ieee80211_sta_join1() (as a result, it will not be processed by sta_leave()).
PR: kern/199676
Differential Revision: Andriy Voskoboinyk <s3erios at gmail.com>
Modified:
head/sys/net80211/ieee80211_node.c
Modified: head/sys/net80211/ieee80211_node.c
==============================================================================
--- head/sys/net80211/ieee80211_node.c Sun May 3 22:13:55 2015 (r282371)
+++ head/sys/net80211/ieee80211_node.c Sun May 3 22:28:42 2015 (r282372)
@@ -93,6 +93,8 @@ static void node_getmimoinfo(const struc
static void _ieee80211_free_node(struct ieee80211_node *);
+static void node_reclaim(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni);
static void ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt, const char *name,
int inact, int keymaxix);
@@ -719,9 +721,15 @@ ieee80211_sta_join1(struct ieee80211_nod
IEEE80211_ADDR_EQ(obss->ni_macaddr, selbs->ni_macaddr));
vap->iv_bss = selbs; /* NB: caller assumed to bump refcnt */
if (obss != NULL) {
+ struct ieee80211_node_table *nt = obss->ni_table;
+
copy_bss(selbs, obss);
ieee80211_node_decref(obss); /* iv_bss reference */
- ieee80211_free_node(obss); /* station table reference */
+
+ IEEE80211_NODE_LOCK(nt);
+ node_reclaim(nt, obss); /* station table reference */
+ IEEE80211_NODE_UNLOCK(nt);
+
obss = NULL; /* NB: guard against later use */
}
More information about the svn-src-all
mailing list