@@ -428,6 +428,18 @@ dpif_create_and_open(const char *name, const char *type, struct dpif **dpifp)
return error;
}
+static
+void dpif_remove_netdev_ports(struct dpif *dpif) {
+ struct dpif_port_dump port_dump;
+ struct dpif_port dpif_port;
+
+ DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
+ if (!dpif_is_internal_port(dpif_port.type)) {
+ netdev_ports_remove(dpif_port.port_no, dpif->dpif_class);
+ }
+ }
+}
+
/* Closes and frees the connection to 'dpif'. Does not destroy the datapath
* itself; call dpif_delete() first, instead, if that is desirable. */
void
@@ -435,18 +447,14 @@ dpif_close(struct dpif *dpif)
{
if (dpif) {
struct registered_dpif_class *rc;
- struct dpif_port_dump port_dump;
- struct dpif_port dpif_port;
rc = shash_find_data(&dpif_classes, dpif->dpif_class->type);
- DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
- if (!dpif_is_internal_port(dpif_port.type)) {
- netdev_ports_remove(dpif_port.port_no, dpif->dpif_class);
- }
- }
dpif_uninit(dpif, true);
dp_class_unref(rc);
+ if (rc->refcount == 0) {
+ dpif_remove_netdev_ports(dpif);
+ }
}
}