X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fclassifier.c;h=556278f3d745920fc8aa220fac3373eccb5d6260;hb=591cb419cf3694e0ae66a95973e73c61bad9e03d;hp=2d1e50bbb48a840a350d485cd2e047f931c34c6c;hpb=4aacd02daa1ece830c604b9c5679e2175ff53194;p=sliver-openvswitch.git diff --git a/lib/classifier.c b/lib/classifier.c index 2d1e50bbb..556278f3d 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -25,6 +25,7 @@ #include "odp-util.h" #include "ofp-util.h" #include "packets.h" +#include "ovs-thread.h" static struct cls_table *find_table(const struct classifier *, const struct minimask *); @@ -143,6 +144,7 @@ classifier_init(struct classifier *cls) cls->n_rules = 0; hmap_init(&cls->tables); list_init(&cls->tables_priority); + ovs_rwlock_init(&cls->rwlock); } /* Destroys 'cls'. Rules within 'cls', if any, are not freed; this is the @@ -157,6 +159,7 @@ classifier_destroy(struct classifier *cls) destroy_table(cls, table); } hmap_destroy(&cls->tables); + ovs_rwlock_destroy(&cls->rwlock); } } @@ -252,9 +255,15 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule) /* Finds and returns the highest-priority rule in 'cls' that matches 'flow'. * Returns a null pointer if no rules in 'cls' match 'flow'. If multiple rules - * of equal priority match 'flow', returns one arbitrarily. */ + * of equal priority match 'flow', returns one arbitrarily. + * + * If a rule is found and 'wc' is non-null, bitwise-OR's 'wc' with the + * set of bits that were significant in the lookup. At some point + * earlier, 'wc' should have been initialized (e.g., by + * flow_wildcards_init_catchall()). */ struct cls_rule * -classifier_lookup(const struct classifier *cls, const struct flow *flow) +classifier_lookup(const struct classifier *cls, const struct flow *flow, + struct flow_wildcards *wc) { struct cls_table *table; struct cls_rule *best; @@ -262,6 +271,10 @@ classifier_lookup(const struct classifier *cls, const struct flow *flow) best = NULL; LIST_FOR_EACH (table, list_node, &cls->tables_priority) { struct cls_rule *rule = find_match(table, flow); + + if (wc) { + flow_wildcards_fold_minimask(wc, &table->mask); + } if (rule) { best = rule; LIST_FOR_EACH_CONTINUE (table, list_node, &cls->tables_priority) { @@ -271,6 +284,9 @@ classifier_lookup(const struct classifier *cls, const struct flow *flow) return best; } rule = find_match(table, flow); + if (wc) { + flow_wildcards_fold_minimask(wc, &table->mask); + } if (rule && rule->priority > best->priority) { best = rule; }