2 * Distributed under the terms of the GNU GPL version 2.
3 * Copyright (c) 2007, 2008 The Board of Trustees of The Leland
4 * Stanford Junior University
10 #include <linux/rcupdate.h>
11 #include <linux/slab.h>
13 /* Attempts to append 'table' to the set of tables in 'chain'. Returns 0 or
14 * negative error. If 'table' is null it is assumed that table creation failed
15 * due to out-of-memory. */
16 static int add_table(struct sw_chain *chain, struct sw_table *table)
20 if (chain->n_tables >= CHAIN_MAX_TABLES) {
21 printk("too many tables in chain\n");
22 table->destroy(table);
25 chain->tables[chain->n_tables++] = table;
29 /* Creates and returns a new chain associated with 'dp'. Returns NULL if the
30 * chain cannot be created. */
31 struct sw_chain *chain_create(struct datapath *dp)
33 struct sw_chain *chain = kzalloc(sizeof *chain, GFP_KERNEL);
38 if (add_table(chain, table_mac_create(TABLE_MAC_NUM_BUCKETS,
40 || add_table(chain, table_hash2_create(0x1EDC6F41, TABLE_HASH_MAX_FLOWS,
41 0x741B8CD7, TABLE_HASH_MAX_FLOWS))
42 || add_table(chain, table_linear_create(TABLE_LINEAR_MAX_FLOWS))) {
50 /* Searches 'chain' for a flow matching 'key', which must not have any wildcard
51 * fields. Returns the flow if successful, otherwise a null pointer.
53 * Caller must hold rcu_read_lock, and not release it until it is done with the
55 struct sw_flow *chain_lookup(struct sw_chain *chain,
56 const struct sw_flow_key *key)
60 BUG_ON(key->wildcards);
61 for (i = 0; i < chain->n_tables; i++) {
62 struct sw_table *t = chain->tables[i];
63 struct sw_flow *flow = t->lookup(t, key);
70 /* Inserts 'flow' into 'chain', replacing any duplicate flow. Returns 0 if
71 * successful or a negative error.
73 * If successful, 'flow' becomes owned by the chain, otherwise it is retained
76 * Caller must hold rcu_read_lock. If insertion is successful, it must not
77 * release rcu_read_lock until it is done with the inserted flow. */
78 int chain_insert(struct sw_chain *chain, struct sw_flow *flow)
82 for (i = 0; i < chain->n_tables; i++) {
83 struct sw_table *t = chain->tables[i];
84 if (t->insert(t, flow))
91 /* Deletes from 'chain' any and all flows that match 'key'. Returns the number
92 * of flows that were deleted.
94 * Expensive in the general case as currently implemented, since it requires
95 * iterating through the entire contents of each table for keys that contain
96 * wildcards. Relatively cheap for fully specified keys.
98 * The caller need not hold any locks. */
99 int chain_delete(struct sw_chain *chain, const struct sw_flow_key *key, int strict)
104 for (i = 0; i < chain->n_tables; i++) {
105 struct sw_table *t = chain->tables[i];
107 count += t->delete(t, key, strict);
115 /* Performs timeout processing on all the tables in 'chain'. Returns the
116 * number of flow entries deleted through expiration.
118 * Expensive as currently implemented, since it iterates through the entire
119 * contents of each table.
121 * The caller need not hold any locks. */
122 int chain_timeout(struct sw_chain *chain)
127 for (i = 0; i < chain->n_tables; i++) {
128 struct sw_table *t = chain->tables[i];
130 count += t->timeout(chain->dp, t);
136 /* Destroys 'chain', which must not have any users. */
137 void chain_destroy(struct sw_chain *chain)
142 for (i = 0; i < chain->n_tables; i++) {
143 struct sw_table *t = chain->tables[i];
149 /* Prints statistics for each of the tables in 'chain'. */
150 void chain_print_stats(struct sw_chain *chain)
155 for (i = 0; i < chain->n_tables; i++) {
156 struct sw_table *t = chain->tables[i];
157 struct sw_table_stats stats;
159 printk("%s: %lu/%lu flows\n",
160 stats.name, stats.n_flows, stats.max_flows);