diff options
author | sam <sam@FreeBSD.org> | 2007-01-08 18:23:43 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2007-01-08 18:23:43 +0000 |
commit | 12b187d03590cc37d2e30dc8b8e75d1f3128a86b (patch) | |
tree | 16f43e89d59db0da857e97f067440967345c42c3 /sys/net80211/ieee80211_freebsd.c | |
parent | c4c1a3359ab0fc711ab65651930ac7b11c785272 (diff) | |
download | FreeBSD-src-12b187d03590cc37d2e30dc8b8e75d1f3128a86b.zip FreeBSD-src-12b187d03590cc37d2e30dc8b8e75d1f3128a86b.tar.gz |
Fix potential node refcnt leak. If mbufs are q'd on ic_mgtq when
the state machine clocks to INIT, node references are not reclaimed.
Add a new routine ieee80211_drain_ifq that does this and use it
instead of IF_DRAIN.
Submitted by: Sepherosa Ziehau
Obtained from: DragonFly
MFC after: 1 month
Diffstat (limited to 'sys/net80211/ieee80211_freebsd.c')
-rw-r--r-- | sys/net80211/ieee80211_freebsd.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 423eab6..a44e4c8 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -150,6 +150,26 @@ ieee80211_node_dectestref(struct ieee80211_node *ni) return atomic_cmpset_int(&ni->ni_refcnt, 0, 1); } +void +ieee80211_drain_ifq(struct ifqueue *ifq) +{ + struct ieee80211_node *ni; + struct mbuf *m; + + for (;;) { + IF_DEQUEUE(ifq, m); + if (m == NULL) + break; + + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + KASSERT(ni != NULL, ("frame w/o node")); + ieee80211_free_node(ni); + m->m_pkthdr.rcvif = NULL; + + m_freem(m); + } +} + /* * Allocate and setup a management frame of the specified * size. We return the mbuf and a pointer to the start |