Skip to content

Commit

Permalink
tests: add topotest for static routes in VRF
Browse files Browse the repository at this point in the history
Test how staticd handles VRF creation/deletion.

Signed-off-by: Igor Ryzhov <[email protected]>
  • Loading branch information
idryzhov committed Feb 3, 2024
1 parent 3714f69 commit 3a5cc0a
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
20 changes: 20 additions & 0 deletions tests/topotests/static_vrf/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
debug static route

interface r1-eth0 vrf red
ip address 1.1.1.1/24
exit

interface r1-eth1 vrf blue
ip address 2.2.2.1/24
exit

ip route 30.30.30.30/32 1.1.1.2 nexthop-vrf red
ip route 30.30.30.30/32 2.2.2.2 nexthop-vrf blue
ip route 31.31.31.31/32 r1-eth0 nexthop-vrf red
ip route 31.31.31.31/32 r1-eth1 nexthop-vrf blue

ip route 10.10.10.10/32 2.2.2.2 vrf red nexthop-vrf blue
ip route 11.11.11.11/32 r1-eth1 vrf red nexthop-vrf blue

ip route 20.20.20.20/32 1.1.1.2 vrf blue nexthop-vrf red
ip route 21.21.21.21/32 r1-eth0 vrf blue nexthop-vrf red
126 changes: 126 additions & 0 deletions tests/topotests/static_vrf/test_static_vrf.py
Original file line number Diff line number Diff line change
@@ -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, "30.30.30.30", ["1.1.1.2", "2.2.2.2"], None)
check_kernel(r1, "31.31.31.31", ["r1-eth0", "r1-eth1"], None)
check_kernel(r1, "10.10.10.10", ["2.2.2.2"], "red")
check_kernel(r1, "11.11.11.11", ["r1-eth1"], "red")
check_kernel(r1, "20.20.20.20", ["1.1.1.2"], "blue")
check_kernel(r1, "21.21.21.21", ["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, "30.30.30.30", ["1.1.1.2"], None, expected_nh=False)
check_kernel(r1, "30.30.30.30", ["2.2.2.2"], None)
check_kernel(r1, "31.31.31.31", ["r1-eth0"], None, expected_nh=False)
check_kernel(r1, "31.31.31.31", ["r1-eth1"], None)
check_kernel(r1, "20.20.20.20", ["1.1.1.2"], "blue", expected_p=False)
check_kernel(r1, "21.21.21.21", ["r1-eth0"], "blue", expected_p=False)

# Delete VRF blue
r1.net.del_iface("blue")

# Check that "blue" nexthops are removed
check_kernel(r1, "30.30.30.30", ["2.2.2.2"], None, expected_p=False)
check_kernel(r1, "31.31.31.31", ["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, "30.30.30.30", ["1.1.1.2"], None)
check_kernel(r1, "31.31.31.31", ["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, "30.30.30.30", ["1.1.1.2", "2.2.2.2"], None)
check_kernel(r1, "31.31.31.31", ["r1-eth0", "r1-eth1"], None)
check_kernel(r1, "10.10.10.10", ["2.2.2.2"], "red")
check_kernel(r1, "11.11.11.11", ["r1-eth1"], "red")
check_kernel(r1, "20.20.20.20", ["1.1.1.2"], "blue")
check_kernel(r1, "21.21.21.21", ["r1-eth0"], "blue")

0 comments on commit 3a5cc0a

Please sign in to comment.