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
This commit is contained in:
Adrian Chadd 2015-10-12 04:30:38 +00:00
parent 940aa8080c
commit d3a4ade3b8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=289164
8 changed files with 19 additions and 39 deletions

View File

@ -4950,9 +4950,7 @@ iwn_transmit(struct ieee80211com *ic, struct mbuf *m)
} }
error = iwn_tx_data(sc, m, ni); error = iwn_tx_data(sc, m, ni);
if (error) { if (!error)
if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
} else
sc->sc_tx_timer = 5; sc->sc_tx_timer = 5;
IWN_UNLOCK(sc); IWN_UNLOCK(sc);
return (error); return (error);

View File

@ -529,9 +529,6 @@ ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
/* /*
* Transmit a frame to the parent interface. * 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 int
ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m) 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); IEEE80211_TX_LOCK_ASSERT(ic);
error = ic->ic_transmit(ic, m); 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); ieee80211_free_mbuf(m);
}
return (error); return (error);
} }

View File

@ -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 * 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(). * call ieee80211_vap_xmitpkt().
*/ */
if (m->m_flags & M_ENCAP) { if (m->m_flags & M_ENCAP) {
if (ieee80211_parent_xmitpkt(ic, m) != 0) (void) ieee80211_parent_xmitpkt(ic, m);
ieee80211_free_node(ni);
} else { } else {
(void) ieee80211_vap_xmitpkt(vap, m); (void) ieee80211_vap_xmitpkt(vap, m);
} }

View File

@ -1239,12 +1239,8 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
IEEE80211_TX_LOCK(ic); IEEE80211_TX_LOCK(ic);
err = ieee80211_parent_xmitpkt(ic, mcopy); err = ieee80211_parent_xmitpkt(ic, mcopy);
IEEE80211_TX_UNLOCK(ic); IEEE80211_TX_UNLOCK(ic);
if (err != 0) { if (!err)
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
} else {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
} }
static struct mbuf * static struct mbuf *

View File

@ -132,7 +132,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
{ {
struct ieee80211com *ic = vap->iv_ic; struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp; struct ifnet *ifp = vap->iv_ifp;
int error, len, mcast; int len, mcast;
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
(m->m_flags & M_PWR_SAV) == 0) { (m->m_flags & M_PWR_SAV) == 0) {
@ -264,18 +264,13 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
return (ENOBUFS); return (ENOBUFS);
} }
} }
error = ieee80211_parent_xmitpkt(ic, m); (void) ieee80211_parent_xmitpkt(ic, m);
/* /*
* Unlock at this point - no need to hold it across * Unlock at this point - no need to hold it across
* ieee80211_free_node() (ie, the comlock) * ieee80211_free_node() (ie, the comlock)
*/ */
IEEE80211_TX_UNLOCK(ic); 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; ic->ic_lastdata = ticks;
return (0); return (0);

View File

@ -457,12 +457,7 @@ pwrsave_flushq(struct ieee80211_node *ni)
KASSERT((m->m_flags & M_ENCAP), KASSERT((m->m_flags & M_ENCAP),
("%s: parentq with non-M_ENCAP frame!\n", ("%s: parentq with non-M_ENCAP frame!\n",
__func__)); __func__));
/* (void) ieee80211_parent_xmitpkt(ic, m);
* For encaped frames, we need to free the node
* reference upon failure.
*/
if (ieee80211_parent_xmitpkt(ic, m) != 0)
ieee80211_free_node(ni);
} }
/* VAP frames, aren't encapsulated */ /* VAP frames, aren't encapsulated */

View File

@ -475,13 +475,9 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m)
if (m != NULL) { if (m != NULL) {
struct ifnet *ifp = vap->iv_ifp; struct ifnet *ifp = vap->iv_ifp;
error = ieee80211_parent_xmitpkt(ic, m);; error = ieee80211_parent_xmitpkt(ic, m);
if (error != 0) { if (!error)
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
} else {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
} else } else
ieee80211_free_node(ni); ieee80211_free_node(ni);
} }

View File

@ -298,11 +298,7 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
mcopy->m_pkthdr.rcvif = (void *) ni; mcopy->m_pkthdr.rcvif = (void *) ni;
err = ieee80211_parent_xmitpkt(ic, mcopy); err = ieee80211_parent_xmitpkt(ic, mcopy);
if (err) { if (!err) {
/* NB: IFQ_HANDOFF reclaims mbuf */
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
} else {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
if_inc_counter(ifp, IFCOUNTER_OBYTES, if_inc_counter(ifp, IFCOUNTER_OBYTES,