summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2020-06-13 22:20:02 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2020-06-13 22:20:02 +0000
commitea3d5fd9df90708b5b996a96dc694c7939e0305d (patch)
treed87793c05799a4d9ef06202817d82da2630d4bbd
parentd60bdf8569958540cef80559a94bfdec9491d191 (diff)
Notes
-rw-r--r--sys/net80211/ieee80211_node.c27
-rw-r--r--sys/net80211/ieee80211_var.h13
2 files changed, 39 insertions, 1 deletions
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 1aecc01089dc9..14e1e762aa847 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -80,6 +80,7 @@ static int ieee80211_sta_join1(struct ieee80211_node *);
static struct ieee80211_node *node_alloc(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+static int node_init(struct ieee80211_node *);
static void node_cleanup(struct ieee80211_node *);
static void node_free(struct ieee80211_node *);
static void node_age(struct ieee80211_node *);
@@ -116,6 +117,7 @@ ieee80211_node_attach(struct ieee80211com *ic)
ieee80211_node_timeout, ic);
ic->ic_node_alloc = node_alloc;
+ ic->ic_node_init = node_init;
ic->ic_node_free = node_free;
ic->ic_node_cleanup = node_cleanup;
ic->ic_node_age = node_age;
@@ -1074,6 +1076,12 @@ node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
return ni;
}
+static int
+node_init(struct ieee80211_node *ni)
+{
+ return 0;
+}
+
/*
* Initialize an ie blob with the specified data. If previous
* data exists re-use the data block. As a side effect we clear
@@ -1414,6 +1422,15 @@ ieee80211_alloc_node(struct ieee80211_node_table *nt,
ni->ni_ic = ic;
IEEE80211_NODE_UNLOCK(nt);
+ /* handle failure; free node state */
+ if (ic->ic_node_init(ni) != 0) {
+ vap->iv_stats.is_rx_nodealloc++;
+ ieee80211_psq_cleanup(&ni->ni_psq);
+ ieee80211_ratectl_node_deinit(ni);
+ _ieee80211_free_node(ni);
+ return NULL;
+ }
+
IEEE80211_NOTE(vap, IEEE80211_MSG_INACT, ni,
"%s: inact_reload %u", __func__, ni->ni_inact_reload);
@@ -1456,6 +1473,16 @@ ieee80211_tmp_node(struct ieee80211vap *vap,
ieee80211_psq_init(&ni->ni_psq, "unknown");
ieee80211_ratectl_node_init(ni);
+
+ /* handle failure; free node state */
+ if (ic->ic_node_init(ni) != 0) {
+ vap->iv_stats.is_rx_nodealloc++;
+ ieee80211_psq_cleanup(&ni->ni_psq);
+ ieee80211_ratectl_node_deinit(ni);
+ _ieee80211_free_node(ni);
+ return NULL;
+ }
+
} else {
/* XXX msg */
vap->iv_stats.is_rx_nodealloc++;
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 6af94ed343c82..6bdbd609a4120 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -310,11 +310,22 @@ struct ieee80211com {
/* TDMA update notification */
void (*ic_tdma_update)(struct ieee80211_node *,
const struct ieee80211_tdma_param *, int);
- /* node state management */
+
+ /* Node state management */
+
+ /* Allocate a new node */
struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+
+ /* Driver node initialisation after net80211 setup */
+ int (*ic_node_init)(struct ieee80211_node *);
+
+ /* Driver node deallocation */
void (*ic_node_free)(struct ieee80211_node *);
+
+ /* Driver node state cleanup before deallocation */
void (*ic_node_cleanup)(struct ieee80211_node *);
+
void (*ic_node_age)(struct ieee80211_node *);
void (*ic_node_drain)(struct ieee80211_node *);
int8_t (*ic_node_getrssi)(const struct ieee80211_node*);