All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nikolay Aleksandrov <razor@blackwall.org>
To: Joachim Wiberg <troglobit@gmail.com>,
	Mattias Forsblad <mattias.forsblad@gmail.com>,
	netdev@vger.kernel.org
Cc: "David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, Andrew Lunn <andrew@lunn.ch>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Roopa Prabhu <roopa@nvidia.com>,
	Tobias Waldekranz <tobias@waldekranz.com>
Subject: Re: [PATCH 2/5] net: bridge: Implement bridge flood flag
Date: Thu, 17 Mar 2022 12:30:51 +0200	[thread overview]
Message-ID: <810a0399-4505-bafc-a99a-07d7943df8bb@blackwall.org> (raw)
In-Reply-To: <87r1717xrz.fsf@gmail.com>

On 17/03/2022 11:07, Joachim Wiberg wrote:
> On Thu, Mar 17, 2022 at 07:50, Mattias Forsblad <mattias.forsblad@gmail.com> wrote:
>> This patch implements the bridge flood flags. There are three different
>> flags matching unicast, multicast and broadcast. When the corresponding
>> flag is cleared packets received on bridge ports will not be flooded
>> towards the bridge.
> 
> If I've not completely misunderstood things, I believe the flood and
> mcast_flood flags operate on unknown unicast and multicast.  With that
> in mind I think the hot path in br_input.c needs a bit more eyes.  I'll
> add my own comments below.
> 
> Happy incident I saw this patch set, I have a very similar one for these
> flags to the bridge itself, with the intent to improve handling of all
> classes of multicast to/from the bridge itself.

+1

I'll add my comments below, yours are pretty spot on. I have one more
that's for the snipped part, I'll send that separately. :)

First please split this into 3 separate patches - one for each flag.
That would make reviewing much easier.

> >> [snip]
>> diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
>> index e0c13fcc50ed..fcb0757bfdcc 100644
>> --- a/net/bridge/br_input.c
>> +++ b/net/bridge/br_input.c
>> @@ -109,11 +109,12 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
>>  		/* by definition the broadcast is also a multicast address */
>>  		if (is_broadcast_ether_addr(eth_hdr(skb)->h_dest)) {
>>  			pkt_type = BR_PKT_BROADCAST;
>> -			local_rcv = true;
>> +			local_rcv = true && br_opt_get(br, BROPT_BCAST_FLOOD);
> 
> Minor comment, I believe the preferred style is more like this:
> 
> 	if (br_opt_get(br, BROPT_BCAST_FLOOD))
>         	local_rcv = true;
> 

ack

>>  		} else {
>>  			pkt_type = BR_PKT_MULTICAST;
>> -			if (br_multicast_rcv(&brmctx, &pmctx, vlan, skb, vid))
>> -				goto drop;
>> +			if (br_opt_get(br, BROPT_MCAST_FLOOD))
>> +				if (br_multicast_rcv(&brmctx, &pmctx, vlan, skb, vid))
>> +					goto drop;
> 
> Since the BROPT_MCAST_FLOOD flag should only control uknown multicast,
> we cannot bypass the call to br_multicast_rcv(), which helps with the
> classifcation.  E.g., we want IGMP/MLD reports to be forwarded to all
> router ports, while the mdb lookup (below) is what an tell us if we
> have uknown multicast and there we can check the BROPT_MCAST_FLOOD
> flag for the bridge itself.
> 

+1

>>  		}
>>  	}
>>  
>> @@ -155,9 +156,13 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
>>  			local_rcv = true;
>>  			br->dev->stats.multicast++;
>>  		}
>> +		if (!br_opt_get(br, BROPT_MCAST_FLOOD))
>> +			local_rcv = false;
> 
> We should never set local_rcv to false, only ever use constructs that
> set it to true.  Here the PROMISC flag (above) condition would be
> negated, which would be a regression.
> 
> Instead, for multicast I believe we should ensure that we reach the
> else statement for unknown IP multicast, preventing mcast_hit from
> being set, and instead flood unknown multicast using br_flood().
> 
> This is a bigger change that involves:
> 
>   1) dropping the mrouters_only skb flag for unknown multicast,
>      keeping it only for IGMP/MLD reports
>   2) extending br_flood() slightly to flood unknown multicast
>      also to mcast_router ports
> 
> As I mentioned above, I have some patches, including selftests, for
> forwarding known/unknown multicast using the mdb and mcast_flood +
> mcast_router flags.  Maybe we should combine efforts here somehow?
> 

Ack, sounds good! Please coordinate that between yourselves, if the mcast
flood flag will be dropped from this set or if Joachim's will be integrated.

>>  		break;
>>  	case BR_PKT_UNICAST:
>>  		dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
>> +		if (!br_opt_get(br, BROPT_FLOOD))
>> +			local_rcv = false;
> 
> Again, never set it to false, invert the check instead, like this:
> 
> 		if (!dst && br_opt_get(br, BROPT_FLOOD))
> 			local_rcv = true;
> 
>>  		break;
>>  	default:
>>  		break;
>> @@ -166,7 +171,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
>>  	if (dst) {
>>  		unsigned long now = jiffies;
>>  
>> -		if (test_bit(BR_FDB_LOCAL, &dst->flags))
>> +		if (test_bit(BR_FDB_LOCAL, &dst->flags) && local_rcv)
>>  			return br_pass_frame_up(skb);
> 
> I believe this would break both the flooding of unknown multicast and
> the PROMISC case.  Down here we are broadcast or known/unknown multicast
> land, so the local_rcv flag should be sufficient.
> 
>>  		if (now != dst->used)
>> @@ -190,6 +195,16 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
>>  }
>>  EXPORT_SYMBOL_GPL(br_handle_frame_finish);
>>  
>> +bool br_flood_enabled(const struct net_device *dev)
>> +{
>> +	struct net_bridge *br = netdev_priv(dev);

const

>> +
>> +	return !!(br_opt_get(br, BROPT_FLOOD) ||
>> +		   br_opt_get(br, BROPT_MCAST_FLOOD) ||
>> +		   br_opt_get(br, BROPT_BCAST_FLOOD));
> 
> Minor nit, don't know what the rest of the list feels about this, but
> maybe the BROPT_FLOOD option should be renamed to BR_UCAST_FLOOD or
> BR_UNICAST_FLOOD?
> 

Exactly, very good suggestion. Unfortunately we already have BR_FLOOD and can't
do anything about it, but we shouldn't follow that bad example.

> Best regards
>  /Joachim

Cheers,
 Nik

  reply	other threads:[~2022-03-17 10:30 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-17  6:50 [PATCH v3 net-next 0/5] bridge: dsa: switchdev: mv88e6xxx: Implement bridge flood flags Mattias Forsblad
2022-03-17  6:50 ` [PATCH 1/5] switchdev: Add local_receive attribute Mattias Forsblad
2022-03-17  6:50 ` [PATCH 2/5] net: bridge: Implement bridge flood flag Mattias Forsblad
2022-03-17  9:07   ` Joachim Wiberg
2022-03-17 10:30     ` Nikolay Aleksandrov [this message]
2022-03-17 11:39     ` Mattias Forsblad
2022-03-17 11:42       ` Nikolay Aleksandrov
2022-03-17 12:26         ` Ido Schimmel
2022-03-17 13:34           ` Tobias Waldekranz
2022-03-17 14:10             ` Ido Schimmel
2022-03-17 16:02               ` Tobias Waldekranz
2022-03-17 10:11   ` Nikolay Aleksandrov
2022-03-17 10:32     ` Nikolay Aleksandrov
2022-03-17 11:15     ` Vladimir Oltean
2022-03-17 11:57       ` Vladimir Oltean
2022-03-17 11:59         ` Vladimir Oltean
2022-03-17 12:08           ` Mattias Forsblad
2022-03-17  6:50 ` [PATCH 3/5] dsa: Handle the flood flag in the DSA layer Mattias Forsblad
2022-03-17  6:50 ` [PATCH 4/5] mv88e6xxx: Offload the flood flag Mattias Forsblad
2022-03-17 13:05   ` Vladimir Oltean
2022-03-31  8:11     ` Tobias Waldekranz
2022-03-31 15:00       ` Vladimir Oltean
2022-03-17  6:50 ` [PATCH 5/5] selftest: Add bridge flood flag tests Mattias Forsblad

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=810a0399-4505-bafc-a99a-07d7943df8bb@blackwall.org \
    --to=razor@blackwall.org \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=f.fainelli@gmail.com \
    --cc=kuba@kernel.org \
    --cc=mattias.forsblad@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=roopa@nvidia.com \
    --cc=tobias@waldekranz.com \
    --cc=troglobit@gmail.com \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.