NetBSD Problem Report #60056
From martin@duskware.de Wed Mar 4 14:42:33 2026
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "R13" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 3250E1A9239
for <gnats-bugs@gnats.NetBSD.org>; Wed, 4 Mar 2026 14:42:33 +0000 (UTC)
Message-Id: <20260304144230.0723EE1FFD0@mail.duskware.de>
Date: Wed, 04 Mar 2026 15:42:24 +0100 (CET)
From: martin@NetBSD.org
Reply-To: martin@NetBSD.org
To: gnats-bugs@NetBSD.org
Subject: tap(4) loses carrier randomly
X-Send-Pr-Version: 3.95
X-From4GNATS: "martin@NetBSD.org via gnats" <gnats-admin@NetBSD.org>
>Number: 60056
>Category: kern
>Synopsis: tap(4) loses carrier randomly
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 04 14:45:00 +0000 2026
>Last-Modified: Thu May 07 18:20:01 +0000 2026
>Originator: Martin Husemann
>Release: NetBSD 11.99.5
>Organization:
The NetBSD Foundation, Inc.
>Environment:
System: NetBSD seven-days-to-the-wolves.aprisoft.de 11.99.5 NetBSD 11.99.5 (GENERIC) #849: Wed Mar 4 10:02:57 CET 2026 martin@seven-days-to-the-wolves.aprisoft.de:/work/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
I have a version of the uae (amiga emulator) that runs my virtual NetBSD/amiga
machine.
The uae process opens /dev/tap0 to access my host network.
Before I start uae, I run this as root:
---8<---
ifconfig tap0 create up
ifconfig bridge0 create up
brconfig bridge0 add re0
brconfig bridge0 add tap0
chown martin:users /dev/tap0
--->8---
When the virtual amiga boots, I initially have working network. After a while
though tap0 starts flapping the carrier status (w/o any reason I see).
root@seven-days-to-the-wolves # fstat -p 1678 ; ifconfig tap0
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
martin uae 1678 wd / 16642980 drwxr-xr-x 512 r
martin uae 1678 0 /dev/pts 9 crw--w---- pts/3 rw
martin uae 1678 1 /dev/pts 9 crw--w---- pts/3 rw
martin uae 1678 2 /dev/pts 9 crw--w---- pts/3 rw
martin uae 1678 3 / 3750038 crw------- tap0 rw
martin uae 1678 4 / 16642994 -rw-r--r-- 8589934592 rw
martin uae 1678 5 / 16642995 -rw-r--r-- 8589934592 rw
martin uae 1678 6* internet stream tcp *:vnc-server
martin uae 1678 7* internet6 stream tcp *:vnc-server
tap0: flags=0x8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
ec_capabilities=0x5<VLAN_MTU,JUMBO_MTU>
ec_enabled=0x1<VLAN_MTU>
address: f2:0b:a4:f1:11:21
status: no carrier
inet6 fe80::f00b:a4ff:fef1:1121%tap0/64 flags 0x8<DETACHED> scopeid 0x21b
So despite /dev/tap0 still being open, carrier is lost.
I think this should not happen :-)
It used to work quite stable (but I am not sure when exactly this started
happening).
>How-To-Repeat:
s/a
>Fix:
n/a
>Audit-Trail:
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/60056: tap(4) loses carrier randomly
Date: Fri, 17 Apr 2026 17:39:28 +0200
I looked at ktrace output from the emulator and tried to build
do the same in simple code.
I can reproduce it -- but not without gdb interaction. Something magic
going on.
Compile the code below with: cc -O2 -g -Wall pr60056.c
Prepare the tap as described in the original PR.
Then do:
Reading symbols from ./a.out...
(gdb) break 35
Breakpoint 1 at 0x4015ce: file pr60056.c, line 35.
(gdb) run 3
Starting program: /tmp/a.out 3
opening /dev/tap0...
... and closing it again
Breakpoint 1, main (argc=<optimized out>, argv=<optimized out>) at pr60056.c:35
35 close(dev);
check status: ifconfig tap0 | fgrep status:
status: active
now remove the breakpoint and continue:
(gdb) delete 1
(gdb) c
Continuing.
opening /dev/tap0...
... and closing it again
opening /dev/tap0...
... and closing it again
finally opening it for real!
waiting, check carrier
and check carrier status again:
ifconfig tap0 | fgrep status:
status: no carrier
but it should be active!
I have not managed to create a reproducer w/o the gdb interaction.
Martin
/*
* minimal reproducer for
* https://gnats.netbsd.org/60056
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define DEVICE "/dev/tap0"
int main(int argc, char **argv)
{
if (argc < 2)
return 1;
int others[3];
int cnt = atoi(argv[1]);
int dev;
for (int i = 0; i < cnt; i++) {
if (i == 0) {
for (size_t j = 0; j <
sizeof(others)/sizeof(others[0]); j++)
others[j] = open("/dev/zero", O_RDONLY);
}
printf("opening %s...\n", DEVICE);
dev = open(DEVICE, O_RDWR|O_NONBLOCK);
if (dev == -1)
return 1;
printf("... and closing it again\n");
close(dev);
if (i == 0) {
for (size_t j = 0; j <
sizeof(others)/sizeof(others[0]); j++)
close(others[j]);
}
}
printf("finally opening it for real!\n");
dev = open(DEVICE, O_RDWR|O_NONBLOCK);
printf("waiting, check carrier\n");
sleep(20);
printf("terminating...");
return 0;
}
From: Roy Marples <roy@marples.name>
To: "gnats-bugs" <gnats-bugs@netbsd.org>
Cc: "Martin Husemann" <martin@duskware.de>
Subject: Re: kern/60056: tap(4) loses carrier randomly
Date: Mon, 20 Apr 2026 22:46:07 +0100
------=_Part_3300106_1681026036.1776721567631
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
The patch here should fix it: https://mollari.netbsd.org/~roy/if_link.patch
Note that the field if_link_scheduled in ifnet is now unused and should be removed in another commit so we can easily port this change to -10 or -11 if needed.
Roy
------=_Part_3300106_1681026036.1776721567631
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta content="text/html;charset=UTF-8" http-equiv="Content-Type"></head><body ><div style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt;">The patch here should fix it:<a target="_blank" href="https://mollari.netbsd.org/~roy/if_link.patch">https://mollari.netbsd.org/~roy/if_link.patch</a><br><br><div>Note that the field if_link_scheduled in ifnet is now unused and should be removed in another commit so we can easily port this change to -10 or -11 if needed.<br></div><div><br></div><div>Roy</div></div><br></body></html>
------=_Part_3300106_1681026036.1776721567631--
From: "Roy Marples" <roy@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60056 CVS commit: src/sys/net
Date: Tue, 5 May 2026 10:23:34 +0000
Module Name: src
Committed By: roy
Date: Tue May 5 10:23:34 UTC 2026
Modified Files:
src/sys/net: if.c if.h
Log Message:
if: replace link state change queue with state transition
if_link_queue is now a normal bitmask rather than holding a queue.
It holds three bits to mirror the link state - UNKNOWN, DOWN and UP.
There are also some bits to indicate that the link state has been scheduled
for change and if it has been locked for changes (ie the interface being
destroyed).
The logic is simple - transitioning to DOWN will remove UNKNOWN and UP,
transitioning to UNKNOWN will remove UP (no driver should do this).
This means that even in the event of transitions happening faster than
the kernel can spit them out, the correct state of the link will be
preserved which is more important than the exact chain of events.
This also fixes an issue where the workqueue for the link state change
was incorrectly scheduled.
if_link_scheduled is now unused and will be removed in a future patch.
Fixes PR kern/60056.
To generate a diff of this commit:
cvs rdiff -u -r1.536 -r1.537 src/sys/net/if.c
cvs rdiff -u -r1.309 -r1.310 src/sys/net/if.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60056 CVS commit: [netbsd-11] src/sys/net
Date: Thu, 7 May 2026 18:17:32 +0000
Module Name: src
Committed By: martin
Date: Thu May 7 18:17:32 UTC 2026
Modified Files:
src/sys/net [netbsd-11]: if.c if.h
Log Message:
Pull up following revision(s) (requested by roy in ticket #278):
sys/net/if.c: revision 1.537
sys/net/if.h: revision 1.310
if: replace link state change queue with state transition
if_link_queue is now a normal bitmask rather than holding a queue.
It holds three bits to mirror the link state - UNKNOWN, DOWN and UP.
There are also some bits to indicate that the link state has been scheduled
for change and if it has been locked for changes (ie the interface being
destroyed).
The logic is simple - transitioning to DOWN will remove UNKNOWN and UP,
transitioning to UNKNOWN will remove UP (no driver should do this).
This means that even in the event of transitions happening faster than
the kernel can spit them out, the correct state of the link will be
preserved which is more important than the exact chain of events.
This also fixes an issue where the workqueue for the link state change
was incorrectly scheduled.
if_link_scheduled is now unused and will be removed in a future patch.
Fixes PR kern/60056.
To generate a diff of this commit:
cvs rdiff -u -r1.535 -r1.535.2.1 src/sys/net/if.c
cvs rdiff -u -r1.308 -r1.308.2.1 src/sys/net/if.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.