diff options
| author | Rafael Zalamena <rzalamena@users.noreply.github.com> | 2024-12-16 09:57:31 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-16 09:57:31 -0300 |
| commit | 3bebb7be9204a51f194317438aa883f1b10c8646 (patch) | |
| tree | 6e4e508a35f6d03491661b25b645008d8ae7dd5a /tests/topotests/pim_mrib/test_pim_mrib.py | |
| parent | 30467f8f2b3a671973aa4b0aa2bcc1e3a208cc56 (diff) | |
| parent | 06c3436a12226d1f7e18e549f562ba9ecde4b394 (diff) | |
Merge pull request #17252 from nabahr/mcast-mode
Fix PIMD RPF lookup mode and nexthop tracking
Diffstat (limited to 'tests/topotests/pim_mrib/test_pim_mrib.py')
| -rw-r--r-- | tests/topotests/pim_mrib/test_pim_mrib.py | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/tests/topotests/pim_mrib/test_pim_mrib.py b/tests/topotests/pim_mrib/test_pim_mrib.py new file mode 100644 index 0000000000..355c503e3b --- /dev/null +++ b/tests/topotests/pim_mrib/test_pim_mrib.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_pim_mrib.py +# +# Copyright (c) 2024 ATCorp +# Nathan Bahr +# + +import os +import sys +import pytest +from functools import partial + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.pim import ( + verify_pim_rp_info, +) +from lib.common_config import step, write_test_header + +""" +test_pim_mrib.py: Test PIM MRIB overrides and RPF modes +""" + +TOPOLOGY = """ + Test PIM MRIB overrides and RPF modes + + +---+---+ +---+---+ + | | 10.0.0.0/24 | | + + R1 +----------------------+ R2 | + | | .1 .2 | | + +---+---+ r1-eth0 r2-eth0 +---+---+ + .1 | r1-eth1 r2-eth1 | .2 + | | + 10.0.1.0/24 | | 10.0.2.0/24 + | | + .3 | r3-eth0 r4-eth0 | .4 + +---+---+ r3-eth1 r4-eth1 +---+---+ + | | .3 .4 | | + + R3 +----------------------+ R4 | + | | 10.0.3.0/24 | | + +---+---+ +---+---+ +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# Required to instantiate the topology builder class. +pytestmark = [pytest.mark.pimd] + + +def build_topo(tgen): + '''Build function''' + + # Create routers + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_router("r3") + tgen.add_router("r4") + + # Create topology links + tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth0", "r2-eth0") + tgen.add_link(tgen.gears["r1"], tgen.gears["r3"], "r1-eth1", "r3-eth0") + tgen.add_link(tgen.gears["r2"], tgen.gears["r4"], "r2-eth1", "r4-eth0") + tgen.add_link(tgen.gears["r3"], tgen.gears["r4"], "r3-eth1", "r4-eth1") + + +def setup_module(mod): + logger.info("PIM MRIB/RPF functionality:\n {}".format(TOPOLOGY)) + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(mod): + '''Teardown the pytest environment''' + tgen = get_topogen() + tgen.stop_topology() + + +def test_pim_mrib_init(request): + '''Test boot in MRIB-than-URIB with the default MRIB''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Verify rp-info using default URIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth0", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_override(request): + '''Test MRIB override nexthop''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Install a MRIB route that has a shorter prefix length and lower cost. + # In MRIB-than-URIB mode, it should use this route + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + ip mroute 10.0.0.0/16 10.0.3.3 25 + ''' + ) + + step("Verify rp-info using MRIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth1", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_prefix_mode(request): + '''Test longer prefix lookup mode''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Switch to longer prefix match, should switch back to the URIB route + # even with the lower cost, the longer prefix match will win because of the mode + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + router pim + rpf-lookup-mode longer-prefix + ''' + ) + + step("Verify rp-info using URIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth0", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_dist_mode(request): + '''Test lower distance lookup mode''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Switch to lower distance match, should switch back to the MRIB route + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + router pim + rpf-lookup-mode lower-distance + ''' + ) + + step("Verify rp-info using MRIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth1", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_urib_mode(request): + '''Test URIB only lookup mode''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Switch to urib only match, should switch back to the URIB route + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + router pim + rpf-lookup-mode urib-only + ''' + ) + + step("Verify rp-info using URIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth0", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_mrib_mode(request): + '''Test MRIB only lookup mode''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Switch to mrib only match, should switch back to the MRIB route + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + router pim + rpf-lookup-mode mrib-only + ''' + ) + + step("Verify rp-info using MRIB nexthop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "r4-eth1", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_pim_mrib_mrib_mode_no_route(request): + '''Test MRIB only with no route''' + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Remove the MRIB route, in mrib-only mode, it should switch to no path for the RP + tgen.routers()["r4"].vtysh_cmd( + ''' + conf term + no ip mroute 10.0.0.0/16 10.0.3.3 25 + ''' + ) + + step("Verify rp-info with Unknown next hop") + result = verify_pim_rp_info( + tgen, + None, + "r4", + "224.0.0.0/4", + "Unknown", + "10.0.0.1", + "Static", + False, + "ipv4", + True, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + +def test_memory_leak(): + '''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") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) |
