[ovs-dev] [PATCH ovn 16/16] tests: Miscellaneous improvements.

Ben Pfaff blp at ovn.org
Fri Oct 30 00:24:47 UTC 2020


- Add "check" to a lot of commands, to ensure that they succeed.

- Dump flows to files instead of to stdout, to make them easier to
  compare between different runs.

- Compare all the packets that should be sent for a given run, rather
  than just comparing them for a single interface.  This gives a better
  overview on failure (did everything fail? or just one packet for a
  given interface?)

- Better comments and log messages.

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 tests/ovn-northd.at |  284 +++---
 tests/ovn.at        | 2308 ++++++++++++++++++++++++-------------------
 2 files changed, 1425 insertions(+), 1167 deletions(-)

diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 7ceefe04572a..ae845e4eafd4 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -280,22 +280,22 @@ AT_CLEANUP
 AT_SETUP([ovn -- check HA_Chassis_Group propagation from NBDB to SBDB])
 ovn_start
 
-ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
+check 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.
 check_row_count HA_Chassis_Group 0 name=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
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 30
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch2 20
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch3 10
 
 # There should be no HA_Chassis rows in SB DB.
 check_row_count HA_Chassis 0
 
 # Add chassis ch1.
-ovn-sbctl chassis-add ch1 geneve 127.0.0.2
+check ovn-sbctl chassis-add ch1 geneve 127.0.0.2
 
 wait_row_count Chassis 1 name=ch1
 
@@ -303,16 +303,21 @@ wait_row_count Chassis 1 name=ch1
 check_row_count HA_Chassis 0
 
 # Create a logical router port and attach ha chassis group.
-ovn-nbctl lr-add lr0
+check ovn-nbctl lr-add lr0
 check ovn-nbctl --wait=sb lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
 
 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
+echo "hagrp1_uuid=$hagrp1_uuid"
 check ovn-nbctl --wait=sb set logical_router_port lr0-public ha_chassis_group=$hagrp1_uuid
 
 wait_row_count HA_Chassis_Group 1 name=hagrp1
 
 check_row_count HA_Chassis 3
 
+# ovn-northd has a weird history regarding HA_Chassis and missing
+# Chassis records, see commit f879850b5f2c ("ovn-northd: Fix the
+# HA_Chassis sync issue in OVN SB DB").
+#
 # Make sure that ovn-northd doesn't recreate the ha_chassis
 # records if the chassis record is missing in SB DB.
 ha_ch_list=$(fetch_column HA_Chassis _uuid)
@@ -326,10 +331,10 @@ check_row_count HA_Chassis 2 'chassis=[[]]'
 check_row_count HA_Chassis 1 'chassis!=[[]]'
 
 # 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
+check ovn-nbctl lr-add lr1
+check ovn-nbctl lrp-add lr1 lr1-public 00:00:20:20:12:14 182.168.0.100/24
 
-ovn-nbctl set logical_router_port lr1-public ha_chassis_group=$hagrp1_uuid
+check 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.
 wait_row_count HA_Chassis_Group 1 name=hagrp1
@@ -397,18 +402,18 @@ wait_row_count HA_Chassis 2
 
 # Test if 'ref_chassis' column is properly set or not in
 # SB DB ha_chassis_group.
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-p1
-
-ovn-sbctl chassis-add ch2 geneve 127.0.0.3
-ovn-sbctl chassis-add ch3 geneve 127.0.0.4
-ovn-sbctl chassis-add comp1 geneve 127.0.0.5
-ovn-sbctl chassis-add comp2 geneve 127.0.0.6
-
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:20:20:12:14 10.0.0.1/24
-ovn-nbctl lsp-add sw0 sw0-lr0
-ovn-nbctl lsp-set-type sw0-lr0 router
-ovn-nbctl lsp-set-addresses sw0-lr0 router
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-p1
+
+check ovn-sbctl chassis-add ch2 geneve 127.0.0.3
+check ovn-sbctl chassis-add ch3 geneve 127.0.0.4
+check ovn-sbctl chassis-add comp1 geneve 127.0.0.5
+check ovn-sbctl chassis-add comp2 geneve 127.0.0.6
+
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:20:20:12:14 10.0.0.1/24
+check ovn-nbctl lsp-add sw0 sw0-lr0
+check ovn-nbctl lsp-set-type sw0-lr0 router
+check ovn-nbctl lsp-set-addresses sw0-lr0 router
 check ovn-nbctl --wait=sb lsp-set-options sw0-lr0 router-port=lr0-sw0
 
 ovn-sbctl lsp-bind sw0-p1 comp1
@@ -418,6 +423,7 @@ comp1_ch_uuid=$(fetch_column Chassis _uuid name=comp1)
 comp2_ch_uuid=$(fetch_column Chassis _uuid name=comp2)
 ch2_ch_uuid=$comp1_ch_uuid
 
+# Check ref_chassis.
 echo "comp1_ch_uuid = $comp1_ch_uuid"
 wait_column "$comp1_ch_uuid" HA_Chassis_Group ref_chassis
 
@@ -440,7 +446,7 @@ ovn-nbctl lsp-set-addresses sw1-lr1 router
 check ovn-nbctl --wait=sb lsp-set-options sw1-lr1 router-port=lr1-sw1
 
 # Bind sw1-p1 in comp1.
-ovn-sbctl lsp-bind sw1-p1 comp1
+check ovn-sbctl lsp-bind sw1-p1 comp1
 # Wait until sw1-p1 is up
 wait_row_count nb:Logical_Switch_Port 1 name=sw1-p1 up=true
 
@@ -448,10 +454,10 @@ wait_row_count nb:Logical_Switch_Port 1 name=sw1-p1 up=true
 wait_column "$comp2_ch_uuid" HA_Chassis_Group ref_chassis
 
 # Now attach sw0 to lr1
-ovn-nbctl lrp-add lr1 lr1-sw0 00:00:20:20:12:16 10.0.0.10/24
-ovn-nbctl lsp-add sw0 sw0-lr1
-ovn-nbctl lsp-set-type sw0-lr1 router
-ovn-nbctl lsp-set-addresses sw0-lr1 router
+check ovn-nbctl lrp-add lr1 lr1-sw0 00:00:20:20:12:16 10.0.0.10/24
+check ovn-nbctl lsp-add sw0 sw0-lr1
+check ovn-nbctl lsp-set-type sw0-lr1 router
+check ovn-nbctl lsp-set-addresses sw0-lr1 router
 check ovn-nbctl --wait=sb lsp-set-options sw0-lr1 router-port=lr1-sw0
 
 # Both comp1 and comp2 should be in 'ref_chassis' as sw1 is indirectly
@@ -466,17 +472,17 @@ wait_row_count nb:Logical_Switch_Port 1 name=sw1-p1 up=false
 wait_column "$comp2_ch_uuid" HA_Chassis_Group ref_chassis
 
 # Create sw2 and attach it to lr2
-ovn-nbctl ls-add sw2
-ovn-nbctl lsp-add sw2 sw2-p1
-ovn-nbctl lr-add lr2
-ovn-nbctl lrp-add lr2 lr2-sw2 00:00:20:20:12:17 30.0.0.1/24
-ovn-nbctl lsp-add sw2 sw2-lr2
-ovn-nbctl lsp-set-type sw2-lr2 router
-ovn-nbctl lsp-set-addresses sw2-lr2 router
+check ovn-nbctl ls-add sw2
+check ovn-nbctl lsp-add sw2 sw2-p1
+check ovn-nbctl lr-add lr2
+check ovn-nbctl lrp-add lr2 lr2-sw2 00:00:20:20:12:17 30.0.0.1/24
+check ovn-nbctl lsp-add sw2 sw2-lr2
+check ovn-nbctl lsp-set-type sw2-lr2 router
+check ovn-nbctl lsp-set-addresses sw2-lr2 router
 check ovn-nbctl --wait=sb lsp-set-options sw2-lr2 router-port=lr2-sw2
 
 # Bind sw2-p1 to comp1
-ovn-sbctl lsp-bind sw2-p1 comp1
+check ovn-sbctl lsp-bind sw2-p1 comp1
 # Wait until sw2-p1 is up
 wait_row_count nb:Logical_Switch_Port 1 name=sw2-p1 up=true
 
@@ -484,10 +490,10 @@ wait_row_count nb:Logical_Switch_Port 1 name=sw2-p1 up=true
 wait_column "$comp2_ch_uuid" HA_Chassis_Group ref_chassis
 
 # Now attach sw1 to lr2. With this sw2-p1 is indirectly connected to lr0.
-ovn-nbctl lrp-add lr2 lr2-sw1 00:00:20:20:12:18 20.0.0.10/24
-ovn-nbctl lsp-add sw1 sw1-lr2
-ovn-nbctl lsp-set-type sw1-lr2 router
-ovn-nbctl lsp-set-addresses sw1-lr2 router
+check ovn-nbctl lrp-add lr2 lr2-sw1 00:00:20:20:12:18 20.0.0.10/24
+check ovn-nbctl lsp-add sw1 sw1-lr2
+check ovn-nbctl lsp-set-type sw1-lr2 router
+check ovn-nbctl lsp-set-addresses sw1-lr2 router
 check ovn-nbctl --wait=sb lsp-set-options sw1-lr2 router-port=lr2-sw1
 
 # sw2-p1 is indirectly connected to lr0. So comp1 (and comp2) should be in
@@ -507,13 +513,13 @@ wait_column "$exp_ref_ch_list" HA_Chassis_Group ref_chassis
 
 # 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
+check ovn-nbctl lrp-del lr1-sw0
 
 wait_column "$comp2_ch_uuid" HA_Chassis_Group ref_chassis
 
 # Set redirect-chassis option to lr0-public. It should be ignored
 # (because redirect-chassis is obsolete).
-ovn-nbctl set logical_router_port lr0-public options:redirect-chassis=ch1
+check ovn-nbctl set logical_router_port lr0-public options:redirect-chassis=ch1
 
 wait_row_count HA_Chassis_Group 1
 wait_row_count HA_Chassis_Group 1 name=lr0-public
@@ -521,29 +527,29 @@ wait_row_count HA_Chassis_Group 1 name=lr0-public
 wait_row_count HA_Chassis 2
 
 # Delete the gateway chassis.
-ovn-nbctl clear logical_router_port lr0-public gateway_chassis
+check ovn-nbctl clear logical_router_port lr0-public gateway_chassis
 
 wait_row_count HA_Chassis_Group 0
 check_row_count HA_Chassis 0
 
 # Delete old sw0.
-ovn-nbctl ls-del sw0
+check ovn-nbctl --wait=sb 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
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-pext1
+check ovn-nbctl lsp-add sw0 sw0-pext2
+check 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"
+check ovn-nbctl lsp-set-addresses sw0-pext1 "00:00:00:00:00:03 10.0.0.3"
+check ovn-nbctl lsp-set-addresses sw0-pext2 "00:00:00:00:00:03 10.0.0.4"
+check ovn-nbctl lsp-set-addresses sw0-p1 "00:00:00:00:00:03 10.0.0.5"
 
 check 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
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch1 30
+check ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 ch2 20
+check 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
@@ -712,78 +718,45 @@ ovn-nbctl lsp-set-options S1-R1 router-port=R1-S1
 
 check ovn-nbctl --wait=sb lrp-set-gateway-chassis R1-S1 gw1
 
-# IPV4
-ovn-nbctl lr-nat-add R1 dnat_and_snat  172.16.1.1 50.0.0.11
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [2
-])
+check_flow_matches() {
+    local regex=$1 count=$2
+    local found=$(grep -c "$1" r1-flows)
+    echo "checking for $count flows matching $regex... found $found"
+    AT_FAIL_IF([test $found != $count])
+}
 
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [2
-])
+check_flow_match_sets() {
+    ovn-sbctl dump-flows R1 > r1-flows
+    AT_CAPTURE_FILE([r1-flows])
 
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [0
-])
+    for regex in lr_in_unsnat ct_snat ct_dnat ip4.dst= ip4.src= ip6.dst= ip6.src=; do
+        check_flow_matches $regex $1
+        shift
+    done
+}
 
+echo
+echo "IPv4: stateful"
+ovn-nbctl --wait=sb lr-nat-add R1 dnat_and_snat  172.16.1.1 50.0.0.11
+check_flow_match_sets 2 2 2 0 0 0 0
 ovn-nbctl lr-nat-del R1 dnat_and_snat  172.16.1.1
 
-ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat  172.16.1.1 50.0.0.11
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.dst=| wc -l], [0], [2
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip4.src=| wc -l], [0], [2
-])
+echo
+echo "IPv4: stateless"
+ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat  172.16.1.1 50.0.0.11
+check_flow_match_sets 2 0 0 2 2 0 0
 ovn-nbctl lr-nat-del R1 dnat_and_snat  172.16.1.1
 
-# IPV6
-ovn-nbctl lr-nat-add R1 dnat_and_snat fd01::1 fd11::2
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [2
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [2
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.dst=| wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.src=| wc -l], [0], [0
-])
-
+echo
+echo "IPv6: stateful"
+ovn-nbctl --wait=sb lr-nat-add R1 dnat_and_snat fd01::1 fd11::2
+check_flow_match_sets 2 2 2 0 0 0 0
 ovn-nbctl lr-nat-del R1 dnat_and_snat  fd01::1
-ovn-nbctl --stateless lr-nat-add R1 dnat_and_snat fd01::1 fd11::2
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
 
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.dst=| wc -l], [0], [2
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ip6.src=| wc -l], [0], [2
-])
+echo
+echo "IPv6: stateless"
+ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat fd01::1 fd11::2
+check_flow_match_sets 2 0 0 0 0 2 2
 
 AT_CLEANUP
 
@@ -809,43 +782,29 @@ echo "CR-LRP UUID is: " $uuid
 # IPV4
 ovn-nbctl --portrange lr-nat-add R1 dnat_and_snat  172.16.1.1 50.0.0.11 1-3000
 
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | grep 3000 | wc -l], [0], [1
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | grep 3000 | wc -l], [0], [1
+AT_CAPTURE_FILE([sbflows])
+OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows && test 2 = `grep -c lr_in_unsnat sbflows`])
+AT_CHECK([grep -c 'ct_snat.*3000' sbflows && grep -c 'ct_dnat.*3000' sbflows],
+  [0], [1
+1
 ])
 
-
 ovn-nbctl lr-nat-del R1 dnat_and_snat  172.16.1.1
+ovn-nbctl --wait=sb --portrange lr-nat-add R1 snat  172.16.1.1 50.0.0.11 1-3000
 
-ovn-nbctl --portrange lr-nat-add R1 snat  172.16.1.1 50.0.0.11 1-3000
-
-OVS_WAIT_UNTIL([test 2 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | grep 3000 | wc -l], [0], [1
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | grep 3000 | wc -l], [0], [0
+AT_CAPTURE_FILE([sbflows2])
+OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows2 && test 2 = `grep -c lr_in_unsnat sbflows`])
+AT_CHECK([grep -c 'ct_snat.*3000' sbflows2 && grep -c 'ct_dnat.*3000' sbflows2],
+  [1], [1
+0
 ])
 
 ovn-nbctl lr-nat-del R1 snat  172.16.1.1
+ovn-nbctl --wait=sb --portrange --stateless lr-nat-add R1 dnat_and_snat  172.16.1.2 50.0.0.12 1-3000
 
-ovn-nbctl --portrange --stateless lr-nat-add R1 dnat_and_snat  172.16.1.2 50.0.0.12 1-3000
-ovn-sbctl dump-flows R1
-
-OVS_WAIT_UNTIL([test 3 = `ovn-sbctl dump-flows R1 | grep lr_in_unsnat | \
-wc -l`])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_snat | grep 3000 | grep 172.16.1.2 | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows R1 | grep ct_dnat | grep 3000 | grep 172.16.1.2 | wc -l], [0], [0
-])
-
+AT_CAPTURE_FILE([sbflows3])
+OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 > sbflows3 && test 3 = `grep -c lr_in_unsnat sbflows3`])
+AT_CHECK([grep 'ct_[s]dnat.*172\.16\.1\.2.*3000' sbflows3], [1])
 
 ovn-nbctl lr-nat-del R1 dnat_and_snat  172.16.1.1
 
@@ -1289,16 +1248,19 @@ ovn-nbctl lr-nat-add lr0 snat 192.168.2.1 10.0.0.0/24
 ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.2.4 10.0.0.4
 check ovn-nbctl --wait=sb lr-nat-add lr0 dnat 192.168.2.5 10.0.0.5
 
-OVS_WAIT_UNTIL([test 1 = $(ovn-sbctl dump-flows lr0 | grep lr_in_unsnat | \
+ovn-sbctl dump-flows lr0 > sbflows
+AT_CAPTURE_FILE([sbflows])
+
+OVS_WAIT_UNTIL([test 1 = $(grep lr_in_unsnat sbflows | \
 grep "ip4 && ip4.dst == 192.168.2.1 && tcp && tcp.dst == 8080" -c) ])
 
-AT_CHECK([test 1 = $(ovn-sbctl dump-flows lr0 | grep lr_in_unsnat | \
+AT_CHECK([test 1 = $(grep lr_in_unsnat sbflows | \
 grep "ip4 && ip4.dst == 192.168.2.4 && udp && udp.dst == 8080" -c) ])
 
-AT_CHECK([test 1 = $(ovn-sbctl dump-flows lr0 | grep lr_in_unsnat | \
+AT_CHECK([test 1 = $(grep lr_in_unsnat sbflows | \
 grep "ip4 && ip4.dst == 192.168.2.5 && tcp && tcp.dst == 8080" -c) ])
 
-AT_CHECK([test 0 = $(ovn-sbctl dump-flows lr0 | grep lr_in_unsnat | \
+AT_CHECK([test 0 = $(grep lr_in_unsnat sbflows | \
 grep "ip4 && ip4.dst == 192.168.2.6 && tcp && tcp.dst == 8080" -c) ])
 
 AT_CLEANUP
@@ -1325,24 +1287,26 @@ AT_CLEANUP
 AT_SETUP([ovn -- check reconcile stale Datapath_Binding])
 ovn_start
 
-ovn-nbctl lr-add lr
-ovn-nbctl lrp-add lr p 00:00:00:00:00:01 1.1.1.1/24
-
-AT_CHECK([ovn-nbctl --wait=sb sync], [0])
+check ovn-nbctl lr-add lr
+check ovn-nbctl lrp-add lr p 00:00:00:00:00:01 1.1.1.1/24
+check ovn-nbctl --wait=sb sync
 
 # Create a MAC_Binding referring the router datapath.
-dp=$(ovn-sbctl --bare --columns _uuid list datapath .)
-ovn-sbctl create mac_binding logical_port="p" ip="1.1.1.2" datapath="$dp"
+AT_CHECK([ovn-sbctl --id=@dp get datapath . -- create mac_binding logical_port=p ip=1.1.1.2 datapath=@dp | uuidfilt], [0], [<0>
+])
 
-ovn-nbctl lrp-del p -- lr-del lr -- \
-    lr-add lr -- lrp-add lr p 00:00:00:00:00:01 1.1.1.1/24
-AT_CHECK([ovn-nbctl --wait=sb sync], [0])
+check ovn-nbctl --wait=sb \
+             -- lrp-del p \
+             -- lr-del lr \
+             -- lr-add lr \
+             -- lrp-add lr p 00:00:00:00:00:01 1.1.1.1/24
 
-AT_CHECK([test 1 = $(ovn-sbctl --columns _uuid list Datapath_Binding | wc -l)])
+check_row_count Datapath_Binding 1
 
 nb_uuid=$(ovn-sbctl get Datapath_Binding . external_ids:logical-router)
-lr_uuid=$(ovn-nbctl --columns _uuid list Logical_Router .)
-AT_CHECK[test ${nb_uuid} = ${lr_uuid}]
+lr_uuid=\"$(ovn-nbctl get Logical_Router . _uuid)\"
+echo nb_uuid="$nb_uuid" lr_uuid="$lr_uuid"
+AT_CHECK([test "${nb_uuid}" = "${lr_uuid}"])
 
 AT_CLEANUP
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 245a6feb202b..de776bb11b8c 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -2002,19 +2002,8 @@ tip=`ip_to_hex 192 169 0 13`
 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
+ovn-sbctl dump-flows -- list multicast_group > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 # Now check the packets actually received against the ones expected.
 for i in 1 2 3; do
@@ -2216,6 +2205,8 @@ ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:0
 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
 
 ovn-nbctl --wait=sb sync
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 on_exit 'kill `cat ovn-trace.pid`'
 ovn-trace --detach --pidfile --no-chdir
 
@@ -2486,7 +2477,8 @@ for i in 1 2; do
     done
 done
 ovn-nbctl --wait=sb sync
-ovn-sbctl dump-flows
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 OVN_POPULATE_ARP
 
@@ -2651,12 +2643,14 @@ done
 
 
 ovn-nbctl --wait=sb sync
-ovn-nbctl show
-ovn-sbctl dump-flows
 
-echo "------ OVN dump ------"
-ovn-nbctl show
-ovn-sbctl show
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
+ovn-nbctl show > nbctl-show
+AT_CAPTURE_FILE([nbctl-show])
+ovn-sbctl show > sbctl-show
+AT_CAPTURE_FILE([sbctl-show])
 
 for i in 1 2; do
     hv=hv-$i
@@ -2783,7 +2777,8 @@ done
 
 ovn-nbctl --wait=sb sync
 ovn-nbctl show
-ovn-sbctl dump-flows
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 echo "------ OVN dump ------"
 ovn-nbctl show
@@ -2919,7 +2914,8 @@ done
 
 ovn-nbctl --wait=sb sync
 ovn-nbctl show
-ovn-sbctl dump-flows
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 # vif ports
 for i in 1 2; do
@@ -3608,11 +3604,12 @@ test_ip() {
 # SHA and REPLY_HA are each 12 hex digits.
 # SPA and TPA are each 8 hex digits.
 test_arp() {
+    echo "$@"
     local inport=$1 sha=$2 spa=$3 tpa=$4 flood=$5 reply_ha=$6
     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
+    as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request > trace
 
     # Expect to receive the broadcast ARP on the other logical switch ports if
     # IP address is not configured on the switch patch port or on the router
@@ -3640,11 +3637,15 @@ test_arp() {
     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
+as hv1 ovs-vsctl --columns=name,ofport list interface > interfaces
+(as hv1 ovn-sbctl list port_binding
+ as hv1 ovn-sbctl list datapath_binding) > bindings
+as hv1 ovn-sbctl dump-flows > sbflows
+as hv1 ovs-ofctl dump-flows br-int > offlows
+AT_CAPTURE_FILE([interfaces])
+AT_CAPTURE_FILE([bindings])
+AT_CAPTURE_FILE([sbflows])
+AT_CAPTURE_FILE([offlows])
 
 # Send IP packets between all pairs of source and destination ports:
 #
@@ -3668,15 +3669,16 @@ for is in 1 2 3; do
                 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
+                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
+      test_ip $s $smac ffffffffffff $sip ffffffff $bcast & #2
       done
   done
+  wait
 done
 
 : > mac_bindings.expected
@@ -3837,22 +3839,34 @@ for is in 1 2 3; do
   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])
+ovn-sbctl dump-flows > sbflows2
+AT_CAPTURE_FILE([sbflows2])
+
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+check_packets() {
+    > expected
+    > received
+    for i in 1 2 3; do
+        for j in 1 2 3; do
+            for k in 1 2 3; do
+                pcap=hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap
+                echo "--- $pcap" | tee -a expected >> received
+                sort $i$j$k.expected >> expected
+                $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | sort >> received
+                echo | tee -a expected >> received
+            done
         done
     done
-done
 
-# Check the MAC bindings against those expected.
-AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
-])
+    echo '--- MAC bindings' | tee -a expected >> received
+    ovn-sbctl -f csv -d bare --no-heading \
+        -- --columns=logical_port,ip,mac list mac_binding | sort >> received
+    sort < mac_bindings.expected >> expected
+
+    $at_diff expected received >/dev/null
+}
+OVS_WAIT_UNTIL([check_packets], [$at_diff -F'^---' expected received])
 
 # Gracefully terminate daemons
 OVN_CLEANUP([hv1], [hv2], [hv3])
@@ -5271,6 +5285,8 @@ check ovs-vsctl -- add-port br-int hv1-vif4 -- \
     options:rxq_pcap=hv1/vif4-rx.pcap \
     ofport-request=4
 
+as hv1 ovs-appctl vlog/set dbg
+
 OVN_POPULATE_ARP
 
 sleep 2
@@ -5279,7 +5295,19 @@ as hv1 ovs-vsctl show
 
 # This shell function sends a DHCP request packet
 # test_dhcp INPORT SRC_MAC DHCP_TYPE BROADCAST CIADDR OFFER_IP REQUEST_IP ETH_BOOT USE_IP ...
+packet_num=0
 test_dhcp() {
+    local expect_resume=:
+    local trace=false
+    while :; do
+        case $1 in 
+            (--no-resume) expect_resume=false; shift ;;
+            # --trace isn't used but it can be useful for debugging:
+            (--trace) trace=:; shift ;;
+            (*) break ;;
+        esac
+    done
+
     local inport=$1 src_mac=$2 dhcp_type=$3 broadcast=$4 ciaddr=$5 offer_ip=$6 request_ip=$7 eth_boot=$8 use_ip=$9
     shift; shift; shift; shift; shift; shift; shift; shift; shift;
 
@@ -5291,6 +5319,19 @@ test_dhcp() {
         src_ip=`ip_to_hex 0 0 0 0`
         dst_ip=`ip_to_hex 255 255 255 255`
     fi
+    packet_num=$(expr $packet_num + 1)
+
+    AS_BOX([dhcp test packet $packet_num])
+
+    as hv1
+    if test -f hv1/ovs-ofctl.pid; then
+        OVS_APP_EXIT_AND_WAIT([ovs-ofctl])
+        AT_FAIL_IF([test -f ovs-ofctl.pid])
+    fi
+    AT_CAPTURE_FILE([ofctl_monitor$packet_num.log])
+    ovs-ofctl monitor br-int resume --detach --no-chdir \
+        --pidfile=ovs-ofctl.pid 2> ofctl_monitor$packet_num.log
+
     echo "inport=$inport src_mac=$src_mac dhcp_type=$dhcp_type broadcast=$broadcast ciaddr=$ciaddr offer_ip=$offer_ip request_ip=$request_ip use_ip=$use_ip src_ip=$src_ip dst_ip=$dst_ip"
 
     if test $request_ip != 0; then
@@ -5354,6 +5395,7 @@ test_dhcp() {
     fi
     # dhcp end option
     request=${request}ff
+    tcpdump_hex "-- sending DHCP request on hv1-vif$inport" $request
 
     for port in $inport "$@"; do
         : >> $port.expected
@@ -5399,12 +5441,23 @@ test_dhcp() {
         reply=${reply}63825363
         reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
         echo $reply >> $inport.expected
+        tcpdump_hex "-- expecting DHCP reply on $inport" $request
     else
         for outport; do
             echo $request >> $outport.expected
         done
     fi
-    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
+    if $trace; then
+        as hv1 ovs-appctl ofproto/trace br-int in_port=hv1-vif$inport $request > trace$packet_num
+        AT_CAPTURE_FILE([trace$packet_num])
+    else
+        check as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
+    fi
+
+    # NXT_RESUMEs should be 1.
+    if $expect_resume; then
+        OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor$packet_num.log | grep -c NXT_RESUME`])
+    fi
 }
 
 reset_pcap_file() {
@@ -5417,13 +5470,11 @@ options:rxq_pcap=dummy-rx.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
-
 AT_CAPTURE_FILE([sbflows])
 ovn-sbctl dump-flows > sbflows
 
+# ----------------------------------------------------------------------
+
 # Send DHCPDISCOVER.
 offer_ip=`ip_to_hex 10 0 0 4`
 server_ip=`ip_to_hex 10 0 0 1`
@@ -5432,9 +5483,6 @@ request_ip=0
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
 cat 1.expected | cut -c -48 > expout
 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
@@ -5442,6 +5490,8 @@ AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
 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
@@ -5458,9 +5508,6 @@ request_ip=$offer_ip
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5468,6 +5515,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5482,9 +5531,6 @@ request_ip=`ip_to_hex 10 0 0 7`
 expected_dhcp_opts=""
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5492,6 +5538,7 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5507,19 +5554,17 @@ request_ip=0
 test_dhcp 2 f00000000002 09 0 $ciaddr $offer_ip $request_ip 0 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
 
 # NXT_RESUMEs should be 4.
-OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
 # 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`
@@ -5531,9 +5576,6 @@ dst_ip=$server_ip
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5541,6 +5583,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5557,9 +5601,6 @@ dst_ip=`ip_to_hex 255 255 255 255`
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5567,6 +5608,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5583,9 +5626,6 @@ dst_ip=`ip_to_hex 255 255 255 255`
 expected_dhcp_opts=""
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5593,6 +5633,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5609,9 +5651,6 @@ dst_ip=`ip_to_hex 255 255 255 255`
 expected_dhcp_opts=""
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 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 "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5619,6 +5658,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5629,14 +5670,13 @@ rm -f 2.expected
 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 0 $ciaddr 0 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`])
+test_dhcp --no-resume 2 f00000000002 03 0 $ciaddr 0 0 0 1 $src_ip $dst_ip 1
 
 # vif1-tx.pcap should have received the DHCPv4 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
@@ -5650,9 +5690,6 @@ request_ip=0
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 1 f00000000001 01 1 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 9.
-OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
 cat 1.expected | cut -c -48 > expout
 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
@@ -5660,6 +5697,8 @@ AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
 cat 1.expected | cut -c 53- > expout
 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
 
+# ----------------------------------------------------------------------
+
 reset_pcap_file hv1-vif1 hv1/vif1
 reset_pcap_file hv1-vif2 hv1/vif2
 rm -f 1.expected
@@ -5673,9 +5712,6 @@ request_ip=0
 expected_dhcp_opts=0
 test_dhcp 2 f00000000002 07 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001
 
-# NXT_RESUMEs should be 10.
-OVS_WAIT_UNTIL([test 10 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
-
 # There is no reply for this. Check for the INFO log in ovn-controller.log
 AT_CHECK([test 1 = $(cat hv1/ovn-controller.log | \
 grep "DHCPRELEASE f0:00:00:00:00:02 10.0.0.6" -c)])
@@ -5683,6 +5719,8 @@ grep "DHCPRELEASE f0:00:00:00:00:02 10.0.0.6" -c)])
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 AT_CHECK([cat 2.packets], [0], [])
 
+# ----------------------------------------------------------------------
+
 reset_pcap_file hv1-vif1 hv1/vif1
 reset_pcap_file hv1-vif2 hv1/vif2
 rm -f 1.expected
@@ -5700,9 +5738,6 @@ dst_ip=$server_ip
 expected_dhcp_opts=03040a00000136040a000001
 test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 11.
-OVS_WAIT_UNTIL([test 11 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5712,6 +5747,10 @@ AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
 
 # Now add the dhcp option T1 to the dhcp options.
 check ovn-nbctl --wait=hv set dhcp_options ${d1} options:T1=4000
+AT_CAPTURE_FILE([sbflows2])
+ovn-sbctl dump-flows > sbflows2
+
+# ----------------------------------------------------------------------
 
 reset_pcap_file hv1-vif1 hv1/vif1
 reset_pcap_file hv1-vif2 hv1/vif2
@@ -5730,9 +5769,6 @@ dst_ip=$server_ip
 expected_dhcp_opts=3a0400000fa0330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 12.
-OVS_WAIT_UNTIL([test 12 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5740,6 +5776,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5757,9 +5795,6 @@ dst_ip=$server_ip
 expected_dhcp_opts=03040a00000136040a000001
 test_dhcp 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 13.
-OVS_WAIT_UNTIL([test 13 = $(cat ofctl_monitor*.log | grep -c NXT_RESUME)])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5767,6 +5802,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5777,6 +5814,8 @@ echo "------ Set tftp server (IPv4 address) --------"
 ovn-nbctl --wait=hv dhcp-options-set-options $d1 server_id=10.0.0.1 \
 server_mac=ff:10:00:00:00:01 lease_time=3600 router=10.0.0.1 \
 tftp_server=10.10.10.10
+AT_CAPTURE_FILE([sbflows3])
+ovn-sbctl dump-flows > sbflows3
 echo "----------------------------------------------"
 
 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
@@ -5788,9 +5827,6 @@ request_ip=$offer_ip
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a00000142040a0a0a0a
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 14.
-OVS_WAIT_UNTIL([test 14 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5798,6 +5834,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5808,6 +5846,8 @@ echo "------ Set tftp server (hostname) --------"
 ovn-nbctl --wait=hv dhcp-options-set-options $d1 server_id=10.0.0.1 \
 server_mac=ff:10:00:00:00:01 lease_time=3600 router=10.0.0.1 \
 tftp_server=\"test_tftp_server\"
+AT_CAPTURE_FILE([sbflows4])
+ovn-sbctl dump-flows > sbflows4
 echo "------------------------------------------"
 
 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
@@ -5819,9 +5859,6 @@ request_ip=$offer_ip
 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a0000014210746573745f746674705f736572766572
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 15.
-OVS_WAIT_UNTIL([test 15 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5829,6 +5866,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 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
@@ -5839,6 +5878,8 @@ echo "------ Set domain search list --------"
 ovn-nbctl --wait=hv dhcp-options-set-options $d1 server_id=10.0.0.1 \
 server_mac=ff:10:00:00:00:01 lease_time=3600 router=10.0.0.1 \
 domain_search_list=\"test1.com,test2.com\"
+AT_CAPTURE_FILE([sbflows5])
+ovn-sbctl dump-flows > sbflows5
 echo "------------------------------------------"
 
 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
@@ -5850,9 +5891,6 @@ request_ip=$offer_ip
 expected_dhcp_opts=771305746573743103636f6d00057465737432c006330400000e100104ffffff0003040a00000136040a000001
 test_dhcp 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
 
-# NXT_RESUMEs should be 16.
-OVS_WAIT_UNTIL([test 16 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
-
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
 cat 2.expected | cut -c -48 > expout
 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
@@ -5860,6 +5898,8 @@ AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
 cat 2.expected | cut -c 53- > expout
 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
 
+# ----------------------------------------------------------------------
+
 # test DHCPDECLINE
 offer_ip=`ip_to_hex 10 0 0 4`
 server_ip=`ip_to_hex 10 0 0 1`
@@ -6581,6 +6621,7 @@ ls3_p1_mac=00:00:00:01:02:05
 check ovn-nbctl --wait=hv lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
 
 # Check logical flow
+ovn-sbctl dump-flows > sbflows
 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
 1
 ])
@@ -6603,7 +6644,7 @@ AT_CHECK([ovs-ofctl dump-flows br-int | \
 # Expected to drop the packet.
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
 rcvd_packet=`cat vif2.packets`
-AT_FAIL_IF([rcvd_packet = ""])
+AT_FAIL_IF([test "$rcvd_packet" != ""])
 
 # Override drop policy with allow
 check ovn-nbctl --wait=hv lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
@@ -6653,13 +6694,13 @@ as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
 sleep 1
 
 echo "southbound flows"
-
-ovn-sbctl dump-flows | grep lr_in_policy
+ovn-sbctl --ovs dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 echo "ovs flows"
-ovs-ofctl dump-flows br-int
+ovs-ofctl dump-flows br-int > brflows
+AT_CAPTURE_FILE([brflows])
 # 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" | \
+AT_CHECK([grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" brflows | \
     grep "priority=30" | \
     grep "n_packets=1" | wc -l], [0], [dnl
 1
@@ -6768,7 +6809,9 @@ ls3_p1_mac=00:00:00:01:02:05
 check ovn-nbctl --wait=sb 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
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+AT_CHECK([grep lr_in_policy sbflows | grep "2001" | wc -l], [0], [dnl
 1
 ])
 
@@ -6789,14 +6832,15 @@ AT_CHECK([ovs-ofctl dump-flows br-int | \
 
 # Expected to drop the packet.
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
-rcvd_packet=`cat vif2.packets`
-AT_FAIL_IF([rcvd_packet = ""])
+AT_FAIL_IF([test -s vif2.packets])
 
 # Override drop policy with allow
 check ovn-nbctl --wait=sb 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
+ovn-sbctl dump-flows > sbflows2
+AT_CAPTURE_FILE([sbflows2])
+AT_CHECK([grep lr_in_policy sbflows2 | grep "2001" | wc -l], [0], [dnl
 2
 ])
 
@@ -6807,7 +6851,9 @@ packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
 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 | \
+ovn-sbctl dump-flows > sbflows3
+AT_CAPTURE_FILE([sbflows3])
+AT_CHECK([grep lr_in_policy sbflows3 | \
     grep "2001" | \
     grep "priority=20" | wc -l], [0], [dnl
 1
@@ -6825,7 +6871,9 @@ OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
 check ovn-nbctl --wait=sb 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 | \
+ovn-sbctl dump-flows > sbflows4
+AT_CAPTURE_FILE([sbflows4])
+AT_CHECK([grep lr_in_policy sbflows4 | \
     grep "2001" | \
     grep "priority=30" | wc -l], [0], [dnl
 1
@@ -6838,19 +6886,16 @@ packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
 sleep 1
 
-echo "southbound flows"
-
-ovn-sbctl dump-flows | grep lr_in_policy
-echo "ovs flows"
-ovs-ofctl dump-flows br-int
+ovn-sbctl dump-flows > sbflows5
+ovs-ofctl dump-flows br-int > offlows5
+AT_CAPTURE_FILE([sbflows5])
+AT_CAPTURE_FILE([offlows5])
 # Check if packet hit the allow policy
-AT_CHECK([ovs-ofctl dump-flows br-int | \
-    grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
+AT_CHECK([grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" offlows5 | \
     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 &&
@@ -7851,17 +7896,19 @@ AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
 grep "Port patch-br-int-to-ln_port" | wc -l`])
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 # Wait for packet to be received.
-OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
+OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 140])
 trim_zeros() {
     sed 's/\(00\)\{1,\}$//'
 }
 $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
-echo $expected > expout
-expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
-echo $expected >> expout
-AT_CHECK([sort packets], [0], [expout])
+AT_CHECK([sort packets], [0], [dnl
+fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001
+fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002
+])
 
 OVN_CLEANUP([hv1])
 
@@ -8245,8 +8292,8 @@ ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
 ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
 
-ovn-sbctl dump-flows
-
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 # Send packet that should be dropped without logging.
 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
@@ -8354,6 +8401,9 @@ check ovn-nbctl --wait=hv sync
 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
 ovn-nbctl --wait=hv sync
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 # For each ACL, send 100 packets.
 for i in `seq 1 100`; do
     ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
@@ -8455,23 +8505,23 @@ AT_SETUP([ovn -- DSCP marking and meter check])
 AT_KEYWORDS([ovn])
 ovn_start
 
-ovn-nbctl ls-add lsw0
-ovn-nbctl --wait=sb lsp-add lsw0 lp1
-ovn-nbctl --wait=sb lsp-add lsw0 lp2
-ovn-nbctl --wait=sb lsp-add lsw0 lp3
-ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
-ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
-ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
-ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
-ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
-ovn-nbctl --wait=sb sync
+check ovn-nbctl ls-add lsw0
+check ovn-nbctl --wait=sb lsp-add lsw0 lp1
+check ovn-nbctl --wait=sb lsp-add lsw0 lp2
+check ovn-nbctl --wait=sb lsp-add lsw0 lp3
+check ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
+check ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
+check ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
+check ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
+check ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
+check ovn-nbctl --wait=sb sync
 net_add n1
 sim_add hv
 as hv
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
-ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
+check ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
+check ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
 
 AT_CAPTURE_FILE([trace])
 ovn_trace () {
@@ -8529,7 +8579,7 @@ AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l],
 ])
 
 # Update the meter rate
-ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
+check ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
 
 # check at hv with a qos meter table
 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
@@ -8538,11 +8588,11 @@ AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l],
 ])
 
 # Update the DSCP marking
-ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
+check ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
 check_tos 63
 
 # Update the meter rate
-ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
+check ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
 
 # check at hv with a qos meter table
 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
@@ -8550,11 +8600,11 @@ AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=429
 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
 ])
 
-ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
+check ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
 check_tos 63
 
 # Disable DSCP marking
-ovn-nbctl --wait=hv qos-del lsw0
+check ovn-nbctl --wait=hv qos-del lsw0
 as hv check_row_count nb:QoS 0
 check_tos 0
 
@@ -8563,7 +8613,7 @@ AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l],
 ])
 
 # check meter with chassis not resident
-ovn-nbctl --wait=hv qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
+check ovn-nbctl --wait=hv qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
 as hv check_row_count nb:QoS 1
 
 # check no meter table
@@ -8573,10 +8623,10 @@ AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | w
 ])
 
 # Check multiple qos meters
-ovn-nbctl qos-del lsw0
-ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp1" && is_chassis_resident("lp1")' rate=100000 burst=100000
-ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp2" && is_chassis_resident("lp2")' rate=100000 burst=100000
-ovn-nbctl qos-add lsw0 to-lport 1002 'inport=="lp1" && is_chassis_resident("lp1")' rate=100001 burst=100001
+check ovn-nbctl qos-del lsw0
+check ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp1" && is_chassis_resident("lp1")' rate=100000 burst=100000
+check ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp2" && is_chassis_resident("lp2")' rate=100000 burst=100000
+check ovn-nbctl qos-add lsw0 to-lport 1002 'inport=="lp1" && is_chassis_resident("lp1")' rate=100001 burst=100001
 check ovn-nbctl --wait=hv qos-add lsw0 to-lport 1002 'inport=="lp2" && is_chassis_resident("lp2")' rate=100001 burst=100001
 
 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep meter | wc -l], [0], [4
@@ -9687,9 +9737,9 @@ net_add n1
 
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check 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 \
@@ -9697,19 +9747,19 @@ ovs-vsctl -- add-port br-int hv1-vif1 -- \
 
 sim_add gw1
 as gw1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
 
 sim_add gw2
 as gw2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.4
 
 sim_add ext1
 as ext1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int ext1-vif1 -- \
+check ovs-vsctl -- add-port br-int ext1-vif1 -- \
     set interface ext1-vif1 external-ids:iface-id=outside1 \
     options:tx_pcap=ext1/vif1-tx.pcap \
     options:rxq_pcap=ext1/vif1-rx.pcap \
@@ -9720,73 +9770,76 @@ ovs-vsctl -- add-port br-int ext1-vif1 -- \
 # for ARP resolution).
 OVN_POPULATE_ARP
 
-ovn-nbctl create Logical_Router name=R1
+AT_CHECK([ovn-nbctl create Logical_Router name=R1 | uuidfilt], [0], [<0>
+])
 
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
+check ovn-nbctl ls-add foo
+check ovn-nbctl ls-add alice
+check ovn-nbctl ls-add outside
 
 # Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
+check ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+check ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
     type=router options:router-port=foo \
     -- lsp-set-addresses rp-foo router
 
 # Connect alice to R1 as distributed router gateway port on gw1
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
+check ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
 
-ovn-nbctl \
-    --id=@gc0 create Gateway_Chassis name=alice_gw1 \
-                                     chassis_name=gw1 \
-                                     priority=20 -- \
-    --id=@gc1 create Gateway_Chassis name=alice_gw2 \
-                                     chassis_name=gw2 \
-                                     priority=10 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0, at gc1]'
+AT_CHECK([ovn-nbctl \
+          --id=@gc0 create Gateway_Chassis name=alice_gw1 \
+                                           chassis_name=gw1 \
+                                           priority=20 -- \
+          --id=@gc1 create Gateway_Chassis name=alice_gw2 \
+                                           chassis_name=gw2 \
+                                           priority=10 -- \
+          set Logical_Router_Port alice 'gateway_chassis=[@gc0, at gc1]' \
+          | uuidfilt], [0], [<0>
+<1>
+])
 
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
+check ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
     type=router options:router-port=alice \
     -- lsp-set-addresses rp-alice router
 
 # Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
+check ovn-nbctl lsp-add foo foo1 \
 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
 
 # Create logical port outside1 in outside
-ovn-nbctl lsp-add outside outside1 \
+check ovn-nbctl lsp-add outside outside1 \
 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
 
 # Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
+check ovn-nbctl lsp-add alice ln-alice
+check ovn-nbctl lsp-set-addresses ln-alice unknown
+check ovn-nbctl lsp-set-type ln-alice localnet
+check ovn-nbctl lsp-set-options ln-alice network_name=phys
 
 # Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
+check ovn-nbctl lsp-add outside ln-outside
+check ovn-nbctl lsp-set-addresses ln-outside unknown
+check ovn-nbctl lsp-set-type ln-outside localnet
+check ovn-nbctl lsp-set-options ln-outside network_name=phys
 
 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
 # mapping to the external network, is the one generating packets
-as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-
-AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
+check as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
-# Allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --wait=hv sync
+AT_CHECK([ovn-nbctl --wait=sb sync], [0], [ignore])
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 reset_pcap_file() {
     local iface=$1
     local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
+    check 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 \
+    check ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
 options:rxq_pcap=${pcap_file}-rx.pcap
 }
 
@@ -9806,7 +9859,7 @@ test_ip_packet()
     # ARP request packet to expect at outside1
     #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
 
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
 
     # Send ARP reply from outside1 back to the router
     # XXX: note, we could avoid this if we plug this port into a netns
@@ -9817,11 +9870,12 @@ test_ip_packet()
     src_ip=`ip_to_hex 172 16 1 1`
     arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
 
-    as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
+    check as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
 
+    AT_CAPTURE_FILE([offlows])
     OVS_WAIT_UNTIL([
-        test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
-grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
+        as $active_gw ovs-ofctl dump-flows br-int > offlows
+        test `grep table=66 offlows | grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
     ])
 
     # Packet to Expect at ext1 chassis, outside1 port
@@ -9844,16 +9898,35 @@ grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
     sleep 1
 
     # Resend packet from foo1 to outside1
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+
+    sleep 1
+
+    AT_CAPTURE_FILE([exp])
+    AT_CAPTURE_FILE([rcv])
+    check_packets() {
+        > exp
+        > rcv
+
+        pcap=ext1/vif1-tx.pcap
+        type=ext1-vif1.expected
+        echo "--- $pcap" | tee -a exp >> rcv
+        sort -u "$type" >> exp
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | sort -u >> rcv
+        echo | tee -a exp >> rcv
+
+        pcap=$active_gw/br-phys_n1-tx.pcap
+        echo "--- $pcap" | tee -a exp >> rcv
+        sort -u "$type" >> exp
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap > packets
+        (grep "$expected" packets; grep "$exp_gw_ip_garp" packets) | sort -u >> rcv
+        echo | tee -a exp >> rcv
+
+        $at_diff exp rcv >/dev/null
+    }
+
+    OVS_WAIT_UNTIL([check_packets], [$at_diff -F'^---' exp rcv])
 
-    OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
-    $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap  > packets
-    cat packets | grep $expected > exp
-    # Its possible that $active_gw/br-phys_n1-tx.pcap may have received multiple
-    # garp packets. So consider only the first packet.
-    cat packets | grep $exp_gw_ip_garp | head -1 >> exp
-    AT_CHECK([cat exp], [0], [expout])
-    rm -f expout
     if test $backup_vswitchd_dead != 1; then
         # Check for backup gw only if vswitchd is alive
         $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap  > packets
@@ -9863,14 +9936,18 @@ grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
 
 test_ip_packet gw1 gw2 0
 
-ovn-nbctl --timeout=3 --wait=hv \
+AT_CHECK(
+  [ovn-nbctl --wait=hv \
     --id=@gc0 create Gateway_Chassis name=alice_gw1 \
                                      chassis_name=gw1 \
                                      priority=10 -- \
     --id=@gc1 create Gateway_Chassis name=alice_gw2 \
                                      chassis_name=gw2 \
                                      priority=20 -- \
-    set Logical_Router_Port alice 'gateway_chassis=[@gc0, at gc1]'
+    set Logical_Router_Port alice 'gateway_chassis=[@gc0, at gc1]' | uuidfilt], 0,
+  [<0>
+<1>
+])
 
 test_ip_packet gw2 gw1 0
 
@@ -10143,9 +10220,9 @@ net_add n1
 
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check 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 \
@@ -10153,14 +10230,14 @@ ovs-vsctl -- add-port br-int hv1-vif1 -- \
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
 
 sim_add hv3
 as hv3
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl -- add-port br-int hv3-vif1 -- \
+check ovs-vsctl -- add-port br-int hv3-vif1 -- \
     set interface hv3-vif1 external-ids:iface-id=outside1 \
     options:tx_pcap=hv3/vif1-tx.pcap \
     options:rxq_pcap=hv3/vif1-rx.pcap \
@@ -10173,46 +10250,46 @@ OVN_POPULATE_ARP
 
 ovn-nbctl create Logical_Router name=R1
 
-ovn-nbctl ls-add foo
-ovn-nbctl ls-add alice
-ovn-nbctl ls-add outside
+check ovn-nbctl ls-add foo
+check ovn-nbctl ls-add alice
+check ovn-nbctl ls-add outside
 
 # Connect foo to R1
-ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
-ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
+check ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+check ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
     type=router options:router-port=foo \
     -- lsp-set-addresses rp-foo router
 
 # Connect alice to R1 as distributed router gateway port on hv2
-ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
+check ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
     -- lrp-set-gateway-chassis alice hv2
-ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
+check ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
     type=router options:router-port=alice \
     -- lsp-set-addresses rp-alice router
 
 # Create logical port foo1 in foo
-ovn-nbctl lsp-add foo foo1 \
--- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
+check ovn-nbctl lsp-add foo foo1 \
+    -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
 
 # Create logical port outside1 in outside
-ovn-nbctl lsp-add outside outside1 \
--- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
+check ovn-nbctl lsp-add outside outside1 \
+    -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
 
 # Create localnet port in alice
-ovn-nbctl lsp-add alice ln-alice
-ovn-nbctl lsp-set-addresses ln-alice unknown
-ovn-nbctl lsp-set-type ln-alice localnet
-ovn-nbctl lsp-set-options ln-alice network_name=phys
+check ovn-nbctl lsp-add alice ln-alice
+check ovn-nbctl lsp-set-addresses ln-alice unknown
+check ovn-nbctl lsp-set-type ln-alice localnet
+check ovn-nbctl lsp-set-options ln-alice network_name=phys
 
 # Create localnet port in outside
-ovn-nbctl lsp-add outside ln-outside
-ovn-nbctl lsp-set-addresses ln-outside unknown
-ovn-nbctl lsp-set-type ln-outside localnet
-ovn-nbctl lsp-set-options ln-outside network_name=phys
+check ovn-nbctl lsp-add outside ln-outside
+check ovn-nbctl lsp-set-addresses ln-outside unknown
+check ovn-nbctl lsp-set-type ln-outside localnet
+check ovn-nbctl lsp-set-options ln-outside network_name=phys
 
 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
-as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
-as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
 
 dnl Allow some time for ovn-northd and ovn-controller to catch up.
@@ -11443,8 +11520,10 @@ echo "---------------------"
 ovn-sbctl list chassis
 ovn-sbctl list encap
 echo "---------------------"
-echo "------ Gateway_Chassis dump (SBDB) -------"
-ovn-sbctl list Gateway_Chassis
+echo "------ ha_Chassis_Group dump (SBDB) -------"
+ovn-sbctl list HA_Chassis_Group
+echo "------ ha_Chassis dump (SBDB) -------"
+ovn-sbctl list HA_Chassis
 echo "------ Port_Binding chassisredirect -------"
 ovn-sbctl find Port_Binding type=chassisredirect
 echo "-------------------------------------------"
@@ -12625,42 +12704,42 @@ ra_test() {
     rm -f expected
 }
 
-# Baseline test with no MTU
+echo "Baseline test with no MTU"
 ra_test 0 00 0 0 0 c0 40 aef00000000000000000000000000000
 
-# Now make sure an MTU option makes it
+echo "Now make sure an MTU option makes it"
 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
 ra_test 000005dc 00 0 0 0 c0 40 aef00000000000000000000000000000
 
-# Now test for multiple network prefixes
+echo "Now test for multiple network prefixes"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
 ra_test 000005dc 00 0 0 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
-# Test PRF for default gw
+echo "Test PRF for default gw"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:router_preference="LOW"
 ra_test 000005dc 18 0 0 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
-# Now test for RDNSS
+echo "Now test for RDNSS"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:rdnss='aef0::11'
 dns_addr=aef00000000000000000000000000011
 ra_test 000005dc 18 $dns_addr 0 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
-# Now test for DNSSL
+echo "Now test for DNSSL"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:dnssl="aa.bb.cc"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:router_preference="HIGH"
 dnssl=02616102626202636300000000000000
 ra_test 000005dc 08 $dns_addr $dnssl 0 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
-# Now test Route Info option
+echo "Now test Route Info option"
 ovn-nbctl --wait=hv set Logical_Router_port ro-sw ipv6_ra_configs:route_info="HIGH-aef1::11/48,LOW-aef2::11/96"
 route_info=18023008ffffffffaef100000000000018036018ffffffffaef20000000000000000000000000000
 ra_test 000005dc 08 $dns_addr $dnssl $route_info c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
-
-## Test a different address mode now
+exit 0
+echo "Test a different address mode now"
 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
 ra_test 000005dc 88 $dns_addr $dnssl $route_info 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
-# And the other address mode
+echo "And the other address mode"
 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
 ra_test 000005dc 48 $dns_addr $dnssl $route_info c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
 
@@ -12698,7 +12777,7 @@ test_ip_packet() {
     local reply=${eth_src}${eth_dst}08004500003000004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
     echo $reply$orig_pkt_in_reply >> vif$inport.expected
 
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
+    check as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
 }
 
 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
@@ -12716,7 +12795,7 @@ test_ipv6_packet() {
     local reply=${eth_src}${eth_dst}86dd6000000000383aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}0000000000000000
     echo $reply >> vif$inport.expected
 
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
+    check as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
 }
 
 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
@@ -12744,7 +12823,7 @@ test_tcp_syn_packet() {
     local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000250140000${exp_tcp_rst_chksum}0000
     echo $reply >> vif$inport.expected
 
-    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
+    check as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
 }
 
 # Create hypervisors hv[123].
@@ -12752,18 +12831,18 @@ test_tcp_syn_packet() {
 # Add all of the vifs to a single logical switch sw0.
 
 net_add n1
-ovn-nbctl ls-add sw0
+check ovn-nbctl ls-add sw0
 for i in 1 2 3; do
     sim_add hv$i
     as hv$i
-    ovs-vsctl add-br br-phys
+    check ovs-vsctl add-br br-phys
     ovn_attach n1 br-phys 192.168.0.$i
 
     for j in 1 2 3; do
         ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
                 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
 
-        ovs-vsctl -- add-port br-int vif$i$j -- \
+        check ovs-vsctl -- add-port br-int vif$i$j -- \
                 set interface vif$i$j \
                 external-ids:iface-id=sw0-p$i$j \
                 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
@@ -12780,12 +12859,15 @@ for i in 1 2 3; do
     : > vif${i}1.expected
 done
 
-ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
-ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
-ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
+check ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
+check ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
+check ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
-ovn-nbctl --timeout=3 --wait=hv sync
+check ovn-nbctl --wait=hv sync
+
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 f85b f576
 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 f85b f576
@@ -13348,28 +13430,31 @@ ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
 ovn-nbctl --wait=sb sync
 
 dnl Check if port group address sets were populated with ports' addresses
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.1.0.2", "10.2.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
-         [0], [[["10.2.0.2", "10.3.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
-         [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
+AT_CHECK(
+  [ovn-sbctl get Address_Set pg1_ip4 addresses \
+          -- get Address_Set pg2_ip4 addresses \
+          -- get Address_Set pg1_ip6 addresses \
+          -- get Address_Set pg2_ip6 addresses],
+  [0],
+  [[["10.1.0.2", "10.2.0.2"]]
+[["10.2.0.2", "10.3.0.2"]]
+[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
+[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
 ])
 
+dnl Check if updated address got propagated to the port group address sets
 ovn-nbctl --wait=sb set Logical_Switch ls1 \
     other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
-
-dnl Check if updated address got propagated to the port group address sets
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
-         [0], [[["10.11.0.2", "10.2.0.2"]]
-])
-AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
-         [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
+AT_CHECK(
+  [ovn-sbctl get Address_Set pg1_ip4 addresses \
+          -- get Address_Set pg2_ip4 addresses \
+          -- get Address_Set pg1_ip6 addresses \
+          -- get Address_Set pg2_ip6 addresses],
+  [0],
+  [[["10.11.0.2", "10.2.0.2"]]
+[["10.2.0.2", "10.3.0.2"]]
+[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
+[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
 ])
 
 AT_CLEANUP
@@ -13925,6 +14010,10 @@ for sf in 0 1; do
         # allow rule is still effective..
         check ovn-nbctl --wait=hv acl-add lsw0 from-lport 2000  "inport == lp31 && ip" allow-related
     fi
+    # dump information and flows with counters
+    ovn-sbctl dump-flows -- list multicast_group > sbflows$sf
+    AT_CAPTURE_FILE([sbflows0])
+    AT_CAPTURE_FILE([sbflows1])
     for is in 1 2 3; do
         s=${is}1
         for id in 1 2 3; do
@@ -13949,52 +14038,48 @@ for sf in 0 1; do
     done
 done
 
-# Clean up the ACL
-ovn-nbctl acl-del lsw0
-
-# 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
+as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int > offlows1
+as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int > offlows2
+as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int > offlows3
 
 # Now check the packets actually received against the ones expected.
-for i in 1 2 3; do
-    OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [${i}1.expected])
-done
-
-# need to verify the log for ACL hit as well, since in the allow case
-# (unlike the drop case) it is tricky to pass just with the expected;
-# since with the stateful rule the packet will still get by (default
-# rule) even if it doesn't hit the allow rule.
-# The hit count for the ACL is 6 (1 unicast + 2 non-unicast) * 2
-# (with/without stateful rule) for hv1 and hv2, each.
-
-hv1_drop_acl_hit=`grep acl_log hv1/ovn-controller.log | grep "|INFO|name=\"drop-acl\"" | wc -l`
-hv2_drop_acl_hit=`grep acl_log hv2/ovn-controller.log | grep "|INFO|name=\"drop-acl\"" | wc -l`
-
-hv1_allow_acl_hit=`grep acl_log hv1/ovn-controller.log | grep "|INFO|name=\"allow-acl\"" | wc -l`
-hv2_allow_acl_hit=`grep acl_log hv2/ovn-controller.log | grep "|INFO|name=\"allow-acl\"" | wc -l`
-
-echo "hv1_drop hit $hv1_drop_acl_hit"
-echo "hv2_drop hit $hv2_drop_acl_hit"
-echo "hv1_allow hit $hv1_allow_acl_hit"
-echo "hv2_allow hit $hv2_allow_acl_hit"
-
-AT_CHECK([test $hv1_drop_acl_hit = 6])
-AT_CHECK([test $hv2_drop_acl_hit = 6])
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+check_packets() {
+    > expected
+    > received
+    for i in 1 2 3; do
+        echo "--- hv$i vif${i}1" | tee -a expected >> received
+        sort ${i}1.expected >> expected
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv$i/vif${i}1-tx.pcap | sort >> received
+        echo | tee -a expected >> received
+    done
 
-AT_CHECK([test $hv1_allow_acl_hit = 6])
-AT_CHECK([test $hv2_allow_acl_hit = 6])
+    # need to verify the log for ACL hit as well, since in the allow case
+    # (unlike the drop case) it is tricky to pass just with the expected;
+    # since with the stateful rule the packet will still get by (default
+    # rule) even if it doesn't hit the allow rule.
+    # The hit count for the ACL is 6 (1 unicast + 2 non-unicast) * 2
+    # (with/without stateful rule) for hv1 and hv2, each.
+    cat >>expected <<EOF
+--- acl logging
+hv1_drop hit 6
+hv2_drop hit 6
+hv1_allow hit 6
+hv2_allow hit 6
+EOF
+
+cat >>received <<EOF
+--- acl logging
+hv1_drop hit `grep -c 'acl_log.*|INFO|name="drop-acl"' hv1/ovn-controller.log`
+hv2_drop hit `grep -c 'acl_log.*|INFO|name="drop-acl"' hv2/ovn-controller.log`
+hv1_allow hit `grep -c 'acl_log.*|INFO|name="allow-acl"' hv1/ovn-controller.log`
+hv2_allow hit `grep -c 'acl_log.*|INFO|name="allow-acl"' hv2/ovn-controller.log`
+EOF
+
+    $at_diff expected received >/dev/null
+}
+OVS_WAIT_UNTIL([check_packets], [$at_diff -F'^---' expected received])
 
 OVN_CLEANUP([hv1],[hv2],[hv3])
 
@@ -14455,17 +14540,21 @@ port_binding logical_port=ls1-lp_ext1`
 
 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
 # as no localnet port added to ls1 yet.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+#
+# This used to be specific to a particular OpenFlow table, but that can
+# easily shift around as OVN evolves, so it's been removed to avoid
+# gratuitous breakage.
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
 ])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
 ])
@@ -14487,38 +14576,40 @@ logical_port=ls1-lp_ext1`
     test "$chassis" = "$hv1_uuid"])
 
 # There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+(ovn-sbctl dump-flows lr0; ovn-sbctl dump-flows ls1) > sbflows
+as hv1 ovs-ofctl dump-flows br-int > brintflows
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
 wc -l], [0], [3
 ])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
 grep reg14=0x$ln_public_key | wc -l], [0], [1
 ])
 
 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
 ])
 
 # No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
 # hv2 as requested-chassis option is not set.
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
 ])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
 ])
@@ -14766,21 +14857,21 @@ logical_port=ls1-lp_ext1`
     test "$chassis" = "$hv2_uuid"])
 
 # There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
 wc -l], [0], [3
 ])
-AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
 grep reg14=0x$ln_public_key | wc -l], [0], [1
 ])
 
 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
 ])
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=23 | \
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
 grep controller | grep tp_src=546 | grep \
 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
 grep reg14=0x$ln_public_key | wc -l], [0], [0
@@ -15356,7 +15447,7 @@ reset_pcap_file() {
 }
 
 test_ip_packet_larger() {
-    local icmp_pmtu_reply_expected=$1
+    local mtu=$1
 
     # Send ip packet from sw0-port1 to outside
     src_mac="505400000001" # sw-port1 mac
@@ -15377,13 +15468,16 @@ test_ip_packet_larger() {
 
     gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
 
+    packet_bytes=$(expr ${#packet} / 2)
+    mtu_needed=$(expr ${packet_bytes} - 18)
+
     # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
     # the gateway mtu and should be delivered to the provider bridge via the
     # localnet port.
     # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
     # the gateway mtu and ovn-controller should drop the packet and instead
     # generate ICMPv4  Destination Unreachable message with pmtu set to 100.
-    if test $icmp_pmtu_reply_expected = 0; then
+    if test $mtu -ge $mtu_needed; then
         # Packet to expect at br-phys.
         src_mac="000020201213"
         dst_mac="00000012af11"
@@ -15399,15 +15493,13 @@ test_ip_packet_larger() {
         echo $expected > br_phys_n1.expected
         echo $gw_ip_garp >> br_phys_n1.expected
     else
-        # MTU would be 118 - 18 = 100 (hex 0064)
-        mtu=0064
         src_ip=`ip_to_hex 10 0 0 1`
         dst_ip=`ip_to_hex 10 0 0 3`
         # pkt len should be 146 (28 (icmp packet) + 118 (orig ip + payload))
         reply_pkt_len=0092
         ip_csum=f993
         icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016867
-        icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
+        icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000$(printf "%04x" $mtu)
         icmp_reply=${icmp_reply}4500${pkt_len}000000003f01c4d9
         icmp_reply=${icmp_reply}${orig_packet_l3}
         echo $icmp_reply > hv1-vif1.expected
@@ -15417,9 +15509,9 @@ test_ip_packet_larger() {
     as hv1 reset_pcap_file hv1-vif1 hv1/vif1
 
     # Send packet from sw0-port1 to outside
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
 
-    if test $icmp_pmtu_reply_expected = 0; then
+    if test $mtu -ge $mtu_needed; then
         OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
         $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap  > pkts
         # hv1/vif1-tx.pcap can receive the GARP packet generated by ovn-controller
@@ -15438,7 +15530,7 @@ test_ip_packet_larger() {
 }
 
 test_ip6_packet_larger() {
-    local icmp_pmtu_reply_expected=$1
+    local mtu=$1
 
     local eth_src=505400000001
     local eth_dst=00000000ff01
@@ -15459,21 +15551,48 @@ test_ip6_packet_larger() {
     as hv1 reset_pcap_file hv1-vif1 hv1/vif1
 
     # Send packet from sw0-port1 to outside
-    as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    tcpdump_hex ">> sending packet:" $packet
+    check as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+    AT_CHECK([as hv1 ovs-appctl ofproto/trace br-int in_port=hv1-vif1 $packet > trace-$mtu],
+             [0], [ignore])
+    AT_CAPTURE_FILE([trace-$mtu])
+
+    packet_bytes=$(expr ${#packet} / 2)
+    mtu_needed=$(expr ${packet_bytes} - 18)
+    if test $mtu -lt $mtu_needed; then
+        # First construct the inner IPv6 packet.
+        inner_ip6=6000000000583afe${ipv6_src}${ipv6_dst}
+        inner_icmp6=8000000062f00001
+        inner_icmp6_and_payload=$(icmp6_csum_inplace ${inner_icmp6}${payload} ${inner_ip6})
+        inner_packet=${inner_ip6}${inner_icmp6_and_payload}
+        
+        # Then the outer.
+        outer_ip6=6000000000883afe${ipv6_rt}${ipv6_src}
+        outer_icmp6_and_payload=$(icmp6_csum_inplace 020000000000$(printf "%04x" $mtu)${inner_packet} $outer_ip6)
+        outer_packet=${outer_ip6}${outer_icmp6_and_payload}
+
+        icmp6_reply=${eth_src}${eth_dst}86dd${outer_packet}
+
+        echo
+        tcpdump_hex ">> expecting reply packet" $icmp6_reply
 
-    if test $icmp_pmtu_reply_expected = 1; then
-        icmp6_reply=${eth_src}${eth_dst}86dd6000000000883afe
-        icmp6_reply=${icmp6_reply}${ipv6_rt}${ipv6_src}020041ff00000076
-        icmp6_reply=${icmp6_reply}6000000000583afe${ipv6_src}${ipv6_dst}
-        icmp6_reply=${icmp6_reply}8000ec7662f00001${payload}
-        echo $icmp6_reply > hv1-vif1.expected
+        # The "trace" above sends a second packets as a side effect.
+        (echo $icmp6_reply; echo $icmp6_reply) > hv1-vif1.expected
 
         OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
     fi
 }
 
-ovn-nbctl show
-ovn-sbctl show
+ovn-nbctl --wait=hv sync
+
+ovn-nbctl show > nbdump
+AT_CAPTURE_FILE([nbdump])
+
+ovn-sbctl show > sbdump
+AT_CAPTURE_FILE([sbdump])
+
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int  \
 | grep "check_pkt_larger" | wc -l], [0], [[0
@@ -15483,34 +15602,27 @@ awk '{print $3}')
 ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
 logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
 
-# Set the gateway mtu to 100. If the packet length is > 118, ovn-controller
-# should send icmp host not reachable with pmtu set to 100.
-ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
-as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
-OVS_WAIT_UNTIL([
-    test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(118)" | \
-    wc -l` -eq 1
-])
-
-icmp_reply_expected=1
-test_ip_packet_larger $icmp_reply_expected
+# Try different gateway mtus and send a 142-byte packet (corresponding
+# to a 124-byte MTU).  If the MTU is less than 124, ovn-controller
+# should send icmp host not reachable with pmtu set to $mtu.
+for mtu in 100 500 118; do
+    AS_BOX([testing mtu $mtu])
+    check ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=$mtu
+    ovn-sbctl dump-flows > sbflows-$mtu
+    AT_CAPTURE_FILE([sbflows-$mtu])
 
-# Set the gateway mtu to 500.
-ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
-as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
-OVS_WAIT_UNTIL([
-    test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(518)" | \
-    wc -l` -eq 1
+    OVS_WAIT_FOR_OUTPUT([
+        as hv1 ovs-ofctl dump-flows br-int > br-int-flows-$mtu
+        AT_CAPTURE_FILE([br-int-flows-$mtu])
+        grep "check_pkt_larger($(expr $mtu + 18))" br-int-flows-$mtu | wc -l], [0], [1
 ])
 
-# Now the packet should be sent via the localnet port to br-phys.
-icmp_reply_expected=0
-test_ip_packet_larger $icmp_reply_expected
+    AS_BOX([testing mtu $mtu - IPv4])
+    test_ip_packet_larger $mtu
 
-# Set the gateway mtu to 118
-ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=118
-icmp_reply_expected=1
-test_ip6_packet_larger $icmp_reply_expected
+    AS_BOX([testing mtu $mtu - IPv6])
+    test_ip6_packet_larger $mtu
+done
 
 OVN_CLEANUP([hv1])
 AT_CLEANUP
@@ -15632,6 +15744,8 @@ ovn-nbctl lr-nat-add lr0 snat 2002::1 2001::/64
 OVN_POPULATE_ARP
 ovn-nbctl --wait=hv sync
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 src_mac=f00000010203
 src_ip=$(ip_to_hex 192 168 1 2)
@@ -15672,6 +15786,9 @@ OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
 ovn-nbctl lr-nat-del lr0 snat
 ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.16.1.2 192.168.1.3 sw0-p1 f0:00:00:01:02:04
 ovn-nbctl lr-route-add lr0 172.16.2.0/24 172.16.1.11
+ovn-nbctl --wait=hv sync
+ovn-sbctl dump-flows > sbflows2
+AT_CAPTURE_FILE([sbflows2])
 
 dst_ip=$(ip_to_hex 172 16 2 10)
 fip_ip=$(ip_to_hex 172 16 1 2)
@@ -15704,64 +15821,66 @@ ovn_start
 # GARPs have been sent out to the external network as well.
 
 # Create logical switches
-ovn-nbctl ls-add sw0
-ovn-nbctl ls-add sw1
-ovn-nbctl ls-add pub
+check ovn-nbctl ls-add sw0
+check ovn-nbctl ls-add sw1
+check ovn-nbctl ls-add pub
 
 # Created localnet port on public switch
-ovn-nbctl lsp-add pub ln-pub
-ovn-nbctl lsp-set-type ln-pub localnet
-ovn-nbctl lsp-set-addresses ln-pub unknown
-ovn-nbctl lsp-set-options ln-pub network_name=phys
+check ovn-nbctl lsp-add pub ln-pub
+check ovn-nbctl lsp-set-type ln-pub localnet
+check ovn-nbctl lsp-set-addresses ln-pub unknown
+check ovn-nbctl lsp-set-options ln-pub network_name=phys
 
 # Create logical routers and connect them to public switch
-ovn-nbctl create Logical_Router name=lr0
-ovn-nbctl create Logical_Router name=lr1
+AT_CHECK([(ovn-nbctl create Logical_Router name=lr0;
+           ovn-nbctl create Logical_Router name=lr1) | uuidfilt], [0], [<0>
+<1>
+])
 
-ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
-ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
+check ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
+check ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
     type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
-ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
-ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
+check ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
+check ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
     type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
 
-ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
-ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
+check ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
+check ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
 
 # Connect sw0 and sw1 to lr0 and lr1
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
-ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
+check ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
     options:router-port=lr0-sw0 addresses="router"
-ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
-ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
+check ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
+check ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
     options:router-port=lr1-sw1 addresses="router"
 
 
 # Add SNAT rules
-ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
-ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
+check ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
+check ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
 
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 172.24.4.1
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
-ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
-ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
+check ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
+check ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
 
-ovn-nbctl lsp-add sw0 lp0
-ovn-nbctl lsp-add sw1 lp1
-ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
-ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
+check ovn-nbctl lsp-add sw0 lp0
+check ovn-nbctl lsp-add sw1 lp1
+check ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
+check ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
 
 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
 
 # Create two floating IPs, one for each VIF
-ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
-ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
+check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
+check ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
 
 # Check that the MAC_Binding entries have been properly created
 wait_row_count MAC_Binding 1 logical_port=lr0-pub ip=172.24.4.200
@@ -15770,19 +15889,21 @@ wait_row_count MAC_Binding 1 logical_port=lr1-pub ip=172.24.4.100
 # Check that the GARPs went also to the external physical network
 # Wait until at least 4 packets have arrived and copy them to a separate file as
 # more GARPs are expected in the capture in order to avoid race conditions.
-OVS_WAIT_UNTIL([test `$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
-$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
-
+#
+# The expected output is:
 # GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
-echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
 # GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
-echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
 # GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
-echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
 # GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
-echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
-AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
-#OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
+
+OVS_WAIT_FOR_OUTPUT(
+  [$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | sort | uniq],
+  [0],
+  [fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464
+fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc
+fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8
+fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd
+])
 
 OVN_CLEANUP([hv1])
 AT_CLEANUP
@@ -16303,21 +16424,22 @@ ovn-nbctl --wait=hv sync
 # Check that logical flows are added for sw0-vir in lsp_in_arp_rsp pipeline
 # with bind_vport action.
 
-ovn-sbctl dump-flows sw0 | grep ls_in_arp_rsp | grep bind_vport > lflows.txt
+ovn-sbctl dump-flows sw0 > sw0-flows
+AT_CAPTURE_FILE([sw0-flows])
 
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=14(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
-  table=14(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p2" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
-  table=14(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
+AT_CHECK([grep ls_in_arp_rsp sw0-flows | grep bind_vport | sed 's/table=../table=??/'], [0], [dnl
+  table=??(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
+  table=??(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p2" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
+  table=??(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
 ])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
+ovn-sbctl dump-flows lr0 > lr0-flows
+AT_CAPTURE_FILE([lr0-flows])
 
 # Since the sw0-vir is not claimed by any chassis, eth.dst should be set to
 # zero if the ip4.dst is the virtual ip in the router pipeline.
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 00:00:00:00:00:00; next;)
+AT_CHECK([grep lr_in_arp_resolve lr0-flows | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 00:00:00:00:00:00; next;)
 ])
 
 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
@@ -16358,13 +16480,13 @@ logical_port=sw0-vir) = x$hv1_ch_uuid], [0], [])
 AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = xsw0-p1])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
 
 # There should be an arp resolve flow to resolve the virtual_ip with the
 # sw0-p1's MAC.
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:03; next;)
+ovn-sbctl dump-flows lr0 > lr0-flows2
+AT_CAPTURE_FILE([lr0-flows2])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows2 | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:03; next;)
 ])
 
 # Forcibly clear virtual_parent. ovn-controller should release the binding
@@ -16399,13 +16521,15 @@ logical_port=sw0-vir) = x$hv1_ch_uuid], [0], [])
 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = xsw0-p3])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
 
 # There should be an arp resolve flow to resolve the virtual_ip with the
 # sw0-p2's MAC.
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:05; next;)
+sleep 1
+ovn-sbctl dump-flows lr0 > lr0-flows3
+AT_CAPTURE_FILE([lr0-flows3])
+cp ovn-sb/ovn-sb.db lr0-flows3.db
+AT_CHECK([grep lr_in_arp_resolve lr0-flows3 | grep "reg0 == 10.0.0.10"  | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:05; next;)
 ])
 
 # send the garp from sw0-p2 (in hv2). hv2 should claim sw0-vir
@@ -16422,13 +16546,14 @@ logical_port=sw0-vir) = x$hv2_ch_uuid], [0], [])
 AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = xsw0-p2])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
 
 # There should be an arp resolve flow to resolve the virtual_ip with the
 # sw0-p3's MAC.
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:04; next;)
+sleep 1
+ovn-sbctl dump-flows lr0 > lr0-flows4
+AT_CAPTURE_FILE([lr0-flows4])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows4 | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:04; next;)
 ])
 
 # Now send arp reply from sw0-p1. hv1 should claim sw0-vir
@@ -16446,11 +16571,10 @@ sleep 1
 AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = xsw0-p1])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:03; next;)
+ovn-sbctl dump-flows lr0 > lr0-flows5
+AT_CAPTURE_FILE([lr0-flows5])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows5 | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:03; next;)
 ])
 
 # Delete hv1-vif1 port. hv1 should release sw0-vir
@@ -16465,11 +16589,10 @@ logical_port=sw0-vir) = x])
 
 # Since the sw0-vir is not claimed by any chassis, eth.dst should be set to
 # zero if the ip4.dst is the virtual ip.
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 00:00:00:00:00:00; next;)
+ovn-sbctl dump-flows lr0 > lr0-flows6
+AT_CAPTURE_FILE([lr0-flows6])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows6 | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 00:00:00:00:00:00; next;)
 ])
 
 # Now send arp reply from sw0-p2. hv2 should claim sw0-vir
@@ -16479,18 +16602,18 @@ eth_dst=ffffffffffff
 spa=$(ip_to_hex 10 0 0 10)
 tpa=$(ip_to_hex 10 0 0 3)
 send_arp_reply 2 1 $eth_src $eth_dst $spa $tpa
+sleep 1
 
 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
 logical_port=sw0-vir) = x$hv2_ch_uuid], [0], [])
-
+sleep 1
 AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = xsw0-p2])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=13(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:04; next;)
+ovn-sbctl dump-flows lr0 > lr0-flows7
+AT_CAPTURE_FILE([lr0-flows7])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows7 | grep "reg0 == 10.0.0.10" | sed 's/table=../table=??/'], [0], [dnl
+  table=??(lr_in_arp_resolve  ), priority=100  , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:04; next;)
 ])
 
 # Delete sw0-p2 logical port
@@ -16498,39 +16621,34 @@ ovn-nbctl lsp-del sw0-p2
 
 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding \
 logical_port=sw0-vir) = x], [0], [])
-
 AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \
 logical_port=sw0-vir) = x])
 
 # Clear virtual_ip column of sw0-vir. There should be no bind_vport flows.
 ovn-nbctl --wait=hv remove logical_switch_port sw0-vir options virtual-ip
 
-ovn-sbctl dump-flows sw0 | grep ls_in_arp_rsp | grep bind_vport > lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-])
+ovn-sbctl dump-flows sw0 > sw0-flows2
+AT_CAPTURE_FILE([sw0-flows2])
+AT_CHECK([grep ls_in_arp_rsp sw0-flows2 | grep bind_vport], [1])
 
 # Add back virtual_ip and clear virtual_parents.
 ovn-nbctl --wait=hv set logical_switch_port sw0-vir options:virtual-ip=10.0.0.10
 
-ovn-sbctl dump-flows sw0 | grep ls_in_arp_rsp | grep bind_vport > lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=14(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
-  table=14(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
+ovn-sbctl dump-flows sw0 > sw0-flows3
+AT_CAPTURE_FILE([sw0-flows3])
+AT_CHECK([grep ls_in_arp_rsp sw0-flows3 | grep bind_vport | sed 's/table=../table=??/'], [0], [dnl
+  table=??(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
+  table=??(ls_in_arp_rsp      ), priority=100  , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;)
 ])
 
 ovn-nbctl --wait=hv remove logical_switch_port sw0-vir options virtual-parents
-ovn-sbctl dump-flows sw0 | grep ls_in_arp_rsp | grep bind_vport > lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-])
+ovn-sbctl dump-flows sw0 > sw0-flows4
+AT_CAPTURE_FILE([sw0-flows4])
+AT_CHECK([grep ls_in_arp_rsp sw0-flows4 | grep bind_vport], [1])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_arp_resolve | grep "reg0 == 10.0.0.10" \
-> lflows.txt
-
-AT_CHECK([cat lflows.txt], [0], [dnl
-])
+ovn-sbctl dump-flows lr0 > lr0-flows8
+AT_CAPTURE_FILE([lr0-flows8])
+AT_CHECK([grep lr_in_arp_resolve lr0-flows8 | grep "reg0 == 10.0.0.10"], [1])
 
 OVN_CLEANUP([hv1], [hv2])
 AT_CLEANUP
@@ -16625,16 +16743,21 @@ ovn-nbctl --wait=hv meter-add event-elb drop 100 pktps 10
 
 OVN_POPULATE_ARP
 ovn-nbctl --timeout=3 --wait=hv sync
-ovn-sbctl lflow-list
-as hv1 ovs-ofctl dump-flows br-int
+ovn-sbctl lflow-list > sbflows
+AT_CAPTURE_FILE([sbflows])
+as hv1 ovs-ofctl dump-flows br-int > offlows
+AT_CAPTURE_FILE([offlows])
 
 packet0="inport==\"sw0-p11\" && eth.src==00:00:00:00:00:11 && eth.dst==00:00:00:00:00:21 &&
          ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==192.168.1.100 &&
          tcp && tcp.src==10000 && tcp.dst==80"
 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet0"
 
-ovn-sbctl list controller_event
-uuid=$(ovn-sbctl list controller_event | awk '/_uuid/{print $3}')
+ovn-sbctl list controller_event > events
+AT_CAPTURE_FILE([events])
+uuid=$(awk '/_uuid/{print $3}' < events)
+echo uuid=$uuid
+AT_CHECK([test -n "$uuid"])
 AT_CHECK([ovn-sbctl get controller_event $uuid event_type], [0], [dnl
 empty_lb_backends
 ])
@@ -16711,10 +16834,10 @@ ovn_start
 reset_pcap_file() {
     local iface=$1
     local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
+    check 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 \
+    check ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
 options:rxq_pcap=${pcap_file}-rx.pcap
 }
 
@@ -16750,7 +16873,7 @@ send_igmp_v3_report() {
     local packet=${eth}${ip}${igmp}
 
     echo ${packet} >> ${outfile}
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
+    check as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
 }
 
 #
@@ -16795,7 +16918,7 @@ send_ip_multicast_pkt() {
     local ip=450000${ip_len}95f14000${ip_ttl}${proto}${ip_chksum}${ip_src}${ip_dst}
     local packet=${eth}${ip}${data}
 
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
+    check as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
 }
 
 #
@@ -16842,11 +16965,11 @@ ovn-nbctl lsp-add sw1 sw1-rtr                      \
     -- lsp-set-type sw1-rtr router                 \
     -- lsp-set-addresses sw1-rtr 00:00:00:00:01:00 \
     -- lsp-set-options sw1-rtr router-port=rtr-sw1
-ovn-nbctl lsp-add sw2 sw2-rtr                      \
+check ovn-nbctl lsp-add sw2 sw2-rtr                \
     -- lsp-set-type sw2-rtr router                 \
     -- lsp-set-addresses sw2-rtr 00:00:00:00:02:00 \
     -- lsp-set-options sw2-rtr router-port=rtr-sw2
-ovn-nbctl lsp-add sw3 sw3-rtr                      \
+check ovn-nbctl lsp-add sw3 sw3-rtr                \
     -- lsp-set-type sw3-rtr router                 \
     -- lsp-set-addresses sw3-rtr 00:00:00:00:03:00 \
     -- lsp-set-options sw3-rtr router-port=rtr-sw3
@@ -16854,24 +16977,24 @@ ovn-nbctl lsp-add sw3 sw3-rtr                      \
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw1-p11 \
     options:tx_pcap=hv1/vif1-tx.pcap \
     options:rxq_pcap=hv1/vif1-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw1-p12 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
+check ovs-vsctl -- add-port br-int hv1-vif3 -- \
     set interface hv1-vif3 external-ids:iface-id=sw2-p1 \
     options:tx_pcap=hv1/vif3-tx.pcap \
     options:rxq_pcap=hv1/vif3-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif4 -- \
+check ovs-vsctl -- add-port br-int hv1-vif4 -- \
     set interface hv1-vif4 external-ids:iface-id=sw3-p1 \
     options:tx_pcap=hv1/vif4-tx.pcap \
     options:rxq_pcap=hv1/vif4-rx.pcap \
@@ -16880,24 +17003,24 @@ ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
+check ovs-vsctl -- add-port br-int hv2-vif1 -- \
     set interface hv2-vif1 external-ids:iface-id=sw1-p21 \
     options:tx_pcap=hv2/vif1-tx.pcap \
     options:rxq_pcap=hv2/vif1-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif2 -- \
+check ovs-vsctl -- add-port br-int hv2-vif2 -- \
     set interface hv2-vif2 external-ids:iface-id=sw1-p22 \
     options:tx_pcap=hv2/vif2-tx.pcap \
     options:rxq_pcap=hv2/vif2-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif3 -- \
+check ovs-vsctl -- add-port br-int hv2-vif3 -- \
     set interface hv2-vif3 external-ids:iface-id=sw2-p2 \
     options:tx_pcap=hv2/vif3-tx.pcap \
     options:rxq_pcap=hv2/vif3-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif4 -- \
+check ovs-vsctl -- add-port br-int hv2-vif4 -- \
     set interface hv2-vif4 external-ids:iface-id=sw3-p2 \
     options:tx_pcap=hv2/vif4-tx.pcap \
     options:rxq_pcap=hv2/vif4-rx.pcap \
@@ -16911,15 +17034,32 @@ check ovn-nbctl --wait=hv set Logical_Switch sw1       \
     other_config:mcast_querier="false" \
     other_config:mcast_snoop="true"
 
+AT_CAPTURE_FILE([sbflows])
+cp ovn-sb/ovn-sb.db ovn-sb.db
+ovn-sbctl dump-flows > sbflows
+
 # No IGMP query should be generated by sw1 (mcast_querier="false").
+# (Therefore everything is expected to be empty.)
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
 > expected
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
+> received
+for i in 1 2; do
+    for j in 1 2; do
+        pcap=hv$i/vif$j-tx.pcap
+        echo "--- $pcap" | tee -a expected >> received
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | sort >> received
+        echo | tee -a expected >> received
+    done
+done
+check $at_diff -F'^---' expected received
 
 check ovn-nbctl --wait=hv sync
 
+AT_CAPTURE_FILE([sbflows2])
+cp ovn-sb/ovn-sb.db ovn-sb2.db
+ovn-sbctl dump-flows > sbflows2
+
 # Inject IGMP Join for 239.0.1.68 on sw1-p11.
 send_igmp_v3_report hv1-vif1 hv1 \
     000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
@@ -16931,12 +17071,13 @@ send_igmp_v3_report hv2-vif1 hv2 000000000002 $(ip_to_hex 10 0 0 2) f9f9 \
     /dev/null
 
 # Check that the IGMP Group is learned on both hv.
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
-    test "${total_entries}" = "2"
-])
+wait_row_count IGMP_Group 2 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
+AT_CAPTURE_FILE([sbflows3])
+cp ovn-sb/ovn-sb.db ovn-sb3.db
+ovn-sbctl dump-flows > sbflows3
+
 # Send traffic and make sure it gets forwarded only on the two ports that
 # joined.
 > expected
@@ -16950,12 +17091,30 @@ store_ip_multicast_pkt \
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
     e518e518000a3b3a0000 expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
+AT_CAPTURE_FILE([exp])
+AT_CAPTURE_FILE([rcv])
+check_packets() {
+    > exp
+    > rcv
+    for tuple in "$@"; do
+        set $tuple; pcap=$1 type=$2
+        echo "--- $pcap" | tee -a exp >> rcv
+        sort "$type" >> exp
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | sort >> rcv
+        echo | tee -a exp >> rcv
+    done
+
+    $at_diff exp rcv >/dev/null
+}
+
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Inject IGMP Leave for 239.0.1.68 on sw1-p11.
 send_igmp_v3_report hv1-vif1 hv1 \
@@ -16981,15 +17140,17 @@ store_ip_multicast_pkt \
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
     e518e518000a3b3a0000 expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Flush IGMP groups.
-ovn-sbctl ip-multicast-flush sw1
+check ovn-sbctl ip-multicast-flush sw1
 wait_row_count IGMP_Group 0 address=239.0.1.68
 check ovn-nbctl --wait=hv sync
 
@@ -17019,12 +17180,14 @@ store_ip_multicast_pkt \
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 224 0 0 42) 1e 01 f989 11 \
     e518e518000a4b540000 expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv2/vif2-tx.pcap expected'],
+  [$at_diff -F'^---' exp rcv])
 
 # Enable IGMP snooping and querier on sw2 and set query interval to minimum.
-ovn-nbctl set Logical_Switch sw2 \
+check ovn-nbctl set Logical_Switch sw2 \
     other_config:mcast_snoop="true" \
     other_config:mcast_querier="true" \
     other_config:mcast_query_interval=1 \
@@ -17036,16 +17199,17 @@ ovn-nbctl set Logical_Switch sw2 \
 store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
 store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
 
-sleep 1
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif3-tx.pcap expected' \
+                 'hv2/vif3-tx.pcap expected'],
+  [$at_diff -F'^---' exp rcv])
 
 # Disable IGMP querier on sw2.
-ovn-nbctl set Logical_Switch sw2 \
+check ovn-nbctl set Logical_Switch sw2 \
     other_config:mcast_querier="false"
 
 # Enable IGMP snooping on sw3.
-ovn-nbctl set Logical_Switch sw3       \
+check ovn-nbctl set Logical_Switch sw3       \
     other_config:mcast_querier="false" \
     other_config:mcast_snoop="true"
 
@@ -17070,17 +17234,19 @@ send_ip_multicast_pkt hv2-vif4 hv2 \
 
 # Sleep a bit to make sure no traffic is received and then check.
 sleep 1
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_empty' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Enable IGMP relay on rtr
-ovn-nbctl set logical_router rtr \
+check ovn-nbctl set logical_router rtr \
     options:mcast_relay="true"
 
 # Inject IGMP Join for 239.0.1.68 on sw1-p11.
@@ -17126,14 +17292,16 @@ store_ip_multicast_pkt \
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 1f cb70 11 \
     e518e518000a3b3a0000 expected_routed_sw2
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_routed_sw1])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_routed_sw2])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_routed_sw1' \
+                 'hv2/vif3-tx.pcap expected_routed_sw2' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Inject IGMP Join for 239.0.1.68 on sw3-p1.
 send_igmp_v3_report hv1-vif4 hv1 \
@@ -17193,14 +17361,16 @@ store_ip_multicast_pkt \
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 1f cb70 11 \
     e518e518000a3b3a0000 expected_routed_sw2
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_routed_sw1])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_routed_sw2])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_routed_sw1' \
+                 'hv2/vif3-tx.pcap expected_routed_sw2' \
+                 'hv1/vif4-tx.pcap expected_switched' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Flush IGMP groups.
 ovn-sbctl ip-multicast-flush sw1
@@ -17269,14 +17439,18 @@ store_ip_multicast_pkt \
 # Check that traffic is switched to sw1-p11 and sw1-p12
 # Check that IGMP join is flooded on sw1-p21
 # Check that traffic is routed by rtr to rtr-sw2 and then switched to sw2-p1
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_routed])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_reports])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_switched' \
+                 'hv1/vif2-tx.pcap expected_switched' \
+                 'hv1/vif3-tx.pcap expected_routed' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_reports' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # With ovn-monitor-all=true, make sure ovn-controllers don't delete each
 # other's IGMP_Group records.
@@ -17345,10 +17519,10 @@ ovn_start
 reset_pcap_file() {
     local iface=$1
     local pcap_file=$2
-    ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
+    check 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 \
+    check ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
 options:rxq_pcap=${pcap_file}-rx.pcap
 }
 
@@ -17385,7 +17559,7 @@ send_mld_v2_report() {
     local packet=${eth}${ip}${mld}
 
     echo ${packet} >> ${outfile}
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
+    check as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
 }
 
 #
@@ -17432,7 +17606,7 @@ send_ip_multicast_pkt() {
     local ip=60000000${ip_len}${proto}${ip_ttl}${ip_src}${ip_dst}
     local packet=${eth}${ip}${data}
 
-    as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
+    check as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
 }
 
 #
@@ -17479,11 +17653,11 @@ ovn-nbctl lsp-add sw1 sw1-rtr                      \
     -- lsp-set-type sw1-rtr router                 \
     -- lsp-set-addresses sw1-rtr 00:00:00:00:01:00 \
     -- lsp-set-options sw1-rtr router-port=rtr-sw1
-ovn-nbctl lsp-add sw2 sw2-rtr                      \
+check ovn-nbctl lsp-add sw2 sw2-rtr                \
     -- lsp-set-type sw2-rtr router                 \
     -- lsp-set-addresses sw2-rtr 00:00:00:00:02:00 \
     -- lsp-set-options sw2-rtr router-port=rtr-sw2
-ovn-nbctl lsp-add sw3 sw3-rtr                      \
+check ovn-nbctl lsp-add sw3 sw3-rtr                \
     -- lsp-set-type sw3-rtr router                 \
     -- lsp-set-addresses sw3-rtr 00:00:00:00:03:00 \
     -- lsp-set-options sw3-rtr router-port=rtr-sw3
@@ -17506,24 +17680,24 @@ ovn-nbctl ls-lb-add sw3 lb0
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw1-p11 \
     options:tx_pcap=hv1/vif1-tx.pcap \
     options:rxq_pcap=hv1/vif1-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw1-p12 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif3 -- \
+check ovs-vsctl -- add-port br-int hv1-vif3 -- \
     set interface hv1-vif3 external-ids:iface-id=sw2-p1 \
     options:tx_pcap=hv1/vif3-tx.pcap \
     options:rxq_pcap=hv1/vif3-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif4 -- \
+check ovs-vsctl -- add-port br-int hv1-vif4 -- \
     set interface hv1-vif4 external-ids:iface-id=sw3-p1 \
     options:tx_pcap=hv1/vif4-tx.pcap \
     options:rxq_pcap=hv1/vif4-rx.pcap \
@@ -17532,46 +17706,77 @@ ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
+check ovs-vsctl -- add-port br-int hv2-vif1 -- \
     set interface hv2-vif1 external-ids:iface-id=sw1-p21 \
     options:tx_pcap=hv2/vif1-tx.pcap \
     options:rxq_pcap=hv2/vif1-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif2 -- \
+check ovs-vsctl -- add-port br-int hv2-vif2 -- \
     set interface hv2-vif2 external-ids:iface-id=sw1-p22 \
     options:tx_pcap=hv2/vif2-tx.pcap \
     options:rxq_pcap=hv2/vif2-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif3 -- \
+check ovs-vsctl -- add-port br-int hv2-vif3 -- \
     set interface hv2-vif3 external-ids:iface-id=sw2-p2 \
     options:tx_pcap=hv2/vif3-tx.pcap \
     options:rxq_pcap=hv2/vif3-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv2-vif4 -- \
+check ovs-vsctl -- add-port br-int hv2-vif4 -- \
     set interface hv2-vif4 external-ids:iface-id=sw3-p2 \
     options:tx_pcap=hv2/vif4-tx.pcap \
     options:rxq_pcap=hv2/vif4-rx.pcap \
     ofport-request=1
 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 
+check ovn-nbctl --wait=hv sync
+
+AT_CAPTURE_FILE([sbflows])
+ovn-sbctl dump-flows > sbflows
+
+AT_CAPTURE_FILE([exp])
+AT_CAPTURE_FILE([rcv])
+check_packets() {
+    > exp
+    > rcv
+    if test "$1" = --uniq; then
+        sort="sort -u"; shift
+    else
+        sort=sort
+    fi
+    for tuple in "$@"; do
+        set $tuple; pcap=$1 type=$2
+        echo "--- $pcap" | tee -a exp >> rcv
+        $sort "$type" >> exp
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | $sort >> rcv
+        echo | tee -a exp >> rcv
+    done
+
+    $at_diff exp rcv # >/dev/null
+}
+
 OVN_POPULATE_ARP
 
 # Enable multicast snooping on sw1.
-ovn-nbctl set Logical_Switch sw1       \
+check ovn-nbctl --wait=hv set Logical_Switch sw1 \
     other_config:mcast_querier="false" \
     other_config:mcast_snoop="true"
 
 # No IGMP/MLD query should be generated by sw1 (mcast_querier="false").
 > expected
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected' \
+                 'hv1/vif2-tx.pcap expected' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv2/vif2-tx.pcap expected'],
+  [$at_diff -F'^---' exp rcv])
 
 check ovn-nbctl --wait=hv sync
 
+AT_CAPTURE_FILE([sbflows2])
+ovn-sbctl dump-flows > sbflows2
+
 # Inject MLD Join for ff0a:dead:beef::1 on sw1-p11.
 send_mld_v2_report hv1-vif1 hv1 \
     000000000001 10000000000000000000000000000001 \
@@ -17589,6 +17794,9 @@ wait_row_count IGMP_Group 2 address='"ff0a:dead:beef::1"'
 # This gives the ovn-controller nodes a chance to see the new IGMP_Group.
 check ovn-nbctl --wait=hv sync
 
+AT_CAPTURE_FILE([sbflows3])
+ovn-sbctl dump-flows > sbflows3
+
 # Send traffic and make sure it gets forwarded only on the two ports that
 # joined.
 > expected
@@ -17606,12 +17814,14 @@ store_ip_multicast_pkt \
     93407a69000e1b5e61736461640a \
     expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Inject MLD Leave for ff0a:dead:beef::1 on sw1-p11.
 send_mld_v2_report hv1-vif1 hv1 \
@@ -17640,15 +17850,17 @@ store_ip_multicast_pkt \
     93407a69000e1b5e61736461640a \
     expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Flush IP multicast groups.
-ovn-sbctl ip-multicast-flush sw1
+check ovn-sbctl ip-multicast-flush sw1
 wait_row_count IGMP_Group 0 address='"ff0a:dead:beef::1"'
 
 # Check that traffic for "all-hosts" is flooded even if some hosts register
@@ -17680,9 +17892,11 @@ store_ip_multicast_pkt \
     93407a69000eb90361736461640a \
     expected
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected' \
+                 'hv2/vif1-tx.pcap expected' \
+                 'hv2/vif2-tx.pcap expected'],
+  [$at_diff -F'^---' exp rcv])
 
 # Enable multicast snooping and querier on sw2 and set query interval to
 # minimum.
@@ -17693,16 +17907,31 @@ check ovn-nbctl --wait=hv set Logical_Switch sw2 \
     other_config:mcast_eth_src="00:00:00:00:02:fe" \
     other_config:mcast_ip6_src="fe80::fe"
 
-# Wait for 1 query interval (1 sec) and check that two queries are generated.
+AT_CAPTURE_FILE([sbflows4])
+ovn-sbctl dump-flows > sbflows4
+
+# Check that multiple queries are generated over time.
 > expected
 store_mld_query 0000000002fe fe8000000000000000000000000000fe expected
 store_mld_query 0000000002fe fe8000000000000000000000000000fe expected
-
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected])
+for count in 1 2 3; do
+    as hv1 reset_pcap_file hv1-vif1 hv1/vif1
+    as hv1 reset_pcap_file hv1-vif2 hv1/vif2
+    as hv1 reset_pcap_file hv1-vif3 hv1/vif3
+    as hv1 reset_pcap_file hv1-vif4 hv1/vif4
+    as hv2 reset_pcap_file hv2-vif1 hv2/vif1
+    as hv2 reset_pcap_file hv2-vif2 hv2/vif2
+    as hv2 reset_pcap_file hv2-vif3 hv2/vif3
+    as hv2 reset_pcap_file hv2-vif4 hv2/vif4
+    OVS_WAIT_UNTIL(
+      [check_packets --uniq \
+                     'hv1/vif3-tx.pcap expected' \
+                     'hv2/vif3-tx.pcap expected'],
+      [$at_diff -F'^---' exp rcv])
+done
 
 # Disable multicast querier on sw2.
-ovn-nbctl set Logical_Switch sw2 \
+check ovn-nbctl set Logical_Switch sw2 \
     other_config:mcast_querier="false"
 
 # Enable multicast snooping on sw3.
@@ -17710,6 +17939,9 @@ check ovn-nbctl --wait=sb set Logical_Switch sw3       \
     other_config:mcast_querier="false" \
     other_config:mcast_snoop="true"
 
+AT_CAPTURE_FILE([sbflows5])
+ovn-sbctl dump-flows > sbflows5
+
 # Send traffic from sw3 and make sure rtr doesn't relay it.
 > expected_empty
 
@@ -17730,18 +17962,23 @@ send_ip_multicast_pkt hv2-vif4 hv2 \
 
 # Sleep a bit to make sure no traffic is received and then check.
 sleep 1
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_empty' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Enable multicast relay on rtr
 check ovn-nbctl --wait=sb set logical_router rtr options:mcast_relay="true"
 
+AT_CAPTURE_FILE([sbflows6])
+ovn-sbctl dump-flows > sbflows6
+
 # Inject MLD Join for ff0a:dead:beef::1 on sw1-p11.
 send_mld_v2_report hv1-vif1 hv1 \
     000000000001 10000000000000000000000000000001 \
@@ -17790,14 +18027,16 @@ store_ip_multicast_pkt \
     93407a69000e1b5e61736461640a \
     expected_routed_sw2
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_routed_sw1])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_routed_sw2])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_routed_sw1' \
+                 'hv2/vif3-tx.pcap expected_routed_sw2' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Inject MLD Join for 239.0.1.68 on sw3-p1.
 send_mld_v2_report hv1-vif4 hv1 \
@@ -17864,23 +18103,22 @@ store_ip_multicast_pkt \
     93407a69000e1b5e61736461640a \
     expected_routed_sw2
 
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_routed_sw1])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_routed_sw2])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_routed_sw1' \
+                 'hv2/vif3-tx.pcap expected_routed_sw2' \
+                 'hv1/vif4-tx.pcap expected_switched' \
+                 'hv1/vif2-tx.pcap expected_empty' \
+                 'hv1/vif3-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_empty' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 # Flush multicast groups.
-ovn-sbctl ip-multicast-flush sw1
-ovn-sbctl ip-multicast-flush sw2
-ovn-sbctl ip-multicast-flush sw3
-OVS_WAIT_UNTIL([
-    total_entries=`ovn-sbctl find IGMP_Group | grep "ff0a:dead:beef::1" -c`
-    test "${total_entries}" = "0"
-])
+check ovn-sbctl ip-multicast-flush sw1
+check ovn-sbctl ip-multicast-flush sw2
+check ovn-sbctl ip-multicast-flush sw3
+wait_row_count IGMP_Group 0 address='"ff0a:dead:beef::1"'
 
 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
 as hv1 reset_pcap_file hv1-vif2 hv1/vif2
@@ -17897,16 +18135,16 @@ as hv2 reset_pcap_file hv2-vif4 hv2/vif4
 > expected_reports
 
 # Enable mcast_flood on sw1-p11
-ovn-nbctl set Logical_Switch_Port sw1-p11 options:mcast_flood='true'
+check ovn-nbctl set Logical_Switch_Port sw1-p11 options:mcast_flood='true'
 
 # Enable mcast_flood_reports on sw1-p21
-ovn-nbctl set Logical_Switch_Port sw1-p21 options:mcast_flood_reports='true'
+check ovn-nbctl set Logical_Switch_Port sw1-p21 options:mcast_flood_reports='true'
 # Enable mcast_flood on rtr-sw2
-ovn-nbctl set Logical_Router_Port rtr-sw2 options:mcast_flood='true'
+check ovn-nbctl set Logical_Router_Port rtr-sw2 options:mcast_flood='true'
 # Enable mcast_flood on sw2-p1
-ovn-nbctl set Logical_Switch_Port sw2-p1 options:mcast_flood='true'
+check ovn-nbctl set Logical_Switch_Port sw2-p1 options:mcast_flood='true'
 
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
 
 # Inject MLD Join for ff0a:dead:beef::1 on sw1-p12.
 send_mld_v2_report hv1-vif2 hv1 \
@@ -17940,17 +18178,22 @@ store_ip_multicast_pkt \
 # Sleep a bit to make sure no duplicate traffic is received
 sleep 1
 
+AT_CAPTURE_FILE([sbflows7])
+ovn-sbctl dump-flows > sbflows7
+
 # Check that traffic is switched to sw1-p11 and sw1-p12
 # Check that MLD join is flooded on sw1-p21
 # Check that traffic is routed by rtr to rtr-sw2 and then switched to sw2-p1
-OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_switched])
-OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_routed])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_reports])
-OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+OVS_WAIT_UNTIL(
+  [check_packets 'hv1/vif1-tx.pcap expected_switched' \
+                 'hv1/vif2-tx.pcap expected_switched' \
+                 'hv1/vif3-tx.pcap expected_routed' \
+                 'hv1/vif4-tx.pcap expected_empty' \
+                 'hv2/vif1-tx.pcap expected_reports' \
+                 'hv2/vif2-tx.pcap expected_empty' \
+                 'hv2/vif3-tx.pcap expected_empty' \
+                 'hv2/vif4-tx.pcap expected_empty'],
+  [$at_diff -F'^---' exp rcv])
 
 OVN_CLEANUP([hv1], [hv2])
 AT_CLEANUP
@@ -17976,7 +18219,8 @@ AT_CLEANUP
 
 
 m4_define([DVR_N_S_ARP_HANDLING],
-  [AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S ARP handling, encap $1])
+  [OVN_FOR_EACH_NORTHD([
+   AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S ARP handling, encap $1])
    set -x
    encap=$1
    ovn_start
@@ -18171,29 +18415,26 @@ m4_define([DVR_N_S_ARP_HANDLING],
 
    # Dump a bunch of info helpful for debugging if there's a failure.
 
-   echo "------ OVN dump ------"
-   ovn-nbctl show
-   ovn-sbctl show
-   ovn-sbctl list port_binding
-   ovn-sbctl list mac_binding
+   ovn-sbctl dump-flows > sbflows
+   AT_CAPTURE_FILE([sbflows])
 
-   echo "------ hv1 dump ------"
-   as hv1 ovs-vsctl show
-   as hv1 ovs-vsctl list Open_Vswitch
+   (ovn-nbctl show
+    ovn-sbctl show
+    ovn-sbctl list port_binding
+    ovn-sbctl list mac_binding) > ovndump
+   AT_CAPTURE_FILE([ovndump])
 
-   echo "------ hv2 dump ------"
-   as hv2 ovs-vsctl show
-   as hv2 ovs-vsctl list Open_Vswitch
+   (as hv1 ovs-vsctl show; as hv1 ovs-vsctl list Open_Vswitch) > hv1dump
+   AT_CAPTURE_FILE([hv1dump])
 
-   echo "------ hv3 dump ------"
-   as hv3 ovs-vsctl show
-   as hv3 ovs-vsctl list Open_Vswitch
+   (as hv2 ovs-vsctl show; as hv2 ovs-vsctl list Open_Vswitch) > hv2dump
+   AT_CAPTURE_FILE([hv2dump])
 
-   echo "------ hv4 dump ------"
-   as hv4 ovs-vsctl show
-   as hv4 ovs-vsctl list Open_Vswitch
+   (as hv3 ovs-vsctl show; as hv3 ovs-vsctl list Open_Vswitch) > hv3dump
+   AT_CAPTURE_FILE([hv3dump])
 
-   OVS_WAIT_UNTIL([test x`ovn-sbctl --bare --columns chassis find port_binding  logical_port=cr-router-to-underlay | wc -l` = x1])
+   (as hv4 ovs-vsctl show; as hv4 ovs-vsctl list Open_Vswitch) > hv4dump
+   AT_CAPTURE_FILE([hv4dump])
 
    test_arp vif-north f0f000000011 $sip $tip 000001010207
 
@@ -18214,13 +18455,14 @@ m4_define([DVR_N_S_ARP_HANDLING],
 
    # validate max_tunid reflects the type of encapsulation used
    max_tunid=`ovn-nbctl get NB_Global . options:max_tunid | sed s/":"//g | sed s/\"//g`
-   echo $max_tunid
    if [[ $encap = vxlan ]]; then
        max_tunid_expected=4095
    else
        max_tunid_expected=16711680
    fi
-   AT_CHECK([test $max_tunid -eq $max_tunid_expected])
+   echo max_tunid=$max_tunid max_tunid_expected=$max_tunid_expected
+   AT_CHECK([test -n "$max_tunid"])
+   AT_CHECK([test "$max_tunid" -eq "$max_tunid_expected"])
 
    echo "----------- Post Traffic hv1 dump -----------"
    as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
@@ -18240,13 +18482,14 @@ m4_define([DVR_N_S_ARP_HANDLING],
 
    OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
 
-   AT_CLEANUP])
+   AT_CLEANUP])])
 
 DVR_N_S_ARP_HANDLING([geneve])
 DVR_N_S_ARP_HANDLING([vxlan])
 
 m4_define([DVR_N_S_PING],
-  [AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S Ping, encap $1])
+  [OVN_FOR_EACH_NORTHD([
+   AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR N-S Ping, encap $1])
    AT_KEYWORDS([$1])
    encap=$1
    ovn_start
@@ -18541,7 +18784,7 @@ m4_define([DVR_N_S_PING],
 
    OVN_CLEANUP([hv1],[hv2],[hv3],[hv4])
 
-   AT_CLEANUP])
+   AT_CLEANUP])])
 
 DVR_N_S_PING([geneve])
 DVR_N_S_PING([vxlan])
@@ -19086,17 +19329,14 @@ test_ip vif11 f00000000011 000001010203 $sip $dip vif-north
 OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected])
 
 # Confirm that NATing happened without connection tracker
-
-AT_CHECK([ovn-sbctl dump-flows router | grep ct_snat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows router | grep ct_dnat | wc -l], [0], [0
-])
-
-AT_CHECK([ovn-sbctl dump-flows router | grep ip4.dst=| wc -l], [0], [2
-])
-
-AT_CHECK([ovn-sbctl dump-flows router | grep ip4.src=| wc -l], [0], [2
+ovn-sbctl dump-flows router > sbflows
+AT_CAPTURE_FILE([sbflows])
+AT_CHECK([for regex in ct_snat ct_dnat ip4.dst= ip4.src=; do
+  grep -c "$regex" sbflows;
+done], [0], [0
+0
+2
+2
 ])
 
 echo "----------- Post Traffic hv1 dump -----------"
@@ -19136,12 +19376,12 @@ 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 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
     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 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw0-p2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
@@ -19149,107 +19389,104 @@ ovs-vsctl -- add-port br-int hv1-vif2 -- \
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
-ovs-vsctl -- add-port br-int hv2-vif1 -- \
+check ovs-vsctl -- add-port br-int hv2-vif1 -- \
     set interface hv2-vif1 external-ids:iface-id=sw1-p1 \
     options:tx_pcap=hv2/vif1-tx.pcap \
     options:rxq_pcap=hv2/vif1-rx.pcap \
     ofport-request=1
 
-ovn-nbctl ls-add sw0
-
-ovn-nbctl lsp-add sw0 sw0-p1
-ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3"
-ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3"
+check ovn-nbctl ls-add sw0
 
-ovn-nbctl lsp-set-addresses sw0-p2 "50:54:00:00:00:04 10.0.0.4"
-ovn-nbctl lsp-set-port-security sw0-p2 "50:54:00:00:00:04 10.0.0.4"
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3"
+check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3"
 
 # Create port group and ACLs for sw0 ports.
-ovn-nbctl pg-add pg0_drop sw0-p1 sw0-p2
-ovn-nbctl acl-add pg0_drop from-lport 1001 "inport == @pg0_drop && ip" drop
-ovn-nbctl acl-add pg0_drop to-lport 1001 "outport == @pg0_drop && ip" drop
-
-ovn-nbctl pg-add pg0 sw0-p1 sw0-p2
-ovn-nbctl acl-add pg0 from-lport 1002 "inport == @pg0 && ip4" allow-related
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && ip4.src == 0.0.0.0/0 && icmp4" allow-related
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && ip4.src == 0.0.0.0/0 && tcp && tcp.dst == 80" allow-related
-ovn-nbctl acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 && ip4.src == 0.0.0.0/0 && udp && udp.dst == 80" allow-related
+check ovn-nbctl pg-add pg0_drop sw0-p1
+check ovn-nbctl acl-add pg0_drop from-lport 1001 "inport == @pg0_drop && ip" drop
+check ovn-nbctl acl-add pg0_drop to-lport 1001 "outport == @pg0_drop && ip" drop
 
 # Create the second logical switch with one port
-ovn-nbctl ls-add sw1
-ovn-nbctl lsp-add sw1 sw1-p1
-ovn-nbctl lsp-set-addresses sw1-p1 "40:54:00:00:00:03 20.0.0.3"
-ovn-nbctl lsp-set-port-security sw1-p1 "40:54:00:00:00:03 20.0.0.3"
+check ovn-nbctl ls-add sw1
+check ovn-nbctl lsp-add sw1 sw1-p1
+check ovn-nbctl lsp-set-addresses sw1-p1 "40:54:00:00:00:03 20.0.0.3"
+check ovn-nbctl lsp-set-port-security sw1-p1 "40:54:00:00:00:03 20.0.0.3"
 
 # Create port group and ACLs for sw1 ports.
-ovn-nbctl pg-add pg1_drop sw1-p1
-ovn-nbctl acl-add pg1_drop from-lport 1001 "inport == @pg1_drop && ip" drop
-ovn-nbctl acl-add pg1_drop to-lport 1001 "outport == @pg1_drop && ip" drop
+check ovn-nbctl pg-add pg1_drop sw1-p1
+check ovn-nbctl acl-add pg1_drop from-lport 1001 "inport == @pg1_drop && ip" drop
+check ovn-nbctl acl-add pg1_drop to-lport 1001 "outport == @pg1_drop && ip" drop
 
-ovn-nbctl pg-add pg1 sw1-p1
-ovn-nbctl acl-add pg1 from-lport 1002 "inport == @pg1 && ip4" allow-related
-ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && icmp4" allow-related
-ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && tcp && tcp.dst == 80" allow-related
-ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && udp && udp.dst == 80" allow-related
+check ovn-nbctl pg-add pg1 sw1-p1
+check ovn-nbctl acl-add pg1 from-lport 1002 "inport == @pg1 && ip4" allow-related
+check ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && icmp4" allow-related
+check ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && tcp && tcp.dst == 80" allow-related
+check ovn-nbctl acl-add pg1 to-lport 1002 "outport == @pg1 && ip4 && ip4.src == 0.0.0.0/0 && udp && udp.dst == 80" allow-related
 
 # Create a logical router and attach both logical switches
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
-ovn-nbctl lsp-add sw0 sw0-lr0
-ovn-nbctl lsp-set-type sw0-lr0 router
-ovn-nbctl lsp-set-addresses sw0-lr0 router
-ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
+check ovn-nbctl lr-add lr0
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
+check ovn-nbctl lsp-add sw0 sw0-lr0
+check ovn-nbctl lsp-set-type sw0-lr0 router
+check ovn-nbctl lsp-set-addresses sw0-lr0 router
+check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
 
-ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 20.0.0.1/24
-ovn-nbctl lsp-add sw1 sw1-lr0
-ovn-nbctl lsp-set-type sw1-lr0 router
-ovn-nbctl lsp-set-addresses sw1-lr0 router
-ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1
+check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 20.0.0.1/24
+check ovn-nbctl lsp-add sw1 sw1-lr0
+check ovn-nbctl lsp-set-type sw1-lr0 router
+check ovn-nbctl lsp-set-addresses sw1-lr0 router
+check ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1
 
-ovn-nbctl lb-add lb1 10.0.0.10:80 10.0.0.3:80,20.0.0.3:80
+check ovn-nbctl lb-add lb1 10.0.0.10:80 10.0.0.3:80,20.0.0.3:80
 
-ovn-nbctl --wait=sb set load_balancer . ip_port_mappings:10.0.0.3=sw0-p1:10.0.0.2
-ovn-nbctl --wait=sb set load_balancer . ip_port_mappings:20.0.0.3=sw1-p1:20.0.0.2
+check ovn-nbctl --wait=sb set load_balancer . ip_port_mappings:10.0.0.3=sw0-p1:10.0.0.2
+check ovn-nbctl --wait=sb set load_balancer . ip_port_mappings:20.0.0.3=sw1-p1:20.0.0.2
 
-ovn-nbctl --wait=sb -- --id=@hc create \
-Load_Balancer_Health_Check vip="10.0.0.10\:80" -- add Load_Balancer . \
-health_check @hc
+AT_CHECK([ovn-nbctl --wait=sb \
+          -- --id=@hc create Load_Balancer_Health_Check vip="10.0.0.10\:80" \
+             options:failure_count=100 \
+          -- add Load_Balancer . health_check @hc | uuidfilt], [0], [<0>
+])
 
-ovn-nbctl --wait=sb ls-lb-add sw0 lb1
-ovn-nbctl --wait=sb ls-lb-add sw1 lb1
-ovn-nbctl --wait=sb lr-lb-add lr0 lb1
+check ovn-nbctl --wait=sb ls-lb-add sw0 lb1
+check ovn-nbctl --wait=sb ls-lb-add sw1 lb1
+check ovn-nbctl --wait=sb lr-lb-add lr0 lb1
 
-ovn-nbctl ls-add public
-ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
-ovn-nbctl lsp-add public public-lr0
-ovn-nbctl lsp-set-type public-lr0 router
-ovn-nbctl lsp-set-addresses public-lr0 router
-ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
+check ovn-nbctl ls-add public
+check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
+check ovn-nbctl lsp-add public public-lr0
+check ovn-nbctl lsp-set-type public-lr0 router
+check ovn-nbctl lsp-set-addresses public-lr0 router
+check ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
 
 # localnet port
-ovn-nbctl lsp-add public ln-public
-ovn-nbctl lsp-set-type ln-public localnet
-ovn-nbctl lsp-set-addresses ln-public unknown
-ovn-nbctl lsp-set-options ln-public network_name=public
+check ovn-nbctl lsp-add public ln-public
+check ovn-nbctl lsp-set-type ln-public localnet
+check ovn-nbctl lsp-set-addresses ln-public unknown
+check ovn-nbctl lsp-set-options ln-public network_name=public
 
 # schedule the gw router port to a chassis. Change the name of the chassis
-ovn-nbctl --wait=hv lrp-set-gateway-chassis lr0-public hv1 20
+check ovn-nbctl --wait=hv lrp-set-gateway-chassis lr0-public hv1 20
 
 OVN_POPULATE_ARP
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
 
 wait_row_count Service_Monitor 2
 
-ovn-sbctl dump-flows sw0 | grep ct_lb | grep priority=120 > lflows.txt
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=11(ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
+AT_CAPTURE_FILE([sbflows])
+OVS_WAIT_FOR_OUTPUT(
+  [ovn-sbctl dump-flows > sbflows
+   ovn-sbctl dump-flows sw0 | grep ct_lb | grep priority=120 | sed 's/table=..//'], 0,
+  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
-ovn-sbctl dump-flows lr0 | grep ct_lb | grep priority=120 > lflows.txt
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=6 (lr_in_dnat         ), priority=120  , match=(ct.new && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
+AT_CAPTURE_FILE([sbflows2])
+OVS_WAIT_FOR_OUTPUT(
+  [ovn-sbctl dump-flows > sbflows2
+   ovn-sbctl dump-flows lr0 | grep ct_lb | grep priority=120 | sed 's/table=..//'], 0,
+  [  (lr_in_dnat         ), priority=120  , match=(ct.new && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
 ])
 
 # get the svc monitor mac.
@@ -19266,6 +19503,7 @@ OVS_WAIT_UNTIL(
 grep "405400000003${svc_mon_src_mac}" | wc -l`]
 )
 
+check ovn-nbctl set load_balancer_health_check 10.0.0.10:80 options:failure_count=1
 wait_row_count Service_Monitor 2 status=offline
 
 OVS_WAIT_UNTIL(
@@ -19278,37 +19516,39 @@ OVS_WAIT_UNTIL(
 grep "405400000003${svc_mon_src_mac}" | wc -l`]
 )
 
-ovn-sbctl dump-flows sw0 | grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" \
-| grep priority=120 > lflows.txt
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=11(ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(drop;)
+AT_CAPTURE_FILE([sbflows3])
+ovn-sbctl dump-flows sw0 > sbflows3
+AT_CHECK(
+  [grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" sbflows3 | grep priority=120 |\
+   sed 's/table=../table=??/'], [0],
+  [  table=??(ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(drop;)
 ])
 
-ovn-sbctl dump-flows lr0 | grep lr_in_dnat | grep priority=120 > lflows.txt
-AT_CHECK([cat lflows.txt], [0], [dnl
-  table=6 (lr_in_dnat         ), priority=120  , match=(ct.est && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;)
-  table=6 (lr_in_dnat         ), priority=120  , match=(ct.new && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(drop;)
+AT_CAPTURE_FILE([sbflows4])
+ovn-sbctl dump-flows lr0 > sbflows4
+AT_CHECK([grep lr_in_dnat sbflows4 | grep priority=120 | sed 's/table=..//'], [0], [dnl
+  (lr_in_dnat         ), priority=120  , match=(ct.est && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_dnat;)
+  (lr_in_dnat         ), priority=120  , match=(ct.new && ip && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 && is_chassis_resident("cr-lr0-public")), action=(drop;)
 ])
 
 # Delete sw0-p1
-ovn-nbctl lsp-del sw0-p1
+check ovn-nbctl lsp-del sw0-p1
 
 wait_row_count Service_Monitor 1
 
 # Add back sw0-p1 but without any IP address.
-ovn-nbctl lsp-add sw0 sw0-p1
-ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03" -- \
-lsp-set-port-security sw0-p1 "50:54:00:00:00:03"
+check ovn-nbctl lsp-add sw0 sw0-p1
+check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03" -- \
+    lsp-set-port-security sw0-p1 "50:54:00:00:00:03"
 
 wait_row_count Service_Monitor 2 status=offline
 
-ovn-nbctl lsp-del sw0-p1
-ovn-nbctl lsp-del sw1-p1
+check ovn-nbctl lsp-del sw0-p1
+check ovn-nbctl lsp-del sw1-p1
 wait_row_count Service_Monitor 0
 
 # Add back sw0-p1 but without any address set.
-ovn-nbctl lsp-add sw0 sw0-p1
-
+check ovn-nbctl lsp-add sw0 sw0-p1
 
 wait_row_count Service_Monitor 1
 wait_row_count Service_Monitor 0 status=offline
@@ -19444,7 +19684,7 @@ send_arp_request() {
     local arp=0001080006040001${eth_src}${spa}${eth_dst}${tpa}
 
     local request=${eth}${arp}
-    as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
+    check as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
 }
 
 send_nd_ns() {
@@ -19471,7 +19711,7 @@ send_nd_ns() {
 
     local request=${eth}${ip}${icmp6}
 
-    as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
+    check as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
 }
 
 src_mac=000000000001
@@ -19479,63 +19719,63 @@ src_mac=000000000001
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check ovs-vsctl add-br br-phys
+check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 ovn_attach n1 br-phys 192.168.0.1
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
-ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
+check ovs-vsctl add-br br-phys
+check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
 ovn_attach n1 br-phys 192.168.0.2
 
 # One Aggregation Switch connected to two Logical networks (routers).
-ovn-nbctl ls-add sw-agg
-ovn-nbctl lsp-add sw-agg sw-agg-ext \
+check ovn-nbctl ls-add sw-agg
+check ovn-nbctl lsp-add sw-agg sw-agg-ext \
     -- lsp-set-addresses sw-agg-ext 00:00:00:00:00:01
 
-ovn-nbctl lsp-add sw-agg sw-rtr1                   \
+check ovn-nbctl lsp-add sw-agg sw-rtr1             \
     -- lsp-set-type sw-rtr1 router                 \
     -- lsp-set-addresses sw-rtr1 00:00:00:00:01:00 \
     -- lsp-set-options sw-rtr1 router-port=rtr1-sw
-ovn-nbctl lsp-add sw-agg sw-rtr2                   \
+check ovn-nbctl lsp-add sw-agg sw-rtr2             \
     -- lsp-set-type sw-rtr2 router                 \
     -- lsp-set-addresses sw-rtr2 00:00:00:00:02:00 \
     -- lsp-set-options sw-rtr2 router-port=rtr2-sw
 
 # Localnet port on the Aggregation Switch.
-ovn-nbctl lsp-add sw-agg sw-agg-ln
-ovn-nbctl lsp-set-addresses sw-agg-ln unknown
-ovn-nbctl lsp-set-type sw-agg-ln localnet
-ovn-nbctl lsp-set-options sw-agg-ln network_name=phys
+check ovn-nbctl lsp-add sw-agg sw-agg-ln
+check ovn-nbctl lsp-set-addresses sw-agg-ln unknown
+check ovn-nbctl lsp-set-type sw-agg-ln localnet
+check ovn-nbctl lsp-set-options sw-agg-ln network_name=phys
 
 # Configure L3 interface IPv4 & IPv6 on both routers.
-ovn-nbctl lr-add rtr1
-ovn-nbctl lrp-add rtr1 rtr1-sw 00:00:00:00:01:00 10.0.0.1/24 10::1/64
+check ovn-nbctl lr-add rtr1
+check ovn-nbctl lrp-add rtr1 rtr1-sw 00:00:00:00:01:00 10.0.0.1/24 10::1/64
 
-ovn-nbctl lrp-add rtr1 rtr1-sw1 00:00:01:00:00:00 20.0.0.1/24 20::1/64
+check ovn-nbctl lrp-add rtr1 rtr1-sw1 00:00:01:00:00:00 20.0.0.1/24 20::1/64
 
-ovn-nbctl lr-add rtr2
-ovn-nbctl lrp-add rtr2 rtr2-sw 00:00:00:00:02:00 10.0.0.2/24 10::2/64
+check ovn-nbctl lr-add rtr2
+check ovn-nbctl lrp-add rtr2 rtr2-sw 00:00:00:00:02:00 10.0.0.2/24 10::2/64
 
 # Configure router gateway ports.
-ovn-nbctl lrp-set-gateway-chassis rtr1-sw hv1 20
-ovn-nbctl lrp-set-gateway-chassis rtr2-sw hv1 20
+check ovn-nbctl lrp-set-gateway-chassis rtr1-sw hv1 20
+check ovn-nbctl lrp-set-gateway-chassis rtr2-sw hv1 20
 
 # One private network behind rtr1 with two VMs.
-ovn-nbctl ls-add sw1
-ovn-nbctl lsp-add sw1 sw1-p1 \
+check ovn-nbctl ls-add sw1
+check ovn-nbctl lsp-add sw1 sw1-p1 \
     -- lsp-set-addresses sw1-p1 00:00:00:01:00:00
-ovn-nbctl lsp-add sw1 sw1-p2 \
+check ovn-nbctl lsp-add sw1 sw1-p2 \
     -- lsp-set-addresses sw1-p2 00:00:00:02:00:00
-ovn-nbctl lsp-add sw1 sw1-rtr1                       \
+check ovn-nbctl lsp-add sw1 sw1-rtr1                 \
     -- lsp-set-type sw1-rtr1 router                  \
     -- lsp-set-addresses sw1-rtr1 00:00:01:00:00:00  \
     -- lsp-set-options sw1-rtr1 router-port=rtr1-sw1
 
 # Bind a "VM" connected to sw-agg on hv1.
 as hv1
-ovs-vsctl -- add-port br-int hv1-vif0 -- \
+check ovs-vsctl -- add-port br-int hv1-vif0 -- \
     set interface hv1-vif0 external-ids:iface-id=sw-agg-ext \
     options:tx_pcap=hv1/vif0-tx.pcap \
     options:rxq_pcap=hv1/vif0-rx.pcap \
@@ -19543,7 +19783,7 @@ ovs-vsctl -- add-port br-int hv1-vif0 -- \
 
 # Bind a "VM" connected to sw1 on hv1.
 as hv1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
     options:tx_pcap=hv1/vif1-tx.pcap \
     options:rxq_pcap=hv1/vif1-rx.pcap \
@@ -19551,14 +19791,17 @@ ovs-vsctl -- add-port br-int hv1-vif1 -- \
 
 # Bind a "VM" connected to sw1 on hv2.
 as hv2
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw1-p2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=3
 
 OVN_POPULATE_ARP
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
+
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
 
 sw_dp_uuid=$(ovn-sbctl --bare --columns _uuid list datapath_binding sw-agg)
 sw_dp_key=$(ovn-sbctl --bare --columns tunnel_key list datapath_binding sw-agg)
@@ -19617,16 +19860,16 @@ OVS_WAIT_UNTIL([
 ])
 
 # Configure load balancing on both routers.
-ovn-nbctl lb-add lb1-v4 10.0.0.11 42.42.42.1
-ovn-nbctl lb-add lb1-v6 10::11 42::1
-ovn-nbctl lr-lb-add rtr1 lb1-v4
-ovn-nbctl lr-lb-add rtr1 lb1-v6
-
-ovn-nbctl lb-add lb2-v4 10.0.0.22 42.42.42.2
-ovn-nbctl lb-add lb2-v6 10::22 42::2
-ovn-nbctl lr-lb-add rtr2 lb2-v4
-ovn-nbctl lr-lb-add rtr2 lb2-v6
-ovn-nbctl --wait=hv sync
+check ovn-nbctl lb-add lb1-v4 10.0.0.11 42.42.42.1
+check ovn-nbctl lb-add lb1-v6 10::11 42::1
+check ovn-nbctl lr-lb-add rtr1 lb1-v4
+check ovn-nbctl lr-lb-add rtr1 lb1-v6
+
+check ovn-nbctl lb-add lb2-v4 10.0.0.22 42.42.42.2
+check ovn-nbctl lb-add lb2-v6 10::22 42::2
+check ovn-nbctl lr-lb-add rtr2 lb2-v4
+check ovn-nbctl lr-lb-add rtr2 lb2-v6
+check ovn-nbctl --wait=hv sync
 
 # Inject ARP request for first router owned VIP address.
 send_arp_request 1 0 ${src_mac} $(ip_to_hex 10 0 0 254) $(ip_to_hex 10 0 0 11)
@@ -19673,18 +19916,21 @@ OVS_WAIT_UNTIL([
 ])
 
 # Configure NAT on both routers.
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.111 42.42.42.1
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::111 42::1
-ovn-nbctl lr-nat-add rtr2 dnat_and_snat 10.0.0.222 42.42.42.2
-ovn-nbctl lr-nat-add rtr2 dnat_and_snat 10::222 42::2
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.111 42.42.42.1
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::111 42::1
+check ovn-nbctl lr-nat-add rtr2 dnat_and_snat 10.0.0.222 42.42.42.2
+check ovn-nbctl lr-nat-add rtr2 dnat_and_snat 10::222 42::2
 check ovn-nbctl --wait=hv sync
 
 # Configure FIP1 and FIP2 on rtr1 for sw1-p1 and sw1-p2.
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.121 20.0.0.11 sw1-p1 00:00:00:01:00:00
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::121 20::11 sw1-p1 00:00:00:01:00:00
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.122 20.0.0.12 sw1-p2 00:00:00:02:00:00
-ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::122 20::12 sw1-p2 00:00:00:02:00:00
-ovn-nbctl --wait=hv sync
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.121 20.0.0.11 sw1-p1 00:00:00:01:00:00
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::121 20::11 sw1-p1 00:00:00:01:00:00
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10.0.0.122 20.0.0.12 sw1-p2 00:00:00:02:00:00
+check ovn-nbctl lr-nat-add rtr1 dnat_and_snat 10::122 20::12 sw1-p2 00:00:00:02:00:00
+check ovn-nbctl --wait=hv sync
+
+ovn-sbctl dump-flows > sbflows2
+AT_CAPTURE_FILE([sbflows2])
 
 # Check that broadcast domain limiting flows match only on IPs that are
 # directly reachable via the router port.
@@ -19957,14 +20203,20 @@ done
 
 for ts in `seq 1 $n_ts`; do
     ovn-ic-nbctl create Transit_Switch name=ts$ts
+    for az in `seq 1 $n_az`; do
+        echo "az$az: wait for ts$ts..."
+        AT_CHECK([ovn_as az$az ovn-nbctl wait-until logical_switch ts$ts])
+    done
 done
 
 for az in `seq 1 $n_az`; do
     ovn_as az$az
-    ovn-nbctl set nb_global . options:ic-route-learn=true
-    ovn-nbctl set nb_global . options:ic-route-adv=true
+    check ovn-nbctl set nb_global . options:ic-route-learn=true
+    check ovn-nbctl set nb_global . options:ic-route-adv=true
 
     # Each AZ has n_ts LSPi->LSi->LRi connecting to each TSi
+    echo
+    echo "az$az"
     for i in `seq 1 $n_ts`; do
         lsp_mac=00:00:00:0$az:0$i:00
         lrp_ls_mac=00:00:00:0$az:0$i:01
@@ -19973,26 +20225,27 @@ for az in `seq 1 $n_az`; do
         lrp_ls_ip=10.$az.$i.1
         lrp_ts_ip=169.254.$i.$az
 
-        ovn-nbctl ls-add ls$az-$i
-        ovn-nbctl lsp-add ls$az-$i lsp$az-$i
-        ovn-nbctl lsp-set-addresses lsp$az-$i "$lsp_mac $lsp_ip"
+        check ovn-nbctl ls-add ls$az-$i
+        check ovn-nbctl lsp-add ls$az-$i lsp$az-$i
+        check ovn-nbctl lsp-set-addresses lsp$az-$i "$lsp_mac $lsp_ip"
 
-        ovn-nbctl lr-add lr$az-$i
+        check ovn-nbctl lr-add lr$az-$i
 
-        ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ls$az-$i $lrp_ls_mac $lrp_ls_ip/24
-        ovn-nbctl lsp-add ls$az-$i lsp-ls$az-$i-lr$az-$i
-        ovn-nbctl lsp-set-addresses lsp-ls$az-$i-lr$az-$i router
-        ovn-nbctl lsp-set-type lsp-ls$az-$i-lr$az-$i router
-        ovn-nbctl lsp-set-options lsp-ls$az-$i-lr$az-$i router-port=lrp-lr$az-$i-ls$az-$i
+        check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ls$az-$i $lrp_ls_mac $lrp_ls_ip/24
+        check ovn-nbctl lsp-add ls$az-$i lsp-ls$az-$i-lr$az-$i
+        check ovn-nbctl lsp-set-addresses lsp-ls$az-$i-lr$az-$i router
+        check ovn-nbctl lsp-set-type lsp-ls$az-$i-lr$az-$i router
+        check ovn-nbctl lsp-set-options lsp-ls$az-$i-lr$az-$i router-port=lrp-lr$az-$i-ls$az-$i
 
-        ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ts$i $lrp_ts_mac $lrp_ts_ip/24
-        ovn-nbctl lsp-add ts$i lsp-ts$i-lr$az-$i
-        ovn-nbctl lsp-set-addresses lsp-ts$i-lr$az-$i router
-        ovn-nbctl lsp-set-type lsp-ts$i-lr$az-$i router
-        ovn-nbctl lsp-set-options lsp-ts$i-lr$az-$i router-port=lrp-lr$az-$i-ts$i
-        ovn-nbctl lrp-set-gateway-chassis lrp-lr$az-$i-ts$i gw$az
+        check ovn-nbctl lrp-add lr$az-$i lrp-lr$az-$i-ts$i $lrp_ts_mac $lrp_ts_ip/24
+        check ovn-nbctl lsp-add ts$i lsp-ts$i-lr$az-$i
+        check ovn-nbctl lsp-set-addresses lsp-ts$i-lr$az-$i router
+        check ovn-nbctl lsp-set-type lsp-ts$i-lr$az-$i router
+        check ovn-nbctl lsp-set-options lsp-ts$i-lr$az-$i router-port=lrp-lr$az-$i-ts$i
+        check ovn-nbctl lrp-set-gateway-chassis lrp-lr$az-$i-ts$i gw$az
     done
     check ovn-nbctl --wait=hv sync
+    ovn-sbctl list Port_Binding > az$az.ports
 done
 
 # Pre-populate the hypervisors' ARP tables so that we don't lose any
@@ -20001,21 +20254,64 @@ done
 OVN_POPULATE_ARP
 
 for i in `seq 1 $n_az`; do
-    AT_CHECK([ovn_as az$i ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
+    AT_CHECK([ovn_as az$i ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
+    ovn_as az$i ovn-sbctl dump-flows > az$i/sbflows
 done
 
 # Allow some time for ovn-northd and ovn-controller to catch up.
 # XXX This should be more systematic.
 sleep 2
 
+ovn-ic-nbctl show > ic-nbctl.dump
+AT_CAPTURE_FILE([ic-nbctl.dump])
+
+(echo "---------ISB dump-----"
+ ovn-ic-sbctl show
+ echo "---------------------"
+ ovn-ic-sbctl list gateway
+ echo "---------------------"
+ ovn-ic-sbctl list datapath_binding
+ echo "---------------------"
+ ovn-ic-sbctl list port_binding
+ echo "---------------------"
+ ovn-ic-sbctl list route
+ echo "---------------------") > ic-sbctl.dump
+AT_CAPTURE_FILE([ic-sbctl.dump])
+
+AT_CAPTURE_FILE([expected])
+AT_CAPTURE_FILE([received])
+check_packets() {
+    > expected
+    > received
+    for az in `seq 1 $n_az`; do
+        for i in `seq 1 $n_ts`; do
+            pcap=hv$az/vif$i-tx.pcap
+            echo "--- $pcap" | tee -a expected >> received
+            if test -e $az-$i.expected; then
+                sort $az-$i.expected >> expected
+            fi
+            if test -e $pcap; then
+                $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $pcap | sort >> received
+            fi
+            echo | tee -a expected >> received
+        done
+    done
+
+    $at_diff expected received >/dev/null
+}
+
 # Send packets between AZs on each TS
-for s_az in `seq 1 $n_az`; do
-    for d_az in `seq 1 $n_az`; do
+for s_az in $(seq 1 $n_az); do
+    ovn_as az${s_az}
+    as hv${s_az}
+    for d_az in $(seq 1 $n_az); do
         if test $s_az = $d_az; then
             continue
         fi
 
-        for i in `seq 1 $n_ts`; do
+        for i in $(seq 1 $n_ts); do
+            echo
+            AS_BOX([packet from az$s_az to az$d_az via ts$i])
             lsp_smac=00:00:00:0${s_az}:0$i:00
             lsp_dmac=00:00:00:0${d_az}:0$i:00
             lrp_ls_smac=00:00:00:0${s_az}:0$i:01
@@ -20023,10 +20319,18 @@ for s_az in `seq 1 $n_az`; do
             lsp_sip=10.${s_az}.$i.123
             lsp_dip=10.${d_az}.$i.123
 
-            packet="inport==\"lsp${s_az}-$i\" && eth.src==$lsp_smac && eth.dst==$lrp_ls_smac &&
+            ovn_inport=lsp${s_az}-$i
+            packet="inport==\"$ovn_inport\" && eth.src==$lsp_smac && eth.dst==$lrp_ls_smac &&
                     ip4 && ip.ttl==64 && ip4.src==$lsp_sip && ip4.dst==$lsp_dip &&
                     udp && udp.src==53 && udp.dst==4369"
-            AT_CHECK([as hv${s_az} ovs-appctl -t ovn-controller inject-pkt "$packet"])
+            echo "sending: $packet"
+            AT_CHECK([ovn-trace --ovs "$packet" > ${s_az}-${d_az}-$i.ovn-trace])
+            AT_CHECK([ovs-appctl -t ovn-controller inject-pkt "$packet"])
+            ovs_inport=$(ovs-vsctl --bare --columns=ofport find Interface external-ids:iface-id="$ovn_inport")
+
+            ovs_packet=$(echo $packet | ovstest test-ovn expr-to-packets)
+            echo ovs_inport=$ovs_inport ovs_packet=$ovs_packet
+            AT_CHECK([ovs-appctl ofproto/trace br-int in_port="$ovs_inport" "$ovs_packet" > ${s_az}-${d_az}-$i.ovs-trace])
 
             # Packet to Expect
             # The TTL should be decremented by 2.
@@ -20034,31 +20338,11 @@ for s_az in `seq 1 $n_az`; do
                     ip4 && ip.ttl==62 && ip4.src==$lsp_sip && ip4.dst==$lsp_dip &&
                     udp && udp.src==53 && udp.dst==4369"
             echo $packet | ovstest test-ovn expr-to-packets >> ${d_az}-$i.expected
+OVS_WAIT_UNTIL([check_packets], [$at_diff -F'^---' expected received])
         done
     done
 done
 
-echo "---------INB dump-----"
-ovn-ic-nbctl show
-echo "---------------------"
-
-echo "---------ISB dump-----"
-ovn-ic-sbctl show
-echo "---------------------"
-ovn-ic-sbctl list gateway
-echo "---------------------"
-ovn-ic-sbctl list datapath_binding
-echo "---------------------"
-ovn-ic-sbctl list port_binding
-echo "---------------------"
-ovn-ic-sbctl list route
-echo "---------------------"
-
-for az in `seq 1 $n_az`; do
-    for i in `seq 1 $n_ts`; do
-        OVN_CHECK_PACKETS([hv$az/vif$i-tx.pcap], [$az-$i.expected])
-    done
-done
 
 for az in `seq 1 $n_az`; do
     OVN_CLEANUP_SBOX([hv$az])
@@ -20139,6 +20423,9 @@ ovs-vsctl -- add-port br-int hv1-vif3 -- \
 # wait for earlier changes to take effect
 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 for i in $(seq 5001 5010); do
     packet="inport==\"lsp11\" && eth.src==f0:00:00:00:01:11 && eth.dst==00:00:00:01:01:01 &&
             ip4 && ip.ttl==64 && ip4.src==192.168.1.11 && ip4.dst==10.0.0.123 &&
@@ -20179,24 +20466,24 @@ ovn_start
 # One LR - R1 has a logical switch ls1 and ls2 connected to it.
 # Logical switch ls1 has one port while ls2 has two logical switch ports as
 # child ports.
-ovn-nbctl lr-add R1
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
+check ovn-nbctl lr-add R1
+check ovn-nbctl ls-add ls1
+check ovn-nbctl ls-add ls2
 
 # Logical switch ls1 to R1 connectivity
-ovn-nbctl lrp-add R1 R1-ls1 00:00:00:01:02:f1 192.168.1.1/24
-ovn-nbctl lsp-add ls1 ls1-R1 -- set Logical_Switch_Port ls1-R1 \
+check ovn-nbctl lrp-add R1 R1-ls1 00:00:00:01:02:f1 192.168.1.1/24
+check ovn-nbctl lsp-add ls1 ls1-R1 -- set Logical_Switch_Port ls1-R1 \
     type=router options:router-port=R1-ls1 -- lsp-set-addresses ls1-R1 router
-ovn-nbctl lsp-add ls1 lsp11 \
+check ovn-nbctl lsp-add ls1 lsp11 \
     -- lsp-set-addresses lsp11 "00:00:00:01:02:01 192.168.1.2"
 
 # Logical switch ls2 to R1 connectivity
-ovn-nbctl lrp-add R1 R1-ls2 00:00:00:01:02:f2 172.16.1.1/24
-ovn-nbctl lsp-add ls2 ls2-R1 -- set Logical_Switch_Port ls2-R1 \
+check ovn-nbctl lrp-add R1 R1-ls2 00:00:00:01:02:f2 172.16.1.1/24
+check ovn-nbctl lsp-add ls2 ls2-R1 -- set Logical_Switch_Port ls2-R1 \
     type=router options:router-port=R1-ls2 -- lsp-set-addresses ls2-R1 router
-ovn-nbctl lsp-add ls2 lsp21 \
+check ovn-nbctl lsp-add ls2 lsp21 \
     -- lsp-set-addresses lsp21 "00:00:00:01:02:01 172.16.1.2"
-ovn-nbctl lsp-add ls2 lsp22 \
+check ovn-nbctl lsp-add ls2 lsp22 \
     -- lsp-set-addresses lsp22 "00:00:00:01:02:02 172.16.1.3"
 
 # Create a network
@@ -20205,45 +20492,47 @@ net_add n1
 # Create hypervisor hv1 connected to n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check 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=lsp11 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
+check ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lsp11 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
+check 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=lsp21 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
+check ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lsp21 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
 
 # Create hypervisor hv3 connected to n1
 sim_add hv3
 as hv3
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.3
-ovs-vsctl add-port br-int vif3 -- set Interface vif3 external-ids:iface-id=lsp22 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
+check ovs-vsctl add-port br-int vif3 -- set Interface vif3 external-ids:iface-id=lsp22 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
 
 # Add a forwarding group on ls2 with lsp21 and lsp22 as child ports
 # virtual IP - 172.16.1.11, virtual MAC - 00:11:de:ad:be:ef
 check ovn-nbctl --wait=hv fwd-group-add fwd_grp1 ls2 172.16.1.11 00:11:de:ad:be:ef lsp21 lsp22
 
 # Check logical flow
-AT_CHECK([ovn-sbctl dump-flows | grep ls_in_l2_lkup | grep fwd_group | wc -l], [0], [dnl
-1
+AT_CAPTURE_FILE([sbflows])
+ovn-sbctl dump-flows > sbflows
+AT_CHECK([grep ls_in_l2_lkup sbflows | grep fwd_group | wc -l], [0], [1
 ])
 
 # Check openflow rule with "group" on hypervisor
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
-    grep "dl_dst=00:11:de:ad:be:ef actions=group" | wc -l], [0], [dnl
-1
+AT_CAPTURE_FILE([offlows])
+as hv1 ovs-ofctl dump-flows br-int > offlows
+AT_CHECK([grep -c "dl_dst=00:11:de:ad:be:ef actions=group" offlows], [0], [1
 ])
 
 # Verify openflow group members
+ # Verify openflow group members
+AT_CAPTURE_FILE([ofgroups])
+as hv1 ovs-ofctl -O OpenFlow13 dump-groups br-int > ofgroups
 for child_port in lsp21 lsp22; do
-    tunnel_key=`ovn-sbctl --bare --column tunnel_key find port_binding logical_port=$child_port`
-    AT_CHECK([as hv1 ovs-ofctl -O OpenFlow13 dump-groups br-int | \
-        grep "bucket=actions=load:0x"$tunnel_key | wc -l], [0], [dnl
-1
+    tunnel_key=`ovn-sbctl get Port_Binding $child_port tunnel_key`
+    AT_CHECK([grep -c "bucket=actions=load:0x"$tunnel_key ofgroups], [0], [1
 ])
 done
 
@@ -20255,17 +20544,17 @@ dst_ip=172.16.1.11
 packet="inport==\"lsp11\" && eth.src==$src_mac && eth.dst==$dst_mac &&
         ip4 && ip.ttl==64 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
         udp && udp.src==53 && udp.dst==4369"
-as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
+check as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
 
 # Check if the packet hit the forwarding group policy
-AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | \
-    grep "dl_dst=00:11:de:ad:be:ef actions=group" | \
-    grep "n_packets=1" | wc -l], [0], [dnl
-1
+AT_CAPTURE_FILE([offlows2])
+OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int > offlows2
+    grep "dl_dst=00:11:de:ad:be:ef actions=group" offlows2 | \
+    grep "n_packets=1" | wc -l], [0], [1
 ])
 
 # Delete the forwarding group
-ovn-nbctl fwd-group-del fwd_grp1
+check ovn-nbctl fwd-group-del fwd_grp1
 
 # Add a forwarding group with liveness on ls2 with lsp21 and lsp22 as child
 # ports virtual IP - 172.16.1.11, virtual MAC - 00:11:de:ad:be:ef
@@ -20402,6 +20691,9 @@ send_ipv4_pkt hv1 hv1-vif1 000000000001 000000000100 \
     ${tcp_payload} ${hp_tcp_payload} \
     expected
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+
 # Check that traffic is hairpinned.
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
 
@@ -20535,109 +20827,109 @@ ovn_start
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
     options:tx_pcap=hv1/vif1-tx.pcap \
     options:rxq_pcap=hv1/vif1-rx.pcap \
     ofport-request=1
-ovs-vsctl -- add-port br-int hv1-vif2 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw0-port2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=2
 
-as hv1 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-phys
+as hv1 check ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-phys
 
-ovn-nbctl ls-add sw0
-ovn-nbctl lsp-add sw0 sw0-port1
-ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:03 10.0.0.3 10.0.0.5"
-ovn-nbctl lsp-set-port-security sw0-port1 "50:54:00:00:00:03 10.0.0.3 10.0.0.5"
+check ovn-nbctl ls-add sw0
+check ovn-nbctl lsp-add sw0 sw0-port1
+check ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:03 10.0.0.3 10.0.0.5"
+check ovn-nbctl lsp-set-port-security sw0-port1 "50:54:00:00:00:03 10.0.0.3 10.0.0.5"
 
-ovn-nbctl lsp-add sw0 sw0-port2
-ovn-nbctl lsp-set-addresses sw0-port2 "50:54:00:00:00:04 10.0.0.4 aef0::4"
+check ovn-nbctl lsp-add sw0 sw0-port2
+check ovn-nbctl lsp-set-addresses sw0-port2 "50:54:00:00:00:04 10.0.0.4 aef0::4"
 
-ovn-nbctl lr-add lr0
-ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 aef0::1/64
-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
+check ovn-nbctl lr-add lr0
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 aef0::1/64
+check ovn-nbctl lsp-add sw0 sw0-lr0
+check ovn-nbctl lsp-set-type sw0-lr0 router
+check ovn-nbctl lsp-set-addresses sw0-lr0 router
+check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
 
-ovn-nbctl ls-add public
-ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24 bef0::1/64
-ovn-nbctl lsp-add public public-lr0
-ovn-nbctl lsp-set-type public-lr0 router
-ovn-nbctl lsp-set-addresses public-lr0 router
-ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
+check ovn-nbctl ls-add public
+check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24 bef0::1/64
+check ovn-nbctl lsp-add public public-lr0
+check ovn-nbctl lsp-set-type public-lr0 router
+check ovn-nbctl lsp-set-addresses public-lr0 router
+check ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
 
 # localnet port
-ovn-nbctl lsp-add public ln-public
-ovn-nbctl lsp-set-type ln-public localnet
-ovn-nbctl lsp-set-addresses ln-public unknown
-ovn-nbctl lsp-set-options ln-public network_name=public
+check ovn-nbctl lsp-add public ln-public
+check ovn-nbctl lsp-set-type ln-public localnet
+check ovn-nbctl lsp-set-addresses ln-public unknown
+check ovn-nbctl lsp-set-options ln-public network_name=public
 
-ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
-ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
+check ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
+check ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
 check ovn-nbctl --wait=hv sync
+
+wait_row_count datapath_binding 1 external-ids:name=lr0
 lr0_dp_uuid=$(ovn-sbctl --bare --columns _uuid list datapath_binding lr0)
-ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip=172.168.0.120 \
-logical_port=lr0-public mac="10\:54\:00\:00\:00\:03"
-ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip=172.168.0.200 \
-logical_port=lr0-public mac="10\:54\:00\:00\:00\:04"
-ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:4" \
-logical_port=lr0-public mac="10\:54\:00\:00\:00\:05"
-ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:5" \
-logical_port=lr0-public mac="10\:54\:00\:00\:00\:06"
-ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:6" \
-logical_port=lr0-public mac="10\:54\:00\:00\:00\:07"
 
-ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
-ip_prefix="\:\:/64" nexthop="bef0\:\:4" -- add Logical_Router lr0 \
-static_routes @lrt
+AT_CHECK(
+  [ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip=172.168.0.120 \
+       logical_port=lr0-public mac="10\:54\:00\:00\:00\:03"
+   ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip=172.168.0.200 \
+       logical_port=lr0-public mac="10\:54\:00\:00\:00\:04"
+   ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:4" \
+       logical_port=lr0-public mac="10\:54\:00\:00\:00\:05"
+   ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:5" \
+       logical_port=lr0-public mac="10\:54\:00\:00\:00\:06"
+   ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip="bef0\:\:6" \
+       logical_port=lr0-public mac="10\:54\:00\:00\:00\:07"
+   ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+       ip_prefix="\:\:/64" nexthop="bef0\:\:4" -- add Logical_Router lr0 \
+       static_routes @lrt],
+  [0], [stdout])
+AT_CHECK([uuidfilt stdout], [0],
+  [<0>
+<1>
+<2>
+<3>
+<4>
+<5>
+])
 
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
 
 # Add logical router policy and set pkt_mark on it.
-ovn-nbctl lr-policy-add lr0 2000 "ip4.src == 10.0.0.3" allow pkt_mark=100
-ovn-nbctl lr-policy-add lr0 1000 "ip4.src == 10.0.0.4" allow
-ovn-nbctl lr-policy-add lr0 900 "ip4.src == 10.0.0.5" reroute 172.168.0.200 pkt_mark=3
-ovn-nbctl lr-policy-add lr0 2001 "ip6.dst == bef0::5" reroute bef0::6
-ovn-nbctl lr-policy-add lr0 1001 "ip6" allow
+check ovn-nbctl lr-policy-add lr0 2000 "ip4.src == 10.0.0.3" allow pkt_mark=100
+check ovn-nbctl lr-policy-add lr0 1000 "ip4.src == 10.0.0.4" allow
+check ovn-nbctl lr-policy-add lr0 900 "ip4.src == 10.0.0.5" reroute 172.168.0.200 pkt_mark=3
+check ovn-nbctl lr-policy-add lr0 2001 "ip6.dst == bef0::5" reroute bef0::6
+check ovn-nbctl lr-policy-add lr0 1001 "ip6" allow
 
 pol1=$(ovn-nbctl --bare --columns _uuid find logical_router_policy priority=2000)
 pol4=$(ovn-nbctl --bare --columns _uuid find logical_router_policy priority=2001)
 pol5=$(ovn-nbctl --bare --columns _uuid find logical_router_policy priority=1001)
 
-ovn-nbctl set logical_router_policy $pol4 options:pkt_mark=4
-ovn-nbctl set logical_router_policy $pol5 options:pkt_mark=4294967295
-ovn-nbctl --wait=hv sync
-
-OVS_WAIT_UNTIL([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \
-    grep "load:0x64->NXM_NX_PKT_MARK" -c)
-])
-
-OVS_WAIT_UNTIL([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \
-    grep "load:0x3->NXM_NX_PKT_MARK" -c)
-])
-
-OVS_WAIT_UNTIL([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \
-    grep "load:0x4->NXM_NX_PKT_MARK" -c)
-])
-
-as hv1 ovs-ofctl dump-flows br-int table=20 | grep NXM_NX_PKT_MARK
+check ovn-nbctl set logical_router_policy $pol4 options:pkt_mark=4
+check ovn-nbctl set logical_router_policy $pol5 options:pkt_mark=4294967295
 check ovn-nbctl --wait=hv sync
 
+ovn-sbctl dump-flows > sbflows
+AT_CAPTURE_FILE([sbflows])
+AT_CAPTURE_FILE([offlows])
 OVS_WAIT_UNTIL([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=20 | \
-    grep "load:0xffffffff->NXM_NX_PKT_MARK" -c)
+    as hv1 ovs-ofctl dump-flows br-int table=20 > offlows
+    test $(grep -c "load:0x64->NXM_NX_PKT_MARK" offlows) = 1 && \
+    test $(grep -c "load:0x3->NXM_NX_PKT_MARK" offlows) = 1 && \
+    test $(grep -c "load:0x4->NXM_NX_PKT_MARK" offlows) = 1 && \
+    test $(grep -c "load:0xffffffff->NXM_NX_PKT_MARK" offlows) = 1
 ])
 
-AT_CHECK([as hv1 ovs-ofctl del-flows br-phys])
+as hv1 check ovs-ofctl del-flows br-phys
 AT_DATA([flows.txt], [dnl
 table=0, priority=0 actions=NORMAL
 table=0, priority=200 arp,actions=drop
@@ -20648,13 +20940,14 @@ table=0, priority=100, pkt_mark=0x4 actions=drop
 table=0, priority=100, pkt_mark=0xffffffff actions=drop
 ])
 
-AT_CHECK([as hv1 ovs-ofctl --protocols=OpenFlow13 add-flows br-phys flows.txt])
+as hv1 check ovs-ofctl --protocols=OpenFlow13 add-flows br-phys flows.txt
 sleep 5
 
 send_ipv4_pkt() {
     local hv=$1 inport=$2 eth_src=$3 eth_dst=$4
     local ip_src=$5 ip_dst=$6
     packet=${eth_dst}${eth_src}08004500001c0000000040110000${ip_src}${ip_dst}0035111100080000
+    tcpdump_hex $packet
     as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
 }
 
@@ -20670,10 +20963,11 @@ send_icmp6_packet() {
 send_ipv4_pkt hv1 hv1-vif1 505400000003 00000000ff01 \
     $(ip_to_hex 10 0 0 3) $(ip_to_hex 172 168 0 120)
 
+AT_CAPTURE_FILE([offlows2])
 OVS_WAIT_UNTIL([
-    test 1 -eq $(as hv1 ovs-ofctl dump-flows br-phys table=0 | \
-    grep "priority=100,pkt_mark=0x64" | \
-    grep "n_packets=1" -c)
+    as hv1 ovs-ofctl dump-flows br-phys table=0 > offlows2
+    test 1 -eq $(grep "priority=100,pkt_mark=0x64" offlows2 | \
+                 grep -c "n_packets=1")
 ])
 
 AT_CHECK([
@@ -20868,14 +21162,14 @@ net_add n1
 
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw0-p1 \
     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 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=sw0-p2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
@@ -21304,12 +21598,12 @@ ovn_start
 net_add n1
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.2
 
 # Logical network
@@ -21329,44 +21623,44 @@ ovn_attach n1 br-phys 192.168.0.2
 ovn-nbctl create Logical_Router name=DR
 gw_uuid=$(ovn-nbctl create Logical_Router name=GW)
 
-ovn-nbctl ls-add ls1
-ovn-nbctl ls-add ls2
-ovn-nbctl ls-add join
-ovn-nbctl ls-add ext
+check ovn-nbctl ls-add ls1
+check ovn-nbctl ls-add ls2
+check ovn-nbctl ls-add join
+check ovn-nbctl ls-add ext
 
 # Connect ls1 to DR
-ovn-nbctl lrp-add DR dr-ls1 00:00:01:01:02:03 10.0.0.1/24
-ovn-nbctl lsp-add ls1 ls1-dr -- set Logical_Switch_Port ls1-dr \
+check ovn-nbctl lrp-add DR dr-ls1 00:00:01:01:02:03 10.0.0.1/24
+check ovn-nbctl lsp-add ls1 ls1-dr -- set Logical_Switch_Port ls1-dr \
     type=router options:router-port=dr-ls1 addresses='"00:00:01:01:02:03"'
 
 # Connect ls2 to DR
-ovn-nbctl lrp-add DR dr-ls2 00:00:01:01:02:04 10.0.0.2/24
-ovn-nbctl lsp-add ls2 ls2-dr -- set Logical_Switch_Port ls2-dr \
+check ovn-nbctl lrp-add DR dr-ls2 00:00:01:01:02:04 10.0.0.2/24
+check ovn-nbctl lsp-add ls2 ls2-dr -- set Logical_Switch_Port ls2-dr \
     type=router options:router-port=dr-ls2 addresses='"00:00:01:01:02:04"'
 
 # Connect join to DR
-ovn-nbctl lrp-add DR dr-join 00:00:02:01:02:03 20.0.0.1/24
-ovn-nbctl lsp-add join join-dr -- set Logical_Switch_Port join-dr \
+check ovn-nbctl lrp-add DR dr-join 00:00:02:01:02:03 20.0.0.1/24
+check ovn-nbctl lsp-add join join-dr -- set Logical_Switch_Port join-dr \
     type=router options:router-port=dr-join addresses='"00:00:02:01:02:03"'
 
 # Connect join to GW
-ovn-nbctl lrp-add GW gw-join 00:00:02:01:02:04 20.0.0.2/24
-ovn-nbctl lsp-add join join-gw -- set Logical_Switch_Port join-gw \
+check ovn-nbctl lrp-add GW gw-join 00:00:02:01:02:04 20.0.0.2/24
+check ovn-nbctl lsp-add join join-gw -- set Logical_Switch_Port join-gw \
     type=router options:router-port=gw-join addresses='"00:00:02:01:02:04"'
 
 # Connect ext to GW
-ovn-nbctl lrp-add GW gw-ext 00:00:03:01:02:03 172.16.0.1/16
-ovn-nbctl lsp-add ext ext-gw -- set Logical_Switch_Port ext-gw \
+check ovn-nbctl lrp-add GW gw-ext 00:00:03:01:02:03 172.16.0.1/16
+check ovn-nbctl lsp-add ext ext-gw -- set Logical_Switch_Port ext-gw \
     type=router options:router-port=gw-ext addresses='"00:00:03:01:02:03"'
 
-ovn-nbctl lr-route-add GW 10.0.0.0/24 20.0.0.1
-ovn-nbctl --policy="src-ip" lr-route-add DR 10.0.0.0/24 20.0.0.2
+check ovn-nbctl lr-route-add GW 10.0.0.0/24 20.0.0.1
+check ovn-nbctl --policy="src-ip" lr-route-add DR 10.0.0.0/24 20.0.0.2
 
 # Now add some ECMP routes to the GW router.
-ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.2
-ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.3
+check ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.2
+check ovn-nbctl --ecmp-symmetric-reply --policy="src-ip" lr-route-add GW 10.0.0.0/24 172.16.0.3
 
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
 
 # Ensure ECMP symmetric reply flows are not present on any hypervisor.
 AT_CHECK([
@@ -21889,7 +22183,7 @@ net_add n1
 
 sim_add hv1
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
 ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
@@ -21906,7 +22200,7 @@ ovs-vsctl set open . external_ids:ovn-enable-lflow-cache=false
 
 sim_add hv2
 as hv2
-ovs-vsctl add-br br-phys
+check 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=sw0-port2 \
@@ -22147,35 +22441,35 @@ AT_CLEANUP
 AT_SETUP([ovn -- conflict or duplicate ACLs resulting in same OVS match])
 ovn_start
 
-ovn-nbctl ls-add ls1
+check ovn-nbctl ls-add ls1
 
-ovn-nbctl lsp-add ls1 lsp1 \
--- lsp-set-addresses lsp1 "f0:00:00:00:00:01 10.0.0.1"
+check ovn-nbctl lsp-add ls1 lsp1 \
+    -- lsp-set-addresses lsp1 "f0:00:00:00:00:01 10.0.0.1"
 
-ovn-nbctl lsp-add ls1 lsp2 \
--- lsp-set-addresses lsp2 "f0:00:00:00:00:02 10.0.0.2"
+check ovn-nbctl lsp-add ls1 lsp2 \
+    -- lsp-set-addresses lsp2 "f0:00:00:00:00:02 10.0.0.2"
 
 net_add n1
 sim_add hv1
 
 as hv1
-ovs-vsctl add-br br-phys
+check ovs-vsctl add-br br-phys
 ovn_attach n1 br-phys 192.168.0.1
-ovs-vsctl -- add-port br-int hv1-vif1 -- \
+check ovs-vsctl -- add-port br-int hv1-vif1 -- \
     set interface hv1-vif1 external-ids:iface-id=lsp1 \
     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 -- \
+check ovs-vsctl -- add-port br-int hv1-vif2 -- \
     set interface hv1-vif2 external-ids:iface-id=lsp2 \
     options:tx_pcap=hv1/vif2-tx.pcap \
     options:rxq_pcap=hv1/vif2-rx.pcap \
     ofport-request=2
 
 # Default drop
-ovn-nbctl acl-add ls1 to-lport 1000 \
-'outport == "lsp1" && ip4' drop
+check ovn-nbctl acl-add ls1 to-lport 1000 \
+    'outport == "lsp1" && ip4' drop
 
 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
 #
@@ -22209,12 +22503,12 @@ options:rxq_pcap=${pcap_file}-rx.pcap
 
 
 # Create overlapping ACLs resulting in duplicated desired OVS flows
-ovn-nbctl acl-add ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2' allow
-ovn-nbctl acl-add ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}' allow
+check ovn-nbctl acl-add ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2' allow
+check ovn-nbctl acl-add ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}' allow
 
-ovn-nbctl --wait=hv sync
+check ovn-nbctl --wait=hv sync
 
 sip=`ip_to_hex 10 0 0 2`
 dip=`ip_to_hex 10 0 0 1`
@@ -22222,21 +22516,21 @@ test_ip 2 f00000000002 f00000000001 $sip $dip 1
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
 
 # Delete one of the ACLs.
-ovn-nbctl acl-del ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}'
+check ovn-nbctl acl-del ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}'
 check ovn-nbctl --wait=hv sync
 
 test_ip 2 f00000000002 f00000000001 $sip $dip 1
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
 
 # Add a conflict ACL with drop action.
-ovn-nbctl acl-add ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}' drop
+check ovn-nbctl acl-add ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}' drop
 # Don't test because it is unpredicatable which rule will take effect.
 
 # Delete the ACL that has "allow" action
-ovn-nbctl acl-del ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2'
+check ovn-nbctl acl-del ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2'
 check ovn-nbctl --wait=hv sync
 
 # Packet should be dropped
@@ -22244,10 +22538,10 @@ test_ip 2 f00000000002 f00000000001 $sip $dip
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
 
 # Add the ACL back and delete the "drop" ACL
-ovn-nbctl acl-add ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2' allow
-ovn-nbctl acl-del ls1 to-lport 1001 \
-'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}'
+check ovn-nbctl acl-add ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == 10.0.0.2' allow
+check ovn-nbctl acl-del ls1 to-lport 1001 \
+    'outport == "lsp1" && ip4 && ip4.src == {10.0.0.2, 10.0.0.3}'
 check ovn-nbctl --wait=hv sync
 
 # Packet should be received
-- 
2.26.2



More information about the dev mailing list