qemu/hw/net
Akihiko Odaki 6071d13c6a virtio-net: Fix VLAN filter table reset timing
Problem
-------

The expected initial state of the table depends on feature negotiation:

With VIRTIO_NET_F_CTRL_VLAN:
  The table must be empty in accordance with the specification.
Without VIRTIO_NET_F_CTRL_VLAN:
  The table must be filled to permit all VLAN traffic.

Prior to commit 06b636a1e2 ("virtio-net: do not reset vlan filtering
at set_features"), virtio_net_set_features() always reset the VLAN
table. That commit changed the behavior to skip table reset when
VIRTIO_NET_F_CTRL_VLAN was negotiated, assuming the table would be
properly cleared during device reset and remain stable.

However, this assumption breaks when a driver renegotiates features:
1. Initial negotiation without VIRTIO_NET_F_CTRL_VLAN (table filled)
2. Renegotiation with VIRTIO_NET_F_CTRL_VLAN (table will not be cleared)

The problem was exacerbated by commit 0caed25cd1 ("virtio: Call
set_features during reset"), which triggered virtio_net_set_features()
during device reset, exposing the bug whenever VIRTIO_NET_F_CTRL_VLAN
was negotiated after a device reset.

Solution
--------

Fix the issue by initializing the table when virtio_net_set_features()
is called to change the VIRTIO_NET_F_CTRL_VLAN bit of
vdev->guest_features.

This approach ensures the correct table state regardless of feature
negotiation sequence by performing initialization in
virtio_net_set_features() as QEMU did prior to commit 06b636a1e2
("virtio-net: do not reset vlan filtering at set_features").

This change still preserves the goal of the commit, which was to avoid
resetting the table during migration, by checking whether the
VIRTIO_NET_F_CTRL_VLAN bit of vdev->guest_features is being changed;
vdev->guest_features is set before virtio_net_set_features() gets called
during migration.

It also avoids resetting the table when the driver sets a feature
bitmask with no change for the VIRTIO_NET_F_CTRL_VLAN bit, which makes
the operation idempotent and its semantics cleaner.

Additionally, this change ensures the table is initialized after
feature negotiation and before the DRIVER_OK status bit being set for
compatibility with the Linux driver before commit 50c0ada627f5
("virtio-net: fix race between ndo_open() and virtio_device_ready()"),
which did not ensure to set the DRIVER_OK status bit before modifying
the table.

Fixes: 06b636a1e2 ("virtio-net: do not reset vlan filtering at set_features")
Cc: qemu-stable@nongnu.org
Reported-by: Konstantin Shkolnyy <kshk@linux.ibm.com>
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Tested-by: Konstantin Shkolnyy <kshk@linux.ibm.com>
Tested-by: Lei Yang <leiyang@redhat.com>
Message-Id: <20250727-vlan-v3-1-bbee738619b1@rsg.ci.i.u-tokyo.ac.jp>
Tested-by: Konstantin Shkolnyy <kshk@linux.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2025-08-01 08:33:04 -04:00
..
can qemu: Declare all load/store helper in 'qemu/bswap.h' 2025-07-15 02:56:39 -04:00
fsl_etsec hw/net/fsl_etsec: Set default MAC address 2025-06-10 12:59:09 +02:00
rocker rocker: do not pollute the namespace 2025-05-28 19:00:41 +02:00
allwinner_emac.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
allwinner-sun8i-emac.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
cadence_gem.c hw/net/cadence_gem: fix register mask initialization 2025-07-29 13:56:39 +02:00
dp8393x.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
e1000_common.h e1000: Split header files 2023-03-10 15:35:38 +08:00
e1000_regs.h hw/net: spelling fixes 2023-09-20 07:54:34 +03:00
e1000.c hw/net/e1000: Remove unused E1000_FLAG_MAC flag 2025-05-30 09:52:08 +02:00
e1000e_core.c include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
e1000e_core.h e1000e: fix link state on resume 2024-03-12 19:28:32 +08:00
e1000e.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
e1000x_common.c e1000x: Take CRC into consideration for size check 2023-05-23 15:20:15 +08:00
e1000x_common.h e1000x: Share more Rx filtering logic 2023-05-23 15:20:15 +08:00
e1000x_regs.h hw/net/e1000: Remove stray empty comment in header 2025-05-09 23:49:26 +03:00
eepro100.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
ftgmac100.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
i82596.c hw/net/i82596: Factor configure function out 2025-06-10 15:08:46 +02:00
i82596.h include/system: Move exec/address-spaces.h to system/address-spaces.h 2025-04-23 14:08:21 -07:00
igb_common.h igb: Add a VF reset handler 2023-11-13 15:33:37 +08:00
igb_core.c include: Rename sysemu/ -> system/ 2024-12-20 17:44:56 +01:00
igb_core.h igb: fix link state on resume 2024-03-12 19:28:31 +08:00
igb_regs.h license: Update deprecated SPDX tag GPL-2.0 to GPL-2.0-only 2024-09-20 10:11:59 +03:00
igb.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
igbvf.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
imx_fec.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
Kconfig hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations 2024-12-11 15:30:51 +00:00
lan9118_phy.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
lan9118.c qemu: Declare all load/store helper in 'qemu/bswap.h' 2025-07-15 02:56:39 -04:00
lance.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
lasi_i82596.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
mcf_fec.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
meson.build hw/net: Add NPCM8XX PCS Module 2025-02-20 15:22:22 +00:00
mipsnet.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
msf2-emac.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
mv88w8618_eth.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
ne2000-isa.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
ne2000-pci.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
ne2000.c include/system: Move exec/memory.h to system/memory.h 2025-04-23 14:08:21 -07:00
ne2000.h Include hw/hw.h exactly where needed 2019-08-16 13:31:52 +02:00
net_rx_pkt.c hw/net/net_rx_pkt: Remove deadcode 2024-10-03 17:26:05 +03:00
net_rx_pkt.h hw/net/net_rx_pkt: Remove deadcode 2024-10-03 17:26:05 +03:00
net_tx_pkt.c Revert "hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()" 2025-03-10 17:07:16 +08:00
net_tx_pkt.h igb: Implement Tx SCTP CSO 2023-05-23 15:20:15 +08:00
npcm7xx_emc.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
npcm_gmac.c hw/net/npcm_gmac.c: Drop 'buf' local variable 2025-07-21 10:21:51 +08:00
npcm_pcs.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
opencores_eth.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
pcnet-pci.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
pcnet.c Avoid unaligned fetch in ladr_match() 2024-03-12 19:28:32 +08:00
pcnet.h include/system: Move exec/memory.h to system/memory.h 2025-04-23 14:08:21 -07:00
rtl8139.c qemu: Declare all load/store helper in 'qemu/bswap.h' 2025-07-15 02:56:39 -04:00
smc91c111.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
spapr_llan.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
stellaris_enet.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
sungem.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
sunhme.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
trace-events hw/net: Add NPCM8XX PCS Module 2025-02-20 15:22:22 +00:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
tulip.c hw/net/tulip: skip automatic zero-init of large array 2025-06-12 13:40:15 -04:00
tulip.h Use OBJECT_DECLARE_SIMPLE_TYPE when possible 2020-09-18 14:12:32 -04:00
vhost_net-stub.c net: Add save_acked_features callback to vhost_net 2025-07-14 13:27:09 +08:00
vhost_net.c net: Add is_vhost_user flag to vhost_net struct 2025-07-14 13:27:09 +08:00
virtio-net.c virtio-net: Fix VLAN filter table reset timing 2025-08-01 08:33:04 -04:00
vmware_utils.h hw/net/vmxnet3: Fix code to work on big endian hosts, too 2017-11-20 11:08:00 +08:00
vmxnet3_defs.h include/hw/pci: Split pci_device.h off pci.h 2023-01-08 01:54:22 -05:00
vmxnet3.c qemu: Declare all load/store helper in 'qemu/bswap.h' 2025-07-15 02:56:39 -04:00
vmxnet3.h hw: replace FSF postal address with licenses URL 2025-06-26 00:42:37 +02:00
vmxnet_debug.h Clean up ill-advised or unusual header guards 2016-07-12 16:20:46 +02:00
xen_nic.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00
xgmac.c hw/net/xgamc: skip automatic zero-init of large array 2025-06-12 13:40:16 -04:00
xilinx_axienet.c qom: Make InterfaceInfo[] uses const 2025-04-25 17:00:41 +02:00
xilinx_ethlite.c qom: Have class_init() take a const data argument 2025-04-25 17:00:41 +02:00