diff options
Diffstat (limited to 'tests')
36 files changed, 975 insertions, 87 deletions
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c index 627ccfee6f..a3acd0786f 100644 --- a/tests/isisd/test_fuzz_isis_tlv.c +++ b/tests/isisd/test_fuzz_isis_tlv.c @@ -22,7 +22,7 @@ static bool atexit_registered; static void show_meminfo_at_exit(void) { - log_memstats(stderr, "isis fuzztest"); + log_memstats(NULL, true); } static int comp_line(const void *p1, const void *p2) diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index e5a8f7a513..9c1ce3d193 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -475,7 +475,7 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); - log_memstats(stderr, "test-isis-spf"); + log_memstats(NULL, true); if (!isexit) exit(0); } diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c index 342a91cc79..5c23a71258 100644 --- a/tests/lib/cli/common_cli.c +++ b/tests/lib/cli/common_cli.c @@ -43,7 +43,7 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); - log_memstats(stderr, "testcli"); + log_memstats(NULL, true); if (!isexit) exit(0); } diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index fdc9e53ca3..3d700d8a19 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -427,7 +427,7 @@ static void vty_do_exit(int isexit) yang_terminate(); event_master_free(master); - log_memstats(stderr, "test-nb-oper-data"); + log_memstats(NULL, true); if (!isexit) exit(0); } diff --git a/tests/lib/test_typelist.c b/tests/lib/test_typelist.c index 070a304335..3ce6683ae5 100644 --- a/tests/lib/test_typelist.c +++ b/tests/lib/test_typelist.c @@ -156,6 +156,6 @@ int main(int argc, char **argv) test_ATOMSORT_UNIQ(); test_ATOMSORT_NONUNIQ(); - log_memstats_stderr("test: "); + log_memstats(NULL, true); return 0; } diff --git a/tests/lib/test_zmq.c b/tests/lib/test_zmq.c index 2cd9d47cb4..5cb518d81a 100644 --- a/tests/lib/test_zmq.c +++ b/tests/lib/test_zmq.c @@ -285,7 +285,7 @@ static void run_server(int syncfd) zmq_close(zmqsock); frrzmq_finish(); event_master_free(master); - log_memstats_stderr("test"); + log_memstats(NULL, true); } int main(void) diff --git a/tests/topotests/bgp_aigp_rr/r1/bgpd.conf b/tests/topotests/bgp_aigp_rr/r1/bgpd.conf new file mode 100644 index 0000000000..4099a248f1 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r1/bgpd.conf @@ -0,0 +1,32 @@ +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + bgp route-reflector allow-outbound-policy + neighbor 10.0.0.2 remote-as internal + neighbor 10.0.0.2 update-source lo + neighbor 10.0.0.2 timers 1 3 + neighbor 10.0.0.2 timers connect 1 + neighbor 10.0.0.2 route-reflector-client + neighbor 10.0.0.3 remote-as internal + neighbor 10.0.0.3 update-source lo + neighbor 10.0.0.3 timers 1 3 + neighbor 10.0.0.3 timers connect 1 + neighbor 10.0.0.3 route-reflector-client + neighbor 10.0.0.4 remote-as internal + neighbor 10.0.0.4 update-source lo + neighbor 10.0.0.4 timers 1 3 + neighbor 10.0.0.4 timers connect 1 + neighbor 10.0.0.4 route-reflector-client + address-family ipv4 + network 10.0.1.2/32 route-map set-aigp + neighbor 10.0.0.4 route-map set-nexthop out + exit-address-family +! +route-map set-nexthop permit 10 + set ip next-hop peer-address +exit +! +route-map set-aigp permit 10 + set aigp 50 + set weight 0 +! diff --git a/tests/topotests/bgp_aigp_rr/r1/ospfd.conf b/tests/topotests/bgp_aigp_rr/r1/ospfd.conf new file mode 100644 index 0000000000..b5b43c76be --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r1/ospfd.conf @@ -0,0 +1,23 @@ +! +interface lo + ip ospf passive +! +interface r1-eth0 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +interface r1-eth1 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +interface r1-eth2 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +router ospf + router-id 10.0.0.1 + network 0.0.0.0/0 area 0 +! diff --git a/tests/topotests/bgp_aigp_rr/r1/zebra.conf b/tests/topotests/bgp_aigp_rr/r1/zebra.conf new file mode 100644 index 0000000000..bf4a3497e8 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r1/zebra.conf @@ -0,0 +1,13 @@ +! +interface lo + ip address 10.0.0.1/32 +! +interface r1-eth0 + ip address 192.168.12.1/24 +! +interface r1-eth1 + ip address 192.168.13.1/24 +! +interface r1-eth2 + ip address 192.168.14.1/24 +! diff --git a/tests/topotests/bgp_aigp_rr/r2/bgpd.conf b/tests/topotests/bgp_aigp_rr/r2/bgpd.conf new file mode 100644 index 0000000000..0159dc8e7c --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r2/bgpd.conf @@ -0,0 +1,22 @@ +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 10.0.0.1 remote-as internal + neighbor 10.0.0.1 update-source lo + neighbor 10.0.0.1 timers 1 3 + neighbor 10.0.0.1 timers connect 1 + address-family ipv4 + redistribute connected route-map connected-to-bgp + network 10.0.1.2/32 route-map set-aigp + neighbor 10.0.0.1 next-hop-self + exit-address-family +! +ip prefix-list p22 seq 5 permit 10.0.2.2/32 +! +route-map connected-to-bgp permit 10 + match ip address prefix-list p22 + set aigp 2 +! +route-map set-aigp permit 10 + set aigp 10 +! diff --git a/tests/topotests/bgp_aigp_rr/r2/ospfd.conf b/tests/topotests/bgp_aigp_rr/r2/ospfd.conf new file mode 100644 index 0000000000..dd91101d90 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r2/ospfd.conf @@ -0,0 +1,18 @@ +! +interface lo + ip ospf passive +! +interface r2-eth0 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +interface r2-eth1 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +router ospf + router-id 10.0.0.2 + network 0.0.0.0/0 area 0 +! diff --git a/tests/topotests/bgp_aigp_rr/r2/zebra.conf b/tests/topotests/bgp_aigp_rr/r2/zebra.conf new file mode 100644 index 0000000000..6e2130f7e8 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r2/zebra.conf @@ -0,0 +1,11 @@ +! +interface lo + ip address 10.0.0.2/32 + ip address 10.0.2.2/32 +! +interface r2-eth0 + ip address 192.168.12.2/24 +! +interface r2-eth1 + ip address 192.168.23.2/24 +! diff --git a/tests/topotests/bgp_aigp_rr/r3/bgpd.conf b/tests/topotests/bgp_aigp_rr/r3/bgpd.conf new file mode 100644 index 0000000000..b8a36c5ad0 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r3/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 10.0.0.1 remote-as internal + neighbor 10.0.0.1 update-source lo + neighbor 10.0.0.1 timers 1 3 + neighbor 10.0.0.1 timers connect 1 + address-family ipv4 + neighbor 10.0.0.1 next-hop-self + exit-address-family +! diff --git a/tests/topotests/bgp_aigp_rr/r3/ospfd.conf b/tests/topotests/bgp_aigp_rr/r3/ospfd.conf new file mode 100644 index 0000000000..48702e4e4c --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r3/ospfd.conf @@ -0,0 +1,18 @@ +! +interface lo + ip ospf passive +! +interface r3-eth0 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +interface r3-eth1 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +router ospf + router-id 10.0.0.3 + network 0.0.0.0/0 area 0 +! diff --git a/tests/topotests/bgp_aigp_rr/r3/zebra.conf b/tests/topotests/bgp_aigp_rr/r3/zebra.conf new file mode 100644 index 0000000000..ea6663724e --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r3/zebra.conf @@ -0,0 +1,10 @@ +! +interface lo + ip address 10.0.0.3/32 +! +interface r3-eth0 + ip address 192.168.13.3/24 +! +interface r3-eth1 + ip address 192.168.23.3/24 +! diff --git a/tests/topotests/bgp_aigp_rr/r4/bgpd.conf b/tests/topotests/bgp_aigp_rr/r4/bgpd.conf new file mode 100644 index 0000000000..b8a36c5ad0 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r4/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 10.0.0.1 remote-as internal + neighbor 10.0.0.1 update-source lo + neighbor 10.0.0.1 timers 1 3 + neighbor 10.0.0.1 timers connect 1 + address-family ipv4 + neighbor 10.0.0.1 next-hop-self + exit-address-family +! diff --git a/tests/topotests/bgp_aigp_rr/r4/ospfd.conf b/tests/topotests/bgp_aigp_rr/r4/ospfd.conf new file mode 100644 index 0000000000..1d95b2ac2b --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r4/ospfd.conf @@ -0,0 +1,13 @@ +! +interface lo + ip ospf passive +! +interface r4-eth0 + ip ospf dead-interval 4 + ip ospf hello-interval 1 + ip ospf cost 10 +! +router ospf + router-id 10.0.0.4 + network 0.0.0.0/0 area 0 +! diff --git a/tests/topotests/bgp_aigp_rr/r4/zebra.conf b/tests/topotests/bgp_aigp_rr/r4/zebra.conf new file mode 100644 index 0000000000..d7a7dece2b --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r4/zebra.conf @@ -0,0 +1,7 @@ +! +interface lo + ip address 10.0.0.4/32 +! +interface r4-eth0 + ip address 192.168.14.4/24 +! diff --git a/tests/topotests/bgp_aigp_rr/test_bgp_aigp_rr.py b/tests/topotests/bgp_aigp_rr/test_bgp_aigp_rr.py new file mode 100644 index 0000000000..206e229b2e --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/test_bgp_aigp_rr.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024, Palo Alto Networks, Inc. +# Enke Chen <enchen@paloaltonetworks.com> +# + +""" +r1, r2, and r3 are directly connectd to each other. +r4 is only connected to r1 directly. + +r1 is the route reflector. +r1 sets the nexthop to itself when advertising routes to r4. + +r2 sources 10.0.2.2/32 with agigp-metric 2. + +Results: + +r1, r2 and r3 should have aigp-meric 2. +r4 should have aigp-metric 12, i.e., aigp + nexthop-metric. +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 5): + tgen.add_router("r{}".format(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["r1"]) + switch.add_link(tgen.gears["r4"]) + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + 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)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_aigp_rr(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] + + def _bgp_check_aigp_metric(router, prefix, aigp): + output = json.loads( + router.vtysh_cmd("show bgp ipv4 unicast {} json".format(prefix)) + ) + expected = {"paths": [{"aigpMetric": aigp, "valid": True}]} + return topotest.json_cmp(output, expected) + + def _bgp_check_aigp_bestpath(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.0.1.2/32 json")) + expected = { + "prefix": "10.0.1.2/32", + "paths": [ + { + "aigpMetric": 50, + "valid": True, + "sourced": True, + "local": True, + "bestpath": {"overall": True, "selectionReason": "Local Route"}, + "nexthops": [ + { + "ip": "0.0.0.0", + "hostname": "r1", + "afi": "ipv4", + "metric": 0, + "accessible": True, + "used": True, + } + ], + }, + { + "aigpMetric": 10, + "valid": True, + "nexthops": [ + { + "ip": "10.0.0.2", + "hostname": "r2", + "afi": "ipv4", + "metric": 10, + "accessible": True, + "used": True, + } + ], + }, + ], + } + return topotest.json_cmp(output, expected) + + # r2, 10.0.2.2/32 with aigp-metric 2 + test_func = functools.partial(_bgp_check_aigp_metric, r2, "10.0.2.2/32", 2) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert result is None, "aigp-metric for 10.0.2.2/32 is not 2" + + # r1, 10.0.2.2/32 with aigp-metric 2 + test_func = functools.partial(_bgp_check_aigp_metric, r1, "10.0.2.2/32", 2) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert result is None, "aigp-metric for 10.0.2.2/32 is not 2" + + # r3, 10.0.2.2/32 with aigp-metric 2 + test_func = functools.partial(_bgp_check_aigp_metric, r3, "10.0.2.2/32", 2) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert result is None, "aigp-metric for 10.0.2.2/32 is not 2" + + # r4, 10.0.2.2/32 with aigp-metric 12: aigp + nexthop-metric + test_func = functools.partial(_bgp_check_aigp_metric, r4, "10.0.2.2/32", 12) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert result is None, "aigp-metric for 10.0.2.2/32 is not 12" + + # r1, check if the local route is favored over AIGP comparison + test_func = functools.partial(_bgp_check_aigp_bestpath) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + assert result is None, "Local route is not favored over AIGP in best-path selection" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf index d0c0813e84..18b312c60f 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf +++ b/tests/topotests/bgp_extended_link_bandwidth/r1/frr.conf @@ -22,7 +22,7 @@ ip prefix-list p200 seq 5 permit 10.10.10.200/32 ! route-map r2 permit 10 match ip address prefix-list p40 - set extcommunity bandwidth 40000 + set extcommunity bandwidth 40000 non-transitive route-map r2 permit 20 match ip address prefix-list p100 set extcommunity bandwidth 100000 diff --git a/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf index 5cad150aef..af07c7cc5c 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf +++ b/tests/topotests/bgp_extended_link_bandwidth/r2/frr.conf @@ -2,9 +2,15 @@ int r2-eth0 ip address 192.168.1.2/24 ! +int r2-eth1 + ip address 192.168.2.2/24 +! router bgp 65000 no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as internal neighbor 192.168.1.1 timers 1 3 neighbor 192.168.1.1 timers connect 1 + neighbor 192.168.2.1 remote-as external + neighbor 192.168.2.1 timers 1 3 + neighbor 192.168.2.1 timers connect 1 ! diff --git a/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf new file mode 100644 index 0000000000..61b13c8893 --- /dev/null +++ b/tests/topotests/bgp_extended_link_bandwidth/r3/frr.conf @@ -0,0 +1,16 @@ +! +int r3-eth0 + ip address 192.168.2.1/24 +! +int r3-eth1 + ip address 192.168.3.1/24 +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.2.2 remote-as external + neighbor 192.168.2.2 timers 1 3 + neighbor 192.168.2.2 timers connect 1 + neighbor 192.168.3.2 remote-as external + neighbor 192.168.3.2 timers 1 3 + neighbor 192.168.3.2 timers connect 1 +! diff --git a/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf b/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf new file mode 100644 index 0000000000..49f0caf7de --- /dev/null +++ b/tests/topotests/bgp_extended_link_bandwidth/r4/frr.conf @@ -0,0 +1,10 @@ +! +int r4-eth0 + ip address 192.168.3.2/24 +! +router bgp 65004 + no bgp ebgp-requires-policy + neighbor 192.168.3.1 remote-as external + neighbor 192.168.3.1 timers 1 3 + neighbor 192.168.3.1 timers connect 1 +! diff --git a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py index e9006b81c9..3e5be0310f 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py +++ b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py @@ -22,7 +22,7 @@ pytestmark = [pytest.mark.bgpd] def setup_module(mod): - topodef = {"s1": ("r1", "r2")} + topodef = {"s1": ("r1", "r2"), "s2": ("r2", "r3"), "s3": ("r3", "r4")} tgen = Topogen(topodef, mod.__name__) tgen.start_topology() @@ -46,9 +46,11 @@ def test_bgp_dynamic_capability_role(): pytest.skip(tgen.errors) r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] - def _bgp_converge(): - output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json detail")) + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast json detail")) expected = { "routes": { "10.10.10.40/32": { @@ -84,9 +86,60 @@ def test_bgp_dynamic_capability_role(): test_func = functools.partial( _bgp_converge, + r2, ) _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert result is None, "Can't see link bandwidths as expected" + assert result is None, "r2 (iBGP) should see link bandwidth extended communities" + + test_func = functools.partial( + _bgp_converge, + r3, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "r3 (eBGP) should see link bandwidth extended communities (including non-transitive)" + + def _bgp_check_non_transitive_extended_communities(): + output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast json detail")) + expected = { + "routes": { + "10.10.10.40/32": { + "paths": [ + { + "extendedIpv6Community": None, + } + ] + }, + "10.10.10.100/32": { + "paths": [ + { + "extendedIpv6Community": { + "string": "LB:65000:12500000000 (100.000 Gbps)", + } + } + ] + }, + "10.10.10.200/32": { + "paths": [ + { + "extendedIpv6Community": { + "string": "LB:65000:25000000000 (200.000 Gbps)", + } + } + ] + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_non_transitive_extended_communities, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "r4 (eBGP) should NOT see non-transitive link bandwidth extended communities" if __name__ == "__main__": diff --git a/tests/topotests/bgp_oad/r1/frr.conf b/tests/topotests/bgp_oad/r1/frr.conf index 39045ba648..f00bdfe7d2 100644 --- a/tests/topotests/bgp_oad/r1/frr.conf +++ b/tests/topotests/bgp_oad/r1/frr.conf @@ -4,6 +4,7 @@ int r1-eth0 ! router bgp 65001 no bgp ebgp-requires-policy + no bgp network import-check neighbor 192.168.1.2 remote-as external neighbor 192.168.1.2 timers 1 3 neighbor 192.168.1.2 timers connect 1 @@ -12,10 +13,14 @@ router bgp 65001 neighbor 192.168.1.4 timers 1 3 neighbor 192.168.1.4 timers connect 1 address-family ipv4 unicast + network 10.10.10.1/32 route-map local neighbor 192.168.1.4 route-map r4 in exit-address-family ! route-map r4 permit 10 set local-preference 123 set metric 123 -exit +! +route-map local permit 10 + set community no-export +! diff --git a/tests/topotests/bgp_oad/test_bgp_oad.py b/tests/topotests/bgp_oad/test_bgp_oad.py index 6dd46fbdaa..b2ea7e0f19 100644 --- a/tests/topotests/bgp_oad/test_bgp_oad.py +++ b/tests/topotests/bgp_oad/test_bgp_oad.py @@ -8,6 +8,8 @@ """ Test if local-preference is passed between different EBGP peers when EBGP-OAD is configured. + +Also check if no-export community is passed to the EBGP-OAD peer. """ import os @@ -51,6 +53,9 @@ def test_bgp_oad(): pytest.skip(tgen.errors) r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] def _bgp_converge(): output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) @@ -85,6 +90,37 @@ def test_bgp_oad(): _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Can't converge" + def _bgp_check_no_export(router, arg=[{"valid": True}]): + output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast json")) + expected = { + "routes": { + "10.10.10.1/32": arg, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_no_export, + r2, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.1/32 should be advertised to r2" + + test_func = functools.partial( + _bgp_check_no_export, + r3, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.1/32 should be advertised to r3" + + test_func = functools.partial( + _bgp_check_no_export, + r4, + None, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.1/32 should not be advertised to r4 (not OAD peer)" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/lib/bmp_collector/bmp.py b/tests/topotests/lib/bmp_collector/bmp.py index f3c0be49c5..ac8af02844 100644 --- a/tests/topotests/lib/bmp_collector/bmp.py +++ b/tests/topotests/lib/bmp_collector/bmp.py @@ -10,11 +10,13 @@ BMP main module: - XXX: more bmp messages types to dissect - XXX: complete bgp message dissection """ -import datetime import ipaddress import json import os import struct +import sys + +from datetime import datetime from bgp.update import BGPUpdate from bgp.update.rd import RouteDistinguisher @@ -48,6 +50,13 @@ def log2file(logs, log_file): f.write(json.dumps(logs) + "\n") +def timestamp_print(message, file=sys.stderr): + """Helper function to timestamp_print messages with timestamps.""" + + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[{current_time}] {message}", file=file) + + # ------------------------------------------------------------------------------ class BMPCodes: """ @@ -196,14 +205,18 @@ class BMPMsg: data = data[msglen:] if version != BMPCodes.VERSION: - # XXX: log something + timestamp_print( + f"Expected BMP version {BMPCodes.VERSION} but got version {version}." + ) return data msg_cls = cls.lookup_msg_type(msgtype) if msg_cls == cls.UNKNOWN_TYPE: - # XXX: log something + timestamp_print(f"Got unknown message type ") return data + timestamp_print(f"Got message type: {msg_cls}") + msg_cls.MSG_LEN = msglen - cls.MIN_LEN logs = msg_cls.dissect(msg_data) logs["seq"] = SEQ @@ -281,7 +294,7 @@ class BMPPerPeerMessage: "peer_distinguisher": str(RouteDistinguisher(peer_distinguisher)), "peer_asn": peer_asn, "peer_bgp_id": peer_bgp_id, - "timestamp": str(datetime.datetime.fromtimestamp(timestamp)), + "timestamp": str(datetime.fromtimestamp(timestamp)), } ) diff --git a/tests/topotests/lib/bmp_collector/bmpserver b/tests/topotests/lib/bmp_collector/bmpserver index 5257df7530..56d85fc74b 100755 --- a/tests/topotests/lib/bmp_collector/bmpserver +++ b/tests/topotests/lib/bmp_collector/bmpserver @@ -5,43 +5,105 @@ # Authored by Farid Mihoub <farid.mihoub@6wind.com> # import argparse + # XXX: something more reliable should be used "Twisted" a great choice. +import signal import socket import sys +from datetime import datetime + from bmp import BMPMsg BGP_MAX_SIZE = 4096 +# Global variable to track shutdown signal +shutdown = False + + parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", type=str, default="0.0.0.0") parser.add_argument("-p", "--port", type=int, default=1789) parser.add_argument("-l", "--logfile", type=str, default="/var/log/bmp.log") + +def handle_signal(signum, frame): + global shutdown + timestamp_print(f"Received signal {signum}, shutting down.") + shutdown = True + + +def timestamp_print(message, file=sys.stderr): + """Helper function to timestamp_print messages with timestamps.""" + + current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"[{current_time}] {message}", file=file) + + def main(): + global shutdown + + # Set up signal handling for SIGTERM and SIGINT + signal.signal(signal.SIGTERM, handle_signal) + signal.signal(signal.SIGINT, handle_signal) + args = parser.parse_args() ADDRESS, PORT = args.address, args.port LOG_FILE = args.logfile + timestamp_print(f"Starting bmpserver on {args.address}:{args.port}") + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind((ADDRESS, PORT)) - s.listen() - connection, _ = s.accept() - try: - while True: - data = connection.recv(BGP_MAX_SIZE) - while len(data) > BMPMsg.MIN_LEN: - data = BMPMsg.dissect(data, log_file=LOG_FILE) + s.bind((ADDRESS, PORT)) + s.listen() + timestamp_print(f"Listening on TCP {args.address}:{args.port}") + + connection, client_address = s.accept() + timestamp_print(f"TCP session opened from {client_address}") + + try: + while not shutdown: # Check for shutdown signal + data = connection.recv(BGP_MAX_SIZE) + if shutdown: + break + + if not data: + # connection closed + break + + timestamp_print( + f"Data received from {client_address}: length {len(data)}" + ) + + while len(data) > BMPMsg.MIN_LEN: + data = BMPMsg.dissect(data, log_file=LOG_FILE) + + timestamp_print( + f"Finished dissecting data from {client_address}" + ) + + except Exception as e: + timestamp_print(f"{e}") + pass + except KeyboardInterrupt: + timestamp_print(f"Got Keyboard Interrupt.") + pass + finally: + timestamp_print(f"TCP session closed with {client_address}") + connection.close() + except socket.error as sock_err: + timestamp_print(f"Socket error: {e}") except Exception as e: - # XXX: do something - pass - except KeyboardInterrupt: - # XXX: do something - pass + timestamp_print(f"{e}") finally: - connection.close() + timestamp_print(f"Server shutting down on {ADDRESS}:{PORT}") + if __name__ == "__main__": - sys.exit(main()) + try: + sys.exit(main()) + except KeyboardInterrupt: + logging.info("BMP server was interrupted and is shutting down.") + sys.exit(0) diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index 14dd61b077..641295258e 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -1273,16 +1273,24 @@ class TopoBMPCollector(TopoHost): return gear def start(self, log_file=None): + log_dir = os.path.join(self.logdir, self.name) + self.run("chmod 777 {}".format(log_dir)) + + log_err = os.path.join(log_dir, "bmpserver.log") + log_arg = "-l {}".format(log_file) if log_file else "" - self.run( - "{}/bmp_collector/bmpserver -a {} -p {} {}&".format( - CWD, self.ip, self.port, log_arg - ), - stdout=None, - ) + + with open(log_err, "w") as err: + self.run( + "{}/bmp_collector/bmpserver -a {} -p {} {}&".format( + CWD, self.ip, self.port, log_arg + ), + stdout=None, + stderr=err, + ) def stop(self): - self.run("pkill -9 -f bmpserver") + self.run("pkill -f bmpserver") return "" diff --git a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf index d0aa3d529f..899e9c0684 100644 --- a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf @@ -5,21 +5,45 @@ log file /tmp/r1-frr.log ! !debug pim packet !debug pim bsm +!debug pimv6 bsm ! -ip route 0.0.0.0/0 10.0.0.4 +! +interface lo + ip address 10.0.0.1/32 + ipv6 address fd00:0:0:0::1/128 + ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r1-eth0 ip address 10.0.0.1/24 + ipv6 address fd00:0:0:0::1/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r1-eth1 ip address 10.0.1.1/24 + ipv6 address fd00:0:0:1::1/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! router pim bsr candidate-bsr priority 200 source address 10.0.0.1 ! +router pim6 + bsr candidate-bsr priority 200 source address fd00:0:0:0::1 +! +router ospf + ospf router-id 10.0.0.1 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.0.1 +! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf index 741c839f19..85af461d5e 100644 --- a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf @@ -3,20 +3,46 @@ hostname r2 password zebra log file /tmp/r2-frr.log ! -ip route 0.0.0.0/0 10.0.0.4 +!debug pim packet +!debug pim bsm +!debug pimv6 bsm +! +interface lo + ip address 10.0.0.2/32 + ipv6 address fd00:0:0:0::2/128 + ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r2-eth0 ip address 10.0.0.2/24 + ipv6 address fd00:0:0:0::2/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r2-eth1 ip address 10.0.2.2/24 + ipv6 address fd00:0:0:2::2/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! router pim - bsr candidate-bsr priority 100 source address 10.0.0.2 + bsr candidate-bsr priority 100 +! +router pim6 + bsr candidate-bsr priority 100 +! +router ospf + ospf router-id 10.0.0.2 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.0.2 ! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf index bd5c8ce93f..022c44ea58 100644 --- a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf @@ -5,28 +5,48 @@ log file /tmp/r3-frr.log ! !debug pim packet !debug pim bsm +!debug pimv6 bsm ! -ip route 0.0.0.0/0 10.0.3.4 -ip route 10.0.6.0/24 10.0.3.6 ! interface r3-eth0 ip address 10.0.1.3/24 + ipv6 address fd00:0:0:1::3/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r3-eth1 ip address 10.0.3.3/24 + ipv6 address fd00:0:0:3::3/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r3-eth2 ip address 10.0.4.3/24 + ipv6 address fd00:0:0:4::3/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! router pim bsr candidate-rp group 239.0.0.0/16 bsr candidate-rp priority 10 source address 10.0.3.3 ! +router pim6 + bsr candidate-rp group ffbb::/64 + bsr candidate-rp priority 10 source address fd00:0:0:3::3 +! +router ospf + ospf router-id 10.0.1.3 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.1.3 +! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf index 825b227728..2d0a035f9a 100644 --- a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf @@ -3,35 +3,64 @@ hostname r4 password zebra log file /tmp/r4-frr.log ! -ip route 10.0.1.0/24 10.0.0.1 -ip route 10.0.4.0/24 10.0.3.3 -ip route 10.0.6.0/24 10.0.3.6 +! +interface lo + ip address 10.0.3.4/32 + ipv6 address fd00:0:0:3::4/64 + ip pim + ipv6 pim ! interface r4-eth0 ip address 10.0.2.4/24 + ipv6 address fd00:0:0:2::4/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r4-eth1 ip address 10.0.3.4/24 + ipv6 address fd00:0:0:3::4/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r4-eth2 ip address 10.0.5.4/24 + ipv6 address fd00:0:0:5::4/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r4-eth3 ip address 10.0.0.4/24 + ipv6 address fd00:0:0:0::4/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! router pim bsr candidate-rp group 239.0.0.0/24 bsr candidate-rp group 239.0.0.0/16 bsr candidate-rp group 239.0.0.0/8 - bsr candidate-rp priority 20 source address 10.0.3.4 + bsr candidate-rp priority 20 +! +router pim6 + bsr candidate-rp group ffbb::/124 + bsr candidate-rp group ffbb::/64 + bsr candidate-rp group ffbb::/108 + bsr candidate-rp priority 20 +! +router ospf + ospf router-id 10.0.2.4 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.2.4 ! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf index c934717d08..552e51f417 100644 --- a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf @@ -3,15 +3,32 @@ hostname r5 password zebra log file /tmp/r5-frr.log ! -ip route 0.0.0.0/0 10.0.4.3 ! interface r5-eth0 ip address 10.0.4.5/24 + ipv6 address fd00:0:0:4::5/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r5-eth1 ip address 10.0.6.5/24 + ipv6 address fd00:0:0:6::5/64 + ip igmp + ip pim + ipv6 pim + ipv6 ospf6 area 0 +! +router pim6 +! +router ospf + ospf router-id 10.0.4.5 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.4.5 ! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf index fd9d1eb5c4..20955a12c7 100644 --- a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf @@ -3,20 +3,40 @@ hostname r6 password zebra log file /tmp/r6-frr.log ! -ip route 0.0.0.0/0 10.0.6.6 ! interface r6-eth0 ip address 10.0.5.6/24 + ipv6 address fd00:0:0:5::6/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r6-eth1 ip address 10.0.6.6/24 + ipv6 address fd00:0:0:6::6/64 + ip igmp + ip pim + ipv6 pim + ipv6 ospf6 area 0 ! interface r6-eth2 ip address 10.0.3.6/24 + ipv6 address fd00:0:0:3::6/64 ip igmp ip pim + ipv6 pim + ipv6 ospf6 area 0 +! +router pim6 +! +router ospf + ospf router-id 10.0.5.6 + network 10.0.0.0/16 area 0 +! +router ospf6 + ospf6 router-id 10.0.5.6 ! ip forwarding +ipv6 forwarding ! diff --git a/tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py b/tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py index ce7bc9dc56..96a3241a2b 100644 --- a/tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py +++ b/tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py @@ -59,7 +59,12 @@ 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] +pytestmark = [ + pytest.mark.pimd, + pytest.mark.pim6d, + pytest.mark.ospfd, + pytest.mark.ospf6d, +] def build_topo(tgen): @@ -102,6 +107,7 @@ def build_topo(tgen): sw1.add_link(tgen.gears["r4"]) sw3.add_link(tgen.gears["r6"]) + def setup_module(mod): logger.info("PIM Candidate RP/BSR:\n {}".format(TOPOLOGY)) @@ -125,6 +131,7 @@ def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() + def test_pim_bsr_election_r1(request): "Test PIM BSR Election" tgen = get_topogen() @@ -137,19 +144,18 @@ def test_pim_bsr_election_r1(request): r2 = tgen.gears["r2"] # r1 should be the BSR winner because it has higher priority expected = { - "bsr":"10.0.0.1", - "priority":200, - "state":"ACCEPT_PREFERRED", + "bsr": "10.0.0.1", + "priority": 200, + "state": "ACCEPT_PREFERRED", } - test_func = partial( - topotest.router_json_cmp, r2, "show ip pim bsr json", expected - ) + test_func = partial(topotest.router_json_cmp, r2, "show ip pim bsr json", expected) _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) assertmsg = "r2: r1 was not elected, bsr election mismatch" assert result is None, assertmsg + def test_pim_bsr_cand_bsr_r1(request): "Test PIM BSR candidate BSR" tgen = get_topogen() @@ -162,11 +168,7 @@ def test_pim_bsr_cand_bsr_r1(request): r2 = tgen.gears["r2"] # r2 is a candidate bsr with low priority: elected = False - expected = { - "address": "10.0.0.2", - "priority": 100, - "elected": False - } + expected = {"address": "10.0.0.2", "priority": 100, "elected": False} test_func = partial( topotest.router_json_cmp, r2, "show ip pim bsr candidate-bsr json", expected ) @@ -175,6 +177,7 @@ def test_pim_bsr_cand_bsr_r1(request): assertmsg = "r2: candidate bsr mismatch " assert result is None, assertmsg + def test_pim_bsr_cand_rp(request): "Test PIM BSR candidate RP" tgen = get_topogen() @@ -187,10 +190,7 @@ def test_pim_bsr_cand_rp(request): r3 = tgen.gears["r3"] # r3 is a candidate rp - expected = { - "address":"10.0.3.3", - "priority":10 - } + expected = {"address": "10.0.3.3", "priority": 10} test_func = partial( topotest.router_json_cmp, r3, "show ip pim bsr candidate-rp json", expected ) @@ -211,29 +211,95 @@ def test_pim_bsr_rp_info(request): # At this point, all nodes, including r5 should have synced the RP state step("Verify rp-info on r5 from BSR") - result = verify_pim_rp_info(tgen, None, "r5", "239.0.0.0/16", None, "10.0.3.3", - "BSR", False, "ipv4", True, retry_timeout = 90) + result = verify_pim_rp_info( + tgen, + None, + "r5", + "239.0.0.0/16", + None, + "10.0.3.3", + "BSR", + False, + "ipv4", + True, + retry_timeout=90, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - result = verify_pim_rp_info(tgen, None, "r5", "239.0.0.0/8", None, "10.0.3.4", - "BSR", False, "ipv4", True, retry_timeout = 30) + result = verify_pim_rp_info( + tgen, + None, + "r5", + "239.0.0.0/8", + None, + "10.0.3.4", + "BSR", + False, + "ipv4", + True, + retry_timeout=30, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - result = verify_pim_rp_info(tgen, None, "r5", "239.0.0.0/24", None, "10.0.3.4", - "BSR", False, "ipv4", True, retry_timeout = 30) + result = verify_pim_rp_info( + tgen, + None, + "r5", + "239.0.0.0/24", + None, + "10.0.3.4", + "BSR", + False, + "ipv4", + True, + retry_timeout=30, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step("Verify rp-info on the BSR node itself r1") - result = verify_pim_rp_info(tgen, None, "r1", "239.0.0.0/16", None, "10.0.3.3", - "BSR", False, "ipv4", True, retry_timeout = 10) + result = verify_pim_rp_info( + tgen, + None, + "r1", + "239.0.0.0/16", + None, + "10.0.3.3", + "BSR", + False, + "ipv4", + True, + retry_timeout=10, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - result = verify_pim_rp_info(tgen, None, "r1", "239.0.0.0/8", None, "10.0.3.4", - "BSR", False, "ipv4", True, retry_timeout = 10) + result = verify_pim_rp_info( + tgen, + None, + "r1", + "239.0.0.0/8", + None, + "10.0.3.4", + "BSR", + False, + "ipv4", + True, + retry_timeout=10, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - result = verify_pim_rp_info(tgen, None, "r1", "239.0.0.0/24", None, "10.0.3.4", - "BSR", False, "ipv4", True, retry_timeout = 10) + result = verify_pim_rp_info( + tgen, + None, + "r1", + "239.0.0.0/24", + None, + "10.0.3.4", + "BSR", + False, + "ipv4", + True, + retry_timeout=10, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) @@ -253,7 +319,8 @@ def test_pim_bsr_election_fallback_r2(request): configure router pim no bsr candidate-bsr priority 200 source address 10.0.0.1 - """) + """ + ) step("Verify r1 is no longer a BSR candidate") expected = {} @@ -269,16 +336,14 @@ def test_pim_bsr_election_fallback_r2(request): r2 = tgen.gears["r2"] # We should fall back to r2 as the BSR expected = { - "bsr":"10.0.0.2", - "priority":100, - "state":"BSR_ELECTED", + "bsr": "10.0.0.2", + "priority": 100, + "state": "BSR_ELECTED", } step("Verify that we fallback to r2 as the new BSR") - test_func = partial( - topotest.router_json_cmp, r2, "show ip pim bsr json", expected - ) + test_func = partial(topotest.router_json_cmp, r2, "show ip pim bsr json", expected) _, result = topotest.run_and_expect(test_func, None, count=180, wait=1) assertmsg = "r2: failed to fallback to r2 as a BSR" @@ -301,12 +366,129 @@ def test_pim_bsr_rp_info_fallback(request): configure router pim no bsr candidate-rp group 239.0.0.0/16 - """) + """ + ) step("Verify falling back to r4 as the new RP for 239.0.0.0/16") - result = verify_pim_rp_info(tgen, None, "r5", "239.0.0.0/16", None, "10.0.3.4", - "BSR", False, "ipv4", True, retry_timeout = 30) + result = verify_pim_rp_info( + tgen, + None, + "r5", + "239.0.0.0/16", + None, + "10.0.3.4", + "BSR", + False, + "ipv4", + True, + retry_timeout=30, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + +def test_pimv6_bsr_election_r1(request): + "Test PIMv6 BSR Election" + 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") + + r2 = tgen.gears["r2"] + # r1 should be the BSR winner because it has higher priority + expected = { + "bsr": "fd00::1", + "priority": 200, + "state": "ACCEPT_PREFERRED", + } + + test_func = partial( + topotest.router_json_cmp, r2, "show ipv6 pim bsr json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + + assertmsg = "r2: r1 was not elected, IPv6 bsr election mismatch" + assert result is None, assertmsg + + +def test_pimv6_bsr_cand_rp(request): + "Test PIMv6 BSR candidate RP" + 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") + + r3 = tgen.gears["r3"] + + # r3 is a candidate rp + expected = {"address": "fd00:0:0:3::3", "priority": 10} + test_func = partial( + topotest.router_json_cmp, r3, "show ipv6 pim bsr candidate-rp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + + assertmsg = "r3: bsr candidate rp mismatch" + assert result is None, assertmsg + + +def test_pimv6_bsr_rp_info(request): + "Test IPv6 RP info state" + 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") + + # At this point, all nodes, including r5 should have synced the RP state + step("Verify rp-info on r5 from BSR") + result = verify_pim_rp_info( + tgen, + None, + "r5", + "ffbb::0/64", + None, + "fd00:0:0:3::3", + "BSR", + False, + "ipv6", + True, + retry_timeout=90, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + result = verify_pim_rp_info( + tgen, + None, + "r5", + "ffbb::0/124", + None, + "fd00:0:0:3::4", + "BSR", + False, + "ipv6", + True, + retry_timeout=30, + ) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + result = verify_pim_rp_info( + tgen, + None, + "r5", + "ffbb::0/108", + None, + "fd00:0:0:3::4", + "BSR", + False, + "ipv6", + True, + retry_timeout=30, + ) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) |
