[ovs-dev] [bug 7550 1/9] ofproto: Encapsulate classifier tables in new "struct oftable".
Ben Pfaff
blp at nicira.com
Wed Dec 21 21:03:49 UTC 2011
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 <blp at 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
More information about the dev
mailing list