}
}
-/* Performs periodic work needed by all the various kinds of dpifs.
- *
- * If your program opens any dpifs, it must call both this function and
- * netdev_run() within its main poll loop. */
-void
-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();
- }
- }
-}
-
-/* Arranges for poll_block() to wake up when dp_run() needs to be called.
- *
- * If your program opens any dpifs, it must call both this function and
- * netdev_wait() within its main poll loop. */
-void
-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();
- }
- }
-}
-
/* Registers a new datapath provider. After successful registration, new
* datapaths of that type can be opened using dpif_open(). */
int
return error;
}
-/* Parses 'datapath name', which is of the form type@name into its
- * component pieces. 'name' and 'type' must be freed by the caller. */
+/* Parses 'datapath_name_', which is of the form [type@]name into its
+ * component pieces. 'name' and 'type' must be freed by the caller.
+ *
+ * The returned 'type' is normalized, as if by dpif_normalize_type(). */
void
dp_parse_name(const char *datapath_name_, char **name, char **type)
{
if (separator) {
*separator = '\0';
*type = datapath_name;
- *name = xstrdup(separator + 1);
+ *name = xstrdup(dpif_normalize_type(separator + 1));
} else {
*name = datapath_name;
- *type = NULL;
+ *type = xstrdup(dpif_normalize_type(NULL));
}
}
}
}
+/* Performs periodic work needed by 'dpif'. */
+void
+dpif_run(struct dpif *dpif)
+{
+ if (dpif->dpif_class->run) {
+ dpif->dpif_class->run(dpif);
+ }
+}
+
+/* Arranges for poll_block() to wake up when dp_run() needs to be called for
+ * 'dpif'. */
+void
+dpif_wait(struct dpif *dpif)
+{
+ if (dpif->dpif_class->wait) {
+ dpif->dpif_class->wait(dpif);
+ }
+}
+
/* Returns the name of datapath 'dpif' prefixed with the type
* (for use in log messages). */
const char *
dst->name = xstrdup(src->name);
dst->type = xstrdup(src->type);
dst->port_no = src->port_no;
+ dst->stats = src->stats;
}
/* Frees memory allocated to members of 'dpif_port'.
} else {
memset(port, 0, sizeof *port);
- /* Log level is DBG here because all the current callers are interested
- * in whether 'dpif' actually has a port 'devname', so that it's not an
- * issue worth logging if it doesn't. */
- VLOG_DBG_RL(&error_rl, "%s: failed to query port %s: %s",
- dpif_name(dpif), devname, strerror(error));
+ /* For ENOENT or ENODEV we use DBG level because the caller is probably
+ * interested in whether 'dpif' actually has a port 'devname', so that
+ * it's not an issue worth logging if it doesn't. Other errors are
+ * uncommon and more likely to indicate a real problem. */
+ VLOG_RL(&error_rl,
+ error == ENOENT || error == ENODEV ? VLL_DBG : VLL_WARN,
+ "%s: failed to query port %s: %s",
+ dpif_name(dpif), devname, strerror(error));
}
return error;
}