@@ -2989,6 +2989,148 @@ OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec frr-ns ping -W 1 -c 1 172.16.10.2])
29892989
29902990AT_CLEANUP
29912991
2992+ AT_SETUP([ovn multinode dynamic-routing - BGP learned routes with router filter name and multiple DGPs])
2993+
2994+ # This is the multinode counterpart of the system test
2995+ # "dynamic-routing - BGP learned routes with router filter name and multiple
2996+ # DGPs": a single logical router with dynamic routing enabled has two
2997+ # distributed gateway ports scheduled on different chassis. Both LRPs are used
2998+ # for dynamic routing and each has its own dynamic-routing-port-name filter
2999+ # resolving to the interface local to the chassis hosting the port.
3000+ #
3001+ # Each chassis learns a route for the same prefix from its own VRF, so both
3002+ # gateway ports learn it. Because every LRP has a dynamic-routing-port-name
3003+ # that resolves to a local interface, neither route is flushed: the route
3004+ # learned on ovn-gw-1 (lrp-local-bgp-port) and the route learned on ovn-gw-2
3005+ # (lrp-dgp-dummy) both remain.
3006+ #
3007+ # Topology:
3008+ #
3009+ # public ls-dummy
3010+ # (local-bgp-port, ovn-gw-1) (ovn-gw-2)
3011+ # | |
3012+ # lrp-local-bgp-port lrp-dgp-dummy
3013+ # (DGP @ ovn-gw-1, (DGP @ ovn-gw-2,
3014+ # port-name local-bgp-port) port-name dummy-bgp-port)
3015+ # \ /
3016+ # +------------- lr-frr -----------+
3017+ # (dynamic-routing, vrf-id $vrf)
3018+
3019+ # Check that ovn-fake-multinode setup is up and running.
3020+ check_fake_multinode_setup
3021+
3022+ CHECK_VRF()
3023+
3024+ # Delete the multinode NB and OVS resources before starting the test.
3025+ cleanup_multinode_resources
3026+
3027+ CHECK_VRF()
3028+
3029+ vrf=1000
3030+
3031+ # Create the VRF manually on both gateway chassis (dynamic-routing-maintain-vrf
3032+ # is false, so OVN does not create it) and learn/read routes from table $vrf.
3033+ for gw in ovn-gw-1 ovn-gw-2; do
3034+ check m_as $gw ip link add vrf-bgp type vrf table $vrf
3035+ on_exit "m_as $gw ip link del vrf-bgp"
3036+ check m_as $gw ip link set vrf-bgp up
3037+ done
3038+
3039+ # Create the logical router with dynamic routing in VRF $vrf.
3040+ check multinode_nbctl lr-add lr-frr
3041+ check multinode_nbctl set Logical_Router lr-frr \
3042+ options:dynamic-routing=true \
3043+ options:dynamic-routing-vrf-id=$vrf \
3044+ options:dynamic-routing-redistribute=static
3045+
3046+ # The DGP that is used for dynamic routing, scheduled on ovn-gw-1.
3047+ check multinode_nbctl lrp-add lr-frr lrp-local-bgp-port 00:00:00:00:00:03 20.0.0.3/24 \
3048+ -- set Logical_Router_Port lrp-local-bgp-port \
3049+ options:dynamic-routing-maintain-vrf=false \
3050+ -- set Logical_Router_Port lrp-local-bgp-port \
3051+ options:routing-protocol-redirect=local-bgp-port
3052+ check multinode_nbctl lrp-set-gateway-chassis lrp-local-bgp-port ovn-gw-1
3053+
3054+ check multinode_nbctl ls-add public
3055+ check multinode_nbctl lsp-add-router-port public public-lr-frr lrp-local-bgp-port
3056+ check multinode_nbctl lsp-add public local-bgp-port \
3057+ -- lsp-set-addresses local-bgp-port unknown
3058+
3059+ # The second DGP used for dynamic routing, scheduled on ovn-gw-2. bgp-dummy is
3060+ # not an OVN logical port, so the dynamic-routing-port-name filter is resolved
3061+ # through the dynamic-routing-port-mapping configured on ovn-gw-2 below.
3062+ check multinode_nbctl lrp-add lr-frr lrp-dgp-dummy 00:00:00:00:00:04 20.0.1.3/24 \
3063+ -- set Logical_Router_Port lrp-dgp-dummy \
3064+ options:dynamic-routing-maintain-vrf=false
3065+ check multinode_nbctl lrp-set-gateway-chassis lrp-dgp-dummy ovn-gw-2
3066+
3067+ check multinode_nbctl ls-add ls-dummy
3068+ check multinode_nbctl lsp-add-router-port ls-dummy lsp-dummy lrp-dgp-dummy
3069+
3070+ check multinode_nbctl --wait=hv sync
3071+
3072+ # Bind local-bgp-port on ovn-gw-1 and move its interface into the VRF. The
3073+ # dynamic-routing-port-name filter will be resolved to this interface name.
3074+ check m_as ovn-gw-1 ovs-vsctl add-port br-int local-bgp-port \
3075+ -- set Interface local-bgp-port type=internal \
3076+ -- set Interface local-bgp-port external_ids:iface-id=local-bgp-port
3077+ on_exit "m_as ovn-gw-1 ovs-vsctl del-port br-int local-bgp-port"
3078+ check m_as ovn-gw-1 ip link set local-bgp-port master vrf-bgp
3079+ check m_as ovn-gw-1 ip link set local-bgp-port address 00:00:00:00:00:03
3080+ check m_as ovn-gw-1 ip addr add dev local-bgp-port 20.0.0.3/24
3081+ check m_as ovn-gw-1 ip link set local-bgp-port up
3082+
3083+ # ovn-gw-2 hosts lrp-dgp-dummy. Add an interface to its VRF so a route can be
3084+ # present in the VRF table and get learned on this gateway port, and map the
3085+ # dynamic-routing-port-name (dummy-bgp-port) to this interface so the filter
3086+ # resolves locally on ovn-gw-2.
3087+ check m_as ovn-gw-2 ip link add bgp-dummy type dummy
3088+ on_exit "m_as ovn-gw-2 ip link del bgp-dummy"
3089+ check m_as ovn-gw-2 ip link set bgp-dummy master vrf-bgp
3090+ check m_as ovn-gw-2 ip addr add dev bgp-dummy 20.0.1.3/24
3091+ check m_as ovn-gw-2 ip link set bgp-dummy up
3092+
3093+ check m_as ovn-gw-2 ovs-vsctl set open . \
3094+ external-ids:dynamic-routing-port-mapping="dummy-bgp-port=bgp-dummy"
3095+ on_exit "m_as ovn-gw-2 ovs-vsctl remove open . external-ids dynamic-routing-port-mapping"
3096+
3097+ m_wait_for_ports_up
3098+ check multinode_nbctl --wait=hv sync
3099+
3100+ # Both gateway ports are flagged for dynamic routing.
3101+ m_check_row_count Port_Binding 1 logical_port=cr-lrp-local-bgp-port 'options:dynamic-routing=true'
3102+ m_check_row_count Port_Binding 1 logical_port=cr-lrp-dgp-dummy 'options:dynamic-routing=true'
3103+
3104+ # Simulate a route learned via a dynamic routing protocol in each chassis' VRF
3105+ # for the same prefix.
3106+ check m_as ovn-gw-1 ip route add 10.10.3.0/24 via 20.0.0.25 vrf vrf-bgp proto bgp
3107+ check m_as ovn-gw-2 ip route add 10.10.3.0/24 via 20.0.1.25 vrf vrf-bgp proto bgp
3108+
3109+ # Each chassis learns the route on its own gateway port, so there are two
3110+ # Learned_Route rows for the prefix.
3111+ m_wait_row_count Learned_Route 2 ip_prefix=10.10.3.0/24
3112+
3113+ # Configure a dynamic-routing-port-name filter on both LRPs, each resolving to
3114+ # the interface local to the chassis hosting the port: lrp-local-bgp-port ->
3115+ # local-bgp-port (ovn-gw-1) and lrp-dgp-dummy -> dummy-bgp-port (ovn-gw-2, via
3116+ # the port-mapping configured above).
3117+ check multinode_nbctl set Logical_Router_Port lrp-local-bgp-port \
3118+ options:dynamic-routing-port-name=local-bgp-port
3119+ check multinode_nbctl --wait=hv set Logical_Router_Port lrp-dgp-dummy \
3120+ options:dynamic-routing-port-name=dummy-bgp-port
3121+
3122+ local_lp=$(m_fetch_column port_binding _uuid logical_port=lrp-local-bgp-port)
3123+ dummy_lp=$(m_fetch_column port_binding _uuid logical_port=lrp-dgp-dummy)
3124+
3125+ # Both filters resolve to a local interface, so no route is flushed: the route
3126+ # learned on ovn-gw-1 (lrp-local-bgp-port) and the route learned on ovn-gw-2
3127+ # (lrp-dgp-dummy) both remain.
3128+ m_wait_row_count Learned_Route 2 ip_prefix=10.10.3.0/24
3129+ m_wait_row_count Learned_Route 1 ip_prefix=10.10.3.0/24 logical_port=$local_lp
3130+ m_wait_row_count Learned_Route 1 ip_prefix=10.10.3.0/24 logical_port=$dummy_lp
3131+
3132+ AT_CLEANUP
3133+
29923134AT_SETUP([HA: Check for missing garp on leader when BFD goes back up])
29933135# Network topology
29943136# ┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐
0 commit comments