void
bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
{
+ struct ovsdb_idl_txn *txn;
struct shash old_br, new_br;
struct shash_node *node;
struct bridge *br, *next;
COVERAGE_INC(bridge_reconfigure);
+ txn = ovsdb_idl_txn_create(ovs_cfg->header_.table->idl);
+
/* Collect old and new bridges. */
shash_init(&old_br);
shash_init(&new_br);
uint64_t dpid;
struct iface *local_iface;
struct iface *hw_addr_iface;
+ char *dpid_string;
bridge_fetch_dp_ifaces(br);
iterate_and_prune_ifaces(br, init_iface_netdev, NULL);
dpid = bridge_pick_datapath_id(br, ea, hw_addr_iface);
ofproto_set_datapath_id(br->ofproto, dpid);
+ dpid_string = xasprintf("%012"PRIx64, dpid);
+ ovsrec_bridge_set_datapath_id(br->cfg, dpid_string);
+ free(dpid_string);
+
/* Set NetFlow configuration on this bridge. */
if (br->cfg->netflow) {
struct ovsrec_netflow *nf_cfg = br->cfg->netflow;
LIST_FOR_EACH (br, struct bridge, node, &all_bridges) {
iterate_and_prune_ifaces(br, set_iface_properties, NULL);
}
+
+ ovsrec_open_vswitch_set_cur_cfg(ovs_cfg, ovs_cfg->next_cfg);
+
+ ovsdb_idl_txn_commit(txn);
+ ovsdb_idl_txn_destroy(txn); /* XXX */
+}
+
+static const char *
+bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
+{
+ size_t i;
+
+ for (i = 0; i < br_cfg->n_other_config; i++) {
+ if (!strcmp(br_cfg->key_other_config[i], key)) {
+ return br_cfg->value_other_config[i];
+ }
+ }
+ return NULL;
}
static void
bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
struct iface **hw_addr_iface)
{
+ const char *hwaddr;
size_t i, j;
int error;
*hw_addr_iface = NULL;
/* Did the user request a particular MAC? */
- if (br->cfg->hwaddr && eth_addr_from_string(br->cfg->hwaddr, ea)) {
+ hwaddr = bridge_get_other_config(br->cfg, "hwaddr");
+ if (hwaddr && eth_addr_from_string(hwaddr, ea)) {
if (eth_addr_is_multicast(ea)) {
VLOG_ERR("bridge %s: cannot set MAC address to multicast "
"address "ETH_ADDR_FMT, br->name, ETH_ADDR_ARGS(ea));
}
}
- /* Otherwise choose the minimum MAC address among all of the interfaces.
- * (Xen uses FE:FF:FF:FF:FF:FF for virtual interfaces so this will get the
- * MAC of the physical interface in such an environment.) */
+ /* Otherwise choose the minimum non-local MAC address among all of the
+ * interfaces. */
memset(ea, 0xff, sizeof ea);
for (i = 0; i < br->n_ports; i++) {
struct port *port = br->ports[i];
}
/* The local port doesn't count (since we're trying to choose its
- * MAC address anyway). Other internal ports don't count because
- * we really want a physical MAC if we can get it, and internal
- * ports typically have randomly generated MACs. */
- if (iface->dp_ifidx == ODPP_LOCAL
- || !strcmp(iface->cfg->type, "internal")) {
+ * MAC address anyway). */
+ if (iface->dp_ifidx == ODPP_LOCAL) {
continue;
}
/* Compare against our current choice. */
if (!eth_addr_is_multicast(iface_ea) &&
+ !eth_addr_is_local(iface_ea) &&
!eth_addr_is_reserved(iface_ea) &&
!eth_addr_is_zero(iface_ea) &&
memcmp(iface_ea, ea, ETH_ADDR_LEN) < 0)
*hw_addr_iface = iface;
}
}
- if (eth_addr_is_multicast(ea) || eth_addr_is_vif(ea)) {
+ if (eth_addr_is_multicast(ea)) {
memcpy(ea, br->default_ea, ETH_ADDR_LEN);
*hw_addr_iface = NULL;
VLOG_WARN("bridge %s: using default bridge Ethernet "
* stable from one run to the next, so that policy set on a datapath
* "sticks".
*/
+ const char *datapath_id;
uint64_t dpid;
- if (br->cfg->datapath_id
- && dpid_from_string(br->cfg->datapath_id, &dpid)) {
+ datapath_id = bridge_get_other_config(br->cfg, "datapath-id");
+ if (datapath_id && dpid_from_string(datapath_id, &dpid)) {
return dpid;
}
rate_limit = c->controller_rate_limit ? *c->controller_rate_limit : 0;
burst_limit = c->controller_burst_limit ? *c->controller_burst_limit : 0;
ofproto_set_rate_limit(br->ofproto, rate_limit, burst_limit);
-
- ofproto_set_remote_execution(br->ofproto, NULL, NULL); /* XXX */
} else {
union ofp_action action;
flow_t flow;
port_array_set(&br->ifaces, p->port, iface);
iface->dp_ifidx = p->port;
}
+
+ if (iface->cfg) {
+ int64_t ofport = (iface->dp_ifidx >= 0
+ ? odp_port_to_ofp_port(iface->dp_ifidx)
+ : -1);
+ ovsrec_interface_set_ofport(iface->cfg, &ofport, 1);
+ }
}
}
free(dpif_ports);