ofproto: Complete abstraction by adding enumeration and deletion functions.
authorBen Pfaff <blp@nicira.com>
Mon, 9 May 2011 16:33:02 +0000 (09:33 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 11 May 2011 19:26:08 +0000 (12:26 -0700)
This eliminates the final reference from bridge.c directly into the dpif
layer, which will make it easier to change the implementation of ofproto
to support other lower layers.

lib/dpif.h
ofproto/ofproto.c
ofproto/ofproto.h
vswitchd/bridge.c

index a4e5568f97e3b940285833f7624c59c05beaed3a..447ccd9800b119ff60b20df96c44da2069c760ba 100644 (file)
@@ -40,6 +40,7 @@ struct dpif_class;
 int dp_register_provider(const struct dpif_class *);
 int dp_unregister_provider(const char *type);
 void dp_enumerate_types(struct sset *types);
+const char *dpif_normalize_type(const char *);
 
 int dp_enumerate_names(const char *type, struct sset *names);
 void dp_parse_name(const char *datapath_name, char **name, char **type);
@@ -55,8 +56,6 @@ void dpif_wait(struct dpif *);
 const char *dpif_name(const struct dpif *);
 const char *dpif_base_name(const struct dpif *);
 
-const char *dpif_normalize_type(const char *);
-
 int dpif_delete(struct dpif *);
 
 int dpif_get_dp_stats(const struct dpif *, struct odp_stats *);
index 7ca859bea44174edd3380d2b933adf5753ed1c8d..dadc546b25ef7414ac2e3a244f030015fde426ca 100644 (file)
@@ -409,6 +409,36 @@ static bool is_admissible(struct ofproto *, const struct flow *,
 
 static void ofproto_unixctl_init(void);
 
+/* Clears 'types' and enumerates all registered ofproto types into it.  The
+ * caller must first initialize the sset. */
+void
+ofproto_enumerate_types(struct sset *types)
+{
+    dp_enumerate_types(types);
+}
+
+/* Returns the fully spelled out name for the given ofproto 'type'.
+ *
+ * Normalized type string can be compared with strcmp().  Unnormalized type
+ * string might be the same even if they have different spellings. */
+const char *
+ofproto_normalize_type(const char *type)
+{
+    return dpif_normalize_type(type);
+}
+
+/* Clears 'names' and enumerates the names of all known created ofprotos with
+ * the given 'type'.  The caller must first initialize the sset.  Returns 0 if
+ * successful, otherwise a positive errno value.
+ *
+ * Some kinds of datapaths might not be practically enumerable.  This is not
+ * considered an error. */
+int
+ofproto_enumerate_names(const char *type, struct sset *names)
+{
+    return dp_enumerate_names(type, names);
+}
+
 int
 ofproto_create(const char *datapath, const char *datapath_type,
                struct ofproto **ofprotop)
@@ -1331,6 +1361,26 @@ ofproto_destroy(struct ofproto *p)
     free(p);
 }
 
+/* Destroys the datapath with the respective 'name' and 'type'.  With the Linux
+ * kernel datapath, for example, this destroys the datapath in the kernel, and
+ * with the netdev-based datapath, it tears down the data structures that
+ * represent the datapath.
+ *
+ * The datapath should not be currently open as an ofproto. */
+int
+ofproto_delete(const char *name, const char *type)
+{
+    struct dpif *dpif;
+    int error;
+
+    error = dpif_open(name, type, &dpif);
+    if (!error) {
+        error = dpif_delete(dpif);
+        dpif_close(dpif);
+    }
+    return error;
+}
+
 static void
 process_port_change(struct ofproto *ofproto, int error, char *devname)
 {
index 2fb951a23743b29f40629e3484a58dfdbfbc11cd..183e58865e42c3df413851f642d3a9dae284eaf0 100644 (file)
@@ -92,11 +92,17 @@ struct ofproto_controller {
 #define DEFAULT_SERIAL_DESC "None"
 #define DEFAULT_DP_DESC "None"
 
+void ofproto_enumerate_types(struct sset *types);
+const char *ofproto_normalize_type(const char *);
+
+int ofproto_enumerate_names(const char *type, struct sset *names);
 void ofproto_parse_name(const char *name, char **dp_name, char **dp_type);
 
 int ofproto_create(const char *datapath, const char *datapath_type,
                    struct ofproto **ofprotop);
 void ofproto_destroy(struct ofproto *);
+int ofproto_delete(const char *name, const char *type);
+
 int ofproto_run(struct ofproto *);
 void ofproto_wait(struct ofproto *);
 bool ofproto_is_alive(const struct ofproto *);
index 6caf086a83262cec3210bde6b5cbe6018efb971e..e23ee6fcf73781738d43ef1340c005402e3ad48c 100644 (file)
@@ -38,7 +38,6 @@
 #include "coverage.h"
 #include "daemon.h"
 #include "dirs.h"
-#include "dpif.h"
 #include "dynamic-string.h"
 #include "flow.h"
 #include "hash.h"
@@ -158,8 +157,8 @@ static long long int stats_timer = LLONG_MIN;
 static long long int db_limiter = LLONG_MIN;
 
 static void add_del_bridges(const struct ovsrec_open_vswitch *);
-static void bridge_del_dps(void);
-static bool bridge_add_dp(struct bridge *);
+static void bridge_del_ofprotos(void);
+static bool bridge_add_ofprotos(struct bridge *);
 static void bridge_create(const struct ovsrec_bridge *);
 static void bridge_destroy(struct bridge *);
 static struct bridge *bridge_lookup(const char *name);
@@ -395,7 +394,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
      * that port already belongs to a different datapath, so we must do all
      * port deletions before any port additions.  A datapath always has a
      * "local port" so we must delete not-configured datapaths too. */
-    bridge_del_dps();
+    bridge_del_ofprotos();
     HMAP_FOR_EACH (br, node, &all_bridges) {
         if (br->ofproto) {
             bridge_del_ofproto_ports(br);
@@ -409,7 +408,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
      * has at least one iface, every "struct iface" has a valid ofp_port and
      * netdev. */
     HMAP_FOR_EACH_SAFE (br, next, node, &all_bridges) {
-        if (!br->ofproto && !bridge_add_dp(br)) {
+        if (!br->ofproto && !bridge_add_ofprotos(br)) {
             bridge_destroy(br);
         }
     }
@@ -448,40 +447,35 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
     daemonize_complete();
 }
 
-/* Iterate over all system dpifs and delete any of them that do not have a
+/* Iterate over all ofprotos and delete any of them that do not have a
  * configured bridge or that are the wrong type. */
 static void
-bridge_del_dps(void)
+bridge_del_ofprotos(void)
 {
-    struct sset dpif_names;
-    struct sset dpif_types;
+    struct sset names;
+    struct sset types;
     const char *type;
 
-    sset_init(&dpif_names);
-    sset_init(&dpif_types);
-    dp_enumerate_types(&dpif_types);
-    SSET_FOR_EACH (type, &dpif_types) {
+    sset_init(&names);
+    sset_init(&types);
+    ofproto_enumerate_types(&types);
+    SSET_FOR_EACH (type, &types) {
         const char *name;
 
-        dp_enumerate_names(type, &dpif_names);
-        SSET_FOR_EACH (name, &dpif_names) {
+        ofproto_enumerate_names(type, &names);
+        SSET_FOR_EACH (name, &names) {
             struct bridge *br = bridge_lookup(name);
             if (!br || strcmp(type, br->type)) {
-                struct dpif *dpif;
-
-                if (!dpif_open(name, type, &dpif)) {
-                    dpif_delete(dpif);
-                    dpif_close(dpif);
-                }
+                ofproto_delete(name, type);
             }
         }
     }
-    sset_destroy(&dpif_names);
-    sset_destroy(&dpif_types);
+    sset_destroy(&names);
+    sset_destroy(&types);
 }
 
 static bool
-bridge_add_dp(struct bridge *br)
+bridge_add_ofprotos(struct bridge *br)
 {
     int error = ofproto_create(br->name, br->type, &br->ofproto);
     if (error) {
@@ -740,8 +734,8 @@ add_del_bridges(const struct ovsrec_open_vswitch *cfg)
      * Update 'cfg' of bridges that still exist. */
     HMAP_FOR_EACH_SAFE (br, next, node, &all_bridges) {
         br->cfg = shash_find_data(&new_br, br->name);
-        if (!br->cfg || strcmp(br->type,
-                               dpif_normalize_type(br->cfg->datapath_type))) {
+        if (!br->cfg || strcmp(br->type, ofproto_normalize_type(
+                                   br->cfg->datapath_type))) {
             bridge_destroy(br);
         }
     }
@@ -854,7 +848,7 @@ bridge_refresh_ofp_port(struct bridge *br)
     }
 }
 
-/* Add a dpif port for any "struct iface" that doesn't have one.
+/* Add an ofproto port for any "struct iface" that doesn't have one.
  * Delete any "struct iface" for which this fails.
  * Delete any "struct port" that thereby ends up with no ifaces. */
 static void
@@ -1654,7 +1648,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
     br = xzalloc(sizeof *br);
 
     br->name = xstrdup(br_cfg->name);
-    br->type = xstrdup(dpif_normalize_type(br_cfg->datapath_type));
+    br->type = xstrdup(ofproto_normalize_type(br_cfg->datapath_type));
     br->cfg = br_cfg;
     eth_addr_nicira_random(br->default_ea);