brcompat: Simplify generation of bridge ID.
[openvswitch] / lib / dpif.c
index a7706e4e7c9f28260fee4202b1bd3e8b1a24b29f..03e13acc51b5877aa86eb367c9b2a7942bf979eb 100644 (file)
 #include "coverage.h"
 #include "dynamic-string.h"
 #include "flow.h"
+#include "netdev.h"
 #include "netlink.h"
 #include "odp-util.h"
 #include "ofp-print.h"
+#include "ofp-util.h"
 #include "ofpbuf.h"
 #include "packets.h"
 #include "poll-loop.h"
 #include "valgrind.h"
 #include "vlog.h"
 
-VLOG_DEFINE_THIS_MODULE(dpif)
+VLOG_DEFINE_THIS_MODULE(dpif);
+
+COVERAGE_DEFINE(dpif_destroy);
+COVERAGE_DEFINE(dpif_port_add);
+COVERAGE_DEFINE(dpif_port_del);
+COVERAGE_DEFINE(dpif_flow_flush);
+COVERAGE_DEFINE(dpif_flow_get);
+COVERAGE_DEFINE(dpif_flow_put);
+COVERAGE_DEFINE(dpif_flow_del);
+COVERAGE_DEFINE(dpif_flow_query_list);
+COVERAGE_DEFINE(dpif_flow_query_list_n);
+COVERAGE_DEFINE(dpif_execute);
+COVERAGE_DEFINE(dpif_purge);
 
 static const struct dpif_class *base_dpif_classes[] = {
 #ifdef HAVE_NETLINK
@@ -49,7 +63,7 @@ static const struct dpif_class *base_dpif_classes[] = {
 };
 
 struct registered_dpif_class {
-    struct dpif_class dpif_class;
+    const struct dpif_class *dpif_class;
     int refcount;
 };
 static struct shash dpif_classes = SHASH_INITIALIZER(&dpif_classes);
@@ -96,8 +110,8 @@ dp_run(void)
     struct shash_node *node;
     SHASH_FOR_EACH(node, &dpif_classes) {
         const struct registered_dpif_class *registered_class = node->data;
-        if (registered_class->dpif_class.run) {
-            registered_class->dpif_class.run();
+        if (registered_class->dpif_class->run) {
+            registered_class->dpif_class->run();
         }
     }
 }
@@ -112,8 +126,8 @@ dp_wait(void)
     struct shash_node *node;
     SHASH_FOR_EACH(node, &dpif_classes) {
         const struct registered_dpif_class *registered_class = node->data;
-        if (registered_class->dpif_class.wait) {
-            registered_class->dpif_class.wait();
+        if (registered_class->dpif_class->wait) {
+            registered_class->dpif_class->wait();
         }
     }
 }
@@ -132,8 +146,7 @@ dp_register_provider(const struct dpif_class *new_class)
     }
 
     registered_class = xmalloc(sizeof *registered_class);
-    memcpy(&registered_class->dpif_class, new_class,
-           sizeof registered_class->dpif_class);
+    registered_class->dpif_class = new_class;
     registered_class->refcount = 0;
 
     shash_add(&dpif_classes, new_class->type, registered_class);
@@ -181,7 +194,7 @@ dp_enumerate_types(struct svec *types)
 
     SHASH_FOR_EACH(node, &dpif_classes) {
         const struct registered_dpif_class *registered_class = node->data;
-        svec_add(types, registered_class->dpif_class.type);
+        svec_add(types, registered_class->dpif_class->type);
     }
 }
 
@@ -207,7 +220,7 @@ dp_enumerate_names(const char *type, struct svec *names)
         return EAFNOSUPPORT;
     }
 
-    dpif_class = &registered_class->dpif_class;
+    dpif_class = registered_class->dpif_class;
     error = dpif_class->enumerate ? dpif_class->enumerate(names) : 0;
 
     if (error) {
@@ -258,8 +271,10 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
         goto exit;
     }
 
-    error = registered_class->dpif_class.open(name, type, create, &dpif);
+    error = registered_class->dpif_class->open(registered_class->dpif_class,
+                                               name, create, &dpif);
     if (!error) {
+        assert(dpif->dpif_class == registered_class->dpif_class);
         registered_class->refcount++;
     }
 
@@ -373,6 +388,7 @@ dpif_get_all_names(const struct dpif *dpif, struct svec *all_names)
     }
 }
 
+
 /* Destroys the datapath that 'dpif' is connected to, first removing all of its
  * ports.  After calling this function, it does not make sense to pass 'dpif'
  * to any functions other than dpif_name() or dpif_close(). */
@@ -428,27 +444,26 @@ dpif_set_drop_frags(struct dpif *dpif, bool drop_frags)
     return error;
 }
 
-/* Attempts to add 'devname' as a port on 'dpif', given the combination of
- * ODP_PORT_* flags in 'flags'.  If successful, returns 0 and sets '*port_nop'
- * to the new port's port number (if 'port_nop' is non-null).  On failure,
- * returns a positive errno value and sets '*port_nop' to UINT16_MAX (if
- * 'port_nop' is non-null). */
+/* Attempts to add 'netdev' as a port on 'dpif'.  If successful, returns 0 and
+ * sets '*port_nop' to the new port's port number (if 'port_nop' is non-null).
+ * On failure, returns a positive errno value and sets '*port_nop' to
+ * UINT16_MAX (if 'port_nop' is non-null). */
 int
-dpif_port_add(struct dpif *dpif, const char *devname, uint16_t flags,
-              uint16_t *port_nop)
+dpif_port_add(struct dpif *dpif, struct netdev *netdev, uint16_t *port_nop)
 {
+    const char *netdev_name = netdev_get_name(netdev);
     uint16_t port_no;
     int error;
 
     COVERAGE_INC(dpif_port_add);
 
-    error = dpif->dpif_class->port_add(dpif, devname, flags, &port_no);
+    error = dpif->dpif_class->port_add(dpif, netdev, &port_no);
     if (!error) {
         VLOG_DBG_RL(&dpmsg_rl, "%s: added %s as port %"PRIu16,
-                    dpif_name(dpif), devname, port_no);
+                    dpif_name(dpif), netdev_name, port_no);
     } else {
         VLOG_WARN_RL(&error_rl, "%s: failed to add %s as port: %s",
-                     dpif_name(dpif), devname, strerror(error));
+                     dpif_name(dpif), netdev_name, strerror(error));
         port_no = UINT16_MAX;
     }
     if (port_nop) {
@@ -467,7 +482,12 @@ dpif_port_del(struct dpif *dpif, uint16_t port_no)
     COVERAGE_INC(dpif_port_del);
 
     error = dpif->dpif_class->port_del(dpif, port_no);
-    log_operation(dpif, "port_del", error);
+    if (!error) {
+        VLOG_DBG_RL(&dpmsg_rl, "%s: port_del(%"PRIu16")",
+                    dpif_name(dpif), port_no);
+    } else {
+        log_operation(dpif, "port_del", error);
+    }
     return error;
 }
 
@@ -1085,9 +1105,13 @@ log_operation(const struct dpif *dpif, const char *operation, int error)
 {
     if (!error) {
         VLOG_DBG_RL(&dpmsg_rl, "%s: %s success", dpif_name(dpif), operation);
-    } else {
+    } else if (is_errno(error)) {
         VLOG_WARN_RL(&error_rl, "%s: %s failed (%s)",
                      dpif_name(dpif), operation, strerror(error));
+    } else {
+        VLOG_WARN_RL(&error_rl, "%s: %s failed (%d/%d)",
+                     dpif_name(dpif), operation,
+                     get_ofp_err_type(error), get_ofp_err_code(error));
     }
 }