ifconfig(8) on trying to destroy tap(4) interface used by a process

From: Roman Bogorodskiy <bogorodskiy_at_gmail.com>
Date: Sat, 04 Oct 2025 12:55:58 UTC
Hi,

Accidentally noticed ifconfig(8) and tap(4) behavior that seems strange
to me: when I have a process using tap(4) and call ifconfig(8) destroy
on this interface, ifconfig hangs.

For example, in Python I do:

>>> open('/dev/tap')
<_io.TextIOWrapper name='/dev/tap' mode='r' encoding='UTF-8'>
>>>

And then:

tap1: flags=1008842<BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4080000<LINKSTATE,MEXTPG>
        ether 58:9c:fc:10:5b:26
        groups: tap
        media: Ethernet 1000baseT <full-duplex>
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        Opened by PID 5409
(14:45) novel@tulp:~ %> sudo ifconfig tap1 destroy
load: 0.08  cmd: ifconfig 5620 [tun_condvar] 50.80r 0.00u 0.00s 0% 3576k
mi_switch+0x172 sleepq_switch+0x109 sleepq_catch_signals+0x276 sleepq_wait_sig+0x9 _cv_wait_sig+0x165 tun_destroy+0x96 if_clone_destroyif_flags+0x69 if_clone_destroy+0x100 ifioctl+0xa0a kern_ioctl+0x286 sys_ioctl+0x12f amd64_syscall+0x169 fast_syscall_common+0xf8

ifconfig keeps hanging like that and exits only when the process that
owns the tap(4) interface releases it.

I don't seem to find anything about that in manual pages for both
tap(4) and ifconfig(8) (probably missed something), but generally, I'd
expect ifconfig to immediately exit with an error and non-zero exit
code.

Additionally, while trying to reproduce and document that, I've got a
panic:

FreeBSD tulp 16.0-CURRENT FreeBSD 16.0-CURRENT #6 main-n280778-f45608124286: Tue Sep 30 22:25:58 CEST 2025     root@tulp:/usr/obj/usr/src/amd64.amd64/sys/GENERIC  amd64

panic: deadlres_td_sleep_q: possible deadlock detected for 0xfffff80022425780 (ifconfig), blocked for 1802579 ticks

I was able to reproduce this ifconfig(8) behavior on 14.3-RELEASE-p1
too.

Is it expected?

Thanks,
Roman