diff options
Diffstat (limited to 'tests/topotests/bgp_community_change_update')
14 files changed, 374 insertions, 0 deletions
diff --git a/tests/topotests/bgp_community_change_update/__init__.py b/tests/topotests/bgp_community_change_update/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/__init__.py diff --git a/tests/topotests/bgp_community_change_update/c1/bgpd.conf b/tests/topotests/bgp_community_change_update/c1/bgpd.conf new file mode 100644 index 0000000..24cf9df --- /dev/null +++ b/tests/topotests/bgp_community_change_update/c1/bgpd.conf @@ -0,0 +1,11 @@ +! +debug bgp updates +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 10.0.1.2 remote-as external + neighbor 10.0.1.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_community_change_update/c1/zebra.conf b/tests/topotests/bgp_community_change_update/c1/zebra.conf new file mode 100644 index 0000000..e3dbbc0 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/c1/zebra.conf @@ -0,0 +1,6 @@ +! +interface c1-eth0 + ip address 10.0.1.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py new file mode 100644 index 0000000..31f033a --- /dev/null +++ b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python + +# Copyright (c) 2020 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +r""" +Reference: https://www.cmand.org/communityexploration + + --y2-- + / | \ + c1 ---- x1 ---- y1 | z1 + \ | / + --y3-- + +1. z1 announces 192.168.255.254/32 to y2, y3. +2. y2 and y3 tags this prefix at ingress with appropriate +communities 65004:2 (y2) and 65004:3 (y3). +3. x1 filters all communities at the egress to c1. +4. Shutdown the link between y1 and y2. +5. y1 will generate a BGP UPDATE message regarding the next-hop change. +6. x1 will generate a BGP UPDATE message regarding community change. + +To avoid sending duplicate BGP UPDATE messages we should make sure +we send only actual route updates. In this example, x1 will skip +BGP UPDATE to c1 because the actual route is the same +(filtered communities - nothing changes). +""" + +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 + +from lib.common_config import step +from time import sleep + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + tgen.add_router("z1") + tgen.add_router("y1") + tgen.add_router("y2") + tgen.add_router("y3") + tgen.add_router("x1") + tgen.add_router("c1") + + # 10.0.1.0/30 + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["c1"]) + switch.add_link(tgen.gears["x1"]) + + # 10.0.2.0/30 + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["x1"]) + switch.add_link(tgen.gears["y1"]) + + # 10.0.3.0/30 + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["y1"]) + switch.add_link(tgen.gears["y2"]) + + # 10.0.4.0/30 + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["y1"]) + switch.add_link(tgen.gears["y3"]) + + # 10.0.5.0/30 + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["y2"]) + switch.add_link(tgen.gears["y3"]) + + # 10.0.6.0/30 + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["y2"]) + switch.add_link(tgen.gears["z1"]) + + # 10.0.7.0/30 + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["y3"]) + switch.add_link(tgen.gears["z1"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (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_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_community_update_path_change(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_converge_initial(): + output = json.loads( + tgen.gears["c1"].vtysh_cmd("show ip bgp neighbor 10.0.1.2 json") + ) + expected = { + "10.0.1.2": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 8}}, + } + } + return topotest.json_cmp(output, expected) + + step("Check if an initial topology is converged") + test_func = functools.partial(_bgp_converge_initial) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see bgp convergence in c1" + + step("Disable link between y1 and y2") + tgen.gears["y1"].run("ip link set dev y1-eth1 down") + + def _bgp_converge_link_disabled(): + output = json.loads(tgen.gears["y1"].vtysh_cmd("show ip bgp nei 10.0.3.2 json")) + expected = {"10.0.3.2": {"bgpState": "Active"}} + return topotest.json_cmp(output, expected) + + step("Check if a topology is converged after a link down between y1 and y2") + test_func = functools.partial(_bgp_converge_link_disabled) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see bgp convergence in y1" + + def _bgp_check_for_duplicate_updates(): + duplicate = False + i = 0 + while i < 5: + if ( + len( + tgen.gears["c1"].run( + 'grep "10.0.1.2(x1) rcvd 192.168.255.254/32 IPv4 unicast...duplicate ignored" bgpd.log' + ) + ) + > 0 + ): + duplicate = True + i += 1 + sleep(0.5) + return duplicate + + step("Check if we see duplicate BGP UPDATE message in c1 (suppress-duplicates)") + assert ( + _bgp_check_for_duplicate_updates() == False + ), "Seen duplicate BGP UPDATE message in c1 from x1" + + step("Disable bgp suppress-duplicates at x1") + tgen.gears["x1"].run( + "vtysh -c 'conf' -c 'router bgp' -c 'no bgp suppress-duplicates'" + ) + + step("Enable link between y1 and y2") + tgen.gears["y1"].run("ip link set dev y1-eth1 up") + + def _bgp_converge_link_enabled(): + output = json.loads(tgen.gears["y1"].vtysh_cmd("show ip bgp nei 10.0.3.2 json")) + expected = { + "10.0.3.2": { + "bgpState": "Established", + "addressFamilyInfo": { + "ipv4Unicast": {"acceptedPrefixCounter": 5, "sentPrefixCounter": 4} + }, + } + } + return topotest.json_cmp(output, expected) + + step("Check if a topology is converged after a link up between y1 and y2") + test_func = functools.partial(_bgp_converge_link_enabled) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see bgp convergence in y1" + + step( + "Check if we see duplicate BGP UPDATE message in c1 (no bgp suppress-duplicates)" + ) + assert ( + _bgp_check_for_duplicate_updates() == True + ), "Didn't see duplicate BGP UPDATE message in c1 from x1" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_community_change_update/x1/bgpd.conf b/tests/topotests/bgp_community_change_update/x1/bgpd.conf new file mode 100644 index 0000000..8d7bcb9 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/x1/bgpd.conf @@ -0,0 +1,20 @@ +! +debug bgp updates +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.1.1 remote-as external + neighbor 10.0.1.1 timers 3 10 + neighbor 10.0.2.2 remote-as external + neighbor 10.0.2.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + neighbor 10.0.1.1 route-map c1 out + exit-address-family +! +bgp community-list standard c1 seq 1 permit 65004:2 +bgp community-list standard c1 seq 2 permit 65004:3 +! +route-map c1 permit 10 + set comm-list c1 delete +! diff --git a/tests/topotests/bgp_community_change_update/x1/zebra.conf b/tests/topotests/bgp_community_change_update/x1/zebra.conf new file mode 100644 index 0000000..8b7c03f --- /dev/null +++ b/tests/topotests/bgp_community_change_update/x1/zebra.conf @@ -0,0 +1,9 @@ +! +interface x1-eth0 + ip address 10.0.1.2/30 +! +interface x1-eth1 + ip address 10.0.2.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_community_change_update/y1/bgpd.conf b/tests/topotests/bgp_community_change_update/y1/bgpd.conf new file mode 100644 index 0000000..a010085 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y1/bgpd.conf @@ -0,0 +1,12 @@ +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 10.0.2.1 remote-as external + neighbor 10.0.2.1 timers 3 10 + neighbor 10.0.3.2 remote-as internal + neighbor 10.0.3.2 timers 3 10 + neighbor 10.0.4.2 remote-as internal + neighbor 10.0.4.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_community_change_update/y1/zebra.conf b/tests/topotests/bgp_community_change_update/y1/zebra.conf new file mode 100644 index 0000000..4096f2a --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y1/zebra.conf @@ -0,0 +1,12 @@ +! +interface y1-eth0 + ip address 10.0.2.2/30 +! +interface y1-eth1 + ip address 10.0.3.1/30 +! +interface y1-eth2 + ip address 10.0.4.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_community_change_update/y2/bgpd.conf b/tests/topotests/bgp_community_change_update/y2/bgpd.conf new file mode 100644 index 0000000..27f1e81 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y2/bgpd.conf @@ -0,0 +1,18 @@ +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 10.0.3.1 remote-as internal + neighbor 10.0.3.1 timers 3 10 + neighbor 10.0.5.2 remote-as internal + neighbor 10.0.5.2 timers 3 10 + neighbor 10.0.6.2 remote-as external + neighbor 10.0.6.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + neighbor 10.0.3.1 route-reflector-client + neighbor 10.0.5.2 route-reflector-client + neighbor 10.0.6.2 route-map z1 in + exit-address-family +! +route-map z1 permit 10 + set community 65004:2 +! diff --git a/tests/topotests/bgp_community_change_update/y2/zebra.conf b/tests/topotests/bgp_community_change_update/y2/zebra.conf new file mode 100644 index 0000000..7e9458a --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y2/zebra.conf @@ -0,0 +1,12 @@ +! +interface y2-eth0 + ip address 10.0.3.2/30 +! +interface y2-eth1 + ip address 10.0.5.1/30 +! +interface y2-eth2 + ip address 10.0.6.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_community_change_update/y3/bgpd.conf b/tests/topotests/bgp_community_change_update/y3/bgpd.conf new file mode 100644 index 0000000..8e57284 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y3/bgpd.conf @@ -0,0 +1,18 @@ +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 10.0.4.1 remote-as internal + neighbor 10.0.4.1 timers 3 10 + neighbor 10.0.5.1 remote-as internal + neighbor 10.0.5.1 timers 3 10 + neighbor 10.0.7.2 remote-as external + neighbor 10.0.7.2 timers 3 10 + address-family ipv4 unicast + redistribute connected + neighbor 10.0.4.1 route-reflector-client + neighbor 10.0.5.1 route-reflector-client + neighbor 10.0.7.2 route-map z1 in + exit-address-family +! +route-map z1 permit 10 + set community 65004:3 +! diff --git a/tests/topotests/bgp_community_change_update/y3/zebra.conf b/tests/topotests/bgp_community_change_update/y3/zebra.conf new file mode 100644 index 0000000..93dd87d --- /dev/null +++ b/tests/topotests/bgp_community_change_update/y3/zebra.conf @@ -0,0 +1,12 @@ +! +interface y3-eth0 + ip address 10.0.4.2/30 +! +interface y3-eth1 + ip address 10.0.5.2/30 +! +interface y3-eth2 + ip address 10.0.7.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_community_change_update/z1/bgpd.conf b/tests/topotests/bgp_community_change_update/z1/bgpd.conf new file mode 100644 index 0000000..2f470f1 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/z1/bgpd.conf @@ -0,0 +1,10 @@ +router bgp 65004 + no bgp ebgp-requires-policy + neighbor 10.0.6.1 remote-as external + neighbor 10.0.6.1 timers 3 10 + neighbor 10.0.7.1 remote-as external + neighbor 10.0.7.1 timers 3 10 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_community_change_update/z1/zebra.conf b/tests/topotests/bgp_community_change_update/z1/zebra.conf new file mode 100644 index 0000000..7f6bbb6 --- /dev/null +++ b/tests/topotests/bgp_community_change_update/z1/zebra.conf @@ -0,0 +1,12 @@ +! +interface lo + ip address 192.168.255.254/32 +! +interface z1-eth0 + ip address 10.0.6.2/30 +! +interface z1-eth1 + ip address 10.0.7.2/30 +! +ip forwarding +! |