lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fb4027a7-48a7-4488-a008-584d3b69c025@blackwall.org>
Date: Wed, 18 Dec 2024 16:04:39 +0200
From: Nikolay Aleksandrov <razor@...ckwall.org>
To: Yong Wang <yongwang@...dia.com>, roopa@...dia.com, davem@...emloft.net,
 edumazet@...gle.com, netdev@...r.kernel.org
Cc: aroulin@...dia.com, idosch@...dia.com, nmiyar@...dia.com
Subject: Re: [RFC v2 net-next 1/2] net: bridge: multicast: re-implement port
 multicast enable/disable functions

On 13/12/2024 05:35, Yong Wang wrote:
> Re-implement br_multicast_enable_port() / br_multicast_disable_port() by
> adding br_multicast_toggle_port() helper function in order to support
> per vlan multicast context enabling/disabling for bridge ports. As the
> port state could be changed by STP, that impacts multicast behaviors
> like igmp query. The corresponding context should be used either for
> per port context or per vlan context accordingly.
> 
> Signed-off-by: Yong Wang <yongwang@...dia.com>
> Reviewed-by: Andy Roulin <aroulin@...dia.com>
> ---
>   net/bridge/br_multicast.c | 72 ++++++++++++++++++++++++++++++++++-----
>   1 file changed, 64 insertions(+), 8 deletions(-)
> 
> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index b2ae0d2434d2..67438a75babd 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -2105,12 +2105,17 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
>   	}
>   }
>   
> -void br_multicast_enable_port(struct net_bridge_port *port)
> +static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
>   {
> -	struct net_bridge *br = port->br;
> +	struct net_bridge *br = pmctx->port->br;
>   
>   	spin_lock_bh(&br->multicast_lock);
> -	__br_multicast_enable_port_ctx(&port->multicast_ctx);
> +	if (br_multicast_port_ctx_is_vlan(pmctx) &&
> +	    !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
> +		spin_unlock_bh(&br->multicast_lock);
> +		return;
> +	}
> +	__br_multicast_enable_port_ctx(pmctx);
>   	spin_unlock_bh(&br->multicast_lock);
>   }
>   
> @@ -2137,11 +2142,62 @@ static void __br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
>   	br_multicast_rport_del_notify(pmctx, del);
>   }
>   
> +static void br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
> +{
> +	struct net_bridge *br = pmctx->port->br;
> +
> +	spin_lock_bh(&br->multicast_lock);
> +	if (br_multicast_port_ctx_is_vlan(pmctx) &&
> +	    !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED)) {
> +		spin_unlock_bh(&br->multicast_lock);
> +		return;
> +	}
> +
> +	__br_multicast_disable_port_ctx(pmctx);
> +	spin_unlock_bh(&br->multicast_lock);
> +}
> +
> +static void br_multicast_toggle_port(struct net_bridge_port *port, bool on)
> +{
> +	struct net_bridge *br = port->br;
> +
> +	if (br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) {
> +		struct net_bridge_vlan_group *vg;
> +		struct net_bridge_vlan *vlan;
> +
> +		rcu_read_lock();
> +		vg = nbp_vlan_group_rcu(port);
> +		if (!vg) {
> +			rcu_read_unlock();
> +			return;
> +		}
> +
> +		/* iterate each vlan of the port, toggle port_mcast_ctx per vlan */
> +		list_for_each_entry(vlan, &vg->vlan_list, vlist) {

list_for_each_entry_rcu()

> +			/* enable port_mcast_ctx when vlan is LEARNING or FORWARDING */
> +			if (on && br_vlan_state_allowed(br_vlan_get_state(vlan), true))
> +				br_multicast_enable_port_ctx(&vlan->port_mcast_ctx);
> +			else
> +				br_multicast_disable_port_ctx(&vlan->port_mcast_ctx);
> +		}
> +		rcu_read_unlock();
> +	} else {
> +		/* use the port's multicast context when vlan snooping is disabled */
> +		if (on)
> +			br_multicast_enable_port_ctx(&port->multicast_ctx);
> +		else
> +			br_multicast_disable_port_ctx(&port->multicast_ctx);
> +	}
> +}
> +
> +void br_multicast_enable_port(struct net_bridge_port *port)
> +{
> +	br_multicast_toggle_port(port, true);
> +}
> +
>   void br_multicast_disable_port(struct net_bridge_port *port)
>   {
> -	spin_lock_bh(&port->br->multicast_lock);
> -	__br_multicast_disable_port_ctx(&port->multicast_ctx);
> -	spin_unlock_bh(&port->br->multicast_lock);
> +	br_multicast_toggle_port(port, false);
>   }
>   
>   static int __grp_src_delete_marked(struct net_bridge_port_group *pg)
> @@ -4304,9 +4360,9 @@ int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
>   		__br_multicast_open(&br->multicast_ctx);
>   	list_for_each_entry(p, &br->port_list, list) {
>   		if (on)
> -			br_multicast_disable_port(p);
> +			br_multicast_disable_port_ctx(&p->multicast_ctx);
>   		else
> -			br_multicast_enable_port(p);
> +			br_multicast_enable_port_ctx(&p->multicast_ctx);
>   	}
>   
>   	list_for_each_entry(vlan, &vg->vlan_list, vlist)


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ