Page MenuHomeFreeBSD

D57559.id179674.diff
No OneTemporary

D57559.id179674.diff

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -213,7 +213,7 @@
* That is: for read accesses we only need to be in NET_EPOCH, but for write
* accesses we must hold:
*
- * - BRIDGE_RT_LOCK, for any change to bridge_rtnodes
+ * - BRIDGE_RT_LOCK, for any change to bridge_rtnodes or MDB state
* - BRIDGE_LOCK, for any other change
*
* The BRIDGE_LOCK is a sleepable lock, because it is held across ioctl()
@@ -278,6 +278,31 @@
};
#define brt_ifp brt_dst->bif_ifp
+/*
+ * Bridge multicast database entry. The MDB records which member interfaces
+ * have listeners for a multicast group.
+ */
+struct bridge_mdb_key {
+ sa_family_t bmk_family;
+ ether_vlanid_t bmk_vlan;
+ union {
+ struct in_addr bmk_ip4;
+ struct in6_addr bmk_ip6;
+ } bmk_addr;
+};
+
+struct bridge_mdb_member {
+ CK_LIST_ENTRY(bridge_mdb_member) bmm_next;
+ struct bridge_iflist *bmm_bif;
+ unsigned long bmm_expire;
+};
+
+struct bridge_mdb_entry {
+ CK_LIST_ENTRY(bridge_mdb_entry) bmd_next;
+ struct bridge_mdb_key bmd_key;
+ CK_LIST_HEAD(, bridge_mdb_member) bmd_members;
+};
+
/*
* Software state for each bridge.
*/
@@ -293,6 +318,9 @@
CK_LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */
CK_LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */
CK_LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */
+ CK_LIST_HEAD(, bridge_mdb_entry) sc_mdb; /* multicast database */
+ uint32_t sc_mdbcnt; /* # of multicast groups */
+ uint32_t sc_mdbmembercnt; /* # of multicast members */
uint32_t sc_rthash_key; /* key for hash */
CK_LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */
struct bstp_state sc_stp; /* STP state */
@@ -366,6 +394,8 @@
static void bridge_rtable_init(struct bridge_softc *);
static void bridge_rtable_fini(struct bridge_softc *);
+static void bridge_mdb_init(struct bridge_softc *);
+static void bridge_mdb_fini(struct bridge_softc *);
static int bridge_rtnode_addr_cmp(const uint8_t *, const uint8_t *);
static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
@@ -862,6 +892,7 @@
/* Initialize our routing table. */
bridge_rtable_init(sc);
+ bridge_mdb_init(sc);
callout_init_mtx(&sc->sc_brcallout, &sc->sc_rt_mtx, 0);
@@ -913,6 +944,46 @@
return (0);
}
+static void
+bridge_mdb_init(struct bridge_softc *sc)
+{
+ CK_LIST_INIT(&sc->sc_mdb);
+ sc->sc_mdbcnt = 0;
+ sc->sc_mdbmembercnt = 0;
+}
+
+static void
+bridge_mdb_destroy_entry(struct bridge_softc *sc, struct bridge_mdb_entry *bmd)
+{
+ struct bridge_mdb_member *bmm;
+
+ BRIDGE_RT_LOCK_ASSERT(sc);
+
+ while ((bmm = CK_LIST_FIRST(&bmd->bmd_members)) != NULL) {
+ CK_LIST_REMOVE(bmm, bmm_next);
+ sc->sc_mdbmembercnt--;
+ free(bmm, M_DEVBUF);
+ }
+
+ CK_LIST_REMOVE(bmd, bmd_next);
+ sc->sc_mdbcnt--;
+ free(bmd, M_DEVBUF);
+}
+
+static void
+bridge_mdb_fini(struct bridge_softc *sc)
+{
+ struct bridge_mdb_entry *bmd;
+
+ BRIDGE_RT_LOCK_ASSERT(sc);
+
+ while ((bmd = CK_LIST_FIRST(&sc->sc_mdb)) != NULL)
+ bridge_mdb_destroy_entry(sc, bmd);
+
+ KASSERT(sc->sc_mdbcnt == 0 && sc->sc_mdbmembercnt == 0,
+ ("%s: MDB entries remain", __func__));
+}
+
static void
bridge_clone_destroy_cb(struct epoch_context *ctx)
{
@@ -947,6 +1018,10 @@
bridge_delete_span(sc, bif);
}
+ BRIDGE_RT_LOCK(sc);
+ bridge_mdb_fini(sc);
+ BRIDGE_RT_UNLOCK(sc);
+
/* Tear down the routing table. */
bridge_rtable_fini(sc);

File Metadata

Mime Type
text/plain
Expires
Sun, Jun 14, 9:18 AM (16 h, 4 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33946587
Default Alt Text
D57559.id179674.diff (3 KB)

Event Timeline