mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 21:50:39 +00:00
topotests: add tests to bgp-vrf-route-leak-basic
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
parent
a1d9f6f2f2
commit
56748da55f
@ -1,5 +1,11 @@
|
|||||||
hostname r1
|
hostname r1
|
||||||
|
|
||||||
|
|
||||||
|
#debug bgp vpn leak-to-vrf
|
||||||
|
#debug bgp vpn leak-from-vrf
|
||||||
|
#debug bgp nht
|
||||||
|
|
||||||
|
|
||||||
router bgp 99 vrf DONNA
|
router bgp 99 vrf DONNA
|
||||||
no bgp ebgp-requires-policy
|
no bgp ebgp-requires-policy
|
||||||
address-family ipv4 unicast
|
address-family ipv4 unicast
|
||||||
|
@ -29,6 +29,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import pytest
|
import pytest
|
||||||
|
import time
|
||||||
|
|
||||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||||
sys.path.append(os.path.join(CWD, "../"))
|
sys.path.append(os.path.join(CWD, "../"))
|
||||||
@ -77,7 +78,103 @@ def teardown_module(mod):
|
|||||||
tgen.stop_topology()
|
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")
|
logger.info("Ensure that routes are leaked back and forth")
|
||||||
tgen = get_topogen()
|
tgen = get_topogen()
|
||||||
# Don't run this test if we have any failure.
|
# Don't run this test if we have any failure.
|
||||||
@ -86,53 +183,79 @@ def test_vrf_route_leak():
|
|||||||
|
|
||||||
r1 = tgen.gears["r1"]
|
r1 = tgen.gears["r1"]
|
||||||
|
|
||||||
# Test DONNA VRF.
|
for vrf in ["EVA", "DONNA"]:
|
||||||
expect = {
|
result, diff = check_bgp_rib(r1, vrf, True)
|
||||||
"10.0.0.0/24": [
|
assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff)
|
||||||
{
|
result, output = check_bgp_fib(r1, vrf, True)
|
||||||
"protocol": "connected",
|
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)
|
||||||
"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}]}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
tgen = get_topogen()
|
||||||
assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
|
# Don't run this test if we have any failure.
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
# Test EVA VRF.
|
r1 = tgen.gears["r1"]
|
||||||
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(
|
logger.info("Adding and removing an IPv4 address to EVA and DONNA VRF ifaces")
|
||||||
topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect
|
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")
|
||||||
result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
|
|
||||||
assert result, "BGP VRF EVA check failed:\n{}".format(diff)
|
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():
|
def test_memory_leak():
|
||||||
|
Loading…
Reference in New Issue
Block a user