@@ -388,7 +388,6 @@ chassis_tzones_overlap(const struct sset *transport_zones,
void
encaps_run(struct ovsdb_idl_txn *ovs_idl_txn,
- const struct ovsrec_bridge_table *bridge_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis_table *chassis_table,
const struct sbrec_chassis *this_chassis,
@@ -401,7 +400,6 @@ encaps_run(struct ovsdb_idl_txn *ovs_idl_txn,
}
const struct sbrec_chassis *chassis_rec;
- const struct ovsrec_bridge *br;
struct tunnel_ctx tc = {
.chassis = SHASH_INITIALIZER(&tc.chassis),
@@ -419,27 +417,25 @@ encaps_run(struct ovsdb_idl_txn *ovs_idl_txn,
/* Collect all port names into tc.port_names.
*
* Collect all the OVN-created tunnels into tc.tunnel_hmap. */
- OVSREC_BRIDGE_TABLE_FOR_EACH (br, bridge_table) {
- for (size_t i = 0; i < br->n_ports; i++) {
- const struct ovsrec_port *port = br->ports[i];
- sset_add(&tc.port_names, port->name);
-
- /*
- * note that the id here is not just the chassis name, but the
- * combination of <chassis_name><delim><encap_ip>
- */
- const char *id = smap_get(&port->external_ids, "ovn-chassis-id");
- if (id) {
- if (!shash_find(&tc.chassis, id)) {
- struct chassis_node *chassis = xzalloc(sizeof *chassis);
- chassis->bridge = br;
- chassis->port = port;
- shash_add_assert(&tc.chassis, id, chassis);
- } else {
- /* Duplicate port for ovn-chassis-id. Arbitrarily choose
- * to delete this one. */
- ovsrec_bridge_update_ports_delvalue(br, port);
- }
+ for (size_t i = 0; i < br_int->n_ports; i++) {
+ const struct ovsrec_port *port = br_int->ports[i];
+ sset_add(&tc.port_names, port->name);
+
+ /*
+ * note that the id here is not just the chassis name, but the
+ * combination of <chassis_name><delim><encap_ip>
+ */
+ const char *id = smap_get(&port->external_ids, "ovn-chassis-id");
+ if (id) {
+ if (!shash_find(&tc.chassis, id)) {
+ struct chassis_node *chassis = xzalloc(sizeof *chassis);
+ chassis->bridge = br_int;
+ chassis->port = port;
+ shash_add_assert(&tc.chassis, id, chassis);
+ } else {
+ /* Duplicate port for ovn-chassis-id. Arbitrarily choose
+ * to delete this one. */
+ ovsrec_bridge_update_ports_delvalue(br_int, port);
}
}
}
@@ -30,7 +30,6 @@ struct sset;
void encaps_register_ovs_idl(struct ovsdb_idl *);
void encaps_run(struct ovsdb_idl_txn *ovs_idl_txn,
- const struct ovsrec_bridge_table *,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis_table *,
const struct sbrec_chassis *,
@@ -4244,8 +4244,7 @@ main(int argc, char *argv[])
}
if (chassis) {
- encaps_run(ovs_idl_txn,
- bridge_table, br_int,
+ encaps_run(ovs_idl_txn, br_int,
sbrec_chassis_table_get(ovnsb_idl_loop.idl),
chassis,
sbrec_sb_global_first(ovnsb_idl_loop.idl),
@@ -33565,3 +33565,82 @@ check_column "" Encap ip chassis_name=hv1 type=vxlan
OVN_CLEANUP([hv1],[hv2])
AT_CLEANUP
])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([controllers don't touch tunnels that are not on br-int])
+ovn_start
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys1
+ovn_attach n1 br-phys1 192.168.0.1
+
+# use a port as a canary in the mine to wait until the controller is up
+# (meaning, ssl configuration was read from the database)
+ovn-nbctl ls-add ls
+ovn-nbctl lsp-add ls lp
+ovs-vsctl -- add-port br-int vif -- \
+ set interface vif external-ids:iface-id=lp
+wait_for_ports_up
+ovn-nbctl --wait=hv sync
+
+# the file is read once at startup so it's safe to write it
+# here after the first ovn-controller has started
+echo hv2 > ${OVN_SYSCONFDIR}/system-id-override
+ovs-vsctl add-br br-phys2
+
+# This function is similar to ovn_attach but makes sure it doesn't
+# mess with another controller settings
+start_virtual_controller() {
+ local net=$1 bridge=$2 ip=$3 masklen=${4-24} encap=${5-geneve,vxlan} systemid=${6-$sandbox} cli_args=${@:7}
+ net_attach $net $bridge || return 1
+
+ mac=`ovs-vsctl get Interface $bridge mac_in_use | sed s/\"//g`
+ arp_table="$arp_table $sandbox,$bridge,$ip,$mac"
+ ovs-appctl netdev-dummy/ip4addr $bridge $ip/$masklen >/dev/null || return 1
+ ovs-appctl ovs/route/add $ip/$masklen $bridge >/dev/null || return 1
+
+ local ovn_remote
+ if test X$HAVE_OPENSSL = Xyes; then
+ ovn_remote=$SSL_OVN_SB_DB
+ else
+ ovn_remote=unix:$ovs_base/ovn-sb/ovn-sb.sock
+ fi
+ ovs-vsctl \
+ -- set Open_vSwitch . external-ids:ovn-remote-$systemid=$ovn_remote \
+ -- set Open_vSwitch . external-ids:ovn-encap-type-$systemid=$encap \
+ -- set Open_vSwitch . external-ids:ovn-encap-ip-$systemid=$ip \
+ -- set Open_vSwitch . external-ids:ovn-bridge-$systemid=br-int-2 \
+ -- --may-exist add-br br-int-2 \
+ -- set bridge br-int-2 fail-mode=secure other-config:disable-in-band=true \
+ || return 1
+
+ ovn-controller --enable-dummy-vif-plug ${cli_args} -vconsole:off --detach --no-chdir
+}
+
+# for some reason SSL ovsdb configuration overrides CLI, so
+# delete ssl config from ovsdb to give CLI arguments priority
+ovs-vsctl del-ssl
+
+start_virtual_controller n1 br-phys2 192.168.0.2 24 geneve,vxlan hv2 \
+ --pidfile=${OVS_RUNDIR}/ovn-controller-2.pid \
+ --log-file=${OVS_RUNDIR}/ovn-controller-2.log \
+ -p $PKIDIR/testpki-hv2-privkey.pem \
+ -c $PKIDIR/testpki-hv2-cert.pem \
+ -C $PKIDIR/testpki-cacert.pem
+pidfile="$OVS_RUNDIR"/ovn-controller-2.pid
+on_exit "test -e \"$pidfile\" && kill \`cat \"$pidfile\"\`"
+
+# check that both tunnel ports are present, meaning controllers
+# don't step on each other
+OVS_WAIT_UNTIL([ovs-vsctl --columns _uuid --bare find Port \
+ name=ovn-hv1-hv2-0 | wc -l], [0],[[1
+]])
+OVS_WAIT_UNTIL([ovs-vsctl --columns _uuid --bare find Port \
+ name=ovn-hv2-hv1-0 | wc -l], [0],[[1
+]])
+
+OVN_CLEANUP([hv1])
+AT_CLEANUP
+])