diff --git a/tests/automake.mk b/tests/automake.mk
index d6ab517..decca46 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -23,8 +23,7 @@ EXTRA_DIST += \
 COMMON_MACROS_AT = \
 	tests/ovsdb-macros.at \
 	tests/ovs-macros.at \
-	tests/ofproto-macros.at \
-	tests/ovn-macros.at
+	tests/ofproto-macros.at
 
 TESTSUITE_AT = \
 	tests/testsuite.at \
@@ -104,16 +103,9 @@ TESTSUITE_AT = \
 	tests/vlog.at \
 	tests/vtep-ctl.at \
 	tests/auto-attach.at \
-	tests/ovn.at \
-	tests/ovn-northd.at \
-	tests/ovn-nbctl.at \
-	tests/ovn-sbctl.at \
-	tests/ovn-controller.at \
-	tests/ovn-controller-vtep.at \
 	tests/mcast-snooping.at \
 	tests/packet-type-aware.at \
-	tests/nsh.at \
-	tests/ovn-performance.at
+	tests/nsh.at
 
 EXTRA_DIST += $(FUZZ_REGRESSION_TESTS)
 FUZZ_REGRESSION_TESTS = \
@@ -158,7 +150,6 @@ SYSTEM_KMOD_TESTSUITE_AT = \
 
 SYSTEM_USERSPACE_TESTSUITE_AT = \
 	tests/system-userspace-testsuite.at \
-	tests/system-ovn.at \
 	tests/system-userspace-macros.at \
 	tests/system-userspace-packet-type-aware.at
 
@@ -169,7 +160,6 @@ SYSTEM_AFXDP_TESTSUITE_AT = \
 
 SYSTEM_TESTSUITE_AT = \
 	tests/system-common-macros.at \
-	tests/system-ovn.at \
 	tests/system-layer3-tunnels.at \
 	tests/system-traffic.at \
 	tests/system-interface.at
@@ -197,7 +187,7 @@ SYSTEM_DPDK_TESTSUITE = $(srcdir)/tests/system-dpdk-testsuite
 OVSDB_CLUSTER_TESTSUITE = $(srcdir)/tests/ovsdb-cluster-testsuite
 DISTCLEANFILES += tests/atconfig tests/atlocal
 
-AUTOTEST_PATH = utilities:vswitchd:ovsdb:vtep:tests:$(PTHREAD_WIN32_DIR_DLL):$(SSL_DIR):ovn/controller-vtep:ovn/northd:ovn/utilities:ovn/controller
+AUTOTEST_PATH = utilities:vswitchd:ovsdb:vtep:tests:$(PTHREAD_WIN32_DIR_DLL):$(SSL_DIR)
 
 check-local:
 	set $(SHELL) '$(TESTSUITE)' -C tests AUTOTEST_PATH=$(AUTOTEST_PATH); \
@@ -238,10 +228,6 @@ check-lcov: all $(check_DATA) clean-lcov
 # valgrind support
 
 valgrind_wrappers = \
-	tests/valgrind/ovn-controller \
-	tests/valgrind/ovn-nbctl \
-	tests/valgrind/ovn-northd \
-	tests/valgrind/ovn-sbctl \
 	tests/valgrind/ovs-appctl \
 	tests/valgrind/ovs-ofctl \
 	tests/valgrind/ovs-vsctl \
@@ -446,7 +432,6 @@ tests_ovstest_SOURCES = \
 	tests/test-netflow.c \
 	tests/test-odp.c \
 	tests/test-ofpbuf.c \
-	tests/test-ovn.c \
 	tests/test-packets.c \
 	tests/test-random.c \
 	tests/test-rcu.c \
@@ -474,7 +459,7 @@ tests_ovstest_SOURCES += \
 	tests/test-netlink-conntrack.c
 endif
 
-tests_ovstest_LDADD = lib/libopenvswitch.la ovn/lib/libovn.la
+tests_ovstest_LDADD = lib/libopenvswitch.la
 
 noinst_PROGRAMS += tests/test-stream
 tests_test_stream_SOURCES = tests/test-stream.c
diff --git a/tests/ovn-controller-vtep.at b/tests/ovn-controller-vtep.at
deleted file mode 100644
index a3fe8cb..0000000
--- a/tests/ovn-controller-vtep.at
+++ /dev/null
@@ -1,467 +0,0 @@
-AT_BANNER([ovn_controller_vtep])
-
-# OVN_CONTROLLER_VTEP_START
-#
-# Starts the test with a setup with vtep device.  Each test case must first
-# call this macro.
-#
-# Uses vtep-ovs to simulate the vtep switch 'br-vtep' with two physical ports
-# 'p0', 'p1'.
-#
-# Configures ovn-nb with a logical switch 'br-test'.
-#
-#
-m4_define([OVN_CONTROLLER_VTEP_START],
-  [
-   AT_KEYWORDS([ovn])
-   # this will cause skip when 'make check' using Windows setup.
-   AT_SKIP_IF([test $HAVE_PYTHON = no])
-
-   dnl Create databases (ovn-nb, ovn-sb, vtep).
-   AT_CHECK([ovsdb-tool create vswitchd.db $abs_top_srcdir/vswitchd/vswitch.ovsschema])
-   for daemon in ovn-nb ovn-sb vtep; do
-      AT_CHECK([ovsdb-tool create $daemon.db $abs_top_srcdir/${daemon%%-*}/${daemon}.ovsschema])
-   done
-
-   dnl Start ovsdb-server.
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --log-file --remote=punix:$OVS_RUNDIR/db.sock vswitchd.db vtep.db], [0], [], [stderr])
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=ovsdb-nb-server.pid --log-file=ovsdb-nb-server.log --remote=punix:$OVS_RUNDIR/ovnnb_db.sock ovn-nb.db], [0], [], [stderr])
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=ovsdb-sb-server.pid --log-file=ovsdb-sb-server.log --remote=punix:$OVS_RUNDIR/ovnsb_db.sock ovn-sb.db ovn-sb.db], [0], [], [stderr])
-   on_exit "kill `cat ovsdb-server.pid` `cat ovsdb-nb-server.pid` `cat ovsdb-sb-server.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d
-/ovsdb_server|INFO|ovsdb-server (Open vSwitch)/d']])
-   AT_CAPTURE_FILE([ovsdb-server.log])
-
-   dnl Start ovs-vswitchd.
-   AT_CHECK([ovs-vswitchd --enable-dummy=system --disable-system --detach --no-chdir --pidfile --log-file -vvconn -vofproto_dpif], [0], [], [stderr])
-   AT_CAPTURE_FILE([ovs-vswitchd.log])
-   on_exit "kill `cat ovs-vswitchd.pid`"
-   AT_CHECK([[sed < stderr '
-/ovs_numa|INFO|Discovered /d
-/vlog|INFO|opened log file/d
-/vswitchd|INFO|ovs-vswitchd (Open vSwitch)/d
-/reconnect|INFO|/d
-/ofproto|INFO|using datapath ID/d
-/netlink_socket|INFO|netlink: could not enable listening to all nsid/d
-/ofproto|INFO|datapath ID changed to fedcba9876543210/d']])
-   AT_CHECK([ovs-vsctl -- add-br br-vtep \
-              -- set bridge br-vtep datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15]] fail-mode=secure \
-              -- add-port br-vtep p0 -- set Interface p0 type=dummy ofport_request=1 \
-              -- add-port br-vtep p1 -- set Interface p1 type=dummy ofport_request=2])
-
-   dnl Start ovs-vtep.
-   AT_CHECK([vtep-ctl add-ps br-vtep -- set Physical_Switch br-vtep tunnel_ips=1.2.3.4])
-   AT_CHECK([ovs-vtep --log-file=ovs-vtep.log --pidfile=ovs-vtep.pid --detach --no-chdir br-vtep \], [0], [], [stderr])
-   on_exit "kill `cat ovs-vtep.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d']])
-   # waits until ovs-vtep starts up.
-   OVS_WAIT_UNTIL([test -n "`vtep-ctl show | grep Physical_Port`"])
-
-   dnl Start ovn-northd.
-   AT_CHECK([ovn-nbctl ls-add br-test])
-   AT_CHECK([ovn-northd --detach --no-chdir --pidfile --log-file], [0], [], [stderr])
-   on_exit "kill `cat ovn-northd.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d']])
-   AT_CAPTURE_FILE([ovn-northd.log])
-
-   dnl Start ovn-controllger-vtep.
-   AT_CHECK([ovn-controller-vtep --detach --no-chdir --pidfile --log-file --vtep-db=unix:$OVS_RUNDIR/db.sock --ovnsb-db=unix:$OVS_RUNDIR/ovnsb_db.sock], [0], [], [stderr])
-   AT_CAPTURE_FILE([ovn-controller-vtep.log])
-   on_exit "kill `cat ovn-controller-vtep.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d
-/reconnect|INFO|/d']])
-])
-
-# OVN_CONTROLLER_VTEP_STOP
-#
-# So many exits... Yeah, we started a lot daemons~
-#
-m4_define([OVN_CONTROLLER_VTEP_STOP],
-  [AT_CHECK([check_logs "$1"])
-   OVS_APP_EXIT_AND_WAIT([ovs-vtep])
-   OVS_APP_EXIT_AND_WAIT([ovn-northd])
-   OVS_APP_EXIT_AND_WAIT([ovn-controller-vtep])
-   OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-   OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])])
-
-# Adds logical port for a vtep gateway chassis in ovn-nb database.
-#
-# $1: logical switch name in ovn-nb database
-# $2: logical port name
-# $3: physical vtep gateway name
-# $4: logical switch name on vtep gateway chassis
-m4_define([OVN_NB_ADD_VTEP_PORT], [
-AT_CHECK([ovn-nbctl lsp-add $1 $2])
-
-AT_CHECK([ovn-nbctl lsp-set-type $2 vtep])
-AT_CHECK([ovn-nbctl lsp-set-options $2 vtep-physical-switch=$3 vtep-logical-switch=$4])
-])
-
-##############################################
-
-# tests chassis related updates.
-AT_SETUP([ovn-controller-vtep - chassis])
-OVN_CONTROLLER_VTEP_START
-
-# verifies the initial ovn-sb db configuration.
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl show | grep Chassis`"])
-AT_CHECK([ovn-sbctl show], [0], [dnl
-Chassis br-vtep
-    Encap vxlan
-        ip: "1.2.3.4"
-        options: {csum="false"}
-])
-
-# deletes the chassis via ovn-sbctl and check that it is readded back
-# with the log.
-AT_CHECK([ovn-sbctl chassis-del br-vtep])
-OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"])
-AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log], [0], [dnl
-|WARN|Chassis for VTEP physical switch (br-vtep) disappears, maybe deleted by ovn-sbctl, adding it back
-])
-
-# changes the tunnel_ip on physical switch, watches the update of chassis's
-# encap.
-AT_CHECK([vtep-ctl set Physical_Switch br-vtep tunnel_ips=1.2.3.5])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl show | grep 1\.2\.3\.5`"])
-AT_CHECK([ovn-sbctl --columns=ip list Encap | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-"1.2.3.5"
-])
-
-# adds vlan_bindings to physical ports.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 -- bind-ls br-vtep p0 200 lswitch0 -- bind-ls br-vtep p1 300 lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Chassis | grep -- lswitch0`"])
-AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
-[[lswitch0]]
-])
-
-# adds another logical switch and new vlan_bindings.
-AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 300 lswitch1])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Chassis | grep -- lswitch1`"])
-AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-[[lswitch0,lswitch1]]
-])
-
-# unbinds one port from lswitch0, nothing should change.
-AT_CHECK([vtep-ctl unbind-ls br-vtep p0 200])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=vlan_bindings list physical_port p0 | grep -- '200='`"])
-AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
-[[lswitch0,lswitch1]]
-])
-
-# unbinds all ports from lswitch0.
-AT_CHECK([vtep-ctl unbind-ls br-vtep p0 100 -- unbind-ls br-vtep p1 300])
-OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch0`"])
-AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
-[[lswitch1]]
-])
-
-# unbinds all ports from lswitch1.
-AT_CHECK([vtep-ctl unbind-ls br-vtep p0 300])
-OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch1`"])
-AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-[[]]
-])
-
-OVN_CONTROLLER_VTEP_STOP([/Chassis for VTEP physical switch (br-vtep) disappears/d])
-AT_CLEANUP
-
-
-# Tests binding updates.
-AT_SETUP([ovn-controller-vtep - binding 1])
-OVN_CONTROLLER_VTEP_START
-
-# adds logical switch 'lswitch0' and vlan_bindings.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 -- bind-ls br-vtep p1 300 lswitch0])
-# adds logical switch port in ovn-nb database, and sets the type and options.
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-ovn-sbctl --timeout=10 wait-until Port_Binding br-vtep_lswitch0 chassis!='[[]]'
-# should see one binding, associated to chassis of 'br-vtep'.
-chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d ':' -f2 | tr -d ' ')
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-${chassis_uuid}
-])
-
-# adds another logical switch 'lswitch1' and vlan_bindings.
-AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 200 lswitch1])
-# adds logical switch port in ovn-nb database for lswitch1.
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch1], [br-vtep], [lswitch1])
-ovn-sbctl --timeout=10 wait-until Port_Binding br-vtep_lswitch1 chassis!='[[]]'
-# This is allowed, but not recommended, to have two vlan_bindings (to different vtep logical switches)
-# from one vtep gateway physical port in one ovn-nb logical swithch.
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort], [0], [dnl
-
-${chassis_uuid}
-${chassis_uuid}
-])
-
-# adds another logical switch port in ovn-nb database for lswitch0.
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0_dup], [br-vtep], [lswitch0])
-ovn-sbctl --timeout=10 wait-until Port_Binding br-vtep_lswitch0_dup chassis!='[[]]'
-# it is not allowed to have more than one ovn-nb logical port for the same
-# vtep logical switch on a vtep gateway chassis, so should still see only
-# two port_binding entries bound.
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort | sort -d], [0], [dnl
-
-
-[[]]
-${chassis_uuid}
-${chassis_uuid}
-])
-# confirms the warning log.
-AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g' | uniq], [0], [dnl
-|WARN|logical switch (), on vtep gateway chassis () has already been associated with logical port (), ignore logical port ()
-])
-
-# deletes physical ports from vtep.
-AT_CHECK([ovs-vsctl del-port p0 -- del-port p1])
-OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch`"])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl list physical_port p0`"])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl list physical_port p1`"])
-# should see empty chassis column in both binding entries.
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort], [0], [dnl
-
-
-[[]]
-[[]]
-[[]]
-])
-
-OVN_CONTROLLER_VTEP_STOP([/has already been associated with logical port/d])
-AT_CLEANUP
-
-
-# Tests corner case: Binding the vtep logical switch from two different
-# datapath.
-AT_SETUP([ovn-controller-vtep - binding 2])
-OVN_CONTROLLER_VTEP_START
-
-# adds logical switch 'lswitch0' and vlan_bindings.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0])
-# adds logical switch port in ovn-nb database, and sets the type and options.
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-ovn-sbctl --timeout=10 wait-until Port_Binding br-vtep_lswitch0 chassis!='[[]]'
-
-# adds another lswitch 'br-void' in ovn-nb database.
-AT_CHECK([ovn-nbctl ls-add br-void])
-# adds another vtep pswitch 'br-vtep-void' in vtep database.
-AT_CHECK([vtep-ctl add-ps br-vtep-void -- add-port br-vtep-void p0-void -- bind-ls br-vtep-void p0-void 100 lswitch0])
-# adds a conflicting logical port (both br-vtep_lswitch0 and br-vtep-void_lswitch0
-# are bound to the same logical switch, but they are on different datapath).
-OVN_NB_ADD_VTEP_PORT([br-void], [br-vtep-void_lswitch0], [br-vtep-void], [lswitch0])
-ovn-sbctl --timeout=10 wait-until Port_Binding br-vtep_lswitch0
-OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"])
-# confirms the warning log.
-AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g;s/(with tunnel key [[0-9]][[0-9]]*)/()/g' | uniq], [0], [dnl
-|WARN|logical switch (), on vtep gateway chassis () has already been associated with logical datapath (), ignore logical port () which belongs to logical datapath ()
-])
-
-# then deletes 'br-void' and 'br-vtep-void', should see 'br-vtep_lswitch0'
-# bound correctly.
-AT_CHECK([ovn-nbctl ls-del br-void])
-# adds another vtep pswitch 'br-vtep-void' in vtep database.
-AT_CHECK([vtep-ctl del-ps br-vtep-void])
-OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Port_Binding | grep br-vtep-void_lswitch0`"])
-chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d ':' -f2 | tr -d ' ')
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-${chassis_uuid}
-])
-
-OVN_CONTROLLER_VTEP_STOP([/has already been associated with logical datapath/d])
-AT_CLEANUP
-
-
-# Tests vtep module vtep logical switch tunnel key update.
-AT_SETUP([ovn-controller-vtep - vtep-lswitch])
-OVN_CONTROLLER_VTEP_START
-
-# creates the logical switch in vtep and adds the corresponding logical
-# port to 'br-test'.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0])
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep -- br-vtep_lswitch0`"])
-
-# retrieves the expected tunnel key.
-datapath_uuid=$(ovn-sbctl --columns=datapath list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' ')
-tunnel_key=$(ovn-sbctl --columns=tunnel_key list Datapath_Binding ${datapath_uuid} | cut -d ':' -f2 | tr -d ' ')
-OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=tunnel_key list Logical_Switch | grep 0`"])
-# checks the vtep logical switch tunnel key configuration.
-AT_CHECK_UNQUOTED([vtep-ctl --columns=tunnel_key list Logical_Switch | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-${tunnel_key}
-])
-
-# creates a second physical switch in vtep database, and binds its p0 vlan-100
-# to the same logical switch 'lswitch0'.
-AT_CHECK([vtep-ctl add-ps br-vtep-void -- add-port br-vtep-void p0 -- bind-ls br-vtep-void p0 100 lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl --columns=name list Chassis  | grep -- br-vtep-void`"])
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep-void_lswitch0], [br-vtep-void], [lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep -- br-vtep-void_lswitch0`"])
-
-# checks the vtep logical switch tunnel key configuration.
-AT_CHECK_UNQUOTED([vtep-ctl --columns=tunnel_key list Logical_Switch | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-${tunnel_key}
-])
-
-# now, deletes br-vtep-void.
-AT_CHECK([vtep-ctl del-ps br-vtep-void])
-OVS_WAIT_UNTIL([test -z "`ovn-sbctl --columns=name list Chassis  | grep -- br-vtep-void`"])
-# checks the vtep logical switch tunnel key configuration.
-AT_CHECK_UNQUOTED([vtep-ctl --columns=tunnel_key list Logical_Switch | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-${tunnel_key}
-])
-
-# changes the ovn-nb logical port type so that it is no longer
-# vtep port.
-AT_CHECK([ovn-nbctl lsp-set-type br-vtep_lswitch0 ""])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=tunnel_key list Logical_Switch | grep 1`"])
-# now should see the tunnel key reset.
-AT_CHECK([vtep-ctl --columns=tunnel_key list Logical_Switch | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-0
-])
-
-OVN_CONTROLLER_VTEP_STOP
-AT_CLEANUP
-
-
-# Tests vtep module 'Ucast_Macs_Remote's.
-AT_SETUP([ovn-controller-vtep - vtep-macs 1])
-OVN_CONTROLLER_VTEP_START
-
-# creates a simple logical network with the vtep device and a fake hv chassis
-# 'ch0'.
-AT_CHECK([ovn-nbctl lsp-add br-test vif0])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-nbctl --timeout=10 --wait=sb sync])
-AT_CHECK([ovn-sbctl chassis-add ch0 vxlan 1.2.3.5])
-AT_CHECK([ovn-sbctl lsp-bind vif0 ch0])
-
-# creates the logical switch in vtep and adds the corresponding logical
-# port to 'br-test'.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0])
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-vtep_lswitch0`"])
-
-# adds another lswitch 'br-void' in ovn-nb database.
-AT_CHECK([ovn-nbctl ls-add br-void])
-# adds fake hv chassis 'ch1'.
-AT_CHECK([ovn-nbctl lsp-add br-void vif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif1 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-nbctl --timeout=10 --wait=sb sync])
-AT_CHECK([ovn-sbctl chassis-add ch1 vxlan 1.2.3.6])
-AT_CHECK([ovn-sbctl lsp-bind vif1 ch1])
-
-# checks Ucast_Macs_Remote creation.
-OVS_WAIT_UNTIL([test -n "`vtep-ctl list Ucast_Macs_Remote | grep _uuid`"])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' '], [0], [dnl
-"f0:ab:cd:ef:01:02"
-])
-
-# checks physical locator creation.
-OVS_WAIT_UNTIL([test -n "`vtep-ctl list Physical_Locator | grep _uuid`"])
-AT_CHECK([vtep-ctl --columns=dst_ip list Physical_Locator | cut -d ':' -f2 | tr -d ' ' | grep -v 1.2.3.4 | sed '/^$/d'], [0], [dnl
-"1.2.3.5"
-])
-
-# checks tunnel creation by ovs-vtep.
-OVS_WAIT_UNTIL([test -n "`ovs-vsctl list Interface bfd1.2.3.5`"])
-AT_CHECK([ovs-vsctl --columns=options list Interface bfd1.2.3.5 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
-{remote_ip="1.2.3.5"}
-])
-
-# adds another mac to logical switch port.
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0 f0:ab:cd:ef:01:02 f0:ab:cd:ef:01:03])
-OVS_WAIT_UNTIL([test -n "`vtep-ctl list Ucast_Macs_Remote | grep 03`"])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' ' | sort], [0], [dnl
-
-"f0:ab:cd:ef:01:02"
-"f0:ab:cd:ef:01:03"
-])
-
-# removes one mac to logical switch port.
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0 f0:ab:cd:ef:01:03])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=MAC list Ucast_Macs_Remote | grep 02`"])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' ' | sort], [0], [dnl
-"f0:ab:cd:ef:01:03"
-])
-
-# migrates mac to logical switch port vif1 on 'br-void'.
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif1 f0:ab:cd:ef:01:03])
-OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=MAC list Ucast_Macs_Remote | grep 03`"])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' ' | sort], [0], [dnl
-])
-
-OVN_CONTROLLER_VTEP_STOP
-AT_CLEANUP
-
-
-# Tests vtep module 'Ucast_Macs_Remote's (corner cases).
-AT_SETUP([ovn-controller-vtep - vtep-macs 2])
-OVN_CONTROLLER_VTEP_START
-
-# creates a simple logical network with the vtep device and a fake hv chassis
-# 'ch0'.
-AT_CHECK([ovn-nbctl lsp-add br-test vif0])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-nbctl --timeout=10 --wait=sb sync])
-AT_CHECK([ovn-sbctl chassis-add ch0 vxlan 1.2.3.5])
-AT_CHECK([ovn-sbctl lsp-bind vif0 ch0])
-
-# creates another vif in the same logical switch with duplicate mac.
-AT_CHECK([ovn-nbctl lsp-add br-test vif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif1 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-nbctl --timeout=10 --wait=sb sync])
-AT_CHECK([ovn-sbctl lsp-bind vif1 ch0])
-
-# creates the logical switch in vtep and adds the corresponding logical
-# port to 'br-test'.
-AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0])
-OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-vtep_lswitch0`"])
-
-# checks Ucast_Macs_Remote creation.  Should still only be one entry, since duplicate
-# mac in the same logical switch is not allowed.
-OVS_WAIT_UNTIL([test -n "`vtep-ctl list Ucast_Macs_Remote | grep _uuid`"])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' '], [0], [dnl
-"f0:ab:cd:ef:01:02"
-])
-# confirms the warning log.
-OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"])
-AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_:0-9a-z]][[-_:0-9a-z]]*)/()/g' | uniq], [0], [dnl
-|WARN|MAC address () has already been known to be on logical port () in the same logical datapath, so just ignore this logical port ()
-])
-
-# deletes vif1.
-AT_CHECK([ovn-nbctl lsp-del vif1])
-
-# adds another lswitch 'br-void' in ovn-nb database.
-AT_CHECK([ovn-nbctl ls-add br-void])
-# adds fake hv chassis 'ch1' and vif1 with same mac address as vif0.
-AT_CHECK([ovn-nbctl lsp-add br-void vif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif1 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-nbctl --timeout=10 --wait=sb sync])
-AT_CHECK([ovn-sbctl chassis-add ch1 vxlan 1.2.3.6])
-AT_CHECK([ovn-sbctl lsp-bind vif1 ch1])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep vif1`"])
-
-# creates another logical switch in vtep and adds the corresponding logical
-# port to 'br-void'.
-AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 200 lswitch1])
-OVN_NB_ADD_VTEP_PORT([br-void], [br-void_lswitch1], [br-vtep], [lswitch1])
-OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-void_lswitch1`"])
-
-# checks Ucast_Macs_Remote creation.  Should see two entries since it is allowed
-# to have duplicate macs in different logical switches.
-OVS_WAIT_UNTIL([test `vtep-ctl --columns=MAC list Ucast_Macs_Remote | grep 02 | wc -l` -gt 1])
-AT_CHECK([vtep-ctl --columns=MAC list Ucast_Macs_Remote | cut -d ':' -f2- | tr -d ' ' | sort], [0], [dnl
-
-"f0:ab:cd:ef:01:02"
-"f0:ab:cd:ef:01:02"
-])
-
-OVN_CONTROLLER_VTEP_STOP([/has already been known to be on logical port/d])
-AT_CLEANUP
diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at
deleted file mode 100644
index 343c2ab..0000000
--- a/tests/ovn-controller.at
+++ /dev/null
@@ -1,294 +0,0 @@
-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 ""])
-
-# Set the datapath_type in external_ids:ovn-bridge-datapath-type.
-ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-datapath-type=foo
-OVS_WAIT_UNTIL([check_datapath_type foo])
-
-# Change the br-int's datapath type to bar.
-# It should be reset to foo since ovn-bridge-datapath-type is configured.
-ovs-vsctl set Bridge br-int datapath-type=bar
-OVS_WAIT_UNTIL([test foo=`ovs-vsctl get Bridge br-int datapath-type`])
-OVS_WAIT_UNTIL([check_datapath_type foo])
-
-ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-datapath-type=foobar
-OVS_WAIT_UNTIL([test foobar=`ovs-vsctl get Bridge br-int datapath-type`])
-OVS_WAIT_UNTIL([check_datapath_type foobar])
-
-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}"
-])
-
-# Change the value of external_ids:system-id and make sure it's mirrored
-# in the Chassis record in the OVN_Southbound database.
-sysid=${sysid}-foo
-ovs-vsctl set Open_vSwitch . external-ids:system-id="${sysid}"
-OVS_WAIT_UNTIL([
-    chassis_id=$(ovn-sbctl get Chassis "${sysid}" name)
-    test "${sysid}" = "${chassis_id}"
-])
-
-# 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
-# With multi-VTEP support we support tunnels with different IPs to the
-# same chassis, and hence use the IP to annotate the tunnel (along with
-# the chassis-id in ovn-chassis-id); if we supply a different IP here
-# we won't be able to co-relate this to the tunnel port that was created
-# in the previous step and, as a result, will end up creating another tunnel,
-# ie. we can't just lookup using "ovn-fakech-0". So, need to use the same IP
-# as above, i.e 192.168.0.2, here.
-encap_uuid=$(ovn-sbctl add chassis fakechassis encaps @encap -- --id=@encap create encap type=geneve ip="192.168.0.2")
-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
-
-# Check ovn-controller connection status to Southbound database
-AT_SETUP([ovn-controller - check sbdb connection])
-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_sbdb_connection () {
-    test "$(ovs-appctl -t ovn-controller connection-status)" = "$1"
-}
-
-OVS_WAIT_UNTIL([check_sbdb_connection connected])
-
-ovs-vsctl set open . external_ids:ovn-remote=tcp:192.168.0.10:6642
-OVS_WAIT_UNTIL([check_sbdb_connection 'not connected'])
-
-# reset the remote for clean-up
-ovs-vsctl set open . external_ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock
-# Gracefully terminate daemons
-OVN_CLEANUP_SBOX([hv])
-OVN_CLEANUP_VSWITCH([main])
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-AT_CLEANUP
diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
deleted file mode 100644
index 7dba42c..0000000
--- a/tests/ovn-macros.at
+++ /dev/null
@@ -1,180 +0,0 @@
-# OVN_CLEANUP_VSWITCH(sim)
-#
-# Gracefully terminate vswitch daemons in the
-# specified sandbox.
-m4_define([OVN_CLEANUP_VSWITCH],[
-    as $1
-    OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
-    OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-])
-
-# OVN_CLEANUP_SBOX(sbox)
-#
-# Gracefully terminate OVN daemons in the specified
-# sandbox instance. The sandbox name "vtep" is treated
-# as a special case, and is assumed to have ovn-controller-vtep
-# and ovs-vtep daemons running instead of ovn-controller.
-m4_define([OVN_CLEANUP_SBOX],[
-    as $1
-    if test "$1" = "vtep"; then
-        OVS_APP_EXIT_AND_WAIT([ovn-controller-vtep])
-        OVS_APP_EXIT_AND_WAIT([ovs-vtep])
-    else
-        OVS_APP_EXIT_AND_WAIT([ovn-controller])
-    fi
-    OVN_CLEANUP_VSWITCH([$1])
-])
-
-# OVN_CLEANUP(sim [, sim ...])
-#
-# Gracefully terminate all OVN daemons, including those in the
-# specified sandbox instances.
-m4_define([OVN_CLEANUP],[
-    m4_foreach([sbox], [$@], [
-        OVN_CLEANUP_SBOX([sbox])
-    ])
-    as ovn-sb
-    OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-    as ovn-nb
-    OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-    as northd
-    OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-    as northd-backup
-    OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-    OVN_CLEANUP_VSWITCH([main])
-])
-
-m4_divert_push([PREPARE_TESTS])
-
-# ovn_init_db DATABASE
-#
-# Creates and initializes the given DATABASE (one of "ovn-sb" or "ovn-nb"),
-# starts its ovsdb-server instance, and sets the appropriate environment
-# variable (OVN_SB_DB or OVN_NB_DB) so that ovn-sbctl or ovn-nbctl uses the
-# database by default.
-#
-# Usually invoked from ovn_start.
-ovn_init_db () {
-    echo "creating $1 database"
-    local d=$ovs_base/$1
-    mkdir "$d" || return 1
-    : > "$d"/.$1.db.~lock~
-    as $1 ovsdb-tool create "$d"/$1.db "$abs_top_srcdir"/ovn/$1.ovsschema
-    as $1 start_daemon ovsdb-server --remote=punix:"$d"/$1.sock "$d"/$1.db
-    local var=`echo $1_db | tr a-z- A-Z_`
-    AS_VAR_SET([$var], [unix:$ovs_base/$1/$1.sock]); export $var
-}
-
-# ovn_start
-#
-# Creates and initializes ovn-sb and ovn-nb databases and starts their
-# ovsdb-server instance, sets appropriate environment variables so that
-# ovn-sbctl and ovn-nbctl use them by default, and starts ovn-northd running
-# against them.
-ovn_start () {
-    ovn_init_db ovn-sb; ovn-sbctl init
-    ovn_init_db ovn-nb; ovn-nbctl init
-
-    echo "starting ovn-northd"
-    mkdir "$ovs_base"/northd
-    as northd start_daemon ovn-northd -v \
-               --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
-               --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-
-    echo "starting backup ovn-northd"
-    mkdir "$ovs_base"/northd-backup
-    as northd-backup start_daemon ovn-northd -v \
-               --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
-               --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-}
-
-# Interconnection networks.
-#
-# When multiple sandboxed Open vSwitch instances exist, one will inevitably
-# want to connect them together.  These commands allow for that.  Conceptually,
-# an interconnection network is a switch for which these functions make it easy
-# to plug into other switches in other sandboxed Open vSwitch instances.
-# Interconnection networks are implemented as bridges in a switch named "main",
-# so to use interconnection networks please avoid working with that switch
-# directly.
-
-# net_add NETWORK
-#
-# Creates a new interconnection network named NETWORK.
-net_add () {
-    test -d "$ovs_base"/main || sim_add main || return 1
-    as main ovs-vsctl add-br "$1"
-}
-
-# net_attach NETWORK BRIDGE
-#
-# Adds a new port to BRIDGE in the default sandbox (as set with as()) and plugs
-# it into the NETWORK interconnection network.  NETWORK must already have been
-# created by a previous invocation of net_add.  The default sandbox must not be
-# "main".
-net_attach () {
-    local net=$1 bridge=$2
-
-    local port=${sandbox}_$bridge
-    as main ovs-vsctl \
-        -- add-port $net $port \
-        -- set Interface $port options:pstream="punix:$ovs_base/main/$port.sock" options:rxq_pcap="$ovs_base/main/$port-rx.pcap" options:tx_pcap="$ovs_base/main/$port-tx.pcap" \
-        || return 1
-
-    ovs-vsctl \
-        -- set Interface $bridge options:tx_pcap="$ovs_base/$sandbox/$bridge-tx.pcap" options:rxq_pcap="$ovs_base/$sandbox/$bridge-rx.pcap" \
-        -- add-port $bridge ${bridge}_$net \
-        -- set Interface ${bridge}_$net options:stream="unix:$ovs_base/main/$port.sock" options:rxq_pcap="$ovs_base/$sandbox/${bridge}_$net-rx.pcap" options:tx_pcap="$ovs_base/$sandbox/${bridge}_$net-tx.pcap" \
-        || return 1
-}
-
-# ovn_attach NETWORK BRIDGE IP [MASKLEN]
-#
-# First, this command attaches BRIDGE to interconnection network NETWORK, just
-# like "net_attach NETWORK BRIDGE".  Second, it configures (simulated) IP
-# address IP (with network mask length MASKLEN, which defaults to 24) on
-# BRIDGE.  Finally, it configures the Open vSwitch database to work with OVN
-# and starts ovn-controller.
-ovn_attach() {
-    local net=$1 bridge=$2 ip=$3 masklen=${4-24}
-    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
-    ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=$sandbox \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=$ip \
-        -- add-br br-int \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
-        || return 1
-    start_daemon ovn-controller || return 1
-}
-
-# OVN_POPULATE_ARP
-#
-# This pre-populates the ARP tables of all of the OVN instances that have been
-# started with ovn_attach().  That means that packets sent from one hypervisor
-# to another never get dropped or delayed by ARP resolution, which makes
-# testing easier.
-ovn_populate_arp__() {
-    for e1 in $arp_table; do
-        set `echo $e1 | sed 's/,/ /g'`; sb1=$1 br1=$2 ip=$3 mac=$4
-        for e2 in $arp_table; do
-            set `echo $e2 | sed 's/,/ /g'`; sb2=$1 br2=$2
-            if test $sb1,$br1 != $sb2,$br2; then
-                as $sb2 ovs-appctl tnl/neigh/set $br2 $ip $mac || return 1
-            fi
-        done
-    done
-}
-m4_divert_pop([PREPARE_TESTS])
-
-m4_define([OVN_POPULATE_ARP], [AT_CHECK(ovn_populate_arp__, [0], [ignore])])
diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
deleted file mode 100644
index d99d3af..0000000
--- a/tests/ovn-nbctl.at
+++ /dev/null
@@ -1,1660 +0,0 @@
-AT_BANNER([ovn-nbctl])
-
-OVS_START_SHELL_HELPERS
-# OVN_NBCTL_TEST_START
-m4_define([OVN_NBCTL_TEST_START],
-  [AT_KEYWORDS([ovn])
-   AT_CAPTURE_FILE([ovsdb-server.log])
-   ovn_nbctl_test_start $1])
-ovn_nbctl_test_start() {
-   dnl Create ovn-nb database.
-   AT_CHECK([ovsdb-tool create ovn-nb.db $abs_top_srcdir/ovn/ovn-nb.ovsschema])
-
-   dnl Start ovsdb-server.
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --log-file --remote=punix:$OVS_RUNDIR/ovnnb_db.sock ovn-nb.db], [0], [], [stderr])
-   on_exit "kill `cat ovsdb-server.pid`"
-   AS_CASE([$1],
-     [daemon],
-       [export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach --no-chdir --log-file -vsocket_util:off)
-        on_exit "kill `cat ovn-nbctl.pid`"],
-     [direct], [],
-     [*], [AT_FAIL_IF(:)])
-   AT_CHECK([ovn-nbctl init])
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d
-/ovsdb_server|INFO|ovsdb-server (Open vSwitch)/d']])
-}
-
-# OVN_NBCTL_TEST_STOP
-m4_define([OVN_NBCTL_TEST_STOP], [ovn_nbctl_test_stop])
-ovn_nbctl_test_stop() {
-   AT_CHECK([check_logs "$1"])
-   OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-}
-OVS_END_SHELL_HELPERS
-
-# OVN_NBCTL_TEST(NAME, TITLE, COMMANDS)
-m4_define([OVN_NBCTL_TEST],
-   [OVS_START_SHELL_HELPERS
-    $1() {
-      $3
-    }
-    OVS_END_SHELL_HELPERS
-
-    AT_SETUP([ovn-nbctl - $2 - direct])
-    OVN_NBCTL_TEST_START direct
-    $1
-    OVN_NBCTL_TEST_STOP
-    AT_CLEANUP
-
-    AT_SETUP([ovn-nbctl - $2 - daemon])
-    OVN_NBCTL_TEST_START daemon
-    $1
-    OVN_NBCTL_TEST_STOP
-    AT_CLEANUP])
-
-OVN_NBCTL_TEST([ovn_nbctl_basic_switch], [basic switch commands], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl ls-list | uuidfilt], [0], [dnl
-<0> (ls0)
-])
-
-AT_CHECK([ovn-nbctl ls-add ls1])
-AT_CHECK([ovn-nbctl ls-list | uuidfilt], [0], [dnl
-<0> (ls0)
-<1> (ls1)
-])
-
-AT_CHECK([ovn-nbctl ls-del ls0])
-AT_CHECK([ovn-nbctl ls-list | uuidfilt], [0], [dnl
-<0> (ls1)
-])
-
-AT_CHECK([ovn-nbctl show ls0])
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl show ls0 | uuidfilt], [0],
-  [switch <0> (ls0)
-])
-AT_CHECK([ovn-nbctl ls-add ls0], [1], [],
-  [ovn-nbctl: ls0: a switch with this name already exists
-])
-AT_CHECK([ovn-nbctl --may-exist ls-add ls0])
-AT_CHECK([ovn-nbctl show ls0 | uuidfilt], [0],
-  [switch <0> (ls0)
-])
-AT_CHECK([ovn-nbctl --add-duplicate ls-add ls0])
-AT_CHECK([ovn-nbctl --may-exist --add-duplicate ls-add ls0], [1], [],
-  [ovn-nbctl: --may-exist and --add-duplicate may not be used together
-])
-AT_CHECK([ovn-nbctl ls-del ls0], [1], [],
-  [ovn-nbctl: Multiple logical switches named 'ls0'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl ls-del ls2], [1], [],
-  [ovn-nbctl: ls2: switch name not found
-])
-AT_CHECK([ovn-nbctl --if-exists ls-del ls2])
-
-AT_CHECK([ovn-nbctl ls-add])
-AT_CHECK([ovn-nbctl ls-add])
-AT_CHECK([ovn-nbctl --add-duplicate ls-add], [1], [],
-  [ovn-nbctl: --add-duplicate requires specifying a name
-])
-AT_CHECK([ovn-nbctl --may-exist ls-add], [1], [],
-  [ovn-nbctl: --may-exist requires specifying a name
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_basic_lsp], [basic logical switch port commands], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0], [1], [],
-  [ovn-nbctl: lp0: a port with this name already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls0 lp0])
-AT_CHECK([ovn-nbctl lsp-list ls0 | uuidfilt], [0], [dnl
-<0> (lp0)
-])
-
-AT_CHECK([ovn-nbctl lsp-add ls0 lp1])
-AT_CHECK([ovn-nbctl lsp-list ls0 | uuidfilt], [0], [dnl
-<0> (lp0)
-<1> (lp1)
-])
-
-AT_CHECK([ovn-nbctl ls-add ls1])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp1], [1], [],
-  [ovn-nbctl: lp1: a port with this name already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls1 lp1], [1], [],
-  [ovn-nbctl: lp1: port already exists but in switch ls0
-])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls0 lp1 lp0 5], [1], [],
-  [ovn-nbctl: lp1: port already exists but has no parent
-])
-
-AT_CHECK([ovn-nbctl lsp-del lp1])
-AT_CHECK([ovn-nbctl lsp-list ls0 | uuidfilt], [0], [dnl
-<0> (lp0)
-])
-
-AT_CHECK([ovn-nbctl lsp-add ls0 lp2 lp3 5])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls0 lp2 lp4 5], [1], [],
-  [ovn-nbctl: lp2: port already exists with different parent lp3
-])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls0 lp2 lp3 10], [1], [],
-  [ovn-nbctl: lp2: port already exists with different tag_request 5
-])
-AT_CHECK([ovn-nbctl clear Logical_Switch_Port lp2 tag_request])
-AT_CHECK([ovn-nbctl --may-exist lsp-add ls0 lp2 lp3 5], [1], [],
-  [ovn-nbctl: lp2: port already exists but has no tag_request
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lsp_get_ls], [lsp get ls], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-
-AT_CHECK([ovn-nbctl lsp-get-ls lp0 | uuidfilt], [0], [dnl
-<0> (ls0)
-])
-
-AT_CHECK([ovn-nbctl lsp-get-ls lp1], [1], [],
-  [ovn-nbctl: lp1: port name not found
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lport_addresses], [lport addresses], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-AT_CHECK([ovn-nbctl lsp-get-addresses lp0], [0], [dnl
-])
-
-AT_CHECK([ovn-nbctl lsp-set-addresses lp0 00:11:22:33:44:55 unknown])
-AT_CHECK([ovn-nbctl lsp-get-addresses lp0], [0], [dnl
-00:11:22:33:44:55
-unknown
-])
-
-AT_CHECK([ovn-nbctl lsp-set-addresses lp0])
-AT_CHECK([ovn-nbctl lsp-get-addresses lp0], [0], [dnl
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_port_security], [port security], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-AT_CHECK([ovn-nbctl lsp-get-addresses lp0], [0], [dnl
-])
-
-AT_CHECK([ovn-nbctl lsp-set-port-security lp0 aa:bb:cc:dd:ee:ff 00:11:22:33:44:55])
-AT_CHECK([ovn-nbctl lsp-get-port-security lp0], [0], [dnl
-00:11:22:33:44:55
-aa:bb:cc:dd:ee:ff
-])
-
-AT_CHECK([ovn-nbctl lsp-set-port-security lp0])
-AT_CHECK([ovn-nbctl lsp-get-port-security lp0], [0], [dnl
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_acls], [ACLs], [
-ovn_nbctl_test_acl() {
-   AT_CHECK([ovn-nbctl $2 --log acl-add $1 from-lport 600 udp drop])
-   AT_CHECK([ovn-nbctl $2 --log --name=test --severity=info acl-add $1 to-lport 500 udp drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 from-lport 400 tcp drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 to-lport 300 tcp drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 from-lport 200 ip drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 to-lport 100 ip drop])
-   dnl Add duplicated ACL
-   AT_CHECK([ovn-nbctl $2 acl-add $1 to-lport 100 ip drop], [1], [], [stderr])
-   AT_CHECK([grep 'already existed' stderr], [0], [ignore])
-   AT_CHECK([ovn-nbctl $2 --may-exist acl-add $1 to-lport 100 ip drop])
-
-   AT_CHECK([ovn-nbctl $2 acl-list $1], [0], [dnl
-from-lport   600 (udp) drop log()
-from-lport   400 (tcp) drop
-from-lport   200 (ip) drop
-  to-lport   500 (udp) drop log(name=test,severity=info)
-  to-lport   300 (tcp) drop
-  to-lport   100 (ip) drop
-])
-
-   dnl Delete in one direction.
-   AT_CHECK([ovn-nbctl $2 acl-del $1 to-lport])
-   AT_CHECK([ovn-nbctl $2 acl-list $1], [0], [dnl
-from-lport   600 (udp) drop log()
-from-lport   400 (tcp) drop
-from-lport   200 (ip) drop
-])
-
-   dnl Delete all ACLs.
-   AT_CHECK([ovn-nbctl $2 acl-del $1])
-   AT_CHECK([ovn-nbctl $2 acl-list $1], [0], [dnl
-])
-
-   AT_CHECK([ovn-nbctl $2 acl-add $1 from-lport 600 udp drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 from-lport 400 tcp drop])
-   AT_CHECK([ovn-nbctl $2 acl-add $1 from-lport 200 ip drop])
-
-   dnl Delete a single flow.
-   AT_CHECK([ovn-nbctl $2 acl-del $1 from-lport 400 tcp])
-   AT_CHECK([ovn-nbctl $2 acl-list $1], [0], [dnl
-from-lport   600 (udp) drop
-from-lport   200 (ip) drop
-])
-}
-
-AT_CHECK([ovn-nbctl ls-add ls0])
-ovn_nbctl_test_acl ls0
-AT_CHECK([ovn-nbctl ls-add ls1])
-ovn_nbctl_test_acl ls1 --type=switch
-AT_CHECK([ovn-nbctl create port_group name=pg0], [0], [ignore])
-ovn_nbctl_test_acl pg0 --type=port-group
-
-dnl Test when port group doesn't exist
-AT_CHECK([ovn-nbctl --type=port-group acl-add pg1 to-lport 100 ip drop], [1], [], [dnl
-ovn-nbctl: pg1: port group name not found
-])
-
-dnl Test when same name exists in logical switches and portgroups
-AT_CHECK([ovn-nbctl create port_group name=ls0], [0], [ignore])
-AT_CHECK([ovn-nbctl acl-add ls0 to-lport 100 ip drop], [1], [], [stderr])
-AT_CHECK([grep 'exists in both' stderr], [0], [ignore])
-AT_CHECK([ovn-nbctl --type=port-group acl-add ls0 to-lport 100 ip drop], [0], [ignore])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_qos], [QoS], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 tcp dscp=63])
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 500 udp rate=100 burst=1000])
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 400 tcp dscp=0 rate=300 burst=3000])
-AT_CHECK([ovn-nbctl qos-add ls0 to-lport 300 tcp dscp=48])
-AT_CHECK([ovn-nbctl qos-add ls0 to-lport 200 ip rate=101])
-AT_CHECK([ovn-nbctl qos-add ls0 to-lport 100 ip4 dscp=13 rate=301 burst=30000])
-
-dnl Add duplicated qos
-AT_CHECK([ovn-nbctl qos-add ls0 to-lport 100 ip4 dscp=11 rate=302 burst=30002], [1], [], [stderr])
-AT_CHECK([grep 'already existed' stderr], [0], [ignore])
-AT_CHECK([ovn-nbctl --may-exist qos-add ls0 to-lport 100 ip4 dscp=11 rate=302 burst=30002])
-
-AT_CHECK([ovn-nbctl qos-list ls0], [0], [dnl
-from-lport   600 (tcp) dscp=63
-from-lport   500 (udp) rate=100 burst=1000
-from-lport   400 (tcp) rate=300 burst=3000 dscp=0
-  to-lport   300 (tcp) dscp=48
-  to-lport   200 (ip) rate=101
-  to-lport   100 (ip4) rate=301 burst=30000 dscp=13
-])
-
-dnl Delete in one direction.
-AT_CHECK([ovn-nbctl qos-del ls0 to-lport])
-AT_CHECK([ovn-nbctl qos-list ls0], [0], [dnl
-from-lport   600 (tcp) dscp=63
-from-lport   500 (udp) rate=100 burst=1000
-from-lport   400 (tcp) rate=300 burst=3000 dscp=0
-])
-
-dnl Delete all qos_rules.
-AT_CHECK([ovn-nbctl qos-del ls0])
-AT_CHECK([ovn-nbctl qos-list ls0], [0], [dnl
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip rate=1000101])
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 400 tcp dscp=44])
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 200 ip burst=1000102 rate=301 dscp=19])
-
-dnl Delete a single flow.
-AT_CHECK([ovn-nbctl qos-del ls0 from-lport 400 tcp])
-AT_CHECK([ovn-nbctl qos-list ls0], [0], [dnl
-from-lport   600 (ip) rate=1000101
-from-lport   200 (ip) rate=301 burst=1000102 dscp=19
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip rate=100010111111], [1], [],
-[ovn-nbctl: 100010111111: rate must be in the range 1...4294967295
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip burst=100010111112 rate=100010], [1], [],
-[ovn-nbctl: 100010111112: burst must be in the range 1...4294967295
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip dscp=-1], [1], [],
-[ovn-nbctl: -1: dscp must be in the range 0...63
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip dscpa=-1], [1], [],
-[ovn-nbctl: dscpa=-1: supported arguments are "dscp=", "rate=", and "burst="
-])
-
-AT_CHECK([ovn-nbctl qos-add ls0 from-lport 600 ip burst=123], [1], [],
-[ovn-nbctl: Either "rate" and/or "dscp" must be specified
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_meters], [meters], [
-AT_CHECK([ovn-nbctl meter-add meter1 drop 10 kbps])
-AT_CHECK([ovn-nbctl meter-add meter2 drop 3 kbps 2])
-AT_CHECK([ovn-nbctl meter-add meter3 drop 100 kbps 200])
-AT_CHECK([ovn-nbctl meter-add meter4 drop 10 pktps 30])
-
-dnl Add duplicate meter name
-AT_CHECK([ovn-nbctl meter-add meter1 drop 10 kbps], [1], [], [stderr])
-AT_CHECK([grep 'already exists' stderr], [0], [ignore])
-
-dnl Add reserved meter name
-AT_CHECK([ovn-nbctl meter-add __meter1 drop 10 kbps], [1], [], [stderr])
-AT_CHECK([grep 'reserved' stderr], [0], [ignore])
-
-dnl Add meter with invalid rates
-AT_CHECK([ovn-nbctl meter-add meter5 drop 100010111111 kbps], [1], [],
-[ovn-nbctl: rate must be in the range 1...4294967295
-])
-
-dnl Add meter with invalid rates
-AT_CHECK([ovn-nbctl meter-add meter5 drop 100010111111 foo], [1], [],
-[ovn-nbctl: rate must be in the range 1...4294967295
-])
-
-AT_CHECK([ovn-nbctl meter-add meter5 drop 0 kbps], [1], [],
-[ovn-nbctl: rate must be in the range 1...4294967295
-])
-
-dnl Add meter with invalid burst
-AT_CHECK([ovn-nbctl meter-add meter5 drop 10 100010111111 kbps], [1], [],
-[ovn-nbctl: unit must be "kbps" or "pktps"
-])
-
-AT_CHECK([ovn-nbctl meter-list], [0], [dnl
-meter1: bands:
-  drop: 10 kbps
-meter2: bands:
-  drop: 3 kbps, 2 kb burst
-meter3: bands:
-  drop: 100 kbps, 200 kb burst
-meter4: bands:
-  drop: 10 pktps, 30 packet burst
-])
-
-dnl Delete a single meter.
-AT_CHECK([ovn-nbctl meter-del meter2])
-AT_CHECK([ovn-nbctl meter-list], [0], [dnl
-meter1: bands:
-  drop: 10 kbps
-meter3: bands:
-  drop: 100 kbps, 200 kb burst
-meter4: bands:
-  drop: 10 pktps, 30 packet burst
-])
-
-dnl Delete all meters.
-AT_CHECK([ovn-nbctl meter-del])
-AT_CHECK([ovn-nbctl meter-list], [0], [dnl
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_nats], [NATs], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snatt 30.0.0.2 192.168.1.2], [1], [],
-[ovn-nbctl: snatt: type must be one of "dnat", "snat" and "dnat_and_snat".
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2a 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0.2a: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2/24 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0.2/24: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2:80 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0.2:80: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2a], [1], [],
-[ovn-nbctl: 192.168.1.2a: should be an IPv4 address or network.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1], [1], [],
-[ovn-nbctl: 192.168.1: should be an IPv4 address or network.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2:80], [1], [],
-[ovn-nbctl: 192.168.1.2:80: should be an IPv4 address or network.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2/a], [1], [],
-[ovn-nbctl: 192.168.1.2/a: should be an IPv4 address or network.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2a], [1], [],
-[ovn-nbctl: 192.168.1.2a: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1], [1], [],
-[ovn-nbctl: 192.168.1: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2:80], [1], [],
-[ovn-nbctl: 192.168.1.2:80: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2/24], [1], [],
-[ovn-nbctl: 192.168.1.2/24: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2/24], [1], [],
-[ovn-nbctl: 192.168.1.2/24: should be an IPv4 address.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2 lp0], [1], [],
-[ovn-nbctl: lr-nat-add with logical_port must also specify external_mac.
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.2 192.168.1.2 lp0 00:00:00:01:02:03], [1], [],
-[ovn-nbctl: logical_port and external_mac are only valid when type is "dnat_and_snat".
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.2 lp0 00:00:00:01:02:03], [1], [],
-[ovn-nbctl: logical_port and external_mac are only valid when type is "dnat_and_snat".
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2 lp0 00:00:00:01:02:03], [1], [],
-[ovn-nbctl: lp0: port name not found
-])
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.2 lp0 00:00:00:01:02], [1], [],
-[ovn-nbctl: invalid mac address 00:00:00:01:02.
-])
-
-dnl Add snat and dnat
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.1 192.168.1.2])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.2])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3 lp0 00:00:00:01:02:03])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl
-TYPE             EXTERNAL_IP        LOGICAL_IP            EXTERNAL_MAC         LOGICAL_PORT
-dnat             30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.2           192.168.1.3           00:00:00:01:02:03    lp0
-snat             30.0.0.1           192.168.1.0/24
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24], [1], [],
-[ovn-nbctl: 30.0.0.1, 192.168.1.0/24: a NAT with this external_ip and logical_ip already exists
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.10/24], [1], [],
-[ovn-nbctl: 30.0.0.1, 192.168.1.0/24: a NAT with this external_ip and logical_ip already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.0/24], [1], [],
-[ovn-nbctl: a NAT with this type (snat) and logical_ip (192.168.1.0/24) already exists
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.1 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0.1, 192.168.1.2: a NAT with this external_ip and logical_ip already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat 30.0.0.1 192.168.1.2])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 30.0.0.1 192.168.1.3], [1], [],
-[ovn-nbctl: a NAT with this type (dnat) and external_ip (30.0.0.1) already exists
-])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.2], [1], [],
-[ovn-nbctl: 30.0.0.1, 192.168.1.2: a NAT with this external_ip and logical_ip already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.2])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 30.0.0.1 192.168.1.3], [1], [],
-[ovn-nbctl: a NAT with this type (dnat_and_snat) and external_ip (30.0.0.1) already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3 lp0 00:00:00:04:05:06])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl
-TYPE             EXTERNAL_IP        LOGICAL_IP            EXTERNAL_MAC         LOGICAL_PORT
-dnat             30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.2           192.168.1.3           00:00:00:04:05:06    lp0
-snat             30.0.0.1           192.168.1.0/24
-])
-AT_CHECK([ovn-nbctl --may-exist lr-nat-add lr0 dnat_and_snat 30.0.0.2 192.168.1.3])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl
-TYPE             EXTERNAL_IP        LOGICAL_IP            EXTERNAL_MAC         LOGICAL_PORT
-dnat             30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.2           192.168.1.3
-snat             30.0.0.1           192.168.1.0/24
-])
-
-dnl Deletes the NATs
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.3], [1], [],
-[ovn-nbctl: no matching NAT with the type (dnat_and_snat) and external_ip (30.0.0.3)
-])
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat 30.0.0.2], [1], [],
-[ovn-nbctl: no matching NAT with the type (dnat) and external_ip (30.0.0.2)
-])
-AT_CHECK([ovn-nbctl lr-nat-del lr0 snat 192.168.10.0/24], [1], [],
-[ovn-nbctl: no matching NAT with the type (snat) and logical_ip (192.168.10.0/24)
-])
-AT_CHECK([ovn-nbctl --if-exists lr-nat-del lr0 snat 192.168.10.0/24])
-
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.1])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl
-TYPE             EXTERNAL_IP        LOGICAL_IP            EXTERNAL_MAC         LOGICAL_PORT
-dnat             30.0.0.1           192.168.1.2
-dnat_and_snat    30.0.0.2           192.168.1.3
-snat             30.0.0.1           192.168.1.0/24
-])
-
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [dnl
-TYPE             EXTERNAL_IP        LOGICAL_IP            EXTERNAL_MAC         LOGICAL_PORT
-dnat_and_snat    30.0.0.2           192.168.1.3
-snat             30.0.0.1           192.168.1.0/24
-])
-
-AT_CHECK([ovn-nbctl lr-nat-del lr0])
-AT_CHECK([ovn-nbctl lr-nat-list lr0], [0], [])
-AT_CHECK([ovn-nbctl lr-nat-del lr0])
-AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lbs], [LBs], [
-dnl Add two LBs.
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:80a 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: 30.0.0.10:80a: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:a80 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: 30.0.0.10:a80: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20 tcp], [1], [],
-[ovn-nbctl: 192.168.10.20: should be an IP address and a port number with : as a separator.
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.1a 192.168.10.10:80,192.168.10.20:80], [1], [],
-[ovn-nbctl: 30.0.0.1a: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0 192.168.10.10:80,192.168.10.20:80], [1], [],
-[ovn-nbctl: 30.0.0: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10,192.168.10.20:80], [1], [],
-[ovn-nbctl: 192.168.10.20:80: should be an IP address.
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10:a80], [1], [],
-[ovn-nbctl: 192.168.10.10:a80: should be an IP address.
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.10:], [1], [],
-[ovn-nbctl: 192.168.10.10:: should be an IP address.
-])
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 30.0.0.10 192.168.10.1a], [1], [],
-[ovn-nbctl: 192.168.10.1a: should be an IP address.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10: 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 192.168.10.10:900 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-dnl Add ips to lb
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 ,,,192.168.10.10:80,,,,,])
-AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 ,,,192.168.10.10:80,,,,192.168.10.20:80,,,,])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80
-<1>    lb1                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-])
-AT_CHECK([ovn-nbctl lb-del lb0])
-AT_CHECK([ovn-nbctl lb-del lb1])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80])
-AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80 tcp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-])
-
-dnl Update the VIP of the lb1.
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:8080
-])
-
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:8080 udp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:8080
-])
-
-dnl Config lb1 with another VIP.
-AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.20:80 192.168.10.10:80 udp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:8080
-                                                            udp        30.0.0.20:80    192.168.10.10:80
-])
-
-AT_CHECK([ovn-nbctl lb-del lb1 30.0.0.20:80])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:8080
-])
-
-dnl Add LBs whose vip is just an IP address.
-AT_CHECK([ovn-nbctl lb-add lb2 30.0.0.30 192.168.10.10])
-AT_CHECK([ovn-nbctl lb-add lb3 30.0.0.30 192.168.10.10])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:8080
-<2>    lb2                 tcp/udp    30.0.0.30       192.168.10.10
-<3>    lb3                 tcp/udp    30.0.0.30       192.168.10.10
-])
-AT_CHECK([ovn-nbctl lb-del lb2 30.0.0.30])
-AT_CHECK([ovn-nbctl lb-del lb3 30.0.0.30])
-
-AT_CHECK([ovn-nbctl lb-add lb2 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80 tcp])
-AT_CHECK([ovn-nbctl --add-duplicate lb-add lb2 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80 tcp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP               IPs
-<0>    lb0                 tcp        30.0.0.10:80      192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80      192.168.10.10:80,192.168.10.20:8080
-<2>    lb2                 tcp        30.0.0.10:8080    192.168.10.10:80,192.168.10.20:80
-<3>    lb2                 tcp        30.0.0.10:8080    192.168.10.10:80,192.168.10.20:80
-])
-
-dnl If there are multiple load balancers with the same name, use a UUID to update/delete.
-AT_CHECK([ovn-nbctl lb-add lb2 30.0.0.10:8080 192.168.10.10:80,192.168.10.20:80 tcp], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl lb-del lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80 192.168.10.10:8080,192.168.10.20:8080 udp])
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:8080 192.168.10.10:8080,192.168.10.20:8080 udp])
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:9090 192.168.10.10:8080,192.168.10.20:8080 udp])
-AT_CHECK([ovn-nbctl lb-del lb0 30.0.0.10:80])
-AT_CHECK([ovn-nbctl lb-del lb1])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP               IPs
-<0>    lb2                 tcp        30.0.0.10:8080    192.168.10.10:80,192.168.10.20:80
-<1>    lb2                 tcp        30.0.0.10:8080    192.168.10.10:80,192.168.10.20:80
-])
-
-dnl Add load balancer to logical switch.
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80])
-AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 192.168.10.10:80,192.168.10.20:80 udp])
-AT_CHECK([ovn-nbctl lb-add lb3 30.0.0.10 192.168.10.10,192.168.10.20])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl --may-exist ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
-
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<2>    lb3                 tcp/udp    30.0.0.10       192.168.10.10,192.168.10.20
-])
-
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb3                 tcp/udp    30.0.0.10       192.168.10.10,192.168.10.20
-])
-
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb3])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [])
-AT_CHECK([ovn-nbctl --if-exists ls-lb-del ls0 lb1])
-
-dnl Remove all load balancers from logical switch.
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
-AT_CHECK([ovn-nbctl ls-lb-del ls0])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [])
-
-dnl Add load balancer to logical router.
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl --may-exist lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
-
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb0                 tcp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<2>    lb3                 tcp/udp    30.0.0.10       192.168.10.10,192.168.10.20
-])
-
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP             IPs
-<0>    lb1                 udp        30.0.0.10:80    192.168.10.10:80,192.168.10.20:80
-<1>    lb3                 tcp/udp    30.0.0.10       192.168.10.10,192.168.10.20
-])
-
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb3])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [])
-AT_CHECK([ovn-nbctl --if-exists lr-lb-del lr0 lb1])
-
-dnl Remove all load balancers from logical router.
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
-AT_CHECK([ovn-nbctl lr-lb-del lr0])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [])
-
-dnl Remove load balancers after adding them to a logical router/switch.
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl lb-del lb0])
-AT_CHECK([ovn-nbctl lb-del lb1])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lbs_ipv6], [LBs IPv6], [
-dnl A bunch of commands that should fail
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:80a [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
-[ovn-nbctl: [[ae0f::10]]:80a: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:a80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
-[ovn-nbctl: [[ae0f::10]]:a80: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,fd0f::20 tcp], [1], [],
-[ovn-nbctl: fd0f::20: should be an IP address and a port number with : as a separator.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10fff [[fd0f::10]]:80,fd0f::20 tcp], [1], [],
-[ovn-nbctl: ae0f::10fff: should be an IP address (or an IP address and a port number with : as a separator).
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:80,[[fd0f::20]]:80], [1], [],
-[ovn-nbctl: [[fd0f::10]]:80: should be an IP address.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 fd0f::10,[[fd0f::20]]:80], [1], [],
-[ovn-nbctl: [[fd0f::20]]:80: should be an IP address.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:a80], [1], [],
-[ovn-nbctl: [[fd0f::10]]:a80: should be an IP address.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 [[fd0f::10]]:], [1], [],
-[ovn-nbctl: [[fd0f::10]]:: should be an IP address.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 ae0f::10 fd0f::1001a], [1], [],
-[ovn-nbctl: fd0f::1001a: should be an IP address.
-])
-
-
-AT_CHECK([ovn-nbctl -vsocket_util:off lb-add lb0 [[ae0f::10]]: [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 [[fd0f::10]]:900 tcp], [1], [],
-[ovn-nbctl: Protocol is unnecessary when no port of vip is given.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 192.168.10.10], [1], [],
-[ovn-nbctl: 192.168.10.10: IP address family is different from VIP ae0f::10.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 192.168.10.10], [1], [],
-[ovn-nbctl: 192.168.10.10: IP address family is different from VIP ae0f::10.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 192.168.10.10:80], [1], [],
-[ovn-nbctl: 192.168.10.10:80: IP address family is different from VIP [[ae0f::10]]:80.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10 ae0f::10], [1], [],
-[ovn-nbctl: ae0f::10: IP address family is different from VIP 30.0.0.10.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 30.0.0.10:80 [[ae0f::10]]:80], [1], [],
-[ovn-nbctl: [[ae0f::10]]:80: IP address family is different from VIP 30.0.0.10:80.
-])
-
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f::10 fd0f::10])
-AT_CHECK([ovn-nbctl lb-add lb0 ae0f:0000:0000:0000:0000:0000:0000:0010 fd0f::20],
-[1], [], [ovn-nbctl: lb0: a load balancer with this vip (ae0f::10) already exists
-])
-
-AT_CHECK([ovn-nbctl lb-del lb0])
-
-dnl Add ips to lb
-AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 ,,,[[fd0f::10]]:80,,,,,])
-AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 ,,,[[fd0f::10]]:80,,,,[[fd0f::20]]:80,,,,])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80
-<1>    lb1                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-])
-AT_CHECK([ovn-nbctl lb-del lb0])
-AT_CHECK([ovn-nbctl lb-del lb1])
-
-
-AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80])
-AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-])
-
-dnl Update the VIP of the lb1.
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:8080
-])
-
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:8080 udp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:8080
-])
-
-dnl Config lb1 with another VIP.
-AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::20]]:80 [[fd0f::10]]:80 udp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:8080
-                                                            udp        [[ae0f::20]]:80    [[fd0f::10]]:80
-])
-
-AT_CHECK([ovn-nbctl lb-del lb1 [[ae0f::20]]:80])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:8080
-])
-
-dnl Add LBs whose vip is just an IP address.
-AT_CHECK([ovn-nbctl lb-add lb2 ae0f::30 fd0f::10])
-AT_CHECK([ovn-nbctl lb-add lb3 ae0f::30 fd0f::10])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:8080
-<2>    lb2                 tcp/udp    ae0f::30         fd0f::10
-<3>    lb3                 tcp/udp    ae0f::30         fd0f::10
-])
-AT_CHECK([ovn-nbctl lb-del lb2 ae0f::30])
-AT_CHECK([ovn-nbctl lb-del lb3 ae0f::30])
-
-AT_CHECK([ovn-nbctl lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
-AT_CHECK([ovn-nbctl --add-duplicate lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP                IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80      [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80      [[fd0f::10]]:80,[[fd0f::20]]:8080
-<2>    lb2                 tcp        [[ae0f::10]]:8080    [[fd0f::10]]:80,[[fd0f::20]]:80
-<3>    lb2                 tcp        [[ae0f::10]]:8080    [[fd0f::10]]:80,[[fd0f::20]]:80
-])
-
-dnl If there are multiple load balancers with the same name, use a UUID to update/delete.
-AT_CHECK([ovn-nbctl lb-add lb2 [[ae0f::10]]:8080 [[fd0f::10]]:80,[[fd0f::20]]:80 tcp], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl lb-del lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:8080 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
-AT_CHECK([ovn-nbctl --may-exist lb-add lb1 [[ae0f::10]]:9090 [[fd0f::10]]:8080,[[fd0f::20]]:8080 udp])
-AT_CHECK([ovn-nbctl lb-del lb0 [[ae0f::10]]:80])
-AT_CHECK([ovn-nbctl lb-del lb1])
-AT_CHECK([ovn-nbctl lb-list | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP                IPs
-<0>    lb2                 tcp        [[ae0f::10]]:8080    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb2                 tcp        [[ae0f::10]]:8080    [[fd0f::10]]:80,[[fd0f::20]]:80
-])
-
-dnl Add load balancer to logical switch.
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lb-add lb0 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80])
-AT_CHECK([ovn-nbctl lb-add lb1 [[ae0f::10]]:80 [[fd0f::10]]:80,[[fd0f::20]]:80 udp])
-AT_CHECK([ovn-nbctl lb-add lb3 ae0f::10 fd0f::10,fd0f::20])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl --may-exist ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
-
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<2>    lb3                 tcp/udp    ae0f::10         fd0f::10,fd0f::20
-])
-
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb3                 tcp/udp    ae0f::10         fd0f::10,fd0f::20
-])
-
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-del ls0 lb3])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [])
-AT_CHECK([ovn-nbctl --if-exists ls-lb-del ls0 lb1])
-
-dnl Remove all load balancers from logical switch.
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb0])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb1])
-AT_CHECK([ovn-nbctl ls-lb-add ls0 lb3])
-AT_CHECK([ovn-nbctl ls-lb-del ls0])
-AT_CHECK([ovn-nbctl ls-lb-list ls0 | uuidfilt], [0], [])
-
-dnl Add load balancer to logical router.
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl --may-exist lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb2], [1], [],
-[ovn-nbctl: Multiple load balancers named 'lb2'.  Use a UUID.
-])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
-
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb0                 tcp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<2>    lb3                 tcp/udp    ae0f::10         fd0f::10,fd0f::20
-])
-
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [dnl
-UUID                                    LB                  PROTO      VIP              IPs
-<0>    lb1                 udp        [[ae0f::10]]:80    [[fd0f::10]]:80,[[fd0f::20]]:80
-<1>    lb3                 tcp/udp    ae0f::10         fd0f::10,fd0f::20
-])
-
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-del lr0 lb3])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [])
-AT_CHECK([ovn-nbctl --if-exists lr-lb-del lr0 lb1])
-
-dnl Remove all load balancers from logical router.
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb3])
-AT_CHECK([ovn-nbctl lr-lb-del lr0])
-AT_CHECK([ovn-nbctl lr-lb-list lr0 | uuidfilt], [0], [])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_basic_lr], [basic logical router commands], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lr-list | uuidfilt], [0], [dnl
-<0> (lr0)
-])
-
-AT_CHECK([ovn-nbctl lr-add lr1])
-AT_CHECK([ovn-nbctl lr-list | uuidfilt], [0], [dnl
-<0> (lr0)
-<1> (lr1)
-])
-
-AT_CHECK([ovn-nbctl lr-del lr0])
-AT_CHECK([ovn-nbctl lr-list | uuidfilt], [0], [dnl
-<0> (lr1)
-])
-
-AT_CHECK([ovn-nbctl show lr0])
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl show lr0 | uuidfilt], [0],
-  [router <0> (lr0)
-])
-AT_CHECK([ovn-nbctl lr-add lr0], [1], [],
-  [ovn-nbctl: lr0: a router with this name already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lr-add lr0])
-AT_CHECK([ovn-nbctl show lr0 | uuidfilt], [0],
-  [router <0> (lr0)
-])
-AT_CHECK([ovn-nbctl --add-duplicate lr-add lr0])
-AT_CHECK([ovn-nbctl --may-exist --add-duplicate lr-add lr0], [1], [],
-  [ovn-nbctl: --may-exist and --add-duplicate may not be used together
-])
-AT_CHECK([ovn-nbctl lr-del lr0], [1], [],
-  [ovn-nbctl: Multiple logical routers named 'lr0'.  Use a UUID.
-])
-
-AT_CHECK([ovn-nbctl lr-del lr2], [1], [],
-  [ovn-nbctl: lr2: router name not found
-])
-AT_CHECK([ovn-nbctl --if-exists lr-del lr2])
-
-AT_CHECK([ovn-nbctl lr-add])
-AT_CHECK([ovn-nbctl lr-add])
-AT_CHECK([ovn-nbctl --add-duplicate lr-add], [1], [],
-  [ovn-nbctl: --add-duplicate requires specifying a name
-])
-AT_CHECK([ovn-nbctl --may-exist lr-add], [1], [],
-  [ovn-nbctl: --may-exist requires specifying a name
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_basic_lrp], [basic logical router port commands], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp0: invalid mac address 00:00:00:01:02
-])
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03:04 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp0: invalid mac address 00:00:00:01:02:03:04
-])
-
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
-
-AT_CHECK([ovn-nbctl show lr0 | uuidfilt], [0], [dnl
-router <0> (lr0)
-    port lrp0
-        mac: "00:00:00:01:02:03"
-        networks: [["192.168.1.1/24"]]
-])
-
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp0: a port with this name already exists
-])
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
-AT_CHECK([ovn-nbctl lrp-list lr0 | uuidfilt], [0], [dnl
-<0> (lrp0)
-])
-
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24 peer=lrp1-peer])
-AT_CHECK([ovn-nbctl lrp-list lr0 | uuidfilt], [0], [dnl
-<0> (lrp0)
-<1> (lrp1)
-])
-
-AT_CHECK([ovn-nbctl lr-add lr1])
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp1: a port with this name already exists
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr1 lrp1 00:00:00:01:02:03 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp1: port already exists but in router lr0
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:04:05:06 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp1: port already exists with mac 00:00:00:01:02:03
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24], [1], [],
-  [ovn-nbctl: lrp1: port already exists with mismatching peer
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 10.0.0.1/24 peer=lrp1-peer], [1], [],
-  [ovn-nbctl: lrp1: port already exists with different network
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24 peer=lrp1-peer])
-
-AT_CHECK([ovn-nbctl lrp-del lrp1])
-AT_CHECK([ovn-nbctl lrp-list lr0 | uuidfilt], [0], [dnl
-<0> (lrp0)
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24 10.0.0.1/24 peer=lrp1-peer])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 192.168.1.1/24 172.16.0.1/24 peer=lrp1-peer], [1], [],
-  [ovn-nbctl: lrp1: port already exists with different network
-])
-
-AT_CHECK([ovn-nbctl --may-exist lrp-add lr0 lrp1 00:00:00:01:02:03 10.0.0.1/24 192.168.1.1/24 peer=lrp1-peer])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lrp_gw_chassi], [logical router port gateway chassis], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [])
-
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lp0 chassis1], [1], [],
-[ovn-nbctl: lp0: port name not found
-])
-
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lp0], [1], [],
-[ovn-nbctl: lp0: port name not found
-])
-
-AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lp0 chassis1], [1], [],
-[ovn-nbctl: lp0: port name not found
-])
-
-AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis1], [1], [],
-[ovn-nbctl: chassis chassis1 is not added to logical port lrp0
-])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1])
-
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis1     0
-])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1 10])
-
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis1    10
-])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1 20])
-
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis1    20
-])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis2 5])
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis1    20
-lrp0-chassis2     5
-])
-
-AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis1])
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis2     5
-])
-
-AT_CHECK([ovn-nbctl lrp-del-gateway-chassis lrp0 chassis2])
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0])
-
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis1 1])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis2 10])
-AT_CHECK([ovn-nbctl lrp-set-gateway-chassis lrp0 chassis3 5])
-AT_CHECK([ovn-nbctl lrp-get-gateway-chassis lrp0], [0], [dnl
-lrp0-chassis2    10
-lrp0-chassis3     5
-lrp0-chassis1     1
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lrp_enable], [logical router port enable and disable], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03 192.168.1.1/24])
-AT_CHECK([ovn-nbctl lrp-get-enabled lrp0], [0], [enabled
-])
-
-AT_CHECK([ovn-nbctl lrp-set-enabled lrp0 disabled])
-AT_CHECK([ovn-nbctl lrp-get-enabled lrp0], [0], [disabled
-])
-
-AT_CHECK([ovn-nbctl lrp-set-enabled lrp0 enabled])
-AT_CHECK([ovn-nbctl lrp-get-enabled lrp0], [0], [enabled
-])
-
-AT_CHECK([ovn-nbctl lrp-set-enabled lrp0 xyzzy], [1], [],
-  [ovn-nbctl: xyzzy: state must be "enabled" or "disabled"
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_routes], [routes], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-
-dnl Check IPv4 routes
-AT_CHECK([ovn-nbctl lr-route-add lr0 0.0.0.0/0 192.168.0.1])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.1.0/24 11.0.1.1 lp0])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.1/24 11.0.0.2])
-
-dnl Add overlapping route with 10.0.0.1/24
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24 11.0.0.1], [1], [],
-  [ovn-nbctl: duplicate prefix: 10.0.0.0/24
-])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111a/24 11.0.0.1], [1], [],
-  [ovn-nbctl: bad prefix argument: 10.0.0.111a/24
-])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24a 11.0.0.1], [1], [],
-  [ovn-nbctl: bad prefix argument: 10.0.0.111/24a
-])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24 11.0.0.1a], [1], [],
-  [ovn-nbctl: bad next hop argument: 11.0.0.1a
-])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24 11.0.0.1/24], [1], [],
-  [ovn-nbctl: bad IPv4 nexthop argument: 11.0.0.1/24
-])
-AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1/64], [1], [],
-  [ovn-nbctl: bad IPv6 nexthop argument: 2001:0db8:0:f103::1/64
-])
-
-AT_CHECK([ovn-nbctl --may-exist lr-route-add lr0 10.0.0.111/24 11.0.0.1])
-AT_CHECK([ovn-nbctl --policy=src-ip lr-route-add lr0 9.16.1.0/24 11.0.0.1])
-
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv4 Routes
-              10.0.0.0/24                  11.0.0.1 dst-ip
-              10.0.1.0/24                  11.0.1.1 dst-ip lp0
-              9.16.1.0/24                  11.0.0.1 src-ip
-                0.0.0.0/0               192.168.0.1 dst-ip
-])
-
-AT_CHECK([ovn-nbctl --may-exist lr-route-add lr0 10.0.0.111/24 11.0.0.1 lp1])
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv4 Routes
-              10.0.0.0/24                  11.0.0.1 dst-ip lp1
-              10.0.1.0/24                  11.0.1.1 dst-ip lp0
-              9.16.1.0/24                  11.0.0.1 src-ip
-                0.0.0.0/0               192.168.0.1 dst-ip
-])
-
-dnl Delete non-existent prefix
-AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.2.1/24], [1], [],
-  [ovn-nbctl: no matching prefix: 10.0.2.0/24
-])
-AT_CHECK([ovn-nbctl --if-exists lr-route-del lr0 10.0.2.1/24])
-
-AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.1.1/24])
-AT_CHECK([ovn-nbctl lr-route-del lr0 9.16.1.0/24])
-
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv4 Routes
-              10.0.0.0/24                  11.0.0.1 dst-ip lp1
-                0.0.0.0/0               192.168.0.1 dst-ip
-])
-
-AT_CHECK([ovn-nbctl lr-route-del lr0])
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-])
-
-dnl Check IPv6 routes
-AT_CHECK([ovn-nbctl lr-route-add lr0 0:0:0:0:0:0:0:0/0 2001:0db8:0:f101::1])
-AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:0::/64 2001:0db8:0:f102::1 lp0])
-AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1])
-
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv6 Routes
-            2001:db8::/64        2001:db8:0:f102::1 dst-ip lp0
-          2001:db8:1::/64        2001:db8:0:f103::1 dst-ip
-                     ::/0        2001:db8:0:f101::1 dst-ip
-])
-
-AT_CHECK([ovn-nbctl lr-route-del lr0 2001:0db8:0::/64])
-
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv6 Routes
-          2001:db8:1::/64        2001:db8:0:f103::1 dst-ip
-                     ::/0        2001:db8:0:f101::1 dst-ip
-])
-
-AT_CHECK([ovn-nbctl lr-route-del lr0])
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-])
-
-dnl Check IPv4 and IPv6 routes
-AT_CHECK([ovn-nbctl lr-route-add lr0 0.0.0.0/0 192.168.0.1])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.1.1/24 11.0.1.1 lp0])
-AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.1/24 11.0.0.1])
-AT_CHECK([ovn-nbctl lr-route-add lr0 0:0:0:0:0:0:0:0/0 2001:0db8:0:f101::1])
-AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:0::/64 2001:0db8:0:f102::1 lp0])
-AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1])
-
-AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
-IPv4 Routes
-              10.0.0.0/24                  11.0.0.1 dst-ip
-              10.0.1.0/24                  11.0.1.1 dst-ip lp0
-                0.0.0.0/0               192.168.0.1 dst-ip
-
-IPv6 Routes
-            2001:db8::/64        2001:db8:0:f102::1 dst-ip lp0
-          2001:db8:1::/64        2001:db8:0:f103::1 dst-ip
-                     ::/0        2001:db8:0:f101::1 dst-ip
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_policies], [policies], [
-AT_CHECK([ovn-nbctl lr-add lr0])
-
-dnl Add policies with allow and drop actions
-AT_CHECK([ovn-nbctl lr-policy-add lr0 100 "ip4.src == 1.1.1.0/24" drop])
-AT_CHECK([ovn-nbctl lr-policy-add lr0 100 "ip4.src == 1.1.2.0/24" allow])
-AT_CHECK([ovn-nbctl lr-policy-add lr0 101 "ip4.src == 2.1.1.0/24" allow])
-AT_CHECK([ovn-nbctl lr-policy-add lr0 101 "ip4.src == 2.1.2.0/24" drop])
-AT_CHECK([ovn-nbctl lr-policy-add lr0 101 "ip6.src == 2002::/64" drop])
-
-dnl Add duplicated policy
-AT_CHECK([ovn-nbctl lr-policy-add lr0 100 "ip4.src == 1.1.1.0/24" drop], [1], [],
-  [ovn-nbctl: Same routing policy already existed on the logical router lr0.
-])
-
-dnl Add duplicated policy
-AT_CHECK([ovn-nbctl lr-policy-add lr0 103 "ip4.src == 1.1.1.0/24" deny], [1], [],
-  [ovn-nbctl: deny: action must be one of "allow", "drop", and "reroute"
-])
-
-dnl Delete by priority and match string
-AT_CHECK([ovn-nbctl lr-policy-del lr0 100 "ip4.src == 1.1.1.0/24"])
-AT_CHECK([ovn-nbctl lr-policy-list lr0], [0], [dnl
-Routing Policies
-       101                              ip4.src == 2.1.1.0/24           allow
-       101                              ip4.src == 2.1.2.0/24            drop
-       101                               ip6.src == 2002::/64            drop
-       100                              ip4.src == 1.1.2.0/24           allow
-])
-
-dnl Delete all policies for given priority
-AT_CHECK([ovn-nbctl lr-policy-del lr0 101])
-AT_CHECK([ovn-nbctl lr-policy-list lr0], [0], [dnl
-Routing Policies
-       100                              ip4.src == 1.1.2.0/24           allow
-])
-
-dnl Add policy with reroute action
-AT_CHECK([ovn-nbctl lr-policy-add lr0 102 "ip4.src == 3.1.2.0/24" reroute 3.3.3.3])
-
-dnl Add policy with invalid reroute ip
-AT_CHECK([ovn-nbctl lr-policy-add lr0 103 "ip4.src == 3.1.2.0/24" reroute 3.3.3.x], [1], [],
-  [ovn-nbctl: bad next hop argument: 3.3.3.x
-])
-
-dnl Add policy with reroute action
-AT_CHECK([ovn-nbctl lr-policy-add lr0 104 "ip6.src == 2001::/64" reroute 2002::5])
-
-dnl Add policy with invalid reroute ip
-AT_CHECK([ovn-nbctl lr-policy-add lr0 105 "ip6.src == 2001::/64" reroute 2002::x], [1], [],
-  [ovn-nbctl: bad next hop argument: 2002::x
-])
-
-])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_lsp_types], [lsp types], [
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 lp0])
-
-dnl switchport type defaults to empty
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-
-])
-
-dnl The following are the valid entries for
-dnl switchport type
-AT_CHECK([ovn-nbctl lsp-set-type lp0 l2gateway])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-l2gateway
-])
-
-AT_CHECK([ovn-nbctl lsp-set-type lp0 router])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-router
-])
-
-AT_CHECK([ovn-nbctl lsp-set-type lp0 localnet])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-localnet
-])
-
-AT_CHECK([ovn-nbctl lsp-set-type lp0 localport])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-localport
-])
-
-AT_CHECK([ovn-nbctl lsp-set-type lp0 vtep])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-vtep
-])
-
-dnl All of these are valid southbound port types but
-dnl should be rejected for northbound logical switch
-dnl ports.
-AT_CHECK([ovn-nbctl lsp-set-type lp0 l3gateway], [1], [], [dnl
-ovn-nbctl: Logical switch port type 'l3gateway' is unrecognized. Not setting type.
-])
-AT_CHECK([ovn-nbctl lsp-set-type lp0 patch], [1], [], [dnl
-ovn-nbctl: Logical switch port type 'patch' is unrecognized. Not setting type.
-])
-AT_CHECK([ovn-nbctl lsp-set-type lp0 chassisredirect], [1], [], [dnl
-ovn-nbctl: Logical switch port type 'chassisredirect' is unrecognized. Not setting type.
-])
-
-dnl switch port type should still be "vtep" since previous
-dnl commands failed.
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-vtep
-])
-
-dnl Attempt a nonsense type
-AT_CHECK([ovn-nbctl lsp-set-type lp0 eggs], [1], [], [dnl
-ovn-nbctl: Logical switch port type 'eggs' is unrecognized. Not setting type.
-])
-
-dnl Empty string should work too
-AT_CHECK([ovn-nbctl lsp-set-type lp0 ""])
-AT_CHECK([ovn-nbctl lsp-get-type lp0], [0], [dnl
-
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_connection], [connection], [
-AT_CHECK([ovn-nbctl --inactivity-probe=30000 set-connection ptcp:6641:127.0.0.1 punix:$OVS_RUNDIR/ovnnb_db.sock])
-AT_CHECK([ovn-nbctl list connection | grep inactivity_probe], [0], [dnl
-inactivity_probe    : 30000
-inactivity_probe    : 30000
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_dry_run_mode], [dry run mode], [
-dnl Check that dry run has no permanent effect.
-AT_CHECK([ovn-nbctl --dry-run ls-add ls0 -- ls-list | uuidfilt], [0], [dnl
-<0> (ls0)
-])
-AT_CHECK([ovn-nbctl ls-list | uuidfilt], [0], [dnl
-])
-
-dnl Check that dry-run mode is not sticky.
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl ls-list | uuidfilt], [0], [dnl
-<0> (ls0)
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_oneline_output], [oneline output], [
-AT_CHECK([ovn-nbctl ls-add ls0 -- ls-add ls1])
-
-dnl Expect one line for one command.
-AT_CHECK([ovn-nbctl --oneline ls-list | uuidfilt], [0], [dnl
-<0> (ls0)\n<1> (ls1)
-])
-
-dnl Expect lines for two commands.
-AT_CHECK([ovn-nbctl --oneline ls-list -- ls-list | uuidfilt], [0], [dnl
-<0> (ls0)\n<1> (ls1)
-<0> (ls0)\n<1> (ls1)
-])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_error_paths], [commands parser error paths], [
-dnl FIXME: Duplicate options are allowed when passed with global options.
-dnl        For example: ovn-nbctl --if-exists --if-exists list Logical_Switch
-
-dnl Duplicate option
-AT_CHECK([ovn-nbctl -- --if-exists --if-exists list Logical_Switch], [1], [], [stderr])
-AT_CHECK([grep 'option specified multiple times' stderr], [0], [ignore])
-
-dnl Missing command
-AT_CHECK([ovn-nbctl], [1], [], [stderr])
-AT_CHECK([grep 'missing command name' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl --if-exists], [1], [], [stderr])
-AT_CHECK([grep 'missing command name' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl --], [1], [], [stderr])
-AT_CHECK([grep 'missing command name' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- --if-exists], [1], [], [stderr])
-AT_CHECK([grep 'missing command name' stderr], [0], [ignore])
-
-dnl Unknown command
-AT_CHECK([ovn-nbctl foo], [1], [], [stderr])
-AT_CHECK([grep 'unknown command' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- foo], [1], [], [stderr])
-AT_CHECK([grep 'unknown command' stderr], [0], [ignore])
-
-dnl Unknown option
-AT_CHECK([ovn-nbctl --foo list Logical_Switch], [1], [], [stderr])
-AT_CHECK([grep 'unrecognized option' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- --foo list Logical_Switch], [1], [], [stderr])
-AT_CHECK([grep 'command has no .* option' stderr], [0], [ignore])
-
-dnl Missing option argument
-AT_CHECK([ovn-nbctl --columns], [1], [], [stderr])
-AT_CHECK([grep 'option .* requires an argument' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- --columns list Logical_Switch], [1], [], [stderr])
-AT_CHECK([grep 'missing argument to .* option' stderr], [0], [ignore])
-
-dnl Unexpected option argument
-AT_CHECK([ovn-nbctl --if-exists=foo list Logical_Switch], [1], [], [stderr])
-AT_CHECK([egrep 'option .* doesn'\''t allow an argument|option .* requires an argument' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- --if-exists=foo list Logical_Switch], [1], [], [stderr])
-AT_CHECK([grep 'option on .* does not accept an argument' stderr], [0], [ignore])
-
-dnl Not enough arguments
-AT_CHECK([ovn-nbctl list], [1], [], [stderr])
-AT_CHECK([grep 'command requires at least .* arguments' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- list], [1], [], [stderr])
-AT_CHECK([grep 'command requires at least .* arguments' stderr], [0], [ignore])
-
-dnl Too many arguments
-AT_CHECK([ovn-nbctl show foo bar], [1], [], [stderr])
-AT_CHECK([grep 'command takes at most .* arguments' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- show foo bar], [1], [], [stderr])
-AT_CHECK([grep 'command takes at most .* arguments' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl show foo --bar], [1], [], [stderr])
-AT_CHECK([grep 'command takes at most .* arguments' stderr], [0], [ignore])
-
-AT_CHECK([ovn-nbctl -- show foo --bar], [1], [], [stderr])
-AT_CHECK([grep 'command takes at most .* arguments' stderr], [0], [ignore])])
-
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_port_groups], [port groups], [
-dnl Check that port group can be looked up by name
-AT_CHECK([ovn-nbctl create Port_Group name=pg0], [0], [ignore])
-AT_CHECK([ovn-nbctl get Port_Group pg0 name], [0], [dnl
-pg0
-])])
-
-OVN_NBCTL_TEST([ovn_nbctl_extra_newlines], [extra newlines], [
-dnl This test addresses a specific issue seen when running ovn-nbctl in
-dnl daemon mode. All we have to do is ensure that each time we list database
-dnl information, there is not an extra newline at the beginning of the output.
-AT_CHECK([ovn-nbctl ls-add sw1], [0], [ignore])
-AT_CHECK([ovn-nbctl --columns=name list logical_switch sw1], [0], [dnl
-name                : sw1
-])
-AT_CHECK([ovn-nbctl --columns=name list logical_switch sw1], [0], [dnl
-name                : sw1
-])])
-
-OVN_NBCTL_TEST([ovn_nbctl_table_formatting], [table formatting], [
-dnl This test addresses a specific issue seen when running ovn-nbctl in
-dnl daemon mode. We need to ensure that table formatting options are honored
-dnl when listing database information.
-AT_CHECK([ovn-nbctl ls-add sw1], [0], [ignore])
-AT_CHECK([ovn-nbctl --bare --columns=name list logical_switch sw1], [0], [dnl
-sw1
-])])
-dnl ---------------------------------------------------------------------
-
-OVN_NBCTL_TEST([ovn_nbctl_port_group_commands], [port group commands], [
-AT_CHECK([ovn-nbctl pg-add pg1], [0], [ignore])
-AT_CHECK([ovn-nbctl --bare --columns=name list port_group pg1], [0],
-[pg1
-])
-
-AT_CHECK([ovn-nbctl pg-del pg1], [0], [ignore])
-AT_CHECK([ovn-nbctl list port_group], [0], [])
-
-AT_CHECK([ovn-nbctl ls-add sw1], [0], [ignore])
-AT_CHECK([ovn-nbctl lsp-add sw1 sw1-p1], [0], [ignore])
-SW1P1=$(ovn-nbctl --bare --columns=_uuid list logical_switch_port sw1-p1)
-AT_CHECK([ovn-nbctl lsp-add sw1 sw1-p2], [0], [ignore])
-SW1P2=$(ovn-nbctl --bare --columns=_uuid list logical_switch_port sw1-p2)
-
-AT_CHECK([ovn-nbctl pg-add pg1 sw1-p1], [0], [ignore])
-AT_CHECK([ovn-nbctl --bare --columns=name list port_group pg1], [0],[dnl
-pg1
-])
-AT_CHECK_UNQUOTED([ovn-nbctl --bare --columns=ports list port_group pg1], [0], [dnl
-$SW1P1
-])
-
-AT_CHECK([ovn-nbctl pg-set-ports pg1 sw1-p2], [0], [ignore])
-AT_CHECK_UNQUOTED([ovn-nbctl --bare --columns=ports list port_group pg1], [0], [dnl
-$SW1P2
-])
-
-AT_CHECK([ovn-nbctl pg-del pg1], [0], [ignore])
-AT_CHECK([ovn-nbctl list port_group], [0], [])
-])
-
-AT_SETUP([ovn-nbctl - daemon retry connection])
-OVN_NBCTL_TEST_START daemon
-AT_CHECK([kill `cat ovsdb-server.pid`])
-AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --log-file --remote=punix:$OVS_RUNDIR/ovnnb_db.sock ovn-nb.db], [0], [], [stderr])
-AT_CHECK([ovn-nbctl show], [0], [ignore])
-OVN_NBCTL_TEST_STOP /Terminated/d
-AT_CLEANUP
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
deleted file mode 100644
index 62e58fd..0000000
--- a/tests/ovn-northd.at
+++ /dev/null
@@ -1,900 +0,0 @@
-AT_BANNER([OVN northd])
-AT_SETUP([ovn -- check   from NBDB to SBDB])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl create Logical_Router name=R1
-ovn-sbctl chassis-add gw1 geneve 127.0.0.1
-ovn-sbctl chassis-add gw2 geneve 1.2.4.8
-
-# Connect alice to R1 as distributed router gateway port on hv2
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
-
-ovn-nbctl --wait=sb \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=20 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=10 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
-
-nb_gwc1_uuid=`ovn-nbctl --bare --columns _uuid find Gateway_Chassis name="alice_gw1"`
-
-# With the new ha_chassis_group table added, there should be no rows in
-# gateway_chassis table in SB DB.
-AT_CHECK([ovn-sbctl list gateway_chassis | wc -l], [0], [0
-])
-
-# There should be one ha_chassis_group with the name "alice"
-ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
-ha_chassis_group name="alice"`
-
-AT_CHECK([test $ha_chassi_grp_name = alice])
-
-ha_chgrp_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group name=alice`
-
-AT_CHECK([ovn-sbctl --bare --columns ha_chassis_group find port_binding \
-logical_port="cr-alice" | grep $ha_chgrp_uuid | wc -l], [0], [1
-])
-
-# There should be one ha_chassis_group with the name "alice"
-ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
-ha_chassis_group name="alice"`
-
-AT_CHECK([test $ha_chassi_grp_name = alice])
-
-ha_chgrp_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group name=alice`
-
-AT_CHECK([ovn-sbctl --bare --columns ha_chassis_group find port_binding \
-logical_port="cr-alice" | grep $ha_chgrp_uuid | wc -l], [0], [1
-])
-
-ha_ch=`ovn-sbctl --bare --columns ha_chassis  find ha_chassis_group`
-# Trim the spaces.
-ha_ch=`echo $ha_ch | sed 's/ //g'`
-
-ha_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list="$ha_ch_list $i"
-done
-
-# Trim the spaces.
-ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
-
-AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
-
-# Delete chassis - gw2 in SB DB.
-# ovn-northd should not recreate ha_chassis rows
-# repeatedly when gw2 is deleted.
-ovn-sbctl chassis-del gw2
-
-ha_ch_list_1=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list_1="$ha_ch_list_1 $i"
-done
-
-# Trim the spaces.
-ha_ch_list_1=`echo $ha_ch_list_1 | sed 's/ //g'`
-
-ha_ch_list_2=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list_2="$ha_ch_list_2 $i"
-done
-
-# Trim the spaces.
-ha_ch_list_2=`echo $ha_ch_list_2 | sed 's/ //g'`
-
-AT_CHECK([test "$ha_ch_list_1" = "$ha_ch_list_2"])
-
-# Add back the gw2 chassis
-ovn-sbctl chassis-add gw2 geneve 1.2.4.8
-
-# delete the 2nd Gateway_Chassis on NBDB for alice port
-gw_ch=`ovn-sbctl --bare --columns gateway_chassis find port_binding \
-logical_port="cr-alice"`
-AT_CHECK([test "$gw_ch" = ""])
-
-ha_ch=`ovn-sbctl --bare --columns ha_chassis  find ha_chassis_group`
-ha_ch=`echo $ha_ch | sed 's/ //g'`
-# Trim the spaces.
-echo "ha ch in grp = $ha_ch"
-
-ha_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list="$ha_ch_list $i"
-done
-
-# Trim the spaces.
-ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
-
-AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
-
-# delete the 2nd Gateway_Chassis on NBDB for alice port
-ovn-nbctl --wait=sb set Logical_Router_Port alice gateway_chassis=${nb_gwc1_uuid}
-
-# There should be only 1 row in ha_chassis SB DB table.
-AT_CHECK([ovn-sbctl --bare --columns _uuid list ha_chassis | wc -l], [0], [1
-])
-
-AT_CHECK([ovn-sbctl list gateway_chassis | wc -l], [0], [0
-])
-
-# There should be only 1 row in ha_chassis SB DB table.
-AT_CHECK([ovn-sbctl --bare --columns _uuid list ha_chassis | wc -l], [0], [1
-])
-
-# delete all the gateway_chassis on NBDB for alice port
-
-ovn-nbctl --wait=sb clear Logical_Router_Port alice gateway_chassis
-
-# expect that the ha_chassis doesn't exist anymore
-AT_CHECK([ovn-sbctl list gateway_chassis | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl list ha_chassis | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl list ha_chassis_group | wc -l], [0], [0
-])
-
-# expect that the ha_chassis doesn't exist anymore
-AT_CHECK([ovn-sbctl list ha_chassis | wc -l], [0], [0
-])
-AT_CHECK([ovn-sbctl list ha_chassis_group | wc -l], [0], [0
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check Gateway_Chassis propagation from NBDB to SBDB backwards compatibility])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl create Logical_Router name=R1
-ovn-sbctl chassis-add gw1 geneve 127.0.0.1
-ovn-sbctl chassis-add gw2 geneve 1.2.4.8
-
-ovn-nbctl --wait=sb lrp-add R1 bob 00:00:02:01:02:03 172.16.1.1/24 \
-    -- set Logical_Router_Port bob options:redirect-chassis="gw1"
-
-
-# It should be converted to ha_chassis_group entries in SBDB, and
-# still redirect-chassis is kept for backwards compatibility
-
-AT_CHECK([ovn-sbctl list gateway_chassis | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl --bare --columns _uuid list ha_chassis | wc -l], [0], [1
-])
-
-AT_CHECK([ovn-sbctl --bare --columns _uuid list ha_chassis_group | wc -l], [0], [1
-])
-
-# There should be one ha_chassis_group with the name "bob_gw1"
-ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
-ha_chassis_group name="bob_gw1"`
-
-AT_CHECK([test $ha_chassi_grp_name = bob_gw1])
-
-ha_chgrp_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group name=bob_gw1`
-
-AT_CHECK([ovn-sbctl --bare --columns ha_chassis_group find port_binding \
-logical_port="cr-bob" | grep $ha_chgrp_uuid | wc -l], [0], [1
-])
-
-ovn-nbctl --wait=sb remove Logical_Router_Port bob options redirect-chassis
-
-# expect that the ha_chassis/ha_chassis_group doesn't exist anymore
-
-AT_CHECK([ovn-sbctl find Gateway_Chassis name=bob_gw1], [0], [])
-AT_CHECK([ovn-sbctl list ha_chassis | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl list ha_chassis_group | wc -l], [0], [0
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check up state of VIF LSP])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add S1
-ovn-nbctl --wait=sb lsp-add S1 S1-vm1
-AT_CHECK([test x`ovn-nbctl lsp-get-up S1-vm1` = xdown])
-
-ovn-sbctl chassis-add hv1 geneve 127.0.0.1
-ovn-sbctl lsp-bind S1-vm1 hv1
-AT_CHECK([test x`ovn-nbctl lsp-get-up S1-vm1` = xup])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check up state of router LSP linked to a distributed LR])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl lr-add R1
-ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
-
-ovn-nbctl ls-add S1
-ovn-nbctl lsp-add S1 S1-R1
-ovn-nbctl lsp-set-type S1-R1 router
-ovn-nbctl lsp-set-addresses S1-R1 02:ac:10:01:00:01
-ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
-AT_CHECK([test x`ovn-nbctl lsp-get-up S1-R1` = xup])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check up state of router LSP linked to a gateway LR])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-sbctl chassis-add gw1 geneve 127.0.0.1
-
-ovn-nbctl create Logical_Router name=R1 options:chassis=gw1
-ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
-
-ovn-nbctl ls-add S1
-ovn-nbctl lsp-add S1 S1-R1
-ovn-nbctl lsp-set-type S1-R1 router
-ovn-nbctl lsp-set-addresses S1-R1 02:ac:10:01:00:01
-ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
-
-ovn-sbctl lsp-bind S1-R1 gw1
-AT_CHECK([test x`ovn-nbctl lsp-get-up S1-R1` = xup])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check up state of router LSP linked to an LRP with set Gateway Chassis])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-sbctl chassis-add gw1 geneve 127.0.0.1
-
-ovn-nbctl lr-add R1
-ovn-nbctl lrp-add R1 R1-S1 02:ac:10:01:00:01 172.16.1.1/24
-ovn-nbctl lrp-set-gateway-chassis R1-S1 gw1
-
-ovn-nbctl ls-add S1
-ovn-nbctl lsp-add S1 S1-R1
-ovn-nbctl lsp-set-type S1-R1 router
-ovn-nbctl lsp-set-addresses S1-R1 router
-ovn-nbctl --wait=sb lsp-set-options S1-R1 router-port=R1-S1
-AT_CHECK([test x`ovn-nbctl lsp-get-up S1-R1` = xup])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check IPv6 RA config propagation to SBDB])
-ovn_start
-
-ovn-nbctl lr-add ro
-ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
-ovn-nbctl ls-add sw
-ovn-nbctl lsp-add sw sw-ro
-ovn-nbctl lsp-set-type sw-ro router
-ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
-ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
-ovn-nbctl --wait=sb set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1280
-
-uuid=$(ovn-sbctl --columns=_uuid --bare find Port_Binding logical_port=ro-sw)
-
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_send_periodic],
-[0], ["true"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_address_mode],
-[0], [slaac
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[0], ["600"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[0], ["200"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_mtu],
-[0], ["1280"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_src_eth],
-[0], ["00:00:00:00:00:01"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_src_addr],
-[0], ["fe80::200:ff:fe00:1"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_prefixes],
-[0], ["aef0::/64"
-])
-
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=300
-ovn-nbctl --wait=sb set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=600
-
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[0], ["300"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[0], ["225"
-])
-
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=300
-ovn-nbctl --wait=sb set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=250
-
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[0], ["300"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[0], ["225"
-])
-
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=0
-ovn-nbctl --wait=sb set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=0
-
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[0], ["4"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[0], ["3"
-])
-
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=3600
-ovn-nbctl --wait=sb set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=2400
-
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[0], ["1800"
-])
-AT_CHECK([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[0], ["1350"
-])
-
-ovn-nbctl --wait=sb set Logical_Router_port ro-sw ipv6_ra_configs:send_periodic=false
-
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_send_periodic],
-[1], [], [ovn-sbctl: no key "ipv6_ra_send_periodic" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_max_interval],
-[1], [], [ovn-sbctl: no key "ipv6_ra_max_interval" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_min_interval],
-[1], [], [ovn-sbctl: no key "ipv6_ra_min_interval" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_mtu],
-[1], [], [ovn-sbctl: no key "ipv6_ra_mtu" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_address_mode],
-[1], [], [ovn-sbctl: no key "ipv6_ra_address_mode" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_src_eth],
-[1], [], [ovn-sbctl: no key "ipv6_ra_src_eth" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_src_addr],
-[1], [], [ovn-sbctl: no key "ipv6_ra_src_addr" in Port_Binding record "${uuid}" column options
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get Port_Binding ${uuid} options:ipv6_ra_prefixes],
-[1], [], [ovn-sbctl: no key "ipv6_ra_prefixes" in Port_Binding record "${uuid}" column options
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- test unixctl])
-ovn_init_db ovn-sb; ovn-sbctl init
-ovn_init_db ovn-nb; ovn-nbctl init
-
-# test unixctl option
-mkdir "$ovs_base"/northd
-as northd start_daemon ovn-northd --unixctl="$ovs_base"/northd/ovn-northd.ctl --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-ovn-nbctl ls-add sw
-ovn-nbctl --wait=sb lsp-add sw p1
-# northd created with unixctl option successfully created port_binding entry
-AT_CHECK([ovn-sbctl --bare --columns datapath find port_binding logical_port="p1" | wc -l], [0], [1
-])
-AT_CHECK([ovn-nbctl --wait=sb lsp-del p1])
-
-# ovs-appctl exit with unixctl option
-OVS_APP_EXIT_AND_WAIT_BY_TARGET(["$ovs_base"/northd/ovn-northd.ctl], ["$ovs_base"/northd/ovn-northd.pid])
-
-# Check no port_binding entry for new port as ovn-northd is not running
-ovn-nbctl lsp-add sw p2
-ovn-nbctl --timeout=10 --wait=sb sync
-AT_CHECK([ovn-sbctl --bare --columns datapath find port_binding logical_port="p2" | wc -l], [0], [0
-])
-
-# test default unixctl path
-as northd start_daemon ovn-northd --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-ovn-nbctl --wait=sb lsp-add sw p3
-# northd created with default unixctl path successfully created port_binding entry
-AT_CHECK([ovn-sbctl --bare --columns datapath find port_binding logical_port="p3" | wc -l], [0], [1
-])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- check HA_Chassis_Group propagation from NBDB to SBDB])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
-
-# ovn-northd should not create HA chassis group and HA chassis rows
-# unless the HA chassis group in OVN NB DB is associated to
-# a logical router port or logical port of type external.
-AT_CHECK([ovn-sbctl --bare --columns name find ha_chassis_group name="hagrp1" \
-| wc -l], [0], [0
-])
-
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 30
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch2 20
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch3 10
-
-# There should be no HA_Chassis rows in SB DB.
-AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
-| grep -v '-' | wc -l ], [0], [0
-])
-
-# Add chassis ch1.
-ovn-sbctl chassis-add ch1 geneve 127.0.0.2
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl list chassis | grep ch1 | wc -l`])
-
-# There should be no HA_Chassis rows
-AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
-| grep -v '-' | wc -l ], [0], [0
-])
-
-# Create a logical router port and attach ha chassis group.
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
-
-hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
-ovn-nbctl set logical_router_port lr0-public ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Make sure that ovn-northd doesn't recreate the ha_chassis
-# records if the chassis record is missing in SB DB.
-
-ha_ch_list_1=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list_1="$ha_ch_list_1 $i"
-done
-
-# Trim the spaces.
-ha_ch_list_1=`echo $ha_ch_list_1 | sed 's/ //g'`
-
-ha_ch_list_2=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list_2="$ha_ch_list_2 $i"
-done
-
-# Trim the spaces.
-ha_ch_list_2=`echo $ha_ch_list_2 | sed 's/ //g'`
-
-AT_CHECK([test "$ha_ch_list_1" = "$ha_ch_list_2"])
-
-# 2 HA chassis should be created with 'chassis' column empty because
-# we have not added hv1 and hv2 chassis to the SB DB.
-AT_CHECK([test 2 = `ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
-| grep -v '-' | wc -l`])
-
-# We should have 1 ha chassis with 'chassis' column set for hv1
-AT_CHECK([test 1 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | awk '{print $3}' \
-| grep '-' | wc -l`])
-
-# Create another logical router port and associate to the same ha_chasis_group
-ovn-nbctl lr-add lr1
-ovn-nbctl lrp-add lr1 lr1-public 00:00:20:20:12:14 182.168.0.100/24
-
-ovn-nbctl set logical_router_port lr1-public ha_chassis_group=$hagrp1_uuid
-
-# We should still have 1 HA chassis group and 3 HA chassis in SB DB.
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Change the priority of ch1 - ha chassis in NB DB. It should get
-# reflected in SB DB.
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 100
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns priority find \
-ha_chassis | grep 100 | wc -l`])
-
-# Delete ch1 HA chassis in NB DB.
-ovn-nbctl --wait=sb ha-chassis-group-remove-chassis hagrp1 ch1
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Add back the ha chassis
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 40
-OVS_WAIT_UNTIL([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Delete lr0-public. We should still have 1 HA chassis group and
-# 3 HA chassis in SB DB.
-ovn-nbctl --wait=sb lrp-del lr0-public
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Delete lr1-public. There should be no HA chassis group in SB DB.
-ovn-nbctl --wait=sb lrp-del lr1-public
-
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 0 = `ovn-sbctl list ha_chassis | grep chassis | wc -l`])
-
-# Add lr0-public again
-ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
-ovn-nbctl set logical_router_port lr0-public ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Create a Gateway chassis. ovn-northd should ignore this.
-ovn-nbctl lrp-set-gateway-chassis lr0-public ch-1 20
-
-# There should be only 1 HA chassis group in SB DB with the
-# name hagrp1.
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group | wc -l`])
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Now delete HA chassis group. ovn-northd should create HA chassis group
-# with the Gateway chassis name
-ovn-nbctl clear logical_router_port lr0-public ha_chassis_group
-ovn-nbctl ha-chassis-group-del hagrp1
-
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="lr0-public" | wc -l`])
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
-find ha_chassis | wc -l`])
-
-ovn-nbctl lrp-set-gateway-chassis lr0-public ch2 10
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="lr0-public" | wc -l`])
-
-ovn-sbctl --bare --columns _uuid find ha_chassis
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Test if 'ref_chassis' column is properly set or not in
-# SB DB ha_chassis_group.
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-p1
-
-ovn-sbctl chassis-add ch2 geneve 127.0.0.3
-ovn-sbctl chassis-add ch3 geneve 127.0.0.4
-ovn-sbctl chassis-add comp1 geneve 127.0.0.5
-ovn-sbctl chassis-add comp2 geneve 127.0.0.6
-
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:20:20:12:14 10.0.0.1/24
-ovn-nbctl lsp-add sw0 sw0-lr0
-ovn-nbctl lsp-set-type sw0-lr0 router
-ovn-nbctl lsp-set-addresses sw0-lr0 router
-ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
-
-ovn-sbctl lsp-bind sw0-p1 comp1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0-p1` = xup])
-
-comp1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="comp1"`
-comp2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="comp2"`
-ch2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="comp1"`
-
-echo "comp1_ch_uuid = $comp1_ch_uuid"
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp1_ch_uuid" = "$ref_ch_list"])
-
-# unbind sw0-p1
-ovn-sbctl lsp-unbind sw0-p1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0-p1` = xdown])
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "" = "$ref_ch_list"])
-
-# Bind sw0-p1 in comp2
-ovn-sbctl lsp-bind sw0-p1 comp2
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp2_ch_uuid" = "$ref_ch_list"])
-
-ovn-nbctl ls-add sw1
-ovn-nbctl lsp-add sw1 sw1-p1
-ovn-nbctl lr-add lr1
-ovn-nbctl lrp-add lr1 lr1-sw1 00:00:20:20:12:15 20.0.0.1/24
-ovn-nbctl lsp-add sw1 sw1-lr1
-ovn-nbctl lsp-set-type sw1-lr1 router
-ovn-nbctl lsp-set-addresses sw1-lr1 router
-ovn-nbctl lsp-set-options sw1-lr1 router-port=lr1-sw1
-
-# Bind sw1-p1 in comp1.
-ovn-sbctl lsp-bind sw1-p1 comp1
-# Wait until sw1-p1 is up
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw1-p1` = xup])
-
-# sw1-p1 is not connected to lr0. So comp1 should not be in 'ref_chassis'
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp2_ch_uuid" = "$ref_ch_list"])
-
-# Now attach sw0 to lr1
-ovn-nbctl lrp-add lr1 lr1-sw0 00:00:20:20:12:16 10.0.0.10/24
-ovn-nbctl lsp-add sw0 sw0-lr1
-ovn-nbctl lsp-set-type sw0-lr1 router
-ovn-nbctl lsp-set-addresses sw0-lr1 router
-ovn-nbctl lsp-set-options sw0-lr1 router-port=lr1-sw0
-
-# Both comp1 and comp2 should be in 'ref_chassis' as sw1 is indirectly
-# connected to lr0
-exp_ref_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
-do
-    if test $i = $comp1_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    elif test $i = $comp2_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    fi
-done
-
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# Unind sw1-p1. comp2 should not be in the ref_chassis.
-ovn-sbctl lsp-unbind sw1-p1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw1-p1` = xdown])
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp2_ch_uuid" = "$ref_ch_list"])
-
-# Create sw2 and attach it to lr2
-ovn-nbctl ls-add sw2
-ovn-nbctl lsp-add sw2 sw2-p1
-ovn-nbctl lr-add lr2
-ovn-nbctl lrp-add lr2 lr2-sw2 00:00:20:20:12:17 30.0.0.1/24
-ovn-nbctl lsp-add sw2 sw2-lr2
-ovn-nbctl lsp-set-type sw2-lr2 router
-ovn-nbctl lsp-set-addresses sw2-lr2 router
-ovn-nbctl lsp-set-options sw2-lr2 router-port=lr2-sw2
-
-# Bind sw2-p1 to comp1
-ovn-sbctl lsp-bind sw2-p1 comp1
-# Wait until sw2-p1 is up
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw2-p1` = xup])
-
-# sw2-p1 is not connected to lr0. So comp1 should not be in 'ref_chassis'
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp2_ch_uuid" = "$ref_ch_list"])
-
-# Now attach sw1 to lr2. With this sw2-p1 is indirectly connected to lr0.
-ovn-nbctl lrp-add lr2 lr2-sw1 00:00:20:20:12:18 20.0.0.10/24
-ovn-nbctl lsp-add sw1 sw1-lr2
-ovn-nbctl lsp-set-type sw1-lr2 router
-ovn-nbctl lsp-set-addresses sw1-lr2 router
-ovn-nbctl lsp-set-options sw1-lr2 router-port=lr2-sw1
-
-# sw2-p1 is indirectly connected to lr0. So comp1 (and comp2) should be in
-# 'ref_chassis'
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# Create sw0-p2 and bind it to comp1
-ovn-nbctl lsp-add sw0 sw0-p2
-ovn-sbctl lsp-bind sw0-p2 comp1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0-p2` = xup])
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# unbind sw0-p2
-ovn-sbctl lsp-unbind sw0-p2
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0-p2` = xdown])
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# Delete lr1-sw0. comp1 should be deleted from ref_chassis as there is no link
-# from sw1 and sw2 to lr0.
-ovn-nbctl lrp-del lr1-sw0
-
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$comp2_ch_uuid" = "$ref_ch_list"])
-
-# Set redirect-chassis option to lr0-public. It should be ignored.
-ovn-nbctl set logical_router_port lr0-public options:redirect-chassis=ch1
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group | wc -l`])
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="lr0-public" | wc -l`])
-
-ovn-sbctl --bare --columns _uuid find ha_chassis
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Delete the gateway chassis. HA chassis group should be created in SB DB
-# for the redirect-chassis option.
-ovn-nbctl clear logical_router_port lr0-public gateway_chassis
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group | wc -l`])
-
-ovn-sbctl list ha_chassis_group
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="lr0-public_ch1" | wc -l`])
-
-ovn-sbctl --bare --columns _uuid find ha_chassis
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl list ha_chassis | grep chassis |
-grep -v chassis-name | wc -l`])
-
-# Clear the redirect-chassis option.
-ovn-nbctl clear logical_router_port lr0-public options
-
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group |  wc -l`])
-AT_CHECK([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
-
-# Delete old sw0.
-ovn-nbctl ls-del sw0
-
-# Create external logical ports and associate ha_chassis_group
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-pext1
-ovn-nbctl lsp-add sw0 sw0-pext2
-ovn-nbctl lsp-add sw0 sw0-p1
-
-ovn-nbctl lsp-set-addresses sw0-pext1 "00:00:00:00:00:03 10.0.0.3"
-ovn-nbctl lsp-set-addresses sw0-pext2 "00:00:00:00:00:03 10.0.0.4"
-ovn-nbctl lsp-set-addresses sw0-p1 "00:00:00:00:00:03 10.0.0.5"
-
-ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
-
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 30
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch2 20
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch3 10
-
-# ovn-northd should not create HA chassis group and HA chassis rows
-# unless the HA chassis group in OVN NB DB is associated to
-# a logical router port or logical port of type external.
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group |  wc -l`])
-AT_CHECK([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
-
-hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group \
-name=hagrp1`
-
-# The type of the lsp - sw0-pext1 is still not set to external.
-# So ha_chassis_group should be ignored.
-ovn-nbctl set logical_switch_port sw0-pext1 ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 0 = `ovn-sbctl list ha_chassis | grep chassis | wc -l`])
-
-# Set the type of sw0-pext1 to external
-ovn-nbctl lsp-set-type sw0-pext1 external
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
-name=hagrp1`
-
-AT_CHECK([test "$sb_hagrp1_uuid" = `ovn-sbctl --bare --columns \
-ha_chassis_group find port_binding logical_port=sw0-pext1`])
-
-# Set the type of sw0-pext2 to external and associate ha_chassis_group
-ovn-nbctl lsp-set-type sw0-pext2 external
-ovn-nbctl set logical_switch_port sw0-pext2 ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis |
-grep -v chassis-name | wc -l`])
-AT_CHECK([test "$sb_hagrp1_uuid" = `ovn-sbctl --bare --columns \
-ha_chassis_group find port_binding logical_port=sw0-pext1`])
-
-OVS_WAIT_UNTIL([test "$sb_hagrp1_uuid" = `ovn-sbctl --bare --columns \
-ha_chassis_group find port_binding logical_port=sw0-pext2`])
-
-# sw0-p1 is a normal port. So ha_chassis_group should not be set
-# in port_binding.
-ovn-nbctl --wait=sb set logical_switch_port sw0-p1 \
-ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=sw0-p1) = x], [0], [])
-
-# Clear ha_chassis_group for sw0-pext1
-ovn-nbctl --wait=sb clear logical_switch_port sw0-pext1 ha_chassis_group
-
-OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=sw0-pext1) = x], [0], [])
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns name find \
-ha_chassis_group name="hagrp1" | wc -l`])
-
-AT_CHECK([test 3 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-# Clear ha_chassis_group for sw0-pext2
-ovn-nbctl --wait=sb clear logical_switch_port sw0-pext2 ha_chassis_group
-
-OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=sw0-pext2) = x], [0], [])
-
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group |  wc -l`])
-AT_CHECK([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-AT_CLEANUP
diff --git a/tests/ovn-performance.at b/tests/ovn-performance.at
deleted file mode 100644
index a8a15f8..0000000
--- a/tests/ovn-performance.at
+++ /dev/null
@@ -1,424 +0,0 @@
-#
-# Tests targeting performance of OVN components.
-#
-
-m4_divert_push([PREPARE_TESTS])
-
-# vec_cmp VALUE_VEC OP-VALUE_VEC
-#
-# Compares each value from VALUE_VEC to the operator-value pair from the
-# OP-VALUE_VEC.
-#
-# VALUE_VEC must be a list of values separated by a character from $IFS.
-# OP-VALUE_VEC must be a list of operator-value expressions separated by a
-# character from $IFS.  Operator-value expressions cannot contain any characters
-# from $IFS like spaces. '=' is treated as an equality operator ('==') for
-# conciseness.
-#
-# Returns the result of each comparison as a list of boolean values (0 or 1)
-# separated by a new-line character.
-vec_cmp() {
-    local a b i j
-
-    i=0
-    for a in $1; do
-        j=0
-        for b in $2; do
-            if test $i -eq $j; then
-                # Replace assignment '=' with equality comparison '=='
-                case "$b" in
-                =[[0-9]]*) b="=$b" ;;
-                esac
-
-                echo $(($a $b))
-                break
-            fi
-            j=$((j + 1))
-        done
-        i=$((i + 1))
-    done
-}
-
-# vec_sub VEC_A VEC_B
-#
-# Subtracts two vectors:
-#
-#     VEC_A = [a1, a2, ...]
-#     VEC_B = [b1, b2, ...]
-#     OUT = [(a1 - b1), (a2 - b2), ...]
-#
-# VEC_A and VEC_B must be lists of values separated by a character from $IFS.
-vec_sub() {
-    local a b i j
-
-    i=0
-    for a in $1; do
-        j=0
-        for b in $2; do
-            if test $i -eq $j; then
-                echo $((a - b))
-                break
-            fi
-            j=$((j + 1))
-        done
-        i=$((i + 1))
-    done
-}
-
-# vec_fold VEC OP
-#
-# Reduces a vector to a single value by applying the binary operator OP (i.e.,
-# one that requires two arguments) cumulatively to all vector elements from left
-# to right:
-#
-#     VEC = [e1, e2, e3 ...]
-#     OUT = (...((e1 OP e2) OP e3) OP ...)
-#
-# VEC must be a list of values separated by a character from $IFS.
-vec_fold() {
-    local first op prod
-
-    first=1
-    op=$2
-    for a in $1; do
-        if test $first -eq 1; then
-            prod=$a
-            first=0
-        else
-            prod=$((prod $op a))
-        fi
-    done
-    echo $prod
-}
-
-# read_counters SANDBOXES TARGET COUNTER
-#
-# Prints out the coverage COUNTER for the TARGET in each of the SANDBOXES.
-#
-# SANDBOXES must be a list of strings separated by a character from $IFS.
-read_counters() {
-    local sims="$1" target="$2" counter="$3"
-
-    for sim in $sims; do
-        as $sim ovs-appctl -t "$target" coverage/read-counter "$counter" || return 1
-    done
-}
-
-# counter_delta_ SANDBOXES TARGET COUNTER COMMAND
-#
-# Runs the COMMAND and reports the COUNTER change registered during the command
-# run for the given TARGET in each of the SANDBOXES.
-counter_delta_() {
-    local sims="$1" target="$2" counter="$3" cmd="$4"
-    local before after
-
-    before=$(read_counters "$sims" "$target" "$counter") || return 1
-    eval "$cmd" >/dev/null || return 1
-    after=$(read_counters "$sims" "$target" "$counter") || return 1
-
-    vec_sub "$after" "$before"
-}
-
-# counter_delta SANDBOXES TARGET COUNTER COMMAND
-#
-# Same as counter_delta_ but also prints the COUNTER values together with the
-# COMMAND to standard error.
-counter_delta() {
-    local cmd="$4"
-    local v
-
-    v=$(counter_delta_ "$@") || return 1
-
-    # Dump the counters and the command for troubleshooting
-    echo "$v" | tr '\n' '\t' >&2
-    echo "$cmd" >&2
-
-    echo "$v"
-}
-
-# vec_cmp_counter_delta SANDBOXES TARGET COUNTER CONDS COMMAND
-#
-# Check if COUNTER change in the TARGET app in each of the SANDBOXES after
-# running the COMMAND meets the conditions listed as operator-value pairs in
-# CONDS.
-vec_cmp_counter_delta() {
-    local v
-
-    v=$(counter_delta "$1" "$2" "$3" "$5") || return 1
-    v=$(vec_cmp "$v" "$4") || return 1
-    v=$(vec_fold "$v" "&&") || return 1
-
-    echo "$v"
-}
-
-# cmp_counter_delta SANDBOXES TARGET COUNTER COND COMMAND
-#
-# Check if COUNTER change in the TARGET app in each of the SANDBOXES after
-# running the COMMAND meets the COND condition given as a operator-value pair.
-cmp_counter_delta() {
-    local conds=""
-
-    # Use the same condition for each sandbox
-    for _ in $1; do
-        conds="$conds $4"
-    done
-
-    vec_cmp_counter_delta "$1" "$2" "$3" "$conds" "$5"
-}
-
-m4_divert_pop([PREPARE_TESTS])
-
-# CHECK_COUNTER_DELTA_IS_ZERO SANDBOXES TARGET COUNTER COMMAND
-#
-# Runs the COMMAND and checks if the COUNTER value for the TARGET in all of
-# the SANDBOXES did not change.
-m4_define([CHECK_COUNTER_DELTA_IS_ZERO],[
-    rv=$(cmp_counter_delta "$1" "$2" "$3" "=0" "$4")
-    rc=$?
-    AT_CHECK([test $rc -eq 0 -a $rv -eq 1])
-])
-
-# CHECK_COUNTER_DELTA_IS_NOT_ZERO SANDBOXES TARGET COUNTER COMMAND
-#
-# Runs the COMMAND and checks if the COUNTER value for the TARGET in
-# all of the SANDBOXES has changed.
-m4_define([CHECK_COUNTER_DELTA_IS_NOT_ZERO],[
-    rv=$(cmp_counter_delta "$1" "$2" "$3" ">0" "$4")
-    rc=$?
-    AT_CHECK([test $rc -eq 0 -a $rv -eq 1])
-])
-
-# CHECK_COUNTER_DELTA_COND SANDBOXES TARGET COUNTER CONDS COMMAND
-#
-# Runs the COMMAND and checks if the COUNTER value for the TARGET in all of the
-# SANDBOXES satisfies the conditions listed in CONDS.
-m4_define([CHECK_COUNTER_DELTA_COND],[
-    rv=$(vec_cmp_counter_delta "$1" "$2" "$3" "$4" "$5")
-    rc=$?
-    AT_CHECK([test $rc -eq 0 -a $rv -eq 1])
-])
-
-# OVN_CONTROLLER_EXPECT_HIT SANDBOXES COUNTER COMMAND
-#
-# Checks if the COUNTER value has changed for any of the ovn-controller
-# processes in the SANDBOXES when the COMMAND was run.
-m4_define([OVN_CONTROLLER_EXPECT_HIT],[
-    CHECK_COUNTER_DELTA_IS_NOT_ZERO([$1], [ovn-controller], [$2], [$3])
-])
-
-# OVN_CONTROLLER_EXPECT_NO_HIT SANDBOXES COUNTER COMMAND
-#
-# Checks if the COUNTER value has not changed for any of the ovn-controller
-# processes in the SANDBOXES when the COMMAND was run.
-m4_define([OVN_CONTROLLER_EXPECT_NO_HIT],[
-    CHECK_COUNTER_DELTA_IS_ZERO([$1], [ovn-controller], [$2], [$3])
-])
-
-# OVN_CONTROLLER_EXPECT_HIT_COND SANDBOXES COUNTER CONDS COMMAND
-#
-# Checks if the change of the COUNTER value, when the COMMAND was run, of the
-# ovn-controller process in each of the SANDBOXES meets the conditions in
-# CONDS. CONDS must be a list of operator-value pairs, for example "[>0 =0]",
-# following the same order as SANDBOXES.
-m4_define([OVN_CONTROLLER_EXPECT_HIT_COND],[
-    CHECK_COUNTER_DELTA_COND([$1], [ovn-controller], [$2], [$3], [$4])
-])
-
-AT_SETUP([ovn -- ovn-controller incremental processing])
-# Check which operations the trigger full logical flow processing.
-#
-# Create and destroy logical routers, switches, ports, address sets and ACLs
-# while counting calls to lflow_run() in ovn-controller.
-
-ovn_start
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-done
-
-# Add router lr1
-OVN_CONTROLLER_EXPECT_HIT(
-    [hv1 hv2], [lflow_run],
-    [ovn-nbctl --wait=hv lr-add lr1]
-)
-
-for i in 1 2; do
-    ls=ls$i
-    lsp=$ls-lr1
-    lrp=lr1-$ls
-
-    # Add switch $ls
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv ls-add $ls]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv add Logical_Switch $ls other_config subnet=10.0.$i.0/24]
-    )
-
-    # Add router port to $ls
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lrp-add lr1 $lrp 02:00:00:00:0$i:01 10.0.$i.1/24]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-add $ls $lsp]
-    )
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-set-type $lsp router]
-    )
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-set-options $lsp router-port=$lrp]
-    )
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-set-addresses $lsp router]
-    )
-done
-
-get_lsp_uuid () {
-    ovn-nbctl lsp-list ls${1#lp} | grep $1 | awk '{ print $1 }'
-}
-
-pg_ports=
-
-for i in 1 2; do
-    j=$((i%2 + 1))
-    as=as$i
-    ls=ls$i
-    lp=lp$i
-    vif=vif$i
-
-    # Add port $lp
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-add $ls $lp]
-    )
-
-    pg_ports="$pg_port `get_lsp_uuid $lp`"
-
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv lsp-set-addresses $lp "dynamic"]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl wait-until Logical_Switch_Port $lp dynamic_addresses!=[[]] &&
-         ovn-nbctl --wait=hv sync]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl get Logical_Switch_Port $lp dynamic_addresses &&
-         ovn-nbctl --wait=hv sync]
-    )
-
-    # Add address set $as
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv create Address_Set name="$as"]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv add Address_Set "$as" addresses "10.0.$i.10"]
-    )
-
-    # Add ACLs for port $lp
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv acl-add $ls to-lport 1001 'outport == \"$lp\" && ip4.src == \$$as' allow]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv acl-add $ls to-lport 1000 'outport == \"$lp\"' drop]
-    )
-
-    # Bind port $lp and wait for it to come up
-    OVN_CONTROLLER_EXPECT_HIT_COND(
-        [hv$i hv$j], [lflow_run], [>0 =0],
-        [as hv$i ovs-vsctl add-port br-int $vif -- set Interface $vif external-ids:iface-id=$lp &&
-         ovn-nbctl wait-until Logical_Switch_Port $lp 'up=true' &&
-         ovn-nbctl --wait=hv sync]
-    )
-done
-
-for i in 1 2; do
-    j=$((i%2 + 1))
-    as=as$i
-    ls=ls$i
-    lp=lp$i
-
-    # Delete ACLs for port $lp
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv acl-del $ls to-lport 1001 'outport == \"$lp\" && ip4.src == \$$as']
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv acl-del $ls to-lport 1000 'outport == \"$lp\"']
-    )
-
-    # Delete address set $as
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv remove Address_Set "$as" addresses "10.0.$i.10"]
-    )
-    OVN_CONTROLLER_EXPECT_NO_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv destroy Address_Set "$as"]
-    )
-done
-
-OVN_CONTROLLER_EXPECT_NO_HIT(
-    [hv1 hv2], [lflow_run],
-    [ovn-nbctl --wait=hv create Port_Group name=pg1 ports=\"$pg_ports\"]
-)
-
-# Add ACLs for port group pg1
-OVN_CONTROLLER_EXPECT_NO_HIT(
-    [hv1 hv2], [lflow_run],
-    [ovn-nbctl --wait=hv acl-add pg1 to-lport 1001 'outport == @pg1 && ip4.src == $pg1_ip4' allow]
-)
-
-for i in 1 2; do
-    j=$((i%2 + 1))
-    lp=lp$i
-
-    # Delete port $lp
-    OVN_CONTROLLER_EXPECT_HIT_COND(
-        [hv$i hv$j], [lflow_run], [>0 =0],
-        [ovn-nbctl --wait=hv lsp-del $lp]
-    )
-done
-
-# Delete port group pg1
-OVN_CONTROLLER_EXPECT_NO_HIT(
-    [hv1 hv2], [lflow_run],
-    [ovn-nbctl --wait=hv destroy Port_Group pg1]
-)
-
-for i in 1 2; do
-    ls=ls$i
-
-    # Delete switch $ls
-    OVN_CONTROLLER_EXPECT_HIT(
-        [hv1 hv2], [lflow_run],
-        [ovn-nbctl --wait=hv ls-del $ls]
-    )
-done
-
-# Delete router lr1
-OVN_CONTROLLER_EXPECT_HIT(
-    [hv1 hv2], [lflow_run],
-    [ovn-nbctl --wait=hv lr-del lr1]
-)
-
-OVN_CLEANUP([hv1], [hv2])
-
-AT_CLEANUP
diff --git a/tests/ovn-sbctl.at b/tests/ovn-sbctl.at
deleted file mode 100644
index 650e357..0000000
--- a/tests/ovn-sbctl.at
+++ /dev/null
@@ -1,150 +0,0 @@
-AT_BANNER([ovn-sbctl])
-
-# OVN_SBCTL_TEST_START
-m4_define([OVN_SBCTL_TEST_START],
-  [dnl Create databases (ovn-nb, ovn-sb).
-   AT_KEYWORDS([ovn])
-   for daemon in ovn-nb ovn-sb; do
-      AT_CHECK([ovsdb-tool create $daemon.db $abs_top_srcdir/${daemon%%-*}/${daemon}.ovsschema])
-   done
-
-   dnl Start ovsdb-servers.
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=ovnnb_db.pid --unixctl=$OVS_RUNDIR/ovnnb_db.ctl --log-file=ovsdb_nb.log --remote=punix:$OVS_RUNDIR/ovnnb_db.sock ovn-nb.db ], [0], [], [stderr])
-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=ovnsb_db.pid --unixctl=$OVS_RUNDIR/ovnsb_db.ctl --log-file=ovsdb_sb.log --remote=punix:$OVS_RUNDIR/ovnsb_db.sock ovn-sb.db], [0], [], [stderr])
-   on_exit "kill `cat ovnnb_db.pid` `cat ovnsb_db.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d
-/ovsdb_server|INFO|ovsdb-server (Open vSwitch)/d']])
-   AT_CAPTURE_FILE([ovsdb-server.log])
-
-   dnl Start ovn-northd.
-   AT_CHECK([ovn-northd --detach --no-chdir --pidfile --log-file --ovnnb-db=unix:$OVS_RUNDIR/ovnnb_db.sock --ovnsb-db=unix:$OVS_RUNDIR/ovnsb_db.sock], [0], [], [stderr])
-   on_exit "kill `cat ovn-northd.pid`"
-   AT_CHECK([[sed < stderr '
-/vlog|INFO|opened log file/d']])
-   AT_CAPTURE_FILE([ovn-northd.log])
-])
-
-# OVN_SBCTL_TEST_STOP
-m4_define([OVN_SBCTL_TEST_STOP],
-  [AT_CHECK([check_logs "$1"])
-   OVS_APP_EXIT_AND_WAIT([ovn-northd])
-   OVS_APP_EXIT_AND_WAIT_BY_TARGET([$OVS_RUNDIR/ovnnb_db.ctl], [$OVS_RUNDIR/ovnnb_db.pid])
-   OVS_APP_EXIT_AND_WAIT_BY_TARGET([$OVS_RUNDIR/ovnsb_db.ctl], [$OVS_RUNDIR/ovnsb_db.pid])])
-
-dnl ---------------------------------------------------------------------
-
-AT_SETUP([ovn-sbctl - chassis commands])
-OVN_SBCTL_TEST_START
-ovn_init_db ovn-sb
-
-AT_CHECK([ovn-sbctl chassis-add ch0 geneve 1.2.3.4])
-AT_CHECK([ovn-sbctl -f csv -d bare --no-headings --columns ip,type list encap | sort],
-         [0], [dnl
-1.2.3.4,geneve
-])
-
-AT_CHECK([ovn-sbctl chassis-add ch1 stt,geneve,vxlan 1.2.3.5])
-AT_CHECK([ovn-sbctl -f csv -d bare --no-headings --columns ip,type list encap | sort],
-         [0], [dnl
-1.2.3.4,geneve
-1.2.3.5,geneve
-1.2.3.5,stt
-1.2.3.5,vxlan
-])
-
-AT_CHECK([ovn-sbctl chassis-del ch0])
-AT_CHECK([ovn-sbctl -f csv -d bare --no-headings --columns ip,type list encap | sort],
-         [0], [dnl
-1.2.3.5,geneve
-1.2.3.5,stt
-1.2.3.5,vxlan
-])
-
-OVN_SBCTL_TEST_STOP
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-AT_CLEANUP
-
-dnl ---------------------------------------------------------------------
-
-AT_SETUP([ovn-sbctl])
-OVN_SBCTL_TEST_START
-
-AT_CHECK([ovn-nbctl ls-add br-test])
-AT_CHECK([ovn-nbctl lsp-add br-test vif0])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif0 f0:ab:cd:ef:01:02])
-AT_CHECK([ovn-sbctl chassis-add ch0 stt 1.2.3.5])
-AT_CHECK([ovn-nbctl --wait=sb sync])
-AT_CHECK([ovn-sbctl lsp-bind vif0 ch0])
-
-AT_CHECK([ovn-sbctl show], [0], [dnl
-Chassis ch0
-    Encap stt
-        ip: "1.2.3.5"
-        options: {csum="true"}
-    Port_Binding vif0
-])
-
-# adds another 'vif1'
-AT_CHECK([ovn-nbctl --wait=sb lsp-add br-test vif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses vif1 f0:ab:cd:ef:01:03])
-AT_CHECK([ovn-sbctl lsp-bind vif1 ch0])
-
-AT_CHECK([ovn-sbctl show | sed 's/vif[[0-9]]/vif/'], [0], [dnl
-Chassis ch0
-    Encap stt
-        ip: "1.2.3.5"
-        options: {csum="true"}
-    Port_Binding vif
-    Port_Binding vif
-])
-
-# deletes 'vif1'
-AT_CHECK([ovn-nbctl lsp-del vif1])
-AT_CHECK([ovn-nbctl --wait=sb sync])
-
-AT_CHECK([ovn-sbctl show], [0], [dnl
-Chassis ch0
-    Encap stt
-        ip: "1.2.3.5"
-        options: {csum="true"}
-    Port_Binding vif0
-])
-
-uuid=$(ovn-sbctl --columns=_uuid list Chassis ch0 | cut -d ':' -f2 | tr -d ' ')
-AT_CHECK_UNQUOTED([ovn-sbctl --columns=logical_port,mac,chassis list Port_Binding], [0], [dnl
-logical_port        : vif0
-mac                 : [["f0:ab:cd:ef:01:02"]]
-chassis             : ${uuid}
-])
-
-# test the passing down of logical port type and options.
-AT_CHECK([ovn-nbctl --wait=sb lsp-add br-test vtep0])
-AT_CHECK([ovn-nbctl lsp-set-type vtep0 vtep])
-AT_CHECK([ovn-nbctl lsp-set-options vtep0 vtep_physical_switch=p0 vtep_logical_switch=l0])
-
-AT_CHECK([ovn-sbctl --timeout=10 wait-until Port_Binding vtep0 options!={}])
-AT_CHECK([ovn-sbctl --columns=logical_port,mac,type,options list Port_Binding vtep0], [0], [dnl
-logical_port        : vtep0
-mac                 : [[]]
-type                : vtep
-options             : {vtep_logical_switch=l0, vtep_physical_switch=p0}
-])
-
-OVN_SBCTL_TEST_STOP
-AT_CLEANUP
-
-dnl ---------------------------------------------------------------------
-
-AT_SETUP([ovn-sbctl - connection])
-OVN_SBCTL_TEST_START
-
-AT_CHECK([ovn-sbctl --inactivity-probe=30000 set-connection ptcp:6641:127.0.0.1 punix:$OVS_RUNDIR/ovnsb_db.sock])
-AT_CHECK([ovn-sbctl list connection | grep inactivity_probe], [0], [dnl
-inactivity_probe    : 30000
-inactivity_probe    : 30000
-])
-
-OVN_SBCTL_TEST_STOP
-AT_CLEANUP
diff --git a/tests/ovn.at b/tests/ovn.at
deleted file mode 100644
index cb380d2..0000000
--- a/tests/ovn.at
+++ /dev/null
@@ -1,14702 +0,0 @@
-# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
-#
-# This compares packets read from PCAP, in pcap format, to those read
-# from EXPECTED, which is a text file containing packets as hex
-# strings, one per line.  If PCAP contains fewer packets than
-# EXPECTED, it waits up to 10 seconds for more packets to appear.
-#
-# The implementation is an m4 macro that is mostly implemented in
-# terms of a shell function.  This reduces the size of the generated
-# testsuite file since the shell function is only emitted once even
-# when this macro is invoked many times.
-m4_divert_text([PREPARE_TESTS],
-  [ovn_check_packets__ () {
-     echo
-     echo "checking packets in $1 against $2:"
-     rcv_pcap=$1
-     rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
-     exp_text=$2
-     exp_n=`wc -l < "$exp_text"`
-     OVS_WAIT_UNTIL(
-       [$PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
-        rcv_n=`wc -l < "$rcv_text"`
-        echo "rcv_n=$rcv_n exp_n=$exp_n"
-        test $rcv_n -ge $exp_n])
-     sort $exp_text > expout
-   }
-])
-m4_define([OVN_CHECK_PACKETS],
-  [ovn_check_packets__ "$1" "$2"
-   AT_CHECK([sort $rcv_text], [0], [expout])])
-
-AT_BANNER([OVN components])
-
-AT_SETUP([ovn -- lexer])
-dnl For lines without =>, input and expected output are identical.
-dnl For lines with =>, input precedes => and expected output follows =>.
-AT_DATA([test-cases.txt], [dnl
-foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
-"abc\u0020def" => "abc def"
-" => error("Input ends inside quoted string.")dnl "
-
-$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
-$1 => error("`$' must be followed by a valid identifier.") 1
-
-a/*b*/c => a c
-a//b c => a
-a/**/b => a b
-a/*/b => a error("`/*' without matching `*/'.")
-a/*/**/b => a b
-a/b => a error("`/' is only valid as part of `//' or `/*'.") b
-
-0 1 12345 18446744073709551615
-18446744073709551616 => error("Decimal constants must be less than 2**64.")
-9999999999999999999999 => error("Decimal constants must be less than 2**64.")
-01 => error("Decimal constants must not have leading zeros.")
-
-0/0
-0/1
-1/0 => error("Value contains unmasked 1-bits.")
-1/1
-128/384
-1/3
-1/ => error("Integer constant expected.")
-
-1/0x123 => error("Value and mask have incompatible formats.")
-
-0x1234
-0x01234 => 0x1234
-0x0 => 0
-0x000 => 0
-0xfedcba9876543210
-0XFEDCBA9876543210 => 0xfedcba9876543210
-0xfedcba9876543210fedcba9876543210
-0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
-0x => error("Hex digits expected following 0x.")
-0X => error("Hex digits expected following 0X.")
-0x0/0x0 => 0/0
-0x0/0x1 => 0/0x1
-0x1/0x0 => error("Value contains unmasked 1-bits.")
-0xffff/0x1ffff
-0x. => error("Invalid syntax in hexadecimal constant.")
-
-192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
-256.1.2.3 => error("Invalid numeric constant.")
-192.168.0.0/16
-192.168.0.0/255.255.0.0 => 192.168.0.0/16
-192.168.0.0/255.255.255.0 => 192.168.0.0/24
-192.168.0.0/255.255.0.255
-192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
-192.168.0.0/32
-192.168.0.0/255.255.255.255 => 192.168.0.0/32
-1.2.3.4:5 => 1.2.3.4 : 5
-
-::
-::1
-ff00::1234 => ff00::1234
-2001:db8:85a3::8a2e:370:7334
-2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
-2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
-::ffff:192.0.2.128
-::ffff:c000:0280 => ::ffff:192.0.2.128
-::1/::1
-::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
-::1/128
-ff00::/8
-ff00::/ff00:: => ff00::/8
-
-01:23:45:67:ab:cd
-01:23:45:67:AB:CD => 01:23:45:67:ab:cd
-fe:dc:ba:98:76:54
-FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
-01:00:00:00:00:00/01:00:00:00:00:00
-ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
-fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
-ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
-fe:x => error("Invalid numeric constant.")
-00:01:02:03:04:x => error("Invalid numeric constant.")
-
-# Test that operators are tokenized as expected, even without white space.
-(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
-& => error("`&' is only valid as part of `&&'.")
-| => error("`|' is only valid as part of `||'.")
-- => error("`-' is only valid as part of `--'.")
-
-^ => error("Invalid character `^' in input.")
-])
-AT_CAPTURE_FILE([input.txt])
-sed 's/ =>.*//' test-cases.txt > input.txt
-sed 's/.* => //' test-cases.txt > expout
-AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
-AT_CLEANUP
-
-dnl The OVN expression parser needs to know what fields overlap with one
-dnl another.  This test therefore verifies that all the smaller registers
-dnl are defined as terms of subfields of the larger ones.
-dnl
-dnl When we add or remove registers this test needs to be updated, of course.
-AT_SETUP([ovn -- registers])
-AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
-[[reg0 = xxreg0[96..127]
-reg1 = xxreg0[64..95]
-reg2 = xxreg0[32..63]
-reg3 = xxreg0[0..31]
-reg4 = xxreg1[96..127]
-reg5 = xxreg1[64..95]
-reg6 = xxreg1[32..63]
-reg7 = xxreg1[0..31]
-reg8 = xreg4[32..63]
-reg9 = xreg4[0..31]
-xreg0 = xxreg0[64..127]
-xreg1 = xxreg0[0..63]
-xreg2 = xxreg1[64..127]
-xreg3 = xxreg1[0..63]
-xreg4 = OXM_OF_PKT_REG4
-xxreg0 = NXM_NX_XXREG0
-xxreg1 = NXM_NX_XXREG1
-]])
-AT_CLEANUP
-
-dnl Check that the OVN conntrack field definitions are correct.
-AT_SETUP([ovn -- conntrack fields])
-AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
-[[ct.dnat = ct_state[7]
-ct.est = ct_state[1]
-ct.inv = ct_state[4]
-ct.new = ct_state[0]
-ct.rel = ct_state[2]
-ct.rpl = ct_state[3]
-ct.snat = ct_state[6]
-ct.trk = ct_state[5]
-ct_label = NXM_NX_CT_LABEL
-ct_label.blocked = ct_label[0]
-ct_mark = NXM_NX_CT_MARK
-ct_state = NXM_NX_CT_STATE
-]])
-AT_CLEANUP
-
-AT_SETUP([ovn -- composition])
-AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
-AT_CLEANUP
-
-AT_SETUP([ovn -- expression parser])
-dnl For lines without =>, input and expected output are identical.
-dnl For lines with =>, input precedes => and expected output follows =>.
-AT_DATA([test-cases.txt], [[
-eth.type == 0x800
-eth.type==0x800 => eth.type == 0x800
-eth.type[0..15] == 0x800 => eth.type == 0x800
-
-vlan.present
-vlan.present == 1 => vlan.present
-!(vlan.present == 0) => vlan.present
-!(vlan.present != 1) => vlan.present
-!vlan.present
-vlan.present == 0 => !vlan.present
-vlan.present != 1 => !vlan.present
-!(vlan.present == 1) => !vlan.present
-!(vlan.present != 0) => !vlan.present
-
-eth.dst[0]
-eth.dst[0] == 1 => eth.dst[0]
-eth.dst[0] != 0 => eth.dst[0]
-!(eth.dst[0] == 0) => eth.dst[0]
-!(eth.dst[0] != 1) => eth.dst[0]
-
-!eth.dst[0]
-eth.dst[0] == 0 => !eth.dst[0]
-eth.dst[0] != 1 => !eth.dst[0]
-!(eth.dst[0] == 1) => !eth.dst[0]
-!(eth.dst[0] != 0) => !eth.dst[0]
-
-vlan.tci[12..15] == 0x3
-vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
-vlan.tci[12..15] != 0x3
-vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
-
-!vlan.pcp => vlan.pcp == 0
-!(vlan.pcp) => vlan.pcp == 0
-vlan.pcp == 0x4
-vlan.pcp != 0x4
-vlan.pcp > 0x4
-vlan.pcp >= 0x4
-vlan.pcp < 0x4
-vlan.pcp <= 0x4
-!(vlan.pcp != 0x4) => vlan.pcp == 0x4
-!(vlan.pcp == 0x4) => vlan.pcp != 0x4
-!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
-!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
-!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
-!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
-0x4 == vlan.pcp => vlan.pcp == 0x4
-0x4 != vlan.pcp => vlan.pcp != 0x4
-0x4 < vlan.pcp => vlan.pcp > 0x4
-0x4 <= vlan.pcp => vlan.pcp >= 0x4
-0x4 > vlan.pcp => vlan.pcp < 0x4
-0x4 >= vlan.pcp => vlan.pcp <= 0x4
-!(0x4 != vlan.pcp) => vlan.pcp == 0x4
-!(0x4 == vlan.pcp) => vlan.pcp != 0x4
-!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
-!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
-!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
-!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
-
-1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
-1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
-1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
-1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
-1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
-4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
-4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
-4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
-4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
-!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
-!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
-!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
-!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
-!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
-!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
-!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
-!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
-!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
-
-vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
-vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
-
-vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
-vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
-
-vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
-vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
-vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
-
-ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
-ip6.src == ::1 => ip6.src == 0x1
-
-ip4.src == 1.2.3.4 => ip4.src == 0x1020304
-ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
-ip6.src == ::1 => ip6.src == 0x1
-
-1
-0
-!1 => 0
-!0 => 1
-
-inport == "eth0"
-!(inport != "eth0") => inport == "eth0"
-
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0
-
-ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
-inport == 1 => String field inport is not compatible with integer constant.
-ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
-
-ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
-eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
-vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
-
-inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
-!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
-eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
-!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
-inport = "eth0" => Syntax error at `=' expecting relational operator.
-
-123 == 123 => Syntax error at `123' expecting field name.
-
-$name => Syntax error at `$name' expecting address set name.
-@name => Syntax error at `@name' expecting port group name.
-
-123 == xyzzy => Syntax error at `xyzzy' expecting field name.
-xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
-
-inport[1] == 1 => Cannot select subfield of string field inport.
-
-eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
-eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
-eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
-
-eth.type[5!] => Syntax error at `!' expecting `@:>@'.
-
-eth.type[5..1] => Invalid bit range 5 to 1.
-
-eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
-
-eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
-
-eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
-
-!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
-
-123 => Syntax error at end of input expecting relational operator.
-
-123 x => Syntax error at `x' expecting relational operator.
-
-{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
-
-eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
-
-(1 x) => Syntax error at `x' expecting `)'.
-
-!0x800 != eth.type => Missing parentheses around operand of !.
-
-eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
-
-eth.dst == {} => Syntax error at `}' expecting constant.
-
-eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants.  Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
-
-ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
-
-1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
-
-eth.dst[40] x => Syntax error at `x' expecting end of input.
-
-ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
-eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
-
-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
-
-ct_label > $set4 => Only == and != operators may be used to compare a field against an empty value set.
-]])
-sed 's/ =>.*//' test-cases.txt > input.txt
-sed 's/.* => //' test-cases.txt > expout
-AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
-AT_CLEANUP
-
-AT_SETUP([ovn -- expression annotation])
-dnl Input precedes =>, expected output follows =>.
-dnl Empty lines and lines starting with # are ignored.
-AT_DATA([test-cases.txt], [[
-ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
-ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
-ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
-ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
-ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
-
-# Nested expressions over a single symbol should be annotated with symbol's
-# prerequisites only once, at the top level.
-tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-
-ip => eth.type == 0x800 || eth.type == 0x86dd
-ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
-ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
-ip > 0 => Only == and != operators may be used with nominal field ip.
-!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
-ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
-
-vlan.present => vlan.tci[12]
-!vlan.present => !vlan.tci[12]
-
-!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
-vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
-!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
-
-ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
-!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
-ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
-
-bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
-self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
-mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
-mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
-]])
-sed 's/ =>.*//' test-cases.txt > input.txt
-sed 's/.* => //' test-cases.txt > expout
-AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 1-term expression conversion])
-AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
-  [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2-term expression conversion])
-AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
-  [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 3-term expression conversion])
-AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
-  [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 3-term numeric expression simplification])
-AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
-  [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term string expression simplification])
-AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
-  [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 3-term mixed expression simplification])
-AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
-  [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- simplification special cases])
-simplify() {
-    echo "$1" | ovstest test-ovn simplify-expr
-}
-AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
-])
-AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
-])
-AT_CHECK([simplify 'tcp.dst >= 0'], [0],
-    [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-])
-AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
-    [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-])
-AT_CHECK([simplify 'tcp.dst > 0'], [0],
-    [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-]])
-AT_CHECK([simplify 'tcp.dst < 65535'], [0],
-    [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-]])
-AT_CLEANUP
-
-AT_SETUP([ovn -- is_chassis_resident simplification])
-simplify() {
-    echo "$1" | ovstest test-ovn simplify-expr
-}
-AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
-])
-AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
-])
-AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
-])
-AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term numeric expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
-  [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term string expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
-  [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term mixed expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
-  [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 5-term numeric expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
-  [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 5-term string expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
-  [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 5-term mixed expression normalization])
-AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
-  [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term numeric expressions to flows])
-AT_KEYWORDS([expression])
-AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
-  [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term string expressions to flows])
-AT_KEYWORDS([expression])
-AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
-  [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4-term mixed expressions to flows])
-AT_KEYWORDS([expression])
-AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
-  [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 3-term numeric expressions to flows])
-AT_KEYWORDS([expression])
-AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
-  [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- converting expressions to flows -- string fields])
-AT_KEYWORDS([expression])
-expr_to_flow () {
-    echo "$1" | ovstest test-ovn expr-to-flows | sort
-}
-AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
-])
-AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
-])
-AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
-])
-AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
-ip,reg14=0x5
-ipv6,reg14=0x5
-])
-AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
-ip,reg14=0x6
-ipv6,reg14=0x6
-])
-AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
-])
-AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
-[reg14=0x5
-reg14=0x6
-reg14=0xfffe
-])
-AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
-ip,reg14=0x5
-ip,reg14=0x6
-ipv6,reg14=0x5
-ipv6,reg14=0x6
-])
-AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
-(no flows)
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- converting expressions to flows -- address sets])
-AT_KEYWORDS([expression])
-expr_to_flow () {
-    echo "$1" | ovstest test-ovn expr-to-flows | sort
-}
-AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
-ip,nw_src=10.0.0.1
-ip,nw_src=10.0.0.2
-ip,nw_src=10.0.0.3
-])
-AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
-ip,nw_src=10.0.0.1
-ip,nw_src=10.0.0.2
-ip,nw_src=10.0.0.3
-])
-AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
-ip,nw_src=1.2.3.4
-ip,nw_src=10.0.0.1
-ip,nw_src=10.0.0.2
-ip,nw_src=10.0.0.3
-])
-AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
-ip,nw_src=1.2.0.0/20
-ip,nw_src=10.0.0.1
-ip,nw_src=10.0.0.2
-ip,nw_src=10.0.0.3
-ip,nw_src=5.5.5.0/24
-])
-AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
-ipv6,ipv6_src=::1
-ipv6,ipv6_src=::2
-ipv6,ipv6_src=::3
-])
-AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
-ipv6,ipv6_src=::1
-ipv6,ipv6_src=::2
-ipv6,ipv6_src=::3
-ipv6,ipv6_src=::4
-])
-AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
-dl_src=00:00:00:00:00:01
-dl_src=00:00:00:00:00:02
-dl_src=00:00:00:00:00:03
-])
-AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
-dl_src=00:00:00:00:00:01
-dl_src=00:00:00:00:00:02
-dl_src=00:00:00:00:00:03
-])
-AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
-dl_src=00:00:00:00:00:01
-dl_src=00:00:00:00:00:02
-dl_src=00:00:00:00:00:03
-dl_src=ba:be:be:ef:de:ad
-])
-AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
-(no flows)
-])
-AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
-ip,nw_src=1.2.3.4
-])
-AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
-ip,nw_src=1.2.3.4
-])
-AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
-
-])
-AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
-ip,nw_src=0.0.0.0/1.0.0.0
-ip,nw_src=128.0.0.0/1
-ip,nw_src=16.0.0.0/16.0.0.0
-ip,nw_src=2.0.0.0/2.0.0.0
-ip,nw_src=32.0.0.0/32.0.0.0
-ip,nw_src=4.0.0.0/4.0.0.0
-ip,nw_src=64.0.0.0/64.0.0.0
-ip,nw_src=8.0.0.0/8.0.0.0
-])
-AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
-ip,nw_src=0.0.0.0/1.0.0.0
-ip,nw_src=128.0.0.0/1
-ip,nw_src=16.0.0.0/16.0.0.0
-ip,nw_src=2.0.0.0/2.0.0.0
-ip,nw_src=32.0.0.0/32.0.0.0
-ip,nw_src=4.0.0.0/4.0.0.0
-ip,nw_src=64.0.0.0/64.0.0.0
-ip,nw_src=8.0.0.0/8.0.0.0
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- converting expressions to flows -- port groups])
-AT_KEYWORDS([expression])
-expr_to_flow () {
-    echo "$1" | ovstest test-ovn expr-to-flows | sort
-}
-AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
-reg15=0x11
-reg15=0x12
-reg15=0x13
-])
-AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
-(no flows)
-])
-AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
-reg15=0x11
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- converting expressions to flows -- conjunction])
-AT_KEYWORDS([conjunction])
-expr_to_flow () {
-    echo "$1" | ovstest test-ovn expr-to-flows | sort
-}
-
-lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
-ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
-AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
-conj_id=1,ip
-ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
-ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
-ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
-ip,nw_src=10.0.0.1: conjunction(1, 1/2)
-ip,nw_src=10.0.0.2: conjunction(1, 1/2)
-ip,nw_src=10.0.0.3: conjunction(1, 1/2)
-])
-
-lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
-AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
-ct_state=+est+trk,ct_label=0x1/0x1,ip
-ct_state=+est+trk,ct_label=0x1/0x1,ipv6
-ct_state=-est+trk,ip
-ct_state=-est+trk,ipv6
-])
-
-lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
-ip4.dst == {20.0.0.1, 20.0.0.2}"
-AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
-conj_id=1,ip
-ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
-ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
-ip,nw_src=10.0.0.1: conjunction(1, 1/2)
-ip,nw_src=10.0.0.2: conjunction(1, 1/2)
-ip,nw_src=10.0.0.3: conjunction(1, 1/2)
-])
-
-lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
-ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
-tcp.dst >= 1000 && tcp.dst <= 1010"
-
-AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
-conj_id=1,tcp
-tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
-tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
-tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
-tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
-tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
-tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
-tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
-tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
-tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
-tcp,tp_dst=1000: conjunction(1, 2/3)
-tcp,tp_dst=1001: conjunction(1, 2/3)
-tcp,tp_dst=1010: conjunction(1, 2/3)
-])
-
-lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
-((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
-tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
-|| ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
-
-AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
-conj_id=1,tcp
-ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
-ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
-ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
-ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
-ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
-ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
-tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
-tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
-tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
-tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
-tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
-tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
-tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
-tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
-tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
-tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
-tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
-tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
-tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
-tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
-tcp,tp_dst=1000: conjunction(1, 2/4)
-tcp,tp_dst=1001: conjunction(1, 2/4)
-tcp,tp_dst=2000: conjunction(1, 2/4)
-tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
-tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
-tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
-tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
-tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
-tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
-tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
-tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
-tcp,tp_src=1000: conjunction(1, 3/4)
-tcp,tp_src=1001: conjunction(1, 3/4)
-tcp,tp_src=2000: conjunction(1, 3/4)
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- action parsing])
-dnl Unindented text is input (a set of OVN logical actions).
-dnl Indented text is expected output.
-AT_DATA([test-cases.txt],
-[[# drop
-drop;
-    encodes as drop
-drop; next;
-    Syntax error at `next' expecting end of input.
-next; drop;
-    Syntax error at `drop' expecting action.
-
-# output
-output;
-    encodes as resubmit(,64)
-
-# next
-next;
-    encodes as resubmit(,19)
-next(11);
-    formats as next;
-    encodes as resubmit(,19)
-next(0);
-    encodes as resubmit(,8)
-next(23);
-    encodes as resubmit(,31)
-
-next();
-    Syntax error at `)' expecting "pipeline" or "table".
-next(10;
-    Syntax error at `;' expecting `)'.
-next(24);
-    "next" action cannot advance beyond table 23.
-
-next(table=11);
-    formats as next;
-    encodes as resubmit(,19)
-next(pipeline=ingress);
-    formats as next;
-    encodes as resubmit(,19)
-next(table=11, pipeline=ingress);
-    formats as next;
-    encodes as resubmit(,19)
-next(pipeline=ingress, table=11);
-    formats as next;
-    encodes as resubmit(,19)
-
-next(pipeline=egress);
-    "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
-
-next(table=10);
-    formats as next(10);
-    encodes as resubmit(,18)
-
-# Loading a constant value.
-tcp.dst=80;
-    formats as tcp.dst = 80;
-    encodes as set_field:80->tcp_dst
-    has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
-eth.dst[40] = 1;
-    encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
-vlan.pcp = 2;
-    encodes as set_field:0x4000/0xe000->vlan_tci
-    has prereqs vlan.tci[12]
-vlan.tci[13..15] = 2;
-    encodes as set_field:0x4000/0xe000->vlan_tci
-inport = "";
-    encodes as set_field:0->reg14
-ip.ttl=4;
-    formats as ip.ttl = 4;
-    encodes as set_field:4->nw_ttl
-    has prereqs eth.type == 0x800 || eth.type == 0x86dd
-outport="eth0"; next; outport="LOCAL"; next;
-    formats as outport = "eth0"; next; outport = "LOCAL"; next;
-    encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
-
-inport[1] = 1;
-    Cannot select subfield of string field inport.
-ip.proto[1] = 1;
-    Cannot select subfield of nominal field ip.proto.
-eth.dst[40] == 1;
-    Syntax error at `==' expecting `=' or `<->'.
-ip = 1;
-    Predicate symbol ip used where lvalue required.
-ip.proto = 6;
-    Field ip.proto is not modifiable.
-inport = {"a", "b"};
-    Syntax error at `{' expecting constant.
-inport = {};
-    Syntax error at `{' expecting constant.
-bad_prereq = 123;
-    Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
-self_recurse = 123;
-    Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
-vlan.present = 0;
-    Predicate symbol vlan.present used where lvalue required.
-
-# Moving one field into another.
-reg0=reg1;
-    formats as reg0 = reg1;
-    encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
-vlan.pcp = reg0[0..2];
-    encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
-    has prereqs vlan.tci[12]
-reg0[10] = vlan.pcp[1];
-    encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
-    has prereqs vlan.tci[12]
-outport = inport;
-    encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
-
-reg0[0] = vlan.present;
-    Predicate symbol vlan.present used where lvalue required.
-reg0 = reg1[0..10];
-    Can't assign 11-bit value to 32-bit destination.
-inport = reg0;
-    Can't assign integer field (reg0) to string field (inport).
-inport = big_string;
-    String fields inport and big_string are incompatible for assignment.
-ip.proto = reg0[0..7];
-    Field ip.proto is not modifiable.
-
-# Exchanging fields.
-reg0 <-> reg1;
-    encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
-vlan.pcp <-> reg0[0..2];
-    encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
-    has prereqs vlan.tci[12]
-reg0[10] <-> vlan.pcp[1];
-    encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
-    has prereqs vlan.tci[12]
-outport <-> inport;
-    encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
-
-reg0[0] <-> vlan.present;
-    Predicate symbol vlan.present used where lvalue required.
-reg0 <-> reg1[0..10];
-    Can't exchange 32-bit field with 11-bit field.
-inport <-> reg0;
-    Can't exchange string field (inport) with integer field (reg0).
-inport <-> big_string;
-    String fields inport and big_string are incompatible for exchange.
-ip.proto <-> reg0[0..7];
-    Field ip.proto is not modifiable.
-reg0[0..7] <-> ip.proto;
-    Field ip.proto is not modifiable.
-
-# TTL decrement.
-ip.ttl--;
-    encodes as dec_ttl
-    has prereqs ip
-ip.ttl
-    Syntax error at end of input expecting `--'.
-
-# load balancing.
-ct_lb;
-    encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
-    has prereqs ip
-ct_lb();
-    formats as ct_lb;
-    encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
-    has prereqs ip
-ct_lb(192.168.1.2:80, 192.168.1.3:80);
-    encodes as group:1
-    has prereqs ip
-ct_lb(192.168.1.2, 192.168.1.3, );
-    formats as ct_lb(192.168.1.2, 192.168.1.3);
-    encodes as group:2
-    has prereqs ip
-ct_lb(fd0f::2, fd0f::3, );
-    formats as ct_lb(fd0f::2, fd0f::3);
-    encodes as group:3
-    has prereqs ip
-
-ct_lb(192.168.1.2:);
-    Syntax error at `)' expecting port number.
-ct_lb(192.168.1.2:123456);
-    Syntax error at `123456' expecting port number.
-ct_lb(foo);
-    Syntax error at `foo' expecting IP address.
-ct_lb([192.168.1.2]);
-    Syntax error at `192.168.1.2' expecting IPv6 address.
-
-# ct_next
-ct_next;
-    encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
-    has prereqs ip
-
-# ct_commit
-ct_commit;
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15])
-    has prereqs ip
-ct_commit();
-    formats as ct_commit;
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15])
-    has prereqs ip
-ct_commit(ct_mark=1);
-    formats as ct_commit(ct_mark=0x1);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
-    has prereqs ip
-ct_commit(ct_mark=1/1);
-    formats as ct_commit(ct_mark=0x1/0x1);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
-    has prereqs ip
-ct_commit(ct_label=1);
-    formats as ct_commit(ct_label=0x1);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
-    has prereqs ip
-ct_commit(ct_label=1/1);
-    formats as ct_commit(ct_label=0x1/0x1);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
-    has prereqs ip
-ct_commit(ct_mark=1, ct_label=2);
-    formats as ct_commit(ct_mark=0x1, ct_label=0x2);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
-    has prereqs ip
-
-ct_commit(ct_label=0x01020304050607080910111213141516);
-    formats as ct_commit(ct_label=0x1020304050607080910111213141516);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
-    has prereqs ip
-ct_commit(ct_label=0x181716151413121110090807060504030201);
-    formats as ct_commit(ct_label=0x16151413121110090807060504030201);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
-    has prereqs ip
-ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
-    has prereqs ip
-ct_commit(ct_label=18446744073709551615);
-    formats as ct_commit(ct_label=0xffffffffffffffff);
-    encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
-    has prereqs ip
-ct_commit(ct_label=18446744073709551616);
-    Decimal constants must be less than 2**64.
-
-# ct_dnat
-ct_dnat;
-    encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
-    has prereqs ip
-ct_dnat(192.168.1.2);
-    encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
-    has prereqs ip
-
-ct_dnat(192.168.1.2, 192.168.1.3);
-    Syntax error at `,' expecting `)'.
-ct_dnat(foo);
-    Syntax error at `foo' expecting IPv4 address.
-ct_dnat(foo, bar);
-    Syntax error at `foo' expecting IPv4 address.
-ct_dnat();
-    Syntax error at `)' expecting IPv4 address.
-
-# ct_snat
-ct_snat;
-    encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
-    has prereqs ip
-ct_snat(192.168.1.2);
-    encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
-    has prereqs ip
-
-ct_snat(192.168.1.2, 192.168.1.3);
-    Syntax error at `,' expecting `)'.
-ct_snat(foo);
-    Syntax error at `foo' expecting IPv4 address.
-ct_snat(foo, bar);
-    Syntax error at `foo' expecting IPv4 address.
-ct_snat();
-    Syntax error at `)' expecting IPv4 address.
-
-# ct_clear
-ct_clear;
-    encodes as ct_clear
-
-# clone
-clone { ip4.dst = 255.255.255.255; output; }; next;
-    encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
-    has prereqs eth.type == 0x800
-
-# arp
-arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
-    encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip4
-arp { };
-    formats as arp { drop; };
-    encodes as controller(userdata=00.00.00.00.00.00.00.00)
-    has prereqs ip4
-
-# get_arp
-get_arp(outport, ip4.dst);
-    encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
-    has prereqs eth.type == 0x800
-get_arp(inport, reg0);
-    encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
-
-get_arp;
-    Syntax error at `;' expecting `('.
-get_arp();
-    Syntax error at `)' expecting field name.
-get_arp(inport);
-    Syntax error at `)' expecting `,'.
-get_arp(inport ip4.dst);
-    Syntax error at `ip4.dst' expecting `,'.
-get_arp(inport, ip4.dst;
-    Syntax error at `;' expecting `)'.
-get_arp(inport, eth.dst);
-    Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
-get_arp(inport, outport);
-    Cannot use string field outport where numeric field is required.
-get_arp(reg0, ip4.dst);
-    Cannot use numeric field reg0 where string field is required.
-
-# put_arp
-put_arp(inport, arp.spa, arp.sha);
-    encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
-    has prereqs eth.type == 0x806 && eth.type == 0x806
-
-# put_dhcp_opts
-reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
-    encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
-reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot");
-    formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain_name = "ovn.org", wpad = "https://example.org", bootfile_name = "https://127.0.0.1/boot.ipxe", path_prefix = "/tftpboot");
-    encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
-reg0[15] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0,tftp_server_address={10.0.0.4,10.0.0.5});
-    formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0, tftp_server_address = {10.0.0.4, 10.0.0.5});
-    encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00.96.08.0a.00.00.04.0a.00.00.05,pause)
-
-reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
-    Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
-reg1[0] = put_dhcp_opts();
-    put_dhcp_opts requires offerip to be specified.
-reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
-    Syntax error at `x' expecting DHCPv4 option name.
-reg1[0] = put_dhcp_opts(router = 10.0.0.1);
-    put_dhcp_opts requires offerip to be specified.
-reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
-    Syntax error at `"hi"'.
-reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
-    Syntax error at `xyzzy' expecting DHCPv4 option name.
-reg1[0] = put_dhcp_opts(offerip="xyzzy");
-    DHCPv4 option offerip requires numeric value.
-reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain_name=1.2.3.4);
-    DHCPv4 option domain_name requires string value.
-
-# nd_ns
-nd_ns { nd.target = xxreg0; output; };
-    encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
-    has prereqs ip6
-
-nd_ns { };
-    formats as nd_ns { drop; };
-    encodes as controller(userdata=00.00.00.09.00.00.00.00)
-    has prereqs ip6
-
-# nd_na
-nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
-    formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
-    encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
-    has prereqs nd_ns
-# nd_na_router
-nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
-    formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
-    encodes as controller(userdata=00.00.00.0c.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
-    has prereqs nd_ns
-
-# get_nd
-get_nd(outport, ip6.dst);
-    encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
-    has prereqs eth.type == 0x86dd
-get_nd(inport, xxreg0);
-    encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
-get_nd;
-    Syntax error at `;' expecting `('.
-get_nd();
-    Syntax error at `)' expecting field name.
-get_nd(inport);
-    Syntax error at `)' expecting `,'.
-get_nd(inport ip6.dst);
-    Syntax error at `ip6.dst' expecting `,'.
-get_nd(inport, ip6.dst;
-    Syntax error at `;' expecting `)'.
-get_nd(inport, eth.dst);
-    Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
-get_nd(inport, outport);
-    Cannot use string field outport where numeric field is required.
-get_nd(xxreg0, ip6.dst);
-    Cannot use numeric field xxreg0 where string field is required.
-
-# put_nd
-put_nd(inport, nd.target, nd.sll);
-    encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
-    has prereqs (icmp6.type == 0x87 || icmp6.type == 0x88) && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
-
-# put_dhcpv6_opts
-reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
-    encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
-reg1[0] = put_dhcpv6_opts();
-    encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
-reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
-    formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
-    encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
-reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
-    formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
-    encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
-reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
-    encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
-reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
-    Syntax error at `x' expecting DHCPv6 option name.
-reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
-    Syntax error at `"hi"'.
-reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
-    Syntax error at `xyzzy' expecting DHCPv6 option name.
-reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
-    DHCPv6 option ia_addr requires numeric value.
-reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
-    DHCPv6 option domain_search requires string value.
-
-# set_queue
-set_queue(0);
-    encodes as set_queue:0
-set_queue(61440);
-    encodes as set_queue:61440
-set_queue(65535);
-    Queue ID 65535 for set_queue is not in valid range 0 to 61440.
-
-# dns_lookup
-reg1[0] = dns_lookup();
-    encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
-    has prereqs udp
-reg1[0] = dns_lookup("foo");
-    dns_lookup doesn't take any parameters
-
-# set_meter
-set_meter(0);
-    Rate 0 for set_meter is not in valid.
-set_meter(1);
-    encodes as meter:1
-set_meter(100, 1000);
-    encodes as meter:2
-set_meter(100, 1000, );
-    Syntax error at `,' expecting `)'.
-set_meter(4294967295, 4294967295);
-    encodes as meter:3
-
-# log
-log(verdict=allow, severity=warning);
-    encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
-log(name="test1", verdict=drop, severity=info);
-    encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
-log(verdict=drop, severity=info, meter="meter1");
-    encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
-log(name="test1", verdict=drop, severity=info, meter="meter1");
-    encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
-log(verdict=drop);
-    formats as log(verdict=drop, severity=info);
-    encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
-log(verdict=bad_verdict, severity=info);
-    Syntax error at `bad_verdict' unknown verdict.
-log(verdict=drop, severity=bad_severity);
-    Syntax error at `bad_severity' unknown severity.
-log(severity=notice);
-    Syntax error at `;' expecting verdict.
-
-# put_nd_ra_opts
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
-    encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
-    has prereqs ip6
-reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
-    encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
-    has prereqs ip6
-reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
-    encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
-    has prereqs ip6
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
-    slla option not present
-reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
-    encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
-    has prereqs ip6
-reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
-    encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
-    has prereqs ip6
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
-    prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
-reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
-    prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
-reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
-    Syntax error at `dhcpv6_stateless' expecting constant.
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
-    Invalid value for "prefix" option
-reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
-    Invalid value for "addr_mode" option
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
-    IPv6 ND RA option mtu requires numeric value.
-reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
-    Invalid value for "mtu" option
-
-# icmp4
-icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
-    encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip4
-
-icmp4 { };
-    formats as icmp4 { drop; };
-    encodes as controller(userdata=00.00.00.0a.00.00.00.00)
-    has prereqs ip4
-
-# icmp4 with icmp4.frag_mtu
-icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
-    encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip4
-
-# icmp4_error
-icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
-    encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip4
-
-icmp4_error { };
-    formats as icmp4_error { drop; };
-    encodes as controller(userdata=00.00.00.0e.00.00.00.00)
-    has prereqs ip4
-
-# icmp4_error with icmp4.frag_mtu
-icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
-    encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip4
-
-icmp4.frag_mtu = 1500;
-    encodes as controller(userdata=00.00.00.0d.00.00.00.00.05.dc,pause)
-
-# icmp6
-icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
-    encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs ip6
-
-icmp6 { };
-    formats as icmp6 { drop; };
-    encodes as controller(userdata=00.00.00.0a.00.00.00.00)
-    has prereqs ip6
-
-# tcp_reset
-tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
-    encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
-    has prereqs tcp
-
-tcp_reset { };
-    formats as tcp_reset { drop; };
-    encodes as controller(userdata=00.00.00.0b.00.00.00.00)
-    has prereqs tcp
-
-# trigger_event
-trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c");
-    encodes as controller(userdata=00.00.00.0f.00.00.00.00.00.00.00.00.00.01.00.0b.31.30.2e.30.2e.30.2e.31.3a.38.30.00.02.00.03.74.63.70.00.03.00.24.31.32.33.34.35.36.37.38.2d.61.62.63.64.2d.39.38.37.36.2d.66.65.64.63.2d.31.31.31.31.39.66.38.65.37.64.36.63)
-
-# Testing invalid vip results in extra error messages from socket-util.c
-trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "sctp", load_balancer = "12345678-abcd-9876-fedc-11119f8e7d6c");
-    Load balancer protocol 'sctp' is not 'tcp' or 'udp'
-trigger_event(event = "empty_lb_backends", vip = "10.0.0.1:80", protocol = "tcp", load_balancer = "bacon");
-    Load balancer 'bacon' is not a UUID
-
-# IGMP
-igmp;
-    encodes as controller(userdata=00.00.00.10.00.00.00.00)
-
-# Contradictionary prerequisites (allowed but not useful):
-ip4.src = ip6.src[0..31];
-    encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
-    has prereqs eth.type == 0x800 && eth.type == 0x86dd
-ip4.src <-> ip6.src[0..31];
-    encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
-    has prereqs eth.type == 0x800 && eth.type == 0x86dd
-
-# check_pkt_larger
-reg0[0] = check_pkt_larger(1500);
-    encodes as check_pkt_larger(1500)->NXM_NX_XXREG0[96]
-
-reg0 = check_pkt_larger(1500);
-    Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
-
-reg0 = check_pkt_larger(foo);
-    Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
-
-reg0[0] = check_pkt_larger(foo);
-    Syntax error at `foo' expecting `;'.
-
-# Miscellaneous negative tests.
-;
-    Syntax error at `;'.
-xyzzy;
-    Syntax error at `xyzzy' expecting action.
-next; 123;
-    Syntax error at `123'.
-next; xyzzy;
-    Syntax error at `xyzzy' expecting action.
-next
-    Syntax error at end of input expecting `;'.
-]])
-sed '/^[[ 	]]/d' test-cases.txt > input.txt
-cp test-cases.txt expout
-AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
-AT_CLEANUP
-
-AT_BANNER([OVN end-to-end tests])
-
-# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
-AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
-AT_KEYWORDS([ovnarp])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Create hypervisors hv[123].
-# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
-# Add all of the vifs to a single logical switch lsw0.
-# Turn on port security on all the vifs except vif[123]1.
-# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
-# Add some ACLs for Ethertypes 1234, 1235, 1236.
-ovn-nbctl ls-add lsw0
-net_add n1
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2 3; do
-        ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
-        ovn-nbctl lsp-add lsw0 lp$i$j
-        if test $j = 1; then
-            ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
-        else
-            if test $j = 3; then
-                ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
-            else
-                ip_addrs="192.168.0.$i$j"
-            fi
-            ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
-            ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
-        fi
-    done
-done
-ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
-ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
-ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
-ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:00:00:00:21\",\"f0:00:00:00:00:31\"
-ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
-
-get_lsp_uuid () {
-    ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
-}
-
-ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
-ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Make sure there is no attempt to adding duplicated flows by ovn-controller
-AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
-AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
-AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv${1%?}
-}
-
-# test_packet INPORT DST SRC ETHTYPE OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        : > $i$j.expected
-    done
-done
-test_packet() {
-    local inport=$1 packet=$2$3$4; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
-    local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-    hv=`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $request
-
-    if test X$reply_ha = X; then
-        # Expect to receive the broadcast ARP on the other logical switch ports
-        # if no reply is expected.
-        local i j
-        for i in 1 2 3; do
-            for j in 1 2 3; do
-                if test $i$j != $inport; then
-                    echo $request >> $i$j.expected
-                fi
-            done
-        done
-    else
-        # Expect to receive the reply, if any.
-        local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
-        echo $reply >> $inport.expected
-    fi
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send packets between all pairs of source and destination ports:
-#
-# 1. Unicast packets are delivered to exactly one logical switch port
-#    (except that packets destined to their input ports are dropped).
-#
-# 2. Broadcast and multicast are delivered to all logical switch ports
-#    except the input port.
-#
-# 3. When port security is turned on, the switch drops packets from the wrong
-#    MAC address.
-#
-# 4. The switch drops all packets with a VLAN tag.
-#
-# 5. The switch drops all packets with a multicast source address.  (This only
-#    affects behavior when port security is turned off, since otherwise port
-#    security would drop the packet anyway.)
-#
-# 6. The switch delivers packets with an unknown destination to logical
-#    switch ports with "unknown" among their MAC addresses (and port
-#    security disabled).
-#
-# 7. The switch drops unicast packets that violate an ACL.
-#
-# 8. The switch drops multicast and broadcast packets that violate an ACL.
-#
-# 9. OVN generates responses to ARP requests for known IPs, except for
-#    requests from a port for the port's own IP.
-#
-# 10. No response to ARP requests for unknown IPs.
-
-for is in 1 2 3; do
-    for js in 1 2 3; do
-        s=$is$js
-        bcast=
-        unknown=
-        bacl2=
-        bacl3=
-        for id in 1 2 3; do
-            for jd in 1 2 3; do
-                d=$id$jd
-
-                if test $d != $s; then unicast=$d; else unicast=; fi
-                test_packet $s f000000000$d f000000000$s $s$d $unicast     #1
-
-                if test $d != $s && test $js = 1; then
-                    impersonate=$d
-                else
-                    impersonate=
-                fi
-                test_packet $s f000000000$d f00000000055 55$d $impersonate #3
-
-                if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
-                if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
-                if test $d = $s || (test $js = 1 && test $d = 33); then
-                    # Source of 11, 21, or 31 and dest of 33 should be dropped
-                    # due to the 4th ACL that uses address_set(set1).
-                    acl4=
-                else
-                    acl4=$d
-                fi
-                if test $d = $s || test $d = 22 || test $d = 33; then
-                    # dest of 22 and 33 should be dropped
-                    # due to the 5th ACL that uses port_group(pg1).
-                    acl5=
-                else
-                    acl5=$d
-                fi
-                test_packet $s f000000000$d f000000000$s 1234        #7, acl1
-                test_packet $s f000000000$d f000000000$s 1235 $acl2  #7, acl2
-                test_packet $s f000000000$d f000000000$s 1236 $acl3  #7, acl3
-                test_packet $s f000000000$d f000000000$s 1237 $acl4  #7, acl4
-                test_packet $s f000000000$d f000000000$s 1238 $acl5  #7, acl5
-
-                test_packet $s f000000000$d f00000000055 810000091234      #4
-                test_packet $s f000000000$d 0100000000$s $s$d              #5
-
-                if test $d != $s && test $jd = 1; then
-                    unknown="$unknown $d"
-                fi
-                bcast="$bcast $unicast"
-                bacl2="$bacl2 $acl2"
-                bacl3="$bacl3 $acl3"
-
-                sip=`ip_to_hex 192 168 0 $is$js`
-                tip=`ip_to_hex 192 168 0 $id$jd`
-                tip_unknown=`ip_to_hex 11 11 11 11`
-                if test $d != $s; then
-                    reply_ha=f000000000$d
-                else
-                    reply_ha=
-                fi
-                test_arp $s f000000000$s $sip $tip $reply_ha               #9
-                test_arp $s f000000000$s $sip $tip_unknown                 #10
-
-                if test $jd = 3; then
-                    # lsp[123]3 has an additional ip 192.169.0.[123]3.
-                    tip=`ip_to_hex 192 169 0 $id$jd`
-                    test_arp $s f000000000$s $sip $tip $reply_ha           #9
-                fi
-            done
-        done
-
-        # Broadcast and multicast.
-        test_packet $s ffffffffffff f000000000$s ${s}ff $bcast             #2
-        test_packet $s 010000000000 f000000000$s ${s}ff $bcast             #2
-        if test $js = 1; then
-            bcast_impersonate=$bcast
-        else
-            bcast_impersonate=
-        fi
-        test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate   #3
-
-        test_packet $s f0000000ffff f000000000$s ${s}66 $unknown           #6
-
-        test_packet $s ffffffffffff f000000000$s 1234                #8, acl1
-        test_packet $s ffffffffffff f000000000$s 1235 $bacl2         #8, acl2
-        test_packet $s ffffffffffff f000000000$s 1236 $bacl3         #8, acl3
-        test_packet $s 010000000000 f000000000$s 1234                #8, acl1
-        test_packet $s 010000000000 f000000000$s 1235 $bacl2         #8, acl2
-        test_packet $s 010000000000 f000000000$s 1236 $bacl3         #8, acl3
-    done
-done
-
-# set address for lp13 with invalid characters.
-# lp13 should be configured with only 192.168.0.13.
-ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-sip=`ip_to_hex 192 168 0 11`
-tip=`ip_to_hex 192 168 0 13`
-test_arp 11 f00000000011  $sip $tip f00000000013
-
-tip=`ip_to_hex 192 169 0 13`
-#arp request for 192.169.0.13 should be flooded
-test_arp 11 f00000000011  $sip $tip
-
-# dump information and flows with counters
-ovn-sbctl dump-flows -- list multicast_group
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
-    done
-done
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-# 2 hypervisors, one logical switch, 2 logical ports per hypervisor
-# logical ports bound to chassis encap-ip.
-AT_SETUP([ovn -- 2 HVs, 1 LS, 2 lports/HV])
-AT_KEYWORDS([ovnarp])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Create hypervisors hv[12].
-# Add vif1[12] to hv1, vif2[12] to hv2
-ovn-nbctl ls-add lsw0
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2; do
-        ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
-        ovn-nbctl lsp-add lsw0 lp$i$j
-        ip_addrs="192.168.0.$i$j"
-        ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
-        ovn-nbctl --wait=hv lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
-    done
-done
-
-get_lsp_uuid () {
-    ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
-}
-
-# XXX-Check how to pass lp$i1 in AT_CHECK_UNQUOTED, for now just do it
-# explictly
-
-# For Chassis hv1
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp11], [0], [dnl
-encap               : [[]]
-])
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp12], [0], [dnl
-encap               : [[]]
-])
-
-# For Chassis hv2
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp21], [0], [dnl
-encap               : [[]]
-])
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp22], [0], [dnl
-encap               : [[]]
-])
-
-# Bind the ports to the encap-ip
-for i in 1 2; do
-    for j in 1 2; do
-        as hv$i
-        ovs-vsctl set Interface vif$i$j external-ids:encap-ip=192.168.0.$i
-    done
-done
-
-sleep 1
-
-# dump port bindings; since we have vxlan and geneve tunnels, we expect the
-# ports to be bound to geneve tunnels.
-
-# For Chassis 1
-encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv1 type=geneve ip=192.168.0.1`
-
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp11], [0], [dnl
-encap               : ${encap_rec}
-])
-
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp12], [0], [dnl
-encap               : ${encap_rec}
-])
-
-# For Chassis 2
-encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv2 type=geneve ip=192.168.0.2`
-
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp21], [0], [dnl
-encap               : ${encap_rec}
-])
-
-AT_CHECK_UNQUOTED([ovn-sbctl  --column encap list port_binding lp22], [0], [dnl
-encap               : ${encap_rec}
-])
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Make sure there is no attempt to adding duplicated flows by ovn-controller
-AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
-AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
-AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv${1%?}
-}
-
-# test_packet INPORT DST SRC ETHTYPE OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
-for i in 1 2; do
-    for j in 1 2; do
-        : > $i$j.expected
-    done
-done
-test_packet() {
-    local inport=$1 packet=$2$3$4; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send packets between all pairs of source and destination ports:
-#
-# 1. Unicast packets are delivered to exactly one logical switch port
-#    (except that packets destined to their input ports are dropped).
-
-for is in 1 2; do
-    for js in 1 2; do
-        s=$is$js
-        bcast=
-        unknown=
-        bacl2=
-        bacl3=
-        for id in 1 2 3; do
-            for jd in 1 2 3; do
-                d=$id$jd
-
-                if test $d != $s; then unicast=$d; else unicast=; fi
-                test_packet $s f000000000$d f000000000$s $s$d $unicast     #1
-            done
-        done
-
-    done
-done
-
-# dump information and flows with counters
-ovn-sbctl dump-flows -- list multicast_group
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2; do
-    for j in 1 2; do
-        OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
-    done
-done
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Create a logical switch and some logical ports.
-# Turn on port security on all lports except ls1.
-# Make ls1 a destination for unknown MACs.
-# Add some ACLs for Ethertypes 1234, 1235, 1236.
-ovn-nbctl ls-add lsw0
-ovn-sbctl chassis-add hv0 geneve 127.0.0.1
-for i in 1 2 3; do
-    ovn-nbctl lsp-add lsw0 lp$i
-done
-ovn-nbctl --wait=sb sync
-for i in 1 2 3; do
-    ovn-sbctl lsp-bind lp$i hv0
-    if test $i = 1; then
-        ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
-    else
-        if test $i = 3; then
-           ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
-        else
-           ip_addrs="192.168.0.$i"
-        fi
-        ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
-        ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
-    fi
-done
-ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
-ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
-ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
-ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
-ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
-
-ovn-nbctl --wait=sb sync
-on_exit 'kill `cat ovn-trace.pid`'
-ovn-trace --detach --pidfile --no-chdir
-
-# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
-test_packet() {
-    local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
-    uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
-    while :; do
-        case $1 in # (
-            -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
-            -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
-            *) break ;;
-        esac
-    done
-    for outport; do
-        echo "output(\"lp$outport\");"
-    done > expout
-
-    AT_CAPTURE_FILE([trace])
-    AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
-}
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
-
-    local request="inport == \"lp$inport\"
-                   && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
-                   && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
-                   && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
-
-    if test -z "$reply_ha"; then
-        reply=
-        local i
-        for i in 1 2 3; do
-            if test $i != $inport; then
-                reply="${reply}output(\"lp$i\");
-"
-            fi
-        done
-    else
-        reply="\
-eth.dst = $sha;
-eth.src = $reply_ha;
-arp.op = 2;
-arp.tha = $sha;
-arp.sha = $reply_ha;
-arp.tpa = $spa;
-arp.spa = $tpa;
-output(\"lp$inport\");
-"
-    fi
-
-    AT_CAPTURE_FILE([trace])
-    AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
-}
-
-# Send packets between all pairs of source and destination ports:
-#
-# 1. Unicast packets are delivered to exactly one logical switch port
-#    (except that packets destined to their input ports are dropped).
-#
-# 2. Broadcast and multicast are delivered to all logical switch ports
-#    except the input port.
-#
-# 3. When port security is turned on, the switch drops packets from the wrong
-#    MAC address.
-#
-# 4. The switch drops all packets with a VLAN tag.
-#
-# 5. The switch drops all packets with a multicast source address.  (This only
-#    affects behavior when port security is turned off, since otherwise port
-#    security would drop the packet anyway.)
-#
-# 6. The switch delivers packets with an unknown destination to logical
-#    switch ports with "unknown" among their MAC addresses (and port
-#    security disabled).
-#
-# 7. The switch drops unicast packets that violate an ACL.
-#
-# 8. The switch drops multicast and broadcast packets that violate an ACL.
-#
-# 9. OVN generates responses to ARP requests for known IPs, except for
-#    requests from a port for the port's own IP.
-#
-# 10. No response to ARP requests for unknown IPs.
-
-for s in 1 2 3; do
-    bcast=
-    unknown=
-    bacl2=
-    bacl3=
-    for d in 1 2 3; do
-        echo
-        echo "lp$s -> lp$d"
-        if test $d != $s; then unicast=$d; else unicast=; fi
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast      #1
-
-        if test $d != $s && test $s = 1; then
-            impersonate=$d
-        else
-            impersonate=
-        fi
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate   #3
-
-        if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
-        if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
-        if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
-            # Source of 1 or 2 and dest of 3 should be dropped
-            # due to the 4th ACL that uses address_set(set1).
-            acl4=
-        else
-            acl4=$d
-        fi
-
-        #7, acl1 to acl4:
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
-
-        test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan          #4
-        test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s               #5
-
-        if test $d != $s && test $d = 1; then
-            unknown="$unknown $d"
-        fi
-        bcast="$bcast $unicast"
-        bacl2="$bacl2 $acl2"
-        bacl3="$bacl3 $acl3"
-
-        sip=192.168.0.$s
-        tip=192.168.0.$d
-        tip_unknown=11.11.11.11
-        if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
-        test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha                 #9
-        test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown                   #10
-
-        if test $d = 3; then
-            # lp3 has an additional ip 192.169.0.[123]3.
-            tip=192.169.0.$d
-            test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha             #9
-        fi
-    done
-
-    # Broadcast and multicast.
-    test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast             #2
-    test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast             #2
-    if test $s = 1; then
-       bcast_impersonate=$bcast
-    else
-       bcast_impersonate=
-    fi
-    test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate  #3
-
-    test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown           #6
-
-    #8, acl1 to acl3:
-    test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
-    test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
-    test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
-
-    #8, acl1 to acl3:
-    test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
-    test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
-    test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
-done
-
-AT_CLEANUP
-
-# 2 hypervisors, 4 logical ports per HV
-# 2 locally attached networks (one flat, one vlan tagged over same device)
-# 2 ports per HV on each network
-AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# In this test cases we create 3 switches, all connected to same
-# physical network (through br-phys on each HV). Each switch has
-# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
-# of VIF port name indicates the hypervisor it is bound to, e.g.
-# lp23 means VIF 3 on hv2.
-#
-# Each switch's VLAN tag and their logical switch ports are:
-#   - ls1:
-#       - untagged
-#       - ports: lp11, lp12, lp21, lp22
-#
-#   - ls2:
-#       - tagged with VLAN 101
-#       - ports: lp13, lp14, lp23, lp24
-#   - ls3:
-#       - untagged
-#       - ports: lp15, lp25
-#
-# Note: a localnet port is created for each switch to connect to
-# physical network.
-
-for i in 1 2 3; do
-    ls_name=ls$i
-    ovn-nbctl ls-add $ls_name
-    ln_port_name=ln$i
-    if test $i -eq 2; then
-        ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
-    else
-        ovn-nbctl lsp-add $ls_name $ln_port_name
-    fi
-    ovn-nbctl lsp-set-addresses $ln_port_name unknown
-    ovn-nbctl lsp-set-type $ln_port_name localnet
-    ovn-nbctl lsp-set-options $ln_port_name network_name=phys
-done
-
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
-    case $1 in dnl (
-        lp?[[12]]) echo ls1 ;; dnl (
-        lp?[[34]]) echo ls2 ;; dnl (
-        lp?5) echo ls3 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2 3 4 5; do
-        ovs-vsctl add-port br-int vif$i$j -- \
-            set Interface vif$i$j external-ids:iface-id=lp$i$j \
-                                  options:tx_pcap=hv$i/vif$i$j-tx.pcap \
-                                  options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
-                                  ofport-request=$i$j
-
-        lsp_name=lp$i$j
-        ls_name=$(lsp_to_ls $lsp_name)
-
-        ovn-nbctl lsp-add $ls_name $lsp_name
-        ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
-        ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
-
-        OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
-    done
-done
-ovn-nbctl --wait=sb sync
-ovn-sbctl dump-flows
-
-OVN_POPULATE_ARP
-
-# XXX This is now the 3rd copy of these functions in this file ...
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv${1%?}
-}
-#
-# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  INPORT is specified as
-# logical switch port numbers, e.g. 11 for vif11.
-#
-# EOUT is the end-to-end output port, that is, where the packet will end up
-# after possibly bouncing through one or more localnet ports.  LOUT is the
-# logical output port, which might be a localnet port, as seen by ovn-trace
-# (which doesn't know what localnet ports are connected to and therefore can't
-# figure out the end-to-end answer).
-for i in 1 2; do
-    for j in 1 2 3 4 5; do
-        : > $i$j.expected
-    done
-done
-test_packet() {
-    local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
-    echo "$@"
-
-    # First try tracing the packet.
-    uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
-    if test $lout != drop; then
-        echo "output(\"$lout\");"
-    fi > expout
-    AT_CAPTURE_FILE([trace])
-    AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
-
-    # Then actually send a packet, for an end-to-end test.
-    local packet=$(echo $dst$src | sed 's/://g')${eth}
-    hv=`vif_to_hv $inport`
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    if test $eout != drop; then
-        echo $packet >> ${eout#lp}.expected
-    fi
-}
-
-# lp11 and lp21 are on the same network (phys, untagged)
-# and on different hypervisors
-test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
-test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
-
-# lp11 and lp12 are on the same network (phys, untagged)
-# and on the same hypervisor
-test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
-test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
-
-# lp13 and lp23 are on the same network (phys, VLAN 101)
-# and on different hypervisors
-test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
-test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
-
-# lp13 and lp14 are on the same network (phys, VLAN 101)
-# and on the same hypervisor
-test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
-test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
-
-# lp11 and lp15 are on the same network (phys, untagged),
-# same hypervisor, and on different switches
-test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
-test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
-
-# lp11 and lp25 are on the same network (phys, untagged),
-# different hypervisors, and on different switches
-test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
-test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
-
-# Ports that should not be able to communicate
-test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
-test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
-test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
-test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
-test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
-test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
-test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
-test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
-
-# Dump a bunch of info helpful for debugging if there's a failure.
-
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2; do
-    for j in 1 2 3 4 5; do
-        OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
-    done
-done
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
-AT_KEYWORDS([vtep])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Configure the Northbound database
-ovn-nbctl ls-add lsw0
-
-ovn-nbctl lsp-add lsw0 lp1
-ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
-
-ovn-nbctl lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
-
-ovn-nbctl lsp-add lsw0 lp-vtep
-ovn-nbctl lsp-set-type lp-vtep vtep
-ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
-ovn-nbctl lsp-set-addresses lp-vtep unknown
-
-# lpr, lr and lrp1 are used for the ARP request handling test only.
-ovn-nbctl lsp-add lsw0 lpr
-ovn-nbctl lr-add lr
-ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
-ovn-nbctl set Logical_Switch_Port lpr type=router \
-                             options:router-port=lrp1 \
-    addresses='"f0:00:00:00:00:f1 192.168.1.1"'
-
-
-net_add n1               # Network to connect hv1, hv2, and vtep
-net_add n2               # Network to connect vtep and hv3
-
-# Create hypervisor hv1 connected to n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
-
-# Create hypervisor hv2 connected to n1
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
-
-
-# Start the vtep emulator with a leg in both networks
-sim_add vtep
-as vtep
-
-ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
-ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
-
-ovs-vsctl add-br br-phys
-net_attach n1 br-phys
-
-mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
-arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
-ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
-ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
-
-ovs-vsctl add-br br-vtep
-net_attach n2 br-vtep
-
-vtep-ctl add-ps br-vtep
-vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
-vtep-ctl add-ls lsw0
-
-start_daemon ovs-vtep br-vtep
-start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-
-OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
-
-OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
-               grep -- source`"])
-# It takes more time for the update to be processed by ovs-vtep.
-sleep 1
-
-# Add hv3 on the other side of the vtep
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-net_attach n2 br-phys
-
-ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# test_packet INPORT DST SRC ETHTYPE OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
-for i in 1 2 3; do
-    : > $i.expected
-done
-test_packet() {
-    local inport=$1 packet=$2$3$4; shift; shift; shift; shift
-    #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
-    hv=hv$inport
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-# Send packets between all pairs of source and destination ports:
-#
-# 1. Unicast packets are delivered to exactly one logical switch port
-#    (except that packets destined to their input ports are dropped).
-#
-# 2. Broadcast and multicast are delivered to all logical switch ports
-#    except the input port.
-#
-# 3. The switch delivers packets with an unknown destination to logical
-#    switch ports with "unknown" among their MAC addresses (and port
-#    security disabled).
-for s in 1 2 3; do
-    bcast=
-    unknown=
-    for d in 1 2 3; do
-        if test $d != $s; then unicast=$d; else unicast=; fi
-        test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast       #1
-
-        # The vtep (vif3) is the only one configured for "unknown"
-        if test $d != $s && test $d = 3; then
-            unknown="$unknown $d"
-        fi
-        bcast="$bcast $unicast"
-    done
-
-    # Broadcast and multicast.
-    test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast             #2
-    test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast             #2
-
-    test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown           #3
-done
-
-# ARP request should not be responded to by logical switch router
-# type arp responder on HV1 and HV2 and should reach directly to
-# vif1 and vif2
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-sha=f00000000003
-spa=`ip_to_hex 192 168 1 2`
-tpa=`ip_to_hex 192 168 1 1`
-request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-as hv3 ovs-appctl netdev-dummy/receive vif3 $request
-echo $request >> 1.expected
-echo $request >> 2.expected
-
-# dump information with counters
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 show br-int
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-ofctl -O OpenFlow13 show br-int
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-# note: hv3 has no logical port bind, thus it should not have br-int
-AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
-[ovs-ofctl: br-int is not a bridge or a socket
-])
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
-done
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1],[hv2],[vtep])
-OVN_CLEANUP_VSWITCH([hv3])
-
-AT_CLEANUP
-
-# Similar test to "hardware GW"
-AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Configure the Northbound database
-ovn-nbctl ls-add lsw0
-
-ovn-nbctl lsp-add lsw0 lp1
-ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
-
-ovn-nbctl lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
-
-ovn-nbctl lsp-add lsw0 lp-gw
-ovn-nbctl lsp-set-type lp-gw l2gateway
-ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
-ovn-nbctl lsp-set-addresses lp-gw unknown
-
-net_add n1               # Network to connect hv1, hv2, and gw
-net_add n2               # Network to connect gw and hv3
-
-# Create hypervisor hv1 connected to n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
-
-# Create hypervisor hv2 connected to n1
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
-
-# Create hypervisor hv_gw connected to n1 and n2
-# connect br-phys bridge to n1; connect hv-gw bridge to n2
-sim_add hv_gw
-as hv_gw
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl add-br br-phys2
-net_attach n2 br-phys2
-ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
-
-# Add hv3 on the other side of the GW
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-net_attach n2 br-phys
-ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
-
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# test_packet INPORT DST SRC ETHTYPE OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
-for i in 1 2 3; do
-    : > $i.expected
-done
-test_packet() {
-    local inport=$1 packet=$2$3$4; shift; shift; shift; shift
-    #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
-    hv=hv$inport
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-# Send packets between all pairs of source and destination ports:
-#
-# 1. Unicast packets are delivered to exactly one lport (except that packets
-#    destined to their input ports are dropped).
-#
-# 2. Broadcast and multicast are delivered to all lports except the input port.
-#
-# 3. The lswitch delivers packets with an unknown destination to lports with
-#    "unknown" among their MAC addresses (and port security disabled).
-for s in 1 2 3 ; do
-    bcast=
-    unknown=
-    for d in 1 2 3 ; do
-        if test $d != $s; then unicast=$d; else unicast=; fi
-        test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast       #1
-
-        # The vtep (vif3) is the only one configured for "unknown"
-        if test $d != $s && test $d = 3; then
-            unknown="$unknown $d"
-        fi
-        bcast="$bcast $unicast"
-    done
-
-    test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast             #2
-    test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast             #3
-    test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown           #4
-done
-
-echo "------ ovn-nbctl show ------"
-ovn-nbctl show
-echo "------ ovn-sbctl show ------"
-ovn-sbctl show
-
-echo "------ hv1 ------"
-as hv1 ovs-vsctl show
-echo "------ hv1 br-int ------"
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-echo "------ hv1 br-phys ------"
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
-
-echo "------ hv2 ------"
-as hv2 ovs-vsctl show
-echo "------ hv2 br-int ------"
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-echo "------ hv2 br-phys ------"
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
-
-echo "------ hv_gw ------"
-as hv_gw ovs-vsctl show
-echo "------ hv_gw br-phys ------"
-as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
-echo "------ hv_gw br-phys2 ------"
-as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
-
-echo "------ hv3 ------"
-as hv3 ovs-vsctl show
-echo "------ hv3 br-phys ------"
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
-done
-AT_CLEANUP
-
-# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
-AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-#
-# Three logical switches ls1, ls2, ls3.
-# One logical router lr0 connected to ls[123],
-# with nine subnets, three per logical switch:
-#
-#    lrp11 on ls1 for subnet 192.168.11.0/24
-#    lrp12 on ls1 for subnet 192.168.12.0/24
-#    lrp13 on ls1 for subnet 192.168.13.0/24
-#    ...
-#    lrp33 on ls3 for subnet 192.168.33.0/24
-#
-# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
-# digits are the subnet and the last digit distinguishes the VIF.
-for i in 1 2 3; do
-    ovn-nbctl ls-add ls$i
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            # Add "unknown" to MAC addresses for lp?11, so packets for
-            # MAC-IP bindings discovered via ARP later have somewhere to go.
-            if test $j$k = 11; then unknown=unknown; else unknown=; fi
-
-            ovn-nbctl \
-                -- lsp-add ls$i lp$i$j$k \
-                -- lsp-set-addresses lp$i$j$k \
-                   "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
-        done
-    done
-done
-
-ovn-nbctl lr-add lr0
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
-        ovn-nbctl \
-            -- lsp-add ls$i lrp$i$j-attachment \
-            -- set Logical_Switch_Port lrp$i$j-attachment type=router \
-                             options:router-port=lrp$i$j \
-                             addresses='"00:00:00:00:ff:'$i$j'"'
-    done
-done
-
-ovn-nbctl set Logical_Switch_Port lrp33-attachment \
-    addresses='"00:00:00:00:ff:33 192.168.33.254"'
-
-# Physical network:
-#
-# Three hypervisors hv[123].
-# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
-# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
-# lp?3[123] all on hv3.
-
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    case $1 in dnl (
-        ?11) echo 1 ;; dnl (
-        ?12 | ?21 | ?22) echo 2 ;; dnl (
-        ?13 | ?23 | ?3?) echo 3 ;;
-    esac
-}
-
-# Given the name of a logical port, prints the name of its logical router
-# port, e.g. "vif_to_lrp 123" yields 12.
-vif_to_lrp() {
-    echo ${1%?}
-}
-
-# Given the name of a logical port, prints the name of its logical
-# switch, e.g. "vif_to_ls 123" yields 1.
-vif_to_ls() {
-    echo ${1%??}
-}
-
-net_add n1
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-done
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            hv=`vif_to_hv $i$j$k`
-                as hv$hv ovs-vsctl \
-                -- add-port br-int vif$i$j$k \
-                -- set Interface vif$i$j$k \
-                    external-ids:iface-id=lp$i$j$k \
-                    options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
-                    options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
-                    ofport-request=$i$j$k
-        done
-    done
-done
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            : > $i$j$k.expected
-        done
-    done
-done
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    in_ls=`vif_to_ls $inport`
-    in_lrp=`vif_to_lrp $inport`
-    for outport; do
-        out_ls=`vif_to_ls $outport`
-        if test $in_ls = $out_ls; then
-            # Ports on the same logical switch receive exactly the same packet.
-            echo $packet
-        else
-            # Routing decrements TTL and updates source and dest MAC
-            # (and checksum).
-            out_lrp=`vif_to_lrp $outport`
-            echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
-        fi >> $outport.expected
-    done
-}
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
-    local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $request
-    as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
-
-    # Expect to receive the broadcast ARP on the other logical switch ports if
-    # IP address is not configured to the switch patch port.
-    local i=`vif_to_ls $inport`
-    local j k
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            # 192.168.33.254 is configured to the switch patch port for lrp33,
-            # so no ARP flooding expected for it.
-            if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
-                echo $request >> $i$j$k.expected
-            fi
-        done
-    done
-
-    # Expect to receive the reply, if any.
-    if test X$reply_ha != X; then
-        lrp=`vif_to_lrp $inport`
-        local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
-        echo $reply >> $inport.expected
-    fi
-}
-
-as hv1 ovs-vsctl --columns=name,ofport list interface
-as hv1 ovn-sbctl list port_binding
-as hv1 ovn-sbctl list datapath_binding
-as hv1 ovn-sbctl dump-flows
-as hv1 ovs-ofctl dump-flows br-int
-
-# Send IP packets between all pairs of source and destination ports:
-#
-# 1. Unicast IP packets are delivered to exactly one logical switch port
-#    (except that packets destined to their input ports are dropped).
-#
-# 2. Broadcast IP packets are delivered to all logical switch ports
-#    except the input port.
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-for is in 1 2 3; do
-  for js in 1 2 3; do
-    for ks in 1 2 3; do
-      bcast=
-      s=$is$js$ks
-      smac=f00000000$s
-      sip=`ip_to_hex 192 168 $is$js $ks`
-      for id in 1 2 3; do
-          for jd in 1 2 3; do
-              for kd in 1 2 3; do
-                d=$id$jd$kd
-                dip=`ip_to_hex 192 168 $id$jd $kd`
-                if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
-                if test $d != $s; then unicast=$d; else unicast=; fi
-
-                test_ip $s $smac $dmac $sip $dip $unicast #1
-
-                if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
-              done
-          done
-        done
-      test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
-      done
-  done
-done
-
-: > mac_bindings.expected
-
-# 3. Send an IP packet from every logical port to every other subnet,
-#    to an IP address that does not have a static IP-MAC binding.
-#    This should generate a broadcast ARP request for the destination
-#    IP address in the destination subnet.
-#    Moreover generate an ARP reply for each of the IP addresses ARPed
-for is in 1 2 3; do
-  for js in 1 2 3; do
-    for ks in 1 2 3; do
-      s=$is$js$ks
-      smac=f00000000$s
-      sip=`ip_to_hex 192 168 $is$js $ks`
-      for id in 1 2 3; do
-        for jd in 1 2 3; do
-          if test $is$js = $id$jd; then
-            continue
-          fi
-
-          # Send the packet.
-          dmac=00000000ff$is$js
-          # Calculate a 4th octet for the destination that is
-          # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
-          # that have static MAC bindings, and fits in the range
-          # 0-255.
-          o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
-          dip=`ip_to_hex 192 168 $id$jd $o4`
-          test_ip $s $smac $dmac $sip $dip
-
-          # Every LP on the destination subnet's lswitch should
-          # receive the ARP request.
-          lrmac=00000000ff$id$jd
-          lrip=`ip_to_hex 192 168 $id$jd 254`
-          arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
-          for jd2 in 1 2 3; do
-            for kd in 1 2 3; do
-              echo $arp >> $id$jd2$kd.expected
-            done
-          done
-
-          hmac=8000000000$o4
-          rmac=00000000ff$id$jd
-          echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
-
-          host_mac=8000000000$o4
-          lrmac=00000000ff$id$jd
-
-          arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
-
-          hv=hv`vif_to_hv ${id}${jd}1`
-          as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
-
-          host_ip_pretty=192.168.$id$jd.$o4
-          host_mac_pretty=80:00:00:00:00:$o4
-          echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
-        done
-      done
-    done
-  done
-done
-
-# Test router replies to ARP requests from all source ports:
-#
-# 4. Router replies to query for its MAC address from port's own IP address.
-#
-# 5. Router replies to query for its MAC address from any random IP address
-#    in its subnet.
-#
-# 6. No reply to query for IP address other than router IP.
-#
-# 7. No reply to query from another subnet.
-for i in 1 2 3; do
-  for j in 1 2 3; do
-    for k in 1 2 3; do
-      smac=f00000000$i$j$k               # Source MAC
-      sip=`ip_to_hex 192 168 $i$j $k`    # Source IP
-      rip=`ip_to_hex 192 168 $i$j 254`   # Router IP
-      rmac=00000000ff$i$j                # Router MAC
-      otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
-      externalip=`ip_to_hex 1 2 3 4`      # Some other IP not in subnet
-
-      test_arp $i$j$k $smac $sip        $rip        $rmac      #4
-      test_arp $i$j$k $smac $otherip    $rip        $rmac      #5
-      test_arp $i$j$k $smac $sip        $otherip               #6
-
-      # When rip is 192.168.33.254, ARP request from externalip won't be
-      # filtered, because 192.168.33.254 is configured to switch peer port
-      # for lrp33.
-      lrp33_rsp=
-      if test $i = 3 && test $j = 3; then
-        lrp33_rsp=$rmac
-      fi
-      test_arp $i$j$k $smac $externalip $rip        $lrp33_rsp #7
-
-      # MAC binding should be learned from ARP request.
-      host_mac_pretty=f0:00:00:00:0$i:$j$k
-
-      host_ip_pretty=192.168.$i$j.$k
-      echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
-
-      # mac_binding is learned and overwritten so only the last one remains.
-      if test $k = 3; then
-          # lrp33 will not learn from ARP request, because 192.168.33.254 is
-          # configured to switch peer port for lrp33.
-          if test $i != 3 || test $j != 3; then
-              host_ip_pretty=192.168.$i$j.55
-              echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
-          fi
-      fi
-
-    done
-  done
-done
-
-
-# Allow some time for packet forwarding.
-# XXX This can be improved.
-sleep 1
-
-# 8. Send an IP packet from every logical port to every other subnet.  These
-#    are the same packets already sent as #3, but now the destinations' IP-MAC
-#    bindings have been discovered via ARP, so instead of provoking an ARP
-#    request, these packets now get routed to their destinations (which don't
-#    have static MAC bindings, so they go to the port we've designated as
-#    accepting "unknown" MACs.)
-for is in 1 2 3; do
-  for js in 1 2 3; do
-    for ks in 1 2 3; do
-      s=$is$js$ks
-      smac=f00000000$s
-      sip=`ip_to_hex 192 168 $is$js $ks`
-      for id in 1 2 3; do
-        for jd in 1 2 3; do
-          if test $is$js = $id$jd; then
-            continue
-          fi
-
-          # Send the packet.
-          dmac=00000000ff$is$js
-          # Calculate a 4th octet for the destination that is
-          # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
-          # that have static MAC bindings, and fits in the range
-          # 0-255.
-          o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
-          dip=`ip_to_hex 192 168 $id$jd $o4`
-          test_ip $s $smac $dmac $sip $dip
-
-          # Expect the packet egress.
-          host_mac=8000000000$o4
-          outport=${id}11
-          out_lrp=$id$jd
-          echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
-        done
-      done
-    done
-  done
-done
-
-ovn-sbctl -f csv -d bare --no-heading \
-    -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
-                              [$i$j$k.expected])
-        done
-    done
-done
-
-# Check the MAC bindings against those expected.
-AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
-])
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1], [hv2], [hv3])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- IP relocation using GARP request])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-#
-# Two logical switches ls1, ls2.
-# One logical router lr0 connected to ls[12],
-# with 2 subnets, 1 per logical switch:
-#
-#    lrp1 on ls1 for subnet 192.168.1.1/24
-#    lrp2 on ls2 for subnet 192.168.2.1/24
-#
-# 4 VIFs, 2 per LS lp[12][12], first digit being LS.
-# VIFs' fixed IP addresses are 192.168.[12].1[12].
-#
-# There is a secondary IP 192.168.1.100 that is unknown in NB and learned
-# through ARP only, and it can move between lp11 and lp12.
-#
-ovn-nbctl lr-add lr0
-for i in 1 2 ; do
-    ovn-nbctl ls-add ls$i
-    ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
-    ovn-nbctl \
-        -- lsp-add ls$i lrp$i-attachment \
-        -- set Logical_Switch_Port lrp$i-attachment type=router \
-                         options:router-port=lrp$i \
-                         addresses=router
-    for j in 1 2; do
-        ovn-nbctl \
-            -- lsp-add ls$i lp$i$j \
-            -- lsp-set-addresses lp$i$j \
-               "f0:00:00:00:00:$i$j 192.168.$i.1$j"
-    done
-done
-
-# Physical network:
-# 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located, e.g. "vif_to_hv 12" yields 2.
-vif_to_hv() {
-    echo ${1#?}
-}
-
-# Given the name of a logical port, prints the name of its logical router
-# port, e.g. "vif_to_lrp 12" yields 1.
-vif_to_lrp() {
-    echo ${1%?}
-}
-
-# Given the name of a logical port, prints the name of its logical
-# switch, e.g. "vif_to_ls 12" yields 1.
-vif_to_ls() {
-    echo ${1%?}
-}
-
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-done
-for i in 1 2; do
-    for j in 1 2; do
-        hv=`vif_to_hv $i$j`
-            as hv$hv ovs-vsctl \
-                -- add-port br-int vif$i$j \
-                -- set Interface vif$i$j \
-                    external-ids:iface-id=lp$i$j \
-                    options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
-                    options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
-                    ofport-request=$i$j
-    done
-done
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
-for i in 1 2; do
-    for j in 1 2; do
-        : > $i$j.expected
-    done
-done
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    in_ls=`vif_to_ls $inport`
-    in_lrp=`vif_to_lrp $inport`
-    for outport; do
-        out_ls=`vif_to_ls $outport`
-        if test $in_ls = $out_ls; then
-            # Ports on the same logical switch receive exactly the same packet.
-            echo $packet
-        else
-            # Routing decrements TTL and updates source and dest MAC
-            # (and checksum).
-            out_lrp=`vif_to_lrp $outport`
-            echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
-        fi >> $outport.expected
-    done
-}
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
-    local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $request
-
-    # Expect to receive the broadcast ARP on the other logical switch ports if
-    # IP address is not configured to the switch patch port.
-    local i=`vif_to_ls $inport`
-    local j
-    for j in 1 2; do
-        if test $i$j != $inport; then
-            echo $request >> $i$j$k.expected
-        fi
-    done
-
-    # Expect to receive the reply, if any.
-    if test X$reply_ha != X; then
-        lrp=`vif_to_lrp $inport`
-        local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
-        echo $reply >> $inport.expected
-    fi
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# lp11 send GARP request to announce ownership of 192.168.1.100.
-
-sha=f00000000011
-spa=`ip_to_hex 192 168 1 100`
-tpa=$spa
-test_arp 11 $sha $spa $tpa
-OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
-ovn-nbctl --wait=hv sync
-
-# Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
-
-smac=f00000000021
-dmac=00000000ff02
-sip=`ip_to_hex 192 168 2 11`
-dip=`ip_to_hex 192 168 1 100`
-test_ip 21 $smac $dmac $sip $dip 11
-
-# lp12 send GARP request to announce ownership of 192.168.1.100.
-
-sha=f00000000012
-test_arp 12 $sha $spa $tpa
-OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
-ovn-nbctl --wait=hv sync
-# give to the hv the time to send queued ip packets
-sleep 1
-
-# Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
-
-test_ip 21 $smac $dmac $sip $dip 12
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2; do
-    for j in 1 2; do
-        OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
-                          [$i$j.expected])
-    done
-done
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1], [hv2])
-
-AT_CLEANUP
-
-# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
-AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Create hypervisors hv[123].
-# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
-# Add all of the vifs to a single logical switch lsw0.
-# Turn off port security on vifs vif[123]1
-# Turn on l2 port security on vifs vif[123]2
-# Turn of l2 and l3 port security on vifs vif[123]3
-# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
-ovn-nbctl ls-add lsw0
-net_add n1
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2 3; do
-        ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
-        ovn-nbctl lsp-add lsw0 lp$i$j
-        if test $j = 1; then
-            ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
-        elif test $j = 2; then
-            ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
-            ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
-        else
-            extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
-            ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
-            ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
-        fi
-    done
-done
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv${1%?}
-}
-
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        : > $i$j.expected
-    done
-done
-
-# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-#
-# This shell function causes an ip packet to be received on INPORT.
-# The packet's content has Ethernet destination DST and source SRC
-# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
-# The OUTPORTs (zero or more) list the VIFs on which the packet should
-# be received.  INPORT and the OUTPORTs are specified as logical switch
-# port numbers, e.g. 11 for vif11.
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
-    local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-    hv=`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $request
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
-    if test $drop != 1; then
-        if test X$reply_ha = X; then
-            # Expect to receive the broadcast ARP on the other logical switch ports
-            # if no reply is expected.
-            local i j
-            for i in 1 2 3; do
-                for j in 1 2 3; do
-                    if test $i$j != $inport; then
-                        echo $request >> $i$j.expected
-                    fi
-                done
-            done
-        else
-            # Expect to receive the reply, if any.
-            local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
-            echo $reply >> $inport.expected
-        fi
-    fi
-}
-
-# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-# This function is similar to test_ip() except that it sends
-# ipv6 packet
-test_ipv6() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
-    shift; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-# test_icmpv6 INPORT  SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
-# This function is similar to test_ipv6() except it specifies the ICMPv6 type
-# of the test packet
-test_icmpv6() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
-    local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
-    shift; shift; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# no port security
-sip=`ip_to_hex 192 168 0 12`
-tip=`ip_to_hex 192 168 0 13`
-# the arp packet should be allowed even if lp[123]1 is
-# not configured with mac f00000000023 and ip 192.168.0.12
-for i in 1 2 3; do
-    test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
-    for j in 1 2 3; do
-        if test $i != $j; then
-            test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
-        fi
-    done
-done
-
-# l2 port security
-sip=`ip_to_hex 192 168 0 12`
-tip=`ip_to_hex 192 168 0 13`
-
-# arp packet should be allowed since lp22 is configured with
-# mac f00000000022
-test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
-
-# arp packet should not be allowed since lp32 is not configured with
-# mac f00000000021
-test_arp 32 f00000000021 f00000000021 $sip $tip 1
-
-# arp packet with sha set to f00000000021 should not be allowed
-# for lp12
-test_arp 12 f00000000012 f00000000021 $sip $tip 1
-
-# ip packets should be allowed and received since lp[123]2 do not
-# have l3 port security
-sip=`ip_to_hex 192 168 0 55`
-tip=`ip_to_hex 192 168 0 66`
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        if test $i != $j; then
-            test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
-        fi
-    done
-done
-
-# ipv6 packets should be received by lp[123]2
-# lp[123]1 can send ipv6 traffic as there is no port security
-sip=fe800000000000000000000000000000
-tip=ff020000000000000000000000000000
-
-for i in 1 2 3; do
-    test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
-done
-
-
-# l2 and l3 port security
-sip=`ip_to_hex 192 168 0 13`
-tip=`ip_to_hex 192 168 0 22`
-# arp packet should be allowed since lp13 is configured with
-# f00000000013 and 192.168.0.13
-test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
-
-# the arp packet should be dropped because lp23 is not configured
-# with mac f00000000022
-sip=`ip_to_hex 192 168 0 13`
-tip=`ip_to_hex 192 168 0 22`
-test_arp 23 f00000000022 f00000000022 $sip $tip 1
-
-# the arp packet should be dropped because lp33 is not configured
-# with ip 192.168.0.55
-spa=`ip_to_hex 192 168 0 55`
-tpa=`ip_to_hex 192 168 0 22`
-test_arp 33 f00000000031 f00000000031 $spa $tpa 1
-
-# ip packets should not be received by lp[123]3 since
-# l3 port security is enabled
-sip=`ip_to_hex 192 168 0 55`
-tip=`ip_to_hex 192 168 0 66`
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
-    done
-done
-
-# ipv6 packets should be dropped for lp[123]3 since
-# it is configured with only ipv4 address
-sip=fe800000000000000000000000000000
-tip=ff020000000000000000000000000000
-
-for i in 1 2 3; do
-    test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
-done
-
-# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
-# lp[123]1 can send ipv6 traffic as there is no port security
-for i in 1 2 3; do
-    test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
-done
-
-# lp13 has extra port security with mac f0000000113 and ipv6 addr
-# fe80::ea2a:eaff:fe28:0012
-
-# ipv4 packet should be dropped for lp13 with mac f0000000113
-sip=`ip_to_hex 192 168 0 13`
-tip=`ip_to_hex 192 168 0 23`
-test_ip 13 f00000000113 f00000000023 $sip $tip
-
-# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
-# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
-# lp11 can send ipv6 traffic as there is no port security
-sip=ee800000000000000000000000000000
-for i in 1 2 3; do
-    tip=fe80000000000000ea2aeafffe2800${i}3
-    test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
-done
-
-
-# ipv6 packet should not be received by lp33 with mac f0000000333
-# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
-# configured with fe80::ea2a:eaff:fe28:0033
-# lp11 can send ipv6 traffic as there is no port security
-
-sip=ee800000000000000000000000000000
-tip=fe80000000000000ea2aeafffe280023
-test_ipv6 11 f00000000011 f00000000333 $sip $tip
-
-# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
-# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
-# and should be dropped for any other ip6.src
-# lp21 can receive ipv6 traffic as there is no port security
-
-tip=ee800000000000000000000000000000
-for i in 1 2 3; do
-    sip=fe80000000000000ea2aeafffe2800${i}3
-    test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
-
-    # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
-    sip=00000000000000000000000000000000
-    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
-    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
-    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
-    # Traffic to non-multicast traffic should be dropped
-    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
-    # Traffic of other ICMPv6 types should be dropped
-    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
-
-    # should be dropped
-    sip=ae80000000000000ea2aeafffe2800aa
-    test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
-done
-
-# configure lsp13 to send and received IPv4 packets with an address range
-ovn-nbctl lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24"
-
-sleep 2
-
-sip=`ip_to_hex 10 0 0 13`
-tip=`ip_to_hex 192 168 0 22`
-# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
-test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
-
-sip=`ip_to_hex 10 0 0 14`
-tip=`ip_to_hex 192 168 0 23`
-# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
-# with dst ip 192.168.0.23 should be allowed
-test_ip 13 f00000000013 f00000000023 $sip $tip 23
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 10 0 0 15`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 10.0.0.15 should be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip 13
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 20 0 0 4`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 20.0.0.4 should be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip 13
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 20 0 0 5`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 20.0.0.5 should not be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 20 0 0 255`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 20.0.0.255 should be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip 13
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 192 168 0 255`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 192.168.0.255 should not be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip
-
-sip=`ip_to_hex 192 168 0 33`
-tip=`ip_to_hex 224 0 0 4`
-# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
-# with dst ip 224.0.0.4  should be received by lsp13
-test_ip 33 f00000000033 f00000000013 $sip $tip 13
-
-#dump information including flow counters
-ovn-nbctl show
-ovn-sbctl dump-flows -- list multicast_group
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 show br-int
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-ofctl -O OpenFlow13 show br-int
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-echo "------ hv3 dump ------"
-as hv3 ovs-vsctl show
-as hv3 ovs-ofctl -O OpenFlow13 show br-int
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
-    done
-done
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
-# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
-# R2 has ls2 (172.16.1.0/24) connected to it.
-
-ls1_lp1_mac="f0:00:00:01:02:03"
-rp_ls1_mac="00:00:00:01:02:03"
-rp_ls2_mac="00:00:00:01:02:04"
-ls2_lp1_mac="f0:00:00:01:02:04"
-
-ls1_lp1_ip="192.168.1.2"
-ls2_lp1_ip="172.16.1.2"
-
-ovn-nbctl lr-add R1
-ovn-nbctl lr-add R2
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
-
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
-  options:router-port=ls1 addresses=\"$rp_ls1_mac\"
-
-# Connect ls2 to R2
-ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
-
-ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
-  options:router-port=ls2 addresses=\"$rp_ls2_mac\"
-
-# Connect R1 to R2
-ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
-ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
-
-ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
-ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
-
-# Create logical port ls2-lp1 in ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Packet to send.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
-        udp && udp.src==53 && udp.dst==4369"
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-
-# Packet to Expect
-# The TTL should be decremented by 2.
-packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
-        ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
-        udp && udp.src==53 && udp.dst==4369"
-echo $packet | ovstest test-ovn expr-to-packets > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
-grep "reg0 == 172.16.1.2" | wc -l], [0], [1
-])
-
-# Disable the ls2-lp1 port.
-ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
-
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
-grep "reg0 == 172.16.1.2" | wc -l], [0], [0
-])
-
-# Generate the packet destined for ls2-lp1 and it should not be delivered.
-# Packet to send.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
-        udp && udp.src==53 && udp.dst==4369"
-
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-# The 2nd packet sent shound not be received.
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-
-AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
-AT_KEYWORDS([router-admin-state])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
-# and 172.16.1.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add ls1
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
-          options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
-          -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port ls1-lp2 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp2 \
-          -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
-
-# Create one hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int vif1 -- \
-    set interface vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif2 -- \
-    set interface vif2 external-ids:iface-id=ls1-lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=1
-
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Send ip packets between the two ports.
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Packet to send.
-src_mac="f00000010203"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
-
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-
-#Disable router R1
-ovn-nbctl set Logical_Router R1 enabled=false
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
-
-# Packet to Expect
-expect_src_mac="000000010203"
-expect_dst_mac="f00000010204"
-echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-
-AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
-AT_KEYWORDS([router-admin-state])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
-# and has switch ls2 (172.16.1.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
-          options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
-
-# Connect ls2 to R1
-ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
-ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
-          options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port ls2-lp1 in ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Create one hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int vif1 -- \
-    set interface vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif2 -- \
-    set interface vif2 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=1
-
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Send ip packets between the two ports.
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Packet to send.
-src_mac="f00000010203"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
-
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-#Disable router R1
-ovn-nbctl set Logical_Router R1 enabled=false
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-# Allow some time for the disabling of logical router R1 to propagate.
-# XXX This should be more systematic.
-sleep 1
-
-as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
-
-# Packet to Expect
-expect_src_mac="000000010204"
-expect_dst_mac="f00000010204"
-echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
-# network. R1 has switchess foo (192.168.1.0/24)
-# connected to it.
-# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-ovn-nbctl lr-add R2
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add bob
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-          options:router-port=foo addresses=\"00:00:00:01:02:03\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-          type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
-
-# Connect bob to R2
-ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
-ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
-          options:router-port=bob addresses=\"00:00:00:01:02:05\"
-
-# Connect R1 to R2
-ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
-ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
-
-#install static routes
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
-ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port alice1 in alice
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Create logical port bob1 in bob
-ovn-nbctl lsp-add bob bob1 \
--- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=bob1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and alice1
-src_mac="f00000010203"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-# Send ip packets between foo1 and bob1
-src_mac="f00000010203"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 2 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl dump-flows br-int
-
-# Packet to Expect at bob1
-src_mac="000000010205"
-dst_mac="f00000010205"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 2 2`
-echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Packet to Expect at alice1
-src_mac="000000010204"
-dst_mac="f00000010204"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- send gratuitous arp on localnet])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-ovn-nbctl ls-add lsw0
-net_add n1
-sim_add hv
-as hv
-ovs-vsctl \
-    -- add-br br-phys \
-    -- add-br br-eth0
-
-ovn_attach n1 br-phys 192.168.0.1
-
-AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
-AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv/snoopvif-tx.pcap options:rxq_pcap=hv/snoopvif-rx.pcap])
-
-# Create a vif.
-AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
-AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
-
-AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
-
-# Wait for packet to be received.
-echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
-OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
-
-# Check GARP packet when restart openflow connection.
-as hv
-OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
-
-OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
-
-as hv
-start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
-
-# Wait for packet to be received.
-echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
-OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
-
-# Delete the localnet ports.
-AT_CHECK([ovs-vsctl del-port localvif1])
-AT_CHECK([ovn-nbctl lsp-del ln_port])
-
-OVN_CLEANUP([hv])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
-# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
-# connected to it.
-
-ovn-nbctl lr-add R1
-ovn-nbctl lr-add R2
-ovn-nbctl lr-add R3
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add bob
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-    options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect bob to R3
-ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
-ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
-    type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Connect R3 to join
-ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
-ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
-    type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
-
-#install static routes
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
-
-ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
-ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
-
-ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
-ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port alice1 in alice
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Create logical port bob1 in bob
-ovn-nbctl lsp-add bob bob1 \
--- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=bob1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and alice1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
-
-# Send ip packets between foo1 and bob1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 10 32 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-echo "----------------------------"
-
-# Packet to Expect at bob1
-src_mac="000003010203"
-dst_mac="f00000010205"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 10 32 1 2`
-echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Packet to Expect at alice1
-src_mac="000002010203"
-dst_mac="f00000010204"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-ovn-nbctl lsp-add ls1 ls1-lp2 \
--- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
-
-ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
-
-ovn-nbctl ls-add ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
-ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
-ovn-nbctl lsp-add ls2 ls2-lp2 \
--- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
-ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
-
-d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
-options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
-\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
-
-ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
-ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
-
-d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
-options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
-\"lease_time\"=\"3600\"")"
-
-ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
-
-net_add n1
-sim_add hv1
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
-    set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=hv1/vif3-tx.pcap \
-    options:rxq_pcap=hv1/vif3-rx.pcap \
-    ofport-request=3
-
-ovs-vsctl -- add-port br-int hv1-vif4 -- \
-    set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
-    options:tx_pcap=hv1/vif4-tx.pcap \
-    options:rxq_pcap=hv1/vif4-rx.pcap \
-    ofport-request=4
-
-OVN_POPULATE_ARP
-
-sleep 2
-
-as hv1 ovs-vsctl show
-
-# This shell function sends a DHCP request packet
-# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
-test_dhcp() {
-    local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
-    shift; shift; shift; shift; shift; shift; shift;
-    if test $use_ip != 0; then
-        src_ip=$1
-        dst_ip=$2
-        shift; shift;
-    else
-        src_ip=`ip_to_hex 0 0 0 0`
-        dst_ip=`ip_to_hex 255 255 255 255`
-    fi
-    if test $request_ip != 0; then
-        ip_len=0120
-        udp_len=010b
-    else
-        ip_len=011a
-        udp_len=0106
-    fi
-    local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
-    # udp header and dhcp header
-    request=${request}00440043${udp_len}0000
-    request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
-    # client hardware padding
-    request=${request}00000000000000000000
-    # server hostname
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    # boot file name
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    # dhcp magic cookie
-    request=${request}63825363
-    # dhcp message type
-    request=${request}3501${dhcp_type}
-    # dhcp unknown option
-    request=${request}d70701020304050607
-    # dhcp pad option
-    request=${request}00
-    if test $request_ip != 0; then
-        # dhcp requested ip
-        request=${request}3204${request_ip}
-    fi
-    # dhcp end option
-    request=${request}ff
-
-    for port in $inport "$@"; do
-        : >> $port.expected
-    done
-    if test $offer_ip != 0; then
-        local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
-        # total IP length will be the IP length of the request packet
-        # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
-        ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
-        udp_len=`expr $ip_len - 20`
-        ip_len=$(printf "%x" $ip_len)
-        udp_len=$(printf "%x" $udp_len)
-        # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
-        local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
-        # udp header and dhcp header.
-        # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
-        reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
-        # your ip address; 0 for NAK
-        if test $dhcp_reply_type = 06; then
-            reply=${reply}00000000
-        else
-            reply=${reply}${offer_ip}
-        fi
-        # next server ip address, relay agent ip address, client mac address
-        reply=${reply}0000000000000000${src_mac}
-        # client hardware padding
-        reply=${reply}00000000000000000000
-        # server hostname
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        # boot file name
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-        # dhcp magic cookie
-        reply=${reply}63825363
-        reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
-        echo $reply >> $inport.expected
-    else
-        for outport; do
-            echo $request >> $outport.expected
-        done
-    fi
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-AT_CAPTURE_FILE([ofctl_monitor0.log])
-as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-# Send DHCPDISCOVER.
-offer_ip=`ip_to_hex 10 0 0 4`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=`ip_to_hex 0 0 0 0`
-request_ip=0
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 1.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-cat 1.expected | cut -c -48 > expout
-AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 1.expected | cut -c 53- > expout
-AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
-
-# ovs-ofctl also resumes the packets and this causes other ports to receive
-# the DHCP request packet. So reset the pcap files so that its easier to test.
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
-# address in the Requested IP Address option.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=`ip_to_hex 0 0 0 0`
-request_ip=$offer_ip
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
-# the Requested IP Address option, expect a DHCPNAK.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=`ip_to_hex 0 0 0 0`
-request_ip=`ip_to_hex 10 0 0 7`
-expected_dhcp_opts=""
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 3.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
-# but should be resumed without the reply.
-# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
-# one from ovn-controller and the other from "ovs-ofctl resume."
-ciaddr=`ip_to_hex 0 0 0 0`
-offer_ip=0
-request_ip=0
-test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
-
-# NXT_RESUMEs should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
-# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
-
-ciaddr=`ip_to_hex 0 0 0 0`
-test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
-
-# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
-# this lport.
-ciaddr=`ip_to_hex 0 0 0 0`
-test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
-
-# NXT_RESUMEs should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-#OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
-#OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
-
-# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
-# and ip4.dst set to 10.0.0.1.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=$offer_ip
-request_ip=0
-src_ip=$offer_ip
-dst_ip=$server_ip
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 5.
-OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
-# and ip4.dst set to 255.255.255.255.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=$offer_ip
-request_ip=0
-src_ip=$offer_ip
-dst_ip=`ip_to_hex 255 255 255 255`
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 6.
-OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
-# ciaddr, expect a DHCPNAK.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=`ip_to_hex 10 0 0 7`
-request_ip=0
-src_ip=$offer_ip
-dst_ip=`ip_to_hex 255 255 255 255`
-expected_dhcp_opts=""
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 7.
-OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
-# expect a DHCPNAK.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-ciaddr=`ip_to_hex 0 0 0 0`
-request_ip=0
-src_ip=$offer_ip
-dst_ip=`ip_to_hex 255 255 255 255`
-expected_dhcp_opts=""
-test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
-
-# NXT_RESUMEs should be 8.
-OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
-# The packet should not be received by ovn-controller.
-ciaddr=`ip_to_hex 0 0 0 0`
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 4`
-test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
-
-# NXT_RESUMEs should be 8.
-OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-# vif1-tx.pcap should have received the DHCPv4 request packet
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
-
-ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
-
-ovn-nbctl lsp-add ls1 ls1-lp2 \
--- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
-
-ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
-
-ovn-nbctl lsp-add ls1 ls1-lp3 \
--- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
-
-ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
-
-d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
-options="\"server_id\"=\"00:00:00:10:00:01\"")"
-
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
-
-d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
-options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
-
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
-
-ovn-nbctl ls-add ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
-ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
-ovn-nbctl lsp-add ls2 ls2-lp2 \
--- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
-ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
-
-net_add n1
-sim_add hv1
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
-    set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=hv1/vif3-tx.pcap \
-    options:rxq_pcap=hv1/vif3-rx.pcap \
-    ofport-request=3
-
-ovs-vsctl -- add-port br-int hv1-vif4 -- \
-    set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
-    options:tx_pcap=hv1/vif4-tx.pcap \
-    options:rxq_pcap=hv1/vif4-rx.pcap \
-    ofport-request=4
-
-ovs-vsctl -- add-port br-int hv1-vif5 -- \
-    set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
-    options:tx_pcap=hv1/vif5-tx.pcap \
-    options:rxq_pcap=hv1/vif5-rx.pcap \
-    ofport-request=5
-
-OVN_POPULATE_ARP
-
-sleep 2
-
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-# This shell function sends a DHCPv6 request packet
-# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
-# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
-# packet should be received twice (one from ovn-controller and the other
-# from the "ovs-ofctl monitor br-int resume"
-test_dhcpv6() {
-    local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
-    if test $msg_code != 0b; then
-        req_len=2a
-    else
-        req_len=1a
-    fi
-    local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
-    # dst ip ff02::1:2
-    request=${request}ff020000000000000000000000010002
-    # udp header and dhcpv6 header
-    request=${request}0222022300${req_len}ffff${msg_code}010203
-    # Client identifier
-    request=${request}0001000a00030001${src_mac}
-    # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
-    # is not 11 (information request packet)
-    if test $msg_code != 0b; then
-        request=${request}0003000c0102030400000e1000001518
-    fi
-    shift; shift; shift; shift; shift;
-    if test $offer_ip != 0; then
-        local server_mac=000000100001
-        local server_lla=fe80000000000000020000fffe100001
-        local reply_code=07
-        if test $msg_code = 01; then
-            reply_code=02
-        fi
-        local msg_len=54
-        if test $offer_ip = 1; then
-            msg_len=28
-        fi
-        local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
-        # udp header and dhcpv6 header
-        reply=${reply}0223022200${msg_len}ffff${reply_code}010203
-        # Client identifier
-        reply=${reply}0001000a00030001${src_mac}
-        # IA-NA
-        if test $offer_ip != 1; then
-            reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
-        fi
-        # Server identifier
-        reply=${reply}0002000a00030001${server_mac}
-        echo $reply | trim_zeros >> $inport.expected
-    else
-        for outport; do
-            echo $request | trim_zeros >> $outport.expected
-        done
-    fi
-
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-AT_CAPTURE_FILE([ofctl_monitor0.log])
-as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-src_mac=f00000000001
-src_lla=fe80000000000000f20000fffe000001
-offer_ip=ae700000000000000000000000000004
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
-
-# NXT_RESUMEs should be 1.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
-# cat 1.expected | trim_zeros > expout
-cat 1.expected | cut -c -120 > expout
-AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
-# Skipping the UDP checksum
-cat 1.expected | cut -c 125- > expout
-AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
-
-rm  1.expected
-
-# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
-# without any modifications and the packet should be received by ls1-lp1.
-# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
-# resume and the other from ovs-ofctl monitor resume.
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-
-src_mac=f00000000002
-src_lla=fe80000000000000f20000fffe000002
-offer_ip=ae700000000000000000000000000005
-# Set invalid msg_type
-
-test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
-
-# NXT_RESUMEs should be 2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-# vif2-tx.pcap should not have received the DHCPv6 reply packet
-rm 2.packets
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
-AT_CHECK([cat 2.packets], [0], [])
-
-# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
-cat 1.expected > expout
-AT_CHECK([cat 1.packets], [0], [expout])
-
-# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
-# There should be no DHCPv6 reply from ovn-controller and the request packet
-# should be received by ls2-lp2.
-
-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-test_dhcpv6 3 $src_mac $src_lla 01 0 4
-
-# NXT_RESUMEs should be 2 only.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-# vif3-tx.pcap should not have received the DHCPv6 reply packet
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
-AT_CHECK([cat 3.packets], [0], [])
-
-# vif4-tx.pcap should have received the DHCPv6 request packet
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
-cat 4.expected > expout
-AT_CHECK([cat 4.packets], [0], [expout])
-
-# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
-# The DHCPv6 reply shouldn't contain offer_ip.
-src_mac=f00000000022
-src_lla=fe80000000000000f20000fffe000022
-reset_pcap_file hv1-vif5 hv1/vif5
-test_dhcpv6 5 $src_mac $src_lla 01 1 5
-
-# NXT_RESUMEs should be 3.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
-# Skipping the UDP checksum
-cat 5.expected | cut -c 1-120,125- > expout
-AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
-
-# Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
-# shouldn't contain offer_ip
-src_mac=f00000000022
-src_lla=fe80000000000000f20000fffe000022
-reset_pcap_file hv1-vif5 hv1/vif5
-rm -f 5.expected
-test_dhcpv6 5 $src_mac $src_lla 0b 1 5
-
-# NXT_RESUMEs should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
-trim_zeros > 5.packets
-# Skipping the UDP checksum
-cat 5.expected | cut -c 1-120,125- > expout
-AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
-# connected to it. R2 has alice (172.16.1.0/24) connected to it.
-# R2 is a gateway router.
-
-
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-
-#install static routes
-ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
-ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
-R1 static_routes @lrt
-
-ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
-ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
-R2 static_routes @lrt
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port alice1 in alice
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and alice1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-ovn-sbctl list encap
-echo "---------------------"
-
-# Packet to Expect at alice1
-src_mac="000002010203"
-dst_mac="f00000010204"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
-
-
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
-
-echo "------ hv1 dump after packet 1 ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump after packet 1 ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-echo "----------------------------"
-
-echo $expected > expected
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Delete the router and re-create it. Things should work as before.
-ovn-nbctl  lr-del R2
-ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-
-ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
-ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
-R2 static_routes @lrt
-
-# Wait for ovn-controller to catch up.
-sleep 1
-
-# Send the packet again.
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-echo "------ hv1 dump after packet 2 ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump after packet 2 ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-echo "----------------------------"
-
-echo $expected >> expected
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
-AT_KEYWORDS([router-icmp-reply])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
-# and has switch ls2 (172.16.1.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
-    type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
-
-# Connect ls2 to R1
-ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
-ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
-    type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
-
-# Create logical port ls2-lp1 in ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
-
-# Create one hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int vif1 -- \
-    set interface vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif2 -- \
-    set interface vif2 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=1
-
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-for i in 1 2; do
-    : > vif$i.expected
-done
-# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
-#
-# Causes a packet to be received on INPORT.  The packet is an ICMPv4
-# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
-# ICMP_CHKSUM as specified.  If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
-# provided, then it should be the ip and icmp checksums of the packet
-# responded; otherwise, no reply is expected.
-# In the absence of an ip checksum calculation helpers, this relies
-# on the caller to provide the checksums for the ip and icmp headers.
-# XXX This should be more systematic.
-#
-# INPORT is an lport number, e.g. 11 for vif11.
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC and IPV4_DST are each 8 hex digits.
-# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
-# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
-test_ipv4_icmp_request() {
-    local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
-    local exp_ip_chksum=$8 exp_icmp_chksum=$9
-    shift; shift; shift; shift; shift; shift; shift
-    shift; shift
-
-    # Use ttl to exercise section 4.2.2.9 of RFC1812
-    local ip_ttl=01
-    local icmp_id=5fbf
-    local icmp_seq=0001
-    local icmp_data=$(seq 1 56 | xargs printf "%02x")
-    local icmp_type_code_request=0800
-    local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
-    local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
-
-    as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
-    if test X$exp_icmp_chksum != X; then
-        # Expect to receive the reply, if any. In same port where packet was sent.
-        # Note: src and dst fields are expected to be reversed.
-        local icmp_type_code_response=0000
-        local reply_icmp_ttl=fe
-        local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
-        local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
-        echo $reply >> vif$inport.expected
-    fi
-}
-
-# Send ping packet to router's ip addresses, from each of the 2 logical ports.
-rtr_l1_ip=$(ip_to_hex 192 168 1 1)
-rtr_l2_ip=$(ip_to_hex 172 16 1 1)
-l1_ip=$(ip_to_hex 192 168 1 2)
-l2_ip=$(ip_to_hex 172 16 1 2)
-
-# Ping router ip address that is on same subnet as the logical port
-test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
-test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
-
-# Ping router ip address that is on the other side of the logical ports
-test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
-test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
-
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list logical_flow
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-# Now check the packets actually received against the ones expected.
-for inport in 1 2; do
-    OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
-done
-
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- policy-based routing: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
-AT_KEYWORDS([policy-based-routing])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
-# and has switch ls2 (172.16.1.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-ovn-nbctl ls-add ls3
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
-    type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
-
-# Connect ls2 to R1
-ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
-ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
-    type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
-
-# Connect ls3 to R1
-ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 20.20.1.1/24
-ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
-    type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
-
-# Create logical port ls2-lp1 in ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
-
-# Create logical port ls3-lp1 in ls3
-ovn-nbctl lsp-add ls3 ls3-lp1 \
--- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 20.20.1.2"
-
-# Create one hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add pbr-hv
-as pbr-hv
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-
-ovs-vsctl -- add-port br-int vif1 -- \
-    set interface vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=pbr-hv/vif1-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif2 -- \
-    set interface vif2 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=pbr-hv/vif2-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif2-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif3 -- \
-    set interface vif3 external-ids:iface-id=ls3-lp1 \
-    options:tx_pcap=pbr-hv/vif3-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif3-rx.pcap \
-    ofport-request=1
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ls1_ro_mac=00:00:00:01:02:f1
-ls1_ro_ip=192.168.1.1
-
-ls2_ro_mac=00:00:00:01:02:f2
-ls2_ro_ip=172.16.1.1
-
-ls3_ro_mac=00:00:00:01:02:f3
-
-ls1_p1_mac=00:00:00:01:02:03
-ls1_p1_ip=192.168.1.2
-
-ls2_p1_mac=00:00:00:01:02:04
-ls2_p1_ip=172.16.1.2
-
-ls3_p1_mac=00:00:00:01:02:05
-
-# Create a drop policy
-ovn-nbctl lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
-1
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Check if packet hit the drop policy
-AT_CHECK([ovs-ofctl dump-flows br-int | \
-    grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24 actions=drop" | \
-    grep "priority=10" | \
-    grep "n_packets=1" | wc -l], [0], [dnl
-1
-])
-
-# Expected to drop the packet.
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
-rcvd_packet=`cat vif2.packets`
-AT_FAIL_IF([rcvd_packet = ""])
-
-# Override drop policy with allow
-ovn-nbctl lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
-2
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Check if packet hit the allow policy
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
-    grep "192.168.1.0" | \
-    grep "priority=20" | wc -l], [0], [dnl
-1
-])
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
-       ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > expected
-
-OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
-
-# Override allow policy with reroute
-ovn-nbctl lr-policy-add R1 30 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" reroute 20.20.1.2
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
-    grep "192.168.1.0" | \
-    grep "priority=30" | wc -l], [0], [dnl
-1
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-echo "southbound flows"
-
-ovn-sbctl dump-flows | grep lr_in_policy
-echo "ovs flows"
-ovs-ofctl dump-flows br-int
-# Check if packet hit the allow policy
-AT_CHECK([ovs-ofctl dump-flows br-int | \
-    grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" | \
-    grep "priority=30" | \
-    grep "n_packets=1" | wc -l], [0], [dnl
-1
-])
-echo "packet hit reroute policy"
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
-       ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > 3.expected
-
-OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
-
-OVN_CLEANUP([pbr-hv])
-AT_CLEANUP
-
-AT_SETUP([ovn -- policy-based routing IPv6: 1 HVs, 3 LSs, 1 lport/LS, 1 LR])
-AT_KEYWORDS([policy-based-routing])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
-# and has switch ls2 (172.16.1.0/24) connected to it.
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-ovn-nbctl ls-add ls3
-
-# Connect ls1 to R1
-ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 2001::1/64
-ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
-    type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
-
-# Connect ls2 to R1
-ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 2002::1/64
-ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
-    type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
-
-# Connect ls3 to R1
-ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 2003::1/64
-ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
-    type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
-
-# Create logical port ls1-lp1 in ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 2001::2"
-
-# Create logical port ls2-lp1 in ls2
-ovn-nbctl lsp-add ls2 ls2-lp1 \
--- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 2002::2"
-
-# Create logical port ls3-lp1 in ls3
-ovn-nbctl lsp-add ls3 ls3-lp1 \
--- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 2003::2"
-
-# Create one hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add pbr-hv
-as pbr-hv
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-
-ovs-vsctl -- add-port br-int vif1 -- \
-    set interface vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=pbr-hv/vif1-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif2 -- \
-    set interface vif2 external-ids:iface-id=ls2-lp1 \
-    options:tx_pcap=pbr-hv/vif2-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif2-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int vif3 -- \
-    set interface vif3 external-ids:iface-id=ls3-lp1 \
-    options:tx_pcap=pbr-hv/vif3-tx.pcap \
-    options:rxq_pcap=pbr-hv/vif3-rx.pcap \
-    ofport-request=1
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ls1_ro_mac=00:00:00:01:02:f1
-ls1_ro_ip=2001::1
-
-ls2_ro_mac=00:00:00:01:02:f2
-ls2_ro_ip=2002::1
-
-ls3_ro_mac=00:00:00:01:02:f3
-
-ls1_p1_mac=00:00:00:01:02:03
-ls1_p1_ip=2001::2
-
-ls2_p1_mac=00:00:00:01:02:04
-ls2_p1_ip=2002::2
-
-ls3_p1_mac=00:00:00:01:02:05
-
-# Create a drop policy
-ovn-nbctl lr-policy-add R1 10 "ip6.src==2001::/64 && ip6.dst==2002::/64" drop
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
-1
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Check if packet hit the drop policy
-AT_CHECK([ovs-ofctl dump-flows br-int | \
-    grep "ipv6_src=2001::/64,ipv6_dst=2002::/64 actions=drop" | \
-    grep "priority=10" | \
-    grep "n_packets=1" | wc -l], [0], [dnl
-1
-])
-
-# Expected to drop the packet.
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
-rcvd_packet=`cat vif2.packets`
-AT_FAIL_IF([rcvd_packet = ""])
-
-# Override drop policy with allow
-ovn-nbctl lr-policy-add R1 20 "ip6.src==2001::/64 && ip6.dst==2002::/64" allow
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
-2
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Check if packet hit the allow policy
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
-    grep "2001" | \
-    grep "priority=20" | wc -l], [0], [dnl
-1
-])
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
-       ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > expected
-
-OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
-
-# Override allow policy with reroute
-ovn-nbctl lr-policy-add R1 30 "ip6.src==2001::/64 && ip6.dst==2002::/64" reroute 2003::2
-
-# Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
-    grep "2001" | \
-    grep "priority=30" | wc -l], [0], [dnl
-1
-])
-
-# Send packet.
-packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
-       ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-echo "southbound flows"
-
-ovn-sbctl dump-flows | grep lr_in_policy
-echo "ovs flows"
-ovs-ofctl dump-flows br-int
-# Check if packet hit the allow policy
-AT_CHECK([ovs-ofctl dump-flows br-int | \
-    grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
-    grep "priority=30" | \
-    grep "n_packets=1" | wc -l], [0], [dnl
-1
-])
-echo "packet hit reroute policy"
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
-       ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > 3.expected
-
-OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
-
-OVN_CLEANUP([pbr-hv])
-AT_CLEANUP
-
-# 1 hypervisor, 1 port
-# make sure that the port state is properly set to up and back down
-# when created and deleted.
-AT_SETUP([ovn -- port state up and down])
-ovn_start
-
-ovn-nbctl ls-add ls1
-ovn-nbctl lsp-add ls1 lp1
-ovn-nbctl lsp-set-addresses lp1 unknown
-
-net_add n1
-sim_add hv1
-as hv1 ovs-vsctl add-br br-phys
-as hv1 ovn_attach n1 br-phys 192.168.0.1
-
-as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
-
-as hv1 ovs-vsctl del-port br-int vif1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-# 1 hypervisor, 1 port
-# make sure that the OF rules created to support a datapath are added/cleared
-# when logical switch is created and removed.
-AT_SETUP([ovn -- datapath rules added/removed])
-AT_KEYWORDS([cleanup])
-ovn_start
-
-net_add n1
-sim_add hv1
-as hv1 ovs-vsctl add-br br-phys
-as hv1 ovn_attach n1 br-phys 192.168.0.1
-
-# This shell function checks if OF rules in br-int have clauses
-# related to OVN datapaths. The caller determines if it should find
-# a match in the output, or not.
-#
-# EXPECT_DATAPATH param determines whether flows that refer to
-#                 datapath to should be present or not. 0 means
-#                 they should not be.
-# STAGE_INFO param is a simple string to help identify the stage
-#            in the test when this function was invoked.
-test_datapath_in_of_rules() {
-    local expect_datapath=$1 stage_info=$2
-    echo "------ ovn-nbctl show ${stage_info} ------"
-    ovn-nbctl show
-    echo "------ ovn-sbctl show ${stage_info} ------"
-    ovn-sbctl show
-    echo "------ OF rules ${stage_info} ------"
-    AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
-    # if there is a datapath mentioned in the output, check for the
-    # magic keyword that represents one, based on the exit status of
-    # a quiet grep
-    if test $expect_datapath != 0; then
-       AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
-    else
-       AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
-    fi
-}
-
-test_datapath_in_of_rules 0 "before ls+port create"
-
-ovn-nbctl ls-add ls1
-ovn-nbctl lsp-add ls1 lp1
-ovn-nbctl lsp-set-addresses lp1 unknown
-
-as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
-
-test_datapath_in_of_rules 1 "after port is bound"
-
-as hv1 ovs-vsctl del-port br-int vif1
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
-
-ovn-nbctl lsp-set-addresses lp1
-ovn-nbctl lsp-del lp1
-ovn-nbctl ls-del ls1
-
-# wait for earlier changes to take effect
-AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
-
-# ensure OF rules are no longer present. There used to be a bug here.
-test_datapath_in_of_rules 0 "after lport+ls removal"
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- nd_na ])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-#TODO: since patch port for IPv6 logical router port is not ready not,
-#  so we are not going to test vifs on different lswitches cases. Try
-#  to update for that once relevant stuff implemented.
-
-# In this test cases we create 1 lswitch, it has 2 VIF ports attached
-# with. NS packet we test, from one VIF for another VIF, will be replied
-# by local ovn-controller, but not by target VIF.
-
-# Create hypervisors and logical switch lsw0.
-ovn-nbctl ls-add lsw0
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
-ovn-nbctl lsp-add lsw0 lp1
-ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
-ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
-
-# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
-ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv1/vif2-tx.pcap options:rxq_pcap=hv1/vif2-rx.pcap ofport-request=2
-ovn-nbctl lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
-ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
-
-# Add ACL rule for ICMPv6 on lsw0
-ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6'  allow-related
-ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6'  allow-related
-ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6'  allow-related
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv1${1%?}
-}
-for i in 1 2; do
-    : > $i.expected
-done
-
-# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
-# vif1 -> NS -> vif2.  vif1 <- NA <- ovn-controller.
-# vif2 will not receive NS packet, since ovn-controller will reply for it.
-ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
-na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
-
-as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
-echo $na_packet >> 1.expected
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-ofctl -O OpenFlow13 show br-int
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-
-for i in 1 2; do
-    OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
-done
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- address sets modification/removal smoke test])
-ovn_start
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-
-row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
-ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
-ovn-nbctl destroy Address_Set $row
-
-sleep 1
-
-# A bug previously existed in the address set support code
-# that caused ovn-controller to crash after an address set
-# was updated and then removed.  This test case ensures
-# that ovn-controller is at least still running after
-# creating, updating, and deleting an address set.
-AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ipam])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Add a port to a switch that does not have a subnet set, then set the
-# subnet which should result in an address being allocated for the port.
-ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
-ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:03 192.168.1.2"
-])
-
-# Add 9 more ports to sw0, addresses should all be unique.
-for n in `seq 1 9`; do
-    ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
-done
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:04 192.168.1.3"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:05 192.168.1.4"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:06 192.168.1.5"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:07 192.168.1.6"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:08 192.168.1.7"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:09 192.168.1.8"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:0a 192.168.1.9"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:0b 192.168.1.10"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:0c 192.168.1.11"
-])
-
-# Trying similar tests with a second switch. MAC addresses should be unique
-# across both switches but IP's only need to be unique within the same switch.
-ovn-nbctl ls-add sw1
-ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
-ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:0d 192.168.1.2"
-])
-
-for n in `seq 11 19`; do
-    ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
-done
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:0e 192.168.1.3"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:0f 192.168.1.4"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:10 192.168.1.5"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:11 192.168.1.6"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:12 192.168.1.7"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:13 192.168.1.8"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:14 192.168.1.9"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:15 192.168.1.10"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:16 192.168.1.11"
-])
-
-# Change a port's address to test for multiple ip's for a single address entry
-# and addresses set by the user.
-ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
-ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:18 192.168.1.13"
-])
-
-# Test for logical router port address management.
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
-network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
--- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
--- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
-ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:1a 192.168.1.15"
-])
-
-# Test for address reuse after logical port is deleted.
-ovn-nbctl lsp-del p0
-ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:03 192.168.1.2"
-])
-
-# Test for multiple addresses to one logical port.
-ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
-"0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
-ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:17 192.168.1.16"
-])
-
-# Test for exhausting subnet address space.
-ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
-ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
-     ["0a:00:00:10:01:03 172.16.1.2"
-])
-
-ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
-     ["0a:00:00:00:00:01"
-])
-
-# Test that address management does not add duplicate MAC for lsp/lrp peers.
-ovn-nbctl create Logical_Router name=R2
-ovn-nbctl ls-add sw3
-ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
-"0a:00:00:a8:01:18"
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
-network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
--- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
--- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
-ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:1d 192.168.1.17"
-])
-
-# Test static MAC address with dynamically allocated IP
-ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
-"fe:dc:ba:98:76:54 dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
-     ["fe:dc:ba:98:76:54 192.168.1.18"
-])
-
-# Update the static MAC address with dynamically allocated IP and check
-# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
-ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
-
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
-     ["fe:dc:ba:98:76:55 192.168.1.18"
-])
-
-ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:1e 192.168.1.18"
-])
-
-ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
-     ["fe:dc:ba:98:76:56 192.168.1.18"
-])
-
-
-# Test the exclude_ips from the IPAM list
-ovn-nbctl --wait=sb set logical_switch sw0 \
-other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
-
-ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
-"dynamic"
-# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:1e 192.168.1.20"
-])
-
-ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
-"dynamic"
-# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:1f 192.168.1.22"
-])
-
-ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
-"dynamic"
-# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:34 192.168.1.51"
-])
-
-# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
-ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
-ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
-"dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:20 192.168.1.19"
-])
-
-# Set invalid data in exclude_ips list. It should be ignored.
-ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
-ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
-"dynamic"
-# 192.168.1.21 should be assigned as that's the next free one.
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:21 192.168.1.21"
-])
-
-# Clear the dynamic addresses assignment request.
-ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
-         [[[]]
-])
-
-# Set IPv6 prefix
-ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
-ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
-"dynamic"
-
-# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
-# - aef0::800:ff:fe00:26 (EUI64)
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
-     ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
-])
-
-ovn-nbctl --wait=sb ls-add sw4
-ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
--- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
-ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
-"dynamic"
-
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
-     ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
-])
-
-ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
-"f0:00:00:00:10:12 dynamic"
-
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
-     ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
-])
-
-# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
-# p40 should not have an IPv4 address since the pool is exhausted
-ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
-"dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
-         ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
-])
-
-# Test dynamic changes on switch ports.
-#
-ovn-nbctl --wait=sb ls-add sw5
-ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
-"dynamic"
-# p41 will start with nothing
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         [[[]]
-])
-
-# Set a subnet. Now p41 should have an ipv4 address, too
-ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["0a:00:00:a8:01:22 192.168.1.2"
-])
-
-# Clear the other_config. The IPv4 address should be gone
-ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         [[[]]
-])
-
-# Set an IPv6 prefix. Now p41 should have an IPv6 address.
-ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
-])
-
-# Change the MAC address to a static one. The IPv6 address should update.
-ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
-])
-
-# Change the IPv6 prefix. The IPv6 address should update.
-ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
-])
-
-# Clear the other_config. The IPv6 address should be gone
-ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         [[[]]
-])
-
-# Set the subnet again. Now p41 should get the IPv4 address again.
-ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["f0:00:00:00:10:2b 192.168.1.2"
-])
-
-# Add an excluded IP address that conflicts with p41. p41 should update.
-ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
-exclude_ips="192.168.1.2"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["f0:00:00:00:10:2b 192.168.1.3"
-])
-
-# Add static ip address
-ovn-nbctl --wait=sb lsp-set-addresses p41 "dynamic 192.168.1.100"
-ovn-nbctl list Logical-Switch-Port p41
-ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
-"dynamic 192.168.1.101"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
-         ["0a:00:00:a8:01:65 192.168.1.100"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p42 dynamic_addresses], [0],
-         ["0a:00:00:a8:01:66 192.168.1.101"
-])
-
-# define a mac address prefix
-ovn-nbctl ls-add sw6
-ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
-ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
-for n in $(seq 1 3); do
-    ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
-done
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
-    ["00:11:22:a8:64:03 192.168.100.2"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
-    ["00:11:22:a8:64:04 192.168.100.3"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
-    ["00:11:22:a8:64:05 192.168.100.4"
-])
-
-# verify configuration order does not break IPAM/MACAM
-ovn-nbctl ls-add sw7
-for n in $(seq 1 3); do
-    ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
-done
-ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
-p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
-p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
-p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
-AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
-AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
-AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
-
-# request to assign mac only
-#
-ovn-nbctl ls-add sw8
-ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
-for n in $(seq 1 3); do
-    ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
-done
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
-    ["00:11:22:00:00:06"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
-    ["00:11:22:00:00:07"
-])
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
-    ["00:11:22:00:00:08"
-])
-
-# clear mac_prefix and check it is allocated in a random manner
-ovn-nbctl --wait=hv remove NB_Global . options mac_prefix
-ovn-nbctl ls-add sw9
-ovn-nbctl --wait=sb set Logical-Switch sw9 other_config:mac_only=true
-ovn-nbctl --wait=sb lsp-add sw9 p91 -- lsp-set-addresses p91 dynamic
-
-mac_prefix=$(ovn-nbctl --wait=sb get NB_Global . options:mac_prefix | tr -d \")
-port_addr=$(ovn-nbctl get Logical-Switch-Port p91 dynamic_addresses | tr -d \")
-AT_CHECK([test "$port_addr" = "${mac_prefix}:00:00:09"], [0], [])
-
-ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22"
-ovn-nbctl ls-add sw10
-ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:ipv6_prefix="ae01::"
-ovn-nbctl --wait=sb lsp-add sw10 p101 -- lsp-set-addresses p101 "dynamic ae01::1"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p101 dynamic_addresses], [0],
-    ["00:11:22:00:00:0a ae01::1"
-])
-
-ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:subnet=192.168.110.0/24
-ovn-nbctl --wait=sb lsp-add sw10 p102 -- lsp-set-addresses p102 "dynamic 192.168.110.10 ae01::2"
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p102 dynamic_addresses], [0],
-    ["00:11:22:a8:6e:0b 192.168.110.10 ae01::2"
-])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as northd-backup
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ipam connectivity])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl lr-add R1
-
-# Test for a ping using dynamically allocated addresses.
-ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
-ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
-ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-          options:router-port=foo \
-          -- lsp-set-addresses rp-foo router
-
-# Connect alice to R1
-ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
-          options:router-port=alice addresses=\"00:00:00:01:02:04\"
-
-# Create logical port foo1 in foo
-ovn-nbctl --wait=sb lsp-add foo foo1 \
--- lsp-set-addresses foo1 "dynamic"
-AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:a8:01:03 192.168.1.2"'], [0])
-
-# Create logical port alice1 in alice
-ovn-nbctl --wait=sb lsp-add alice alice1 \
--- lsp-set-addresses alice1 "dynamic"
-AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:a8:02:03 192.168.2.2"'])
-
-# Create logical port foo2 in foo
-ovn-nbctl --wait=sb lsp-add foo foo2 \
--- lsp-set-addresses foo2 "dynamic"
-AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:a8:01:04 192.168.1.3"'])
-
-# Create a hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=foo2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
-    set interface hv1-vif3 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv1/vif3-tx.pcap \
-    options:rxq_pcap=hv1/vif3-rx.pcap \
-    ofport-request=3
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and foo2
-src_mac="0a0000a80103"
-dst_mac="0a0000a80104"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 1 3`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-# Send ip packets between foo1 and alice1
-src_mac="0a0000a80103"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-
-# Packet to Expect at foo2
-src_mac="0a0000a80103"
-dst_mac="0a0000a80104"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 1 3`
-expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
-echo $expected > expout
-AT_CHECK([cat received1.packets], [0], [expout])
-
-# Packet to Expect at alice1
-src_mac="000000010204"
-dst_mac="0a0000a80203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
-echo $expected > expout
-AT_CHECK([cat received2.packets], [0], [expout])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ovs-vswitchd restart])
-AT_KEYWORDS([vswitchd])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-net_add n1
-sim_add hv1
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-OVN_POPULATE_ARP
-sleep 2
-
-as hv1 ovs-vsctl show
-
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl dump-flows br-int
-total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
-
-echo "Total flows before vswitchd restart = " $total_flows
-
-# Code taken from ovs-save utility
-save_flows () {
-    echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
-    as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
-            -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
-    echo "EOF" >> restore_flows.sh
-}
-
-restart_vswitchd () {
-    restore_flows=$1
-
-    if test $restore_flows = true; then
-        save_flows
-    fi
-
-    as hv1
-    OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
-
-    if test $restore_flows = true; then
-        as hv1
-        ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
-    fi
-
-    as hv1
-    start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
-    ovs-ofctl dump-flows br-int
-
-    if test $restore_flows = true; then
-        sh ./restore_flows.sh
-        echo "Flows after restore"
-        as hv1
-        ovs-ofctl dump-flows br-int
-        ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
-            flow-restore-wait="true"
-    fi
-}
-
-# Save the flows, restart vswitchd and restore the flows
-restart_vswitchd true
-OVS_WAIT_UNTIL([
-    total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
-    echo "Total flows after vswitchd restart = " $total_flows_after_restart
-    test "${total_flows}" = "${total_flows_after_restart}"
-])
-
-# Restart vswitchd without restoring
-restart_vswitchd false
-OVS_WAIT_UNTIL([
-    total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
-    echo "Total flows after vswitchd restart = " $total_flows_after_restart
-    test "${total_flows}" = "${total_flows_after_restart}"
-])
-
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- send arp for nexthop])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Topology: Two LSs - ls1 and ls2 are connected via router r0
-
-# Create logical switches
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-
-# Create  router
-ovn-nbctl create Logical_Router name=lr0
-
-# Add router ls1p1 port to gateway router
-ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
-ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1  \
-    type=router options:router-port=lrp-ls1lp1 \
-    addresses='"f0:00:00:00:00:01 192.168.0.1"'
-
-# Add router ls2p2 port to gateway router
-ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
-ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
-    type=router options:router-port=lrp-ls2lp1 \
-    addresses='"f0:00:00:00:00:02 192.168.1.1"'
-
-# Set default gateway (nexthop) to 192.168.1.254
-ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
-
-# Create logical port ls1lp2 in ls1
-ovn-nbctl lsp-add ls1 ls1lp2 \
--- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
-
-# Create logical port ls2lp2 in ls2
-ovn-nbctl lsp-add ls2 ls2lp2 \
--- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
-    set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
-    options:tx_pcap=hv1/ls1lp2-tx.pcap \
-    options:rxq_pcap=hv1/ls1lp2-rx.pcap \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
-    set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
-    options:tx_pcap=hv1/ls2lp2-tx.pcap \
-    options:rxq_pcap=hv1/ls2lp2-rx.pcap \
-    ofport-request=2
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-ovn-sbctl list encap
-echo "---------------------"
-
-echo "------Flows dump-----"
-as hv1
-ovs-ofctl dump-flows
-echo "---------------------"
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-src_mac="f00000000003"
-dst_mac="f00000000001"
-src_ip=`ip_to_hex 192 168 0 2`
-dst_ip=`ip_to_hex 8 8 8 8`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-# Send IP packet destined to 8.8.8.8 from lsp1lp2
-as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
-
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-# ARP packet should be received with Target IP Address set to 192.168.1.254 and
-# not 8.8.8.8
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
-expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
-echo $expected > expout
-AT_CHECK([cat packets], [0], [expout])
-cat packets
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-# Create logical switch
-ovn-nbctl ls-add ls0
-# Create gateway router
-ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
-# Add router port to gateway router
-ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
-ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
-    type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
-# Add nat-address option
-ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl \
-    -- add-br br-phys \
-    -- add-br br-eth0
-
-ovn_attach n1 br-phys 192.168.0.1
-
-AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
-AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
-
-# Wait until the patch ports are created in hv1 to connect br-int to br-eth0
-OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
-grep "Port patch-br-int-to-ln_port" | wc -l`])
-
-# Wait for packet to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
-echo $expected > expout
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
-echo $expected >> expout
-AT_CHECK([sort packets], [0], [expout])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-# Create logical switch
-ovn-nbctl ls-add ls0
-# Create gateway router
-ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
-# Add router port to gateway router
-ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
-ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
-    type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
-# Add nat-address option
-ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
-# Add NAT rules
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
-# Add load balancers
-AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
-AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
-AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl \
-    -- add-br br-phys \
-    -- add-br br-eth0
-
-ovn_attach n1 br-phys 192.168.0.1
-
-AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
-AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
-
-# Wait until the patch ports are created to connect br-int to br-eth0
-OVS_WAIT_UNTIL([test 1 = `ovs-vsctl show | \
-grep "Port patch-br-int-to-ln_port" | wc -l`])
-
-ovn-sbctl list port_binding lrp0-rp
-echo "*****"
-ovn-nbctl list logical_switch_port lrp0-rp
-ovn-nbctl list logical_router_port lrp0
-ovn-nbctl show
-# Wait for packet to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
-echo $expected > expout
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
-echo $expected >> expout
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
-echo $expected >> expout
-AT_CHECK([sort packets], [0], [expout])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- delete mac bindings])
-ovn_start
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl -- add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-# Create logical switch ls0
-ovn-nbctl ls-add ls0
-# Create ports lp0, lp1 in ls0
-ovn-nbctl lsp-add ls0 lp0
-ovn-nbctl lsp-add ls0 lp1
-ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
-ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
-dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
-ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
-ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
-ovn-sbctl find MAC_Binding
-# Delete port lp0 and check that its MAC_Binding is deleted.
-ovn-nbctl lsp-del lp0
-ovn-sbctl find MAC_Binding
-OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
-# Delete logical switch ls0 and check that its MAC_Binding is deleted.
-ovn-nbctl ls-del ls0
-ovn-sbctl find MAC_Binding
-OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- conntrack zone allocation])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
-# connected to a router R1.
-# foo has foo1 to act as a client.
-# bar has bar1, bar2, bar3 to act as servers.
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-for i in foo1 bar1 bar2 bar3; do
-    ovs-vsctl -- add-port br-int $i -- \
-        set interface $i external-ids:iface-id=$i \
-        options:tx_pcap=hv1/$i-tx.pcap \
-        options:rxq_pcap=hv1/$i-rx.pcap
-done
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port bar1, bar2 and bar3 in bar
-for i in `seq 1 3`; do
-    ip=`expr $i + 1`
-    ovn-nbctl lsp-add bar bar$i \
-    -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
-done
-
-OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- tag allocation])
-ovn_start
-
-AT_CHECK([ovn-nbctl ls-add ls0])
-AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
-AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
-AT_CHECK([ovn-nbctl ls-add ls1])
-
-dnl When a tag is provided, no allocation is done
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
-AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
-])
-dnl The same 'tag' gets created in southbound database.
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c0"], [0], [3
-])
-
-dnl Allocate tags and see it getting created in both NB and SB
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c1"], [0], [1
-])
-
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c2"], [0], [2
-])
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c3"], [0], [4
-])
-
-dnl A different parent.
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c4"], [0], [1
-])
-
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c5"], [0], [2
-])
-
-dnl Delete a logical port and create a new one.
-AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
-AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c6"], [0], [1
-])
-
-dnl Restart northd to see that the same allocation remains.
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-start_daemon ovn-northd \
-    --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
-    --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
-
-dnl Create a switch to make sure that ovn-northd has run through the main loop.
-AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
-AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
-])
-
-dnl Create a switch port with a tag that has already been allocated.
-dnl It should go through fine with a duplicate tag.
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
-AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
-])
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="c7"], [0], [2
-])
-AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
-])
-
-AT_CHECK([ovn-nbctl ls-add ls2])
-dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
-dnl gets copied to 'tag'
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
-AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
-])
-dnl The same 'tag' gets created in southbound database.
-AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
-logical_port="local0"], [0], [25
-])
-dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
-AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
-AT_CHECK([ovn-nbctl lsp-get-tag local1])
-dnl change the tag_request.
-AT_CHECK([ovn-nbctl --wait=sb  set logical_switch_port local1 tag_request=50])
-AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
-ovn_start
-ovn-nbctl ls-add lsw0
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-    ovs-vsctl add-br br-eth0
-    AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
-done
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
-
-
-# Create 3 vifs.
-AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
-AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
-AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
-AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
-AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
-AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
-AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
-AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
-AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
-
-# Bind the localvif1 to hv1.
-as hv1
-AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
-
-# On hv1, check that there are no flows outputting bcast to tunnel
-OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
-
-# On hv2, check that no flow outputs bcast to tunnel to hv1.
-as hv2
-OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
-
-# Now bind vif2 on hv2.
-AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
-
-# At this point, the broadcast flow on vif2 should be deleted.
-# because, there is now a localnet vif bound (table=32 programming logic)
-OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
-
-# Verify that the local net patch port exists on hv2.
-OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
-
-# Now bind vif3 on hv2.
-AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
-
-# Verify that the local net patch port still exists on hv2
-OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
-
-# Delete localvif2
-AT_CHECK([ovn-nbctl lsp-del localvif2])
-
-# Verify that the local net patch port still exists on hv2,
-# because, localvif3 is still bound.
-OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-
-AT_SETUP([ovn -- ACL logging])
-AT_KEYWORDS([ovn])
-ovn_start
-
-net_add n1
-
-sim_add hv
-as hv
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-for i in lp1 lp2; do
-    ovs-vsctl -- add-port br-int $i -- \
-        set interface $i external-ids:iface-id=$i \
-        options:tx_pcap=hv/$i-tx.pcap \
-        options:rxq_pcap=hv/$i-rx.pcap
-done
-
-lp1_mac="f0:00:00:00:00:01"
-lp1_ip="192.168.1.2"
-
-lp2_mac="f0:00:00:00:00:02"
-lp2_ip="192.168.1.3"
-
-ovn-nbctl ls-add lsw0
-ovn-nbctl --wait=sb lsp-add lsw0 lp1
-ovn-nbctl --wait=sb lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp1 $lp1_mac
-ovn-nbctl lsp-set-addresses lp2 $lp2_mac
-ovn-nbctl --wait=sb sync
-
-ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
-ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
-
-ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
-ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
-
-ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
-ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
-
-ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
-ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
-
-ovn-sbctl dump-flows
-
-
-# Send packet that should be dropped without logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should be dropped with logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should be allowed without logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should be allowed with logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should allow related flows without logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should allow related flows with logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should be rejected without logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Send packet that should be rejected with logging.
-packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
-        ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
-        tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
-as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
-
-AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
-name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
-name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
-name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
-name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
-])
-
-OVN_CLEANUP([hv])
-AT_CLEANUP
-
-
-AT_SETUP([ovn -- ACL rate-limited logging])
-AT_KEYWORDS([ovn])
-ovn_start
-
-net_add n1
-
-sim_add hv
-as hv
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-for i in lp1 lp2; do
-    ovs-vsctl -- add-port br-int $i -- \
-        set interface $i external-ids:iface-id=$i \
-        options:tx_pcap=hv/$i-tx.pcap \
-        options:rxq_pcap=hv/$i-rx.pcap
-done
-
-lp1_mac="f0:00:00:00:00:01"
-lp1_ip="192.168.1.2"
-
-lp2_mac="f0:00:00:00:00:02"
-lp2_ip="192.168.1.3"
-
-ovn-nbctl ls-add lsw0
-ovn-nbctl --wait=sb lsp-add lsw0 lp1
-ovn-nbctl --wait=sb lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp1 $lp1_mac
-ovn-nbctl lsp-set-addresses lp2 $lp2_mac
-ovn-nbctl --wait=sb sync
-
-
-# Add an ACL that rate-limits logs at 10 per second.
-ovn-nbctl meter-add http-rl1 drop 10 pktps
-ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
-
-# Add an ACL that rate-limits logs at 5 per second.
-ovn-nbctl meter-add http-rl2 drop 5 pktps
-ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
-
-# Add an ACL that doesn't rate-limit logs.
-ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
-ovn-nbctl --wait=hv sync
-
-# For each ACL, send 100 packets.
-for i in `seq 1 100`; do
-    ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
-
-    ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
-
-    ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
-done
-
-# The rate at which packets are sent is highly system-dependent, so we
-# can't count on precise drop counts.  To work around that, we just
-# check that exactly 100 "http-acl3" actions were logged and that there
-# were more "http-acl1" actions than "http-acl2" ones.
-OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
-
-# On particularly slow or overloaded systems, the transmission rate may
-# be lower than the configured meter rate.  To prevent false test
-# failures, we check the duration count of the meter, and if it's
-# greater than nine seconds, just skip the test.
-d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
-
-echo "Meter duration: $d_secs"
-AT_SKIP_IF([test $d_secs -gt 9])
-
-# Print some information that may help debugging.
-as hv ovs-appctl -t ovn-controller meter-table-list
-as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
-
-n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
-n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
-n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
-
-AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
-AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
-
-OVN_CLEANUP([hv])
-AT_CLEANUP
-
-
-AT_SETUP([ovn -- DSCP marking and meter check])
-AT_KEYWORDS([ovn])
-ovn_start
-
-ovn-nbctl ls-add lsw0
-ovn-nbctl --wait=sb lsp-add lsw0 lp1
-ovn-nbctl --wait=sb lsp-add lsw0 lp2
-ovn-nbctl --wait=sb lsp-add lsw0 lp3
-ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
-ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
-ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
-ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
-ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
-ovn-nbctl --wait=sb sync
-net_add n1
-sim_add hv
-as hv
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
-ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
-
-AT_CAPTURE_FILE([trace])
-ovn_trace () {
-    ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
-}
-
-# Extracts nw_tos from the final flow from ofproto/trace output and prints
-# it on stdout.  Prints "none" if no nw_tos was included.
-get_final_nw_tos() {
-    if flow=$(grep '^Final flow:' stdout); then :; else
-       # The output didn't have a final flow.
-       return 99
-    fi
-
-    tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
-    case $tos in
-        '') echo none ;;
-        *) echo $tos ;;
-    esac
-}
-
-# check_tos TOS
-#
-# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
-check_tos() {
-    # First check with ovn-trace for logical flows.
-    echo "checking for tos $1"
-    (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
-     echo 'output("lp2");') > expout
-    AT_CHECK_UNQUOTED([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02 && ip4.src == 1.1.1.1 && ip4.dst == 1.1.1.2'], [0], [expout])
-
-    # Then re-check with ofproto/trace for a physical packet.
-    AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,dl_type=0x800,nw_src=1.1.1.1,nw_dst=1.1.1.2'], [0], [stdout-nolog])
-    AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
-])
-}
-
-# check at L2
-AT_CHECK([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02'], [0], [output("lp2");
-])
-AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02'], [0], [stdout-nolog])
-AT_CHECK([get_final_nw_tos], [0], [none
-])
-
-# check at L3 without dscp marking
-check_tos 0
-
-# Mark DSCP with a valid value
-qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
-AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
-])
-check_tos 48
-
-# check at hv without qos meter
-AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
-])
-
-# Update the meter rate
-ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
-
-# check at hv with a qos meter table
-AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
-])
-AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
-])
-
-# Update the DSCP marking
-ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
-check_tos 63
-
-# Update the meter rate
-ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
-
-# check at hv with a qos meter table
-AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
-])
-AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
-])
-
-ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
-check_tos 63
-
-# Disable DSCP marking
-ovn-nbctl --wait=hv qos-del lsw0
-AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
-])
-check_tos 0
-
-# check at hv without qos meter
-AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
-])
-
-# check meter with chassis not resident
-ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
-AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
-])
-
-# check no meter table
-AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
-])
-AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
-])
-
-OVN_CLEANUP([hv])
-AT_CLEANUP
-
-AT_SETUP([ovn -- read-only sb db:ptcp access])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-
-: > .$1.db.~lock~
-ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
-
-# Add read-only remote to sb ovsdb-server
-AT_CHECK(
-  [ovsdb-tool transact ovn-sb.db \
-     ['["OVN_Southbound",
-       {"op": "insert",
-        "table": "SB_Global",
-        "row": {
-          "connections": ["set", [["named-uuid", "xyz"]]]}},
-       {"op": "insert",
-        "table": "Connection",
-        "uuid-name": "xyz",
-        "row": {"target": "ptcp:0:127.0.0.1",
-               "read_only": true}}]']], [0], [ignore], [ignore])
-
-start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
-
-PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
-
-# read-only accesses should succeed
-AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
-AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
-
-# write access should fail
-AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
-[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
-])
-
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-AT_CLEANUP
-
-AT_SETUP([ovn -- read-only sb db:pssl access])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
-PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
-AT_SKIP_IF([expr "$PKIDIR" : ".*[ 	'\"
-\\]"])
-
-: > .$1.db.~lock~
-ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
-
-# Add read-only remote to sb ovsdb-server
-AT_CHECK(
-  [ovsdb-tool transact ovn-sb.db \
-     ['["OVN_Southbound",
-       {"op": "insert",
-        "table": "SB_Global",
-        "row": {
-          "connections": ["set", [["named-uuid", "xyz"]]]}},
-       {"op": "insert",
-        "table": "Connection",
-        "uuid-name": "xyz",
-        "row": {"target": "pssl:0:127.0.0.1",
-               "read_only": true}}]']], [0], [ignore], [ignore])
-
-start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
-                          --remote=db:OVN_Southbound,SB_Global,connections \
-                          --private-key="$PKIDIR/testpki-privkey2.pem" \
-                          --certificate="$PKIDIR/testpki-cert2.pem" \
-                          --ca-cert="$PKIDIR/testpki-cacert.pem" \
-                          ovn-sb.db
-
-PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
-
-# read-only accesses should succeed
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-                    list SB_Global], [0], [stdout], [ignore])
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-                    list Connection], [0], [stdout], [ignore])
-
-# write access should fail
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-                    chassis-add ch vxlan 1.2.4.8], [1], [ignore],
-[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
-])
-
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-AT_CLEANUP
-
-AT_SETUP([ovn -- nb connection/ssl commands])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
-PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
-AT_SKIP_IF([expr "$PKIDIR" : ".*[ 	'\"
-\\]"])
-
-: > .$1.db.~lock~
-ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
-
-# Start nb db server using db connection/ssl entries (unpopulated initially)
-start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
-                          --remote=db:OVN_Northbound,NB_Global,connections \
-                          --private-key=db:OVN_Northbound,SSL,private_key \
-                          --certificate=db:OVN_Northbound,SSL,certificate \
-                          --ca-cert=db:OVN_Northbound,SSL,ca_cert \
-                          ovn-nb.db
-
-# Populate SSL configuration entries in nb db
-AT_CHECK(
-    [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
-                       $PKIDIR/testpki-cert.pem \
-                       $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
-
-# Populate a passive SSL connection in nb db
-AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
-
-PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
-
-# Verify SSL connetivity to nb db server
-AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          list NB_Global],
-         [0], [stdout], [ignore])
-AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          list Connection],
-         [0], [stdout], [ignore])
-AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          get-connection],
-         [0], [stdout], [ignore])
-
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-AT_CLEANUP
-
-AT_SETUP([ovn -- sb connection/ssl commands])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
-PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
-AT_SKIP_IF([expr "$PKIDIR" : ".*[ 	'\"
-\\]"])
-
-: > .$1.db.~lock~
-ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
-
-# Start sb db server using db connection/ssl entries (unpopulated initially)
-start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
-                          --remote=db:OVN_Southbound,SB_Global,connections \
-                          --private-key=db:OVN_Southbound,SSL,private_key \
-                          --certificate=db:OVN_Southbound,SSL,certificate \
-                          --ca-cert=db:OVN_Southbound,SSL,ca_cert \
-                          ovn-sb.db
-
-# Populate SSL configuration entries in sb db
-AT_CHECK(
-    [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
-                       $PKIDIR/testpki-cert.pem \
-                       $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
-
-# Populate a passive SSL connection in sb db
-AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
-
-PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
-
-# Verify SSL connetivity to sb db server
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          list SB_Global],
-         [0], [stdout], [ignore])
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          list Connection],
-         [0], [stdout], [ignore])
-AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
-                    --private-key=$PKIDIR/testpki-privkey.pem \
-                    --certificate=$PKIDIR/testpki-cert.pem \
-                    --ca-cert=$PKIDIR/testpki-cacert.pem \
-          get-connection],
-         [0], [stdout], [ignore])
-
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-AT_CLEANUP
-
-AT_SETUP([ovn -- nested containers])
-ovn_start
-
-# Physical network:
-# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
-
-# Logical network:
-# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
-# and "bar" (192.168.2.0/24). They are all connected to router R1.
-
-ovn-nbctl lr-add R1
-ovn-nbctl ls-add mgmt
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-
-# Connect mgmt to R1
-ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
-ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
-          options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-          options:router-port=foo addresses=\"00:00:00:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
-          options:router-port=bar addresses=\"00:00:00:01:02:04\"
-
-# "mgmt" has VM1 and VM2 connected
-ovn-nbctl lsp-add mgmt vm1 \
--- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
-
-ovn-nbctl lsp-add mgmt vm2 \
--- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
-
-# "foo1" and "foo2" are containers belonging to switch "foo"
-# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
-ovn-nbctl lsp-add foo foo1 vm1 1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
-
-ovn-nbctl lsp-add foo foo2 vm2 2 \
--- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
-
-# "bar1" and "bar2" are containers belonging to switch "bar"
-# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
-ovn-nbctl lsp-add bar bar1 vm1 2 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
-
-ovn-nbctl lsp-add bar bar2 vm2 1 \
--- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
-
-# bar3 is a standalone VM belonging to switch "bar"
-ovn-nbctl lsp-add bar bar3 \
--- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int vm1 -- \
-    set interface vm1 external-ids:iface-id=vm1 \
-    options:tx_pcap=hv1/vm1-tx.pcap \
-    options:rxq_pcap=hv1/vm1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int bar3 -- \
-    set interface bar3 external-ids:iface-id=bar3 \
-    options:tx_pcap=hv1/bar3-tx.pcap \
-    options:rxq_pcap=hv1/bar3-rx.pcap \
-    ofport-request=2
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int vm2 -- \
-    set interface vm2 external-ids:iface-id=vm2 \
-    options:tx_pcap=hv2/vm2-tx.pcap \
-    options:rxq_pcap=hv2/vm2-rx.pcap \
-    ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and foo2 (same switch, different HVs and
-# different VLAN tags).
-src_mac="f00000010205"
-dst_mac="f00000010206"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 1 3`
-packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at foo2
-packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-echo  $packet > expected
-OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
-
-# Send ip packets between foo1 and bar2 (different switch, different HV)
-src_mac="f00000010205"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 3`
-packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at bar2
-src_mac="000000010204"
-dst_mac="f00000010208"
-packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-echo  $packet >> expected
-OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
-
-# Send ip packets between foo1 and bar1
-# (different switch, loopback to same vm but different tag)
-src_mac="f00000010205"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at bar1
-src_mac="000000010204"
-dst_mac="f00000010207"
-packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-echo  $packet > expected1
-OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
-
-# Send ip packets between bar1 and bar3
-# (same switch. But one is container and another is a standalone VM)
-src_mac="f00000010207"
-dst_mac="f00000010209"
-src_ip=`ip_to_hex 192 168 2 2`
-dst_ip=`ip_to_hex 192 168 2 3`
-packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at bar3
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-echo  $packet > expected
-OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
-
-# Send ip packets between foo1 and vm1.
-(different switch, container to the VM hosting it.)
-src_mac="f00000010205"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 2`
-packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at vm1
-src_mac="000000010202"
-dst_mac="f00000010203"
-packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-echo  $packet >> expected1
-OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
-
-# Send packets from vm1 to bar1.
-(different switch, A hosting VM to a container inside it)
-src_mac="f00000010203"
-dst_mac="000000010202"
-src_ip=`ip_to_hex 172 16 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at vm1
-src_mac="000000010204"
-dst_mac="f00000010207"
-packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-echo  $packet >> expected1
-OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
-
-# Send broadcast packet from foo1. foo1 should not receive the same packet.
-src_mac="f00000010205"
-dst_mac="ffffffffffff"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 255 255 255 255`
-packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
-
-# expected packet at VM1
-OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
-# (192.168.2.0/24) connected to it.
-#
-# R2 and R3 are gateway routers.
-# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
-# connected to it. Note how both alice and bob have the same subnet behind it.
-# We are trying to simulate external network via those 2 switches. In real
-# world the switch ports of these switches will have addresses set as "unknown"
-# to make them learning switches. Or those switches will be "localnet" ones.
-
-# Create three hypervisors and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=bar1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int hv3-vif1 -- \
-    set interface hv3-vif1 external-ids:iface-id=bob1 \
-    options:tx_pcap=hv3/vif1-tx.pcap \
-    options:rxq_pcap=hv3/vif1-rx.pcap \
-    ofport-request=1
-
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
-ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add bob
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-    options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
-    options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect bob to R3
-ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
-ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
-    type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Connect R3 to join
-ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
-ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
-    type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
-
-# Install static routes with source ip address as the policy for routing.
-# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
-
-# Install static routes with destination ip address as the policy for routing.
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-
-ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port bar1 in bar
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
-
-# Create logical port alice1 in alice
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
-
-# Create logical port bob1 in bob
-ovn-nbctl lsp-add bob bob1 \
--- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-# Send ip packets between foo1 and bar1
-# (East-west traffic should flow normally)
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-# Send ip packets between foo1 and alice1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 3`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
-
-# Send ip packets between bar1 and bob1
-src_mac="f00000010204"
-dst_mac="000001010204"
-src_ip=`ip_to_hex 192 168 2 2`
-dst_ip=`ip_to_hex 172 16 1 4`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
-#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
-
-# Packet to expect at bar1
-src_mac="000001010204"
-dst_mac="f00000010204"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 192 168 2 2`
-expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-echo $expected > expected
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-
-# Packet to Expect at alice1
-src_mac="000002010203"
-dst_mac="f00000010205"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 3`
-expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
-echo $expected > expected
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Packet to Expect at bob1
-src_mac="000003010203"
-dst_mac="f00000010206"
-src_ip=`ip_to_hex 192 168 2 2`
-dst_ip=`ip_to_hex 172 16 1 4`
-expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
-echo $expected > expected
-OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
-
-ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
-
-ovn-nbctl lsp-add ls1 ls1-lp2 \
--- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
-
-ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
-
-DNS1=`ovn-nbctl create DNS records={}`
-DNS2=`ovn-nbctl create DNS records={}`
-
-ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
-ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
-ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
-
-ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
-
-net_add n1
-sim_add hv1
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-OVN_POPULATE_ARP
-sleep 2
-as hv1 ovs-vsctl show
-
-echo "*************************"
-ovn-sbctl list DNS
-echo "*************************"
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-# set_dns_params host_name
-# Sets the dns_req_data and dns_resp_data
-set_dns_params() {
-    local hname=$1
-    local ttl=00000e10
-    an_count=0001
-    type=0001
-    case $hname in
-    vm1)
-        # vm1.ovn.org
-        query_name=03766d31036f766e036f726700
-        # IPv4 address - 10.0.0.4
-        expected_dns_answer=${query_name}00010001${ttl}00040a000004
-        ;;
-    vm2)
-        # vm2.ovn.org
-        query_name=03766d32036f766e036f726700
-        # IPv4 address - 10.0.0.6
-        expected_dns_answer=${query_name}00010001${ttl}00040a000006
-        # IPv4 address - 20.0.0.4
-        expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
-        an_count=0002
-        ;;
-    vm3)
-        # vm3.ovn.org
-        query_name=03766d33036f766e036f726700
-        # IPv4 address - 40.0.0.4
-        expected_dns_answer=${query_name}00010001${ttl}000428000004
-        ;;
-    vm1_ipv6_only)
-        # vm1.ovn.org
-        query_name=03766d31036f766e036f726700
-        # IPv6 address - aef0::4
-        type=001c
-        expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
-        ;;
-    vm1_ipv4_v6)
-        # vm1.ovn.org
-        query_name=03766d31036f766e036f726700
-        type=00ff
-        an_count=0002
-        # IPv4 address - 10.0.0.4
-        # IPv6 address - aef0::4
-        expected_dns_answer=${query_name}00010001${ttl}00040a000004
-        expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
-        expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
-        ;;
-    vm1_invalid_type)
-        # vm1.ovn.org
-        query_name=03766d31036f766e036f726700
-        # IPv6 address - aef0::4
-        type=0002
-        ;;
-    vm1_incomplete)
-        # set type to none
-        type=''
-    esac
-    # TTL - 3600
-    local dns_req_header=010201200001000000000000
-    local dns_resp_header=010281200001${an_count}00000000
-    dns_req_data=${dns_req_header}${query_name}${type}0001
-    dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
-}
-
-# This shell function sends a DNS request packet
-# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
-test_dns() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
-    local dns_query_data=$7
-    shift; shift; shift; shift; shift; shift; shift;
-    # Packet size => IPv4 header (20) + UDP header (8) +
-    #                DNS data (header + query)
-    ip_len=`expr 28 + ${#dns_query_data} / 2`
-    udp_len=`expr $ip_len - 20`
-    ip_len=$(printf "%x" $ip_len)
-    udp_len=$(printf "%x" $udp_len)
-    local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
-    request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
-    # dns data
-    request=${request}${dns_query_data}
-
-    if test $dns_reply != 0; then
-        local dns_reply=$1
-        ip_len=`expr 28 + ${#dns_reply} / 2`
-        udp_len=`expr $ip_len - 20`
-        ip_len=$(printf "%x" $ip_len)
-        udp_len=$(printf "%x" $udp_len)
-        local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
-        reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
-        echo $reply >> $inport.expected
-    else
-        for outport; do
-            echo $request >> $outport.expected
-        done
-    fi
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
-}
-
-test_dns6() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
-    local dns_query_data=$7
-    shift; shift; shift; shift; shift; shift; shift;
-    # Packet size => UDP header (8) +
-    #                DNS data (header + query)
-    ip_len=`expr 8 + ${#dns_query_data} / 2`
-    udp_len=$ip_len
-    ip_len=$(printf "%x" $ip_len)
-    udp_len=$(printf "%x" $udp_len)
-    local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
-    request=${request}9234003500${udp_len}0000
-    #dns data
-    request=${request}${dns_query_data}
-
-    if test $dns_reply != 0; then
-        local dns_reply=$1
-        ip_len=`expr 8 + ${#dns_reply} / 2`
-        udp_len=$ip_len
-        ip_len=$(printf "%x" $ip_len)
-        udp_len=$(printf "%x" $udp_len)
-        local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
-        reply=${reply}0035923400${udp_len}0000${dns_reply}
-        echo $reply >> $inport.expected
-    else
-        for outport; do
-            echo $request >> $outport.expected
-        done
-    fi
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
-}
-
-AT_CAPTURE_FILE([ofctl_monitor0.log])
-as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
-
-set_dns_params vm2
-src_ip=`ip_to_hex 10 0 0 4`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=1
-test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 1.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-cat 1.expected | cut -c -48 > expout
-AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 1.expected | cut -c 53- > expout
-AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-set_dns_params vm1
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=1
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Clear the query name options for ls1-lp2
-ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
-
-set_dns_params vm2
-src_ip=`ip_to_hex 10 0 0 4`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=0
-test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
-
-# NXT_RESUMEs should be 3.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-AT_CHECK([cat 1.packets], [0], [])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Clear the query name for ls1-lp1
-# Since ls1 has no query names configued,
-# ovn-northd should not add the DNS flows.
-ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
-
-set_dns_params vm1
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=0
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
-
-# NXT_RESUMEs should be 3 only.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-AT_CHECK([cat 2.packets], [0], [])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Test IPv6 (AAAA records) using IPv4 packet.
-# Add back the DNS options for ls1-lp1.
-ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
-
-set_dns_params vm1_ipv6_only
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=1
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
-set_dns_params vm1_ipv4_v6
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=1
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 5.
-OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-cat 2.expected | cut -c -48 > expout
-AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 2.expected | cut -c 53- > expout
-AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Invalid type.
-set_dns_params vm1_invalid_type
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=0
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
-
-# NXT_RESUMEs should be 6.
-OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-AT_CHECK([cat 2.packets], [0], [])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Incomplete DNS packet.
-set_dns_params vm1_incomplete
-src_ip=`ip_to_hex 10 0 0 6`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=0
-test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
-
-# NXT_RESUMEs should be 7.
-OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-AT_CHECK([cat 2.packets], [0], [])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Add one more DNS record to the ls1.
-ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
-
-set_dns_params vm3
-src_ip=`ip_to_hex 10 0 0 4`
-dst_ip=`ip_to_hex 10 0 0 1`
-dns_reply=1
-test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 8.
-OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-cat 1.expected | cut -c -48 > expout
-AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat 1.expected | cut -c 53- > expout
-AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-# Try DNS query over IPv6
-set_dns_params vm1
-src_ip=aef00000000000000000000000000004
-dst_ip=aef00000000000000000000000000001
-dns_reply=1
-test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
-
-# NXT_RESUMEs should be 9.
-OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-# Skipping the UDP checksum.
-cat 1.expected | cut -c 1-120,125- > expout
-AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
-
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-rm -f 1.expected
-rm -f 2.expected
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add gw1
-as gw1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-sim_add gw2
-as gw2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.4
-
-sim_add ext1
-as ext1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int ext1-vif1 -- \
-    set interface ext1-vif1 external-ids:iface-id=outside1 \
-    options:tx_pcap=ext1/vif1-tx.pcap \
-    options:rxq_pcap=ext1/vif1-rx.pcap \
-    ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect alice to R1 as distributed router gateway port on gw1
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
-
-ovn-nbctl \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=20 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=10 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
-
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port outside1 in outside
-ovn-nbctl lsp-add outside outside1 \
--- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
-
-# Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
-# mapping to the external network, is the one generating packets
-as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-test_ip_packet()
-{
-    local active_gw=$1
-    local backup_gw=$2
-    local backup_vswitchd_dead=$3
-
-    # Send ip packet between foo1 and outside1
-    src_mac="f00000010203" # foo1 mac
-    dst_mac="000001010203" # rp-foo mac (internal router leg)
-    src_ip=`ip_to_hex 192 168 1 2`
-    dst_ip=`ip_to_hex 172 16 1 3`
-    packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-    # ARP request packet to expect at outside1
-    #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
-
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-    # Send ARP reply from outside1 back to the router
-    # XXX: note, we could avoid this if we plug this port into a netns
-    # and setup the IP address into the port, so the kernel would simply reply
-    src_mac="000002010203"
-    reply_mac="f00000010204"
-    dst_ip=`ip_to_hex 172 16 1 3`
-    src_ip=`ip_to_hex 172 16 1 1`
-    arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
-
-    as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
-
-    OVS_WAIT_UNTIL([
-        test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
-grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
-    ])
-
-    # Packet to Expect at ext1 chassis, outside1 port
-    src_mac="000002010203"
-    dst_mac="f00000010204"
-    src_ip=`ip_to_hex 192 168 1 2`
-    dst_ip=`ip_to_hex 172 16 1 3`
-    expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-    echo $expected > ext1-vif1.expected
-    exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
-    echo $exp_gw_ip_garp >> ext1-vif1.expected
-    as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
-
-    if test $backup_vswitchd_dead != 1; then
-        # Reset the file only if vswitchd in backup gw is alive
-        as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
-    fi
-    as ext1 reset_pcap_file ext1-vif1 ext1/vif1
-
-    # Resend packet from foo1 to outside1
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-    sleep 1
-
-    OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
-    $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap  > packets
-    cat packets | grep $expected > exp
-    # Its possible that $active_gw/br-phys_n1-tx.pcap may have received multiple
-    # garp packets. So consider only the first packet.
-    cat packets | grep $exp_gw_ip_garp | head -1 >> exp
-    AT_CHECK([cat exp], [0], [expout])
-    rm -f expout
-    if test $backup_vswitchd_dead != 1; then
-        # Check for backup gw only if vswitchd is alive
-        $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap  > packets
-        AT_CHECK([grep $expected packets | sort], [0], [])
-    fi
-}
-
-test_ip_packet gw1 gw2 0
-
-ovn-nbctl --timeout=3 --wait=hv \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=10 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=20 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
-
-test_ip_packet gw2 gw1 0
-
-# Get the claim count of both gw1 and gw2.
-gw1_claim_ct=`grep "cr-alice: Claiming" gw1/ovn-controller.log | wc -l`
-gw2_claim_ct=`grep "cr-alice: Claiming" gw2/ovn-controller.log | wc -l`
-
-# Stop ovs-vswitchd in gw2. gw1 should claim the gateway port.
-as gw2
-OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
-
-# gw1 should claim the cr-alice and the claim count of gw1 should be
-# incremented by 1.
-gw1_claim_ct=$((gw1_claim_ct+1))
-
-OVS_WAIT_UNTIL([test $gw1_claim_ct = `cat gw1/ovn-controller.log \
-| grep -c "cr-alice: Claiming"`])
-
-AT_CHECK([test $gw2_claim_ct = `cat gw2/ovn-controller.log | \
-grep -c "cr-alice: Claiming"`])
-
-test_ip_packet gw1 gw2 1
-
-as gw2
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-OVN_CLEANUP([hv1],[gw1],[ext1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add gw1
-as gw1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-sim_add gw2
-as gw2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.4
-
-sim_add ext1
-as ext1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int ext1-vif1 -- \
-    set interface ext1-vif1 external-ids:iface-id=outside1 \
-    options:tx_pcap=ext1/vif1-tx.pcap \
-    options:rxq_pcap=ext1/vif1-rx.pcap \
-    ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R0
-ovn-nbctl create Logical_Router name=R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add join
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
-
-#Connect foo to R0
-ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
-    type=router options:router-port=R0-foo \
-    -- lsp-set-addresses foo-R0 router
-
-#Connect R0 to join
-ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
-ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
-    type=router options:router-port=R0-join \
-    -- lsp-set-addresses join-R0 router
-
-#Connect join to R1
-ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
-ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
-    type=router options:router-port=R1-join \
-    -- lsp-set-addresses join-R1 router
-
-#add route rules
-ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
-ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
-
-# Connect alice to R1 as distributed router gateway port on gw1
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
-
-ovn-nbctl \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=20 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=10 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
-
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port outside1 in outside
-ovn-nbctl lsp-add outside outside1 \
--- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
-
-# Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
-# mapping to the external network, is the one generating packets
-as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
-
-# hv1 should be in 'ref_chassis' of the ha_chasssi_group as logical
-# switch 'foo' can reach the router 'R1' (which has gw router port)
-# via foo1 -> foo -> R0 -> join -> R1
-hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$hv1_ch_uuid" = "$ref_ch_list"])
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-test_ip_packet()
-{
-    local active_gw=$1
-    local backup_gw=$2
-
-    # Send ip packet between foo1 and outside1
-    src_mac="f00000010203" # foo1 mac
-    dst_mac="000001010203" # foo-R0 mac (internal router leg)
-    src_ip=`ip_to_hex 192 168 1 2`
-    dst_ip=`ip_to_hex 172 16 1 3`
-    packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-    # ARP request packet to expect at outside1
-    #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
-
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-    # Send ARP reply from outside1 back to the router
-    # XXX: note, we could avoid this if we plug this port into a netns
-    # and setup the IP address into the port, so the kernel would simply reply
-    src_mac="000002010203"
-    reply_mac="f00000010204"
-    dst_ip=`ip_to_hex 172 16 1 3`
-    src_ip=`ip_to_hex 172 16 1 1`
-    arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
-
-    as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
-
-    OVS_WAIT_UNTIL([
-        test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
-grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
-    ])
-
-    # Packet to Expect at ext1 chassis, outside1 port
-    src_mac="000002010203"
-    dst_mac="f00000010204"
-    src_ip=`ip_to_hex 192 168 1 2`
-    dst_ip=`ip_to_hex 172 16 1 3`
-    expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
-    echo $expected > ext1-vif1.expected
-    exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
-    echo $exp_gw_ip_garp >> ext1-vif1.expected
-
-    as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
-    as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
-    as ext1 reset_pcap_file ext1-vif1 ext1/vif1
-
-    # Resend packet from foo1 to outside1
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-    OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
-    $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap  > packets
-    cat packets | grep $expected > exp
-    cat packets | grep $exp_gw_ip_garp | head -1 >> exp
-    AT_CHECK([cat exp], [0], [expout])
-
-    $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap  > packets
-    AT_CHECK([grep $expected packets | sort], [0], [])
-}
-
-test_ip_packet gw1 gw2
-
-ovn-nbctl --timeout=3 --wait=hv \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=10 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=20 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
-
-test_ip_packet gw2 gw1
-
-OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 1 LR with distributed router gateway port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR R1 that has switches foo (192.168.1.0/24) and
-# alice (172.16.1.0/24) connected to it.  The logical port
-# between R1 and alice has a "redirect-chassis" specified,
-# i.e. it is the distributed router gateway port.
-# Switch alice also has a localnet port defined.
-# An additional switch outside has a localnet port and the
-# same subnet as alice (172.16.1.0/24).
-
-# Physical network:
-# Three hypervisors hv[123].
-# hv1 hosts vif foo1.
-# hv2 is the "redirect-chassis" that hosts the distributed
-# router gateway port.
-# hv3 hosts vif outside1.
-# In order to show that connectivity works only through hv2,
-# an initial round of tests is run without any bridge-mapping
-# defined for the localnet on hv2.  These tests are expected
-# to fail.
-# Subsequent tests are run after defining the bridge-mapping
-# for the localnet on hv2. These tests are expected to succeed.
-
-# Create three hypervisors and create OVS ports corresponding
-# to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int hv3-vif1 -- \
-    set interface hv3-vif1 external-ids:iface-id=outside1 \
-    options:tx_pcap=hv3/vif1-tx.pcap \
-    options:rxq_pcap=hv3/vif1-rx.pcap \
-    ofport-request=1
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect alice to R1 as distributed router gateway port on hv2
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
-    -- set Logical_Router_Port alice options:redirect-chassis="hv2"
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port outside1 in outside
-ovn-nbctl lsp-add outside outside1 \
--- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
-
-# Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
-as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-ovn-sbctl list encap
-echo "------ Gateway_Chassis dump (SBDB) -------"
-ovn-sbctl list Gateway_Chassis
-echo "------ Port_Binding chassisredirect -------"
-ovn-sbctl find Port_Binding type=chassisredirect
-echo "-------------------------------------------"
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-echo "------ hv3 dump ----------"
-as hv3 ovs-ofctl show br-int
-as hv3 ovs-ofctl dump-flows br-int
-echo "--------------------------"
-
-
-# Check that redirect mapping is programmed only on hv2
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
-])
-# Check that hv1 sends chassisredirect port traffic to hv2
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
-])
-# Check that arp reply on distributed gateway port is only programmed on hv2
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
-])
-
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-
-: > hv2-vif1.expected
-: > hv3-vif1.expected
-
-# test_arp INPORT SHA SPA TPA [REPLY_HA]
-#
-# Causes a packet to be received on INPORT.  The packet is an ARP
-# request with SHA, SPA, and TPA as specified.  If REPLY_HA is provided, then
-# it should be the hardware address of the target to expect to receive in an
-# ARP reply; otherwise no reply is expected.
-#
-# INPORT is an logical switch port number, e.g. 11 for vif11.
-# SHA and REPLY_HA are each 12 hex digits.
-# SPA and TPA are each 8 hex digits.
-test_arp() {
-    local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
-    local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
-    as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
-
-    if test X$reply_ha != X; then
-        # Expect to receive the reply, if any.
-        local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
-        echo $reply >> hv${hv}-vif$inport.expected
-    fi
-}
-
-rtr_ip=$(ip_to_hex 172 16 1 1)
-foo_ip=$(ip_to_hex 192 168 1 2)
-outside_ip=$(ip_to_hex 172 16 1 3)
-
-echo $rtr_ip
-echo $foo_ip
-echo $outside_ip
-
-# ARP for router IP address from outside1, no response expected
-test_arp 3 1 f00000010204 $outside_ip $rtr_ip
-
-# Now check the packets actually received against the ones expected.
-OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
-
-# Send ip packet between foo1 and outside1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 3`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-# Now check the packets actually received against the ones expected.
-OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
-
-# Now add bridge-mappings on hv2, which should make everything work
-as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-# Wait until the patch ports are created in hv2 to connect br-int to br-phys
-OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
-grep "Port patch-br-int-to-ln-alice" | wc -l`])
-
-# ARP for router IP address from outside1
-test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
-
-# hv3-vif1.expected should also have the gw router port garp packet.
-exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
-echo $exp_gw_ip_garp >> hv3-vif1.expected
-
-# Now check the packets actually received against the ones expected.
-OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
-
-# Send ip packet between foo1 and outside1
-src_mac="f00000010203"
-dst_mac="000001010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 172 16 1 3`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-# Packet to Expect at outside1
-src_mac="000002010203"
-dst_mac="f00000010204"
-expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-echo "------ hv1 dump ----------"
-as hv1 ovs-ofctl show br-int
-as hv1 ovs-ofctl dump-flows br-int
-echo "------ hv2 dump ----------"
-as hv2 ovs-ofctl show br-int
-as hv2 ovs-ofctl dump-flows br-int
-echo "------ hv3 dump ----------"
-as hv3 ovs-ofctl show br-int
-as hv3 ovs-ofctl dump-flows br-int
-echo "----------------------------"
-
-echo $expected >> hv3-vif1.expected
-OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
-
-#Check ovn-trace over "chassisredirect" port
-AT_CAPTURE_FILE([trace])
-ovn_trace () {
-    ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
-}
-
-echo 'ip.ttl--;' > expout
-echo 'eth.src = 00:00:02:01:02:03;' >> expout
-echo 'eth.dst = f0:00:00:01:02:04;' >> expout
-echo 'output("ln-alice");' >> expout
-AT_CHECK_UNQUOTED([ovn_trace foo 'inport == "foo1" && eth.src == f0:00:00:01:02:03 && eth.dst == 00:00:01:01:02:03 && ip4.src == 192.168.1.2 && ip4.dst == 172.16.1.3 && ip.ttl == 0xff'], [0], [expout])
-
-# Create logical port alice1 in alice on hv1
-as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=1
-
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
-
-# Create logical port foo2 in foo on hv2
-as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=foo2 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-ovn-nbctl lsp-add foo foo2 \
--- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-: > hv1-vif2.expected
-
-# Send ip packet between alice1 and foo2
-src_mac="f00000010205"
-dst_mac="000002010203"
-src_ip=`ip_to_hex 172 16 1 4`
-dst_ip=`ip_to_hex 192 168 1 3`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
-
-# Packet to Expect at foo2
-src_mac="000001010203"
-dst_mac="f00000010206"
-src_ip=`ip_to_hex 172 16 1 4`
-dst_ip=`ip_to_hex 192 168 1 3`
-expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
-
-echo $expected >> hv2-vif1.expected
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
-
-AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
-])
-
-ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
-
-AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
-])
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-# Create logical switches
-ovn-nbctl ls-add ls0
-ovn-nbctl ls-add ls1
-# Create distributed router
-ovn-nbctl create Logical_Router name=lr0
-# Add distributed gateway port to distributed router
-ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
-    -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
-ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
-    type=router options:router-port=lrp0 addresses="router"
-# Add router port to ls1
-ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
-ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
-    type=router options:router-port=lrp1 addresses="router"
-# Add logical ports for NAT rules
-ovn-nbctl lsp-add ls1 foo1 \
--- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
-ovn-nbctl lsp-add ls1 foo2 \
--- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
-# Add nat-addresses option
-ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
-# Add NAT rules
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
-AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-
-AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-# Initially test with no bridge-mapping on hv2, expect to receive no packets
-
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-# Initially test with no bridge-mapping on hv3
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 2
-
-# Expect no packets when hv2 bridge-mapping is not present
-: > packets
-OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
-
-# Add bridge-mapping on hv2
-AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-
-# Wait until the patch ports are created in hv2 to connect br-int to br-phys
-OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
-grep "Port patch-br-int-to-ln_port" | wc -l`])
-
-# Wait for packets to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
-echo $expected > expout
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
-echo $expected >> expout
-AT_CHECK([sort packets], [0], [expout])
-sort packets | cat
-
-# Temporarily remove nat-addresses option to avoid race conditions
-# due to GARP backoff
-ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-as hv1 reset_pcap_file snoopvif hv1/snoopvif
-
-# Add OVS ports for foo1 and foo2 on hv3
-ovs-vsctl -- add-port br-int hv3-vif1 -- \
-    set interface hv3-vif1 external-ids:iface-id=foo1 \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv3-vif2 -- \
-    set interface hv3-vif2 external-ids:iface-id=foo2 \
-    ofport-request=2
-
-# Add bridge-mapping on hv3
-AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-
-# Wait until the patch ports are created in hv3 to connect br-int to br-phys
-OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-vsctl show | \
-grep "Port patch-br-int-to-ln_port" | wc -l`])
-
-# Re-add nat-addresses option
-ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
-
-# Wait for packets to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
-garp_1="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
-echo $garp_1 > expout
-garp_2="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
-echo $garp_2 >> expout
-
-cat packets | grep $garp_1 | head -1 > exp
-cat packets | grep $garp_2 | head -1 >> exp
-AT_CHECK([cat exp], [0], [expout])
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-# VLAN traffic for external network redirected through distributed router
-# gateway port should use vlans(i.e input network vlan tag) across hypervisors
-# instead of tunneling.
-AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# # One LR R1 that has switches foo (192.168.1.0/24) and
-# # alice (172.16.1.0/24) connected to it.  The logical port
-# # between R1 and alice has a "redirect-chassis" specified,
-# # i.e. it is the distributed router gateway port(172.16.1.6).
-# # Switch alice also has a localnet port defined.
-# # An additional switch outside has the same subnet as alice
-# # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
-# # which will receive the packet destined for external network
-# # (i.e 8.8.8.8 as destination ip).
-
-# Physical network:
-# # Four hypervisors hv[1234].
-# # hv1 hosts vif foo1.
-# # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
-# # Later to test GARPs for the router port - foo, hv2 and hv4 are added to the ha_chassis_group
-# # hv3 hosts nexthop port vif outside1.
-# # All other tests connect hypervisors to network n1 through br-phys for tunneling.
-# # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
-# # in order to show vlans(instead of tunneling) used between hv1 and hv2,
-# # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
-# # hv2 and hv3 are still connected to n1 network through br-phys.
-net_add n1
-
-# We are not calling ovn_attach for hv1, to avoid adding br-phys.
-# Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
-sim_add hv1
-as hv1
-ovs-vsctl \
-    -- set Open_vSwitch . external-ids:system-id=hv1 \
-    -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-    -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
-    -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
-    -- add-br br-int \
-    -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
-    -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
-
-start_daemon ovn-controller
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
-
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int hv3-vif1 -- \
-    set interface hv3-vif1 external-ids:iface-id=outside1 \
-    options:tx_pcap=hv3/vif1-tx.pcap \
-    options:rxq_pcap=hv3/vif1-rx.pcap \
-    ofport-request=1
-ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
-
-sim_add hv4
-as hv4
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.4
-ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
-
-# Create network n2 for vlan connectivity between hv1 and hv2
-net_add n2
-
-as hv1
-ovs-vsctl add-br br-ex
-net_attach n2 br-ex
-
-as hv2
-ovs-vsctl add-br br-ex
-net_attach n2 br-ex
-
-as hv4
-ovs-vsctl add-br br-ex
-net_attach n2 br-ex
-
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
-    -- set Logical_Router_Port alice options:redirect-chassis="hv2"
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router \
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port outside1 in outside, which is a nexthop address
-# for 172.16.1.0/24
-ovn-nbctl lsp-add outside outside1 \
--- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
-
-# Set default gateway (nexthop) to 172.16.1.1
-ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
-AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
-ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
-
-ovn-nbctl lsp-add foo ln-foo
-ovn-nbctl lsp-set-addresses ln-foo unknown
-ovn-nbctl lsp-set-options ln-foo network_name=public
-ovn-nbctl lsp-set-type ln-foo localnet
-AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
-
-# Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-ovn-nbctl --wait=hv --timeout=3 sync
-
-# Check that there is a logical flow in logical switch foo's pipeline
-# to set the outport to rp-foo (which is expected).
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
-grep rp-foo | grep -v is_chassis_resident | wc -l`])
-
-# Set the option 'reside-on-redirect-chassis' for foo
-ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
-# Check that there is a logical flow in logical switch foo's pipeline
-# to set the outport to rp-foo with the condition is_chassis_redirect.
-ovn-sbctl dump-flows foo
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
-grep rp-foo | grep is_chassis_resident | wc -l`])
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list nat
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-echo "---------------------"
-
-for chassis in hv1 hv2 hv3; do
-    as $chassis
-    echo "------ $chassis dump ----------"
-    ovs-vsctl show br-int
-    ovs-ofctl show br-int
-    ovs-ofctl dump-flows br-int
-    echo "--------------------------"
-done
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-foo1_ip=$(ip_to_hex 192 168 1 2)
-gw_ip=$(ip_to_hex 172 16 1 6)
-dst_ip=$(ip_to_hex 8 8 8 8)
-nexthop_ip=$(ip_to_hex 172 16 1 1)
-
-foo1_mac="f00000010203"
-foo_mac="000001010203"
-gw_mac="000002010203"
-nexthop_mac="f00000010204"
-
-# Send ip packet from foo1 to 8.8.8.8
-src_mac="f00000010203"
-dst_mac="000001010203"
-packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
-
-# Wait for GARPs announcing gw IP to arrive
-OVS_WAIT_UNTIL([
-    test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
-grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
-    ])
-
-# VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
-# is expected on bridge connecting hv1 and hv2
-expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
-echo $expected > hv1-br-ex_n2.expected
-
-# Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
-# As connection tracking not enabled for this test, snat can't be done on the packet.
-# We still see foo1 as the source ip address. But source mac(gateway MAC) and
-# dest mac(nexthop mac) are properly configured.
-expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
-echo $expected > hv3-vif1.expected
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
-as hv3 reset_pcap_file hv3-vif1 hv3/vif1
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-sleep 2
-
-# On hv1, table 32 check that no packet goes via the tunnel port
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
-| grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
-]])
-
-ip_packet() {
-    grep "1010203f00000010203"
-}
-
-# Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
-# foo1's mac.
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
-cat hv1-br-ex_n2.expected > expout
-AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
-
-# Check expected packet on nexthop interface
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
-cat hv3-vif1.expected > expout
-AT_CHECK([sort hv3-vif1], [0], [expout])
-
-# Test the GARP for the router port ip - 192.168.1.1
-ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
-
-as hv1 reset_pcap_file hv1-vif1 hv1/vif1
-as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
-as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
-
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv2 30
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 20
-
-hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
-ovn-nbctl remove logical_router_port alice options redirect-chassis
-ovn-nbctl --wait=sb set logical_router_port alice ha_chassis_group=$hagrp1_uuid
-
-# When hv2 claims the gw router port cr-alice, it should send out
-# GARP for 192.168.1.1 and it should be received by foo1 on hv1.
-
-# foo1 (on hv1) should receive GARP without VLAN tag
-exp_garp_on_foo1="ffffffffffff00000101020308060001080006040001000001010203c0a80101000000000000c0a80101"
-echo $exp_garp_on_foo1 > foo1.expout
-
-# ovn-controller on hv2 should send garp with VLAN tag
-sent_garp="ffffffffffff0000010102038100000208060001080006040001000001010203c0a80101000000000000c0a80101"
-
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
-# Wait until we receive atleast 1 packet
-OVS_WAIT_UNTIL([test 1=`$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | wc -l`])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | head -1 > packets
-echo $sent_garp > expout
-AT_CHECK([cat packets], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv4/br-ex_n2-tx.pcap > empty
-AT_CHECK([cat empty], [0], [])
-
-# Make hv4 master
-as hv1 reset_pcap_file hv1-vif1 hv1/vif1
-as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 40
-
-# Wait till cr-alice is claimed by hv4
-hv4_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=hv4)
-# check that the chassis redirect port has been claimed by the gw1 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-alice | grep $hv4_chassis | wc -l], [0],[[1
-]])
-
-# Reset the pcap file for hv2/br-ex_n2. From now on ovn-controller in hv2
-# should not send GARPs for the router ports.
-as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
-
-echo $sent_garp > br-ex_n2.expout
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
-OVN_CHECK_PACKETS([hv4/br-ex_n2-tx.pcap], [br-ex_n2.expout])
-
-sleep 2
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap > empty
-AT_CHECK([cat empty], [0], [])
-
-OVN_CLEANUP([hv1],[hv2],[hv3], [hv4])
-AT_CLEANUP
-
-AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
-AT_KEYWORDS([ovn-nd_ra])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# In this test case we create 1 lswitch with 3 VIF ports attached,
-# and a lrouter connected to the lswitch.
-# We generate the Router solicitation packet and verify the Router Advertisement
-# reply packet from the ovn-controller.
-
-# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
-# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
-# 'slaac' to allow lrp0 send RA for SLAAC mode.
-ovn-nbctl ls-add lsw0
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
-ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
-ovn-nbctl \
-    -- lsp-add lsw0 lsp0 \
-    -- set Logical_Switch_Port lsp0 type=router \
-                     options:router-port=lrp0 \
-                     addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-ovn-nbctl lsp-add lsw0 lp1
-ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
-ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
-
-ovn-nbctl lsp-add lsw0 lp2
-ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
-ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
-
-ovn-nbctl lsp-add lsw0 lp3
-ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
-ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
-
-# Add ACL rule for ICMPv6 on lsw0
-ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6'  allow-related
-ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6'  allow-related
-ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6'  allow-related
-ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6'  allow-related
-
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
-    set interface hv1-vif3 external-ids:iface-id=lp3 \
-    options:tx_pcap=hv1/vif3-tx.pcap \
-    options:rxq_pcap=hv1/vif3-rx.pcap \
-    ofport-request=3
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-# Make sure that ovn-controller has installed the corresponding OF Flow.
-OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
-
-# This shell function sends a Router Solicitation packet.
-# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
-test_ipv6_ra() {
-    local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
-    local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
-
-    local len=24
-    local mtu_opt=""
-    if test $mtu != 0; then
-        len=`expr $len + 8`
-        mtu_opt=05010000${mtu}
-    fi
-
-    if test ${#prefix_opt} != 0; then
-        prefix_opt=${prefix_opt}fdad1234567800000000000000000000
-        len=`expr $len + ${#prefix_opt} / 2`
-    fi
-
-    len=$(printf "%x" $len)
-    local lrp_mac=fa163e000001
-    local lrp_lla=fe80000000000000f8163efffe000001
-    local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
-    echo $reply >> $inport.expected
-
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
-}
-
-AT_CAPTURE_FILE([ofctl_monitor0.log])
-as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
-
-# MTU is not set and the address mode is set to slaac
-addr_mode=00
-default_prefix_option_config=030440c0ffffffffffffffff00000000
-src_mac=fa163e000002
-src_lla=fe80000000000000f8163efffe000002
-test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
-
-# NXT_RESUME should be 1.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap  > 1.packets
-
-cat 1.expected | cut -c -112 > expout
-AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum.
-cat 1.expected | cut -c 117- > expout
-AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
-
-rm -f *.expected
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-reset_pcap_file hv1-vif3 hv1/vif3
-
-# Set the MTU to 1500
-ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
-
-# Make sure that ovn-controller has installed the corresponding OF Flow.
-OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
-
-addr_mode=00
-default_prefix_option_config=030440c0ffffffffffffffff00000000
-src_mac=fa163e000003
-src_lla=fe80000000000000f8163efffe000003
-mtu=000005dc
-
-test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
-
-# NXT_RESUME should be 2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap  > 2.packets
-
-cat 2.expected | cut -c -112 > expout
-AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum.
-cat 2.expected | cut -c 117- > expout
-AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
-
-rm -f *.expected
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-reset_pcap_file hv1-vif3 hv1/vif3
-
-# Set the address mode to dhcpv6_stateful
-ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
-# Make sure that ovn-controller has installed the corresponding OF Flow.
-OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
-
-addr_mode=80
-default_prefix_option_config=03044080ffffffffffffffff00000000
-src_mac=fa163e000004
-src_lla=fe80000000000000f8163efffe000004
-mtu=000005dc
-
-test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
-
-# NXT_RESUME should be 3.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap  > 3.packets
-
-cat 3.expected | cut -c -112 > expout
-AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum.
-cat 3.expected | cut -c 117- > expout
-AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
-
-rm -f *.expected
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-reset_pcap_file hv1-vif3 hv1/vif3
-
-# Set the address mode to dhcpv6_stateless
-ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
-# Make sure that ovn-controller has installed the corresponding OF Flow.
-OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
-
-addr_mode=40
-default_prefix_option_config=030440c0ffffffffffffffff00000000
-src_mac=fa163e000002
-src_lla=fe80000000000000f8163efffe000002
-mtu=000005dc
-
-test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
-
-# NXT_RESUME should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap  > 1.packets
-
-cat 1.expected | cut -c -112 > expout
-AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum.
-cat 1.expected | cut -c 117- > expout
-AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
-
-rm -f *.expected
-reset_pcap_file hv1-vif1 hv1/vif1
-reset_pcap_file hv1-vif2 hv1/vif2
-reset_pcap_file hv1-vif3 hv1/vif3
-
-# Set the address mode to invalid.
-ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
-# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
-OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
-
-addr_mode=40
-default_prefix_option_config=""
-src_mac=fa163e000002
-src_lla=fe80000000000000f8163efffe000002
-mtu=000005dc
-
-test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
-
-# NXT_RESUME should be 4 only.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap  > 1.packets
-AT_CHECK([cat 1.packets], [0], [])
-
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- /32 router IP address])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# 2 LS 'foo' and 'alice' connected via router R1.
-# R1 connects to 'alice' with a /32 IP address. We use static routes and
-# nexthop to push traffic to a logical port in switch 'alice'
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
-          options:router-port=foo addresses=\"00:00:00:01:02:03\"
-
-# Connect alice to R1.
-ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-          type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
-
-# Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical port alice1 in alice
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
-
-#install default route in R1 to use alice1's IP address as nexthop
-ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
-
-# Create two hypervisor and create OVS ports corresponding to logical ports.
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=foo1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=alice1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-# Send ip packets between foo1 and alice1
-src_mac="f00000010203"
-dst_mac="000000010203"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 10 0 0 2`
-packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-
-# Send the first packet to trigger a ARP response and population of
-# mac_bindings table.
-as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
-ovn-nbctl --wait=hv sync
-
-# Packet to Expect at 'alice1'
-src_mac="000000010204"
-dst_mac="f00000010204"
-src_ip=`ip_to_hex 192 168 1 2`
-dst_ip=`ip_to_hex 10 0 0 2`
-echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-# Add localport to the switch
-ovn-nbctl lsp-add ls1 lp01
-ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
-ovn-nbctl lsp-set-type lp01 localport
-
-net_add n1
-
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-    ovs-vsctl add-port br-int vif01 -- \
-        set Interface vif01 external-ids:iface-id=lp01 \
-                              options:tx_pcap=hv${i}/vif01-tx.pcap \
-                              options:rxq_pcap=hv${i}/vif01-rx.pcap \
-                              ofport-request=${i}0
-
-    ovs-vsctl add-port br-int vif${i}1 -- \
-        set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
-                              options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
-                              options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
-                              ofport-request=${i}1
-
-    ovn-nbctl lsp-add ls1 lp${i}1
-    ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
-    ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
-
-        OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
-done
-
-ovn-nbctl --wait=sb sync
-ovn-sbctl dump-flows
-
-OVN_POPULATE_ARP
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    echo hv${1%?}
-}
-#
-# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  INPORT is specified as
-# logical switch port numbers, e.g. 11 for vif11.
-#
-# EOUT is the end-to-end output port, that is, where the packet will end up
-# after possibly bouncing through one or more localnet ports.  LOUT is the
-# logical output port, which might be a localnet port, as seen by ovn-trace
-# (which doesn't know what localnet ports are connected to and therefore can't
-# figure out the end-to-end answer).
-#
-# DEFHV is the default hypervisor from where the packet is going to be sent
-# if the source port is a localport.
-for i in 1 2; do
-    for j in 0 1; do
-        : > $i$j.expected
-    done
-done
-test_packet() {
-    local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
-    echo "$@"
-
-    # First try tracing the packet.
-    uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
-    if test $lout != drop; then
-        echo "output(\"$lout\");"
-    fi > expout
-    AT_CAPTURE_FILE([trace])
-    AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
-
-    # Then actually send a packet, for an end-to-end test.
-    local packet=$(echo $dst$src | sed 's/://g')${eth}
-    hv=`vif_to_hv $inport`
-    # If hypervisor 0 (localport) use the defhv parameter
-    if test $hv = hv0; then
-        hv=$defhv
-    fi
-    vif=vif$inport
-    as $hv ovs-appctl netdev-dummy/receive $vif $packet
-    if test $eout != drop; then
-        echo $packet >> ${eout#lp}.expected
-    fi
-}
-
-
-# lp11 and lp21 are on different hypervisors
-test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
-test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
-
-# Both VIFs should be able to reach the localport on their own HV
-test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
-test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
-
-# Packet sent from localport on same hv should reach the vif
-test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
-test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
-
-# Packet sent from localport on different hv should be dropped
-test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
-test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2; do
-    for j in 0 1; do
-        OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
-    done
-done
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-
-# create gateways with external network connectivity
-
-for i in 1 2; do
-    sim_add gw$i
-    as gw$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-    ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-done
-
-ovn-nbctl ls-add inside
-ovn-nbctl ls-add outside
-
-# create hypervisors with a vif port each to an internal network
-
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.1$i
-    ovs-vsctl -- add-port br-int hv$i-vif1 -- \
-        set interface hv$i-vif1 external-ids:iface-id=inside$i \
-        options:tx_pcap=hv$i/vif1-tx.pcap \
-        options:rxq_pcap=hv$i/vif1-rx.pcap \
-        ofport-request=1
-
-        ovn-nbctl lsp-add inside inside$i \
-            -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
-
-done
-
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-
-# Connect inside to R1
-ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
-    type=router options:router-port=inside \
-    -- lsp-set-addresses rp-inside router
-
-# Connect outside to R1 as distributed router gateway port on gw1+gw2
-ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
-
-ovn-nbctl --id=@gc0 create Gateway_Chassis \
-                    name=outside_gw1 chassis_name=gw1 priority=20 -- \
-          --id=@gc1 create Gateway_Chassis \
-                    name=outside_gw2 chassis_name=gw2 priority=10 -- \
-          set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
-
-ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
-    type=router options:router-port=outside \
-    -- lsp-set-addresses rp-outside router
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-ovn-nbctl --wait=hv --timeout=3 sync
-
-echo "---------NB dump-----"
-ovn-nbctl show
-echo "---------------------"
-ovn-nbctl list logical_router
-echo "---------------------"
-ovn-nbctl list logical_router_port
-echo "---------------------"
-
-echo "---------SB dump-----"
-ovn-sbctl list datapath_binding
-echo "---------------------"
-ovn-sbctl list port_binding
-echo "---------------------"
-ovn-sbctl dump-flows
-echo "---------------------"
-ovn-sbctl list chassis
-ovn-sbctl list encap
-echo "---------------------"
-echo "------ Gateway_Chassis dump (SBDB) -------"
-ovn-sbctl list Gateway_Chassis
-echo "------ Port_Binding chassisredirect -------"
-ovn-sbctl find Port_Binding type=chassisredirect
-echo "-------------------------------------------"
-
-# There should be one ha_chassis_group with the name "outside"
-ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
-ha_chassis_group name="outside"`
-
-AT_CHECK([test $ha_chassi_grp_name = outside])
-
-# There should be 2 ha_chassis rows in SB DB.
-AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | awk '{print $3}' \
-| grep '-' | wc -l ], [0], [2
-])
-
-ha_ch=`ovn-sbctl --bare --columns ha_chassis  find ha_chassis_group`
-# Trim the spaces.
-ha_ch=`echo $ha_ch | sed 's/ //g'`
-
-ha_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
-do
-    ha_ch_list="$ha_ch_list $i"
-done
-
-# Trim the spaces.
-ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
-
-AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
-
-for chassis in gw1 gw2 hv1 hv2; do
-    as $chassis
-    echo "------ $chassis dump ----------"
-    ovs-ofctl show br-int
-    ovs-ofctl dump-flows br-int
-    echo "--------------------------"
-done
-bfd_dump() {
-    for chassis in gw1 gw2 hv1 hv2; do
-        as $chassis
-        echo "------ $chassis dump (BFD)----"
-        echo "BFD (from $chassis):"
-        # dump BFD config and status to the other chassis
-        for chassis2 in gw1 gw2 hv1 hv2; do
-            if [[ "$chassis" != "$chassis2" ]]; then
-                echo " -> $chassis2:"
-                echo "   $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
-            fi
-        done
-        echo "--------------------------"
-    done
-}
-
-bfd_dump
-
-hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
-hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
-hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
-hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
-
-echo $hv1_gw1_ofport
-echo $hv1_gw2_ofport
-echo $hv2_gw1_ofport
-echo $hv2_gw2_ofport
-
-echo "--- hv1 ---"
-as hv1 ovs-ofctl dump-flows br-int table=32
-
-echo "--- hv2 ---"
-as hv2 ovs-ofctl dump-flows br-int table=32
-
-gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
-gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
-
-OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
-| wc -l], [0], [1
-])
-
-OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
-| wc -l], [0], [1
-])
-
-# make sure that flows for handling the outside router port reside on gw1
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# make sure ARP responder flows for outside router port reside on gw1 too
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
-grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
-]])
-
-# check that the chassis redirect port has been claimed by the gw1 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
-]])
-
-hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
-hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
-
-exp_ref_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
-do
-    if test $i = $hv1_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    elif test $i = $hv2_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    fi
-done
-
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-
-# at this point, we invert the priority of the gw chassis between gw1 and gw2
-
-ovn-nbctl --id=@gc0 create Gateway_Chassis \
-                    name=outside_gw1 chassis_name=gw1 priority=10 -- \
-          --id=@gc1 create Gateway_Chassis \
-                    name=outside_gw2 chassis_name=gw2 priority=20 -- \
-          set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
-
-
-# XXX: Let the change propagate down to the ovn-controllers
-ovn-nbctl --wait=hv --timeout=3 sync
-
-# we make sure that the hypervisors noticed, and inverted the slave ports
-OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
-| wc -l], [0], [1
-])
-
-OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
-| wc -l], [0], [1
-])
-
-# check that the chassis redirect port has been reclaimed by the gw2 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
-]])
-
-# check BFD enablement on tunnel ports from gw1 #########
-as gw1
-for chassis in gw2 hv1 hv2; do
-    echo "checking gw1 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-
-
-# check BFD enablement on tunnel ports from gw2 ##########
-as gw2
-for chassis in gw1 hv1 hv2; do
-    echo "checking gw2 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-
-# check BFD enablement on tunnel ports from hv1 ###########
-as hv1
-for chassis in gw1 gw2; do
-    echo "checking hv1 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-# make sure BFD is not enabled to hv2, we don't need it
-AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
-         [[
-]])
-
-
-# check BFD enablement on tunnel ports from hv2 ##########
-as hv2
-for chassis in gw1 gw2; do
-    echo "checking hv2 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-# make sure BFD is not enabled to hv1, we don't need it
-AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
-         [[
-]])
-
-# make sure that flows for handling the outside router port reside on gw2 now
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# disconnect GW2 from the network, GW1 should take over
-as gw2
-port=${sandbox}_br-phys
-as main ovs-vsctl del-port n1 $port
-
-bfd_dump
-
-# make sure that flows for handling the outside router port reside on gw2 now
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# check that the chassis redirect port has been reclaimed by the gw1 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
-]])
-
-ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
-as gw2
-for chassis in gw1 hv1 hv2; do
-    echo "checking gw2 -> $chassis"
-    OVS_WAIT_UNTIL([
-    bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
-    test "$bfd_cfg" = "enable=true min_rx=2000"
-])
-done
-ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
-for chassis in gw1 hv1 hv2; do
-    echo "checking gw2 -> $chassis"
-    OVS_WAIT_UNTIL([
-    bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
-    test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
-])
-done
-ovn-nbctl remove NB_Global . options "bfd-min-rx"
-ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
-for chassis in gw1 hv1 hv2; do
-    echo "checking gw2 -> $chassis"
-    OVS_WAIT_UNTIL([
-    bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
-    test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
-])
-done
-
-# Delete the inside1 vif. The ref_chassis in ha_chassis_group shouldn't have
-# reference to hv1.
-as hv1 ovs-vsctl del-port hv1-vif1
-
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$hv2_ch_uuid" = "$ref_ch_list"])
-
-# Delete the inside2 vif.
-ovn-sbctl show
-
-echo "Deleting hv2-vif1"
-as hv2 ovs-vsctl del-port hv2-vif1
-
-# ref_chassis of ha_chassis_group should be empty
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     exp_ref_ch_list=""
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# Delete the Gateway_Chassis for lrp - outside
-ovn-nbctl clear Logical_Router_Port outside gateway_chassis
-
-# There shoud be no ha_chassis_group rows in SB DB.
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group | wc -l`])
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
-
-ovn-nbctl remove NB_Global . options "bfd-min-rx"
-ovn-nbctl remove NB_Global . options "bfd-min-tx"
-ovn-nbctl remove NB_Global . options "bfd-mult"
-
-# Now test with HA chassis group instead of Gateway chassis in NB DB
-ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
-
-ovn-nbctl list ha_chassis_group
-ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1
-hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw1 30
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 20
-
-# ovn-northd should not create HA chassis group and HA chassis rows
-# unless the HA chassis group in OVN NB DB is associated to
-# a logical router port.
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
-
-# Associate hagrp1 to outside logical router port
-ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid
-
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
-find ha_chassis_group | wc -l`])
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
-grep -v chassis-name | wc -l`])
-
-OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
-| wc -l], [0], [1
-])
-
-OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
-| wc -l], [0], [1
-])
-
-# make sure that flows for handling the outside router port reside on gw1
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# make sure ARP responder flows for outside router port reside on gw1 too
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
-grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
-]])
-
-# check that the chassis redirect port has been claimed by the gw1 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
-]])
-
-# Re add the ovs ports.
-for i in 1 2; do
-    as hv$i
-    ovs-vsctl -- add-port br-int hv$i-vif1 -- \
-        set interface hv$i-vif1 external-ids:iface-id=inside$i \
-        options:tx_pcap=hv$i/vif1-tx.pcap \
-        options:rxq_pcap=hv$i/vif1-rx.pcap \
-        ofport-request=1
-done
-
-hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
-hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
-
-exp_ref_ch_list=''
-for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
-do
-    if test $i = $hv1_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    elif test $i = $hv2_ch_uuid; then
-        exp_ref_ch_list="${exp_ref_ch_list}$i"
-    fi
-done
-
-OVS_WAIT_UNTIL(
-    [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
-     # Trim the spaces.
-     ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
-     test "$exp_ref_ch_list" = "$ref_ch_list"])
-
-# Increase the priority of gw2
-ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40
-
-OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
-| wc -l], [0], [1
-])
-
-OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
-grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
-| wc -l], [0], [1
-])
-
-# check that the chassis redirect port has been reclaimed by the gw2 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
-]])
-
-# check BFD enablement on tunnel ports from gw1 #########
-as gw1
-for chassis in gw2 hv1 hv2; do
-    echo "checking gw1 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-
-# check BFD enablement on tunnel ports from gw2 ##########
-as gw2
-for chassis in gw1 hv1 hv2; do
-    echo "checking gw2 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-
-# check BFD enablement on tunnel ports from hv1 ###########
-as hv1
-for chassis in gw1 gw2; do
-    echo "checking hv1 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-# make sure BFD is not enabled to hv2, we don't need it
-AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
-         [[
-]])
-
-# check BFD enablement on tunnel ports from hv2 ##########
-as hv2
-for chassis in gw1 gw2; do
-    echo "checking hv2 -> $chassis"
-    AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
-             [[enable=true
-]])
-done
-# make sure BFD is not enabled to hv1, we don't need it
-AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
-         [[
-]])
-
-# make sure that flows for handling the outside router port reside on gw2 now
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# disconnect GW2 from the network, GW1 should take over
-as gw2
-port=${sandbox}_br-phys
-as main ovs-vsctl del-port n1 $port
-
-bfd_dump
-
-# make sure that flows for handling the outside router port reside on gw2 now
-OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[1
-]])
-OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
-grep 00:00:02:01:02:04 | wc -l], [0], [[0
-]])
-
-# check that the chassis redirect port has been reclaimed by the gw1 chassis
-OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
-logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
-]])
-
-OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-ovn-nbctl ls-add ls0
-ovn-nbctl ls-add ls1
-ovn-nbctl create Logical_Router name=lr0
-ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
-
-ovn-nbctl --id=@gc0 create Gateway_Chassis \
-                    name=outside_gw1 chassis_name=hv2 priority=10 -- \
-          --id=@gc1 create Gateway_Chassis \
-                    name=outside_gw2 chassis_name=hv3 priority=1 -- \
-          set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
-
-ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
-    type=router options:router-port=lrp0 addresses="router"
-ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
-ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
-    type=router options:router-port=lrp1 addresses="router"
-
-# Add NAT rules
-AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-
-sim_add hv3
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
-
-# Create a localnet port.
-AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
-AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
-AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
-AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
-
-# wait for earlier changes to take effect
-AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-as hv1 reset_pcap_file snoopvif hv1/snoopvif
-as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
-as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
-# add nat-addresses option
-ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
-
-# Wait for packets to be received through hv2.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-only_broadcast_from_lrp1() {
-    grep "fffffffffffff00000000001"
-}
-
-garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
-echo $garp > expout
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
-echo "packets on hv1-snoopvif:"
-cat hv1_snoop_tx
-AT_CHECK([sort hv1_snoop_tx], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
-echo "packets on hv2 br-phys tx"
-cat hv2_br_phys_tx
-AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
-echo "packets on hv3 br-phys tx"
-cat hv3_br_phys_tx
-AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
-
-
-# at this point, we invert the priority of the gw chassis between hv2 and hv3
-
-ovn-nbctl --wait=hv \
-          --id=@gc0 create Gateway_Chassis \
-                    name=outside_gw1 chassis_name=hv2 priority=1 -- \
-          --id=@gc1 create Gateway_Chassis \
-                    name=outside_gw2 chassis_name=hv3 priority=10 -- \
-          set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
-
-
-as hv1 reset_pcap_file snoopvif hv1/snoopvif
-as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
-as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
-
-# Wait for packets to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq >  hv1_snoopvif_tx
-AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
-AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
-AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
-
-# change localnet port tag.
-AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
-
-# wait for earlier changes to take effect
-OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-ofctl dump-flows br-int table=65 | \
-grep "actions=mod_vlan_vid:2014" | wc -l`
-])
-
-OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-ofctl dump-flows br-int table=65 | \
-grep "actions=mod_vlan_vid:2014" | wc -l`
-])
-
-# update nat-addresses option
-ovn-nbctl --wait=hv clear logical_switch_port lrp0-rp options
-
-#Wait until the Port_Binding.nat_addresses is cleared.
-OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
-logical_port=lrp0-rp | grep is_chassis | wc -l`])
-
-as hv1 reset_pcap_file snoopvif hv1/snoopvif
-as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
-as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
-
-ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
-
-#Wait until the Port_Binding.nat_addresses is set.
-OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
-logical_port=lrp0-rp | grep is_chassis | wc -l`])
-
-# Wait for packets to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
-echo $garp > expout
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq >  hv1_snoopvif_tx
-AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
-AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
-AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-
-# create two gateways with external network connectivity
-for i in 1 2; do
-    sim_add gw$i
-    as gw$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-    ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-done
-
-ovn-nbctl ls-add inside
-ovn-nbctl ls-add outside
-
-# create one hypervisors with a vif port the internal network
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.11
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=inside1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovn-nbctl lsp-add inside inside1 \
-        -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
-
-
-OVN_POPULATE_ARP
-
-ovn-nbctl create Logical_Router name=R1
-
-# Connect inside to R1
-ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
-    type=router options:router-port=inside \
-    -- lsp-set-addresses rp-inside router
-
-# Connect outside to R1 as distributed router gateway port on gw1+gw2
-ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
-
-ovn-nbctl --id=@gc0 create Gateway_Chassis \
-                    name=outside_gw1 chassis_name=gw1 priority=20 -- \
-          --id=@gc1 create Gateway_Chassis \
-                    name=outside_gw2 chassis_name=gw2 priority=10 -- \
-          set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
-
-ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
-    type=router options:router-port=outside \
-    -- lsp-set-addresses rp-outside router
-
-# Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --wait=hv --timeout=3 sync
-
-# currently when ovn-controller is restarted, the old entry is deleted
-# and a new one is created, which leaves the Gateway_Chassis with
-# an empty chassis for a while. NOTE: restarting ovn-controller in tests
-# doesn't have the same effect because "name" is conserved, and the
-# Chassis entry is not replaced.
-
-> gw1/ovn-controller.log
-
-gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
-ovn-sbctl destroy Chassis $gw2_chassis
-
-OVS_WAIT_UNTIL([test 0 = `grep -c "Releasing lport" gw1/ovn-controller.log`])
-
-OVN_CLEANUP([gw1],[gw2],[hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
-AT_KEYWORDS([ovn-nd_ns for unknown mac])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add sw0_ip6
-ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
-ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
-"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
-
-ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
-"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
-
-ovn-nbctl lr-add lr0_ip6
-ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
-ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
-ovn-nbctl lsp-set-type lrp0_ip6-attachment router
-ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
-ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
-ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
-
-ovn-nbctl ls-add public
-ovn-nbctl lsp-add public ln-public
-ovn-nbctl lsp-set-addresses ln-public unknown
-ovn-nbctl lsp-set-type ln-public localnet
-ovn-nbctl lsp-set-options ln-public network_name=phys
-
-ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
-2001:db8:1:0:200:02ff:fe01:0204/64 \
--- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
-
-#install static route
-ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
-ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
--- add Logical_Router lr0_ip6 static_routes @lrt
-
-ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
-rp-ip6_public  type=router options:router-port=ip6_public \
--- lsp-set-addresses rp-ip6_public router
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
-
-# There should be 2 Neighbor Advertisement flows for the router port
-# aef0:: ip address in logical switch pipeline with action nd_na_router.
-AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
-grep "nd_na_router" | wc -l], [0], [2
-])
-
-# There should be 4 Neighbor Advertisement flows with action nd_na_router
-# in the router pipeline for the router lr0_ip6.
-AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
-wc -l], [0], [4
-])
-
-cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
-
-# There is only one chassis.
-chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
-OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
-
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
-# addresses. ovn-controller should generate an IPv6 NS request for IPv6
-# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
-# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-# This function sends ipv6 packet
-test_ipv6() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
-
-    local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
-    packet=${packet}8000000000000000
-
-    src_mac=000002010204
-    expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
-    expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
-    expected_packet=${expected_packet}${nd_target}0101${src_mac}
-
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
-    rm -f ipv6_ns.expected
-    echo $expected_packet >> ipv6_ns.expected
-}
-
-src_mac=506400000002
-dst_mac=00000000af01
-src_ip=aef0000000000000526400fffe000002
-dst_ip=20010db800010000020002fffe010205
-dst_mcast_mac=3333ff010205
-mcast_node_ip=ff0200000000000000000001ff010205
-nd_target=20010db800010000020002fffe010205
-# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
-# should be received by the ports attached to br-phys.
-test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
-$mcast_node_ip $nd_target
-
-OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
-OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
-trim_zeros > 1.packets
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
-trim_zeros > 2.packets
-
-cat ipv6_ns.expected | cut -c -112 > expout
-AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
-AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum
-cat ipv6_ns.expected | cut -c 117- > expout
-AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
-AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
-
-# Now send a packet with destination ip other than
-# 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
-reset_pcap_file br-phys_n1 hv1/br-phys_n1
-reset_pcap_file br-phys hv1/br-phys
-
-src_mac=506400000002
-dst_mac=00000000af01
-src_ip=aef0000000000000526400fffe000002
-dst_ip=20020ab8000100000200020000020306
-# multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
-dst_mcast_mac=3333ff011305
-mcast_node_ip=ff0200000000000000000001ff011305
-nd_target=20010db800010000020002fffe011305
-test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
-$mcast_node_ip $nd_target
-
-OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
-OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
-trim_zeros > 1.packets
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
-trim_zeros > 2.packets
-
-cat ipv6_ns.expected | cut -c -112 > expout
-AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
-AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
-
-# Skipping the ICMPv6 checksum
-cat ipv6_ns.expected | cut -c 117- > expout
-AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
-AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- options:requested-chassis for logical port])
-ovn_start
-
-net_add n1
-
-ovn-nbctl ls-add ls0
-ovn-nbctl lsp-add ls0 lsp0
-
-# create two hypervisors, each with one vif port
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.11
-ovs-vsctl -- add-port br-int hv1-vif0 -- \
-set Interface hv1-vif0 ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.12
-ovs-vsctl -- add-port br-int hv2-vif0 -- \
-set Interface hv2-vif0 ofport-request=1
-
-# Allow only chassis hv1 to bind logical port lsp0.
-ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --wait=hv --timeout=3 sync
-
-# Retrieve hv1 and hv2 chassis UUIDs from southbound database
-ovn-sbctl wait-until chassis hv1
-ovn-sbctl wait-until chassis hv2
-hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
-hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
-
-# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
-echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
-as hv2
-ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
-
-OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
-AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
-
-# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
-
-# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
-echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
-as hv1
-ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
-
-OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
-AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
-
-# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
-as hv1 ovs-ofctl dump-flows br-int
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
-
-# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
-# the requested chassis for lsp0 is changed from hv1 to hv2.
-echo "verifying that lsp0 binding moves when requested-chassis is changed"
-
-ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
-OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
-OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
-
-# (6) Chassis hv2 should add flows and hv1 should not.
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
-
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- options:requested-chassis with hostname])
-
-ovn_start
-
-ovn-nbctl ls-add ls0
-ovn-nbctl lsp-add ls0 lsp0
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.11
-ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
-
-ovn-sbctl wait-until chassis hv1
-hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
-echo "hv1_hostname=${hv1_hostname}"
-ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
-as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
-
-hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
-echo "hv1_uuid=${hv1_uuid}"
-OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
-AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
-
-ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
-OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
-ovn-nbctl --wait=hv --timeout=3 sync
-AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
-
-OVN_CLEANUP([hv1])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- IPv6 periodic RA])
-ovn_start
-
-# This test sets up two hypervisors.
-# hv1 and hv2 run ovn-controllers, and
-# each has a VIF connected to the same
-# logical switch in OVN. The logical
-# switch is connected to a logical
-# router port that is configured to send
-# periodic router advertisements.
-#
-# The reason for having two ovn-controller
-# hypervisors is to ensure that the
-# periodic RAs being sent by each ovn-controller
-# are kept to their local hypervisors. If the
-# packets are not kept local, then each port
-# will receive too many RAs.
-
-net_add n1
-sim_add hv1
-sim_add hv2
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-
-ovn-nbctl lr-add ro
-ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
-
-ovn-nbctl ls-add sw
-ovn-nbctl lsp-add sw sw-ro
-ovn-nbctl lsp-set-type sw-ro router
-ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
-ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
-ovn-nbctl lsp-add sw sw-p1
-ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
-ovn-nbctl lsp-add sw sw-p2
-ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
-
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
-ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
-
-for i in 1 2 ; do
-    as hv$i
-    ovs-vsctl -- add-port br-int hv$i-vif1 -- \
-        set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
-        options:tx_pcap=hv$i/vif1-tx.pcap \
-        options:rxq_pcap=hv$i/vif1-rx.pcap \
-        ofport-request=1
-done
-
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-
-}
-
-construct_expected_ra() {
-    local src_mac=000000000001
-    local dst_mac=333300000001
-    local src_addr=fe80000000000000020000fffe000001
-    local dst_addr=ff020000000000000000000000000001
-
-    local mtu=$1
-    local ra_mo=$2
-    local ra_prefix_la=$3
-
-    local slla=0101${src_mac}
-    local mtu_opt=""
-    if test $mtu != 0; then
-        mtu_opt=05010000${mtu}
-    fi
-    shift 3
-
-    local prefix=""
-    while [[ $# -gt 0 ]] ; do
-        local size=$1
-        local net=$2
-        prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
-        shift 2
-    done
-
-    local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
-    local icmp=8600XXXX${ra}
-
-    local ip_len=$(expr ${#icmp} / 2)
-    ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
-
-    local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
-    local eth=${dst_mac}${src_mac}86dd${ip}
-    local packet=${eth}
-    echo $packet >> expected
-}
-
-ra_test() {
-    construct_expected_ra $@
-
-    for i in hv1 hv2 ; do
-        OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
-
-        $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
-
-        cat expected | cut -c -112 > expout
-        AT_CHECK([cat packets | cut -c -112], [0], [expout])
-
-        # Skip ICMPv6 checksum.
-        cat expected | cut -c 117- > expout
-        AT_CHECK([cat packets | cut -c 117-], [0], [expout])
-
-        rm -f packets
-        as $i reset_pcap_file $i-vif1 $i/vif1
-    done
-
-    rm -f expected
-}
-
-# Baseline test with no MTU
-ra_test 0 00 c0 40 aef00000000000000000000000000000
-
-# Now make sure an MTU option makes it
-ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
-ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
-
-# Now test for multiple network prefixes
-ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
-ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
-
-# Test a different address mode now
-ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
-ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
-
-# And the other address mode
-ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
-ra_test 000005dc 40 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
-
-OVN_CLEANUP([hv1],[hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ACL reject rule test])
-AT_KEYWORDS([acl-reject])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
-# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
-# unreachable frame generated from ACL rule hit
-#
-# INPORT is a lport number, e.g. 11 for vif11.
-# HV is a hypervisor number
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC and IPV4_DST are each 8 hex digits.
-# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
-test_ip_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
-    local exp_ip_chksum=$8 exp_icmp_chksum=$9
-    shift 9
-
-    local ip_ttl=ff
-    local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
-
-    local reply_icmp_ttl=ff
-    local icmp_type_code_response=0301
-    local icmp_data=00000000
-    local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
-    local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
-# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
-# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
-test_ipv6_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
-    shift 7
-
-    local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
-    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
-
-    local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM  as specified.
-# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
-#
-# INPORT is an lport number, e.g. 11 for vif11.
-# HV is an hypervisor number
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC and IPV4_DST are each 8 hex digits.
-# TCP_SPORT and TCP_DPORT are 4 hex digits.
-# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
-test_tcp_syn_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
-    local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
-    local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
-    shift 12
-
-    local ip_ttl=ff
-    local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
-
-    local tcp_rst_ttl=ff
-    local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# Create hypervisors hv[123].
-# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
-# Add all of the vifs to a single logical switch sw0.
-
-net_add n1
-ovn-nbctl ls-add sw0
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2 3; do
-        ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
-                lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
-
-        ovs-vsctl -- add-port br-int vif$i$j -- \
-                set interface vif$i$j \
-                external-ids:iface-id=sw0-p$i$j \
-                options:tx_pcap=hv$i/vif$i$j-tx.pcap \
-                options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
-                ofport-request=$i$j
-    done
-done
-
-OVN_POPULATE_ARP
-# allow some time for ovn-northd and ovn-controller to catch up.
-sleep 1
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-for i in 1 2 3; do
-    : > vif${i}1.expected
-done
-
-ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
-ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
-ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --timeout=3 --wait=hv sync
-
-test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
-test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
-test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
-
-test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
-
-test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
-test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
-test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
-
-for i in 1 2 3; do
-    OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
-done
-
-OVN_CLEANUP([hv1], [hv2], [hv3])
-AT_CLEANUP
-
-AT_SETUP([ovn -- Port Groups])
-AT_KEYWORDS([ovnpg])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-#
-# Three logical switches ls1, ls2, ls3.
-# One logical router lr0 connected to ls[123],
-# with nine subnets, three per logical switch:
-#
-#    lrp11 on ls1 for subnet 192.168.11.0/24
-#    lrp12 on ls1 for subnet 192.168.12.0/24
-#    lrp13 on ls1 for subnet 192.168.13.0/24
-#    ...
-#    lrp33 on ls3 for subnet 192.168.33.0/24
-#
-# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
-# digits are the subnet and the last digit distinguishes the VIF.
-#
-# This test will create two port groups and uses them in ACL.
-
-get_lsp_uuid () {
-    ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
-}
-
-pg1_ports=
-pg2_ports=
-for i in 1 2 3; do
-    ovn-nbctl ls-add ls$i
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            ovn-nbctl \
-                -- lsp-add ls$i lp$i$j$k \
-                -- lsp-set-addresses lp$i$j$k \
-                   "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
-            # logical ports lp[12]?1 belongs to port group pg1
-            if test $i != 3 && test $k == 1; then
-                pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
-            fi
-            # logical ports lp[23]?2 belongs to port group pg2
-            if test $i != 1 && test $k == 2; then
-                pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
-            fi
-        done
-    done
-done
-
-ovn-nbctl lr-add lr0
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
-        ovn-nbctl \
-            -- lsp-add ls$i lrp$i$j-attachment \
-            -- set Logical_Switch_Port lrp$i$j-attachment type=router \
-                             options:router-port=lrp$i$j \
-                             addresses='"00:00:00:00:ff:'$i$j'"'
-    done
-done
-
-ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
-ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
-
-# create ACLs on all lswitches to drop traffic from pg2 to pg1
-ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
-ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
-ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
-
-# Physical network:
-#
-# Three hypervisors hv[123].
-# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
-# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
-# lp?3[123] all on hv3.
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    case $1 in dnl (
-        ?11) echo 1 ;; dnl (
-        ?12 | ?21 | ?22) echo 2 ;; dnl (
-        ?13 | ?23 | ?3?) echo 3 ;;
-    esac
-}
-
-# Given the name of a logical port, prints the name of its logical router
-# port, e.g. "vif_to_lrp 123" yields 12.
-vif_to_lrp() {
-    echo ${1%?}
-}
-
-# Given the name of a logical port, prints the name of its logical
-# switch, e.g. "vif_to_ls 123" yields 1.
-vif_to_ls() {
-    echo ${1%??}
-}
-
-net_add n1
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-done
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            hv=`vif_to_hv $i$j$k`
-                as hv$hv ovs-vsctl \
-                -- add-port br-int vif$i$j$k \
-                -- set Interface vif$i$j$k \
-                    external-ids:iface-id=lp$i$j$k \
-                    options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
-                    options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
-                    ofport-request=$i$j$k
-        done
-    done
-done
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-#
-# This shell function causes a packet to be received on INPORT.  The packet's
-# content has Ethernet destination DST and source SRC (each exactly 12 hex
-# digits) and Ethernet type ETHTYPE (4 hex digits).  The OUTPORTs (zero or
-# more) list the VIFs on which the packet should be received.  INPORT and the
-# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            : > $i$j$k.expected
-        done
-    done
-done
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    in_ls=`vif_to_ls $inport`
-    in_lrp=`vif_to_lrp $inport`
-    for outport; do
-        out_ls=`vif_to_ls $outport`
-        if test $in_ls = $out_ls; then
-            # Ports on the same logical switch receive exactly the same packet.
-            echo $packet
-        else
-            # Routing decrements TTL and updates source and dest MAC
-            # (and checksum).
-            out_lrp=`vif_to_lrp $outport`
-            echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
-        fi >> $outport.expected
-    done
-}
-
-as hv1 ovs-vsctl --columns=name,ofport list interface
-as hv1 ovn-sbctl list port_binding
-as hv1 ovn-sbctl list datapath_binding
-as hv1 ovn-sbctl list port_group
-as hv1 ovn-sbctl list address_set
-as hv1 ovn-sbctl dump-flows
-as hv1 ovs-ofctl dump-flows br-int
-
-# Send IP packets between all pairs of source and destination ports,
-# packets matches ACL (pg2 to pg1) should be dropped
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-for is in 1 2 3; do
-  for js in 1 2 3; do
-    for ks in 1 2 3; do
-      bcast=
-      s=$is$js$ks
-      smac=f00000000$s
-      sip=`ip_to_hex 192 168 $is$js $ks`
-      for id in 1 2 3; do
-          for jd in 1 2 3; do
-              for kd in 1 2 3; do
-                d=$id$jd$kd
-                dip=`ip_to_hex 192 168 $id$jd $kd`
-                if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
-                if test $d != $s; then unicast=$d; else unicast=; fi
-
-                # packets matches ACL should be dropped
-                if test $id != 3 && test $kd == 1; then
-                    if test $is != 1 && test $ks == 2; then
-                        unicast=
-                    fi
-                fi
-                test_ip $s $smac $dmac $sip $dip $unicast #1
-              done
-          done
-        done
-      done
-  done
-done
-
-# Allow some time for packet forwarding.
-# XXX This can be improved.
-sleep 1
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
-                              [$i$j$k.expected])
-        done
-    done
-done
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1], [hv2], [hv3])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ACLs on Port Groups])
-AT_KEYWORDS([ovnpg_acl])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-#
-# Three logical switches ls1, ls2, ls3.
-# One logical router lr0 connected to ls[123],
-# with nine subnets, three per logical switch:
-#
-#    lrp11 on ls1 for subnet 192.168.11.0/24
-#    lrp12 on ls1 for subnet 192.168.12.0/24
-#    lrp13 on ls1 for subnet 192.168.13.0/24
-#    ...
-#    lrp33 on ls3 for subnet 192.168.33.0/24
-#
-# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
-# digits are the subnet and the last digit distinguishes the VIF.
-#
-# This test will create two port groups and ACLs will be applied on them.
-
-get_lsp_uuid () {
-    ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
-}
-
-pg1_ports=
-pg2_ports=
-for i in 1 2 3; do
-    ovn-nbctl ls-add ls$i
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            ovn-nbctl \
-                -- lsp-add ls$i lp$i$j$k \
-                -- lsp-set-addresses lp$i$j$k \
-                   "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
-            # logical ports lp[12]?1 belongs to port group pg1
-            if test $i != 3 && test $k == 1; then
-                pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
-            fi
-            # logical ports lp[23]?2 belongs to port group pg2
-            if test $i != 1 && test $k == 2; then
-                pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
-            fi
-        done
-    done
-done
-
-ovn-nbctl lr-add lr0
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
-        ovn-nbctl \
-            -- lsp-add ls$i lrp$i$j-attachment \
-            -- set Logical_Switch_Port lrp$i$j-attachment type=router \
-                             options:router-port=lrp$i$j \
-                             addresses='"00:00:00:00:ff:'$i$j'"'
-    done
-done
-
-ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
-ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
-
-# create ACLs on pg1 to drop traffic from pg2 to pg1
-ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
-ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
-        'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
-
-# Physical network:
-#
-# Three hypervisors hv[123].
-# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
-# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
-# lp?3[123] all on hv3.
-
-# Given the name of a logical port, prints the name of the hypervisor
-# on which it is located.
-vif_to_hv() {
-    case $1 in dnl (
-        ?11) echo 1 ;; dnl (
-        ?12 | ?21 | ?22) echo 2 ;; dnl (
-        ?13 | ?23 | ?3?) echo 3 ;;
-    esac
-}
-
-# Given the name of a logical port, prints the name of its logical router
-# port, e.g. "vif_to_lrp 123" yields 12.
-vif_to_lrp() {
-    echo ${1%?}
-}
-
-# Given the name of a logical port, prints the name of its logical
-# switch, e.g. "vif_to_ls 123" yields 1.
-vif_to_ls() {
-    echo ${1%??}
-}
-
-net_add n1
-for i in 1 2 3; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-done
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            hv=`vif_to_hv $i$j$k`
-                as hv$hv ovs-vsctl \
-                -- add-port br-int vif$i$j$k \
-                -- set Interface vif$i$j$k \
-                    external-ids:iface-id=lp$i$j$k \
-                    options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
-                    options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
-                    ofport-request=$i$j$k
-        done
-    done
-done
-
-# Pre-populate the hypervisors' ARP tables so that we don't lose any
-# packets for ARP resolution (native tunneling doesn't queue packets
-# for ARP resolution).
-OVN_POPULATE_ARP
-
-# Allow some time for ovn-northd and ovn-controller to catch up.
-# XXX This should be more systematic.
-sleep 1
-
-lsp_to_mac() {
-    echo f0:00:00:00:0${1:0:1}:${1:1:2}
-}
-
-lrp_to_mac() {
-    echo 00:00:00:00:ff:$1
-}
-
-# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
-#
-# This shell function causes a ICMP packet to be received on INPORT.
-# The OUTPORTs (zero or more) list the VIFs on which the packet should
-# be received.  INPORT and the OUTPORTs are specified as logical switch
-# port numbers, e.g. 123 for vif123.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            : > $i$j$k.expected
-        done
-    done
-done
-
-test_icmp() {
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
-    local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
-                  eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
-                  && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
-                  icmp4.code==0"
-    shift; shift; shift; shift; shift; shift
-    hv=hv`vif_to_hv $inport`
-    as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
-    in_ls=`vif_to_ls $inport`
-    in_lrp=`vif_to_lrp $inport`
-    for outport; do
-        out_ls=`vif_to_ls $outport`
-        if test $in_ls = $out_ls; then
-            # Ports on the same logical switch receive exactly the same packet.
-            echo $packet | ovstest test-ovn expr-to-packets
-        else
-            # Routing decrements TTL and updates source and dest MAC
-            # (and checksum).
-            out_lrp=`vif_to_lrp $outport`
-            exp_smac=`lrp_to_mac $out_lrp`
-            exp_dmac=`lsp_to_mac $outport`
-            exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
-                ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
-                icmp4.type==$icmp_type && icmp4.code==0"
-            echo $exp_packet | ovstest test-ovn expr-to-packets
-
-        fi >> $outport.expected
-    done
-}
-
-as hv1 ovs-vsctl --columns=name,ofport list interface
-as hv1 ovn-sbctl list port_binding
-as hv1 ovn-sbctl list datapath_binding
-as hv1 ovn-sbctl list port_group
-as hv1 ovn-sbctl list address_set
-as hv1 ovn-sbctl dump-flows
-as hv1 ovs-ofctl dump-flows br-int
-
-# Send IP packets between all pairs of source and destination ports,
-# packets matches ACL1 but not ACL2 should be dropped
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-for is in 1 2 3; do
-  for js in 1 2 3; do
-    for ks in 1 2 3; do
-      bcast=
-      s=$is$js$ks
-      slsp_mac=`lsp_to_mac $s`
-      slrp_mac=`lrp_to_mac $is$js`
-      sip=192.168.$is$js.$ks
-      for id in 1 2 3; do
-          for jd in 1 2 3; do
-              for kd in 1 2 3; do
-                d=$id$jd$kd
-                dlsp_mac=`lsp_to_mac $d`
-                dlrp_mac=`lrp_to_mac $id$jd`
-                dip=192.168.$id$jd.$kd
-                if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
-                if test $d != $s; then unicast=$d; else unicast=; fi
-
-                # packets matches ACL1 but not ACL2 should be dropped
-                if test $id != 3 && test $kd == 1; then
-                    if test $is == 1 || test $ks != 2; then
-                        unicast=
-                    fi
-                fi
-                # icmp request (type = 8)
-                test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
-
-                # if packets are not dropped, test the return traffic (icmp echo)
-                # to make sure stateful works, too.
-                if test x$unicast != x; then
-                    if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
-                    # icmp echo (type = 0)
-                    test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
-                fi
-              done
-          done
-        done
-      done
-  done
-done
-
-# Allow some time for packet forwarding.
-# XXX This can be improved.
-sleep 1
-
-# Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    for j in 1 2 3; do
-        for k in 1 2 3; do
-            OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
-                              [$i$j$k.expected])
-        done
-    done
-done
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1], [hv2], [hv3])
-AT_CLEANUP
-
-AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-ovn-nbctl lsp-add ls1 lp1
-ovn-nbctl lsp-add ls1 lp2
-ovn-nbctl lsp-add ls1 lp3
-
-ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
-ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
-ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
-
-ovn-nbctl create Port_Group name=pg1
-ovn-nbctl create Port_Group name=pg2
-
-ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
-
-ovn-nbctl --wait=sb sync
-
-dnl Check if port group address sets were populated with ports' addresses
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.0.0.1", "10.0.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
-         [0], [[["10.0.0.2", "10.0.0.3"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8::1", "2001:db8::2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
-         [0], [[["2001:db8::2", "2001:db8::3"]]
-])
-
-ovn-nbctl --wait=sb lsp-set-addresses lp1 \
-    "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
-
-dnl Check if updated address got propagated to the port group address sets
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.0.0.11", "10.0.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8::11", "2001:db8::2"]]
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
-ovn_start
-
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-ovn-nbctl ls-add ls3
-
-ovn-nbctl set Logical_Switch ls1 \
-    other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
-ovn-nbctl set Logical_Switch ls2 \
-    other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
-ovn-nbctl set Logical_Switch ls3 \
-    other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
-
-ovn-nbctl lsp-add ls1 lp1
-ovn-nbctl lsp-add ls2 lp2
-ovn-nbctl lsp-add ls3 lp3
-
-ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
-ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
-ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
-
-ovn-nbctl create Port_Group name=pg1
-ovn-nbctl create Port_Group name=pg2
-
-ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
-ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
-
-ovn-nbctl --wait=sb sync
-
-dnl Check if port group address sets were populated with ports' addresses
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.1.0.2", "10.2.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
-         [0], [[["10.2.0.2", "10.3.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
-         [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
-])
-
-ovn-nbctl --wait=sb set Logical_Switch ls1 \
-    other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
-
-dnl Check if updated address got propagated to the port group address sets
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.11.0.2", "10.2.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ACL conjunction])
-ovn_start
-
-ovn-nbctl ls-add ls1
-
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
-
-ovn-nbctl lsp-add ls1 ls1-lp2 \
--- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
-
-ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
-
-net_add n1
-sim_add hv1
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=2
-
-ovn-nbctl create Address_Set name=set1 \
-addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
-ovn-nbctl create Address_Set name=set2 \
-addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
-ovn-nbctl acl-add ls1 to-lport 1002 \
-'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
-ovn-nbctl acl-add ls1 to-lport 1001 \
-'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
-
-# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
-#
-# This shell function causes an ip packet to be received on INPORT.
-# The packet's content has Ethernet destination DST and source SRC
-# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
-# The OUTPORTs (zero or more) list the VIFs on which the packet should
-# be received.  INPORT and the OUTPORTs are specified as logical switch
-# port numbers, e.g. 11 for vif11.
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
-${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-    for outport; do
-        echo $packet >> $outport.expected
-    done
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-
-sip=`ip_to_hex 10 0 0 4`
-dip=`ip_to_hex 10 0 0 6`
-
-test_ip 1 f00000000001 f00000000002 $sip $dip 2
-
-cat 2.expected > expout
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-AT_CHECK([cat 2.packets], [0], [expout])
-
-# There should be total of 12 flows present with conjunction action and 2 flows
-# with conj match. Eg.
-# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
-# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
-# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
-# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
-# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
-# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
-# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
-# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
-# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
-# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
-
-OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
-grep conjunction | wc -l`])
-OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
-grep conj_id | wc -l`])
-
-as hv1 ovs-ofctl dump-flows br-int
-
-# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
-ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
-ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
-
-reset_pcap_file hv1-vif2 hv1/vif2
-
-rm -f 2.packets
-
-sip=`ip_to_hex 10 0 0 4`
-dip=`ip_to_hex 10 0 0 7`
-
-test_ip 1 f00000000001 f00000000002 $sip $dip
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
-AT_CHECK([cat 2.packets], [0], [])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- TTL exceeded])
-AT_KEYWORDS([ttl-exceeded])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
-# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
-# generated by OVN logical router
-#
-# INPORT is a lport number, e.g. 11 for vif11.
-# HV is a hypervisor number
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
-# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
-test_ip_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
-    local exp_ip_chksum=$9 exp_icmp_chksum=${10}
-    shift 10
-
-    local ip_ttl=01
-    local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
-
-    local reply_icmp_ttl=fe
-    local icmp_type_code_response=0b00
-    local icmp_data=00000000
-    local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
-    local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
-# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
-# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
-# packet sent by OVN logical router
-test_ip6_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
-    shift 8
-
-    local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
-    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
-
-    local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-for i in 1 2; do
-    net_add n$i
-    ovn-nbctl ls-add sw$i
-
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n$i br-phys 192.168.$i.1
-
-    ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
-        lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
-
-    ovs-vsctl -- add-port br-int vif$i -- \
-        set interface vif$i \
-        external-ids:iface-id=sw$i-p${i}0 \
-            options:tx_pcap=hv$i/vif$i-tx.pcap \
-            options:rxq_pcap=hv$i/vif$i-rx.pcap \
-            ofport-request=$i
-done
-
-ovn-nbctl lr-add lr0
-for i in 1 2; do
-    ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
-    ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
-              -- set Logical_Switch_Port lrp$i-attachment type=router \
-                options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
-done
-
-OVN_POPULATE_ARP
-# allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-
-test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
-test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
-
-OVN_CLEANUP([hv1], [hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- router port unreachable])
-AT_KEYWORDS([router-port-unreachable])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
-# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
-# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
-#
-# INPORT is a lport number, e.g. 11 for vif11.
-# HV is a hypervisor number
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
-# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
-test_ip_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
-    local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
-    shift 11
-
-    local ip_ttl=ff
-    local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
-
-    local reply_icmp_ttl=fe
-    local icmp_data=00000000
-    local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
-    local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM  as specified.
-# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
-#
-# INPORT is an lport number, e.g. 11 for vif11.
-# HV is an hypervisor number
-# ETH_SRC and ETH_DST are each 12 hex digits.
-# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
-# TCP_SPORT and TCP_DPORT are 4 hex digits.
-# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
-test_tcp_syn_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
-    local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
-    local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
-    shift 12
-
-    local ip_ttl=ff
-    local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
-
-    local tcp_rst_ttl=fe
-    local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
-# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
-# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
-test_tcp6_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
-    local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
-    local exp_tcp_rst_chksum=${10}
-    shift 10
-
-    local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
-    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
-
-    local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
-#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
-# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
-# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
-test_ip6_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
-    local exp_icmp_code=${10} exp_icmp_chksum=${11}
-    shift 11
-
-    local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
-    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
-
-    local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
-    echo $reply >> vif$inport.expected
-
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-for i in 1 2; do
-    net_add n$i
-    ovn-nbctl ls-add sw$i
-
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n$i br-phys 192.168.$i.1
-
-    ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
-        lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
-
-    ovs-vsctl -- add-port br-int vif$i -- \
-        set interface vif$i \
-        external-ids:iface-id=sw$i-p${i}0 \
-            options:tx_pcap=hv$i/vif$i-tx.pcap \
-            options:rxq_pcap=hv$i/vif$i-rx.pcap \
-            ofport-request=$i
-done
-
-ovn-nbctl lr-add lr0
-for i in 1 2; do
-    ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
-    ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
-              -- set Logical_Switch_Port lrp$i-attachment type=router \
-                options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
-done
-
-OVN_POPULATE_ARP
-# allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-
-test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
-test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
-test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
-
-test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
-test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
-test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
-
-OVN_CLEANUP([hv1], [hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ovn-controller exit])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-# Logical network:
-# One Logical Router: ro, with two logical switches sw1 and sw2.
-# sw1 is for subnet 10.0.0.0/8
-# sw2 is for subnet 20.0.0.0/8
-# sw1 has a single port bound on hv1
-# sw2 has a single port bound on hv2
-
-ovn-nbctl lr-add ro
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add sw2
-
-sw1_ro_mac=00:00:10:00:00:01
-sw1_ro_ip=10.0.0.1
-sw2_ro_mac=00:00:20:00:00:01
-sw2_ro_ip=20.0.0.1
-sw1_p1_mac=00:00:10:00:00:02
-sw1_p1_ip=10.0.0.2
-sw2_p1_mac=00:00:20:00:00:02
-sw2_p1_ip=20.0.0.2
-
-ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
-ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
-ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
-  options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
-ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
-  options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
-
-ovn-nbctl lsp-add sw1 sw1-p1 \
--- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
-
-ovn-nbctl lsp-add sw2 sw2-p1 \
--- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-OVN_POPULATE_ARP
-
-sleep 1
-
-packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
-       ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-
-# Start by Sending the packet and make sure it makes it there as expected
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
-       ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Stop ovn-controller on hv2
-as hv2 ovs-appctl -t ovn-controller exit
-
-# Now send the packet again. This time, it should not arrive.
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Start ovn-controller again just so OVN_CLEANUP doesn't complain
-as hv2 start_daemon ovn-controller
-
-OVN_CLEANUP([hv1],[hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- external logical port])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-sim_add hv1
-sim_add hv2
-sim_add hv3
-
-ovn-nbctl ls-add ls1
-ovn-nbctl lsp-add ls1 ls1-lp1 \
--- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
-
-# Add a couple of external logical port
-ovn-nbctl lsp-add ls1 ls1-lp_ext1 \
--- lsp-set-addresses ls1-lp_ext1 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
-ovn-nbctl lsp-set-port-security ls1-lp_ext1 \
-"f0:00:00:00:00:03 10.0.0.6 ae70::6"
-ovn-nbctl lsp-set-type ls1-lp_ext1 external
-
-ovn-nbctl lsp-add ls1 ls1-lp_ext2 \
--- lsp-set-addresses ls1-lp_ext2 "f0:00:00:00:00:04 10.0.0.7 ae70::7"
-ovn-nbctl lsp-set-port-security ls1-lp_ext2 \
-"f0:00:00:00:00:04 10.0.0.7 ae70::8"
-ovn-nbctl lsp-set-type ls1-lp_ext2 external
-
-d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
-options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
-\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
-
-d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
-options="\"server_id\"=\"00:00:00:10:00:01\"")"
-
-ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
-ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext1 ${d1}
-ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext2 ${d1}
-
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d2}
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext1 ${d2}
-ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext2 ${d2}
-
-# Create a logical router and connect it to ls1
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lr0-ls1 a0:10:00:00:00:01 10.0.0.1/24
-ovn-nbctl lsp-add ls1 ls1-lr0
-ovn-nbctl set Logical_Switch_Port ls1-lr0 type=router \
-    options:router-port=lr0-ls1 addresses=router
-
-# Create HA chassis group
-ovn-nbctl ha-chassis-group-add hagrp1
-ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
-
-hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name="hagrp1"`
-
-# There should be 1 HA_Chassis rows with chassis sets
-OVS_WAIT_UNTIL([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
-| grep '-' | wc -l ], [0], [1
-])
-
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-phys hv1-ext1 -- \
-    set interface hv1-ext1 options:tx_pcap=hv1/ext1-tx.pcap \
-    options:rxq_pcap=hv1/ext1-rx.pcap \
-    ofport-request=2
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-phys hv2-ext2 -- \
-    set interface hv2-ext2 options:tx_pcap=hv2/ext2-tx.pcap \
-    options:rxq_pcap=hv2/ext2-rx.pcap \
-    ofport-request=2
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-as hv3
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-phys hv3-ext3 -- \
-    set interface hv3-ext3 options:tx_pcap=hv3/ext3-tx.pcap \
-    options:rxq_pcap=hv3/ext3-rx.pcap \
-    ofport-request=2
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-# No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and
-# hv2 as ha-chassis-group is not set and no localnet port added to ls1.
-AT_CHECK([ovn-sbctl dump-flows ls1 | grep "offerip = 10.0.0.6" | \
-wc -l], [0], [0
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
-])
-
-hv1_uuid=$(ovn-sbctl list chassis hv1 | grep uuid | awk '{print $3}')
-hv2_uuid=$(ovn-sbctl list chassis hv2 | grep uuid | awk '{print $3}')
-hv3_uuid=$(ovn-sbctl list chassis hv3 | grep uuid | awk '{print $3}')
-
-# The port_binding row for ls1-lp_ext1 should have empty chassis
-chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-
-AT_CHECK([test x$chassis == x], [0], [])
-
-# Associate hagrp1 ha-chassis-group to ls1-lp_ext1
-ovn-nbctl --wait=hv set Logical_Switch_Port ls1-lp_ext1 \
-ha-chassis-group=$hagrp1_uuid
-
-# Get the hagrp1 uuid in SB DB.
-sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
-name="hagrp1"`
-
-# Wait till ls1-lp_ext1 port_binding has ha_chassis_group set
-OVS_WAIT_UNTIL(
-    [sb_pb_hagrp=`ovn-sbctl --bare --columns ha_chassis_group find \
-port_binding logical_port=ls1-lp_ext1`
-     test "$sb_pb_hagrp" = "$sb_hagrp1_uuid"])
-
-# No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
-# as no localnet port added to ls1 yet.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
-])
-
-# Add the localnet port to the logical switch ls1
-ovn-nbctl lsp-add ls1 ln-public
-ovn-nbctl lsp-set-addresses ln-public unknown
-ovn-nbctl lsp-set-type ln-public localnet
-ovn-nbctl --wait=hv lsp-set-options ln-public network_name=phys
-
-ln_public_key=$(ovn-sbctl list port_binding ln-public | grep  tunnel_key | \
-awk '{print $3}')
-
-# The ls1-lp_ext1 should be bound to hv1 as only hv1 is part of the
-# ha chassis group.
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = "$hv1_uuid"])
-
-# There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
-wc -l], [0], [3
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
-grep reg14=0x$ln_public_key | wc -l], [0], [1
-])
-
-# There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
-])
-
-# No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
-# hv2 as requested-chassis option is not set.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.07" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.07" | wc -l], [0], [0
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
-])
-
-as hv1
-ovs-vsctl show
-
-# This shell function sends a DHCP request packet
-# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
-test_dhcp() {
-    local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
-    shift; shift; shift; shift; shift;
-    if test $use_ip != 0; then
-        src_ip=$1
-        dst_ip=$2
-        shift; shift;
-    else
-        src_ip=`ip_to_hex 0 0 0 0`
-        dst_ip=`ip_to_hex 255 255 255 255`
-    fi
-    local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
-    # udp header and dhcp header
-    request=${request}0044004300fc0000
-    request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
-    # client hardware padding
-    request=${request}00000000000000000000
-    # server hostname
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    # boot file name
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    request=${request}0000000000000000000000000000000000000000000000000000000000000000
-    # dhcp magic cookie
-    request=${request}63825363
-    # dhcp message type
-    request=${request}3501${dhcp_type}ff
-
-    local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
-    # total IP length will be the IP length of the request packet
-    # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
-    ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
-    udp_len=`expr $ip_len - 20`
-    ip_len=$(printf "%x" $ip_len)
-    udp_len=$(printf "%x" $udp_len)
-    # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
-    local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
-    # udp header and dhcp header.
-    # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
-    reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
-    # your ip address
-    reply=${reply}${offer_ip}
-    # next server ip address, relay agent ip address, client mac address
-    reply=${reply}0000000000000000${src_mac}
-    # client hardware padding
-    reply=${reply}00000000000000000000
-    # server hostname
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    # boot file name
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
-    # dhcp magic cookie
-    reply=${reply}63825363
-    # dhcp message type
-    local dhcp_reply_type=02
-    if test $dhcp_type = 03; then
-        dhcp_reply_type=05
-    fi
-    reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
-    echo $reply >> ext1_v4.expected
-
-    as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
-}
-
-
-trim_zeros() {
-    sed 's/\(00\)\{1,\}$//'
-}
-
-# This shell function sends a DHCPv6 request packet
-# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
-# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
-# packet should be received twice (one from ovn-controller and the other
-# from the "ovs-ofctl monitor br-int resume"
-test_dhcpv6() {
-    local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
-    local req_pkt_in_expected=$6
-    local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
-    # dst ip ff02::1:2
-    request=${request}ff020000000000000000000000010002
-    # udp header and dhcpv6 header
-    request=${request}02220223002affff${msg_code}010203
-    # Client identifier
-    request=${request}0001000a00030001${src_mac}
-    # IA-NA (Identity Association for Non Temporary Address)
-    request=${request}0003000c0102030400000e1000001518
-    shift; shift; shift; shift; shift;
-
-    local server_mac=000000100001
-    local server_lla=fe80000000000000020000fffe100001
-    local reply_code=07
-    if test $msg_code = 01; then
-        reply_code=02
-    fi
-    local msg_len=54
-    if test $offer_ip = 1; then
-        msg_len=28
-    fi
-    local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101
-    reply=${reply}${server_lla}${src_lla}
-
-    # udp header and dhcpv6 header
-    reply=${reply}0223022200${msg_len}ffff${reply_code}010203
-    # Client identifier
-    reply=${reply}0001000a00030001${src_mac}
-    # IA-NA
-    if test $offer_ip != 1; then
-        reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}
-        reply=${reply}ffffffffffffffff
-    fi
-    # Server identifier
-    reply=${reply}0002000a00030001${server_mac}
-
-    echo $reply | trim_zeros >> ext${inport}_v6.expected
-    # The inport also receives the request packet since it is connected
-    # to the br-phys.
-    #echo $request >> ext${inport}_v6.expected
-
-    as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
-}
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-AT_CAPTURE_FILE([ofctl_monitor0_hv1.log])
-as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv1.log
-
-AT_CAPTURE_FILE([ofctl_monitor0_hv2.log])
-as hv2 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv2.log
-
-AT_CAPTURE_FILE([ofctl_monitor0_hv3.log])
-as hv3 ovs-ofctl monitor br-int resume --detach --no-chdir \
---pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv3.log
-
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-# Send DHCPDISCOVER.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-server_mac=ff1000000001
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
-$expected_dhcp_opts
-
-# NXT_RESUMEs should be 1 in hv1.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 0 in hv2.
-OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
-cat ext1_v4.expected | cut -c -48 > expout
-AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat ext1_v4.expected | cut -c 53- > expout
-AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
-
-# ovs-ofctl also resumes the packets and this causes other ports to receive
-# the DHCP request packet. So reset the pcap files so that its easier to test.
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-rm -f ext1_v4.expected
-rm -f ext1_v4.packets
-
-# Send DHCPv6 request
-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-offer_ip=ae700000000000000000000000000006
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
-
-# NXT_RESUMEs should be 2 in hv1.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 0 in hv2.
-OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
-sort > ext1_v6.packets
-cat ext1_v6.expected | cut -c -120 > expout
-AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
-# Skipping the UDP checksum
-cat ext1_v6.expected | cut -c 125- > expout
-AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
-
-rm -f ext1_v6.expected
-rm -f ext1_v6.packets
-
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-# Delete the ha-chassis hv1.
-ovn-nbctl ha-chassis-group-remove-chassis hagrp1 hv1
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = ""])
-
-# Add hv2 to the ha chassis group
-ovn-nbctl --wait=hv ha-chassis-group-add-chassis hagrp1 hv2 20
-
-ovn-sbctl list ha_chassis_group
-ovn-sbctl list ha_chassis
-
-ovn-sbctl find port_binding logical_port=ls1-lp_ext1
-
-# The ls1-lp_ext1 should be bound to hv2
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = "$hv2_uuid"])
-
-# There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
-wc -l], [0], [3
-])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
-grep reg14=0x$ln_public_key | wc -l], [0], [1
-])
-
-# There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep "0a.00.00.06" | wc -l], [0], [0
-])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
-grep controller | grep tp_src=546 | grep \
-"ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
-grep reg14=0x$ln_public_key | wc -l], [0], [0
-])
-
-# Send DHCPDISCOVER again for hv1/ext1. The DHCP response should come from
-# hv2 ovn-controller.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-server_mac=ff1000000001
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
-$expected_dhcp_opts
-
-# NXT_RESUMEs should be 2 in hv1.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 1 in hv2.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
-cat ext1_v4.expected | cut -c -48 > expout
-AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat ext1_v4.expected | cut -c 53- > expout
-AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
-
-# ovs-ofctl also resumes the packets and this causes other ports to receive
-# the DHCP request packet. So reset the pcap files so that its easier to test.
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-rm -f ext1_v4.expected
-
-# Send DHCPv6 request again
-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-offer_ip=ae700000000000000000000000000006
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 1
-
-# NXT_RESUMEs should be 2 in hv1.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
-sort > ext1_v6.packets
-cat ext1_v6.expected | cut -c -120 > expout
-AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
-# Skipping the UDP checksum
-cat ext1_v6.expected | cut -c 125- > expout
-AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
-
-rm -f ext1_v6.expected
-rm -f ext1_v6.packets
-
-as hv1
-ovs-vsctl show
-reset_pcap_file hv1-ext1 hv1/ext1
-reset_pcap_file br-phys_n1 hv1/br-phys_n1
-reset_pcap_file br-phys hv1/br-phys
-
-as hv2
-ovs-vsctl show
-reset_pcap_file hv2-ext2 hv2/ext2
-reset_pcap_file br-phys_n1 hv2/br-phys_n1
-reset_pcap_file br-phys hv2/br-phys
-
-# From  ls1-lp_ext1, send ARP request for the router ip. The ARP
-# response should come from the router pipeline of hv2.
-ext1_mac=f00000000003
-router_mac=a01000000001
-ext1_ip=`ip_to_hex 10 0 0 6`
-router_ip=`ip_to_hex 10 0 0 1`
-arp_request=ffffffffffff${ext1_mac}08060001080006040001${ext1_mac}${ext1_ip}000000000000${router_ip}
-
-as hv1 ovs-appctl netdev-dummy/receive hv1-ext1 $arp_request
-expected_response=${src_mac}${router_mac}08060001080006040002${router_mac}${router_ip}${ext1_mac}${ext1_ip}
-echo $expected_response > expout
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_arp_resp
-AT_CHECK([cat ext1_arp_resp], [0], [expout])
-
-# Verify that the response came from hv2
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > ext1_arp_resp
-AT_CHECK([cat ext1_arp_resp], [0], [expout])
-
-# Now add 3 ha chassis to the ha chassis group
-ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
-ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv2 20
-ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 10
-
-# hv1 should be master and claim ls1-lp_ext1
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = "$hv1_uuid"])
-
-as hv1
-ovs-vsctl show
-reset_pcap_file hv1-ext1 hv1/ext1
-reset_pcap_file br-phys_n1 hv1/br-phys_n1
-reset_pcap_file br-phys hv1/br-phys
-
-as hv2
-ovs-vsctl show
-reset_pcap_file hv2-ext2 hv2/ext2
-reset_pcap_file br-phys_n1 hv2/br-phys_n1
-reset_pcap_file br-phys hv2/br-phys
-
-as hv3
-ovs-vsctl show
-reset_pcap_file hv3-ext3 hv3/ext3
-reset_pcap_file br-phys_n1 hv3/br-phys_n1
-reset_pcap_file br-phys hv3/br-phys
-
-# Send DHCPDISCOVER.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-server_mac=ff1000000001
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
-$expected_dhcp_opts
-
-# NXT_RESUMEs should be 3 in hv1.
-OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
-cat ext1_v4.expected | cut -c -48 > expout
-AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat ext1_v4.expected | cut -c 53- > expout
-AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
-
-# ovs-ofctl also resumes the packets and this causes other ports to receive
-# the DHCP request packet. So reset the pcap files so that its easier to test.
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-rm -f ext1_v4.expected
-rm -f ext1_v4.packets
-
-# Send DHCPv6 request
-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-offer_ip=ae700000000000000000000000000006
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
-
-# NXT_RESUMEs should be 4 in hv1.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
-sort > ext1_v6.packets
-cat ext1_v6.expected | cut -c -120 > expout
-AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
-# Skipping the UDP checksum
-cat ext1_v6.expected | cut -c 125- > expout
-AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
-
-rm -f ext1_v6.expected
-rm -f ext1_v6.packets
-as hv1 reset_pcap_file hv1-ext1 hv1/ext1
-
-# Now increase the priority of hv3 so it becomes master.
-ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 50
-
-# hv3 should be master and claim ls1-lp_ext1
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = "$hv3_uuid"])
-
-as hv1
-ovs-vsctl show
-reset_pcap_file hv1-ext1 hv1/ext1
-reset_pcap_file br-phys_n1 hv1/br-phys_n1
-reset_pcap_file br-phys hv1/br-phys
-
-as hv2
-ovs-vsctl show
-reset_pcap_file hv2-ext2 hv2/ext2
-reset_pcap_file br-phys_n1 hv2/br-phys_n1
-reset_pcap_file br-phys hv2/br-phys
-
-as hv2
-ovs-vsctl show
-reset_pcap_file hv3-ext3 hv3/ext3
-reset_pcap_file br-phys_n1 hv3/br-phys_n1
-reset_pcap_file br-phys hv3/br-phys
-
-# Send DHCPDISCOVER.
-offer_ip=`ip_to_hex 10 0 0 6`
-server_ip=`ip_to_hex 10 0 0 1`
-server_mac=ff1000000001
-expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
-test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
-$expected_dhcp_opts
-
-# NXT_RESUMEs should be 4 in hv1.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 1 in hv3.
-OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
-cat ext1_v4.expected | cut -c -48 > expout
-AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
-# Skipping the IPv4 checksum.
-cat ext1_v4.expected | cut -c 53- > expout
-AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
-
-# ovs-ofctl also resumes the packets and this causes other ports to receive
-# the DHCP request packet. So reset the pcap files so that its easier to test.
-as hv1
-reset_pcap_file hv1-ext1 hv1/ext1
-
-rm -f ext1_v4.expected
-rm -f ext1_v4.packets
-
-# Send DHCPv6 request
-src_mac=f00000000003
-src_lla=fe80000000000000f20000fffe000003
-offer_ip=ae700000000000000000000000000006
-test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
-
-# NXT_RESUMEs should be 4 in hv1.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv2.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
-
-# NXT_RESUMEs should be 2 in hv3.
-OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
-
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
-sort > ext1_v6.packets
-cat ext1_v6.expected | cut -c -120 > expout
-AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
-# Skipping the UDP checksum
-cat ext1_v6.expected | cut -c 125- > expout
-AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
-
-# disconnect hv3 from the network, hv1 should take over
-as hv3
-port=${sandbox}_br-phys
-as main ovs-vsctl del-port n1 $port
-
-# hv1 should be master and claim ls1-lp_ext1
-OVS_WAIT_UNTIL(
-    [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
-logical_port=ls1-lp_ext1`
-    test "$chassis" = "$hv1_uuid"])
-
-OVN_CLEANUP([hv1],[hv2],[hv3])
-AT_CLEANUP
-
-AT_SETUP([ovn -- Address Set Incremental Processing])
-AT_KEYWORDS([ovn_as_inc])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.10
-
-ovn-nbctl ls-add ls1
-for i in 1 2; do
-    ovn-nbctl lsp-add ls1 lp$i \
-        -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i"
-    as hv1 ovs-vsctl \
-        -- add-port br-int vif$i \
-        -- set Interface vif$i \
-            external-ids:iface-id=lp$i
-done
-
-for i in 1 2 3; do
-    as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
-    as2_uuid=`ovn-nbctl --wait=hv create addr name=as2`
-    ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
-            'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related
-    ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10"
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore])
-
-    # Update address set as1
-    ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11"
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore])
-
-    # Update address set as2
-    ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13"
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
-
-    # Add another ACL referencing as1
-    n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
-    ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
-            'outport=="lp2" && ip4 && ip4.src == $as1' allow-related
-    n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
-    AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore])
-
-    # Remove an ACL
-    ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \
-            'outport=="lp2" && ip4 && ip4.src == $as1'
-    n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
-    AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore])
-
-    # Remove as1 while it is still used by an ACL, the lflows should be reparsed and
-    # parsing should fail.
-    echo "before del as1"
-    ovn-nbctl list addr | grep as1
-    ovn-nbctl --wait=hv destroy addr $as1_uuid
-    echo "after del as1"
-    ovn-nbctl list addr | grep as1
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore])
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
-
-    # Recreate as1
-    as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
-
-    # Remove ACLs and address sets
-    ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid
-    AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
-
-    ovn-nbctl --wait=hv acl-del ls1
-done
-
-# Gracefully terminate daemons
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ovn-controller restart])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One Logical Router: ro, with two logical switches sw1 and sw2.
-# sw1 is for subnet 10.0.0.0/8
-# sw2 is for subnet 20.0.0.0/8
-# sw1 has a single port bound on hv1
-# sw2 has a single port bound on hv2
-
-ovn-nbctl lr-add ro
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add sw2
-
-sw1_ro_mac=00:00:10:00:00:01
-sw1_ro_ip=10.0.0.1
-sw2_ro_mac=00:00:20:00:00:01
-sw2_ro_ip=20.0.0.1
-sw1_p1_mac=00:00:10:00:00:02
-sw1_p1_ip=10.0.0.2
-sw2_p1_mac=00:00:20:00:00:02
-sw2_p1_ip=20.0.0.2
-
-ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
-ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
-ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
-  options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
-ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
-  options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
-
-ovn-nbctl lsp-add sw1 sw1-p1 \
--- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
-
-ovn-nbctl lsp-add sw2 sw2-p1 \
--- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-OVN_POPULATE_ARP
-
-sleep 1
-
-packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
-       ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-
-# Start by Sending the packet and make sure it makes it there as expected
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-# Expected packet has TTL decreased by 1
-expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
-       ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
-       udp && udp.src==53 && udp.dst==4369"
-echo $expected | ovstest test-ovn expr-to-packets > expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-# Stop ovn-controller on hv2 with --restart flag
-as hv2 ovs-appctl -t ovn-controller exit --restart
-
-# Now send the packet again. This time, it should still arrive
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-cat expected expected > expected2
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
-
-# Start ovn-controller again just so OVN_CLEANUP doesn't complain
-as hv2 start_daemon ovn-controller
-
-OVN_CLEANUP([hv1],[hv2])
-
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
-ovn_start
-
-# Set up a switch with some switch ports of varying address types
-ovn-nbctl ls-add sw1
-ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
-
-ovn-nbctl lsp-add sw1 sw1-p1
-ovn-nbctl lsp-add sw1 sw1-p2
-ovn-nbctl lsp-add sw1 sw1-p3
-ovn-nbctl lsp-add sw1 sw1-p4
-
-ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1" "00:00:00:00:00:02 10.0.0.2 aef0::2"
-ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
-ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
-ovn-nbctl lsp-set-addresses sw1-p4 "router"
-ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
-
-ovn-nbctl list logical_switch_port
-
-# Now try to add duplicate addresses on a new port. These should all fail
-ovn-nbctl --wait=sb lsp-add sw1 sw1-p5
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
-])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
-])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
-])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
-])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
-])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
-[ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
-])
-
-# Now try re-setting sw1-p1. This should succeed
-AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
-
-# Now create a new switch and try setting IP addresses the same as the
-# first switch. This should succeed.
-ovn-nbctl ls-add sw2
-ovn-nbctl lsp-add sw2 sw2-p1
-
-AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
-AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- router - check packet length - icmp defrag])
-AT_KEYWORDS([check packet length])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-port1
-ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3"
-
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
-ovn-nbctl lsp-add sw0 sw0-lr0
-ovn-nbctl lsp-set-type sw0-lr0 router
-ovn-nbctl lsp-set-addresses sw0-lr0 router
-ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
-
-ovn-nbctl ls-add public
-ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
-ovn-nbctl lsp-add public public-lr0
-ovn-nbctl lsp-set-type public-lr0 router
-ovn-nbctl lsp-set-addresses public-lr0 router
-ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
-
-# localnet port
-ovn-nbctl lsp-add public ln-public
-ovn-nbctl lsp-set-type ln-public localnet
-ovn-nbctl lsp-set-addresses ln-public unknown
-ovn-nbctl lsp-set-options ln-public network_name=phys
-
-ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
-ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-reset_pcap_file() {
-     local iface=$1
-     local pcap_file=$2
-     ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
- options:rxq_pcap=dummy-rx.pcap
-     rm -f ${pcap_file}*.pcap
-     ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
- options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-ip_to_hex() {
-     printf "%02x%02x%02x%02x" "$@"
-}
-
-test_ip_packet_larger() {
-    local icmp_pmtu_reply_expected=$1
-
-    # Send ip packet from sw0-port1 to outside
-    src_mac="505400000001" # sw-port1 mac
-    dst_mac="00000000ff01" # sw0-lr0 mac (internal router leg)
-    src_ip=`ip_to_hex 10 0 0 3`
-    dst_ip=`ip_to_hex 172 168 0 3`
-    # Set the packet length to 100.
-    pkt_len=0064
-    packet=${dst_mac}${src_mac}08004500${pkt_len}0000000040010000
-    orig_packet_l3=${src_ip}${dst_ip}0304000000000000
-    orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
-    orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
-    orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
-    orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
-    packet=${packet}${orig_packet_l3}
-
-    gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
-
-    # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
-    # the gateway mtu and should be delivered to the provider bridge via the
-    # localnet port.
-    # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
-    # the gateway mtu and ovn-controller should drop the packet and instead
-    # generate ICMPv4  Destination Unreachable message with pmtu set to 42.
-    if test $icmp_pmtu_reply_expected = 0; then
-        # Packet to expect at br-phys.
-        src_mac="000020201213"
-        dst_mac="00000012af11"
-        src_ip=`ip_to_hex 10 0 0 3`
-        dst_ip=`ip_to_hex 172 168 0 3`
-        expected=${dst_mac}${src_mac}08004500${pkt_len}000000003f010100
-        expected=${expected}${src_ip}${dst_ip}0304000000000000
-        expected=${expected}000000000000000000000000000000000000
-        expected=${expected}000000000000000000000000000000000000
-        expected=${expected}000000000000000000000000000000000000
-        expected=${expected}000000000000000000000000000000000000
-        echo $expected > br_phys_n1.expected
-        echo $gw_ip_garp >> br_phys_n1.expected
-    else
-        # MTU would be 100 - 18 = 82 (hex 0052)
-        mtu=0052
-        src_ip=`ip_to_hex 10 0 0 1`
-        dst_ip=`ip_to_hex 10 0 0 3`
-        # pkt len should be 128 (28 (icmp packet) + 100 (orig ip + payload))
-        reply_pkt_len=0080
-        ip_csum=bd91
-        icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016879
-        icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
-        icmp_reply=${icmp_reply}4500${pkt_len}000000003f010100
-        icmp_reply=${icmp_reply}${orig_packet_l3}
-        echo $icmp_reply > hv1-vif1.expected
-    fi
-
-    as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
-    as hv1 reset_pcap_file hv1-vif1 hv1/vif1
-
-    # Send packet from sw0-port1 to outside
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
-
-    if test $icmp_pmtu_reply_expected = 0; then
-        OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
-        $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap  > pkts
-        # hv1/vif1-tx.pcap can receive the GARP packet generated by ovn-controller
-        # for the gateway router port. So ignore this packet.
-        cat pkts | grep -v $gw_ip_garp > packets
-        AT_CHECK([cat packets], [0], [])
-    else
-        OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
-        $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap  > \
-        pkts
-        # hv1/br-phys_n1-tx.pcap can receive the GARP packet generated by ovn-controller
-        # for the gateway router port. So ignore this packet.
-        cat pkts | grep -v $gw_ip_garp > packets
-        AT_CHECK([cat packets], [0], [])
-    fi
-}
-
-ovn-nbctl show
-ovn-sbctl show
-
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int  \
-| grep "check_pkt_larger" | wc -l], [0], [[0
-]])
-dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
-awk '{print $3}')
-ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
-logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
-
-# Set the gateway mtu to 100. If the packet length is > 100, ovn-controller
-# should send icmp host not reachable with pmtu set to 100.
-ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
-as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
-OVS_WAIT_UNTIL([
-    test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(100)" | \
-    wc -l` -eq 1
-])
-
-icmp_reply_expected=1
-test_ip_packet_larger $icmp_reply_expected
-
-# Set the gateway mtu to 500.
-ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
-as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
-OVS_WAIT_UNTIL([
-    test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(500)" | \
-    wc -l` -eq 1
-])
-
-# Now the packet should be sent via the localnet port to br-phys.
-icmp_reply_expected=0
-test_ip_packet_larger $icmp_reply_expected
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- IP packet buffering])
-AT_KEYWORDS([ip-buffering])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# One LR lr0 that has switches sw0 (192.168.1.0/24) and
-# sw1 (172.16.1.0/24) connected to it.
-#
-# Physical network:
-# Tw0 hypervisors hv[12].
-# hv1 hosts vif sw0-p0.
-# hv1 hosts vif sw1-p0.
-
-send_icmp_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
-    shift 8
-
-    local ip_ttl=ff
-    local ip_len=001c
-    local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
-    as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
-}
-
-send_icmp6_packet() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
-    shift 8
-
-    local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
-    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
-
-    as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
-}
-
-get_arp_req() {
-    local eth_src=$1 spa=$2 tpa=$3
-    local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
-    echo $request
-}
-
-send_arp_reply() {
-    local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
-    local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
-    as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
-}
-
-send_na() {
-    local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
-    local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
-    local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
-
-    as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
-}
-
-get_nd() {
-    local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
-    local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
-    request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
-
-    echo $request
-}
-
-net_add n1
-
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-
-ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
-ovn-nbctl ls-add sw0
-ovn-nbctl ls-add sw1
-
-ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001:0:0:0:0:0:0:1/64
-ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
-    type=router options:router-port=sw0 \
-    -- lsp-set-addresses rp-sw0 router
-
-ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
-ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
-    type=router options:router-port=sw1 \
-    -- lsp-set-addresses rp-sw1 router
-
-ovn-nbctl lsp-add sw0 sw0-p0 \
-    -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
-
-ovn-nbctl lsp-add sw1 sw1-p0 \
-    -- lsp-set-addresses sw1-p0 unknown
-
-OVN_POPULATE_ARP
-ovn-nbctl --wait=hv sync
-
-ip_to_hex() {
-    printf "%02x%02x%02x%02x" "$@"
-}
-
-src_mac=f00000010203
-src_ip=$(ip_to_hex 192 168 1 2)
-src_ip6=20010000000000000000000000000002
-
-router_mac0=000001010203
-router_mac1=000002010203
-router_ip=$(ip_to_hex 172 16 1 1)
-router_ip6=20020000000000000000000000000001
-
-dst_mac=001122334455
-dst_ip=$(ip_to_hex 172 16 1 10)
-dst_ip6=20020000000000000000000000000010
-
-data=0800bee4391a0001
-
-send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
-send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
-echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
-echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-nd_ip=ff0200000000000000000001ff000010
-ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
-
-send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
-echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
-echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
-send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
-
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1],[hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- neighbor update on same HV])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
-# each with a distributed gateway port.
-# Two VMs: lp0 on sw0 connected to lr0
-#          lp1 on sw1 connected to lr1
-#
-# This test adds a floating IP to each VM so when they are bound to the same
-# hypervisor, it checks that the GARP sent by ovn-controller causes the
-# MAC_Binding entries to be updated properly on each logical router.
-# It will also capture packets on the physical interface to make sure that the
-# GARPs have been sent out to the external network as well.
-
-# Create logical switches
-ovn-nbctl ls-add sw0
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add pub
-
-# Created localnet port on public switch
-ovn-nbctl lsp-add pub ln-pub
-ovn-nbctl lsp-set-type ln-pub localnet
-ovn-nbctl lsp-set-addresses ln-pub unknown
-ovn-nbctl lsp-set-options ln-pub network_name=phys
-
-# Create logical routers and connect them to public switch
-ovn-nbctl create Logical_Router name=lr0
-ovn-nbctl create Logical_Router name=lr1
-
-ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
-ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
-    type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
-ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
-ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
-    type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
-
-ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
-ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
-
-# Connect sw0 and sw1 to lr0 and lr1
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
-ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
-    options:router-port=lr0-sw0 addresses="router"
-ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
-ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
-    options:router-port=lr1-sw1 addresses="router"
-
-
-# Add SNAT rules
-ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
-ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 172.24.4.1
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
-
-ovn-nbctl lsp-add sw0 lp0
-ovn-nbctl lsp-add sw1 lp1
-ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
-ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
-
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
-OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
-
-# Create two floating IPs, one for each VIF
-ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
-ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
-
-# Check that the MAC_Binding entries have been properly created
-OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
-OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
-
-# Check that the GARPs went also to the external physical network
-# Wait until at least 4 packets have arrived and copy them to a separate file as
-# more GARPs are expected in the capture in order to avoid race conditions.
-OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
-$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
-
-# GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
-echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
-# GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
-echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
-# GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
-echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
-# GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
-echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
-AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
-#OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
-
-OVN_CLEANUP([hv1])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ipam to non-ipam])
-ovn_start
-
-ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
-ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
-
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
-    ["0a:00:00:a8:01:03 192.168.1.2"
-])
-
-ovn-nbctl --wait=sb lsp-set-addresses p0 router
-
-ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses
-
-AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0], [[[]]
-])
-AT_CLEANUP
-
-AT_SETUP([ovn -- ipam router ports])
-ovn_start
-
-ovn-nbctl ls-add sw
-ovn-nbctl set logical_switch sw other-config:subnet=192.168.1.0/24
-
-for i in 2 3 4; do
-    ovn-nbctl lr-add ro$i
-    ovn-nbctl lsp-add sw swp$i
-    ovn-nbctl --wait=sb lsp-set-addresses swp$i "02:00:00:00:00:0$i dynamic"
-    cidr=$(ovn-nbctl get logical_switch_port swp$i dynamic_addresses |cut -f2 -d' '|cut -f1 -d\")
-    ovn-nbctl lrp-add ro$i rop$i 02:00:00:00:00:0$i $cidr/24 -- set logical_switch_port swp$i type=router options:router-port=rop$i addresses=router;
-    AT_CHECK_UNQUOTED([ovn-nbctl get logical_router_port rop$i networks], [0], [[["192.168.1.$i/24"]]
-])
-done
-
-ovn-nbctl list logical_switch_port
-ovn-nbctl list logical_router_port
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- test transport zones])
-ovn_start
-
-net_add n1
-for i in 1 2 3 4 5; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.$i.1
-done
-
-dnl Wait for the changes to be propagated
-ovn-nbctl --wait=sb --timeout=3 sync
-ovn-nbctl --wait=hv --timeout=3 sync
-
-dnl Assert that each Chassis has a tunnel formed to every other Chassis
-as hv1
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv2-0
-ovn-hv3-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv2
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv3-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv3
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv4
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv3-0
-ovn-hv5-0
-]])
-
-as hv5
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv3-0
-ovn-hv4-0
-]])
-
-dnl Let's now add some Chassis to different transport zones
-dnl * hv1: Will be part of two transport zones: tz1 and tz2 so it
-dnl   should have tunnels formed between the other two Chassis (hv2 and hv3)
-dnl
-dnl * hv2: Will be part of one transport zone: tz1. It should have a tunnel
-dnl   to hv1 but not to hv3
-dnl
-dnl * hv3: Will be part of one transport zone: tz2. It should have a tunnel
-dnl   to hv1 but not to hv2
-dnl
-dnl * hv4 and hv5: Will not have any TZ set so they will keep the tunnels
-dnl   between themselves and remove the tunnels to other Chassis which now
-dnl   belongs to some TZs
-dnl
-as hv1
-ovs-vsctl set open . external-ids:ovn-transport-zones=tz1,tz2
-
-as hv2
-ovs-vsctl set open . external-ids:ovn-transport-zones=tz1
-
-as hv3
-ovs-vsctl set open . external-ids:ovn-transport-zones=tz2
-
-dnl Wait for the changes to be propagated
-ovn-nbctl --wait=sb --timeout=3 sync
-ovn-nbctl --wait=hv --timeout=3 sync
-
-as hv1
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv2-0
-ovn-hv3-0
-]])
-
-as hv2
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-]])
-
-as hv3
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-]])
-
-as hv4
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv5-0
-]])
-
-as hv5
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv4-0
-]])
-
-dnl Removing the transport zones should make all Chassis to create
-dnl tunnels between every other Chassis again
-for i in 1 2 3; do
-    as hv$i
-    ovs-vsctl remove open . external-ids ovn-transport-zones
-done
-
-dnl Wait for the changes to be propagated
-ovn-nbctl --wait=sb --timeout=3 sync
-ovn-nbctl --wait=hv --timeout=3 sync
-
-as hv1
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv2-0
-ovn-hv3-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv2
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv3-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv3
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv4-0
-ovn-hv5-0
-]])
-
-as hv4
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv3-0
-ovn-hv5-0
-]])
-
-as hv5
-AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
-[[ovn-hv1-0
-ovn-hv2-0
-ovn-hv3-0
-ovn-hv4-0
-]])
-
-OVN_CLEANUP([hv1], [hv2], [hv3])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR chassis mac])
-ovn_start
-
-
-# In this test cases we create 2 switches, all connected to same
-# physical network (through br-phys on each HV). Each switch has
-# 1 VIF. Each HV has 1 VIF port. The first digit
-# of VIF port name indicates the hypervisor it is bound to, e.g.
-# lp23 means VIF 3 on hv2.
-#
-# Each switch's VLAN tag and their logical switch ports are:
-#   - ls1:
-#       - tagged with VLAN 101
-#       - ports: lp11
-#   - ls2:
-#       - tagged with VLAN 201
-#       - ports: lp22
-#
-# Note: a localnet port is created for each switch to connect to
-# physical network.
-
-for i in 1 2; do
-    ls_name=ls$i
-    ovn-nbctl ls-add $ls_name
-    ln_port_name=ln$i
-    if test $i -eq 1; then
-        ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
-    elif test $i -eq 2; then
-        ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
-    fi
-    ovn-nbctl lsp-set-addresses $ln_port_name unknown
-    ovn-nbctl lsp-set-type $ln_port_name localnet
-    ovn-nbctl lsp-set-options $ln_port_name network_name=phys
-done
-
-# lsp_to_ls LSP
-#
-# Prints the name of the logical switch that contains LSP.
-lsp_to_ls () {
-    case $1 in dnl (
-        lp?[[11]]) echo ls1 ;; dnl (
-        lp?[[12]]) echo ls2 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-vif_to_ls () {
-    case $1 in dnl (
-        vif?[[11]]) echo ls1 ;; dnl (
-        vif?[[12]]) echo ls2 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-hv_to_num () {
-    case $1 in dnl (
-        hv1) echo 1 ;; dnl (
-        hv2) echo 2 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-vif_to_num () {
-    case $1 in dnl (
-        vif22) echo 22 ;; dnl (
-        vif21) echo 21 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-vif_to_hv () {
-    case $1 in dnl (
-        vif[[1]]?) echo hv1 ;; dnl (
-        vif[[2]]?) echo hv2 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-vif_to_lrp () {
-    echo router-to-`vif_to_ls $1`
-}
-
-hv_to_chassis_mac () {
-     case $1 in dnl (
-        hv[[1]]) echo aa:bb:cc:dd:ee:11 ;; dnl (
-        hv[[2]]) echo aa:bb:cc:dd:ee:22 ;; dnl (
-        *) AT_FAIL_IF([:]) ;;
-    esac
-}
-
-ip_to_hex() {
-       printf "%02x%02x%02x%02x" "$@"
-}
-
-net_add n1
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-    ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    ovs-vsctl add-port br-int vif$i$i -- \
-        set Interface vif$i$i external-ids:iface-id=lp$i$i \
-                              options:tx_pcap=hv$i/vif$i$i-tx.pcap \
-                              options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
-                              ofport-request=$i$i
-
-    lsp_name=lp$i$i
-    ls_name=$(lsp_to_ls $lsp_name)
-
-    ovn-nbctl lsp-add $ls_name $lsp_name
-    ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
-    ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
-
-    OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
-
-done
-
-ovn-nbctl lr-add router
-ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
-ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
-
-ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
-ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
-
-ovn-nbctl --wait=sb sync
-#ovn-sbctl dump-flows
-
-ovn-nbctl show
-ovn-sbctl show
-
-OVN_POPULATE_ARP
-
-test_ip() {
-    # This packet has bad checksums but logical L3 routing doesn't check.
-    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
-    local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
-    shift; shift; shift; shift; shift
-    hv=`vif_to_hv $inport`
-    hv_num=`hv_to_num $hv`
-    chassis_mac=`hv_to_chassis_mac $hv`
-    as $hv ovs-appctl netdev-dummy/receive $inport $packet
-    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
-    in_ls=`vif_to_ls $inport`
-    in_lrp=`vif_to_lrp $inport`
-    for outport; do
-        out_ls=`vif_to_ls $outport`
-        if test $in_ls = $out_ls; then
-            # Ports on the same logical switch receive exactly the same packet.
-            echo $packet
-        else
-            # Routing decrements TTL and updates source and dest MAC
-            # (and checksum).
-            outport_num=`vif_to_num $outport`
-            out_lrp=`vif_to_lrp $outport`
-            echo f000000000${outport_num}aabbccddee${hv_num}${hv_num}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
-        fi >> $outport.expected
-    done
-}
-
-# Dump a bunch of info helpful for debugging if there's a failure.
-
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
-
-echo "------ hv1 dump ------"
-as hv1 ovs-vsctl show
-as hv1 ovs-vsctl list Open_Vswitch
-
-echo "------ hv2 dump ------"
-as hv2 ovs-vsctl show
-as hv2 ovs-vsctl list Open_Vswitch
-
-echo "Send traffic"
-sip=`ip_to_hex 192 168 1 1`
-dip=`ip_to_hex 192 168 2 2`
-test_ip vif11 f00000000011  000001010203 $sip $dip vif22
-
-echo "----------- Post Traffic hv1 dump -----------"
-as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv1 ovs-appctl fdb/show br-phys
-
-echo "----------- Post Traffic hv2 dump -----------"
-as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
-as hv2 ovs-appctl fdb/show br-phys
-
-OVN_CHECK_PACKETS([hv2/vif22-tx.pcap], [vif22.expected])
-
-OVN_CLEANUP([hv1],[hv2])
-
-AT_CLEANUP
-
-# Run ovn-nbctl in daemon mode, change to a backup database and verify that
-# an insert operation is not allowed.
-AT_SETUP([ovn -- can't write to a backup database server instance])
-ovn_start
-on_exit 'kill $(cat ovn-nbctl.pid)'
-export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach)
-
-AT_CHECK([ovn-nbctl ls-add sw0])
-as ovn-nb
-AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep active | wc -l], [0], [1
-])
-ovs-appctl -t ovsdb-server ovsdb-server/set-active-ovsdb-server tcp:192.0.2.2:6641
-ovs-appctl -t ovsdb-server ovsdb-server/connect-active-ovsdb-server
-AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep -c backup], [0], [1
-])
-AT_CHECK([ovn-nbctl ls-add sw1], [1], [ignore],
-[ovn-nbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
-])
-
-AT_CLEANUP
-
-AT_SETUP([ovn -- controller event])
-AT_KEYWORDS([ovn_controller_event])
-ovn_start
-
-# Create hypervisors hv[12].
-# Add vif1[12] to hv1, vif2[12] to hv2
-# Add all of the vifs to a single logical switch sw0.
-
-net_add n1
-ovn-nbctl ls-add sw0
-for i in 1 2; do
-    sim_add hv$i
-    as hv$i
-    ovs-vsctl add-br br-phys
-    ovn_attach n1 br-phys 192.168.0.$i
-
-    for j in 1 2; do
-        ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
-                lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
-
-        ovs-vsctl -- add-port br-int vif$i$j -- \
-                set interface vif$i$j \
-                external-ids:iface-id=sw0-p$i$j \
-                options:tx_pcap=hv$i/vif$i$j-tx.pcap \
-                options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
-                ofport-request=$i$j
-    done
-done
-
-ovn-nbctl --wait=hv set NB_Global . options:controller_event=true
-ovn-nbctl lb-add lb0 192.168.1.100:80 ""
-ovn-nbctl ls-lb-add sw0 lb0
-uuid_lb=$(ovn-nbctl --bare --columns=_uuid find load_balancer name=lb0)
-
-OVN_POPULATE_ARP
-ovn-nbctl --timeout=3 --wait=hv sync
-ovn-sbctl lflow-list
-as hv1 ovs-ofctl dump-flows br-int
-
-packet="inport==\"sw0-p11\" && eth.src==00:00:00:00:00:11 && eth.dst==00:00:00:00:00:21 &&
-       ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==192.168.1.100 &&
-       tcp && tcp.src==10000 && tcp.dst==80"
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
-
-ovn-sbctl list controller_event
-uuid=$(ovn-sbctl list controller_event | awk '/_uuid/{print $3}')
-AT_CHECK([ovn-sbctl get controller_event $uuid event_type], [0], [dnl
-empty_lb_backends
-])
-AT_CHECK([ovn-sbctl get controller_event $uuid event_info:vip], [0], [dnl
-"192.168.1.100:80"
-])
-AT_CHECK([ovn-sbctl get controller_event $uuid event_info:protocol], [0], [dnl
-tcp
-])
-AT_CHECK_UNQUOTED([ovn-sbctl get controller_event $uuid event_info:load_balancer], [0], [dnl
-"$uuid_lb"
-])
-AT_CHECK([ovn-sbctl get controller_event $uuid seq_num], [0], [dnl
-1
-])
-
-OVN_CLEANUP([hv1], [hv2])
-AT_CLEANUP
-
-AT_SETUP([ovn -- IGMP snoop/querier])
-AT_SKIP_IF([test $HAVE_PYTHON = no])
-ovn_start
-
-# Logical network:
-# Two independent logical switches (sw1 and sw2).
-# sw1:
-#   - subnet 10.0.0.0/8
-#   - 2 ports bound on hv1 (sw1-p11, sw1-p12)
-#   - 2 ports bound on hv2 (sw1-p21, sw1-p22)
-# sw2:
-#   - subnet 20.0.0.0/8
-#   - 1 port bound on hv1 (sw2-p1)
-#   - 1 port bound on hv2 (sw2-p2)
-#   - IGMP Querier from 20.0.0.254
-
-reset_pcap_file() {
-    local iface=$1
-    local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
-options:rxq_pcap=dummy-rx.pcap
-    rm -f ${pcap_file}*.pcap
-    ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
-options:rxq_pcap=${pcap_file}-rx.pcap
-}
-
-ip_to_hex() {
-     printf "%02x%02x%02x%02x" "$@"
-}
-
-#
-# send_igmp_v3_report INPORT HV ETH_SRC IP_SRC IP_CSUM GROUP REC_TYPE
-#                     IGMP_CSUM OUTFILE
-#
-# This shell function causes an IGMPv3 report to be received on INPORT of HV.
-# The packet's content has Ethernet destination 01:00:5E:00:00:22 and source
-# ETH_SRC (exactly 12 hex digits). Ethernet type is set to IP.
-# GROUP is the IP multicast group to be joined/to leave (based on REC_TYPE).
-# REC_TYPE == 04: join GROUP
-# REC_TYPE == 03: leave GROUP
-# The packet hexdump is also stored in OUTFILE.
-#
-send_igmp_v3_report() {
-    local inport=$1 hv=$2 eth_src=$3 ip_src=$4 ip_chksum=$5 group=$6
-    local rec_type=$7 igmp_chksum=$8 outfile=$9
-
-    local eth_dst=01005e000016
-    local ip_dst=$(ip_to_hex 224 0 0 22)
-    local ip_ttl=01
-    local ip_ra_opt=94040000
-
-    local igmp_type=2200
-    local num_rec=00000001
-    local aux_dlen=00
-    local num_src=0000
-
-    local eth=${eth_dst}${eth_src}0800
-    local ip=46c0002800004000${ip_ttl}02${ip_chksum}${ip_src}${ip_dst}${ip_ra_opt}
-    local igmp=${igmp_type}${igmp_chksum}${num_rec}${rec_type}${aux_dlen}${num_src}${group}
-    local packet=${eth}${ip}${igmp}
-
-    echo ${packet} >> ${outfile}
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
-}
-
-#
-# store_igmp_v3_query ETH_SRC IP_SRC IP_CSUM OUTFILE
-#
-# This shell function builds an IGMPv3 general query from ETH_SRC and IP_SRC
-# and stores the hexdump of the packet in OUTFILE.
-#
-store_igmp_v3_query() {
-    local eth_src=$1 ip_src=$2 ip_chksum=$3 outfile=$4
-
-    local eth_dst=01005e000001
-    local ip_dst=$(ip_to_hex 224 0 0 1)
-    local ip_ttl=01
-    local igmp_type=11
-    local max_resp=0a
-    local igmp_chksum=eeeb
-    local addr=00000000
-
-    local eth=${eth_dst}${eth_src}0800
-    local ip=4500002000004000${ip_ttl}02${ip_chksum}${ip_src}${ip_dst}
-    local igmp=${igmp_type}${max_resp}${igmp_chksum}${addr}000a0000
-    local packet=${eth}${ip}${igmp}
-
-    echo ${packet} >> ${outfile}
-}
-
-#
-# send_ip_multicast_pkt INPORT HV ETH_SRC ETH_DST IP_SRC IP_DST IP_LEN
-#    IP_PROTO DATA OUTFILE
-#
-# This shell function causes an IP multicast packet to be received on INPORT
-# of HV.
-# The hexdump of the packet is stored in OUTFILE.
-#
-send_ip_multicast_pkt() {
-    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ip_src=$5 ip_dst=$6
-    local ip_len=$7 ip_chksum=$8 proto=$9 data=${10} outfile=${11}
-
-    local ip_ttl=20
-
-    local eth=${eth_dst}${eth_src}0800
-    local ip=450000${ip_len}95f14000${ip_ttl}${proto}${ip_chksum}${ip_src}${ip_dst}
-    local packet=${eth}${ip}${data}
-
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
-    echo ${packet} >> ${outfile}
-}
-
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add sw2
-
-ovn-nbctl lsp-add sw1 sw1-p11
-ovn-nbctl lsp-add sw1 sw1-p12
-ovn-nbctl lsp-add sw1 sw1-p21
-ovn-nbctl lsp-add sw1 sw1-p22
-ovn-nbctl lsp-add sw2 sw2-p1
-ovn-nbctl lsp-add sw2 sw2-p2
-
-net_add n1
-sim_add hv1
-as hv1
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
-    set interface hv1-vif1 external-ids:iface-id=sw1-p11 \
-    options:tx_pcap=hv1/vif1-tx.pcap \
-    options:rxq_pcap=hv1/vif1-rx.pcap \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
-    set interface hv1-vif2 external-ids:iface-id=sw1-p12 \
-    options:tx_pcap=hv1/vif2-tx.pcap \
-    options:rxq_pcap=hv1/vif2-rx.pcap \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
-    set interface hv1-vif3 external-ids:iface-id=sw2-p1 \
-    options:tx_pcap=hv1/vif3-tx.pcap \
-    options:rxq_pcap=hv1/vif3-rx.pcap \
-    ofport-request=1
-
-sim_add hv2
-as hv2
-ovs-vsctl add-br br-phys
-ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
-    set interface hv2-vif1 external-ids:iface-id=sw1-p21 \
-    options:tx_pcap=hv2/vif1-tx.pcap \
-    options:rxq_pcap=hv2/vif1-rx.pcap \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif2 -- \
-    set interface hv2-vif2 external-ids:iface-id=sw1-p22 \
-    options:tx_pcap=hv2/vif2-tx.pcap \
-    options:rxq_pcap=hv2/vif2-rx.pcap \
-    ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif3 -- \
-    set interface hv2-vif3 external-ids:iface-id=sw2-p2 \
-    options:tx_pcap=hv2/vif3-tx.pcap \
-    options:rxq_pcap=hv2/vif3-rx.pcap \
-    ofport-request=1
-
-OVN_POPULATE_ARP
-
-# Enable IGMP snooping on sw1.
-ovn-nbctl set Logical_Switch sw1 other_config:mcast_querier="false"
-ovn-nbctl set Logical_Switch sw1 other_config:mcast_snoop="true"
-
-# No IGMP query should be generated by sw1 (mcast_querier="false").
-truncate -s 0 expected
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
-
-ovn-nbctl --wait=hv sync
-
-# Inject IGMP Join for 239.0.1.68 on sw1-p11.
-send_igmp_v3_report hv1-vif1 hv1 \
-    000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
-    $(ip_to_hex 239 0 1 68) 04 e9b9 \
-    /dev/null
-# Inject IGMP Join for 239.0.1.68 on sw1-p21.
-send_igmp_v3_report hv2-vif1 hv2 000000000002 $(ip_to_hex 10 0 0 2) f9f9 \
-    $(ip_to_hex 239 0 1 68) 04 e9b9 \
-    /dev/null
-
-# Check that the IGMP Group is learned on both hv.
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    test "${total_entries}" = "2"
-])
-
-# Send traffic and make sure it gets forwarded only on the two ports that
-# joined.
-truncate -s 0 expected
-truncate -s 0 expected_empty
-send_ip_multicast_pkt hv1-vif2 hv1 \
-    000000000001 01005e000144 \
-    $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e ca70 11 \
-    e518e518000a3b3a0000 \
-    expected
-
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-
-# Inject IGMP Leave for 239.0.1.68 on sw1-p11.
-send_igmp_v3_report hv1-vif1 hv1 \
-    000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
-    $(ip_to_hex 239 0 1 68) 03 eab9 \
-    /dev/null
-
-# Check IGMP_Group table on both HV.
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    test "${total_entries}" = "1"
-])
-
-# Send traffic traffic and make sure it gets forwarded only on the port that
-# joined.
-as hv1 reset_pcap_file hv1-vif1 hv1/vif1
-as hv2 reset_pcap_file hv2-vif1 hv2/vif1
-truncate -s 0 expected
-truncate -s 0 expected_empty
-send_ip_multicast_pkt hv1-vif2 hv1 \
-    000000000001 01005e000144 \
-    $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e ca70 11 \
-    e518e518000a3b3a0000 \
-    expected
-
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-
-# Flush IGMP groups.
-ovn-sbctl ip-multicast-flush sw1
-ovn-nbctl --wait=hv -t 3 sync
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    test "${total_entries}" = "0"
-])
-
-# Enable IGMP snooping and querier on sw2 and set query interval to minimum.
-ovn-nbctl set Logical_Switch sw2 \
-    other_config:mcast_snoop="true" \
-    other_config:mcast_querier="true" \
-    other_config:mcast_query_interval=1 \
-    other_config:mcast_eth_src="00:00:00:00:02:fe" \
-    other_config:mcast_ip4_src="20.0.0.254"
-
-# Wait for 1 query interval (1 sec) and check that two queries are generated.
-truncate -s 0 expected
-store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
-store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
-
-sleep 1
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected])
-
-OVN_CLEANUP([hv1], [hv2])
-AT_CLEANUP
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
deleted file mode 100644
index f88ad31..0000000
--- a/tests/system-ovn.at
+++ /dev/null
@@ -1,1667 +0,0 @@
-AT_BANNER([system-ovn])
-
-AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, SNAT and DNAT])
-AT_KEYWORDS([ovnnat])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
-# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
-# to it.  R2 is a gateway router on which we add NAT rules.
-#
-#    foo -- R1 -- join - R2 -- alice
-#           |
-#    bar ----
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Static routes.
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
-"192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
-
-# Add a DNAT rule.
-ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
-    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
-
-# Add a SNAT rule
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
-    external_ip=30.0.0.1 -- add logical_router R2 nat @nat
-
-# wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=30.0.0.1)'])
-
-# 'alice1' should be able to ping 'foo1' directly.
-NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2
-NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# Check conntrack entries.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
-# from 30.0.0.1
-NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# Add static routes to handle east-west NAT.
-ovn-nbctl lr-route-add R1 30.0.0.0/24 20.0.0.2
-
-# wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-
-# Flush conntrack entries for easier output parsing of next test.
-AT_CHECK([ovs-appctl dpctl/flush-conntrack])
-
-# East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it.
-NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# As we have a static route that sends all packets with destination
-# 30.0.0.2 to R2, it hits the DNAT rule and converts 30.0.0.2 to 192.168.1.2
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.2.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# As we have a SNAT rule that converts 192.168.2.2 to 30.0.0.1, the source is
-# SNATted and 'foo1' receives it.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, easy SNAT])
-AT_KEYWORDS([ovnnat])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) connected
-# to it.  R2 has alice (172.16.1.0/24) connected to it.
-# R2 is a gateway router on which we add NAT rules.
-#
-#    foo -- R1 -- join - R2 -- alice
-
-ovn-nbctl lr-add R1
-ovn-nbctl lr-add R2 -- set Logical_Router R2 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add join
-
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-
-# Connect foo to R1
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect alice to R2
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Static routes.
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Add a SNAT rule
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.1.2 \
-    external_ip=172.16.1.1 -- add logical_router R2 nat @nat
-
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)'])
-
-# South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
-# from 172.16.1.1
-NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- multiple gateway routers, SNAT and DNAT])
-AT_KEYWORDS([ovnnat])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
-# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
-# to it.  R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
-# bob have the same subnet behind it.  We are trying to simulate external
-# network via those 2 switches. In real world the switch ports of these
-# switches will have addresses set as "unknown" to make them learning switches.
-# Or those switches will be "localnet" ones.
-#
-#    foo -- R1 -- join - R2 -- alice
-#           |          |
-#    bar ----          - R3 --- bob
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
-ovn-nbctl create Logical_Router name=R3 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add bob
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect bob to R3
-ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
-ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
-    type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Connect R3 to join
-ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
-ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
-    type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
-
-# Install static routes with source ip address as the policy for routing.
-# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
-
-# Static routes.
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
-
-# For gateway routers R2 and R3, set a force SNAT rule.
-ovn-nbctl set logical_router R2 options:dnat_force_snat_ip=20.0.0.2
-ovn-nbctl set logical_router R3 options:dnat_force_snat_ip=20.0.0.3
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.3/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
-"192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
-
-# Logical port 'bob1' in switch 'bob'.
-ADD_NAMESPACES(bob1)
-ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
-         "172.16.1.2")
-ovn-nbctl lsp-add bob bob1 \
--- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
-
-# Router R2
-# Add a DNAT rule.
-ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
-    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
-
-# Add a SNAT rule
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.1.2 \
-    external_ip=30.0.0.1 -- add logical_router R2 nat @nat
-
-# Router R3
-# Add a DNAT rule.
-ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
-    external_ip=30.0.0.3 -- add logical_router R3 nat @nat
-
-# Add a SNAT rule
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
-    external_ip=30.0.0.4 -- add logical_router R3 nat @nat
-
-# wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=30.0.0.4)'])
-
-# North-South DNAT: 'alice1' should be able to ping 'foo1' via 30.0.0.2
-NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# Check conntrack entries.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.3) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.3,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# But foo1 should receive traffic from 20.0.0.2
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.3,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=20.0.0.2,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# North-South DNAT: 'bob1' should be able to ping 'foo1' via 30.0.0.3
-NS_CHECK_EXEC([bob1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.3 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# Check conntrack entries.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.4) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.4,dst=30.0.0.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# But foo1 should receive traffic from 20.0.0.3
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.3) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.4,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=20.0.0.3,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# South-North SNAT: 'bar1' pings 'bob1'. But 'bob1' receives traffic
-# from 30.0.0.4
-NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.4) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.2.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=30.0.0.4,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
-# from 30.0.0.1
-NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.3 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.1.2,dst=172.16.1.3,id=<cleared>,type=8,code=0),reply=(src=172.16.1.3,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- load-balancing])
-AT_KEYWORDS([ovnlb])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
-# connected to a router R1.
-# foo has foo1 to act as a client.
-# bar has bar1, bar2, bar3 to act as servers.
-#
-# Loadbalancer VIPs in 30.0.0.0/24 network.
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Create logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
-         "172.16.1.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:0f:01:02:03 172.16.1.2"
-
-ADD_NAMESPACES(bar2)
-ADD_VETH(bar2, bar2, br-int, "172.16.1.3/24", "f0:00:0f:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add bar bar2 \
--- lsp-set-addresses bar2 "f0:00:0f:01:02:04 172.16.1.3"
-
-ADD_NAMESPACES(bar3)
-ADD_VETH(bar3, bar3, br-int, "172.16.1.4/24", "f0:00:0f:01:02:05", \
-         "172.16.1.1")
-ovn-nbctl lsp-add bar bar3 \
--- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4"
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="172.16.1.2,172.16.1.3,172.16.1.4"`
-ovn-nbctl set logical_switch foo load_balancer=$uuid
-
-# Create another load-balancer with another VIP.
-uuid=`ovn-nbctl create load_balancer vips:30.0.0.3="172.16.1.2,172.16.1.3,172.16.1.4"`
-ovn-nbctl add logical_switch foo load_balancer $uuid
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"172.16.1.2:80,172.16.1.3:80,172.16.1.4:80"'
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=172.16.1.4:80)'])
-
-# Start webservers in 'bar1', 'bar2' and 'bar3'.
-OVS_START_L7([bar1], [http])
-OVS_START_L7([bar2], [http])
-OVS_START_L7([bar3], [http])
-
-dnl Should work with the virtual IP 30.0.0.1 address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Should work with the virtual IP 30.0.0.3 address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- load-balancing - same subnet.])
-AT_KEYWORDS([ovnlb])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# 1 logical switch "foo" (192.168.1.0/24) connected to router R1.
-# foo has foo1, foo2, foo3, foo4 as logical ports.
-#
-# Loadbalancer VIPs in 30.0.0.0/24 network. Router is needed for default
-# gateway. We will test load-balancing with foo1 as a client and foo2, foo3 and
-# foo4 as servers.
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl ls-add foo
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Create logical port 'foo1', 'foo2', 'foo3' and 'foo4' in switch 'foo'.
-ADD_NAMESPACES(foo1, foo2, foo3, foo4)
-for i in `seq 1 4`; do
-    j=`expr $i + 1`
-    ADD_VETH(foo$i, foo$i, br-int, "192.168.1.$j/24", "f0:00:00:01:02:0$j", \
-             "192.168.1.1")
-    ovn-nbctl lsp-add foo foo$i \
-        -- lsp-set-addresses foo$i "f0:00:00:01:02:0$j 192.168.1.$j"
-done
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="192.168.1.3,192.168.1.4,192.168.1.5"`
-ovn-nbctl set logical_switch foo load_balancer=$uuid
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.3:80,192.168.1.4:80,192.168.1.5:80"'
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=192.168.1.5:80)'])
-
-# Start webservers in 'foo2', 'foo3' and 'foo4'.
-OVS_START_L7([foo2], [http])
-OVS_START_L7([foo3], [http])
-OVS_START_L7([foo4], [http])
-
-dnl Should work with the virtual IP address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- load balancing in gateway router])
-AT_KEYWORDS([ovnlb])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Two LRs - R1 and R2 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
-# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
-# to it.  R2 is a gateway router on which we add load-balancing rules.
-#
-#    foo -- R1 -- join - R2 -- alice
-#           |
-#    bar ----
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Static routes.
-ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
-"192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="192.168.1.2,192.168.2.2"`
-ovn-nbctl set logical_router R2 load_balancer=$uuid
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:80,192.168.2.2:80"'
-
-# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
-ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
-    external_ip=30.0.0.2 -- add logical_router R2 nat @nat
-
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=192.168.2.2:80)'])
-
-# Start webservers in 'foo1', 'bar1'.
-OVS_START_L7([foo1], [http])
-OVS_START_L7([bar1], [http])
-
-dnl Should work with the virtual IP address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- multiple gateway routers, load-balancing])
-AT_KEYWORDS([ovnlb])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
-# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
-# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
-# to it.  R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
-# bob have the same subnet behind it.  We are trying to simulate external
-# network via those 2 switches. In real world the switch ports of these
-# switches will have addresses set as "unknown" to make them learning switches.
-# Or those switches will be "localnet" ones.
-#
-#    foo -- R1 -- join - R2 -- alice
-#           |          |
-#    bar ----          - R3 --- bob
-
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
-ovn-nbctl create Logical_Router name=R3 options:chassis=hv1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add bob
-ovn-nbctl ls-add join
-
-# Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
-
-# Connect bar to R1
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
-
-# Connect alice to R2
-ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
-
-# Connect bob to R3
-ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
-ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
-    type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
-
-# Connect R1 to join
-ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
-    type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
-
-# Connect R2 to join
-ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
-    type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
-
-# Connect R3 to join
-ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
-ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
-    type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
-
-# Install static routes with source ip address as the policy for routing.
-# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
-ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
-
-# Static routes.
-ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
-ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
-
-# For gateway routers R2 and R3, set a force SNAT rule.
-ovn-nbctl set logical_router R2 options:lb_force_snat_ip=20.0.0.2
-ovn-nbctl set logical_router R3 options:lb_force_snat_ip=20.0.0.3
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.3/24", "f0:00:00:01:02:04", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
-"192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
-
-# Logical port 'bob1' in switch 'bob'.
-ADD_NAMESPACES(bob1)
-ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
-         "172.16.1.2")
-ovn-nbctl lsp-add bob bob1 \
--- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="192.168.1.2,192.168.2.2"`
-ovn-nbctl set logical_router R2 load_balancer=$uuid
-ovn-nbctl set logical_router R3 load_balancer=$uuid
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=192.168.2.2)'])
-
-# Start webservers in 'foo1', 'bar1'.
-OVS_START_L7([foo1], [http])
-OVS_START_L7([bar1], [http])
-
-dnl Should work with the virtual IP address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Force SNAT should have worked.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.3,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- load balancing in router with gateway router port])
-AT_KEYWORDS([ovnlb])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# One LR R1 with switches foo (192.168.1.0/24), bar (192.168.2.0/24),
-# and alice (172.16.1.0/24) connected to it.  The port between R1 and
-# alice is the router gateway port where the R1 LB rules are applied.
-#
-#    foo -- R1 -- bar
-#           |
-#    alice ----
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
-    -- set Logical_Router_Port alice options:redirect-chassis=hv1
-
-# Connect foo to R1
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect bar to R1
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar \
-    -- lsp-set-addresses rp-bar router
-
-# Connect alice to R1
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'foo2' in switch 'foo'.
-ADD_NAMESPACES(foo2)
-ADD_VETH(foo2, foo2, br-int, "192.168.1.3/24", "f0:00:00:01:02:06", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo2 \
--- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:04", \
-         "192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:05", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.2"
-
-# Config OVN load-balancer with a VIP.
-uuid=`ovn-nbctl  create load_balancer vips:172.16.1.10="192.168.1.2,192.168.2.2"`
-ovn-nbctl set logical_router R1 load_balancer=$uuid
-
-# Config OVN load-balancer with another VIP (this time with ports).
-ovn-nbctl set load_balancer $uuid vips:'"172.16.1.11:8000"'='"192.168.1.2:80,192.168.2.2:80"'
-
-# Wait for ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-grep 'nat(dst=192.168.2.2:80)'])
-
-# Start webservers in 'foo1', 'bar1'.
-OVS_START_L7([foo1], [http])
-OVS_START_L7([bar1], [http])
-
-dnl Should work with the virtual IP address through NAT
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [wget 172.16.1.10 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.10) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.2,dst=172.16.1.10,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.2,dst=172.16.1.10,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-dnl Test load-balancing that includes L4 ports in NAT.
-for i in `seq 1 20`; do
-    echo Request $i
-    NS_CHECK_EXEC([alice1], [wget 172.16.1.11:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
-done
-
-dnl Each server should have at least one connection.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.11) |
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-tcp,orig=(src=172.16.1.2,dst=172.16.1.11,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-tcp,orig=(src=172.16.1.2,dst=172.16.1.11,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- DNAT and SNAT on distributed router - N/S])
-AT_KEYWORDS([ovnnat])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# One LR R1 with switches foo (192.168.1.0/24), bar (192.168.2.0/24),
-# and alice (172.16.1.0/24) connected to it.  The port between R1 and
-# alice is the router gateway port where the R1 NAT rules are applied.
-#
-#    foo -- R1 -- alice
-#           |
-#    bar ----
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
-    -- set Logical_Router_Port alice options:redirect-chassis=hv1
-
-# Connect foo to R1
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect bar to R1
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar \
-    -- lsp-set-addresses rp-bar router
-
-# Connect alice to R1
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'foo2' in switch 'foo'.
-ADD_NAMESPACES(foo2)
-ADD_VETH(foo2, foo2, br-int, "192.168.1.3/24", "f0:00:00:01:02:06", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo2 \
--- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:04", \
-         "192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:05", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.2"
-
-# Add DNAT rules
-AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.3 192.168.1.2 foo1 00:00:02:02:03:04])
-AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.4 192.168.1.3 foo2 00:00:02:02:03:05])
-
-# Add a SNAT rule
-AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.1 192.168.0.0/16])
-
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)'])
-
-# North-South DNAT: 'alice1' pings 'foo1' using 172.16.1.3.
-NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.3 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that DNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.3) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.2,dst=172.16.1.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-# South-North SNAT: 'foo2' pings 'alice1'. But 'alice1' receives traffic
-# from 172.16.1.4
-NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.1.3,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-AT_CHECK([ovs-appctl dpctl/flush-conntrack])
-
-# South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
-# from 172.16.1.1
-NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that SNAT indeed happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- DNAT and SNAT on distributed router - E/W])
-AT_KEYWORDS([ovnnat])
-
-CHECK_CONNTRACK()
-CHECK_CONNTRACK_NAT()
-ovn_start
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# One LR R1 with switches foo (192.168.1.0/24), bar (192.168.2.0/24),
-# and alice (172.16.1.0/24) connected to it.  The port between R1 and
-# alice is the router gateway port where the R1 NAT rules are applied.
-#
-#    foo -- R1 -- alice
-#           |
-#    bar ----
-
-ovn-nbctl lr-add R1
-
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add bar
-ovn-nbctl ls-add alice
-
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
-    -- set Logical_Router_Port alice options:redirect-chassis=hv1
-
-# Connect foo to R1
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
-    type=router options:router-port=foo \
-    -- lsp-set-addresses rp-foo router
-
-# Connect bar to R1
-ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
-    type=router options:router-port=bar \
-    -- lsp-set-addresses rp-bar router
-
-# Connect alice to R1
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
-    type=router options:router-port=alice \
-    -- lsp-set-addresses rp-alice router
-
-# Logical port 'foo1' in switch 'foo'.
-ADD_NAMESPACES(foo1)
-ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
-
-# Logical port 'foo2' in switch 'foo'.
-ADD_NAMESPACES(foo2)
-ADD_VETH(foo2, foo2, br-int, "192.168.1.3/24", "f0:00:00:01:02:06", \
-         "192.168.1.1")
-ovn-nbctl lsp-add foo foo2 \
--- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
-
-# Logical port 'bar1' in switch 'bar'.
-ADD_NAMESPACES(bar1)
-ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:04", \
-         "192.168.2.1")
-ovn-nbctl lsp-add bar bar1 \
--- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
-
-# Logical port 'alice1' in switch 'alice'.
-ADD_NAMESPACES(alice1)
-ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:05", \
-         "172.16.1.1")
-ovn-nbctl lsp-add alice alice1 \
--- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.2"
-
-# Add DNAT rules
-AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.3 192.168.1.2 foo1 00:00:02:02:03:04])
-AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.4 192.168.2.2 bar1 00:00:02:02:03:05])
-
-# Add a SNAT rule
-AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.1 192.168.0.0/16])
-
-ovn-nbctl --wait=hv sync
-OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)'])
-
-echo "------ hv dump ------"
-ovs-ofctl show br-int
-ovs-ofctl dump-flows br-int
-echo "---------------------"
-
-# East-West No NAT: 'foo1' pings 'bar1' using 192.168.2.2.
-NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that no NAT happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' | wc -l], [0], [0
-])
-
-# East-West No NAT: 'foo2' pings 'bar1' using 192.168.2.2.
-NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 192.168.2.2 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that no NAT happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' | wc -l], [0], [0
-])
-
-# East-West No NAT: 'bar1' pings 'foo2' using 192.168.1.3.
-NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.3 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# We verify that no NAT happened via 'dump-conntrack' command.
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.168.2.2) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/' | wc -l], [0], [0
-])
-
-# East-West NAT: 'foo1' pings 'bar1' using 172.16.1.4.
-NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# Check conntrack entries.  First SNAT of 'foo1' address happens.
-# Then DNAT of 'bar1' address happens (listed first below).
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.4) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.1,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-icmp,orig=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-AT_CHECK([ovs-appctl dpctl/flush-conntrack])
-
-# East-West NAT: 'foo2' pings 'bar1' using 172.16.1.4.
-NS_CHECK_EXEC([foo2], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \
-[0], [dnl
-3 packets transmitted, 3 received, 0% packet loss, time 0ms
-])
-
-# Check conntrack entries.  First SNAT of 'foo2' address happens.
-# Then DNAT of 'bar1' address happens (listed first below).
-AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \
-sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
-icmp,orig=(src=172.16.1.1,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=192.168.2.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-icmp,orig=(src=192.168.1.3,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
-
-AT_SETUP([ovn -- 2 LSs IGMP])
-AT_KEYWORDS([ovnigmp])
-
-ovn_start
-
-OVS_TRAFFIC_VSWITCHD_START()
-ADD_BR([br-int])
-
-# Set external-ids in br-int needed for ovn-controller
-ovs-vsctl \
-        -- set Open_vSwitch . external-ids:system-id=hv1 \
-        -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
-
-# Start ovn-controller
-start_daemon ovn-controller
-
-# Logical network:
-# Two independent logical switches (sw1 and sw2).
-# sw1:
-#   - subnet 10.0.0.0/8
-#   - 2 ports (sw1-p1 - sw1-p2)
-# sw2:
-#   - subnet 20.0.0.0/8
-#   - 2 port (sw2-p1 - sw2-p2)
-#   - IGMP Querier from 20.0.0.254
-
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add sw2
-
-for i in `seq 1 2`
-do
-    ADD_NAMESPACES(sw1-p$i)
-    ADD_VETH(sw1-p$i, sw1-p$i, br-int, "10.0.0.$i/24", "00:00:00:00:01:0$i", \
-            "10.0.0.254")
-    ovn-nbctl lsp-add sw1 sw1-p$i \
-        -- lsp-set-addresses sw1-p$i "00:00:00:00:01:0$i 10.0.0.$i"
-done
-
-for i in `seq 1 2`
-do
-    ADD_NAMESPACES(sw2-p$i)
-    ADD_VETH(sw2-p$i, sw2-p$i, br-int, "20.0.0.$i/24", "00:00:00:00:02:0$i", \
-            "20.0.0.254")
-    ovn-nbctl lsp-add sw2 sw2-p$i \
-        -- lsp-set-addresses sw2-p$i "00:00:00:00:02:0$i 20.0.0.$i"
-done
-
-# Enable IGMP snooping on sw1.
-ovn-nbctl set Logical_Switch sw1 other_config:mcast_querier="false"
-ovn-nbctl set Logical_Switch sw1 other_config:mcast_snoop="true"
-
-# Inject IGMP Join for 239.0.1.68 on sw1-p1.
-NS_CHECK_EXEC([sw1-p1], [ip addr add dev sw1-p1 239.0.1.68/32 autojoin], [0])
-
-# Inject IGMP Join for 239.0.1.68 on sw1-p2
-NS_CHECK_EXEC([sw1-p2], [ip addr add dev sw1-p2 239.0.1.68/32 autojoin], [0])
-
-# Check that the IGMP Group is learned.
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    ports=`ovn-sbctl find IGMP_Group | grep ports | cut -f 2 -d ":" | wc -w`
-    test "${total_entries}" = "1"
-    test "${ports}" = "2"
-])
-
-# Inject IGMP Leave for 239.0.1.68 on sw1-p2.
-NS_CHECK_EXEC([sw1-p2], [ip addr del dev sw1-p2 239.0.1.68/32], [0])
-
-# Check that only one port is left in the group.
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    ports=`ovn-sbctl find IGMP_Group | grep ports | cut -f 2 -d ":" | wc -w`
-    test "${total_entries}" = "1"
-    test "${ports}" = "1"
-])
-
-# Flush IGMP groups.
-ovn-sbctl ip-multicast-flush sw1
-ovn-nbctl --wait=hv -t 3 sync
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
-    test "${total_entries}" = "0"
-])
-
-# Enable IGMP snooping and querier on sw2 and set query interval to minimum.
-ovn-nbctl set Logical_Switch sw2 \
-    other_config:mcast_snoop="true" \
-    other_config:mcast_querier="true" \
-    other_config:mcast_query_interval=1 \
-    other_config:mcast_eth_src="00:00:00:00:02:fe" \
-    other_config:mcast_ip4_src="20.0.0.254"
-
-# Check that queries are generated.
-NS_CHECK_EXEC([sw2-p1], [tcpdump -n -c 2 -i sw2-p1 igmp > sw2-p1.pcap &])
-
-OVS_WAIT_UNTIL([
-    total_queries=`cat sw2-p1.pcap | grep "igmp query" | wc -l`
-    test "${total_queries}" = "2"
-])
-
-OVS_APP_EXIT_AND_WAIT([ovn-controller])
-
-as ovn-sb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as ovn-nb
-OVS_APP_EXIT_AND_WAIT([ovsdb-server])
-
-as northd
-OVS_APP_EXIT_AND_WAIT([ovn-northd])
-
-as
-OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
-/connection dropped.*/d"])
-AT_CLEANUP
diff --git a/tests/test-ovn.c b/tests/test-ovn.c
deleted file mode 100644
index 0b9e824..0000000
--- a/tests/test-ovn.c
+++ /dev/null
@@ -1,1584 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 2017 Nicira, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <config.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/wait.h>
-
-#include "command-line.h"
-#include "dp-packet.h"
-#include "fatal-signal.h"
-#include "flow.h"
-#include "openvswitch/dynamic-string.h"
-#include "openvswitch/match.h"
-#include "openvswitch/ofp-actions.h"
-#include "openvswitch/ofpbuf.h"
-#include "openvswitch/vlog.h"
-#include "ovn/actions.h"
-#include "ovn/expr.h"
-#include "ovn/lex.h"
-#include "ovn/logical-fields.h"
-#include "ovn/lib/ovn-l7.h"
-#include "ovn/lib/extend-table.h"
-#include "ovs-thread.h"
-#include "ovstest.h"
-#include "openvswitch/shash.h"
-#include "simap.h"
-#include "util.h"
-
-/* --relops: Bitmap of the relational operators to test, in exhaustive test. */
-static unsigned int test_relops;
-
-/* --nvars: Number of numeric variables to test, in exhaustive test. */
-static int test_nvars = 2;
-
-/* --svars: Number of string variables to test, in exhaustive test. */
-static int test_svars = 2;
-
-/* --bits: Number of bits per variable, in exhaustive test. */
-static int test_bits = 3;
-
-/* --operation: The operation to test, in exhaustive test. */
-static enum { OP_CONVERT, OP_SIMPLIFY, OP_NORMALIZE, OP_FLOW } operation
-    = OP_FLOW;
-
-/* --parallel: Number of parallel processes to use in test. */
-static int test_parallel = 1;
-
-/* -m, --more: Message verbosity */
-static int verbosity;
-
-static void
-compare_token(const struct lex_token *a, const struct lex_token *b)
-{
-    if (a->type != b->type) {
-        fprintf(stderr, "type differs: %d -> %d\n", a->type, b->type);
-        return;
-    }
-
-    if (!((a->s && b->s && !strcmp(a->s, b->s))
-          || (!a->s && !b->s))) {
-        fprintf(stderr, "string differs: %s -> %s\n",
-                a->s ? a->s : "(null)",
-                b->s ? b->s : "(null)");
-        return;
-    }
-
-    if (a->type == LEX_T_INTEGER || a->type == LEX_T_MASKED_INTEGER) {
-        if (memcmp(&a->value, &b->value, sizeof a->value)) {
-            fprintf(stderr, "value differs\n");
-            return;
-        }
-
-        if (a->type == LEX_T_MASKED_INTEGER
-            && memcmp(&a->mask, &b->mask, sizeof a->mask)) {
-            fprintf(stderr, "mask differs\n");
-            return;
-        }
-
-        if (a->format != b->format
-            && !(a->format == LEX_F_HEXADECIMAL
-                 && b->format == LEX_F_DECIMAL
-                 && a->value.integer == 0)) {
-            fprintf(stderr, "format differs: %d -> %d\n",
-                    a->format, b->format);
-        }
-    }
-}
-
-static void
-test_lex(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    struct ds input;
-    struct ds output;
-
-    ds_init(&input);
-    ds_init(&output);
-    while (!ds_get_test_line(&input, stdin)) {
-        struct lexer lexer;
-
-        lexer_init(&lexer, ds_cstr(&input));
-        ds_clear(&output);
-        while (lexer_get(&lexer) != LEX_T_END) {
-            size_t len = output.length;
-            lex_token_format(&lexer.token, &output);
-
-            /* Check that the formatted version can really be parsed back
-             * losslessly. */
-            if (lexer.token.type != LEX_T_ERROR) {
-                const char *s = ds_cstr(&output) + len;
-                struct lexer l2;
-
-                lexer_init(&l2, s);
-                lexer_get(&l2);
-                compare_token(&lexer.token, &l2.token);
-                lexer_destroy(&l2);
-            }
-            ds_put_char(&output, ' ');
-        }
-        lexer_destroy(&lexer);
-
-        ds_chomp(&output, ' ');
-        puts(ds_cstr(&output));
-    }
-    ds_destroy(&input);
-    ds_destroy(&output);
-}
-
-static void
-create_symtab(struct shash *symtab)
-{
-    ovn_init_symtab(symtab);
-
-    /* For negative testing. */
-    expr_symtab_add_field(symtab, "bad_prereq", MFF_XREG0, "xyzzy", false);
-    expr_symtab_add_field(symtab, "self_recurse", MFF_XREG0,
-                          "self_recurse != 0", false);
-    expr_symtab_add_field(symtab, "mutual_recurse_1", MFF_XREG0,
-                          "mutual_recurse_2 != 0", false);
-    expr_symtab_add_field(symtab, "mutual_recurse_2", MFF_XREG0,
-                          "mutual_recurse_1 != 0", false);
-    expr_symtab_add_string(symtab, "big_string", MFF_XREG0, NULL);
-}
-
-static void
-create_gen_opts(struct hmap *dhcp_opts, struct hmap *dhcpv6_opts,
-                struct hmap *nd_ra_opts,
-                struct controller_event_options *event_opts)
-{
-    hmap_init(dhcp_opts);
-    dhcp_opt_add(dhcp_opts, "offerip", 0, "ipv4");
-    dhcp_opt_add(dhcp_opts, "netmask", 1, "ipv4");
-    dhcp_opt_add(dhcp_opts, "router",  3, "ipv4");
-    dhcp_opt_add(dhcp_opts, "dns_server", 6, "ipv4");
-    dhcp_opt_add(dhcp_opts, "log_server", 7, "ipv4");
-    dhcp_opt_add(dhcp_opts, "lpr_server",  9, "ipv4");
-    dhcp_opt_add(dhcp_opts, "domain_name", 15, "str");
-    dhcp_opt_add(dhcp_opts, "swap_server", 16, "ipv4");
-    dhcp_opt_add(dhcp_opts, "policy_filter", 21, "ipv4");
-    dhcp_opt_add(dhcp_opts, "router_solicitation",  32, "ipv4");
-    dhcp_opt_add(dhcp_opts, "nis_server", 41, "ipv4");
-    dhcp_opt_add(dhcp_opts, "ntp_server", 42, "ipv4");
-    dhcp_opt_add(dhcp_opts, "server_id",  54, "ipv4");
-    dhcp_opt_add(dhcp_opts, "tftp_server", 66, "ipv4");
-    dhcp_opt_add(dhcp_opts, "classless_static_route", 121, "static_routes");
-    dhcp_opt_add(dhcp_opts, "ip_forward_enable",  19, "bool");
-    dhcp_opt_add(dhcp_opts, "router_discovery", 31, "bool");
-    dhcp_opt_add(dhcp_opts, "ethernet_encap", 36, "bool");
-    dhcp_opt_add(dhcp_opts, "default_ttl",  23, "uint8");
-    dhcp_opt_add(dhcp_opts, "tcp_ttl", 37, "uint8");
-    dhcp_opt_add(dhcp_opts, "mtu", 26, "uint16");
-    dhcp_opt_add(dhcp_opts, "lease_time",  51, "uint32");
-    dhcp_opt_add(dhcp_opts, "wpad", 252, "str");
-    dhcp_opt_add(dhcp_opts, "bootfile_name", 67, "str");
-    dhcp_opt_add(dhcp_opts, "path_prefix", 210, "str");
-    dhcp_opt_add(dhcp_opts, "tftp_server_address", 150, "ipv4");
-
-    /* DHCPv6 options. */
-    hmap_init(dhcpv6_opts);
-    dhcp_opt_add(dhcpv6_opts, "server_id",  2, "mac");
-    dhcp_opt_add(dhcpv6_opts, "ia_addr",  5, "ipv6");
-    dhcp_opt_add(dhcpv6_opts, "dns_server",  23, "ipv6");
-    dhcp_opt_add(dhcpv6_opts, "domain_search",  24, "str");
-
-    /* IPv6 ND RA options. */
-    hmap_init(nd_ra_opts);
-    nd_ra_opts_init(nd_ra_opts);
-
-    /* OVN controller events options. */
-    controller_event_opts_init(event_opts);
-}
-
-static void
-create_addr_sets(struct shash *addr_sets)
-{
-    shash_init(addr_sets);
-
-    static const char *const addrs1[] = {
-        "10.0.0.1", "10.0.0.2", "10.0.0.3",
-    };
-    static const char *const addrs2[] = {
-        "::1", "::2", "::3",
-    };
-    static const char *const addrs3[] = {
-        "00:00:00:00:00:01", "00:00:00:00:00:02", "00:00:00:00:00:03",
-    };
-    static const char *const addrs4[] = { NULL };
-
-    expr_const_sets_add(addr_sets, "set1", addrs1, 3, true);
-    expr_const_sets_add(addr_sets, "set2", addrs2, 3, true);
-    expr_const_sets_add(addr_sets, "set3", addrs3, 3, true);
-    expr_const_sets_add(addr_sets, "set4", addrs4, 0, true);
-}
-
-static void
-create_port_groups(struct shash *port_groups)
-{
-    shash_init(port_groups);
-
-    static const char *const pg1[] = {
-        "lsp1", "lsp2", "lsp3",
-    };
-    static const char *const pg2[] = { NULL };
-
-    expr_const_sets_add(port_groups, "pg1", pg1, 3, false);
-    expr_const_sets_add(port_groups, "pg_empty", pg2, 0, false);
-}
-
-static bool
-lookup_port_cb(const void *ports_, const char *port_name, unsigned int *portp)
-{
-    const struct simap *ports = ports_;
-    const struct simap_node *node = simap_find(ports, port_name);
-    if (!node) {
-        return false;
-    }
-    *portp = node->data;
-    return true;
-}
-
-static bool
-is_chassis_resident_cb(const void *ports_, const char *port_name)
-{
-    const struct simap *ports = ports_;
-    const struct simap_node *node = simap_find(ports, port_name);
-    if (node) {
-        return true;
-    }
-    return false;
-}
-
-static void
-test_parse_expr__(int steps)
-{
-    struct shash symtab;
-    struct shash addr_sets;
-    struct shash port_groups;
-    struct simap ports;
-    struct ds input;
-
-    create_symtab(&symtab);
-    create_addr_sets(&addr_sets);
-    create_port_groups(&port_groups);
-
-    simap_init(&ports);
-    simap_put(&ports, "eth0", 5);
-    simap_put(&ports, "eth1", 6);
-    simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL));
-    simap_put(&ports, "lsp1", 0x11);
-    simap_put(&ports, "lsp2", 0x12);
-    simap_put(&ports, "lsp3", 0x13);
-
-    ds_init(&input);
-    while (!ds_get_test_line(&input, stdin)) {
-        struct expr *expr;
-        char *error;
-
-        expr = expr_parse_string(ds_cstr(&input), &symtab, &addr_sets,
-                                 &port_groups, NULL, &error);
-        if (!error && steps > 0) {
-            expr = expr_annotate(expr, &symtab, &error);
-        }
-        if (!error) {
-            if (steps > 1) {
-                expr = expr_simplify(expr, is_chassis_resident_cb, &ports);
-            }
-            if (steps > 2) {
-                expr = expr_normalize(expr);
-                ovs_assert(expr_is_normalized(expr));
-            }
-        }
-        if (!error) {
-            if (steps > 3) {
-                struct hmap matches;
-
-                expr_to_matches(expr, lookup_port_cb, &ports, &matches);
-                expr_matches_print(&matches, stdout);
-                expr_matches_destroy(&matches);
-            } else {
-                struct ds output = DS_EMPTY_INITIALIZER;
-                expr_format(expr, &output);
-                puts(ds_cstr(&output));
-                ds_destroy(&output);
-            }
-        } else {
-            puts(error);
-            free(error);
-        }
-        expr_destroy(expr);
-    }
-    ds_destroy(&input);
-
-    simap_destroy(&ports);
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-    expr_const_sets_destroy(&addr_sets);
-    shash_destroy(&addr_sets);
-    expr_const_sets_destroy(&port_groups);
-    shash_destroy(&port_groups);
-}
-
-static void
-test_parse_expr(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    test_parse_expr__(0);
-}
-
-static void
-test_annotate_expr(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    test_parse_expr__(1);
-}
-
-static void
-test_simplify_expr(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    test_parse_expr__(2);
-}
-
-static void
-test_normalize_expr(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    test_parse_expr__(3);
-}
-
-static void
-test_expr_to_flows(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    test_parse_expr__(4);
-}
-
-/* Print the symbol table. */
-
-static void
-test_dump_symtab(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    struct shash symtab;
-    create_symtab(&symtab);
-
-    const struct shash_node **nodes = shash_sort(&symtab);
-    for (size_t i = 0; i < shash_count(&symtab); i++) {
-        const struct expr_symbol *symbol = nodes[i]->data;
-        struct ds s = DS_EMPTY_INITIALIZER;
-        expr_symbol_format(symbol, &s);
-        puts(ds_cstr(&s));
-        ds_destroy(&s);
-    }
-
-    free(nodes);
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-}
-
-/* Evaluate an expression. */
-
-static bool
-lookup_atoi_cb(const void *aux OVS_UNUSED, const char *port_name,
-               unsigned int *portp)
-{
-    *portp = atoi(port_name);
-    return true;
-}
-
-static void
-test_evaluate_expr(struct ovs_cmdl_context *ctx)
-{
-    struct shash symtab;
-    struct ds input;
-
-    ovn_init_symtab(&symtab);
-
-    struct flow uflow;
-    char *error = expr_parse_microflow(ctx->argv[1], &symtab, NULL, NULL,
-                                       lookup_atoi_cb, NULL, &uflow);
-    if (error) {
-        ovs_fatal(0, "%s", error);
-    }
-
-    ds_init(&input);
-    while (!ds_get_test_line(&input, stdin)) {
-        struct expr *expr;
-
-        expr = expr_parse_string(ds_cstr(&input), &symtab, NULL, NULL, NULL,
-                                 &error);
-        if (!error) {
-            expr = expr_annotate(expr, &symtab, &error);
-        }
-        if (!error) {
-            printf("%d\n", expr_evaluate(expr, &uflow, lookup_atoi_cb, NULL));
-        } else {
-            puts(error);
-            free(error);
-        }
-        expr_destroy(expr);
-    }
-    ds_destroy(&input);
-
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-}
-
-/* Compositions.
- *
- * The "compositions" of a positive integer N are all of the ways that one can
- * add up positive integers to sum to N.  For example, the compositions of 3
- * are 3, 2+1, 1+2, and 1+1+1.
- *
- * We use compositions to find all the ways to break up N terms of a Boolean
- * expression into subexpressions.  Suppose we want to generate all expressions
- * with 3 terms.  The compositions of 3 (ignoring 3 itself) provide the
- * possibilities (x && x) || x, x || (x && x), and x || x || x.  (Of course one
- * can exchange && for || in each case.)  One must recursively compose the
- * sub-expressions whose values are 3 or greater; that is what the "tree shape"
- * concept later covers.
- *
- * To iterate through all compositions of, e.g., 5:
- *
- *     unsigned int state;
- *     int s[5];
- *     int n;
- *
- *     for (n = first_composition(ARRAY_SIZE(s), &state, s); n > 0;
- *          n = next_composition(&state, s, n)) {
- *          // Do something with composition 's' with 'n' elements.
- *     }
- *
- * Algorithm from D. E. Knuth, _The Art of Computer Programming, Vol. 4A:
- * Combinatorial Algorithms, Part 1_, section 7.2.1.1, answer to exercise
- * 12(a).
- */
-
-/* Begins iteration through the compositions of 'n'.  Initializes 's' to the
- * number of elements in the first composition of 'n' and returns that number
- * of elements.  The first composition in fact is always 'n' itself, so the
- * return value will be 1.
- *
- * Initializes '*state' to some internal state information.  The caller must
- * maintain this state (and 's') for use by next_composition().
- *
- * 's' must have room for at least 'n' elements. */
-static int
-first_composition(int n, unsigned int *state, int s[])
-{
-    *state = 0;
-    s[0] = n;
-    return 1;
-}
-
-/* Advances 's', with 'sn' elements, to the next composition and returns the
- * number of elements in this new composition, or 0 if no compositions are
- * left.  'state' is the same internal state passed to first_composition(). */
-static int
-next_composition(unsigned int *state, int s[], int sn)
-{
-    int j = sn - 1;
-    if (++*state & 1) {
-        if (s[j] > 1) {
-            s[j]--;
-            s[j + 1] = 1;
-            j++;
-        } else {
-            j--;
-            s[j]++;
-        }
-    } else {
-        if (s[j - 1] > 1) {
-            s[j - 1]--;
-            s[j + 1] = s[j];
-            s[j] = 1;
-            j++;
-        } else {
-            j--;
-            if (!j) {
-                return 0;
-            }
-            s[j] = s[j + 1];
-            s[j - 1]++;
-        }
-    }
-    return j + 1;
-}
-
-static void
-test_composition(struct ovs_cmdl_context *ctx)
-{
-    int n = atoi(ctx->argv[1]);
-    unsigned int state;
-    int s[50];
-
-    for (int sn = first_composition(n, &state, s); sn;
-         sn = next_composition(&state, s, sn)) {
-        for (int i = 0; i < sn; i++) {
-            printf("%d%c", s[i], i == sn - 1 ? '\n' : ' ');
-        }
-    }
-}
-
-/* Tree shapes.
- *
- * This code generates all possible Boolean expressions with a specified number
- * of terms N (equivalent to the number of external nodes in a tree).
- *
- * See test_tree_shape() for a simple example. */
-
-/* An array of these structures describes the shape of a tree.
- *
- * A single element of struct tree_shape describes a single node in the tree.
- * The node has 'sn' direct children.  From left to right, for i in 0...sn-1,
- * s[i] is 1 if the child is a leaf node, otherwise the child is a subtree and
- * s[i] is the number of leaf nodes within that subtree.  In the latter case,
- * the subtree is described by another struct tree_shape within the enclosing
- * array.  The tree_shapes are ordered in the array in in-order.
- */
-struct tree_shape {
-    unsigned int state;
-    int s[50];
-    int sn;
-};
-
-static int
-init_tree_shape__(struct tree_shape ts[], int n)
-{
-    if (n <= 2) {
-        return 0;
-    }
-
-    int n_tses = 1;
-    /* Skip the first composition intentionally. */
-    ts->sn = first_composition(n, &ts->state, ts->s);
-    ts->sn = next_composition(&ts->state, ts->s, ts->sn);
-    for (int i = 0; i < ts->sn; i++) {
-        n_tses += init_tree_shape__(&ts[n_tses], ts->s[i]);
-    }
-    return n_tses;
-}
-
-/* Initializes 'ts[]' as the first in the set of all of possible shapes of
- * trees with 'n' leaves.  Returns the number of "struct tree_shape"s in the
- * first tree shape. */
-static int
-init_tree_shape(struct tree_shape ts[], int n)
-{
-    switch (n) {
-    case 1:
-        ts->sn = 1;
-        ts->s[0] = 1;
-        return 1;
-    case 2:
-        ts->sn = 2;
-        ts->s[0] = 1;
-        ts->s[1] = 1;
-        return 1;
-    default:
-        return init_tree_shape__(ts, n);
-    }
-}
-
-/* Advances 'ts', which currently has 'n_tses' elements, to the next possible
- * tree shape with the number of leaves passed to init_tree_shape().  Returns
- * the number of "struct tree_shape"s in the next shape, or 0 if all tree
- * shapes have been visited. */
-static int
-next_tree_shape(struct tree_shape ts[], int n_tses)
-{
-    if (n_tses == 1 && ts->sn == 2 && ts->s[0] == 1 && ts->s[1] == 1) {
-        return 0;
-    }
-    while (n_tses > 0) {
-        struct tree_shape *p = &ts[n_tses - 1];
-        p->sn = p->sn > 1 ? next_composition(&p->state, p->s, p->sn) : 0;
-        if (p->sn) {
-            for (int i = 0; i < p->sn; i++) {
-                n_tses += init_tree_shape__(&ts[n_tses], p->s[i]);
-            }
-            break;
-        }
-        n_tses--;
-    }
-    return n_tses;
-}
-
-static void
-print_tree_shape(const struct tree_shape ts[], int n_tses)
-{
-    for (int i = 0; i < n_tses; i++) {
-        if (i) {
-            printf(", ");
-        }
-        for (int j = 0; j < ts[i].sn; j++) {
-            int k = ts[i].s[j];
-            if (k > 9) {
-                printf("(%d)", k);
-            } else {
-                printf("%d", k);
-            }
-        }
-    }
-}
-
-static void
-test_tree_shape(struct ovs_cmdl_context *ctx)
-{
-    int n = atoi(ctx->argv[1]);
-    struct tree_shape ts[50];
-    int n_tses;
-
-    for (n_tses = init_tree_shape(ts, n); n_tses;
-         n_tses = next_tree_shape(ts, n_tses)) {
-        print_tree_shape(ts, n_tses);
-        putchar('\n');
-    }
-}
-
-/* Iteration through all possible terminal expressions (e.g. EXPR_T_CMP and
- * EXPR_T_BOOLEAN expressions).
- *
- * Given a tree shape, this allows the code to try all possible ways to plug in
- * terms.
- *
- * Example use:
- *
- *     struct expr terminal;
- *     const struct expr_symbol *vars = ...;
- *     int n_vars = ...;
- *     int n_bits = ...;
- *
- *     init_terminal(&terminal, vars[0]);
- *     do {
- *         // Something with 'terminal'.
- *     } while (next_terminal(&terminal, vars, n_vars, n_bits));
- */
-
-/* Sets 'expr' to the first possible terminal expression.  'var' should be the
- * first variable in the ones to be tested. */
-static void
-init_terminal(struct expr *expr, int phase,
-              const struct expr_symbol *nvars[], int n_nvars,
-              const struct expr_symbol *svars[], int n_svars)
-{
-    if (phase < 1 && n_nvars) {
-        expr->type = EXPR_T_CMP;
-        expr->cmp.symbol = nvars[0];
-        expr->cmp.relop = rightmost_1bit_idx(test_relops);
-        memset(&expr->cmp.value, 0, sizeof expr->cmp.value);
-        memset(&expr->cmp.mask, 0, sizeof expr->cmp.mask);
-        expr->cmp.value.integer = htonll(0);
-        expr->cmp.mask.integer = htonll(0);
-        return;
-    }
-
-    if (phase < 2 && n_svars) {
-        expr->type = EXPR_T_CMP;
-        expr->cmp.symbol = svars[0];
-        expr->cmp.relop = EXPR_R_EQ;
-        expr->cmp.string = xstrdup("0");
-        return;
-    }
-
-    expr->type = EXPR_T_BOOLEAN;
-    expr->boolean = false;
-}
-
-/* Returns 'x' with the rightmost contiguous string of 1s changed to 0s,
- * e.g. 01011100 => 01000000.  See H. S. Warren, Jr., _Hacker's Delight_, 2nd
- * ed., section 2-1. */
-static unsigned int
-turn_off_rightmost_1s(unsigned int x)
-{
-    return ((x & -x) + x) & x;
-}
-
-static const struct expr_symbol *
-next_var(const struct expr_symbol *symbol,
-         const struct expr_symbol *vars[], int n_vars)
-{
-    for (int i = 0; i < n_vars; i++) {
-        if (symbol == vars[i]) {
-            return i + 1 >= n_vars ? NULL : vars[i + 1];
-        }
-    }
-    OVS_NOT_REACHED();
-}
-
-static enum expr_relop
-next_relop(enum expr_relop relop)
-{
-    unsigned int remaining_relops = test_relops & ~((1u << (relop + 1)) - 1);
-    return (remaining_relops
-            ? rightmost_1bit_idx(remaining_relops)
-            : rightmost_1bit_idx(test_relops));
-}
-
-/* Advances 'expr' to the next possible terminal expression within the 'n_vars'
- * variables of 'n_bits' bits each in 'vars[]'. */
-static bool
-next_terminal(struct expr *expr,
-              const struct expr_symbol *nvars[], int n_nvars, int n_bits,
-              const struct expr_symbol *svars[], int n_svars)
-{
-    if (expr->type == EXPR_T_BOOLEAN) {
-        if (expr->boolean) {
-            return false;
-        } else {
-            expr->boolean = true;
-            return true;
-        }
-    }
-
-    if (!expr->cmp.symbol->width) {
-        int next_value = atoi(expr->cmp.string) + 1;
-        free(expr->cmp.string);
-        if (next_value > 1) {
-            expr->cmp.symbol = next_var(expr->cmp.symbol, svars, n_svars);
-            if (!expr->cmp.symbol) {
-                init_terminal(expr, 2, nvars, n_nvars, svars, n_svars);
-                return true;
-            }
-            next_value = 0;
-        }
-        expr->cmp.string = xasprintf("%d", next_value);
-        return true;
-    }
-
-    unsigned int next;
-
-    next = (ntohll(expr->cmp.value.integer)
-            + (ntohll(expr->cmp.mask.integer) << n_bits));
-    for (;;) {
-        next++;
-        unsigned m = next >> n_bits;
-        unsigned v = next & ((1u << n_bits) - 1);
-        if (next >= (1u << (2 * n_bits))) {
-            enum expr_relop old_relop = expr->cmp.relop;
-            expr->cmp.relop = next_relop(old_relop);
-            if (expr->cmp.relop <= old_relop) {
-                expr->cmp.symbol = next_var(expr->cmp.symbol, nvars, n_nvars);
-                if (!expr->cmp.symbol) {
-                    init_terminal(expr, 1, nvars, n_nvars, svars, n_svars);
-                    return true;
-                }
-            }
-            next = UINT_MAX;
-        } else if (v & ~m) {
-            /* Skip: 1-bits in value correspond to 0-bits in mask. */
-        } else if ((!m || turn_off_rightmost_1s(m))
-                   && (expr->cmp.relop != EXPR_R_EQ &&
-                       expr->cmp.relop != EXPR_R_NE)) {
-            /* Skip: can't have discontiguous or all-0 mask for > >= < <=. */
-        } else {
-            expr->cmp.value.integer = htonll(v);
-            expr->cmp.mask.integer = htonll(m);
-            return true;
-        }
-    }
-}
-
-static struct expr *
-make_terminal(struct expr ***terminalp)
-{
-    struct expr *e = expr_create_boolean(true);
-    **terminalp = e;
-    (*terminalp)++;
-    return e;
-}
-
-static struct expr *
-build_simple_tree(enum expr_type type, int n, struct expr ***terminalp)
-{
-    if (n == 2) {
-        struct expr *e = expr_create_andor(type);
-        for (int i = 0; i < 2; i++) {
-            struct expr *sub = make_terminal(terminalp);
-            ovs_list_push_back(&e->andor, &sub->node);
-        }
-        return e;
-    } else if (n == 1) {
-        return make_terminal(terminalp);
-    } else {
-        OVS_NOT_REACHED();
-    }
-}
-
-static struct expr *
-build_tree_shape(enum expr_type type, const struct tree_shape **tsp,
-                 struct expr ***terminalp)
-{
-    const struct tree_shape *ts = *tsp;
-    (*tsp)++;
-
-    struct expr *e = expr_create_andor(type);
-    enum expr_type t = type == EXPR_T_AND ? EXPR_T_OR : EXPR_T_AND;
-    for (int i = 0; i < ts->sn; i++) {
-        struct expr *sub = (ts->s[i] > 2
-                            ? build_tree_shape(t, tsp, terminalp)
-                            : build_simple_tree(t, ts->s[i], terminalp));
-        ovs_list_push_back(&e->andor, &sub->node);
-    }
-    return e;
-}
-
-struct test_rule {
-    struct cls_rule cr;
-};
-
-static void
-free_rule(struct test_rule *test_rule)
-{
-    cls_rule_destroy(&test_rule->cr);
-    free(test_rule);
-}
-
-static bool
-tree_shape_is_chassis_resident_cb(const void *c_aux OVS_UNUSED,
-                                  const char *port_name OVS_UNUSED)
-{
-    return true;
-}
-
-static int
-test_tree_shape_exhaustively(struct expr *expr, struct shash *symtab,
-                             struct expr *terminals[], int n_terminals,
-                             const struct expr_symbol *nvars[], int n_nvars,
-                             int n_bits,
-                             const struct expr_symbol *svars[], int n_svars)
-{
-    int n_tested = 0;
-
-    const unsigned int var_mask = (1u << n_bits) - 1;
-    for (int i = 0; i < n_terminals; i++) {
-        init_terminal(terminals[i], 0, nvars, n_nvars, svars, n_svars);
-    }
-
-    struct ds s = DS_EMPTY_INITIALIZER;
-    struct flow f;
-    memset(&f, 0, sizeof f);
-    for (;;) {
-        for (int i = n_terminals - 1; ; i--) {
-            if (!i) {
-                ds_destroy(&s);
-                return n_tested;
-            }
-            if (next_terminal(terminals[i], nvars, n_nvars, n_bits,
-                              svars, n_svars)) {
-                break;
-            }
-            init_terminal(terminals[i], 0, nvars, n_nvars, svars, n_svars);
-        }
-        ovs_assert(expr_honors_invariants(expr));
-
-        n_tested++;
-
-        struct expr *modified;
-        if (operation == OP_CONVERT) {
-            ds_clear(&s);
-            expr_format(expr, &s);
-
-            char *error;
-            modified = expr_parse_string(ds_cstr(&s), symtab, NULL,
-                                         NULL, NULL, &error);
-            if (error) {
-                fprintf(stderr, "%s fails to parse (%s)\n",
-                        ds_cstr(&s), error);
-                exit(EXIT_FAILURE);
-            }
-        } else if (operation >= OP_SIMPLIFY) {
-            modified = expr_simplify(expr_clone(expr),
-                                     tree_shape_is_chassis_resident_cb,
-                                     NULL);
-            ovs_assert(expr_honors_invariants(modified));
-
-            if (operation >= OP_NORMALIZE) {
-                modified = expr_normalize(modified);
-                ovs_assert(expr_honors_invariants(modified));
-                ovs_assert(expr_is_normalized(modified));
-            }
-        }
-
-        struct hmap matches;
-        struct classifier cls;
-        if (operation >= OP_FLOW) {
-            struct expr_match *m;
-            struct test_rule *test_rule;
-
-            expr_to_matches(modified, lookup_atoi_cb, NULL, &matches);
-
-            classifier_init(&cls, NULL);
-            HMAP_FOR_EACH (m, hmap_node, &matches) {
-                test_rule = xmalloc(sizeof *test_rule);
-                cls_rule_init(&test_rule->cr, &m->match, 0);
-                classifier_insert(&cls, &test_rule->cr, OVS_VERSION_MIN,
-                                  m->conjunctions, m->n);
-            }
-        }
-        for (int subst = 0; subst < 1 << (n_bits * n_nvars + n_svars);
-             subst++) {
-            for (int i = 0; i < n_nvars; i++) {
-                f.regs[i] = (subst >> (i * n_bits)) & var_mask;
-            }
-            for (int i = 0; i < n_svars; i++) {
-                f.regs[n_nvars + i] = ((subst >> (n_nvars * n_bits + i))
-                                       & 1);
-            }
-
-            bool expected = expr_evaluate(expr, &f, lookup_atoi_cb, NULL);
-            bool actual = expr_evaluate(modified, &f, lookup_atoi_cb, NULL);
-            if (actual != expected) {
-                struct ds expr_s, modified_s;
-
-                ds_init(&expr_s);
-                expr_format(expr, &expr_s);
-
-                ds_init(&modified_s);
-                expr_format(modified, &modified_s);
-
-                fprintf(stderr,
-                        "%s evaluates to %d, but %s evaluates to %d, for",
-                        ds_cstr(&expr_s), expected,
-                        ds_cstr(&modified_s), actual);
-                for (int i = 0; i < n_nvars; i++) {
-                    if (i > 0) {
-                        fputs(",", stderr);
-                    }
-                    fprintf(stderr, " n%d = 0x%x", i,
-                            (subst >> (n_bits * i)) & var_mask);
-                }
-                for (int i = 0; i < n_svars; i++) {
-                    fprintf(stderr, ", s%d = \"%d\"", i,
-                            (subst >> (n_bits * n_nvars + i)) & 1);
-                }
-                putc('\n', stderr);
-                exit(EXIT_FAILURE);
-            }
-
-            if (operation >= OP_FLOW) {
-                bool found = classifier_lookup(&cls, OVS_VERSION_MIN,
-                                               &f, NULL) != NULL;
-                if (expected != found) {
-                    struct ds expr_s, modified_s;
-
-                    ds_init(&expr_s);
-                    expr_format(expr, &expr_s);
-
-                    ds_init(&modified_s);
-                    expr_format(modified, &modified_s);
-
-                    fprintf(stderr,
-                            "%s and %s evaluate to %d, for",
-                            ds_cstr(&expr_s), ds_cstr(&modified_s), expected);
-                    for (int i = 0; i < n_nvars; i++) {
-                        if (i > 0) {
-                            fputs(",", stderr);
-                        }
-                        fprintf(stderr, " n%d = 0x%x", i,
-                                (subst >> (n_bits * i)) & var_mask);
-                    }
-                    for (int i = 0; i < n_svars; i++) {
-                        fprintf(stderr, ", s%d = \"%d\"", i,
-                                (subst >> (n_bits * n_nvars + i)) & 1);
-                    }
-                    fputs(".\n", stderr);
-
-                    fprintf(stderr, "Converted to classifier:\n");
-                    expr_matches_print(&matches, stderr);
-                    fprintf(stderr,
-                            "However, %s flow was found in the classifier.\n",
-                            found ? "a" : "no");
-                    exit(EXIT_FAILURE);
-                }
-            }
-        }
-        if (operation >= OP_FLOW) {
-            struct test_rule *test_rule;
-
-            CLS_FOR_EACH (test_rule, cr, &cls) {
-                classifier_remove_assert(&cls, &test_rule->cr);
-                ovsrcu_postpone(free_rule, test_rule);
-            }
-            classifier_destroy(&cls);
-            ovsrcu_quiesce();
-
-            expr_matches_destroy(&matches);
-        }
-        expr_destroy(modified);
-    }
-}
-
-#ifndef _WIN32
-static void
-wait_pid(pid_t *pids, int *n)
-{
-    int status;
-    pid_t pid;
-
-    pid = waitpid(-1, &status, 0);
-    if (pid < 0) {
-        ovs_fatal(errno, "waitpid failed");
-    } else if (WIFEXITED(status)) {
-        if (WEXITSTATUS(status)) {
-            exit(WEXITSTATUS(status));
-        }
-    } else if (WIFSIGNALED(status)) {
-        raise(WTERMSIG(status));
-        exit(1);
-    } else {
-        OVS_NOT_REACHED();
-    }
-
-    for (int i = 0; i < *n; i++) {
-        if (pids[i] == pid) {
-            pids[i] = pids[--*n];
-            return;
-        }
-    }
-    ovs_fatal(0, "waitpid returned unknown child");
-}
-#endif
-
-static void
-test_exhaustive(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    int n_terminals = atoi(ctx->argv[1]);
-    struct tree_shape ts[50];
-    int n_tses;
-
-    struct shash symtab;
-    const struct expr_symbol *nvars[4];
-    const struct expr_symbol *svars[4];
-
-    ovs_assert(test_nvars <= ARRAY_SIZE(nvars));
-    ovs_assert(test_svars <= ARRAY_SIZE(svars));
-    ovs_assert(test_nvars + test_svars <= FLOW_N_REGS);
-
-    shash_init(&symtab);
-    for (int i = 0; i < test_nvars; i++) {
-        char *name = xasprintf("n%d", i);
-        nvars[i] = expr_symtab_add_field(&symtab, name, MFF_REG0 + i, NULL,
-                                         false);
-        free(name);
-    }
-    for (int i = 0; i < test_svars; i++) {
-        char *name = xasprintf("s%d", i);
-        svars[i] = expr_symtab_add_string(&symtab, name,
-                                          MFF_REG0 + test_nvars + i, NULL);
-        free(name);
-    }
-
-#ifndef _WIN32
-    pid_t *children = xmalloc(test_parallel * sizeof *children);
-    int n_children = 0;
-#endif
-
-    int n_tested = 0;
-    for (int i = 0; i < 2; i++) {
-        enum expr_type base_type = i ? EXPR_T_OR : EXPR_T_AND;
-
-        for (n_tses = init_tree_shape(ts, n_terminals); n_tses;
-             n_tses = next_tree_shape(ts, n_tses)) {
-            const struct tree_shape *tsp = ts;
-            struct expr *terminals[50];
-            struct expr **terminalp = terminals;
-            struct expr *expr = build_tree_shape(base_type, &tsp, &terminalp);
-            ovs_assert(terminalp == &terminals[n_terminals]);
-
-            if (verbosity > 0) {
-                print_tree_shape(ts, n_tses);
-                printf(": ");
-                struct ds s = DS_EMPTY_INITIALIZER;
-                expr_format(expr, &s);
-                puts(ds_cstr(&s));
-                ds_destroy(&s);
-            }
-
-#ifndef _WIN32
-            if (test_parallel > 1) {
-                pid_t pid = xfork();
-                if (!pid) {
-                    test_tree_shape_exhaustively(expr, &symtab,
-                                                 terminals, n_terminals,
-                                                 nvars, test_nvars, test_bits,
-                                                 svars, test_svars);
-                    expr_destroy(expr);
-                    exit(0);
-                } else {
-                    if (n_children >= test_parallel) {
-                        wait_pid(children, &n_children);
-                    }
-                    children[n_children++] = pid;
-                }
-            } else
-#endif
-            {
-                n_tested += test_tree_shape_exhaustively(
-                    expr, &symtab, terminals, n_terminals,
-                    nvars, test_nvars, test_bits,
-                    svars, test_svars);
-            }
-            expr_destroy(expr);
-        }
-    }
-#ifndef _WIN32
-    while (n_children > 0) {
-        wait_pid(children, &n_children);
-    }
-    free(children);
-#endif
-
-    printf("Tested ");
-    switch (operation) {
-    case OP_CONVERT:
-        printf("converting");
-        break;
-    case OP_SIMPLIFY:
-        printf("simplifying");
-        break;
-    case OP_NORMALIZE:
-        printf("normalizing");
-        break;
-    case OP_FLOW:
-        printf("converting to flows");
-        break;
-    }
-    if (n_tested) {
-        printf(" %d expressions of %d terminals", n_tested, n_terminals);
-    } else {
-        printf(" all %d-terminal expressions", n_terminals);
-    }
-    if (test_nvars || test_svars) {
-        printf(" with");
-        if (test_nvars) {
-            printf(" %d numeric vars (each %d bits) in terms of operators",
-                   test_nvars, test_bits);
-            for (unsigned int relops = test_relops; relops;
-                 relops = zero_rightmost_1bit(relops)) {
-                enum expr_relop r = rightmost_1bit_idx(relops);
-                printf(" %s", expr_relop_to_string(r));
-            }
-        }
-        if (test_nvars && test_svars) {
-            printf (" and");
-        }
-        if (test_svars) {
-            printf(" %d string vars", test_svars);
-        }
-    } else {
-        printf(" in terms of Boolean constants only");
-    }
-    printf(".\n");
-
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-}
-
-static void
-test_expr_to_packets(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    struct shash symtab;
-    struct ds input;
-
-    create_symtab(&symtab);
-
-    ds_init(&input);
-    while (!ds_get_test_line(&input, stdin)) {
-        struct flow uflow;
-        char *error = expr_parse_microflow(ds_cstr(&input), &symtab, NULL,
-                                           NULL, lookup_atoi_cb, NULL, &uflow);
-        if (error) {
-            puts(error);
-            free(error);
-            continue;
-        }
-
-        uint64_t packet_stub[128 / 8];
-        struct dp_packet packet;
-        dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
-        flow_compose(&packet, &uflow, NULL, 64);
-
-        struct ds output = DS_EMPTY_INITIALIZER;
-        const uint8_t *buf = dp_packet_data(&packet);
-        for (int i = 0; i < dp_packet_size(&packet); i++) {
-            uint8_t val = buf[i];
-            ds_put_format(&output, "%02"PRIx8, val);
-        }
-        puts(ds_cstr(&output));
-        ds_destroy(&output);
-
-        dp_packet_uninit(&packet);
-    }
-    ds_destroy(&input);
-
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-}
-
-/* Actions. */
-
-static void
-test_parse_actions(struct ovs_cmdl_context *ctx OVS_UNUSED)
-{
-    struct shash symtab;
-    struct hmap dhcp_opts;
-    struct hmap dhcpv6_opts;
-    struct hmap nd_ra_opts;
-    struct controller_event_options event_opts;
-    struct simap ports;
-    struct ds input;
-    bool ok = true;
-
-    create_symtab(&symtab);
-    create_gen_opts(&dhcp_opts, &dhcpv6_opts, &nd_ra_opts, &event_opts);
-
-    /* Initialize group ids. */
-    struct ovn_extend_table group_table;
-    ovn_extend_table_init(&group_table);
-
-    /* Initialize meter ids for QoS. */
-    struct ovn_extend_table meter_table;
-    ovn_extend_table_init(&meter_table);
-
-    simap_init(&ports);
-    simap_put(&ports, "eth0", 5);
-    simap_put(&ports, "eth1", 6);
-    simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL));
-
-    ds_init(&input);
-    while (!ds_get_test_line(&input, stdin)) {
-        struct ofpbuf ovnacts;
-        struct expr *prereqs;
-        char *error;
-
-        puts(ds_cstr(&input));
-
-        ofpbuf_init(&ovnacts, 0);
-
-        const struct ovnact_parse_params pp = {
-            .symtab = &symtab,
-            .dhcp_opts = &dhcp_opts,
-            .dhcpv6_opts = &dhcpv6_opts,
-            .nd_ra_opts = &nd_ra_opts,
-            .controller_event_opts = &event_opts,
-            .n_tables = 24,
-            .cur_ltable = 10,
-        };
-        error = ovnacts_parse_string(ds_cstr(&input), &pp, &ovnacts, &prereqs);
-        if (!error) {
-            /* Convert the parsed representation back to a string and print it,
-             * if it's different from the input. */
-            struct ds ovnacts_s = DS_EMPTY_INITIALIZER;
-            ovnacts_format(ovnacts.data, ovnacts.size, &ovnacts_s);
-            if (strcmp(ds_cstr(&input), ds_cstr(&ovnacts_s))) {
-                printf("    formats as %s\n", ds_cstr(&ovnacts_s));
-            }
-
-            /* Encode the actions into OpenFlow and print. */
-            const struct ovnact_encode_params ep = {
-                .lookup_port = lookup_port_cb,
-                .aux = &ports,
-                .is_switch = true,
-                .group_table = &group_table,
-                .meter_table = &meter_table,
-
-                .pipeline = OVNACT_P_INGRESS,
-                .ingress_ptable = 8,
-                .egress_ptable = 40,
-                .output_ptable = 64,
-                .mac_bind_ptable = 65,
-            };
-            struct ofpbuf ofpacts;
-            ofpbuf_init(&ofpacts, 0);
-            ovnacts_encode(ovnacts.data, ovnacts.size, &ep, &ofpacts);
-            struct ds ofpacts_s = DS_EMPTY_INITIALIZER;
-            struct ofpact_format_params fp = { .s = &ofpacts_s };
-            ofpacts_format(ofpacts.data, ofpacts.size, &fp);
-            printf("    encodes as %s\n", ds_cstr(&ofpacts_s));
-            ds_destroy(&ofpacts_s);
-            ofpbuf_uninit(&ofpacts);
-
-            /* Print prerequisites if any. */
-            if (prereqs) {
-                struct ds prereqs_s = DS_EMPTY_INITIALIZER;
-                expr_format(prereqs, &prereqs_s);
-                printf("    has prereqs %s\n", ds_cstr(&prereqs_s));
-                ds_destroy(&prereqs_s);
-            }
-
-            /* Now re-parse and re-format the string to verify that it's
-             * round-trippable. */
-            struct ofpbuf ovnacts2;
-            struct expr *prereqs2;
-            ofpbuf_init(&ovnacts2, 0);
-            error = ovnacts_parse_string(ds_cstr(&ovnacts_s), &pp, &ovnacts2,
-                                         &prereqs2);
-            if (!error) {
-                struct ds ovnacts2_s = DS_EMPTY_INITIALIZER;
-                ovnacts_format(ovnacts2.data, ovnacts2.size, &ovnacts2_s);
-                if (strcmp(ds_cstr(&ovnacts_s), ds_cstr(&ovnacts2_s))) {
-                    printf("    bad reformat: %s\n", ds_cstr(&ovnacts2_s));
-                    ok = false;
-                }
-                ds_destroy(&ovnacts2_s);
-            } else {
-                printf("    reparse error: %s\n", error);
-                free(error);
-                ok = false;
-            }
-            expr_destroy(prereqs2);
-
-            ovnacts_free(ovnacts2.data, ovnacts2.size);
-            ofpbuf_uninit(&ovnacts2);
-            ds_destroy(&ovnacts_s);
-        } else {
-            printf("    %s\n", error);
-            free(error);
-        }
-
-        expr_destroy(prereqs);
-        ovnacts_free(ovnacts.data, ovnacts.size);
-        ofpbuf_uninit(&ovnacts);
-    }
-    ds_destroy(&input);
-
-    simap_destroy(&ports);
-    expr_symtab_destroy(&symtab);
-    shash_destroy(&symtab);
-    dhcp_opts_destroy(&dhcp_opts);
-    dhcp_opts_destroy(&dhcpv6_opts);
-    nd_ra_opts_destroy(&nd_ra_opts);
-    controller_event_opts_destroy(&event_opts);
-    ovn_extend_table_destroy(&group_table);
-    ovn_extend_table_destroy(&meter_table);
-    exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
-}
-
-static unsigned int
-parse_relops(const char *s)
-{
-    unsigned int relops = 0;
-    struct lexer lexer;
-
-    lexer_init(&lexer, s);
-    lexer_get(&lexer);
-    do {
-        enum expr_relop relop;
-
-        if (expr_relop_from_token(lexer.token.type, &relop)) {
-            relops |= 1u << relop;
-            lexer_get(&lexer);
-        } else {
-            ovs_fatal(0, "%s: relational operator expected at `%.*s'",
-                      s, (int) (lexer.input - lexer.start), lexer.start);
-        }
-        lexer_match(&lexer, LEX_T_COMMA);
-    } while (lexer.token.type != LEX_T_END);
-    lexer_destroy(&lexer);
-
-    return relops;
-}
-
-static void
-usage(void)
-{
-    printf("\
-%s: OVN test utility\n\
-usage: test-ovn %s [OPTIONS] COMMAND [ARG...]\n\
-\n\
-lex\n\
-  Lexically analyzes OVN input from stdin and print them back on stdout.\n\
-\n\
-parse-expr\n\
-annotate-expr\n\
-simplify-expr\n\
-normalize-expr\n\
-expr-to-flows\n\
-  Parses OVN expressions from stdin and prints them back on stdout after\n\
-  differing degrees of analysis.  Available fields are based on packet\n\
-  headers.\n\
-\n\
-expr-to-packets\n\
-  Parses OVN expressions from stdin and prints out matching packets in\n\
-  hexadecimal on stdout.\n\
-\n\
-evaluate-expr MICROFLOW\n\
-  Parses OVN expressions from stdin and evaluates them against the flow\n\
-  specified in MICROFLOW, which must be an expression that constrains\n\
-  the packet, e.g. \"ip4 && tcp.src == 80\" for a TCP packet with source\n\
-  port 80, and prints the results on stdout, either 1 for true or 0 for\n\
-  false.  Use quoted integers, e.g. \"123\", for string fields.\n\
-\n\
-  Example: for MICROFLOW of \"ip4 && tcp.src == 80\", \"eth.type == 0x800\"\n\
-  evaluates to true, \"udp\" evaluates to false, and \"udp || tcp\"\n\
-  evaluates to true.\n\
-\n\
-composition N\n\
-  Prints all the compositions of N on stdout.\n\
-\n\
-tree-shape N\n\
-  Prints all the tree shapes with N terminals on stdout.\n\
-\n\
-exhaustive N\n\
-  Tests that all possible Boolean expressions with N terminals are properly\n\
-  simplified, normalized, and converted to flows.  Available options:\n\
-   Overall options:\n\
-    --operation=OPERATION  Operation to test, one of: convert, simplify,\n\
-        normalize, flow.  Default: flow.  'normalize' includes 'simplify',\n\
-        'flow' includes 'simplify' and 'normalize'.\n\
-    --parallel=N  Number of processes to use in parallel, default 1.\n\
-   Numeric vars:\n\
-    --nvars=N  Number of numeric vars to test, in range 0...4, default 2.\n\
-    --bits=N  Number of bits per variable, in range 1...3, default 3.\n\
-    --relops=OPERATORS   Test only the specified Boolean operators.\n\
-                         OPERATORS may include == != < <= > >=, space or\n\
-                         comma separated.  Default is all operators.\n\
-   String vars:\n\
-    --svars=N  Number of string vars to test, in range 0...4, default 2.\n\
-\n\
-parse-actions\n\
-  Parses OVN actions from stdin and prints the equivalent OpenFlow actions\n\
-  on stdout.\n\
-",
-           program_name, program_name);
-    exit(EXIT_SUCCESS);
-}
-
-static void
-test_ovn_main(int argc, char *argv[])
-{
-    enum {
-        OPT_RELOPS = UCHAR_MAX + 1,
-        OPT_NVARS,
-        OPT_SVARS,
-        OPT_BITS,
-        OPT_OPERATION,
-        OPT_PARALLEL
-    };
-    static const struct option long_options[] = {
-        {"relops", required_argument, NULL, OPT_RELOPS},
-        {"nvars", required_argument, NULL, OPT_NVARS},
-        {"svars", required_argument, NULL, OPT_SVARS},
-        {"bits", required_argument, NULL, OPT_BITS},
-        {"operation", required_argument, NULL, OPT_OPERATION},
-        {"parallel", required_argument, NULL, OPT_PARALLEL},
-        {"more", no_argument, NULL, 'm'},
-        {"help", no_argument, NULL, 'h'},
-        {NULL, 0, NULL, 0},
-    };
-    char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
-
-    set_program_name(argv[0]);
-
-    test_relops = parse_relops("== != < <= > >=");
-    for (;;) {
-        int option_index = 0;
-        int c = getopt_long (argc, argv, short_options, long_options,
-                             &option_index);
-
-        if (c == -1) {
-            break;
-        }
-        switch (c) {
-        case OPT_RELOPS:
-            test_relops = parse_relops(optarg);
-            break;
-
-        case OPT_NVARS:
-            test_nvars = atoi(optarg);
-            if (test_nvars < 0 || test_nvars > 4) {
-                ovs_fatal(0, "number of numeric variables must be "
-                          "between 0 and 4");
-            }
-            break;
-
-        case OPT_SVARS:
-            test_svars = atoi(optarg);
-            if (test_svars < 0 || test_svars > 4) {
-                ovs_fatal(0, "number of string variables must be "
-                          "between 0 and 4");
-            }
-            break;
-
-        case OPT_BITS:
-            test_bits = atoi(optarg);
-            if (test_bits < 1 || test_bits > 3) {
-                ovs_fatal(0, "number of bits must be between 1 and 3");
-            }
-            break;
-
-        case OPT_OPERATION:
-            if (!strcmp(optarg, "convert")) {
-                operation = OP_CONVERT;
-            } else if (!strcmp(optarg, "simplify")) {
-                operation = OP_SIMPLIFY;
-            } else if (!strcmp(optarg, "normalize")) {
-                operation = OP_NORMALIZE;
-            } else if (!strcmp(optarg, "flow")) {
-                operation = OP_FLOW;
-            } else {
-                ovs_fatal(0, "%s: unknown operation", optarg);
-            }
-            break;
-
-        case OPT_PARALLEL:
-            test_parallel = atoi(optarg);
-            break;
-
-        case 'm':
-            verbosity++;
-            break;
-
-        case 'h':
-            usage();
-            /* fall through */
-
-        case '?':
-            exit(1);
-
-        default:
-            abort();
-        }
-    }
-    free(short_options);
-
-    static const struct ovs_cmdl_command commands[] = {
-        /* Lexer. */
-        {"lex", NULL, 0, 0, test_lex, OVS_RO},
-
-        /* Symbol table. */
-        {"dump-symtab", NULL, 0, 0, test_dump_symtab, OVS_RO},
-
-        /* Expressions. */
-        {"parse-expr", NULL, 0, 0, test_parse_expr, OVS_RO},
-        {"annotate-expr", NULL, 0, 0, test_annotate_expr, OVS_RO},
-        {"simplify-expr", NULL, 0, 0, test_simplify_expr, OVS_RO},
-        {"normalize-expr", NULL, 0, 0, test_normalize_expr, OVS_RO},
-        {"expr-to-flows", NULL, 0, 0, test_expr_to_flows, OVS_RO},
-        {"evaluate-expr", NULL, 1, 1, test_evaluate_expr, OVS_RO},
-        {"composition", NULL, 1, 1, test_composition, OVS_RO},
-        {"tree-shape", NULL, 1, 1, test_tree_shape, OVS_RO},
-        {"exhaustive", NULL, 1, 1, test_exhaustive, OVS_RO},
-        {"expr-to-packets", NULL, 0, 0, test_expr_to_packets, OVS_RO},
-
-        /* Actions. */
-        {"parse-actions", NULL, 0, 0, test_parse_actions, OVS_RO},
-
-        {NULL, NULL, 0, 0, NULL, OVS_RO},
-    };
-    struct ovs_cmdl_context ctx;
-    ctx.argc = argc - optind;
-    ctx.argv = argv + optind;
-    ovs_cmdl_run_command(&ctx, commands);
-}
-
-OVSTEST_REGISTER("test-ovn", test_ovn_main);
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 4d5e816..e759123 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -19,7 +19,6 @@ m4_ifdef([AT_COLOR_TESTS], [AT_COLOR_TESTS])
 m4_include([tests/ovs-macros.at])
 m4_include([tests/ovsdb-macros.at])
 m4_include([tests/ofproto-macros.at])
-m4_include([tests/ovn-macros.at])
 
 m4_include([tests/completion.at])
 m4_include([tests/checkpatch.at])
@@ -74,13 +73,6 @@ m4_include([tests/rstp.at])
 m4_include([tests/vlog.at])
 m4_include([tests/vtep-ctl.at])
 m4_include([tests/auto-attach.at])
-m4_include([tests/ovn.at])
-m4_include([tests/ovn-northd.at])
-m4_include([tests/ovn-nbctl.at])
-m4_include([tests/ovn-sbctl.at])
-m4_include([tests/ovn-controller.at])
-m4_include([tests/ovn-controller-vtep.at])
 m4_include([tests/mcast-snooping.at])
 m4_include([tests/packet-type-aware.at])
 m4_include([tests/nsh.at])
-m4_include([tests/ovn-performance.at])
