summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-10-12 03:27:08 +0000
committeradrian <adrian@FreeBSD.org>2015-10-12 03:27:08 +0000
commit9c9f0d74e16010325bf5e43d168ce604b10a6943 (patch)
tree1b2473150d991e361c2b7c638b1825555a2fff7c /sys/net80211
parent2b83d5a980404ddde25f082a1515d59a921b7f4b (diff)
downloadFreeBSD-src-9c9f0d74e16010325bf5e43d168ce604b10a6943.zip
FreeBSD-src-9c9f0d74e16010325bf5e43d168ce604b10a6943.tar.gz
net80211: separate mbuf cleanup from ieee80211_fragment()
* Create ieee80211_free_mbuf() which frees a list of mbufs. * Use it in the fragment transmit path and ath / uath transmit paths. * Call it in xmit_pkt() if the transmission fails; otherwise fragments may be leaked. This should be a big no-op. Submitted by: <s3erios@gmail.com> Differential Revision: https://reviews.freebsd.org/D3769
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_freebsd.c2
-rw-r--r--sys/net80211/ieee80211_output.c23
-rw-r--r--sys/net80211/ieee80211_proto.h1
3 files changed, 19 insertions, 7 deletions
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 6fdfb5c..5b2c103 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -545,7 +545,7 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
IEEE80211_TX_LOCK_ASSERT(ic);
error = ic->ic_transmit(ic, m);
if (error)
- m_freem(m);
+ ieee80211_free_mbuf(m);
return (error);
}
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 19af613..149b726 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1583,6 +1583,21 @@ bad:
#undef MC01
}
+void
+ieee80211_free_mbuf(struct mbuf *m)
+{
+ struct mbuf *next;
+
+ if (m == NULL)
+ return;
+
+ do {
+ next = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ m_freem(m);
+ } while ((m = next) != NULL);
+}
+
/*
* Fragment the frame according to the specified mtu.
* The size of the 802.11 header (w/o padding) is provided
@@ -1597,7 +1612,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_frame *wh, *whf;
- struct mbuf *m, *prev, *next;
+ struct mbuf *m, *prev;
u_int totalhdrsize, fragno, fragsize, off, remainder, payload;
u_int hdrspace;
@@ -1692,11 +1707,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
return 1;
bad:
/* reclaim fragments but leave original frame for caller to free */
- for (m = m0->m_nextpkt; m != NULL; m = next) {
- next = m->m_nextpkt;
- m->m_nextpkt = NULL; /* XXX paranoid */
- m_freem(m);
- }
+ ieee80211_free_mbuf(m0->m_nextpkt);
m0->m_nextpkt = NULL;
return 0;
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 4305863..38bd3d6 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -93,6 +93,7 @@ struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,
struct ieee80211_key *, struct mbuf *);
struct mbuf *ieee80211_encap(struct ieee80211vap *, struct ieee80211_node *,
struct mbuf *);
+void ieee80211_free_mbuf(struct mbuf *);
int ieee80211_send_mgmt(struct ieee80211_node *, int, int);
struct ieee80211_appie;
int ieee80211_send_probereq(struct ieee80211_node *ni,
OpenPOWER on IntegriCloud