/*
* Distributed under the terms of the GNU GPL version 2.
- * Copyright (c) 2007 The Board of Trustees of The Leland Stanford Junior Univer
-sity
+ * Copyright (c) 2007, 2008 The Board of Trustees of The Leland
+ * Stanford Junior University
*/
#include <linux/module.h>
{
struct sw_flow *flow = flow_alloc(n_actions, flags);
if (flow) {
- struct ofp_action *actions = flow->actions;
+ struct sw_flow_actions *sfa = flow->sf_acts;
memset(flow, 0, sizeof *flow);
- flow->actions = actions;
+ flow->sf_acts = sfa;
}
return flow;
}
static void
-simple_insert_delete(struct sw_table *swt, uint16_t wildcards)
+simple_insert_delete(struct sw_table *swt, uint32_t wildcards)
{
struct sw_flow *a_flow = flow_zalloc(0, GFP_KERNEL);
struct sw_flow *b_flow = flow_zalloc(0, GFP_KERNEL);
if (swt->lookup(swt, &b_flow->key))
unit_fail("lookup should not succeed (1)");
- swt->delete(swt, &a_flow->key, 0);
+ swt->delete(swt, &a_flow->key, 0, 0);
if (swt->lookup(swt, &a_flow->key))
unit_fail("lookup should not succeed (3)");
}
static void
-multiple_insert_destroy(struct sw_table *swt, int inserts, uint16_t wildcards,
+multiple_insert_destroy(struct sw_table *swt, int inserts, uint32_t wildcards,
int min_collisions, int max_collisions)
{
int i;
}
static void
-set_random_key(struct sw_flow_key *key, uint16_t wildcards)
+set_random_key(struct sw_flow_key *key, uint32_t wildcards)
{
key->nw_src = random32();
key->nw_dst = random32();
*/
static struct flow_key_entry *
-allocate_random_keys(int n_keys, uint16_t wildcards)
+allocate_random_keys(int n_keys, uint32_t wildcards)
{
struct flow_key_entry *entries, *pos;
struct list_head *keys;
}
+struct check_iteration_state
+{
+ int n_found;
+ struct list_head *to_find;
+ struct list_head *found;
+};
+
+static int
+check_iteration_callback(struct sw_flow *flow, void *private)
+{
+ struct check_iteration_state *s = private;
+ struct flow_key_entry *entry;
+
+ entry = find_flow(s->to_find, flow);
+ if (entry == NULL) {
+ unit_fail("UNKNOWN ITERATOR FLOW %p", flow);
+ rcu_read_unlock();
+ return 1;
+ }
+ s->n_found++;
+ list_del(&entry->node);
+ list_add(&entry->node, s->found);
+ return 0;
+}
+
/*
* Compares an iterator's view of the 'swt' table to the list of
* flow_key_entrys in 'to_find'. flow_key_entrys that are matched are removed
static int
check_iteration(struct sw_table *swt, struct list_head *to_find, struct list_head *found)
{
- struct swt_iterator iter;
- struct flow_key_entry *entry;
- int n_found = 0;
+ struct sw_flow_key key;
+ struct sw_table_position position;
+ struct check_iteration_state state;
- rcu_read_lock();
- if (!swt->iterator(swt, &iter)) {
- rcu_read_unlock();
- unit_fail("Could not initialize iterator");
- return -1;
- }
+ memset(&key, 0, sizeof key);
+ key.wildcards = -1;
- while (iter.flow != NULL) {
- entry = find_flow(to_find, iter.flow);
- if (entry == NULL) {
- unit_fail("UNKNOWN ITERATOR FLOW %p",
- iter.flow);
- swt->iterator_destroy(&iter);
- rcu_read_unlock();
- return -1;
- }
- n_found++;
- list_del(&entry->node);
- list_add(&entry->node, found);
- swt->iterator_next(&iter);
- }
+ memset(&position, 0, sizeof position);
- swt->iterator_destroy(&iter);
+ state.n_found = 0;
+ state.to_find = to_find;
+ state.found = found;
+
+ rcu_read_lock();
+ swt->iterate(swt, &key, &position, check_iteration_callback, &state);
rcu_read_unlock();
- return n_found;
+ return state.n_found;
}
/*
list_for_each_entry_safe (pos, next, keys, node) {
if (del_all == 1 || i % 3 == 0) {
- n_del = swt->delete(swt, &pos->key, 0);
+ n_del = swt->delete(swt, &pos->key, 0, 0);
if (n_del > 1) {
unit_fail("%d flows deleted for one entry", n_del);
unit_fail("\tfuture 'errors' could just be product duplicate flow_key_entries");
*/
static int
-iterator_test(struct sw_table *swt, int n_flows, uint16_t wildcards)
+iterator_test(struct sw_table *swt, int n_flows, uint32_t wildcards)
{
struct flow_key_entry *allocated, h1, h2;
struct list_head *added, *deleted, *tmp;
iterator_test_destr:
allocated->key.wildcards = OFPFW_ALL;
- swt->delete(swt, &allocated->key, 0);
+ swt->delete(swt, &allocated->key, 0, 0);
vfree(allocated);
return success;
}
*/
static int
-add_test(struct sw_table *swt, uint16_t wildcards)
+add_test(struct sw_table *swt, uint32_t wildcards)
{
struct flow_key_entry *allocated, h1, h2;
struct list_head *added, *deleted, *tmp, *tmp2;
add_test_destr:
allocated->key.wildcards = OFPFW_ALL;
- swt->delete(swt, &allocated->key, 0);
+ swt->delete(swt, &allocated->key, 0, 0);
vfree(allocated);
return success;
}
*/
static int
-delete_test(struct sw_table *swt, uint16_t wildcards)
+delete_test(struct sw_table *swt, uint32_t wildcards)
{
struct flow_key_entry *allocated, h1, h2;
struct list_head *added, *deleted, *tmp, *tmp2;
delete_test_destr:
allocated->key.wildcards = OFPFW_ALL;
- swt->delete(swt, &allocated->key, 0);
+ swt->delete(swt, &allocated->key, 0, 0);
vfree(allocated);
return success;
}
*/
static int
-complex_add_delete_test(struct sw_table *swt, int n_flows, int i, uint16_t wildcards)
+complex_add_delete_test(struct sw_table *swt, int n_flows, int i, uint32_t wildcards)
{
struct flow_key_entry *allocated, h1, h2;
struct list_head *added, *deleted, *tmp;
complex_test_destr:
allocated->key.wildcards = OFPFW_ALL;
- swt->delete(swt, &allocated->key, 0);
+ swt->delete(swt, &allocated->key, 0, 0);
vfree(allocated);
return success;
void run_table_t(void)
{
- int mac_buckets, mac_max, linear_max, hash_buckets, hash2_buckets1;
+ int linear_max, hash_buckets, hash2_buckets1;
int hash2_buckets2, num_flows, num_iterations;
int i;
struct sw_table *swt;
/* Most basic operations. */
- simple_insert_delete(table_mac_create(2048, 65536),
- OFPFW_ALL & ~OFPFW_DL_SRC);
simple_insert_delete(table_linear_create(2048), 0);
simple_insert_delete(table_hash_create(0x04C11DB7, 2048), 0);
simple_insert_delete(table_hash2_create(0x04C11DB7, 2048,
0x1EDC6F41, 2048), 0);
- /* MAC table operations. */
- multiple_insert_destroy(table_mac_create(2048, 65536), 1024,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536), 2048,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536), 65535,
- OFPFW_ALL & ~OFPFW_DL_SRC, 0, 0);
- multiple_insert_destroy(table_mac_create(2048, 65536),
- 131072, OFPFW_ALL & ~OFPFW_DL_SRC, 65536, 65536);
-
/* Linear table operations. */
multiple_insert_destroy(table_linear_create(2048), 1024, 0, 0, 0);
multiple_insert_destroy(table_linear_create(2048), 2048, 0, 0, 0);
multiple_insert_destroy(table_hash2_create(0x04C11DB7, 1<<20,
0x04C11DB7, 1<<20), 1<<16, 0, 0, 100);
- mac_buckets = 1024;
- mac_max = 2048;
linear_max = 2048;
hash_buckets = 2048;
hash2_buckets1 = 1024;
printk(" complex_add_delete_test with %d flows and %d iterations\n\n",
num_flows, num_iterations);
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 3; i++) {
unsigned int mask = i == 0 ? : 0;
if (unit_failed())
mask = 0;
switch (i) {
case 0:
- swt = table_mac_create(mac_buckets, mac_max);
- mask = OFPFW_ALL & ~OFPFW_DL_SRC;
- break;
- case 1:
swt = table_linear_create(linear_max);
break;
- case 2:
+ case 1:
swt = table_hash_create (0x04C11DB7, hash_buckets);
break;
- case 3:
+ case 2:
swt = table_hash2_create(0x04C11DB7, hash2_buckets1,
0x1EDC6F41, hash2_buckets2);
break;
return;
}
printk("Testing %s table with %d buckets and %d max flows...\n",
- table_name(swt), mac_buckets, mac_max);
+ table_name(swt), hash_buckets, num_flows);
iterator_test(swt, 0, mask);
iterator_test(swt, num_flows, mask);
add_test(swt, mask);