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
31 from lib
.topotest
import frr_unicode
33 # Save the Current Working Directory to find configuration files.
34 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
35 sys
.path
.append(os
.path
.join(CWD
, "../"))
36 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
38 # pylint: disable=C0413
39 # Import topogen and topotest helpers
40 from lib
.topogen
import Topogen
, get_topogen
42 # Import topoJson from lib, to create topology and initial configuration
43 from lib
.common_config
import (
47 reset_config_on_routers
,
49 shutdown_bringup_interface
,
51 from lib
.topolog
import logger
52 from lib
.topojson
import build_config_from_json
53 from lib
.ospf
import verify_ospf_neighbor
, config_ospf_interface
, clear_ospf
54 from ipaddress
import IPv4Address
56 pytestmark
= [pytest
.mark
.ospfd
]
63 Please view in a fixed-width font such as Courier.
65 +R1 +------------+R2 |
74 +R0 +-------------+R3 |
78 1. Verify ospf authentication with Simple password authentication.
79 2. Verify ospf authentication with MD5 authentication.
80 3. Verify ospf authentication with different authentication methods.
85 def setup_module(mod
):
87 Sets up the pytest environment
91 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
92 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
95 logger
.info("Running setup_module to create topology")
97 # This function initiates the topology build with Topogen...
98 json_file
= "{}/ospf_authentication.json".format(CWD
)
99 tgen
= Topogen(json_file
, mod
.__name
__)
101 topo
= tgen
.json_topo
102 # ... and here it calls Mininet initialization functions.
104 # Starting topology, create tmp files which are loaded to routers
105 # to start daemons and then start routers
108 # Creating configuration from JSON
109 build_config_from_json(tgen
, topo
)
111 # Don't run this test if we have any failure.
112 if tgen
.routers_have_failure():
113 pytest
.skip(tgen
.errors
)
115 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
)
116 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
120 logger
.info("Running setup_module() done")
123 def teardown_module(mod
):
125 Teardown the pytest environment.
130 logger
.info("Running teardown_module to delete topology")
134 # Stop toplogy and Remove tmp files
138 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
140 logger
.info("=" * 40)
143 # ##################################
144 # Test cases start here.
145 # ##################################
148 def test_ospf_authentication_simple_pass_tc28_p1(request
):
150 OSPF Authentication - Verify ospf authentication with Simple
151 password authentication.
154 tc_name
= request
.node
.name
155 write_test_header(tc_name
)
158 step("Bring up the base config.")
159 reset_config_on_routers(tgen
)
161 "Configure ospf with on R1 and R2, enable ospf on R1 interface"
162 "connected to R2 with simple password authentication using ip ospf "
163 "authentication Simple password cmd."
169 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
173 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
174 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
176 step("clear ip ospf after configuring the authentication.")
177 clear_ospf(tgen
, "r1")
179 step("Verify that the neighbour is not FULL between R1 and R2.")
181 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
182 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
187 "On R2 enable ospf on interface with simple password authentication "
188 "using ip ospf authentication Simple password cmd."
194 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
198 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
199 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
202 "Verify that the neighbour is FULL between R1 and R2 "
203 "using show ip ospf neighbor cmd."
207 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
208 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
213 "Disable simple password authentication on R2 using no ip ospf "
214 "authentication Simple password cmd."
221 "authentication": True,
222 "authentication-key": "ospf",
229 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
230 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
232 step("Verify on R1 neighbour is deleted for R2 after dead interval expiry")
233 # wait till the dead time expiry
236 ospf_covergence
= verify_ospf_neighbor(
237 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
239 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
243 step("Again On R2 enable ospf on interface with Simple password auth")
247 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
251 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
252 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
255 "Verify that the neighbour is FULL between R1 and R2 using"
256 " show ip ospf neighbor cmd."
260 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
261 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
265 step("Shut no shut interface on R1")
267 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
268 shutdown_bringup_interface(tgen
, dut
, intf
, False)
272 "Verify that the neighbour is not FULL between R1 and R2 using "
273 "show ip ospf neighbor cmd."
275 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
276 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
281 shutdown_bringup_interface(tgen
, dut
, intf
, True)
284 "Verify that the neighbour is FULL between R1 and R2 using "
285 "show ip ospf neighbor cmd."
289 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
290 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
294 step("Change Ip address on R1 and R2")
296 topo_modify_change_ip
= deepcopy(topo
)
297 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
298 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
299 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
300 ) + "/{}".format(intf_ip
.split("/")[1])
302 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
304 reset_config_on_routers(tgen
, routerName
="r1")
306 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
307 shutdown_bringup_interface(tgen
, dut
, intf
, False)
308 shutdown_bringup_interface(tgen
, dut
, intf
, True)
310 # clear ip ospf after configuring the authentication.
311 clear_ospf(tgen
, "r1")
316 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
320 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
321 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
324 "Verify that the neighbour is FULL between R1 and R2 with new "
325 "ip address using show ip ospf "
329 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
330 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
334 write_test_footer(tc_name
)
337 def test_ospf_authentication_md5_tc29_p1(request
):
339 OSPF Authentication - Verify ospf authentication with MD5 authentication.
342 tc_name
= request
.node
.name
343 write_test_header(tc_name
)
346 step("Bring up the base config.")
347 reset_config_on_routers(tgen
)
349 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
350 "connected to R2 with message-digest authentication using ip "
351 "ospf authentication message-digest cmd."
359 "authentication": "message-digest",
360 "authentication-key": "ospf",
361 "message-digest-key": "10",
367 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
368 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
370 step("Verify that the neighbour is not FULL between R1 and R2.")
371 # wait for dead time expiry.
374 ospf_covergence
= verify_ospf_neighbor(
375 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=6
377 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
382 "On R2 enable ospf on interface with message-digest authentication"
383 " using ip ospf authentication message-digest password cmd."
391 "authentication": "message-digest",
392 "authentication-key": "ospf",
393 "message-digest-key": "10",
399 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
400 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
403 "Verify that the neighbour is FULL between R1 and R2 "
404 "using show ip ospf neighbor cmd."
408 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
409 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
414 "Disable message-digest authentication on R2 using no ip ospf "
415 "authentication message-digest password cmd."
423 "authentication": "message-digest",
424 "authentication-key": "ospf",
425 "message-digest-key": "10",
432 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
433 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
435 step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry")
436 # wait till the dead timer expiry
439 ospf_covergence
= verify_ospf_neighbor(
440 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
442 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
446 step("Again On R2 enable ospf on interface with message-digest auth")
452 "authentication": "message-digest",
453 "authentication-key": "ospf",
454 "message-digest-key": "10",
460 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
461 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
464 "Verify that the neighbour is FULL between R1 and R2 using"
465 " show ip ospf neighbor cmd."
469 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
470 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
474 step("Shut no shut interface on R1")
476 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
477 shutdown_bringup_interface(tgen
, dut
, intf
, False)
481 "Verify that the neighbour is not FULL between R1 and R2 using "
482 "show ip ospf neighbor cmd."
484 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
485 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
490 shutdown_bringup_interface(tgen
, dut
, intf
, True)
493 "Verify that the neighbour is FULL between R1 and R2 using "
494 "show ip ospf neighbor cmd."
498 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
499 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
503 step("Change Ip address on R1 and R2")
505 topo_modify_change_ip
= deepcopy(topo
)
507 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
509 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
510 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
511 ) + "/{}".format(intf_ip
.split("/")[1])
513 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
515 reset_config_on_routers(tgen
, routerName
="r1")
517 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
518 shutdown_bringup_interface(tgen
, dut
, intf
, False)
519 shutdown_bringup_interface(tgen
, dut
, intf
, True)
520 clear_ospf(tgen
, "r1")
526 "authentication": "message-digest",
527 "authentication-key": "ospf",
528 "message-digest-key": "10",
534 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
535 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
538 "Verify that the neighbour is FULL between R1 and R2 with new "
539 "ip address using show ip ospf "
543 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
544 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
548 write_test_footer(tc_name
)
551 def test_ospf_authentication_different_auths_tc30_p1(request
):
553 OSPF Authentication - Verify ospf authentication with different
554 authentication methods.
557 tc_name
= request
.node
.name
558 write_test_header(tc_name
)
561 step("Bring up the base config.")
562 reset_config_on_routers(tgen
)
564 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
565 "connected to R2 with message-digest authentication using ip "
566 "ospf authentication message-digest cmd."
574 "authentication": "message-digest",
575 "authentication-key": "ospf",
576 "message-digest-key": "10",
582 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
583 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
585 # wait for dead timer expiry
587 step("Verify that the neighbour is not FULL between R1 and R2.")
589 ospf_covergence
= verify_ospf_neighbor(
590 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
592 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
597 "On R2 enable ospf on interface with message-digest authentication"
598 " using ip ospf authentication message-digest password cmd."
606 "authentication": "message-digest",
607 "authentication-key": "ospf",
608 "message-digest-key": "10",
614 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
615 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
618 "Verify that the neighbour is FULL between R1 and R2 "
619 "using show ip ospf neighbor cmd."
623 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
624 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
628 step(" Delete the configured password on both the routers.")
635 "authentication": "message-digest",
636 "authentication-key": "ospf",
637 "message-digest-key": "10",
644 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
645 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
652 "authentication": "message-digest",
653 "authentication-key": "ospf",
654 "message-digest-key": "10",
661 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
662 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
665 "Verify that the deletion is successful and neighbour is FULL"
666 " between R1 and R2 using show ip ospf neighbor cmd."
670 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
671 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
675 step("Change the authentication type to simple password.")
679 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
683 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
684 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
689 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
693 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
694 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
697 "Verify that the deletion is successful and neighbour is"
698 " FULL between R1 and R2 using show ip "
702 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
703 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
707 step("Change the password in simple password.")
712 "r2": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
716 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
717 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
722 "r1": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
726 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
727 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
730 "Verify that the deletion is successful and neighbour is"
731 " FULL between R1 and R2 using show ip "
735 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
736 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
740 step("Delete the password authentication on the interface ")
747 "authentication": True,
748 "authentication-key": "OSPFv4",
755 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
756 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
763 "authentication": True,
764 "authentication-key": "OSPFv4",
771 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
772 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
775 "Verify that the deletion is successful and neighbour is"
776 " FULL between R1 and R2 using show ip "
780 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
781 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
785 step("Enable Md5 authentication on the interface")
792 "authentication": "message-digest",
793 "authentication-key": "ospf",
794 "message-digest-key": "10",
800 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
801 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
808 "authentication": "message-digest",
809 "authentication-key": "ospf",
810 "message-digest-key": "10",
816 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
817 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
820 "Verify that the neighbour is FULL between R1 and R2 using"
821 " show ip ospf neighbor cmd."
825 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
826 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
830 step("Change the MD5 authentication password")
837 "authentication": "message-digest",
838 "authentication-key": "OSPFv4",
839 "message-digest-key": "10",
845 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
846 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
853 "authentication": "message-digest",
854 "authentication-key": "OSPFv4",
855 "message-digest-key": "10",
861 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
862 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
864 write_test_footer(tc_name
)
867 if __name__
== "__main__":
868 args
= ["-s"] + sys
.argv
[1:]
869 sys
.exit(pytest
.main(args
))