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, "../"))
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.
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():