Scenario
Su un server Debian GNU/Linux 11 Bullseye con kernel 5.10.0-38-amd64 avevo una configurazione abbastanza classica per un host KVM/QEMU:
eno1 -> br0 -> VM
La macchina aveva IP statico sulla LAN 192.168.50.0/24:
- server:
192.168.50.23 - gateway/router:
192.168.50.254 - DNS locale Pi-hole:
192.168.50.10
Il bridge usato dalle VM era br0. La scheda fisica integrata era eno1, gestita dal driver e1000e.
Il problema era semplice da vedere ma meno simpatico da subire: ogni tanto la rete cadeva, poi tornava su. Questo impattava sia l’host sia le VM, perche’ eno1 era la porta fisica del bridge.
Il sintomo nei log
Il primo controllo utile e’ stato guardare i messaggi del kernel legati alla scheda di rete:
sudo dmesg -T | egrep -i "e1000e|tx unit hang|watchdog|reset|hang|netdev"
L’estratto piu’ interessante era questo:
[Sun Feb 22 21:01:27 2026] e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
[Sun Feb 22 21:01:29 2026] e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
[Sun Feb 22 21:01:31 2026] e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
[Sun Feb 22 21:01:32 2026] NETDEV WATCHDOG: eno1 (e1000e): transmit queue 0 timed out
[Sun Feb 22 21:01:32 2026] WARNING: CPU: 10 PID: 0 at net/sched/sch_generic.c:470 dev_watchdog+0x260/0x270
[Sun Feb 22 21:01:32 2026] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly
[Sun Feb 22 21:01:32 2026] br0: topology change detected, propagating
[Sun Feb 22 21:01:36 2026] e1000e 0000:00:1f.6 eno1: NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
Qui la parte importante non e’ br0. La sequenza dice altro:
Detected Hardware Unit Hangindica che la scheda, o il driver che la gestisce, si blocca.NETDEV WATCHDOG: transmit queue 0 timed outindica un timeout della coda di trasmissione.Reset adapter unexpectedlyindica che il driver ha resettato la NIC.br0: topology change detected, propagatinge’ una conseguenza: il bridge vede la porta fisica cadere e tornare su.
Con bridge_stp on, il bridge propaga il cambio di topologia. Quella riga quindi non era la causa principale. STP stava reagendo a un evento sulla porta fisica.
In altre parole: il problema non era KVM, non era QEMU e non era br0. Il problema era eno1, con driver e1000e, che andava in hang e veniva resettata.
La stessa cosa si e’ ripetuta anche nei giorni successivi:
[Mon Feb 23 07:58:10 2026] e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
[Mon Feb 23 07:58:14 2026] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly
[Mon Feb 23 07:58:14 2026] br0: topology change detected, propagating
[Tue Feb 24 08:49:30 2026] e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang:
[Tue Feb 24 08:49:33 2026] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly
[Tue Feb 24 08:49:34 2026] br0: topology change detected, propagating
[Sat Mar 14 14:11:26 2026] e1000e 0000:00:1f.6 eno1: Reset adapter unexpectedly
[Sat Mar 14 14:11:26 2026] br0: topology change detected, propagating
La configurazione iniziale
La configurazione in /etc/network/interfaces era questa:
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto eno1
iface eno1 inet manual
auto br0
iface br0 inet static
address 192.168.50.23
network 192.168.50.0
netmask 255.255.255.0
broadcast 192.168.50.255
gateway 192.168.50.254
bridge_ports eno1
bridge_stp on
bridge_fd 0
bridge_hello 2
bridge_maxage 12
bridge_maxwait 0
La riga chiave era:
bridge_ports eno1
Significava che eno1 era la porta fisica del bridge br0. Quindi, quando eno1 si resettava, il bridge perdeva e riacquisiva la sua porta verso la rete fisica. Le VM non dovevano essere modificate: il punto debole era sotto di loro, nel collegamento fisico.
Perche’ il bridge non era il problema
In un host KVM/QEMU con bridge, le VM usano br0 come se fossero collegate alla stessa rete dell’host.
La regola pratica e’ questa:
corretto:
scheda fisica senza IP -> br0 con IP -> VM
sbagliato:
scheda fisica con IP + bridge separato
La scheda fisica non deve avere un IP proprio. Deve essere solo una porta del bridge. L’IP del server resta su br0.
Nel mio caso l’obiettivo era cambiare solo la porta fisica:
prima:
eno1 -> br0 -> VM
dopo:
lanusb0 -> br0 -> VM
Rilevamento della nuova USB Ethernet Realtek 2.5G
Ho collegato una scheda USB Ethernet Realtek 2.5G. Nei log e’ apparsa cosi':
usb 1-4: Product: USB 10/100/1G/2.5G LAN
usb 1-4: Manufacturer: Realtek
cdc_ncm 1-4:2.0: MAC-Address: 02:42:ac:32:00:25
cdc_ncm 1-4:2.0 enx0242ac320025: renamed from eth0
Il nome iniziale assegnato dal sistema era:
enx0242ac320025
Il MAC era:
02:42:ac:32:00:25
Con ip a la scheda risultava su e aveva preso un IP temporaneo via DHCP:
enx0242ac320025: <BROADCAST,MULTICAST,UP,LOWER_UP>
inet 192.168.50.84/24
Questo IP serviva solo per verificare che link e cavo funzionassero. Nella configurazione finale l’IP non deve stare sulla scheda fisica, ma su br0.
Ho controllato anche il link:
ethtool enx0242ac320025
Output rilevante:
Link detected: yes
Nome stabile per la nuova scheda
Il nome enx0242ac320025 funziona, ma e’ scomodo da leggere e da usare dentro una configurazione stabile. Ho quindi assegnato un nome prevedibile alla scheda, basandomi sul suo MAC address.
Ho creato il file:
nano /etc/systemd/network/10-lanusb0.link
Con questo contenuto:
[Match]
MACAddress=02:42:ac:32:00:25
[Link]
Name=lanusb0
Questo dice a systemd/udev: quando trovi una scheda con MAC 02:42:ac:32:00:25, chiamala lanusb0.
Prima di cambiare la configurazione di rete, ho verificato che il file venisse riconosciuto:
udevadm test-builtin net_setup_link /sys/class/net/enx0242ac320025 2>/dev/null | grep -E 'Config file|ID_NET_NAME|lanusb0'
Output:
ID_NET_LINK_FILE=/etc/systemd/network/10-lanusb0.link
Backup della configurazione
Prima di toccare /etc/network/interfaces, backup semplice:
cp /etc/network/interfaces /etc/network/interfaces.bak
Nuova configurazione di rete
La nuova configurazione di /etc/network/interfaces sostituisce eno1 con lanusb0 come porta fisica del bridge:
source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto lanusb0
iface lanusb0 inet manual
auto br0
iface br0 inet static
address 192.168.50.23
network 192.168.50.0
netmask 255.255.255.0
broadcast 192.168.50.255
gateway 192.168.50.254
bridge_ports lanusb0
bridge_stp on
bridge_fd 0
bridge_hello 2
bridge_maxage 12
bridge_maxwait 0
Riga per riga, la parte importante e’ questa:
auto loeiface lo inet loopbacksono la loopback e restano sempre.auto lanusb0porta su la nuova scheda.iface lanusb0 inet manualdice che la scheda fisica non deve avere IP proprio.bridge_ports lanusb0mette la nuova scheda dentrobr0.- l’IP statico resta su
br0. eno1viene rimossa perche’ non deve piu’ essere usata.
Riavvio
Su un server remoto non conviene fare esperimenti aggressivi tipo:
ifdown br0 && ifup br0
Se qualcosa va storto, ci si taglia fuori via SSH.
La strada piu’ prudente e’ stata riavviare, lasciando collegati entrambi i cavi al primo boot:
reboot
Dopo aver verificato che tutto funzionasse tramite lanusb0, ho scollegato fisicamente il cavo da eno1, lasciandola come eventuale backup.
Verifica dopo il reboot
Dopo il riavvio ho controllato stato delle interfacce e bridge:
ip a
brctl show
bridge link
Output rilevante:
3: lanusb0: <BROADCAST,MULTICAST,UP,LOWER_UP> master br0 state UP
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP>
inet 192.168.50.23/24
E il bridge:
bridge name bridge id STP enabled interfaces
br0 8000.0242ac320025 yes lanusb0
vnet0
vnet1
vnet2
Questo conferma tre cose importanti:
lanusb0e’ dentrobr0.br0ha ancora l’IP statico192.168.50.23.vnet0,vnet1evnet2sono ancora dentrobr0.
Le VM continuano quindi a funzionare senza modifiche. L’unica cosa cambiata e’ la porta fisica usata dal bridge.
Problema DNS dopo il cambio
Dopo il cambio di cavo e scheda, la rete IP funzionava, ma il DNS no.
Sintomo:
ping google.com
Output:
ping: google.com: Name or service not known
Il file /etc/resolv.conf era:
# Generated by NetworkManager
Nel mio caso il DNS locale e’ Pi-hole:
192.168.50.10
Il router e':
192.168.50.254
Fix immediato, usando solo Pi-hole:
printf "nameserver 192.168.50.10\n" > /etc/resolv.conf
Oppure, con router come fallback:
printf "nameserver 192.168.50.10\nnameserver 192.168.50.254\n" > /etc/resolv.conf
Se si vuole che tutto passi sempre da Pi-hole, ha senso usare solo 192.168.50.10. Se invece si preferisce avere un fallback, si puo’ aggiungere anche 192.168.50.254.
Nel blocco br0 si puo’ aggiungere:
dns-nameservers 192.168.50.10
Oppure:
dns-nameservers 192.168.50.10 192.168.50.254
NetworkManager
Ho controllato anche NetworkManager:
nmcli device status
systemctl is-active NetworkManager
Output:
DEVICE TYPE STATE CONNECTION
br0 bridge connected (externally) br0
vnet0 tun connected (externally) vnet0
vnet1 tun connected (externally) vnet1
vnet2 tun connected (externally) vnet2
eno1 ethernet unavailable --
lanusb0 ethernet unmanaged --
lo loopback unmanaged --
NetworkManager era active, ma br0 risultava connected (externally). Questo significa che br0 e’ gestito da /etc/network/interfaces.
Anche lanusb0 come unmanaged e’ corretto: non deve essere gestita direttamente da NetworkManager, perche’ e’ solo la porta fisica del bridge.
Driver della Realtek USB 2.5G
La scheda Realtek 2.5G e’ stata vista come device USB:
idVendor=0bda, idProduct=8156
Su Debian 11 con kernel 5.10 e’ stata usata con cdc_ncm.
Controllo moduli:
lsmod | egrep 'r8152|cdc_ncm|cdc_ether'
Output:
cdc_ncm 53248 1 cdc_mbim
cdc_ether 24576 1 cdc_ncm
usbnet 53248 3 cdc_mbim,cdc_ncm,cdc_ether
Ho verificato anche r8152:
modinfo r8152
Il modulo r8152 era presente, ma vecchio:
r8152 version v1.11.11
Su Debian 11, con kernel 5.10, quel modulo non includeva l’alias per 0bda:8156. Per questo non l’ho forzato.
La rete fisica, in questo caso, e’ a 1 Gbit. Per ora cdc_ncm va bene. Se in futuro servisse usare davvero i 2.5G, oppure se comparissero problemi di stabilita’, valuterei prima un kernel piu’ recente o un upgrade di Debian, invece di installare driver esterni.
Controlli dopo la migrazione
Per controllare eventuali reset, disconnessioni o problemi di carrier:
journalctl -k -b | grep -i -E 'lanusb0|cdc_ncm|usbnet|realtek|reset|disconnect|carrier|link'
Oppure:
dmesg -T | grep -i -E 'lanusb0|cdc_ncm|usbnet|realtek|reset|disconnect|carrier|link'
Per seguire i log live:
journalctl -k -f | grep -i -E 'lanusb0|cdc_ncm|usbnet|realtek|reset|disconnect|link|carrier'
E per guardare le statistiche delle interfacce:
ip -s link show lanusb0
ip -s link show br0
Qui conviene controllare soprattutto:
errorsdroppedoverrunscarrier
Se questi contatori restano puliti e non compaiono reset nei log, la migrazione ha fatto il suo lavoro.
Conclusione
Il problema era causato dalla scheda integrata eno1 o dal suo driver e1000e.
Gli errori chiave erano:
Detected Hardware Unit Hang
NETDEV WATCHDOG
Reset adapter unexpectedly
Siccome eno1 era la porta fisica del bridge, ogni reset impattava br0 e quindi sia l’host sia le VM.
La soluzione e’ stata sostituire la porta fisica del bridge con lanusb0, lasciando invariati IP, bridge e configurazione delle VM:
lanusb0 = porta fisica senza IP
br0 = interfaccia principale con IP 192.168.50.23
In pratica, il bridge non e’ stato “riparato”. E’ stata tolta dal bridge la porta instabile.
Usa i pulsanti qui sotto se ti è piaciuto.
Il tuo click è il mio high-five virtuale.