diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-06-21 10:19:22 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2021-06-21 10:19:22 +0000 |
commit | 1ab8aa69ffe478241f532aa744b423c57325c1da (patch) | |
tree | 8dc73c4a0350fc1951190b0bc160cc2ec629e07c /sys/dev/pci/if_iwm.c | |
parent | 2324f61fd122a00405c4441a7ec30694e197fe3d (diff) |
Fix ieee80211_node leak in iwm(4) and iwx(4).
CVS commit mPRyhYmlmonmI11J which added support for Rx aggregation offload
contains a node leak in the rx_reorder() function. Node leaks will cause
the driver to get stuck when roaming between access points.
Add missing calls to ieee80211_release_node() to fix this.
ok mpi@
Diffstat (limited to 'sys/dev/pci/if_iwm.c')
-rw-r--r-- | sys/dev/pci/if_iwm.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c index 180f46391f1..e33fe39b978 100644 --- a/sys/dev/pci/if_iwm.c +++ b/sys/dev/pci/if_iwm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwm.c,v 1.328 2021/06/01 18:03:56 stsp Exp $ */ +/* $OpenBSD: if_iwm.c,v 1.329 2021/06/21 10:19:21 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -4876,7 +4876,6 @@ iwm_rx_reorder(struct iwm_softc *sc, struct mbuf *m, int chanidx, type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - ni = ieee80211_find_rxnode(ic, wh); /* * We are only interested in Block Ack requests and unicast QoS data. @@ -4918,6 +4917,7 @@ iwm_rx_reorder(struct iwm_softc *sc, struct mbuf *m, int chanidx, buffer->valid = 1; } + ni = ieee80211_find_rxnode(ic, wh); if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { iwm_release_frames(sc, ni, rxba, buffer, nssn, ml); @@ -4958,6 +4958,7 @@ iwm_rx_reorder(struct iwm_softc *sc, struct mbuf *m, int chanidx, if (iwm_is_sn_less(buffer->head_sn, nssn, buffer->buf_size) && (!is_amsdu || last_subframe)) buffer->head_sn = nssn; + ieee80211_release_node(ic, ni); return 0; } @@ -4972,6 +4973,7 @@ iwm_rx_reorder(struct iwm_softc *sc, struct mbuf *m, int chanidx, if (!buffer->num_stored && sn == buffer->head_sn) { if (!is_amsdu || last_subframe) buffer->head_sn = (buffer->head_sn + 1) & 0xfff; + ieee80211_release_node(ic, ni); return 0; } @@ -5027,10 +5029,12 @@ iwm_rx_reorder(struct iwm_softc *sc, struct mbuf *m, int chanidx, if (!is_amsdu || last_subframe) iwm_release_frames(sc, ni, rxba, buffer, nssn, ml); + ieee80211_release_node(ic, ni); return 1; drop: m_freem(m); + ieee80211_release_node(ic, ni); return 1; } |