4 # Copyright (c) 2020 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6 # ("NetDEF") in this file.
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 """OSPF Basic Functionality Automation."""
29 from time
import sleep
30 from copy
import deepcopy
32 from lib
.topotest
import frr_unicode
34 # Save the Current Working Directory to find configuration files.
35 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
36 sys
.path
.append(os
.path
.join(CWD
, "../"))
37 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
39 # pylint: disable=C0413
40 # Import topogen and topotest helpers
41 from mininet
.topo
import Topo
42 from lib
.topogen
import Topogen
, get_topogen
44 # Import topoJson from lib, to create topology and initial configuration
45 from lib
.common_config
import (
49 reset_config_on_routers
,
51 shutdown_bringup_interface
,
54 from lib
.topolog
import logger
55 from lib
.topojson
import build_topo_from_json
, build_config_from_json
56 from lib
.ospf
import verify_ospf_neighbor
, config_ospf_interface
, clear_ospf
57 from ipaddress
import IPv4Address
61 # Reading the data from JSON File for topology creation
62 jsonFile
= "{}/ospf_authentication.json".format(CWD
)
64 with
open(jsonFile
, "r") as topoJson
:
65 topo
= json
.load(topoJson
)
67 assert False, "Could not read file {}".format(jsonFile
)
70 Please view in a fixed-width font such as Courier.
72 +R1 +------------+R2 |
81 +R0 +-------------+R3 |
85 1. Verify ospf authentication with Simple password authentication.
86 2. Verify ospf authentication with MD5 authentication.
87 3. Verify ospf authentication with different authentication methods.
92 class CreateTopo(Topo
):
94 Test topology builder.
96 * `Topo`: Topology object
99 def build(self
, *_args
, **_opts
):
100 """Build function."""
101 tgen
= get_topogen(self
)
103 # Building topology from json file
104 build_topo_from_json(tgen
, topo
)
107 def setup_module(mod
):
109 Sets up the pytest environment
114 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
115 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
116 logger
.info("=" * 40)
118 logger
.info("Running setup_module to create topology")
120 # This function initiates the topology build with Topogen...
121 tgen
= Topogen(CreateTopo
, mod
.__name
__)
122 # ... and here it calls Mininet initialization functions.
124 # get list of daemons needs to be started for this suite.
125 daemons
= topo_daemons(tgen
, topo
)
127 # Starting topology, create tmp files which are loaded to routers
128 # to start deamons and then start routers
129 start_topology(tgen
, daemons
)
131 # Creating configuration from JSON
132 build_config_from_json(tgen
, topo
)
134 # Don't run this test if we have any failure.
135 if tgen
.routers_have_failure():
136 pytest
.skip(tgen
.errors
)
138 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
)
139 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
143 logger
.info("Running setup_module() done")
146 def teardown_module(mod
):
148 Teardown the pytest environment.
153 logger
.info("Running teardown_module to delete topology")
157 # Stop toplogy and Remove tmp files
161 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
163 logger
.info("=" * 40)
166 # ##################################
167 # Test cases start here.
168 # ##################################
171 def test_ospf_authentication_simple_pass_tc28_p1(request
):
173 OSPF Authentication - Verify ospf authentication with Simple
174 password authentication.
177 tc_name
= request
.node
.name
178 write_test_header(tc_name
)
181 step("Bring up the base config.")
182 reset_config_on_routers(tgen
)
184 "Configure ospf with on R1 and R2, enable ospf on R1 interface"
185 "connected to R2 with simple password authentication using ip ospf "
186 "authentication Simple password cmd."
192 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
196 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
197 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
199 step("clear ip ospf after configuring the authentication.")
200 clear_ospf(tgen
, "r1")
202 step("Verify that the neighbour is not FULL between R1 and R2.")
204 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
205 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
210 "On R2 enable ospf on interface with simple password authentication "
211 "using ip ospf authentication Simple password cmd."
217 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
221 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
222 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
225 "Verify that the neighbour is FULL between R1 and R2 "
226 "using show ip ospf neighbor cmd."
230 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
231 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
236 "Disable simple password authentication on R2 using no ip ospf "
237 "authentication Simple password cmd."
244 "authentication": True,
245 "authentication-key": "ospf",
252 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
253 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
255 step("Verify on R1 neighbour is deleted for R2 after dead interval expiry")
256 # wait till the dead time expiry
259 ospf_covergence
= verify_ospf_neighbor(
260 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
262 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
266 step("Again On R2 enable ospf on interface with Simple password auth")
270 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
274 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
275 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
278 "Verify that the neighbour is FULL between R1 and R2 using"
279 " show ip ospf neighbor cmd."
283 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
284 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
288 step("Shut no shut interface on R1")
290 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
291 shutdown_bringup_interface(tgen
, dut
, intf
, False)
295 "Verify that the neighbour is not FULL between R1 and R2 using "
296 "show ip ospf neighbor cmd."
298 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
299 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
304 shutdown_bringup_interface(tgen
, dut
, intf
, True)
307 "Verify that the neighbour is FULL between R1 and R2 using "
308 "show ip ospf neighbor cmd."
312 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
313 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
317 step("Change Ip address on R1 and R2")
319 topo_modify_change_ip
= deepcopy(topo
)
320 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
321 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
322 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
323 ) + "/{}".format(intf_ip
.split("/")[1])
325 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
327 reset_config_on_routers(tgen
, routerName
="r1")
329 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
330 shutdown_bringup_interface(tgen
, dut
, intf
, False)
331 shutdown_bringup_interface(tgen
, dut
, intf
, True)
333 # clear ip ospf after configuring the authentication.
334 clear_ospf(tgen
, "r1")
339 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
343 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
344 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
347 "Verify that the neighbour is FULL between R1 and R2 with new "
348 "ip address using show ip ospf "
352 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
353 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
357 write_test_footer(tc_name
)
360 def test_ospf_authentication_md5_tc29_p1(request
):
362 OSPF Authentication - Verify ospf authentication with MD5 authentication.
365 tc_name
= request
.node
.name
366 write_test_header(tc_name
)
369 step("Bring up the base config.")
370 reset_config_on_routers(tgen
)
372 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
373 "connected to R2 with message-digest authentication using ip "
374 "ospf authentication message-digest cmd."
382 "authentication": "message-digest",
383 "authentication-key": "ospf",
384 "message-digest-key": "10",
390 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
391 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
393 step("Verify that the neighbour is not FULL between R1 and R2.")
394 # wait for dead time expiry.
397 ospf_covergence
= verify_ospf_neighbor(
398 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=6
400 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
405 "On R2 enable ospf on interface with message-digest authentication"
406 " using ip ospf authentication message-digest password cmd."
414 "authentication": "message-digest",
415 "authentication-key": "ospf",
416 "message-digest-key": "10",
422 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
423 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
426 "Verify that the neighbour is FULL between R1 and R2 "
427 "using show ip ospf neighbor cmd."
431 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
432 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
437 "Disable message-digest authentication on R2 using no ip ospf "
438 "authentication message-digest password cmd."
446 "authentication": "message-digest",
447 "authentication-key": "ospf",
448 "message-digest-key": "10",
455 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
456 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
458 step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry")
459 # wait till the dead timer expiry
462 ospf_covergence
= verify_ospf_neighbor(
463 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
465 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
469 step("Again On R2 enable ospf on interface with message-digest auth")
475 "authentication": "message-digest",
476 "authentication-key": "ospf",
477 "message-digest-key": "10",
483 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
484 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
487 "Verify that the neighbour is FULL between R1 and R2 using"
488 " show ip ospf neighbor cmd."
492 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
493 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
497 step("Shut no shut interface on R1")
499 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
500 shutdown_bringup_interface(tgen
, dut
, intf
, False)
504 "Verify that the neighbour is not FULL between R1 and R2 using "
505 "show ip ospf neighbor cmd."
507 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
508 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
513 shutdown_bringup_interface(tgen
, dut
, intf
, True)
516 "Verify that the neighbour is FULL between R1 and R2 using "
517 "show ip ospf neighbor cmd."
521 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
522 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
526 step("Change Ip address on R1 and R2")
528 topo_modify_change_ip
= deepcopy(topo
)
530 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
532 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
533 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
534 ) + "/{}".format(intf_ip
.split("/")[1])
536 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
538 reset_config_on_routers(tgen
, routerName
="r1")
540 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
541 shutdown_bringup_interface(tgen
, dut
, intf
, False)
542 shutdown_bringup_interface(tgen
, dut
, intf
, True)
543 clear_ospf(tgen
, "r1")
549 "authentication": "message-digest",
550 "authentication-key": "ospf",
551 "message-digest-key": "10",
557 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
558 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
561 "Verify that the neighbour is FULL between R1 and R2 with new "
562 "ip address using show ip ospf "
566 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
567 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
571 write_test_footer(tc_name
)
574 def test_ospf_authentication_different_auths_tc30_p1(request
):
576 OSPF Authentication - Verify ospf authentication with different
577 authentication methods.
580 tc_name
= request
.node
.name
581 write_test_header(tc_name
)
584 step("Bring up the base config.")
585 reset_config_on_routers(tgen
)
587 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
588 "connected to R2 with message-digest authentication using ip "
589 "ospf authentication message-digest cmd."
597 "authentication": "message-digest",
598 "authentication-key": "ospf",
599 "message-digest-key": "10",
605 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
606 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
608 # wait for dead timer expiry
610 step("Verify that the neighbour is not FULL between R1 and R2.")
612 ospf_covergence
= verify_ospf_neighbor(
613 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
615 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
620 "On R2 enable ospf on interface with message-digest authentication"
621 " using ip ospf authentication message-digest password cmd."
629 "authentication": "message-digest",
630 "authentication-key": "ospf",
631 "message-digest-key": "10",
637 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
638 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
641 "Verify that the neighbour is FULL between R1 and R2 "
642 "using show ip ospf neighbor cmd."
646 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
647 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
651 step(" Delete the configured password on both the routers.")
658 "authentication": "message-digest",
659 "authentication-key": "ospf",
660 "message-digest-key": "10",
667 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
668 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
675 "authentication": "message-digest",
676 "authentication-key": "ospf",
677 "message-digest-key": "10",
684 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
685 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
688 "Verify that the deletion is successful and neighbour is FULL"
689 " between R1 and R2 using show ip ospf neighbor cmd."
693 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
694 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
698 step("Change the authentication type to simple password.")
702 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
706 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
707 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
712 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
716 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
717 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
720 "Verify that the deletion is successful and neighbour is"
721 " FULL between R1 and R2 using show ip "
725 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
726 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
730 step("Change the password in simple password.")
735 "r2": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
739 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
740 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
745 "r1": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
749 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
750 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
753 "Verify that the deletion is successful and neighbour is"
754 " FULL between R1 and R2 using show ip "
758 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
759 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
763 step("Delete the password authentication on the interface ")
770 "authentication": True,
771 "authentication-key": "OSPFv4",
778 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
779 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
786 "authentication": True,
787 "authentication-key": "OSPFv4",
794 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
795 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
798 "Verify that the deletion is successful and neighbour is"
799 " FULL between R1 and R2 using show ip "
803 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
804 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
808 step("Enable Md5 authentication on the interface")
815 "authentication": "message-digest",
816 "authentication-key": "ospf",
817 "message-digest-key": "10",
823 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
824 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
831 "authentication": "message-digest",
832 "authentication-key": "ospf",
833 "message-digest-key": "10",
839 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
840 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
843 "Verify that the neighbour is FULL between R1 and R2 using"
844 " show ip ospf neighbor cmd."
848 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
849 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
853 step("Change the MD5 authentication password")
860 "authentication": "message-digest",
861 "authentication-key": "OSPFv4",
862 "message-digest-key": "10",
868 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
869 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
876 "authentication": "message-digest",
877 "authentication-key": "OSPFv4",
878 "message-digest-key": "10",
884 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
885 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
887 write_test_footer(tc_name
)
890 if __name__
== "__main__":
891 args
= ["-s"] + sys
.argv
[1:]
892 sys
.exit(pytest
.main(args
))