summaryrefslogtreecommitdiffstats
path: root/tests/topotests/static_vrf/test_static_vrf.py
blob: 97c0800133e8ae4deb0830f144e94636baf0a82f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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")