diff options
author | Flavio Leitner <fbl@redhat.com> | 2014-12-11 09:38:19 -0200 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2015-02-04 10:49:07 -0800 |
commit | 8e04a33ffcb673b5c9253a59870aeeda94cddd66 (patch) | |
tree | 178ddf0e453d63e45b50b28b11d0ee824f5bd645 /lib | |
parent | f4ae6e23c3df0efbdf6b9a71949829210666f790 (diff) | |
download | openvswitch-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.c | 34 | ||||
-rw-r--r-- | lib/mcast-snooping.h | 9 |
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 * |