DF-3429 / fix.diff
--- a/sys/netproto/802_11/wlan/ieee80211_node.c +++ b/sys/netproto/802_11/wlan/ieee80211_node.c @@ -2233,6 +2233,7 @@ ieee80211_node_timeout(void *arg) void ieee80211_node_timeout(void *arg) { struct ieee80211com *ic = arg; + struct mbuf *m; /* * Defer timeout processing if a channel switch is pending. @@ -2251,7 +2252,16 @@ ieee80211_node_timeout(void *arg) */ if ((ic->ic_flags & IEEE80211_F_CSAPENDING) == 0) { ieee80211_scan_timeout(ic); ieee80211_timeout_stations(ic); - ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT); + /* + * DF-3429: ieee80211_ageq_age() REMOVES expired frames + * from the stage queue and returns them as an + * m_nextpkt-joined list for the caller to reclaim. + * Dropping the return value leaks every expired DWDS + * discovery frame (mbuf + cluster) staged by + * ieee80211_dwds_discover(). + */ + m = ieee80211_ageq_age(&ic->ic_stageq, IEEE80211_INACT_WAIT); + if (m != NULL) + ieee80211_ageq_mfree(m); IEEE80211_LOCK(ic); ieee80211_erp_timeout(ic); |