summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_hostap.c16
-rw-r--r--sys/net80211/ieee80211_hwmp.c14
-rw-r--r--sys/net80211/ieee80211_radiotap.h13
3 files changed, 40 insertions, 3 deletions
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 675f3da..7087748 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2324,5 +2324,19 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
ifp = vap->iv_ic->ic_ifp;
else
ifp = vap->iv_ifp;
- (void) ifp->if_transmit(ifp, m);
+
+ /*
+ * Free any node ref which this mbuf may have.
+ *
+ * Much like psq_mfree(), we assume that M_ENCAP nodes have
+ * node references.
+ */
+ if (ifp->if_transmit(ifp, m) != 0) {
+ /*
+ * XXX m is invalid (freed) at this point, determine M_ENCAP
+ * an alternate way.
+ */
+ if (ifp == vap->iv_ic->ic_ifp)
+ ieee80211_free_node(ni);
+ }
}
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index fcc4af1..2f8ec85 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -1227,6 +1227,8 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
struct mbuf *m, *next;
uint32_t metric = 0;
const uint8_t *addr;
+ int is_encap;
+ struct ieee80211_node *ni_encap;
if (ni == vap->iv_bss ||
ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
@@ -1403,11 +1405,21 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
(struct ieee80211_node *)(uintptr_t)
ieee80211_mac_hash(ic, addr)); /* either dest or ext_dest */
for (; m != NULL; m = next) {
+ is_encap = !! (m->m_flags & M_ENCAP);
+ ni_encap = (struct ieee80211_node *) m->m_pkthdr.rcvif;
next = m->m_nextpkt;
m->m_nextpkt = NULL;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"flush queued frame %p len %d", m, m->m_pkthdr.len);
- ifp->if_transmit(ifp, m);
+
+ /*
+ * If the mbuf has M_ENCAP set, ensure we free it.
+ * Note that after if_transmit() is called, m is invalid.
+ */
+ if (ifp->if_transmit(ifp, m) != 0) {
+ if (is_encap)
+ ieee80211_free_node(ni_encap);
+ }
}
#undef IS_PROXY
#undef PROXIED_BY_US
diff --git a/sys/net80211/ieee80211_radiotap.h b/sys/net80211/ieee80211_radiotap.h
index f11ba73..388d70e 100644
--- a/sys/net80211/ieee80211_radiotap.h
+++ b/sys/net80211/ieee80211_radiotap.h
@@ -194,9 +194,20 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
- /* NB: gap for netbsd definitions */
+ /*
+ * 14-17 are from Linux, they overlap the netbsd-specific
+ * fields.
+ */
+ IEEE80211_RADIOTAP_RX_FLAGS = 14,
+ IEEE80211_RADIOTAP_TX_FLAGS = 15,
+ IEEE80211_RADIOTAP_RTS_RETRIES = 16,
+ IEEE80211_RADIOTAP_DATA_RETRIES = 17,
+
IEEE80211_RADIOTAP_XCHANNEL = 18,
IEEE80211_RADIOTAP_MCS = 19,
+ IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
+
+ IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOREXT = 30,
IEEE80211_RADIOTAP_EXT = 31,
};
OpenPOWER on IntegriCloud