[<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