From: Ethan Jackson <et...@nicira.com> A future commit will want to know what bits were significant during the classifier lookup.
Signed-off-by: Ethan Jackson <et...@nicira.com> Co-authored-by: Justin Pettit <jpet...@nicira.com> Signed-off-by: Justin Pettit <jpet...@nicira.com> --- lib/classifier.c | 17 +++++++++++++++-- lib/classifier.h | 3 ++- ofproto/ofproto-dpif.c | 4 ++-- tests/test-classifier.c | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/classifier.c b/lib/classifier.c index 2d1e50b..a717bd3 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 d318864..fdc3af7 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 ec2d95d..992ff94 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5463,11 +5463,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 18dee86..da7bdcb 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) { -- 1.7.5.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev