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