]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py
*: auto-convert to SPDX License IDs
[mirror_frr.git] / tests / topotests / ospfv3_basic_functionality / test_ospfv3_nssa2.py
CommitLineData
d1b5fa5b 1#!/usr/bin/python
acddc0ed 2# SPDX-License-Identifier: ISC
d1b5fa5b 3
4#
5# Copyright (c) 2021 by VMware, Inc. ("VMware")
6# Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
7# ("NetDEF") in this file.
8#
d1b5fa5b 9
10
11"""OSPF Basic Functionality Automation."""
12import os
13import sys
14import time
15import pytest
16from copy import deepcopy
17import ipaddress
18from lib.ospf import (
19 verify_ospf6_neighbor,
20 config_ospf6_interface,
21 clear_ospf,
22 verify_ospf6_rib,
23 verify_ospf6_interface,
24 verify_ospf6_database,
25 create_router_ospf,
26)
27
28# pylint: disable=C0413
29# Import topogen and topotest helpers
30from lib.topogen import Topogen, get_topogen
31
32from lib.bgp import (
33 verify_bgp_convergence,
34 create_router_bgp,
35 clear_bgp_and_verify,
36 verify_bgp_rib,
37)
38from lib.topolog import logger
39from lib.common_config import (
40 start_topology,
41 write_test_header,
42 write_test_footer,
43 reset_config_on_routers,
44 verify_rib,
45 create_static_routes,
46 step,
d1b5fa5b 47 create_route_maps,
48 shutdown_bringup_interface,
49 create_interfaces_cfg,
50 check_router_status,
51)
52from ipaddress import IPv4Address
53from lib.topolog import logger
54from lib.topojson import build_config_from_json
55
56
57# Save the Current Working Directory to find configuration files.
58CWD = os.path.dirname(os.path.realpath(__file__))
59sys.path.append(os.path.join(CWD, "../"))
60
61pytestmark = [pytest.mark.ospfd, pytest.mark.staticd]
62
63# Global variables
64topo = None
65NETWORK = {
66 "ipv4": [
67 "11.0.20.1/32",
68 "11.0.20.2/32",
69 "11.0.20.3/32",
70 "11.0.20.4/32",
71 "11.0.20.5/32",
72 ],
73 "ipv6": [
74 "2011:0:20::1/128",
75 "2011:0:20::2/128",
76 "2011:0:20::3/128",
77 "2011:0:20::4/128",
78 "2011:0:20::5/128",
79 ],
80}
81"""
82TOPOOLOGY =
83 Please view in a fixed-width font such as Courier.
84 +---+ A1 +---+
85 +R1 +------------+R2 |
86 +-+-+- +--++
87 | -- -- |
88 | -- A0 -- |
89 A0| ---- |
90 | ---- | A2
91 | -- -- |
92 | -- -- |
93 +-+-+- +-+-+
94 +R0 +-------------+R3 |
95 +---+ A3 +---+
96
97
98
99TESTCASES =
1001. OSPF Learning - Verify OSPF can learn different types of LSA and
101 processes them.[Edge learning different types of LSAs]
1022. Verify that ospf non back bone area can be configured as NSSA area
1033. Verify that ospf NSSA area DUT is capable receiving & processing
104 Type7 N2 route.
105"""
106
107
108def setup_module(mod):
109 """
110 Sets up the pytest environment
111
112 * `mod`: module name
113 """
114 global topo
115 testsuite_run_time = time.asctime(time.localtime(time.time()))
116 logger.info("Testsuite start time: {}".format(testsuite_run_time))
117 logger.info("=" * 40)
118
119 logger.info("Running setup_module to create topology")
120
121 # This function initiates the topology build with Topogen...
122 json_file = "{}/ospfv3_nssa2.json".format(CWD)
123 tgen = Topogen(json_file, mod.__name__)
124 global topo
125 topo = tgen.json_topo
126 # ... and here it calls Mininet initialization functions.
127
d1b5fa5b 128 # Starting topology, create tmp files which are loaded to routers
d60a3f0e 129 # to start daemons and then start routers
991a971f 130 start_topology(tgen)
d1b5fa5b 131
132 # Creating configuration from JSON
133 build_config_from_json(tgen, topo)
134
135 # Don't run this test if we have any failure.
136 if tgen.routers_have_failure():
137 pytest.skip(tgen.errors)
138
139 # Api call verify whether OSPF is converged
140 ospf_covergence = verify_ospf6_neighbor(tgen, topo)
141 assert ospf_covergence is True, "setup_module :Failed \n Error:" " {}".format(
142 ospf_covergence
143 )
144
145 logger.info("Running setup_module() done")
146
147
148def teardown_module():
149 """Teardown the pytest environment."""
150 logger.info("Running teardown_module to delete topology")
151
152 tgen = get_topogen()
153
154 # Stop toplogy and Remove tmp files
155 tgen.stop_topology()
156
157
158def red_static(dut, config=True):
159 """Local def for Redstribute static routes inside ospf."""
160 global topo
161 tgen = get_topogen()
162 if config:
163 ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "static"}]}}}
164 else:
165 ospf_red = {
166 dut: {
167 "ospf6": {"redistribute": [{"redist_type": "static", "delete": True}]}
168 }
169 }
170 result = create_router_ospf(tgen, topo, ospf_red)
171 assert result is True, "Testcase : Failed \n Error: {}".format(result)
172
173
174def red_connected(dut, config=True):
175 """Local def for Redstribute connected routes inside ospf."""
176 global topo
177 tgen = get_topogen()
178 if config:
179 ospf_red = {dut: {"ospf6": {"redistribute": [{"redist_type": "connected"}]}}}
180 else:
181 ospf_red = {
182 dut: {
183 "ospf6": {
184 "redistribute": [{"redist_type": "connected", "del_action": True}]
185 }
186 }
187 }
188 result = create_router_ospf(tgen, topo, ospf_red)
189 assert result is True, "Testcase: Failed \n Error: {}".format(result)
190
191
192# ##################################
193# Test cases start here.
194# ##################################
195
196
197def test_ospfv3_nssa_tc26_p0(request):
198 """Verify that ospf non back bone area can be configured as NSSA area"""
199 tc_name = request.node.name
200 write_test_header(tc_name)
201 tgen = get_topogen()
202
203 # Don't run this test if we have any failure.
204 if tgen.routers_have_failure():
205 check_router_status(tgen)
206
207 global topo
208 step("Bring up the base config as per the topology")
209 step("Configure ospf area 2 on r0 , r1 & r4, make the area 2 as NSSA area")
210
211 reset_config_on_routers(tgen)
212
213 input_dict = {
214 "r2": {
215 "static_routes": [
216 {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
217 ]
218 }
219 }
220 result = create_static_routes(tgen, input_dict)
221 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
222
223 step("Redistribute static route in R2 ospf.")
224 dut = "r2"
225 red_static(dut)
226
227 step("Verify that Type 5 LSA is originated by R2.")
228 dut = "r0"
229 protocol = "ospf6"
230 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
231 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
232
233 step("Un configure redistribute command in R4")
234 dut = "r2"
235 red_static(dut, config=False)
236
237 input_dict = {
238 "r1": {
239 "static_routes": [
240 {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
241 ]
242 }
243 }
244
245 step("Configure area 0 on interface of r2 connecting to r1")
246
247 input_dict = {
248 "r2": {
249 "links": {
250 "r1": {
251 "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
252 "ospf6": {"area": "0.0.0.2"},
253 "delete": True,
254 }
255 }
256 }
257 }
258
259 result = create_interfaces_cfg(tgen, input_dict)
260 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
261
262 input_dict = {
263 "r2": {
264 "links": {
265 "r1": {
266 "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
267 "ospf6": {"area": "0.0.0.0"},
268 }
269 }
270 }
271 }
272
273 result = create_interfaces_cfg(tgen, input_dict)
274 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
275
276 step("verify that ospf neighbor goes down between r2 and r1.")
277 result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
278 assert (
279 result is not True
280 ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
281
282 step("Now configure area 0 on interface of r1 connecting to r2.")
283
284 input_dict = {
285 "r1": {
286 "links": {
287 "r2": {
288 "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
289 "ospf6": {"area": "0.0.0.2"},
290 "delete": True,
291 }
292 }
293 }
294 }
295
296 result = create_interfaces_cfg(tgen, input_dict)
297 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
298
299 input_dict = {
300 "r1": {
301 "links": {
302 "r2": {
303 "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
304 "ospf6": {"area": "0.0.0.0"},
305 }
306 }
307 }
308 }
309
310 result = create_interfaces_cfg(tgen, input_dict)
311 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
312
313 step("Verify that ospf neighbour comes up between r2 and r1.")
314 result = verify_ospf6_neighbor(tgen, topo, dut="r2")
315 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
316
317 step("Configure area 2 on interface of r2 connecting to r1.")
318
319 input_dict = {
320 "r2": {
321 "links": {
322 "r1": {
323 "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
324 "ospf6": {"area": "0.0.0.0"},
325 "delete": True,
326 }
327 }
328 }
329 }
330
331 result = create_interfaces_cfg(tgen, input_dict)
332 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
333
334 input_dict = {
335 "r2": {
336 "links": {
337 "r1": {
338 "interface": topo["routers"]["r2"]["links"]["r1"]["interface"],
339 "ospf6": {"area": "0.0.0.2"},
340 }
341 }
342 }
343 }
344
345 result = create_interfaces_cfg(tgen, input_dict)
346 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
347
348 step("verify that ospf neighbor goes down between r2 and r1.")
349 result = verify_ospf6_neighbor(tgen, topo, dut="r2", expected=False)
350 assert (
351 result is not True
352 ), "Testcase {} : Failed \n Nbrs are not down" "Error: {}".format(tc_name, result)
353
354 step("Now configure area 2 on interface of r1 connecting to r2.")
355
356 input_dict = {
357 "r1": {
358 "links": {
359 "r2": {
360 "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
361 "ospf6": {"area": "0.0.0.0"},
362 "delete": True,
363 }
364 }
365 }
366 }
367
368 result = create_interfaces_cfg(tgen, input_dict)
369 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
370
371 input_dict = {
372 "r1": {
373 "links": {
374 "r2": {
375 "interface": topo["routers"]["r1"]["links"]["r2"]["interface"],
376 "ospf6": {"area": "0.0.0.2"},
377 }
378 }
379 }
380 }
381
382 result = create_interfaces_cfg(tgen, input_dict)
383 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
384
385 step("Verify that ospf neighbour comes up between r2 and r1.")
386 result = verify_ospf6_neighbor(tgen, topo, dut="r2")
387 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
388
389 write_test_footer(tc_name)
390
391
50a275d7
MN
392def test_ospfv3_learning_tc15_p0(request):
393 """Verify OSPF can learn different types of LSA and processes them.
394
395 OSPF Learning : Edge learning different types of LSAs.
396 """
397 tc_name = request.node.name
398 write_test_header(tc_name)
399 tgen = get_topogen()
400
401 # Don't run this test if we have any failure.
402 if tgen.routers_have_failure():
403 check_router_status(tgen)
404
405 global topo
406 step("Bring up the base config as per the topology")
407 step("Configure area 1 as NSSA Area")
408
409 reset_config_on_routers(tgen)
410
411 step("Verify that Type 3 summary LSA is originated for the same Area 0")
412 ip = topo["routers"]["r1"]["links"]["r3-link0"]["ipv6"]
413 ip_net = str(ipaddress.ip_interface(u"{}".format(ip)).network)
414
415 input_dict = {
416 "r1": {
417 "static_routes": [
418 {
419 "network": ip_net,
420 "no_of_ip": 1,
421 "routeType": "Network",
422 "pathtype": "Inter-Area",
423 }
424 ]
425 }
426 }
427
428 dut = "r0"
429 result = verify_ospf6_rib(tgen, dut, input_dict)
430 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
431
432 protocol = "ospf6"
433 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
434 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
435
436 input_dict = {
437 "r2": {
438 "static_routes": [
439 {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
440 ]
441 }
442 }
443 result = create_static_routes(tgen, input_dict)
444 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
445
446 step("Redistribute static route in R2 ospf.")
447 dut = "r2"
448 red_static(dut)
449
450 step("Verify that Type 5 LSA is originated by R2.")
451 dut = "r0"
452 protocol = "ospf6"
453 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
454 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
455
456 input_dict = {
457 "r1": {
458 "static_routes": [
459 {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
460 ]
461 }
462 }
463
464 dut = "r1"
465 result = verify_ospf6_rib(tgen, dut, input_dict)
466 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
467
468 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
469 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
470
471 result = verify_ospf6_neighbor(tgen, topo)
472 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
473
474 step("Change area 1 as non nssa area (on the fly changing area" " type on DUT).")
475
476 for rtr in ["r1", "r2", "r3"]:
477 input_dict = {
478 rtr: {
479 "ospf6": {"area": [{"id": "0.0.0.2", "type": "nssa", "delete": True}]}
480 }
481 }
482 result = create_router_ospf(tgen, topo, input_dict)
483 assert result is True, "Testcase {} : Failed \n Error: {}".format(
484 tc_name, result
485 )
486
487 step("Verify that OSPF neighbours are reset after changing area type.")
488 step("Verify that ABR R2 originates type 5 LSA in area 1.")
489 step("Verify that R1 installs type 5 lsa in its database.")
490 step("Verify that route is calculated and installed in R1.")
491
492 input_dict = {
493 "r1": {
494 "static_routes": [
495 {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
496 ]
497 }
498 }
499
500 dut = "r1"
501 result = verify_ospf6_rib(tgen, dut, input_dict)
502 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
503
504 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
505 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
506
507 write_test_footer(tc_name)
508
509
d1b5fa5b 510# As per internal discussion, this script has to be removed as translator
511# function is not supported, for more details kindly check this PR 2565570
512def ospfv3_nssa_tc27_p0(request):
513 """
514 OSPF NSSA.
515
516 Verify that ospf NSSA area DUT is capable receiving & processing
517 Type7 N2 route.
518 """
519 tc_name = request.node.name
520 write_test_header(tc_name)
521 tgen = get_topogen()
522
523 # Don't run this test if we have any failure.
524 if tgen.routers_have_failure():
525 check_router_status(tgen)
526
527 global topo
528 step("Bring up the base config as per the topology")
529 step("Configure ospf area 2 on r0 , r1 & r4, make the area 2 as NSSA area")
530
531 reset_config_on_routers(tgen)
532
533 input_dict = {
534 "r2": {
535 "static_routes": [
536 {"network": NETWORK["ipv6"][0], "no_of_ip": 5, "next_hop": "Null0"}
537 ]
538 }
539 }
540 result = create_static_routes(tgen, input_dict)
541 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
542
543 step("Redistribute static route in R2 ospf.")
544 dut = "r2"
545 red_static(dut)
546
547 step("Verify that Type 5 LSA is originated by R2.")
548 dut = "r0"
549 protocol = "ospf6"
550 result = verify_rib(tgen, "ipv6", dut, input_dict, protocol=protocol)
551 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
552
553 step("Un configure redistribute command in R4")
554 dut = "r2"
555 red_static(dut, config=False)
556
557 input_dict = {
558 "r1": {
559 "static_routes": [
560 {"network": NETWORK["ipv6"][0], "no_of_ip": 1, "routeType": "Network"}
561 ]
562 }
563 }
564
565 dut = "r0"
566 result = verify_ospf6_rib(tgen, dut, input_dict, expected=False)
567 assert result is not True, "Testcase {} : Failed \n Error: {}".format(
568 tc_name, result
569 )
570
571 result = verify_rib(
572 tgen, "ipv6", dut, input_dict, protocol=protocol, expected=False
573 )
574 assert result is not True, "Testcase {} : Failed \n Error: {}".format(
575 tc_name, result
576 )
577
578 write_test_footer(tc_name)
579
580
581if __name__ == "__main__":
582 args = ["-s"] + sys.argv[1:]
583 sys.exit(pytest.main(args))