classifier: Merge classifier_lookup_wild(), classifier_lookup_exact().
authorBen Pfaff <blp@nicira.com>
Thu, 14 Oct 2010 17:13:51 +0000 (10:13 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 29 Oct 2010 16:53:51 +0000 (09:53 -0700)
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
lib/classifier.h
ofproto/ofproto.c
tests/test-classifier.c

index 70fee9548e8f395e104dff9a46b25c462ef21e21..779c7e88c5d1172d1b98992f585cb475a8e93842 100644 (file)
@@ -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,
index 3ad69e00c65817a5cc7b3813c66c04eeb170090f..28be2471a7629d3e5edfc2df34b59c66c2a4edbe 100644 (file)
@@ -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 *,
index 5bdf1b7d0d3ae09816d47f790392d8077a443ae2..727f39605198dc388bdb24ea720b0ed4af797a53 100644 (file)
@@ -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;
index d8c0e10213b5e7012a437b27e04b3c351280d54b..b5972bdbacf4c915cd63a798a705db263bc526b1 100644 (file)
@@ -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) {