You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
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>
1 week ago
..
can qemu: Declare all load/store helper in 'qemu/bswap.h' 4 weeks ago
fsl_etsec hw/net/fsl_etsec: Set default MAC address 2 months ago
rocker rocker: do not pollute the namespace 3 months ago
Kconfig hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations 8 months ago
allwinner-sun8i-emac.c qom: Have class_init() take a const data argument 4 months ago
allwinner_emac.c qom: Have class_init() take a const data argument 4 months ago
cadence_gem.c hw/net/cadence_gem: fix register mask initialization 2 weeks ago
dp8393x.c qom: Have class_init() take a const data argument 4 months ago
e1000.c hw/net/e1000: Remove unused E1000_FLAG_MAC flag 2 months ago
e1000_common.h e1000: Split header files 2 years ago
e1000_regs.h hw/net: spelling fixes 2 years ago
e1000e.c qom: Make InterfaceInfo[] uses const 4 months ago
e1000e_core.c include: Rename sysemu/ -> system/ 8 months ago
e1000e_core.h e1000e: fix link state on resume 1 year ago
e1000x_common.c e1000x: Take CRC into consideration for size check 2 years ago
e1000x_common.h e1000x: Share more Rx filtering logic 2 years ago
e1000x_regs.h hw/net/e1000: Remove stray empty comment in header 3 months ago
eepro100.c qom: Make InterfaceInfo[] uses const 4 months ago
ftgmac100.c qom: Have class_init() take a const data argument 4 months ago
i82596.c hw/net/i82596: Factor configure function out 2 months ago
i82596.h include/system: Move exec/address-spaces.h to system/address-spaces.h 4 months ago
igb.c qom: Make InterfaceInfo[] uses const 4 months ago
igb_common.h igb: Add a VF reset handler 2 years ago
igb_core.c include: Rename sysemu/ -> system/ 8 months ago
igb_core.h igb: fix link state on resume 1 year ago
igb_regs.h license: Update deprecated SPDX tag GPL-2.0 to GPL-2.0-only 11 months ago
igbvf.c qom: Make InterfaceInfo[] uses const 4 months ago
imx_fec.c qom: Have class_init() take a const data argument 4 months ago
lan9118.c qemu: Declare all load/store helper in 'qemu/bswap.h' 4 weeks ago
lan9118_phy.c qom: Have class_init() take a const data argument 4 months ago
lance.c qom: Have class_init() take a const data argument 4 months ago
lasi_i82596.c qom: Have class_init() take a const data argument 4 months ago
mcf_fec.c qom: Have class_init() take a const data argument 4 months ago
meson.build hw/net: Add NPCM8XX PCS Module 6 months ago
mipsnet.c qom: Have class_init() take a const data argument 4 months ago
msf2-emac.c qom: Have class_init() take a const data argument 4 months ago
mv88w8618_eth.c qom: Have class_init() take a const data argument 4 months ago
ne2000-isa.c qom: Have class_init() take a const data argument 4 months ago
ne2000-pci.c qom: Make InterfaceInfo[] uses const 4 months ago
ne2000.c include/system: Move exec/memory.h to system/memory.h 4 months ago
ne2000.h Include hw/hw.h exactly where needed 6 years ago
net_rx_pkt.c hw/net/net_rx_pkt: Remove deadcode 10 months ago
net_rx_pkt.h hw/net/net_rx_pkt: Remove deadcode 10 months ago
net_tx_pkt.c Revert "hw/net/net_tx_pkt: Fix overrun in update_sctp_checksum()" 5 months ago
net_tx_pkt.h igb: Implement Tx SCTP CSO 2 years ago
npcm7xx_emc.c qom: Have class_init() take a const data argument 4 months ago
npcm_gmac.c hw/net/npcm_gmac.c: Drop 'buf' local variable 3 weeks ago
npcm_pcs.c qom: Have class_init() take a const data argument 4 months ago
opencores_eth.c qom: Have class_init() take a const data argument 4 months ago
pcnet-pci.c qom: Make InterfaceInfo[] uses const 4 months ago
pcnet.c Avoid unaligned fetch in ladr_match() 1 year ago
pcnet.h include/system: Move exec/memory.h to system/memory.h 4 months ago
rtl8139.c qemu: Declare all load/store helper in 'qemu/bswap.h' 4 weeks ago
smc91c111.c qom: Have class_init() take a const data argument 4 months ago
spapr_llan.c qom: Have class_init() take a const data argument 4 months ago
stellaris_enet.c qom: Have class_init() take a const data argument 4 months ago
sungem.c qom: Make InterfaceInfo[] uses const 4 months ago
sunhme.c qom: Make InterfaceInfo[] uses const 4 months ago
trace-events hw/net: Add NPCM8XX PCS Module 6 months ago
trace.h trace: switch position of headers to what Meson requires 5 years ago
tulip.c hw/net/tulip: skip automatic zero-init of large array 2 months ago
tulip.h Use OBJECT_DECLARE_SIMPLE_TYPE when possible 5 years ago
vhost_net-stub.c net: Add save_acked_features callback to vhost_net 4 weeks ago
vhost_net.c net: Add is_vhost_user flag to vhost_net struct 4 weeks ago
virtio-net.c virtio-net: Fix VLAN filter table reset timing 1 week ago
vmware_utils.h hw/net/vmxnet3: Fix code to work on big endian hosts, too 8 years ago
vmxnet3.c qemu: Declare all load/store helper in 'qemu/bswap.h' 4 weeks ago
vmxnet3.h hw: replace FSF postal address with licenses URL 2 months ago
vmxnet3_defs.h include/hw/pci: Split pci_device.h off pci.h 3 years ago
vmxnet_debug.h Clean up ill-advised or unusual header guards 9 years ago
xen_nic.c qom: Have class_init() take a const data argument 4 months ago
xgmac.c hw/net/xgamc: skip automatic zero-init of large array 2 months ago
xilinx_axienet.c qom: Make InterfaceInfo[] uses const 4 months ago
xilinx_ethlite.c qom: Have class_init() take a const data argument 4 months ago