So far, each OpenFlow table has just been a classifier. Upcoming commits will add more data for each OpenFlow table, so this commit encapsulates the struct classifier in a higher-level structure to provide a good place to keep that data.
Signed-off-by: Ben Pfaff <b...@nicira.com> --- ofproto/ofproto-dpif.c | 16 ++++---- ofproto/ofproto-provider.h | 23 +++++++---- ofproto/ofproto.c | 92 ++++++++++++++++++++++---------------------- 3 files changed, 68 insertions(+), 63 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 7dc8cae..b6c1087 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -698,7 +698,7 @@ destruct(struct ofproto *ofproto_) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); struct rule_dpif *rule, *next_rule; - struct classifier *table; + struct oftable *table; int i; hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node); @@ -707,7 +707,7 @@ destruct(struct ofproto *ofproto_) OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) { struct cls_cursor cursor; - cls_cursor_init(&cursor, table, NULL); + cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) { ofproto_rule_destroy(&rule->up); } @@ -2828,7 +2828,7 @@ static int expire(struct ofproto_dpif *ofproto) { struct rule_dpif *rule, *next_rule; - struct classifier *table; + struct oftable *table; int dp_max_idle; /* Update stats for each flow in the datapath. */ @@ -2842,7 +2842,7 @@ expire(struct ofproto_dpif *ofproto) OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) { struct cls_cursor cursor; - cls_cursor_init(&cursor, table, NULL); + cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) { rule_expire(rule); } @@ -3824,7 +3824,7 @@ rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow, return NULL; } - cls = &ofproto->up.tables[table_id]; + cls = &ofproto->up.tables[table_id].cls; if (flow->nw_frag & FLOW_NW_FRAG_ANY && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) { /* For OFPC_NORMAL frag_handling, we must pretend that transport ports @@ -5378,13 +5378,13 @@ static void table_update_taggable(struct ofproto_dpif *ofproto, uint8_t table_id) { struct table_dpif *table = &ofproto->tables[table_id]; - const struct classifier *cls = &ofproto->up.tables[table_id]; + const struct oftable *oftable = &ofproto->up.tables[table_id]; struct cls_table *catchall, *other; struct cls_table *t; catchall = other = NULL; - switch (hmap_count(&cls->tables)) { + switch (hmap_count(&oftable->cls.tables)) { case 0: /* We could tag this OpenFlow table but it would make the logic a * little harder and it's a corner case that doesn't seem worth it @@ -5393,7 +5393,7 @@ table_update_taggable(struct ofproto_dpif *ofproto, uint8_t table_id) case 1: case 2: - HMAP_FOR_EACH (t, hmap_node, &cls->tables) { + HMAP_FOR_EACH (t, hmap_node, &oftable->cls.tables) { if (cls_table_is_catchall(t)) { catchall = t; } else if (!other) { diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 6c8583e..164e88a 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -58,7 +58,7 @@ struct ofproto { struct shash port_by_name; /* Flow tables. */ - struct classifier *tables; /* Each classifier contains "struct rule"s. */ + struct oftable *tables; int n_tables; /* OpenFlow connections. */ @@ -83,14 +83,6 @@ struct ofproto { struct ofproto *ofproto_lookup(const char *name); struct ofport *ofproto_get_port(const struct ofproto *, uint16_t ofp_port); -/* Assigns CLS to each classifier table, in turn, in OFPROTO. - * - * All parameters are evaluated multiple times. */ -#define OFPROTO_FOR_EACH_TABLE(CLS, OFPROTO) \ - for ((CLS) = (OFPROTO)->tables; \ - (CLS) < &(OFPROTO)->tables[(OFPROTO)->n_tables]; \ - (CLS)++) - /* An OpenFlow port within a "struct ofproto". * * With few exceptions, ofproto implementations may look at these fields but @@ -107,6 +99,19 @@ struct ofport { void ofproto_port_set_state(struct ofport *, ovs_be32 state); +/* A flow table within a "struct ofproto". */ +struct oftable { + struct classifier cls; /* Contains "struct rule"s. */ +}; + +/* Assigns TABLE to each oftable, in turn, in OFPROTO. + * + * All parameters are evaluated multiple times. */ +#define OFPROTO_FOR_EACH_TABLE(TABLE, OFPROTO) \ + for ((TABLE) = (OFPROTO)->tables; \ + (TABLE) < &(OFPROTO)->tables[(OFPROTO)->n_tables]; \ + (TABLE)++) + /* An OpenFlow flow within a "struct ofproto". * * With few exceptions, ofproto implementations may look at these fields but diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 521533b..ceec11f 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -286,8 +286,8 @@ ofproto_create(const char *datapath_name, const char *datapath_type, struct ofproto **ofprotop) { const struct ofproto_class *class; - struct classifier *table; struct ofproto *ofproto; + struct oftable *table; int n_tables; int error; @@ -353,7 +353,7 @@ ofproto_create(const char *datapath_name, const char *datapath_type, ofproto->n_tables = n_tables; ofproto->tables = xmalloc(n_tables * sizeof *ofproto->tables); OFPROTO_FOR_EACH_TABLE (table, ofproto) { - classifier_init(table); + classifier_init(&table->cls); } ofproto->datapath_id = pick_datapath_id(ofproto); @@ -798,8 +798,8 @@ ofproto_get_snoops(const struct ofproto *ofproto, struct sset *snoops) static void ofproto_flush__(struct ofproto *ofproto) { - struct classifier *table; struct ofopgroup *group; + struct oftable *table; if (ofproto->ofproto_class->flush) { ofproto->ofproto_class->flush(ofproto); @@ -810,11 +810,11 @@ ofproto_flush__(struct ofproto *ofproto) struct rule *rule, *next_rule; struct cls_cursor cursor; - cls_cursor_init(&cursor, table, NULL); + cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, cr, &cursor) { if (!rule->pending) { ofoperation_create(group, rule, OFOPERATION_DELETE); - classifier_remove(table, &rule->cr); + classifier_remove(&table->cls, &rule->cr); ofproto->ofproto_class->rule_destruct(rule); } } @@ -825,7 +825,7 @@ ofproto_flush__(struct ofproto *ofproto) static void ofproto_destroy__(struct ofproto *ofproto) { - struct classifier *table; + struct oftable *table; assert(list_is_empty(&ofproto->pending)); assert(!ofproto->n_pending); @@ -844,8 +844,8 @@ ofproto_destroy__(struct ofproto *ofproto) shash_destroy(&ofproto->port_by_name); OFPROTO_FOR_EACH_TABLE (table, ofproto) { - assert(classifier_is_empty(table)); - classifier_destroy(table); + assert(classifier_is_empty(&table->cls)); + classifier_destroy(&table->cls); } free(ofproto->tables); @@ -1176,7 +1176,7 @@ ofproto_add_flow(struct ofproto *ofproto, const struct cls_rule *cls_rule, const struct rule *rule; rule = rule_from_cls_rule(classifier_find_rule_exactly( - &ofproto->tables[0], cls_rule)); + &ofproto->tables[0].cls, cls_rule)); if (!rule || !ofputil_actions_equal(rule->actions, rule->n_actions, actions, n_actions)) { struct ofputil_flow_mod fm; @@ -1212,7 +1212,7 @@ ofproto_delete_flow(struct ofproto *ofproto, const struct cls_rule *target) struct rule *rule; rule = rule_from_cls_rule(classifier_find_rule_exactly( - &ofproto->tables[0], target)); + &ofproto->tables[0].cls, target)); if (!rule) { /* No such rule -> success. */ return true; @@ -1224,7 +1224,7 @@ ofproto_delete_flow(struct ofproto *ofproto, const struct cls_rule *target) /* Initiate deletion -> success. */ struct ofopgroup *group = ofopgroup_create_unattached(ofproto); ofoperation_create(group, rule, OFOPERATION_DELETE); - classifier_remove(&ofproto->tables[rule->table_id], &rule->cr); + classifier_remove(&ofproto->tables[rule->table_id].cls, &rule->cr); rule->ofproto->ofproto_class->rule_destruct(rule); ofopgroup_submit(group); return true; @@ -1648,7 +1648,7 @@ void ofproto_rule_destroy(struct rule *rule) { assert(!rule->pending); - classifier_remove(&rule->ofproto->tables[rule->table_id], &rule->cr); + classifier_remove(&rule->ofproto->tables[rule->table_id].cls, &rule->cr); ofproto_rule_destroy__(rule); } @@ -1947,7 +1947,7 @@ handle_table_stats_request(struct ofconn *ofconn, sprintf(ots[i].name, "table%zu", i); ots[i].wildcards = htonl(OFPFW_ALL); ots[i].max_entries = htonl(1000000); /* An arbitrary big number. */ - ots[i].active_count = htonl(classifier_count(&p->tables[i])); + ots[i].active_count = htonl(classifier_count(&p->tables[i].cls)); } p->ofproto_class->get_tables(p, ots); @@ -2027,7 +2027,7 @@ check_table_id(const struct ofproto *ofproto, uint8_t table_id) } -static struct classifier * +static struct oftable * first_matching_table(struct ofproto *ofproto, uint8_t table_id) { if (table_id == 0xff) { @@ -2039,17 +2039,16 @@ first_matching_table(struct ofproto *ofproto, uint8_t table_id) } } -static struct classifier * +static struct oftable * next_matching_table(struct ofproto *ofproto, - struct classifier *cls, uint8_t table_id) + struct oftable *table, uint8_t table_id) { - return (table_id == 0xff && cls != &ofproto->tables[ofproto->n_tables - 1] - ? cls + 1 + return (table_id == 0xff && table < &ofproto->tables[ofproto->n_tables - 1] + ? table + 1 : NULL); } -/* Assigns CLS to each classifier table, in turn, that matches TABLE_ID in - * OFPROTO: +/* Assigns TABLE to each oftable, in turn, that matches TABLE_ID in OFPROTO: * * - If TABLE_ID is 0xff, this iterates over every classifier table in * OFPROTO. @@ -2063,10 +2062,10 @@ next_matching_table(struct ofproto *ofproto, * * All parameters are evaluated multiple times. */ -#define FOR_EACH_MATCHING_TABLE(CLS, TABLE_ID, OFPROTO) \ - for ((CLS) = first_matching_table(OFPROTO, TABLE_ID); \ - (CLS) != NULL; \ - (CLS) = next_matching_table(OFPROTO, CLS, TABLE_ID)) +#define FOR_EACH_MATCHING_TABLE(TABLE, TABLE_ID, OFPROTO) \ + for ((TABLE) = first_matching_table(OFPROTO, TABLE_ID); \ + (TABLE) != NULL; \ + (TABLE) = next_matching_table(OFPROTO, TABLE, TABLE_ID)) /* Searches 'ofproto' for rules in table 'table_id' (or in all tables, if * 'table_id' is 0xff) that match 'match' in the "loose" way required for @@ -2084,7 +2083,7 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, const struct cls_rule *match, uint16_t out_port, struct list *rules) { - struct classifier *cls; + struct oftable *table; int error; error = check_table_id(ofproto, table_id); @@ -2093,11 +2092,11 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, } list_init(rules); - FOR_EACH_MATCHING_TABLE (cls, table_id, ofproto) { + FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { struct cls_cursor cursor; struct rule *rule; - cls_cursor_init(&cursor, cls, match); + cls_cursor_init(&cursor, &table->cls, match); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { if (rule->pending) { return OFPROTO_POSTPONE; @@ -2126,7 +2125,7 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, const struct cls_rule *match, uint16_t out_port, struct list *rules) { - struct classifier *cls; + struct oftable *table; int error; error = check_table_id(ofproto, table_id); @@ -2135,10 +2134,11 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, } list_init(rules); - FOR_EACH_MATCHING_TABLE (cls, table_id, ofproto) { + FOR_EACH_MATCHING_TABLE (table, table_id, ofproto) { struct rule *rule; - rule = rule_from_cls_rule(classifier_find_rule_exactly(cls, match)); + rule = rule_from_cls_rule(classifier_find_rule_exactly(&table->cls, + match)); if (rule) { if (rule->pending) { return OFPROTO_POSTPONE; @@ -2226,13 +2226,13 @@ flow_stats_ds(struct rule *rule, struct ds *results) void ofproto_get_all_flows(struct ofproto *p, struct ds *results) { - struct classifier *cls; + struct oftable *table; - OFPROTO_FOR_EACH_TABLE (cls, p) { + OFPROTO_FOR_EACH_TABLE (table, p) { struct cls_cursor cursor; struct rule *rule; - cls_cursor_init(&cursor, cls, NULL); + cls_cursor_init(&cursor, &table->cls, NULL); CLS_CURSOR_FOR_EACH (rule, cr, &cursor) { flow_stats_ds(rule, results); } @@ -2454,7 +2454,7 @@ static int add_flow(struct ofproto *ofproto, struct ofconn *ofconn, const struct ofputil_flow_mod *fm, const struct ofp_header *request) { - struct classifier *table; + struct oftable *table; struct ofopgroup *group; struct rule *victim; struct rule *rule; @@ -2487,7 +2487,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, /* Check for overlap, if requested. */ if (fm->flags & OFPFF_CHECK_OVERLAP - && classifier_rule_overlaps(table, &fm->cr)) { + && classifier_rule_overlaps(&table->cls, &fm->cr)) { return ofp_mkerr(OFPET_FLOW_MOD_FAILED, OFPFMFC_OVERLAP); } @@ -2516,7 +2516,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, rule->n_actions = fm->n_actions; /* Insert new rule. */ - victim = rule_from_cls_rule(classifier_replace(table, &rule->cr)); + victim = rule_from_cls_rule(classifier_replace(&table->cls, &rule->cr)); if (victim && victim->pending) { error = OFPROTO_POSTPONE; } else { @@ -2534,9 +2534,9 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, /* Back out if an error occurred. */ if (error) { if (victim) { - classifier_replace(table, &victim->cr); + classifier_replace(&table->cls, &victim->cr); } else { - classifier_remove(table, &rule->cr); + classifier_remove(&table->cls, &rule->cr); } ofproto_rule_destroy__(rule); } @@ -2639,7 +2639,7 @@ delete_flows__(struct ofproto *ofproto, struct ofconn *ofconn, ofproto_rule_send_removed(rule, OFPRR_DELETE); ofoperation_create(group, rule, OFOPERATION_DELETE); - classifier_remove(&ofproto->tables[rule->table_id], &rule->cr); + classifier_remove(&ofproto->tables[rule->table_id].cls, &rule->cr); rule->ofproto->ofproto_class->rule_destruct(rule); } ofopgroup_submit(group); @@ -2719,7 +2719,7 @@ ofproto_rule_expire(struct rule *rule, uint8_t reason) group = ofopgroup_create_unattached(ofproto); ofoperation_create(group, rule, OFOPERATION_DELETE); - classifier_remove(&ofproto->tables[rule->table_id], &rule->cr); + classifier_remove(&ofproto->tables[rule->table_id].cls, &rule->cr); rule->ofproto->ofproto_class->rule_destruct(rule); ofopgroup_submit(group); } @@ -3149,7 +3149,7 @@ ofoperation_complete(struct ofoperation *op, int error) struct ofopgroup *group = op->group; struct rule *rule = op->rule; struct ofproto *ofproto = rule->ofproto; - struct classifier *table = &ofproto->tables[rule->table_id]; + struct oftable *table = &rule->ofproto->tables[rule->table_id]; assert(rule->pending == op); assert(op->status < 0); @@ -3192,10 +3192,10 @@ ofoperation_complete(struct ofoperation *op, int error) } } else { if (op->victim) { - classifier_replace(table, &op->victim->cr); + classifier_replace(&table->cls, &op->victim->cr); op->victim = NULL; } else { - classifier_remove(table, &rule->cr); + classifier_remove(&table->cls, &rule->cr); } ofproto_rule_destroy__(rule); } @@ -3316,16 +3316,16 @@ ofproto_unixctl_init(void) void ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) { - const struct classifier *cls; + const struct oftable *oftable; free(ofproto->vlan_bitmap); ofproto->vlan_bitmap = bitmap_allocate(4096); ofproto->vlans_changed = false; - OFPROTO_FOR_EACH_TABLE (cls, ofproto) { + OFPROTO_FOR_EACH_TABLE (oftable, ofproto) { const struct cls_table *table; - HMAP_FOR_EACH (table, hmap_node, &cls->tables) { + HMAP_FOR_EACH (table, hmap_node, &oftable->cls.tables) { if (!(table->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) { const struct cls_rule *rule; -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev