From 666158e792ab53cf80aad7c27c1805cfefc4daa6 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 31 Mar 2008 13:49:28 -0700 Subject: [PATCH] Get rid of tables' dependency on the datapath. --- switch/chain.c | 20 +++++++------------- switch/chain.h | 4 ++-- switch/datapath.c | 13 +++++++++++-- switch/datapath.h | 2 -- switch/table-hash.c | 17 +++++++---------- switch/table-linear.c | 11 ++++------- switch/table-mac.c | 11 ++++------- switch/table.h | 7 ++++--- 8 files changed, 39 insertions(+), 46 deletions(-) diff --git a/switch/chain.c b/switch/chain.c index ce8fe9d8..e2ac53c6 100644 --- a/switch/chain.c +++ b/switch/chain.c @@ -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. */ diff --git a/switch/chain.h b/switch/chain.h index cd3f205b..3c930aa7 100644 --- a/switch/chain.h +++ b/switch/chain.h @@ -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 *); diff --git a/switch/datapath.c b/switch/datapath.c index 764f8e2a..93c71347 100644 --- a/switch/datapath.c +++ b/switch/datapath.c @@ -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; diff --git a/switch/datapath.h b/switch/datapath.h index 1c52e435..6d52360d 100644 --- a/switch/datapath.h +++ b/switch/datapath.h @@ -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 */ diff --git a/switch/table-hash.c b/switch/table-hash.c index 315da516..e35f9abe 100644 --- a/switch/table-hash.c +++ b/switch/table-hash.c @@ -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) diff --git a/switch/table-linear.c b/switch/table-linear.c index 5db64517..9e7cec32 100644 --- a/switch/table-linear.c +++ b/switch/table-linear.c @@ -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) diff --git a/switch/table-mac.c b/switch/table-mac.c index 6686477e..5d2d0e98 100644 --- a/switch/table-mac.c +++ b/switch/table-mac.c @@ -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) diff --git a/switch/table.h b/switch/table.h index e16e134e..86b46132 100644 --- a/switch/table.h +++ b/switch/table.h @@ -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); -- 2.30.2