AT_BANNER([ovn-controller]) AT_SETUP([ovn-controller - ovn-bridge-mappings]) AT_KEYWORDS([ovn]) ovn_init_db ovn-sb net_add n1 sim_add hv as hv ovs-vsctl \ -- add-br br-phys \ -- add-br br-eth0 \ -- add-br br-eth1 \ -- add-br br-eth2 ovn_attach n1 br-phys 192.168.0.1 # Waits until the OVS database contains exactly the specified patch ports. # Each argument should be of the form BRIDGE PORT PEER. check_patches () { # Generate code to check that the set of patch ports is exactly as # specified. echo 'ovs-vsctl -f csv -d bare --no-headings --columns=name find Interface type=patch | sort' > query for patch do echo $patch done | cut -d' ' -f 2 | sort > expout # Generate code to verify that the configuration of each patch # port is correct. for patch do set $patch; bridge=$1 port=$2 peer=$3 echo >>query "ovs-vsctl iface-to-br $port -- get Interface $port type options" echo >>expout "$bridge patch {peer=$peer}" done # Run the query until we get the expected result (or until a timeout). # # (We use sed to drop all "s from output because ovs-vsctl quotes some # of the port names but not others.) AT_CAPTURE_FILE([query]) AT_CAPTURE_FILE([expout]) AT_CAPTURE_FILE([stdout]) OVS_WAIT_UNTIL([. ./query | sed 's/"//g' > stdout #" diff -u stdout expout >/dev/null]) } # Make sure that the configured bridge mappings in the Open_vSwitch db # is mirrored into the Chassis record in the OVN_Southbound db. check_bridge_mappings () { local_mappings=$1 sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id) OVS_WAIT_UNTIL([test x"${local_mappings}" = x$(ovn-sbctl get Chassis ${sysid} external_ids:ovn-bridge-mappings | sed -e 's/\"//g')]) } # Initially there should be no patch ports. check_patches # Configure two ovn-bridge mappings, but no patch ports should be created yet AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0,physnet2:br-eth1]) check_bridge_mappings "physnet1:br-eth0,physnet2:br-eth1" check_patches # Create a localnet port, but we should still have no patch ports, as they # won't be created until there's a localnet port on a logical switch with # another logical port bound to this chassis. ovn-sbctl \ -- --id=@dp101 create Datapath_Binding tunnel_key=101 \ -- create Port_Binding datapath=@dp101 logical_port=localnet1 tunnel_key=1 \ type=localnet options:network_name=physnet1 check_patches # Create a localnet port on a logical switch with a port bound to this chassis. # Now we should get some patch ports created. ovn-sbctl \ -- --id=@dp102 create Datapath_Binding tunnel_key=102 \ -- create Port_Binding datapath=@dp102 logical_port=localnet2 tunnel_key=1 \ type=localnet options:network_name=physnet1 \ -- create Port_Binding datapath=@dp102 logical_port=localvif2 tunnel_key=2 ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2 check_patches \ 'br-int patch-br-int-to-localnet2 patch-localnet2-to-br-int' \ 'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2' # Add logical patch ports to connect new logical datapath. # # OVN no longer uses OVS patch ports to implement logical patch ports, so # the set of OVS patch ports doesn't change. AT_CHECK([ovn-sbctl \ -- --id=@dp1 create Datapath_Binding tunnel_key=1 \ -- --id=@dp2 create Datapath_Binding tunnel_key=2 \ -- create Port_Binding datapath=@dp1 logical_port=foo tunnel_key=1 type=patch options:peer=bar \ -- create Port_Binding datapath=@dp2 logical_port=bar tunnel_key=2 type=patch options:peer=foo \ -- create Port_Binding datapath=@dp1 logical_port=dp1vif tunnel_key=3 \ | uuidfilt], [0], [<0> <1> <2> <3> <4> ]) ovs-vsctl add-port br-int dp1vif -- set Interface dp1vif external_ids:iface-id=dp1vif check_patches \ 'br-int patch-br-int-to-localnet2 patch-localnet2-to-br-int' \ 'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2' # Delete the mapping and the ovn-bridge-mapping patch ports should go away. AT_CHECK([ovs-vsctl remove Open_vSwitch . external-ids ovn-bridge-mappings]) check_bridge_mappings check_patches # Gracefully terminate daemons OVN_CLEANUP_SBOX([hv]) OVN_CLEANUP_VSWITCH([main]) as ovn-sb OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP # Checks that ovn-controller populates datapath-type and iface-types # correctly in the Chassis external-ids column. AT_SETUP([ovn-controller - Chassis external_ids]) AT_KEYWORDS([ovn]) ovn_init_db ovn-sb net_add n1 sim_add hv as hv ovs-vsctl \ -- add-br br-phys \ -- add-br br-eth0 \ -- add-br br-eth1 \ -- add-br br-eth2 ovn_attach n1 br-phys 192.168.0.1 sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id) # Make sure that the datapath_type set in the Bridge table # is mirrored into the Chassis record in the OVN_Southbound db. check_datapath_type () { datapath_type=$1 chassis_datapath_type=$(ovn-sbctl get Chassis ${sysid} external_ids:datapath-type | sed -e 's/"//g') #" test "${datapath_type}" = "${chassis_datapath_type}" } OVS_WAIT_UNTIL([check_datapath_type ""]) ovs-vsctl set Bridge br-int datapath-type=foo OVS_WAIT_UNTIL([check_datapath_type foo]) # Change "ovn-bridge-mappings" value. It should not change the "datapath-type". ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-mappings=foo-mapping check_datapath_type foo ovs-vsctl set Bridge br-int datapath-type=bar OVS_WAIT_UNTIL([check_datapath_type bar]) ovs-vsctl set Bridge br-int datapath-type=\"\" OVS_WAIT_UNTIL([check_datapath_type ""]) expected_iface_types=$(ovs-vsctl get Open_vSwitch . iface_types | tr -d '[[]] ""') echo "expected_iface_types = ${expected_iface_types}" chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g') echo "chassis_iface_types = ${chassis_iface_types}" AT_CHECK([test "${expected_iface_types}" = "${chassis_iface_types}"]) # Change the value of external_ids:iface-types using ovn-sbctl. # ovn-controller should again set it back to proper one. ovn-sbctl set Chassis ${sysid} external_ids:iface-types="foo" OVS_WAIT_UNTIL([ chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g') echo "chassis_iface_types = ${chassis_iface_types}" test "${expected_iface_types}" = "${chassis_iface_types}" ]) # Gracefully terminate daemons OVN_CLEANUP_SBOX([hv]) OVN_CLEANUP_VSWITCH([main]) as ovn-sb OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP # Checks that ovn-controller correctly maintains the mapping from the Encap # table in the Southbound database to OVS in the face of changes on both sides AT_SETUP([ovn-controller - change Encap properties]) AT_KEYWORDS([ovn]) ovn_init_db ovn-sb net_add n1 sim_add hv as hv ovs-vsctl \ -- add-br br-phys \ -- add-br br-eth0 \ -- add-br br-eth1 \ -- add-br br-eth2 ovn_attach n1 br-phys 192.168.0.1 check_tunnel_property () { test "`ovs-vsctl get interface ovn-fakech-0 $1`" = "$2" } # Start off with a remote chassis supporting STT ovn-sbctl chassis-add fakechassis stt 192.168.0.2 OVS_WAIT_UNTIL([check_tunnel_property type stt]) # See if we switch to Geneve as the first choice when it is available encap_uuid=$(ovn-sbctl add chassis fakechassis encaps @encap -- --id=@encap create encap type=geneve ip="127.0.0.1") OVS_WAIT_UNTIL([check_tunnel_property type geneve]) # Check that changes within an encap row are propagated ovn-sbctl set encap ${encap_uuid} ip=192.168.0.2 OVS_WAIT_UNTIL([check_tunnel_property options:remote_ip "\"192.168.0.2\""]) # Change the type on the OVS side and check than OVN fixes it ovs-vsctl set interface ovn-fakech-0 type=vxlan OVS_WAIT_UNTIL([check_tunnel_property type geneve]) # Delete the port entirely and it should be resurrected ovs-vsctl del-port ovn-fakech-0 OVS_WAIT_UNTIL([check_tunnel_property type geneve]) # Gracefully terminate daemons OVN_CLEANUP_SBOX([hv]) OVN_CLEANUP_VSWITCH([main]) as ovn-sb OVS_APP_EXIT_AND_WAIT([ovsdb-server]) AT_CLEANUP