From 9fe80cddc0628815cecf87a732d4345fe099e9ea Mon Sep 17 00:00:00 2001 From: Enke Chen Date: Sun, 20 Oct 2024 13:35:12 -0700 Subject: [PATCH] tests: add a topotest bgp_aigp_rr In this topotest, the route reflector advertises a route with the aigp attribute to its client, some with the nexthop unchanged and some with the nexthp changed. Different aigp values are sent to the clients depending on the nexthop setting. Signed-off-by: Enke Chen --- tests/topotests/bgp_aigp_rr/r1/bgpd.conf | 27 ++++ tests/topotests/bgp_aigp_rr/r1/ospfd.conf | 23 ++++ tests/topotests/bgp_aigp_rr/r1/zebra.conf | 13 ++ tests/topotests/bgp_aigp_rr/r2/bgpd.conf | 18 +++ tests/topotests/bgp_aigp_rr/r2/ospfd.conf | 18 +++ tests/topotests/bgp_aigp_rr/r2/zebra.conf | 11 ++ tests/topotests/bgp_aigp_rr/r3/bgpd.conf | 11 ++ tests/topotests/bgp_aigp_rr/r3/ospfd.conf | 18 +++ tests/topotests/bgp_aigp_rr/r3/zebra.conf | 10 ++ tests/topotests/bgp_aigp_rr/r4/bgpd.conf | 11 ++ tests/topotests/bgp_aigp_rr/r4/ospfd.conf | 13 ++ tests/topotests/bgp_aigp_rr/r4/zebra.conf | 7 + .../topotests/bgp_aigp_rr/test_bgp_aigp_rr.py | 128 ++++++++++++++++++ 13 files changed, 308 insertions(+) create mode 100644 tests/topotests/bgp_aigp_rr/r1/bgpd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r1/ospfd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r1/zebra.conf create mode 100644 tests/topotests/bgp_aigp_rr/r2/bgpd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r2/ospfd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r2/zebra.conf create mode 100644 tests/topotests/bgp_aigp_rr/r3/bgpd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r3/ospfd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r3/zebra.conf create mode 100644 tests/topotests/bgp_aigp_rr/r4/bgpd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r4/ospfd.conf create mode 100644 tests/topotests/bgp_aigp_rr/r4/zebra.conf create mode 100644 tests/topotests/bgp_aigp_rr/test_bgp_aigp_rr.py 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 000000000000..90d34bdf8382 --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r1/bgpd.conf @@ -0,0 +1,27 @@ +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 + 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 +! 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 000000000000..b5b43c76bed4 --- /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 000000000000..bf4a3497e836 --- /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 000000000000..97059fdd333f --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/r2/bgpd.conf @@ -0,0 +1,18 @@ +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 + 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 +! 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 000000000000..dd91101d9050 --- /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 000000000000..6e2130f7e829 --- /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 000000000000..b8a36c5ad05a --- /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 000000000000..48702e4e4c65 --- /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 000000000000..ea6663724e9b --- /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 000000000000..b8a36c5ad05a --- /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 000000000000..1d95b2ac2bd6 --- /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 000000000000..d7a7dece2bca --- /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 000000000000..0079535da7ce --- /dev/null +++ b/tests/topotests/bgp_aigp_rr/test_bgp_aigp_rr.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024, Palo Alto Networks, Inc. +# Enke Chen +# + +""" +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) + + + # 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" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args))