summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-10-12 04:30:38 +0000
committeradrian <adrian@FreeBSD.org>2015-10-12 04:30:38 +0000
commit5a44e8c44b09f08ee9e42d177f79640c96f4c857 (patch)
treed270a0b32ce9aceeddcb5e0b590514b3f652a0fd /sys/net80211
parent3051919e5d532bac767ea80495ef5b5d1b6eac50 (diff)
downloadFreeBSD-src-5a44e8c44b09f08ee9e42d177f79640c96f4c857.zip
FreeBSD-src-5a44e8c44b09f08ee9e42d177f79640c96f4c857.tar.gz
net80211: free node reference in the ieee80211_parent_xmitpkt() when error happened.
Move error handling into ieee80211_parent_xmitpkt() instead of spreading it between functions. Submitted by: <s3erios@gmail.com> Differential Revision: https://reviews.freebsd.org/D3772
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_freebsd.c13
-rw-r--r--sys/net80211/ieee80211_hostap.c5
-rw-r--r--sys/net80211/ieee80211_mesh.c6
-rw-r--r--sys/net80211/ieee80211_output.c9
-rw-r--r--sys/net80211/ieee80211_power.c7
-rw-r--r--sys/net80211/ieee80211_superg.c8
-rw-r--r--sys/net80211/ieee80211_wds.c6
7 files changed, 18 insertions, 36 deletions
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 5b2c103..7f2eae5 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -529,9 +529,6 @@ ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
/*
* Transmit a frame to the parent interface.
- *
- * TODO: if the transmission fails, make sure the parent node is freed
- * (the callers will first need modifying.)
*/
int
ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
@@ -544,8 +541,16 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
*/
IEEE80211_TX_LOCK_ASSERT(ic);
error = ic->ic_transmit(ic, m);
- if (error)
+ if (error) {
+ struct ieee80211_node *ni;
+
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+
+ /* XXX number of fragments */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
ieee80211_free_mbuf(m);
+ }
return (error);
}
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index ccb31ab..34d1b4e 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2327,12 +2327,11 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
/*
* Do the right thing; if it's an encap'ed frame then
- * call ieee80211_parent_xmitpkt() (and free the ref) else
+ * call ieee80211_parent_xmitpkt() else
* call ieee80211_vap_xmitpkt().
*/
if (m->m_flags & M_ENCAP) {
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
+ (void) ieee80211_parent_xmitpkt(ic, m);
} else {
(void) ieee80211_vap_xmitpkt(vap, m);
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index cb6ab81..1778c09 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1239,12 +1239,8 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
IEEE80211_TX_LOCK(ic);
err = ieee80211_parent_xmitpkt(ic, mcopy);
IEEE80211_TX_UNLOCK(ic);
- if (err != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- } else {
+ if (!err)
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- }
}
static struct mbuf *
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 149b726..81d9eb1 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -132,7 +132,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
{
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
- int error, len, mcast;
+ int len, mcast;
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
(m->m_flags & M_PWR_SAV) == 0) {
@@ -264,18 +264,13 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
return (ENOBUFS);
}
}
- error = ieee80211_parent_xmitpkt(ic, m);
+ (void) ieee80211_parent_xmitpkt(ic, m);
/*
* Unlock at this point - no need to hold it across
* ieee80211_free_node() (ie, the comlock)
*/
IEEE80211_TX_UNLOCK(ic);
- if (error != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
ic->ic_lastdata = ticks;
return (0);
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 2d216c2..73c1382 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -457,12 +457,7 @@ pwrsave_flushq(struct ieee80211_node *ni)
KASSERT((m->m_flags & M_ENCAP),
("%s: parentq with non-M_ENCAP frame!\n",
__func__));
- /*
- * For encaped frames, we need to free the node
- * reference upon failure.
- */
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
+ (void) ieee80211_parent_xmitpkt(ic, m);
}
/* VAP frames, aren't encapsulated */
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index e91da01..8be098a 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -475,13 +475,9 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m)
if (m != NULL) {
struct ifnet *ifp = vap->iv_ifp;
- error = ieee80211_parent_xmitpkt(ic, m);;
- if (error != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- } else {
+ error = ieee80211_parent_xmitpkt(ic, m);
+ if (!error)
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- }
} else
ieee80211_free_node(ni);
}
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index 1d3f30a..a444b79 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -298,11 +298,7 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
mcopy->m_pkthdr.rcvif = (void *) ni;
err = ieee80211_parent_xmitpkt(ic, mcopy);
- if (err) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- ieee80211_free_node(ni);
- } else {
+ if (!err) {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
if_inc_counter(ifp, IFCOUNTER_OBYTES,
OpenPOWER on IntegriCloud