X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fclassifier.c;h=a5eccf53111cdca5bad337ea0a6c9e4aee9a0578;hb=06036898849;hp=378faf8e0e09f215728be2a2185a45bd4ee74c62;hpb=d295e8e97acae13552a5b220d3fbcff8201064a2;p=openvswitch diff --git a/lib/classifier.c b/lib/classifier.c index 378faf8e..a5eccf53 100644 --- a/lib/classifier.c +++ b/lib/classifier.c @@ -25,17 +25,18 @@ const struct cls_field cls_fields[CLS_N_FIELDS + 1] = { #define CLS_FIELD(WILDCARDS, MEMBER, NAME) \ - { offsetof(flow_t, MEMBER), \ - sizeof ((flow_t *)0)->MEMBER, \ + { offsetof(struct flow, MEMBER), \ + sizeof ((struct flow *)0)->MEMBER, \ WILDCARDS, \ #NAME }, CLS_FIELDS #undef CLS_FIELD - { sizeof(flow_t), 0, 0, "exact" }, + { sizeof(struct flow), 0, 0, "exact" }, }; -static uint32_t hash_fields(const flow_t *, int table_idx); -static bool equal_fields(const flow_t *, const flow_t *, int table_idx); +static uint32_t hash_fields(const struct flow *, int table_idx); +static bool equal_fields(const struct flow *, const struct flow *, + int table_idx); static int table_idx_from_wildcards(uint32_t wildcards); static struct cls_rule *table_insert(struct hmap *, struct cls_rule *); @@ -46,7 +47,7 @@ static struct cls_bucket *find_bucket(struct hmap *, size_t hash, static struct cls_rule *search_table(const struct hmap *table, int field_idx, const struct cls_rule *); static struct cls_rule *search_exact_table(const struct classifier *, - size_t hash, const flow_t *); + size_t hash, const struct flow *); static bool rules_match_1wild(const struct cls_rule *fixed, const struct cls_rule *wild, int field_idx); static bool rules_match_2wild(const struct cls_rule *wild1, @@ -55,10 +56,9 @@ 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(const flow_t *flow, uint32_t wildcards, +cls_rule_from_flow(const struct flow *flow, uint32_t wildcards, unsigned int priority, struct cls_rule *rule) { - assert(!flow->reserved[0] && !flow->reserved[1] && !flow->reserved[2]); rule->flow = *flow; flow_wildcards_init(&rule->wc, wildcards); rule->priority = priority; @@ -177,8 +177,7 @@ classifier_destroy(struct classifier *cls) struct hmap *tbl; for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) { - HMAP_FOR_EACH_SAFE (bucket, next_bucket, - struct cls_bucket, hmap_node, tbl) { + HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, tbl) { free(bucket); } hmap_destroy(tbl); @@ -282,7 +281,7 @@ classifier_remove(struct classifier *cls, struct cls_rule *rule) * 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 flow_t *flow) +classifier_lookup(const struct classifier *cls, const struct flow *flow) { struct cls_rule *rule = classifier_lookup_exact(cls, flow); if (!rule) { @@ -292,7 +291,7 @@ classifier_lookup(const struct classifier *cls, const flow_t *flow) } struct cls_rule * -classifier_lookup_exact(const struct classifier *cls, const flow_t *flow) +classifier_lookup_exact(const struct classifier *cls, const struct flow *flow) { return (!hmap_is_empty(&cls->exact_table) ? search_exact_table(cls, flow_hash(flow, 0), flow) @@ -300,7 +299,7 @@ classifier_lookup_exact(const struct classifier *cls, const flow_t *flow) } struct cls_rule * -classifier_lookup_wild(const struct classifier *cls, const flow_t *flow) +classifier_lookup_wild(const struct classifier *cls, const struct flow *flow) { struct cls_rule *best = NULL; if (cls->n_rules > hmap_count(&cls->exact_table)) { @@ -320,7 +319,7 @@ classifier_lookup_wild(const struct classifier *cls, const flow_t *flow) struct cls_rule * classifier_find_rule_exactly(const struct classifier *cls, - const flow_t *target, uint32_t wildcards, + const struct flow *target, uint32_t wildcards, unsigned int priority) { struct cls_bucket *bucket; @@ -335,11 +334,11 @@ classifier_find_rule_exactly(const struct classifier *cls, 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, + HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node, hash, &cls->tables[table_idx]) { if (equal_fields(&bucket->fixed, target, table_idx)) { struct cls_rule *pos; - LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) { + LIST_FOR_EACH (pos, node.list, &bucket->rules) { if (pos->priority < priority) { return NULL; } else if (pos->priority == priority && @@ -358,7 +357,7 @@ classifier_find_rule_exactly(const struct classifier *cls, * Two rules are considered overlapping if a packet could match both. */ bool classifier_rule_overlaps(const struct classifier *cls, - const flow_t *target, uint32_t wildcards, + const struct flow *target, uint32_t wildcards, unsigned int priority) { struct cls_rule target_rule; @@ -374,13 +373,12 @@ classifier_rule_overlaps(const struct classifier *cls, for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) { struct cls_bucket *bucket; - HMAP_FOR_EACH (bucket, struct cls_bucket, hmap_node, tbl) { + HMAP_FOR_EACH (bucket, hmap_node, tbl) { struct cls_rule *rule; - LIST_FOR_EACH (rule, struct cls_rule, node.list, - &bucket->rules) { + LIST_FOR_EACH (rule, node.list, &bucket->rules) { if (rule->priority == priority - && rules_match_2wild(rule, &target_rule, 0)) { + && rules_match_2wild(rule, &target_rule, 0)) { return true; } } @@ -409,8 +407,7 @@ classifier_for_each_match(const struct classifier *cls, table++) { struct cls_bucket *bucket, *next_bucket; - HMAP_FOR_EACH_SAFE (bucket, next_bucket, - struct cls_bucket, hmap_node, table) { + HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, table) { /* XXX there is a bit of room for optimization here based on * rejecting entire buckets on their fixed fields, but it will * only be worthwhile for big buckets (which we hope we won't @@ -422,8 +419,7 @@ classifier_for_each_match(const struct classifier *cls, * bucket itself will be destroyed. The bucket contains the * list head so that's a use-after-free error. */ prev_rule = NULL; - LIST_FOR_EACH (rule, struct cls_rule, node.list, - &bucket->rules) { + LIST_FOR_EACH (rule, node.list, &bucket->rules) { if (rules_match_1wild(rule, target, 0)) { if (prev_rule) { callback(prev_rule, aux); @@ -442,7 +438,7 @@ classifier_for_each_match(const struct classifier *cls, if (target->wc.wildcards) { struct cls_rule *rule, *next_rule; - HMAP_FOR_EACH_SAFE (rule, next_rule, struct cls_rule, node.hmap, + HMAP_FOR_EACH_SAFE (rule, next_rule, node.hmap, &cls->exact_table) { if (rules_match_1wild(rule, target, 0)) { callback(rule, aux); @@ -465,7 +461,10 @@ classifier_for_each_match(const struct classifier *cls, * it must not delete (or move) any other rules in 'cls' that are in the same * table as the argument rule. Two rules are in the same table if their * cls_rule structs have the same table_idx; as a special case, a rule with - * wildcards and an exact-match rule will never be in the same table. */ + * wildcards and an exact-match rule will never be in the same table. + * + * If 'include' is CLS_INC_EXACT then CLASSIFIER_FOR_EACH_EXACT_RULE(_SAFE) is + * probably easier to use. */ void classifier_for_each(const struct classifier *cls, int include, void (*callback)(struct cls_rule *, void *aux), @@ -477,8 +476,7 @@ classifier_for_each(const struct classifier *cls, int include, for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) { struct cls_bucket *bucket, *next_bucket; - HMAP_FOR_EACH_SAFE (bucket, next_bucket, - struct cls_bucket, hmap_node, tbl) { + HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, tbl) { struct cls_rule *prev_rule, *rule; /* We can't just use LIST_FOR_EACH_SAFE here because, if the @@ -486,8 +484,7 @@ classifier_for_each(const struct classifier *cls, int include, * bucket itself will be destroyed. The bucket contains the * list head so that's a use-after-free error. */ prev_rule = NULL; - LIST_FOR_EACH (rule, struct cls_rule, node.list, - &bucket->rules) { + LIST_FOR_EACH (rule, node.list, &bucket->rules) { if (prev_rule) { callback(prev_rule, aux); } @@ -503,15 +500,14 @@ classifier_for_each(const struct classifier *cls, int include, if (include & CLS_INC_EXACT) { struct cls_rule *rule, *next_rule; - HMAP_FOR_EACH_SAFE (rule, next_rule, - struct cls_rule, node.hmap, &cls->exact_table) { + HMAP_FOR_EACH_SAFE (rule, next_rule, node.hmap, &cls->exact_table) { callback(rule, aux); } } } static struct cls_bucket *create_bucket(struct hmap *, size_t hash, - const flow_t *fixed); + const struct flow *fixed); static struct cls_rule *bucket_insert(struct cls_bucket *, struct cls_rule *); static inline bool equal_bytes(const void *, const void *, size_t n); @@ -520,7 +516,7 @@ static inline bool equal_bytes(const void *, const void *, size_t n); * (CLS_F_IDX_*) are less than 'table_idx'. (If 'table_idx' is * CLS_F_IDX_EXACT, hashes all the fields in 'flow'). */ static uint32_t -hash_fields(const flow_t *flow, int table_idx) +hash_fields(const struct flow *flow, int table_idx) { /* I just know I'm going to hell for writing code this way. * @@ -586,7 +582,7 @@ finish: * * Returns true if all the compared fields are equal, false otherwise. */ static bool -equal_fields(const flow_t *a, const flow_t *b, int table_idx) +equal_fields(const struct flow *a, const struct flow *b, int table_idx) { /* XXX The generated code could be better here. */ #define CLS_FIELD(WILDCARDS, MEMBER, NAME) \ @@ -641,7 +637,7 @@ static struct cls_rule * 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) { + LIST_FOR_EACH (pos, node.list, &bucket->rules) { if (pos->priority == rule->priority) { if (pos->wc.wildcards == rule->wc.wildcards && rules_match_1wild(pos, rule, rule->table_idx)) @@ -679,8 +675,7 @@ static struct cls_bucket * find_bucket(struct hmap *table, size_t hash, const struct cls_rule *rule) { struct cls_bucket *bucket; - HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node, hash, - table) { + HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node, hash, table) { if (equal_fields(&bucket->fixed, &rule->flow, rule->table_idx)) { return bucket; } @@ -691,7 +686,7 @@ find_bucket(struct hmap *table, size_t hash, const struct cls_rule *rule) /* Creates a bucket and inserts it in 'table' with the given 'hash' and 'fixed' * values. Returns the new bucket. */ static struct cls_bucket * -create_bucket(struct hmap *table, size_t hash, const flow_t *fixed) +create_bucket(struct hmap *table, size_t hash, const struct flow *fixed) { struct cls_bucket *bucket = xmalloc(sizeof *bucket); list_init(&bucket->rules); @@ -752,7 +747,7 @@ read_uint32(const void *p) * The compared field is the one with wildcard bit or bits 'field_wc', offset * 'rule_ofs' within cls_rule's "fields" member, and length 'len', in bytes. */ static inline bool ALWAYS_INLINE -field_matches(const flow_t *a_, const flow_t *b_, +field_matches(const struct flow *a_, const struct flow *b_, uint32_t wildcards, uint32_t nw_src_mask, uint32_t nw_dst_mask, uint32_t field_wc, int ofs, int len) { @@ -793,7 +788,7 @@ rules_match(const struct cls_rule *a, const struct cls_rule *b, case CLS_F_IDX_##NAME: \ if (!field_matches(&a->flow, &b->flow, \ wildcards, nw_src_mask, nw_dst_mask, \ - WILDCARDS, offsetof(flow_t, MEMBER), \ + WILDCARDS, offsetof(struct flow, MEMBER), \ sizeof a->flow.MEMBER)) { \ return false; \ } \ @@ -850,7 +845,7 @@ search_bucket(struct cls_bucket *bucket, int field_idx, return NULL; } - LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) { + LIST_FOR_EACH (pos, node.list, &bucket->rules) { if (rules_match_1wild(target, pos, field_idx)) { return pos; } @@ -878,7 +873,7 @@ search_table(const struct hmap *table, int field_idx, return search_bucket(bucket, field_idx, target); } - HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node, + HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node, hash_fields(&target->flow, field_idx), table) { struct cls_rule *rule = search_bucket(bucket, field_idx, target); if (rule) { @@ -890,12 +885,11 @@ search_table(const struct hmap *table, int field_idx, static struct cls_rule * search_exact_table(const struct classifier *cls, size_t hash, - const flow_t *target) + const struct flow *target) { struct cls_rule *rule; - HMAP_FOR_EACH_WITH_HASH (rule, struct cls_rule, node.hmap, - hash, &cls->exact_table) { + HMAP_FOR_EACH_WITH_HASH (rule, node.hmap, hash, &cls->exact_table) { if (flow_equal(&rule->flow, target)) { return rule; }