]>
Commit | Line | Data |
---|---|---|
7cd87abc CH |
1 | # -*- coding: utf-8 eval: (blacken-mode 1) -*- |
2 | # SPDX-License-Identifier: ISC | |
3 | # | |
4 | # May 28 2023, Christian Hopps <chopps@labn.net> | |
5 | # | |
6 | # Copyright (c) 2023, LabN Consulting, L.L.C. | |
7 | # | |
8 | ||
9 | import ipaddress | |
10 | import math | |
11 | import re | |
12 | ||
13 | import pytest | |
14 | from lib.common_config import retry, step | |
15 | from lib.topolog import logger | |
16 | from munet.base import proc_error | |
17 | ||
18 | ||
19 | @retry(retry_timeout=30) | |
20 | def check_vtysh_up(router): | |
21 | rc, o, e = router.net.cmd_status("vtysh -c 'show version'") | |
22 | return None if not rc else proc_error(rc, o, e) | |
23 | ||
24 | ||
25 | @retry(retry_timeout=3, initial_wait=0.1) | |
26 | def check_kernel(r1, prefix, expected=True): | |
27 | net = ipaddress.ip_network(prefix) | |
28 | if net.version == 6: | |
29 | kernel = r1.net.cmd_nostatus("ip -6 route show", warn=not expected) | |
30 | else: | |
31 | kernel = r1.net.cmd_nostatus("ip -4 route show", warn=not expected) | |
32 | ||
33 | logger.debug("checking kernel routing table:\n%0.1920s", kernel) | |
34 | route = f"{str(net)}(?: nhid [0-9]+)?.*proto (static|196)" | |
35 | m = re.search(route, kernel) | |
36 | if expected and not m: | |
37 | return f"Failed to find \n'{route}'\n in \n'{kernel:.1920}'" | |
38 | elif not expected and m: | |
39 | return f"Failed found \n'{route}'\n in \n'{kernel:.1920}'" | |
40 | return None | |
41 | ||
42 | ||
43 | def get_ip_networks(super_prefix, count): | |
44 | count_log2 = math.log(count, 2) | |
45 | if count_log2 != int(count_log2): | |
46 | count_log2 = int(count_log2) + 1 | |
47 | else: | |
48 | count_log2 = int(count_log2) | |
49 | network = ipaddress.ip_network(super_prefix) | |
50 | return tuple(network.subnets(count_log2))[0:count] | |
51 | ||
52 | ||
53 | def write_big_route_conf(super_prefix, count, confpath): | |
54 | start = None | |
55 | end = None | |
56 | ||
57 | with open(confpath, "w+", encoding="ascii") as f: | |
58 | for net in get_ip_networks(super_prefix, count): | |
59 | end = net | |
60 | if not start: | |
61 | start = net | |
62 | f.write(f"ip route {net} lo\n") | |
63 | ||
64 | return start, end | |
65 | ||
66 | ||
67 | def _test_staticd_late_start(tgen, router): | |
68 | if tgen.routers_have_failure(): | |
69 | pytest.skip(tgen.errors) | |
70 | ||
71 | # for x in ["r1"]: | |
72 | # tgen.gears[x].net.cmd_nostatus( | |
73 | # "vtysh -c 'debug mgmt client frontend' " | |
74 | # "-c 'debug mgmt client backend' " | |
75 | # "-c 'debug mgmt backend frontend datastore transaction'" | |
76 | # ) | |
77 | ||
78 | step("Verifying startup route is not present w/o staticd running") | |
79 | result = check_kernel(router, "12.0.0.0/24", expected=False) | |
80 | assert result is not None | |
81 | ||
82 | step("Configure another static route verify is not present w/o staticd running") | |
83 | router.net.cmd_nostatus("vtysh -c 'config t' -c 'ip route 12.1.0.0/24 101.0.0.2'") | |
84 | result = check_kernel(router, "12.0.0.0/24", expected=False) | |
85 | assert result is not None | |
86 | result = check_kernel(router, "12.1.0.0/24", expected=False) | |
87 | assert result is not None | |
88 | ||
89 | step("Starting staticd") | |
90 | router.startDaemons(["staticd"]) | |
91 | ||
92 | step("Verifying both routes are present") | |
93 | result = check_kernel(router, "12.0.0.0/24") | |
94 | assert result is None | |
95 | result = check_kernel(router, "12.1.0.0/24") | |
96 | assert result is None |