}
 
 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;
 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;
 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;
 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;
 
 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,
 
 }
 
 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;
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 }
 
 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;
 
 
 }
 
 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);
 }
 
 }
 
 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];
 }
 
 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];
 }
 
 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];
 }
 
 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];
 
 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;
 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;
 
 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 */
 
 
 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;
 
 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;
 
 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;
 
 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;
 
 }
 
 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;
 }
 
 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;
 }
 
 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;
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 
 
 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);
 
 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);
 
 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;
 
 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;
 
 }
 
 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;
 
 }
 
 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;
 
 
 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++) {
 
                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",
 }
 
 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.
 
        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 {
         */
        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;
 
         * 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);
        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
         */
 
        int port;
        const unsigned char *addr;
        u16 vid;
+       struct dsa_db db;
 };
 
 /* DSA_NOTIFIER_LAG_FDB_* */
        struct dsa_lag *lag;
        const unsigned char *addr;
        u16 vid;
+       struct dsa_db db;
 };
 
 /* DSA_NOTIFIER_MDB_* */
        const struct switchdev_obj_port_mdb *mdb;
        int sw_index;
        int port;
+       struct dsa_db db;
 };
 
 /* DSA_NOTIFIER_LAG_* */
 
                .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);
 }
 
                .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);
 }
 
                .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;
                        return err;
        }
 
+       if (!dp->ds->fdb_isolation)
+               info.db.bridge.num = 0;
+
        return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_ADD, &info);
 }
 
                .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;
                        return err;
        }
 
+       if (!dp->ds->fdb_isolation)
+               info.db.bridge.num = 0;
+
        return dsa_port_notify(dp, DSA_NOTIFIER_HOST_FDB_DEL, &info);
 }
 
                .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);
 }
 
                .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);
 }
 
                .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);
 }
 
                .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);
 }
 
                .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;
        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);
 }
 
                .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;
        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);
 }
 
 
        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;
 
        /* 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;
                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;
 
        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);
 
 }
 
 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;
 
        /* 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;
        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;
 }
 
 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;
 
        /* 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;
                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;
 
        ether_addr_copy(a->addr, addr);
        a->vid = vid;
+       a->db = db;
        refcount_set(&a->refcount, 1);
        list_add_tail(&a->list, &dp->fdbs);
 
 }
 
 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;
 
        /* 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;
        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;
 }
 
 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;
                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;
 }
 
 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;
        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;
        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;
                }
        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;
                }
        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,
        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,
        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;
 }
        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;
 }
        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,
        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,
        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;
                }
        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;
                }