[ovs-dev] [PATCH v3 3/7] ofproto-dpif: Introduce multicast snooping handler

Flavio Leitner fbl at redhat.com
Sat May 31 04:53:17 UTC 2014


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 <fbl at 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




More information about the dev mailing list