It follows mac learning, but since the multicast snooping feature can be disabled, the locking is handled in the library.
Signed-off-by: Flavio Leitner <f...@redhat.com> --- ofproto/ofproto-dpif-xlate.c | 21 ++++++++++++++++----- ofproto/ofproto-dpif-xlate.h | 2 ++ ofproto/ofproto-dpif.c | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 11f62f9..771b318 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -33,6 +33,7 @@ #include "learn.h" #include "list.h" #include "mac-learning.h" +#include "mcast-snooping.h" #include "meta-flow.h" #include "multipath.h" #include "netdev-vport.h" @@ -75,6 +76,7 @@ struct xbridge { char *name; /* Name used in log messages. */ struct dpif *dpif; /* Datapath interface. */ struct mac_learning *ml; /* Mac learning handle. */ + struct mcast_snooping *ms; /* Multicast Snooping handle. */ struct mbridge *mbridge; /* Mirroring. */ struct dpif_sflow *sflow; /* SFlow handle, or null. */ struct dpif_ipfix *ipfix; /* Ipfix handle, or null. */ @@ -344,6 +346,7 @@ static void xlate_xbridge_set(struct xbridge *xbridge, struct rule_dpif *miss_rule, struct rule_dpif *no_packet_in_rule, const struct mac_learning *ml, struct stp *stp, + const struct mcast_snooping *ms, const struct mbridge *mbridge, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, @@ -408,6 +411,7 @@ xlate_xbridge_set(struct xbridge *xbridge, struct rule_dpif *miss_rule, struct rule_dpif *no_packet_in_rule, const struct mac_learning *ml, struct stp *stp, + const struct mcast_snooping *ms, const struct mbridge *mbridge, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, @@ -422,6 +426,11 @@ xlate_xbridge_set(struct xbridge *xbridge, xbridge->ml = mac_learning_ref(ml); } + if (xbridge->ms != ms) { + mcast_snooping_unref(xbridge->ms); + xbridge->ms = mcast_snooping_ref(ms); + } + if (xbridge->mbridge != mbridge) { mbridge_unref(xbridge->mbridge); xbridge->mbridge = mbridge_ref(mbridge); @@ -527,10 +536,10 @@ xlate_xbridge_copy(struct xbridge *xbridge) xlate_xbridge_set(new_xbridge, xbridge->dpif, xbridge->miss_rule, xbridge->no_packet_in_rule, xbridge->ml, xbridge->stp, - xbridge->mbridge, xbridge->sflow, xbridge->ipfix, - xbridge->netflow, xbridge->frag, xbridge->forward_bpdu, - xbridge->has_in_band, xbridge->enable_recirc, - xbridge->variable_length_userdata, + xbridge->ms, xbridge->mbridge, xbridge->sflow, + xbridge->ipfix, xbridge->netflow, xbridge->frag, + xbridge->forward_bpdu, xbridge->has_in_band, + xbridge->enable_recirc, xbridge->variable_length_userdata, xbridge->max_mpls_depth); LIST_FOR_EACH (xbundle, list_node, &xbridge->xbundles) { xlate_xbundle_copy(new_xbridge, xbundle); @@ -677,6 +686,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, struct dpif *dpif, struct rule_dpif *miss_rule, struct rule_dpif *no_packet_in_rule, const struct mac_learning *ml, struct stp *stp, + const struct mcast_snooping *ms, const struct mbridge *mbridge, const struct dpif_sflow *sflow, const struct dpif_ipfix *ipfix, @@ -702,7 +712,7 @@ xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name, xbridge->name = xstrdup(name); xlate_xbridge_set(xbridge, dpif, miss_rule, no_packet_in_rule, ml, stp, - mbridge, sflow, ipfix, netflow, frag, forward_bpdu, + ms, mbridge, sflow, ipfix, netflow, frag, forward_bpdu, has_in_band, enable_recirc, variable_length_userdata, max_mpls_depth); } @@ -727,6 +737,7 @@ xlate_xbridge_remove(struct xlate_cfg *xcfg, struct xbridge *xbridge) hmap_remove(&xcfg->xbridges, &xbridge->hmap_node); mac_learning_unref(xbridge->ml); + mcast_snooping_unref(xbridge->ms); mbridge_unref(xbridge->mbridge); dpif_sflow_unref(xbridge->sflow); dpif_ipfix_unref(xbridge->ipfix); diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 6065db3..4bdf2d3 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -31,6 +31,7 @@ struct lacp; struct dpif_ipfix; struct dpif_sflow; struct mac_learning; +struct mcast_snooping; struct xlate_cache; struct xlate_recirc { @@ -140,6 +141,7 @@ void xlate_ofproto_set(struct ofproto_dpif *, const char *name, struct dpif *, struct rule_dpif *miss_rule, struct rule_dpif *no_packet_in_rule, const struct mac_learning *, struct stp *, + const struct mcast_snooping *, const struct mbridge *, const struct dpif_sflow *, const struct dpif_ipfix *, const struct netflow *, enum ofp_config_flags, bool forward_bpdu, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 06be234..7f042d9 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -37,6 +37,7 @@ #include "lacp.h" #include "learn.h" #include "mac-learning.h" +#include "mcast-snooping.h" #include "meta-flow.h" #include "multipath.h" #include "netdev-vport.h" @@ -229,6 +230,7 @@ enum revalidate_reason { REV_PORT_TOGGLED, /* Port enabled or disabled by CFM, LACP, ...*/ REV_FLOW_TABLE, /* Flow table changed. */ REV_MAC_LEARNING, /* Mac learning changed. */ + REV_MCAST_SNOOPING, /* Multicast snooping changed. */ }; COVERAGE_DEFINE(rev_reconfigure); COVERAGE_DEFINE(rev_stp); @@ -236,6 +238,7 @@ COVERAGE_DEFINE(rev_bond); COVERAGE_DEFINE(rev_port_toggled); COVERAGE_DEFINE(rev_flow_table); COVERAGE_DEFINE(rev_mac_learning); +COVERAGE_DEFINE(rev_mcast_snooping); /* All datapaths of a given type share a single dpif backer instance. */ struct dpif_backer { @@ -288,6 +291,7 @@ struct ofproto_dpif { struct dpif_ipfix *ipfix; struct hmap bundles; /* Contains "struct ofbundle"s. */ struct mac_learning *ml; + struct mcast_snooping *ms; bool has_bonded_bundles; bool lacp_enabled; struct mbridge *mbridge; @@ -588,6 +592,7 @@ type_run(const char *type) case REV_PORT_TOGGLED: COVERAGE_INC(rev_port_toggled); break; case REV_FLOW_TABLE: COVERAGE_INC(rev_flow_table); break; case REV_MAC_LEARNING: COVERAGE_INC(rev_mac_learning); break; + case REV_MCAST_SNOOPING: COVERAGE_INC(rev_mcast_snooping); break; } backer->need_revalidate = 0; @@ -603,7 +608,7 @@ type_run(const char *type) xlate_ofproto_set(ofproto, ofproto->up.name, ofproto->backer->dpif, ofproto->miss_rule, ofproto->no_packet_in_rule, ofproto->ml, - ofproto->stp, ofproto->mbridge, + ofproto->stp, ofproto->ms, ofproto->mbridge, ofproto->sflow, ofproto->ipfix, ofproto->netflow, ofproto->up.frag_handling, ofproto->up.forward_bpdu, @@ -1144,6 +1149,7 @@ construct(struct ofproto *ofproto_) ofproto->dump_seq = 0; hmap_init(&ofproto->bundles); ofproto->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME); + ofproto->ms = NULL; ofproto->mbridge = mbridge_create(); ofproto->has_bonded_bundles = false; ofproto->lacp_enabled = false; @@ -1327,6 +1333,7 @@ destruct(struct ofproto *ofproto_) dpif_sflow_unref(ofproto->sflow); hmap_destroy(&ofproto->bundles); mac_learning_unref(ofproto->ml); + mcast_snooping_unref(ofproto->ms); hmap_destroy(&ofproto->vlandev_map); hmap_destroy(&ofproto->realdev_vid_map); @@ -1354,6 +1361,7 @@ run(struct ofproto *ofproto_) ovs_rwlock_wrlock(&ofproto->ml->rwlock); mac_learning_flush(ofproto->ml); ovs_rwlock_unlock(&ofproto->ml->rwlock); + mcast_snooping_mdb_flush(ofproto->ms); } /* Always updates the ofproto->pins_seqno to avoid frequent wakeup during @@ -1412,6 +1420,10 @@ run(struct ofproto *ofproto_) } ovs_rwlock_unlock(&ofproto->ml->rwlock); + if (mcast_snooping_run(ofproto->ms)) { + ofproto->backer->need_revalidate = REV_MCAST_SNOOPING; + } + new_dump_seq = seq_read(udpif_dump_seq(ofproto->backer->udpif)); if (ofproto->dump_seq != new_dump_seq) { struct rule *rule, *next_rule; @@ -1473,6 +1485,7 @@ wait(struct ofproto *ofproto_) ovs_rwlock_rdlock(&ofproto->ml->rwlock); mac_learning_wait(ofproto->ml); ovs_rwlock_unlock(&ofproto->ml->rwlock); + mcast_snooping_wait(ofproto->ms); stp_wait(ofproto); if (ofproto->backer->need_revalidate) { /* Shouldn't happen, but if it does just go around again. */ @@ -1986,6 +1999,7 @@ update_stp_port_state(struct ofport_dpif *ofport) ovs_rwlock_wrlock(&ofproto->ml->rwlock); mac_learning_flush(ofproto->ml); ovs_rwlock_unlock(&ofproto->ml->rwlock); + mcast_snooping_mdb_flush(ofproto->ms); } fwd_change = stp_forward_in_state(ofport->stp_state) != stp_forward_in_state(state); @@ -2111,6 +2125,7 @@ stp_run(struct ofproto_dpif *ofproto) ovs_rwlock_wrlock(&ofproto->ml->rwlock); mac_learning_flush(ofproto->ml); ovs_rwlock_unlock(&ofproto->ml->rwlock); + mcast_snooping_mdb_flush(ofproto->ms); } } } -- 1.9.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev