On Sat, Mar 07, 2026 at 05:45:43AM +0100, Linus Lüssing wrote:
> If VLAN aware multicast snooping is enabled then we need to perform a
> few extra checks to figure out if multicast snooping is actually enabled
> for a specific VLAN, as there is then an additional per VLAN multicast
> snooping toggle.
>
> Signed-off-by: Linus Lüssing <[email protected]>
> ---
> net/bridge/br_multicast.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index cdc921b97243..1059984d8147 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -1142,9 +1142,31 @@ static void br_multicast_update_active(struct
> net_bridge_mcast *brmctx)
>
> lockdep_assert_held_once(&brmctx->br->multicast_lock);
>
> - if (!br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED))
> + if (!br_opt_get(brmctx->br, BROPT_MULTICAST_ENABLED)) {
> force_inactive = true;
> + goto update;
> + }
>
> + if (br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) {
> + /* with per-vlan snooping enabled there is an extra per-vlan
> + * toggle to enable/disable snooping which we must check
> + */
> + if (br_multicast_ctx_vlan_global_disabled(brmctx))
> + force_inactive = true;
> + /* with per-vlan snooping enabled the non-vlan multicast
> + * snooping context is inactive
> + */
> + else if (!br_multicast_ctx_is_vlan(brmctx))
> + force_inactive = true;
> + } else {
> + /* with per-vlan snooping disabled a vlan multicast
> + * snooping context is inactive
> + */
> + if (br_multicast_ctx_is_vlan(brmctx))
> + force_inactive = true;
> + }
> +
> +update:
> br_ip4_multicast_update_active(brmctx, force_inactive);
> br_ip6_multicast_update_active(brmctx, force_inactive);
>
> @@ -4505,6 +4527,7 @@ void br_multicast_toggle_one_vlan(struct
> net_bridge_vlan *vlan, bool on)
>
> spin_lock_bh(&br->multicast_lock);
> vlan->priv_flags ^= BR_VLFLAG_MCAST_ENABLED;
> + br_multicast_update_active(&vlan->br_mcast_ctx);
>
> if (on)
> __br_multicast_open(&vlan->br_mcast_ctx);
I believe the active state is not disabled when snooping is disabled on
a specific VLAN. AFAICT that's because br_multicast_update_active() is
only called when the VLAN is actually used by the bridge (i.e.,
"brentry"). Can be reproduced with [1]. Please add it as a test case in
patch #2.
Will continue tomorrow.
[1]
#!/bin/bash
for ns in ns0 ns1; do
ip netns del $ns &> /dev/null
ip netns add $ns
ip -n $ns link set dev lo up
done
ip -n ns0 link add name veth0 type veth peer name veth1 netns ns1
ip -n ns0 link add name br0 up type bridge vlan_filtering 1 mcast_snooping 1
mcast_vlan_snooping 1
ip -n ns1 link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1
mcast_vlan_snooping 1
ip -n ns0 link set dev veth0 up master br0
ip -n ns1 link set dev veth1 up master br1
bridge -n ns0 vlan add vid 10 dev veth0 master
bridge -n ns1 vlan add vid 10 dev veth1 master
sleep 1
bridge -n ns0 vlan global set vid 10 dev br0 mcast_snooping 1
mcast_query_response_interval 100 mcast_querier 1
bridge -n ns1 vlan global set vid 10 dev br1 mcast_snooping 1
mcast_query_response_interval 100 mcast_querier 0
sleep 1
bridge -n ns1 -j -p vlan global show dev br1 vid 10 | jq
'.[]["vlans"][]["mcast_active_v4"]'
bridge -n ns1 vlan global set vid 10 dev br1 mcast_snooping 0
sleep 1
bridge -n ns1 -j -p vlan global show dev br1 vid 10 | jq
'.[]["vlans"][]["mcast_active_v4"]'