Most callers of mac_learning_flush() need to revalidate all flows
anyway, but this update forces new callers of mac_learning_flush()
to think about whether or not they need to explicitly handle
revalidation.  Also, it's theoretically more efficient when there
are lots of flows but the learning table is empty, (e.g. bridges
that don't use the NORMAL action).

Signed-off-by: Ethan Jackson <et...@nicira.com>
---

I plan to insert this patch before stp_tcn 1/2 and use the new
mac_learning_flush() function to ensure that proper revalidation happens upon
topology change events.


---
 lib/mac-learning.c     |   12 ++++++++----
 lib/mac-learning.h     |    2 +-
 ofproto/ofproto-dpif.c |   15 ++++++---------
 3 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/lib/mac-learning.c b/lib/mac-learning.c
index efd1dd4..7872e2b 100644
--- a/lib/mac-learning.c
+++ b/lib/mac-learning.c
@@ -260,14 +260,18 @@ mac_learning_expire(struct mac_learning *ml, struct 
mac_entry *e)
     free(e);
 }
 
-/* Expires all the mac-learning entries in 'ml'.  The tags in 'ml' are
- * discarded, so the client is responsible for revalidating any flows that
- * depend on 'ml', if necessary. */
+/* Expires all the mac-learning entries in 'ml'.  If not NULL, the tags in 'ml'
+ * are added to 'tags'.  Otherwise the tags in 'ml' are discarded.  The client
+ * is responsible for revalidating any flows that depend on 'ml', if
+ * necessary. */
 void
-mac_learning_flush(struct mac_learning *ml)
+mac_learning_flush(struct mac_learning *ml, struct tag_set *tags)
 {
     struct mac_entry *e;
     while (get_lru(ml, &e)){
+        if (tags) {
+            tag_set_add(tags, e->tag);
+        }
         mac_learning_expire(ml, e);
     }
     hmap_shrink(&ml->table);
diff --git a/lib/mac-learning.h b/lib/mac-learning.h
index 0263e49..ab73954 100644
--- a/lib/mac-learning.h
+++ b/lib/mac-learning.h
@@ -109,6 +109,6 @@ struct mac_entry *mac_learning_lookup(const struct 
mac_learning *,
 
 /* Flushing. */
 void mac_learning_expire(struct mac_learning *, struct mac_entry *);
-void mac_learning_flush(struct mac_learning *);
+void mac_learning_flush(struct mac_learning *, struct tag_set *);
 
 #endif /* mac-learning.h */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index ea5ed1e..1e9b341 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1193,7 +1193,7 @@ update_stp_port_state(struct ofport_dpif *ofport)
         if (stp_learn_in_state(ofport->stp_state)
                 != stp_learn_in_state(state)) {
             /* xxx Learning action flows should also be flushed. */
-            mac_learning_flush(ofproto->ml);
+            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
         }
         fwd_change = stp_forward_in_state(ofport->stp_state)
                         != stp_forward_in_state(state);
@@ -2064,7 +2064,7 @@ mirror_set(struct ofproto *ofproto_, void *aux,
     }
 
     ofproto->need_revalidate = true;
-    mac_learning_flush(ofproto->ml);
+    mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
     mirror_update_dups(ofproto);
 
     return 0;
@@ -2083,7 +2083,7 @@ mirror_destroy(struct ofmirror *mirror)
 
     ofproto = mirror->ofproto;
     ofproto->need_revalidate = true;
-    mac_learning_flush(ofproto->ml);
+    mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
 
     mirror_bit = MIRROR_MASK_C(1) << mirror->idx;
     HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
@@ -2126,8 +2126,7 @@ set_flood_vlans(struct ofproto *ofproto_, unsigned long 
*flood_vlans)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     if (mac_learning_set_flood_vlans(ofproto->ml, flood_vlans)) {
-        ofproto->need_revalidate = true;
-        mac_learning_flush(ofproto->ml);
+        mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
     }
     return 0;
 }
@@ -5823,12 +5822,10 @@ ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, 
int argc,
             unixctl_command_reply(conn, 501, "no such bridge");
             return;
         }
-        mac_learning_flush(ofproto->ml);
-        ofproto->need_revalidate = true;
+        mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
     } else {
         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
-            mac_learning_flush(ofproto->ml);
-            ofproto->need_revalidate = true;
+            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
         }
     }
 
-- 
1.7.8.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to