topotests: test BFD static route integration

Test that BFD static monitoring works:
When BFD session is up the routes are installed in the RIB and
distributed with routing protocol (in this case BGP). When the session
is down it is removed from RIB and propagated.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
Rafael Zalamena 2021-03-24 09:41:04 -03:00
parent a89958e508
commit 771fdeaf39
20 changed files with 347 additions and 2 deletions

View File

@ -0,0 +1,12 @@
{
"path-list": {
"ipv4-multicast": [],
"ipv4-unicast": [],
"ipv6-unicast": [
{
"prefix": "2001:db8:5::\/64",
"vrf": "default",
"installed": false
}
]
}}

View File

@ -0,0 +1,13 @@
{
"path-list": {
"ipv4-multicast": [],
"ipv4-unicast": [],
"ipv6-unicast": [
{
"prefix": "2001:db8:5::\/64",
"vrf": "default",
"installed": true
}
]
}
}

View File

@ -0,0 +1 @@
ipv6 route 2001:db8:5::/64 2001:db8:4::3 bfd multi-hop profile slow-tx

View File

@ -19,7 +19,8 @@
"remote-transmit-interval": 2000,
"status": "up",
"uptime": "*",
"transmit-interval": 2000
"transmit-interval": 2000,
"vrf": "default"
},
{
"detect-multiplier": 3,
@ -41,6 +42,49 @@
"remote-transmit-interval": 2000,
"status": "up",
"uptime": "*",
"transmit-interval": 2000
"transmit-interval": 2000,
"vrf": "default"
},
{
"detect-multiplier": 3,
"diagnostic": "ok",
"echo-receive-interval": 50,
"echo-transmit-interval": 0,
"id": "*",
"multihop": false,
"passive-mode": false,
"peer": "192.168.4.3",
"receive-interval": 2000,
"remote-detect-multiplier": 3,
"remote-diagnostic": "ok",
"remote-echo-receive-interval": 50,
"remote-id": "*",
"remote-receive-interval": 2000,
"remote-transmit-interval": 2000,
"status": "up",
"transmit-interval": 2000,
"uptime": "*",
"vrf": "default"
},
{
"detect-multiplier": 3,
"diagnostic": "ok",
"echo-receive-interval": 50,
"echo-transmit-interval": 0,
"id": "*",
"multihop": false,
"passive-mode": false,
"peer": "192.168.4.2",
"receive-interval": 2000,
"remote-detect-multiplier": 3,
"remote-diagnostic": "ok",
"remote-echo-receive-interval": 50,
"remote-id": "*",
"remote-receive-interval": 2000,
"remote-transmit-interval": 2000,
"status": "up",
"transmit-interval": 2000,
"uptime": "*",
"vrf": "default"
}
]

View File

@ -9,6 +9,7 @@ router bgp 400
neighbor 2001:db8:1::1 bfd profile slow-tx-mh
address-family ipv4 unicast
redistribute connected
redistribute static
exit-address-family
address-family ipv6 unicast
redistribute connected

View File

@ -0,0 +1,2 @@
ip route 10.254.254.5/32 192.168.4.2 bfd profile slow-tx
ip route 10.254.254.6/32 192.168.4.3 bfd profile slow-tx

View File

@ -8,3 +8,7 @@ interface r4-eth0
ip address 192.168.3.1/24
ipv6 address 2001:db8:3::1/64
!
interface r4-eth1
ip address 192.168.4.1/24
ipv6 address 2001:db8:4::1/64
!

View File

@ -0,0 +1,23 @@
[
{
"detect-multiplier": 3,
"diagnostic": "ok",
"echo-receive-interval": 50,
"echo-transmit-interval": 0,
"id": "*",
"multihop": false,
"passive-mode": false,
"peer": "192.168.4.1",
"receive-interval": 2000,
"remote-detect-multiplier": 3,
"remote-diagnostic": "ok",
"remote-echo-receive-interval": 50,
"remote-id": "*",
"remote-receive-interval": 2000,
"remote-transmit-interval": 2000,
"status": "up",
"transmit-interval": 2000,
"uptime": "*",
"vrf": "default"
}
]

View File

@ -0,0 +1,11 @@
debug bfd network
debug bfd peer
debug bfd zebra
!
bfd
profile slow-tx
receive-interval 2000
transmit-interval 2000
minimum-ttl 250
!
!

View File

@ -0,0 +1,2 @@
ip route 0.0.0.0/0 192.168.4.1
ip route 10.254.254.4/32 192.168.4.1 bfd profile slow-tx

View File

@ -0,0 +1,10 @@
ip forwarding
ipv6 forwarding
!
interface lo
ip address 10.254.254.5/32
!
interface r5-eth0
ip address 192.168.4.2/24
ipv6 address 2001:db8:4::2/64
!

View File

@ -0,0 +1,46 @@
[
{
"detect-multiplier": 3,
"diagnostic": "ok",
"echo-receive-interval": 50,
"echo-transmit-interval": 0,
"id": "*",
"multihop": false,
"passive-mode": false,
"peer": "192.168.4.1",
"receive-interval": 2000,
"remote-detect-multiplier": 3,
"remote-diagnostic": "ok",
"remote-echo-receive-interval": 50,
"remote-id": "*",
"remote-receive-interval": 2000,
"remote-transmit-interval": 2000,
"status": "up",
"transmit-interval": 2000,
"uptime": "*",
"vrf": "default"
},
{
"detect-multiplier": 3,
"diagnostic": "ok",
"echo-receive-interval": 50,
"echo-transmit-interval": 0,
"id": "*",
"local": "2001:db8:4::3",
"minimum-ttl": 2,
"multihop": true,
"passive-mode": false,
"peer": "2001:db8:3::2",
"receive-interval": 2000,
"remote-detect-multiplier": 3,
"remote-diagnostic": "ok",
"remote-echo-receive-interval": 50,
"remote-id": "*",
"remote-receive-interval": 2000,
"remote-transmit-interval": 2000,
"status": "up",
"transmit-interval": 2000,
"uptime": "*",
"vrf": "default"
}
]

View File

@ -0,0 +1,19 @@
{
"path-list": {
"ipv4-multicast": [],
"ipv4-unicast": [
{
"installed": true,
"prefix": "10.254.254.4/32",
"vrf": "default"
}
],
"ipv6-unicast": [
{
"prefix": "2001:db8:1::\/64",
"vrf": "default",
"installed": false
}
]
}
}

View File

@ -0,0 +1,19 @@
{
"path-list": {
"ipv4-multicast": [],
"ipv4-unicast": [
{
"installed": true,
"prefix": "10.254.254.4/32",
"vrf": "default"
}
],
"ipv6-unicast": [
{
"prefix": "2001:db8:1::\/64",
"vrf": "default",
"installed": true
}
]
}
}

View File

@ -0,0 +1,11 @@
debug bfd network
debug bfd peer
debug bfd zebra
!
bfd
profile slow-tx
receive-interval 2000
transmit-interval 2000
minimum-ttl 250
!
!

View File

@ -0,0 +1,5 @@
ip route 0.0.0.0/0 192.168.4.1
ip route 10.254.254.4/32 192.168.4.1 bfd profile slow-tx
!
ipv6 route 2001:db8:3::/64 2001:db8:4::1
ipv6 route 2001:db8:1::/64 2001:db8:3::2 bfd multi-hop source 2001:db8:4::3 profile slow-tx

View File

@ -0,0 +1,10 @@
ip forwarding
ipv6 forwarding
!
interface lo
ip address 10.254.254.6/32
!
interface r6-eth0
ip address 192.168.4.3/24
ipv6 address 2001:db8:4::3/64
!

View File

@ -40,6 +40,18 @@ graph template {
fillcolor="#f08080",
style=filled,
];
r5 [
shape=doubleoctagon
label="r5",
fillcolor="#f08080",
style=filled,
];
r6 [
shape=doubleoctagon
label="r6",
fillcolor="#f08080",
style=filled,
];
# Switches
sw1 [
@ -60,6 +72,12 @@ graph template {
fillcolor="#d0e0d0",
style=filled,
];
sw4 [
shape=oval,
label="sw4\n192.168.4.0/24\n2001:db8:4::/64",
fillcolor="#d0e0d0",
style=filled,
];
# Connections
r1 -- sw1 [label="eth0\n.1"];
@ -70,4 +88,8 @@ graph template {
r4 -- sw3 [label="eth0\n.1"];
r3 -- sw3 [label="eth2\n.2"];
r4 -- sw4 [label="eth1\n.1"];
r5 -- sw4 [label="eth0\n.2"];
r6 -- sw4 [label="eth0\n.3"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -51,6 +51,7 @@ def setup_module(mod):
"s1": ("r1", "r2"),
"s2": ("r2", "r3"),
"s3": ("r3", "r4"),
"s4": ("r4", "r5", "r6"),
}
tgen = Topogen(topodef, mod.__name__)
tgen.start_topology()
@ -69,6 +70,10 @@ def setup_module(mod):
if os.path.isfile(daemon_file):
router.load_config(TopoRouter.RD_BGP, daemon_file)
daemon_file = "{}/{}/staticd.conf".format(CWD, rname)
if os.path.isfile(daemon_file):
router.load_config(TopoRouter.RD_STATIC, daemon_file)
# Initialize all routers.
tgen.start_router()
@ -100,6 +105,10 @@ def test_wait_bgp_convergence():
expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp")
# Wait for R1 <-> R4 convergence.
expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp")
# Wait for R1 <-> R5 convergence.
expect_loopback_route("r1", "ip", "10.254.254.5/32", "bgp")
# Wait for R1 <-> R6 convergence.
expect_loopback_route("r1", "ip", "10.254.254.6/32", "bgp")
# Wait for R2 <-> R1 convergence.
expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
@ -107,6 +116,10 @@ def test_wait_bgp_convergence():
expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
# Wait for R2 <-> R4 convergence.
expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp")
# Wait for R2 <-> R5 convergence.
expect_loopback_route("r2", "ip", "10.254.254.5/32", "bgp")
# Wait for R2 <-> R6 convergence.
expect_loopback_route("r2", "ip", "10.254.254.6/32", "bgp")
# Wait for R3 <-> R1 convergence.
expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp")
@ -114,6 +127,10 @@ def test_wait_bgp_convergence():
expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
# Wait for R3 <-> R4 convergence.
expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp")
# Wait for R3 <-> R5 convergence.
expect_loopback_route("r3", "ip", "10.254.254.5/32", "bgp")
# Wait for R3 <-> R6 convergence.
expect_loopback_route("r3", "ip", "10.254.254.6/32", "bgp")
# Wait for R4 <-> R1 convergence.
expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp")
@ -121,6 +138,15 @@ def test_wait_bgp_convergence():
expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp")
# Wait for R4 <-> R3 convergence.
expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp")
# Wait for R4 <-> R5 convergence.
expect_loopback_route("r4", "ip", "10.254.254.5/32", "static")
# Wait for R4 <-> R6 convergence.
expect_loopback_route("r4", "ip", "10.254.254.6/32", "static")
# Wait for R5 <-> R6 convergence.
expect_loopback_route("r3", "ipv6", "2001:db8:5::/64", "static")
# Wait for R6 <-> R5 convergence.
expect_loopback_route("r6", "ipv6", "2001:db8:1::/64", "static")
def test_wait_bfd_convergence():
@ -149,6 +175,70 @@ def test_wait_bfd_convergence():
expect_bfd_configuration("r2")
expect_bfd_configuration("r3")
expect_bfd_configuration("r4")
expect_bfd_configuration("r5")
expect_bfd_configuration("r6")
def test_static_route_monitoring():
"Test static route monitoring output."
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("test BFD static route status")
def expect_static_bfd_output(router, filename):
"Load JSON file and compare with 'show bfd peer json'"
logger.info("waiting BFD configuration on router {}".format(router))
bfd_config = json.loads(
open("{}/{}/{}.json".format(CWD, router, filename)).read()
)
test_func = partial(
topotest.router_json_cmp,
tgen.gears[router],
"show bfd static route json",
bfd_config,
)
_, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
assertmsg = '"{}" BFD static route status failure'.format(router)
assert result is None, assertmsg
expect_static_bfd_output("r3", "bfd-static")
expect_static_bfd_output("r6", "bfd-static")
logger.info("Setting r4 link down ...")
tgen.gears["r4"].link_enable("r4-eth0", False)
expect_static_bfd_output("r3", "bfd-static-down")
expect_static_bfd_output("r6", "bfd-static-down")
def test_expect_static_rib_removal():
"Test that route got removed from RIB (staticd and bgpd)."
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
def expect_route_missing(router, iptype, route):
"Wait until route is present on RIB for protocol."
logger.info("waiting route {} to disapear in {}".format(route, router))
test_func = partial(
topotest.router_json_cmp,
tgen.gears[router],
"show {} route json".format(iptype),
{route: None},
)
rv, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
assertmsg = '"{}" convergence failure'.format(router)
assert result is None, assertmsg
expect_route_missing("r1", "ip", "10.254.254.5/32")
expect_route_missing("r2", "ip", "10.254.254.5/32")
expect_route_missing("r3", "ip", "10.254.254.5/32")
expect_route_missing("r3", "ipv6", "2001:db8:5::/64")
expect_route_missing("r6", "ipv6", "2001:db8:1::/64")
def teardown_module(_mod):