Netdev Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Vladimir Oltean <vladimir.oltean@nxp.com>
To: netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
	"David S. Miller" <davem@davemloft.net>
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>,
	Tobias Waldekranz <tobias@waldekranz.com>,
	Roopa Prabhu <roopa@nvidia.com>,
	Nikolay Aleksandrov <nikolay@nvidia.com>,
	Stephen Hemminger <stephen@networkplumber.org>,
	bridge@lists.linux-foundation.org,
	Grygorii Strashko <grygorii.strashko@ti.com>
Subject: [RFC PATCH v3 net-next 13/24] net: bridge: use the public notifier chain for br_fdb_replay
Date: Mon, 12 Jul 2021 18:21:31 +0300	[thread overview]
Message-ID: <20210712152142.800651-14-vladimir.oltean@nxp.com> (raw)
In-Reply-To: <20210712152142.800651-1-vladimir.oltean@nxp.com>

Currently, switchdev users of br_fdb_replay pass a pointer to their
atomic notifier block for the bridge to replay the FDB entries on the
port and local to the bridge, and the bridge whispers those FDB entries
to that driver only, and not publicly on the switchdev atomic notifier
call chain.

Going forward we would like to introduce push-mode FDB replays for all
switchdev drivers, and there are at least two reasons why the current
setup is not ideal.

First and most obvious, every driver would have to be changed to pass
its atomic notifier block to the switchdev_bridge_port_offload() and
switchdev_bridge_port_unoffload() calls, which gets a bit cumbersome.

The second is that it wasn't a good idea in the first place for the
other switchdev drivers to not hear anything about the FDB entries on
foreign interfaces. For example, DSA treats these FDB entries in a
special way since commit 3068d466a67e ("net: dsa: sync static FDB
entries on foreign interfaces to hardware"). With the static FDB entry
addition being public on everybody's notifier block but the deletion
being whispered only to the driver whose port leaves the bridge, DSA
would have a lingering static FDB entry pointing towards the host.

Making br_fdb_replay() use the atomic switchdev call chain solves both
problems.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 include/linux/if_bridge.h |  4 ++--
 net/bridge/br_fdb.c       | 43 +++++++--------------------------------
 net/dsa/dsa_priv.h        |  1 -
 net/dsa/port.c            | 10 ++++-----
 net/dsa/slave.c           |  2 +-
 5 files changed, 14 insertions(+), 46 deletions(-)

diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 13acc1ff476c..8d4a157d249d 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -168,7 +168,7 @@ bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
 u8 br_port_get_stp_state(const struct net_device *dev);
 clock_t br_get_ageing_time(const struct net_device *br_dev);
 int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
-		  bool adding, struct notifier_block *nb);
+		  bool adding);
 #else
 static inline struct net_device *
 br_fdb_find_port(const struct net_device *br_dev,
@@ -200,7 +200,7 @@ static inline clock_t br_get_ageing_time(const struct net_device *br_dev)
 
 static inline int br_fdb_replay(const struct net_device *br_dev,
 				const struct net_device *dev,
-				bool adding, struct notifier_block *nb)
+				bool adding)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index c93a2b3a0ad8..4434aee4cfbc 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -732,31 +732,12 @@ static inline size_t fdb_nlmsg_size(void)
 		+ nla_total_size(sizeof(u8)); /* NFEA_ACTIVITY_NOTIFY */
 }
 
-static int br_fdb_replay_one(struct notifier_block *nb,
-			     const struct net_bridge_fdb_entry *fdb,
-			     struct net_device *dev, unsigned long action)
-{
-	struct switchdev_notifier_fdb_info item;
-	int err;
-
-	item.addr = fdb->key.addr.addr;
-	item.vid = fdb->key.vlan_id;
-	item.added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
-	item.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags);
-	item.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
-	item.info.dev = dev;
-
-	err = nb->notifier_call(nb, action, &item);
-	return notifier_to_errno(err);
-}
-
 int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
-		  bool adding, struct notifier_block *nb)
+		  bool adding)
 {
 	struct net_bridge_fdb_entry *fdb;
 	struct net_bridge *br;
-	unsigned long action;
-	int err = 0;
+	int type;
 
 	if (!netif_is_bridge_master(br_dev))
 		return -EINVAL;
@@ -767,28 +748,18 @@ int br_fdb_replay(const struct net_device *br_dev, const struct net_device *dev,
 	br = netdev_priv(br_dev);
 
 	if (adding)
-		action = SWITCHDEV_FDB_ADD_TO_DEVICE;
+		type = RTM_NEWNEIGH;
 	else
-		action = SWITCHDEV_FDB_DEL_TO_DEVICE;
+		type = RTM_DELNEIGH;
 
 	rcu_read_lock();
 
-	hlist_for_each_entry_rcu(fdb, &br->fdb_list, fdb_node) {
-		const struct net_bridge_port *dst = READ_ONCE(fdb->dst);
-		struct net_device *dst_dev;
-
-		dst_dev = dst ? dst->dev : br->dev;
-		if (dst_dev != br_dev && dst_dev != dev)
-			continue;
-
-		err = br_fdb_replay_one(nb, fdb, dst_dev, action);
-		if (err)
-			break;
-	}
+	hlist_for_each_entry_rcu(fdb, &br->fdb_list, fdb_node)
+		br_switchdev_fdb_notify(br, fdb, type);
 
 	rcu_read_unlock();
 
-	return err;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(br_fdb_replay);
 
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index f201c33980bf..20003512d8f8 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -285,7 +285,6 @@ static inline bool dsa_tree_offloads_bridge_port(struct dsa_switch_tree *dst,
 
 /* slave.c */
 extern const struct dsa_device_ops notag_netdev_ops;
-extern struct notifier_block dsa_slave_switchdev_notifier;
 extern struct notifier_block dsa_slave_switchdev_blocking_notifier;
 
 void dsa_slave_mii_bus_init(struct dsa_switch *ds);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 34b7f64348c2..ccf11bc518fe 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -200,13 +200,12 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp,
 		return err;
 
 	/* Forwarding and termination FDB entries on the port */
-	err = br_fdb_replay(br, brport_dev, true,
-			    &dsa_slave_switchdev_notifier);
+	err = br_fdb_replay(br, brport_dev, true);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
 	/* Termination FDB entries on the bridge itself */
-	err = br_fdb_replay(br, br, true, &dsa_slave_switchdev_notifier);
+	err = br_fdb_replay(br, br, true);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
@@ -232,13 +231,12 @@ static int dsa_port_switchdev_unsync_objs(struct dsa_port *dp,
 		return err;
 
 	/* Forwarding and termination FDB entries on the port */
-	err = br_fdb_replay(br, brport_dev, false,
-			    &dsa_slave_switchdev_notifier);
+	err = br_fdb_replay(br, brport_dev, false);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
 	/* Termination FDB entries on the bridge itself */
-	err = br_fdb_replay(br, br, false, &dsa_slave_switchdev_notifier);
+	err = br_fdb_replay(br, br, false);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ffbba1e71551..461c80bc066a 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2517,7 +2517,7 @@ static struct notifier_block dsa_slave_nb __read_mostly = {
 	.notifier_call  = dsa_slave_netdevice_event,
 };
 
-struct notifier_block dsa_slave_switchdev_notifier = {
+static struct notifier_block dsa_slave_switchdev_notifier = {
 	.notifier_call = dsa_slave_switchdev_event,
 };
 
-- 
2.25.1


  parent reply	other threads:[~2021-07-12 15:22 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-12 15:21 [RFC PATCH v3 net-next 00/24] Allow forwarding for the software bridge data path to be offloaded to capable devices Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 01/24] net: dpaa2-switch: use extack in dpaa2_switch_port_bridge_join Vladimir Oltean
2021-07-13  2:20   ` Florian Fainelli
2021-07-12 15:21 ` [RFC PATCH v3 net-next 02/24] net: dpaa2-switch: refactor prechangeupper sanity checks Vladimir Oltean
2021-07-13  2:21   ` Florian Fainelli
2021-07-12 15:21 ` [RFC PATCH v3 net-next 03/24] net: mlxsw: " Vladimir Oltean
2021-07-13  2:21   ` Florian Fainelli
2021-07-12 15:21 ` [RFC PATCH v3 net-next 04/24] net: ocelot: fix switchdev objects synced for wrong netdev with LAG offload Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 05/24] net: prestera: if the LAG that we're joining is under a bridge, join it Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 06/24] net: prestera: refactor prechangeupper sanity checks Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 07/24] net: bridge: disambiguate offload_fwd_mark Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 08/24] net: bridge: switchdev: recycle unused hwdoms Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 09/24] net: bridge: switchdev: let drivers inform which bridge ports are offloaded Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 10/24] net: prestera: guard against multiple switchdev obj replays on same bridge port Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 11/24] net: mlxsw: " Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 12/24] net: bridge: drop context pointer from br_fdb_replay Vladimir Oltean
2021-07-12 15:21 ` Vladimir Oltean [this message]
2021-07-12 15:21 ` [RFC PATCH v3 net-next 14/24] net: bridge: unexport call_switchdev_blocking_notifiers Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 15/24] net: bridge: propagate ctx to switchdev_port_obj_{add,del} Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 16/24] net: bridge: propagate ctx to br_switchdev_port_vlan_{add,del} Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 17/24] net: bridge: replay mdb entries on the public switchdev notifier chain Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 18/24] net: bridge: replay vlan entries on the public switchdev notifier Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 19/24] net: bridge: switchdev object replay helpers for everybody Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 20/24] net: bridge: switchdev: allow the TX data plane forwarding to be offloaded Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 21/24] net: dsa: track the number of switches in a tree Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 22/24] net: dsa: add support for bridge TX forwarding offload Vladimir Oltean
2021-07-15 14:49   ` Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 23/24] net: dsa: mv88e6xxx: map virtual bridges with forwarding offload in the PVT Vladimir Oltean
2021-07-12 15:21 ` [RFC PATCH v3 net-next 24/24] net: dsa: tag_dsa: offload the bridge forwarding process Vladimir Oltean
2021-07-12 15:40 ` [RFC PATCH v3 net-next 00/24] Allow forwarding for the software bridge data path to be offloaded to capable devices Marek Behun
2021-07-12 17:01   ` Vladimir Oltean
2021-07-12 17:27     ` Marek Behun
2021-07-22  9:50       ` Vladimir Oltean

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=20210712152142.800651-14-vladimir.oltean@nxp.com \
    --to=vladimir.oltean@nxp.com \
    --cc=andrew@lunn.ch \
    --cc=bridge@lists.linux-foundation.org \
    --cc=davem@davemloft.net \
    --cc=f.fainelli@gmail.com \
    --cc=grygorii.strashko@ti.com \
    --cc=idosch@idosch.org \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nikolay@nvidia.com \
    --cc=roopa@nvidia.com \
    --cc=stephen@networkplumber.org \
    --cc=tobias@waldekranz.com \
    --cc=vivien.didelot@gmail.com \
    --subject='Re: [RFC PATCH v3 net-next 13/24] net: bridge: use the public notifier chain for br_fdb_replay' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).