topotests: add tests to bgp-vrf-route-leak-basic

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2022-05-12 16:12:34 +02:00
parent a1d9f6f2f2
commit 56748da55f
2 changed files with 173 additions and 44 deletions

View 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

View 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
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 DONNA 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)
# 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",
}
],
}
r1 = tgen.gears["r1"]
test_func = partial(
topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect
)
result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
assert result, "BGP VRF EVA check failed:\n{}".format(diff)
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():