diff options
author | Abhinay Ramesh <rabhinay@vmware.com> | 2021-06-28 11:47:17 +0200 |
---|---|---|
committer | Abhinay Ramesh <rabhinay@vmware.com> | 2022-02-09 02:57:08 +0100 |
commit | 0afa645317cc51f6213024bd2f15843f791475bd (patch) | |
tree | 08c40a2a9781d2a60be0aeb7a70020d781ab8a4b /tests | |
parent | ospf6d: Enable the feature using configure.ac (diff) | |
download | frr-0afa645317cc51f6213024bd2f15843f791475bd.tar.xz frr-0afa645317cc51f6213024bd2f15843f791475bd.zip |
tests: Added ospf6 authentication trailer topotest
Have added topotest to verify below combination.
Auth support for md5
Auth support for hmac-sha-256
Auth support with keychain for md5
Auth support with keychain for hmac-sha-256
Have sussessfully run all 4 test cases in my local setup.
Signed-off-by: Abhinay Ramesh <rabhinay@vmware.com>
Diffstat (limited to 'tests')
3 files changed, 1630 insertions, 4 deletions
diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 92d29ad1a..8d2bf12af 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -1933,7 +1933,7 @@ def verify_ospf6_interface(tgen, topo=None, dut=None, lan=False, input_dict=None True or False (Error Message) """ - logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name)) + logger.debug("Entering lib API: verify_ospf6_interface") result = False if topo is None: @@ -2311,6 +2311,7 @@ def config_ospf6_interface( ------- True or False """ + logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name)) result = False if topo is None: @@ -2337,6 +2338,7 @@ def config_ospf6_interface( ospf_data = input_dict[router]["links"][lnk]["ospf6"] data_ospf_area = ospf_data.setdefault("area", None) data_ospf_auth = ospf_data.setdefault("hash-algo", None) + data_ospf_keychain = ospf_data.setdefault("keychain", None) data_ospf_dr_priority = ospf_data.setdefault("priority", None) data_ospf_cost = ospf_data.setdefault("cost", None) data_ospf_mtu = ospf_data.setdefault("mtu_ignore", None) @@ -2369,9 +2371,18 @@ def config_ospf6_interface( ospf_data["hash-algo"], ospf_data["key"], ) - if "del_action" in ospf_data: - cmd = "no {}".format(cmd) - config_data.append(cmd) + config_data.append(cmd) + + # interface ospf auth with keychain + if data_ospf_keychain: + cmd = "ipv6 ospf6 authentication" + + if "del_action" in ospf_data: + cmd = "no {}".format(cmd) + + if "keychain" in ospf_data: + cmd = "{} keychain {}".format(cmd, ospf_data["keychain"]) + config_data.append(cmd) # interface ospf dr priority if data_ospf_dr_priority: diff --git a/tests/topotests/ospfv3_basic_functionality/ospfv3_authentication.json b/tests/topotests/ospfv3_basic_functionality/ospfv3_authentication.json new file mode 100644 index 000000000..08ff253b7 --- /dev/null +++ b/tests/topotests/ospfv3_basic_functionality/ospfv3_authentication.json @@ -0,0 +1,169 @@ +{ + "address_types": [ + "ipv6" + ], + "ipv6base": "fd00::", + "ipv6mask": 64, + "link_ip_start": { + "ipv6": "fd00::", + "v6mask": 64 + }, + "lo_prefix": { + "ipv6": "2001:db8:f::", + "v6mask": 128 + }, + "routers": { + "r0": { + "links": { + "r1": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r2": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r3": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + } + }, + "ospf6": { + "router_id": "100.1.1.0", + "neighbors": { + "r1": {}, + "r2": {}, + "r3": {} + }, + "redistribute": [ + { + "redist_type": "static" + }, + { + "redist_type": "connected" + } + ] + } + }, + "r1": { + "links": { + "r0": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r2": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r3": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + } + }, + "ospf6": { + "router_id": "100.1.1.1", + "neighbors": { + "r0": {}, + "r2": {}, + "r3": {} + } + } + }, + "r2": { + "links": { + "r0": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r1": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r3": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + } + }, + "ospf6": { + "router_id": "100.1.1.2", + "neighbors": { + "r1": {}, + "r0": {}, + "r3": {} + } + } + }, + "r3": { + "links": { + "r0": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r1": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + }, + "r2": { + "ipv6": "auto", + "ospf6": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4 + } + } + }, + "ospf6": { + "router_id": "100.1.1.3", + "neighbors": { + "r0": {}, + "r1": {}, + "r2": {} + } + } + } + } +}
\ No newline at end of file diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py new file mode 100644 index 000000000..baa0071f9 --- /dev/null +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py @@ -0,0 +1,1446 @@ +#!/usr/bin/python + +# +# Copyright (c) 2021 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, Inc. +# ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + + +"""OSPF Basic Functionality Automation.""" +import os +import sys +import time +import pytest +from time import sleep +from copy import deepcopy +import json +from lib.topotest import frr_unicode + +pytestmark = pytest.mark.ospf6d + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib.topogen import Topogen, get_topogen + +# Import topoJson from lib, to create topology and initial configuration +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + step, + shutdown_bringup_interface, + topo_daemons, +) +from lib.topolog import logger +from lib.topojson import build_topo_from_json, build_config_from_json +from lib.ospf import verify_ospf6_neighbor, config_ospf6_interface, clear_ospf +from ipaddress import IPv4Address + +# Global variables +topo = None +# Reading the data from JSON File for topology creation +jsonFile = "{}/ospfv3_authentication.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) +""" +TOPOOLOGY = + Please view in a fixed-width font such as Courier. + +---+ A1 +---+ + +R1 +------------+R2 | + +-+-+- +--++ + | -- -- | + | -- A0 -- | + A0| ---- | + | ---- | A2 + | -- -- | + | -- -- | + +-+-+- +-+-+ + +R0 +-------------+R3 | + +---+ A3 +---+ + +TESTCASES = +1. OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 manual key configuration. +2. OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 manual key configuration. +3. OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 keychain configuration. +4. OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 keychain configuration. + + """ + +def setup_module(mod): + """ + Sets up the pytest environment + * `mod`: module name + """ + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + json_file = "{}/ospfv3_single_area.json".format(CWD) + tgen = Topogen(json_file, mod.__name__) + global topo + topo = tgen.json_topo + # ... and here it calls Mininet initialization functions. + + # get list of daemons needs to be started for this suite. + daemons = topo_daemons(tgen, topo) + + # Starting topology, create tmp files which are loaded to routers + # to start deamons and then start routers + start_topology(tgen, daemons) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + ospf6_covergence = verify_ospf6_neighbor(tgen, topo) + assert ospf6_covergence is True, "setup_module :Failed \n Error:" " {}".format( + ospf6_covergence + ) + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment. + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +# ################################## +# Test cases start here. +# ################################## + +def test_ospf6_auth_trailer_tc1_md5(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 manual key configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Disable authentication on R2 " + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + "del_action": True + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry") + # wait till the dead timer expiry + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=5 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Again On R2 enable ospf6 on interface with message-digest auth") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 using" + " show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Shut no shut interface on R1") + dut = "r1" + intf = topo["routers"]["r1"]["links"]["r2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + dut = "r2" + step( + "Verify that the neighbour is not FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + dut = "r1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step( + "Verify that the neighbour is FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + + +def test_ospf6_auth_trailer_tc2_sha256(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 manual key configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Disable authentication on R2 " + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + "del_action": True + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry") + # wait till the dead timer expiry + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=5 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Again On R2 enable ospf6 on interface with message-digest auth") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 using" + " show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Shut no shut interface on R1") + dut = "r1" + intf = topo["routers"]["r1"]["links"]["r2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + dut = "r2" + step( + "Verify that the neighbour is not FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + dut = "r1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step( + "Verify that the neighbour is FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc3_keychain_md5(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 keychain configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + router1.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm md5""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm md5""" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Disable authentication on R2 " + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + "del_action": True + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry") + # wait till the dead timer expiry + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=5 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Again On R2 enable ospf6 on interface with message-digest auth") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 using" + " show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Shut no shut interface on R1") + dut = "r1" + intf = topo["routers"]["r1"]["links"]["r2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + dut = "r2" + step( + "Verify that the neighbour is not FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + dut = "r1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step( + "Verify that the neighbour is FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc4_keychain_sha256(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 keychain configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + router1.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm hmac-sha-256""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm hmac-sha-256""" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Disable authentication on R2 " + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + "del_action": True + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry") + # wait till the dead timer expiry + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=5 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Again On R2 enable ospf6 on interface with message-digest auth") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 using" + " show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step("Shut no shut interface on R1") + dut = "r1" + intf = topo["routers"]["r1"]["links"]["r2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + dut = "r2" + step( + "Verify that the neighbour is not FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + dut = "r1" + shutdown_bringup_interface(tgen, dut, intf, True) + + step( + "Verify that the neighbour is FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc5_md5_keymissmatch(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 manual key configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer wrong key" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6-missmatch", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is not FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + step("Verify that the neighbour is FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer correct key" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "md5", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc6_sha256_mismatch(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 manual key configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 with on R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer wrong key" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6-missmatch", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 with on R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer wrong key" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc7_keychain_md5_missmatch(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using MD5 keychain configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + router1.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm md5""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm md5""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth-missmatch + key 10 + key-string ospf6-missmatch + cryptographic-algorithm md5""" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer with wrong keychain" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth-missmatch", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer with correct keychain" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc8_keychain_sha256_missmatch(request): + """ + OSPFv3 Authentication Trailer - Verify ospfv3 authentication trailer + using HMAC-SHA-256 keychain configuration. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + router1.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm hmac-sha-256""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth + key 10 + key-string ospf6 + cryptographic-algorithm hmac-sha-256""" + ) + + router2.vtysh_cmd( + """configure terminal + key chain auth-missmatch + key 10 + key-string ospf6-missmatch + cryptographic-algorithm hmac-sha-256""" + ) + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer wrong keychain" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth-missmatch", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer correct keychain" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc9_keychain_not_configured(request): + """ + OSPFv3 Neighborship without Authentication Trailer - + Verify ospfv3 neighborship when no authentication trailer is configured. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + step( + "Configure ospf6 between R1 and R2, enable ospf6 auth on R1 interface " + "connected to R2 with auth trailer" + ) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + r1_ospf6_auth = { + "r1": { + "links": { + "r2": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r1" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + step( + "Configure ospf6 between R1 and R2, enable ospf6 on R2 interface " + "connected to R1 with auth trailer non existing keychain" + ) + + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "keychain": "auth", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify that the neighbour is not FULL between R1 and R2.") + # wait for dead time expiry. + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=3 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +def test_ospf6_auth_trailer_tc10_no_auth_trailer(request): + """ + OSPFv3 Neighborship without Authentication Trailer - + Verify ospfv3 neighborship when no authentication trailer is configured. + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + global topo + step("Bring up the base config.") + reset_config_on_routers(tgen) + + router1 = tgen.gears["r1"] + router2 = tgen.gears["r2"] + + step( + "Verify that the neighbour is FULL between R1 and R2 " + "using show ipv6 ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error:" " {}".format( + tc_name, ospf6_covergence + ) + + write_test_footer(tc_name) + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) |