diff options
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_hostap.c | 16 | ||||
-rw-r--r-- | sys/net80211/ieee80211_hwmp.c | 14 | ||||
-rw-r--r-- | sys/net80211/ieee80211_radiotap.h | 13 |
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, }; |