[ovs-dev] [cleanups 03/12] Add functions to determine how port should be opened based on type.

Justin Pettit jpettit at nicira.com
Fri Nov 16 08:02:56 UTC 2012


Depending on the port and type of datapath, a port may need to be opened
as a different type of device than it's configured.  For example, an
"internal" port on a "dummy" datapath should opened as a "dummy" port.
This commit adds the ability for a dpif to provide this information to a
caller.  It will be used in a future commit.

Signed-off-by: Justin Pettit <jpettit at nicira.com>
---
 lib/dpif-linux.c           |    1 +
 lib/dpif-netdev.c          |   13 ++++++++++---
 lib/dpif-provider.h        |    7 +++++++
 lib/dpif.c                 |   17 +++++++++++++++++
 lib/dpif.h                 |    2 ++
 ofproto/ofproto-dpif.c     |    7 +++++++
 ofproto/ofproto-provider.h |    7 +++++++
 ofproto/ofproto.c          |   20 ++++++++++++++++++++
 ofproto/ofproto.h          |    2 ++
 9 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index 67ff805..496230e 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -1281,6 +1281,7 @@ dpif_linux_recv_purge(struct dpif *dpif_)
 const struct dpif_class dpif_linux_class = {
     "system",
     dpif_linux_enumerate,
+    NULL,
     dpif_linux_open,
     dpif_linux_close,
     dpif_linux_destroy,
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index a294ffc..cd4ab28 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -181,6 +181,14 @@ dpif_netdev_enumerate(struct sset *all_dps)
     return 0;
 }
 
+static const char *
+dpif_netdev_port_open_type(const struct dpif_class *class, const char *type)
+{
+    return strcmp(type, "internal") ? type
+                  : class != &dpif_netdev_class ? "dummy"
+                  : "tap";
+}
+
 static struct dpif *
 create_dpif_netdev(struct dp_netdev *dp)
 {
@@ -369,9 +377,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
     /* XXX reject devices already in some dp_netdev. */
 
     /* Open and validate network device. */
-    open_type = (strcmp(type, "internal") ? type
-                 : dp->class != &dpif_netdev_class ? "dummy"
-                 : "tap");
+    open_type = dpif_netdev_port_open_type(dp->class, type);
     error = netdev_open(devname, open_type, &netdev);
     if (error) {
         return error;
@@ -1282,6 +1288,7 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
 const struct dpif_class dpif_netdev_class = {
     "netdev",
     dpif_netdev_enumerate,
+    dpif_netdev_port_open_type,
     dpif_netdev_open,
     dpif_netdev_close,
     dpif_netdev_destroy,
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index bc18942..3a8519e 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -80,6 +80,13 @@ struct dpif_class {
      * case this function may be a null pointer. */
     int (*enumerate)(struct sset *all_dps);
 
+    /* Returns how a port of 'type' should be opened based on using a
+     * dpif of class 'dpif_class'.
+     *
+     * The caller must not free the returned string. */
+    const char *(*port_open_type)(const struct dpif_class *dpif_class,
+                                  const char *type);
+
     /* Attempts to open an existing dpif called 'name', if 'create' is false,
      * or to open an existing dpif or create a new one, if 'create' is true.
      *
diff --git a/lib/dpif.c b/lib/dpif.c
index 0093f61..9577e4f 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -417,6 +417,23 @@ dpif_get_dp_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
     return error;
 }
 
+const char *
+dpif_port_open_type(const char *datapath_type, const char *port_type)
+{
+    struct registered_dpif_class *registered_class;
+
+    datapath_type = dpif_normalize_type(datapath_type);
+
+    registered_class = shash_find_data(&dpif_classes, datapath_type);
+    if (!registered_class
+            || !registered_class->dpif_class->port_open_type) {
+        return port_type;
+    }
+
+    return registered_class->dpif_class->port_open_type(
+                          registered_class->dpif_class, port_type);
+}
+
 /* Attempts to add 'netdev' as a port on 'dpif'.  If 'port_nop' is
  * non-null and its value is not UINT32_MAX, then attempts to use the
  * value as the port number.
diff --git a/lib/dpif.h b/lib/dpif.h
index 7d0881f..893338b 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -73,6 +73,8 @@ int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *);
 
 /* Port operations. */
 
+const char *dpif_port_open_type(const char *datapath_type,
+                                const char *port_type);
 int dpif_port_add(struct dpif *, struct netdev *, uint32_t *port_nop);
 int dpif_port_del(struct dpif *, uint32_t port_no);
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 283aea9..fe0aae3 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -780,6 +780,12 @@ del(const char *type, const char *name)
     return error;
 }
 
+static const char *
+port_open_type(const char *datapath_type, const char *port_type)
+{
+    return dpif_port_open_type(datapath_type, port_type);
+}
+
 /* Type functions. */
 
 static int
@@ -7865,6 +7871,7 @@ const struct ofproto_class ofproto_dpif_class = {
     enumerate_types,
     enumerate_names,
     del,
+    port_open_type,
     type_run,
     type_run_fast,
     type_wait,
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index 26343cf..66cf930 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -382,6 +382,13 @@ struct ofproto_class {
      */
     int (*del)(const char *type, const char *name);
 
+    /* Returns how a port of 'port_type' should be opened based on using
+     * a datapath of type 'datapath_type'.
+     *
+     * The caller must not free the returned string. */
+    const char *(*port_open_type)(const char *datapath_type,
+                                  const char *port_type);
+
 /* ## ------------------------ ## */
 /* ## Top-Level type Functions ## */
 /* ## ------------------------ ## */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 0aeb07e..8555130 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -1433,6 +1433,26 @@ ofproto_port_dump_done(struct ofproto_port_dump *dump)
     return dump->error == EOF ? 0 : dump->error;
 }
 
+/* Returns how a port of 'port_type' should be opened based on using a
+ * datapath of type 'datapath_type'.
+ *
+ * The caller must not free the returned string. */
+const char *
+ofproto_port_open_type(const char *datapath_type, const char *port_type)
+{
+    const struct ofproto_class *class;
+
+    datapath_type = ofproto_normalize_type(datapath_type);
+    class = ofproto_class_find__(datapath_type);
+    if (!class) {
+        return port_type;
+    }
+
+    return (class->port_open_type
+            ? class->port_open_type(datapath_type, port_type)
+            : port_type);
+}
+
 /* Attempts to add 'netdev' as a port on 'ofproto'.  If 'ofp_portp' is
  * non-null and '*ofp_portp' is not OFPP_NONE, attempts to use that as
  * the port's OpenFlow port number.
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index 0366c89..e4abe52 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -207,6 +207,8 @@ int ofproto_port_dump_done(struct ofproto_port_dump *);
 #define OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT  1000
 #define OFPROTO_FLOW_EVICTION_THRESHOLD_MIN 100
 
+const char *ofproto_port_open_type(const char *datapath_type,
+                                   const char *port_type);
 int ofproto_port_add(struct ofproto *, struct netdev *, uint16_t *ofp_portp);
 int ofproto_port_del(struct ofproto *, uint16_t ofp_port);
 int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
-- 
1.7.5.4




More information about the dev mailing list