]>
Commit | Line | Data |
---|---|---|
4436ba8d | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
4436ba8d | 3 | |
4 | # | |
5 | # test_ospf_suppres_fa.py | |
6 | # Carles Kishimoto | |
7 | # | |
4436ba8d | 8 | |
9 | """ | |
10 | test_ospf_suppres_fa.py: Test OSPF suppress-fa feature | |
11 | - Topology: r1 --- R2 (ABR) --- R3 (redistribute static) | |
12 | ||
13 | test_ospf_set_suppress_fa() | |
14 | 1) R1: Get a dict[LSA_ID] = fwd_addr for all type 5 LSA | |
15 | 2) R2: Configure: area 1 nssa suppress-fa | |
16 | 3) R1: Get a dict[LSA_ID] and compare fwd_address with 0.0.0.0 | |
17 | ||
18 | test_ospf_unset_suppress_fa() | |
19 | 4) R2: Configure: no area 1 nssa suppress-fa | |
20 | 5) R1: Get a dict[LSA_ID] = fwd_addr and compare it with the dict obtained in 1) | |
21 | """ | |
22 | ||
23 | import os | |
24 | import sys | |
25 | import re | |
26 | import pytest | |
27 | ||
28 | # Save the Current Working Directory to find configuration files. | |
29 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
30 | sys.path.append(os.path.join(CWD, "../")) | |
31 | ||
32 | # pylint: disable=C0413 | |
33 | # Import topogen and topotest helpers | |
34 | from lib import topotest | |
35 | from lib.topogen import Topogen, TopoRouter, get_topogen | |
36 | ||
37 | # Required to instantiate the topology builder class. | |
4436ba8d | 38 | |
6ff492b1 DS |
39 | pytestmark = [pytest.mark.ospfd] |
40 | ||
4436ba8d | 41 | |
e82b531d CH |
42 | def build_topo(tgen): |
43 | "Build function" | |
4436ba8d | 44 | |
e82b531d CH |
45 | # Create routers |
46 | for router in range(1, 4): | |
47 | tgen.add_router("r{}".format(router)) | |
4436ba8d | 48 | |
e82b531d CH |
49 | # R1-R2 backbone area |
50 | switch = tgen.add_switch("s1") | |
51 | switch.add_link(tgen.gears["r1"]) | |
52 | switch.add_link(tgen.gears["r2"]) | |
4436ba8d | 53 | |
e82b531d CH |
54 | # R2-R3 NSSA area |
55 | switch = tgen.add_switch("s2") | |
56 | switch.add_link(tgen.gears["r2"]) | |
57 | switch.add_link(tgen.gears["r3"]) | |
4436ba8d | 58 | |
59 | ||
60 | def setup_module(mod): | |
61 | "Sets up the pytest environment" | |
62 | ||
e82b531d | 63 | tgen = Topogen(build_topo, mod.__name__) |
4436ba8d | 64 | tgen.start_topology() |
65 | ||
66 | # This is a sample of configuration loading. | |
67 | router_list = tgen.routers() | |
68 | ||
b515c81a | 69 | # For all registered routers, load the zebra and ospf configuration file |
4436ba8d | 70 | for rname, router in router_list.items(): |
71 | router.load_config( | |
72 | TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) | |
73 | ) | |
74 | router.load_config( | |
75 | TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) | |
76 | ) | |
77 | ||
78 | tgen.start_router() | |
79 | ||
0b25370e | 80 | |
4436ba8d | 81 | def teardown_module(_mod): |
82 | "Teardown the pytest environment" | |
83 | ||
84 | tgen = get_topogen() | |
85 | tgen.stop_topology() | |
86 | ||
0b25370e | 87 | |
4436ba8d | 88 | def test_converge_protocols(): |
89 | "Wait for protocol convergence" | |
90 | ||
91 | tgen = get_topogen() | |
92 | # Don't run this test if we have any failure. | |
93 | if tgen.routers_have_failure(): | |
94 | pytest.skip(tgen.errors) | |
95 | ||
96 | topotest.sleep(10, "Waiting for OSPF convergence") | |
97 | ||
0b25370e | 98 | |
4436ba8d | 99 | def ospf_configure_suppress_fa(router_name, area): |
100 | "Configure OSPF suppress-fa in router_name" | |
101 | ||
102 | tgen = get_topogen() | |
103 | router = tgen.gears[router_name] | |
0b25370e DS |
104 | router.vtysh_cmd( |
105 | "conf t\nrouter ospf\narea {} nssa suppress-fa\nexit\n".format(area) | |
106 | ) | |
107 | ||
4436ba8d | 108 | |
109 | def ospf_unconfigure_suppress_fa(router_name, area): | |
110 | "Remove OSPF suppress-fa in router_name" | |
111 | ||
112 | tgen = get_topogen() | |
113 | router = tgen.gears[router_name] | |
e85194f5 | 114 | router.vtysh_cmd("conf t\nrouter ospf\narea {} nssa\nexit\n".format(area)) |
0b25370e | 115 | |
4436ba8d | 116 | |
117 | def ospf_get_lsa_type5(router_name): | |
118 | "Return a dict with link state id as key and forwarding addresses as value" | |
119 | ||
120 | result = dict() | |
121 | tgen = get_topogen() | |
122 | router = tgen.gears[router_name] | |
123 | cmd = "show ip ospf database external\n" | |
124 | output = topotest.normalize_text(router.vtysh_cmd(cmd)) | |
125 | for line in output.splitlines(): | |
126 | re0 = re.match(r"\s+Link State ID: (\S+) \(External Network Number\)", line) | |
127 | if re0: | |
128 | lsa = re0.group(1) | |
129 | re1 = re.match(r"\s+Forward Address: (\S+)", line) | |
130 | if re1: | |
131 | result[lsa] = re1.group(1) | |
132 | return result | |
133 | ||
0b25370e DS |
134 | |
135 | @pytest.fixture(scope="module", name="original") | |
4436ba8d | 136 | def test_ospf_set_suppress_fa(): |
137 | "Test OSPF area [x] nssa suppress-fa" | |
138 | ||
139 | # Get current forwarding address for each LSA type-5 in r1 | |
140 | initial = ospf_get_lsa_type5("r1") | |
141 | ||
142 | # Configure suppres-fa in r2 area 1 | |
143 | ospf_configure_suppress_fa("r2", "1") | |
144 | topotest.sleep(10, "Waiting for OSPF convergence") | |
145 | ||
146 | # Check forwarding address on r1 for all statics is 0.0.0.0 | |
147 | assertmsg = "Forwarding address is not 0.0.0.0 after enabling OSPF suppress-fa" | |
148 | suppress = ospf_get_lsa_type5("r1") | |
149 | for prefix in suppress: | |
150 | assert suppress[prefix] == "0.0.0.0", assertmsg | |
151 | ||
152 | # Return the original forwarding addresses so we can compare them | |
153 | # in the test_ospf_unset_supress_fa | |
154 | return initial | |
155 | ||
0b25370e | 156 | |
4436ba8d | 157 | def test_ospf_unset_supress_fa(original): |
158 | "Test OSPF no area [x] nssa suppress-fa" | |
159 | ||
160 | # Remove suppress-fa in r2 area 1 | |
161 | ospf_unconfigure_suppress_fa("r2", "1") | |
162 | topotest.sleep(10, "Waiting for OSPF convergence") | |
163 | ||
164 | # Check forwarding address is the original value on r1 for all statics | |
165 | assertmsg = "Forwarding address is not correct after removing OSPF suppress-fa" | |
166 | restore = ospf_get_lsa_type5("r1") | |
167 | for prefix in restore: | |
168 | assert restore[prefix] == original[prefix], assertmsg | |
169 | ||
170 | ||
171 | if __name__ == "__main__": | |
172 | args = ["-s"] + sys.argv[1:] | |
173 | sys.exit(pytest.main(args)) |