ovn-nbctl: Update logical router port commands.
[cascardo/ovs.git] / tests / ovn.at
index cc5c468..0b9d3d1 100644 (file)
@@ -774,7 +774,7 @@ test_arp 11 f00000000011  $sip $tip
 # XXX This can be improved.
 sleep 1
 
-# dump infomration and flows with counters
+# dump information and flows with counters
 ovn-sbctl dump-flows -- list multicast_group
 
 echo "------ hv1 dump ------"
@@ -1026,7 +1026,8 @@ OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
-AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
+AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
+AT_KEYWORDS([vtep])
 AT_SKIP_IF([test $HAVE_PYTHON = no])
 ovn_start
 
@@ -1175,18 +1176,20 @@ ovn-sbctl show
 
 echo "------ hv1 dump ------"
 as hv1 ovs-vsctl show
-as hv1 ovs-ofctl show br-int
+as hv1 ovs-ofctl -O OpenFlow13 show br-int
 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
 
 echo "------ hv2 dump ------"
 as hv2 ovs-vsctl show
-as hv2 ovs-ofctl show br-int
+as hv2 ovs-ofctl -O OpenFlow13 show br-int
 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
 
 echo "------ hv3 dump ------"
 as hv3 ovs-vsctl show
-as hv3 ovs-ofctl show br-int
-as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
+# note: hv3 has no logical port bind, thus it should not have br-int
+AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
+[ovs-ofctl: br-int is not a bridge or a socket
+])
 
 # Now check the packets actually received against the ones expected.
 for i in 1 2 3; do
@@ -1260,16 +1263,14 @@ for i in 1 2 3; do
     done
 done
 
-ovn-nbctl create Logical_Router name=lr0
+ovn-nbctl lr-add lr0
 for i in 1 2 3; do
     for j in 1 2 3; do
-       lrp_uuid=`ovn-nbctl \
-           -- --id=@lrp create Logical_Router_Port name=lrp$i$j \
-              network=192.168.$i$j.254/24 mac='"00:00:00:00:ff:'$i$j'"' \
-           -- add Logical_Router lr0 ports @lrp \
-           -- lport-add ls$i lrp$i$j-attachment`
-       ovn-nbctl \
-           set Logical_Port lrp$i$j-attachment type=router \
+           ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j \
+            192.168.$i$j.254/24 lrp$i$j-attachment
+           ovn-nbctl \
+            -- lport-add ls$i lrp$i$j-attachment \
+               -- set Logical_Port lrp$i$j-attachment type=router \
                              options:router-port=lrp$i$j \
                              addresses='"00:00:00:00:ff:'$i$j'"'
     done
@@ -1786,6 +1787,21 @@ test_ipv6() {
     done
 }
 
+# test_icmpv6 INPORT  SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
+# This function is similar to test_ipv6() except it specifies the ICMPv6 type
+# of the test packet
+test_icmpv6() {
+    local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
+    local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
+    shift; shift; shift; shift; shift; shift
+    hv=`vif_to_hv $inport`
+    as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
+    #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
+    for outport; do
+        echo $packet | trim_zeros >> $outport.expected
+    done
+}
+
 ip_to_hex() {
     printf "%02x%02x%02x%02x" "$@"
 }
@@ -1923,8 +1939,15 @@ for i in 1 2 3; do
     sip=fe80000000000000ea2aeafffe2800${i}3
     test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
 
+    # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
     sip=00000000000000000000000000000000
-    test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
+    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
+    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
+    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
+    # Traffic to non-multicast traffic should be dropped
+    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
+    # Traffic of other ICMPv6 types should be dropped
+    test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
 
     # should be dropped
     sip=ae80000000000000ea2aeafffe2800aa
@@ -1994,17 +2017,17 @@ ovn-sbctl dump-flows -- list multicast_group
 
 echo "------ hv1 dump ------"
 as hv1 ovs-vsctl show
-as hv1 ovs-ofctl show br-int
+as hv1 ovs-ofctl -O OpenFlow13 show br-int
 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
 
 echo "------ hv2 dump ------"
 as hv2 ovs-vsctl show
-as hv2 ovs-ofctl show br-int
+as hv2 ovs-ofctl -O OpenFlow13 show br-int
 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
 
 echo "------ hv3 dump ------"
 as hv3 ovs-vsctl show
-as hv3 ovs-ofctl show br-int
+as hv3 ovs-ofctl -O OpenFlow13 show br-int
 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
 
 # Now check the packets actually received against the ones expected.
@@ -2052,39 +2075,27 @@ ovn_start
 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
 # R2 has ls2 (172.16.1.0/24) connected to it.
 
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2
+ovn-nbctl lr-add R1
+ovn-nbctl lr-add R2
 
 ovn-nbctl lswitch-add ls1
 ovn-nbctl lswitch-add ls2
 
 # Connect ls1 to R1
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=ls1 \
-network=192.168.1.1/24 mac=\"00:00:00:01:02:03\" -- add Logical_Router R1 \
-ports @lrp -- lport-add ls1 rp-ls1
+ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 rp-ls1
 
-ovn-nbctl set Logical_port rp-ls1 type=router options:router-port=ls1 \
-addresses=\"00:00:00:01:02:03\"
+ovn-nbctl lport-add ls1 rp-ls1 -- set Logical_port rp-ls1 type=router \
+  options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
 
 # Connect ls2 to R2
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=ls2 \
-network=172.16.1.1/24 mac=\"00:00:00:01:02:04\" -- add Logical_Router R2 \
-ports @lrp -- lport-add ls2 rp-ls2
+ovn-nbctl lrp-add R2 ls2 00:00:00:01:02:04 172.16.1.1/24 rp-ls2
 
-ovn-nbctl set Logical_port rp-ls2 type=router options:router-port=ls2 \
-addresses=\"00:00:00:01:02:04\"
+ovn-nbctl lport-add ls2 rp-ls2 -- set Logical_port rp-ls2 type=router \
+  options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
 
 # Connect R1 to R2
-lrp1_uuid=`ovn-nbctl -- --id=@lrp create Logical_Router_port name=R1_R2 \
-network="20.0.0.1/24" mac=\"00:00:00:02:03:04\" \
--- add Logical_Router R1 ports @lrp`
-
-lrp2_uuid=`ovn-nbctl -- --id=@lrp create Logical_Router_port name=R2_R1 \
-network="20.0.0.2/24" mac=\"00:00:00:02:03:05\" \
--- add Logical_Router R2 ports @lrp`
-
-ovn-nbctl set logical_router_port $lrp1_uuid peer="R2_R1"
-ovn-nbctl set logical_router_port $lrp2_uuid peer="R1_R2"
+ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 R2_R1
+ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 R1_R2
 
 ovn-nbctl set Logical_Router R1 default_gw="20.0.0.2"
 ovn-nbctl set Logical_Router R2 default_gw="20.0.0.1"
@@ -2209,26 +2220,20 @@ ovn_start
 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
 # and has switch ls2 (172.16.1.0/24) connected to it.
 
-ovn-nbctl create Logical_Router name=R1
+ovn-nbctl lr-add R1
 
 ovn-nbctl lswitch-add ls1
 ovn-nbctl lswitch-add ls2
 
 # Connect ls1 to R1
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=ls1 \
-network=192.168.1.1/24 mac=\"00:00:00:01:02:03\" -- add Logical_Router R1 \
-ports @lrp -- lport-add ls1 rp-ls1
-
-ovn-nbctl set Logical_port rp-ls1 type=router options:router-port=ls1 \
-addresses=\"00:00:00:01:02:03\"
+ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 rp-ls1
+ovn-nbctl lport-add ls1 rp-ls1 -- set Logical_port rp-ls1 type=router \
+          options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
 
 # Connect ls2 to R1
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=ls2 \
-network=172.16.1.1/24 mac=\"00:00:00:01:02:04\" -- add Logical_Router R1 \
-ports @lrp -- lport-add ls2 rp-ls2
-
-ovn-nbctl set Logical_port rp-ls2 type=router options:router-port=ls2 \
-addresses=\"00:00:00:01:02:04\"
+ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24 rp-ls2
+ovn-nbctl lport-add ls2 rp-ls2 -- set Logical_port rp-ls2 type=router \
+          options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
 
 # Create logical port ls1-lp1 in ls1
 ovn-nbctl lport-add ls1 ls1-lp1 \
@@ -2352,48 +2357,31 @@ ovn_start
 # connected to it.
 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
 
-ovn-nbctl create Logical_Router name=R1
-ovn-nbctl create Logical_Router name=R2
+ovn-nbctl lr-add R1
+ovn-nbctl lr-add R2
 
 ovn-nbctl lswitch-add foo
 ovn-nbctl lswitch-add alice
 ovn-nbctl lswitch-add bob
 
 # Connect foo to R1
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=foo \
-network=192.168.1.1/24 mac=\"00:00:00:01:02:03\" -- add Logical_Router R1 \
-ports @lrp -- lport-add foo rp-foo
-
-ovn-nbctl set Logical_port rp-foo type=router options:router-port=foo \
-addresses=\"00:00:00:01:02:03\"
+ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24 rp-foo
+ovn-nbctl lport-add foo rp-foo -- set Logical_port rp-foo type=router \
+          options:router-port=foo addresses=\"00:00:00:01:02:03\"
 
 # Connect alice to R2
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=alice \
-network=172.16.1.1/24 mac=\"00:00:00:01:02:04\" -- add Logical_Router R2 \
-ports @lrp -- lport-add alice rp-alice
-
-ovn-nbctl set Logical_port rp-alice type=router options:router-port=alice \
-addresses=\"00:00:00:01:02:04\"
+ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24 rp-alice
+ovn-nbctl lport-add alice rp-alice -- set Logical_port rp-alice type=router \
+          options:router-port=alice addresses=\"00:00:00:01:02:04\"
 
 # Connect bob to R2
-ovn-nbctl -- --id=@lrp create Logical_Router_port name=bob \
-network=172.16.2.1/24 mac=\"00:00:00:01:02:05\" -- add Logical_Router R2 \
-ports @lrp -- lport-add bob rp-bob
-
-ovn-nbctl set Logical_port rp-bob type=router options:router-port=bob \
-addresses=\"00:00:00:01:02:05\"
+ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24 rp-bob
+ovn-nbctl lport-add bob rp-bob -- set Logical_port rp-bob type=router \
+          options:router-port=bob addresses=\"00:00:00:01:02:05\"
 
 # Connect R1 to R2
-lrp1_uuid=`ovn-nbctl -- --id=@lrp create Logical_Router_port name=R1_R2 \
-network="20.0.0.1/24" mac=\"00:00:00:02:03:04\" \
--- add Logical_Router R1 ports @lrp`
-
-lrp2_uuid=`ovn-nbctl -- --id=@lrp create Logical_Router_port name=R2_R1 \
-network="20.0.0.2/24" mac=\"00:00:00:02:03:05\" \
--- add Logical_Router R2 ports @lrp`
-
-ovn-nbctl set logical_router_port $lrp1_uuid peer="R2_R1"
-ovn-nbctl set logical_router_port $lrp2_uuid peer="R1_R2"
+ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 R2_R1
+ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 R1_R2
 
 #install static routes
 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
@@ -2608,3 +2596,562 @@ OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 
 AT_CLEANUP
+
+AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
+AT_KEYWORDS([ovnstaticroutes])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+# Logical network:
+# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
+# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
+# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
+# connected to it.
+
+ovn-nbctl lr-add R1
+ovn-nbctl lr-add R2
+ovn-nbctl lr-add R3
+
+ovn-nbctl lswitch-add foo
+ovn-nbctl lswitch-add alice
+ovn-nbctl lswitch-add bob
+ovn-nbctl lswitch-add join
+
+# Connect foo to R1
+ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+ovn-nbctl lport-add foo rp-foo -- set Logical_port rp-foo type=router \
+    options:router-port=foo addresses=\"00:00:01:01:02:03\"
+
+# Connect alice to R2
+ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
+ovn-nbctl lport-add alice rp-alice -- set Logical_port rp-alice type=router \
+    options:router-port=alice addresses=\"00:00:02:01:02:03\"
+
+# Connect bob to R3
+ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
+ovn-nbctl lport-add bob rp-bob -- set Logical_port rp-bob type=router \
+    options:router-port=bob addresses=\"00:00:03:01:02:03\"
+
+# Connect R1 to join
+ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
+ovn-nbctl lport-add join r1-join -- set Logical_port r1-join type=router \
+    options:router-port=R1_join addresses='"00:00:04:01:02:03"'
+
+# Connect R2 to join
+ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
+ovn-nbctl lport-add join r2-join -- set Logical_port r2-join type=router \
+    options:router-port=R2_join addresses='"00:00:04:01:02:04"'
+
+
+# Connect R3 to join
+ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
+ovn-nbctl lport-add join r3-join -- set Logical_port r3-join type=router \
+    options:router-port=R3_join addresses='"00:00:04:01:02:05"'
+
+#install static routes
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
+R1 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=10.32.1.0/24 nexthop=20.0.0.3 -- add Logical_Router \
+R1 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
+R2 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=10.32.1.0/24 nexthop=20.0.0.3 -- add Logical_Router \
+R2 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
+R3 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
+R3 static_routes @lrt
+
+# Create logical port foo1 in foo
+ovn-nbctl lport-add foo foo1 \
+-- lport-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
+
+# Create logical port alice1 in alice
+ovn-nbctl lport-add alice alice1 \
+-- lport-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
+
+# Create logical port bob1 in bob
+ovn-nbctl lport-add bob bob1 \
+-- lport-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
+
+# Create two hypervisor and create OVS ports corresponding to logical ports.
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+    set interface hv1-vif1 external-ids:iface-id=foo1 \
+    options:tx_pcap=hv1/vif1-tx.pcap \
+    options:rxq_pcap=hv1/vif1-rx.pcap \
+    ofport-request=1
+
+ovs-vsctl -- add-port br-int hv1-vif2 -- \
+    set interface hv1-vif2 external-ids:iface-id=alice1 \
+    options:tx_pcap=hv1/vif2-tx.pcap \
+    options:rxq_pcap=hv1/vif2-rx.pcap \
+    ofport-request=2
+
+sim_add hv2
+as hv2
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.2
+ovs-vsctl -- add-port br-int hv2-vif1 -- \
+    set interface hv2-vif1 external-ids:iface-id=bob1 \
+    options:tx_pcap=hv2/vif1-tx.pcap \
+    options:rxq_pcap=hv2/vif1-rx.pcap \
+    ofport-request=1
+
+
+# Pre-populate the hypervisors' ARP tables so that we don't lose any
+# packets for ARP resolution (native tunneling doesn't queue packets
+# for ARP resolution).
+ovn_populate_arp
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+# XXX This should be more systematic.
+sleep 1
+
+ip_to_hex() {
+    printf "%02x%02x%02x%02x" "$@"
+}
+trim_zeros() {
+    sed 's/\(00\)\{1,\}$//'
+}
+
+# Send ip packets between foo1 and alice1
+src_mac="f00000010203"
+dst_mac="000001010203"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 172 16 1 2`
+packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
+
+# Send ip packets between foo1 and bob1
+src_mac="f00000010203"
+dst_mac="000001010203"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 10 32 1 2`
+packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+
+echo "---------NB dump-----"
+ovn-nbctl show
+echo "---------------------"
+ovn-nbctl list logical_router
+echo "---------------------"
+ovn-nbctl list logical_router_port
+echo "---------------------"
+
+echo "---------SB dump-----"
+ovn-sbctl list datapath_binding
+echo "---------------------"
+ovn-sbctl list port_binding
+echo "---------------------"
+ovn-sbctl dump-flows
+echo "---------------------"
+
+echo "------ hv1 dump ----------"
+as hv1 ovs-ofctl show br-int
+as hv1 ovs-ofctl dump-flows br-int
+echo "------ hv2 dump ----------"
+as hv2 ovs-ofctl show br-int
+as hv2 ovs-ofctl dump-flows br-int
+echo "----------------------------"
+
+# Packet to Expect at bob1
+src_mac="000003010203"
+dst_mac="f00000010205"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 10 32 1 2`
+expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
+
+$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received.packets
+echo $expected | trim_zeros > expout
+AT_CHECK([cat received.packets], [0], [expout])
+
+# Packet to Expect at alice1
+src_mac="000002010203"
+dst_mac="f00000010204"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 172 16 1 2`
+expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
+
+$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > received1.packets
+echo $expected | trim_zeros > expout
+AT_CHECK([cat received1.packets], [0], [expout])
+
+for sim in hv1 hv2; do
+    as $sim
+    OVS_APP_EXIT_AND_WAIT([ovn-controller])
+    OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+    OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+done
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([ovn-northd])
+
+as main
+OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+AT_CLEANUP
+
+
+AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
+AT_KEYWORDS([ovngatewayrouter])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+# Logical network:
+# Two LRs - R1 and R2 that are connected to each other via LS "join"
+# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
+# connected to it. R2 has alice (172.16.1.0/24) connected to it.
+# R2 is a gateway router.
+
+
+
+# Create two hypervisor and create OVS ports corresponding to logical ports.
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
+    set interface hv1-vif1 external-ids:iface-id=foo1 \
+    options:tx_pcap=hv1/vif1-tx.pcap \
+    options:rxq_pcap=hv1/vif1-rx.pcap \
+    ofport-request=1
+
+
+sim_add hv2
+as hv2
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.2
+ovs-vsctl -- add-port br-int hv2-vif1 -- \
+    set interface hv2-vif1 external-ids:iface-id=alice1 \
+    options:tx_pcap=hv2/vif1-tx.pcap \
+    options:rxq_pcap=hv2/vif1-rx.pcap \
+    ofport-request=1
+
+# Pre-populate the hypervisors' ARP tables so that we don't lose any
+# packets for ARP resolution (native tunneling doesn't queue packets
+# for ARP resolution).
+ovn_populate_arp
+
+ovn-nbctl create Logical_Router name=R1
+ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
+
+ovn-nbctl lswitch-add foo
+ovn-nbctl lswitch-add alice
+ovn-nbctl lswitch-add join
+
+# Connect foo to R1
+ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
+ovn-nbctl lport-add foo rp-foo -- set Logical_port rp-foo type=router \
+    options:router-port=foo addresses=\"00:00:01:01:02:03\"
+
+# Connect alice to R2
+ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
+ovn-nbctl lport-add alice rp-alice -- set Logical_port rp-alice type=router \
+    options:router-port=alice addresses=\"00:00:02:01:02:03\"
+
+# Connect R1 to join
+ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
+ovn-nbctl lport-add join r1-join -- set Logical_port r1-join type=router \
+    options:router-port=R1_join addresses='"00:00:04:01:02:03"'
+
+# Connect R2 to join
+ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
+ovn-nbctl lport-add join r2-join -- set Logical_port r2-join type=router \
+    options:router-port=R2_join addresses='"00:00:04:01:02:04"'
+
+
+#install static routes
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
+R1 static_routes @lrt
+
+ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
+ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
+R2 static_routes @lrt
+
+# Create logical port foo1 in foo
+ovn-nbctl lport-add foo foo1 \
+-- lport-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
+
+# Create logical port alice1 in alice
+ovn-nbctl lport-add alice alice1 \
+-- lport-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
+
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+# XXX This should be more systematic.
+sleep 2
+
+ip_to_hex() {
+    printf "%02x%02x%02x%02x" "$@"
+}
+trim_zeros() {
+    sed 's/\(00\)\{1,\}$//'
+}
+
+# Send ip packets between foo1 and alice1
+src_mac="f00000010203"
+dst_mac="000001010203"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 172 16 1 2`
+packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
+
+echo "---------NB dump-----"
+ovn-nbctl show
+echo "---------------------"
+ovn-nbctl list logical_router
+echo "---------------------"
+ovn-nbctl list logical_router_port
+echo "---------------------"
+
+echo "---------SB dump-----"
+ovn-sbctl list datapath_binding
+echo "---------------------"
+ovn-sbctl list port_binding
+echo "---------------------"
+ovn-sbctl dump-flows
+echo "---------------------"
+ovn-sbctl list chassis
+ovn-sbctl list encap
+echo "---------------------"
+
+echo "------ hv1 dump ----------"
+as hv1 ovs-ofctl show br-int
+as hv1 ovs-ofctl dump-flows br-int
+echo "------ hv2 dump ----------"
+as hv2 ovs-ofctl show br-int
+as hv2 ovs-ofctl dump-flows br-int
+echo "----------------------------"
+
+# Packet to Expect at alice1
+src_mac="000002010203"
+dst_mac="f00000010204"
+src_ip=`ip_to_hex 192 168 1 2`
+dst_ip=`ip_to_hex 172 16 1 2`
+expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
+
+
+as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
+as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
+
+$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received1.packets
+echo $expected | trim_zeros > expout
+AT_CHECK([cat received1.packets], [0], [expout])
+
+for sim in hv1 hv2; do
+    as $sim
+    OVS_APP_EXIT_AND_WAIT([ovn-controller])
+    OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+    OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+done
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([ovn-northd])
+
+as main
+OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+AT_CLEANUP
+
+AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
+AT_KEYWORDS([router-icmp-reply])
+AT_SKIP_IF([test $HAVE_PYTHON = no])
+ovn_start
+
+# Logical network:
+# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
+# and has switch ls2 (172.16.1.0/24) connected to it.
+
+ovn-nbctl lr-add R1
+
+ovn-nbctl lswitch-add ls1
+ovn-nbctl lswitch-add ls2
+
+# Connect ls1 to R1
+ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
+ovn-nbctl lport-add ls1 rp-ls1 -- set Logical_port rp-ls1 type=router \
+    options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
+
+# Connect ls2 to R1
+ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
+ovn-nbctl lport-add ls2 rp-ls2 -- set Logical_port rp-ls2 type=router \
+    options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
+
+# Create logical port ls1-lp1 in ls1
+ovn-nbctl lport-add ls1 ls1-lp1 \
+-- lport-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
+
+# Create logical port ls2-lp1 in ls2
+ovn-nbctl lport-add ls2 ls2-lp1 \
+-- lport-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
+
+# Create one hypervisor and create OVS ports corresponding to logical ports.
+net_add n1
+
+sim_add hv1
+as hv1
+ovs-vsctl add-br br-phys
+ovn_attach n1 br-phys 192.168.0.1
+ovs-vsctl -- add-port br-int vif1 -- \
+    set interface vif1 external-ids:iface-id=ls1-lp1 \
+    options:tx_pcap=hv1/vif1-tx.pcap \
+    options:rxq_pcap=hv1/vif1-rx.pcap \
+    ofport-request=1
+
+ovs-vsctl -- add-port br-int vif2 -- \
+    set interface vif2 external-ids:iface-id=ls2-lp1 \
+    options:tx_pcap=hv1/vif2-tx.pcap \
+    options:rxq_pcap=hv1/vif2-rx.pcap \
+    ofport-request=1
+
+
+# Allow some time for ovn-northd and ovn-controller to catch up.
+# XXX This should be more systematic.
+sleep 1
+
+
+ip_to_hex() {
+    printf "%02x%02x%02x%02x" "$@"
+}
+trim_zeros() {
+    sed 's/\(00\)\{1,\}$//'
+}
+for i in 1 2; do
+    : > vif$i.expected
+done
+# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
+#
+# Causes a packet to be received on INPORT.  The packet is an ICMPv4
+# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
+# ICMP_CHKSUM as specified.  If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
+# provided, then it should be the ip and icmp checksums of the packet
+# responded; otherwise, no reply is expected.
+# In the absence of an ip checksum calculation helpers, this relies
+# on the caller to provide the checksums for the ip and icmp headers.
+# XXX This should be more systematic.
+#
+# INPORT is an lport number, e.g. 11 for vif11.
+# ETH_SRC and ETH_DST are each 12 hex digits.
+# IPV4_SRC and IPV4_DST are each 8 hex digits.
+# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
+# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
+test_ipv4_icmp_request() {
+    local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
+    local exp_ip_chksum=$8 exp_icmp_chksum=$9
+    shift; shift; shift; shift; shift; shift; shift
+    shift; shift
+
+    # Use ttl to exercise section 4.2.2.9 of RFC1812
+    local ip_ttl=01
+    local icmp_id=5fbf
+    local icmp_seq=0001
+    local icmp_data=$(seq 1 56 | xargs printf "%02x")
+    local icmp_type_code_request=0800
+    local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
+    local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
+
+    as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
+    if test X$exp_icmp_chksum != X; then
+        # Expect to receive the reply, if any. In same port where packet was sent.
+        # Note: src and dst fields are expected to be reversed.
+        local icmp_type_code_response=0000
+        local reply_icmp_ttl=fe
+        local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
+        local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
+        echo $reply >> vif$inport.expected
+    fi
+}
+
+# Send ping packet to router's ip addresses, from each of the 2 logical ports.
+rtr_l1_ip=$(ip_to_hex 192 168 1 1)
+rtr_l2_ip=$(ip_to_hex 172 16 1 1)
+l1_ip=$(ip_to_hex 192 168 1 2)
+l2_ip=$(ip_to_hex 172 16 1 2)
+
+# Ping router ip address that is on same subnet as the logical port
+test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
+test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
+
+# Ping router ip address that is on the other side of the logical ports
+test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
+test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
+
+echo "---------NB dump-----"
+ovn-nbctl show
+echo "---------------------"
+ovn-nbctl list logical_router
+echo "---------------------"
+ovn-nbctl list logical_router_port
+echo "---------------------"
+
+echo "---------SB dump-----"
+ovn-sbctl list datapath_binding
+echo "---------------------"
+ovn-sbctl list logical_flow
+echo "---------------------"
+
+echo "------ hv1 dump ----------"
+as hv1 ovs-ofctl dump-flows br-int
+
+# Now check the packets actually received against the ones expected.
+for inport in 1 2; do
+    file=hv1/vif${inport}-tx.pcap
+    echo $file
+    $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > received.packets
+    cat vif$inport.expected | trim_zeros > expout
+    AT_CHECK([cat received.packets], [0], [expout])
+done
+
+as hv1
+OVS_APP_EXIT_AND_WAIT([ovn-controller])
+OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([ovn-northd])
+
+as main
+OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+AT_CLEANUP