diff options
Diffstat (limited to 'tests/topotests/bgp_auth/test_bgp_auth.py')
| -rw-r--r-- | tests/topotests/bgp_auth/test_bgp_auth.py | 447 |
1 files changed, 146 insertions, 301 deletions
diff --git a/tests/topotests/bgp_auth/test_bgp_auth.py b/tests/topotests/bgp_auth/test_bgp_auth.py index b2cdef1c93..f01c7f206a 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth.py +++ b/tests/topotests/bgp_auth/test_bgp_auth.py @@ -40,110 +40,50 @@ test_bgp_auth.py: Test BGP Md5 Authentication setup is 3 routers with 3 links between each each link in a different vrf Default, blue and red respectively Tests check various fiddling with passwords and checking that the peer -establishment is as expected and passwords are not leaked across sockets +establishment is as expected and passwords are not leaked across sockets for bgp instances """ +# pylint: disable=C0413 -import os -import sys import json +import os import platform -from functools import partial -import pytest +import sys from time import sleep -# Save the Current Working Directory to find configuration files. -CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join(CWD, "../")) - -# pylint: disable=C0413 -# Import topogen and topotest helpers -from lib import topotest +import pytest +from lib import common_config, topotest +from lib.common_config import ( + save_initial_config_on_routers, + reset_with_new_configs, +) from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger - -# Required to instantiate the topology builder class. -from mininet.topo import Topo - -from lib.common_config import apply_raw_config - -ERROR_LIST = ["Malformed", "Failure", "Unknown", "Incomplete"] pytestmark = [pytest.mark.bgpd, pytest.mark.ospfd] +CWD = os.path.dirname(os.path.realpath(__file__)) -class InvalidCLIError(Exception): - """Raise when the CLI command is wrong""" - - pass - - -class TemplateTopo(Topo): - "Test topology builder" - - def build(self, *_args, **_opts): - "Build function" - tgen = get_topogen(self) - - # This function only purpose is to define allocation and relationship - # between routers, switches and hosts. - # - # - # Create routers - tgen.add_router("R1") - tgen.add_router("R2") - tgen.add_router("R3") - - # R1-R2 1 - switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R2"]) - - # R1-R3 1 - switch = tgen.add_switch("s2") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R3"]) - - # R2-R3 1 - switch = tgen.add_switch("s3") - switch.add_link(tgen.gears["R2"]) - switch.add_link(tgen.gears["R3"]) - - # R1-R2 2 - switch = tgen.add_switch("s4") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R2"]) - - # R1-R3 2 - switch = tgen.add_switch("s5") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R3"]) - - # R2-R3 2 - switch = tgen.add_switch("s6") - switch.add_link(tgen.gears["R2"]) - switch.add_link(tgen.gears["R3"]) - - # R1-R2 3 - switch = tgen.add_switch("s7") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R2"]) - # R1-R3 2 - switch = tgen.add_switch("s8") - switch.add_link(tgen.gears["R1"]) - switch.add_link(tgen.gears["R3"]) +def build_topo(tgen): + tgen.add_router("R1") + tgen.add_router("R2") + tgen.add_router("R3") - # R2-R3 2 - switch = tgen.add_switch("s9") - switch.add_link(tgen.gears["R2"]) - switch.add_link(tgen.gears["R3"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R2"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R3"]) + tgen.add_link(tgen.gears["R2"], tgen.gears["R3"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R2"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R3"]) + tgen.add_link(tgen.gears["R2"], tgen.gears["R3"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R2"]) + tgen.add_link(tgen.gears["R1"], tgen.gears["R3"]) + tgen.add_link(tgen.gears["R2"], tgen.gears["R3"]) def setup_module(mod): "Sets up the pytest environment" # This function initiates the topology build with Topogen... - tgen = Topogen(TemplateTopo, mod.__name__) + tgen = Topogen(build_topo, mod.__name__) # ... and here it calls Mininet initialization functions. tgen.start_topology() @@ -152,87 +92,84 @@ def setup_module(mod): r3 = tgen.gears["R3"] # blue vrf - r1.run("ip link add blue type vrf table 1001") - r1.run("ip link set up dev blue") - r2.run("ip link add blue type vrf table 1001") - r2.run("ip link set up dev blue") - r3.run("ip link add blue type vrf table 1001") - r3.run("ip link set up dev blue") - - r1.run("ip link add lo1 type dummy") - r1.run("ip link set lo1 master blue") - r1.run("ip link set up dev lo1") - r2.run("ip link add lo1 type dummy") - r2.run("ip link set up dev lo1") - r2.run("ip link set lo1 master blue") - r3.run("ip link add lo1 type dummy") - r3.run("ip link set up dev lo1") - r3.run("ip link set lo1 master blue") - - r1.run("ip link set R1-eth2 master blue") - r1.run("ip link set R1-eth3 master blue") - r2.run("ip link set R2-eth2 master blue") - r2.run("ip link set R2-eth3 master blue") - r3.run("ip link set R3-eth2 master blue") - r3.run("ip link set R3-eth3 master blue") - - r1.run("ip link set up dev R1-eth2") - r1.run("ip link set up dev R1-eth3") - r2.run("ip link set up dev R2-eth2") - r2.run("ip link set up dev R2-eth3") - r3.run("ip link set up dev R3-eth2") - r3.run("ip link set up dev R3-eth3") + r1.cmd_raises("ip link add blue type vrf table 1001") + r1.cmd_raises("ip link set up dev blue") + r2.cmd_raises("ip link add blue type vrf table 1001") + r2.cmd_raises("ip link set up dev blue") + r3.cmd_raises("ip link add blue type vrf table 1001") + r3.cmd_raises("ip link set up dev blue") + + r1.cmd_raises("ip link add lo1 type dummy") + r1.cmd_raises("ip link set lo1 master blue") + r1.cmd_raises("ip link set up dev lo1") + r2.cmd_raises("ip link add lo1 type dummy") + r2.cmd_raises("ip link set up dev lo1") + r2.cmd_raises("ip link set lo1 master blue") + r3.cmd_raises("ip link add lo1 type dummy") + r3.cmd_raises("ip link set up dev lo1") + r3.cmd_raises("ip link set lo1 master blue") + + r1.cmd_raises("ip link set R1-eth2 master blue") + r1.cmd_raises("ip link set R1-eth3 master blue") + r2.cmd_raises("ip link set R2-eth2 master blue") + r2.cmd_raises("ip link set R2-eth3 master blue") + r3.cmd_raises("ip link set R3-eth2 master blue") + r3.cmd_raises("ip link set R3-eth3 master blue") + + r1.cmd_raises("ip link set up dev R1-eth2") + r1.cmd_raises("ip link set up dev R1-eth3") + r2.cmd_raises("ip link set up dev R2-eth2") + r2.cmd_raises("ip link set up dev R2-eth3") + r3.cmd_raises("ip link set up dev R3-eth2") + r3.cmd_raises("ip link set up dev R3-eth3") # red vrf - r1.run("ip link add red type vrf table 1002") - r1.run("ip link set up dev red") - r2.run("ip link add red type vrf table 1002") - r2.run("ip link set up dev red") - r3.run("ip link add red type vrf table 1002") - r3.run("ip link set up dev red") - - r1.run("ip link add lo2 type dummy") - r1.run("ip link set lo2 master red") - r1.run("ip link set up dev lo2") - r2.run("ip link add lo2 type dummy") - r2.run("ip link set up dev lo2") - r2.run("ip link set lo2 master red") - r3.run("ip link add lo2 type dummy") - r3.run("ip link set up dev lo2") - r3.run("ip link set lo2 master red") - - r1.run("ip link set R1-eth4 master red") - r1.run("ip link set R1-eth5 master red") - r2.run("ip link set R2-eth4 master red") - r2.run("ip link set R2-eth5 master red") - r3.run("ip link set R3-eth4 master red") - r3.run("ip link set R3-eth5 master red") - - r1.run("ip link set up dev R1-eth4") - r1.run("ip link set up dev R1-eth5") - r2.run("ip link set up dev R2-eth4") - r2.run("ip link set up dev R2-eth5") - r3.run("ip link set up dev R3-eth4") - r3.run("ip link set up dev R3-eth5") + r1.cmd_raises("ip link add red type vrf table 1002") + r1.cmd_raises("ip link set up dev red") + r2.cmd_raises("ip link add red type vrf table 1002") + r2.cmd_raises("ip link set up dev red") + r3.cmd_raises("ip link add red type vrf table 1002") + r3.cmd_raises("ip link set up dev red") + + r1.cmd_raises("ip link add lo2 type dummy") + r1.cmd_raises("ip link set lo2 master red") + r1.cmd_raises("ip link set up dev lo2") + r2.cmd_raises("ip link add lo2 type dummy") + r2.cmd_raises("ip link set up dev lo2") + r2.cmd_raises("ip link set lo2 master red") + r3.cmd_raises("ip link add lo2 type dummy") + r3.cmd_raises("ip link set up dev lo2") + r3.cmd_raises("ip link set lo2 master red") + + r1.cmd_raises("ip link set R1-eth4 master red") + r1.cmd_raises("ip link set R1-eth5 master red") + r2.cmd_raises("ip link set R2-eth4 master red") + r2.cmd_raises("ip link set R2-eth5 master red") + r3.cmd_raises("ip link set R3-eth4 master red") + r3.cmd_raises("ip link set R3-eth5 master red") + + r1.cmd_raises("ip link set up dev R1-eth4") + r1.cmd_raises("ip link set up dev R1-eth5") + r2.cmd_raises("ip link set up dev R2-eth4") + r2.cmd_raises("ip link set up dev R2-eth5") + r3.cmd_raises("ip link set up dev R3-eth4") + r3.cmd_raises("ip link set up dev R3-eth5") # This is a sample of configuration loading. router_list = tgen.routers() # For all registred routers, load the zebra configuration file for rname, router in router_list.items(): - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) - ) + router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") + router.load_config(TopoRouter.RD_OSPF) + router.load_config(TopoRouter.RD_BGP) - # After loading the configurations, this function loads configured daemons. + # After copying the configurations, this function loads configured daemons. tgen.start_router() + # Save the initial router config. reset_config_on_routers will return to this config. + save_initial_config_on_routers(tgen) + def teardown_module(mod): "Teardown the pytest environment" @@ -282,94 +219,30 @@ def print_diag(vrf): print(router.vtysh_cmd("show bgp {} neighbor".format(vrf_str(vrf)))) -def configure(conf_file): - "configure from a file" - - tgen = get_topogen() - router_list = tgen.routers() - for rname, router in router_list.items(): - with open( - os.path.join(CWD, "{}/{}").format(router.name, conf_file), "r+" - ) as cfg: - new_config = cfg.read() - - output = router.vtysh_multicmd(new_config, pretty_output=False) - for out_err in ERROR_LIST: - if out_err.lower() in output.lower(): - raise InvalidCLIError("%s" % output) - - -def clear_bgp(): - "clear bgp configuration for a vrf" - - tgen = get_topogen() - r1 = tgen.gears["R1"] - r2 = tgen.gears["R2"] - r3 = tgen.gears["R3"] - - r1.vtysh_cmd("conf t\nno router bgp 65001") - r2.vtysh_cmd("conf t\nno router bgp 65002") - r3.vtysh_cmd("conf t\nno router bgp 65003") - r1.vtysh_cmd("conf t\nno router bgp 65001 vrf blue") - r2.vtysh_cmd("conf t\nno router bgp 65002 vrf blue") - r3.vtysh_cmd("conf t\nno router bgp 65003 vrf blue") - r1.vtysh_cmd("conf t\nno router bgp 65001 vrf red") - r2.vtysh_cmd("conf t\nno router bgp 65002 vrf red") - r3.vtysh_cmd("conf t\nno router bgp 65003 vrf red") - - -def configure_bgp(conf_file): - "configure bgp from file" - - clear_bgp() - configure(conf_file) - - -def clear_ospf(): - "clear ospf configuration for a vrf" - - tgen = get_topogen() - router_list = tgen.routers() - for rname, router in router_list.items(): - router.vtysh_cmd("conf t\nno router ospf") - router.vtysh_cmd("conf t\nno router ospf vrf blue") - router.vtysh_cmd("conf t\nno router ospf vrf red") - +@common_config.retry(retry_timeout=190) +def _check_neigh_state(router, peer, state, vrf=""): + "check BGP neighbor state on a router" -def configure_ospf(conf_file): - "configure bgp from file" + neigh_output = router.vtysh_cmd( + "show bgp {} neighbors {} json".format(vrf_str(vrf), peer) + ) - clear_ospf() - configure(conf_file) + peer_state = "Unknown" + neigh_output_json = json.loads(neigh_output) + if peer in neigh_output_json: + peer_state = neigh_output_json[peer]["bgpState"] + if peer_state == state: + return True + return "{} peer with {} expected state {} got {} ".format( + router.name, peer, state, peer_state + ) def check_neigh_state(router, peer, state, vrf=""): "check BGP neighbor state on a router" - count = 0 - matched = False - neigh_output = "" - while count < 125: - if vrf == "": - neigh_output = router.vtysh_cmd("show bgp neighbors {} json".format(peer)) - else: - neigh_output = router.vtysh_cmd( - "show bgp vrf {} neighbors {} json".format(vrf, peer) - ) - neigh_output_json = json.loads(neigh_output) - if peer in neigh_output_json.keys(): - if neigh_output_json[peer]["bgpState"] == state: - matched = True - break - count += 1 - sleep(1) - - assertmsg = "{} could not peer {} state expected {} got {} ".format( - router.name, peer, state, neigh_output_json[peer]["bgpState"] - ) - if matched != True: - print_diag(vrf) - assert matched == True, assertmsg + assertmsg = _check_neigh_state(router, peer, state, vrf) + assert assertmsg is True, assertmsg def check_all_peers_established(vrf=""): @@ -524,213 +397,185 @@ def check_vrf_peer_change_passwords(vrf="", prefix="no"): check_all_peers_established(vrf) -def test_default_peer_established(): +def test_default_peer_established(tgen): "default vrf 3 peers same password" - configure_bgp("bgpd.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd.conf", "ospfd.conf") check_all_peers_established() - # tgen.mininet_cli() -def test_default_peer_remove_passwords(): +def test_default_peer_remove_passwords(tgen): "selectively remove passwords checking state" - configure_bgp("bgpd.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd.conf", "ospfd.conf") check_vrf_peer_remove_passwords() -def test_default_peer_change_passwords(): +def test_default_peer_change_passwords(tgen): "selectively change passwords checking state" - configure_bgp("bgpd.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd.conf", "ospfd.conf") check_vrf_peer_change_passwords() -def test_default_prefix_peer_established(): +def test_default_prefix_peer_established(tgen): "default vrf 3 peers same password with prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_prefix.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd_prefix.conf", "ospfd.conf") check_all_peers_established() - # tgen.mininet_cli() -def test_prefix_peer_remove_passwords(): +def test_prefix_peer_remove_passwords(tgen): "selectively remove passwords checking state with prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_prefix.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd_prefix.conf", "ospfd.conf") check_vrf_peer_remove_passwords(prefix="yes") -def test_prefix_peer_change_passwords(): +def test_prefix_peer_change_passwords(tgen): "selecively change passwords checkig state with prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_prefix.conf") - configure_ospf("ospfd.conf") + reset_with_new_configs(tgen, "bgpd_prefix.conf", "ospfd.conf") check_vrf_peer_change_passwords(prefix="yes") -def test_vrf_peer_established(): +def test_vrf_peer_established(tgen): "default vrf 3 peers same password with VRF config" # clean routers and load vrf config - configure_bgp("bgpd_vrf.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf.conf", "ospfd_vrf.conf") check_all_peers_established("blue") - # tgen.mininet_cli() -def test_vrf_peer_remove_passwords(): +def test_vrf_peer_remove_passwords(tgen): "selectively remove passwords checking state with VRF config" - configure_bgp("bgpd_vrf.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf.conf", "ospfd_vrf.conf") check_vrf_peer_remove_passwords(vrf="blue") -def test_vrf_peer_change_passwords(): +def test_vrf_peer_change_passwords(tgen): "selectively change passwords checking state with VRF config" - configure_bgp("bgpd_vrf.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf.conf", "ospfd_vrf.conf") check_vrf_peer_change_passwords(vrf="blue") -def test_vrf_prefix_peer_established(): +def test_vrf_prefix_peer_established(tgen): "default vrf 3 peers same password with VRF prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_vrf_prefix.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf_prefix.conf", "ospfd_vrf.conf") check_all_peers_established("blue") -def test_vrf_prefix_peer_remove_passwords(): +def test_vrf_prefix_peer_remove_passwords(tgen): "selectively remove passwords checking state with VRF prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_vrf_prefix.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf_prefix.conf", "ospfd_vrf.conf") check_vrf_peer_remove_passwords(vrf="blue", prefix="yes") -def test_vrf_prefix_peer_change_passwords(): +def test_vrf_prefix_peer_change_passwords(tgen): "selectively change passwords checking state with VRF prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_vrf_prefix.conf") - configure_ospf("ospfd_vrf.conf") + reset_with_new_configs(tgen, "bgpd_vrf_prefix.conf", "ospfd_vrf.conf") check_vrf_peer_change_passwords(vrf="blue", prefix="yes") -def test_multiple_vrf_peer_established(): +def test_multiple_vrf_peer_established(tgen): "default vrf 3 peers same password with multiple VRFs" - configure_bgp("bgpd_multi_vrf.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf.conf", "ospfd_multi_vrf.conf") check_all_peers_established("blue") check_all_peers_established("red") - # tgen.mininet_cli() -def test_multiple_vrf_peer_remove_passwords(): +def test_multiple_vrf_peer_remove_passwords(tgen): "selectively remove passwords checking state with multiple VRFs" - configure_bgp("bgpd_multi_vrf.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf.conf", "ospfd_multi_vrf.conf") check_vrf_peer_remove_passwords("blue") check_all_peers_established("red") check_vrf_peer_remove_passwords("red") check_all_peers_established("blue") - # tgen.mininet_cli() -def test_multiple_vrf_peer_change_passwords(): +def test_multiple_vrf_peer_change_passwords(tgen): "selectively change passwords checking state with multiple VRFs" - configure_bgp("bgpd_multi_vrf.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf.conf", "ospfd_multi_vrf.conf") check_vrf_peer_change_passwords("blue") check_all_peers_established("red") check_vrf_peer_change_passwords("red") check_all_peers_established("blue") - # tgen.mininet_cli() -def test_multiple_vrf_prefix_peer_established(): +def test_multiple_vrf_prefix_peer_established(tgen): "default vrf 3 peers same password with multilpe VRFs and prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_multi_vrf_prefix.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf_prefix.conf", "ospfd_multi_vrf.conf") check_all_peers_established("blue") check_all_peers_established("red") - # tgen.mininet_cli() -def test_multiple_vrf_prefix_peer_remove_passwords(): +def test_multiple_vrf_prefix_peer_remove_passwords(tgen): "selectively remove passwords checking state with multiple vrfs and prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_multi_vrf_prefix.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf_prefix.conf", "ospfd_multi_vrf.conf") check_vrf_peer_remove_passwords(vrf="blue", prefix="yes") check_all_peers_established("red") check_vrf_peer_remove_passwords(vrf="red", prefix="yes") check_all_peers_established("blue") - # tgen.mininet_cli() -def test_multiple_vrf_prefix_peer_change_passwords(): +def test_multiple_vrf_prefix_peer_change_passwords(tgen): "selectively change passwords checking state with multiple vrfs and prefix config" # only supported in kernel > 5.3 if topotest.version_cmp(platform.release(), "5.3") < 0: return - configure_bgp("bgpd_multi_vrf_prefix.conf") - configure_ospf("ospfd_multi_vrf.conf") + reset_with_new_configs(tgen, "bgpd_multi_vrf_prefix.conf", "ospfd_multi_vrf.conf") check_vrf_peer_change_passwords(vrf="blue", prefix="yes") check_all_peers_established("red") check_vrf_peer_change_passwords(vrf="red", prefix="yes") check_all_peers_established("blue") - # tgen.mininet_cli() -def test_memory_leak(): +def test_memory_leak(tgen): "Run the memory leak test and report results." - tgen = get_topogen() if not tgen.is_memleak_enabled(): pytest.skip("Memory leak test/report is disabled") |
