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.
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)
: NULL);
}
-struct cls_rule *
+static struct cls_rule *
classifier_lookup_wild(const struct classifier *cls, const struct flow *flow)
{
struct cls_rule *best = NULL;
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,
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,
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 *,
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. */
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;
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)
{
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) {