secchan: Fix subrule revalidation.
authorBen Pfaff <blp@nicira.com>
Tue, 3 Mar 2009 00:33:01 +0000 (16:33 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 3 Mar 2009 00:33:01 +0000 (16:33 -0800)
When revalidating a subrule, we need to only match rules with wildcards.
Otherwise, a subrule will always match itself and we will explode.

lib/classifier.c
lib/classifier.h
secchan/ofproto.c

index 8172f6269a10297eaf6349be68b8f71ebef73b00..5081823dad93d221065a06fa3c8c0bd6633831b1 100644 (file)
@@ -272,11 +272,26 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule)
 struct cls_rule *
 classifier_lookup(const struct classifier *cls, const flow_t *flow)
 {
-    struct cls_rule *best = NULL;
-    if (!hmap_is_empty(&cls->exact_table)) {
-        best = search_exact_table(cls, flow_hash(flow, 0), flow);
+    struct cls_rule *rule = classifier_lookup_exact(cls, flow);
+    if (!rule) {
+        rule = classifier_lookup_wild(cls, flow);
     }
-    if (!best && cls->n_rules > hmap_count(&cls->exact_table)) {
+    return rule;
+}
+
+struct cls_rule *
+classifier_lookup_exact(const struct classifier *cls, const flow_t *flow)
+{
+    return (!hmap_is_empty(&cls->exact_table)
+            ? search_exact_table(cls, flow_hash(flow, 0), flow)
+            : NULL);
+}
+
+struct cls_rule *
+classifier_lookup_wild(const struct classifier *cls, const flow_t *flow)
+{
+    struct cls_rule *best = NULL;
+    if (cls->n_rules > hmap_count(&cls->exact_table)) {
         struct cls_rule target;
         int i;
 
index 1a9125d4838246b5179497d015ebd3f2790cc6fd..fdbb7bb83cba8ef6b488ec4e5032e4ca94155a31 100644 (file)
@@ -140,6 +140,10 @@ int classifier_count_exact(const struct classifier *);
 struct cls_rule *classifier_insert(struct classifier *, struct cls_rule *);
 void classifier_remove(struct classifier *, struct cls_rule *);
 struct cls_rule *classifier_lookup(const struct classifier *, const flow_t *);
+struct cls_rule *classifier_lookup_wild(const struct classifier *,
+                                        const flow_t *);
+struct cls_rule *classifier_lookup_exact(const struct classifier *,
+                                         const flow_t *);
 
 typedef void cls_cb_func(struct cls_rule *, void *aux);
 void classifier_for_each(const struct classifier *, cls_cb_func *, void *aux);
index f61a35f14f063101a96f770cf8b9184bd4eb72b1..2abb59525cf00f8043c26947efa1bcb29312ee48 100644 (file)
@@ -2153,7 +2153,7 @@ revalidate_subrule(struct cls_rule *sub_, void *p_)
         return;
     }
 
-    super = rule_from_cls_rule(classifier_lookup(&p->cls, &sub->cr.flow));
+    super = rule_from_cls_rule(classifier_lookup_wild(&p->cls, &sub->cr.flow));
     if (super != sub->super) {
         if (!super) {
             struct odp_flow odp_flow;