static struct bridge *bridge_lookup(const char *name);
 static int bridge_run_one(struct bridge *);
 static void bridge_reconfigure_one(struct bridge *);
+static void bridge_reconfigure_controller(struct bridge *);
 static void bridge_get_all_ifaces(const struct bridge *, struct svec *ifaces);
 static void bridge_fetch_dp_ifaces(struct bridge *);
 static void bridge_flush(struct bridge *);
                     br->name);
         }
 
-        /* Set the controller.  (It would be more straightforward to do
-         * this in bridge_reconfigure_one(), but then the
-         * ofproto_set_datapath_id() above would disconnect right away, and
-         * we can't call ofproto_set_datapath_id() until we know the set of
-         * ports actually in the bridge, hence not until now.) */
-        ofproto_set_controller(br->ofproto, br->controller);
+        /* Update the controller and related settings.  It would be more
+         * straightforward to call this from bridge_reconfigure_one(), but we
+         * can't do it there for two reasons.  First, and most importantly, at
+         * that point we don't know the dp_ifidx of any interfaces that have
+         * been added to the bridge (because we haven't actually added them to
+         * the datapath).  Second, at that point we haven't set the datapath ID
+         * yet; when a controller is configured, resetting the datapath ID will
+         * immediately disconnect from the controller, so it's better to set
+         * the datapath ID before the controller. */
+        bridge_reconfigure_controller(br);
     }
     LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
         for (i = 0; i < br->n_ports; i++) {
     LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
         brstp_reconfigure(br);
     }
+    LIST_FOR_EACH_SAFE (br, next, struct bridge, node, &all_bridges) {
+        for (i = 0; i < br->n_ports; i++) {
+            struct port *port = br->ports[i];
+            for (j = 0; j < port->n_ifaces; j++) {
+                struct iface *iface = port->ifaces[j];
+                VLOG_WARN("dp%u: %s on port %d",
+                          dpif_id(&br->dpif), iface->name, iface->dp_ifidx);
+            }
+        }
+    }
 }
 
 static void
     return error;
 }
 
+static const char *
+bridge_get_controller(const struct bridge *br)
+{
+    const char *controller;
+
+    controller = cfg_get_string(0, "bridge.%s.controller", br->name);
+    if (!controller) {
+        controller = cfg_get_string(0, "mgmt.controller");
+    }
+    return controller && controller[0] ? controller : NULL;
+}
+
 static void
 bridge_reconfigure_one(struct bridge *br)
 {
     struct svec old_ports, new_ports, ifaces;
     struct svec listeners, old_listeners;
     struct svec snoops, old_snoops;
-    const char *controller;
     size_t i, j;
-    char *ctl, *pfx;
-
-    /* Decide on remote controller. */
-    pfx = xasprintf("bridge.%s.controller", br->name);
-    controller = cfg_get_string(0, "%s", pfx);
-    ctl = controller ? xstrdup(controller) : NULL;
 
     /* Collect old ports. */
     svec_init(&old_ports);
     svec_init(&new_ports);
     cfg_get_all_keys(&new_ports, "bridge.%s.port", br->name);
     svec_sort(&new_ports);
-    if (ctl && !svec_contains(&new_ports, br->name)) {
+    if (bridge_get_controller(br) && !svec_contains(&new_ports, br->name)) {
         svec_add(&new_ports, br->name);
         svec_sort(&new_ports);
     }
     }
     svec_destroy(&ifaces);
 
-    /* If a controller is not specified for the bridge, try using the
-     * management channel's settings. */
-    if (!ctl) {
-        controller = cfg_get_string(0, "mgmt.controller");
-        ctl = controller ? xstrdup(controller) : NULL;
-    }
-
     /* Delete all flows if we're switching from connected to standalone or vice
      * versa.  (XXX Should we delete all flows if we are switching from one
      * controller to another?) */
-    if ((br->controller != NULL) != (ctl != NULL)) {
+
+    /* Configure OpenFlow management listeners. */
+    svec_init(&listeners);
+    cfg_get_all_strings(&listeners, "bridge.%s.openflow.listeners", br->name);
+    if (!listeners.n) {
+        svec_add_nocopy(&listeners, xasprintf("punix:%s/%s.mgmt",
+                                              ovs_rundir, br->name));
+    } else if (listeners.n == 1 && !strcmp(listeners.names[0], "none")) {
+        svec_clear(&listeners);
+    }
+    svec_sort_unique(&listeners);
+
+    svec_init(&old_listeners);
+    ofproto_get_listeners(br->ofproto, &old_listeners);
+    svec_sort_unique(&old_listeners);
+
+    if (!svec_equal(&listeners, &old_listeners)) {
+        ofproto_set_listeners(br->ofproto, &listeners);
+    }
+    svec_destroy(&listeners);
+    svec_destroy(&old_listeners);
+
+    /* Configure OpenFlow controller connection snooping. */
+    svec_init(&snoops);
+    cfg_get_all_strings(&snoops, "bridge.%s.openflow.snoops", br->name);
+    if (!snoops.n) {
+        svec_add_nocopy(&snoops, xasprintf("punix:%s/%s.snoop",
+                                           ovs_rundir, br->name));
+    } else if (snoops.n == 1 && !strcmp(snoops.names[0], "none")) {
+        svec_clear(&snoops);
+    }
+    svec_sort_unique(&snoops);
+
+    svec_init(&old_snoops);
+    ofproto_get_snoops(br->ofproto, &old_snoops);
+    svec_sort_unique(&old_snoops);
+
+    if (!svec_equal(&snoops, &old_snoops)) {
+        ofproto_set_snoops(br->ofproto, &snoops);
+    }
+    svec_destroy(&snoops);
+    svec_destroy(&old_snoops);
+
+    mirror_reconfigure(br);
+}
+
+static void
+bridge_reconfigure_controller(struct bridge *br)
+{
+    char *pfx = xasprintf("bridge.%s.controller", br->name);
+    const char *controller;
+
+    controller = bridge_get_controller(br);
+    if ((br->controller != NULL) != (controller != NULL)) {
         ofproto_flush_flows(br->ofproto);
     }
+    free(br->controller);
+    br->controller = controller ? xstrdup(controller) : NULL;
 
-    if (ctl && strlen(ctl) != 0) {
+    if (controller) {
         const char *fail_mode;
         int max_backoff, probe;
         int rate_limit, burst_limit;
 
-        if (!strcmp(ctl, "discover")) {
+        if (!strcmp(controller, "discover")) {
             ofproto_set_discovery(br->ofproto, true,
                                   cfg_get_string(0, "%s.accept-regex", pfx),
                                   cfg_get_bool(0, "%s.update-resolv.conf",
 
         probe = cfg_get_int(0, "%s.inactivity-probe", pfx);
         ofproto_set_probe_interval(br->ofproto,
-                probe ? probe : cfg_get_int(0, "mgmt.inactivity-probe"));
+                                   probe ? probe : cfg_get_int(0, "mgmt.inactivity-probe"));
 
         max_backoff = cfg_get_int(0, "%s.max-backoff", pfx);
         if (!max_backoff) {
         ofproto_set_failure(br->ofproto, false);
         ofproto_set_stp(br->ofproto, false);
     }
-    free(br->controller);
-    br->controller = ctl;
     free(pfx);
 
-    /* Configure OpenFlow management listeners. */
-    svec_init(&listeners);
-    cfg_get_all_strings(&listeners, "bridge.%s.openflow.listeners", br->name);
-    if (!listeners.n) {
-        svec_add_nocopy(&listeners, xasprintf("punix:%s/%s.mgmt",
-                                              ovs_rundir, br->name));
-    } else if (listeners.n == 1 && !strcmp(listeners.names[0], "none")) {
-        svec_clear(&listeners);
-    }
-    svec_sort_unique(&listeners);
-
-    svec_init(&old_listeners);
-    ofproto_get_listeners(br->ofproto, &old_listeners);
-    svec_sort_unique(&old_listeners);
-
-    if (!svec_equal(&listeners, &old_listeners)) {
-        ofproto_set_listeners(br->ofproto, &listeners);
-    }
-    svec_destroy(&listeners);
-    svec_destroy(&old_listeners);
-
-    /* Configure OpenFlow controller connection snooping. */
-    svec_init(&snoops);
-    cfg_get_all_strings(&snoops, "bridge.%s.openflow.snoops", br->name);
-    if (!snoops.n) {
-        svec_add_nocopy(&snoops, xasprintf("punix:%s/%s.snoop",
-                                           ovs_rundir, br->name));
-    } else if (snoops.n == 1 && !strcmp(snoops.names[0], "none")) {
-        svec_clear(&snoops);
-    }
-    svec_sort_unique(&snoops);
-
-    svec_init(&old_snoops);
-    ofproto_get_snoops(br->ofproto, &old_snoops);
-    svec_sort_unique(&old_snoops);
-
-    if (!svec_equal(&snoops, &old_snoops)) {
-        ofproto_set_snoops(br->ofproto, &snoops);
-    }
-    svec_destroy(&snoops);
-    svec_destroy(&old_snoops);
-
-    mirror_reconfigure(br);
+    ofproto_set_controller(br->ofproto, br->controller);
 }
 
 static void