Merge 'next' into 'master'.
[sliver-openvswitch.git] / vswitchd / bridge.c
index 127e0b7..3faeee1 100644 (file)
@@ -175,7 +175,8 @@ static struct port *port_lookup(const struct bridge *, const char *name);
 static void port_configure(struct port *);
 static struct lacp_settings *port_configure_lacp(struct port *,
                                                  struct lacp_settings *);
-static void port_configure_bond(struct port *, struct bond_settings *);
+static void port_configure_bond(struct port *, struct bond_settings *,
+                                uint32_t *bond_stable_ids);
 
 static void bridge_configure_mirrors(struct bridge *);
 static struct mirror *mirror_create(struct bridge *,
@@ -521,10 +522,12 @@ port_configure(struct port *port)
 
     /* Get bond settings. */
     if (s.n_slaves > 1) {
-        port_configure_bond(port, &bond_settings);
         s.bond = &bond_settings;
+        s.bond_stable_ids = xmalloc(s.n_slaves * sizeof *s.bond_stable_ids);
+        port_configure_bond(port, &bond_settings, s.bond_stable_ids);
     } else {
         s.bond = NULL;
+        s.bond_stable_ids = NULL;
     }
 
     /* Register. */
@@ -533,6 +536,7 @@ port_configure(struct port *port)
     /* Clean up. */
     free(s.trunks);
     free(s.lacp_slaves);
+    free(s.bond_stable_ids);
 }
 
 /* Pick local port hardware address and datapath ID for 'br'. */
@@ -787,7 +791,7 @@ iface_set_ofp_port(struct iface *iface, int ofp_port)
     assert(iface->ofp_port < 0 && ofp_port >= 0);
     iface->ofp_port = ofp_port;
     hmap_insert(&br->ifaces, &iface->ofp_port_node, hash_int(ofp_port, 0));
-
+    iface_set_ofport(iface->cfg, ofp_port);
 }
 
 static void
@@ -923,7 +927,6 @@ bridge_add_ofproto_ports(struct bridge *br)
                 /* Already exists, nothing to do. */
                 ofproto_port_destroy(&ofproto_port);
             }
-            ofproto_port_destroy(&ofproto_port);
         }
     }
 }
@@ -1626,7 +1629,11 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
     br->name = xstrdup(br_cfg->name);
     br->type = xstrdup(ofproto_normalize_type(br_cfg->datapath_type));
     br->cfg = br_cfg;
-    eth_addr_nicira_random(br->default_ea);
+
+    /* Derive the default Ethernet address from the bridge's UUID.  This should
+     * be unique and it will be stable between ovs-vswitchd runs.  */
+    memcpy(br->default_ea, &br_cfg->header_.uuid, ETH_ADDR_LEN);
+    eth_addr_mark_random(br->default_ea);
 
     hmap_init(&br->ports);
     hmap_init(&br->ifaces);
@@ -2214,9 +2221,12 @@ iface_configure_lacp(struct iface *iface, struct lacp_slave_settings *s)
 }
 
 static void
-port_configure_bond(struct port *port, struct bond_settings *s)
+port_configure_bond(struct port *port, struct bond_settings *s,
+                    uint32_t *bond_stable_ids)
 {
     const char *detect_s;
+    struct iface *iface;
+    size_t i;
 
     s->name = port->name;
     s->balance = BM_SLB;
@@ -2251,6 +2261,18 @@ port_configure_bond(struct port *port, struct bond_settings *s)
     }
 
     s->fake_iface = port->cfg->bond_fake_iface;
+
+    i = 0;
+    LIST_FOR_EACH (iface, port_elem, &port->ifaces) {
+        long long stable_id;
+
+        stable_id = atoll(get_interface_other_config(iface->cfg,
+                                                     "bond-stable-id", "0"));
+        if (stable_id <= 0 || stable_id >= UINT32_MAX) {
+            stable_id = iface->ofp_port;
+        }
+        bond_stable_ids[i++] = stable_id;
+    }
 }
 \f
 /* Interface functions. */