netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans Schultz <schultz.hans@gmail.com>
To: Vladimir Oltean <vladimir.oltean@nxp.com>,
	netdev@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
	"David S. Miller" <davem@davemloft.net>
Cc: "Florian Fainelli" <f.fainelli@gmail.com>,
	"Andrew Lunn" <andrew@lunn.ch>,
	"Vivien Didelot" <vivien.didelot@gmail.com>,
	"Vladimir Oltean" <olteanv@gmail.com>,
	"Kurt Kanzenbach" <kurt@linutronix.de>,
	"Hauke Mehrtens" <hauke@hauke-m.de>,
	"Woojung Huh" <woojung.huh@microchip.com>,
	UNGLinuxDriver@microchip.com,
	"Sean Wang" <sean.wang@mediatek.com>,
	"Landen Chao" <Landen.Chao@mediatek.com>,
	"DENG Qingfang" <dqfext@gmail.com>,
	"Claudiu Manoil" <claudiu.manoil@nxp.com>,
	"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	"Alvin Šipraga" <alsi@bang-olufsen.dk>,
	"George McCollister" <george.mccollister@gmail.com>
Subject: Re: [PATCH v2 net-next 07/10] net: dsa: request drivers to perform FDB isolation
Date: Tue, 26 Apr 2022 17:01:47 +0200	[thread overview]
Message-ID: <867d7bga78.fsf@gmail.com> (raw)
In-Reply-To: <20220225092225.594851-8-vladimir.oltean@nxp.com>

On fre, feb 25, 2022 at 11:22, Vladimir Oltean <vladimir.oltean@nxp.com> wrote:
> For DSA, to encourage drivers to perform FDB isolation simply means to
> track which bridge does each FDB and MDB entry belong to. It then
> becomes the driver responsibility to use something that makes the FDB
> entry from one bridge not match the FDB lookup of ports from other
> bridges.
>
> The top-level functions where the bridge is determined are:
> - dsa_port_fdb_{add,del}
> - dsa_port_host_fdb_{add,del}
> - dsa_port_mdb_{add,del}
> - dsa_port_host_mdb_{add,del}
>
> aka the pre-crosschip-notifier functions.
>
> Changing the API to pass a reference to a bridge is not superfluous, and
> looking at the passed bridge argument is not the same as having the
> driver look at dsa_to_port(ds, port)->bridge from the ->port_fdb_add()
> method.
>
> DSA installs FDB and MDB entries on shared (CPU and DSA) ports as well,
> and those do not have any dp->bridge information to retrieve, because
> they are not in any bridge - they are merely the pipes that serve the
> user ports that are in one or multiple bridges.
>
> The struct dsa_bridge associated with each FDB/MDB entry is encapsulated
> in a larger "struct dsa_db" database. Although only databases associated
> to bridges are notified for now, this API will be the starting point for
> implementing IFF_UNICAST_FLT in DSA. There, the idea is to install FDB
> entries on the CPU port which belong to the corresponding user port's
> port database. These are supposed to match only when the port is
> standalone.
>
> It is better to introduce the API in its expected final form than to
> introduce it for bridges first, then to have to change drivers which may
> have made one or more assumptions.
>
> Drivers can use the provided bridge.num, but they can also use a
> different numbering scheme that is more convenient.
>
> DSA must perform refcounting on the CPU and DSA ports by also taking
> into account the bridge number. So if two bridges request the same local
> address, DSA must notify the driver twice, once for each bridge.
>
> In fact, if the driver supports FDB isolation, DSA must perform
> refcounting per bridge, but if the driver doesn't, DSA must refcount
> host addresses across all bridges, otherwise it would be telling the
> driver to delete an FDB entry for a bridge and the driver would delete
> it for all bridges. So introduce a bool fdb_isolation in drivers which
> would make all bridge databases passed to the cross-chip notifier have
> the same number (0). This makes dsa_mac_addr_find() -> dsa_db_equal()
> say that all bridge databases are the same database - which is
> essentially the legacy behavior.
>
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
>  drivers/net/dsa/b53/b53_common.c       | 12 ++--
>  drivers/net/dsa/b53/b53_priv.h         | 12 ++--
>  drivers/net/dsa/hirschmann/hellcreek.c |  6 +-
>  drivers/net/dsa/lan9303-core.c         | 13 ++--
>  drivers/net/dsa/lantiq_gswip.c         |  6 +-
>  drivers/net/dsa/microchip/ksz9477.c    | 12 ++--
>  drivers/net/dsa/microchip/ksz_common.c |  6 +-
>  drivers/net/dsa/microchip/ksz_common.h |  6 +-
>  drivers/net/dsa/mt7530.c               | 12 ++--
>  drivers/net/dsa/mv88e6xxx/chip.c       | 12 ++--
>  drivers/net/dsa/ocelot/felix.c         | 18 +++--
>  drivers/net/dsa/qca8k.c                | 12 ++--
>  drivers/net/dsa/sja1105/sja1105_main.c | 26 +++++--
>  include/net/dsa.h                      | 42 +++++++++--
>  net/dsa/dsa_priv.h                     |  3 +
>  net/dsa/port.c                         | 75 ++++++++++++++++++-
>  net/dsa/switch.c                       | 99 +++++++++++++++++---------
>  17 files changed, 280 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index 83bf30349c26..a8cc6e182c45 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -1708,7 +1708,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
>  }
>  
>  int b53_fdb_add(struct dsa_switch *ds, int port,
> -		const unsigned char *addr, u16 vid)
> +		const unsigned char *addr, u16 vid,
> +		struct dsa_db db)
>  {
>  	struct b53_device *priv = ds->priv;
>  	int ret;
> @@ -1728,7 +1729,8 @@ int b53_fdb_add(struct dsa_switch *ds, int port,
>  EXPORT_SYMBOL(b53_fdb_add);
>  
>  int b53_fdb_del(struct dsa_switch *ds, int port,
> -		const unsigned char *addr, u16 vid)
> +		const unsigned char *addr, u16 vid,
> +		struct dsa_db db)
>  {
>  	struct b53_device *priv = ds->priv;
>  	int ret;
> @@ -1829,7 +1831,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port,
>  EXPORT_SYMBOL(b53_fdb_dump);
>  
>  int b53_mdb_add(struct dsa_switch *ds, int port,
> -		const struct switchdev_obj_port_mdb *mdb)
> +		const struct switchdev_obj_port_mdb *mdb,
> +		struct dsa_db db)
>  {
>  	struct b53_device *priv = ds->priv;
>  	int ret;
> @@ -1849,7 +1852,8 @@ int b53_mdb_add(struct dsa_switch *ds, int port,
>  EXPORT_SYMBOL(b53_mdb_add);
>  
>  int b53_mdb_del(struct dsa_switch *ds, int port,
> -		const struct switchdev_obj_port_mdb *mdb)
> +		const struct switchdev_obj_port_mdb *mdb,
> +		struct dsa_db db)
>  {
>  	struct b53_device *priv = ds->priv;
>  	int ret;
> diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
> index a6b339fcb17e..d3091f0ad3e6 100644
> --- a/drivers/net/dsa/b53/b53_priv.h
> +++ b/drivers/net/dsa/b53/b53_priv.h
> @@ -359,15 +359,19 @@ int b53_vlan_add(struct dsa_switch *ds, int port,
>  int b53_vlan_del(struct dsa_switch *ds, int port,
>  		 const struct switchdev_obj_port_vlan *vlan);
>  int b53_fdb_add(struct dsa_switch *ds, int port,
> -		const unsigned char *addr, u16 vid);
> +		const unsigned char *addr, u16 vid,
> +		struct dsa_db db);
>  int b53_fdb_del(struct dsa_switch *ds, int port,
> -		const unsigned char *addr, u16 vid);
> +		const unsigned char *addr, u16 vid,
> +		struct dsa_db db);
>  int b53_fdb_dump(struct dsa_switch *ds, int port,
>  		 dsa_fdb_dump_cb_t *cb, void *data);
>  int b53_mdb_add(struct dsa_switch *ds, int port,
> -		const struct switchdev_obj_port_mdb *mdb);
> +		const struct switchdev_obj_port_mdb *mdb,
> +		struct dsa_db db);
>  int b53_mdb_del(struct dsa_switch *ds, int port,
> -		const struct switchdev_obj_port_mdb *mdb);
> +		const struct switchdev_obj_port_mdb *mdb,
> +		struct dsa_db db);
>  int b53_mirror_add(struct dsa_switch *ds, int port,
>  		   struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
>  enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,
> diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
> index 726f267cb228..cb89be9de43a 100644
> --- a/drivers/net/dsa/hirschmann/hellcreek.c
> +++ b/drivers/net/dsa/hirschmann/hellcreek.c
> @@ -827,7 +827,8 @@ static int hellcreek_fdb_get(struct hellcreek *hellcreek,
>  }
>  
>  static int hellcreek_fdb_add(struct dsa_switch *ds, int port,
> -			     const unsigned char *addr, u16 vid)
> +			     const unsigned char *addr, u16 vid,
> +			     struct dsa_db db)
>  {
>  	struct hellcreek_fdb_entry entry = { 0 };
>  	struct hellcreek *hellcreek = ds->priv;
> @@ -872,7 +873,8 @@ static int hellcreek_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int hellcreek_fdb_del(struct dsa_switch *ds, int port,
> -			     const unsigned char *addr, u16 vid)
> +			     const unsigned char *addr, u16 vid,
> +			     struct dsa_db db)
>  {
>  	struct hellcreek_fdb_entry entry = { 0 };
>  	struct hellcreek *hellcreek = ds->priv;
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index 3969d89fa4db..a21184e7fcb6 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -1188,7 +1188,8 @@ static void lan9303_port_fast_age(struct dsa_switch *ds, int port)
>  }
>  
>  static int lan9303_port_fdb_add(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid)
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db)
>  {
>  	struct lan9303 *chip = ds->priv;
>  
> @@ -1200,8 +1201,8 @@ static int lan9303_port_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int lan9303_port_fdb_del(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid)
> -
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db)
>  {
>  	struct lan9303 *chip = ds->priv;
>  
> @@ -1245,7 +1246,8 @@ static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port,
>  }
>  
>  static int lan9303_port_mdb_add(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb)
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db)
>  {
>  	struct lan9303 *chip = ds->priv;
>  	int err;
> @@ -1260,7 +1262,8 @@ static int lan9303_port_mdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int lan9303_port_mdb_del(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb)
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db)
>  {
>  	struct lan9303 *chip = ds->priv;
>  
> diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
> index 8a7a8093a156..3dfb532b7784 100644
> --- a/drivers/net/dsa/lantiq_gswip.c
> +++ b/drivers/net/dsa/lantiq_gswip.c
> @@ -1389,13 +1389,15 @@ static int gswip_port_fdb(struct dsa_switch *ds, int port,
>  }
>  
>  static int gswip_port_fdb_add(struct dsa_switch *ds, int port,
> -			      const unsigned char *addr, u16 vid)
> +			      const unsigned char *addr, u16 vid,
> +			      struct dsa_db db)
>  {
>  	return gswip_port_fdb(ds, port, addr, vid, true);
>  }
>  
>  static int gswip_port_fdb_del(struct dsa_switch *ds, int port,
> -			      const unsigned char *addr, u16 vid)
> +			      const unsigned char *addr, u16 vid,
> +			      struct dsa_db db)
>  {
>  	return gswip_port_fdb(ds, port, addr, vid, false);
>  }
> diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
> index 18ffc8ded7ee..94ad6d9504f4 100644
> --- a/drivers/net/dsa/microchip/ksz9477.c
> +++ b/drivers/net/dsa/microchip/ksz9477.c
> @@ -640,7 +640,8 @@ static int ksz9477_port_vlan_del(struct dsa_switch *ds, int port,
>  }
>  
>  static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid)
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	u32 alu_table[4];
> @@ -697,7 +698,8 @@ static int ksz9477_port_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int ksz9477_port_fdb_del(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid)
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	u32 alu_table[4];
> @@ -839,7 +841,8 @@ static int ksz9477_port_fdb_dump(struct dsa_switch *ds, int port,
>  }
>  
>  static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb)
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	u32 static_table[4];
> @@ -914,7 +917,8 @@ static int ksz9477_port_mdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int ksz9477_port_mdb_del(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb)
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	u32 static_table[4];
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 94e618b8352b..104458ec9cbc 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -276,7 +276,8 @@ int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
>  EXPORT_SYMBOL_GPL(ksz_port_fdb_dump);
>  
>  int ksz_port_mdb_add(struct dsa_switch *ds, int port,
> -		     const struct switchdev_obj_port_mdb *mdb)
> +		     const struct switchdev_obj_port_mdb *mdb,
> +		     struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	struct alu_struct alu;
> @@ -321,7 +322,8 @@ int ksz_port_mdb_add(struct dsa_switch *ds, int port,
>  EXPORT_SYMBOL_GPL(ksz_port_mdb_add);
>  
>  int ksz_port_mdb_del(struct dsa_switch *ds, int port,
> -		     const struct switchdev_obj_port_mdb *mdb)
> +		     const struct switchdev_obj_port_mdb *mdb,
> +		     struct dsa_db db)
>  {
>  	struct ksz_device *dev = ds->priv;
>  	struct alu_struct alu;
> diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
> index c6fa487fb006..66933445a447 100644
> --- a/drivers/net/dsa/microchip/ksz_common.h
> +++ b/drivers/net/dsa/microchip/ksz_common.h
> @@ -166,9 +166,11 @@ void ksz_port_fast_age(struct dsa_switch *ds, int port);
>  int ksz_port_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb,
>  		      void *data);
>  int ksz_port_mdb_add(struct dsa_switch *ds, int port,
> -		     const struct switchdev_obj_port_mdb *mdb);
> +		     const struct switchdev_obj_port_mdb *mdb,
> +		     struct dsa_db db);
>  int ksz_port_mdb_del(struct dsa_switch *ds, int port,
> -		     const struct switchdev_obj_port_mdb *mdb);
> +		     const struct switchdev_obj_port_mdb *mdb,
> +		     struct dsa_db db);
>  int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
>  
>  /* Common register access functions */
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index f74f25f479ed..abe63ec05066 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1349,7 +1349,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
>  
>  static int
>  mt7530_port_fdb_add(struct dsa_switch *ds, int port,
> -		    const unsigned char *addr, u16 vid)
> +		    const unsigned char *addr, u16 vid,
> +		    struct dsa_db db)
>  {
>  	struct mt7530_priv *priv = ds->priv;
>  	int ret;
> @@ -1365,7 +1366,8 @@ mt7530_port_fdb_add(struct dsa_switch *ds, int port,
>  
>  static int
>  mt7530_port_fdb_del(struct dsa_switch *ds, int port,
> -		    const unsigned char *addr, u16 vid)
> +		    const unsigned char *addr, u16 vid,
> +		    struct dsa_db db)
>  {
>  	struct mt7530_priv *priv = ds->priv;
>  	int ret;
> @@ -1416,7 +1418,8 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
>  
>  static int
>  mt7530_port_mdb_add(struct dsa_switch *ds, int port,
> -		    const struct switchdev_obj_port_mdb *mdb)
> +		    const struct switchdev_obj_port_mdb *mdb,
> +		    struct dsa_db db)
>  {
>  	struct mt7530_priv *priv = ds->priv;
>  	const u8 *addr = mdb->addr;
> @@ -1442,7 +1445,8 @@ mt7530_port_mdb_add(struct dsa_switch *ds, int port,
>  
>  static int
>  mt7530_port_mdb_del(struct dsa_switch *ds, int port,
> -		    const struct switchdev_obj_port_mdb *mdb)
> +		    const struct switchdev_obj_port_mdb *mdb,
> +		    struct dsa_db db)
>  {
>  	struct mt7530_priv *priv = ds->priv;
>  	const u8 *addr = mdb->addr;
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index 1b9a20bf1bd6..d79c65bb227e 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -2456,7 +2456,8 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
>  }
>  
>  static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
> -				  const unsigned char *addr, u16 vid)
> +				  const unsigned char *addr, u16 vid,
> +				  struct dsa_db db)
>  {
>  	struct mv88e6xxx_chip *chip = ds->priv;
>  	int err;
> @@ -2470,7 +2471,8 @@ static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
> -				  const unsigned char *addr, u16 vid)
> +				  const unsigned char *addr, u16 vid,
> +				  struct dsa_db db)
>  {
>  	struct mv88e6xxx_chip *chip = ds->priv;
>  	int err;
> @@ -6002,7 +6004,8 @@ static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds, int port,
>  }
>  
>  static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
> -				  const struct switchdev_obj_port_mdb *mdb)
> +				  const struct switchdev_obj_port_mdb *mdb,
> +				  struct dsa_db db)
>  {
>  	struct mv88e6xxx_chip *chip = ds->priv;
>  	int err;
> @@ -6016,7 +6019,8 @@ static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
> -				  const struct switchdev_obj_port_mdb *mdb)
> +				  const struct switchdev_obj_port_mdb *mdb,
> +				  struct dsa_db db)
>  {
>  	struct mv88e6xxx_chip *chip = ds->priv;
>  	int err;
> diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
> index 04f5da33b944..d92feee97c63 100644
> --- a/drivers/net/dsa/ocelot/felix.c
> +++ b/drivers/net/dsa/ocelot/felix.c
> @@ -592,7 +592,8 @@ static int felix_fdb_dump(struct dsa_switch *ds, int port,
>  }
>  
>  static int felix_fdb_add(struct dsa_switch *ds, int port,
> -			 const unsigned char *addr, u16 vid)
> +			 const unsigned char *addr, u16 vid,
> +			 struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> @@ -600,7 +601,8 @@ static int felix_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int felix_fdb_del(struct dsa_switch *ds, int port,
> -			 const unsigned char *addr, u16 vid)
> +			 const unsigned char *addr, u16 vid,
> +			 struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> @@ -608,7 +610,8 @@ static int felix_fdb_del(struct dsa_switch *ds, int port,
>  }
>  
>  static int felix_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
> -			     const unsigned char *addr, u16 vid)
> +			     const unsigned char *addr, u16 vid,
> +			     struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> @@ -616,7 +619,8 @@ static int felix_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
>  }
>  
>  static int felix_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
> -			     const unsigned char *addr, u16 vid)
> +			     const unsigned char *addr, u16 vid,
> +			     struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> @@ -624,7 +628,8 @@ static int felix_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
>  }
>  
>  static int felix_mdb_add(struct dsa_switch *ds, int port,
> -			 const struct switchdev_obj_port_mdb *mdb)
> +			 const struct switchdev_obj_port_mdb *mdb,
> +			 struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> @@ -632,7 +637,8 @@ static int felix_mdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int felix_mdb_del(struct dsa_switch *ds, int port,
> -			 const struct switchdev_obj_port_mdb *mdb)
> +			 const struct switchdev_obj_port_mdb *mdb,
> +			 struct dsa_db db)
>  {
>  	struct ocelot *ocelot = ds->priv;
>  
> diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> index 6844106975a9..7189fd8120d7 100644
> --- a/drivers/net/dsa/qca8k.c
> +++ b/drivers/net/dsa/qca8k.c
> @@ -2397,7 +2397,8 @@ qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
>  
>  static int
>  qca8k_port_fdb_add(struct dsa_switch *ds, int port,
> -		   const unsigned char *addr, u16 vid)
> +		   const unsigned char *addr, u16 vid,
> +		   struct dsa_db db)
>  {
>  	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
>  	u16 port_mask = BIT(port);
> @@ -2407,7 +2408,8 @@ qca8k_port_fdb_add(struct dsa_switch *ds, int port,
>  
>  static int
>  qca8k_port_fdb_del(struct dsa_switch *ds, int port,
> -		   const unsigned char *addr, u16 vid)
> +		   const unsigned char *addr, u16 vid,
> +		   struct dsa_db db)
>  {
>  	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
>  	u16 port_mask = BIT(port);
> @@ -2444,7 +2446,8 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
>  
>  static int
>  qca8k_port_mdb_add(struct dsa_switch *ds, int port,
> -		   const struct switchdev_obj_port_mdb *mdb)
> +		   const struct switchdev_obj_port_mdb *mdb,
> +		   struct dsa_db db)
>  {
>  	struct qca8k_priv *priv = ds->priv;
>  	const u8 *addr = mdb->addr;
> @@ -2455,7 +2458,8 @@ qca8k_port_mdb_add(struct dsa_switch *ds, int port,
>  
>  static int
>  qca8k_port_mdb_del(struct dsa_switch *ds, int port,
> -		   const struct switchdev_obj_port_mdb *mdb)
> +		   const struct switchdev_obj_port_mdb *mdb,
> +		   struct dsa_db db)
>  {
>  	struct qca8k_priv *priv = ds->priv;
>  	const u8 *addr = mdb->addr;
> diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
> index dd89b077aae6..91b0e636d194 100644
> --- a/drivers/net/dsa/sja1105/sja1105_main.c
> +++ b/drivers/net/dsa/sja1105/sja1105_main.c
> @@ -1819,7 +1819,8 @@ int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
>  }
>  
>  static int sja1105_fdb_add(struct dsa_switch *ds, int port,
> -			   const unsigned char *addr, u16 vid)
> +			   const unsigned char *addr, u16 vid,
> +			   struct dsa_db db)
>  {
>  	struct sja1105_private *priv = ds->priv;
>  
> @@ -1827,7 +1828,8 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
>  }
>  
>  static int sja1105_fdb_del(struct dsa_switch *ds, int port,
> -			   const unsigned char *addr, u16 vid)
> +			   const unsigned char *addr, u16 vid,
> +			   struct dsa_db db)
>  {
>  	struct sja1105_private *priv = ds->priv;
>  
> @@ -1885,7 +1887,15 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
>  
>  static void sja1105_fast_age(struct dsa_switch *ds, int port)
>  {
> +	struct dsa_port *dp = dsa_to_port(ds, port);
>  	struct sja1105_private *priv = ds->priv;
> +	struct dsa_db db = {
> +		.type = DSA_DB_BRIDGE,
> +		.bridge = {
> +			.dev = dsa_port_bridge_dev_get(dp),
> +			.num = dsa_port_bridge_num_get(dp),
> +		},
> +	};
>  	int i;
>  
>  	for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) {
> @@ -1913,7 +1923,7 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
>  
>  		u64_to_ether_addr(l2_lookup.macaddr, macaddr);
>  
> -		rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid);
> +		rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db);
>  		if (rc) {
>  			dev_err(ds->dev,
>  				"Failed to delete FDB entry %pM vid %lld: %pe\n",
> @@ -1924,15 +1934,17 @@ static void sja1105_fast_age(struct dsa_switch *ds, int port)
>  }
>  
>  static int sja1105_mdb_add(struct dsa_switch *ds, int port,
> -			   const struct switchdev_obj_port_mdb *mdb)
> +			   const struct switchdev_obj_port_mdb *mdb,
> +			   struct dsa_db db)
>  {
> -	return sja1105_fdb_add(ds, port, mdb->addr, mdb->vid);
> +	return sja1105_fdb_add(ds, port, mdb->addr, mdb->vid, db);
>  }
>  
>  static int sja1105_mdb_del(struct dsa_switch *ds, int port,
> -			   const struct switchdev_obj_port_mdb *mdb)
> +			   const struct switchdev_obj_port_mdb *mdb,
> +			   struct dsa_db db)
>  {
> -	return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid);
> +	return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid, db);
>  }
>  
>  /* Common function for unicast and broadcast flood configuration.
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index 01faba89c987..87c5f18eb381 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -341,11 +341,28 @@ struct dsa_link {
>  	struct list_head list;
>  };
>  
> +enum dsa_db_type {
> +	DSA_DB_PORT,
> +	DSA_DB_LAG,
> +	DSA_DB_BRIDGE,
> +};
> +
> +struct dsa_db {
> +	enum dsa_db_type type;
> +
> +	union {
> +		const struct dsa_port *dp;
> +		struct dsa_lag lag;
> +		struct dsa_bridge bridge;
> +	};
> +};
> +
>  struct dsa_mac_addr {
>  	unsigned char addr[ETH_ALEN];
>  	u16 vid;
>  	refcount_t refcount;
>  	struct list_head list;
> +	struct dsa_db db;
>  };
>  
>  struct dsa_vlan {
> @@ -409,6 +426,13 @@ struct dsa_switch {
>  	 */
>  	u32			mtu_enforcement_ingress:1;
>  
> +	/* Drivers that isolate the FDBs of multiple bridges must set this
> +	 * to true to receive the bridge as an argument in .port_fdb_{add,del}
> +	 * and .port_mdb_{add,del}. Otherwise, the bridge.num will always be
> +	 * passed as zero.
> +	 */
> +	u32			fdb_isolation:1;
> +
>  	/* Listener for switch fabric events */
>  	struct notifier_block	nb;
>  
> @@ -941,23 +965,29 @@ struct dsa_switch_ops {
>  	 * Forwarding database
>  	 */
>  	int	(*port_fdb_add)(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid);
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db);

Hi! Wouldn't it be better to have a struct that has all the functions
parameters in one instead of adding further parameters to these
functions?

I am asking because I am also needing to add a parameter to
port_fdb_add(), and it would be more future oriented to have a single
function parameter as a struct, so that it is easier to add parameters
to these functions without havíng to change the prototype of the
function every time.

>  	int	(*port_fdb_del)(struct dsa_switch *ds, int port,
> -				const unsigned char *addr, u16 vid);
> +				const unsigned char *addr, u16 vid,
> +				struct dsa_db db);
>  	int	(*port_fdb_dump)(struct dsa_switch *ds, int port,
>  				 dsa_fdb_dump_cb_t *cb, void *data);
>  	int	(*lag_fdb_add)(struct dsa_switch *ds, struct dsa_lag lag,
> -			       const unsigned char *addr, u16 vid);
> +			       const unsigned char *addr, u16 vid,
> +			       struct dsa_db db);
>  	int	(*lag_fdb_del)(struct dsa_switch *ds, struct dsa_lag lag,
> -			       const unsigned char *addr, u16 vid);
> +			       const unsigned char *addr, u16 vid,
> +			       struct dsa_db db);
>  
>  	/*
>  	 * Multicast database
>  	 */
>  	int	(*port_mdb_add)(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb);
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db);
>  	int	(*port_mdb_del)(struct dsa_switch *ds, int port,
> -				const struct switchdev_obj_port_mdb *mdb);
> +				const struct switchdev_obj_port_mdb *mdb,
> +				struct dsa_db db);
>  	/*
>  	 * RXNFC
>  	 */
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index 7a1c98581f53..27575fc3883e 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -67,6 +67,7 @@ struct dsa_notifier_fdb_info {
>  	int port;
>  	const unsigned char *addr;
>  	u16 vid;
> +	struct dsa_db db;
>  };
>  
>  /* DSA_NOTIFIER_LAG_FDB_* */
> @@ -74,6 +75,7 @@ struct dsa_notifier_lag_fdb_info {
>  	struct dsa_lag *lag;
>  	const unsigned char *addr;
>  	u16 vid;
> +	struct dsa_db db;
>  };
>  
>  /* DSA_NOTIFIER_MDB_* */
> @@ -81,6 +83,7 @@ struct dsa_notifier_mdb_info {
>  	const struct switchdev_obj_port_mdb *mdb;
>  	int sw_index;
>  	int port;
> +	struct dsa_db db;
>  };
>  
>  /* DSA_NOTIFIER_LAG_* */
> diff --git a/net/dsa/port.c b/net/dsa/port.c
> index adab159c8c21..7af44a28f032 100644
> --- a/net/dsa/port.c
> +++ b/net/dsa/port.c
> @@ -798,8 +798,19 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  		.port = dp->index,
>  		.addr = addr,
>  		.vid = vid,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	/* Refcounting takes bridge.num as a key, and should be global for all
> +	 * bridges in the absence of FDB isolation, and per bridge otherwise.
> +	 * Force the bridge.num to zero here in the absence of FDB isolation.
> +	 */
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
>  }
>  
> @@ -811,9 +822,15 @@ int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  		.port = dp->index,
>  		.addr = addr,
>  		.vid = vid,
> -
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
>  }
>  
> @@ -825,6 +842,10 @@ int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  		.port = dp->index,
>  		.addr = addr,
>  		.vid = vid,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  	struct dsa_port *cpu_dp = dp->cpu_dp;
>  	int err;
> @@ -839,6 +860,9 @@ int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  			return err;
>  	}
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
>  }
>  
> @@ -850,6 +874,10 @@ int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  		.port = dp->index,
>  		.addr = addr,
>  		.vid = vid,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  	struct dsa_port *cpu_dp = dp->cpu_dp;
>  	int err;
> @@ -860,6 +888,9 @@ int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  			return err;
>  	}
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_DEL, &info);
>  }
>  
> @@ -870,8 +901,15 @@ int dsa_port_lag_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  		.lag = dp->lag,
>  		.addr = addr,
>  		.vid = vid,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_LAG_FDB_ADD, &info);
>  }
>  
> @@ -882,8 +920,15 @@ int dsa_port_lag_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  		.lag = dp->lag,
>  		.addr = addr,
>  		.vid = vid,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_LAG_FDB_DEL, &info);
>  }
>  
> @@ -905,8 +950,15 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
>  		.sw_index = dp->ds->index,
>  		.port = dp->index,
>  		.mdb = mdb,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
>  }
>  
> @@ -917,8 +969,15 @@ int dsa_port_mdb_del(const struct dsa_port *dp,
>  		.sw_index = dp->ds->index,
>  		.port = dp->index,
>  		.mdb = mdb,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
>  }
>  
> @@ -929,6 +988,10 @@ int dsa_port_host_mdb_add(const struct dsa_port *dp,
>  		.sw_index = dp->ds->index,
>  		.port = dp->index,
>  		.mdb = mdb,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  	struct dsa_port *cpu_dp = dp->cpu_dp;
>  	int err;
> @@ -937,6 +1000,9 @@ int dsa_port_host_mdb_add(const struct dsa_port *dp,
>  	if (err)
>  		return err;
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_ADD, &info);
>  }
>  
> @@ -947,6 +1013,10 @@ int dsa_port_host_mdb_del(const struct dsa_port *dp,
>  		.sw_index = dp->ds->index,
>  		.port = dp->index,
>  		.mdb = mdb,
> +		.db = {
> +			.type = DSA_DB_BRIDGE,
> +			.bridge = *dp->bridge,
> +		},
>  	};
>  	struct dsa_port *cpu_dp = dp->cpu_dp;
>  	int err;
> @@ -955,6 +1025,9 @@ int dsa_port_host_mdb_del(const struct dsa_port *dp,
>  	if (err)
>  		return err;
>  
> +	if (!dp->ds->fdb_isolation)
> +		info.db.bridge.num = 0;
> +
>  	return dsa_port_notify(dp, DSA_NOTIFIER_HOST_MDB_DEL, &info);
>  }
>  
> diff --git a/net/dsa/switch.c b/net/dsa/switch.c
> index eb38beb10147..1d3c161e3131 100644
> --- a/net/dsa/switch.c
> +++ b/net/dsa/switch.c
> @@ -210,21 +210,41 @@ static bool dsa_port_host_address_match(struct dsa_port *dp,
>  	return false;
>  }
>  
> +static bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b)
> +{
> +	if (a->type != b->type)
> +		return false;
> +
> +	switch (a->type) {
> +	case DSA_DB_PORT:
> +		return a->dp == b->dp;
> +	case DSA_DB_LAG:
> +		return a->lag.dev == b->lag.dev;
> +	case DSA_DB_BRIDGE:
> +		return a->bridge.num == b->bridge.num;
> +	default:
> +		WARN_ON(1);
> +		return false;
> +	}
> +}
> +
>  static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
> -					      const unsigned char *addr,
> -					      u16 vid)
> +					      const unsigned char *addr, u16 vid,
> +					      struct dsa_db db)
>  {
>  	struct dsa_mac_addr *a;
>  
>  	list_for_each_entry(a, addr_list, list)
> -		if (ether_addr_equal(a->addr, addr) && a->vid == vid)
> +		if (ether_addr_equal(a->addr, addr) && a->vid == vid &&
> +		    dsa_db_equal(&a->db, &db))
>  			return a;
>  
>  	return NULL;
>  }
>  
>  static int dsa_port_do_mdb_add(struct dsa_port *dp,
> -			       const struct switchdev_obj_port_mdb *mdb)
> +			       const struct switchdev_obj_port_mdb *mdb,
> +			       struct dsa_db db)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	struct dsa_mac_addr *a;
> @@ -233,11 +253,11 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
>  
>  	/* No need to bother with refcounting for user ports */
>  	if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
> -		return ds->ops->port_mdb_add(ds, port, mdb);
> +		return ds->ops->port_mdb_add(ds, port, mdb, db);
>  
>  	mutex_lock(&dp->addr_lists_lock);
>  
> -	a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
> +	a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
>  	if (a) {
>  		refcount_inc(&a->refcount);
>  		goto out;
> @@ -249,7 +269,7 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
>  		goto out;
>  	}
>  
> -	err = ds->ops->port_mdb_add(ds, port, mdb);
> +	err = ds->ops->port_mdb_add(ds, port, mdb, db);
>  	if (err) {
>  		kfree(a);
>  		goto out;
> @@ -257,6 +277,7 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
>  
>  	ether_addr_copy(a->addr, mdb->addr);
>  	a->vid = mdb->vid;
> +	a->db = db;
>  	refcount_set(&a->refcount, 1);
>  	list_add_tail(&a->list, &dp->mdbs);
>  
> @@ -267,7 +288,8 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp,
>  }
>  
>  static int dsa_port_do_mdb_del(struct dsa_port *dp,
> -			       const struct switchdev_obj_port_mdb *mdb)
> +			       const struct switchdev_obj_port_mdb *mdb,
> +			       struct dsa_db db)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	struct dsa_mac_addr *a;
> @@ -276,11 +298,11 @@ static int dsa_port_do_mdb_del(struct dsa_port *dp,
>  
>  	/* No need to bother with refcounting for user ports */
>  	if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
> -		return ds->ops->port_mdb_del(ds, port, mdb);
> +		return ds->ops->port_mdb_del(ds, port, mdb, db);
>  
>  	mutex_lock(&dp->addr_lists_lock);
>  
> -	a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
> +	a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
>  	if (!a) {
>  		err = -ENOENT;
>  		goto out;
> @@ -289,7 +311,7 @@ static int dsa_port_do_mdb_del(struct dsa_port *dp,
>  	if (!refcount_dec_and_test(&a->refcount))
>  		goto out;
>  
> -	err = ds->ops->port_mdb_del(ds, port, mdb);
> +	err = ds->ops->port_mdb_del(ds, port, mdb, db);
>  	if (err) {
>  		refcount_set(&a->refcount, 1);
>  		goto out;
> @@ -305,7 +327,7 @@ static int dsa_port_do_mdb_del(struct dsa_port *dp,
>  }
>  
>  static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
> -			       u16 vid)
> +			       u16 vid, struct dsa_db db)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	struct dsa_mac_addr *a;
> @@ -314,11 +336,11 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  
>  	/* No need to bother with refcounting for user ports */
>  	if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
> -		return ds->ops->port_fdb_add(ds, port, addr, vid);
> +		return ds->ops->port_fdb_add(ds, port, addr, vid, db);
>  
>  	mutex_lock(&dp->addr_lists_lock);
>  
> -	a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
> +	a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
>  	if (a) {
>  		refcount_inc(&a->refcount);
>  		goto out;
> @@ -330,7 +352,7 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  		goto out;
>  	}
>  
> -	err = ds->ops->port_fdb_add(ds, port, addr, vid);
> +	err = ds->ops->port_fdb_add(ds, port, addr, vid, db);
>  	if (err) {
>  		kfree(a);
>  		goto out;
> @@ -338,6 +360,7 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  
>  	ether_addr_copy(a->addr, addr);
>  	a->vid = vid;
> +	a->db = db;
>  	refcount_set(&a->refcount, 1);
>  	list_add_tail(&a->list, &dp->fdbs);
>  
> @@ -348,7 +371,7 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
>  }
>  
>  static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
> -			       u16 vid)
> +			       u16 vid, struct dsa_db db)
>  {
>  	struct dsa_switch *ds = dp->ds;
>  	struct dsa_mac_addr *a;
> @@ -357,11 +380,11 @@ static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  
>  	/* No need to bother with refcounting for user ports */
>  	if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
> -		return ds->ops->port_fdb_del(ds, port, addr, vid);
> +		return ds->ops->port_fdb_del(ds, port, addr, vid, db);
>  
>  	mutex_lock(&dp->addr_lists_lock);
>  
> -	a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
> +	a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
>  	if (!a) {
>  		err = -ENOENT;
>  		goto out;
> @@ -370,7 +393,7 @@ static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  	if (!refcount_dec_and_test(&a->refcount))
>  		goto out;
>  
> -	err = ds->ops->port_fdb_del(ds, port, addr, vid);
> +	err = ds->ops->port_fdb_del(ds, port, addr, vid, db);
>  	if (err) {
>  		refcount_set(&a->refcount, 1);
>  		goto out;
> @@ -386,14 +409,15 @@ static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
>  }
>  
>  static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
> -				     const unsigned char *addr, u16 vid)
> +				     const unsigned char *addr, u16 vid,
> +				     struct dsa_db db)
>  {
>  	struct dsa_mac_addr *a;
>  	int err = 0;
>  
>  	mutex_lock(&lag->fdb_lock);
>  
> -	a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
> +	a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
>  	if (a) {
>  		refcount_inc(&a->refcount);
>  		goto out;
> @@ -405,7 +429,7 @@ static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
>  		goto out;
>  	}
>  
> -	err = ds->ops->lag_fdb_add(ds, *lag, addr, vid);
> +	err = ds->ops->lag_fdb_add(ds, *lag, addr, vid, db);
>  	if (err) {
>  		kfree(a);
>  		goto out;
> @@ -423,14 +447,15 @@ static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
>  }
>  
>  static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
> -				     const unsigned char *addr, u16 vid)
> +				     const unsigned char *addr, u16 vid,
> +				     struct dsa_db db)
>  {
>  	struct dsa_mac_addr *a;
>  	int err = 0;
>  
>  	mutex_lock(&lag->fdb_lock);
>  
> -	a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
> +	a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
>  	if (!a) {
>  		err = -ENOENT;
>  		goto out;
> @@ -439,7 +464,7 @@ static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
>  	if (!refcount_dec_and_test(&a->refcount))
>  		goto out;
>  
> -	err = ds->ops->lag_fdb_del(ds, *lag, addr, vid);
> +	err = ds->ops->lag_fdb_del(ds, *lag, addr, vid, db);
>  	if (err) {
>  		refcount_set(&a->refcount, 1);
>  		goto out;
> @@ -466,7 +491,8 @@ static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds) {
>  		if (dsa_port_host_address_match(dp, info->sw_index,
>  						info->port)) {
> -			err = dsa_port_do_fdb_add(dp, info->addr, info->vid);
> +			err = dsa_port_do_fdb_add(dp, info->addr, info->vid,
> +						  info->db);
>  			if (err)
>  				break;
>  		}
> @@ -487,7 +513,8 @@ static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds) {
>  		if (dsa_port_host_address_match(dp, info->sw_index,
>  						info->port)) {
> -			err = dsa_port_do_fdb_del(dp, info->addr, info->vid);
> +			err = dsa_port_do_fdb_del(dp, info->addr, info->vid,
> +						  info->db);
>  			if (err)
>  				break;
>  		}
> @@ -505,7 +532,7 @@ static int dsa_switch_fdb_add(struct dsa_switch *ds,
>  	if (!ds->ops->port_fdb_add)
>  		return -EOPNOTSUPP;
>  
> -	return dsa_port_do_fdb_add(dp, info->addr, info->vid);
> +	return dsa_port_do_fdb_add(dp, info->addr, info->vid, info->db);
>  }
>  
>  static int dsa_switch_fdb_del(struct dsa_switch *ds,
> @@ -517,7 +544,7 @@ static int dsa_switch_fdb_del(struct dsa_switch *ds,
>  	if (!ds->ops->port_fdb_del)
>  		return -EOPNOTSUPP;
>  
> -	return dsa_port_do_fdb_del(dp, info->addr, info->vid);
> +	return dsa_port_do_fdb_del(dp, info->addr, info->vid, info->db);
>  }
>  
>  static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
> @@ -532,7 +559,8 @@ static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds)
>  		if (dsa_port_offloads_lag(dp, info->lag))
>  			return dsa_switch_do_lag_fdb_add(ds, info->lag,
> -							 info->addr, info->vid);
> +							 info->addr, info->vid,
> +							 info->db);
>  
>  	return 0;
>  }
> @@ -549,7 +577,8 @@ static int dsa_switch_lag_fdb_del(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds)
>  		if (dsa_port_offloads_lag(dp, info->lag))
>  			return dsa_switch_do_lag_fdb_del(ds, info->lag,
> -							 info->addr, info->vid);
> +							 info->addr, info->vid,
> +							 info->db);
>  
>  	return 0;
>  }
> @@ -604,7 +633,7 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds,
>  	if (!ds->ops->port_mdb_add)
>  		return -EOPNOTSUPP;
>  
> -	return dsa_port_do_mdb_add(dp, info->mdb);
> +	return dsa_port_do_mdb_add(dp, info->mdb, info->db);
>  }
>  
>  static int dsa_switch_mdb_del(struct dsa_switch *ds,
> @@ -616,7 +645,7 @@ static int dsa_switch_mdb_del(struct dsa_switch *ds,
>  	if (!ds->ops->port_mdb_del)
>  		return -EOPNOTSUPP;
>  
> -	return dsa_port_do_mdb_del(dp, info->mdb);
> +	return dsa_port_do_mdb_del(dp, info->mdb, info->db);
>  }
>  
>  static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
> @@ -631,7 +660,7 @@ static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds) {
>  		if (dsa_port_host_address_match(dp, info->sw_index,
>  						info->port)) {
> -			err = dsa_port_do_mdb_add(dp, info->mdb);
> +			err = dsa_port_do_mdb_add(dp, info->mdb, info->db);
>  			if (err)
>  				break;
>  		}
> @@ -652,7 +681,7 @@ static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
>  	dsa_switch_for_each_port(dp, ds) {
>  		if (dsa_port_host_address_match(dp, info->sw_index,
>  						info->port)) {
> -			err = dsa_port_do_mdb_del(dp, info->mdb);
> +			err = dsa_port_do_mdb_del(dp, info->mdb, info->db);
>  			if (err)
>  				break;
>  		}
> -- 
> 2.25.1

  reply	other threads:[~2022-04-26 15:02 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-25  9:22 [PATCH v2 net-next 00/10] DSA FDB isolation Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 01/10] net: dsa: tag_8021q: replace the SVL bridging with VLAN-unaware IVL bridging Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 02/10] net: dsa: tag_8021q: add support for imprecise RX based on the VBID Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 03/10] docs: net: dsa: sja1105: document limitations of tc-flower rule VLAN awareness Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 04/10] net: dsa: felix: delete workarounds present due to SVL tag_8021q bridging Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 05/10] net: dsa: tag_8021q: merge RX and TX VLANs Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 06/10] net: dsa: tag_8021q: rename dsa_8021q_bridge_tx_fwd_offload_vid Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 07/10] net: dsa: request drivers to perform FDB isolation Vladimir Oltean
2022-04-26 15:01   ` Hans Schultz [this message]
2022-04-26 16:14     ` Andrew Lunn
2022-04-26 23:17       ` Vladimir Oltean
2022-04-27  8:38         ` Hans Schultz
2022-04-27 10:32           ` Vladimir Oltean
2022-04-27 11:06             ` Hans Schultz
2022-04-27  6:45       ` Hans Schultz
2022-02-25  9:22 ` [PATCH v2 net-next 08/10] net: dsa: pass extack to .port_bridge_join driver methods Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 09/10] net: dsa: sja1105: enforce FDB isolation Vladimir Oltean
2022-02-25  9:22 ` [PATCH v2 net-next 10/10] net: mscc: ocelot: enforce FDB isolation when VLAN-unaware Vladimir Oltean
2022-02-27 11:10 ` [PATCH v2 net-next 00/10] DSA FDB isolation patchwork-bot+netdevbpf

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=867d7bga78.fsf@gmail.com \
    --to=schultz.hans@gmail.com \
    --cc=Landen.Chao@mediatek.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=alsi@bang-olufsen.dk \
    --cc=andrew@lunn.ch \
    --cc=claudiu.manoil@nxp.com \
    --cc=davem@davemloft.net \
    --cc=dqfext@gmail.com \
    --cc=f.fainelli@gmail.com \
    --cc=george.mccollister@gmail.com \
    --cc=hauke@hauke-m.de \
    --cc=kuba@kernel.org \
    --cc=kurt@linutronix.de \
    --cc=linus.walleij@linaro.org \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=sean.wang@mediatek.com \
    --cc=vivien.didelot@gmail.com \
    --cc=vladimir.oltean@nxp.com \
    --cc=woojung.huh@microchip.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 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).