diff options
Diffstat (limited to 'tests')
199 files changed, 9905 insertions, 472 deletions
diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz Binary files differindex 195a7dd8c1..05e9f723a1 100644 --- a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz +++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz diff --git a/tests/lib/test_ttable.c b/tests/lib/test_ttable.c index 562ddf9d66..7ac0e3516b 100644 --- a/tests/lib/test_ttable.c +++ b/tests/lib/test_ttable.c @@ -20,7 +20,7 @@ int main(int argc, char **argv) assert(tt->nrows == 1); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* add new row with 1 column, assert that it is not added */ assert(ttable_add_row(tt, "%s", "Garbage") == NULL); @@ -28,7 +28,7 @@ int main(int argc, char **argv) assert(tt->nrows == 1); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* add new row, assert that it is added */ assert(ttable_add_row(tt, "%s|%s|%s", "a", "b", "c")); @@ -36,7 +36,7 @@ int main(int argc, char **argv) assert(tt->nrows == 2); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* add empty row, assert that it is added */ assert(ttable_add_row(tt, "||")); @@ -44,7 +44,7 @@ int main(int argc, char **argv) assert(tt->nrows == 3); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* delete 1st row, assert that it is removed */ ttable_del_row(tt, 0); @@ -52,7 +52,7 @@ int main(int argc, char **argv) assert(tt->nrows == 2); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* delete last row, assert that it is removed */ ttable_del_row(tt, 0); @@ -60,7 +60,7 @@ int main(int argc, char **argv) assert(tt->nrows == 1); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* delete the remaining row, check dumping an empty table */ ttable_del_row(tt, 0); @@ -68,7 +68,7 @@ int main(int argc, char **argv) assert(tt->nrows == 0); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* add new row */ ttable_add_row(tt, "%s|%s||%s|%9d", "slick", "black", "triple", 1337); @@ -76,7 +76,7 @@ int main(int argc, char **argv) assert(tt->nrows == 1); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* add bigger row */ ttable_add_row(tt, "%s|%s||%s|%s", @@ -86,7 +86,7 @@ int main(int argc, char **argv) assert(tt->nrows == 2); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* insert new row at beginning */ ttable_insert_row(tt, 0, "%s|%s||%d|%lf", "converting", "vegetarians", @@ -95,7 +95,7 @@ int main(int argc, char **argv) assert(tt->nrows == 3); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* insert new row at end */ ttable_insert_row(tt, tt->nrows - 1, "%s|%s||%d|%ld", "converting", @@ -104,7 +104,7 @@ int main(int argc, char **argv) assert(tt->nrows == 4); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* insert new row at middle */ ttable_insert_row(tt, 1, "%s|%s||%s|%ld", "she", "pioneer", "aki", 1l); @@ -112,7 +112,7 @@ int main(int argc, char **argv) assert(tt->nrows == 5); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* set alignment */ ttable_align(tt, 0, 1, 2, 2, LEFT); @@ -120,14 +120,14 @@ int main(int argc, char **argv) assert(tt->nrows == 5); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); ttable_align(tt, 0, 1, 5, 1, RIGHT); assert(tt->ncols == 5); assert(tt->nrows == 5); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* set padding */ ttable_pad(tt, 0, 1, 1, 1, RIGHT, 2); @@ -135,14 +135,14 @@ int main(int argc, char **argv) assert(tt->nrows == 5); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); ttable_pad(tt, 0, 0, 5, 4, LEFT, 2); assert(tt->ncols == 5); assert(tt->nrows == 5); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* restyle */ tt->style.cell.border.bottom_on = false; @@ -156,13 +156,13 @@ int main(int argc, char **argv) ttable_rowseps(tt, 1, TOP, true, '-'); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* column separators for leftmost column */ ttable_colseps(tt, 0, RIGHT, true, '|'); table = ttable_dump(tt, "\n"); fprintf(stdout, "%s\n", table); - XFREE(MTYPE_TMP, table); + XFREE(MTYPE_TMP_TTABLE, table); /* delete table */ ttable_del(tt); diff --git a/tests/topotests/all_protocol_startup/r1/ip_nht.ref b/tests/topotests/all_protocol_startup/r1/ip_nht.ref index 3592f29b54..2b4363b69e 100644 --- a/tests/topotests/all_protocol_startup/r1/ip_nht.ref +++ b/tests/topotests/all_protocol_startup/r1/ip_nht.ref @@ -1,35 +1,35 @@ VRF default: Resolve via default: on 1.1.1.1 - resolved via static + resolved via static, prefix 1.1.1.1/32 is directly connected, r1-eth1 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.2 - resolved via static + resolved via static, prefix 1.1.1.2/32 is directly connected, r1-eth2 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.3 - resolved via static + resolved via static, prefix 1.1.1.3/32 is directly connected, r1-eth3 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.4 - resolved via static + resolved via static, prefix 1.1.1.4/32 is directly connected, r1-eth4 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.5 - resolved via static + resolved via static, prefix 1.1.1.5/32 is directly connected, r1-eth5 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.6 - resolved via static + resolved via static, prefix 1.1.1.6/32 is directly connected, r1-eth6 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.7 - resolved via static + resolved via static, prefix 1.1.1.7/32 is directly connected, r1-eth7 (vrf default), weight 1 Client list: pbr(fd XX) 1.1.1.8 - resolved via static + resolved via static, prefix 1.1.1.8/32 is directly connected, r1-eth8 (vrf default), weight 1 Client list: pbr(fd XX) 2.2.2.1 @@ -54,19 +54,19 @@ VRF default: unresolved Client list: pbr(fd XX) 192.168.0.2 - resolved via connected + resolved via connected, prefix 192.168.0.0/24 is directly connected, r1-eth0 (vrf default), weight 1 Client list: static(fd XX) 192.168.0.4 - resolved via connected + resolved via connected, prefix 192.168.0.0/24 is directly connected, r1-eth0 (vrf default), weight 1 Client list: static(fd XX) 192.168.7.10 - resolved via connected + resolved via connected, prefix 192.168.7.0/26 is directly connected, r1-eth7 (vrf default), weight 1 Client list: bgp(fd XX) 192.168.7.20(Connected) - resolved via connected + resolved via connected, prefix 192.168.7.0/26 is directly connected, r1-eth7 (vrf default), weight 1 Client list: bgp(fd XX) 192.168.161.4 diff --git a/tests/topotests/all_protocol_startup/r1/ipv6_nht.ref b/tests/topotests/all_protocol_startup/r1/ipv6_nht.ref index 7b71761185..3f03d6fe93 100644 --- a/tests/topotests/all_protocol_startup/r1/ipv6_nht.ref +++ b/tests/topotests/all_protocol_startup/r1/ipv6_nht.ref @@ -1,15 +1,15 @@ VRF default: Resolve via default: on fc00::2 - resolved via connected + resolved via connected, prefix fc00::/64 is directly connected, r1-eth0 (vrf default), weight 1 Client list: static(fd XX) fc00:0:0:8::1000 - resolved via connected + resolved via connected, prefix fc00:0:0:8::/64 is directly connected, r1-eth8 (vrf default), weight 1 Client list: bgp(fd XX) fc00:0:0:8::2000(Connected) - resolved via connected + resolved via connected, prefix fc00:0:0:8::/64 is directly connected, r1-eth8 (vrf default), weight 1 Client list: bgp(fd XX) diff --git a/tests/topotests/bgp_dual_as/__init__.py b/tests/topotests/bgp_dual_as/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_dual_as/__init__.py diff --git a/tests/topotests/bgp_dual_as/r1/frr.conf b/tests/topotests/bgp_dual_as/r1/frr.conf new file mode 100644 index 0000000000..9dcfe05d69 --- /dev/null +++ b/tests/topotests/bgp_dual_as/r1/frr.conf @@ -0,0 +1,11 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 10.0.0.2 remote-as 65002 + neighbor 10.0.0.2 local-as 65001 no-prepend replace-as dual-as + neighbor 10.0.0.2 timers 3 10 + neighbor 10.0.0.2 timers connect 1 +! diff --git a/tests/topotests/bgp_dual_as/r2/frr.conf b/tests/topotests/bgp_dual_as/r2/frr.conf new file mode 100644 index 0000000000..cf5731b601 --- /dev/null +++ b/tests/topotests/bgp_dual_as/r2/frr.conf @@ -0,0 +1,10 @@ +! +interface r2-eth0 + ip address 10.0.0.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.0.1 remote-as 65001 + neighbor 10.0.0.1 timers 3 10 + neighbor 10.0.0.1 timers connect 1 +! diff --git a/tests/topotests/bgp_dual_as/test_bgp_dual_as.py b/tests/topotests/bgp_dual_as/test_bgp_dual_as.py new file mode 100644 index 0000000000..fcac9c94ec --- /dev/null +++ b/tests/topotests/bgp_dual_as/test_bgp_dual_as.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# + +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, get_topogen +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(r2) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + for _, (rname, router) in enumerate(tgen.routers().items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dual_as(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge_65001(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 summary json")) + expected = { + "ipv4Unicast": { + "as": 65000, + "peers": { + "10.0.0.2": { + "hostname": "r2", + "remoteAs": 65002, + "localAs": 65001, + "state": "Established", + "peerState": "OK", + } + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge_65001) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't establish BGP session using local-as AS 65001" + + step("Change remote-as from r2 to use global AS 65000") + r2.vtysh_cmd( + """ + configure terminal + router bgp + neighbor 10.0.0.1 remote-as 65000 + """ + ) + + def _bgp_converge_65000(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 summary json")) + expected = { + "ipv4Unicast": { + "as": 65000, + "peers": { + "10.0.0.2": { + "hostname": "r2", + "remoteAs": 65002, + "localAs": 65000, + "state": "Established", + "peerState": "OK", + } + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge_65000) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't establish BGP session using global AS 65000" + + +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)) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py index 60d959fd1e..5347604250 100755 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py @@ -84,6 +84,9 @@ def test_check_scale_up(): CliOnFail = None # For debugging, uncomment the next line # CliOnFail = 'tgen.mininet_cli' + # Skip test on 32bit platforms (limited memory) + if sys.maxsize <= 2**32: + pytest.skip("skipped because of limited memory on 32bit platforms") CheckFunc = "ltemplateVersionCheck('4.1', iproute2='4.9')" # uncomment next line to start cli *before* script is run # CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')' @@ -94,6 +97,9 @@ def test_check_scale_down(): CliOnFail = None # For debugging, uncomment the next line # CliOnFail = 'tgen.mininet_cli' + # Skip test on 32bit platforms (limited memory) + if sys.maxsize <= 2**32: + pytest.skip("skipped because of limited memory on 32bit platforms") CheckFunc = "ltemplateVersionCheck('4.1', iproute2='4.9')" # uncomment next line to start cli *before* script is run # CheckFunc = 'ltemplateVersionCheck(\'4.1\', cli=True, iproute2=\'4.9\')' diff --git a/tests/topotests/bgp_peer_group_solo/__init__.py b/tests/topotests/bgp_peer_group_solo/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_peer_group_solo/__init__.py diff --git a/tests/topotests/bgp_peer_group_solo/r1/frr.conf b/tests/topotests/bgp_peer_group_solo/r1/frr.conf new file mode 100644 index 0000000000..53959aa134 --- /dev/null +++ b/tests/topotests/bgp_peer_group_solo/r1/frr.conf @@ -0,0 +1,21 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +int r1-eth1 + ip address 192.168.14.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor pg peer-group + neighbor pg remote-as external + neighbor pg solo + neighbor pg timers 1 3 + neighbor pg timers connect 1 + neighbor 192.168.1.2 peer-group pg + neighbor 192.168.1.3 peer-group pg + address-family ipv4 unicast + network 10.0.0.1/32 + exit-address-family +! diff --git a/tests/topotests/bgp_peer_group_solo/r2/frr.conf b/tests/topotests/bgp_peer_group_solo/r2/frr.conf new file mode 100644 index 0000000000..ba99827a47 --- /dev/null +++ b/tests/topotests/bgp_peer_group_solo/r2/frr.conf @@ -0,0 +1,10 @@ +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 +! diff --git a/tests/topotests/bgp_peer_group_solo/r3/frr.conf b/tests/topotests/bgp_peer_group_solo/r3/frr.conf new file mode 100644 index 0000000000..ed06170bf2 --- /dev/null +++ b/tests/topotests/bgp_peer_group_solo/r3/frr.conf @@ -0,0 +1,10 @@ +! +int r3-eth0 + ip address 192.168.1.3/24 +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 +! diff --git a/tests/topotests/bgp_peer_group_solo/test_bgp_peer_group_solo.py b/tests/topotests/bgp_peer_group_solo/test_bgp_peer_group_solo.py new file mode 100644 index 0000000000..cdbc1e02a7 --- /dev/null +++ b/tests/topotests/bgp_peer_group_solo/test_bgp_peer_group_solo.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# + +import os +import re +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, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2", "r3")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_remote_as_auto(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast summary json")) + expected = { + "peers": { + "192.168.1.2": { + "remoteAs": 65002, + "state": "Established", + "peerState": "OK", + }, + "192.168.1.3": { + "remoteAs": 65003, + "state": "Established", + "peerState": "OK", + }, + }, + "totalPeers": 2, + } + + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge initial state" + + def _bgp_update_groups(): + actual = [] + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast update-groups json")) + expected = [ + {"subGroup": [{"adjListCount": 1, "peers": ["192.168.1.2"]}]}, + {"subGroup": [{"adjListCount": 1, "peers": ["192.168.1.3"]}]}, + ] + + # update-group's number can be random and it's not deterministic, + # so we need to normalize the data a bit before checking. + # We care here about the `peers` array only actually. + for updgrp in output["default"].keys(): + actual.append(output["default"][updgrp]) + + return topotest.json_cmp(actual, expected) + + test_func = functools.partial( + _bgp_update_groups, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see separate update-groups" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py index 63f1719e1d..a5232ad694 100644 --- a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py +++ b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py @@ -108,7 +108,7 @@ def test_bgp_set_aspath_exclude(): pytest.skip(tgen.errors) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_1) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed overriding incoming AS-PATH with route-map" @@ -128,7 +128,6 @@ def test_bgp_set_aspath_exclude_access_list(): conf bgp as-path access-list FIRST permit ^65 route-map r2 permit 6 - no set as-path exclude as-path-access-list SECOND set as-path exclude as-path-access-list FIRST """ ) @@ -140,21 +139,20 @@ clear bgp * ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_2) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed change of exclude rule in route map" r1.vtysh_cmd( """ conf route-map r2 permit 6 - no set as-path exclude as-path-access-list FIRST set as-path exclude as-path-access-list SECOND """ ) # tgen.mininet_cli() test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_1) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed reverting exclude rule in route map" @@ -182,7 +180,7 @@ clear bgp * ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to removing current accesslist" @@ -200,7 +198,7 @@ clear bgp * ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_4) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to renegotiate with peers 2" @@ -208,7 +206,7 @@ clear bgp * """ conf route-map r2 permit 6 - no set as-path exclude as-path-access-list SECOND + set as-path exclude 65555 """ ) @@ -219,7 +217,26 @@ clear bgp * ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) - _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, "Failed to renegotiate with peers 2" + + r1.vtysh_cmd( + """ +conf + route-map r2 permit 6 + set as-path exclude as-path-access-list NON-EXISTING + """ + ) + + r1.vtysh_cmd( + """ +clear bgp * + """ + ) + + test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to renegotiate with peers 2" diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py index 2400cd2853..bba0061858 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py @@ -21,7 +21,7 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.common_config import required_linux_kernel_version -from lib.checkping import check_ping, check_ping +from lib.checkping import check_ping pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_vpn_import_nexthop_default_vrf/__init__.py b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/__init__.py diff --git a/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r1/frr.conf b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r1/frr.conf new file mode 100644 index 0000000000..2a2288cf05 --- /dev/null +++ b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r1/frr.conf @@ -0,0 +1,29 @@ +! +interface r1-eth0 + ip address 192.168.179.4/24 +exit +! +router bgp 65001 + bgp router-id 192.168.179.4 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.179.5 remote-as auto +! + address-family ipv4 vpn + neighbor 192.168.179.5 activate + neighbor 192.168.179.5 next-hop-self + exit-address-family +! +router bgp 65001 vrf CUSTOMER-A + bgp router-id 192.168.0.1 + no bgp ebgp-requires-policy + no bgp network import-check +! + address-family ipv4 unicast + label vpn export auto + rd vpn export 100:1 + rt vpn both 100:1 + export vpn + import vpn + exit-address-family +! diff --git a/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r2/frr.conf b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r2/frr.conf new file mode 100644 index 0000000000..6fe07f5622 --- /dev/null +++ b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/r2/frr.conf @@ -0,0 +1,34 @@ +! +interface r2-eth0 + ip address 192.168.179.5/24 +exit +! +interface r2-eth1 + ip address 192.168.2.2/24 +exit +! +router bgp 65002 + bgp router-id 192.168.179.5 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.179.4 remote-as auto +! + address-family ipv4 vpn + neighbor 192.168.179.4 activate + neighbor 192.168.179.4 next-hop-self + exit-address-family +! +router bgp 65002 vrf CUSTOMER-A + bgp router-id 192.168.0.2 + no bgp ebgp-requires-policy + no bgp network import-check +! + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 100:1 + rt vpn both 100:1 + export vpn + import vpn + exit-address-family +! diff --git a/tests/topotests/bgp_vpn_import_nexthop_default_vrf/test_bgp_vpn_import_nexthop_default_vrf.py b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/test_bgp_vpn_import_nexthop_default_vrf.py new file mode 100644 index 0000000000..ccea88b211 --- /dev/null +++ b/tests/topotests/bgp_vpn_import_nexthop_default_vrf/test_bgp_vpn_import_nexthop_default_vrf.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# + +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): + tgen.add_router("r1") + tgen.add_router("r2") + + 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 = tgen.add_switch("s3") + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + r1.run("ip link add CUSTOMER-A type vrf table 1001") + r1.run("ip link set up dev CUSTOMER-A") + r1.run("ip link set r1-eth1 master CUSTOMER-A") + + r2.run("ip link add CUSTOMER-A type vrf table 1001") + r2.run("ip link set up dev CUSTOMER-A") + r2.run("ip link set r2-eth1 master CUSTOMER-A") + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_issue_12502(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp vrf CUSTOMER-A ipv4 unicast json")) + expected = { + "routes": { + "192.168.2.0/24": [ + { + "valid": True, + "pathFrom": "external", + "prefix": "192.168.2.0", + "prefixLen": 24, + "path": "65002", + "nhVrfName": "default", + "nexthops": [ + { + "ip": "192.168.179.5", + "hostname": "r1", + "afi": "ipv4", + "used": True, + } + ], + } + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to see 192.168.2.0/24 with a valid next-hop" + + def _vrf_route_imported_to_zebra(): + output = json.loads( + r1.vtysh_cmd("show ip route vrf CUSTOMER-A 192.168.2.0/24 json") + ) + expected = { + "192.168.2.0/24": [ + { + "prefix": "192.168.2.0/24", + "protocol": "bgp", + "vrfName": "CUSTOMER-A", + "selected": True, + "installed": True, + "table": 1001, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": True, + "ip": "192.168.179.5", + "afi": "ipv4", + "interfaceName": "r1-eth0", + "vrf": "default", + "active": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_vrf_route_imported_to_zebra) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "Failed to see 192.168.2.0/24 to be imported into default VRF (Zebra)" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_init.json b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_init.json index 2769c6eb3f..cb072e3c60 100644 --- a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_init.json +++ b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_init.json @@ -7,6 +7,9 @@ "routes": { "10.204.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.204.0.0", "prefixLen": 24, @@ -63,6 +66,9 @@ ], "10.201.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.201.0.0", "prefixLen": 24, diff --git a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r1_vrf1.json b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r1_vrf1.json index 488dc4aab9..43100aad2d 100644 --- a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r1_vrf1.json +++ b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r1_vrf1.json @@ -7,6 +7,9 @@ "routes": { "10.204.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.204.0.0", "prefixLen": 24, @@ -63,6 +66,9 @@ ], "10.201.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.201.0.0", "prefixLen": 24, diff --git a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf2.json b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf2.json index b751756fce..b11b16bca2 100644 --- a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf2.json +++ b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf2.json @@ -7,6 +7,9 @@ "routes": { "10.204.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.204.0.0", "prefixLen": 24, @@ -63,6 +66,9 @@ ], "10.201.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.201.0.0", "prefixLen": 24, @@ -161,6 +167,9 @@ "routes": { "10.202.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.202.0.0", "prefixLen": 24, diff --git a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf3.json b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf3.json index 49d4066e19..643aae401d 100644 --- a/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf3.json +++ b/tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf3.json @@ -7,6 +7,9 @@ "routes": { "10.204.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.204.0.0", "prefixLen": 24, @@ -63,6 +66,9 @@ ], "10.201.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.201.0.0", "prefixLen": 24, @@ -161,6 +167,9 @@ "routes": { "10.203.0.0/24": [ { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", "pathFrom": "external", "prefix": "10.203.0.0", "prefixLen": 24, diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py index a2315138cc..44536e945e 100755 --- a/tests/topotests/conftest.py +++ b/tests/topotests/conftest.py @@ -18,12 +18,11 @@ from pathlib import Path import lib.fixtures import pytest from lib.common_config import generate_support_bundle -from lib.micronet_compat import Mininet from lib.topogen import diagnose_env, get_topogen from lib.topolog import get_test_logdir, logger from lib.topotest import json_cmp_result from munet import cli -from munet.base import Commander, proc_error +from munet.base import BaseMunet, Commander, proc_error from munet.cleanup import cleanup_current, cleanup_previous from munet.config import ConfigOptionsProxy from munet.testing.util import pause_test @@ -32,7 +31,7 @@ from lib import topolog, topotest try: # Used by munet native tests - from munet.testing.fixtures import event_loop, unet # pylint: disable=all # noqa + from munet.testing.fixtures import unet # pylint: disable=all # noqa @pytest.fixture(scope="module") def rundir_module(pytestconfig): @@ -86,7 +85,7 @@ def pytest_addoption(parser): parser.addoption( "--cli-on-error", action="store_true", - help="Mininet cli on test failure", + help="Munet cli on test failure", ) parser.addoption( @@ -711,7 +710,7 @@ def pytest_runtest_makereport(item, call): wait_for_procs = [] # Really would like something better than using this global here. # Not all tests use topogen though so get_topogen() won't work. - for node in Mininet.g_mnet_inst.hosts.values(): + for node in BaseMunet.g_unet.hosts.values(): pause = True if is_tmux: @@ -720,13 +719,15 @@ def pytest_runtest_makereport(item, call): if not isatty else None ) - Commander.tmux_wait_gen += 1 - wait_for_channels.append(channel) + # If we don't have a tty to pause on pause for tmux windows to exit + if channel is not None: + Commander.tmux_wait_gen += 1 + wait_for_channels.append(channel) pane_info = node.run_in_window( error_cmd, new_window=win_info is None, - background=True, + background=not isatty, title="{} ({})".format(title, node.name), name=title, tmux_target=win_info, @@ -737,9 +738,13 @@ def pytest_runtest_makereport(item, call): win_info = pane_info elif is_xterm: assert isinstance(pane_info, subprocess.Popen) - wait_for_procs.append(pane_info) + # If we don't have a tty to pause on pause for xterm procs to exit + if not isatty: + wait_for_procs.append(pane_info) # Now wait on any channels + if wait_for_channels or wait_for_procs: + logger.info("Pausing for error command windows to exit") for channel in wait_for_channels: logger.debug("Waiting on TMUX channel %s", channel) commander.cmd_raises([commander.get_exec_path("tmux"), "wait", channel]) @@ -752,10 +757,10 @@ def pytest_runtest_makereport(item, call): if error and item.config.option.cli_on_error: # Really would like something better than using this global here. # Not all tests use topogen though so get_topogen() won't work. - if Mininet.g_mnet_inst: - cli.cli(Mininet.g_mnet_inst, title=title, background=False) + if BaseMunet.g_unet: + cli.cli(BaseMunet.g_unet, title=title, background=False) else: - logger.error("Could not launch CLI b/c no mininet exists yet") + logger.error("Could not launch CLI b/c no munet exists yet") if pause and isatty: pause_test() @@ -800,9 +805,20 @@ done""" def pytest_terminal_summary(terminalreporter, exitstatus, config): # Only run if we are the top level test runner is_xdist_worker = "PYTEST_XDIST_WORKER" in os.environ + is_xdist = os.environ["PYTEST_XDIST_MODE"] != "no" if config.option.cov_topotest and not is_xdist_worker: coverage_finish(terminalreporter, config) + if ( + is_xdist + and not is_xdist_worker + and ( + bool(config.getoption("--pause")) + or bool(config.getoption("--pause-at-end")) + ) + ): + pause_test("pause-at-end") + # # Add common fixtures available to all tests as parameters diff --git a/tests/topotests/dump_of_bgp/r1/frr.conf b/tests/topotests/dump_of_bgp/r1/frr.conf new file mode 100644 index 0000000000..d677e2007e --- /dev/null +++ b/tests/topotests/dump_of_bgp/r1/frr.conf @@ -0,0 +1,12 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + neighbor 192.168.1.2 capability dynamic + ! +! diff --git a/tests/topotests/dump_of_bgp/r2/frr.conf b/tests/topotests/dump_of_bgp/r2/frr.conf new file mode 100644 index 0000000000..d68d13d075 --- /dev/null +++ b/tests/topotests/dump_of_bgp/r2/frr.conf @@ -0,0 +1,17 @@ +! +int lo + ip address 10.10.10.10/32 +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 + ! + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/dump_of_bgp/test_dump_of_bgp.py b/tests/topotests/dump_of_bgp/test_dump_of_bgp.py new file mode 100644 index 0000000000..1359c57f31 --- /dev/null +++ b/tests/topotests/dump_of_bgp/test_dump_of_bgp.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by Nvidia Corporation +# Donald Sharp <sharpd@nvidia.com> + +import os +import sys +import json +import pytest +import functools +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +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, get_topogen + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dump(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Test the ability for bgp to dump a file specified") + r1 = tgen.gears["r1"] + + logger.info("Converge BGP") + def _converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + logger.info("Dumping file") + #### + # Create a dump file + #### + r1.vtysh_cmd( + """ + configure terminal + dump bgp all bgp_dump.file + """ + ) + + def _test_dump_file_existence(): + dump_file = "{}/r1/bgp_dump.file".format(tgen.logdir) + + logger.info("Looking for {} file".format(dump_file)) + logger.info(os.path.isfile(dump_file)) + return os.path.isfile(dump_file) + + logger.info("Ensure that Log file exists") + _, result = topotest.run_and_expect(_test_dump_file_existence, True, count=30, wait = 3) + assert result is True + + # At this point all we have done is ensure that the dump file + # is generated for r1. What is correctness of the dump anyways? + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/example_munet/r1/frr.conf b/tests/topotests/example_munet/r1/frr.conf index 468bda5e01..692e4ceb47 100644 --- a/tests/topotests/example_munet/r1/frr.conf +++ b/tests/topotests/example_munet/r1/frr.conf @@ -4,4 +4,4 @@ service integrated-vtysh-config interface eth0 ip address 10.0.1.1/24 -ip route 10.0.0.0/8 blackhole +ip route 10.0.2.0/24 10.0.1.2 diff --git a/tests/topotests/example_munet/r2/frr.conf b/tests/topotests/example_munet/r2/frr.conf index 77d9892485..da3f15b801 100644 --- a/tests/topotests/example_munet/r2/frr.conf +++ b/tests/topotests/example_munet/r2/frr.conf @@ -5,6 +5,4 @@ interface eth0 ip address 10.0.1.2/24 interface eth1 - ip address 10.0.2.2/24 - -ip route 10.0.0.0/8 blackhole + ip address 10.0.2.2/24
\ No newline at end of file diff --git a/tests/topotests/example_munet/r3/frr.conf b/tests/topotests/example_munet/r3/frr.conf index e0839e6d8a..84527b34df 100644 --- a/tests/topotests/example_munet/r3/frr.conf +++ b/tests/topotests/example_munet/r3/frr.conf @@ -4,4 +4,4 @@ service integrated-vtysh-config interface eth0 ip address 10.0.2.3/24 -ip route 10.0.0.0/8 blackhole +ip route 10.0.1.0/24 10.0.2.2
\ No newline at end of file diff --git a/tests/topotests/example_munet/test_munet.py b/tests/topotests/example_munet/test_munet.py index 0d9599fa54..71052099c4 100644 --- a/tests/topotests/example_munet/test_munet.py +++ b/tests/topotests/example_munet/test_munet.py @@ -5,6 +5,22 @@ # # Copyright (c) 2023, LabN Consulting, L.L.C. # +from munet.testing.util import retry + + +@retry(retry_timeout=10) +def wait_for_route(r, p): + o = r.cmd_raises(f"ip route show {p}") + assert p in o + + async def test_native_test(unet): - o = unet.hosts["r1"].cmd_nostatus("ip addr") + r1 = unet.hosts["r1"] + o = r1.cmd_nostatus("ip addr") print(o) + + wait_for_route(r1, "10.0.2.0/24") + + r1.cmd_raises("ping -c1 10.0.1.2") + r1.cmd_raises("ping -c1 10.0.2.2") + r1.cmd_raises("ping -c1 10.0.2.3") diff --git a/tests/topotests/forwarding_on_off/r1/frr.conf b/tests/topotests/forwarding_on_off/r1/frr.conf new file mode 100644 index 0000000000..677ba8f63e --- /dev/null +++ b/tests/topotests/forwarding_on_off/r1/frr.conf @@ -0,0 +1,14 @@ +int lo + ip address 10.1.1.1/32 + ip address 10:1::1:1/128 + +int eth0 + ip address 10.1.2.1/24 + ipv6 address 10:1::2:1/120 + +ip route 10.1.1.2/32 10.1.2.2 +ip route 10.1.1.3/32 10.1.2.2 +ip route 10.1.3.0/24 10.1.2.2 +ipv6 route 10:1::1:2/128 10:1::2:2 +ipv6 route 10:1::1:3/128 10:1::2:2 +ipv6 route 10:1::3:0/90 10:1::2:2
\ No newline at end of file diff --git a/tests/topotests/forwarding_on_off/r2/frr.conf b/tests/topotests/forwarding_on_off/r2/frr.conf new file mode 100644 index 0000000000..b6da6e2231 --- /dev/null +++ b/tests/topotests/forwarding_on_off/r2/frr.conf @@ -0,0 +1,19 @@ +no ip forwarding +no ipv6 forwarding + +int lo + ip address 10.1.1.2/32 + ipv6 address 10:1::1:2/128 + +int eth0 + ip address 10.1.2.2/24 + ipv6 address 10:1::2:2/120 + +int eth1 + ip address 10.1.3.2/24 + ipv6 address 10:1::3:2/120 + +ip route 10.1.1.1/32 10.1.2.1 +ip route 10.1.1.3/32 10.1.3.3 +ipv6 route 10:1::1:1/128 10:1::2:1 +ipv6 route 10:1::1:3/128 10:1::3:3 diff --git a/tests/topotests/forwarding_on_off/r3/frr.conf b/tests/topotests/forwarding_on_off/r3/frr.conf new file mode 100644 index 0000000000..ea05f18400 --- /dev/null +++ b/tests/topotests/forwarding_on_off/r3/frr.conf @@ -0,0 +1,15 @@ +int lo + ip address 10.1.1.3/32 + ipv6 address 10:1::1:3/128 + +int eth0 + ip address 10.1.3.3/24 + ipv6 address 10:1::3:3/120 + + +ip route 10.1.1.1/32 10.1.3.2 +ip route 10.1.1.2/32 10.1.3.2 +ip route 10.1.2.0/24 10.1.3.2 +ipv6 route 10:1::1:1/128 10:1::3:2 +ipv6 route 10:1::1:2/128 10:1::3:2 +ipv6 route 10:1::2:0/120 10:1::3:2
\ No newline at end of file diff --git a/tests/topotests/forwarding_on_off/test_forwarding_on_off.py b/tests/topotests/forwarding_on_off/test_forwarding_on_off.py new file mode 100644 index 0000000000..fa0483888c --- /dev/null +++ b/tests/topotests/forwarding_on_off/test_forwarding_on_off.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# test_forwarding_on_off.py +# +# Copyright (c) 2024 by Nvidia Corporation +# Donald Sharp +# + +""" +test_forwarding_on_off.py: Test that forwarding is turned off then back on + +""" + +import ipaddress +import json +import pytest +import sys +import time + +from functools import partial +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.checkping import check_ping + +pytestmark = [ + pytest.mark.staticd, +] + + +def build_topo(tgen): + """Build the topology used by all tests below.""" + + # Create 3 routers + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + r3 = tgen.add_router("r3") + + # Add a link between r1 <-> r2 and r2 <-> r3 + tgen.add_link(r1, r2, ifname1="eth0", ifname2="eth0") + tgen.add_link(r2, r3, ifname1="eth1", ifname2="eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, router in router_list.items(): + router.load_frr_config("frr.conf") + + tgen.start_router() + + +def teardown_module(): + tgen = get_topogen() + tgen.stop_topology() + + +def test_no_forwarding(): + tgen = get_topogen() + r2 = tgen.gears["r2"] + + def _no_forwarding(family, status): + logger.info("Testing for: {} {}".format(family, status)) + rc, o, e = r2.net.cmd_status( + 'vtysh -c "show zebra" | grep "{}" | grep "{}"'.format(family, status) + ) + + logger.info("Output: {}".format(o)) + return rc + + test_func = partial(_no_forwarding, "v4 Forwarding", "Off") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + test_func = partial(_no_forwarding, "v6 Forwarding", "Off") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + logger.info("Sending pings that should fail") + check_ping("r1", "10.1.1.3", False, 10, 1) + check_ping("r1", "10:1::1:3", False, 10, 1) + + logger.info("Turning on Forwarding") + r2.vtysh_cmd("conf\nip forwarding\nipv6 forwarding") + + test_func = partial(_no_forwarding, "v4 Forwarding", "On") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + test_func = partial(_no_forwarding, "v6 Forwarding", "On") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + check_ping("r1", "10.1.1.3", True, 10, 1) + check_ping("r1", "10:1::1:3", True, 10, 1) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index a574f43d89..1cec2f16f0 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -623,7 +623,7 @@ def test_isis_hello_padding_during_adjacency_formation(): assert result is True, result -@retry(retry_timeout=5) +@retry(retry_timeout=10) def check_last_iih_packet_for_padding(router, expect_padding): logfilename = "{}/{}".format(router.gearlogdir, "isisd.log") last_hello_packet_line = None diff --git a/tests/topotests/kinds.yaml b/tests/topotests/kinds.yaml index 5f4b61d4b7..20c819c79c 100644 --- a/tests/topotests/kinds.yaml +++ b/tests/topotests/kinds.yaml @@ -10,9 +10,10 @@ kinds: /usr/lib/frr/frrinit.sh stop volumes: - "./%NAME%:/etc/frr" + - "%RUNDIR%/var.lib.frr:/var/lib/frr" - "%RUNDIR%/var.log.frr:/var/log/frr" - "%RUNDIR%/var.run.frr:/var/run/frr" - - "%RUNDIR%/var.lib.frr:/var/lib/frr" + - "%RUNDIR%/var.tmp.frr:/var/tmp/frr" cap-add: - SYS_ADMIN - AUDIT_WRITE diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index e856c23d36..cb71112af3 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -936,7 +936,7 @@ def generate_support_bundle(): tgen = get_topogen() if tgen is None: - logger.warn( + logger.warning( "Support bundle attempted to be generated, but topogen is not being used" ) return True @@ -1847,7 +1847,13 @@ def retry(retry_timeout, initial_wait=0, expected=True, diag_pct=0.75): while True: seconds_left = (retry_until - datetime.now()).total_seconds() try: - ret = func(*args, **kwargs) + try: + ret = func(*args, seconds_left=seconds_left, **kwargs) + except TypeError as error: + if "seconds_left" not in str(error): + raise + ret = func(*args, **kwargs) + logger.debug("Function returned %s", ret) negative_result = ret is False or is_string(ret) @@ -1868,7 +1874,7 @@ def retry(retry_timeout, initial_wait=0, expected=True, diag_pct=0.75): return saved_failure except Exception as error: - logger.info("Function raised exception: %s", str(error)) + logger.info('Function raised exception: "%s"', repr(error)) ret = error if seconds_left < 0 and saved_failure: diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index 71e36b6229..eb3723be42 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -1607,7 +1607,7 @@ def verify_pim_rp_info( if type(group_addresses) is not list: group_addresses = [group_addresses] - if type(oif) is not list: + if oif is not None and type(oif) is not list: oif = [oif] for grp in group_addresses: diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index f49e30ea5f..7941e5c1d2 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -832,10 +832,10 @@ class TopoRouter(TopoGear): for daemon in self.RD: # This will not work for all daemons daemonstr = self.RD.get(daemon).rstrip("d") - if daemonstr == "pim": - grep_cmd = "grep 'ip {}' {}".format(daemonstr, source_path) + if daemonstr == "path": + grep_cmd = "grep 'candidate-path' {}".format(source_path) else: - grep_cmd = "grep 'router {}' {}".format(daemonstr, source_path) + grep_cmd = "grep -w '{}' {}".format(daemonstr, source_path) result = self.run(grep_cmd, warn=False).strip() if result: self.load_config(daemon, "") diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 5a8c2e5964..d15fefc039 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -396,6 +396,9 @@ def run_and_expect(func, what, count=20, wait=3): waiting `wait` seconds between tries. By default it tries 20 times with 3 seconds delay between tries. + Changing default count/wait values, please change them below also for + `minimum_wait`, and `minimum_count`. + Returns (True, func-return) on success or (False, func-return) on failure. @@ -414,13 +417,18 @@ def run_and_expect(func, what, count=20, wait=3): # Just a safety-check to avoid running topotests with very # small wait/count arguments. + # If too low count/wait values are defined, override them + # with the minimum values. + minimum_count = 20 + minimum_wait = 3 + minimum_wait_time = 15 # The overall minimum seconds for the test to wait wait_time = wait * count - if wait_time < 5: - assert ( - wait_time >= 5 - ), "Waiting time is too small (count={}, wait={}), adjust timer values".format( - count, wait + if wait_time < minimum_wait_time: + logger.warning( + f"Waiting time is too small (count={count}, wait={wait}), using default values (count={minimum_count}, wait={minimum_wait})" ) + count = minimum_count + wait = minimum_wait logger.debug( "'{}' polling started (interval {} secs, maximum {} tries)".format( diff --git a/tests/topotests/mgmt_oper/oper.py b/tests/topotests/mgmt_oper/oper.py index 9fc504569d..f54e64ae18 100644 --- a/tests/topotests/mgmt_oper/oper.py +++ b/tests/topotests/mgmt_oper/oper.py @@ -63,7 +63,7 @@ def disable_debug(router): @retry(retry_timeout=30, initial_wait=1) -def _do_oper_test(tgen, qr): +def _do_oper_test(tgen, qr, seconds_left=None): r1 = tgen.gears["r1"].net qcmd = ( @@ -80,6 +80,8 @@ def _do_oper_test(tgen, qr): expected = open(qr[1], encoding="ascii").read() output = r1.cmd_nostatus(qcmd.format(qr[0], qr[2] if len(qr) > 2 else "")) + diag = logging.debug if seconds_left else logging.warning + try: ojson = json.loads(output) except json.decoder.JSONDecodeError as error: @@ -92,31 +94,31 @@ def _do_oper_test(tgen, qr): logging.error( "Error decoding json exp result: %s\noutput:\n%s", error, expected ) - logging.warning("FILE: {}".format(qr[1])) + diag("FILE: {}".format(qr[1])) raise if dd_json_cmp: cmpout = json_cmp(ojson, ejson, exact_match=True) if cmpout: - logging.warning( + diag( "-------DIFF---------\n%s\n---------DIFF----------", pprint.pformat(cmpout), ) else: cmpout = tt_json_cmp(ojson, ejson, exact=True) if cmpout: - logging.warning( + diag( "-------EXPECT--------\n%s\n------END-EXPECT------", json.dumps(ejson, indent=4), ) - logging.warning( + diag( "--------GOT----------\n%s\n-------END-GOT--------", json.dumps(ojson, indent=4), ) - logging.warning("----diff---\n{}".format(cmpout)) - logging.warning("Command: {}".format(qcmd.format(qr[0], qr[2] if len(qr) > 2 else ""))) - logging.warning("File: {}".format(qr[1])) - assert cmpout is None + diag("----diff---\n{}".format(cmpout)) + diag("Command: {}".format(qcmd.format(qr[0], qr[2] if len(qr) > 2 else ""))) + diag("File: {}".format(qr[1])) + return cmpout def do_oper_test(tgen, query_results): diff --git a/tests/topotests/mgmt_oper/r1/frr-yanglib.conf b/tests/topotests/mgmt_oper/r1/frr-yanglib.conf new file mode 100644 index 0000000000..f37766b158 --- /dev/null +++ b/tests/topotests/mgmt_oper/r1/frr-yanglib.conf @@ -0,0 +1,10 @@ +log timestamp precision 6 +log file frr.log + +no debug memstats-at-exit + +debug mgmt backend datastore frontend transaction + +interface r1-eth0 + ip address 1.1.1.1/24 +exit diff --git a/tests/topotests/mgmt_oper/test_yanglib.py b/tests/topotests/mgmt_oper/test_yanglib.py new file mode 100644 index 0000000000..e094ca5443 --- /dev/null +++ b/tests/topotests/mgmt_oper/test_yanglib.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# -*- coding: utf-8 eval: (blacken-mode 1) -*- +# +# September 17 2024, Christian Hopps <chopps@labn.net> +# +# Copyright (c) 2024, LabN Consulting, L.L.C. +# + +import json +import pytest +from lib.topogen import Topogen + +pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd] + + +@pytest.fixture(scope="module") +def tgen(request): + "Setup/Teardown the environment and provide tgen argument to tests" + + topodef = {"s1": ("r1",)} + + tgen = Topogen(topodef, request.module.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + router.load_frr_config("frr-yanglib.conf") + + tgen.start_router() + yield tgen + tgen.stop_topology() + + +def test_yang_lib(tgen): + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"].net + output = r1.cmd_nostatus( + "vtysh -c 'show mgmt get-data /ietf-yang-library:yang-library'" + ) + ret = json.loads(output) + loaded_modules = ret['ietf-yang-library:yang-library']['module-set'][0]['module'] + assert len(loaded_modules) > 10, "Modules missing from yang-library" diff --git a/tests/topotests/munet/cli.py b/tests/topotests/munet/cli.py index 01a7091512..d273a30ead 100644 --- a/tests/topotests/munet/cli.py +++ b/tests/topotests/munet/cli.py @@ -745,7 +745,7 @@ async def cli_client_connected(unet, background, reader, writer): await writer.drain() -async def remote_cli(unet, prompt, title, background): +async def remote_cli(unet, prompt, title, background, remote_wait=False): """Open a CLI in a new window.""" try: if not unet.cli_sockpath: @@ -756,6 +756,13 @@ async def remote_cli(unet, prompt, title, background): unet.cli_sockpath = sockpath logging.info("server created on :\n%s\n", sockpath) + if remote_wait: + wait_tmux = bool(os.getenv("TMUX", "")) + wait_x11 = not wait_tmux and bool(os.getenv("DISPLAY", "")) + else: + wait_tmux = False + wait_x11 = False + # Open a new window with a new CLI python_path = await unet.async_get_exec_path(["python3", "python"]) us = os.path.realpath(__file__) @@ -765,7 +772,32 @@ async def remote_cli(unet, prompt, title, background): if prompt: cmd += f" --prompt='{prompt}'" cmd += " " + unet.cli_sockpath - unet.run_in_window(cmd, title=title, background=False) + + channel = None + if wait_tmux: + from .base import Commander # pylint: disable=import-outside-toplevel + + channel = "{}-{}".format(os.getpid(), Commander.tmux_wait_gen) + logger.info("XXX channel is %s", channel) + # If we don't have a tty to pause on pause for tmux windows to exit + if channel is not None: + Commander.tmux_wait_gen += 1 + + pane_info = unet.run_in_window( + cmd, title=title, background=False, wait_for=channel + ) + + if wait_tmux and channel: + from .base import commander # pylint: disable=import-outside-toplevel + + logger.debug("Waiting on TMUX CLI window") + await commander.async_cmd_raises( + [commander.get_exec_path("tmux"), "wait", channel] + ) + elif wait_x11 and isinstance(pane_info, subprocess.Popen): + logger.debug("Waiting on xterm CLI process %s", pane_info) + if hasattr(asyncio, "to_thread"): + await asyncio.to_thread(pane_info.wait) # pylint: disable=no-member except Exception as error: logging.error("cli server: unexpected exception: %s", error) @@ -906,8 +938,22 @@ def cli( prompt=None, background=True, ): + # In the case of no tty a remote_cli will be used, and we want it to wait on finish + # of the spawned cli.py script, otherwise it returns back here and exits async loop + # which kills the server side CLI socket operation. + remote_wait = not sys.stdin.isatty() + asyncio.run( - async_cli(unet, histfile, sockpath, force_window, title, prompt, background) + async_cli( + unet, + histfile, + sockpath, + force_window, + title, + prompt, + background, + remote_wait=remote_wait, + ) ) @@ -919,12 +965,14 @@ async def async_cli( title=None, prompt=None, background=True, + remote_wait=False, ): if prompt is None: prompt = "munet> " if force_window or not sys.stdin.isatty(): - await remote_cli(unet, prompt, title, background) + await remote_cli(unet, prompt, title, background, remote_wait) + return if not unet: logger.debug("client-cli using sockpath %s", sockpath) diff --git a/tests/topotests/munet/native.py b/tests/topotests/munet/native.py index b7c6e4a63e..e3b782396e 100644 --- a/tests/topotests/munet/native.py +++ b/tests/topotests/munet/native.py @@ -2733,7 +2733,7 @@ ff02::2\tip6-allrouters ), "format": "stdout HOST [HOST ...]", "help": "tail -f on the stdout of the qemu/cmd for this node", - "new-window": True, + "new-window": {"background": True, "ns_only": True}, }, { "name": "stderr", @@ -2743,7 +2743,7 @@ ff02::2\tip6-allrouters ), "format": "stderr HOST [HOST ...]", "help": "tail -f on the stdout of the qemu/cmd for this node", - "new-window": True, + "new-window": {"background": True, "ns_only": True}, }, ] } diff --git a/tests/topotests/munet/testing/util.py b/tests/topotests/munet/testing/util.py index a1a94bcd1b..99687c0a83 100644 --- a/tests/topotests/munet/testing/util.py +++ b/tests/topotests/munet/testing/util.py @@ -52,12 +52,13 @@ def pause_test(desc=""): asyncio.run(async_pause_test(desc)) -def retry(retry_timeout, initial_wait=0, expected=True): +def retry(retry_timeout, initial_wait=0, retry_sleep=2, expected=True): """decorator: retry while functions return is not None or raises an exception. * `retry_timeout`: Retry for at least this many seconds; after waiting initial_wait seconds * `initial_wait`: Sleeps for this many seconds before first executing function + * `retry_sleep`: The time to sleep between retries. * `expected`: if False then the return logic is inverted, except for exceptions, (i.e., a non None ends the retry loop, and returns that value) """ @@ -65,9 +66,8 @@ def retry(retry_timeout, initial_wait=0, expected=True): def _retry(func): @functools.wraps(func) def func_retry(*args, **kwargs): - retry_sleep = 2 - # Allow the wrapped function's args to override the fixtures + _retry_sleep = float(kwargs.pop("retry_sleep", retry_sleep)) _retry_timeout = kwargs.pop("retry_timeout", retry_timeout) _expected = kwargs.pop("expected", expected) _initial_wait = kwargs.pop("initial_wait", initial_wait) @@ -82,13 +82,21 @@ def retry(retry_timeout, initial_wait=0, expected=True): while True: seconds_left = (retry_until - datetime.datetime.now()).total_seconds() try: - ret = func(*args, **kwargs) - if _expected and ret is None: + try: + ret = func(*args, seconds_left=seconds_left, **kwargs) + except TypeError as error: + if "seconds_left" not in str(error): + raise + ret = func(*args, **kwargs) + + logging.debug("Function returned %s", ret) + + positive_result = ret is None + if _expected == positive_result: logging.debug("Function succeeds") return ret - logging.debug("Function returned %s", ret) except Exception as error: - logging.info("Function raised exception: %s", str(error)) + logging.info('Function raised exception: "%s"', error) ret = error if seconds_left < 0: @@ -99,10 +107,10 @@ def retry(retry_timeout, initial_wait=0, expected=True): logging.info( "Sleeping %ds until next retry with %.1f retry time left", - retry_sleep, + _retry_sleep, seconds_left, ) - time.sleep(retry_sleep) + time.sleep(_retry_sleep) func_retry._original = func # pylint: disable=W0212 return func_retry diff --git a/tests/topotests/nhrp_redundancy/host/frr.conf b/tests/topotests/nhrp_redundancy/host/frr.conf new file mode 100644 index 0000000000..8bb7da0ad6 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/host/frr.conf @@ -0,0 +1,4 @@ +interface host-eth0 + ip address 10.4.4.7/24 +! +ip route 0.0.0.0/0 10.4.4.4 diff --git a/tests/topotests/nhrp_redundancy/nhc1/frr.conf b/tests/topotests/nhrp_redundancy/nhc1/frr.conf new file mode 100644 index 0000000000..98e848bccf --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/frr.conf @@ -0,0 +1,25 @@ +ip forwarding +!debug nhrp all +interface nhc1-eth0 + ip address 192.168.2.4/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface nhc1-gre0 + ip address 172.16.1.4/32 + no link-detect + ipv6 nd suppress-ra + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp nhs dynamic nbma 192.168.1.1 + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp shortcut + tunnel source nhc1-eth0 +! +interface nhc1-eth1 + ip address 10.4.4.4/24 +! +ip route 0.0.0.0/0 172.16.1.1 50 +ip route 0.0.0.0/0 172.16.1.2 60 +ip route 0.0.0.0/0 172.16.1.3 70 diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_cache.json index f87ebcf5fc..9e8a5c999d 100644 --- a/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_cache.json @@ -4,9 +4,9 @@ }, "table": [ { - "interface": "r4-gre0", + "interface": "nhc1-gre0", "type": "nhs", - "protocol": "176.16.1.2", + "protocol": "172.16.1.2", "nbma": "192.168.1.2", "claimed_nbma": "192.168.1.2", "used": false, @@ -15,9 +15,9 @@ "identity": "" }, { - "interface": "r4-gre0", + "interface": "nhc1-gre0", "type": "local", - "protocol": "176.16.1.4", + "protocol": "172.16.1.4", "nbma": "192.168.2.4", "claimed_nbma": "192.168.2.4", "used": false, @@ -26,9 +26,9 @@ "identity": "-" }, { - "interface": "r4-gre0", + "interface": "nhc1-gre0", "type": "nhs", - "protocol": "176.16.1.3", + "protocol": "172.16.1.3", "nbma": "192.168.1.3", "claimed_nbma": "192.168.1.3", "used": false, @@ -37,9 +37,9 @@ "identity": "" }, { - "interface": "r4-gre0", + "interface": "nhc1-gre0", "type": "nhs", - "protocol": "176.16.1.1", + "protocol": "172.16.1.1", "nbma": "192.168.1.1", "claimed_nbma": "192.168.1.1", "used": false, diff --git a/tests/topotests/nhrp_redundancy/nhc1/nhrp_cache_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_cache_nhs1_down.json new file mode 100644 index 0000000000..5b91f3bcfb --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_cache_nhs1_down.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "nhc1-gre0", + "type": "nhs", + "protocol": "172.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "nhc1-gre0", + "type": "local", + "protocol": "172.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "nhc1-gre0", + "type": "nhs", + "protocol": "172.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_route.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route.json index 1d1c16ffb8..083675651f 100644 --- a/tests/topotests/nhrp_redundancy/r5/nhrp_route.json +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route.json @@ -1,7 +1,7 @@ { - "176.16.1.1\/32": [ + "172.16.1.1\/32": [ { - "prefix": "176.16.1.1\/32", + "prefix": "172.16.1.1\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -16,15 +16,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r5-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.2\/32": [ + "172.16.1.2\/32": [ { - "prefix": "176.16.1.2\/32", + "prefix": "172.16.1.2\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -39,15 +39,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r5-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.3\/32": [ + "172.16.1.3\/32": [ { - "prefix": "176.16.1.3\/32", + "prefix": "172.16.1.3\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -62,7 +62,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r5-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_nhs1_down.json new file mode 100644 index 0000000000..bfb468b0fb --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_nhs1_down.json @@ -0,0 +1,49 @@ +{ + "172.16.1.1\/32": null, + "172.16.1.2\/32": [ + { + "prefix": "172.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ], + "172.16.1.3\/32": [ + { + "prefix": "172.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut.json index f8efff2059..3a91f1baaa 100644 --- a/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut.json @@ -1,7 +1,7 @@ { - "5.5.5.5\/32": [ + "10.5.5.0\/24": [ { - "prefix": "5.5.5.5\/32", + "prefix": "10.5.5.0\/24", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -15,17 +15,17 @@ "nexthops": [ { "fib": true, - "ip": "176.16.1.5", + "ip": "172.16.1.5", "afi": "ipv4", - "interfaceName": "r4-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.1\/32": [ + "172.16.1.1\/32": [ { - "prefix": "176.16.1.1\/32", + "prefix": "172.16.1.1\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -40,15 +40,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.2\/32": [ + "172.16.1.2\/32": [ { - "prefix": "176.16.1.2\/32", + "prefix": "172.16.1.2\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -63,15 +63,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.3\/32": [ + "172.16.1.3\/32": [ { - "prefix": "176.16.1.3\/32", + "prefix": "172.16.1.3\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -86,15 +86,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] } ], - "176.16.1.5\/32": [ + "172.16.1.5\/32": [ { - "prefix": "176.16.1.5\/32", + "prefix": "172.16.1.5\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -109,7 +109,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc1-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut_nhs1_down.json new file mode 100644 index 0000000000..0f38feb6a8 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut_nhs1_down.json @@ -0,0 +1,96 @@ +{ + "10.5.5.0\/24": [ + { + "prefix": "10.5.5.0\/24", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "ip": "172.16.1.5", + "afi": "ipv4", + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ], + "172.16.1.1\/32": null, + "172.16.1.2\/32": [ + { + "prefix": "172.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ], + "172.16.1.3\/32": [ + { + "prefix": "172.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ], + "172.16.1.5\/32": [ + { + "prefix": "172.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc1-gre0", + "active": true + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_absent.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_absent.json new file mode 100644 index 0000000000..78563cb902 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_absent.json @@ -0,0 +1,5 @@ +{ + "attr":{ + "entriesCount":0 + } +} diff --git a/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_present.json b/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_present.json new file mode 100644 index 0000000000..4547c59c88 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_present.json @@ -0,0 +1,9 @@ +{ + "table":[ + { + "type":"dynamic", + "prefix":"10.5.5.0/24", + "via":"172.16.1.5" + } + ] +} diff --git a/tests/topotests/nhrp_redundancy/nhc2/frr.conf b/tests/topotests/nhrp_redundancy/nhc2/frr.conf new file mode 100644 index 0000000000..818dd48251 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc2/frr.conf @@ -0,0 +1,25 @@ +ip forwarding +!debug nhrp all +interface nhc2-eth0 + ip address 192.168.2.5/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface nhc2-gre0 + ip address 172.16.1.5/32 + no link-detect + ipv6 nd suppress-ra + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp nhs dynamic nbma 192.168.1.1 + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp registration no-unique + ip nhrp shortcut + tunnel source nhc2-eth0 +! +interface nhc2-eth1 + ip address 10.5.5.5/24 +! +ip route 0.0.0.0/0 172.16.1.1 50 +ip route 0.0.0.0/0 172.16.1.2 60 +ip route 0.0.0.0/0 172.16.1.3 70 diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json b/tests/topotests/nhrp_redundancy/nhc2/nhrp_cache.json index bc041c6014..8ee02a7cbf 100644 --- a/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json +++ b/tests/topotests/nhrp_redundancy/nhc2/nhrp_cache.json @@ -4,9 +4,9 @@ }, "table": [ { - "interface": "r5-gre0", + "interface": "nhc2-gre0", "type": "nhs", - "protocol": "176.16.1.2", + "protocol": "172.16.1.2", "nbma": "192.168.1.2", "claimed_nbma": "192.168.1.2", "used": false, @@ -15,9 +15,9 @@ "identity": "" }, { - "interface": "r5-gre0", + "interface": "nhc2-gre0", "type": "nhs", - "protocol": "176.16.1.3", + "protocol": "172.16.1.3", "nbma": "192.168.1.3", "claimed_nbma": "192.168.1.3", "used": false, @@ -26,9 +26,9 @@ "identity": "" }, { - "interface": "r5-gre0", + "interface": "nhc2-gre0", "type": "nhs", - "protocol": "176.16.1.1", + "protocol": "172.16.1.1", "nbma": "192.168.1.1", "claimed_nbma": "192.168.1.1", "used": false, @@ -37,9 +37,9 @@ "identity": "" }, { - "interface": "r5-gre0", + "interface": "nhc2-gre0", "type": "local", - "protocol": "176.16.1.5", + "protocol": "172.16.1.5", "nbma": "192.168.2.5", "claimed_nbma": "192.168.2.5", "used": false, diff --git a/tests/topotests/nhrp_redundancy/nhc2/nhrp_cache_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhc2/nhrp_cache_nhs1_down.json new file mode 100644 index 0000000000..bb1c483718 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc2/nhrp_cache_nhs1_down.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "nhc2-gre0", + "type": "nhs", + "protocol": "172.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "nhc2-gre0", + "type": "nhs", + "protocol": "172.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "nhc2-gre0", + "type": "local", + "protocol": "172.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route.json b/tests/topotests/nhrp_redundancy/nhc2/nhrp_route.json index 4f1faee7a7..a69c0caec3 100644 --- a/tests/topotests/nhrp_redundancy/r4/nhrp_route.json +++ b/tests/topotests/nhrp_redundancy/nhc2/nhrp_route.json @@ -1,7 +1,7 @@ { - "176.16.1.1\/32": [ + "172.16.1.1\/32": [ { - "prefix": "176.16.1.1\/32", + "prefix": "172.16.1.1\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -16,15 +16,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc2-gre0", "active": true } ] } ], - "176.16.1.2\/32": [ + "172.16.1.2\/32": [ { - "prefix": "176.16.1.2\/32", + "prefix": "172.16.1.2\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -39,15 +39,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc2-gre0", "active": true } ] } ], - "176.16.1.3\/32": [ + "172.16.1.3\/32": [ { - "prefix": "176.16.1.3\/32", + "prefix": "172.16.1.3\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -62,7 +62,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r4-gre0", + "interfaceName": "nhc2-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhc2/nhrp_route_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhc2/nhrp_route_nhs1_down.json new file mode 100644 index 0000000000..e2dd9dde23 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhc2/nhrp_route_nhs1_down.json @@ -0,0 +1,49 @@ +{ + "172.16.1.1\/32": null, + "172.16.1.2\/32": [ + { + "prefix": "172.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc2-gre0", + "active": true + } + ] + } + ], + "172.16.1.3\/32": [ + { + "prefix": "172.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhc2-gre0", + "active": true + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/nhs1/frr.conf b/tests/topotests/nhrp_redundancy/nhs1/frr.conf new file mode 100644 index 0000000000..583d014348 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs1/frr.conf @@ -0,0 +1,19 @@ +ip forwarding +!debug nhrp all +interface nhs1-eth0 + ip address 192.168.1.1/24 +! +ip route 192.168.2.0/24 192.168.1.6 +nhrp nflog-group 1 +interface nhs1-gre0 + ip address 172.16.1.1/32 + no link-detect + ipv6 nd suppress-ra + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source nhs1-eth0 +! +ip route 10.4.4.0/24 172.16.1.4 +ip route 10.5.5.0/24 172.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json b/tests/topotests/nhrp_redundancy/nhs1/nhrp_cache.json index a94dd9fecf..11d41d1b83 100644 --- a/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json +++ b/tests/topotests/nhrp_redundancy/nhs1/nhrp_cache.json @@ -4,9 +4,9 @@ }, "table": [ { - "interface": "r1-gre0", + "interface": "nhs1-gre0", "type": "dynamic", - "protocol": "176.16.1.4", + "protocol": "172.16.1.4", "nbma": "192.168.2.4", "claimed_nbma": "192.168.2.4", "used": false, @@ -15,9 +15,9 @@ "identity": "" }, { - "interface": "r1-gre0", + "interface": "nhs1-gre0", "type": "local", - "protocol": "176.16.1.1", + "protocol": "172.16.1.1", "nbma": "192.168.1.1", "claimed_nbma": "192.168.1.1", "used": false, @@ -26,9 +26,9 @@ "identity": "-" }, { - "interface": "r1-gre0", + "interface": "nhs1-gre0", "type": "dynamic", - "protocol": "176.16.1.5", + "protocol": "172.16.1.5", "nbma": "192.168.2.5", "claimed_nbma": "192.168.2.5", "used": false, diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_route.json b/tests/topotests/nhrp_redundancy/nhs1/nhrp_route.json index 3d548c08fd..2574b1a5d2 100644 --- a/tests/topotests/nhrp_redundancy/r3/nhrp_route.json +++ b/tests/topotests/nhrp_redundancy/nhs1/nhrp_route.json @@ -1,7 +1,7 @@ { - "176.16.1.4\/32": [ + "172.16.1.4\/32": [ { - "prefix": "176.16.1.4\/32", + "prefix": "172.16.1.4\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -16,15 +16,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r3-gre0", + "interfaceName": "nhs1-gre0", "active": true } ] } ], - "176.16.1.5\/32": [ + "172.16.1.5\/32": [ { - "prefix": "176.16.1.5\/32", + "prefix": "172.16.1.5\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -39,7 +39,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r3-gre0", + "interfaceName": "nhs1-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhs2/frr.conf b/tests/topotests/nhrp_redundancy/nhs2/frr.conf new file mode 100644 index 0000000000..a6e0a98e6b --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs2/frr.conf @@ -0,0 +1,19 @@ +ip forwarding +!debug nhrp all +interface nhs2-eth0 + ip address 192.168.1.2/24 +! +ip route 192.168.2.0/24 192.168.1.6 +nhrp nflog-group 1 +interface nhs2-gre0 + ip address 172.16.1.2/32 + no link-detect + ipv6 nd suppress-ra + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source nhs2-eth0 +! +ip route 10.4.4.0/24 172.16.1.4 +ip route 10.5.5.0/24 172.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json b/tests/topotests/nhrp_redundancy/nhs2/nhrp_cache.json index 91557a1918..6343c4deb9 100644 --- a/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json +++ b/tests/topotests/nhrp_redundancy/nhs2/nhrp_cache.json @@ -4,9 +4,9 @@ }, "table": [ { - "interface": "r2-gre0", + "interface": "nhs2-gre0", "type": "local", - "protocol": "176.16.1.2", + "protocol": "172.16.1.2", "nbma": "192.168.1.2", "claimed_nbma": "192.168.1.2", "used": false, @@ -15,9 +15,9 @@ "identity": "-" }, { - "interface": "r2-gre0", + "interface": "nhs2-gre0", "type": "dynamic", - "protocol": "176.16.1.4", + "protocol": "172.16.1.4", "nbma": "192.168.2.4", "claimed_nbma": "192.168.2.4", "used": false, @@ -26,9 +26,9 @@ "identity": "" }, { - "interface": "r2-gre0", + "interface": "nhs2-gre0", "type": "dynamic", - "protocol": "176.16.1.5", + "protocol": "172.16.1.5", "nbma": "192.168.2.5", "claimed_nbma": "192.168.2.5", "used": false, diff --git a/tests/topotests/nhrp_redundancy/nhs2/nhrp_cache_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhs2/nhrp_cache_nhs1_down.json new file mode 100644 index 0000000000..6343c4deb9 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs2/nhrp_cache_nhs1_down.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "nhs2-gre0", + "type": "local", + "protocol": "172.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "nhs2-gre0", + "type": "dynamic", + "protocol": "172.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "nhs2-gre0", + "type": "dynamic", + "protocol": "172.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_route.json b/tests/topotests/nhrp_redundancy/nhs2/nhrp_route.json index b5f3e29e74..0ad37fc319 100644 --- a/tests/topotests/nhrp_redundancy/r1/nhrp_route.json +++ b/tests/topotests/nhrp_redundancy/nhs2/nhrp_route.json @@ -1,7 +1,7 @@ { - "176.16.1.4\/32": [ + "172.16.1.4\/32": [ { - "prefix": "176.16.1.4\/32", + "prefix": "172.16.1.4\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -16,15 +16,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r1-gre0", + "interfaceName": "nhs2-gre0", "active": true } ] } ], - "176.16.1.5\/32": [ + "172.16.1.5\/32": [ { - "prefix": "176.16.1.5\/32", + "prefix": "172.16.1.5\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -39,7 +39,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r1-gre0", + "interfaceName": "nhs2-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhs2/nhrp_route_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhs2/nhrp_route_nhs1_down.json new file mode 100644 index 0000000000..0ad37fc319 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs2/nhrp_route_nhs1_down.json @@ -0,0 +1,48 @@ +{ + "172.16.1.4\/32": [ + { + "prefix": "172.16.1.4\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhs2-gre0", + "active": true + } + ] + } + ], + "172.16.1.5\/32": [ + { + "prefix": "172.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhs2-gre0", + "active": true + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/nhs3/frr.conf b/tests/topotests/nhrp_redundancy/nhs3/frr.conf new file mode 100644 index 0000000000..e965baf327 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs3/frr.conf @@ -0,0 +1,19 @@ +ip forwarding +!debug nhrp all +interface nhs3-eth0 + ip address 192.168.1.3/24 +! +ip route 192.168.2.0/24 192.168.1.6 +nhrp nflog-group 1 +interface nhs3-gre0 + ip address 172.16.1.3/32 + no link-detect + ipv6 nd suppress-ra + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source nhs3-eth0 +! +ip route 10.4.4.0/24 172.16.1.4 +ip route 10.5.5.0/24 172.16.1.5
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json b/tests/topotests/nhrp_redundancy/nhs3/nhrp_cache.json index ef3ab690bc..d911de348b 100644 --- a/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json +++ b/tests/topotests/nhrp_redundancy/nhs3/nhrp_cache.json @@ -4,9 +4,9 @@ }, "table": [ { - "interface": "r3-gre0", + "interface": "nhs3-gre0", "type": "dynamic", - "protocol": "176.16.1.4", + "protocol": "172.16.1.4", "nbma": "192.168.2.4", "claimed_nbma": "192.168.2.4", "used": false, @@ -15,9 +15,9 @@ "identity": "" }, { - "interface": "r3-gre0", + "interface": "nhs3-gre0", "type": "local", - "protocol": "176.16.1.3", + "protocol": "172.16.1.3", "nbma": "192.168.1.3", "claimed_nbma": "192.168.1.3", "used": false, @@ -26,9 +26,9 @@ "identity": "-" }, { - "interface": "r3-gre0", + "interface": "nhs3-gre0", "type": "dynamic", - "protocol": "176.16.1.5", + "protocol": "172.16.1.5", "nbma": "192.168.2.5", "claimed_nbma": "192.168.2.5", "used": false, diff --git a/tests/topotests/nhrp_redundancy/nhs3/nhrp_cache_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhs3/nhrp_cache_nhs1_down.json new file mode 100644 index 0000000000..d911de348b --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs3/nhrp_cache_nhs1_down.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "nhs3-gre0", + "type": "dynamic", + "protocol": "172.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "nhs3-gre0", + "type": "local", + "protocol": "172.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "nhs3-gre0", + "type": "dynamic", + "protocol": "172.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_route.json b/tests/topotests/nhrp_redundancy/nhs3/nhrp_route.json index f1fa6e54c1..29a4f8f11b 100644 --- a/tests/topotests/nhrp_redundancy/r2/nhrp_route.json +++ b/tests/topotests/nhrp_redundancy/nhs3/nhrp_route.json @@ -1,7 +1,7 @@ { - "176.16.1.4\/32": [ + "172.16.1.4\/32": [ { - "prefix": "176.16.1.4\/32", + "prefix": "172.16.1.4\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -16,15 +16,15 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r2-gre0", + "interfaceName": "nhs3-gre0", "active": true } ] } ], - "176.16.1.5\/32": [ + "172.16.1.5\/32": [ { - "prefix": "176.16.1.5\/32", + "prefix": "172.16.1.5\/32", "protocol": "nhrp", "vrfId": 0, "vrfName": "default", @@ -39,7 +39,7 @@ { "fib": true, "directlyConnected": true, - "interfaceName": "r2-gre0", + "interfaceName": "nhs3-gre0", "active": true } ] diff --git a/tests/topotests/nhrp_redundancy/nhs3/nhrp_route_nhs1_down.json b/tests/topotests/nhrp_redundancy/nhs3/nhrp_route_nhs1_down.json new file mode 100644 index 0000000000..29a4f8f11b --- /dev/null +++ b/tests/topotests/nhrp_redundancy/nhs3/nhrp_route_nhs1_down.json @@ -0,0 +1,48 @@ +{ + "172.16.1.4\/32": [ + { + "prefix": "172.16.1.4\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhs3-gre0", + "active": true + } + ] + } + ], + "172.16.1.5\/32": [ + { + "prefix": "172.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "nhs3-gre0", + "active": true + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrpd.conf b/tests/topotests/nhrp_redundancy/r1/nhrpd.conf deleted file mode 100644 index ad48ce3769..0000000000 --- a/tests/topotests/nhrp_redundancy/r1/nhrpd.conf +++ /dev/null @@ -1,9 +0,0 @@ -!debug nhrp all -nhrp nflog-group 1 -interface r1-gre0 - ip nhrp holdtime 10 - ip nhrp network-id 42 - ip nhrp registration no-unique - ip nhrp redirect - tunnel source r1-eth0 -exit diff --git a/tests/topotests/nhrp_redundancy/r1/zebra.conf b/tests/topotests/nhrp_redundancy/r1/zebra.conf deleted file mode 100644 index 0f11563f57..0000000000 --- a/tests/topotests/nhrp_redundancy/r1/zebra.conf +++ /dev/null @@ -1,12 +0,0 @@ -ip forwarding -interface r1-eth0 - ip address 192.168.1.1/24 -! -ip route 192.168.2.0/24 192.168.1.6 -interface r1-gre0 - ip address 176.16.1.1/32 - no link-detect - ipv6 nd suppress-ra -! -ip route 4.4.4.0/24 176.16.1.4 -ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r2/nhrpd.conf b/tests/topotests/nhrp_redundancy/r2/nhrpd.conf deleted file mode 100644 index 4d63f07d1f..0000000000 --- a/tests/topotests/nhrp_redundancy/r2/nhrpd.conf +++ /dev/null @@ -1,9 +0,0 @@ -!debug nhrp all -nhrp nflog-group 1 -interface r2-gre0 - ip nhrp holdtime 10 - ip nhrp network-id 42 - ip nhrp registration no-unique - ip nhrp redirect - tunnel source r2-eth0 -exit diff --git a/tests/topotests/nhrp_redundancy/r2/zebra.conf b/tests/topotests/nhrp_redundancy/r2/zebra.conf deleted file mode 100644 index 1a9c4ff915..0000000000 --- a/tests/topotests/nhrp_redundancy/r2/zebra.conf +++ /dev/null @@ -1,12 +0,0 @@ -ip forwarding -interface r2-eth0 - ip address 192.168.1.2/24 -! -ip route 192.168.2.0/24 192.168.1.6 -interface r2-gre0 - ip address 176.16.1.2/32 - no link-detect - ipv6 nd suppress-ra -! -ip route 4.4.4.0/24 176.16.1.4 -ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r3/nhrpd.conf b/tests/topotests/nhrp_redundancy/r3/nhrpd.conf deleted file mode 100644 index 87cc2161f8..0000000000 --- a/tests/topotests/nhrp_redundancy/r3/nhrpd.conf +++ /dev/null @@ -1,9 +0,0 @@ -!debug nhrp all -nhrp nflog-group 1 -interface r3-gre0 - ip nhrp holdtime 10 - ip nhrp network-id 42 - ip nhrp registration no-unique - ip nhrp redirect - tunnel source r3-eth0 -exit diff --git a/tests/topotests/nhrp_redundancy/r3/zebra.conf b/tests/topotests/nhrp_redundancy/r3/zebra.conf deleted file mode 100644 index 980cfbcaab..0000000000 --- a/tests/topotests/nhrp_redundancy/r3/zebra.conf +++ /dev/null @@ -1,12 +0,0 @@ -ip forwarding -interface r3-eth0 - ip address 192.168.1.3/24 -! -ip route 192.168.2.0/24 192.168.1.6 -interface r3-gre0 - ip address 176.16.1.3/32 - no link-detect - ipv6 nd suppress-ra -! -ip route 4.4.4.0/24 176.16.1.4 -ip route 5.5.5.0/24 176.16.1.5
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrpd.conf b/tests/topotests/nhrp_redundancy/r4/nhrpd.conf deleted file mode 100644 index 8a52f3386e..0000000000 --- a/tests/topotests/nhrp_redundancy/r4/nhrpd.conf +++ /dev/null @@ -1,11 +0,0 @@ -!debug nhrp all -interface r4-gre0 - ip nhrp holdtime 10 - ip nhrp network-id 42 - ip nhrp registration no-unique - ip nhrp nhs dynamic nbma 192.168.1.1 - ip nhrp nhs dynamic nbma 192.168.1.2 - ip nhrp nhs dynamic nbma 192.168.1.3 - ip nhrp shortcut - tunnel source r4-eth0 -exit diff --git a/tests/topotests/nhrp_redundancy/r4/zebra.conf b/tests/topotests/nhrp_redundancy/r4/zebra.conf deleted file mode 100644 index e4a9a6f80f..0000000000 --- a/tests/topotests/nhrp_redundancy/r4/zebra.conf +++ /dev/null @@ -1,16 +0,0 @@ -ip forwarding -interface r4-eth0 - ip address 192.168.2.4/24 -! -ip route 192.168.1.0/24 192.168.2.6 -interface r4-gre0 - ip address 176.16.1.4/32 - no link-detect - ipv6 nd suppress-ra -! -interface r4-eth1 - ip address 4.4.4.4/24 -! -ip route 0.0.0.0/0 176.16.1.1 50 -ip route 0.0.0.0/0 176.16.1.2 60 -ip route 0.0.0.0/0 176.16.1.3 70
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrpd.conf b/tests/topotests/nhrp_redundancy/r5/nhrpd.conf deleted file mode 100644 index 7241ed592d..0000000000 --- a/tests/topotests/nhrp_redundancy/r5/nhrpd.conf +++ /dev/null @@ -1,11 +0,0 @@ -!debug nhrp all -interface r5-gre0 - ip nhrp holdtime 10 - ip nhrp network-id 42 - ip nhrp nhs dynamic nbma 192.168.1.1 - ip nhrp nhs dynamic nbma 192.168.1.2 - ip nhrp nhs dynamic nbma 192.168.1.3 - ip nhrp registration no-unique - ip nhrp shortcut - tunnel source r5-eth0 -exit diff --git a/tests/topotests/nhrp_redundancy/r5/zebra.conf b/tests/topotests/nhrp_redundancy/r5/zebra.conf deleted file mode 100644 index 9b1e1c0646..0000000000 --- a/tests/topotests/nhrp_redundancy/r5/zebra.conf +++ /dev/null @@ -1,16 +0,0 @@ -ip forwarding -interface r5-eth0 - ip address 192.168.2.5/24 -! -ip route 192.168.1.0/24 192.168.2.6 -interface r5-gre0 - ip address 176.16.1.5/32 - no link-detect - ipv6 nd suppress-ra -! -interface r5-eth1 - ip address 5.5.5.5/24 -! -ip route 0.0.0.0/0 176.16.1.1 50 -ip route 0.0.0.0/0 176.16.1.2 60 -ip route 0.0.0.0/0 176.16.1.3 70 diff --git a/tests/topotests/nhrp_redundancy/r7/zebra.conf b/tests/topotests/nhrp_redundancy/r7/zebra.conf deleted file mode 100644 index 5747b40956..0000000000 --- a/tests/topotests/nhrp_redundancy/r7/zebra.conf +++ /dev/null @@ -1,4 +0,0 @@ -interface r7-eth0 - ip address 4.4.4.7/24 -! -ip route 0.0.0.0/0 4.4.4.4 diff --git a/tests/topotests/nhrp_redundancy/r6/zebra.conf b/tests/topotests/nhrp_redundancy/router/frr.conf index 63a37cd5bf..c0eb19ca40 100644 --- a/tests/topotests/nhrp_redundancy/r6/zebra.conf +++ b/tests/topotests/nhrp_redundancy/router/frr.conf @@ -1,7 +1,7 @@ ip forwarding -interface r6-eth0 +interface router-eth0 ip address 192.168.1.6/24 ! -interface r6-eth1 +interface router-eth1 ip address 192.168.2.6/24 exit diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot index c169436db0..e94e1d0734 100644 --- a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot @@ -16,43 +16,43 @@ graph template { label="nhrp-topo-redundant-nhs"; # Routers - r1 [ + nhs1 [ shape=doubleoctagon, label="NHS 1", fillcolor="#f08080", style=filled, ]; - r2 [ + nhs2 [ shape=doubleoctagon label="NHS 2", fillcolor="#f08080", style=filled, ]; - r3 [ + nhs3 [ shape=doubleoctagon label="NHS 3", fillcolor="#f08080", style=filled, ]; - r4 [ + nhc1 [ shape=doubleoctagon label="NHC 1", fillcolor="#f08080", style=filled, ]; - r5 [ + nhc2 [ shape=doubleoctagon label="NHC 2", fillcolor="#f08080", style=filled, ]; - r6 [ + router [ shape=doubleoctagon label="router", fillcolor="#f08080", style=filled, ]; - r7 [ + host [ shape=doubleoctagon label="host", fillcolor="#f08080", @@ -74,30 +74,30 @@ graph template { ]; sw3 [ shape=oval, - label="sw3\n4.4.4.0/24", + label="sw3\n10.4.4.0/24", fillcolor="#d0e0d0", style=filled, ]; sw4 [ shape=oval, - label="sw4\n5.5.5.0/24", + label="sw4\n10.5.5.0/24", fillcolor="#d0e0d0", style=filled, ]; # Connections - r1 -- sw1 [label="eth0"]; - r2 -- sw1 [label="eth0"]; - r3 -- sw1 [label="eth0"]; - r6 -- sw1 [label="eth0"]; + nhs1 -- sw1 [label="eth0"]; + nhs2 -- sw1 [label="eth0"]; + nhs3 -- sw1 [label="eth0"]; + router -- sw1 [label="eth0"]; - r4 -- sw2 [label="eth0"]; - r5 -- sw2 [label="eth0"]; - r6 -- sw2 [label="eth1"]; + nhc1 -- sw2 [label="eth0"]; + nhc2 -- sw2 [label="eth0"]; + router -- sw2 [label="eth1"]; - r4 -- sw3 [label="eth1"]; - r7 -- sw3 [label="eth0"]; + nhc1 -- sw3 [label="eth1"]; + host -- sw3 [label="eth0"]; - r5 -- sw4 [label="eth1"]; + nhc2 -- sw4 [label="eth1"]; } diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py index ffd9abc9d4..d4cf98596c 100644 --- a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py @@ -29,38 +29,38 @@ test_nhrp_redundancy.py: Test NHS redundancy for NHRP """ TOPOLOGY = """ -+------------+ +------------+ +------------+ -| | | | | | -| | | | | | -| NHS 1 | | NHS 2 | | NHS 3 | -| | | | | | -+-----+------+ +-----+------+ +-----+------+ - |.1 |.2 |.3 - | | | - | | 192.168.1.0/24 | -------+-------------------------------+------------------+-------------+------ - | - |.6 - GRE P2MP between all NHS and NHC +-----+------+ - 172.16.1.x/32 | | - | | - | Router | - | | - +-----+------+ - | - | - ---------+----------------+-------------+------ - | 192.168.2.0/24 | - | | - | |.4 |.5 -+------------+ | +-------+----+ +------+-----+ | -| | | | | | | | -| | +--------+ | | | | -| Host |.7 | | NHC 1 | | NHC 2 +-----+5.5.5.0/24 -| +---------+ | | | | | -+------------+ | +------------+ +------------+ | - | | - 4.4.4.0/24 ++------------+ +------------+ +------------+ +| | | | | | +| | | | | | +| NHS 1 | | NHS 2 | | NHS 3 | +| | | | | | ++-----+------+ +-----+------+ +-----+------+ + |.1 |.2 |.3 + | | | + | | 192.168.1.0/24 | +------+-------------------------------+------------------+-------------+------ + | + |.6 + GRE P2MP between all NHS and NHC +-----+------+ + 172.16.1.x/32 | | + | | + | Router | + | | + +-----+------+ + | + | + ---------+----------------+-------------+------ + | 192.168.2.0/24 | + | | + | |.4 |.5 ++------------+ | +-------+----+ +------+-----+ | +| | | | | | | | +| | +--------+ | | | | +| Host |.7 | | NHC 1 | | NHC 2 +-----+10.5.5.0/24 +| +---------+ | | | | | ++------------+ | +------------+ +------------+ | + | | + 10.4.4.0/24 """ # Save the Current Working Directory to find configuration files. @@ -76,30 +76,26 @@ def build_topo(tgen): "Build function" # Create 7 routers - for routern in range(1, 8): - tgen.add_router("r{}".format(routern)) + for rname in ["nhs1", "nhs2", "nhs3", "nhc1", "nhc2", "router", "host"]: + tgen.add_router(rname) - # Interconnect routers 1, 2, 3, 6 switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["r1"]) - switch.add_link(tgen.gears["r2"]) - switch.add_link(tgen.gears["r3"]) - switch.add_link(tgen.gears["r6"]) + switch.add_link(tgen.gears["nhs1"]) + switch.add_link(tgen.gears["nhs2"]) + switch.add_link(tgen.gears["nhs3"]) + switch.add_link(tgen.gears["router"]) - # Interconnect routers 4, 5, 6 switch = tgen.add_switch("s2") - switch.add_link(tgen.gears["r4"]) - switch.add_link(tgen.gears["r5"]) - switch.add_link(tgen.gears["r6"]) + switch.add_link(tgen.gears["nhc1"]) + switch.add_link(tgen.gears["nhc2"]) + switch.add_link(tgen.gears["router"]) - # Connect router 4, 7 switch = tgen.add_switch("s3") - switch.add_link(tgen.gears["r4"]) - switch.add_link(tgen.gears["r7"]) + switch.add_link(tgen.gears["nhc1"]) + switch.add_link(tgen.gears["host"]) - # Connect router 5 switch = tgen.add_switch("s4") - switch.add_link(tgen.gears["r5"]) + switch.add_link(tgen.gears["nhc2"]) def _populate_iface(): @@ -110,7 +106,7 @@ def _populate_iface(): "echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu", "echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6", "echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6", - "iptables -A FORWARD -i {0}-gre0 -o {0}-gre0 -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 --hashlimit-mode srcip,dstip --hashlimit-srcmask 24 --hashlimit-dstmask 24 --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-range 128", + "iptables -A FORWARD -i {0}-gre0 -o {0}-gre0 -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 --hashlimit-mode srcip,dstip --hashlimit-srcmask 24 --hashlimit-dstmask 24 --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-size 128", ] cmds_tot = [ @@ -122,41 +118,38 @@ def _populate_iface(): ] for cmd in cmds_tot_hub: - # Router 1 - input = cmd.format("r1", "1") + input = cmd.format("nhs1", "1") logger.info("input: " + input) - output = tgen.net["r1"].cmd(input) + output = tgen.net["nhs1"].cmd(input) logger.info("output: " + output) - # Router 2 - input = cmd.format("r2", "2") + input = cmd.format("nhs2", "2") logger.info("input: " + input) - output = tgen.net["r2"].cmd(input) + output = tgen.net["nhs2"].cmd(input) logger.info("output: " + output) - # Router 3 - input = cmd.format("r3", "3") + input = cmd.format("nhs3", "3") logger.info("input: " + input) - output = tgen.net["r3"].cmd(input) + output = tgen.net["nhs3"].cmd(input) logger.info("output: " + output) for cmd in cmds_tot: - input = cmd.format("r4", "4") + input = cmd.format("nhc1", "4") logger.info("input: " + input) - output = tgen.net["r4"].cmd(input) + output = tgen.net["nhc1"].cmd(input) logger.info("output: " + output) - input = cmd.format("r5", "5") + input = cmd.format("nhc2", "5") logger.info("input: " + input) - output = tgen.net["r5"].cmd(input) + output = tgen.net["nhc2"].cmd(input) logger.info("output: " + output) def _verify_iptables(): tgen = get_topogen() # Verify iptables is installed. Required for shortcuts - rc, _, _ = tgen.net["r1"].cmd_status("iptables") - return False if rc == 127 else True + rc, _, _ = tgen.net["nhs1"].cmd_status("iptables -V") + return True if rc == 0 else False def setup_module(mod): @@ -174,14 +167,8 @@ def setup_module(mod): _populate_iface() for rname, router in router_list.items(): - router.load_config( - TopoRouter.RD_ZEBRA, - os.path.join(CWD, "{}/zebra.conf".format(rname)), - ) - if rname in ("r1", "r2", "r3", "r4", "r5"): - router.load_config( - TopoRouter.RD_NHRP, os.path.join(CWD, "{}/nhrpd.conf".format(rname)) - ) + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) # Initialize all routers. tgen.start_router() @@ -202,17 +189,15 @@ def test_protocols_convergence(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info("Checking NHRP cache and IPv4 routes for convergence") + logger.info("Checking NHRP cache for convergence") router_list = tgen.routers() # Check NHRP cache on servers and clients - for _, router in router_list.items(): - - json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name) - if not os.path.isfile(json_file): - logger.info("skipping file {}".format(json_file)) + for rname, router in router_list.items(): + if "nh" not in rname: continue + json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial( topotest.router_json_cmp, router, "show ip nhrp cache json", expected @@ -226,13 +211,12 @@ def test_protocols_convergence(): assert result is None, assertmsg # Check NHRP IPV4 routes on servers and clients + logger.info("Checking IPv4 routes for convergence") for rname, router in router_list.items(): - - json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) - if not os.path.isfile(json_file): - logger.info("skipping file {}".format(json_file)) + if "nh" not in rname: continue + json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) expected = json.loads(open(json_file).read()) test_func = partial( topotest.router_json_cmp, router, "show ip route nhrp json", expected @@ -246,53 +230,53 @@ def test_protocols_convergence(): assert result is None, assertmsg # Test connectivity from 1 NHRP server to all clients - pingrouter = tgen.gears["r1"] - logger.info("Check Ping IPv4 from R1 to R4 = 176.16.1.4)") - output = pingrouter.run("ping 176.16.1.4 -f -c 1000") + nhs1 = tgen.gears["nhs1"] + logger.info("Check Ping IPv4 from nhs1 to nhc1 = 172.16.1.4)") + output = nhs1.run("ping 172.16.1.4 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R1 to R4 should be ok" + assertmsg = "expected ping IPv4 from nhs1 to nhc1 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R1 to R4 OK") + logger.info("Check Ping IPv4 from nhs1 to nhc1 OK") - logger.info("Check Ping IPv4 from R1 to R5 = 176.16.1.5)") - output = pingrouter.run("ping 176.16.1.5 -f -c 1000") + logger.info("Check Ping IPv4 from nhs1 to nhc2 = 172.16.1.5)") + output = nhs1.run("ping 172.16.1.5 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R1 to R5 should be ok" + assertmsg = "expected ping IPv4 from nhs1 to nhc2 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R1 to R5 OK") + logger.info("Check Ping IPv4 from nhs1 to nhc2 OK") # Test connectivity from 1 NHRP client to all servers - pingrouter = tgen.gears["r4"] - logger.info("Check Ping IPv4 from R4 to R1 = 176.16.1.1)") - output = pingrouter.run("ping 176.16.1.1 -f -c 1000") + nhc1 = tgen.gears["nhc1"] + logger.info("Check Ping IPv4 from nhc1 to nhs1 = 172.16.1.1)") + output = nhc1.run("ping 172.16.1.1 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R4 to R1 should be ok" + assertmsg = "expected ping IPv4 from nhc1 to nhs1 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R4 to R1 OK") + logger.info("Check Ping IPv4 from nhc1 to nhs1 OK") - logger.info("Check Ping IPv4 from R4 to R2 = 176.16.1.2)") - output = pingrouter.run("ping 176.16.1.2 -f -c 1000") + logger.info("Check Ping IPv4 from nhc1 to nhs2 = 172.16.1.2)") + output = nhc1.run("ping 172.16.1.2 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R4 to R2 should be ok" + assertmsg = "expected ping IPv4 from nhc1 to nhs2 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R4 to R2 OK") + logger.info("Check Ping IPv4 from nhc1 to nhs2 OK") - logger.info("Check Ping IPv4 from R4 to R3 = 176.16.1.3)") - output = pingrouter.run("ping 176.16.1.3 -f -c 1000") + logger.info("Check Ping IPv4 from nhc1 to nhs3 = 172.16.1.3)") + output = nhc1.run("ping 172.16.1.3 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R4 to R3 should be ok" + assertmsg = "expected ping IPv4 from nhc1 to nhs3 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R4 to R3 OK") + logger.info("Check Ping IPv4 from nhc1 to nhs3 OK") @retry(retry_timeout=30, initial_wait=5) @@ -301,22 +285,21 @@ def verify_shortcut_path(): Verifying that traffic flows through shortcut path """ tgen = get_topogen() - pingrouter = tgen.gears["r7"] - logger.info("Check Ping IPv4 from R7 to R5 = 5.5.5.5") + host = tgen.gears["host"] + logger.info("Check Ping IPv4 from host to nhc2 = 10.5.5.5") - output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + output = host.run("ping 10.5.5.5 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R7 to R5 should be ok" + assertmsg = "expected ping IPv4 from host to nhc2 should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R7 to R5 OK") + logger.info("Check Ping IPv4 from host to nhc2 OK") def test_redundancy_shortcut(): """ Assert that if shortcut created and then NHS goes down, there is no traffic disruption - Stop traffic and verify next time traffic started, shortcut is initiated by backup NHS """ tgen = get_topogen() if tgen.routers_have_failure(): @@ -327,84 +310,207 @@ def test_redundancy_shortcut(): logger.info("Testing NHRP shortcuts with redundant servers") - # Verify R4 nhrp routes before shortcut creation - router = tgen.gears["r4"] - json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) + # Verify nhc1 nhrp routes before shortcut creation + nhc1 = tgen.gears["nhc1"] + json_file = "{}/{}/nhrp_route.json".format(CWD, nhc1.name) assertmsg = "No nhrp_route file found" assert os.path.isfile(json_file), assertmsg expected = json.loads(open(json_file).read()) test_func = partial( - topotest.router_json_cmp, router, "show ip route nhrp json", expected + topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected ) _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) - output = router.vtysh_cmd("show ip route nhrp") + output = nhc1.vtysh_cmd("show ip route nhrp") logger.info(output) - assertmsg = '"{}" JSON output mismatches'.format(router.name) + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) assert result is None, assertmsg # Initiate shortcut by pinging between clients - pingrouter = tgen.gears["r7"] - logger.info("Check Ping IPv4 from R7 to R5 via shortcut = 5.5.5.5") + host = tgen.gears["host"] + logger.info("Check Ping IPv4 from host to nhc2 via shortcut = 10.5.5.5") - output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + output = host.run("ping 10.5.5.5 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" + assertmsg = "expected ping IPv4 from host to nhc2 via shortcut should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + logger.info("Check Ping IPv4 from host to nhc2 via shortcut OK") # Now check that NHRP shortcut route installed - json_file = "{}/{}/nhrp_route_shortcut.json".format(CWD, router.name) + json_file = "{}/{}/nhrp_route_shortcut.json".format(CWD, nhc1.name) assertmsg = "No nhrp_route file found" assert os.path.isfile(json_file), assertmsg expected = json.loads(open(json_file).read()) test_func = partial( - topotest.router_json_cmp, router, "show ip route nhrp json", expected + topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = nhc1.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) + assert result is None, assertmsg + + json_file = "{}/{}/nhrp_shortcut_present.json".format(CWD, nhc1.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected ) _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) - output = router.vtysh_cmd("show ip route nhrp") + output = nhc1.vtysh_cmd("show ip nhrp shortcut") logger.info(output) - assertmsg = '"{}" JSON output mismatches'.format(router.name) + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) assert result is None, assertmsg + # check the shortcut disappears because of no traffic + json_file = "{}/{}/nhrp_shortcut_absent.json".format(CWD, nhc1.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = nhc1.vtysh_cmd("show ip nhrp shortcut") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) + assert result is None, assertmsg + + +def test_redundancy_shortcut_backup(): + """ + Stop traffic and verify next time traffic started, shortcut is initiated by backup NHS + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + if not _verify_iptables(): + pytest.skip("iptables not installed") + + nhc1 = tgen.gears["nhc1"] + router_list = tgen.routers() + # Bring down primary GRE interface and verify shortcut is not disturbed - logger.info("Bringing down R1, primary NHRP server.") - shutdown_bringup_interface(tgen, "r1", "r1-gre0", False) + logger.info("Bringing down nhs1, primary NHRP server.") + shutdown_bringup_interface(tgen, "nhs1", "nhs1-gre0", False) + + # Check NHRP cache on servers and clients + for rname, router in router_list.items(): + if "nh" not in rname: + continue + if "nhs1" in rname: + continue + + json_file = "{}/{}/nhrp_cache_nhs1_down.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip nhrp cache json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip nhrp cache") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + # Check NHRP IPV4 routes on servers and clients + logger.info("Checking IPv4 routes for convergence") + for rname, router in router_list.items(): + if "nh" not in rname: + continue + if "nhs1" in rname: + continue + + json_file = "{}/{}/nhrp_route_nhs1_down.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg # Verify shortcut is still active - pingrouter = tgen.gears["r7"] - logger.info("Check Ping IPv4 from R7 to R5 via shortcut = 5.5.5.5") + host = tgen.gears["host"] + logger.info("Check Ping IPv4 from host to nhc2 via shortcut = 10.5.5.5") - output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + output = host.run("ping 10.5.5.5 -f -c 1000") logger.info(output) if "1000 packets transmitted, 1000 received" not in output: - assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" + assertmsg = "expected ping IPv4 from host to nhc2 via shortcut should be ok" assert 0, assertmsg else: - logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + logger.info("Check Ping IPv4 from host to nhc2 via shortcut OK") + + # Verify shortcut is present in routing table + json_file = "{}/{}/nhrp_route_shortcut_nhs1_down.json".format(CWD, nhc1.name) + assertmsg = "No nhrp_route file found" + assert os.path.isfile(json_file), assertmsg + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = nhc1.vtysh_cmd("show ip route nhrp") + logger.info(output) + + json_file = "{}/{}/nhrp_shortcut_present.json".format(CWD, nhc1.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = nhc1.vtysh_cmd("show ip nhrp shortcut") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) + assert result is None, assertmsg # Now verify shortcut is purged with lack of traffic - json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) + json_file = "{}/{}/nhrp_route_nhs1_down.json".format(CWD, nhc1.name) assertmsg = "No nhrp_route file found" assert os.path.isfile(json_file), assertmsg expected = json.loads(open(json_file).read()) test_func = partial( - topotest.router_json_cmp, router, "show ip route nhrp json", expected + topotest.router_json_cmp, nhc1, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = nhc1.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) + assert result is None, assertmsg + + json_file = "{}/{}/nhrp_shortcut_absent.json".format(CWD, nhc1.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, nhc1, "show ip nhrp shortcut json", expected ) _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) - output = router.vtysh_cmd("show ip route nhrp") + output = nhc1.vtysh_cmd("show ip nhrp shortcut") logger.info(output) - assertmsg = '"{}" JSON output mismatches'.format(router.name) + assertmsg = '"{}" JSON output mismatches'.format(nhc1.name) assert result is None, assertmsg diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index 797bced7b8..131085a47a 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -2,7 +2,7 @@ O 10.0.1.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX C>* 10.0.1.0/24 is directly connected, r1-eth0, weight 1, XX:XX:XX L>* 10.0.1.1/32 is directly connected, r1-eth0, weight 1, XX:XX:XX O>* 10.0.2.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX -B>* 10.0.3.0/24 [20/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX +B>* 10.0.3.0/24 [110/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt index 1dc574f360..45ee1071d4 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt @@ -1,7 +1,7 @@ VRF neno: O>* 10.0.3.0/24 [110/20] via 10.0.30.3, r1-eth2, weight 1, XX:XX:XX -B>* 10.0.4.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.30.0/24 [110/10] is directly connected, r1-eth2, weight 1, XX:XX:XX C>* 10.0.30.0/24 is directly connected, r1-eth2, weight 1, XX:XX:XX L>* 10.0.30.1/32 is directly connected, r1-eth2, weight 1, XX:XX:XX -B>* 10.0.40.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index b5e81bc0e9..f3724bbb9f 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -4,7 +4,7 @@ O 10.0.2.0/24 [110/10] is directly connected, r2-eth0, weight 1, XX:XX:XX C>* 10.0.2.0/24 is directly connected, r2-eth0, weight 1, XX:XX:XX L>* 10.0.2.2/32 is directly connected, r2-eth0, weight 1, XX:XX:XX O>* 10.0.3.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX -B>* 10.0.4.0/24 [20/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX +B>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r2-eth1, weight 1, XX:XX:XX L>* 10.0.20.2/32 is directly connected, r2-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index c403496ff6..0f8b12bdfa 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,10 +1,10 @@ VRF ray: -B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.1.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX -B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.3.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX C>* 10.0.40.0/24 is directly connected, r2-eth2, weight 1, XX:XX:XX L>* 10.0.40.2/32 is directly connected, r2-eth2, weight 1, XX:XX:XX diff --git a/tests/topotests/pim_cand_rp_bsr/__init__.py b/tests/topotests/pim_cand_rp_bsr/__init__.py new file mode 100755 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/__init__.py diff --git a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf new file mode 100644 index 0000000000..d0aa3d529f --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf @@ -0,0 +1,25 @@ +! +hostname r1 +password zebra +log file /tmp/r1-frr.log +! +!debug pim packet +!debug pim bsm +! +ip route 0.0.0.0/0 10.0.0.4 +! +interface r1-eth0 + ip address 10.0.0.1/24 + ip igmp + ip pim +! +interface r1-eth1 + ip address 10.0.1.1/24 + ip igmp + ip pim +! +router pim + bsr candidate-bsr priority 200 source address 10.0.0.1 +! +ip forwarding +! diff --git a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf new file mode 100644 index 0000000000..741c839f19 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf @@ -0,0 +1,22 @@ +! +hostname r2 +password zebra +log file /tmp/r2-frr.log +! +ip route 0.0.0.0/0 10.0.0.4 +! +interface r2-eth0 + ip address 10.0.0.2/24 + ip igmp + ip pim +! +interface r2-eth1 + ip address 10.0.2.2/24 + ip igmp + ip pim +! +router pim + bsr candidate-bsr priority 100 source address 10.0.0.2 +! +ip forwarding +! diff --git a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf new file mode 100644 index 0000000000..bd5c8ce93f --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf @@ -0,0 +1,32 @@ +! +hostname r3 +password zebra +log file /tmp/r3-frr.log +! +!debug pim packet +!debug pim 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 + ip igmp + ip pim +! +interface r3-eth1 + ip address 10.0.3.3/24 + ip igmp + ip pim +! +interface r3-eth2 + ip address 10.0.4.3/24 + ip igmp + ip pim +! +router pim + bsr candidate-rp group 239.0.0.0/16 + bsr candidate-rp priority 10 source address 10.0.3.3 +! +ip forwarding +! diff --git a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf new file mode 100644 index 0000000000..825b227728 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf @@ -0,0 +1,37 @@ +! +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 r4-eth0 + ip address 10.0.2.4/24 + ip igmp + ip pim +! +interface r4-eth1 + ip address 10.0.3.4/24 + ip igmp + ip pim +! +interface r4-eth2 + ip address 10.0.5.4/24 + ip igmp + ip pim +! +interface r4-eth3 + ip address 10.0.0.4/24 + ip igmp + ip pim +! +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 +! +ip forwarding +! diff --git a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf new file mode 100644 index 0000000000..c934717d08 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf @@ -0,0 +1,17 @@ +! +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 + ip igmp + ip pim +! +interface r5-eth1 + ip address 10.0.6.5/24 +! +ip forwarding +! diff --git a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf new file mode 100644 index 0000000000..fd9d1eb5c4 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf @@ -0,0 +1,22 @@ +! +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 + ip igmp + ip pim +! +interface r6-eth1 + ip address 10.0.6.6/24 +! +interface r6-eth2 + ip address 10.0.3.6/24 + ip igmp + ip pim +! +ip 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 new file mode 100644 index 0000000000..ce7bc9dc56 --- /dev/null +++ b/tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_pim_cand_rp_bsr.py +# +# Copyright (c) 2024 ATCorp +# Jafar Al-Gharaibeh +# + +import os +import sys +import pytest +import json +from functools import partial + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.pim import verify_pim_rp_info +from lib.common_config import step, write_test_header, retry + +from time import sleep + +""" +test_pim_cand_rp_bsr.py: Test candidate RP/BSR functionality +""" + +TOPOLOGY = """ + Candidate RP/BSR functionality + + +---+---+ +---+---+ + | C-BSR | 10.0.0.0/24 | C-BSR | + + R1 + <--------+---------> + R2 | + |elected| .1 | .2 | | + +---+---+ | +---+---+ + .1 | | 10.0.2.0/24 | .2 + | 10.0.1.0/24 | | + .3 | +-----| .4 | .4 + +---+---+ |---->+---+---+ + | C-RP | 10.0.3.0/24 | C-RP | + + R3 + <--------+---------> + R4 | + | prio | .3 | .4 | | + +---+---+ | +---+---+ + .3 | | | .4 + |10.0.4.0/24 | 10.0.5.0/24| + .5 | | .6 | .6 + +---+---+ +---------->+---+---+ + | | | | + + R5 + <------------------> + R6 | + | | .5 .6 | | + +---+---+ 10.0.6.0/24 +---+---+ +""" + +# Save the Current Working Directory to find configuration files. +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] + + +def build_topo(tgen): + "Build function" + + # Create 6 routers + for rn in range(1, 7): + tgen.add_router("r{}".format(rn)) + + # Create 7 switches and connect routers + sw1 = tgen.add_switch("s1") + sw1.add_link(tgen.gears["r1"]) + sw1.add_link(tgen.gears["r2"]) + + sw = tgen.add_switch("s2") + sw.add_link(tgen.gears["r1"]) + sw.add_link(tgen.gears["r3"]) + + sw = tgen.add_switch("s3") + sw.add_link(tgen.gears["r2"]) + sw.add_link(tgen.gears["r4"]) + + sw3 = tgen.add_switch("s4") + sw3.add_link(tgen.gears["r3"]) + sw3.add_link(tgen.gears["r4"]) + + sw = tgen.add_switch("s5") + sw.add_link(tgen.gears["r3"]) + sw.add_link(tgen.gears["r5"]) + + sw = tgen.add_switch("s6") + sw.add_link(tgen.gears["r4"]) + sw.add_link(tgen.gears["r6"]) + + sw = tgen.add_switch("s7") + sw.add_link(tgen.gears["r5"]) + sw.add_link(tgen.gears["r6"]) + + # make the diagnoal connections + 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)) + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + logger.info("Loading router %s" % rname) + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + # Initialize all routers. + tgen.start_router() + for router in router_list.values(): + if router.has_version("<", "4.0"): + tgen.set_error("unsupported version") + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + +def test_pim_bsr_election_r1(request): + "Test PIM 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":"10.0.0.1", + "priority":200, + "state":"ACCEPT_PREFERRED", + } + + 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() + 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"] + + # r2 is a candidate bsr with low priority: 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 + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + + 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() + 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":"10.0.3.3", + "priority":10 + } + test_func = partial( + topotest.router_json_cmp, r3, "show ip 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_pim_bsr_rp_info(request): + "Test 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", "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) + 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) + 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) + 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) + 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) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + +def test_pim_bsr_election_fallback_r2(request): + "Test PIM BSR Election Backup" + 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") + + step("Take r1 out from BSR candidates") + r1 = tgen.gears["r1"] + r1.vtysh_cmd( + """ + 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 = {} + + test_func = partial( + topotest.router_json_cmp, r1, "show ip pim bsr candidate-bsr json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=1) + + assertmsg = "r1: failed to remove bsr candidate configuration" + assert result is None, assertmsg + + r2 = tgen.gears["r2"] + # We should fall back to r2 as the BSR + expected = { + "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 + ) + _, result = topotest.run_and_expect(test_func, None, count=180, wait=1) + + assertmsg = "r2: failed to fallback to r2 as a BSR" + assert result is None, assertmsg + + +def test_pim_bsr_rp_info_fallback(request): + "Test RP info state on r5" + 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") + + step("Take r3 out from RP candidates for group 239.0.0.0/16") + r3 = tgen.gears["r3"] + r3.vtysh_cmd( + """ + 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) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + +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)) diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index db806fed39..b234a84252 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -1,6 +1,9 @@ # Skip pytests example directory [pytest] +asyncio_mode = auto +asyncio_default_fixture_loop_scope = module + # NEEDS_EXABGP_4_2_11_FRR # asyncio_mode = auto diff --git a/tests/topotests/srv6_encap_src_addr/r1/zebra.conf b/tests/topotests/srv6_encap_src_addr/r1/zebra.conf index c570756b52..c245dd2d96 100644 --- a/tests/topotests/srv6_encap_src_addr/r1/zebra.conf +++ b/tests/topotests/srv6_encap_src_addr/r1/zebra.conf @@ -4,7 +4,6 @@ hostname r1 ! debug zebra rib detailed ! log stdout notifications -log monitor notifications log commands log file zebra.log debugging ! diff --git a/tests/topotests/srv6_sid_manager/ce1/bgpd.conf b/tests/topotests/srv6_sid_manager/ce1/bgpd.conf new file mode 100644 index 0000000000..3459796629 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce1/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce1 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce1/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce1/ipv6_rib.json new file mode 100644 index 0000000000..a35e2b1b3d --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce1/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:1::1", + "afi": "ipv6", + "interfaceName": "eth-rt1", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt1", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce1/zebra.conf b/tests/topotests/srv6_sid_manager/ce1/zebra.conf new file mode 100644 index 0000000000..0dea0c5751 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce1/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce1 +! +interface eth-rt1 + ipv6 address 2001:1::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:1::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/ce2/bgpd.conf b/tests/topotests/srv6_sid_manager/ce2/bgpd.conf new file mode 100644 index 0000000000..8ed9978749 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce2/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce2 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce2/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce2/ipv6_rib.json new file mode 100644 index 0000000000..b4594d1c57 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce2/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:2::1", + "afi": "ipv6", + "interfaceName": "eth-rt6", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt6", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce2/zebra.conf b/tests/topotests/srv6_sid_manager/ce2/zebra.conf new file mode 100644 index 0000000000..c4755f8485 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce2/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce2 +! +interface eth-rt6 + ipv6 address 2001:2::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:2::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/ce3/bgpd.conf b/tests/topotests/srv6_sid_manager/ce3/bgpd.conf new file mode 100644 index 0000000000..a85d9701c7 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce3/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce3 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce3/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce3/ipv6_rib.json new file mode 100644 index 0000000000..3a50cb0199 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce3/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:3::1", + "afi": "ipv6", + "interfaceName": "eth-rt1", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:3::/64": [ + { + "prefix": "2001:3::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt1", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce3/zebra.conf b/tests/topotests/srv6_sid_manager/ce3/zebra.conf new file mode 100644 index 0000000000..046bcb6af8 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce3/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce3 +! +interface eth-rt1 + ipv6 address 2001:3::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:3::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/ce4/bgpd.conf b/tests/topotests/srv6_sid_manager/ce4/bgpd.conf new file mode 100644 index 0000000000..93fb32fd1b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce4/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce4 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce4/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce4/ipv6_rib.json new file mode 100644 index 0000000000..f6484355ba --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce4/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:4::1", + "afi": "ipv6", + "interfaceName": "eth-rt6", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:4::/64": [ + { + "prefix": "2001:4::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt6", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce4/zebra.conf b/tests/topotests/srv6_sid_manager/ce4/zebra.conf new file mode 100644 index 0000000000..7913d6f397 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce4/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce4 +! +interface eth-rt6 + ipv6 address 2001:4::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:4::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/ce5/bgpd.conf b/tests/topotests/srv6_sid_manager/ce5/bgpd.conf new file mode 100644 index 0000000000..2ab6f2d2a7 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce5/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce5 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce5/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce5/ipv6_rib.json new file mode 100644 index 0000000000..a88df73c5a --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce5/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:5::1", + "afi": "ipv6", + "interfaceName": "eth-rt1", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:5::/64": [ + { + "prefix": "2001:5::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt1", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce5/zebra.conf b/tests/topotests/srv6_sid_manager/ce5/zebra.conf new file mode 100644 index 0000000000..21414ffcbc --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce5/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce5 +! +interface eth-rt1 + ipv6 address 2001:5::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:5::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/ce6/bgpd.conf b/tests/topotests/srv6_sid_manager/ce6/bgpd.conf new file mode 100644 index 0000000000..e0b6540514 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce6/bgpd.conf @@ -0,0 +1,8 @@ +frr defaults traditional +! +hostname ce6 +password zebra +! +log stdout notifications +log commands +log file bgpd.log diff --git a/tests/topotests/srv6_sid_manager/ce6/ipv6_rib.json b/tests/topotests/srv6_sid_manager/ce6/ipv6_rib.json new file mode 100644 index 0000000000..ab6dfc9e13 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce6/ipv6_rib.json @@ -0,0 +1,58 @@ +{ + "::/0": [ + { + "prefix": "::/0", + "protocol": "static", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 1, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 73, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "ip": "2001:6::1", + "afi": "ipv6", + "interfaceName": "eth-rt6", + "active": true, + "weight": 1 + } + ] + } + ], + "2001:6::/64": [ + { + "prefix": "2001:6::/64", + "protocol": "connected", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 254, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-rt6", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/ce6/zebra.conf b/tests/topotests/srv6_sid_manager/ce6/zebra.conf new file mode 100644 index 0000000000..ebe8556092 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/ce6/zebra.conf @@ -0,0 +1,14 @@ +log file zebra.log +! +hostname ce6 +! +interface eth-rt6 + ipv6 address 2001:6::2/64 +! +ip forwarding +ipv6 forwarding +! +ipv6 route ::/0 2001:6::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/dst/sharpd.conf b/tests/topotests/srv6_sid_manager/dst/sharpd.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/dst/sharpd.conf diff --git a/tests/topotests/srv6_sid_manager/dst/zebra.conf b/tests/topotests/srv6_sid_manager/dst/zebra.conf new file mode 100644 index 0000000000..80741856cb --- /dev/null +++ b/tests/topotests/srv6_sid_manager/dst/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname dst +! +! debug zebra kernel +! debug zebra packet +! debug zebra mpls +! +interface lo + ip address 9.9.9.2/32 + ipv6 address fc00:0:9::1/128 +! +interface eth-rt6 + ip address 10.0.10.2/24 + ipv6 address 2001:db8:10::2/64 +! +ip forwarding +! +ip route 2001:db8:1::1 2001:db8:10::1 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt1/bgpd.conf b/tests/topotests/srv6_sid_manager/rt1/bgpd.conf new file mode 100644 index 0000000000..20c396afde --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/bgpd.conf @@ -0,0 +1,66 @@ +frr defaults traditional +! +bgp send-extra-data zebra +! +hostname rt1 +password zebra +! +log stdout notifications +log commands +! +!debug bgp neighbor-events +!debug bgp zebra +!debug bgp vnc verbose +!debug bgp update-groups +!debug bgp updates in +!debug bgp updates out +!debug bgp vpn label +!debug bgp vpn leak-from-vrf +!debug bgp vpn leak-to-vrf +!debug bgp vpn rmap-event +! +router bgp 1 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor fc00:0:6::1 remote-as 6 + neighbor fc00:0:6::1 timers 3 10 + neighbor fc00:0:6::1 timers connect 1 + neighbor fc00:0:6::1 ttl-security hops 20 + ! + address-family ipv6 vpn + neighbor fc00:0:6::1 activate + exit-address-family + ! + segment-routing srv6 + locator loc1 + ! +! +router bgp 1 vrf vrf10 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + address-family ipv6 unicast + sid vpn export 65024 + rd vpn export 1:10 + rt vpn both 99:99 + import vpn + export vpn + redistribute connected + exit-address-family +! +router bgp 1 vrf vrf20 + bgp router-id 1.1.1.1 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + address-family ipv6 unicast + sid vpn export 65025 + rd vpn export 1:20 + rt vpn both 88:88 + import vpn + export vpn + redistribute connected + exit-address-family +! diff --git a/tests/topotests/srv6_sid_manager/rt1/isisd.conf b/tests/topotests/srv6_sid_manager/rt1/isisd.conf new file mode 100644 index 0000000000..29e1a31171 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/isisd.conf @@ -0,0 +1,35 @@ +password 1 +hostname rt1 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0001.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt1/sharpd.conf b/tests/topotests/srv6_sid_manager/rt1/sharpd.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/sharpd.conf diff --git a/tests/topotests/srv6_sid_manager/rt1/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt1/show_ip_route.ref new file mode 100644 index 0000000000..590d75afbf --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/show_ip_route.ref @@ -0,0 +1,276 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt1/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt1/show_ipv6_route.ref new file mode 100644 index 0000000000..cdbec3f2c1 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/show_ipv6_route.ref @@ -0,0 +1,314 @@ +{ + "fc00:0:2::1\/128":[ + { + "prefix":"fc00:0:2::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:3::1\/128":[ + { + "prefix":"fc00:0:3::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::1\/128":[ + { + "prefix":"fc00:0:4::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:5::1\/128":[ + { + "prefix":"fc00:0:5::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:6::1\/128":[ + { + "prefix":"fc00:0:6::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:1:e000::\/64":[ + { + "prefix":"fc00:0:1:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"eth-sw1", + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:1:e001::\/64":[ + { + "prefix":"fc00:0:1:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"eth-sw1", + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:1:fe00::\/128":[ + { + "prefix":"fc00:0:1:fe00::\/128", + "protocol":"bgp", + "selected":true, + "destSelected":true, + "distance":20, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"vrf10", + "active":true, + "seg6local":{ + "action":"End.DT6" + } + } + ] + } + ], + "fc00:0:1:fe01::\/128":[ + { + "prefix":"fc00:0:1:fe01::\/128", + "protocol":"bgp", + "selected":true, + "destSelected":true, + "distance":20, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"vrf20", + "active":true, + "seg6local":{ + "action":"End.DT6" + } + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt1/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt1/show_srv6_locator_table.ref new file mode 100644 index 0000000000..c4a5d7507b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:1::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..9c5901b90f --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,32 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt1/vpnv6_rib.ref b/tests/topotests/srv6_sid_manager/rt1/vpnv6_rib.ref new file mode 100644 index 0000000000..52bc589a7f --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/vpnv6_rib.ref @@ -0,0 +1,169 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "1.1.1.1", + "defaultLocPrf": 100, + "localAS": 1, + "routes": { + "routeDistinguishers": { + "1:10": { + "2001:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:1::", + "prefixLen": 64, + "network": "2001:1::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "::", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ], + "2001:3::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:3::", + "prefixLen": 64, + "network": "2001:3::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "::", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "1:20": { + "2001:5::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:5::", + "prefixLen": 64, + "network": "2001:5::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf20", + "nexthops": [ + { + "ip": "::", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "6:10": { + "2001:2::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:2::", + "prefixLen": 64, + "network": "2001:2::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:6::1", + "path": "6", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:6::1", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "6:20": { + "2001:4::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:4::", + "prefixLen": 64, + "network": "2001:4::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:6::1", + "path": "6", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:6::1", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ], + "2001:6::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:6::", + "prefixLen": 64, + "network": "2001:6::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:6::1", + "path": "6", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:6::1", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/srv6_sid_manager/rt1/vrf10_rib.ref b/tests/topotests/srv6_sid_manager/rt1/vrf10_rib.ref new file mode 100644 index 0000000000..2aae3497f4 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/vrf10_rib.ref @@ -0,0 +1,86 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "protocol": "connected", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce1", + "active": true + } + ] + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-sw1", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:6:fe00::" + } + } + ], + "asPath": "6" + } + ], + "2001:3::/64": [ + { + "prefix": "2001:3::/64", + "protocol": "connected", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce3", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt1/vrf20_rib.ref b/tests/topotests/srv6_sid_manager/rt1/vrf20_rib.ref new file mode 100644 index 0000000000..de9e450cf6 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/vrf20_rib.ref @@ -0,0 +1,92 @@ +{ + "2001:4::/64": [ + { + "prefix": "2001:4::/64", + "protocol": "bgp", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-sw1", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:6:fe01::" + } + } + ], + "asPath": "6" + } + ], + "2001:5::/64": [ + { + "prefix": "2001:5::/64", + "protocol": "connected", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce5", + "active": true + } + ] + } + ], + "2001:6::/64": [ + { + "prefix": "2001:6::/64", + "protocol": "bgp", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-sw1", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:6:fe01::" + } + } + ], + "asPath": "6" + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt1/zebra.conf b/tests/topotests/srv6_sid_manager/rt1/zebra.conf new file mode 100644 index 0000000000..ef7fb78eed --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt1/zebra.conf @@ -0,0 +1,37 @@ +log file zebra.log +! +hostname rt1 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 1.1.1.1/32 + ipv6 address fc00:0:1::1/128 +! +interface eth-sw1 + ip address 10.0.1.1/24 + ipv6 address 2001:db8:1::1/64 +! +interface eth-ce1 vrf vrf10 + ipv6 address 2001:1::1/64 +! +interface eth-ce3 vrf vrf10 + ipv6 address 2001:3::1/64 +! +interface eth-ce5 vrf vrf20 + ipv6 address 2001:5::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:1::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt2/isisd.conf b/tests/topotests/srv6_sid_manager/rt2/isisd.conf new file mode 100644 index 0000000000..b095f04910 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/isisd.conf @@ -0,0 +1,48 @@ +hostname rt2 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt4-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt4-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0002.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt2/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt2/show_ip_route.ref new file mode 100644 index 0000000000..1d4a9e9a25 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/show_ip_route.ref @@ -0,0 +1,320 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1" + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2" + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt2/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt2/show_ipv6_route.ref new file mode 100644 index 0000000000..fc0f1d3bcc --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/show_ipv6_route.ref @@ -0,0 +1,346 @@ +{ + "fc00:0:1::1\/128":[ + { + "prefix":"fc00:0:1::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:3::1\/128":[ + { + "prefix":"fc00:0:3::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::1\/128":[ + { + "prefix":"fc00:0:4::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "fc00:0:5::1\/128":[ + { + "prefix":"fc00:0:5::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:6::1\/128":[ + { + "prefix":"fc00:0:6::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:2:e000::\/64":[ + { + "prefix":"fc00:0:2:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:2:e001::\/64":[ + { + "prefix":"fc00:0:2:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:2:e002::\/64":[ + { + "prefix":"fc00:0:2:e002::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:2:e003::\/64":[ + { + "prefix":"fc00:0:2:e003::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt2/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt2/show_srv6_locator_table.ref new file mode 100644 index 0000000000..f8a5d93f3c --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:2::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt2/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt2/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..5e46ddf728 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,70 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt4-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt4-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0001", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt2/zebra.conf b/tests/topotests/srv6_sid_manager/rt2/zebra.conf new file mode 100644 index 0000000000..32737dfcd6 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt2/zebra.conf @@ -0,0 +1,34 @@ +log file zebra.log +! +hostname rt2 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 2.2.2.2/32 + ipv6 address fc00:0:2::1/128 +! +interface eth-sw1 + ip address 10.0.1.2/24 + ipv6 address 2001:db8:1::2/64 +! +interface eth-rt4-1 + ip address 10.0.2.2/24 +! +interface eth-rt4-2 + ip address 10.0.3.2/24 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:2::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt3/isisd.conf b/tests/topotests/srv6_sid_manager/rt3/isisd.conf new file mode 100644 index 0000000000..e237db2f49 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/isisd.conf @@ -0,0 +1,48 @@ +hostname rt3 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt5-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt5-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0003.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt3/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt3/show_ip_route.ref new file mode 100644 index 0000000000..6ce5760e4f --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/show_ip_route.ref @@ -0,0 +1,320 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1" + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2" + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt3/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt3/show_ipv6_route.ref new file mode 100644 index 0000000000..c590fcfdbc --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/show_ipv6_route.ref @@ -0,0 +1,346 @@ +{ + "fc00:0:1::1\/128":[ + { + "prefix":"fc00:0:1::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:2::1\/128":[ + { + "prefix":"fc00:0:2::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::1\/128":[ + { + "prefix":"fc00:0:4::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:5::1\/128":[ + { + "prefix":"fc00:0:5::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:6::1\/128":[ + { + "prefix":"fc00:0:6::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:3:e000::\/64":[ + { + "prefix":"fc00:0:3:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:3:e001::\/64":[ + { + "prefix":"fc00:0:3:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:3:e002::\/64":[ + { + "prefix":"fc00:0:3:e002::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:3:e003::\/64":[ + { + "prefix":"fc00:0:3:e003::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt3/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt3/show_srv6_locator_table.ref new file mode 100644 index 0000000000..c62870587b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:3::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt3/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt3/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..a284240d24 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,70 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt5-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-sw1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0001", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + }, + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 10, + "neighbor-priority": 64, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt3/zebra.conf b/tests/topotests/srv6_sid_manager/rt3/zebra.conf new file mode 100644 index 0000000000..73cf6b08f4 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt3/zebra.conf @@ -0,0 +1,33 @@ +log file zebra.log +! +hostname rt3 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 3.3.3.3/32 + ipv6 address fc00:0:3::1/128 +! +interface eth-sw1 + ip address 10.0.1.3/24 +! +interface eth-rt5-1 + ip address 10.0.4.3/24 +! +interface eth-rt5-2 + ip address 10.0.5.3/24 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:3::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt4/isisd.conf b/tests/topotests/srv6_sid_manager/rt4/isisd.conf new file mode 100644 index 0000000000..b4c92146a1 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/isisd.conf @@ -0,0 +1,56 @@ +hostname rt4 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt2-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt2-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0004.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt4/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt4/show_ip_route.ref new file mode 100644 index 0000000000..0f26fa5d7a --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/show_ip_route.ref @@ -0,0 +1,296 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1" + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2" + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5" + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6" + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt4/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt4/show_ipv6_route.ref new file mode 100644 index 0000000000..7b575f1888 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/show_ipv6_route.ref @@ -0,0 +1,346 @@ +{ + "fc00:0:1::1\/128":[ + { + "prefix":"fc00:0:1::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "fc00:0:2::1\/128":[ + { + "prefix":"fc00:0:2::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "fc00:0:3::1\/128":[ + { + "prefix":"fc00:0:3::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:5::1\/128":[ + { + "prefix":"fc00:0:5::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:6::1\/128":[ + { + "prefix":"fc00:0:6::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:4:e000::\/64":[ + { + "prefix":"fc00:0:4:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:4:e001::\/64":[ + { + "prefix":"fc00:0:4:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:4:e002::\/64":[ + { + "prefix":"fc00:0:4:e002::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:4:e003::\/64":[ + { + "prefix":"fc00:0:4:e003::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ] +}
\ No newline at end of file diff --git a/tests/topotests/srv6_sid_manager/rt4/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt4/show_srv6_locator_table.ref new file mode 100644 index 0000000000..cb052dbbb5 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:4::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt4/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt4/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..0ca7a76bd4 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,82 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt2-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt2-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt6", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0006", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt4/zebra.conf b/tests/topotests/srv6_sid_manager/rt4/zebra.conf new file mode 100644 index 0000000000..266db7c53a --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt4/zebra.conf @@ -0,0 +1,36 @@ +log file zebra.log +! +hostname rt4 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 4.4.4.4/32 + ipv6 address fc00:0:4::1/128 +! +interface eth-rt2-1 + ip address 10.0.2.4/24 +! +interface eth-rt2-2 + ip address 10.0.3.4/24 +! +interface eth-rt5 + ip address 10.0.6.4/24 +! +interface eth-rt6 + ip address 10.0.7.4/24 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:4::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt5/isisd.conf b/tests/topotests/srv6_sid_manager/rt5/isisd.conf new file mode 100644 index 0000000000..26f895dd82 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/isisd.conf @@ -0,0 +1,56 @@ +hostname rt5 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt3-1 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt3-2 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0005.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt5/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt5/show_ip_route.ref new file mode 100644 index 0000000000..65beaa5998 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/show_ip_route.ref @@ -0,0 +1,296 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1" + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2" + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6" + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt5/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt5/show_ipv6_route.ref new file mode 100644 index 0000000000..a7b3262f86 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/show_ipv6_route.ref @@ -0,0 +1,346 @@ +{ + "fc00:0:1::1\/128":[ + { + "prefix":"fc00:0:1::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:2::1\/128":[ + { + "prefix":"fc00:0:2::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:3::1\/128":[ + { + "prefix":"fc00:0:3::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:4::1\/128":[ + { + "prefix":"fc00:0:4::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:6::1\/128":[ + { + "prefix":"fc00:0:6::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:5:e000::\/64":[ + { + "prefix":"fc00:0:5:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:5:e001::\/64":[ + { + "prefix":"fc00:0:5:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:5:e002::\/64":[ + { + "prefix":"fc00:0:5:e002::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:5:e003::\/64":[ + { + "prefix":"fc00:0:5:e003::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt5/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt5/show_srv6_locator_table.ref new file mode 100644 index 0000000000..ec55f24d7b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:5::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt5/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt5/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..f40b0d353d --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,82 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt3-1", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt3-2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt4", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt6", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0006", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt5/zebra.conf b/tests/topotests/srv6_sid_manager/rt5/zebra.conf new file mode 100644 index 0000000000..901103554b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt5/zebra.conf @@ -0,0 +1,36 @@ +log file zebra.log +! +hostname rt5 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 5.5.5.5/32 + ipv6 address fc00:0:5::1/128 +! +interface eth-rt3-1 + ip address 10.0.4.5/24 +! +interface eth-rt3-2 + ip address 10.0.5.5/24 +! +interface eth-rt4 + ip address 10.0.6.5/24 +! +interface eth-rt6 + ip address 10.0.8.5/24 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:5::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/rt6/bgpd.conf b/tests/topotests/srv6_sid_manager/rt6/bgpd.conf new file mode 100644 index 0000000000..c36fae7901 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/bgpd.conf @@ -0,0 +1,67 @@ +frr defaults traditional +! +bgp send-extra-data zebra +! +hostname rt6 +password zebra +! +log stdout notifications +log commands +! +!debug bgp neighbor-events +!debug bgp zebra +!debug bgp vnc verbose +!debug bgp update-groups +!debug bgp updates in +!debug bgp updates out +!debug bgp updates +!debug bgp vpn label +!debug bgp vpn leak-from-vrf +!debug bgp vpn leak-to-vrf +!!debug bgp vpn rmap-event +! +router bgp 6 + bgp router-id 6.6.6.6 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + neighbor fc00:0:1::1 remote-as 1 + neighbor fc00:0:1::1 timers 3 10 + neighbor fc00:0:1::1 timers connect 1 + neighbor fc00:0:1::1 ttl-security hops 20 + ! + address-family ipv6 vpn + neighbor fc00:0:1::1 activate + exit-address-family + ! + segment-routing srv6 + locator loc1 + ! +! +router bgp 6 vrf vrf10 + bgp router-id 6.6.6.6 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + address-family ipv6 unicast + sid vpn export 65024 + rd vpn export 6:10 + rt vpn both 99:99 + import vpn + export vpn + redistribute connected + exit-address-family +! +router bgp 6 vrf vrf20 + bgp router-id 6.6.6.6 + no bgp ebgp-requires-policy + no bgp default ipv4-unicast + ! + address-family ipv6 unicast + sid vpn export 65025 + rd vpn export 6:20 + rt vpn both 88:88 + import vpn + export vpn + redistribute connected + exit-address-family +! diff --git a/tests/topotests/srv6_sid_manager/rt6/isisd.conf b/tests/topotests/srv6_sid_manager/rt6/isisd.conf new file mode 100644 index 0000000000..f8816db43a --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/isisd.conf @@ -0,0 +1,42 @@ +hostname rt6 +log file isisd.log +! +! debug isis events +! debug isis route-events +! debug isis spf-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis network point-to-point + isis hello-interval 1 + isis hello-multiplier 10 +! +router isis 1 + lsp-gen-interval 2 + net 49.0000.0000.0000.0006.00 + is-type level-1 + topology ipv6-unicast + segment-routing srv6 + locator loc1 + node-msd + max-segs-left 3 + max-end-pop 3 + max-h-encaps 2 + max-end-d 5 + interface sr0 +! diff --git a/tests/topotests/srv6_sid_manager/rt6/sharpd.conf b/tests/topotests/srv6_sid_manager/rt6/sharpd.conf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/sharpd.conf diff --git a/tests/topotests/srv6_sid_manager/rt6/show_ip_route.ref b/tests/topotests/srv6_sid_manager/rt6/show_ip_route.ref new file mode 100644 index 0000000000..5fc293b6d8 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/show_ip_route.ref @@ -0,0 +1,273 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4" + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5" + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt6/show_ipv6_route.ref b/tests/topotests/srv6_sid_manager/rt6/show_ipv6_route.ref new file mode 100644 index 0000000000..d06354b872 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/show_ipv6_route.ref @@ -0,0 +1,312 @@ +{ + "fc00:0:1::1\/128":[ + { + "prefix":"fc00:0:1::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:2::1\/128":[ + { + "prefix":"fc00:0:2::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:3::1\/128":[ + { + "prefix":"fc00:0:3::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:4::1\/128":[ + { + "prefix":"fc00:0:4::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:5::1\/128":[ + { + "prefix":"fc00:0:5::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:1::\/48":[ + { + "prefix":"fc00:0:1::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:2::\/48":[ + { + "prefix":"fc00:0:2::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:3::\/48":[ + { + "prefix":"fc00:0:3::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:4::\/48":[ + { + "prefix":"fc00:0:4::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "fc00:0:5::\/48":[ + { + "prefix":"fc00:0:5::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":10, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "fc00:0:6::\/48":[ + { + "prefix":"fc00:0:6::\/48", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"sr0", + "active":true, + "seg6local":{ + "action":"End" + } + } + ] + } + ], + "fc00:0:6:e000::\/64":[ + { + "prefix":"fc00:0:6:e000::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:6:e001::\/64":[ + { + "prefix":"fc00:0:6:e001::\/64", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "active":true, + "seg6local":{ + "action":"End.X" + } + } + ] + } + ], + "fc00:0:6:fe00::\/128":[ + { + "prefix":"fc00:0:6:fe00::\/128", + "protocol":"bgp", + "selected":true, + "destSelected":true, + "distance":20, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"vrf10", + "active":true, + "seg6local":{ + "action":"End.DT6" + } + } + ] + } + ], + "fc00:0:6:fe01::\/128":[ + { + "prefix":"fc00:0:6:fe01::\/128", + "protocol":"bgp", + "selected":true, + "destSelected":true, + "distance":20, + "metric":0, + "installed":true, + "nexthops":[ + { + "fib":true, + "directlyConnected":true, + "interfaceName":"vrf20", + "active":true, + "seg6local":{ + "action":"End.DT6" + } + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt6/show_srv6_locator_table.ref b/tests/topotests/srv6_sid_manager/rt6/show_srv6_locator_table.ref new file mode 100644 index 0000000000..abcdeddea4 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/show_srv6_locator_table.ref @@ -0,0 +1,15 @@ +{ + "locators":[ + { + "name":"loc1", + "prefix":"fc00:0:6::/48", + "blockBitsLength":32, + "nodeBitsLength":16, + "functionBitsLength":16, + "argumentBitsLength":0, + "statusUp":true, + "chunks":[ + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt6/show_yang_interface_isis_adjacencies.ref b/tests/topotests/srv6_sid_manager/rt6/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..8300ca0b5c --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,44 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt4", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0004", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt5", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1", + "neighbor-sysid": "0000.0000.0005", + "hold-timer": 10, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/srv6_sid_manager/rt6/vpnv6_rib.ref b/tests/topotests/srv6_sid_manager/rt6/vpnv6_rib.ref new file mode 100644 index 0000000000..fe0fa24529 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/vpnv6_rib.ref @@ -0,0 +1,169 @@ +{ + "vrfId": 0, + "vrfName": "default", + "routerId": "6.6.6.6", + "defaultLocPrf": 100, + "localAS": 6, + "routes": { + "routeDistinguishers": { + "1:10": { + "2001:1::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:1::", + "prefixLen": 64, + "network": "2001:1::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:1::1", + "path": "1", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:1::1", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ], + "2001:3::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:3::", + "prefixLen": 64, + "network": "2001:3::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:1::1", + "path": "1", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:1::1", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "1:20": { + "2001:5::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:5::", + "prefixLen": 64, + "network": "2001:5::/64", + "metric": 0, + "weight": 0, + "peerId": "fc00:0:1::1", + "path": "1", + "origin": "incomplete", + "nexthops": [ + { + "ip": "fc00:0:1::1", + "hostname": "rt1", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "6:10": { + "2001:2::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:2::", + "prefixLen": 64, + "network": "2001:2::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf10", + "nexthops": [ + { + "ip": "::", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ] + }, + "6:20": { + "2001:4::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:4::", + "prefixLen": 64, + "network": "2001:4::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf20", + "nexthops": [ + { + "ip": "::", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ], + "2001:6::/64": [ + { + "valid": true, + "bestpath": true, + "selectionReason": "First path received", + "pathFrom": "external", + "prefix": "2001:6::", + "prefixLen": 64, + "network": "2001:6::/64", + "metric": 0, + "weight": 32768, + "peerId": "(unspec)", + "path": "", + "origin": "incomplete", + "announceNexthopSelf": true, + "nhVrfName": "vrf20", + "nexthops": [ + { + "ip": "::", + "hostname": "rt6", + "afi": "ipv6", + "used": true + } + ] + } + ] + } + } + } +} diff --git a/tests/topotests/srv6_sid_manager/rt6/vrf10_rib.ref b/tests/topotests/srv6_sid_manager/rt6/vrf10_rib.ref new file mode 100644 index 0000000000..87ff5a9902 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/vrf10_rib.ref @@ -0,0 +1,92 @@ +{ + "2001:1::/64": [ + { + "prefix": "2001:1::/64", + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-rt5", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:1:fe00::" + } + } + ], + "asPath": "1" + } + ], + "2001:2::/64": [ + { + "prefix": "2001:2::/64", + "protocol": "connected", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce2", + "active": true + } + ] + } + ], + "2001:3::/64": [ + { + "prefix": "2001:3::/64", + "protocol": "bgp", + "vrfName": "vrf10", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 10, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-rt5", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:1:fe00::" + } + } + ], + "asPath": "1" + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt6/vrf20_rib.ref b/tests/topotests/srv6_sid_manager/rt6/vrf20_rib.ref new file mode 100644 index 0000000000..95d7d4412b --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/vrf20_rib.ref @@ -0,0 +1,86 @@ +{ + "2001:4::/64": [ + { + "prefix": "2001:4::/64", + "protocol": "connected", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce4", + "active": true + } + ] + } + ], + "2001:5::/64": [ + { + "prefix": "2001:5::/64", + "protocol": "bgp", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 20, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 9, + "internalNextHopNum": 3, + "internalNextHopActiveNum": 3, + "nexthops": [ + { + "flags": 3, + "fib": true, + "afi": "ipv6", + "interfaceName": "eth-rt5", + "vrf": "default", + "active": true, + "weight": 1, + "seg6": { + "segs": "fc00:0:1:fe01::" + } + } + ], + "asPath": "1" + } + ], + "2001:6::/64": [ + { + "prefix": "2001:6::/64", + "protocol": "connected", + "vrfName": "vrf20", + "selected": true, + "destSelected": true, + "distance": 0, + "metric": 0, + "installed": true, + "table": 20, + "internalStatus": 16, + "internalFlags": 8, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "flags": 3, + "fib": true, + "directlyConnected": true, + "interfaceName": "eth-ce6", + "active": true + } + ] + } + ] +} diff --git a/tests/topotests/srv6_sid_manager/rt6/zebra.conf b/tests/topotests/srv6_sid_manager/rt6/zebra.conf new file mode 100644 index 0000000000..8ac64c559e --- /dev/null +++ b/tests/topotests/srv6_sid_manager/rt6/zebra.conf @@ -0,0 +1,45 @@ +log file zebra.log +! +hostname rt6 +! +! debug zebra kernel +! debug zebra packet +! +interface lo + ip address 6.6.6.6/32 + ipv6 address fc00:0:6::1/128 +! +interface eth-rt4 + ip address 10.0.7.6/24 +! +interface eth-rt5 + ip address 10.0.8.6/24 +! +interface eth-dst + ip address 10.0.10.1/24 + ip address 2001:db8:10::1/64 +! +interface eth-ce2 vrf vrf10 + ipv6 address 2001:2::1/64 +! +interface eth-ce4 vrf vrf20 + ipv6 address 2001:4::1/64 +! +interface eth-ce6 vrf vrf20 + ipv6 address 2001:6::1/64 +! +segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:6::/48 + format usid-f3216 + ! + ! +! +ip forwarding +! +ipv6 route fc00:0:9::1/128 2001:db8:10::2 vrf vrf10 +! +line vty +! diff --git a/tests/topotests/srv6_sid_manager/test_srv6_sid_manager.py b/tests/topotests/srv6_sid_manager/test_srv6_sid_manager.py new file mode 100644 index 0000000000..31f22d9900 --- /dev/null +++ b/tests/topotests/srv6_sid_manager/test_srv6_sid_manager.py @@ -0,0 +1,421 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2023 by Carmine Scarpitta <cscarpit@cisco.com> +# + +""" +test_srv6_sid_manager.py: + + +---------+ + | | + | RT1 | + | 1.1.1.1 | + | | + +---------+ + |eth-sw1 + | + | + | + +---------+ | +---------+ + | | | | | + | RT2 |eth-sw1 | eth-sw1| RT3 | + | 2.2.2.2 +----------+----------+ 3.3.3.3 | + | | 10.0.1.0/24 | | + +---------+ +---------+ + eth-rt4-1| |eth-rt4-2 eth-rt5-1| |eth-rt5-2 + | | | | + 10.0.2.0/24| |10.0.3.0/24 10.0.4.0/24| |10.0.5.0/24 + | | | | + eth-rt2-1| |eth-rt2-2 eth-rt3-1| |eth-rt3-2 + +---------+ +---------+ + | | | | + | RT4 | 10.0.6.0/24 | RT5 | + | 4.4.4.4 +---------------------+ 5.5.5.5 | + | |eth-rt5 eth-rt4| | + +---------+ +---------+ + eth-rt6| |eth-rt6 + | | + 10.0.7.0/24| |10.0.8.0/24 + | +---------+ | + | | | | + | | RT6 | | + +----------+ 6.6.6.6 +-----------+ + eth-rt4| |eth-rt5 + +---------+ + |eth-dst (.1) + | + |10.0.10.0/24 + | + |eth-rt6 (.2) + +---------+ + | | + | DST | + | 9.9.9.2 | + | | + +---------+ + +""" + +import os +import re +import sys +import json +import functools +import pytest + +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 +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.common_config import ( + required_linux_kernel_version, + create_interface_in_kernel, +) +from lib.checkping import check_ping + +pytestmark = [pytest.mark.isisd, pytest.mark.sharpd] + + +def build_topo(tgen): + """Build function""" + + # Define FRR Routers + tgen.add_router("rt1") + tgen.add_router("rt2") + tgen.add_router("rt3") + tgen.add_router("rt4") + tgen.add_router("rt5") + tgen.add_router("rt6") + tgen.add_router("dst") + tgen.add_router("ce1") + tgen.add_router("ce2") + tgen.add_router("ce3") + tgen.add_router("ce4") + tgen.add_router("ce5") + tgen.add_router("ce6") + + # Define connections + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1") + switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1") + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1") + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2") + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1") + + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2") + + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") + + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4") + + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") + + switch = tgen.add_switch("s9") + switch.add_link(tgen.gears["rt6"], nodeif="eth-dst") + switch.add_link(tgen.gears["dst"], nodeif="eth-rt6") + + tgen.add_link(tgen.gears["ce1"], tgen.gears["rt1"], "eth-rt1", "eth-ce1") + tgen.add_link(tgen.gears["ce2"], tgen.gears["rt6"], "eth-rt6", "eth-ce2") + tgen.add_link(tgen.gears["ce3"], tgen.gears["rt1"], "eth-rt1", "eth-ce3") + tgen.add_link(tgen.gears["ce4"], tgen.gears["rt6"], "eth-rt6", "eth-ce4") + tgen.add_link(tgen.gears["ce5"], tgen.gears["rt1"], "eth-rt1", "eth-ce5") + tgen.add_link(tgen.gears["ce6"], tgen.gears["rt6"], "eth-rt6", "eth-ce6") + + tgen.gears["rt1"].run("ip link add vrf10 type vrf table 10") + tgen.gears["rt1"].run("ip link set vrf10 up") + tgen.gears["rt1"].run("ip link add vrf20 type vrf table 20") + tgen.gears["rt1"].run("ip link set vrf20 up") + tgen.gears["rt1"].run("ip link set eth-ce1 master vrf10") + tgen.gears["rt1"].run("ip link set eth-ce3 master vrf10") + tgen.gears["rt1"].run("ip link set eth-ce5 master vrf20") + + tgen.gears["rt6"].run("ip link add vrf10 type vrf table 10") + tgen.gears["rt6"].run("ip link set vrf10 up") + tgen.gears["rt6"].run("ip link add vrf20 type vrf table 20") + tgen.gears["rt6"].run("ip link set vrf20 up") + tgen.gears["rt6"].run("ip link set eth-ce2 master vrf10") + tgen.gears["rt6"].run("ip link set eth-ce4 master vrf20") + tgen.gears["rt6"].run("ip link set eth-ce6 master vrf20") + + # Add dummy interface for SRv6 + create_interface_in_kernel( + tgen, + "rt1", + "sr0", + "2001:db8::1", + netmask="128", + create=True, + ) + create_interface_in_kernel( + tgen, + "rt2", + "sr0", + "2001:db8::2", + netmask="128", + create=True, + ) + create_interface_in_kernel( + tgen, + "rt3", + "sr0", + "2001:db8::3", + netmask="128", + create=True, + ) + create_interface_in_kernel( + tgen, + "rt4", + "sr0", + "2001:db8::4", + netmask="128", + create=True, + ) + create_interface_in_kernel( + tgen, + "rt5", + "sr0", + "2001:db8::5", + netmask="128", + create=True, + ) + create_interface_in_kernel( + tgen, + "rt6", + "sr0", + "2001:db8::6", + netmask="128", + create=True, + ) + + +def setup_module(mod): + """Sets up the pytest environment""" + + # Verify if kernel requirements are satisfied + result = required_linux_kernel_version("4.10") + if result is not True: + pytest.skip("Kernel requirements are not met") + + # Build the topology + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + # For all registered routers, load the zebra and isis configuration files + for rname, router in tgen.routers().items(): + router.load_config(TopoRouter.RD_ZEBRA, + os.path.join(CWD, '{}/zebra.conf'.format(rname))) + router.load_config(TopoRouter.RD_ISIS, + os.path.join(CWD, '{}/isisd.conf'.format(rname))) + router.load_config(TopoRouter.RD_BGP, + os.path.join(CWD, '{}/bgpd.conf'.format(rname))) + if (os.path.exists('{}/sharpd.conf'.format(rname))): + router.load_config(TopoRouter.RD_SHARP, + os.path.join(CWD, '{}/sharpd.conf'.format(rname))) + + # Start routers + tgen.start_router() + + +def teardown_module(mod): + "Teardown the pytest environment" + + # Teardown the topology + tgen = get_topogen() + tgen.stop_topology() + + +def router_compare_json_output(rname, command, reference): + "Compare router JSON output" + + logger.info('Comparing router "%s" "%s" output', rname, command) + + tgen = get_topogen() + filename = "{}/{}/{}".format(CWD, rname, reference) + expected = json.loads(open(filename).read()) + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = functools.partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) + _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) + assert diff is None, assertmsg + + +def check_ping6(name, dest_addr, expect_connected): + def _check(name, dest_addr, match): + tgen = get_topogen() + output = tgen.gears[name].run("ping6 {} -c 1 -w 1".format(dest_addr)) + logger.info(output) + if match not in output: + return "ping fail" + + match = "{} packet loss".format("0%" if expect_connected else "100%") + logger.info("[+] check {} {} {}".format(name, dest_addr, match)) + tgen = get_topogen() + func = functools.partial(_check, name, dest_addr, match) + success, result = topotest.run_and_expect(func, None, count=10, wait=1) + assert result is None, "Failed" + + +def open_json_file(filename): + try: + with open(filename, "r") as f: + return json.load(f) + except IOError: + assert False, "Could not read file {}".format(filename) + + +def check_rib(name, cmd, expected_file): + def _check(name, cmd, expected_file): + logger.info("polling") + tgen = get_topogen() + router = tgen.gears[name] + output = json.loads(router.vtysh_cmd(cmd)) + expected = open_json_file("{}/{}".format(CWD, expected_file)) + return topotest.json_cmp(output, expected) + + logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) + tgen = get_topogen() + func = functools.partial(_check, name, cmd, expected_file) + success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + assert result is None, "Failed" + + +# +# Step 1 +# +# Test initial network convergence +# +def test_isis_adjacencies(): + logger.info("Test: check IS-IS adjacencies") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + "show_yang_interface_isis_adjacencies.ref", + ) + + +def test_rib_ipv4(): + logger.info("Test: verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ip route isis json", "show_ip_route.ref" + ) + + +def test_rib_ipv6(): + logger.info("Test: verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show ipv6 route json", "show_ipv6_route.ref" + ) + + +def test_srv6_locator(): + logger.info("Test: verify SRv6 Locator") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + router_compare_json_output( + rname, "show segment-routing srv6 locator json", "show_srv6_locator_table.ref" + ) + + +def test_vpn_rib(): + check_rib("rt1", "show bgp ipv6 vpn json", "rt1/vpnv6_rib.ref") + check_rib("rt6", "show bgp ipv6 vpn json", "rt6/vpnv6_rib.ref") + check_rib("rt1", "show ipv6 route vrf vrf10 json", "rt1/vrf10_rib.ref") + check_rib("rt1", "show ipv6 route vrf vrf20 json", "rt1/vrf20_rib.ref") + check_rib("rt6", "show ipv6 route vrf vrf10 json", "rt6/vrf10_rib.ref") + check_rib("rt6", "show ipv6 route vrf vrf20 json", "rt6/vrf20_rib.ref") + check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json") + check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json") + check_rib("ce3", "show ipv6 route json", "ce3/ipv6_rib.json") + check_rib("ce4", "show ipv6 route json", "ce4/ipv6_rib.json") + check_rib("ce5", "show ipv6 route json", "ce5/ipv6_rib.json") + check_rib("ce6", "show ipv6 route json", "ce6/ipv6_rib.json") + + +def test_ping(): + logger.info("Test: verify ping") + tgen = get_topogen() + + # Required linux kernel version for this suite to run. + result = required_linux_kernel_version("6.1") + if result is not True: + pytest.skip("Kernel requirements are not met, kernel version should be >=6.1") + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Setup encap route on rt1, decap route on rt2 + # tgen.gears["rt1"].vtysh_cmd("sharp install seg6-routes fc00:0:9::1 nexthop-seg6 2001:db8:1::2 encap fc00:0:2:6:fe00:: 1") + tgen.gears["rt1"].cmd("ip -6 r a fc00:0:9::1/128 encap seg6 mode encap segs fc00:0:2:6:fe00:: via 2001:db8:1::2") + # tgen.gears["rt6"].vtysh_cmd("sharp install seg6local-routes fc00:0:f00d:: nexthop-seg6local eth-dst End_DT6 254 1") + tgen.gears["rt6"].cmd("ip -6 r a fc00:0:9::1/128 via 2001:db8:10::2 vrf vrf10") + tgen.gears["dst"].cmd("ip -6 r a 2001:db8:1::1/128 via 2001:db8:10::1") + + # Try to ping dst from rt1 + check_ping("rt1", "fc00:0:9::1", True, 10, 1) + + +# Memory leak test template +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)) diff --git a/tests/topotests/zebra_fec_nexthop_resolution/__init__.py b/tests/topotests/zebra_fec_nexthop_resolution/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/__init__.py diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf new file mode 100644 index 0000000000..9d28957d99 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf @@ -0,0 +1,24 @@ +! +router bgp 65500 + bgp router-id 192.0.2.1 + neighbor 192.0.2.3 remote-as 65500 + neighbor 192.0.2.3 update-source lo + neighbor 192.0.2.7 remote-as 65500 + neighbor 192.0.2.7 ttl-security hops 10 + neighbor 192.0.2.7 disable-connected-check + neighbor 192.0.2.7 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.1/32 + no neighbor 192.0.2.3 activate + neighbor 192.0.2.7 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.3 activate + neighbor 192.0.2.3 route-reflector-client + neighbor 192.0.2.3 next-hop-self force + exit-address-family + ! +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r1/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r1/ospfd.conf.after new file mode 100644 index 0000000000..3bb8cf8ac5 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r1/ospfd.conf.after @@ -0,0 +1,25 @@ +log stdout +! +interface lo + ip ospf passive +exit +! +interface r1-eth0 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.1 + network 192.0.2.1/32 area 0.0.0.0 + network 192.168.1.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.1 + segment-routing on + segment-routing global-block 1000 10000 local-block 32000 32999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.1/32 index 11 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r1/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r1/zebra.conf new file mode 100644 index 0000000000..1522e90398 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r1/zebra.conf @@ -0,0 +1,13 @@ +interface lo + ip address 192.0.2.1/32 + mpls enable +exit +! +interface r1-eth0 + ip address 192.168.1.1/24 + mpls enable + link-params + enable + exit-link-params +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf new file mode 100644 index 0000000000..46d2c9a01d --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf @@ -0,0 +1,23 @@ +router bgp 65500 + bgp router-id 192.0.2.2 + neighbor 192.0.2.1 remote-as 65500 + neighbor 192.0.2.1 update-source lo + neighbor 192.0.2.3 remote-as 65500 + neighbor 192.0.2.3 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.2/32 + no neighbor 192.0.2.1 activate + no neighbor 192.0.2.3 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.1 activate + neighbor 192.0.2.1 route-reflector-client + neighbor 192.0.2.1 next-hop-self force + neighbor 192.0.2.3 activate + neighbor 192.0.2.3 route-reflector-client + neighbor 192.0.2.3 next-hop-self force + exit-address-family +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r2/isisd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r2/isisd.conf new file mode 100644 index 0000000000..add181ddae --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r2/isisd.conf @@ -0,0 +1,25 @@ +! +interface lo + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +interface r2-eth1 + ip router isis 2 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +router isis 1 + is-type level-1 + net 49.0000.0007.e901.2223.00 + lsp-timers gen-interval 1 refresh-interval 900 max-lifetime 1200 + mpls-te on + mpls-te router-address 192.0.2.2 + segment-routing on + segment-routing global-block 11000 20000 local-block 36000 36999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.2/32 index 22 no-php-flag +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r2/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r2/ospfd.conf.after new file mode 100644 index 0000000000..8b02669862 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r2/ospfd.conf.after @@ -0,0 +1,32 @@ +log stdout +! +interface lo + ip ospf network point-to-point + ip ospf passive +exit +! +interface r2-eth0 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +interface r2-eth1 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.2 + network 192.0.2.2/32 area 0.0.0.0 + network 192.168.1.0/24 area 0.0.0.0 + network 192.168.2.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.2 + segment-routing on + segment-routing global-block 1000 10000 local-block 36000 36999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.2/32 index 22 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r2/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r2/zebra.conf new file mode 100644 index 0000000000..af0d1eb7fe --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r2/zebra.conf @@ -0,0 +1,16 @@ +! +interface lo + ip address 192.0.2.2/32 + mpls enable +exit +! +interface r2-eth0 + ip address 192.168.1.2/24 + mpls enable +exit +! +interface r2-eth1 + ip address 192.168.2.2/24 + mpls enable +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf new file mode 100644 index 0000000000..060777e7fe --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf @@ -0,0 +1,23 @@ +router bgp 65500 + bgp router-id 192.0.2.3 + neighbor 192.0.2.1 remote-as 65500 + neighbor 192.0.2.1 update-source lo + neighbor 192.0.2.5 remote-as 65500 + neighbor 192.0.2.5 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.3/32 + no neighbor 192.0.2.1 activate + no neighbor 192.0.2.5 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.1 activate + neighbor 192.0.2.1 route-reflector-client + neighbor 192.0.2.1 next-hop-self force + neighbor 192.0.2.5 activate + neighbor 192.0.2.5 route-reflector-client + neighbor 192.0.2.5 next-hop-self force + exit-address-family +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r3/isisd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r3/isisd.conf new file mode 100644 index 0000000000..db6a503bb2 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r3/isisd.conf @@ -0,0 +1,25 @@ +! +interface lo + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +interface r3-eth1 + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +router isis 1 + is-type level-1 + net 49.0000.0007.e901.3333.00 + lsp-timers gen-interval 1 refresh-interval 900 max-lifetime 1200 + mpls-te on + mpls-te router-address 192.0.2.3 + segment-routing on + segment-routing global-block 11000 12000 local-block 36000 36999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.3/32 index 33 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r3/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r3/ospfd.conf.after new file mode 100644 index 0000000000..a3f5ae54f0 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r3/ospfd.conf.after @@ -0,0 +1,26 @@ +log stdout +! +interface lo + ip ospf network point-to-point + ip ospf passive +exit +! +interface r3-eth0 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.3 + network 192.0.2.3/32 area 0.0.0.0 + network 192.168.2.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.3 + segment-routing on + segment-routing global-block 1000 10000 local-block 30000 30999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.3/32 index 33 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r3/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r3/zebra.conf new file mode 100644 index 0000000000..b309e15afa --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r3/zebra.conf @@ -0,0 +1,19 @@ +! +interface lo + ip address 192.0.2.3/32 + mpls enable +exit +! +interface r3-eth0 + ip address 192.168.2.3/24 + mpls enable + link-params + enable + exit-link-params +exit +! +interface r3-eth1 + ip address 192.168.3.3/24 + mpls enable +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf new file mode 100644 index 0000000000..dc052da863 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf @@ -0,0 +1,24 @@ +! +router bgp 65500 + bgp router-id 192.0.2.4 + neighbor 192.0.2.1 remote-as 65500 + neighbor 192.0.2.1 ttl-security hops 10 + neighbor 192.0.2.1 disable-connected-check + neighbor 192.0.2.1 update-source lo + neighbor 192.0.2.3 remote-as 65500 + neighbor 192.0.2.3 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.4/32 + neighbor 192.0.2.1 activate + no neighbor 192.0.2.3 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.3 activate + neighbor 192.0.2.3 route-reflector-client + neighbor 192.0.2.3 next-hop-self force + exit-address-family + ! +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r4/isisd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r4/isisd.conf new file mode 100644 index 0000000000..7096ce081e --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r4/isisd.conf @@ -0,0 +1,31 @@ +! +interface lo + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +interface r4-eth0 + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +interface r4-eth1 + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +router isis 1 + is-type level-1 + net 49.0000.0007.e901.4444.00 + lsp-timers gen-interval 1 refresh-interval 900 max-lifetime 1200 + mpls-te on + mpls-te router-address 192.0.2.4 + segment-routing on + segment-routing global-block 11000 12000 local-block 37000 37999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.4/32 index 44 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r4/ospfd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r4/ospfd.conf new file mode 100644 index 0000000000..c160049675 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r4/ospfd.conf @@ -0,0 +1,19 @@ +! +interface lo + ip ospf area 0 + ip ospf passive +exit +! +interface r4-eth0 + ip ospf area 0 +exit +! +router ospf + mpls-te on + mpls-te router-address 192.0.2.4 + segment-routing on + segment-routing global-block 21000 29000 local-block 31000 31999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.4/32 index 44 no-php-flag +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r4/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r4/zebra.conf new file mode 100644 index 0000000000..8591047906 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r4/zebra.conf @@ -0,0 +1,16 @@ +! +interface lo + ip address 192.0.2.4/32 + mpls enable +exit +! +interface r4-eth0 + ip address 192.168.3.4/24 + mpls enable +exit +! +interface r4-eth1 + ip address 192.168.4.4/24 + mpls enable +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf new file mode 100644 index 0000000000..1c73154e27 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf @@ -0,0 +1,23 @@ +router bgp 65500 + bgp router-id 192.0.2.5 + neighbor 192.0.2.3 remote-as 65500 + neighbor 192.0.2.3 update-source lo + neighbor 192.0.2.7 remote-as 65500 + neighbor 192.0.2.7 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.5/32 + no neighbor 192.0.2.3 activate + no neighbor 192.0.2.7 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.3 activate + neighbor 192.0.2.3 route-reflector-client + neighbor 192.0.2.3 next-hop-self force + neighbor 192.0.2.7 activate + neighbor 192.0.2.7 route-reflector-client + neighbor 192.0.2.7 next-hop-self force + exit-address-family +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r5/isisd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r5/isisd.conf new file mode 100644 index 0000000000..959d5be29b --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r5/isisd.conf @@ -0,0 +1,26 @@ +! +interface lo + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis passive +exit +! +interface r5-eth0 + ip router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +exit +! +router isis 1 + is-type level-1 + net 49.0000.0007.e901.5555.00 + lsp-timers gen-interval 1 refresh-interval 900 max-lifetime 1200 + mpls-te on + mpls-te router-address 192.0.2.5 + segment-routing on + segment-routing global-block 11000 12000 local-block 33000 33999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.5/32 index 55 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r5/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r5/ospfd.conf.after new file mode 100644 index 0000000000..868129f890 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r5/ospfd.conf.after @@ -0,0 +1,26 @@ +log stdout +! +interface lo + ip ospf network point-to-point + ip ospf passive +exit +! +interface r5-eth1 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.5 + network 192.0.2.5/32 area 0.0.0.0 + network 192.168.5.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.5 + segment-routing on + segment-routing global-block 21000 22000 local-block 35000 35999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.5/32 index 55 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r5/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r5/zebra.conf new file mode 100644 index 0000000000..dd519e8d12 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r5/zebra.conf @@ -0,0 +1,19 @@ +! +interface lo + ip address 192.0.2.5/32 + mpls enable +exit +! +interface r5-eth0 + ip address 192.168.4.5/24 + mpls enable +exit +! +interface r5-eth1 + ip address 192.168.5.5/24 + mpls enable + link-params + enable + exit-link-params +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r6/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r6/ospfd.conf.after new file mode 100644 index 0000000000..60c4928f77 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r6/ospfd.conf.after @@ -0,0 +1,32 @@ +log stdout +! +interface lo + ip ospf network point-to-point + ip ospf passive +exit +! +interface r6-eth0 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +interface r6-eth1 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.6 + segment-routing on + segment-routing global-block 21000 22000 local-block 38000 38999 + network 192.0.2.6/32 area 0.0.0.0 + network 192.168.5.0/24 area 0.0.0.0 + network 192.168.6.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.6 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.6/32 index 66 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r6/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r6/zebra.conf new file mode 100644 index 0000000000..5e16e3e434 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r6/zebra.conf @@ -0,0 +1,22 @@ +! +interface lo + ip address 192.0.2.6/32 + mpls enable +exit +! +interface r6-eth0 + ip address 192.168.5.6/24 + mpls enable + link-params + enable + exit-link-params +exit +! +interface r6-eth1 + ip address 192.168.6.6/24 + mpls enable + link-params + enable + exit-link-params +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf b/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf new file mode 100644 index 0000000000..eeda9d9cfa --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf @@ -0,0 +1,24 @@ +! +router bgp 65500 + bgp router-id 192.0.2.7 + neighbor 192.0.2.1 remote-as 65500 + neighbor 192.0.2.1 ttl-security hops 10 + neighbor 192.0.2.1 disable-connected-check + neighbor 192.0.2.1 update-source lo + neighbor 192.0.2.5 remote-as 65500 + neighbor 192.0.2.5 update-source lo + ! + address-family ipv4 unicast + network 192.0.2.7/32 + neighbor 192.0.2.1 activate + no neighbor 192.0.2.5 activate + exit-address-family + ! + address-family ipv4 labeled-unicast + neighbor 192.0.2.5 activate + neighbor 192.0.2.5 route-reflector-client + neighbor 192.0.2.5 next-hop-self force + exit-address-family + ! +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r7/ospfd.conf.after b/tests/topotests/zebra_fec_nexthop_resolution/r7/ospfd.conf.after new file mode 100644 index 0000000000..f8e56e1217 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r7/ospfd.conf.after @@ -0,0 +1,26 @@ +log stdout +! +interface lo + ip ospf network point-to-point + ip ospf passive +exit +! +interface r7-eth0 + ip ospf network point-to-point + ip ospf hello-interval 1 +exit +! +router ospf + ospf router-id 192.0.2.7 + network 192.0.2.7/32 area 0.0.0.0 + network 192.168.6.0/24 area 0.0.0.0 + passive-interface lo + capability opaque + mpls-te on + mpls-te router-address 192.0.2.7 + segment-routing on + segment-routing global-block 21000 22000 local-block 31000 31999 + segment-routing node-msd 8 + segment-routing prefix 192.0.2.7/32 index 77 +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/r7/zebra.conf b/tests/topotests/zebra_fec_nexthop_resolution/r7/zebra.conf new file mode 100644 index 0000000000..f520225476 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/r7/zebra.conf @@ -0,0 +1,14 @@ +! +interface lo + ip address 192.0.2.7/32 + mpls enable +exit +! +interface r7-eth0 + ip address 192.168.6.7/24 + mpls enable + link-params + enable + exit-link-params +exit +! diff --git a/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py b/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py new file mode 100644 index 0000000000..984ff3c185 --- /dev/null +++ b/tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python + +# +# Copyright 2022 6WIND S.A. +# +# 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. +# + +""" +Check if fec nexthop resolution works correctly. +""" + +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 + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + """ + r1 ---- r2 ---- r3 ---- r4 ----- r5 ---- r6 ---- r7 + <--- ospf ----> <---- isis -----> <--- ospf ----> + """ + for routern in range(1, 8): + tgen.add_router("r{}".format(routern)) + + switch1 = tgen.add_switch("s1") + switch1.add_link(tgen.gears["r1"]) + switch1.add_link(tgen.gears["r2"]) + + switch2 = tgen.add_switch("s2") + switch2.add_link(tgen.gears["r2"]) + switch2.add_link(tgen.gears["r3"]) + + switch3 = tgen.add_switch("s3") + switch3.add_link(tgen.gears["r3"]) + switch3.add_link(tgen.gears["r4"]) + + switch4 = tgen.add_switch("s4") + switch4.add_link(tgen.gears["r4"]) + switch4.add_link(tgen.gears["r5"]) + + switch5 = tgen.add_switch("s5") + switch5.add_link(tgen.gears["r5"]) + switch5.add_link(tgen.gears["r6"]) + + switch6 = tgen.add_switch("s6") + switch6.add_link(tgen.gears["r6"]) + switch6.add_link(tgen.gears["r7"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + def _enable_mpls_misc(router): + router.run("modprobe mpls_router") + router.run("echo 100000 > /proc/sys/net/mpls/platform_labels") + router.run("echo 1 > /proc/sys/net/mpls/conf/lo/input") + + router = tgen.gears["r1"] + _enable_mpls_misc(router) + + router = tgen.gears["r2"] + _enable_mpls_misc(router) + + router = tgen.gears["r3"] + _enable_mpls_misc(router) + + router = tgen.gears["r4"] + _enable_mpls_misc(router) + + router = tgen.gears["r5"] + _enable_mpls_misc(router) + + router = tgen.gears["r6"] + _enable_mpls_misc(router) + + router = tgen.gears["r7"] + _enable_mpls_misc(router) + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + if rname in ("r1", "r3", "r5", "r7"): + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + if rname in ("r3", "r4", "r5"): + router.load_config( + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + if rname in ("r1", "r2", "r3", "r5", "r6", "r7"): + router.load_config( + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +# There are some startup issued when initialising OSPF +# To avoid those issues, load the ospf configuration after zebra started +def test_zebra_fec_nexthop_resolution_finalise_ospf_config(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + topotest.sleep(2) + + tgen.net["r1"].cmd("vtysh -f {}/r1/ospfd.conf.after".format(CWD)) + tgen.net["r2"].cmd("vtysh -f {}/r2/ospfd.conf.after".format(CWD)) + tgen.net["r3"].cmd("vtysh -f {}/r3/ospfd.conf.after".format(CWD)) + tgen.net["r5"].cmd("vtysh -f {}/r5/ospfd.conf.after".format(CWD)) + tgen.net["r6"].cmd("vtysh -f {}/r6/ospfd.conf.after".format(CWD)) + tgen.net["r7"].cmd("vtysh -f {}/r7/ospfd.conf.after".format(CWD)) + + +def test_zebra_fec_nexthop_resolution_bgp(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _check_bgp_session(): + r1 = tgen.gears["r1"] + + tgen.gears["r3"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") + tgen.gears["r3"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") + tgen.gears["r5"].vtysh_cmd("config \n no mpls fec nexthop-resolution \n end") + tgen.gears["r5"].vtysh_cmd("config \n mpls fec nexthop-resolution \n end") + output = json.loads(r1.vtysh_cmd("show bgp summary json")) + + if output["ipv4Unicast"]["peers"]["192.0.2.7"]["state"] == "Established": + return None + return False + + test_func1 = functools.partial(_check_bgp_session) + _, result1 = topotest.run_and_expect(test_func1, None, count=60, wait=0.5) + assert result1 is None, "Failed to verify the fec_nexthop_resolution: bgp session" + + +def test_zebra_fec_nexthop_resolution_ping(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _check_ping_launch(): + r1 = tgen.gears["r1"] + + ping_launch = "ping 192.0.2.7 -I 192.0.2.1 -c 1" + selected_lines = r1.run(ping_launch).splitlines()[-2:-1] + rtx_stats = "".join(selected_lines[0].split(",")[0:3]) + current = topotest.normalize_text(rtx_stats) + + expected_stats = "1 packets transmitted 1 received 0% packet loss" + expected = topotest.normalize_text(expected_stats) + + if current == expected: + return None + + return False + + test_func2 = functools.partial(_check_ping_launch) + _, result2 = topotest.run_and_expect(test_func2, None, count=60, wait=1) + assert result2 is None, "Failed to verify the fec_nexthop_resolution: ping" + + +def test_zebra_fec_nexthop_resolution_table(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _zebra_check_mpls_table(): + r3 = tgen.gears["r3"] + inLabel = 0 + outLabels = 0 + + """ + Retrieve inLabel from MPLS FEC table + """ + mpls_fec = r3.vtysh_cmd("show mpls fec 192.0.2.7/32") + lines = mpls_fec.split("\n") + for line in lines: + if "Label" in line: + inLabel = line.split(": ", 1)[1] + + """ + Retrieve outLabel from BGP + """ + output = json.loads(r3.vtysh_cmd("show ip route 192.0.2.7/32 json")) + + outLabels = output["192.0.2.7/32"][0]["nexthops"][1]["labels"] + + if (inLabel == 0) or (outLabels == 0): + return True + + """ + Compare expected data with real data + """ + output = json.loads(r3.vtysh_cmd("show mpls table " + str(inLabel) + " json")) + + expected = { + "inLabel": int(inLabel), + "installed": True, + "nexthops": [ + { + "type": "BGP", + "outLabel": outLabels[0], + "outLabelStack": outLabels, + "distance": 20, + "installed": True, + "nexthop": "192.168.3.4", + } + ], + } + return topotest.json_cmp(output, expected) + + test_func3 = functools.partial(_zebra_check_mpls_table) + _, result3 = topotest.run_and_expect(test_func3, None, count=60, wait=0.5) + assert result3 is None, "Failed to verify the fec_nexthop_resolution: mpls table" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/zebra_seg6local_route/r1/routes.json b/tests/topotests/zebra_seg6local_route/r1/routes.json index e391922566..7dcc6450fa 100644 --- a/tests/topotests/zebra_seg6local_route/r1/routes.json +++ b/tests/topotests/zebra_seg6local_route/r1/routes.json @@ -119,5 +119,78 @@ }] }], "required_kernel": "5.14" + }, + { + "in": { + "dest": "6::1", + "context": "End_DX6 2001::1" + }, + "out":[{ + "prefix":"6::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DX6" } + }] + }] + }, + { + "in": { + "dest": "7::1", + "context": "End_DT4 10" + }, + "out":[{ + "prefix":"7::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DT4" } + }] + }], + "required_kernel": "5.11" + }, + { + "in": { + "dest": "8::1", + "context": "End_DT6 10" + }, + "out":[{ + "prefix":"8::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DT6" } + }] + }] } ] diff --git a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py index a90f5c9c98..59c681df48 100755 --- a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py +++ b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py @@ -42,7 +42,7 @@ def setup_module(mod): tgen = Topogen({None: "r1"}, mod.__name__) tgen.start_topology() router_list = tgen.routers() - for rname, router in tgen.routers().items(): + for rname, router in router_list.items(): router.run( "/bin/bash {}".format(os.path.join(CWD, "{}/setup.sh".format(rname))) ) |
