]>
Commit | Line | Data |
---|---|---|
e3c4bd24 CH |
1 | # -*- coding: utf-8 eval: (blacken-mode 1) -*- |
2 | # SPDX-License-Identifier: ISC | |
3 | # | |
4 | # May 2 2023, Christian Hopps <chopps@labn.net> | |
5 | # | |
6 | # Copyright (c) 2023, LabN Consulting, L.L.C. | |
7 | # | |
8 | """ | |
9 | Test static route functionality using old or new configuration files. | |
10 | ||
11 | User compat: | |
12 | ||
13 | - mgmtd split config will first look to `/etc/frr/zebra.conf` | |
14 | then `/etc/frr/staticd.conf` and finally `/etc/frr/mgmtd.conf` | |
15 | ||
16 | - When new components are converted to mgmtd their split config should be | |
17 | added here too. | |
18 | ||
19 | Topotest compat: | |
20 | ||
21 | - `mgmtd.conf` is copied to `/etc/frr/` for use by mgmtd when implicit load, | |
22 | or explicit load no config specified. | |
23 | ||
24 | - `staticd.conf` is copied to `/etc/frr/` for use by mgmtd when staticd | |
25 | is explicit load implict config, and explicit config. | |
26 | ||
27 | """ | |
28 | ||
29 | import ipaddress | |
30 | import re | |
31 | import time | |
32 | ||
33 | import pytest | |
34 | from lib.common_config import create_static_routes, retry, step, verify_rib | |
35 | from lib.topogen import Topogen, TopoRouter | |
36 | from lib.topolog import logger | |
37 | ||
38 | # pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd] | |
39 | pytestmark = [pytest.mark.staticd] | |
40 | ||
41 | ||
42 | @pytest.fixture(scope="module") | |
43 | def tgen(request): | |
44 | "Setup/Teardown the environment and provide tgen argument to tests" | |
45 | ||
46 | topodef = { | |
47 | "s1": ("r1",), | |
48 | } | |
49 | ||
50 | tgen = Topogen(topodef, request.module.__name__) | |
51 | tgen.start_topology() | |
52 | ||
53 | # configure mgmtd using current mgmtd config file | |
54 | tgen.gears["r1"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf") | |
55 | tgen.gears["r1"].load_config(TopoRouter.RD_MGMTD) | |
56 | ||
57 | # Explicit disable staticd now.. | |
58 | tgen.gears["r1"].net.daemons["staticd"] = 0 | |
59 | ||
60 | tgen.start_router() | |
61 | yield tgen | |
62 | tgen.stop_topology() | |
63 | ||
64 | ||
65 | @retry(retry_timeout=3, initial_wait=0.1) | |
66 | def check_kernel(r1, prefix, expected=True): | |
67 | net = ipaddress.ip_network(prefix) | |
68 | if net.version == 6: | |
69 | kernel = r1.net.cmd_nostatus("ip -6 route show", warn=not expected) | |
70 | else: | |
71 | kernel = r1.net.cmd_nostatus("ip -4 route show", warn=not expected) | |
72 | ||
73 | logger.debug("checking kernel routing table:\n%s", kernel) | |
74 | route = f"{str(net)}(?: nhid [0-9]+)?.*proto (static|196)" | |
75 | m = re.search(route, kernel) | |
76 | if expected and not m: | |
77 | return f"Failed to find \n'{route}'\n in \n'{kernel}'" | |
78 | elif not expected and m: | |
79 | return f"Failed found \n'{route}'\n in \n'{kernel}'" | |
80 | return None | |
81 | ||
82 | ||
83 | def test_staticd_late_start(tgen): | |
84 | if tgen.routers_have_failure(): | |
85 | pytest.skip(tgen.errors) | |
86 | ||
87 | # for x in ["r1"]: | |
88 | # tgen.gears[x].net.cmd_nostatus( | |
89 | # "vtysh -c 'debug mgmt client frontend' " | |
90 | # "-c 'debug mgmt client backend' " | |
91 | # "-c 'debug mgmt backend frontend datastore transaction'" | |
92 | # ) | |
93 | ||
94 | r1 = tgen.routers()["r1"] | |
95 | ||
96 | step("Verifying startup route is not present w/o staticd running") | |
97 | result = check_kernel(r1, "12.0.0.0/24", expected=False) | |
98 | assert result is not None | |
99 | ||
100 | step("Configure another static route verify is not present w/o staticd running") | |
101 | r1.net.cmd_nostatus("vtysh -c 'config t' -c 'ip route 12.1.0.0/24 101.0.0.2'") | |
102 | result = check_kernel(r1, "12.0.0.0/24", expected=False) | |
103 | assert result is not None | |
104 | result = check_kernel(r1, "12.1.0.0/24", expected=False) | |
105 | assert result is not None | |
106 | ||
107 | step("Starting staticd") | |
108 | r1.startDaemons(["staticd"]) | |
109 | ||
110 | step("Verifying both routes are present") | |
111 | result = check_kernel(r1, "12.0.0.0/24") | |
112 | assert result is None | |
113 | result = check_kernel(r1, "12.1.0.0/24") | |
114 | assert result is None |