Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106137162
D7996.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D7996.diff
View Options
Index: head/sys/net80211/ieee80211_node.h
===================================================================
--- head/sys/net80211/ieee80211_node.h
+++ head/sys/net80211/ieee80211_node.h
@@ -359,6 +359,7 @@
ieee80211_node_lock_t nt_nodelock; /* on node table */
TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */
LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
+ int nt_count; /* number of nodes */
struct ieee80211_node **nt_keyixmap; /* key ix -> node map */
int nt_keyixmax; /* keyixmap size */
const char *nt_name; /* table name for debug msgs */
@@ -444,8 +445,8 @@
void ieee80211_node_timeout(void *arg);
typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
-int ieee80211_iterate_nt(struct ieee80211_node_table *,
- struct ieee80211_node **, uint16_t);
+int ieee80211_iterate_nodes_vap(struct ieee80211_node_table *,
+ struct ieee80211vap *, ieee80211_iter_func *, void *);
void ieee80211_iterate_nodes(struct ieee80211_node_table *,
ieee80211_iter_func *, void *);
Index: head/sys/net80211/ieee80211_node.c
===================================================================
--- head/sys/net80211/ieee80211_node.c
+++ head/sys/net80211/ieee80211_node.c
@@ -1214,13 +1214,44 @@
/* XXX EVM? */
}
+static void
+ieee80211_add_node_nt(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni)
+{
+ struct ieee80211com *ic = nt->nt_ic;
+ int hash;
+
+ IEEE80211_NODE_LOCK_ASSERT(nt);
+
+ hash = IEEE80211_NODE_HASH(ic, ni->ni_macaddr);
+ (void) ic; /* XXX IEEE80211_NODE_HASH */
+ TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
+ LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
+ nt->nt_count++;
+ ni->ni_table = nt;
+}
+
+static void
+ieee80211_del_node_nt(struct ieee80211_node_table *nt,
+ struct ieee80211_node *ni)
+{
+
+ IEEE80211_NODE_LOCK_ASSERT(nt);
+
+ TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
+ LIST_REMOVE(ni, ni_hash);
+ nt->nt_count--;
+ KASSERT(nt->nt_count >= 0,
+ ("nt_count is negative (%d)!\n", nt->nt_count));
+ ni->ni_table = NULL;
+}
+
struct ieee80211_node *
ieee80211_alloc_node(struct ieee80211_node_table *nt,
struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = nt->nt_ic;
struct ieee80211_node *ni;
- int hash;
ni = ic->ic_node_alloc(vap, macaddr);
if (ni == NULL) {
@@ -1233,7 +1264,6 @@
ether_sprintf(macaddr), nt->nt_name);
IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
- hash = IEEE80211_NODE_HASH(ic, macaddr);
ieee80211_node_initref(ni); /* mark referenced */
ni->ni_chan = IEEE80211_CHAN_ANYC;
ni->ni_authmode = IEEE80211_AUTH_OPEN;
@@ -1250,9 +1280,7 @@
ieee80211_mesh_node_init(vap, ni);
#endif
IEEE80211_NODE_LOCK(nt);
- TAILQ_INSERT_TAIL(&nt->nt_node, ni, ni_list);
- LIST_INSERT_HEAD(&nt->nt_hash[hash], ni, ni_hash);
- ni->ni_table = nt;
+ ieee80211_add_node_nt(nt, ni);
ni->ni_vap = vap;
ni->ni_ic = ic;
IEEE80211_NODE_UNLOCK(nt);
@@ -1815,10 +1843,8 @@
if (vap->iv_aid_bitmap != NULL)
IEEE80211_AID_CLR(vap, ni->ni_associd);
}
- if (nt != NULL) {
- TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
- LIST_REMOVE(ni, ni_hash);
- }
+ if (nt != NULL)
+ ieee80211_del_node_nt(nt, ni);
ni->ni_ic->ic_node_free(ni);
}
@@ -1957,9 +1983,7 @@
* the references are dropped storage will be
* reclaimed.
*/
- TAILQ_REMOVE(&nt->nt_node, ni, ni_list);
- LIST_REMOVE(ni, ni_hash);
- ni->ni_table = NULL; /* clear reference */
+ ieee80211_del_node_nt(nt, ni);
} else
_ieee80211_free_node(ni);
}
@@ -1977,6 +2001,7 @@
nt->nt_ic = ic;
IEEE80211_NODE_LOCK_INIT(nt, ic->ic_name);
TAILQ_INIT(&nt->nt_node);
+ nt->nt_count = 0;
nt->nt_name = name;
nt->nt_inact_init = inact;
nt->nt_keyixmax = keyixmax;
@@ -2261,117 +2286,68 @@
}
/*
- * Iterate over the node table and return an array of ref'ed nodes.
- *
- * This is separated out from calling the actual node function so that
- * no LORs will occur.
- *
- * If there are too many nodes (ie, the number of nodes doesn't fit
- * within 'max_aid' entries) then the node references will be freed
- * and an error will be returned.
- *
- * The responsibility of allocating and freeing "ni_arr" is up to
- * the caller.
+ * The same as ieee80211_iterate_nodes(), but for one vap only.
*/
int
-ieee80211_iterate_nt(struct ieee80211_node_table *nt,
- struct ieee80211_node **ni_arr, uint16_t max_aid)
+ieee80211_iterate_nodes_vap(struct ieee80211_node_table *nt,
+ struct ieee80211vap *vap, ieee80211_iter_func *f, void *arg)
{
- int i, j, ret;
+ struct ieee80211_node **ni_arr;
struct ieee80211_node *ni;
+ size_t size;
+ int count, i;
+ /*
+ * Iterate over the node table and save an array of ref'ed nodes.
+ *
+ * This is separated out from calling the actual node function so that
+ * no LORs will occur.
+ */
IEEE80211_NODE_LOCK(nt);
+ count = nt->nt_count;
+ size = count * sizeof(struct ieee80211_node *);
+ ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
+ if (ni_arr == NULL) {
+ IEEE80211_NODE_UNLOCK(nt);
+ return (ENOMEM);
+ }
- i = ret = 0;
+ i = 0;
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
- if (i >= max_aid) {
- ret = E2BIG;
- ic_printf(nt->nt_ic, "Node array overflow: max=%u",
- max_aid);
- break;
- }
+ if (vap != NULL && ni->ni_vap != vap)
+ continue;
+ KASSERT(i < count,
+ ("node array overflow (vap %p, i %d, count %d)\n",
+ vap, i, count));
ni_arr[i] = ieee80211_ref_node(ni);
i++;
}
-
- /*
- * It's safe to unlock here.
- *
- * If we're successful, the list is returned.
- * If we're unsuccessful, the list is ignored
- * and we remove our references.
- *
- * This avoids any potential LOR with
- * ieee80211_free_node().
- */
IEEE80211_NODE_UNLOCK(nt);
- /*
- * If ret is non-zero, we hit some kind of error.
- * Rather than walking some nodes, we'll walk none
- * of them.
- */
- if (ret) {
- for (j = 0; j < i; j++) {
- /* ieee80211_free_node() locks by itself */
- ieee80211_free_node(ni_arr[j]);
- }
+ for (i = 0; i < count; i++) {
+ if (ni_arr[i] == NULL) /* end of the list */
+ break;
+ (*f)(arg, ni_arr[i]);
+ /* ieee80211_free_node() locks by itself */
+ ieee80211_free_node(ni_arr[i]);
}
- return (ret);
+ IEEE80211_FREE(ni_arr, M_80211_NODE);
+
+ return (0);
}
/*
* Just a wrapper, so we don't have to change every ieee80211_iterate_nodes()
* reference in the source.
- *
- * Note that this fetches 'max_aid' from the first VAP, rather than finding
- * the largest max_aid from all VAPs.
*/
void
ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
ieee80211_iter_func *f, void *arg)
{
- struct ieee80211_node **ni_arr;
- size_t size;
- int i;
- uint16_t max_aid;
- struct ieee80211vap *vap;
-
- /* Overdoing it default */
- max_aid = IEEE80211_AID_MAX;
-
- /* Handle the case of there being no vaps just yet */
- vap = TAILQ_FIRST(&nt->nt_ic->ic_vaps);
- if (vap != NULL)
- max_aid = vap->iv_max_aid;
-
- size = max_aid * sizeof(struct ieee80211_node *);
- ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
- IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
- if (ni_arr == NULL)
- return;
-
- /*
- * If this fails, the node table won't have any
- * valid entries - ieee80211_iterate_nt() frees
- * the references to them. So don't try walking
- * the table; just skip to the end and free the
- * temporary memory.
- */
- if (ieee80211_iterate_nt(nt, ni_arr, max_aid) != 0)
- goto done;
-
- for (i = 0; i < max_aid; i++) {
- if (ni_arr[i] == NULL) /* end of the list */
- break;
- (*f)(arg, ni_arr[i]);
- /* ieee80211_free_node() locks by itself */
- ieee80211_free_node(ni_arr[i]);
- }
-
-done:
- IEEE80211_FREE(ni_arr, M_80211_NODE);
+ /* XXX no way to pass error to the caller. */
+ (void) ieee80211_iterate_nodes_vap(nt, NULL, f, arg);
}
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 27, 12:30 AM (12 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15609491
Default Alt Text
D7996.diff (7 KB)
Attached To
Mode
D7996: net80211: add one-vap version of ieee80211_iterate_nodes()
Attached
Detach File
Event Timeline
Log In to Comment