summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFlavio Leitner <fbl@redhat.com>2014-12-11 09:38:19 -0200
committerBen Pfaff <blp@nicira.com>2015-02-04 10:49:07 -0800
commit8e04a33ffcb673b5c9253a59870aeeda94cddd66 (patch)
tree178ddf0e453d63e45b50b28b11d0ee824f5bd645 /lib
parentf4ae6e23c3df0efbdf6b9a71949829210666f790 (diff)
downloadopenvswitch-8e04a33ffcb673b5c9253a59870aeeda94cddd66.tar.gz
mcast-snoop: Add support to control Reports forwarding
The RFC4541 section 2.1.1 item 1 allows the snooping switch to provide an administrative control to allow Report messages to be flooded to ports not connected to multicast routers. Signed-off-by: Flavio Leitner <fbl@redhat.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/mcast-snooping.c34
-rw-r--r--lib/mcast-snooping.h9
2 files changed, 42 insertions, 1 deletions
diff --git a/lib/mcast-snooping.c b/lib/mcast-snooping.c
index 87b6b0c6d..6fe3890c7 100644
--- a/lib/mcast-snooping.c
+++ b/lib/mcast-snooping.c
@@ -160,6 +160,7 @@ mcast_snooping_create(void)
list_init(&ms->group_lru);
list_init(&ms->mrouter_lru);
list_init(&ms->fport_list);
+ list_init(&ms->rport_list);
ms->secret = random_uint32();
ms->idle_time = MCAST_ENTRY_DEFAULT_IDLE_TIME;
ms->max_entries = MCAST_DEFAULT_MAX_ENTRIES;
@@ -423,6 +424,13 @@ mcast_snooping_leave_group(struct mcast_snooping *ms, ovs_be32 ip4,
{
struct mcast_group *grp;
+ /* Ports flagged to forward Reports usually have more
+ * than one host behind it, so don't leave the group
+ * on the first message and just let it expire */
+ if (mcast_snooping_port_lookup(&ms->rport_list, port)) {
+ return false;
+ }
+
grp = mcast_snooping_lookup(ms, ip4, vlan);
if (grp && mcast_group_delete_bundle(ms, grp, port)) {
ms->need_revalidate = true;
@@ -589,6 +597,25 @@ mcast_snooping_set_port_flood(struct mcast_snooping *ms, void *port,
}
}
+/* Flood Reports ports. */
+
+void
+mcast_snooping_set_port_flood_reports(struct mcast_snooping *ms, void *port,
+ bool flood)
+ OVS_REQ_WRLOCK(ms->rwlock)
+{
+ struct mcast_port_bundle *pbundle;
+
+ pbundle = mcast_snooping_port_lookup(&ms->rport_list, port);
+ if (flood && !pbundle) {
+ mcast_snooping_add_port(&ms->rport_list, port);
+ ms->need_revalidate = true;
+ } else if (!flood && pbundle) {
+ mcast_snooping_flush_port(pbundle);
+ ms->need_revalidate = true;
+ }
+}
+
/* Run and flush. */
static void
@@ -636,13 +663,20 @@ mcast_snooping_flush__(struct mcast_snooping *ms)
hmap_shrink(&ms->table);
+ /* flush multicast routers */
while (mrouter_get_lru(ms, &mrouter)) {
mcast_snooping_flush_mrouter(mrouter);
}
+ /* flush flood ports */
while (mcast_snooping_port_get(&ms->fport_list, &pbundle)) {
mcast_snooping_flush_port(pbundle);
}
+
+ /* flush flood report ports */
+ while (mcast_snooping_port_get(&ms->rport_list, &pbundle)) {
+ mcast_snooping_flush_port(pbundle);
+ }
}
void
diff --git a/lib/mcast-snooping.h b/lib/mcast-snooping.h
index c23ed6be9..979b2aa60 100644
--- a/lib/mcast-snooping.h
+++ b/lib/mcast-snooping.h
@@ -87,7 +87,7 @@ struct mcast_mrouter_bundle {
void *port OVS_GUARDED;
};
-/* The bundle to send multicast traffic.
+/* The bundle to send multicast traffic or Reports.
* Guarded by owning 'mcast_snooping''s rwlock */
struct mcast_port_bundle {
/* Node in parent struct mcast_snooping. */
@@ -117,6 +117,10 @@ struct mcast_snooping {
* packets in no special order. */
struct ovs_list fport_list OVS_GUARDED;
+ /* Contains struct mcast_port_bundle to forward Reports in
+ * no special order. */
+ struct ovs_list rport_list OVS_GUARDED;
+
/* Secret for randomizing hash table. */
uint32_t secret;
@@ -163,6 +167,9 @@ mcast_snooping_set_flood_unreg(struct mcast_snooping *ms, bool enable)
void mcast_snooping_set_port_flood(struct mcast_snooping *ms, void *port,
bool flood)
OVS_REQ_WRLOCK(ms->rwlock);
+void mcast_snooping_set_port_flood_reports(struct mcast_snooping *ms,
+ void *port, bool flood)
+ OVS_REQ_WRLOCK(ms->rwlock);
/* Lookup. */
struct mcast_group *