From: Ben Pfaff Date: Tue, 3 Mar 2009 00:33:01 +0000 (-0800) Subject: secchan: Fix subrule revalidation. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4af66eba75dc07a6f0f7160aaf172e3ccb663c7b;p=openvswitch secchan: Fix subrule revalidation. When revalidating a subrule, we need to only match rules with wildcards. Otherwise, a subrule will always match itself and we will explode. --- diff --git a/lib/classifier.c b/lib/classifier.c index 8172f626..5081823d 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -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; diff --git a/lib/classifier.h b/lib/classifier.h index 1a9125d4..fdbb7bb8 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -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); diff --git a/secchan/ofproto.c b/secchan/ofproto.c index f61a35f1..2abb5952 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -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;