From: Ethan Jackson Date: Fri, 10 May 2013 02:15:54 +0000 (-0700) Subject: classifier: Add 'wc' argument to classifier_lookup(). X-Git-Tag: v1.11.0~89 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=4054bba5a09568bee27dc76b6f3dfd13e98b67a8 classifier: Add 'wc' argument to classifier_lookup(). A future commit will want to know what bits were significant during the classifier lookup. Signed-off-by: Ethan Jackson Co-authored-by: Justin Pettit Signed-off-by: Justin Pettit --- diff --git a/lib/classifier.c b/lib/classifier.c index 2d1e50bbb..a717bd347 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -252,9 +252,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 +268,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 +281,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; } diff --git a/lib/classifier.h b/lib/classifier.h index d318864e1..fdc3af7af 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -96,7 +96,8 @@ void classifier_insert(struct classifier *, struct cls_rule *); struct cls_rule *classifier_replace(struct classifier *, struct cls_rule *); void classifier_remove(struct classifier *, struct cls_rule *); struct cls_rule *classifier_lookup(const struct classifier *, - const struct flow *); + const struct flow *, + struct flow_wildcards *); bool classifier_rule_overlaps(const struct classifier *, const struct cls_rule *); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index f5467a375..61734a320 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5439,11 +5439,11 @@ rule_dpif_lookup__(struct ofproto_dpif *ofproto, const struct flow *flow, struct flow ofpc_normal_flow = *flow; ofpc_normal_flow.tp_src = htons(0); ofpc_normal_flow.tp_dst = htons(0); - cls_rule = classifier_lookup(cls, &ofpc_normal_flow); + cls_rule = classifier_lookup(cls, &ofpc_normal_flow, NULL); } else if (frag && ofproto->up.frag_handling == OFPC_FRAG_DROP) { cls_rule = &ofproto->drop_frags_rule->up.cr; } else { - cls_rule = classifier_lookup(cls, flow); + cls_rule = classifier_lookup(cls, flow, NULL); } return rule_dpif_cast(rule_from_cls_rule(cls_rule)); } diff --git a/tests/test-classifier.c b/tests/test-classifier.c index 18dee86f9..da7bdcba8 100644 --- a/tests/test-classifier.c +++ b/tests/test-classifier.c @@ -422,7 +422,7 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls) flow.nw_proto = nw_proto_values[get_value(&x, N_NW_PROTO_VALUES)]; flow.nw_tos = nw_dscp_values[get_value(&x, N_NW_DSCP_VALUES)]; - cr0 = classifier_lookup(cls, &flow); + cr0 = classifier_lookup(cls, &flow, NULL); cr1 = tcls_lookup(tcls, &flow); assert((cr0 == NULL) == (cr1 == NULL)); if (cr0 != NULL) {