From 25a37e936763056a725accedc8fb182f1090f3ad Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 30 Jan 2025 10:34:32 +0200 Subject: [PATCH] tests: Check if aggregated prefix is not advertised to contributing ASes Signed-off-by: Donatas Abraitis --- .../topotests/bgp_reject_as_sets/r2/bgpd.conf | 3 + .../bgp_reject_as_sets/r2/zebra.conf | 3 + .../topotests/bgp_reject_as_sets/r4/bgpd.conf | 6 + .../bgp_reject_as_sets/r4/zebra.conf | 6 + .../test_bgp_reject_as_sets.py | 113 +++++++++++++----- 5 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 tests/topotests/bgp_reject_as_sets/r4/bgpd.conf create mode 100644 tests/topotests/bgp_reject_as_sets/r4/zebra.conf diff --git a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf index 453961762a..f51634d7f2 100644 --- a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf +++ b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf @@ -6,6 +6,9 @@ router bgp 65002 neighbor 192.168.255.2 timers 3 10 neighbor 192.168.254.2 remote-as 65003 neighbor 192.168.254.2 timers 3 10 + neighbor 192.168.253.2 remote-as 65004 + neighbor 192.168.253.2 timers 3 10 + neighbor 192.168.253.2 solo address-family ipv4 unicast aggregate-address 172.16.0.0/16 as-set summary-only exit-address-family diff --git a/tests/topotests/bgp_reject_as_sets/r2/zebra.conf b/tests/topotests/bgp_reject_as_sets/r2/zebra.conf index f0d357c5ff..6112ca545e 100644 --- a/tests/topotests/bgp_reject_as_sets/r2/zebra.conf +++ b/tests/topotests/bgp_reject_as_sets/r2/zebra.conf @@ -5,5 +5,8 @@ interface r2-eth0 interface r2-eth1 ip address 192.168.254.1/30 ! +interface r2-eth2 + ip address 192.168.253.1/30 +! ip forwarding ! diff --git a/tests/topotests/bgp_reject_as_sets/r4/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r4/bgpd.conf new file mode 100644 index 0000000000..957b5ba568 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r4/bgpd.conf @@ -0,0 +1,6 @@ +! +router bgp 65004 + no bgp ebgp-requires-policy + neighbor 192.168.253.1 remote-as 65002 + neighbor 192.168.253.1 timers 3 10 +! diff --git a/tests/topotests/bgp_reject_as_sets/r4/zebra.conf b/tests/topotests/bgp_reject_as_sets/r4/zebra.conf new file mode 100644 index 0000000000..a8c386f39a --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r4/zebra.conf @@ -0,0 +1,6 @@ +! +interface r4-eth0 + ip address 192.168.253.2/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py index b9d8ce6819..141f353bd7 100644 --- a/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py +++ b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py @@ -38,7 +38,7 @@ pytestmark = [pytest.mark.bgpd] def build_topo(tgen): - for routern in range(1, 4): + for routern in range(1, 5): tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") @@ -49,6 +49,10 @@ def build_topo(tgen): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r4"]) + def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) @@ -78,10 +82,12 @@ def test_bgp_reject_as_sets(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - router = tgen.gears["r2"] + r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] - def _bgp_converge(router): - output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) expected = { "192.168.255.2": { "bgpState": "Established", @@ -90,47 +96,88 @@ def test_bgp_reject_as_sets(): } return topotest.json_cmp(output, expected) - def _bgp_has_aggregated_route_with_stripped_as_set(router): - output = json.loads(router.vtysh_cmd("show ip bgp 172.16.0.0/16 json")) + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed bgp convergence at r2" + + def _bgp_has_aggregated_route(): + output = json.loads(r2.vtysh_cmd("show ip bgp 172.16.0.0/16 json")) expected = { - "paths": [{"aspath": {"string": "Local", "segments": [], "length": 0}}] + "paths": [ + { + "aspath": { + "string": "{65001,65003}", + "segments": [{"type": "as-set", "list": [65001, 65003]}], + "length": 1, + }, + "aggregatorAs": 65002, + "aggregatorId": "192.168.255.1", + } + ] } return topotest.json_cmp(output, expected) - def _bgp_announce_route_without_as_sets(router): - output = json.loads( - router.vtysh_cmd( - "show ip bgp neighbor 192.168.254.2 advertised-routes json" - ) - ) + test_func = functools.partial(_bgp_has_aggregated_route) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see an aggregated route at r2" + + def _bgp_announce_route_without_as_sets(): + output = json.loads(r4.vtysh_cmd("show ip bgp 172.16.0.0/16 json")) expected = { - "advertisedRoutes": { - "172.16.0.0/16": {"path": ""}, - "192.168.254.0/30": {"path": "65003"}, - "192.168.255.0/30": {"path": "65001"}, + "paths": [ + { + "aspath": { + "string": "65002", + "segments": [{"type": "as-sequence", "list": [65002]}], + "length": 1, + }, + "aggregatorAs": 65002, + "aggregatorId": "192.168.255.1", + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_announce_route_without_as_sets) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Route 172.16.0.0/16 should be sent without AS_SET to r4" + + def _bgp_filter_aggregated_route_to_contributing_as(): + output = json.loads(r3.vtysh_cmd("show ip bgp json")) + expected = { + "routes": { + "172.16.254.254/32": [ + { + "valid": True, + "bestpath": True, + } + ], + "192.168.254.0/30": [ + { + "valid": True, + "bestpath": True, + }, + { + "valid": True, + }, + ], + "192.168.255.0/30": [ + { + "valid": True, + "bestpath": True, + } + ], }, - "totalPrefixCounter": 3, + "totalRoutes": 3, + "totalPaths": 4, } return topotest.json_cmp(output, expected) - test_func = functools.partial(_bgp_converge, router) + test_func = functools.partial(_bgp_filter_aggregated_route_to_contributing_as) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - - assert result is None, 'Failed bgp convergence in "{}"'.format(router) - - test_func = functools.partial( - _bgp_has_aggregated_route_with_stripped_as_set, router - ) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - - assert result is None, 'Failed to see an aggregated route in "{}"'.format(router) - - test_func = functools.partial(_bgp_announce_route_without_as_sets, router) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert ( result is None - ), 'Route 172.16.0.0/16 should be sent without AS_SET to r3 "{}"'.format(router) + ), "Route 172.16.0.0/16 should NOT be sent to contributing AS (r3)" if __name__ == "__main__":