From 48c3de13bee26106d8e708600904f2b20bd08818 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 14 Oct 2010 10:13:51 -0700 Subject: [PATCH] classifier: Merge classifier_lookup_wild(), classifier_lookup_exact(). Merge these functions into classifier_lookup() and update its interface. The new version of the classifier soon to be implemented naturally merges these functions, so this commit updates the interface early. --- lib/classifier.c | 46 ++++++++++++++++++++++++----------------- lib/classifier.h | 17 +++++++-------- ofproto/ofproto.c | 6 ++++-- tests/test-classifier.c | 18 +--------------- 4 files changed, 39 insertions(+), 48 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index 70fee9548..779c7e88c 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -212,24 +212,7 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule) cls->n_rules--; } -/* 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. - * - * (When multiple rules of equal priority happen to fall into the same bucket, - * rules added more recently take priority over rules added less recently, but - * this is subject to change and should not be depended upon.) */ -struct cls_rule * -classifier_lookup(const struct classifier *cls, const struct flow *flow) -{ - struct cls_rule *rule = classifier_lookup_exact(cls, flow); - if (!rule) { - rule = classifier_lookup_wild(cls, flow); - } - return rule; -} - -struct cls_rule * +static struct cls_rule * classifier_lookup_exact(const struct classifier *cls, const struct flow *flow) { return (!hmap_is_empty(&cls->exact_table) @@ -237,7 +220,7 @@ classifier_lookup_exact(const struct classifier *cls, const struct flow *flow) : NULL); } -struct cls_rule * +static struct cls_rule * classifier_lookup_wild(const struct classifier *cls, const struct flow *flow) { struct cls_rule *best = NULL; @@ -256,6 +239,31 @@ classifier_lookup_wild(const struct classifier *cls, const struct flow *flow) return best; } +/* 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. + * + * (When multiple rules of equal priority happen to fall into the same bucket, + * rules added more recently take priority over rules added less recently, but + * this is subject to change and should not be depended upon.) */ +struct cls_rule * +classifier_lookup(const struct classifier *cls, const struct flow *flow, + int include) +{ + if (include & CLS_INC_EXACT) { + struct cls_rule *rule = classifier_lookup_exact(cls, flow); + if (rule) { + return rule; + } + } + + if (include & CLS_INC_WILD) { + return classifier_lookup_wild(cls, flow); + } + + return NULL; +} + struct cls_rule * classifier_find_rule_exactly(const struct classifier *cls, const struct flow *target, uint32_t wildcards, diff --git a/lib/classifier.h b/lib/classifier.h index 3ad69e00c..28be2471a 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -123,6 +123,12 @@ struct cls_rule { unsigned int table_idx; /* Index into struct classifier 'tables'. */ }; +enum { + CLS_INC_EXACT = 1 << 0, /* Include exact-match flows? */ + CLS_INC_WILD = 1 << 1, /* Include flows with wildcards? */ + CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD +}; + void cls_rule_from_flow(const struct flow *, uint32_t wildcards, unsigned int priority, struct cls_rule *); void cls_rule_from_match(const struct ofp_match *, unsigned int priority, @@ -140,21 +146,12 @@ struct cls_rule *classifier_insert(struct classifier *, struct cls_rule *); void classifier_insert_exact(struct classifier *, struct cls_rule *); void classifier_remove(struct classifier *, struct cls_rule *); struct cls_rule *classifier_lookup(const struct classifier *, - const struct flow *); -struct cls_rule *classifier_lookup_wild(const struct classifier *, - const struct flow *); -struct cls_rule *classifier_lookup_exact(const struct classifier *, - const struct flow *); + const struct flow *, int include); bool classifier_rule_overlaps(const struct classifier *, const struct flow *, uint32_t wildcards, unsigned int priority); typedef void cls_cb_func(struct cls_rule *, void *aux); -enum { - CLS_INC_EXACT = 1 << 0, /* Include exact-match flows? */ - CLS_INC_WILD = 1 << 1, /* Include flows with wildcards? */ - CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD -}; void classifier_for_each(const struct classifier *, int include, cls_cb_func *, void *aux); void classifier_for_each_match(const struct classifier *, diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 5bdf1b7d0..727f39605 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2499,7 +2499,8 @@ static struct rule * lookup_valid_rule(struct ofproto *ofproto, const struct flow *flow) { struct rule *rule; - rule = rule_from_cls_rule(classifier_lookup(&ofproto->cls, flow)); + rule = rule_from_cls_rule(classifier_lookup(&ofproto->cls, flow, + CLS_INC_ALL)); /* The rule we found might not be valid, since we could be in need of * revalidation. If it is not valid, don't return it. */ @@ -4540,7 +4541,8 @@ revalidate_rule(struct ofproto *p, struct rule *rule) COVERAGE_INC(ofproto_revalidate_rule); if (rule->super) { struct rule *super; - super = rule_from_cls_rule(classifier_lookup_wild(&p->cls, flow)); + super = rule_from_cls_rule(classifier_lookup(&p->cls, flow, + CLS_INC_WILD)); if (!super) { rule_remove(p, rule); return false; diff --git a/tests/test-classifier.c b/tests/test-classifier.c index d8c0e1021..b5972bdba 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -324,22 +324,6 @@ get_value(unsigned int *x, unsigned n_values) return rem; } -static struct cls_rule * -lookup_with_include_bits(const struct classifier *cls, - const struct flow *flow, int include) -{ - switch (include) { - case CLS_INC_WILD: - return classifier_lookup_wild(cls, flow); - case CLS_INC_EXACT: - return classifier_lookup_exact(cls, flow); - case CLS_INC_WILD | CLS_INC_EXACT: - return classifier_lookup(cls, flow); - default: - abort(); - } -} - static void compare_classifiers(struct classifier *cls, struct tcls *tcls) { @@ -373,7 +357,7 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls) flow.nw_tos = nw_tos_values[get_value(&x, N_NW_TOS_VALUES)]; for (include = 1; include <= 3; include++) { - cr0 = lookup_with_include_bits(cls, &flow, include); + cr0 = classifier_lookup(cls, &flow, include); cr1 = tcls_lookup(tcls, &flow, include); assert((cr0 == NULL) == (cr1 == NULL)); if (cr0 != NULL) { -- 2.43.0