Hi all, br_vlan_fill_vids() encodes per-VLAN state, tunnel ID, neighbour flags and multicast context from one v_opts, so every option must be equal across a range. The dump/options paths enforce that through br_vlan_can_enter_range(), but the old-style br_process_vlan_info() range loop only checks whether the request changed PVID/UNTAGGED on each VID.
The old path can therefore merge adjacent VIDs whose state or tunnel id differs and emit one range carrying the start VID's options. The notification then describes a VLAN map that the kernel does not have. Observed on Linux v7.3, commit 08ab31164c55f20c7a2653de3186ae333470e2c1. VID 10 was FORWARDING and VID 11 was BLOCKING. An old-style RTM_SETLINK range request changed UNTAGGED on both VIDs: one RTM_NEWVLAN: vid=10 range=11 state=FORWARDING dump: vid=10 state=FORWARDING dump: vid=11 state=BLOCKING The notification tells listeners that VID 11 is FORWARDING even though the kernel database keeps it BLOCKING. The old range path must run the same option-equality check per VID or emit separate notifications. The February 2026 expansion of br_vlan_opts_eq_range() for neighbour/multicast fields did not add this missing call; I found no matching fix or CVE. The PoC and program/console logs are available on request. This was found with a multi-agent workflow; the notification/dump divergence was reproduced in QEMU/KVM. Thanks, Cheng Yongkang
