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:
parent
940aa8080c
commit
d3a4ade3b8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=289164
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 *
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user