PERFORCE change 81314 for review
Sam Leffler
sam at FreeBSD.org
Mon Aug 1 21:53:52 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=81314
Change 81314 by sam at sam_ebb on 2005/08/01 21:53:50
Fix problems with key map table handling:
o correct braino in ieee80211_free_node (premature node reclaim)
o special case ieee80211_free_node handling when the last
reference is in the key map; otherwise we orphan nodes until
someone resets state
o bandaid ieee80211_node_delkey locking; can be called w/ and
w/o the node table lock held (still need to fix LOR too)
o fix refcnt debug code
o add some debug msgs
While here make ieee80211_node_table_reset static; no longer
needs to be public with new scan code. Also remove extraneous
ieee80211_reset_erp call in clearing the node table (didn't
belong here anyway).
Affected files ...
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#58 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#28 edit
Differences ...
==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#58 (text+ko) ====
@@ -72,6 +72,7 @@
static void ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt, const char *name, int inact);
+static void ieee80211_node_table_reset(struct ieee80211_node_table *);
static void ieee80211_node_table_cleanup(struct ieee80211_node_table *nt);
MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
@@ -943,7 +944,7 @@
struct ieee80211_node *
#ifdef IEEE80211_DEBUG_REFCNT
ieee80211_find_rxnode_withkey_debug(struct ieee80211com *ic,
- const struct ieee80211_frame_min *wh, , u_int16_t keyix,
+ const struct ieee80211_frame_min *wh, u_int16_t keyix,
const char *func, int line)
#else
ieee80211_find_rxnode_withkey(struct ieee80211com *ic,
@@ -974,8 +975,13 @@
("keyix %u out of bounds (2)", keyix));
/* XXX can keyixmap[keyix] != NULL? */
if (keyix != IEEE80211_KEYIX_NONE &&
- nt->nt_keyixmap[keyix] == NULL)
+ nt->nt_keyixmap[keyix] == NULL) {
+ IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE,
+ "%s: add key map entry %p<%s> refcnt %d\n",
+ __func__, ni, ether_sprintf(ni->ni_macaddr),
+ ieee80211_node_refcnt(ni)+1);
nt->nt_keyixmap[keyix] = ieee80211_ref_node(ni);
+ }
} else
ieee80211_ref_node(ni);
IEEE80211_NODE_UNLOCK(nt);
@@ -1125,11 +1131,31 @@
#endif
if (nt != NULL) {
IEEE80211_NODE_LOCK(nt);
- if (ieee80211_node_dectestref(ni))
+ if (ieee80211_node_dectestref(ni)) {
+ /*
+ * Last reference, reclaim state.
+ */
_ieee80211_free_node(ni);
+ } else if (ieee80211_node_refcnt(ni) == 1) {
+ u_int16_t keyix;
+ /*
+ * Check for a last reference in the key mapping table.
+ */
+ keyix = ni->ni_ucastkey.wk_keyix;
+ if (keyix != IEEE80211_KEYIX_NONE &&
+ nt->nt_keyixmap[keyix] == ni) {
+ IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE,
+ "%s: %p<%s> clear key map entry", __func__,
+ ni, ether_sprintf(ni->ni_macaddr));
+ nt->nt_keyixmap[keyix] = NULL;
+ ieee80211_node_decref(ni); /* XXX needed? */
+ _ieee80211_free_node(ni);
+ }
+ }
IEEE80211_NODE_UNLOCK(nt);
} else {
- _ieee80211_free_node(ni);
+ if (ieee80211_node_dectestref(ni))
+ _ieee80211_free_node(ni);
}
}
@@ -1141,14 +1167,23 @@
ieee80211_node_delkey(struct ieee80211_node_table *nt, u_int16_t keyix)
{
struct ieee80211_node *ni;
+ int isowned = mtx_owned(&nt->nt_nodelock);
- IEEE80211_NODE_LOCK(nt);
+ /* XXX can be entered w/ or w/o lock */
+ if (!isowned)
+ IEEE80211_NODE_LOCK(nt);
ni = nt->nt_keyixmap[keyix];
nt->nt_keyixmap[keyix] = NULL;;
- IEEE80211_NODE_UNLOCK(nt);
+ if (!isowned)
+ IEEE80211_NODE_UNLOCK(nt);
- if (ni != NULL)
+ if (ni != NULL) {
+ IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE,
+ "%s: delete key map entry %p<%s> refcnt %d\n",
+ __func__, ni, ether_sprintf(ni->ni_macaddr),
+ ieee80211_node_refcnt(ni)-1);
ieee80211_free_node(ni);
+ }
}
/*
@@ -1176,6 +1211,9 @@
*/
keyix = ni->ni_ucastkey.wk_keyix;
if (keyix != IEEE80211_KEYIX_NONE && nt->nt_keyixmap[keyix] == ni) {
+ IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE,
+ "%s: %p<%s> clear key map entry\n",
+ __func__, ni, ether_sprintf(ni->ni_macaddr));
nt->nt_keyixmap[keyix] = NULL;
ieee80211_node_decref(ni);
}
@@ -1210,7 +1248,6 @@
}
node_reclaim(nt, ni);
}
- ieee80211_reset_erp(ic);
}
/*
@@ -1716,7 +1753,7 @@
nt->nt_inact_init = inact;
}
-void
+static void
ieee80211_node_table_reset(struct ieee80211_node_table *nt)
{
==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#28 (text+ko) ====
@@ -216,7 +216,6 @@
u_int nt_scangen; /* gen# for timeout scan */
int nt_inact_init; /* initial node inact setting */
};
-void ieee80211_node_table_reset(struct ieee80211_node_table *);
struct ieee80211_node *ieee80211_alloc_node(
struct ieee80211_node_table *, const u_int8_t *);
@@ -231,6 +230,10 @@
struct ieee80211_node * ieee80211_find_rxnode_debug(struct ieee80211com *,
const struct ieee80211_frame_min *,
const char *func, int line);
+struct ieee80211_node * ieee80211_find_rxnode_withkey_debug(
+ struct ieee80211com *,
+ const struct ieee80211_frame_min *, u_int16_t keyix,
+ const char *func, int line);
struct ieee80211_node *ieee80211_find_txnode_debug(struct ieee80211com *,
const u_int8_t *,
const char *func, int line);
@@ -244,6 +247,8 @@
ieee80211_find_node_debug(nt, mac, __func__, __LINE__)
#define ieee80211_find_rxnode(nt, wh) \
ieee80211_find_rxnode_debug(nt, wh, __func__, __LINE__)
+#define ieee80211_find_rxnode_withkey(nt, wh, keyix) \
+ ieee80211_find_rxnode_withkey_debug(nt, wh, keyix, __func__, __LINE__)
#define ieee80211_find_txnode(nt, mac) \
ieee80211_find_txnode_debug(nt, mac, __func__, __LINE__)
#define ieee80211_find_node_with_ssid(nt, mac, sl, ss) \
More information about the p4-projects
mailing list