mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-25 06:42:26 +00:00
tests: add topotest for static routes in VRF
Test how staticd handles VRF creation/deletion. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
parent
3c05d53bf8
commit
763ce7bb37
18
tests/topotests/static_vrf/r1/frr.conf
Normal file
18
tests/topotests/static_vrf/r1/frr.conf
Normal file
@ -0,0 +1,18 @@
|
||||
interface r1-eth0 vrf red
|
||||
ip address 192.0.2.1/23
|
||||
exit
|
||||
|
||||
interface r1-eth1 vrf blue
|
||||
ip address 192.0.2.129/24
|
||||
exit
|
||||
|
||||
ip route 198.51.100.1/32 192.0.2.2 nexthop-vrf red
|
||||
ip route 198.51.100.1/32 192.0.2.130 nexthop-vrf blue
|
||||
ip route 198.51.100.2/32 r1-eth0 nexthop-vrf red
|
||||
ip route 198.51.100.2/32 r1-eth1 nexthop-vrf blue
|
||||
|
||||
ip route 203.0.113.1/32 192.0.2.130 vrf red nexthop-vrf blue
|
||||
ip route 203.0.113.2/32 r1-eth1 vrf red nexthop-vrf blue
|
||||
|
||||
ip route 203.0.113.129/32 192.0.2.2 vrf blue nexthop-vrf red
|
||||
ip route 203.0.113.130/32 r1-eth0 vrf blue nexthop-vrf red
|
126
tests/topotests/static_vrf/test_static_vrf.py
Normal file
126
tests/topotests/static_vrf/test_static_vrf.py
Normal file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||
# SPDX-License-Identifier: ISC
|
||||
#
|
||||
# Copyright (c) 2024 NFWare Inc.
|
||||
#
|
||||
# noqa: E501
|
||||
#
|
||||
"""
|
||||
Test static route functionality
|
||||
"""
|
||||
|
||||
import ipaddress
|
||||
|
||||
import pytest
|
||||
from lib.topogen import Topogen
|
||||
from lib.common_config import retry
|
||||
|
||||
pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def tgen(request):
|
||||
"Setup/Teardown the environment and provide tgen argument to tests"
|
||||
|
||||
topodef = {"s1": ("r1",), "s2": ("r1",)}
|
||||
|
||||
tgen = Topogen(topodef, request.module.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
router_list = tgen.routers()
|
||||
for rname, router in router_list.items():
|
||||
# Setup VRF red
|
||||
router.net.add_l3vrf("red", 10)
|
||||
router.net.attach_iface_to_l3vrf(rname + "-eth0", "red")
|
||||
# Setup VRF blue
|
||||
router.net.add_l3vrf("blue", 20)
|
||||
router.net.attach_iface_to_l3vrf(rname + "-eth1", "blue")
|
||||
# Load configuration
|
||||
router.load_frr_config("frr.conf")
|
||||
|
||||
tgen.start_router()
|
||||
yield tgen
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
@retry(retry_timeout=1, initial_wait=0.1)
|
||||
def check_kernel(r1, prefix, nexthops, vrf, expected_p=True, expected_nh=True):
|
||||
vrfstr = f" vrf {vrf}" if vrf else ""
|
||||
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6:
|
||||
kernel = r1.run(f"ip -6 route show{vrfstr} {prefix}")
|
||||
else:
|
||||
kernel = r1.run(f"ip -4 route show{vrfstr} {prefix}")
|
||||
|
||||
if expected_p:
|
||||
assert prefix in kernel, f"Failed to find \n'{prefix}'\n in \n'{kernel:.1920}'"
|
||||
else:
|
||||
assert (
|
||||
prefix not in kernel
|
||||
), f"Failed found \n'{prefix}'\n in \n'{kernel:.1920}'"
|
||||
|
||||
if not expected_p:
|
||||
return
|
||||
|
||||
for nh in nexthops:
|
||||
if expected_nh:
|
||||
assert f"{nh}" in kernel, f"Failed to find \n'{nh}'\n in \n'{kernel:.1920}'"
|
||||
else:
|
||||
assert (
|
||||
f"{nh}" not in kernel
|
||||
), f"Failed found \n'{nh}'\n in \n'{kernel:.1920}'"
|
||||
|
||||
|
||||
def test_static_vrf(tgen):
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
r1 = tgen.gears["r1"]
|
||||
|
||||
# Check initial configuration
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.2", "192.0.2.130"], None)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth0", "r1-eth1"], None)
|
||||
check_kernel(r1, "203.0.113.1", ["192.0.2.130"], "red")
|
||||
check_kernel(r1, "203.0.113.2", ["r1-eth1"], "red")
|
||||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue")
|
||||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue")
|
||||
|
||||
# Delete VRF red
|
||||
r1.net.del_iface("red")
|
||||
|
||||
# Check that "red" nexthops are removed, "blue" nexthops are still there
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.2"], None, expected_nh=False)
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.130"], None)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth0"], None, expected_nh=False)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth1"], None)
|
||||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue", expected_p=False)
|
||||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue", expected_p=False)
|
||||
|
||||
# Delete VRF blue
|
||||
r1.net.del_iface("blue")
|
||||
|
||||
# Check that "blue" nexthops are removed
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.130"], None, expected_p=False)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth1"], None, expected_p=False)
|
||||
|
||||
# Add VRF red back, attach "eth0" to it
|
||||
r1.net.add_l3vrf("red", 10)
|
||||
r1.net.attach_iface_to_l3vrf("r1-eth0", "red")
|
||||
|
||||
# Check that "red" nexthops are restored
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.2"], None)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth0"], None)
|
||||
|
||||
# Add VRF blue back, attach "eth1" to it
|
||||
r1.net.add_l3vrf("blue", 20)
|
||||
r1.net.attach_iface_to_l3vrf("r1-eth1", "blue")
|
||||
|
||||
# Check that everything is restored
|
||||
check_kernel(r1, "198.51.100.1", ["192.0.2.2", "192.0.2.130"], None)
|
||||
check_kernel(r1, "198.51.100.2", ["r1-eth0", "r1-eth1"], None)
|
||||
check_kernel(r1, "203.0.113.1", ["192.0.2.130"], "red")
|
||||
check_kernel(r1, "203.0.113.2", ["r1-eth1"], "red")
|
||||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue")
|
||||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue")
|
Loading…
Reference in New Issue
Block a user