# DF-3400 — ipfw3 NAT delete leaks every nat_state2 (and icmp_in overwrite never frees)

## What

`sys/net/ipfw3_nat/ip_fw3_nat.c:806-842` (`nat_del_dispatch`): the
loops that were supposed to free the per-alias `nat_state2` entries
(`tcp_in[]`, `udp_in[]`, `icmp_in[]`) are **commented out** — only the
RB-tree `nat_state`s are freed before `kfree(alias)`/`kfree(nat)`:

```c
/*
LIST_FOREACH_MUTABLE(s2, &nat->alias->icmp_in, next, tmp2) { ... }
*/
```

Every `nat_state2` created while the NAT was active (one per flow per
direction; up to 3 × 64511 per alias) is leaked on
`ipfw3 nat N delete` / `ipfw3 nat flush` / module unload. The daily
cleanup callout frees expired s2s only while the NAT still exists
(`:948-996`); deleting the NAT first strands them all.

Additionally `:326`'s store (`alias->icmp_in[s->alias_port] = s2`)
overwrites any previous s2 at the same residue without freeing it
(two internal hosts whose `src*dst` collide) — a slow steady leak
even without deletes.

## Impact

Kernel heap leak owned entirely by root configuration churn + traffic:
`add → traffic → delete` cycles leak `28 B × states`. Unbounded with
repeated reconfiguration. Low severity (root-gated), certainty: certain
from code; not verified on the guest (Low → Phase V skipped per
contract).

## Fix

Uncomment/rewrite the s2 free loops in `nat_del_dispatch` to walk
`alias->{tcp,udp,icmp}_in[]` and `kfree` every non-NULL entry before
freeing the alias, and free the displaced s2 when overwriting a
non-NULL `icmp_in` slot at `:326`.
