On 1/21/26 6:56 PM, Lorenzo Bianconi wrote:
> 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]>
> ---

Hi Lorenzo,

Thanks for the patch!

>  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"

This should be just after the interface creation.  Otherwise we risk not
cleaning it up if we fail to add it to the bridge or setting it "up".

> +}
> +
> +# 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

$vni is not used in this function, we can remove it.

> +    local br=br-evpn
> +    local vxlan=vxlan-evpn
> +    local vxlan_port=4789
> +
> +    # Add VNI bridge.

Probably better to say "Add EVPN 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"

This should be one line above.

> +    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).

VNI is not applicable here.

> +    # 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"

Here too, this needs to happen earlier.

> +    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"

This needs to be just after "ip link add ..".

>  }
>  
> -# 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

BGP_AS is not an argument anymore, we should remove this line.

>  # 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).

Typo: nterface

> +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

$svd is unused.

>  
> +    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))

Nit: I'd add an empty line here and some more in the block below too.

> +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

Nit: space at the beggining of the lines.

> +
> +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
> +
> +

Nit: one empty line too many.

> +# 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

Nit: s/switch/switches.

> +# 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"

This should be one line above, to make sure we always clean up.

> +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"

Missing on_exit for evpn_host1; and this one should be one line above.

> +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'])


All the comments I had above are minor so I went ahead and addressed
them and applied the patch to main.

Regards,
Dumitru


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

Reply via email to