X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fclassifier.c;h=4bd894216593f920d5fc26b186ee7c33464c89a1;hb=7103dec49eb569c3196239da6c178a29c3003e2b;hp=036c372bd5437a69ceb7842113c6af849a332833;hpb=834377ea559d665520910968358c522f30d3eb93;p=openvswitch diff --git a/lib/classifier.c b/lib/classifier.c index 036c372b..4bd89421 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -19,6 +19,7 @@ #include #include #include +#include "dynamic-string.h" #include "flow.h" #include "hash.h" @@ -54,8 +55,8 @@ static bool rules_match_2wild(const struct cls_rule *wild1, /* Converts the flow in 'flow' into a cls_rule in 'rule', with the given * 'wildcards' and 'priority'.*/ void -cls_rule_from_flow(struct cls_rule *rule, const flow_t *flow, - uint32_t wildcards, unsigned int priority) +cls_rule_from_flow(const flow_t *flow, uint32_t wildcards, + unsigned int priority, struct cls_rule *rule) { assert(!flow->reserved[0] && !flow->reserved[1] && !flow->reserved[2]); rule->flow = *flow; @@ -65,18 +66,32 @@ cls_rule_from_flow(struct cls_rule *rule, const flow_t *flow, } /* Converts the ofp_match in 'match' into a cls_rule in 'rule', with the given - * 'priority'. */ + * 'priority'. If 'tun_id_from_cookie' is set then the upper 32 bits of + * 'cookie' are stored in the rule as the tunnel ID. */ void -cls_rule_from_match(struct cls_rule *rule, const struct ofp_match *match, - unsigned int priority) +cls_rule_from_match(const struct ofp_match *match, unsigned int priority, + bool tun_id_from_cookie, uint64_t cookie, + struct cls_rule *rule) { uint32_t wildcards; - flow_from_match(&rule->flow, &wildcards, match); + flow_from_match(match, tun_id_from_cookie, cookie, &rule->flow, &wildcards); flow_wildcards_init(&rule->wc, wildcards); rule->priority = rule->wc.wildcards ? priority : UINT16_MAX; rule->table_idx = table_idx_from_wildcards(rule->wc.wildcards); } +/* Converts 'rule' to a string and returns the string. The caller must free + * the string (with free()). */ +char * +cls_rule_to_string(const struct cls_rule *rule) +{ + struct ds s = DS_EMPTY_INITIALIZER; + ds_put_format(&s, "wildcards=%x priority=%u ", + rule->wc.wildcards, rule->priority); + flow_format(&s, &rule->flow); + return ds_cstr(&s); +} + /* Prints cls_rule 'rule', for debugging. * * (The output could be improved and expanded, but this was good enough to @@ -292,7 +307,7 @@ classifier_lookup_wild(const struct classifier *cls, const flow_t *flow) struct cls_rule target; int i; - cls_rule_from_flow(&target, flow, 0, 0); + cls_rule_from_flow(flow, 0, 0, &target); for (i = 0; i < CLS_N_FIELDS; i++) { struct cls_rule *rule = search_table(&cls->tables[i], i, &target); if (rule && (!best || rule->priority > best->priority)) { @@ -317,7 +332,7 @@ classifier_find_rule_exactly(const struct classifier *cls, return search_exact_table(cls, flow_hash(target, 0), target); } - assert(wildcards == (wildcards & OFPFW_ALL)); + assert(wildcards == (wildcards & OVSFW_ALL)); table_idx = table_idx_from_wildcards(wildcards); hash = hash_fields(target, table_idx); HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node, hash, @@ -354,7 +369,7 @@ classifier_rule_overlaps(const struct classifier *cls, true : false; } - cls_rule_from_flow(&target_rule, target, wildcards, priority); + cls_rule_from_flow(target, wildcards, priority, &target_rule); for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) { struct cls_bucket *bucket; @@ -627,14 +642,14 @@ bucket_insert(struct cls_bucket *bucket, struct cls_rule *rule) { struct cls_rule *pos; LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) { - if (pos->priority <= rule->priority) { - if (pos->priority == rule->priority - && pos->wc.wildcards == rule->wc.wildcards + if (pos->priority == rule->priority) { + if (pos->wc.wildcards == rule->wc.wildcards && rules_match_1wild(pos, rule, rule->table_idx)) { list_replace(&rule->node.list, &pos->node.list); return pos; } + } else if (pos->priority < rule->priority) { break; } }