+ struct registered_dpif_class *registered_class;
+
+ if (shash_find(&dpif_classes, new_class->type)) {
+ VLOG_WARN("attempted to register duplicate datapath provider: %s",
+ new_class->type);
+ return EEXIST;
+ }
+
+ registered_class = xmalloc(sizeof *registered_class);
+ registered_class->dpif_class = new_class;
+ registered_class->refcount = 0;
+
+ shash_add(&dpif_classes, new_class->type, registered_class);
+
+ return 0;
+}
+
+/* Unregisters a datapath provider. 'type' must have been previously
+ * registered and not currently be in use by any dpifs. After unregistration
+ * new datapaths of that type cannot be opened using dpif_open(). */
+int
+dp_unregister_provider(const char *type)
+{
+ struct shash_node *node;
+ struct registered_dpif_class *registered_class;
+
+ node = shash_find(&dpif_classes, type);
+ if (!node) {
+ VLOG_WARN("attempted to unregister a datapath provider that is not "
+ "registered: %s", type);
+ return EAFNOSUPPORT;
+ }
+
+ registered_class = node->data;
+ if (registered_class->refcount) {
+ VLOG_WARN("attempted to unregister in use datapath provider: %s", type);
+ return EBUSY;
+ }
+
+ shash_delete(&dpif_classes, node);
+ free(registered_class);
+
+ return 0;
+}
+
+/* Clears 'types' and enumerates the types of all currently registered datapath
+ * providers into it. The caller must first initialize the sset. */
+void
+dp_enumerate_types(struct sset *types)
+{
+ struct shash_node *node;
+
+ dp_initialize();
+ sset_clear(types);
+
+ SHASH_FOR_EACH(node, &dpif_classes) {
+ const struct registered_dpif_class *registered_class = node->data;
+ sset_add(types, registered_class->dpif_class->type);
+ }
+}
+
+/* Clears 'names' and enumerates the names of all known created datapaths 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
+dp_enumerate_names(const char *type, struct sset *names)
+{
+ const struct registered_dpif_class *registered_class;
+ const struct dpif_class *dpif_class;