table = xzalloc(sizeof *table);
hmap_init(&table->rules);
table->wc = *wc;
+ table->is_catchall = flow_wildcards_is_catchall(&table->wc);
hmap_insert(&cls->tables, &table->hmap_node, flow_wildcards_hash(wc, 0));
return table;
find_match(const struct cls_table *table, const struct flow *flow)
{
struct cls_rule *rule;
- struct flow f;
- f = *flow;
- flow_zero_wildcards(&f, &table->wc);
- HMAP_FOR_EACH_WITH_HASH (rule, hmap_node, flow_hash(&f, 0),
- &table->rules) {
- if (flow_equal(&f, &rule->flow)) {
+ if (table->is_catchall) {
+ HMAP_FOR_EACH (rule, hmap_node, &table->rules) {
return rule;
}
+ } else {
+ struct flow f;
+
+ f = *flow;
+ flow_zero_wildcards(&f, &table->wc);
+ HMAP_FOR_EACH_WITH_HASH (rule, hmap_node, flow_hash(&f, 0),
+ &table->rules) {
+ if (flow_equal(&f, &rule->flow)) {
+ return rule;
+ }
+ }
}
+
return NULL;
}
struct hmap rules; /* Contains "struct cls_rule"s. */
struct flow_wildcards wc; /* Wildcards for fields. */
int n_table_rules; /* Number of rules, including duplicates. */
+ bool is_catchall; /* True if this table wildcards every field. */
};
/* Returns true if 'table' is a "catch-all" table that will match every
static inline bool
cls_table_is_catchall(const struct cls_table *table)
{
- /* A catch-all table can only have one rule, so use hmap_count() as a cheap
- * check to rule out other kinds of match before doing the full check with
- * flow_wildcards_is_catchall(). */
- return (hmap_count(&table->rules) == 1
- && flow_wildcards_is_catchall(&table->wc));
+ return table->is_catchall;
}
/* A flow classification rule.