summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/net80211/ieee80211_input.c4
-rw-r--r--sys/net80211/ieee80211_node.c36
-rw-r--r--sys/net80211/ieee80211_node.h2
3 files changed, 40 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index e0c4879..8defa97 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -954,7 +954,7 @@ ieee80211_send_error(struct ieee80211com *ic, struct ieee80211_node *ni,
int istmp;
if (ni == ic->ic_bss) {
- ni = ieee80211_dup_bss(&ic->ic_sta, mac);
+ ni = ieee80211_tmp_node(ic, mac);
if (ni == NULL) {
/* XXX msg */
return;
@@ -2107,7 +2107,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
wh->i_addr2);
} else
- ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
+ ni = ieee80211_tmp_node(ic, wh->i_addr2);
if (ni == NULL)
return;
allocbs = 1;
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 72884f0..12ff342 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -947,6 +947,42 @@ ieee80211_alloc_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
return ni;
}
+/*
+ * Craft a temporary node suitable for sending a management frame
+ * to the specified station. We craft only as much state as we
+ * need to do the work since the node will be immediately reclaimed
+ * once the send completes.
+ */
+struct ieee80211_node *
+ieee80211_tmp_node(struct ieee80211com *ic, const u_int8_t *macaddr)
+{
+ struct ieee80211_node *ni;
+
+ ni = ic->ic_node_alloc(&ic->ic_sta);
+ if (ni != NULL) {
+ IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
+ "%s %p<%s>\n", __func__, ni, ether_sprintf(macaddr));
+
+ IEEE80211_ADDR_COPY(ni->ni_macaddr, macaddr);
+ IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
+ ieee80211_node_initref(ni); /* mark referenced */
+ ni->ni_txpower = ic->ic_bss->ni_txpower;
+ /* NB: required by ieee80211_fix_rate */
+ ieee80211_set_chan(ic, ni, ic->ic_bss->ni_chan);
+ ieee80211_crypto_resetkey(ic, &ni->ni_ucastkey,
+ IEEE80211_KEYIX_NONE);
+ /* XXX optimize away */
+ IEEE80211_NODE_SAVEQ_INIT(ni, "unknown");
+
+ ni->ni_table = NULL; /* NB: pedantic */
+ ni->ni_ic = ic;
+ } else {
+ /* XXX msg */
+ ic->ic_stats.is_rx_nodealloc++;
+ }
+ return ni;
+}
+
struct ieee80211_node *
ieee80211_dup_bss(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
{
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 96f642d..c2941c4 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -218,6 +218,8 @@ void ieee80211_node_table_reset(struct ieee80211_node_table *);
struct ieee80211_node *ieee80211_alloc_node(
struct ieee80211_node_table *, const u_int8_t *);
+struct ieee80211_node *ieee80211_tmp_node(struct ieee80211com *,
+ const u_int8_t *macaddr);
struct ieee80211_node *ieee80211_dup_bss(struct ieee80211_node_table *,
const u_int8_t *);
#ifdef IEEE80211_DEBUG_REFCNT
OpenPOWER on IntegriCloud