X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Ftable-hash.c;h=c87048f710e99bc63ad925e6cf41897036e2cb99;hb=db74f018735cef6f5e975e6278f78997d1de23b3;hp=6f3e419628984e0edb85ccb5b3e3ef14fb88fd91;hpb=3c08544960cc3564135d706ed5d3dfe570b87eed;p=sliver-openvswitch.git diff --git a/datapath/table-hash.c b/datapath/table-hash.c index 6f3e41962..c87048f71 100644 --- a/datapath/table-hash.c +++ b/datapath/table-hash.c @@ -123,7 +123,7 @@ static int table_hash_timeout(struct datapath *dp, struct sw_table *swt) struct sw_flow *flow = *bucket; if (flow && flow_timeout(flow)) { count += do_delete(bucket, flow); - if (dp->hello_flags & OFP_CHELLO_SEND_FLOW_EXP) + if (dp->flags & OFPC_SEND_FLOW_EXP) dp_send_flow_expired(dp, flow); } } @@ -144,58 +144,37 @@ static void table_hash_destroy(struct sw_table *swt) kfree(th); } -struct swt_iterator_hash { - struct sw_table_hash *th; - unsigned int bucket_i; -}; - -static struct sw_flow *next_flow(struct swt_iterator_hash *ih) +static int table_hash_iterate(struct sw_table *swt, + const struct sw_flow_key *key, + struct sw_table_position *position, + int (*callback)(struct sw_flow *, void *private), + void *private) { - for (;ih->bucket_i <= ih->th->bucket_mask; ih->bucket_i++) { - struct sw_flow *f = ih->th->buckets[ih->bucket_i]; - if (f != NULL) - return f; - } - - return NULL; -} - -static int table_hash_iterator(struct sw_table *swt, - struct swt_iterator *swt_iter) -{ - struct swt_iterator_hash *ih; - - swt_iter->private = ih = kmalloc(sizeof *ih, GFP_KERNEL); + struct sw_table_hash *th = (struct sw_table_hash *) swt; - if (ih == NULL) + if (position->private[0] > th->bucket_mask) return 0; - ih->th = (struct sw_table_hash *) swt; - - ih->bucket_i = 0; - swt_iter->flow = next_flow(ih); - - return 1; -} - -static void table_hash_next(struct swt_iterator *swt_iter) -{ - struct swt_iterator_hash *ih; - - if (swt_iter->flow == NULL) - return; - - ih = (struct swt_iterator_hash *) swt_iter->private; - - ih->bucket_i++; - swt_iter->flow = next_flow(ih); -} - -static void table_hash_iterator_destroy(struct swt_iterator *swt_iter) -{ - kfree(swt_iter->private); + if (key->wildcards == 0) { + struct sw_flow *flow = table_hash_lookup(swt, key); + position->private[0] = -1; + return flow ? callback(flow, private) : 0; + } else { + int i; + + for (i = position->private[0]; i <= th->bucket_mask; i++) { + struct sw_flow *flow = th->buckets[i]; + if (flow && flow_matches(key, &flow->key)) { + int error = callback(flow, private); + if (error) { + position->private[0] = i + 1; + return error; + } + } + } + return 0; + } } - static void table_hash_stats(struct sw_table *swt, struct sw_table_stats *stats) { @@ -230,9 +209,7 @@ struct sw_table *table_hash_create(unsigned int polynomial, swt->delete = table_hash_delete; swt->timeout = table_hash_timeout; swt->destroy = table_hash_destroy; - swt->iterator = table_hash_iterator; - swt->iterator_next = table_hash_next; - swt->iterator_destroy = table_hash_iterator_destroy; + swt->iterate = table_hash_iterate; swt->stats = table_hash_stats; spin_lock_init(&th->lock); @@ -295,79 +272,25 @@ static void table_hash2_destroy(struct sw_table *swt) kfree(t2); } -struct swt_iterator_hash2 { - struct sw_table_hash2 *th2; - struct swt_iterator ih; - uint8_t table_i; -}; - -static int table_hash2_iterator(struct sw_table *swt, - struct swt_iterator *swt_iter) -{ - struct swt_iterator_hash2 *ih2; - - swt_iter->private = ih2 = kmalloc(sizeof *ih2, GFP_KERNEL); - if (ih2 == NULL) - return 0; - - ih2->th2 = (struct sw_table_hash2 *) swt; - if (!table_hash_iterator(ih2->th2->subtable[0], &ih2->ih)) { - kfree(ih2); - return 0; - } - - if (ih2->ih.flow != NULL) { - swt_iter->flow = ih2->ih.flow; - ih2->table_i = 0; - } else { - table_hash_iterator_destroy(&ih2->ih); - ih2->table_i = 1; - if (!table_hash_iterator(ih2->th2->subtable[1], &ih2->ih)) { - kfree(ih2); - return 0; - } - swt_iter->flow = ih2->ih.flow; - } - - return 1; -} - -static void table_hash2_next(struct swt_iterator *swt_iter) +static int table_hash2_iterate(struct sw_table *swt, + const struct sw_flow_key *key, + struct sw_table_position *position, + int (*callback)(struct sw_flow *, void *), + void *private) { - struct swt_iterator_hash2 *ih2; - - if (swt_iter->flow == NULL) - return; - - ih2 = (struct swt_iterator_hash2 *) swt_iter->private; - table_hash_next(&ih2->ih); + struct sw_table_hash2 *t2 = (struct sw_table_hash2 *) swt; + int i; - if (ih2->ih.flow != NULL) { - swt_iter->flow = ih2->ih.flow; - } else { - if (ih2->table_i == 0) { - table_hash_iterator_destroy(&ih2->ih); - ih2->table_i = 1; - if (!table_hash_iterator(ih2->th2->subtable[1], &ih2->ih)) { - ih2->ih.private = NULL; - swt_iter->flow = NULL; - } else { - swt_iter->flow = ih2->ih.flow; - } - } else { - swt_iter->flow = NULL; + for (i = position->private[1]; i < 2; i++) { + int error = table_hash_iterate(t2->subtable[i], key, position, + callback, private); + if (error) { + return error; } + position->private[0] = 0; + position->private[1]++; } -} - -static void table_hash2_iterator_destroy(struct swt_iterator *swt_iter) -{ - struct swt_iterator_hash2 *ih2; - - ih2 = (struct swt_iterator_hash2 *) swt_iter->private; - if (ih2->ih.private != NULL) - table_hash_iterator_destroy(&ih2->ih); - kfree(ih2); + return 0; } static void table_hash2_stats(struct sw_table *swt, @@ -409,12 +332,9 @@ struct sw_table *table_hash2_create(unsigned int poly0, unsigned int buckets0, swt->delete = table_hash2_delete; swt->timeout = table_hash2_timeout; swt->destroy = table_hash2_destroy; + swt->iterate = table_hash2_iterate; swt->stats = table_hash2_stats; - swt->iterator = table_hash2_iterator; - swt->iterator_next = table_hash2_next; - swt->iterator_destroy = table_hash2_iterator_destroy; - return swt; out_free_subtable0: