@@ -1712,7 +1712,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,
+ const struct net_device *br)
{
struct b53_device *priv = ds->priv;
@@ -1727,7 +1728,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,
+ const struct net_device *br)
{
struct b53_device *priv = ds->priv;
@@ -1819,7 +1821,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,
+ const struct net_device *br)
{
struct b53_device *priv = ds->priv;
@@ -1834,7 +1837,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,
+ const struct net_device *br)
{
struct b53_device *priv = ds->priv;
int ret;
@@ -358,15 +358,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,
+ const struct net_device *br);
int b53_fdb_del(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid);
+ const unsigned char *addr, u16 vid,
+ const struct net_device *br);
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,
+ const struct net_device *br);
int b53_mdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb);
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct net_device *br);
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,
@@ -826,7 +826,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,
+ const struct net_device *br)
{
struct hellcreek_fdb_entry entry = { 0 };
struct hellcreek *hellcreek = ds->priv;
@@ -871,7 +872,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,
+ const struct net_device *br)
{
struct hellcreek_fdb_entry entry = { 0 };
struct hellcreek *hellcreek = ds->priv;
@@ -1181,7 +1181,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,
+ const struct net_device *br)
{
struct lan9303 *chip = ds->priv;
@@ -1193,8 +1194,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,
+ const struct net_device *br)
{
struct lan9303 *chip = ds->priv;
@@ -1238,7 +1239,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,
+ const struct net_device *br)
{
struct lan9303 *chip = ds->priv;
int err;
@@ -1253,7 +1255,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,
+ const struct net_device *br)
{
struct lan9303 *chip = ds->priv;
@@ -1364,13 +1364,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,
+ const struct net_device *br)
{
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,
+ const struct net_device *br)
{
return gswip_port_fdb(ds, port, addr, vid, false);
}
@@ -583,7 +583,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
u32 alu_table[4];
@@ -640,7 +641,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
u32 alu_table[4];
@@ -782,7 +784,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
u32 static_table[4];
@@ -857,7 +860,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
u32 static_table[4];
@@ -246,7 +246,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
struct alu_struct alu;
@@ -291,7 +292,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,
+ const struct net_device *br)
{
struct ksz_device *dev = ds->priv;
struct alu_struct alu;
@@ -167,9 +167,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,
+ const struct net_device *br);
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,
+ const struct net_device *br);
int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy);
/* Common register access functions */
@@ -1348,7 +1348,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,
+ const struct net_device *br)
{
struct mt7530_priv *priv = ds->priv;
int ret;
@@ -1364,7 +1365,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,
+ const struct net_device *br)
{
struct mt7530_priv *priv = ds->priv;
int ret;
@@ -1415,7 +1417,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,
+ const struct net_device *br)
{
struct mt7530_priv *priv = ds->priv;
const u8 *addr = mdb->addr;
@@ -1441,7 +1444,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,
+ const struct net_device *br)
{
struct mt7530_priv *priv = ds->priv;
const u8 *addr = mdb->addr;
@@ -2241,7 +2241,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,
+ const struct net_device *br)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
@@ -2255,7 +2256,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,
+ const struct net_device *br)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
@@ -5682,7 +5684,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,
+ const struct net_device *br)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
@@ -5696,7 +5699,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,
+ const struct net_device *br)
{
struct mv88e6xxx_chip *chip = ds->priv;
int err;
@@ -628,7 +628,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,
+ const struct net_device *br)
{
struct ocelot *ocelot = ds->priv;
@@ -636,7 +637,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,
+ const struct net_device *br)
{
struct ocelot *ocelot = ds->priv;
@@ -644,7 +646,8 @@ static int felix_fdb_del(struct dsa_switch *ds, int port,
}
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,
+ const struct net_device *br)
{
struct ocelot *ocelot = ds->priv;
@@ -652,7 +655,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,
+ const struct net_device *br)
{
struct ocelot *ocelot = ds->priv;
@@ -1619,7 +1619,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,
+ const struct net_device *br)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
u16 port_mask = BIT(port);
@@ -1629,7 +1630,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,
+ const struct net_device *br)
{
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
u16 port_mask = BIT(port);
@@ -1731,7 +1731,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,
+ const struct net_device *br)
{
struct sja1105_private *priv = ds->priv;
@@ -1739,7 +1740,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,
+ const struct net_device *br)
{
struct sja1105_private *priv = ds->priv;
@@ -1796,6 +1798,7 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
static void sja1105_fast_age(struct dsa_switch *ds, int port)
{
+ const struct net_device *br = dsa_to_port(ds, port)->bridge_dev;
struct sja1105_private *priv = ds->priv;
int i;
@@ -1824,7 +1827,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, br);
if (rc) {
dev_err(ds->dev,
"Failed to delete FDB entry %pM vid %lld: %pe\n",
@@ -1835,15 +1838,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,
+ const struct net_device *br)
{
- return sja1105_fdb_add(ds, port, mdb->addr, mdb->vid);
+ return sja1105_fdb_add(ds, port, mdb->addr, mdb->vid, br);
}
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,
+ const struct net_device *br)
{
- return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid);
+ return sja1105_fdb_del(ds, port, mdb->addr, mdb->vid, br);
}
/* Common function for unicast and broadcast flood configuration.
@@ -305,6 +305,7 @@ struct dsa_link {
struct dsa_mac_addr {
unsigned char addr[ETH_ALEN];
u16 vid;
+ const struct net_device *br;
refcount_t refcount;
struct list_head list;
};
@@ -731,9 +732,11 @@ 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,
+ const struct net_device *br);
int (*port_fdb_del)(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid);
+ const unsigned char *addr, u16 vid,
+ const struct net_device *br);
int (*port_fdb_dump)(struct dsa_switch *ds, int port,
dsa_fdb_dump_cb_t *cb, void *data);
@@ -741,9 +744,11 @@ struct dsa_switch_ops {
* 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,
+ const struct net_device *br);
int (*port_mdb_del)(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb);
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct net_device *br);
/*
* RXNFC
*/
@@ -66,6 +66,7 @@ struct dsa_notifier_fdb_info {
int port;
const unsigned char *addr;
u16 vid;
+ const struct net_device *br;
};
/* DSA_NOTIFIER_MDB_* */
@@ -73,6 +74,7 @@ struct dsa_notifier_mdb_info {
const struct switchdev_obj_port_mdb *mdb;
int sw_index;
int port;
+ const struct net_device *br;
};
/* DSA_NOTIFIER_LAG_* */
@@ -739,6 +739,7 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
.port = dp->index,
.addr = addr,
.vid = vid,
+ .br = dp->bridge_dev,
};
return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info);
@@ -752,7 +753,7 @@ int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
.port = dp->index,
.addr = addr,
.vid = vid,
-
+ .br = dp->bridge_dev,
};
return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
@@ -766,6 +767,7 @@ int dsa_port_host_fdb_add(struct dsa_port *dp, const unsigned char *addr,
.port = dp->index,
.addr = addr,
.vid = vid,
+ .br = dp->bridge_dev,
};
struct dsa_port *cpu_dp = dp->cpu_dp;
int err;
@@ -785,6 +787,7 @@ int dsa_port_host_fdb_del(struct dsa_port *dp, const unsigned char *addr,
.port = dp->index,
.addr = addr,
.vid = vid,
+ .br = dp->bridge_dev,
};
struct dsa_port *cpu_dp = dp->cpu_dp;
int err;
@@ -814,6 +817,7 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
.sw_index = dp->ds->index,
.port = dp->index,
.mdb = mdb,
+ .br = dp->bridge_dev,
};
return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info);
@@ -826,6 +830,7 @@ int dsa_port_mdb_del(const struct dsa_port *dp,
.sw_index = dp->ds->index,
.port = dp->index,
.mdb = mdb,
+ .br = dp->bridge_dev,
};
return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info);
@@ -838,6 +843,7 @@ int dsa_port_host_mdb_add(const struct dsa_port *dp,
.sw_index = dp->ds->index,
.port = dp->index,
.mdb = mdb,
+ .br = dp->bridge_dev,
};
struct dsa_port *cpu_dp = dp->cpu_dp;
int err;
@@ -856,6 +862,7 @@ int dsa_port_host_mdb_del(const struct dsa_port *dp,
.sw_index = dp->ds->index,
.port = dp->index,
.mdb = mdb,
+ .br = dp->bridge_dev,
};
struct dsa_port *cpu_dp = dp->cpu_dp;
int err;
@@ -188,20 +188,22 @@ static bool dsa_switch_host_address_match(struct dsa_switch *ds, int port,
}
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,
+ const struct net_device *br)
{
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 &&
+ a->br == br)
return a;
return NULL;
}
static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb)
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct net_device *br)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
@@ -209,9 +211,9 @@ static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
/* 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, br);
- a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
+ a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, br);
if (a) {
refcount_inc(&a->refcount);
return 0;
@@ -221,7 +223,7 @@ static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
if (!a)
return -ENOMEM;
- err = ds->ops->port_mdb_add(ds, port, mdb);
+ err = ds->ops->port_mdb_add(ds, port, mdb, br);
if (err) {
kfree(a);
return err;
@@ -229,6 +231,7 @@ static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
ether_addr_copy(a->addr, mdb->addr);
a->vid = mdb->vid;
+ a->br = br;
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->mdbs);
@@ -236,7 +239,8 @@ static int dsa_switch_do_mdb_add(struct dsa_switch *ds, int port,
}
static int dsa_switch_do_mdb_del(struct dsa_switch *ds, int port,
- const struct switchdev_obj_port_mdb *mdb)
+ const struct switchdev_obj_port_mdb *mdb,
+ const struct net_device *br)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
@@ -244,16 +248,16 @@ static int dsa_switch_do_mdb_del(struct dsa_switch *ds, int port,
/* 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, br);
- a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
+ a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, br);
if (!a)
return -ENOENT;
if (!refcount_dec_and_test(&a->refcount))
return 0;
- err = ds->ops->port_mdb_del(ds, port, mdb);
+ err = ds->ops->port_mdb_del(ds, port, mdb, br);
if (err) {
refcount_inc(&a->refcount);
return err;
@@ -266,7 +270,8 @@ static int dsa_switch_do_mdb_del(struct dsa_switch *ds, int port,
}
static int dsa_switch_do_fdb_add(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ const struct net_device *br)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
@@ -274,9 +279,9 @@ static int dsa_switch_do_fdb_add(struct dsa_switch *ds, int port,
/* 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, br);
- a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&dp->fdbs, addr, vid, br);
if (a) {
refcount_inc(&a->refcount);
return 0;
@@ -286,7 +291,7 @@ static int dsa_switch_do_fdb_add(struct dsa_switch *ds, int port,
if (!a)
return -ENOMEM;
- err = ds->ops->port_fdb_add(ds, port, addr, vid);
+ err = ds->ops->port_fdb_add(ds, port, addr, vid, br);
if (err) {
kfree(a);
return err;
@@ -294,6 +299,7 @@ static int dsa_switch_do_fdb_add(struct dsa_switch *ds, int port,
ether_addr_copy(a->addr, addr);
a->vid = vid;
+ a->br = br;
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->fdbs);
@@ -301,7 +307,8 @@ static int dsa_switch_do_fdb_add(struct dsa_switch *ds, int port,
}
static int dsa_switch_do_fdb_del(struct dsa_switch *ds, int port,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ const struct net_device *br)
{
struct dsa_port *dp = dsa_to_port(ds, port);
struct dsa_mac_addr *a;
@@ -309,16 +316,16 @@ static int dsa_switch_do_fdb_del(struct dsa_switch *ds, int port,
/* 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, br);
- a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&dp->fdbs, addr, vid, br);
if (!a)
return -ENOENT;
if (!refcount_dec_and_test(&a->refcount))
return 0;
- err = ds->ops->port_fdb_del(ds, port, addr, vid);
+ err = ds->ops->port_fdb_del(ds, port, addr, vid, br);
if (err) {
refcount_inc(&a->refcount);
return err;
@@ -343,7 +350,7 @@ static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
if (dsa_switch_host_address_match(ds, port, info->sw_index,
info->port)) {
err = dsa_switch_do_fdb_add(ds, port, info->addr,
- info->vid);
+ info->vid, info->br);
if (err)
break;
}
@@ -365,7 +372,7 @@ static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
if (dsa_switch_host_address_match(ds, port, info->sw_index,
info->port)) {
err = dsa_switch_do_fdb_del(ds, port, info->addr,
- info->vid);
+ info->vid, info->br);
if (err)
break;
}
@@ -382,7 +389,7 @@ static int dsa_switch_fdb_add(struct dsa_switch *ds,
if (!ds->ops->port_fdb_add)
return -EOPNOTSUPP;
- return dsa_switch_do_fdb_add(ds, port, info->addr, info->vid);
+ return dsa_switch_do_fdb_add(ds, port, info->addr, info->vid, info->br);
}
static int dsa_switch_fdb_del(struct dsa_switch *ds,
@@ -393,7 +400,7 @@ static int dsa_switch_fdb_del(struct dsa_switch *ds,
if (!ds->ops->port_fdb_del)
return -EOPNOTSUPP;
- return dsa_switch_do_fdb_del(ds, port, info->addr, info->vid);
+ return dsa_switch_do_fdb_del(ds, port, info->addr, info->vid, info->br);
}
static int dsa_switch_hsr_join(struct dsa_switch *ds,
@@ -463,7 +470,7 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds,
if (!ds->ops->port_mdb_add)
return -EOPNOTSUPP;
- return dsa_switch_do_mdb_add(ds, port, info->mdb);
+ return dsa_switch_do_mdb_add(ds, port, info->mdb, info->br);
}
static int dsa_switch_mdb_del(struct dsa_switch *ds,
@@ -474,7 +481,7 @@ static int dsa_switch_mdb_del(struct dsa_switch *ds,
if (!ds->ops->port_mdb_del)
return -EOPNOTSUPP;
- return dsa_switch_do_mdb_del(ds, port, info->mdb);
+ return dsa_switch_do_mdb_del(ds, port, info->mdb, info->br);
}
static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
@@ -489,7 +496,8 @@ static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
for (port = 0; port < ds->num_ports; port++) {
if (dsa_switch_host_address_match(ds, port, info->sw_index,
info->port)) {
- err = dsa_switch_do_mdb_add(ds, port, info->mdb);
+ err = dsa_switch_do_mdb_add(ds, port, info->mdb,
+ info->br);
if (err)
break;
}
@@ -510,7 +518,8 @@ static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
for (port = 0; port < ds->num_ports; port++) {
if (dsa_switch_host_address_match(ds, port, info->sw_index,
info->port)) {
- err = dsa_switch_do_mdb_del(ds, port, info->mdb);
+ err = dsa_switch_do_mdb_del(ds, port, info->mdb,
+ info->br);
if (err)
break;
}
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. One might obviously ask: why do you pass the bridge_dev all the way to drivers, can't they just look at dsa_to_port(ds, port)->bridge_dev?! Well, no. While that might work for user ports, it does not work for CPU and DSA ports. Those service multiple bridges, of course. When dsa_port_host_fdb_add(dp) is called, the driver is notified on dp->cpu_dp. So it loses the information about the original dp, so it cannot access dp->bridge_dev. But notice that at least we don't explicitly pass the bridge_num to it. Drivers can call dsa_bridge_num_find(bridge_dev), sure, but it is optional and if they have a better tracking scheme, they should be free to use it. 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. 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 | 12 +++-- drivers/net/dsa/qca8k.c | 6 ++- drivers/net/dsa/sja1105/sja1105_main.c | 19 +++++--- include/net/dsa.h | 13 ++++-- net/dsa/dsa_priv.h | 2 + net/dsa/port.c | 9 +++- net/dsa/switch.c | 63 +++++++++++++++----------- 17 files changed, 143 insertions(+), 78 deletions(-)