#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
};
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);
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();
}
}
}
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();
}
}
}
}
registered_class = xmalloc(sizeof *registered_class);
- memcpy(®istered_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);
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);
}
}
return EAFNOSUPPORT;
}
- dpif_class = ®istered_class->dpif_class;
+ dpif_class = registered_class->dpif_class;
error = dpif_class->enumerate ? dpif_class->enumerate(names) : 0;
if (error) {
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++;
}
}
}
+
/* 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(). */
{
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));
}
}