rule->flow.icmp_code = htons(icmp_code);
}
+/* Returns true if 'a' and 'b' have the same priority, wildcard the same
+ * fields, and have the same values for fixed fields, otherwise false. */
+bool
+cls_rule_equal(const struct cls_rule *a, const struct cls_rule *b)
+{
+ return (a->priority == b->priority
+ && flow_wildcards_equal(&a->wc, &b->wc)
+ && flow_equal(&a->flow, &b->flow));
+}
+
/* Converts 'rule' to a string and returns the string. The caller must free
* the string (with free()). */
char *
void cls_rule_set_icmp_type(struct cls_rule *, uint8_t);
void cls_rule_set_icmp_code(struct cls_rule *, uint8_t);
+bool cls_rule_equal(const struct cls_rule *, const struct cls_rule *);
+
char *cls_rule_to_string(const struct cls_rule *);
void cls_rule_print(const struct cls_rule *);
assert(rule->cls_rule.wc.wildcards || rule->cls_rule.priority == UINT_MAX);
for (i = 0; i < tcls->n_rules; i++) {
const struct cls_rule *pos = &tcls->rules[i]->cls_rule;
- if (pos->priority == rule->cls_rule.priority
- && pos->wc.wildcards == rule->cls_rule.wc.wildcards
- && flow_equal(&pos->flow, &rule->cls_rule.flow)) {
- /* Exact match.
- * XXX flow_equal should ignore wildcarded fields */
+ if (cls_rule_equal(pos, &rule->cls_rule)) {
+ /* Exact match. */
free(tcls->rules[i]);
tcls->rules[i] = xmemdup(rule, sizeof *rule);
return tcls->rules[i];
const struct test_rule *tr0 = test_rule_from_cls_rule(cr0);
const struct test_rule *tr1 = test_rule_from_cls_rule(cr1);
- assert(flow_equal(&cr0->flow, &cr1->flow));
- assert(cr0->wc.wildcards == cr1->wc.wildcards);
- assert(cr0->priority == cr1->priority);
- /* Skip nw_src_mask and nw_dst_mask, because they are derived
- * members whose values are used only for optimization. */
+ assert(cls_rule_equal(cr0, cr1));
assert(tr0->aux == tr1->aux);
}
}