When a struct ifnet goes away it's possible that dummynet will still
have packets queued for it. We must purge those to ensure we do not
attempt to send packets out a removed interface.
This scenario is triggered by the dummynet:ipfw_queue_v6 test and looks
like:
Fatal trap 9: general protection fault while in kernel mode
cpuid = 0; apic id = 00
instruction pointer = 0x20:0xffffffff80e33df6
stack pointer = 0x28:0xfffffe0148d1c170
frame pointer = 0x28:0xfffffe0148d1c240
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 0 (dummynet)
trap number = 9
panic: general protection fault
cpuid = 0
time = 1625664777
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0148d1be70
vpanic() at vpanic+0x187/frame 0xfffffe0148d1bed0
panic() at panic+0x43/frame 0xfffffe0148d1bf30
trap_fatal() at trap_fatal+0x387/frame 0xfffffe0148d1bf90
trap() at trap+0xa4/frame 0xfffffe0148d1c0a0
calltrap() at calltrap+0x8/frame 0xfffffe0148d1c0a0
- trap 0x9, rip = 0xffffffff80e33df6, rsp = 0xfffffe0148d1c170, rbp = 0xfffffe0148d1c240 ---
ip6_input() at ip6_input+0x46/frame 0xfffffe0148d1c240
netisr_dispatch_src() at netisr_dispatch_src+0xb1/frame 0xfffffe0148d1c2a0
dummynet_send() at dummynet_send+0x1dd/frame 0xfffffe0148d1c2e0
dummynet_task() at dummynet_task+0x49c/frame 0xfffffe0148d1c380
taskqueue_run_locked() at taskqueue_run_locked+0xaa/frame 0xfffffe0148d1c400
taskqueue_thread_loop() at taskqueue_thread_loop+0xc2/frame 0xfffffe0148d1c430
fork_exit() at fork_exit+0x80/frame 0xfffffe0148d1c470
fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0148d1c470
- trap 0, rip = 0, rsp = 0, rbp = 0 ---
KDB: enter: panic
On interface removal scan through the dummynet packet queues and remove
any packet destined for the removed interface.
Sponsored by: Rubicon Communications, LLC ("Netgate")