]> git.proxmox.com Git - mirror_frr.git/commitdiff
topotests: add tests to bgp-vrf-route-leak-basic
authorLouis Scalbert <louis.scalbert@6wind.com>
Thu, 12 May 2022 14:12:34 +0000 (16:12 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Fri, 16 Dec 2022 14:07:56 +0000 (15:07 +0100)
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf
tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py

index 03dfbf9322c7f987fb7c6dd79a4f341961ba0522..0540a620965b3a24787d5f4c1f2766669ccabf9e 100644 (file)
@@ -1,5 +1,11 @@
 hostname r1
 
+
+#debug bgp vpn leak-to-vrf
+#debug bgp vpn leak-from-vrf
+#debug bgp nht
+
+
 router bgp 99 vrf DONNA
   no bgp ebgp-requires-policy
   address-family ipv4 unicast
index 191a0b53ec2820c1742178a598972d5e04075689..9c3a4bfdad8dcc037f88f0fa8c9f79f453860ede 100644 (file)
@@ -29,6 +29,7 @@ import os
 import sys
 from functools import partial
 import pytest
+import time
 
 CWD = os.path.dirname(os.path.realpath(__file__))
 sys.path.append(os.path.join(CWD, "../"))
@@ -77,7 +78,103 @@ def teardown_module(mod):
     tgen.stop_topology()
 
 
-def test_vrf_route_leak():
+def check_bgp_rib(router, vrf, in_fib):
+    if in_fib:
+        attr = [{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}]
+    else:
+        attr = [{"protocol": "bgp", "nexthops": []}]
+
+    if vrf == "DONNA":
+        expect = {
+            "10.0.0.0/24": [
+                {
+                    "protocol": "connected",
+                }
+            ],
+            "10.0.1.0/24": attr,
+            "10.0.2.0/24": [{"protocol": "connected"}],
+            "10.0.3.0/24": attr,
+        }
+    else:
+        expect = {
+            "10.0.0.0/24": attr,
+            "10.0.1.0/24": [
+                {
+                    "protocol": "connected",
+                }
+            ],
+            "10.0.2.0/24": attr,
+            "10.0.3.0/24": [
+                {
+                    "protocol": "connected",
+                }
+            ],
+        }
+
+    test_func = partial(
+        topotest.router_json_cmp, router, "show ip route vrf %s json" % vrf, expect
+    )
+    return topotest.run_and_expect(test_func, None, count=10, wait=0.5)
+
+
+def check_bgp_fib(router, vrf, in_rib):
+    # Check FIB
+    # DONNA
+    # 10.0.1.0/24 dev EVA proto bgp metric 20
+    # 10.0.3.0/24 dev EVA proto bgp metric 20
+    # EVA
+    # 10.0.0.0/24 dev DONNA proto bgp metric 20
+    # 10.0.2.0/24 dev DONNA proto bgp metric 20
+
+    if vrf == "DONNA":
+        table = 1001
+        nh_vrf = "EVA"
+    else:
+        table = 1002
+        nh_vrf = "DONNA"
+
+    negate = "" if in_rib else "! "
+
+    cmd = "%sip route show table %s | grep %s" % (negate, table, nh_vrf)
+    result = False
+    retry = 5
+    output = ""
+    while retry:
+        retry -= 1
+        try:
+            output = router.cmd_raises(cmd)
+            result = True
+            break
+        except:
+            time.sleep(0.1)
+
+    logger.info("VRF %s leaked FIB content %s: %s", vrf, cmd, output)
+
+    return result, output
+
+
+def check_bgp_ping(router, vrf):
+    if vrf == "DONNA":
+        cmd = "ip vrf exec DONNA ping -c1 10.0.1.1 -I 10.0.0.1"
+    else:
+        cmd = "ip vrf exec EVA ping -c1 10.0.0.1 -I 10.0.1.1"
+
+    result = False
+    retry = 5
+    output = ""
+    while retry:
+        retry -= 1
+        try:
+            output = router.cmd_raises(cmd)
+            result = True
+            break
+        except:
+            time.sleep(0.1)
+
+    return result, output
+
+
+def test_vrf_route_leak_test1():
     logger.info("Ensure that routes are leaked back and forth")
     tgen = get_topogen()
     # Don't run this test if we have any failure.
@@ -86,53 +183,79 @@ def test_vrf_route_leak():
 
     r1 = tgen.gears["r1"]
 
-    # Test DONNA VRF.
-    expect = {
-        "10.0.0.0/24": [
-            {
-                "protocol": "connected",
-            }
-        ],
-        "10.0.1.0/24": [
-            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
-        ],
-        "10.0.2.0/24": [{"protocol": "connected"}],
-        "10.0.3.0/24": [
-            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
-        ],
-    }
+    for vrf in ["EVA", "DONNA"]:
+        result, diff = check_bgp_rib(r1, vrf, True)
+        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff)
+        result, output = check_bgp_fib(r1, vrf, True)
+        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output)
+        result, output = check_bgp_ping(r1, vrf)
+        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output)
 
-    test_func = partial(
-        topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect
-    )
-    result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
-    assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
-
-    # Test EVA VRF.
-    expect = {
-        "10.0.0.0/24": [
-            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
-        ],
-        "10.0.1.0/24": [
-            {
-                "protocol": "connected",
-            }
-        ],
-        "10.0.2.0/24": [
-            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
-        ],
-        "10.0.3.0/24": [
-            {
-                "protocol": "connected",
-            }
-        ],
-    }
 
-    test_func = partial(
-        topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect
+def test_vrf_route_leak_test2():
+    logger.info(
+        "Ensure that leaked are still present after VRF iface IP address deletion"
     )
-    result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
-    assert result, "BGP VRF EVA check failed:\n{}".format(diff)
+    tgen = get_topogen()
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    r1 = tgen.gears["r1"]
+
+    logger.info("Adding and removing an IPv4 address to EVA and DONNA VRF ifaces")
+    r1.cmd("ip address add 1.1.1.1/32 dev EVA && ip address del 1.1.1.1/32 dev EVA")
+    r1.cmd("ip address add 2.2.2.2/32 dev DONNA && ip address del 2.2.2.2/32 dev DONNA")
+
+    for vrf in ["EVA", "DONNA"]:
+        result, diff = check_bgp_rib(r1, vrf, True)
+        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff)
+        result, output = check_bgp_fib(r1, vrf, True)
+        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output)
+        result, output = check_bgp_ping(r1, vrf)
+        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output)
+
+
+def test_vrf_route_leak_test3():
+    logger.info("Ensure that setting down the VRF ifaces invalidates leaked routes")
+    tgen = get_topogen()
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    r1 = tgen.gears["r1"]
+
+    logger.info("Setting down EVA and DONNA VRF ifaces")
+    r1.cmd("ip link set EVA down")
+    r1.cmd("ip link set DONNA down")
+
+    for vrf in ["EVA", "DONNA"]:
+        result, diff = check_bgp_rib(r1, vrf, False)
+        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff)
+        result, output = check_bgp_fib(r1, vrf, False)
+        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output)
+
+
+def test_vrf_route_leak_test4():
+    logger.info("Ensure that setting up the VRF ifaces validates leaked routes")
+    tgen = get_topogen()
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    r1 = tgen.gears["r1"]
+
+    logger.info("Setting up EVA and DONNA VRF ifaces")
+    r1.cmd("ip link set EVA up")
+    r1.cmd("ip link set DONNA up")
+
+    for vrf in ["EVA", "DONNA"]:
+        result, diff = check_bgp_rib(r1, vrf, True)
+        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff)
+        result, output = check_bgp_fib(r1, vrf, True)
+        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output)
+        result, output = check_bgp_ping(r1, vrf)
+        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output)
 
 
 def test_memory_leak():