2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-17 14:28:02 +00:00

classifier: Fix segfault iterating with rules that differ only in priority.

When CLS_CURSOR_FOR_EACH(_SAFE) iterated through a classifier, the
cls_cursor_next() function did not properly handle the case where there was
more than a single rule on a list.  This commit fixes the problem.

The addition to the testsuite would have found the problem earlier.

Reported-by: Teemu Koponen <koponen@nicira.com>
CC: Teemu Koponen <koponen@nicira.com>
This commit is contained in:
Ben Pfaff
2010-11-19 16:41:02 -08:00
parent 44471ad36d
commit 955f579d42
2 changed files with 24 additions and 3 deletions

View File

@@ -52,6 +52,7 @@ static void zero_wildcards(struct flow *, const struct flow_wildcards *);
(RULE) != NULL && ((NEXT) = next_rule_in_list(RULE), true); \
(RULE) = (NEXT))
static struct cls_rule *next_rule_in_list__(struct cls_rule *);
static struct cls_rule *next_rule_in_list(struct cls_rule *);
static struct cls_table *
@@ -601,11 +602,15 @@ cls_cursor_next(struct cls_cursor *cursor, struct cls_rule *rule)
const struct cls_table *table;
struct cls_rule *next;
next = next_rule_in_list(rule);
if (next) {
next = next_rule_in_list__(rule);
if (next->priority < rule->priority) {
return next;
}
/* 'next' is the head of the list, that is, the rule that is included in
* the table's hmap. (This is important when the classifier contains rules
* that differ only in priority.) */
rule = next;
HMAP_FOR_EACH_CONTINUE (rule, hmap_node, &cursor->table->rules) {
if (rule_matches(rule, cursor->target)) {
return rule;
@@ -744,9 +749,16 @@ insert_rule(struct cls_table *table, struct cls_rule *new)
}
static struct cls_rule *
next_rule_in_list(struct cls_rule *rule)
next_rule_in_list__(struct cls_rule *rule)
{
struct cls_rule *next = OBJECT_CONTAINING(rule->list.next, next, list);
return next;
}
static struct cls_rule *
next_rule_in_list(struct cls_rule *rule)
{
struct cls_rule *next = next_rule_in_list__(rule);
return next->priority < rule->priority ? next : NULL;
}