# DF-3430 — ieee80211_create_wds "in use" branch leaks node reference

## Severity: Low | Analysis pack (Phase V skipped for Low per audit policy)

## The bug
`ieee80211_find_node_locked()` returns the node with a **+1 reference**
(`sys/netproto/802_11/wlan/ieee80211_node.c:1391`, `ieee80211_ref_node`).
`ieee80211_create_wds` (`sys/netproto/802_11/wlan/ieee80211_wds.c:149-188`)
consumes that reference only in the success branch (`vap->iv_bss = ni`,
`:181`). In the `ni->ni_wdsvap != NULL` branch ("station in use",
`:163-175`) it merely DPRINTFs — the reference is never dropped:
permanent +1 refcount inflation of the station node.

Consequences: the node can never be reclaimed by `node_reclaim` (refcount
never reaches 0); it stays in `ic_sta` (and its hash bucket) until reboot.
Each leak also keeps the node's key state, rates etc. resident. Repeated
triggering (see below) pollutes the table unboundedly.

## Trigger
Two WDS vaps with the same `iv_des_bssid` pointing at one associated
station (management daemon races / misconfig): each INIT→RUN transition of
the vap that loses the hookup leaks one reference; alternating up/down
cycles of the two vaps repeats it (down clears `ni_wdsvap` via
`ieee80211_node.c:2004-2010`'s second pass, re-arming the "in use" branch).

## Upstream
FreeBSD HEAD `sys/net80211/ieee80211_wds.c:161-167` — identical branch,
identical leak (verified 2026-09-12). Inherited defect.

## Fix
Drop the reference in the "in use" branch: `ieee80211_free_node(ni);`
(inside the lock is fine — `free_node` handles it, as used elsewhere under
NODE_LOCK; or defer after unlock like obss). See fix.diff.

## Verdict
`untested` — Low severity (requires root to plumb the vaps; slow
exhaustion, no memory unsafety), Phase V skipped per policy; and the QEMU
guest has no 802.11 radio to build vaps on anyway.
