[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