[ovs-dev] [RFC PATCH] ovn: Fix ovn check-kmod tests

Gregory Rose gvrose8192 at gmail.com
Sun Sep 8 05:18:29 UTC 2019


On 9/6/2019 12:10 PM, Mark Michelson wrote:
> On 9/5/19 5:30 PM, Gregory Rose wrote:
>>
>> On 9/5/2019 12:00 PM, Numan Siddique wrote:
>>>
>>> [snip]
>>> Hi Greg,
>>>
>>> This seems reasonable to me. Mark has already submitted a patch to 
>>> delete
>>> the OVN folder. But we may have to keep ovn-nbctl/ovn-sbctl utilities
>>> and OVN schema files for ovsdb-server RAFT tests.
>>>
>>> Until that patch is merged, this seems fine to me.
>>
>> I should have a look at Mark's patch - this work probably needs 
>> integration
>> with that.
>
> FYI, I've just submitted a new version of that patch[1]. The version 
> keeps the ovn-nbctl and ovn-sbctl utilities for the ovsdb-clustering 
> tests. However, all other OVN tests have been removed. Like Numan was
> suggesting, this may be a problem that requires fixing in the OVN repo.
>
> [1] http://patchwork.ozlabs.org/patch/1159033/

Yep, I saw that.  There's a lot of overlap between my RFC and your patch 
- I'll review and test your patch
and then integrate with that.  Then we can work from there.

Thanks!

- Greg

>
>>
>>>
>>> Can you please provide the steps you use to run the system tests ?
>>> I will try to run in the new ovn repo and see if we see failures there.
>>> I tried sometime back and all the tests fail for me. Probably I wasn't
>>> running as expected.
>>
>> Build OVS using the '--with-linux=/lib/modules/$(uname -r)/build 
>> --enable-Werror'
>> to get the kernel datapath and then in the directory where you built 
>> OVS run this
>> command:
>>
>> 'sudo make check-kmod'
>>
>> To only run the ovn tests:
>>
>> 'sudo make check-kmod TESTSUITEFLAGS="-k ovn"'
>>
>> Thanks!
>>
>> - Greg
>>
>>>     ---
>>>      tests/automake.mk <http://automake.mk>         | 23 +-
>>>      tests/ovn-controller-vtep.at <http://ovn-controller-vtep.at> |
>>>      467 --
>>>      tests/ovn-controller.at <http://ovn-controller.at>     |   294 -
>>>      tests/ovn-macros.at <http://ovn-macros.at> |   180 -
>>>      tests/ovn-nbctl.at <http://ovn-nbctl.at>        | 1660 -----
>>>      tests/ovn-northd.at <http://ovn-northd.at> |   900 ---
>>>      tests/ovn-performance.at <http://ovn-performance.at>    |   424 --
>>>      tests/ovn-sbctl.at <http://ovn-sbctl.at>        |  150 -
>>>      tests/ovn.at <http://ovn.at>        | 14702
>>>     -----------------------------------------
>>>      tests/system-ovn.at <http://system-ovn.at> |  1667 -----
>>>      tests/test-ovn.c             |  1584 -----
>>>      tests/testsuite.at <http://testsuite.at>        |    8 -
>>>      12 files changed, 4 insertions(+), 22055 deletions(-)
>>>      delete mode 100644 tests/ovn-controller-vtep.at
>>>     <http://ovn-controller-vtep.at>
>>>      delete mode 100644 tests/ovn-controller.at 
>>> <http://ovn-controller.at>
>>>      delete mode 100644 tests/ovn-macros.at <http://ovn-macros.at>
>>>      delete mode 100644 tests/ovn-nbctl.at <http://ovn-nbctl.at>
>>>      delete mode 100644 tests/ovn-northd.at <http://ovn-northd.at>
>>>      delete mode 100644 tests/ovn-performance.at
>>>     <http://ovn-performance.at>
>>>      delete mode 100644 tests/ovn-sbctl.at <http://ovn-sbctl.at>
>>>      delete mode 100644 tests/ovn.at <http://ovn.at>
>>>      delete mode 100644 tests/system-ovn.at <http://system-ovn.at>
>>>      delete mode 100644 tests/test-ovn.c
>>>
>>>     diff --git a/tests/automake.mk <http://automake.mk>
>>>     b/tests/automake.mk <http://automake.mk>
>>>     index d6ab517..decca46 100644
>>>     --- a/tests/automake.mk <http://automake.mk>
>>>     +++ b/tests/automake.mk <http://automake.mk>
>>>     @@ -23,8 +23,7 @@ EXTRA_DIST += \
>>>      COMMON_MACROS_AT = \
>>>             tests/ovsdb-macros.at <http://ovsdb-macros.at> \
>>>             tests/ovs-macros.at <http://ovs-macros.at> \
>>>     -       tests/ofproto-macros.at <http://ofproto-macros.at> \
>>>     -       tests/ovn-macros.at <http://ovn-macros.at>
>>>     +       tests/ofproto-macros.at <http://ofproto-macros.at>
>>>
>>>      TESTSUITE_AT = \
>>>             tests/testsuite.at <http://testsuite.at> \
>>>     @@ -104,16 +103,9 @@ TESTSUITE_AT = \
>>>             tests/vlog.at <http://vlog.at> \
>>>             tests/vtep-ctl.at <http://vtep-ctl.at> \
>>>             tests/auto-attach.at <http://auto-attach.at> \
>>>     -       tests/ovn.at <http://ovn.at> \
>>>     -       tests/ovn-northd.at <http://ovn-northd.at> \
>>>     -       tests/ovn-nbctl.at <http://ovn-nbctl.at> \
>>>     -       tests/ovn-sbctl.at <http://ovn-sbctl.at> \
>>>     -       tests/ovn-controller.at <http://ovn-controller.at> \
>>>     -       tests/ovn-controller-vtep.at 
>>> <http://ovn-controller-vtep.at> \
>>>             tests/mcast-snooping.at <http://mcast-snooping.at> \
>>>             tests/packet-type-aware.at <http://packet-type-aware.at> \
>>>     -       tests/nsh.at <http://nsh.at> \
>>>     -       tests/ovn-performance.at <http://ovn-performance.at>
>>>     +       tests/nsh.at <http://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
>>>     <http://system-userspace-testsuite.at> \
>>>     -       tests/system-ovn.at <http://system-ovn.at> \
>>>             tests/system-userspace-macros.at
>>>     <http://system-userspace-macros.at> \
>>>             tests/system-userspace-packet-type-aware.at
>>>     <http://system-userspace-packet-type-aware.at>
>>>
>>>     @@ -169,7 +160,6 @@ SYSTEM_AFXDP_TESTSUITE_AT = \
>>>
>>>      SYSTEM_TESTSUITE_AT = \
>>>             tests/system-common-macros.at
>>>     <http://system-common-macros.at> \
>>>     -       tests/system-ovn.at <http://system-ovn.at> \
>>>             tests/system-layer3-tunnels.at
>>>     <http://system-layer3-tunnels.at> \
>>>             tests/system-traffic.at <http://system-traffic.at> \
>>>             tests/system-interface.at <http://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
>>>     <http://libopenvswitch.la> ovn/lib/libovn.la <http://libovn.la>
>>>     +tests_ovstest_LDADD = lib/libopenvswitch.la
>>>     <http://libopenvswitch.la>
>>>
>>>      noinst_PROGRAMS += tests/test-stream
>>>      tests_test_stream_SOURCES = tests/test-stream.c
>>>     diff --git a/tests/ovn-controller-vtep.at
>>>     <http://ovn-controller-vtep.at> b/tests/ovn-controller-vtep.at
>>>     <http://ovn-controller-vtep.at>
>>>     deleted file mode 100644
>>>     index a3fe8cb..0000000
>>>     --- a/tests/ovn-controller-vtep.at <http://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 <http://ovn-controller.at>
>>>     b/tests/ovn-controller.at <http://ovn-controller.at>
>>>     deleted file mode 100644
>>>     index 343c2ab..0000000
>>>     --- a/tests/ovn-controller.at <http://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
>>>     <http://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 <http://ovn-macros.at>
>>>     b/tests/ovn-macros.at <http://ovn-macros.at>
>>>     deleted file mode 100644
>>>     index 7dba42c..0000000
>>>     --- a/tests/ovn-macros.at <http://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 <http://ovn-nbctl.at>
>>>     b/tests/ovn-nbctl.at <http://ovn-nbctl.at>
>>>     deleted file mode 100644
>>>     index d99d3af..0000000
>>>     --- a/tests/ovn-nbctl.at <http://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
>>>     <http://30.0.0.2/24> 192.168.1.2], [1], [],
>>>     -[ovn-nbctl: 30.0.0.2/24 <http://30.0.0.2/24>: should be an IPv4
>>>     address.
>>>     -])
>>>     -AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2:80
>>>     <http://30.0.0.2:80> 192.168.1.2], [1], [],
>>>     -[ovn-nbctl: 30.0.0.2:80 <http://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
>>>     <http://192.168.1.2:80>], [1], [],
>>>     -[ovn-nbctl: 192.168.1.2:80 <http://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
>>>     <http://192.168.1.2/a>], [1], [],
>>>     -[ovn-nbctl: 192.168.1.2/a <http://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
>>>     <http://192.168.1.2:80>], [1], [],
>>>     -[ovn-nbctl: 192.168.1.2:80 <http://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
>>>     <http://192.168.1.2/24>], [1], [],
>>>     -[ovn-nbctl: 192.168.1.2/24 <http://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 <http://192.168.1.2/24>], [1], [],
>>>     -[ovn-nbctl: 192.168.1.2/24 <http://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
>>>     <http://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 <http://192.168.1.0/24>
>>>     -])
>>>     -AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.1 192.168.1.0/24
>>>     <http://192.168.1.0/24>], [1], [],
>>>     -[ovn-nbctl: 30.0.0.1, 192.168.1.0/24 <http://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
>>>     <http://192.168.1.10/24>], [1], [],
>>>     -[ovn-nbctl: 30.0.0.1, 192.168.1.0/24 <http://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 <http://192.168.1.0/24>])
>>>     -AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 30.0.0.2 192.168.1.0/24
>>>     <http://192.168.1.0/24>], [1], [],
>>>     -[ovn-nbctl: a NAT with this type (snat) and logical_ip
>>>     (192.168.1.0/24 <http://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 <http://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 <http://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 <http://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 <http://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
>>>     <http://192.168.10.0/24>], [1], [],
>>>     -[ovn-nbctl: no matching NAT with the type (snat) and logical_ip
>>>     (192.168.10.0/24 <http://192.168.10.0/24>)
>>>     -])
>>>     -AT_CHECK([ovn-nbctl --if-exists lr-nat-del lr0 snat
>>>     192.168.10.0/24 <http://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 <http://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 <http://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 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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
>>>     <http://30.0.0.10:80> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20 tcp], [1], [],
>>>     -[ovn-nbctl: 192.168.10.20 <http://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 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://192.168.10.20:80>], [1], [],
>>>     -[ovn-nbctl: 192.168.10.20:80 <http://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 <http://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 <http://30.0.0.10>:
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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
>>>     <http://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 <http://30.0.0.10:80>
>>>     ,,,192.168.10.10:80 <http://192.168.10.10:80>,,,,,])
>>>     -AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 <http://30.0.0.10:80>
>>>     ,,,192.168.10.10:80 <http://192.168.10.10:80>,,,,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>
>>>     -<1>    lb1                 tcp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>])
>>>     -AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 tcp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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
>>>     <http://30.0.0.10:80> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 tcp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080>
>>>     -])
>>>     -
>>>     -AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:80
>>>     <http://30.0.0.10:80> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080>
>>>     -])
>>>     -
>>>     -dnl Config lb1 with another VIP.
>>>     -AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.20:80 <http://30.0.0.20:80>
>>>     192.168.10.10:80 <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080>
>>>     - udp 30.0.0.20:80 <http://30.0.0.20:80> 192.168.10.10:80
>>>     <http://192.168.10.10:80>
>>>     -])
>>>     -
>>>     -AT_CHECK([ovn-nbctl lb-del lb1 30.0.0.20:80 
>>> <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://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
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80> tcp])
>>>     -AT_CHECK([ovn-nbctl --add-duplicate lb-add lb2 30.0.0.10:8080
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080>
>>>     -<2>    lb2                 tcp 30.0.0.10:8080
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80 
>>> <http://192.168.10.20:80>
>>>     -<3>    lb2                 tcp 30.0.0.10:8080
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80 
>>> <http://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
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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
>>>     <http://30.0.0.10:80> 192.168.10.10:8080
>>>     <http://192.168.10.10:8080>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080> udp])
>>>     -AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:8080
>>>     <http://30.0.0.10:8080> 192.168.10.10:8080
>>>     <http://192.168.10.10:8080>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080> udp])
>>>     -AT_CHECK([ovn-nbctl --may-exist lb-add lb1 30.0.0.10:9090
>>>     <http://30.0.0.10:9090> 192.168.10.10:8080
>>>     <http://192.168.10.10:8080>,192.168.10.20:8080
>>>     <http://192.168.10.20:8080> udp])
>>>     -AT_CHECK([ovn-nbctl lb-del lb0 30.0.0.10:80 
>>> <http://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
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80 
>>> <http://192.168.10.20:80>
>>>     -<1>    lb2                 tcp 30.0.0.10:8080
>>>     <http://30.0.0.10:8080> 192.168.10.10:80
>>>     <http://192.168.10.10:80>,192.168.10.20:80 
>>> <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>])
>>>     -AT_CHECK([ovn-nbctl lb-add lb1 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://192.168.10.20:80>
>>>     -<1>    lb1                 udp 30.0.0.10:80 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://30.0.0.10:80>
>>>     192.168.10.10:80 <http://192.168.10.10:80>,192.168.10.20:80
>>>     <http://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 <http://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 <http://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
>>>     <http://192.168.10.10:80>], [1], [],
>>>     -[ovn-nbctl: 192.168.10.10:80 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://192.168.1.1/24>"]]
>>>     -])
>>>     -
>>>     -AT_CHECK([ovn-nbctl lrp-add lr0 lrp0 00:00:00:01:02:03
>>>     192.168.1.1/24 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://192.168.1.1/24>
>>>     10.0.0.1/24 <http://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 <http://192.168.1.1/24>
>>>     172.16.0.1/24 <http://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 <http://10.0.0.1/24> 192.168.1.1/24
>>>     <http://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 <http://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 <http://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 <http://0.0.0.0/0>
>>>     192.168.0.1])
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.1.0/24
>>>     <http://10.0.1.0/24> 11.0.1.1 lp0])
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.1/24
>>>     <http://10.0.0.1/24> 11.0.0.2])
>>>     -
>>>     -dnl Add overlapping route with 10.0.0.1/24 <http://10.0.0.1/24>
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24
>>>     <http://10.0.0.111/24> 11.0.0.1], [1], [],
>>>     -  [ovn-nbctl: duplicate prefix: 10.0.0.0/24 <http://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
>>>     <http://10.0.0.111/24a> 11.0.0.1], [1], [],
>>>     -  [ovn-nbctl: bad prefix argument: 10.0.0.111/24a
>>>     <http://10.0.0.111/24a>
>>>     -])
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24
>>>     <http://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
>>>     <http://10.0.0.111/24> 11.0.0.1/24 <http://11.0.0.1/24>], [1], [],
>>>     -  [ovn-nbctl: bad IPv4 nexthop argument: 11.0.0.1/24
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://10.0.0.0/24> 11.0.0.1 dst-ip
>>>     - 10.0.1.0/24 <http://10.0.1.0/24> 11.0.1.1 dst-ip lp0
>>>     - 9.16.1.0/24 <http://9.16.1.0/24> 11.0.0.1 src-ip
>>>     - 0.0.0.0/0 <http://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
>>>     <http://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 <http://10.0.0.0/24> 11.0.0.1 dst-ip lp1
>>>     - 10.0.1.0/24 <http://10.0.1.0/24> 11.0.1.1 dst-ip lp0
>>>     - 9.16.1.0/24 <http://9.16.1.0/24> 11.0.0.1 src-ip
>>>     - 0.0.0.0/0 <http://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
>>>     <http://10.0.2.1/24>], [1], [],
>>>     -  [ovn-nbctl: no matching prefix: 10.0.2.0/24 <http://10.0.2.0/24>
>>>     -])
>>>     -AT_CHECK([ovn-nbctl --if-exists lr-route-del lr0 10.0.2.1/24
>>>     <http://10.0.2.1/24>])
>>>     -
>>>     -AT_CHECK([ovn-nbctl lr-route-del lr0 10.0.1.1/24
>>>     <http://10.0.1.1/24>])
>>>     -AT_CHECK([ovn-nbctl lr-route-del lr0 9.16.1.0/24
>>>     <http://9.16.1.0/24>])
>>>     -
>>>     -AT_CHECK([ovn-nbctl lr-route-list lr0], [0], [dnl
>>>     -IPv4 Routes
>>>     - 10.0.0.0/24 <http://10.0.0.0/24> 11.0.0.1 dst-ip lp1
>>>     - 0.0.0.0/0 <http://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 <http://0.0.0.0/0>
>>>     192.168.0.1])
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.1.1/24
>>>     <http://10.0.1.1/24> 11.0.1.1 lp0])
>>>     -AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.1/24
>>>     <http://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 <http://10.0.0.0/24> 11.0.0.1 dst-ip
>>>     - 10.0.1.0/24 <http://10.0.1.0/24> 11.0.1.1 dst-ip lp0
>>>     - 0.0.0.0/0 <http://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
>>>     <http://1.1.1.0/24>" drop])
>>>     -AT_CHECK([ovn-nbctl lr-policy-add lr0 100 "ip4.src == 1.1.2.0/24
>>>     <http://1.1.2.0/24>" allow])
>>>     -AT_CHECK([ovn-nbctl lr-policy-add lr0 101 "ip4.src == 2.1.1.0/24
>>>     <http://2.1.1.0/24>" allow])
>>>     -AT_CHECK([ovn-nbctl lr-policy-add lr0 101 "ip4.src == 2.1.2.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://2.1.1.0/24>           allow
>>>     -       101                              ip4.src == 2.1.2.0/24
>>>     <http://2.1.2.0/24>            drop
>>>     -       101                               ip6.src == 2002::/64
>>>             drop
>>>     -       100                              ip4.src == 1.1.2.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://ovn-northd.at>
>>>     b/tests/ovn-northd.at <http://ovn-northd.at>
>>>     deleted file mode 100644
>>>     index 62e58fd..0000000
>>>     --- a/tests/ovn-northd.at <http://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
>>>     <http://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, at 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 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://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 <http://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 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://ovn-performance.at>
>>>     b/tests/ovn-performance.at <http://ovn-performance.at>
>>>     deleted file mode 100644
>>>     index a8a15f8..0000000
>>>     --- a/tests/ovn-performance.at <http://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 <http://ovn-sbctl.at>
>>>     b/tests/ovn-sbctl.at <http://ovn-sbctl.at>
>>>     deleted file mode 100644
>>>     index 650e357..0000000
>>>     --- a/tests/ovn-sbctl.at <http://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 <http://ovn.at> b/tests/ovn.at
>>>     <http://ovn.at>
>>>     deleted file mode 100644
>>>     index cb380d2..0000000
>>>     --- a/tests/ovn.at <http://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
>>>     <http://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 <http://192.168.0.0/16>
>>>     -192.168.0.0/255.255.0.0 <http://192.168.0.0/255.255.0.0> =>
>>>     192.168.0.0/16 <http://192.168.0.0/16>
>>>     -192.168.0.0/255.255.255.0 <http://192.168.0.0/255.255.255.0> =>
>>>     192.168.0.0/24 <http://192.168.0.0/24>
>>>     -192.168.0.0/255.255.0.255 <http://192.168.0.0/255.255.0.255>
>>>     -192.168.0.0/255.0.0.0 <http://192.168.0.0/255.0.0.0> =>
>>>     error("Value contains unmasked 1-bits.")
>>>     -192.168.0.0/32 <http://192.168.0.0/32>
>>>     -192.168.0.0/255.255.255.255 <http://192.168.0.0/255.255.255.255>
>>>     => 192.168.0.0/32 <http://192.168.0.0/32>
>>>     -1.2.3.4:5 <http://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 <http://10.0.0.0/8>, 192.168.0.0/16
>>>     <http://192.168.0.0/16>, 172.16.20.0/24 <http://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 <http://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.
>>>     - at 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
>>>     <http://1.2.0.0/20>, 5.5.5.0/24 <http://5.5.5.0/24>, $set1}'],
>>>     [0], [dnl
>>>     -ip,nw_src=1.2.0.0/20 <http://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 <http://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 <http://1.0.0.0/8>,
>>>     $set4}'], [0], [dnl
>>>     -ip,nw_src=0.0.0.0/1.0.0.0 <http://0.0.0.0/1.0.0.0>
>>>     -ip,nw_src=128.0.0.0/1 <http://128.0.0.0/1>
>>>     -ip,nw_src=16.0.0.0/16.0.0.0 <http://16.0.0.0/16.0.0.0>
>>>     -ip,nw_src=2.0.0.0/2.0.0.0 <http://2.0.0.0/2.0.0.0>
>>>     -ip,nw_src=32.0.0.0/32.0.0.0 <http://32.0.0.0/32.0.0.0>
>>>     -ip,nw_src=4.0.0.0/4.0.0.0 <http://4.0.0.0/4.0.0.0>
>>>     -ip,nw_src=64.0.0.0/64.0.0.0 <http://64.0.0.0/64.0.0.0>
>>>     -ip,nw_src=8.0.0.0/8.0.0.0 <http://8.0.0.0/8.0.0.0>
>>>     -])
>>>     -AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 <http://1.0.0.0/8>
>>>     && ip4.src != {$set4}'], [0], [dnl
>>>     -ip,nw_src=0.0.0.0/1.0.0.0 <http://0.0.0.0/1.0.0.0>
>>>     -ip,nw_src=128.0.0.0/1 <http://128.0.0.0/1>
>>>     -ip,nw_src=16.0.0.0/16.0.0.0 <http://16.0.0.0/16.0.0.0>
>>>     -ip,nw_src=2.0.0.0/2.0.0.0 <http://2.0.0.0/2.0.0.0>
>>>     -ip,nw_src=32.0.0.0/32.0.0.0 <http://32.0.0.0/32.0.0.0>
>>>     -ip,nw_src=4.0.0.0/4.0.0.0 <http://4.0.0.0/4.0.0.0>
>>>     -ip,nw_src=64.0.0.0/64.0.0.0 <http://64.0.0.0/64.0.0.0>
>>>     -ip,nw_src=8.0.0.0/8.0.0.0 <http://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 <http://20.0.0.1>: conjunction(1, 0/2)
>>>     -ip,nw_dst=20.0.0.2 <http://20.0.0.2>: conjunction(1, 0/2)
>>>     -ip,nw_dst=20.0.0.3 <http://20.0.0.3>: conjunction(1, 0/2)
>>>     -ip,nw_src=10.0.0.1 <http://10.0.0.1>: conjunction(1, 1/2)
>>>     -ip,nw_src=10.0.0.2 <http://10.0.0.2>: conjunction(1, 1/2)
>>>     -ip,nw_src=10.0.0.3 <http://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 <http://20.0.0.1>: conjunction(1, 0/2)
>>>     -ip,nw_dst=20.0.0.2 <http://20.0.0.2>: conjunction(1, 0/2)
>>>     -ip,nw_src=10.0.0.1 <http://10.0.0.1>: conjunction(1, 1/2)
>>>     -ip,nw_src=10.0.0.2 <http://10.0.0.2>: conjunction(1, 1/2)
>>>     -ip,nw_src=10.0.0.3 <http://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 <http://20.0.0.1>: conjunction(1, 0/3)
>>>     -tcp,nw_dst=20.0.0.2 <http://20.0.0.2>: conjunction(1, 0/3)
>>>     -tcp,nw_dst=20.0.0.3 <http://20.0.0.3>: conjunction(1, 0/3)
>>>     -tcp,nw_src=10.0.0.1 <http://10.0.0.1>: conjunction(1, 1/3)
>>>     -tcp,nw_src=10.0.0.2 <http://10.0.0.2>: conjunction(1, 1/3)
>>>     -tcp,nw_src=10.0.0.3 <http://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 <http://20.0.0.4>: conjunction(1, 0/4)
>>>     -tcp,nw_dst=20.0.0.7 <http://20.0.0.7>: conjunction(1, 0/4)
>>>     -tcp,nw_dst=20.0.0.8 <http://20.0.0.8>: conjunction(1, 0/4)
>>>     -tcp,nw_src=10.0.0.4 <http://10.0.0.4>: conjunction(1, 1/4)
>>>     -tcp,nw_src=10.0.0.5 <http://10.0.0.5>: conjunction(1, 1/4)
>>>     -tcp,nw_src=10.0.0.6 <http://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 <http://192.168.1.2:80>, 192.168.1.3:80
>>>     <http://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 <http://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 
>>>
>>> <http://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 <http://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 
>>>
>>> <http://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
>>>     <http://30.0.0.0/24>, 10.0.0.4, 40.0.0.0/16 <http://40.0.0.0/16>,
>>>     10.0.0.6, 0.0.0.0/0 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://192.168.0.3/24> >/dev/null || return 1
>>>     -ovs-appctl ovs/route/add 192.168.0.3/24 <http://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 
>>> <http://192.168.11.0/24>
>>>     -#    lrp12 on ls1 for subnet 192.168.12.0/24 
>>> <http://192.168.12.0/24>
>>>     -#    lrp13 on ls1 for subnet 192.168.13.0/24 
>>> <http://192.168.13.0/24>
>>>     -#    ...
>>>     -#    lrp33 on ls3 for subnet 192.168.33.0/24 
>>> <http://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 <http://192.168.1.1/24>
>>>     -#    lrp2 on ls2 for subnet 192.168.2.1/24 <http://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 <http://20.0.0.4/24> 10.0.0.0/24
>>>     <http://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 <http://20.0.0.0/24>
>>>     -# network. R1 has a switchs ls1 (191.168.1.0/24
>>>     <http://191.168.1.0/24>) connected to it.
>>>     -# R2 has ls2 (172.16.1.0/24 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://20.0.0.2/24> peer=R1_R2
>>>     -
>>>     -ovn-nbctl lr-route-add R1 "0.0.0.0/0 <http://0.0.0.0/0>" 20.0.0.2
>>>     -ovn-nbctl lr-route-add R2 "0.0.0.0/0 <http://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 <http://191.168.1.0/24>
>>>     -# and 172.16.1.0/24 <http://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
>>>     <http://192.168.1.1/24> 172.16.1.1/24
>>>     -ovn-nbctl <http://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
>>>     <http://191.168.1.0/24>) connected to it,
>>>     -# and has switch ls2 (172.16.1.0/24 <http://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
>>>     <http://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
>>>     <http://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 <http://20.0.0.0/24>
>>>     -# network. R1 has switchess foo (192.168.1.0/24
>>>     <http://192.168.1.0/24>)
>>>     -# connected to it.
>>>     -# R2 has alice (172.16.1.0/24 <http://172.16.1.0/24>) and bob
>>>     (172.16.2.0/24 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://20.0.0.2/24> peer=R1_R2
>>>     -
>>>     -#install static routes
>>>     -ovn-nbctl lr-route-add R1 172.16.1.0/24 <http://172.16.1.0/24>
>>>     20.0.0.2
>>>     -ovn-nbctl lr-route-add R2 172.16.2.0/24 <http://172.16.2.0/24>
>>>     20.0.0.2 R1_R2
>>>     -ovn-nbctl lr-route-add R2 192.168.1.0/24 <http://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 <http://20.0.0.0/24> network. R1 has switchess
>>>     foo (192.168.1.0/24 <http://192.168.1.0/24>)
>>>     -# connected to it. R2 has alice (172.16.1.0/24
>>>     <http://172.16.1.0/24>) and R3 has bob (10.32.1.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://172.16.1.0/24>
>>>     20.0.0.2
>>>     -ovn-nbctl lr-route-add R1 10.32.1.0/24 <http://10.32.1.0/24> 
>>> 20.0.0.3
>>>     -
>>>     -ovn-nbctl lr-route-add R2 192.168.1.0/24 <http://192.168.1.0/24>
>>>     20.0.0.1
>>>     -ovn-nbctl lr-route-add R2 10.32.1.0/24 <http://10.32.1.0/24> 
>>> 20.0.0.3
>>>     -
>>>     -ovn-nbctl lr-route-add R3 192.168.1.0/24 <http://192.168.1.0/24>
>>>     20.0.0.1
>>>     -ovn-nbctl lr-route-add R3 172.16.1.0/24 <http://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
>>>     <http://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
>>>     <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://20.0.0.0/24> network. R1 has switchess
>>>     foo (192.168.1.0/24 <http://192.168.1.0/24>)
>>>     -# connected to it. R2 has alice (172.16.1.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://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 <http://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
>>>     <http://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
>>>     <http://20.0.0.2/24>
>>>     -
>>>     -ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
>>>     -ip_prefix=192.168.1.0/24 <http://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
>>>     <http://191.168.1.0/24>) connected to it,
>>>     -# and has switch ls2 (172.16.1.0/24 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://191.168.1.0/24>) connected to it,
>>>     -# and has switch ls2 (172.16.1.0/24 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://192.168.1.0/24> && ip4.dst==172.16.1.0/24
>>>     <http://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
>>>     <http://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 <http://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
>>>     <http://192.168.1.0/24> && ip4.dst==172.16.1.0/24
>>>     <http://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
>>>     <http://192.168.1.0/24> && ip4.dst==172.16.1.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://191.168.1.0/24>) connected to it,
>>>     -# and has switch ls2 (172.16.1.0/24 <http://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 <http://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 <http://192.168.1.0/24-AT_CHECK(%5Bovn-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 <http://192.168.1.0/24-AT_CHECK(%5Bovn-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 <http://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 <http://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 <http://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
>>>     <http://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 <http://192.168.1.0/24-AT_CHECK(%5Bovn-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 <http://192.168.1.0/24-AT_CHECK(%5Bovn-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 <http://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 <http://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 <http://192.168.1.0/24-ovn-nbctl> ls-add alice -- add
>>>     Logical_Switch alice other_config subnet=192.168.2.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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 <http://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 <http://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 <http://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 <http://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 <http://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 <http://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
>>>     <http://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 <http://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
>>>     <http://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
>>>     <http://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
>>>     <http://192.168.0.3:80> 10.0.0.2:80
>>>     <http://10.0.0.2:80>,10.0.0.3:80 <http://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
>>>     <http://192.168.0.3:8080> 10.0.0.2:8080
>>>     <http://10.0.0.2:8080>,10.0.0.3:8080 <http://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 <http://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
>>>     <http://192.168.1.0/24>) and "bar" (172.16.1.0/24
>>>     <http://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
>>>     <http://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
>>>     <http://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-