summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/isisd/test_fuzz_isis_tlv_tests.h.gzbin221814 -> 221875 bytes
-rw-r--r--tests/lib/test_ttable.c36
-rw-r--r--tests/topotests/all_protocol_startup/r1/ip_nht.ref24
-rw-r--r--tests/topotests/all_protocol_startup/r1/ipv6_nht.ref6
-rw-r--r--tests/topotests/bgp_dual_as/__init__.py0
-rw-r--r--tests/topotests/bgp_dual_as/r1/frr.conf11
-rw-r--r--tests/topotests/bgp_dual_as/r2/frr.conf10
-rw-r--r--tests/topotests/bgp_dual_as/test_bgp_dual_as.py124
-rwxr-xr-xtests/topotests/bgp_l3vpn_to_bgp_vrf/test_bgp_l3vpn_to_bgp_vrf.py6
-rw-r--r--tests/topotests/bgp_peer_group_solo/__init__.py0
-rw-r--r--tests/topotests/bgp_peer_group_solo/r1/frr.conf21
-rw-r--r--tests/topotests/bgp_peer_group_solo/r2/frr.conf10
-rw-r--r--tests/topotests/bgp_peer_group_solo/r3/frr.conf10
-rw-r--r--tests/topotests/bgp_peer_group_solo/test_bgp_peer_group_solo.py102
-rw-r--r--tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py35
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py2
-rw-r--r--tests/topotests/bgp_vpn_import_nexthop_default_vrf/__init__.py0
-rw-r--r--tests/topotests/bgp_vpn_import_nexthop_default_vrf/r1/frr.conf29
-rw-r--r--tests/topotests/bgp_vpn_import_nexthop_default_vrf/r2/frr.conf34
-rw-r--r--tests/topotests/bgp_vpn_import_nexthop_default_vrf/test_bgp_vpn_import_nexthop_default_vrf.py145
-rw-r--r--tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_init.json6
-rw-r--r--tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r1_vrf1.json6
-rw-r--r--tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf2.json9
-rw-r--r--tests/topotests/bgp_vpnv4_noretain/r1/ipv4_vrf_all_routes_plus_r2_vrf3.json9
-rwxr-xr-xtests/topotests/conftest.py40
-rw-r--r--tests/topotests/dump_of_bgp/r1/frr.conf12
-rw-r--r--tests/topotests/dump_of_bgp/r2/frr.conf17
-rw-r--r--tests/topotests/dump_of_bgp/test_dump_of_bgp.py102
-rw-r--r--tests/topotests/example_munet/r1/frr.conf2
-rw-r--r--tests/topotests/example_munet/r2/frr.conf4
-rw-r--r--tests/topotests/example_munet/r3/frr.conf2
-rw-r--r--tests/topotests/example_munet/test_munet.py18
-rw-r--r--tests/topotests/forwarding_on_off/r1/frr.conf14
-rw-r--r--tests/topotests/forwarding_on_off/r2/frr.conf19
-rw-r--r--tests/topotests/forwarding_on_off/r3/frr.conf15
-rw-r--r--tests/topotests/forwarding_on_off/test_forwarding_on_off.py104
-rw-r--r--tests/topotests/isis_topo1/test_isis_topo1.py2
-rw-r--r--tests/topotests/kinds.yaml3
-rw-r--r--tests/topotests/lib/common_config.py12
-rw-r--r--tests/topotests/lib/pim.py2
-rw-r--r--tests/topotests/lib/topogen.py6
-rw-r--r--tests/topotests/lib/topotest.py18
-rw-r--r--tests/topotests/mgmt_oper/oper.py20
-rw-r--r--tests/topotests/mgmt_oper/r1/frr-yanglib.conf10
-rw-r--r--tests/topotests/mgmt_oper/test_yanglib.py45
-rw-r--r--tests/topotests/munet/cli.py56
-rw-r--r--tests/topotests/munet/native.py4
-rw-r--r--tests/topotests/munet/testing/util.py26
-rw-r--r--tests/topotests/nhrp_redundancy/host/frr.conf4
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/frr.conf25
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_cache.json (renamed from tests/topotests/nhrp_redundancy/r4/nhrp_cache.json)16
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_cache_nhs1_down.json40
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_route.json (renamed from tests/topotests/nhrp_redundancy/r5/nhrp_route.json)18
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_route_nhs1_down.json49
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut.json (renamed from tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json)32
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_route_shortcut_nhs1_down.json96
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_absent.json5
-rw-r--r--tests/topotests/nhrp_redundancy/nhc1/nhrp_shortcut_present.json9
-rw-r--r--tests/topotests/nhrp_redundancy/nhc2/frr.conf25
-rw-r--r--tests/topotests/nhrp_redundancy/nhc2/nhrp_cache.json (renamed from tests/topotests/nhrp_redundancy/r5/nhrp_cache.json)16
-rw-r--r--tests/topotests/nhrp_redundancy/nhc2/nhrp_cache_nhs1_down.json40
-rw-r--r--tests/topotests/nhrp_redundancy/nhc2/nhrp_route.json (renamed from tests/topotests/nhrp_redundancy/r4/nhrp_route.json)18
-rw-r--r--tests/topotests/nhrp_redundancy/nhc2/nhrp_route_nhs1_down.json49
-rw-r--r--tests/topotests/nhrp_redundancy/nhs1/frr.conf19
-rw-r--r--tests/topotests/nhrp_redundancy/nhs1/nhrp_cache.json (renamed from tests/topotests/nhrp_redundancy/r1/nhrp_cache.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs1/nhrp_route.json (renamed from tests/topotests/nhrp_redundancy/r3/nhrp_route.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs2/frr.conf19
-rw-r--r--tests/topotests/nhrp_redundancy/nhs2/nhrp_cache.json (renamed from tests/topotests/nhrp_redundancy/r2/nhrp_cache.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs2/nhrp_cache_nhs1_down.json40
-rw-r--r--tests/topotests/nhrp_redundancy/nhs2/nhrp_route.json (renamed from tests/topotests/nhrp_redundancy/r1/nhrp_route.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs2/nhrp_route_nhs1_down.json48
-rw-r--r--tests/topotests/nhrp_redundancy/nhs3/frr.conf19
-rw-r--r--tests/topotests/nhrp_redundancy/nhs3/nhrp_cache.json (renamed from tests/topotests/nhrp_redundancy/r3/nhrp_cache.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs3/nhrp_cache_nhs1_down.json40
-rw-r--r--tests/topotests/nhrp_redundancy/nhs3/nhrp_route.json (renamed from tests/topotests/nhrp_redundancy/r2/nhrp_route.json)12
-rw-r--r--tests/topotests/nhrp_redundancy/nhs3/nhrp_route_nhs1_down.json48
-rw-r--r--tests/topotests/nhrp_redundancy/r1/nhrpd.conf9
-rw-r--r--tests/topotests/nhrp_redundancy/r1/zebra.conf12
-rw-r--r--tests/topotests/nhrp_redundancy/r2/nhrpd.conf9
-rw-r--r--tests/topotests/nhrp_redundancy/r2/zebra.conf12
-rw-r--r--tests/topotests/nhrp_redundancy/r3/nhrpd.conf9
-rw-r--r--tests/topotests/nhrp_redundancy/r3/zebra.conf12
-rw-r--r--tests/topotests/nhrp_redundancy/r4/nhrpd.conf11
-rw-r--r--tests/topotests/nhrp_redundancy/r4/zebra.conf16
-rw-r--r--tests/topotests/nhrp_redundancy/r5/nhrpd.conf11
-rw-r--r--tests/topotests/nhrp_redundancy/r5/zebra.conf16
-rw-r--r--tests/topotests/nhrp_redundancy/r7/zebra.conf4
-rw-r--r--tests/topotests/nhrp_redundancy/router/frr.conf (renamed from tests/topotests/nhrp_redundancy/r6/zebra.conf)4
-rw-r--r--tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot38
-rw-r--r--tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py378
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt4
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt6
-rwxr-xr-xtests/topotests/pim_cand_rp_bsr/__init__.py0
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r1/frr.conf25
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r2/frr.conf22
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r3/frr.conf32
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r4/frr.conf37
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r5/frr.conf17
-rw-r--r--tests/topotests/pim_cand_rp_bsr/r6/frr.conf22
-rw-r--r--tests/topotests/pim_cand_rp_bsr/test_pim_cand_rp_bsr.py324
-rw-r--r--tests/topotests/pytest.ini3
-rw-r--r--tests/topotests/srv6_encap_src_addr/r1/zebra.conf1
-rw-r--r--tests/topotests/srv6_sid_manager/ce1/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce1/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce1/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/ce2/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce2/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce2/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/ce3/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce3/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce3/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/ce4/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce4/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce4/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/ce5/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce5/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce5/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/ce6/bgpd.conf8
-rw-r--r--tests/topotests/srv6_sid_manager/ce6/ipv6_rib.json58
-rw-r--r--tests/topotests/srv6_sid_manager/ce6/zebra.conf14
-rw-r--r--tests/topotests/srv6_sid_manager/dst/sharpd.conf0
-rw-r--r--tests/topotests/srv6_sid_manager/dst/zebra.conf22
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/bgpd.conf66
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/isisd.conf35
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/sharpd.conf0
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/show_ip_route.ref276
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/show_ipv6_route.ref314
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/show_yang_interface_isis_adjacencies.ref32
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/vpnv6_rib.ref169
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/vrf10_rib.ref86
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/vrf20_rib.ref92
-rw-r--r--tests/topotests/srv6_sid_manager/rt1/zebra.conf37
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/isisd.conf48
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/show_ip_route.ref320
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/show_ipv6_route.ref346
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/show_yang_interface_isis_adjacencies.ref70
-rw-r--r--tests/topotests/srv6_sid_manager/rt2/zebra.conf34
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/isisd.conf48
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/show_ip_route.ref320
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/show_ipv6_route.ref346
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/show_yang_interface_isis_adjacencies.ref70
-rw-r--r--tests/topotests/srv6_sid_manager/rt3/zebra.conf33
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/isisd.conf56
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/show_ip_route.ref296
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/show_ipv6_route.ref346
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/show_yang_interface_isis_adjacencies.ref82
-rw-r--r--tests/topotests/srv6_sid_manager/rt4/zebra.conf36
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/isisd.conf56
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/show_ip_route.ref296
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/show_ipv6_route.ref346
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/show_yang_interface_isis_adjacencies.ref82
-rw-r--r--tests/topotests/srv6_sid_manager/rt5/zebra.conf36
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/bgpd.conf67
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/isisd.conf42
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/sharpd.conf0
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/show_ip_route.ref273
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/show_ipv6_route.ref312
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/show_srv6_locator_table.ref15
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/show_yang_interface_isis_adjacencies.ref44
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/vpnv6_rib.ref169
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/vrf10_rib.ref92
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/vrf20_rib.ref86
-rw-r--r--tests/topotests/srv6_sid_manager/rt6/zebra.conf45
-rw-r--r--tests/topotests/srv6_sid_manager/test_srv6_sid_manager.py421
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/__init__.py0
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r1/bgpd.conf24
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r1/ospfd.conf.after25
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r1/zebra.conf13
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r2/bgpd.conf23
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r2/isisd.conf25
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r2/ospfd.conf.after32
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r2/zebra.conf16
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r3/bgpd.conf23
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r3/isisd.conf25
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r3/ospfd.conf.after26
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r3/zebra.conf19
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r4/bgpd.conf24
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r4/isisd.conf31
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r4/ospfd.conf19
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r4/zebra.conf16
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r5/bgpd.conf23
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r5/isisd.conf26
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r5/ospfd.conf.after26
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r5/zebra.conf19
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r6/ospfd.conf.after32
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r6/zebra.conf22
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r7/bgpd.conf24
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r7/ospfd.conf.after26
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/r7/zebra.conf14
-rw-r--r--tests/topotests/zebra_fec_nexthop_resolution/test_zebra_fec_nexthop_resolution.py259
-rw-r--r--tests/topotests/zebra_seg6local_route/r1/routes.json73
-rwxr-xr-xtests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py2
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
index 195a7dd8c1..05e9f723a1 100644
--- a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
+++ b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Binary files differ
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)))
)