Introduce EVPN L2 Single Vxlan Device (SVD) test scenario.

Reported-at: https://issues.redhat.com/browse/FDP-2733
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
 tests/multinode-bgp-macros.at | 145 ++++++++---
 tests/multinode.at            | 476 +++++++++++++++++++++++++++++++++-
 2 files changed, 582 insertions(+), 39 deletions(-)

diff --git a/tests/multinode-bgp-macros.at b/tests/multinode-bgp-macros.at
index a036e0848..0693c571d 100644
--- a/tests/multinode-bgp-macros.at
+++ b/tests/multinode-bgp-macros.at
@@ -18,12 +18,12 @@ m_frr_ns_flags() {
     fi
 }
 
-# m_setup_external_frr_vrf NODE VNI VXLAN_IP LOCAL_MAC LOCAL_IP LOCAL_IP6 NETNS
+# m_setup_external_frr_vrf NODE LOCAL_IP LOCAL_IP6 LOCAL_MAC VNI NETNS
 #
 # Sets up a VRF in NETNS so that it can be used by FRR running in that
 # namespace to advertise EVPN routes.
 m_setup_external_frr_vrf() {
-    local node=$1 vni=$2 vxlan_ip=$3 local_mac=$4 local_ip=$5 local_ip6=$6 
ns=$7
+    local node=$1 vxlan_ip=$2 local_ip=$3 local_ip6=$4 local_mac=$5 vni=$6 
ns=$7
 
     local ns_prefix="ip netns exec $ns "
     local vrf=vrf-$vni
@@ -111,16 +111,14 @@ m_setup_external_frr_router() {
     check m_as $node systemctl start frr
 }
 
-# m_config_external_frr_router NODE BGP_AS BGP_ROUTER_ID BGP_IP BGP_IP6 
BGP_MAC [VNI]
+# m_config_external_frr_service NODE BGP_AS BGP_ROUTER_ID
 #
 # Configures an external FRR BGP speaker in a network namespace on the
 # ovn-fake-multinode node NODE.  The BGP autonomous system is configured to be
-# BGP_AS.  The speaker uses as BGP IP address, BGP_IP, BGP_IP6 and BGP_MAC as 
mac
-# address.
-m_config_external_frr_router() {
-    local node=$1 bgp_as=$2 bgp_router_id=$3 bgp_ip=$4 bgp_ip6=$5 bgp_mac=$6 
vni=$7
+# BGP_AS.
+m_config_external_frr_service() {
+    local node=$1 bgp_as=$2 bgp_router_id=$3
     local frr_flags=$(m_frr_ns_flags frr-ns)
-    local br_name=br-$node
 
     # NOTE: we set "no bgp ebgp-requires-policy" to simplify EVPN deployments.
     echo "configure
@@ -143,11 +141,22 @@ m_config_external_frr_router() {
         advertise-all-vni
       exit-address-family
     " | podman exec -i $node vtysh $frr_flags
+}
+
+# m_config_external_frr_router NODE BGP_AS BGP_ROUTER_ID BGP_IP BGP_IP6 
BGP_MAC [VNI]
+#
+# Configures an external FRR BGP speaker in a network namespace on the
+# ovn-fake-multinode node NODE.  The BGP autonomous system is configured to be
+# BGP_AS.  The speaker uses as BGP IP address, BGP_IP, BGP_IP6 and BGP_MAC as 
mac
+# address.
+m_config_external_frr_router() {
+    local node=$1 bgp_as=$2 bgp_router_id=$3 bgp_ip=$4 bgp_ip6=$5 bgp_mac=$6 
vni=$7
 
+    m_config_external_frr_service $node $bgp_as $bgp_router_id
     # Configure VRF, if any provided.
     vxlan_ip=$(echo $bgp_ip | cut -f 1 -d '/')
     if [[[ -n "$vni" ]]]; then
-        m_setup_external_frr_vrf $node $vni $vxlan_ip $bgp_mac $bgp_ip 
$bgp_ip6 frr-ns
+        m_setup_external_frr_vrf $node $vxlan_ip $bgp_ip $bgp_ip6 $bgp_mac 
$vni frr-ns
     fi
 }
 
@@ -207,7 +216,7 @@ m_config_external_frr_router_l3() {
 
     # Configure VRF, if any provided.
     vxlan_ip=$(echo $bgp_ip | cut -f 1 -d '/')
-    m_setup_external_frr_vrf $node $vni $vxlan_ip $bgp_mac $bgp_ip $bgp_ip6 
frr-ns
+    m_setup_external_frr_vrf $node $vxlan_ip $bgp_ip $bgp_ip6 $bgp_mac $vni 
frr-ns
 }
 
 # m_ovn_frr_router_name NODE
@@ -398,12 +407,82 @@ m_setup_host_frr_vrf() {
     # Add a dummy loopback to the VNI bridge to be used for advertising local
     # MACs.
     check m_as $node ip link add name $lo type dummy
+    check m_as $node ip link set $lo master $br
+    check m_as $node ip link set $lo up
     on_exit "m_as $node ip link del $lo"
+}
+
+# m_setup_host_svd_tunnel NODE VXLAN_IP LOCAL_IP LOCAL_MAC VNI
+#
+# Sets up the VXLAN tunnel used in SVD scenarion.
+m_setup_host_svd_tunnel() {
+    local node=$1 vxlan_ip=$2 local_ip=$3 local_mac=$4 vni=$5
+    local br=br-evpn
+    local vxlan=vxlan-evpn
+    local vxlan_port=4789
+
+    # Add VNI bridge.
+    check m_as $node ip link add $br type bridge vlan_filtering 1 
vlan_default_pvid 0
+    check m_as $node ip link set $br addrgenmode none
+    on_exit "m_as $node ip link del $br"
+    check m_as $node ip link set $br address $local_mac
+    check m_as $node ip link set dev $br up
+
+    # Add VXLAN VTEP for the VNI (linked to the OVS vxlan_sys_<port> 
interface).
+    # Use a dstport different than the one used by OVS.
+    # This is fine because we don't actually want traffic to pass through
+    # the $vxlan interface.  FRR should read the dstport from the linked
+    # vxlan_sys_${vxlan_port} device.
+    local dstport=60010
+    check m_as $node ip link add $vxlan type vxlan   \
+        dev vxlan_sys_${vxlan_port}                  \
+        dstport $dstport local $vxlan_ip nolearning external vnifilter
+    check m_as $node ip link set $vxlan addrgenmode none master $br
+    check m_as $node ip link set $vxlan address $local_mac
+    check m_as $node bridge link set dev $vxlan vlan_tunnel on \
+        neigh_suppress on learning off
+    on_exit "m_as $node ip link del $vxlan"
+    check m_as $node ip link set dev $vxlan up
+}
+
+# m_setup_host_frr_vrf_svd NODE VNI
+#
+# Sets up a VRF in the default net namespace so that it can be used by OVN
+# and FRR to advertise EVPN routes.
+m_setup_host_frr_vrf_svd() {
+    local node=$1 vni=$2
+
+    local vrf=vrf-$vni
+    local br=br-evpn
+    local vxlan=vxlan-evpn
+    local lo=lo-$vni
+    local vid=$((vni*10))
+
+    # Setup a VRF for the VNI.
+    check m_as $node ip link add $vrf type vrf table $vni
+    on_exit "m_as $node ip link del $vrf"
+    check m_as $node ip link set $vrf up
+
+    check m_as $node bridge vlan add dev $br vid $vid self
+    check m_as $node bridge vlan add dev $vxlan vid $vid
+    check m_as $node bridge vni add dev $vxlan vni $vni
+    check m_as $node bridge vlan add dev $vxlan vid $vid tunnel_info id $vni
+
+    check m_as $node ip link add vlan-$vid link $br type vlan id $vid
+    check m_as $node ip link set vlan-$vid master $vrf
+    check m_as $node ip link set vlan-$vid addr aa:bb:cc:00:01:$vni
+    check m_as $node ip link set vlan-$vid up
+
+    # Add a dummy loopback to the VNI bridge to be used for advertising local
+    # MACs.
+    check m_as $node ip link add name $lo type dummy
     check m_as $node ip link set $lo master $br
+    check m_as $node bridge vlan add dev $lo vid $vid pvid untagged
     check m_as $node ip link set $lo up
+    on_exit "m_as $node ip link del $lo"
 }
 
-# m_setup_host_frr_router NODE BGP_AS BGP_ROUTER_ID BGP_IP BGP_MAC VNI
+# m_setup_host_frr_router NODE BGP_IP
 #
 # Sets up an FRR BGP speaker in the default network namespace on the
 # ovn-fake-multinode node NODE.  This speaker is running on a ovs bridge
@@ -412,39 +491,22 @@ m_setup_host_frr_vrf() {
 # The BGP autonomous system is configured to be BGP_AS and the FRR instance
 # runs in vrf-VNI.
 m_setup_host_frr_router() {
-    local node=$1 bgp_as=$2 bgp_router_id=$3 bgp_ip=$4 bgp_mac=$5 vni=$6
-
-    local br_name=br-$node physnet=physnet_${node}_ext0
-    local lr=$(m_ovn_frr_router_name $node)
-    local lrp=$(m_ovn_frr_router_port_name $node)
-    local ls=$(m_ovn_frr_switch_name $node)
-    local lsp=$(m_ovn_frr_switch_port_name $node)
-    local lsp_bgp=$(m_ovn_frr_switch_bgp_port_name $node)
-    local lsp_ln=$(m_ovn_frr_switch_localnet_port_name $node)
+    local node=$1 bgp_ip=$2
+    local br_name=br-$node
 
     # Configure the BGP IP on the bridge LOCAL interface.
     check m_as $node ip addr add $bgp_ip dev $br_name
     check m_as $node ip link set $br_name up
 }
 
-# m_config_host_frr_router NODE BGP_AS BGP_ROUTER_ID BGP_IP BGP_MAC VNI
+# m_config_host_frr_service NODE BGP_AS BGP_ROUTER_ID
 #
 # Sets up an FRR BGP speaker in the default network namespace on the
 # ovn-fake-multinode node NODE.  This speaker is running on a ovs bridge
-# interface (simulating the fabric connection).
-#
-# The BGP autonomous system is configured to be BGP_AS and the FRR instance
-# runs in vrf-VNI.
-m_config_host_frr_router() {
-    local node=$1 bgp_as=$2 bgp_router_id=$3 bgp_ip=$4 bgp_mac=$5 vni=$6
-
-    local br_name=br-$node physnet=physnet_${node}_ext0
-    local lr=$(m_ovn_frr_router_name $node)
-    local lrp=$(m_ovn_frr_router_port_name $node)
-    local ls=$(m_ovn_frr_switch_name $node)
-    local lsp=$(m_ovn_frr_switch_port_name $node)
-    local lsp_bgp=$(m_ovn_frr_switch_bgp_port_name $node)
-    local lsp_ln=$(m_ovn_frr_switch_localnet_port_name $node)
+# nterface (simulating the fabric connection).
+m_config_host_frr_service() {
+    local node=$1 bgp_as=$2 bgp_router_id=$3
+    local br_name=br-$node
 
     # NOTE: we set "no bgp ebgp-requires-policy" to simplify EVPN deployments.
     echo "configure
@@ -473,7 +535,20 @@ m_config_host_frr_router() {
         advertise-all-vni
       exit-address-family
     " | podman exec -i $node vtysh
+}
+
+# m_config_host_frr_router NODE BGP_AS BGP_ROUTER_ID BGP_IP BGP_MAC VNI
+#
+# Sets up an FRR BGP speaker in the default network namespace on the
+# ovn-fake-multinode node NODE.  This speaker is running on a ovs bridge
+# interface (simulating the fabric connection).
+#
+# The BGP autonomous system is configured to be BGP_AS and the FRR instance
+# runs in vrf-VNI.
+m_config_host_frr_router() {
+    local node=$1 bgp_as=$2 bgp_router_id=$3 bgp_ip=$4 bgp_mac=$5 vni=$6 svd=$7
 
+    m_config_host_frr_service $node $bgp_as $bgp_router_id
     # Configure VRF.
     vxlan_ip=$(echo $bgp_ip | cut -f 1 -d '/')
     m_setup_host_frr_vrf $node $vni $vxlan_ip $bgp_mac $bgp_ip
diff --git a/tests/multinode.at b/tests/multinode.at
index 561157ba2..514a974ed 100644
--- a/tests/multinode.at
+++ b/tests/multinode.at
@@ -3489,12 +3489,12 @@ host_bgp_mac_gw2=00:00:00:02:00:$vni
 
 m_setup_external_frr_router  ovn-gw-1                             
$ext_bgp_ip_gw1/24
 m_config_external_frr_router ovn-gw-1 4200000100 $ext_bgp_ip_gw1  
$ext_bgp_ip_gw1/24  $ext_bgp_ip6_gw1/64 $ext_bgp_mac_gw1 $vni
-m_setup_host_frr_router      ovn-gw-1 4210000000 $host_bgp_ip_gw1 
$host_bgp_ip_gw1/24                     $host_bgp_mac_gw1 $vni
+m_setup_host_frr_router      ovn-gw-1                             
$host_bgp_ip_gw1/24
 m_config_host_frr_router     ovn-gw-1 4210000000 $host_bgp_ip_gw1 
$host_bgp_ip_gw1/24                     $host_bgp_mac_gw1 $vni
 
 m_setup_external_frr_router  ovn-gw-2                             
$ext_bgp_ip_gw2/24
 m_config_external_frr_router ovn-gw-2 4200000200 $ext_bgp_ip_gw2  
$ext_bgp_ip_gw2/24  $ext_bgp_ip6_gw2/64 $ext_bgp_mac_gw2 $vni
-m_setup_host_frr_router      ovn-gw-2 4210000000 $host_bgp_ip_gw2 
$host_bgp_ip_gw2/24                     $host_bgp_mac_gw2 $vni
+m_setup_host_frr_router      ovn-gw-2                             
$host_bgp_ip_gw2/24
 m_config_host_frr_router     ovn-gw-2 4210000000 $host_bgp_ip_gw2 
$host_bgp_ip_gw2/24                     $host_bgp_mac_gw2 $vni
 
 OVS_WAIT_UNTIL([m_as ovn-gw-1 vtysh -c 'show bgp neighbors' | grep -qE 
'Connections established 1'])
@@ -3744,6 +3744,474 @@ OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows 
br-int table=OFTABLE_GET
 
 AT_CLEANUP
 
+AT_SETUP([ovn multinode bgp L2 EVPN - Single Vxlan Device])
+check_fake_multinode_setup
+
+# Delete the multinode NB and OVS resources before starting the test.
+cleanup_multinode_resources
+
+CHECK_VRF()
+
+vni0=10
+vid0=$((vni0*10))
+vni1=20
+vid1=$((vni1*10))
+ext0_bgp_ip_gw1=42.42.$vni0.11
+ext0_bgp_ip6_gw1=42:42:$vni0::11
+ext0_bgp_mac_gw1=00:00:01:00:00:$vni0
+ext1_bgp_ip_gw1=42.42.$vni1.11
+ext1_bgp_ip6_gw1=42:42:$vni1::11
+ext1_bgp_mac_gw1=00:00:01:00:00:$vni1
+host0_bgp_ip_gw1=42.42.$vni0.12
+host0_bgp_mac_gw1=00:00:00:01:00:$vni0
+ext0_bgp_ip_gw2=42.42.$vni0.21
+ext0_bgp_ip6_gw2=42:42:$vni0::21
+ext0_bgp_mac_gw2=00:00:02:00:00:$vni0
+ext1_bgp_ip_gw2=42.42.$vni1.21
+ext1_bgp_ip6_gw2=42:42:$vni1::21
+ext1_bgp_mac_gw2=00:00:02:00:00:$vni1
+host0_bgp_ip_gw2=42.42.$vni0.22
+host0_bgp_mac_gw2=00:00:00:02:00:$vni0
+
+# Create a flat, distributed OVN localnet switch, with EVPN configured.
+ check m_as ovn-gw-1 ovs-vsctl set open . 
external-ids:ovn-bridge-mappings=public0:br-ex,public1:br-ex
+ check m_as ovn-gw-2 ovs-vsctl set open . 
external-ids:ovn-bridge-mappings=public0:br-ex,public1:br-ex
+ check m_as ovn-gw-1 ovs-vsctl set open . 
external-ids:ovn-evpn-local-ip=${vni0}-$host0_bgp_ip_gw1,${vni1}-$host0_bgp_ip_gw1
+ check m_as ovn-gw-2 ovs-vsctl set open . 
external-ids:ovn-evpn-local-ip=${vni0}-$host0_bgp_ip_gw2,${vni1}-$host0_bgp_ip_gw2
+ # The tunnels need to be created before the call to 
"m_config_host_frr_router()".
+ check m_as ovn-gw-1 ovs-vsctl set open . 
external-ids:ovn-evpn-vxlan-ports=4789
+ check m_as ovn-gw-2 ovs-vsctl set open . 
external-ids:ovn-evpn-vxlan-ports=4789
+
+m_setup_external_frr_router     ovn-gw-1                                    
$ext0_bgp_ip_gw1/24
+m_config_external_frr_service   ovn-gw-1    4200000100  $ext0_bgp_ip_gw1
+m_setup_external_frr_vrf        ovn-gw-1                $ext0_bgp_ip_gw1    
$ext0_bgp_ip_gw1/24     $ext0_bgp_ip6_gw1/64    $ext0_bgp_mac_gw1   $vni0   
frr-ns
+m_setup_external_frr_vrf        ovn-gw-1                $ext0_bgp_ip_gw1    
$ext1_bgp_ip_gw1/24     $ext1_bgp_ip6_gw1/64    $ext1_bgp_mac_gw1   $vni1   
frr-ns
+m_setup_host_frr_router         ovn-gw-1                                    
$host0_bgp_ip_gw1/24
+m_config_host_frr_service       ovn-gw-1    4210000000  $host0_bgp_ip_gw1
+m_setup_host_svd_tunnel         ovn-gw-1                $host0_bgp_ip_gw1   
$host0_bgp_ip_gw1/24                            $host0_bgp_mac_gw1  $vni0
+m_setup_host_frr_vrf_svd        ovn-gw-1                                       
                                                                 $vni0
+m_setup_host_frr_vrf_svd        ovn-gw-1                                       
                                                                 $vni1
+
+m_setup_external_frr_router     ovn-gw-2                                    
$ext0_bgp_ip_gw2/24
+m_config_external_frr_service   ovn-gw-2    4200000200  $ext0_bgp_ip_gw2
+m_setup_external_frr_vrf        ovn-gw-2                $ext0_bgp_ip_gw2    
$ext0_bgp_ip_gw2/24     $ext0_bgp_ip6_gw2/64    $ext0_bgp_mac_gw2   $vni0   
frr-ns
+m_setup_external_frr_vrf        ovn-gw-2                $ext0_bgp_ip_gw2    
$ext1_bgp_ip_gw2/24     $ext1_bgp_ip6_gw2/64    $ext1_bgp_mac_gw2   $vni1   
frr-ns
+m_setup_host_frr_router         ovn-gw-2                                    
$host0_bgp_ip_gw2/24
+m_config_host_frr_service       ovn-gw-2    4210000000  $host0_bgp_ip_gw2
+m_setup_host_svd_tunnel         ovn-gw-2                $host0_bgp_ip_gw2   
$host0_bgp_ip_gw2/24                            $host0_bgp_mac_gw2  $vni0
+m_setup_host_frr_vrf_svd        ovn-gw-2                                       
                                                                 $vni0
+m_setup_host_frr_vrf_svd        ovn-gw-2                                       
                                                                 $vni1
+
+OVS_WAIT_UNTIL([m_as ovn-gw-1 vtysh -c 'show bgp neighbors' | grep -qE 
'Connections established 1'])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 vtysh -c 'show bgp neighbors' | grep -qE 
'Connections established 1'])
+
+check multinode_nbctl ls-add ls0                \
+    -- lsp-add-localnet-port ls0 ls0-ln public0 \
+    -- ls-add ls1                               \
+    -- lsp-add-localnet-port ls1 ls1-ln public1
+
+
+# Configure "workloads" (VIF LSPs) on both chassis.
+check multinode_nbctl lsp-add ls0 w01                              \
+    -- lsp-set-addresses w01 "00:00:00:00:00:01 10.0.0.11 10::11"
+check multinode_nbctl lsp-add ls0 w02                              \
+    -- lsp-set-addresses w02 "00:00:00:00:00:02 10.0.0.12 10::12"
+
+check m_as ovn-gw-1 /data/create_fake_vm.sh w01 w01 00:00:00:00:00:01 1500 
10.0.0.11 24 10.0.0.1 10::11/64 10::1
+check m_as ovn-gw-2 /data/create_fake_vm.sh w02 w02 00:00:00:00:00:02 1500 
10.0.0.12 24 10.0.0.1 10::12/64 10::1
+
+check multinode_nbctl lsp-add ls1 w11                              \
+    -- lsp-set-addresses w11 "00:00:00:00:00:11 11.0.0.11 11::11"
+check multinode_nbctl lsp-add ls1 w12                              \
+    -- lsp-set-addresses w12 "00:00:00:00:00:12 11.0.0.12 11::12"
+
+check m_as ovn-gw-1 /data/create_fake_vm.sh w11 w11 00:00:00:00:00:11 1500 
11.0.0.11 24 11.0.0.1 11::11/64 11::1
+check m_as ovn-gw-2 /data/create_fake_vm.sh w12 w12 00:00:00:00:00:12 1500 
11.0.0.12 24 11.0.0.1 11::12/64 11::1
+m_wait_for_ports_up
+
+# Enable EVPN support for the distributed logical switch and redistribute
+# local FDBs.
+check multinode_nbctl set logical_switch ls0                \
+    other_config:dynamic-routing-vni=$vni0                  \
+    other_config:dynamic-routing-bridge-ifname=vlan-$vid0   \
+    other_config:dynamic-routing-vxlan-ifname=vxlan-evpn    \
+    other_config:dynamic-routing-advertise-ifname=lo-$vni0  \
+    other_config:dynamic-routing-redistribute=fdb,ip
+check multinode_nbctl set logical_switch ls1                \
+    other_config:dynamic-routing-vni=$vni1                  \
+    other_config:dynamic-routing-bridge-ifname=vlan-$vid1   \
+    other_config:dynamic-routing-vxlan-ifname=vxlan-evpn    \
+    other_config:dynamic-routing-advertise-ifname=lo-$vni1  \
+    other_config:dynamic-routing-redistribute=fdb,ip
+check multinode_nbctl --wait=hv sync
+dp0_key=$(m_fetch_column Datapath_Binding tunnel_key external_ids:name=ls0)
+dp1_key=$(m_fetch_column Datapath_Binding tunnel_key external_ids:name=ls1)
+
+OVS_WAIT_UNTIL([m_as ovn-gw-1 bridge fdb | grep vxlan-evpn | grep -q 
"00:00:00:00:00:00"])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 bridge fdb | grep vxlan-evpn | grep -q 
"00:00:00:00:00:00"])
+
+AS_BOX([Checking Remote VTEPs learned in OVN])
+OVS_WAIT_FOR_OUTPUT_UNQUOTED([m_as ovn-gw-1 ovn-appctl evpn/remote-vtep-list | 
sort], [0], [dnl
+IP: $ext0_bgp_ip_gw1, port: 4789, vni: 10
+IP: $ext0_bgp_ip_gw1, port: 4789, vni: 20
+])
+OVS_WAIT_FOR_OUTPUT_UNQUOTED([m_as ovn-gw-2 ovn-appctl evpn/remote-vtep-list | 
sort], [0], [dnl
+IP: $ext0_bgp_ip_gw2, port: 4789, vni: 10
+IP: $ext0_bgp_ip_gw2, port: 4789, vni: 20
+])
+
+AS_BOX([Check traffic to "fabric" hosts - simulate external workloads])
+check m_as ovn-gw-1 ip netns add fabric_workload
+on_exit "m_as ovn-gw-1 ip netns del fabric_workload"
+check m_as ovn-gw-1 ip link add evpn_host0 type veth peer evpn_host_peer0
+check m_as ovn-gw-1 ip link add evpn_host1 type veth peer evpn_host_peer1
+on_exit "m_as ovn-gw-1 ip link del evpn_host0"
+on_exit "m_as ovn-gw-1 ip link del evpn_host1"
+check m_as ovn-gw-1 ip link set netns frr-ns evpn_host_peer0
+check m_as ovn-gw-1 ip link set netns frr-ns evpn_host_peer1
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set evpn_host_peer0 master 
br-10
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set evpn_host_peer1 master 
br-20
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set evpn_host_peer0 up
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set evpn_host_peer1 up
+check m_as ovn-gw-1 ip netns exec frr-ns bridge vlan add dev evpn_host_peer0 
vid $vid0
+check m_as ovn-gw-1 ip netns exec frr-ns bridge vlan add dev evpn_host_peer1 
vid $vid1
+check m_as ovn-gw-1 ip link set netns fabric_workload evpn_host0
+check m_as ovn-gw-1 ip link set netns fabric_workload evpn_host1
+check m_as ovn-gw-1 ip netns exec fabric_workload ip link set evpn_host0 addr 
00:00:00:00:01:00
+check m_as ovn-gw-1 ip netns exec fabric_workload ip link set evpn_host1 addr 
00:00:00:00:11:00
+check m_as ovn-gw-1 ip netns exec fabric_workload ip link set evpn_host0 up
+check m_as ovn-gw-1 ip netns exec fabric_workload ip link set evpn_host1 up
+check m_as ovn-gw-1 ip netns exec fabric_workload ip addr add dev evpn_host0 
10.0.0.41/24
+check m_as ovn-gw-1 ip netns exec fabric_workload ip addr add dev evpn_host1 
11.0.0.41/24
+check m_as ovn-gw-1 ip netns exec fabric_workload ip -6 addr add dev 
evpn_host0 10::41/64 nodad
+check m_as ovn-gw-1 ip netns exec fabric_workload ip -6 addr add dev 
evpn_host1 11::41/64 nodad
+check m_as ovn-gw-1 ip netns exec fabric_workload ip route add default via 
10.0.0.1
+check m_as ovn-gw-1 ip netns exec fabric_workload ip route add 21.0.0.0/24 via 
11.0.0.1
+check m_as ovn-gw-1 ip netns exec fabric_workload ip -6 route add default via 
10::1
+check m_as ovn-gw-1 ip netns exec fabric_workload ip -6 route add 2001::/64 
via 11::1
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set address 00:00:10:00:00:81 
dev br-10
+check m_as ovn-gw-1 ip netns exec frr-ns ip link set address 00:00:11:00:00:81 
dev br-20
+check m_as ovn-gw-1 ip netns exec frr-ns ip addr add dev br-10 10.0.0.81/24
+check m_as ovn-gw-1 ip netns exec frr-ns ip addr add dev br-20 11.0.0.81/24
+check m_as ovn-gw-1 ip netns exec frr-ns ip -6 addr add dev br-10 10::81/64 
nodad
+check m_as ovn-gw-1 ip netns exec frr-ns ip -6 addr add dev br-20 11::81/64 
nodad
+
+check m_as ovn-gw-2 ip netns add fabric_workload
+on_exit "m_as ovn-gw-2 ip netns del fabric_workload"
+check m_as ovn-gw-2 ip link add evpn_host0 type veth peer evpn_host_peer0
+check m_as ovn-gw-2 ip link add evpn_host1 type veth peer evpn_host_peer1
+on_exit "m_as ovn-gw-2 ip link del evpn_host0"
+check m_as ovn-gw-2 ip link set netns frr-ns evpn_host_peer0
+check m_as ovn-gw-2 ip link set netns frr-ns evpn_host_peer1
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set evpn_host_peer0 master 
br-10
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set evpn_host_peer1 master 
br-20
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set evpn_host_peer0 up
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set evpn_host_peer1 up
+check m_as ovn-gw-2 ip netns exec frr-ns bridge vlan add dev evpn_host_peer0 
vid $vid0
+check m_as ovn-gw-2 ip netns exec frr-ns bridge vlan add dev evpn_host_peer1 
vid $vid1
+check m_as ovn-gw-2 ip link set netns fabric_workload evpn_host0
+check m_as ovn-gw-2 ip link set netns fabric_workload evpn_host1
+check m_as ovn-gw-2 ip netns exec fabric_workload ip link set evpn_host0 addr 
00:00:00:00:02:00
+check m_as ovn-gw-2 ip netns exec fabric_workload ip link set evpn_host1 addr 
00:00:00:00:12:00
+check m_as ovn-gw-2 ip netns exec fabric_workload ip link set evpn_host0 up
+check m_as ovn-gw-2 ip netns exec fabric_workload ip link set evpn_host1 up
+check m_as ovn-gw-2 ip netns exec fabric_workload ip addr add dev evpn_host0 
10.0.0.42/24
+check m_as ovn-gw-2 ip netns exec fabric_workload ip addr add dev evpn_host1 
11.0.0.42/24
+check m_as ovn-gw-2 ip netns exec fabric_workload ip -6 addr add dev 
evpn_host0 10::42/64 nodad
+check m_as ovn-gw-2 ip netns exec fabric_workload ip -6 addr add dev 
evpn_host1 11::42/64 nodad
+check m_as ovn-gw-2 ip netns exec fabric_workload ip route add default via 
10.0.0.1
+check m_as ovn-gw-2 ip netns exec fabric_workload ip route add 21.0.0.0/24 via 
11.0.0.1
+check m_as ovn-gw-2 ip netns exec fabric_workload ip -6 r a default via 10::1
+check m_as ovn-gw-2 ip netns exec fabric_workload ip -6 route add 2001::/64 
via 11::1
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set address 00:00:10:00:00:82 
dev br-10
+check m_as ovn-gw-2 ip netns exec frr-ns ip link set address 00:00:11:00:00:82 
dev br-20
+check m_as ovn-gw-2 ip netns exec frr-ns ip addr add dev br-10 10.0.0.82/24
+check m_as ovn-gw-2 ip netns exec frr-ns ip addr add dev br-20 11.0.0.82/24
+check m_as ovn-gw-2 ip netns exec frr-ns ip -6 addr add dev br-10 10::82/64 
nodad
+check m_as ovn-gw-2 ip netns exec frr-ns ip -6 addr add dev br-20 11::82/64 
nodad
+
+AS_BOX([Checking EVPN MACs and IPs on External BGP host])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show evpn mac vni all'], [0], [dnl
+
+VNI 10 #MACs (local and remote) 2
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:00:01 remote       42.42.10.12                          0/0
+00:00:00:00:01:00 local        evpn_host_peer0                      0/0
+
+VNI 20 #MACs (local and remote) 2
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:11:00 local        evpn_host_peer1                      0/0
+00:00:00:00:00:11 remote       42.42.10.12                          0/0
+])
+
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show evpn mac vni all'], [0], [dnl
+
+VNI 10 #MACs (local and remote) 2
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:00:02 remote       42.42.10.22                          0/0
+00:00:00:00:02:00 local        evpn_host_peer0                      0/0
+
+VNI 20 #MACs (local and remote) 2
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:12:00 local        evpn_host_peer1                      0/0
+00:00:00:00:00:12 remote       42.42.10.22                          0/0
+])
+
+# Check that the fabric learned both FDB and IP routes for the workloads.
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep --no-group-separator -A1 00:00:00:00:00:01], [0], [dnl
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:01]]
+                    42.42.10.12                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:01]]:[[32]]:[[10.0.0.11]]
+                    42.42.10.12                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:01]]:[[128]]:[[10::11]]
+                    42.42.10.12                            0 4210000000 i
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep --no-group-separator -A1 00:00:00:00:00:11], [0], [dnl
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:11]]
+                    42.42.10.12                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:11]]:[[32]]:[[11.0.0.11]]
+                    42.42.10.12                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:11]]:[[128]]:[[11::11]]
+                    42.42.10.12                            0 4210000000 i
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep --no-group-separator -A1 00:00:00:00:00:02], [0], [dnl
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:02]]
+                    42.42.10.22                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:02]]:[[32]]:[[10.0.0.12]]
+                    42.42.10.22                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:02]]:[[128]]:[[10::12]]
+                    42.42.10.22                            0 4210000000 i
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep --no-group-separator -A1 00:00:00:00:00:12], [0], [dnl
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:12]]
+                    42.42.10.22                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:12]]:[[32]]:[[11.0.0.12]]
+                    42.42.10.22                            0 4210000000 i
+ *>  [[2]]:[[0]]:[[48]]:[[00:00:00:00:00:12]]:[[128]]:[[11::12]]
+                    42.42.10.22                            0 4210000000 i
+])
+
+AS_BOX([Check traffic to "fabric" hosts - ping from fabric])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping    -W 1 -c 1 
10.0.0.11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping    -W 1 -c 1 
11.0.0.11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping -6 -W 1 -c 1 
10::11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping -6 -W 1 -c 1 
11::11])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping    -W 1 -c 1 
10.0.0.12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping    -W 1 -c 1 
11.0.0.12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping -6 -W 1 -c 1 
10::12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping -6 -W 1 -c 1 
11::12])
+
+AS_BOX([Check type-2 MAC+IP EVPN route advertisements])
+# Ping from the frr-ns to the fabric workload so that its IP is learned on
+# the fabric EVPN peer (and advertised to OVN).
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-10 ping    
-W 1 -c 1 10.0.0.41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-20 ping    
-W 1 -c 1 11.0.0.41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-10 ping -6 
-W 1 -c 1 10::41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-20 ping -6 
-W 1 -c 1 11::41])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-10 ping    
-W 1 -c 1 10.0.0.42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-20 ping    
-W 1 -c 1 11.0.0.42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-10 ping -6 
-W 1 -c 1 10::42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-20 ping -6 
-W 1 -c 1 11::42])
+
+# Check that OVN learned the ARPs.
+OVS_WAIT_FOR_OUTPUT_UNQUOTED([m_as ovn-gw-1 ovn-appctl evpn/vtep-arp-list | 
cut -d',' -f2- | sort], [0], [dnl
+ VNI: 10, MAC: 00:00:00:00:01:00, IP: 10.0.0.41, dp_key: $dp0_key
+ VNI: 10, MAC: 00:00:00:00:01:00, IP: 10::41, dp_key: $dp0_key
+ VNI: 20, MAC: 00:00:00:00:11:00, IP: 11.0.0.41, dp_key: $dp1_key
+ VNI: 20, MAC: 00:00:00:00:11:00, IP: 11::41, dp_key: $dp1_key
+])
+OVS_WAIT_FOR_OUTPUT_UNQUOTED([m_as ovn-gw-2 ovn-appctl evpn/vtep-arp-list | 
cut -d',' -f2- | sort], [0], [dnl
+ VNI: 10, MAC: 00:00:00:00:02:00, IP: 10.0.0.42, dp_key: $dp0_key
+ VNI: 10, MAC: 00:00:00:00:02:00, IP: 10::42, dp_key: $dp0_key
+ VNI: 20, MAC: 00:00:00:00:12:00, IP: 11.0.0.42, dp_key: $dp1_key
+ VNI: 20, MAC: 00:00:00:00:12:00, IP: 11::42, dp_key: $dp1_key
+])
+
+AS_BOX([Check that OVN routers used ARP entries learned through type-2 EVPN 
MAC+IP routes])
+# Add an OVN router with an internal switch and internal workload.
+check multinode_nbctl --wait=hv                                         \
+    -- lr-add lr0                                                       \
+    -- lrp-add lr0 lr0-ls 00:00:00:01:00:00 10.0.0.1/24 10::1/64        \
+    -- lrp-add lr0 lr0-ls-int 00:00:00:02:00:00 20.0.0.1/24 2000::1/64  \
+    -- lsp-add-router-port ls0 ls0-lr lr0-ls                            \
+    -- ls-add ls0-int                                                   \
+    -- lsp-add-router-port ls0-int ls0-int-lr lr0-ls-int                \
+    -- lsp-add ls0-int w0-int1                                          \
+    -- lsp-set-addresses w0-int1 "00:00:00:02:00:01 20.0.0.11 2000::11" \
+    -- lsp-add ls0-int w0-int2                                          \
+    -- lsp-set-addresses w0-int2 "00:00:00:02:00:02 20.0.0.12 2000::12" \
+    -- lr-add lr1                                                       \
+    -- lrp-add lr1 lr1-ls 00:00:00:11:00:00 11.0.0.1/24 11::1/64        \
+    -- lrp-add lr1 lr1-ls-int 00:00:00:12:00:00 21.0.0.1/24 2001::1/64  \
+    -- lsp-add-router-port ls1 ls1-lr lr1-ls                            \
+    -- ls-add ls1-int                                                   \
+    -- lsp-add-router-port ls1-int ls1-int-lr lr1-ls-int                \
+    -- lsp-add ls1-int w1-int1                                          \
+    -- lsp-set-addresses w1-int1 "00:00:00:12:00:01 21.0.0.11 2001::11" \
+    -- lsp-add ls1-int w1-int2                                          \
+    -- lsp-set-addresses w1-int2 "00:00:00:12:00:02 21.0.0.12 2001::12"
+
+rtr_dp_key0=$(m_fetch_column Datapath tunnel_key external_ids:name=lr0)
+rtr_dp_key1=$(m_fetch_column Datapath tunnel_key external_ids:name=lr1)
+rtr_port_key0=$(m_fetch_column Port_Binding tunnel_key logical_port=lr0-ls)
+rtr_port_key1=$(m_fetch_column Port_Binding tunnel_key logical_port=lr1-ls)
+
+check m_as ovn-gw-1 /data/create_fake_vm.sh w0-int1 w0-int1 00:00:00:02:00:01 
1500 20.0.0.11 24 20.0.0.1 2000::11/64 2000::1
+check m_as ovn-gw-1 /data/create_fake_vm.sh w1-int1 w1-int1 00:00:00:12:00:01 
1500 21.0.0.11 24 21.0.0.1 2001::11/64 2001::1
+check m_as ovn-gw-2 /data/create_fake_vm.sh w0-int2 w0-int2 00:00:00:02:00:02 
1500 20.0.0.12 24 20.0.0.1 2000::12/64 2000::1
+check m_as ovn-gw-2 /data/create_fake_vm.sh w1-int2 w1-int2 00:00:00:12:00:02 
1500 21.0.0.12 24 21.0.0.1 2001::12/64 2001::1
+m_wait_for_ports_up
+
+# Check that flows are created for the type-2 EVPN MAC+IP routes, in the
+# router pipeline.
+AT_CHECK_UNQUOTED([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_BINDING | grep priority | grep -vE "reg[[04]]=0xfe80" | \
+                   awk '{print $7, $8}' | sort], [0], [dnl
+priority=100,reg0=0xa00000b,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:00:01,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xa00000c,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:00:02,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xb00000b,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:00:11,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xb00000c,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:00:12,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg0=0xa000029,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:01:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg0=0xb000029,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:11:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg4=0x100000,reg5=0,reg6=0,reg7=0x41,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0
 actions=mod_dl_dst:00:00:00:00:01:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg4=0x110000,reg5=0,reg6=0,reg7=0x41,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1
 actions=mod_dl_dst:00:00:00:00:11:00,load:0x1->NXM_NX_REG10[[6]]
+])
+
+AT_CHECK_UNQUOTED([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_LOOKUP | grep priority | grep -vE "reg[[04]]=0xfe80" | \
+                   awk '{print $7, $8}' | sort], [0], [dnl
+priority=100,arp,reg0=0xa00000b,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:00:01
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xa00000c,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:00:02
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xb00000b,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:00:11
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xb00000c,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:00:12
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,arp,reg0=0xa000029,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:01:00
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,arp,reg0=0xb000029,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:11:00
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,icmp6,reg0=0x100000,reg1=0,reg2=0,reg3=0x41,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:01:00,icmp_code=0
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,icmp6,reg0=0x110000,reg1=0,reg2=0,reg3=0x41,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:11:00,icmp_code=0
 actions=load:0x1->NXM_NX_REG10[[6]]
+])
+
+AT_CHECK_UNQUOTED([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_BINDING | grep priority | grep -vE "reg[[04]]=0xfe80" | \
+                   awk '{print $7, $8}' | sort], [0], [dnl
+priority=100,reg0=0xa00000b,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:00:01,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xa00000c,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:00:02,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xb00000b,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:00:11,load:0x1->NXM_NX_REG10[[6]]
+priority=100,reg0=0xb00000c,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:00:12,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg0=0xa00002a,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0 
actions=mod_dl_dst:00:00:00:00:02:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg0=0xb00002a,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1 
actions=mod_dl_dst:00:00:00:00:12:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg4=0x100000,reg5=0,reg6=0,reg7=0x42,reg15=0x$rtr_port_key0,metadata=0x$rtr_dp_key0
 actions=mod_dl_dst:00:00:00:00:02:00,load:0x1->NXM_NX_REG10[[6]]
+priority=200,reg4=0x110000,reg5=0,reg6=0,reg7=0x42,reg15=0x$rtr_port_key1,metadata=0x$rtr_dp_key1
 actions=mod_dl_dst:00:00:00:00:12:00,load:0x1->NXM_NX_REG10[[6]]
+])
+
+AT_CHECK_UNQUOTED([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_LOOKUP | grep priority | grep -vE "reg[[04]]=0xfe80" | \
+                   awk '{print $7, $8}' | sort], [0], [dnl
+priority=100,arp,reg0=0xa00000b,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:00:01
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xa00000c,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:00:02
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xb00000b,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:00:11
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=100,arp,reg0=0xb00000c,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:00:12
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,arp,reg0=0xa00002a,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:02:00
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,arp,reg0=0xb00002a,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:12:00
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,icmp6,reg0=0x100000,reg1=0,reg2=0,reg3=0x42,reg14=0x$rtr_port_key0,metadata=0x$rtr_dp_key0,dl_src=00:00:00:00:02:00,icmp_code=0
 actions=load:0x1->NXM_NX_REG10[[6]]
+priority=200,icmp6,reg0=0x110000,reg1=0,reg2=0,reg3=0x42,reg14=0x$rtr_port_key1,metadata=0x$rtr_dp_key1,dl_src=00:00:00:00:12:00,icmp_code=0
 actions=load:0x1->NXM_NX_REG10[[6]]
+])
+
+AS_BOX([Check traffic to "fabric" hosts - ping from internal hosts])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w0-int1 ping    -W 1 -c 1 
10.0.0.41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1-int1 ping    -W 1 -c 1 
11.0.0.41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w0-int1 ping -6 -W 1 -c 1 10::41])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1-int1 ping -6 -W 1 -c 1 11::41])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w0-int2 ping    -W 1 -c 1 
10.0.0.42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w1-int2 ping    -W 1 -c 1 
11.0.0.42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w0-int2 ping -6 -W 1 -c 1 10::42])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w1-int2 ping -6 -W 1 -c 1 11::42])
+
+AS_BOX([Check traffic to "fabric" hosts - ping from VNI bridge])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-10 ping    
-W 1 -c 3 10.0.0.11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-20 ping    
-W 1 -c 3 11.0.0.11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-10 ping -6 
-W 1 -c 3 10::11])
+OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec frr-ns ip vrf exec vrf-20 ping -6 
-W 1 -c 3 11::11])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-10 ping    
-W 1 -c 3 10.0.0.12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-20 ping    
-W 1 -c 3 11.0.0.12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-10 ping -6 
-W 1 -c 3 10::12])
+OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ip vrf exec vrf-20 ping -6 
-W 1 -c 3 11::12])
+
+# Check if the dynamic FDB was created.
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:10:00:00:81 | grep -c "cookie"], [0], 
[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:11:00:00:81 | grep -c "cookie"], [0], 
[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:10:00:00:82 | grep -c "cookie"], [0], 
[dnl
+1
+])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:11:00:00:82 | grep -c "cookie"], [0], 
[dnl
+1
+])
+
+# Remove "workloads" (VIF LSPs) on both chassis.
+check multinode_nbctl --wait=hv lsp-del w01 -- lsp-del w02 -- lsp-del w11 -- 
lsp-del w12
+
+AS_BOX([Checking EVPN MACs on External BGP host])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show evpn mac vni all'], [0], [dnl
+
+VNI 10 #MACs (local and remote) 1
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:01:00 local        evpn_host_peer0                      0/0
+
+VNI 20 #MACs (local and remote) 1
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:11:00 local        evpn_host_peer1                      0/0
+])
+
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show evpn mac vni all'], [0], [dnl
+
+VNI 10 #MACs (local and remote) 1
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:02:00 local        evpn_host_peer0                      0/0
+
+VNI 20 #MACs (local and remote) 1
+
+Flags: N=sync-neighs, I=local-inactive, P=peer-active, X=peer-proxy
+MAC               Type   Flags Intf/Remote ES/VTEP            VLAN  Seq #'s
+00:00:00:00:12:00 local        evpn_host_peer1                      0/0
+])
+
+# Check that the fabric un-learned both FDB and IP routes for the workloads.
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep -q 00:00:00:00:00:01], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep -q 00:00:00:00:00:11], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep -q 00:00:00:00:00:02], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ip netns exec frr-ns vtysh --vty_socket 
/run/frr/frr-ns -c 'show bgp l2vpn evpn route' | \
+    grep -q 00:00:00:00:00:12], [1])
+
+# Check if the dynamic FDB was removed.
+check multinode_nbctl remove logical_switch ls0 other_config 
dynamic-routing-vni
+check multinode_nbctl --wait=hv remove logical_switch ls1 other_config 
dynamic-routing-vni
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:10:00:00:81 | grep -q "cookie"], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-1 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:11:00:00:81 | grep -q "cookie"], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:10:00:00:82 | grep -q "cookie"], [1])
+OVS_WAIT_FOR_OUTPUT([m_as ovn-gw-2 ovs-ofctl dump-flows br-int 
table=OFTABLE_GET_REMOTE_FDB,dl_dst=00:00:11:00:00:82 | grep -q "cookie"], [1])
+
+AT_CLEANUP
+
 AT_SETUP([ovn multinode bgp L3 EVPN])
 check_fake_multinode_setup
 
@@ -3785,12 +4253,12 @@ lb_ip6_gw2=42:20:$vni::24
 
 m_setup_external_frr_router     ovn-gw-1                             
$ext_bgp_ip_gw1/24
 m_config_external_frr_router_l3 ovn-gw-1 4200000100 $ext_bgp_ip_gw1  
$ext_bgp_ip_gw1/24  $ext_bgp_ip6_gw1/64 $ext_bgp_mac_gw1 $vni
-m_setup_host_frr_router         ovn-gw-1 4210000000 $host_bgp_ip_gw1 
$host_bgp_ip_gw1/24                     $host_bgp_mac_gw1 $vni
+m_setup_host_frr_router         ovn-gw-1                             
$host_bgp_ip_gw1/24
 m_config_host_frr_router_l3     ovn-gw-1 4210000000 $host_bgp_ip_gw1 
$host_bgp_ip_gw1/24                     $host_bgp_mac_gw1 $vni
 
 m_setup_external_frr_router     ovn-gw-2                             
$ext_bgp_ip_gw2/24
 m_config_external_frr_router_l3 ovn-gw-2 4200000200 $ext_bgp_ip_gw2  
$ext_bgp_ip_gw2/24  $ext_bgp_ip6_gw2/64 $ext_bgp_mac_gw2 $vni
-m_setup_host_frr_router         ovn-gw-2 4210000000 $host_bgp_ip_gw2 
$host_bgp_ip_gw2/24                     $host_bgp_mac_gw2 $vni
+m_setup_host_frr_router         ovn-gw-2                             
$host_bgp_ip_gw2/24
 m_config_host_frr_router_l3     ovn-gw-2 4210000000 $host_bgp_ip_gw2 
$host_bgp_ip_gw2/24                     $host_bgp_mac_gw2 $vni
 
 OVS_WAIT_UNTIL([m_as ovn-gw-1 vtysh -c 'show bgp neighbors' | grep -qE 
'Connections established 1'])
-- 
2.52.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to