From df61ec9392c23fb68fbdd1355223cc77f6062e48 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 20 Dec 2024 14:15:27 -0300 Subject: [PATCH] topotests: add tests for MSDP eBGP integration Add topology for testing MSDP eBGP integration. Signed-off-by: Rafael Zalamena --- tests/topotests/msdp_topo4/__init__.py | 0 tests/topotests/msdp_topo4/r1/frr.conf | 36 ++++ tests/topotests/msdp_topo4/r2/frr.conf | 39 ++++ tests/topotests/msdp_topo4/r3/frr.conf | 31 +++ tests/topotests/msdp_topo4/r4/frr.conf | 31 +++ tests/topotests/msdp_topo4/test_msdp_topo4.py | 184 ++++++++++++++++++ 6 files changed, 321 insertions(+) create mode 100644 tests/topotests/msdp_topo4/__init__.py create mode 100644 tests/topotests/msdp_topo4/r1/frr.conf create mode 100644 tests/topotests/msdp_topo4/r2/frr.conf create mode 100644 tests/topotests/msdp_topo4/r3/frr.conf create mode 100644 tests/topotests/msdp_topo4/r4/frr.conf create mode 100755 tests/topotests/msdp_topo4/test_msdp_topo4.py diff --git a/tests/topotests/msdp_topo4/__init__.py b/tests/topotests/msdp_topo4/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/msdp_topo4/r1/frr.conf b/tests/topotests/msdp_topo4/r1/frr.conf new file mode 100644 index 000000000000..213981e38b52 --- /dev/null +++ b/tests/topotests/msdp_topo4/r1/frr.conf @@ -0,0 +1,36 @@ +ip forwarding +! +interface r1-eth0 + ip address 192.168.0.1/24 + ip pim +! +interface r1-eth1 + ip address 192.168.1.1/24 + ip pim +! +interface r1-eth2 + ip address 192.168.10.1/24 + ip pim + ip igmp +! +interface lo + ip address 10.254.254.1/32 + ip pim + ip pim use-source 10.254.254.1 +! +router pim + msdp timers 10 20 3 + msdp peer 192.168.0.2 source 192.168.0.1 + msdp peer 192.168.1.2 source 192.168.1.1 + rp 10.254.254.1 + join-prune-interval 5 +! +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.0.2 remote-as 65002 + neighbor 192.168.1.2 remote-as 65003 + address-family ipv4 unicast + redistribute connected + exit-address-family +! \ No newline at end of file diff --git a/tests/topotests/msdp_topo4/r2/frr.conf b/tests/topotests/msdp_topo4/r2/frr.conf new file mode 100644 index 000000000000..6042f39cc34f --- /dev/null +++ b/tests/topotests/msdp_topo4/r2/frr.conf @@ -0,0 +1,39 @@ +ip forwarding +! +bgp send-extra-data zebra +! +interface r2-eth0 + ip address 192.168.0.2/24 + ip pim +! +interface r2-eth1 + ip address 192.168.2.1/24 + ip pim +! +interface r2-eth2 + ip address 192.168.3.2/24 + ip pim +! +interface lo + ip address 10.254.254.2/32 + ip pim + ip pim use-source 10.254.254.2 +! +router pim + msdp timers 10 20 3 + msdp peer 192.168.0.1 source 192.168.0.2 as 65001 + msdp peer 192.168.2.2 source 192.168.2.1 as 65003 + msdp peer 192.168.3.1 source 192.168.3.2 as 65004 + rp 10.254.254.2 + join-prune-interval 5 +! +router bgp 65002 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.0.1 remote-as 65001 + neighbor 192.168.2.2 remote-as 65003 + neighbor 192.168.3.1 remote-as 65004 + address-family ipv4 unicast + redistribute connected + exit-address-family +! \ No newline at end of file diff --git a/tests/topotests/msdp_topo4/r3/frr.conf b/tests/topotests/msdp_topo4/r3/frr.conf new file mode 100644 index 000000000000..f799925b87a6 --- /dev/null +++ b/tests/topotests/msdp_topo4/r3/frr.conf @@ -0,0 +1,31 @@ +ip forwarding +! +interface r3-eth0 + ip address 192.168.1.2/24 + ip pim +! +interface r3-eth1 + ip address 192.168.2.2/24 + ip pim +! +interface lo + ip address 10.254.254.3/32 + ip pim + ip pim use-source 10.254.254.3 +! +router pim + msdp timers 10 20 3 + msdp peer 192.168.1.1 source 192.168.1.2 + msdp peer 192.168.2.1 source 192.168.2.2 + rp 10.254.254.3 + join-prune-interval 5 +! +router bgp 65003 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.1.1 remote-as 65001 + neighbor 192.168.2.1 remote-as 65002 + address-family ipv4 unicast + redistribute connected + exit-address-family +! \ No newline at end of file diff --git a/tests/topotests/msdp_topo4/r4/frr.conf b/tests/topotests/msdp_topo4/r4/frr.conf new file mode 100644 index 000000000000..a7ed2b711477 --- /dev/null +++ b/tests/topotests/msdp_topo4/r4/frr.conf @@ -0,0 +1,31 @@ +ip forwarding +! +debug pim zebra +! +interface r4-eth0 + ip address 192.168.3.1/24 + ip pim +! +interface r4-eth1 + ip address 192.168.20.1/24 + ip pim +! +interface lo + ip address 10.254.254.4/32 + ip pim + ip pim use-source 10.254.254.4 +! +router pim + msdp timers 10 20 3 + msdp peer 192.168.3.2 source 192.168.3.1 + rp 10.254.254.4 + join-prune-interval 5 +! +router bgp 65004 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.3.2 remote-as 65002 + address-family ipv4 unicast + redistribute connected + exit-address-family +! \ No newline at end of file diff --git a/tests/topotests/msdp_topo4/test_msdp_topo4.py b/tests/topotests/msdp_topo4/test_msdp_topo4.py new file mode 100755 index 000000000000..c0f99f72d543 --- /dev/null +++ b/tests/topotests/msdp_topo4/test_msdp_topo4.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_msdp_topo4.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2024 by +# Network Device Education Foundation, Inc. ("NetDEF") +# + +""" +test_msdp_topo4.py: Test the FRR PIM MSDP peer. +""" + +import os +import sys +import json +from functools import partial +import re +import pytest + +# 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 + +# Required to instantiate the topology builder class. +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +from lib.pim import McastTesterHelper + +pytestmark = [pytest.mark.bgpd, pytest.mark.pimd] + +app_helper = McastTesterHelper() + + +def build_topo(tgen): + """ + h1----r1----r2----r4----h2 + | / + | / + | / + r3 + """ + + # Create 4 routers + for routern in range(1, 5): + tgen.add_router(f"r{routern}") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r4"]) + + switch = tgen.add_switch("s5") + tgen.add_host("h1", "192.168.10.100/24", "via 192.168.10.1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["h1"]) + + switch = tgen.add_switch("s6") + tgen.add_host("h2", "192.168.20.100/24", "via 192.168.20.1") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["h2"]) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for _, router in router_list.items(): + file = f"{CWD}/{router.name}/frr.conf" + router.load_frr_config(file) + + # Initialize all routers. + tgen.start_router() + + app_helper.init(tgen) + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + app_helper.cleanup() + tgen.stop_topology() + + +def test_bgp_convergence(): + "Wait for BGP protocol convergence" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_loopback_route(router, iptype, route, proto): + "Wait until route is present on RIB for protocol." + logger.info(f"waiting route {route} in {router}") + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + f"show {iptype} route json", + {route: [{"protocol": proto}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = f'"{router}" convergence failure' + assert result is None, assertmsg + + # Wait for R1 + expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp") + expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp") + expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp") + + # Wait for R2 + expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp") + expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp") + expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp") + + # Wait for R3 + expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp") + expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp") + expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp") + + # Wait for R4 + expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp") + expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp") + expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp") + + +def test_msdp_sa_check(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + MCAST_ADDRESS = "229.1.2.3" + app_helper.run("h1", ["--send=0.7", MCAST_ADDRESS, "h1-eth0"]) + app_helper.run("h2", [MCAST_ADDRESS, "h2-eth0"]) + + def test_r2_mroute(): + r2_expect = { + "229.1.2.3": { + "192.168.10.100": { + "rp": "10.254.254.1", + "local": "no", + } + } + } + out = tgen.gears["r2"].vtysh_cmd("show ip msdp sa json", isjson=True) + return topotest.json_cmp(out, r2_expect) + + logger.info("Waiting for R2 multicast routes") + _, val = topotest.run_and_expect(test_r2_mroute, None, count=55, wait=2) + assert val is None, "multicast route convergence failure" + + +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))