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"]'

Reply via email to