New function mac_learning_flush().
authorBen Pfaff <blp@nicira.com>
Mon, 29 Dec 2008 23:55:54 +0000 (15:55 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 30 Dec 2008 00:00:34 +0000 (16:00 -0800)
lib/mac-learning.c
lib/mac-learning.h

index 49dfbefa6704edc5fdec7de7adecb91c6dc4fa3b..61c6fccbfaba1165a87f5c3fdecffb3a6ae891d0 100644 (file)
@@ -122,6 +122,31 @@ search_bucket(struct list *bucket, const uint8_t mac[ETH_ADDR_LEN],
     return NULL;
 }
 
+/* If the LRU list is not empty, stores the least-recently-used entry in '*e'
+ * and returns true.  Otherwise, if the LRU list is empty, stores NULL in '*e'
+ * and return false. */
+static bool
+get_lru(struct mac_learning *ml, struct mac_entry **e)
+{
+    if (!list_is_empty(&ml->lrus)) {
+        *e = mac_entry_from_lru_node(ml->lrus.next);
+        return true;
+    } else {
+        *e = NULL;
+        return false;
+    }
+}
+
+/* Removes 'e' from the 'ml' hash table.  'e' must not already be on the free
+ * list. */
+static void
+free_mac_entry(struct mac_learning *ml, struct mac_entry *e)
+{
+    list_remove(&e->hash_node);
+    list_remove(&e->lru_node);
+    list_push_front(&ml->free, &e->lru_node);
+}
+
 /* Creates and returns a new MAC learning table. */
 struct mac_learning *
 mac_learning_create(void)
@@ -241,20 +266,27 @@ mac_learning_lookup_tag(const struct mac_learning *ml,
     }
 }
 
+/* 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. */
+void
+mac_learning_flush(struct mac_learning *ml)
+{
+    struct mac_entry *e;
+    while (get_lru(ml, &e)){
+        free_mac_entry(ml, e);
+    }
+}
+
 void
 mac_learning_run(struct mac_learning *ml, struct tag_set *set)
 {
-    while (!list_is_empty(&ml->lrus)) {
-        struct mac_entry *e = mac_entry_from_lru_node(ml->lrus.next);
-        if (time_now() < e->expires) {
-            break;
-        }
+    struct mac_entry *e;
+    while (get_lru(ml, &e) && time_now() >= e->expires) {
         if (set) {
             tag_set_add(set, e->tag);
         }
-        list_remove(&e->hash_node);
-        list_remove(&e->lru_node);
-        list_push_front(&ml->free, &e->lru_node);
+        free_mac_entry(ml, e);
     }
 }
 
index 37ebf0bc812500b753346ac4f3aec705d3f73dfe..8e3db910e3374545f06389c60bd7f15d429045e4 100644 (file)
@@ -47,6 +47,7 @@ uint16_t mac_learning_lookup(const struct mac_learning *,
 uint16_t mac_learning_lookup_tag(const struct mac_learning *,
                                  const uint8_t dst[ETH_ADDR_LEN],
                                  uint16_t vlan, tag_type *tag);
+void mac_learning_flush(struct mac_learning *);
 void mac_learning_run(struct mac_learning *, struct tag_set *);
 void mac_learning_wait(struct mac_learning *);