Get rid of tables' dependency on the datapath.
authorBen Pfaff <blp@nicira.com>
Mon, 31 Mar 2008 20:49:28 +0000 (13:49 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 1 Apr 2008 16:52:59 +0000 (09:52 -0700)
switch/chain.c
switch/chain.h
switch/datapath.c
switch/datapath.h
switch/table-hash.c
switch/table-linear.c
switch/table-mac.c
switch/table.h

index ce8fe9d..e2ac53c 100644 (file)
@@ -125,9 +125,7 @@ chain_insert(struct sw_chain *chain, struct sw_flow *flow)
  *
  * Expensive in the general case as currently implemented, since it requires
  * iterating through the entire contents of each table for keys that contain
- * wildcards.  Relatively cheap for fully specified keys.
- *
- * The caller need not hold any locks. */
+ * wildcards.  Relatively cheap for fully specified keys. */
 int
 chain_delete(struct sw_chain *chain, const struct sw_flow_key *key, int strict)
 {
@@ -143,24 +141,20 @@ chain_delete(struct sw_chain *chain, const struct sw_flow_key *key, int strict)
 
 }
 
-/* Performs timeout processing on all the tables in 'chain'.  Returns the
- * number of flow entries deleted through expiration.
+/* Deletes timed-out flow entries from all the tables in 'chain' and appends
+ * the deleted flows to 'deleted'.
  *
  * Expensive as currently implemented, since it iterates through the entire
- * contents of each table.
- *
- * The caller need not hold any locks. */
-int
-chain_timeout(struct sw_chain *chain, struct datapath *dp)
+ * contents of each table. */
+void
+chain_timeout(struct sw_chain *chain, struct list *deleted)
 {
-    int count = 0;
     int i;
 
     for (i = 0; i < chain->n_tables; i++) {
         struct sw_table *t = chain->tables[i];
-        count += t->timeout(dp, t);
+        t->timeout(t, deleted);
     }
-    return count;
 }
 
 /* Destroys 'chain', which must not have any users. */
index cd3f205..3c930aa 100644 (file)
@@ -36,7 +36,7 @@
 
 struct sw_flow;
 struct sw_flow_key;
-struct datapath;
+struct list;
 
 #define TABLE_LINEAR_MAX_FLOWS  100
 #define TABLE_HASH_MAX_FLOWS    65536
@@ -47,7 +47,7 @@ struct sw_chain *chain_create(void);
 struct sw_flow *chain_lookup(struct sw_chain *, const struct sw_flow_key *);
 int chain_insert(struct sw_chain *, struct sw_flow *);
 int chain_delete(struct sw_chain *, const struct sw_flow_key *, int);
-int chain_timeout(struct sw_chain *, struct datapath *);
+void chain_timeout(struct sw_chain *, struct list *deleted);
 void chain_destroy(struct sw_chain *);
 void chain_print_stats(struct sw_chain *);
 
index 764f8e2..93c7134 100644 (file)
@@ -99,6 +99,7 @@ void dp_send_hello(struct datapath *);
 void dp_update_port_flags(struct datapath *dp, const struct ofp_phy_port *opp);
 void dp_output_control(struct datapath *, struct buffer *, int in_port,
                        size_t max_len, int reason);
+static void send_flow_expired(struct datapath *, struct sw_flow *);
 static void send_port_status(struct sw_port *p, uint8_t status);
 static void del_switch_port(struct sw_port *p);
 static void execute_actions(struct datapath *, struct buffer *,
@@ -220,7 +221,15 @@ dp_run(struct datapath *dp)
     int i;
 
     if (now != dp->last_timeout) {
-        chain_timeout(dp->chain, dp);
+        struct list deleted = LIST_INITIALIZER(&deleted);
+        struct sw_flow *f, *n;
+
+        chain_timeout(dp->chain, &deleted);
+        LIST_FOR_EACH_SAFE (f, n, struct sw_flow, node, &deleted) {
+            send_flow_expired(dp, f);
+            list_remove(&f->node);
+            flow_free(f);
+        }
         dp->last_timeout = now;
     }
     poll_timer_wait(1000);
@@ -466,7 +475,7 @@ send_port_status(struct sw_port *p, uint8_t status)
 }
 
 void
-dp_send_flow_expired(struct datapath *dp, struct sw_flow *flow)
+send_flow_expired(struct datapath *dp, struct sw_flow *flow)
 {
     struct buffer *buffer;
     struct ofp_flow_expired *ofe;
index 1c52e43..6d52360 100644 (file)
@@ -50,6 +50,4 @@ int dp_add_port(struct datapath *, const char *netdev);
 void dp_run(struct datapath *);
 void dp_wait(struct datapath *);
 
-void dp_send_flow_expired(struct datapath *, struct sw_flow *);
-
 #endif /* datapath.h */
index 315da51..e35f9ab 100644 (file)
@@ -127,23 +127,20 @@ static int table_hash_delete(struct sw_table *swt,
     return count;
 }
 
-static int table_hash_timeout(struct datapath *dp, struct sw_table *swt)
+static void table_hash_timeout(struct sw_table *swt, struct list *deleted)
 {
     struct sw_table_hash *th = (struct sw_table_hash *) swt;
     unsigned int i;
-    int count = 0;
 
     for (i = 0; i <= th->bucket_mask; i++) {
         struct sw_flow **bucket = &th->buckets[i];
         struct sw_flow *flow = *bucket;
         if (flow && flow_timeout(flow)) {
-            dp_send_flow_expired(dp, flow);
-            do_delete(bucket);
-            count++;
+            list_push_back(deleted, &flow->node);
+            *bucket = NULL;
+            th->n_flows--;
         }
     }
-    th->n_flows -= count;
-    return count;
 }
 
 static void table_hash_destroy(struct sw_table *swt)
@@ -293,11 +290,11 @@ static int table_hash2_delete(struct sw_table *swt,
             + table_hash_delete(t2->subtable[1], key, strict));
 }
 
-static int table_hash2_timeout(struct datapath *dp, struct sw_table *swt)
+static void table_hash2_timeout(struct sw_table *swt, struct list *deleted)
 {
     struct sw_table_hash2 *t2 = (struct sw_table_hash2 *) swt;
-    return (table_hash_timeout(dp, t2->subtable[0])
-            + table_hash_timeout(dp, t2->subtable[1]));
+    table_hash_timeout(t2->subtable[0], deleted);
+    table_hash_timeout(t2->subtable[1], deleted);
 }
 
 static void table_hash2_destroy(struct sw_table *swt)
index 5db6451..9e7cec3 100644 (file)
@@ -108,21 +108,18 @@ static int table_linear_delete(struct sw_table *swt,
     return count;
 }
 
-static int table_linear_timeout(struct datapath *dp, struct sw_table *swt)
+static void table_linear_timeout(struct sw_table *swt, struct list *deleted)
 {
     struct sw_table_linear *tl = (struct sw_table_linear *) swt;
     struct sw_flow *flow, *n;
-    int count = 0;
 
     LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &tl->flows) {
         if (flow_timeout(flow)) {
-            dp_send_flow_expired(dp, flow);
-            do_delete(flow);
-            count++;
+            list_remove(&flow->node);
+            list_push_back(deleted, &flow->node);
+            tl->n_flows--;
         }
     }
-    tl->n_flows -= count;
-    return count;
 }
 
 static void table_linear_destroy(struct sw_table *swt)
index 6686477..5d2d0e9 100644 (file)
@@ -139,25 +139,22 @@ static int table_mac_delete(struct sw_table *swt,
     }
 }
 
-static int table_mac_timeout(struct datapath *dp, struct sw_table *swt)
+static void table_mac_timeout(struct sw_table *swt, struct list *deleted)
 {
     struct sw_table_mac *tm = (struct sw_table_mac *) swt;
     unsigned int i;
-    int count = 0;
 
     for (i = 0; i <= tm->bucket_mask; i++) {
         struct list *bucket = &tm->buckets[i];
         struct sw_flow *flow, *next;
         LIST_FOR_EACH_SAFE (flow, next, struct sw_flow, node, bucket) {
             if (flow_timeout(flow)) {
-                dp_send_flow_expired(dp, flow);
-                do_delete(flow);
-                count++;
+                list_remove(&flow->node);
+                list_push_back(deleted, &flow->node);
+                tm->n_flows--;
             }
         }
     }
-    tm->n_flows -= count;
-    return count;
 }
 
 static void table_mac_destroy(struct sw_table *swt)
index e16e134..86b4613 100644 (file)
@@ -39,7 +39,7 @@
 
 struct sw_flow;
 struct sw_flow_key;
-struct datapath;
+struct list;
 
 /* Iterator through the flows stored in a table. */
 struct swt_iterator {
@@ -78,8 +78,9 @@ struct sw_table {
                   int strict);
 
     /* Performs timeout processing on all the flow entries in 'table'.
-     * Returns the number of flow entries deleted through expiration. */
-    int (*timeout)(struct datapath *dp, struct sw_table *table);
+     * Appends all the flow entries removed from 'table' to 'deleted' for the
+     * caller to free. */
+    void (*timeout)(struct sw_table *table, struct list *deleted);
 
     /* Destroys 'table', which must not have any users. */
     void (*destroy)(struct sw_table *table);