All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Oltean <olteanv@gmail.com>
To: netdev@vger.kernel.org
Cc: Andrew Lunn <andrew@lunn.ch>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Jiri Pirko <jiri@resnulli.us>, Ido Schimmel <idosch@idosch.org>,
	DENG Qingfang <dqfext@gmail.com>,
	Tobias Waldekranz <tobias@waldekranz.com>,
	George McCollister <george.mccollister@gmail.com>,
	Vlad Yasevich <vyasevich@gmail.com>,
	Roopa Prabhu <roopa@nvidia.com>,
	Nikolay Aleksandrov <nikolay@nvidia.com>
Subject: [RFC PATCH v2 net-next 17/17] net: bridge: offloaded ports are always promiscuous
Date: Wed, 24 Feb 2021 13:43:50 +0200	[thread overview]
Message-ID: <20210224114350.2791260-18-olteanv@gmail.com> (raw)
In-Reply-To: <20210224114350.2791260-1-olteanv@gmail.com>

From: Vladimir Oltean <vladimir.oltean@nxp.com>

Automatic bridge ports are ones with source address learning or unicast
flooding enabled (corollary: non-automatic ports have learning and
flooding disabled).

The bridge driver has an optimization which says that if all ports are
non-automatic, they don't need to operate in promiscuous mode (i.e. they
don't need to receive all packets). Instead, if a non-automatic port
supports unicast filtering, it can be made to receive only the packets
which have a static FDB entry towards another port in the same forwarding
domain. The logic is that, if a packet is received and does not have a
static FDB entry for routing, it would be dropped anyway because all the
other ports have flooding disabled. So it makes sense to not accept the
packet on RX in the first place.

When a non-automatic port switches to non-promiscuous mode, the static
FDB entries towards the other bridge ports are synced to the RX filtering
list of this ingress port using dev_uc_add.

However, this optimization doesn't bring any benefit for switchdev ports
that offload the bridge. Their hardware data path is promiscuous by its
very definition, i.e. they accept packets regardless of destination MAC
address, because they need to forward them towards the correct station.

Not only is the optimization not necessary, it is also detrimential.
The promise of switchdev is that it looks just like a regular interface
to user space, and it offers extra offloading functionality for stacked
virtual interfaces that can benefit from it. Therefore, it is imaginable
that a switchdev driver might want to implement IFF_UNICAST_FLT too.
When not offloading the bridge, a switchdev interface should really be
indistinguishable from a normal port from user space's perspective,
which means that addresses installed with dev_uc_add and dev_mc_add
should be accepted, and those which aren't should be dropped.

So a switchdev driver might implement dev_uc_add and dev_mc_add by
extracting these addresses from the hardware data path and delivering
them to the CPU, and drop the rest by disabling flooding to the CPU,
and this makes perfect sense when there is no bridge involved on top.

However, things get complicated when the bridge ports are non-automatic
and enter non-promiscuous mode. The bridge will then panic 'oh no, I
need to do something in order for my packets to not get dropped', and
will do the dev_uc_add procedure mentioned above. This will result in
the undesirable behavior that the switchdev driver will extract those
MAC addresses to the CPU, when in fact all that the bridge wanted was
for the packets to not be dropped.

To avoid this situation, the switchdev driver would need to conditionally
accept an address added through dev_uc_add and extract it to the CPU
only if it wasn't added by the bridge, which is both complicated,
strange and counterproductive. It is already unfortunate enough that the
bridge uses its own notification mechanisms for addresses which need to
be extracted (SWITCHDEV_OBJ_ID_HOST_MDB, SWITCHDEV_FDB_ADD_TO_DEVICE
with dev=br0). It shouldn't monopolize the switchdev driver's
functionality and instead it should allow it to offer its services to
other layers which are unaware of switchdev.

So this patch's premise is that the bridge, which is fully aware of
switchdev anyway, is the one that needs to compromise, and must not do
something which isn't needed if switchdev is being used to offload a
port. This way, dev_uc_add and dev_mc_add can be used as a valid mechanism
for address filtering towards the CPU requested by switchdev-unaware
layers ('towards the CPU' because switchdev-unaware will not benefit
from the hardware offload datapath anyway, that's effectively the only
destination which is relevant for them).

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/bridge/br_if.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 680fc3bed549..fc32066bbfdc 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -111,9 +111,13 @@ static void br_port_clear_promisc(struct net_bridge_port *p)
 	/* Check if the port is already non-promisc or if it doesn't
 	 * support UNICAST filtering.  Without unicast filtering support
 	 * we'll end up re-enabling promisc mode anyway, so just check for
-	 * it here.
+	 * it here. Also, a switchdev offloading this port needs to be
+	 * promiscuous by definition, so don't even attempt to get it out of
+	 * promiscuous mode or sync unicast FDB entries to it, since that is
+	 * pointless and not necessary.
 	 */
-	if (!br_promisc_port(p) || !(p->dev->priv_flags & IFF_UNICAST_FLT))
+	if (!br_promisc_port(p) || !(p->dev->priv_flags & IFF_UNICAST_FLT) ||
+	    p->offloaded)
 		return;
 
 	/* Since we'll be clearing the promisc mode, program the port
-- 
2.25.1


  parent reply	other threads:[~2021-02-24 11:50 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-24 11:43 [RFC PATCH v2 net-next 00/17] RX filtering in DSA Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 01/17] net: dsa: reference count the host mdb addresses Vladimir Oltean
2021-02-26  9:20   ` Tobias Waldekranz
2021-02-24 11:43 ` [RFC PATCH v2 net-next 02/17] net: dsa: reference count the host fdb addresses Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 03/17] net: dsa: install the host MDB and FDB entries in the master's RX filter Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 04/17] net: dsa: install the port MAC addresses as host fdb entries Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 05/17] net: bridge: implement unicast filtering for the bridge device Vladimir Oltean
2021-03-01 15:22   ` Ido Schimmel
2022-02-22 11:21     ` Vladimir Oltean
2022-02-22 16:54       ` Ido Schimmel
2022-02-22 17:18         ` Vladimir Oltean
2022-02-24 13:22           ` Ido Schimmel
2022-02-24 13:52             ` Vladimir Oltean
2022-03-01 16:20               ` Ido Schimmel
2022-03-02 11:17                 ` Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 06/17] net: dsa: add addresses obtained from RX filtering to host addresses Vladimir Oltean
2021-02-26 10:59   ` Tobias Waldekranz
2021-02-26 13:28     ` Vladimir Oltean
2021-02-26 22:44       ` Tobias Waldekranz
2021-02-24 11:43 ` [RFC PATCH v2 net-next 07/17] net: bridge: switchdev: refactor br_switchdev_fdb_notify Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 08/17] net: bridge: switchdev: include local flag in FDB notifications Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 09/17] net: bridge: switchdev: send FDB notifications for host addresses Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 10/17] net: dsa: include bridge addresses which are local in the host fdb list Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 11/17] net: dsa: include fdb entries pointing to bridge " Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 12/17] net: dsa: sync static FDB entries on foreign interfaces to hardware Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 13/17] net: dsa: mv88e6xxx: Request assisted learning on CPU port Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 14/17] net: dsa: replay port and host-joined mdb entries when joining the bridge Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 15/17] net: dsa: replay port and local fdb " Vladimir Oltean
2021-02-26 12:23   ` Tobias Waldekranz
2021-02-26 18:08     ` Vladimir Oltean
2021-02-24 11:43 ` [RFC PATCH v2 net-next 16/17] net: bridge: switchdev: let drivers inform which bridge ports are offloaded Vladimir Oltean
2021-02-24 14:25   ` kernel test robot
2021-02-24 11:43 ` Vladimir Oltean [this message]
2021-02-24 15:21   ` [RFC PATCH v2 net-next 17/17] net: bridge: offloaded ports are always promiscuous kernel test robot

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=20210224114350.2791260-18-olteanv@gmail.com \
    --to=olteanv@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=dqfext@gmail.com \
    --cc=f.fainelli@gmail.com \
    --cc=george.mccollister@gmail.com \
    --cc=idosch@idosch.org \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=nikolay@nvidia.com \
    --cc=roopa@nvidia.com \
    --cc=tobias@waldekranz.com \
    --cc=vivien.didelot@gmail.com \
    --cc=vyasevich@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.