vswitch: Force local port into bridge when in-band control configured.
authorBen Pfaff <blp@nicira.com>
Thu, 19 Mar 2009 19:59:34 +0000 (12:59 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 19 Mar 2009 19:59:57 +0000 (12:59 -0700)
In-band control requires that local port be part of the bridge.  This used
to not matter, because in-band control stole packet-in messages before they
got to any part of the code that cared about configured ports, but now that
in-band control goes through the same flow table as everything else, it
matters.

vswitchd/bridge.c

index ad62181ad2a07490b4ec72962453ef513549926a..4567e66dee532916fe01c1188b3678e2589749a3 100644 (file)
@@ -765,25 +765,36 @@ bridge_reconfigure_one(struct bridge *br)
     size_t i, j;
     char *ctl, *pfx;
 
-    /* Collect old and new ports. */
+    /* 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);
     for (i = 0; i < br->n_ports; i++) {
         svec_add(&old_ports, br->ports[i]->name);
     }
-    cfg_get_all_keys(&new_ports, "bridge.%s.port", br->name);
-
-    ofproto_set_mgmt_id(br->ofproto, mgmt_id);
-
-    /* Get rid of deleted ports and add new ports. */
     svec_sort(&old_ports);
     assert(svec_is_unique(&old_ports));
+
+    /* Collect new 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)) {
+        svec_add(&new_ports, br->name);
+        svec_sort(&new_ports);
+    }
     if (!svec_is_unique(&new_ports)) {
         VLOG_WARN("bridge %s: %s specified twice as bridge port",
                   br->name, svec_get_duplicate(&new_ports));
         svec_unique(&new_ports);
     }
+
+    ofproto_set_mgmt_id(br->ofproto, mgmt_id);
+
+    /* Get rid of deleted ports and add new ports. */
     for (i = 0; i < br->n_ports; ) {
         struct port *port = br->ports[i];
         if (!svec_contains(&new_ports, port->name)) {
@@ -832,11 +843,6 @@ bridge_reconfigure_one(struct bridge *br)
     }
     svec_destroy(&ifaces);
 
-    /* Configure remote controller. */
-    pfx = xasprintf("bridge.%s.controller", br->name);
-    controller = cfg_get_string(0, "%s", pfx);
-    ctl = controller ? xstrdup(controller) : NULL;
-    
     /* If a controller is not specified for the bridge, try using the
      * management channel's settings. */
     if (!ctl) {