summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/bgpd/test_peer_attr.c2
-rw-r--r--tests/helpers/c/main.c2
-rw-r--r--tests/isisd/test_common.c331
-rw-r--r--tests/isisd/test_common.h82
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c11
-rw-r--r--tests/isisd/test_isis_lspdb.c10
-rw-r--r--tests/isisd/test_isis_spf.c313
-rw-r--r--tests/isisd/test_isis_spf.in16
-rw-r--r--tests/isisd/test_isis_spf.py4
-rw-r--r--tests/isisd/test_isis_spf.refout703
-rw-r--r--tests/isisd/test_isis_vertex_queue.c9
-rw-r--r--tests/isisd/test_topologies.c3307
-rw-r--r--tests/lib/cli/common_cli.c2
-rw-r--r--tests/lib/cli/test_commands.c2
-rw-r--r--tests/lib/northbound/test_oper_data.c2
-rw-r--r--tests/subdir.am16
-rw-r--r--tests/topotests/all-protocol-startup/r1/bgpd.conf4
-rwxr-xr-xtests/topotests/all-protocol-startup/test_all_protocol_startup.py29
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf1
-rw-r--r--tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf1
-rw-r--r--tests/topotests/bfd-profiles-topo1/r1/ospfd.conf2
-rw-r--r--tests/topotests/bfd-profiles-topo1/r2/bgpd.conf2
-rw-r--r--tests/topotests/bfd-profiles-topo1/r3/bgpd.conf1
-rw-r--r--tests/topotests/bfd-profiles-topo1/r4/bgpd.conf1
-rw-r--r--tests/topotests/bfd-profiles-topo1/r6/ospfd.conf2
-rw-r--r--tests/topotests/bfd-topo1/r1/bgpd.conf1
-rw-r--r--tests/topotests/bfd-topo1/r2/bgpd.conf3
-rw-r--r--tests/topotests/bfd-topo1/r3/bgpd.conf1
-rw-r--r--tests/topotests/bfd-topo1/r4/bgpd.conf1
-rw-r--r--tests/topotests/bfd-topo2/r1/bgpd.conf1
-rw-r--r--tests/topotests/bfd-topo2/r2/bgpd.conf1
-rw-r--r--tests/topotests/bfd-topo2/r2/ospf6d.conf2
-rw-r--r--tests/topotests/bfd-topo2/r2/ospfd.conf2
-rw-r--r--tests/topotests/bfd-topo2/r3/ospfd.conf2
-rw-r--r--tests/topotests/bfd-topo2/r4/ospf6d.conf2
-rw-r--r--tests/topotests/bfd-topo3/r1/bgpd.conf3
-rw-r--r--tests/topotests/bfd-topo3/r2/bgpd.conf2
-rw-r--r--tests/topotests/bfd-topo3/r3/bgpd.conf3
-rw-r--r--tests/topotests/bfd-topo3/r4/bgpd.conf2
-rw-r--r--tests/topotests/bfd-vrf-topo1/r1/bgpd.conf1
-rw-r--r--tests/topotests/bfd-vrf-topo1/r2/bgpd.conf3
-rw-r--r--tests/topotests/bfd-vrf-topo1/r3/bgpd.conf1
-rw-r--r--tests/topotests/bfd-vrf-topo1/r4/bgpd.conf1
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd.conf18
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd_multi_vrf.conf40
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd_multi_vrf_prefix.conf37
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd_vrf.conf21
-rw-r--r--tests/topotests/bgp-auth/R1/bgpd_vrf_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R1/ospfd.conf4
-rw-r--r--tests/topotests/bgp-auth/R1/ospfd_multi_vrf.conf9
-rw-r--r--tests/topotests/bgp-auth/R1/ospfd_vrf.conf4
-rw-r--r--tests/topotests/bgp-auth/R1/zebra.conf21
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd.conf18
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd_multi_vrf.conf37
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd_multi_vrf_prefix.conf37
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd_vrf.conf18
-rw-r--r--tests/topotests/bgp-auth/R2/bgpd_vrf_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R2/ospfd.conf4
-rw-r--r--tests/topotests/bgp-auth/R2/ospfd_multi_vrf.conf9
-rw-r--r--tests/topotests/bgp-auth/R2/ospfd_vrf.conf4
-rw-r--r--tests/topotests/bgp-auth/R2/zebra.conf21
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd.conf18
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd_multi_vrf.conf37
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd_multi_vrf_prefix.conf37
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd_vrf.conf18
-rw-r--r--tests/topotests/bgp-auth/R3/bgpd_vrf_prefix.conf18
-rw-r--r--tests/topotests/bgp-auth/R3/ospfd.conf4
-rw-r--r--tests/topotests/bgp-auth/R3/ospfd_multi_vrf.conf9
-rw-r--r--tests/topotests/bgp-auth/R3/ospfd_vrf.conf4
-rw-r--r--tests/topotests/bgp-auth/R3/zebra.conf21
-rwxr-xr-xtests/topotests/bgp-auth/test_bgp_auth.py747
-rw-r--r--tests/topotests/bgp-basic-functionality-topo1/bgp_basic_functionality.json159
-rwxr-xr-xtests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py560
-rw-r--r--tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf20
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py6
-rwxr-xr-xtests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py6
-rw-r--r--tests/topotests/bgp-evpn-vxlan_topo1/P1/ospfd.conf9
-rw-r--r--tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf1
-rw-r--r--tests/topotests/bgp-evpn-vxlan_topo1/PE1/ospfd.conf5
-rw-r--r--tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf1
-rw-r--r--tests/topotests/bgp-evpn-vxlan_topo1/PE2/ospfd.conf5
-rw-r--r--tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf1
-rwxr-xr-xtests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py6
-rw-r--r--tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf2
-rw-r--r--tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_comm-list_delete/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_comm-list_delete/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_communities_topo1/test_bgp_communities.py6
-rw-r--r--tests/topotests/bgp_default-route_route-map/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_default-route_route-map/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_distance_change/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_distance_change/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf2
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf2
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf1
-rw-r--r--tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf2
-rw-r--r--tests/topotests/bgp_features/r1/bgp_shutdown_summary.json20
-rw-r--r--tests/topotests/bgp_features/r1/bgp_summary.json28
-rw-r--r--tests/topotests/bgp_features/r1/bgpd.conf41
-rw-r--r--tests/topotests/bgp_features/r1/ospf6d.conf22
-rw-r--r--tests/topotests/bgp_features/r1/ospf_neighbor.json16
-rw-r--r--tests/topotests/bgp_features/r1/ospfd.conf23
-rw-r--r--tests/topotests/bgp_features/r1/zebra.conf28
-rw-r--r--tests/topotests/bgp_features/r2/bgp_shutdown_summary.json20
-rw-r--r--tests/topotests/bgp_features/r2/bgp_summary.json28
-rw-r--r--tests/topotests/bgp_features/r2/bgpd.conf41
-rw-r--r--tests/topotests/bgp_features/r2/ospf6d.conf22
-rw-r--r--tests/topotests/bgp_features/r2/ospf_neighbor.json16
-rw-r--r--tests/topotests/bgp_features/r2/ospfd.conf23
-rw-r--r--tests/topotests/bgp_features/r2/zebra.conf28
-rw-r--r--tests/topotests/bgp_features/r3/bgp_summary.json0
-rw-r--r--tests/topotests/bgp_features/r3/ospf6d.conf22
-rw-r--r--tests/topotests/bgp_features/r3/ospf_neighbor.json16
-rw-r--r--tests/topotests/bgp_features/r3/ospfd.conf23
-rw-r--r--tests/topotests/bgp_features/r3/zebra.conf23
-rw-r--r--tests/topotests/bgp_features/r4/bgp_shutdown_summary.json15
-rw-r--r--tests/topotests/bgp_features/r4/bgp_summary.json19
-rw-r--r--tests/topotests/bgp_features/r4/bgpd.conf34
-rw-r--r--tests/topotests/bgp_features/r4/zebra.conf18
-rw-r--r--tests/topotests/bgp_features/r5/bgp_summary.json20
-rw-r--r--tests/topotests/bgp_features/r5/bgpd.conf34
-rw-r--r--tests/topotests/bgp_features/r5/zebra.conf18
-rw-r--r--tests/topotests/bgp_features/test_bgp_features.dot83
-rw-r--r--tests/topotests/bgp_features/test_bgp_features.pdfbin0 -> 20710 bytes
-rwxr-xr-xtests/topotests/bgp_features/test_bgp_features.py267
-rw-r--r--tests/topotests/bgp_flowspec/__init__.py0
-rw-r--r--tests/topotests/bgp_flowspec/exabgp.env54
-rw-r--r--tests/topotests/bgp_flowspec/peer1/exabgp.cfg32
-rw-r--r--tests/topotests/bgp_flowspec/r1/bgpd.conf19
-rw-r--r--tests/topotests/bgp_flowspec/r1/summary.txt53
-rw-r--r--tests/topotests/bgp_flowspec/r1/zebra.conf8
-rwxr-xr-xtests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py208
-rwxr-xr-xtests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py6
-rwxr-xr-xtests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py6
-rw-r--r--tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r1/ospfd.conf4
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf3
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r2/ospfd.conf12
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r3/ospfd.conf8
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r4/ospfd.conf4
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf1
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/ospfd.conf4
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf3
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/ospfd.conf12
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/ospfd.conf8
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf3
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/ospfd.conf4
-rwxr-xr-xtests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py6
-rwxr-xr-xtests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py6
-rw-r--r--tests/topotests/bgp_link_bw_ip/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_link_bw_ip/r10/bgpd.conf1
-rw-r--r--tests/topotests/bgp_link_bw_ip/r2/bgpd.conf3
-rw-r--r--tests/topotests/bgp_link_bw_ip/r3/bgpd.conf2
-rw-r--r--tests/topotests/bgp_link_bw_ip/r4/bgpd.conf3
-rw-r--r--tests/topotests/bgp_link_bw_ip/r5/bgpd.conf2
-rw-r--r--tests/topotests/bgp_link_bw_ip/r6/bgpd.conf2
-rw-r--r--tests/topotests/bgp_link_bw_ip/r7/bgpd.conf1
-rw-r--r--tests/topotests/bgp_link_bw_ip/r8/bgpd.conf1
-rw-r--r--tests/topotests/bgp_link_bw_ip/r9/bgpd.conf1
-rw-r--r--tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf2
-rw-r--r--tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf2
-rw-r--r--tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf1
-rwxr-xr-xtests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py5
-rwxr-xr-xtests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py6
-rw-r--r--tests/topotests/bgp_multiview_topo1/r1/bgpd.conf8
-rw-r--r--tests/topotests/bgp_prefix_sid/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_reject_as_sets/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_reject_as_sets/r2/bgpd.conf2
-rw-r--r--tests/topotests/bgp_reject_as_sets/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r1/ospfd.conf4
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf3
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r2/ospfd.conf12
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r3/ospfd.conf8
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r4/ospfd.conf4
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf3
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf2
-rw-r--r--tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_update_delay/__init__.py0
-rw-r--r--tests/topotests/bgp_update_delay/r1/bgpd.conf10
-rw-r--r--tests/topotests/bgp_update_delay/r1/zebra.conf9
-rw-r--r--tests/topotests/bgp_update_delay/r2/bgpd.conf18
-rw-r--r--tests/topotests/bgp_update_delay/r2/zebra.conf20
-rw-r--r--tests/topotests/bgp_update_delay/r3/bgpd.conf10
-rw-r--r--tests/topotests/bgp_update_delay/r3/zebra.conf9
-rw-r--r--tests/topotests/bgp_update_delay/r4/bgpd.conf11
-rw-r--r--tests/topotests/bgp_update_delay/r4/zebra.conf9
-rw-r--r--tests/topotests/bgp_update_delay/r5/bgpd.conf11
-rw-r--r--tests/topotests/bgp_update_delay/r5/zebra.conf9
-rwxr-xr-xtests/topotests/bgp_update_delay/test_bgp_update_delay.py295
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo1.json563
-rw-r--r--tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo2.json563
-rwxr-xr-xtests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py1848
-rwxr-xr-xtests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py962
-rw-r--r--tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf1
-rw-r--r--tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf1
-rw-r--r--tests/topotests/bgp_vrf_netns/r1/bgpd.conf1
-rw-r--r--tests/topotests/evpn-pim-1/leaf1/bgpd.conf1
-rw-r--r--tests/topotests/evpn-pim-1/leaf2/bgpd.conf1
-rw-r--r--tests/topotests/evpn-pim-1/spine/bgpd.conf2
-rwxr-xr-xtests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py1
-rwxr-xr-xtests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py1
-rw-r--r--tests/topotests/isis-topo1-vrf/__init__.py0
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r1/isisd.conf15
-rw-r--r--tests/topotests/isis-topo1-vrf/r1/r1_route.json57
-rw-r--r--tests/topotests/isis-topo1-vrf/r1/r1_route6.json40
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json14
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r1/r1_route_linux.json13
-rw-r--r--tests/topotests/isis-topo1-vrf/r1/r1_topology.json80
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r1/zebra.conf9
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r2/isisd.conf15
-rw-r--r--tests/topotests/isis-topo1-vrf/r2/r2_route.json57
-rw-r--r--tests/topotests/isis-topo1-vrf/r2/r2_route6.json40
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json14
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r2/r2_route_linux.json13
-rw-r--r--tests/topotests/isis-topo1-vrf/r2/r2_topology.json80
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r2/zebra.conf9
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r3/isisd.conf22
-rw-r--r--tests/topotests/isis-topo1-vrf/r3/r3_route.json112
-rw-r--r--tests/topotests/isis-topo1-vrf/r3/r3_route6.json78
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json26
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r3/r3_route_linux.json24
-rw-r--r--tests/topotests/isis-topo1-vrf/r3/r3_topology.json132
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r3/zebra.conf13
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r4/isisd.conf25
-rw-r--r--tests/topotests/isis-topo1-vrf/r4/r4_route.json105
-rw-r--r--tests/topotests/isis-topo1-vrf/r4/r4_route6.json78
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json26
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r4/r4_route_linux.json24
-rw-r--r--tests/topotests/isis-topo1-vrf/r4/r4_topology.json132
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r4/zebra.conf13
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r5/isisd.conf21
-rw-r--r--tests/topotests/isis-topo1-vrf/r5/r5_route.json106
-rw-r--r--tests/topotests/isis-topo1-vrf/r5/r5_route6.json78
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json26
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r5/r5_route_linux.json24
-rw-r--r--tests/topotests/isis-topo1-vrf/r5/r5_topology.json124
-rwxr-xr-xtests/topotests/isis-topo1-vrf/r5/zebra.conf13
-rwxr-xr-xtests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot100
-rwxr-xr-xtests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpgbin0 -> 74340 bytes
-rwxr-xr-xtests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py455
-rw-r--r--tests/topotests/ldp-oc-acl-topo1/r1/ospfd.conf4
-rw-r--r--tests/topotests/ldp-oc-acl-topo1/r2/ospfd.conf8
-rw-r--r--tests/topotests/ldp-oc-acl-topo1/r3/ospfd.conf4
-rw-r--r--tests/topotests/ldp-oc-acl-topo1/r4/ospfd.conf4
-rw-r--r--tests/topotests/ldp-oc-topo1/r1/ospfd.conf4
-rw-r--r--tests/topotests/ldp-oc-topo1/r2/ospfd.conf8
-rw-r--r--tests/topotests/ldp-oc-topo1/r3/ospfd.conf4
-rw-r--r--tests/topotests/ldp-oc-topo1/r4/ospfd.conf4
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/ce1/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/ce2/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/ce3/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf26
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/ldpd.conf33
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ip_route.ref143
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r2_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r1_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r2_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_binding.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_vc.ref8
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_discovery.ref25
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/show_yang_interface_isis_adjacencies.ref42
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r1/zebra.conf29
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf27
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/ldpd.conf33
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/ospfd.conf19
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ip_route.ref143
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r2_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r1_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r2_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_binding.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_vc.ref8
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_discovery.ref25
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r2_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/show_yang_interface_isis_adjacencies.ref42
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r2/zebra.conf28
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf28
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/ldpd.conf25
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ip_route.ref143
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r2_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref13
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_binding.ref2
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_vc.ref2
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_discovery.ref18
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/show_yang_interface_isis_adjacencies.ref42
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/r3/zebra.conf32
-rw-r--r--tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.dot111
-rwxr-xr-xtests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py625
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/ce1/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/ce2/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/ce3/zebra.conf12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/ldpd.conf33
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/ospf-nbrs.txt0
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/ospfd.conf20
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r1_eth1_shutdown.ref8
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r2_eth1_shutdown.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_neighbor.json26
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_route.ref157
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_binding.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_vc.ref8
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_discovery.ref25
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r1_eth1_shutdown.ref7
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r2_eth1_shutdown.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r1/zebra.conf29
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/ldpd.conf33
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/ospfd.conf19
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r1_eth1_shutdown.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r2_eth1_shutdown.ref8
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_neighbor.json26
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_route.ref157
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_binding.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_vc.ref8
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_discovery.ref25
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref7
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r2/zebra.conf28
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/ldpd.conf25
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/ospfd.conf18
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r1_eth1_shutdown.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r2_eth1_shutdown.ref11
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_neighbor.json26
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_route.ref157
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_binding.ref2
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_vc.ref2
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_binding.ref44
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_discovery.ref18
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_neighbor.ref16
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref12
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/r3/zebra.conf32
-rw-r--r--tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.dot111
-rwxr-xr-xtests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py429
-rw-r--r--tests/topotests/ldp-topo1/r1/ospfd.conf4
-rw-r--r--tests/topotests/ldp-topo1/r2/ospfd.conf12
-rw-r--r--tests/topotests/ldp-topo1/r3/ospfd.conf8
-rw-r--r--tests/topotests/ldp-topo1/r4/ospfd.conf4
-rw-r--r--tests/topotests/ldp-vpls-topo1/r1/ospfd.conf8
-rw-r--r--tests/topotests/ldp-vpls-topo1/r2/ospfd.conf8
-rw-r--r--tests/topotests/ldp-vpls-topo1/r3/ospfd.conf8
-rw-r--r--tests/topotests/lib/bgp.py55
-rw-r--r--tests/topotests/lib/common_config.py622
-rw-r--r--tests/topotests/lib/topogen.py25
-rw-r--r--tests/topotests/lib/topotest.py113
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json28
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/ospfd.conf7
-rw-r--r--tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json37
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json34
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/ospfd.conf8
-rw-r--r--tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json12
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json16
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/ospfd.conf5
-rw-r--r--tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json8
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json27
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/ospfd.conf5
-rw-r--r--tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json8
-rw-r--r--tests/topotests/ospf-topo1/r1/ospf6d.conf4
-rw-r--r--tests/topotests/ospf-topo1/r1/ospfd.conf4
-rw-r--r--tests/topotests/ospf-topo1/r2/ospf6d.conf8
-rw-r--r--tests/topotests/ospf-topo1/r2/ospfd.conf4
-rw-r--r--tests/topotests/ospf-topo1/r3/ospf6d.conf12
-rw-r--r--tests/topotests/ospf-topo1/r3/ospfd.conf8
-rw-r--r--tests/topotests/ospf-topo1/r4/ospf6d.conf8
-rw-r--r--tests/topotests/ospf-topo1/r4/ospfd.conf4
-rw-r--r--tests/topotests/ospf-topo2/r1/ospfd.conf2
-rw-r--r--tests/topotests/ospf-topo2/r2/ospfd.conf2
-rw-r--r--tests/topotests/pim-basic/r1/bgpd.conf1
-rw-r--r--tests/topotests/pim-basic/rp/bgpd.conf1
444 files changed, 20211 insertions, 282 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 5414cb8cc9..5e809a81e6 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -13,6 +13,7 @@
/isisd/test_fuzz_isis_tlv
/isisd/test_fuzz_isis_tlv_tests.h
/isisd/test_isis_lspdb
+/isisd/test_isis_spf
/isisd/test_isis_vertex_queue
/lib/cli/test_cli
/lib/cli/test_cli_clippy.c
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index f6a892df42..0979622eb3 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -1387,7 +1387,7 @@ static void bgp_startup(void)
master = thread_master_create(NULL);
yang_init(true);
- nb_init(master, NULL, 0);
+ nb_init(master, NULL, 0, false);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_option_set(BGP_OPT_NO_LISTEN);
vrf_init(NULL, NULL, NULL, NULL, NULL);
diff --git a/tests/helpers/c/main.c b/tests/helpers/c/main.c
index 68ed16d513..7f15996daa 100644
--- a/tests/helpers/c/main.c
+++ b/tests/helpers/c/main.c
@@ -156,7 +156,7 @@ int main(int argc, char **argv)
vty_init(master, false);
lib_cmd_init();
yang_init(true);
- nb_init(master, NULL, 0);
+ nb_init(master, NULL, 0, false);
/* OSPF vty inits. */
test_vty_init();
diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c
new file mode 100644
index 0000000000..536847a1da
--- /dev/null
+++ b/tests/isisd/test_common.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2020 NetDEF, Inc.
+ * Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "isisd/isisd.h"
+#include "isisd/isis_dynhn.h"
+#include "isisd/isis_mt.h"
+
+#include "test_common.h"
+
+struct thread_master *master;
+struct zebra_privs_t isisd_privs;
+
+int isis_sock_init(struct isis_circuit *circuit)
+{
+ return 0;
+}
+
+const struct isis_test_node *
+test_topology_find_node(const struct isis_topology *topology,
+ const char *hostname, uint8_t pseudonode_id)
+{
+ for (size_t i = 0; topology->nodes[i].hostname[0]; i++)
+ if (strmatch(hostname, topology->nodes[i].hostname)
+ && pseudonode_id == topology->nodes[i].pseudonode_id)
+ return &topology->nodes[i];
+
+ return NULL;
+}
+
+const struct isis_topology *
+test_topology_find(struct isis_topology *test_topologies, uint16_t number)
+{
+ for (size_t i = 0; test_topologies[i].number; i++)
+ if (test_topologies[i].number == number)
+ return &test_topologies[i];
+
+ return NULL;
+}
+
+static const struct isis_test_node *
+test_find_adjacency(const struct isis_test_node *tnode, const char *hostname)
+{
+ for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
+ const struct isis_test_adj *tadj;
+
+ tadj = &tnode->adjacencies[i];
+ if (strmatch(hostname, tadj->hostname))
+ return tnode;
+ }
+
+ return NULL;
+}
+
+static struct isis_lsp *lsp_add(struct lspdb_head *lspdb,
+ struct isis_area *area, int level,
+ const uint8_t *sysid, uint8_t pseudonode_id)
+{
+ struct isis_lsp *lsp;
+ uint8_t lspid[ISIS_SYS_ID_LEN + 2];
+
+ memcpy(lspid, sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(lspid) = pseudonode_id;
+ LSP_FRAGMENT(lspid) = 0;
+
+ lsp = lsp_new(area, lspid, 6000, 1, 0, 0, NULL, level);
+ lsp->tlvs = isis_alloc_tlvs();
+ lspdb_add(lspdb, lsp);
+
+ return lsp;
+}
+
+static void lsp_add_ip_reach(struct isis_lsp *lsp,
+ const struct isis_test_node *tnode,
+ const char *prefix_str, uint32_t *next_sid_index)
+{
+ struct prefix prefix;
+ struct sr_prefix_cfg pcfg = {};
+ struct sr_prefix_cfg *pcfg_p = NULL;
+
+ if (str2prefix(prefix_str, &prefix) != 1) {
+ zlog_debug("%s: invalid network: %s", __func__, prefix_str);
+ return;
+ }
+
+ if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
+ pcfg_p = &pcfg;
+
+ pcfg.sid = *next_sid_index;
+ *next_sid_index = *next_sid_index + 1;
+ pcfg.sid_type = SR_SID_VALUE_TYPE_INDEX;
+ pcfg.last_hop_behavior = SR_LAST_HOP_BEHAVIOR_PHP;
+ }
+
+ if (prefix.family == AF_INET)
+ isis_tlvs_add_extended_ip_reach(lsp->tlvs,
+ (struct prefix_ipv4 *)&prefix,
+ 10, false, pcfg_p);
+ else
+ isis_tlvs_add_ipv6_reach(lsp->tlvs, ISIS_MT_IPV6_UNICAST,
+ (struct prefix_ipv6 *)&prefix, 10,
+ false, pcfg_p);
+}
+
+static void lsp_add_reach(struct isis_lsp *lsp,
+ const struct isis_test_node *tnode,
+ const uint8_t *ne_id, uint8_t pseudonode_id,
+ uint32_t metric, int family, mpls_label_t *next_label)
+{
+ uint8_t nodeid[ISIS_SYS_ID_LEN + 1];
+ uint16_t mtid;
+ struct isis_ext_subtlvs *ext = NULL;
+
+ memcpy(nodeid, ne_id, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(nodeid) = pseudonode_id;
+
+ if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
+ struct isis_adj_sid *adj_sid;
+
+ adj_sid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*adj_sid));
+ adj_sid->family = family;
+ SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG);
+ SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_LFLG);
+ if (family == AF_INET6)
+ SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_FFLG);
+ adj_sid->weight = 0;
+ adj_sid->sid = *next_label;
+ *next_label = *next_label + 1;
+
+ ext = isis_alloc_ext_subtlvs();
+ isis_tlvs_add_adj_sid(ext, adj_sid);
+ }
+
+ mtid = (family == AF_INET) ? ISIS_MT_IPV4_UNICAST
+ : ISIS_MT_IPV6_UNICAST;
+
+ isis_tlvs_add_extended_reach(lsp->tlvs, mtid, nodeid, metric, ext);
+}
+
+static void lsp_add_router_capability(struct isis_lsp *lsp,
+ const struct isis_test_node *tnode)
+{
+ struct isis_router_cap cap = {};
+
+ if (!tnode->router_id)
+ return;
+
+ if (inet_pton(AF_INET, tnode->router_id, &cap.router_id) != 1) {
+ zlog_debug("%s: invalid router-id: %s", __func__,
+ tnode->router_id);
+ return;
+ }
+
+ if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
+ cap.srgb.flags =
+ ISIS_SUBTLV_SRGB_FLAG_I | ISIS_SUBTLV_SRGB_FLAG_V;
+ cap.srgb.lower_bound = tnode->srgb.lower_bound
+ ? tnode->srgb.lower_bound
+ : SRGB_DFTL_LOWER_BOUND;
+ cap.srgb.range_size = tnode->srgb.range_size
+ ? tnode->srgb.range_size
+ : SRGB_DFTL_RANGE_SIZE;
+ cap.algo[0] = SR_ALGORITHM_SPF;
+ cap.algo[1] = SR_ALGORITHM_UNSET;
+ }
+
+ isis_tlvs_set_router_capability(lsp->tlvs, &cap);
+}
+
+static void lsp_add_mt_router_info(struct isis_lsp *lsp,
+ const struct isis_test_node *tnode)
+{
+ if (tnode->protocols.ipv4)
+ isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV4_UNICAST, 0,
+ false);
+ if (tnode->protocols.ipv6)
+ isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV6_UNICAST, 0,
+ false);
+}
+
+static void lsp_add_protocols_supported(struct isis_lsp *lsp,
+ const struct isis_test_node *tnode)
+{
+ struct nlpids nlpids = {};
+
+ if (!tnode->protocols.ipv4 && !tnode->protocols.ipv6)
+ return;
+
+ if (tnode->protocols.ipv4) {
+ nlpids.nlpids[nlpids.count] = NLPID_IP;
+ nlpids.count++;
+ }
+ if (tnode->protocols.ipv6) {
+ nlpids.nlpids[nlpids.count] = NLPID_IPV6;
+ nlpids.count++;
+ }
+ isis_tlvs_set_protocols_supported(lsp->tlvs, &nlpids);
+}
+
+static int topology_load_node_level(const struct isis_topology *topology,
+ const struct isis_test_node *tnode,
+ size_t tnode_index, struct isis_area *area,
+ struct lspdb_head *lspdb, int level)
+{
+ struct isis_lsp *lsp;
+ uint32_t next_sid_index = (tnode_index + 1) * 10;
+ mpls_label_t next_label = 16;
+
+ lsp = lsp_add(lspdb, area, level, tnode->sysid, tnode->pseudonode_id);
+ lsp_add_mt_router_info(lsp, tnode);
+ lsp_add_protocols_supported(lsp, tnode);
+ lsp_add_router_capability(lsp, tnode);
+
+ /* Add IP Reachability Information. */
+ for (size_t i = 0; tnode->networks[i]; i++) {
+ if (i > MAX_NETWORKS) {
+ zlog_debug(
+ "%s: node has too many networks (maximum is %u)",
+ __func__, MAX_NETWORKS);
+ return -1;
+ }
+ lsp_add_ip_reach(lsp, tnode, tnode->networks[i],
+ &next_sid_index);
+ }
+
+ /* Add IS Reachability Information. */
+ for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
+ const struct isis_test_adj *tadj;
+ const struct isis_test_node *tadj_node;
+
+ if (i > MAX_ADJACENCIES) {
+ zlog_debug(
+ "%s: node has too many adjacencies (maximum is %u)",
+ __func__, MAX_ADJACENCIES);
+ return -1;
+ }
+
+ tadj = &tnode->adjacencies[i];
+ tadj_node = test_topology_find_node(topology, tadj->hostname,
+ tadj->pseudonode_id);
+ if (!tadj_node) {
+ zlog_debug(
+ "%s: node \"%s\" has an adjacency with non-existing node \"%s\"",
+ __func__, tnode->hostname, tadj->hostname);
+ return -1;
+ }
+ if (!test_find_adjacency(tadj_node, tnode->hostname)) {
+ zlog_debug(
+ "%s: node \"%s\" has an one-way adjacency with node \"%s\"",
+ __func__, tnode->hostname, tadj->hostname);
+ return -1;
+ }
+
+ if (tnode->pseudonode_id || tadj_node->pseudonode_id
+ || (tnode->protocols.ipv4 && tadj_node->protocols.ipv4))
+ lsp_add_reach(lsp, tnode, tadj_node->sysid,
+ tadj_node->pseudonode_id, tadj->metric,
+ AF_INET, &next_label);
+ if (tadj_node->pseudonode_id
+ || (tnode->protocols.ipv6 && tadj_node->protocols.ipv6))
+ lsp_add_reach(lsp, tnode, tadj_node->sysid,
+ tadj_node->pseudonode_id, tadj->metric,
+ AF_INET6, &next_label);
+ }
+
+ return 0;
+}
+
+static int topology_load_node(const struct isis_topology *topology,
+ const struct isis_test_node *tnode,
+ size_t tnode_index, struct isis_area *area,
+ struct lspdb_head lspdb[])
+{
+ int ret;
+
+ isis_dynhn_insert(tnode->sysid, tnode->hostname, tnode->level);
+
+ for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
+ if ((tnode->level & level) == 0)
+ continue;
+
+ ret = topology_load_node_level(topology, tnode, tnode_index,
+ area, &lspdb[level - 1], level);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+int test_topology_load(const struct isis_topology *topology,
+ struct isis_area *area, struct lspdb_head lspdb[])
+{
+ for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++)
+ lsp_db_init(&lspdb[level - 1]);
+
+ for (size_t i = 0; topology->nodes[i].hostname[0]; i++) {
+ const struct isis_test_node *tnode = &topology->nodes[i];
+ int ret;
+
+ if (i > MAX_NODES) {
+ zlog_debug(
+ "%s: topology has too many nodes (maximum is %u)",
+ __func__, MAX_NODES);
+ return -1;
+ }
+
+ ret = topology_load_node(topology, tnode, i, area, lspdb);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/tests/isisd/test_common.h b/tests/isisd/test_common.h
new file mode 100644
index 0000000000..6fd0d3813e
--- /dev/null
+++ b/tests/isisd/test_common.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 NetDEF, Inc.
+ * Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _COMMON_ISIS_H
+#define _COMMON_ISIS_H
+
+#include "isisd/isisd.h"
+#include "isisd/isis_spf.h"
+#include "isisd/isis_spf_private.h"
+
+#define MAX_HOSTNAME 16
+#define MAX_NETWORKS 8
+#define MAX_ADJACENCIES 8
+#define MAX_NODES 12
+
+#define SRGB_DFTL_LOWER_BOUND 16000
+#define SRGB_DFTL_RANGE_SIZE 8000
+
+struct isis_test_adj {
+ char hostname[MAX_HOSTNAME];
+ uint8_t pseudonode_id;
+ uint32_t metric;
+};
+
+struct isis_test_node {
+ char hostname[MAX_HOSTNAME];
+ uint8_t sysid[ISIS_SYS_ID_LEN];
+ uint8_t pseudonode_id;
+ int level;
+ struct {
+ bool ipv4;
+ bool ipv6;
+ } protocols;
+ const char *router_id;
+ struct {
+ uint32_t lower_bound;
+ uint32_t range_size;
+ } srgb;
+ const char *networks[MAX_NETWORKS + 1];
+ struct isis_test_adj adjacencies[MAX_ADJACENCIES + 1];
+ uint8_t flags;
+};
+#define F_ISIS_TEST_NODE_SR 0x01
+
+struct isis_topology {
+ uint16_t number;
+ struct isis_test_node nodes[MAX_NODES + 1];
+};
+
+/* Prototypes. */
+extern int isis_sock_init(struct isis_circuit *circuit);
+extern const struct isis_test_node *
+test_topology_find_node(const struct isis_topology *topology,
+ const char *hostname, uint8_t pseudonode_id);
+extern const struct isis_topology *
+test_topology_find(struct isis_topology *test_topologies, uint16_t number);
+extern int test_topology_load(const struct isis_topology *topology,
+ struct isis_area *area,
+ struct lspdb_head lspdb[]);
+
+/* Global variables. */
+extern struct thread_master *master;
+extern struct zebra_privs_t isisd_privs;
+extern struct isis_topology test_topologies[];
+
+#endif /* _COMMON_ISIS_H */
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
index 917ea66f13..97aade6578 100644
--- a/tests/isisd/test_fuzz_isis_tlv.c
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -14,16 +14,9 @@
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlvs.h"
-#define TEST_STREAM_SIZE 1500
-
-struct thread_master *master;
-int isis_sock_init(struct isis_circuit *circuit);
-int isis_sock_init(struct isis_circuit *circuit)
-{
- return 0;
-}
+#include "test_common.h"
-struct zebra_privs_t isisd_privs;
+#define TEST_STREAM_SIZE 1500
static bool atexit_registered;
diff --git a/tests/isisd/test_isis_lspdb.c b/tests/isisd/test_isis_lspdb.c
index 6a571eaa84..244922ea4e 100644
--- a/tests/isisd/test_isis_lspdb.c
+++ b/tests/isisd/test_isis_lspdb.c
@@ -2,15 +2,7 @@
#include "isisd/isis_lsp.c"
-struct thread_master *master;
-
-int isis_sock_init(struct isis_circuit *circuit);
-int isis_sock_init(struct isis_circuit *circuit)
-{
- return 0;
-}
-
-struct zebra_privs_t isisd_privs;
+#include "test_common.h"
static void test_lsp_build_list_nonzero_ht(void)
{
diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c
new file mode 100644
index 0000000000..73bb531dc0
--- /dev/null
+++ b/tests/isisd/test_isis_spf.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2020 NetDEF, Inc.
+ * Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include <lib/version.h>
+#include "getopt.h"
+#include "thread.h"
+#include "vty.h"
+#include "command.h"
+#include "log.h"
+#include "vrf.h"
+#include "yang.h"
+
+#include "isisd/isisd.h"
+#include "isisd/isis_dynhn.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_spf.h"
+#include "isisd/isis_spf_private.h"
+
+#include "test_common.h"
+
+enum test_type {
+ TEST_SPF = 1,
+ TEST_REVERSE_SPF,
+};
+
+#define F_DISPLAY_LSPDB 0x01
+#define F_IPV4_ONLY 0x02
+#define F_IPV6_ONLY 0x04
+#define F_LEVEL1_ONLY 0x08
+#define F_LEVEL2_ONLY 0x10
+
+static struct isis *isis;
+
+static void test_run_spf(struct vty *vty, const struct isis_topology *topology,
+ const struct isis_test_node *root,
+ struct isis_area *area, struct lspdb_head *lspdb,
+ int level, int tree, bool reverse)
+{
+ struct isis_spftree *spftree;
+ enum spf_type spf_type;
+
+ /* Run SPF. */
+ spf_type = reverse ? SPF_TYPE_REVERSE : SPF_TYPE_FORWARD;
+ spftree = isis_spftree_new(area, lspdb, root->sysid, level, tree,
+ spf_type, F_SPFTREE_NO_ADJACENCIES);
+ isis_run_spf(spftree);
+
+ /* Print the SPT and the corresponding routing table. */
+ isis_print_spftree(vty, spftree);
+ isis_print_routes(vty, spftree);
+
+ /* Cleanup SPF tree. */
+ isis_spftree_del(spftree);
+}
+
+static int test_run(struct vty *vty, const struct isis_topology *topology,
+ const struct isis_test_node *root, enum test_type test_type,
+ uint8_t flags)
+{
+ struct isis_area *area;
+
+ /* Init topology. */
+ memcpy(isis->sysid, root->sysid, sizeof(isis->sysid));
+ area = isis_area_create("1", NULL);
+ area->is_type = IS_LEVEL_1_AND_2;
+ area->srdb.enabled = true;
+ if (test_topology_load(topology, area, area->lspdb) != 0) {
+ vty_out(vty, "%% Failed to load topology\n");
+ return CMD_WARNING;
+ }
+
+ for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
+ if (level == IS_LEVEL_1 && CHECK_FLAG(flags, F_LEVEL2_ONLY))
+ continue;
+ if (level == IS_LEVEL_2 && CHECK_FLAG(flags, F_LEVEL1_ONLY))
+ continue;
+ if ((root->level & level) == 0)
+ continue;
+
+ /* Print the LDPDB. */
+ if (CHECK_FLAG(flags, F_DISPLAY_LSPDB))
+ show_isis_database_lspdb(vty, area, level - 1,
+ &area->lspdb[level - 1], NULL,
+ ISIS_UI_LEVEL_DETAIL);
+
+ for (int tree = SPFTREE_IPV4; tree <= SPFTREE_IPV6; tree++) {
+ if (tree == SPFTREE_IPV4
+ && CHECK_FLAG(flags, F_IPV6_ONLY))
+ continue;
+ if (tree == SPFTREE_IPV6
+ && CHECK_FLAG(flags, F_IPV4_ONLY))
+ continue;
+
+ switch (test_type) {
+ case TEST_SPF:
+ test_run_spf(vty, topology, root, area,
+ &area->lspdb[level - 1], level,
+ tree, false);
+ break;
+ case TEST_REVERSE_SPF:
+ test_run_spf(vty, topology, root, area,
+ &area->lspdb[level - 1], level,
+ tree, true);
+ break;
+ }
+ }
+ }
+
+ /* Cleanup IS-IS area. */
+ isis_area_destroy(area);
+
+ /* Cleanup hostnames. */
+ dyn_cache_cleanup_all();
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(test_isis, test_isis_cmd,
+ "test isis topology (1-13) root HOSTNAME\
+ <\
+ spf\
+ |reverse-spf\
+ >\
+ [display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
+ "Test command\n"
+ "IS-IS routing protocol\n"
+ "Test topology\n"
+ "Test topology number\n"
+ "SPF root\n"
+ "SPF root hostname\n"
+ "Normal Shortest Path First\n"
+ "Reverse Shortest Path First\n"
+ "Display the LSPDB\n"
+ "Do IPv4 processing only\n"
+ "Do IPv6 processing only\n"
+ "Skip L2 LSPs\n"
+ "Skip L1 LSPs\n")
+{
+ uint16_t topology_number;
+ const struct isis_topology *topology;
+ const struct isis_test_node *root;
+ enum test_type test_type;
+ uint8_t flags = 0;
+ int idx = 0;
+
+ /* Load topology. */
+ argv_find(argv, argc, "topology", &idx);
+ topology_number = atoi(argv[idx + 1]->arg);
+ topology = test_topology_find(test_topologies, topology_number);
+ if (!topology) {
+ vty_out(vty, "%% Topology \"%s\" not found\n",
+ argv[idx + 1]->arg);
+ return CMD_WARNING;
+ }
+
+ /* Find root node. */
+ argv_find(argv, argc, "root", &idx);
+ root = test_topology_find_node(topology, argv[idx + 1]->arg, 0);
+ if (!root) {
+ vty_out(vty, "%% Node \"%s\" not found\n", argv[idx + 1]->arg);
+ return CMD_WARNING;
+ }
+
+ /* Parse test information. */
+ if (argv_find(argv, argc, "spf", &idx))
+ test_type = TEST_SPF;
+ else if (argv_find(argv, argc, "reverse-spf", &idx))
+ test_type = TEST_REVERSE_SPF;
+ else
+ return CMD_WARNING;
+
+ /* Parse control flags. */
+ if (argv_find(argv, argc, "display-lspdb", &idx))
+ SET_FLAG(flags, F_DISPLAY_LSPDB);
+ if (argv_find(argv, argc, "ipv4-only", &idx))
+ SET_FLAG(flags, F_IPV4_ONLY);
+ else if (argv_find(argv, argc, "ipv6-only", &idx))
+ SET_FLAG(flags, F_IPV6_ONLY);
+ if (argv_find(argv, argc, "level-1-only", &idx))
+ SET_FLAG(flags, F_LEVEL1_ONLY);
+ else if (argv_find(argv, argc, "level-2-only", &idx))
+ SET_FLAG(flags, F_LEVEL2_ONLY);
+
+ return test_run(vty, topology, root, test_type, flags);
+}
+
+static void vty_do_exit(int isexit)
+{
+ printf("\nend.\n");
+
+ isis_finish(isis);
+ cmd_terminate();
+ vty_terminate();
+ yang_terminate();
+ thread_master_free(master);
+
+ log_memstats(stderr, "test-isis-spf");
+ if (!isexit)
+ exit(0);
+}
+
+struct option longopts[] = {{"help", no_argument, NULL, 'h'},
+ {"debug", no_argument, NULL, 'd'},
+ {0}};
+
+/* Help information display. */
+static void usage(char *progname, int status)
+{
+ if (status != 0)
+ fprintf(stderr, "Try `%s --help' for more information.\n",
+ progname);
+ else {
+ printf("Usage : %s [OPTION...]\n\
+isisd SPF test program.\n\n\
+-u, --debug Enable debugging\n\
+-h, --help Display this help and exit\n\
+\n\
+Report bugs to %s\n",
+ progname, FRR_BUG_ADDRESS);
+ }
+ exit(status);
+}
+
+int main(int argc, char **argv)
+{
+ char *p;
+ char *progname;
+ struct thread thread;
+ bool debug = false;
+
+ /* Set umask before anything for security */
+ umask(0027);
+
+ /* get program name */
+ progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
+
+ while (1) {
+ int opt;
+
+ opt = getopt_long(argc, argv, "hd", longopts, 0);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt) {
+ case 0:
+ break;
+ case 'd':
+ debug = true;
+ break;
+ case 'h':
+ usage(progname, 0);
+ break;
+ default:
+ usage(progname, 1);
+ break;
+ }
+ }
+
+ /* master init. */
+ master = thread_master_create(NULL);
+ isis_master_init(master);
+
+ /* Library inits. */
+ cmd_init(1);
+ cmd_hostname_set("test");
+ vty_init(master, false);
+ yang_init(true);
+ if (debug)
+ zlog_aux_init("NONE: ", LOG_DEBUG);
+ else
+ zlog_aux_init("NONE: ", ZLOG_DISABLED);
+
+ /* IS-IS inits. */
+ yang_module_load("frr-isisd");
+ isis = isis_new(VRF_DEFAULT_NAME);
+ listnode_add(im->isis, isis);
+ SET_FLAG(im->options, F_ISIS_UNIT_TEST);
+ debug_spf_events |= DEBUG_SPF_EVENTS;
+ debug_events |= DEBUG_EVENTS;
+ debug_rte_events |= DEBUG_RTE_EVENTS;
+
+ /* Install test command. */
+ install_element(VIEW_NODE, &test_isis_cmd);
+
+ /* Read input from .in file. */
+ vty_stdio(vty_do_exit);
+
+ /* Fetch next active thread. */
+ while (thread_fetch(master, &thread))
+ thread_call(&thread);
+
+ /* Not reached. */
+ exit(0);
+}
diff --git a/tests/isisd/test_isis_spf.in b/tests/isisd/test_isis_spf.in
new file mode 100644
index 0000000000..d9a61782e9
--- /dev/null
+++ b/tests/isisd/test_isis_spf.in
@@ -0,0 +1,16 @@
+test isis topology 1 root rt1 spf
+test isis topology 2 root rt1 spf
+test isis topology 3 root rt1 spf ipv4-only
+test isis topology 4 root rt1 spf ipv4-only
+test isis topology 5 root rt1 spf ipv4-only
+test isis topology 6 root rt1 spf ipv4-only
+test isis topology 7 root rt1 spf ipv4-only
+test isis topology 8 root rt1 spf ipv4-only
+test isis topology 9 root rt1 spf
+test isis topology 10 root rt1 spf
+test isis topology 11 root rt1 spf
+test isis topology 12 root rt1 spf ipv4-only
+test isis topology 13 root rt1 spf ipv4-only
+
+test isis topology 4 root rt1 reverse-spf ipv4-only
+test isis topology 11 root rt1 reverse-spf
diff --git a/tests/isisd/test_isis_spf.py b/tests/isisd/test_isis_spf.py
new file mode 100644
index 0000000000..21e7ef6269
--- /dev/null
+++ b/tests/isisd/test_isis_spf.py
@@ -0,0 +1,4 @@
+import frrtest
+
+class TestIsisSPF(frrtest.TestRefOut):
+ program = './test_isis_spf'
diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout
new file mode 100644
index 0000000000..ed0569947c
--- /dev/null
+++ b/tests/isisd/test_isis_spf.refout
@@ -0,0 +1,703 @@
+test# test isis topology 1 root rt1 spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+ rt3 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ - rt3 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
+ rt3 -
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::2/128 20 - rt2 -
+ 2001:db8::3/128 20 - rt3 -
+ 2001:db8::4/128 30 - rt2 -
+ 2001:db8::5/128 30 - rt3 -
+ 2001:db8::6/128 40 - rt2 -
+ - rt3 -
+
+test# test isis topology 2 root rt1 spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt5 TE-IS 10 rt5 - rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+rt1
+rt6 TE-IS 20 rt4 - rt4(4)
+ rt5 - rt5(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+10.0.255.2/32 IP TE 25 rt2 - rt2(4)
+rt3 TE-IS 30 rt3 - rt1(4)
+10.0.255.6/32 IP TE 30 rt4 - rt6(4)
+ rt5 -
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 25 - rt2 -
+ 10.0.255.3/32 40 - rt3 -
+ 10.0.255.4/32 20 - rt4 -
+ 10.0.255.5/32 20 - rt5 -
+ 10.0.255.6/32 30 - rt4 -
+ - rt5 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt5 TE-IS 10 rt5 - rt1(4)
+rt2 TE-IS 15 rt2 - rt1(4)
+rt1
+rt6 TE-IS 20 rt4 - rt4(4)
+ rt5 - rt5(4)
+2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
+2001:db8::5/128 IP6 internal 20 rt5 - rt5(4)
+2001:db8::2/128 IP6 internal 25 rt2 - rt2(4)
+rt3 TE-IS 30 rt3 - rt1(4)
+2001:db8::6/128 IP6 internal 30 rt4 - rt6(4)
+ rt5 -
+2001:db8::3/128 IP6 internal 40 rt3 - rt3(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::2/128 25 - rt2 -
+ 2001:db8::3/128 40 - rt3 -
+ 2001:db8::4/128 20 - rt4 -
+ 2001:db8::5/128 20 - rt5 -
+ 2001:db8::6/128 30 - rt4 -
+ - rt5 -
+
+test# test isis topology 3 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt5 TE-IS 30 rt2 - rt4(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 40 rt2 - rt5(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 40 - rt2 -
+ 10.0.255.6/32 40 - rt2 -
+
+test# test isis topology 4 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ 10.0.255.7/32 40 - rt3 -
+ 10.0.255.8/32 50 - rt2 -
+
+test# test isis topology 5 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+ rt3 - rt7(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+ rt3 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ 10.0.255.7/32 40 - rt3 -
+ 10.0.255.8/32 50 - rt2 -
+ - rt3 -
+
+test# test isis topology 6 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+ rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 -
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+ rt3 -
+rt5 TE-IS 40 rt2 - rt6(4)
+ rt3 -
+rt8 TE-IS 40 rt2 - rt6(4)
+ rt3 -
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+ rt3 -
+rt7 TE-IS 50 rt2 - rt5(4)
+ rt3 - rt8(4)
+10.0.255.5/32 IP TE 50 rt2 - rt5(4)
+ rt3 -
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+ rt3 -
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+ rt3 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ - rt3 -
+ 10.0.255.5/32 50 - rt2 -
+ - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ - rt3 -
+ 10.0.255.7/32 60 - rt2 -
+ - rt3 -
+ 10.0.255.8/32 50 - rt2 -
+ - rt3 -
+
+test# test isis topology 7 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt5 TE-IS 20 rt4 - rt4(4)
+rt7 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+rt2 TE-IS 30 rt4 - rt5(4)
+rt6 TE-IS 30 rt4 - rt5(4)
+rt8 TE-IS 30 rt4 - rt5(4)
+ rt7(4)
+10.0.255.5/32 IP TE 30 rt4 - rt5(4)
+10.0.255.7/32 IP TE 30 rt4 - rt7(4)
+rt10 TE-IS 40 rt4 - rt7(4)
+rt3 TE-IS 40 rt4 - rt2(4)
+ rt6(4)
+rt9 TE-IS 40 rt4 - rt8(4)
+rt11 TE-IS 40 rt4 - rt8(4)
+10.0.255.2/32 IP TE 40 rt4 - rt2(4)
+10.0.255.6/32 IP TE 40 rt4 - rt6(4)
+10.0.255.8/32 IP TE 40 rt4 - rt8(4)
+rt12 TE-IS 50 rt4 - rt9(4)
+ rt11(4)
+10.0.255.10/32 IP TE 50 rt4 - rt10(4)
+10.0.255.3/32 IP TE 50 rt4 - rt3(4)
+10.0.255.9/32 IP TE 50 rt4 - rt9(4)
+10.0.255.11/32 IP TE 50 rt4 - rt11(4)
+10.0.255.12/32 IP TE 60 rt4 - rt12(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------
+ 10.0.255.2/32 40 - rt4 -
+ 10.0.255.3/32 50 - rt4 -
+ 10.0.255.4/32 20 - rt4 -
+ 10.0.255.5/32 30 - rt4 -
+ 10.0.255.6/32 40 - rt4 -
+ 10.0.255.7/32 30 - rt4 -
+ 10.0.255.8/32 40 - rt4 -
+ 10.0.255.9/32 50 - rt4 -
+ 10.0.255.10/32 50 - rt4 -
+ 10.0.255.11/32 50 - rt4 -
+ 10.0.255.12/32 60 - rt4 -
+
+test# test isis topology 8 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 10 rt4 - rt1(4)
+rt3 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt2 - rt2(4)
+rt7 TE-IS 20 rt4 - rt4(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+rt6 TE-IS 30 rt2 - rt3(4)
+ rt5(4)
+rt8 TE-IS 30 rt2 - rt5(4)
+rt10 TE-IS 30 rt4 - rt7(4)
+10.0.255.3/32 IP TE 30 rt2 - rt3(4)
+10.0.255.5/32 IP TE 30 rt2 - rt5(4)
+10.0.255.7/32 IP TE 30 rt4 - rt7(4)
+rt9 TE-IS 40 rt2 - rt8(4)
+rt11 TE-IS 40 rt2 - rt8(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.8/32 IP TE 40 rt2 - rt8(4)
+10.0.255.10/32 IP TE 40 rt4 - rt10(4)
+rt12 TE-IS 50 rt2 - rt9(4)
+ rt11(4)
+10.0.255.9/32 IP TE 50 rt2 - rt9(4)
+10.0.255.11/32 IP TE 50 rt2 - rt11(4)
+10.0.255.12/32 IP TE 60 rt2 - rt12(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 30 - rt2 -
+ 10.0.255.4/32 20 - rt4 -
+ 10.0.255.5/32 30 - rt2 -
+ 10.0.255.6/32 40 - rt2 -
+ 10.0.255.7/32 30 - rt4 -
+ 10.0.255.8/32 40 - rt2 -
+ 10.0.255.9/32 50 - rt2 -
+ 10.0.255.10/32 40 - rt4 -
+ 10.0.255.11/32 50 - rt2 -
+ 10.0.255.12/32 60 - rt2 -
+
+test# test isis topology 9 root rt1 spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt5 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+rt9 TE-IS 40 rt2 - rt5(4)
+10.0.255.5/32 IP TE 40 rt2 - rt5(4)
+rt6 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt7 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt8 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+10.0.255.9/32 IP TE 50 rt2 - rt9(4)
+10.0.255.6/32 IP TE 60 rt2 - rt6(4)
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+10.0.255.8/32 IP TE 60 rt2 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 40 - rt2 -
+ 10.0.255.6/32 60 - rt2 -
+ 10.0.255.7/32 60 - rt2 -
+ 10.0.255.8/32 60 - rt2 -
+ 10.0.255.9/32 50 - rt2 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt5 TE-IS 30 rt2 - rt4(4)
+2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
+rt9 TE-IS 40 rt2 - rt5(4)
+2001:db8::5/128 IP6 internal 40 rt2 - rt5(4)
+rt6 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt7 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+rt8 TE-IS 50 rt2 - rt4(4)
+ rt9(4)
+2001:db8::9/128 IP6 internal 50 rt2 - rt9(4)
+2001:db8::6/128 IP6 internal 60 rt2 - rt6(4)
+2001:db8::7/128 IP6 internal 60 rt2 - rt7(4)
+2001:db8::8/128 IP6 internal 60 rt2 - rt8(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::2/128 20 - rt2 -
+ 2001:db8::3/128 20 - rt3 -
+ 2001:db8::4/128 30 - rt2 -
+ 2001:db8::5/128 40 - rt2 -
+ 2001:db8::6/128 60 - rt2 -
+ 2001:db8::7/128 60 - rt2 -
+ 2001:db8::8/128 60 - rt2 -
+ 2001:db8::9/128 50 - rt2 -
+
+test# test isis topology 10 root rt1 spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt4 TE-IS 20 rt4 - rt1(4)
+rt5 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt7 TE-IS 30 rt4 - rt4(4)
+rt8 TE-IS 30 rt2 - rt5(4)
+10.0.255.3/32 IP TE 30 rt3 - rt3(4)
+10.0.255.4/32 IP TE 30 rt4 - rt4(4)
+10.0.255.5/32 IP TE 30 rt2 - rt5(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+10.0.255.7/32 IP TE 40 rt4 - rt7(4)
+10.0.255.8/32 IP TE 40 rt2 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 30 - rt3 -
+ 10.0.255.4/32 30 - rt4 -
+ 10.0.255.5/32 30 - rt2 -
+ 10.0.255.6/32 40 - rt3 -
+ 10.0.255.7/32 40 - rt4 -
+ 10.0.255.8/32 40 - rt2 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 20 rt3 - rt1(4)
+rt4 TE-IS 20 rt4 - rt1(4)
+rt5 TE-IS 20 rt2 - rt2(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+rt6 TE-IS 30 rt3 - rt3(4)
+rt7 TE-IS 30 rt4 - rt4(4)
+rt8 TE-IS 30 rt2 - rt5(4)
+2001:db8::3/128 IP6 internal 30 rt3 - rt3(4)
+2001:db8::4/128 IP6 internal 30 rt4 - rt4(4)
+2001:db8::5/128 IP6 internal 30 rt2 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+2001:db8::7/128 IP6 internal 40 rt4 - rt7(4)
+2001:db8::8/128 IP6 internal 40 rt2 - rt8(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::2/128 20 - rt2 -
+ 2001:db8::3/128 30 - rt3 -
+ 2001:db8::4/128 30 - rt4 -
+ 2001:db8::5/128 30 - rt2 -
+ 2001:db8::6/128 40 - rt3 -
+ 2001:db8::7/128 40 - rt4 -
+ 2001:db8::8/128 40 - rt2 -
+
+test# test isis topology 11 root rt1 spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt2 pseudo_TE-IS 20 rt3 - rt3(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+ rt3 -
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ - rt3 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt2 pseudo_TE-IS 20 rt3 - rt3(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
+ rt3 -
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::2/128 20 - rt2 -
+ 2001:db8::3/128 20 - rt3 -
+ 2001:db8::4/128 30 - rt2 -
+ 2001:db8::5/128 30 - rt3 -
+ 2001:db8::6/128 40 - rt2 -
+ - rt3 -
+
+test# test isis topology 12 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+rt9 TE-IS 40 rt3 - rt7(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+rt10 TE-IS 50 rt2 - rt8(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+10.0.255.9/32 IP TE 50 rt3 - rt9(4)
+10.0.255.10/32 IP TE 60 rt2 - rt10(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ 10.0.255.7/32 40 - rt3 -
+ 10.0.255.8/32 50 - rt2 -
+ 10.0.255.9/32 50 - rt3 -
+ 10.0.255.10/32 60 - rt2 -
+
+test# test isis topology 13 root rt1 spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+ rt3 - rt3(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+ rt6(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+ rt3 -
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ - rt3 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 30 - rt3 -
+ 10.0.255.7/32 40 - rt3 -
+
+test#
+test# test isis topology 4 root rt1 reverse-spf ipv4-only
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.2/32 20 - rt2 -
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.4/32 30 - rt2 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt2 -
+ 10.0.255.7/32 40 - rt3 -
+ 10.0.255.8/32 50 - rt2 -
+
+test# test isis topology 11 root rt1 reverse-spf
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt2 pseudo_TE-IS 20 rt3 - rt3(4)
+rt4 TE-IS 20 rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt4(4)
+ rt5(4)
+10.0.255.4/32 IP TE 30 rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.3/32 20 - rt3 -
+ 10.0.255.5/32 30 - rt3 -
+ 10.0.255.6/32 40 - rt3 -
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt2 pseudo_TE-IS 20 rt3 - rt3(4)
+rt4 TE-IS 20 rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 20 rt2(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt4(4)
+ rt5(4)
+2001:db8::4/128 IP6 internal 30 rt4(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -------------------------------------------------------
+ 2001:db8::3/128 20 - rt3 -
+ 2001:db8::5/128 30 - rt3 -
+ 2001:db8::6/128 40 - rt3 -
+
+test#
+end.
diff --git a/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c
index 869dd732eb..d2d9f6293a 100644
--- a/tests/isisd/test_isis_vertex_queue.c
+++ b/tests/isisd/test_isis_vertex_queue.c
@@ -2,14 +2,7 @@
#include "isisd/isis_spf.c"
-struct thread_master *master;
-int isis_sock_init(struct isis_circuit *circuit);
-int isis_sock_init(struct isis_circuit *circuit)
-{
- return 0;
-}
-
-struct zebra_privs_t isisd_privs;
+#include "test_common.h"
static struct isis_vertex **vertices;
static size_t vertex_count;
diff --git a/tests/isisd/test_topologies.c b/tests/isisd/test_topologies.c
new file mode 100644
index 0000000000..ee89407a79
--- /dev/null
+++ b/tests/isisd/test_topologies.c
@@ -0,0 +1,3307 @@
+/*
+ * Copyright (C) 2020 NetDEF, Inc.
+ * Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "isisd/isisd.h"
+
+#include "test_common.h"
+
+/*
+ * clang-format off
+ *
+ * All topologies have the following properties:
+ * - The System-ID is 0000.0000.000X, where X is the node number (in hex);
+ * - The Router-ID is 10.0.255.X, where X is the node number;
+ * - The default link metric is 10;
+ * - When SR is enabled, Adj-SIDs and Prefix-SIDs are generated automatically;
+ * - When SR is enabled, the default SRGB is [16000-23999] (can be overriden).
+ *
+ * Test topology 1:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * +----------+ +----------+
+ * | | | |
+ * | +---------+ |
+ * | |
+ * | |
+ * | |
+ * +----+----+ +----+----+
+ * | | | |
+ * | RT2 | | RT3 |
+ * | | | |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * +---+-+---+ +----+----+
+ * | | | |
+ * | RT4 | | RT5 |
+ * | | | |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * | +---------+ |
+ * | | | |
+ * | | RT6 | |
+ * +----------+ +----------+
+ * | |
+ * +---------+
+ *
+ * Test topology 2:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * +----------+ +----------+
+ * | | | |
+ * | +----+----+ |
+ * | | |
+ * 15 | | | 30
+ * | | |
+ * +----+----+ | +----+----+
+ * | | | | |
+ * | RT2 | | | RT3 |
+ * | | | | |
+ * | | | | |
+ * +----+----+ | +----+----+
+ * | | |
+ * 40 | | | 40
+ * | | |
+ * +----+----+ | +----+----+
+ * | | | | |
+ * | RT4 | | | RT5 |
+ * | +----------+----------+ |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * | +---------+ |
+ * | | | |
+ * | | RT6 | |
+ * +----------+ +----------+
+ * | |
+ * +---------+
+ *
+ * Test topology 3:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * +----------+ +----------+
+ * | | | |
+ * | +---------+ |
+ * | |
+ * | |
+ * | |
+ * +----+----+ +----+----+
+ * | | | |
+ * | RT2 | | RT3 |
+ * | +---------------------+ |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | | 30
+ * | |
+ * +----+----+ +----+----+
+ * | | | |
+ * | RT4 | | RT5 |
+ * | +---------------------+ |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * | +---------+ |
+ * | | | |
+ * | | RT6 | |
+ * +----------+ +----------+
+ * | |
+ * +---------+
+ *
+ * Test topology 4:
+ * ================
+ *
+ * +---------+ +---------+
+ * | | | |
+ * | RT1 | | RT2 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT3 | | RT4 |
+ * | | | |
+ * | | | |
+ * +---+-----+ +------+--+
+ * |^ |
+ * ||200 |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT5 | 50 | RT6 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT7 | | RT8 |
+ * | | | |
+ * | | | |
+ * +---------+ +---------+
+ *
+ * Test topology 5:
+ * ================
+ *
+ * +---------+ +---------+
+ * | | | |
+ * | RT1 | | RT2 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT3 | | RT4 |
+ * | | | |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT5 | | RT6 |
+ * | | | |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT7 | | RT8 |
+ * | +---------------------+ |
+ * | | | |
+ * +---------+ +---------+
+ *
+ * Test topology 6:
+ * ================
+ *
+ * +---------+ +---------+
+ * | | | |
+ * | RT1 | | RT2 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT3 | | RT4 |
+ * | +---------------------+ |
+ * | | | |
+ * +---------+ +------+--+
+ * |
+ * |
+ * |
+ * +---------+ +------+--+
+ * | | | |
+ * | RT5 | | RT6 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT7 | | RT8 |
+ * | +---------------------+ |
+ * | | | |
+ * +---------+ +---------+
+ *
+ * Test topology 7:
+ * ================
+ *
+ * +---------+ +---------+ +---------+
+ * | | | | | |
+ * | RT1 | 40 | RT2 | | RT3 |
+ * | +---------------------+ +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | |
+ * | | |
+ * | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | | | | |
+ * | RT4 | | RT5 | | RT6 |
+ * | +---------------------+ +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | |
+ * | | | 30
+ * | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | | | | |
+ * | RT7 | | RT8 | | RT9 |
+ * | +---------------------+ +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | |
+ * | 20 | |
+ * | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | | | | |
+ * | RT10 | | RT11 | | RT12 |
+ * | +---------------------+ +---------------------+ |
+ * | | | | | |
+ * +---------+ +---------+ +---------+
+ *
+ * Test topology 8:
+ * ================
+ *
+ * +---------+ +---------+ +---------+
+ * | | | | | |
+ * | RT1 | | RT2 | | RT3 |
+ * | +---------------------+ +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | |
+ * | | |
+ * | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | | | | |
+ * | RT4 | | RT5 | | RT6 |
+ * | | | +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +---------+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +----+----+ +---------+
+ * | | | | | |
+ * | RT7 | | RT8 | | RT9 |
+ * | | | +---------------------+ |
+ * | | | | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | |
+ * | | |
+ * | | |
+ * +---+-----+ +----+----+ +------+--+
+ * | | | | | |
+ * | RT10 | | RT11 | | RT12 |
+ * | +---------------------+ +---------------------+ |
+ * | | 30 | | | |
+ * +---------+ +---------+ +---------+
+ *
+ * Test topology 9:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * +----------+ +----------+
+ * | | | |
+ * | +---------+ |
+ * | |
+ * | |
+ * | |
+ * +----+----+ +----+----+
+ * | | | |
+ * | RT2 | | RT3 |
+ * | | | |
+ * | | | |
+ * +----+----+ +------+--+
+ * | |
+ * | |
+ * | |100
+ * | +---------+ |
+ * | | | |
+ * +----------+ RT4 +------------+
+ * +----------------| |----------------+
+ * | +-+ +--+ |
+ * | | +---------+ | |
+ * | | | |
+ * | |30 |30 |30
+ * | | | |
+ * +----+----+ +----+----+ +----+----+ +----+----+
+ * | | | | | | | |
+ * | RT5 | | RT6 | | RT7 | | RT8 |
+ * | | | | | | | |
+ * | | | | | | | |
+ * +----+----+ +----+----+ +----+----+ +----+----+
+ * | | | |
+ * | | | |
+ * | | | |
+ * | | +---------+ | |
+ * | +-+ +--+ |
+ * +----------------+ RT9 +----------------+
+ * | |
+ * | |
+ * +---------+
+ *
+ * Test topology 10:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * +----------+ +----------+
+ * | | | |
+ * | +----+----+ |
+ * | | |
+ * | |20 |20
+ * | | |
+ * +----+----+ +----+----+ +----+----+
+ * | | | | | |
+ * | RT2 | | RT3 | | RT4 |
+ * | | | | | |
+ * | | | | | |
+ * +----+----+ +----+----+ +----+----+
+ * | | |
+ * | | |
+ * | | |
+ * +----+----+ +----+----+ +----+----+
+ * | | | | | |
+ * | RT5 | | RT6 | | RT7 |
+ * | | | | | |
+ * | | | | | |
+ * +----+----+ +----+----+ +----+----+
+ * | | |
+ * | |50 |50
+ * | | |
+ * | +----+----+ |
+ * | | | |
+ * +----------+ RT8 +----------+
+ * | |
+ * | |
+ * +---------+
+ *
+ * Test topology 11:
+ * ================
+ *
+ * +---------+
+ * | |
+ * | RT1 |
+ * | |
+ * | |
+ * +----+----+
+ * |
+ * |
+ * |
+ * +---------+ | +---------+
+ * | | | | |
+ * | RT2 |50 | | RT3 |
+ * | +----------+----------+ |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * +----+----+ +----+----+
+ * | | | |
+ * | RT4 | | RT5 |
+ * | +---------------------+ |
+ * | | | |
+ * +----+----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * | +---------+ |
+ * | | | |
+ * | | RT6 | |
+ * +----------+ +----------+
+ * | |
+ * +---------+
+ *
+ * Test topology 12:
+ * ================
+ *
+ * +---------+ +---------+
+ * | | | |
+ * | RT1 | | RT2 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT3 | | RT4 |
+ * | | | |
+ * | | | |
+ * +---+-----+ +------+--+
+ * |^ |
+ * |400 |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT5 | | RT6 |
+ * | | | |
+ * | | | |
+ * +---+-----+ +------+--+
+ * |^ |
+ * |200 |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT7 | | RT8 |
+ * | +---------------------+ |
+ * | | 100 | |
+ * +---+-----+ +------+--+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +------+--+
+ * | | | |
+ * | RT9 | | RT10 |
+ * | | | |
+ * | | | |
+ * +---------+ +---------+
+ *
+ * Test topology 13:
+ * ================
+ *
+ * +---------+ +---------+
+ * | | | |
+ * | RT1 | | RT2 |
+ * | +---------------------+ |
+ * | | | |
+ * +---+-----+ +----+----+
+ * | |
+ * | |
+ * | |
+ * | +----+----+
+ * | | |
+ * | +----------+ RT4 |
+ * | | | |
+ * +---+-----+ | | |
+ * | | | +----+----+
+ * | RT3 +----------+ |
+ * | +----------+ |100
+ * | | | |
+ * +---+-----+ | +----+----+
+ * | | | |
+ * | | | RT5 |
+ * | +----------+ |
+ * | | |
+ * | +----+----+
+ * | |
+ * | |
+ * | |
+ * +---+-----+ +----+----+
+ * | | | |
+ * | RT6 | | RT7 |
+ * | +---------------------+ |
+ * | | | |
+ * +---------+ +---------+
+ */
+
+struct isis_topology test_topologies[] = {
+ {
+ .number = 1,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ "2001:db8::1/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ "2001:db8::2/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ "2001:db8::3/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ "2001:db8::4/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ "2001:db8::5/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ "2001:db8::6/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 2,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ "2001:db8::1/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .pseudonode_id = 1,
+ .metric = 10,
+ },
+ {
+ .hostname = "rt2",
+ .metric = 15,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 30,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ "2001:db8::2/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 15,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 40,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ "2001:db8::3/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 40,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ "2001:db8::4/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .pseudonode_id = 1,
+ .metric = 10,
+ },
+ {
+ .hostname = "rt2",
+ .metric = 40,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ "2001:db8::5/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .pseudonode_id = 1,
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 40,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ "2001:db8::6/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .pseudonode_id = 1,
+ .level = IS_LEVEL_1,
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 0,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 0,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 0,
+ },
+ },
+ },
+ },
+ },
+ {
+ .number = 3,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 30,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 4,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 200,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 50,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 50,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 5,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 6,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 7,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 40,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 40,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 30,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt10",
+ .metric = 20,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt9",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.9",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.9/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt12",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt10",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.10",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.10/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt7",
+ .metric = 20,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt11",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0b},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.11",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.11/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt10",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt12",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt12",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0c},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.12",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.12/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 8,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt10",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt9",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.9",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.9/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt12",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt10",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.10",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.10/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 30,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt11",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0b},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.11",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.11/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt10",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt12",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt12",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0c},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.12",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.12/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt11",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 9,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ "2001:db8::1/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ "2001:db8::2/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ "2001:db8::3/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 100,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ "2001:db8::4/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 100,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 30,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ "2001:db8::5/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ "2001:db8::6/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ "2001:db8::7/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ "2001:db8::8/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 30,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt9",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.9",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.9/32",
+ "2001:db8::9/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 10,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ "2001:db8::1/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 20,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 20,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ "2001:db8::2/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .srgb = {
+ .lower_bound = 20000,
+ .range_size = 8000,
+ },
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ "2001:db8::3/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 20,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ "2001:db8::4/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 20,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ "2001:db8::5/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ "2001:db8::6/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 50,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ "2001:db8::7/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 50,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ "2001:db8::8/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 50,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 50,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 11,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ "2001:db8::1/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .pseudonode_id = 1,
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ "2001:db8::2/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .pseudonode_id = 1,
+ .metric = 50,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ "2001:db8::3/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .pseudonode_id = 1,
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ "2001:db8::4/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ "2001:db8::5/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ .ipv6 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ "2001:db8::6/128",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .pseudonode_id = 1,
+ .level = IS_LEVEL_1,
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 0,
+ },
+ {
+ .hostname = "rt2",
+ .metric = 0,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 0,
+ },
+ },
+ },
+ },
+ },
+ {
+ .number = 12,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 400,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 200,
+ },
+ {
+ .hostname = "rt8",
+ .metric = 100,
+ },
+ {
+ .hostname = "rt9",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt8",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.8",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.8/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 100,
+ },
+ {
+ .hostname = "rt10",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt9",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.9",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.9/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt10",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.10",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.10/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt8",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ .number = 13,
+ .nodes = {
+ {
+ .hostname = "rt1",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.1",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.1/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt2",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.2",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.2/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt3",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.3",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.3/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt1",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt4",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.4",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.4/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt2",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt5",
+ .metric = 100,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt5",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.5",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.5/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt4",
+ .metric = 100,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt6",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x06},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.6",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.6/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt3",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt7",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ {
+ .hostname = "rt7",
+ .sysid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
+ .level = IS_LEVEL_1,
+ .router_id = "10.0.255.7",
+ .protocols = {
+ .ipv4 = true,
+ },
+ .networks = {
+ "10.0.255.7/32",
+ },
+ .adjacencies = {
+ {
+ .hostname = "rt5",
+ .metric = 10,
+ },
+ {
+ .hostname = "rt6",
+ .metric = 10,
+ },
+ },
+ .flags = F_ISIS_TEST_NODE_SR,
+ },
+ },
+ },
+ {
+ /* sentinel */
+ },
+};
diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c
index 3cade4a2c9..44cc6efe84 100644
--- a/tests/lib/cli/common_cli.c
+++ b/tests/lib/cli/common_cli.c
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
vty_init(master, false);
lib_cmd_init();
yang_init(true);
- nb_init(master, NULL, 0);
+ nb_init(master, NULL, 0, false);
test_init(argc, argv);
diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c
index 2b345c91e8..cb512211a4 100644
--- a/tests/lib/cli/test_commands.c
+++ b/tests/lib/cli/test_commands.c
@@ -209,7 +209,7 @@ static void test_init(void)
cmd_init(1);
yang_init(true);
- nb_init(master, NULL, 0);
+ nb_init(master, NULL, 0, false);
install_node(&bgp_node);
install_node(&rip_node);
diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c
index 202a321e1a..b5f257fa2f 100644
--- a/tests/lib/northbound/test_oper_data.c
+++ b/tests/lib/northbound/test_oper_data.c
@@ -400,7 +400,7 @@ int main(int argc, char **argv)
vty_init(master, false);
lib_cmd_init();
yang_init(true);
- nb_init(master, modules, array_size(modules));
+ nb_init(master, modules, array_size(modules), false);
/* Create artificial data. */
create_data(num_vrfs, num_interfaces, num_routes);
diff --git a/tests/subdir.am b/tests/subdir.am
index 04053a6f46..e54bfc4a35 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -23,6 +23,7 @@ else
TESTS_ISISD = \
tests/isisd/test_fuzz_isis_tlv \
tests/isisd/test_isis_lspdb \
+ tests/isisd/test_isis_spf \
tests/isisd/test_isis_vertex_queue \
# end
endif
@@ -111,6 +112,7 @@ noinst_HEADERS += \
tests/helpers/c/tests.h \
tests/lib/cli/common_cli.h \
tests/lib/test_typelist.h \
+ tests/isisd/test_common.h \
# end
#
@@ -168,16 +170,21 @@ tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c
tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
-tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
+tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c tests/isisd/test_common.c
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
-tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c
+tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c tests/isisd/test_common.c
+tests_isisd_test_isis_spf_CFLAGS = $(TESTS_CFLAGS)
+tests_isisd_test_isis_spf_CPPFLAGS = $(TESTS_CPPFLAGS)
+tests_isisd_test_isis_spf_LDADD = $(ISISD_TEST_LDADD)
+tests_isisd_test_isis_spf_SOURCES = tests/isisd/test_isis_spf.c tests/isisd/test_common.c tests/isisd/test_topologies.c
+nodist_tests_isisd_test_isis_spf_SOURCES = yang/frr-isisd.yang.c
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
-tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c
+tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c tests/isisd/test_common.c
tests_lib_cxxcompat_CFLAGS = $(TESTS_CFLAGS) $(CXX_COMPAT_CFLAGS) $(WERROR)
tests_lib_cxxcompat_CPPFLAGS = $(TESTS_CPPFLAGS)
@@ -327,6 +334,9 @@ EXTRA_DIST += \
tests/isisd/test_fuzz_isis_tlv.py \
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
tests/isisd/test_isis_lspdb.py \
+ tests/isisd/test_isis_spf.py \
+ tests/isisd/test_isis_spf.in \
+ tests/isisd/test_isis_spf.refout \
tests/isisd/test_isis_vertex_queue.py \
tests/lib/cli/test_commands.in \
tests/lib/cli/test_commands.py \
diff --git a/tests/topotests/all-protocol-startup/r1/bgpd.conf b/tests/topotests/all-protocol-startup/r1/bgpd.conf
index e000b4e625..d287b86175 100644
--- a/tests/topotests/all-protocol-startup/r1/bgpd.conf
+++ b/tests/topotests/all-protocol-startup/r1/bgpd.conf
@@ -7,9 +7,13 @@ router bgp 100
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.7.10 remote-as 100
+ neighbor 192.168.7.10 timers 3 10
neighbor 192.168.7.20 remote-as 200
+ neighbor 192.168.7.20 timers 3 10
neighbor fc00:0:0:8::1000 remote-as 100
+ neighbor fc00:0:0:8::1000 timers 3 10
neighbor fc00:0:0:8::2000 remote-as 200
+ neighbor fc00:0:0:8::2000 timers 3 10
!
address-family ipv4 unicast
network 192.168.0.0/24
diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py
index 4602b039a6..8525838d96 100755
--- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py
+++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py
@@ -263,6 +263,22 @@ def test_error_messages_daemons():
if log:
error_logs += "r%s LDPd StdErr Output:\n" % i
error_logs += log
+
+ log = net['r1'].getStdErr('nhrpd')
+ if log:
+ error_logs += "r%s NHRPd StdErr Output:\n" % i
+ error_logs += log
+
+ log = net['r1'].getStdErr('babeld')
+ if log:
+ error_logs += "r%s BABELd StdErr Output:\n" % i
+ error_logs += log
+
+ log = net['r1'].getStdErr('pbrd')
+ if log:
+ error_logs += "r%s PBRd StdErr Output:\n" % i
+ error_logs += log
+
log = net['r%s' % i].getStdErr('zebra')
if log:
error_logs += "r%s Zebra StdErr Output:\n"
@@ -1182,6 +1198,19 @@ def test_shutdown_check_stderr():
log = net['r1'].getStdErr('bgpd')
if log:
print("\nBGPd StdErr Log:\n" + log)
+
+ log = net['r1'].getStdErr('nhrpd')
+ if log:
+ print("\nNHRPd StdErr Log:\n" + log)
+
+ log = net['r1'].getStdErr('pbrd')
+ if log:
+ print("\nPBRd StdErr Log:\n" + log)
+
+ log = net['r1'].getStdErr('babeld')
+ if log:
+ print("\nBABELd StdErr Log:\n" + log)
+
if (net['r1'].daemon_available('ldpd')):
log = net['r1'].getStdErr('ldpd')
if log:
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf
index 82b189b292..689797a5e6 100644
--- a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf
@@ -6,6 +6,7 @@ router bgp 101
timers bgp 8 24
bgp graceful-restart
neighbor 2001:db8:4::1 remote-as 102
+ neighbor 2001:db8:4::1 timers 3 10
neighbor 2001:db8:4::1 remote-as external
neighbor 2001:db8:4::1 bfd
neighbor 2001:db8:4::1 bfd check-control-plane-failure
diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf
index e566e08f7d..1f5aac42ed 100644
--- a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf
+++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf
@@ -10,6 +10,7 @@ router bgp 102
bgp graceful-restart stalepath-time 900
bgp graceful-restart restart-time 900
neighbor 2001:db8:1::1 remote-as 101
+ neighbor 2001:db8:1::1 timers 3 10
neighbor 2001:db8:1::1 remote-as external
neighbor 2001:db8:1::1 update-source 2001:db8:4::1
neighbor 2001:db8:1::1 bfd
diff --git a/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf b/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf
index c0896353ae..4798d17c40 100644
--- a/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf
+++ b/tests/topotests/bfd-profiles-topo1/r1/ospfd.conf
@@ -1,5 +1,7 @@
interface r1-eth1
ip ospf area 0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf bfd
!
router ospf
diff --git a/tests/topotests/bfd-profiles-topo1/r2/bgpd.conf b/tests/topotests/bfd-profiles-topo1/r2/bgpd.conf
index 824d01983f..0c3db97bc1 100644
--- a/tests/topotests/bfd-profiles-topo1/r2/bgpd.conf
+++ b/tests/topotests/bfd-profiles-topo1/r2/bgpd.conf
@@ -4,8 +4,10 @@ router bgp 100
bgp router-id 10.254.254.2
no bgp ebgp-requires-policy
neighbor 172.16.1.1 remote-as 100
+ neighbor 172.16.1.1 timers 3 10
neighbor 172.16.1.1 bfd profile fasttx
neighbor 2001:db8:2::2 remote-as 200
+ neighbor 2001:db8:2::2 timers 3 10
neighbor 2001:db8:2::2 ebgp-multihop 2
neighbor 2001:db8:2::2 bfd profile slowtx
address-family ipv4 unicast
diff --git a/tests/topotests/bfd-profiles-topo1/r3/bgpd.conf b/tests/topotests/bfd-profiles-topo1/r3/bgpd.conf
index c7b75d2fde..65647b39e5 100644
--- a/tests/topotests/bfd-profiles-topo1/r3/bgpd.conf
+++ b/tests/topotests/bfd-profiles-topo1/r3/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 100
bgp router-id 10.254.254.3
neighbor 172.16.1.2 remote-as 100
+ neighbor 172.16.1.2 timers 3 10
neighbor 172.16.1.2 bfd profile DOES_NOT_EXIST
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bfd-profiles-topo1/r4/bgpd.conf b/tests/topotests/bfd-profiles-topo1/r4/bgpd.conf
index aff1016dee..200937a9a5 100644
--- a/tests/topotests/bfd-profiles-topo1/r4/bgpd.conf
+++ b/tests/topotests/bfd-profiles-topo1/r4/bgpd.conf
@@ -4,6 +4,7 @@ router bgp 200
bgp router-id 10.254.254.4
no bgp ebgp-requires-policy
neighbor 2001:db8:1::2 remote-as 100
+ neighbor 2001:db8:1::2 timers 3 10
neighbor 2001:db8:1::2 ebgp-multihop 2
neighbor 2001:db8:1::2 bfd profile DOES_NOT_EXIST
address-family ipv4 unicast
diff --git a/tests/topotests/bfd-profiles-topo1/r6/ospfd.conf b/tests/topotests/bfd-profiles-topo1/r6/ospfd.conf
index f16844401e..d8fce344a8 100644
--- a/tests/topotests/bfd-profiles-topo1/r6/ospfd.conf
+++ b/tests/topotests/bfd-profiles-topo1/r6/ospfd.conf
@@ -1,5 +1,7 @@
interface r6-eth0
ip ospf area 0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf bfd
!
router ospf
diff --git a/tests/topotests/bfd-topo1/r1/bgpd.conf b/tests/topotests/bfd-topo1/r1/bgpd.conf
index 25e16a6e0c..57bde1f234 100644
--- a/tests/topotests/bfd-topo1/r1/bgpd.conf
+++ b/tests/topotests/bfd-topo1/r1/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 101
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.0.2 remote-as 102
+ neighbor 192.168.0.2 timers 3 10
neighbor 192.168.0.2 bfd
address-family ipv4 unicast
network 10.254.254.1/32
diff --git a/tests/topotests/bfd-topo1/r2/bgpd.conf b/tests/topotests/bfd-topo1/r2/bgpd.conf
index 693fb93411..50d75ab67f 100644
--- a/tests/topotests/bfd-topo1/r2/bgpd.conf
+++ b/tests/topotests/bfd-topo1/r2/bgpd.conf
@@ -2,10 +2,13 @@ router bgp 102
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.0.1 remote-as 101
+ neighbor 192.168.0.1 timers 3 10
neighbor 192.168.0.1 bfd
neighbor 192.168.1.1 remote-as 103
+ neighbor 192.168.1.1 timers 3 10
neighbor 192.168.1.1 bfd
neighbor 192.168.2.1 remote-as 104
+ neighbor 192.168.2.1 timers 3 10
neighbor 192.168.2.1 bfd
address-family ipv4 unicast
network 10.254.254.2/32
diff --git a/tests/topotests/bfd-topo1/r3/bgpd.conf b/tests/topotests/bfd-topo1/r3/bgpd.conf
index 7584f98803..ce6055d518 100644
--- a/tests/topotests/bfd-topo1/r3/bgpd.conf
+++ b/tests/topotests/bfd-topo1/r3/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 103
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.1.2 remote-as 102
+ neighbor 192.168.1.2 timers 3 10
neighbor 192.168.1.2 bfd
address-family ipv4 unicast
network 10.254.254.3/32
diff --git a/tests/topotests/bfd-topo1/r4/bgpd.conf b/tests/topotests/bfd-topo1/r4/bgpd.conf
index 3c68e7eec9..0d032b4cdd 100644
--- a/tests/topotests/bfd-topo1/r4/bgpd.conf
+++ b/tests/topotests/bfd-topo1/r4/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 104
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.2.2 remote-as 102
+ neighbor 192.168.2.2 timers 3 10
neighbor 192.168.2.2 bfd
address-family ipv4 unicast
network 10.254.254.4/32
diff --git a/tests/topotests/bfd-topo2/r1/bgpd.conf b/tests/topotests/bfd-topo2/r1/bgpd.conf
index 4d96bec2cb..0918796e95 100644
--- a/tests/topotests/bfd-topo2/r1/bgpd.conf
+++ b/tests/topotests/bfd-topo2/r1/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 101
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r1-eth0 interface peer-group r2g
+ neighbor r1-eth0 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
diff --git a/tests/topotests/bfd-topo2/r2/bgpd.conf b/tests/topotests/bfd-topo2/r2/bgpd.conf
index 4d02fc4f29..55d48560e7 100644
--- a/tests/topotests/bfd-topo2/r2/bgpd.conf
+++ b/tests/topotests/bfd-topo2/r2/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 102
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r2-eth0 interface peer-group r2g
+ neighbor r2-eth0 timers 3 10
!
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bfd-topo2/r2/ospf6d.conf b/tests/topotests/bfd-topo2/r2/ospf6d.conf
index f1cdb50285..48a729ce19 100644
--- a/tests/topotests/bfd-topo2/r2/ospf6d.conf
+++ b/tests/topotests/bfd-topo2/r2/ospf6d.conf
@@ -1,5 +1,7 @@
interface r2-eth2
ipv6 ospf6 bfd
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.254.254.2
diff --git a/tests/topotests/bfd-topo2/r2/ospfd.conf b/tests/topotests/bfd-topo2/r2/ospfd.conf
index 8e0c45980d..c786f1fe43 100644
--- a/tests/topotests/bfd-topo2/r2/ospfd.conf
+++ b/tests/topotests/bfd-topo2/r2/ospfd.conf
@@ -1,5 +1,7 @@
interface r2-eth1
ip ospf area 0.0.0.1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf bfd
!
router ospf
diff --git a/tests/topotests/bfd-topo2/r3/ospfd.conf b/tests/topotests/bfd-topo2/r3/ospfd.conf
index cf2a1bdf76..932ab4da63 100644
--- a/tests/topotests/bfd-topo2/r3/ospfd.conf
+++ b/tests/topotests/bfd-topo2/r3/ospfd.conf
@@ -1,5 +1,7 @@
interface r3-eth0
ip ospf area 0.0.0.1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf bfd
!
router ospf
diff --git a/tests/topotests/bfd-topo2/r4/ospf6d.conf b/tests/topotests/bfd-topo2/r4/ospf6d.conf
index 756597d6f8..57f7f6c079 100644
--- a/tests/topotests/bfd-topo2/r4/ospf6d.conf
+++ b/tests/topotests/bfd-topo2/r4/ospf6d.conf
@@ -1,5 +1,7 @@
interface r4-eth0
ipv6 ospf6 bfd
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
!
router ospf6
ospf6 router-id 10.254.254.4
diff --git a/tests/topotests/bfd-topo3/r1/bgpd.conf b/tests/topotests/bfd-topo3/r1/bgpd.conf
index a0281d50c6..4c75d669c5 100644
--- a/tests/topotests/bfd-topo3/r1/bgpd.conf
+++ b/tests/topotests/bfd-topo3/r1/bgpd.conf
@@ -1,11 +1,14 @@
router bgp 100
no bgp ebgp-requires-policy
neighbor 2001:db8:1::2 remote-as internal
+ neighbor 2001:db8:1::2 timers 3 10
neighbor 2001:db8:1::2 bfd profile fast-tx
neighbor 192.168.2.1 remote-as external
+ neighbor 192.168.2.1 timers 3 10
neighbor 192.168.2.1 ebgp-multihop 2
neighbor 192.168.2.1 bfd profile slow-tx
neighbor 2001:db8:3::1 remote-as external
+ neighbor 2001:db8:3::1 timers 3 10
neighbor 2001:db8:3::1 ebgp-multihop 3
neighbor 2001:db8:3::1 bfd profile slow-tx
address-family ipv4 unicast
diff --git a/tests/topotests/bfd-topo3/r2/bgpd.conf b/tests/topotests/bfd-topo3/r2/bgpd.conf
index 0e96033023..75225765e1 100644
--- a/tests/topotests/bfd-topo3/r2/bgpd.conf
+++ b/tests/topotests/bfd-topo3/r2/bgpd.conf
@@ -1,8 +1,10 @@
router bgp 100
no bgp ebgp-requires-policy
neighbor 2001:db8:1::1 remote-as internal
+ neighbor 2001:db8:1::1 timers 3 10
neighbor 2001:db8:1::1 bfd profile fast-tx
neighbor 2001:db8:2::1 remote-as external
+ neighbor 2001:db8:2::1 timers 3 10
neighbor 2001:db8:2::1 bfd profile slow-tx
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bfd-topo3/r3/bgpd.conf b/tests/topotests/bfd-topo3/r3/bgpd.conf
index e14d2011a0..82adf8be9e 100644
--- a/tests/topotests/bfd-topo3/r3/bgpd.conf
+++ b/tests/topotests/bfd-topo3/r3/bgpd.conf
@@ -1,11 +1,14 @@
router bgp 300
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as external
+ neighbor 192.168.1.1 timers 3 10
neighbor 192.168.1.1 ebgp-multihop 2
neighbor 192.168.1.1 bfd profile slow-tx
neighbor 2001:db8:2::2 remote-as external
+ neighbor 2001:db8:2::2 timers 3 10
neighbor 2001:db8:2::2 bfd profile slow-tx
neighbor 2001:db8:3::1 remote-as external
+ neighbor 2001:db8:3::1 timers 3 10
neighbor 2001:db8:3::1 bfd profile slow-tx
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bfd-topo3/r4/bgpd.conf b/tests/topotests/bfd-topo3/r4/bgpd.conf
index 3e81008d5d..0aab6e3017 100644
--- a/tests/topotests/bfd-topo3/r4/bgpd.conf
+++ b/tests/topotests/bfd-topo3/r4/bgpd.conf
@@ -1,8 +1,10 @@
router bgp 400
no bgp ebgp-requires-policy
neighbor 2001:db8:3::2 remote-as external
+ neighbor 2001:db8:3::2 timers 3 10
neighbor 2001:db8:3::2 bfd profile slow-tx
neighbor 2001:db8:1::1 remote-as external
+ neighbor 2001:db8:1::1 timers 3 10
neighbor 2001:db8:1::1 ebgp-multihop 3
neighbor 2001:db8:1::1 bfd profile slow-tx-mh
address-family ipv4 unicast
diff --git a/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf
index 439c58fb2a..5bb45b9863 100644
--- a/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf
+++ b/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 101 vrf r1-cust1
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.0.2 remote-as 102
+ neighbor 192.168.0.2 timers 3 10
! neighbor 192.168.0.2 ebgp-multihop 10
neighbor 192.168.0.2 bfd
address-family ipv4 unicast
diff --git a/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf
index 4fac25d7bb..b2aac74685 100644
--- a/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf
+++ b/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf
@@ -2,10 +2,13 @@ router bgp 102 vrf r2-cust1
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.0.1 remote-as 101
+ neighbor 192.168.0.1 timers 3 10
neighbor 192.168.0.1 bfd
neighbor 192.168.1.1 remote-as 103
+ neighbor 192.168.1.1 timers 3 10
neighbor 192.168.1.1 bfd
neighbor 192.168.2.1 remote-as 104
+ neighbor 192.168.2.1 timers 3 10
neighbor 192.168.2.1 bfd
address-family ipv4 unicast
network 10.254.254.2/32
diff --git a/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf
index 052707ae1b..1d7c730395 100644
--- a/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf
+++ b/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 103 vrf r3-cust1
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.1.2 remote-as 102
+ neighbor 192.168.1.2 timers 3 10
neighbor 192.168.1.2 bfd
address-family ipv4 unicast
network 10.254.254.3/32
diff --git a/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf
index bcb0a17c01..f34035d460 100644
--- a/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf
+++ b/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf
@@ -2,6 +2,7 @@ router bgp 104 vrf r4-cust1
no bgp ebgp-requires-policy
no bgp network import-check
neighbor 192.168.2.2 remote-as 102
+ neighbor 192.168.2.2 timers 3 10
neighbor 192.168.2.2 bfd
address-family ipv4 unicast
network 10.254.254.4/32
diff --git a/tests/topotests/bgp-auth/R1/bgpd.conf b/tests/topotests/bgp-auth/R1/bgpd.conf
new file mode 100644
index 0000000000..1cb26c6537
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd.conf
@@ -0,0 +1,18 @@
+router bgp 65001
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 password hello1
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 password hello2
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ address-family ipv4 unicast
+ neighbor 2.2.2.2 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R1/bgpd_multi_vrf.conf b/tests/topotests/bgp-auth/R1/bgpd_multi_vrf.conf
new file mode 100644
index 0000000000..aab35073cf
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd_multi_vrf.conf
@@ -0,0 +1,40 @@
+log file /tmp/topotests/test_bgp_auth/R1/bgpd.log debugging
+debug bgp neighbor-events
+
+router bgp 65001 vrf blue
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 password blue1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password blue2
+ address-family ipv4 unicast
+ neighbor 2.2.2.2 activate
+ neighbor 3.3.3.3 activate
+
+router bgp 65001 vrf red
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo2
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 password red1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo2
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password red2
+ address-family ipv4 unicast
+ neighbor 2.2.2.2 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R1/bgpd_multi_vrf_prefix.conf b/tests/topotests/bgp-auth/R1/bgpd_multi_vrf_prefix.conf
new file mode 100644
index 0000000000..7e15720c7e
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd_multi_vrf_prefix.conf
@@ -0,0 +1,37 @@
+router bgp 65001 vrf blue
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor TWO_GROUP_blue peer-group
+ neighbor TWO_GROUP_blue remote-as 65002
+ neighbor TWO_GROUP_blue update-source 1.1.1.1
+ neighbor TWO_GROUP_blue ebgp-multihop 3
+ neighbor TWO_GROUP_blue password blue1
+ neighbor THREE_GROUP_blue peer-group
+ neighbor THREE_GROUP_blue remote-as 65003
+ neighbor THREE_GROUP_blue update-source 1.1.1.1
+ neighbor THREE_GROUP_blue ebgp-multihop 3
+ neighbor THREE_GROUP_blue password blue2
+ bgp listen range 2.2.2.0/24 peer-group TWO_GROUP_blue
+ bgp listen range 3.3.3.0/24 peer-group THREE_GROUP_blue
+ address-family ipv4 unicast
+ neighbor TWO_GROUP_blue maximum-prefix 4294967295
+ neighbor THREE_GROUP_blue maximum-prefix 4294967295
+
+router bgp 65001 vrf red
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor TWO_GROUP_red peer-group
+ neighbor TWO_GROUP_red remote-as 65002
+ neighbor TWO_GROUP_red update-source 1.1.1.1
+ neighbor TWO_GROUP_red ebgp-multihop 3
+ neighbor TWO_GROUP_red password red1
+ neighbor THREE_GROUP_red peer-group
+ neighbor THREE_GROUP_red remote-as 65003
+ neighbor THREE_GROUP_red update-source 1.1.1.1
+ neighbor THREE_GROUP_red ebgp-multihop 3
+ neighbor THREE_GROUP_red password red2
+ bgp listen range 2.2.2.0/24 peer-group TWO_GROUP_red
+ bgp listen range 3.3.3.0/24 peer-group THREE_GROUP_red
+ address-family ipv4 unicast
+ neighbor TWO_GROUP_red maximum-prefix 4294967295
+ neighbor THREE_GROUP_red maximum-prefix 4294967295
diff --git a/tests/topotests/bgp-auth/R1/bgpd_prefix.conf b/tests/topotests/bgp-auth/R1/bgpd_prefix.conf
new file mode 100644
index 0000000000..9200b0501d
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65001
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor TWO_GROUP peer-group
+ neighbor TWO_GROUP remote-as 65002
+ neighbor TWO_GROUP update-source 1.1.1.1
+ neighbor TWO_GROUP ebgp-multihop 3
+ neighbor TWO_GROUP password hello1
+ neighbor THREE_GROUP peer-group
+ neighbor THREE_GROUP remote-as 65003
+ neighbor THREE_GROUP update-source 1.1.1.1
+ neighbor THREE_GROUP ebgp-multihop 3
+ neighbor THREE_GROUP password hello2
+ bgp listen range 2.2.2.0/24 peer-group TWO_GROUP
+ bgp listen range 3.3.3.0/24 peer-group THREE_GROUP
+ address-family ipv4 unicast
+ neighbor TWO_GROUP maximum-prefix 4294967295
+ neighbor THREE_GROUP maximum-prefix 4294967295
diff --git a/tests/topotests/bgp-auth/R1/bgpd_vrf.conf b/tests/topotests/bgp-auth/R1/bgpd_vrf.conf
new file mode 100644
index 0000000000..73aa8c1a03
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd_vrf.conf
@@ -0,0 +1,21 @@
+log file /tmp/topotests/test_bgp_auth/R1/bgpd.log debugging
+debug bgp neighbor-events
+
+router bgp 65001 vrf blue
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 password hello1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password hello2
+ address-family ipv4 unicast
+ neighbor 2.2.2.2 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R1/bgpd_vrf_prefix.conf b/tests/topotests/bgp-auth/R1/bgpd_vrf_prefix.conf
new file mode 100644
index 0000000000..d68951b406
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/bgpd_vrf_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65001 vrf blue
+ timers bgp 3 9
+ bgp router-id 1.1.1.1
+ neighbor TWO_GROUP_blue peer-group
+ neighbor TWO_GROUP_blue remote-as 65002
+ neighbor TWO_GROUP_blue update-source 1.1.1.1
+ neighbor TWO_GROUP_blue ebgp-multihop 3
+ neighbor TWO_GROUP_blue password hello1
+ neighbor THREE_GROUP_blue peer-group
+ neighbor THREE_GROUP_blue remote-as 65003
+ neighbor THREE_GROUP_blue update-source 1.1.1.1
+ neighbor THREE_GROUP_blue ebgp-multihop 3
+ neighbor THREE_GROUP_blue password hello2
+ bgp listen range 2.2.2.0/24 peer-group TWO_GROUP_blue
+ bgp listen range 3.3.3.0/24 peer-group THREE_GROUP_blue
+ address-family ipv4 unicast
+ neighbor TWO_GROUP_blue maximum-prefix 4294967295
+ neighbor THREE_GROUP_blue maximum-prefix 4294967295
diff --git a/tests/topotests/bgp-auth/R1/ospfd.conf b/tests/topotests/bgp-auth/R1/ospfd.conf
new file mode 100644
index 0000000000..79eb0e33da
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/ospfd.conf
@@ -0,0 +1,4 @@
+router ospf
+ network 10.10.0.0/16 area 0
+ network 10.20.0.0/16 area 0
+ network 1.1.1.1/32 area 0
diff --git a/tests/topotests/bgp-auth/R1/ospfd_multi_vrf.conf b/tests/topotests/bgp-auth/R1/ospfd_multi_vrf.conf
new file mode 100644
index 0000000000..e2a28000b8
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/ospfd_multi_vrf.conf
@@ -0,0 +1,9 @@
+router ospf vrf blue
+ network 10.10.0.0/16 area 0
+ network 10.20.0.0/16 area 0
+ network 1.1.1.1/32 area 0
+
+router ospf vrf red
+ network 10.10.0.0/16 area 0
+ network 10.20.0.0/16 area 0
+ network 1.1.1.1/32 area 0
diff --git a/tests/topotests/bgp-auth/R1/ospfd_vrf.conf b/tests/topotests/bgp-auth/R1/ospfd_vrf.conf
new file mode 100644
index 0000000000..0b7fbae8c4
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/ospfd_vrf.conf
@@ -0,0 +1,4 @@
+router ospf vrf blue
+ network 10.10.0.0/16 area 0
+ network 10.20.0.0/16 area 0
+ network 1.1.1.1/32 area 0
diff --git a/tests/topotests/bgp-auth/R1/zebra.conf b/tests/topotests/bgp-auth/R1/zebra.conf
new file mode 100644
index 0000000000..d39915335a
--- /dev/null
+++ b/tests/topotests/bgp-auth/R1/zebra.conf
@@ -0,0 +1,21 @@
+log file zebra.log
+!
+interface lo
+ ip address 1.1.1.1/32
+interface lo1 vrf blue
+ ip address 1.1.1.1/32
+interface lo2 vrf red
+ ip address 1.1.1.1/32
+interface R1-eth0
+ ip address 10.10.0.1/24
+interface R1-eth1
+ ip address 10.20.0.1/24
+interface R1-eth2 vrf blue
+ ip address 10.10.0.1/24
+interface R1-eth3 vrf blue
+ ip address 10.20.0.1/24
+interface R1-eth4 vrf red
+ ip address 10.10.0.1/24
+interface R1-eth5 vrf red
+ ip address 10.20.0.1/24
+! \ No newline at end of file
diff --git a/tests/topotests/bgp-auth/R2/bgpd.conf b/tests/topotests/bgp-auth/R2/bgpd.conf
new file mode 100644
index 0000000000..fa2a570ef9
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd.conf
@@ -0,0 +1,18 @@
+router bgp 65002
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/bgpd_multi_vrf.conf b/tests/topotests/bgp-auth/R2/bgpd_multi_vrf.conf
new file mode 100644
index 0000000000..d5f70edf68
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd_multi_vrf.conf
@@ -0,0 +1,37 @@
+router bgp 65002 vrf blue
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password blue1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password blue3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
+
+router bgp 65002 vrf red
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo2
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password red1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo2
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password red3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/bgpd_multi_vrf_prefix.conf b/tests/topotests/bgp-auth/R2/bgpd_multi_vrf_prefix.conf
new file mode 100644
index 0000000000..d5f70edf68
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd_multi_vrf_prefix.conf
@@ -0,0 +1,37 @@
+router bgp 65002 vrf blue
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password blue1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password blue3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
+
+router bgp 65002 vrf red
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo2
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password red1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo2
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password red3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/bgpd_prefix.conf b/tests/topotests/bgp-auth/R2/bgpd_prefix.conf
new file mode 100644
index 0000000000..fa2a570ef9
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65002
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/bgpd_vrf.conf b/tests/topotests/bgp-auth/R2/bgpd_vrf.conf
new file mode 100644
index 0000000000..d1f3847420
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd_vrf.conf
@@ -0,0 +1,18 @@
+router bgp 65002 vrf blue
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/bgpd_vrf_prefix.conf b/tests/topotests/bgp-auth/R2/bgpd_vrf_prefix.conf
new file mode 100644
index 0000000000..d1f3847420
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/bgpd_vrf_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65002 vrf blue
+ timers bgp 3 9
+ bgp router-id 2.2.2.2
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello1
+ neighbor 3.3.3.3 remote-as 65003
+ neighbor 3.3.3.3 update-source lo1
+ neighbor 3.3.3.3 ebgp-multihop 3
+ neighbor 3.3.3.3 timers 3 10
+ neighbor 3.3.3.3 timers connect 10
+ neighbor 3.3.3.3 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp-auth/R2/ospfd.conf b/tests/topotests/bgp-auth/R2/ospfd.conf
new file mode 100644
index 0000000000..028b546a0c
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/ospfd.conf
@@ -0,0 +1,4 @@
+router ospf
+ network 10.10.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 2.2.2.2/32 area 0
diff --git a/tests/topotests/bgp-auth/R2/ospfd_multi_vrf.conf b/tests/topotests/bgp-auth/R2/ospfd_multi_vrf.conf
new file mode 100644
index 0000000000..a05dfb8e41
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/ospfd_multi_vrf.conf
@@ -0,0 +1,9 @@
+router ospf vrf blue
+ network 10.10.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 2.2.2.2/32 area 0
+
+router ospf vrf red
+ network 10.10.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 2.2.2.2/32 area 0
diff --git a/tests/topotests/bgp-auth/R2/ospfd_vrf.conf b/tests/topotests/bgp-auth/R2/ospfd_vrf.conf
new file mode 100644
index 0000000000..b198d352e2
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/ospfd_vrf.conf
@@ -0,0 +1,4 @@
+router ospf vrf blue
+ network 10.10.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 2.2.2.2/32 area 0
diff --git a/tests/topotests/bgp-auth/R2/zebra.conf b/tests/topotests/bgp-auth/R2/zebra.conf
new file mode 100644
index 0000000000..fece68472a
--- /dev/null
+++ b/tests/topotests/bgp-auth/R2/zebra.conf
@@ -0,0 +1,21 @@
+log file zebra.log
+!
+interface lo
+ ip address 2.2.2.2/32
+interface lo1 vrf blue
+ ip address 2.2.2.2/32
+interface lo2 vrf red
+ ip address 2.2.2.2/32
+interface R2-eth0
+ ip address 10.10.0.2/24
+interface R2-eth1
+ ip address 10.30.0.2/24
+interface R2-eth2 vrf blue
+ ip address 10.10.0.2/24
+interface R2-eth3 vrf blue
+ ip address 10.30.0.2/24
+interface R2-eth4 vrf red
+ ip address 10.10.0.2/24
+interface R2-eth5 vrf red
+ ip address 10.30.0.2/24
+! \ No newline at end of file
diff --git a/tests/topotests/bgp-auth/R3/bgpd.conf b/tests/topotests/bgp-auth/R3/bgpd.conf
new file mode 100644
index 0000000000..deccfd418b
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd.conf
@@ -0,0 +1,18 @@
+router bgp 65003
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/bgpd_multi_vrf.conf b/tests/topotests/bgp-auth/R3/bgpd_multi_vrf.conf
new file mode 100644
index 0000000000..fe3e64d8d5
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd_multi_vrf.conf
@@ -0,0 +1,37 @@
+router bgp 65003 vrf blue
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password blue2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password blue3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
+
+router bgp 65003 vrf red
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo2
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password red2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo2
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password red3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/bgpd_multi_vrf_prefix.conf b/tests/topotests/bgp-auth/R3/bgpd_multi_vrf_prefix.conf
new file mode 100644
index 0000000000..fe3e64d8d5
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd_multi_vrf_prefix.conf
@@ -0,0 +1,37 @@
+router bgp 65003 vrf blue
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password blue2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password blue3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
+
+router bgp 65003 vrf red
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo2
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password red2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo2
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password red3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/bgpd_prefix.conf b/tests/topotests/bgp-auth/R3/bgpd_prefix.conf
new file mode 100644
index 0000000000..deccfd418b
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65003
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/bgpd_vrf.conf b/tests/topotests/bgp-auth/R3/bgpd_vrf.conf
new file mode 100644
index 0000000000..c109aa801b
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd_vrf.conf
@@ -0,0 +1,18 @@
+router bgp 65003 vrf blue
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/bgpd_vrf_prefix.conf b/tests/topotests/bgp-auth/R3/bgpd_vrf_prefix.conf
new file mode 100644
index 0000000000..c109aa801b
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/bgpd_vrf_prefix.conf
@@ -0,0 +1,18 @@
+router bgp 65003 vrf blue
+ timers bgp 3 9
+ bgp router-id 3.3.3.3
+ neighbor 1.1.1.1 remote-as 65001
+ neighbor 1.1.1.1 update-source lo1
+ neighbor 1.1.1.1 ebgp-multihop 3
+ neighbor 1.1.1.1 timers 3 10
+ neighbor 1.1.1.1 timers connect 10
+ neighbor 1.1.1.1 password hello2
+ neighbor 2.2.2.2 remote-as 65002
+ neighbor 2.2.2.2 update-source lo1
+ neighbor 2.2.2.2 ebgp-multihop 3
+ neighbor 2.2.2.2 timers connect 10
+ neighbor 2.2.2.2 timers 3 10
+ neighbor 2.2.2.2 password hello3
+ address-family ipv4 unicast
+ neighbor 1.1.1.1 activate
+ neighbor 2.2.2.2 activate
diff --git a/tests/topotests/bgp-auth/R3/ospfd.conf b/tests/topotests/bgp-auth/R3/ospfd.conf
new file mode 100644
index 0000000000..0f0a2e926a
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/ospfd.conf
@@ -0,0 +1,4 @@
+router ospf
+ network 10.20.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 3.3.3.3/32 area 0
diff --git a/tests/topotests/bgp-auth/R3/ospfd_multi_vrf.conf b/tests/topotests/bgp-auth/R3/ospfd_multi_vrf.conf
new file mode 100644
index 0000000000..f32d2a8423
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/ospfd_multi_vrf.conf
@@ -0,0 +1,9 @@
+router ospf vrf blue
+ network 10.20.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 3.3.3.3/32 area 0
+!
+router ospf vrf red
+ network 10.20.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 3.3.3.3/32 area 0
diff --git a/tests/topotests/bgp-auth/R3/ospfd_vrf.conf b/tests/topotests/bgp-auth/R3/ospfd_vrf.conf
new file mode 100644
index 0000000000..6465b635aa
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/ospfd_vrf.conf
@@ -0,0 +1,4 @@
+router ospf vrf blue
+ network 10.20.0.0/16 area 0
+ network 10.30.0.0/16 area 0
+ network 3.3.3.3/32 area 0
diff --git a/tests/topotests/bgp-auth/R3/zebra.conf b/tests/topotests/bgp-auth/R3/zebra.conf
new file mode 100644
index 0000000000..0fe3acdfd0
--- /dev/null
+++ b/tests/topotests/bgp-auth/R3/zebra.conf
@@ -0,0 +1,21 @@
+log file zebra.log
+!
+interface lo
+ ip address 3.3.3.3/32
+interface lo1 vrf blue
+ ip address 3.3.3.3/32
+interface lo2 vrf red
+ ip address 3.3.3.3/32
+interface R3-eth0
+ ip address 10.20.0.3/24
+interface R3-eth1
+ ip address 10.30.0.3/24
+interface R3-eth2 vrf blue
+ ip address 10.20.0.3/24
+interface R3-eth3 vrf blue
+ ip address 10.30.0.3/24
+interface R3-eth4 vrf red
+ ip address 10.20.0.3/24
+interface R3-eth5 vrf red
+ ip address 10.30.0.3/24
+! \ No newline at end of file
diff --git a/tests/topotests/bgp-auth/test_bgp_auth.py b/tests/topotests/bgp-auth/test_bgp_auth.py
new file mode 100755
index 0000000000..6198997b86
--- /dev/null
+++ b/tests/topotests/bgp-auth/test_bgp_auth.py
@@ -0,0 +1,747 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_auth.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by Volta Networks
+#
+# 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.
+#
+
+"""
+test_bgp_auth.py: Test BGP Md5 Authentication
+
+ +------+
+ +--------| |--------+
+ | +------| R1 |------+ |
+ | | -----| |----+ | |
+ | | | +------+ | | |
+ | | | | | |
+ +------+ +------+
+ | |------------| |
+ | R2 |------------| R3 |
+ | |------------| |
+ +------+ +------+
+
+
+setup is 3 routers with 3 links between each each link in a different vrf
+Default, blue and red respectively
+Tests check various fiddling with passwords and checking that the peer
+establishment is as expected and passwords are not leaked across sockets
+for bgp instances
+"""
+
+import os
+import sys
+import json
+import platform
+from functools import partial
+import pytest
+from time import sleep
+
+# Save the Current Working Directory to find configuration files.
+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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+from lib.common_config import apply_raw_config
+
+ERROR_LIST = ["Malformed", "Failure", "Unknown", "Incomplete"]
+
+
+class InvalidCLIError(Exception):
+ """Raise when the CLI command is wrong"""
+
+ pass
+
+
+class TemplateTopo(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # This function only purpose is to define allocation and relationship
+ # between routers, switches and hosts.
+ #
+ #
+ # Create routers
+ tgen.add_router("R1")
+ tgen.add_router("R2")
+ tgen.add_router("R3")
+
+ # R1-R2 1
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R2"])
+
+ # R1-R3 1
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R3"])
+
+ # R2-R3 1
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["R2"])
+ switch.add_link(tgen.gears["R3"])
+
+ # R1-R2 2
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R2"])
+
+ # R1-R3 2
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R3"])
+
+ # R2-R3 2
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["R2"])
+ switch.add_link(tgen.gears["R3"])
+
+ # R1-R2 3
+ switch = tgen.add_switch("s7")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R2"])
+
+ # R1-R3 2
+ switch = tgen.add_switch("s8")
+ switch.add_link(tgen.gears["R1"])
+ switch.add_link(tgen.gears["R3"])
+
+ # R2-R3 2
+ switch = tgen.add_switch("s9")
+ switch.add_link(tgen.gears["R2"])
+ switch.add_link(tgen.gears["R3"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+ tgen.start_topology()
+
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+
+ # blue vrf
+ r1.run("ip link add blue type vrf table 1001")
+ r1.run("ip link set up dev blue")
+ r2.run("ip link add blue type vrf table 1001")
+ r2.run("ip link set up dev blue")
+ r3.run("ip link add blue type vrf table 1001")
+ r3.run("ip link set up dev blue")
+
+ r1.run("ip link add lo1 type dummy")
+ r1.run("ip link set lo1 master blue")
+ r1.run("ip link set up dev lo1")
+ r2.run("ip link add lo1 type dummy")
+ r2.run("ip link set up dev lo1")
+ r2.run("ip link set lo1 master blue")
+ r3.run("ip link add lo1 type dummy")
+ r3.run("ip link set up dev lo1")
+ r3.run("ip link set lo1 master blue")
+
+ r1.run("ip link set R1-eth2 master blue")
+ r1.run("ip link set R1-eth3 master blue")
+ r2.run("ip link set R2-eth2 master blue")
+ r2.run("ip link set R2-eth3 master blue")
+ r3.run("ip link set R3-eth2 master blue")
+ r3.run("ip link set R3-eth3 master blue")
+
+ r1.run("ip link set up dev R1-eth2")
+ r1.run("ip link set up dev R1-eth3")
+ r2.run("ip link set up dev R2-eth2")
+ r2.run("ip link set up dev R2-eth3")
+ r3.run("ip link set up dev R3-eth2")
+ r3.run("ip link set up dev R3-eth3")
+
+ # red vrf
+ r1.run("ip link add red type vrf table 1002")
+ r1.run("ip link set up dev red")
+ r2.run("ip link add red type vrf table 1002")
+ r2.run("ip link set up dev red")
+ r3.run("ip link add red type vrf table 1002")
+ r3.run("ip link set up dev red")
+
+ r1.run("ip link add lo2 type dummy")
+ r1.run("ip link set lo2 master red")
+ r1.run("ip link set up dev lo2")
+ r2.run("ip link add lo2 type dummy")
+ r2.run("ip link set up dev lo2")
+ r2.run("ip link set lo2 master red")
+ r3.run("ip link add lo2 type dummy")
+ r3.run("ip link set up dev lo2")
+ r3.run("ip link set lo2 master red")
+
+ r1.run("ip link set R1-eth4 master red")
+ r1.run("ip link set R1-eth5 master red")
+ r2.run("ip link set R2-eth4 master red")
+ r2.run("ip link set R2-eth5 master red")
+ r3.run("ip link set R3-eth4 master red")
+ r3.run("ip link set R3-eth5 master red")
+
+ r1.run("ip link set up dev R1-eth4")
+ r1.run("ip link set up dev R1-eth5")
+ r2.run("ip link set up dev R2-eth4")
+ r2.run("ip link set up dev R2-eth5")
+ r3.run("ip link set up dev R3-eth4")
+ r3.run("ip link set up dev R3-eth5")
+
+ # This is a sample of configuration loading.
+ router_list = tgen.routers()
+
+ # For all registred routers, load the zebra configuration file
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ # After loading the configurations, this function loads configured daemons.
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ tgen.stop_topology()
+
+
+def vrf_str(vrf):
+ if vrf == "":
+ vrf_str = ""
+ else:
+ vrf_str = "vrf {}".format(vrf)
+
+ return vrf_str
+
+
+def peer_name(rtr, prefix, vrf):
+ "generate VRF string for CLI"
+ if vrf == "":
+ vrf_str = ""
+ else:
+ vrf_str = "_" + vrf
+
+ if prefix == "yes":
+ if rtr == "R2":
+ return "TWO_GROUP" + vrf_str
+ else:
+ return "THREE_GROUP" + vrf_str
+ else:
+ if rtr == "R2":
+ return "2.2.2.2"
+ else:
+ return "3.3.3.3"
+
+
+def print_diag(vrf):
+ "print failure disagnostics"
+
+ tgen = get_topogen()
+ router_list = tgen.routers()
+ for rname, router in router_list.iteritems():
+ print(rname + ":")
+ print(router.vtysh_cmd("show run"))
+ print(router.vtysh_cmd("show ip route {}".format(vrf_str(vrf))))
+ print(router.vtysh_cmd("show bgp {} neighbor".format(vrf_str(vrf))))
+
+
+def configure(conf_file):
+ "configure from a file"
+
+ tgen = get_topogen()
+ router_list = tgen.routers()
+ for rname, router in router_list.iteritems():
+ with open(
+ os.path.join(CWD, "{}/{}").format(router.name, conf_file), "r+"
+ ) as cfg:
+ new_config = cfg.read()
+
+ output = router.vtysh_multicmd(new_config, pretty_output=False)
+ for out_err in ERROR_LIST:
+ if out_err.lower() in output.lower():
+ raise InvalidCLIError("%s" % output)
+
+
+def clear_bgp(vrf=""):
+ " clear bgp configuration for a vrf"
+
+ tgen = get_topogen()
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+
+ router_list = tgen.routers()
+ if vrf == "":
+ r1.vtysh_cmd("conf t\nno router bgp 65001")
+ r2.vtysh_cmd("conf t\nno router bgp 65002")
+ r2.vtysh_cmd("conf t\nno router bgp 65003")
+ else:
+ r1.vtysh_cmd("conf t\nno router bgp 65001 vrf {}".format(vrf))
+ r2.vtysh_cmd("conf t\nno router bgp 65002 vrf {}".format(vrf))
+ r3.vtysh_cmd("conf t\nno router bgp 65003 vrf {}".format(vrf))
+
+
+def clear_ospf(vrf=""):
+ "clear ospf configuration for a vrf"
+
+ tgen = get_topogen()
+ router_list = tgen.routers()
+ for rname, router in router_list.iteritems():
+ if vrf == "":
+ router.vtysh_cmd("conf t\nno router ospf")
+ else:
+ router.vtysh_cmd("conf t\nno router ospf vrf {}".format(vrf))
+
+
+def check_neigh_state(router, peer, state, vrf=""):
+ "check BGP neighbor state on a router"
+
+ count = 0
+ matched = False
+ neigh_output = ""
+ while count < 125:
+ if vrf == "":
+ neigh_output = router.vtysh_cmd("show bgp neighbors {} json".format(peer))
+ else:
+ neigh_output = router.vtysh_cmd(
+ "show bgp vrf {} neighbors {} json".format(vrf, peer)
+ )
+ neigh_output_json = json.loads(neigh_output)
+ if neigh_output_json[peer]["bgpState"] == state:
+ matched = True
+ break
+ count += 1
+ sleep(1)
+
+ assertmsg = "{} could not peer {} state expected {} got {} ".format(
+ router.name, peer, state, neigh_output_json[peer]["bgpState"]
+ )
+ if matched != True:
+ print_diag(vrf)
+ assert matched == True, assertmsg
+
+
+def check_all_peers_established(vrf=""):
+ "standard check for extablished peers per vrf"
+
+ tgen = get_topogen()
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+ # do r1 last as he might be the dynamic one
+ check_neigh_state(r2, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Established", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "3.3.3.3", "Established", vrf)
+
+
+def check_vrf_peer_remove_passwords(vrf="", prefix="no"):
+ "selectively remove passwords checking state"
+
+ tgen = get_topogen()
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+
+ r1.vtysh_cmd(
+ "conf t\nrouter bgp 65001 {}\nno neighbor {} password".format(
+ vrf_str(vrf), peer_name("R2", prefix, vrf)
+ )
+ )
+
+ check_neigh_state(r2, "1.1.1.1", "Connect", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Established", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Established", vrf)
+ # don't check dynamic downed peers - they are removed
+ if prefix == "no":
+ check_neigh_state(r1, "2.2.2.2", "Connect", vrf)
+ check_neigh_state(r1, "3.3.3.3", "Established", vrf)
+
+ r2.vtysh_cmd(
+ "conf t\nrouter bgp 65002 {}\nno neighbor 1.1.1.1 password".format(vrf_str(vrf))
+ )
+ check_all_peers_established(vrf)
+
+ r1.vtysh_cmd(
+ "conf t\nrouter bgp 65001 {}\nno neighbor {} password".format(
+ vrf_str(vrf), peer_name("R3", prefix, vrf)
+ )
+ )
+ check_neigh_state(r2, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Established", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Connect", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "2.2.2.2", "Established", vrf)
+ # don't check dynamic downed peers - they are removed
+ if prefix == "no":
+ check_neigh_state(r1, "3.3.3.3", "Connect", vrf)
+
+ r3.vtysh_cmd(
+ "conf t\nrouter bgp 65003 {}\nno neighbor 1.1.1.1 password".format(vrf_str(vrf))
+ )
+ check_all_peers_established(vrf)
+
+ r2.vtysh_cmd(
+ "conf t\nrouter bgp 65002 {}\nno neighbor 3.3.3.3 password".format(vrf_str(vrf))
+ )
+ check_neigh_state(r2, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Connect", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Connect", vrf)
+ check_neigh_state(r1, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "3.3.3.3", "Established", vrf)
+
+ r3.vtysh_cmd(
+ "conf t\nrouter bgp 65003 {}\nno neighbor 2.2.2.2 password".format(vrf_str(vrf))
+ )
+ check_all_peers_established(vrf)
+
+
+def check_vrf_peer_change_passwords(vrf="", prefix="no"):
+ "selectively change passwords checking state"
+
+ tgen = get_topogen()
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+ check_all_peers_established(vrf)
+
+ r1.vtysh_cmd(
+ "conf t\nrouter bgp 65001 {}\nneighbor {} password change1".format(
+ vrf_str(vrf), peer_name("R2", prefix, vrf)
+ )
+ )
+ check_neigh_state(r2, "1.1.1.1", "Connect", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Established", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Established", vrf)
+ # don't check dynamic downed peers - they are removed
+ if prefix == "no":
+ check_neigh_state(r1, "2.2.2.2", "Connect", vrf)
+ check_neigh_state(r1, "3.3.3.3", "Established", vrf)
+
+ r2.vtysh_cmd(
+ "conf t\nrouter bgp 65002 {}\nneighbor 1.1.1.1 password change1".format(
+ vrf_str(vrf)
+ )
+ )
+ check_all_peers_established(vrf)
+
+ r1.vtysh_cmd(
+ "conf t\nrouter bgp 65001 {}\nneighbor {} password change2".format(
+ vrf_str(vrf), peer_name("R3", prefix, vrf)
+ )
+ )
+ check_neigh_state(r2, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Established", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Connect", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "2.2.2.2", "Established", vrf)
+ # don't check dynamic downed peers - they are removed
+ if prefix == "no":
+ check_neigh_state(r1, "3.3.3.3", "Connect", vrf)
+
+ r3.vtysh_cmd(
+ "conf t\nrouter bgp 65003 {}\nneighbor 1.1.1.1 password change2".format(
+ vrf_str(vrf)
+ )
+ )
+ check_all_peers_established(vrf)
+
+ r2.vtysh_cmd(
+ "conf t\nrouter bgp 65002 {}\nneighbor 3.3.3.3 password change3".format(
+ vrf_str(vrf)
+ )
+ )
+ check_neigh_state(r2, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r2, "3.3.3.3", "Connect", vrf)
+ check_neigh_state(r3, "1.1.1.1", "Established", vrf)
+ check_neigh_state(r3, "2.2.2.2", "Connect", vrf)
+ check_neigh_state(r1, "2.2.2.2", "Established", vrf)
+ check_neigh_state(r1, "3.3.3.3", "Established", vrf)
+
+ r3.vtysh_cmd(
+ "conf t\nrouter bgp 65003 {}\nneighbor 2.2.2.2 password change3".format(
+ vrf_str(vrf)
+ )
+ )
+ check_all_peers_established(vrf)
+
+
+def test_default_peer_established():
+ "default vrf 3 peers same password"
+
+ check_all_peers_established()
+ clear_bgp()
+ # tgen.mininet_cli()
+
+
+def test_default_peer_remove_passwords():
+ "selectively remove passwords checking state"
+
+ configure("bgpd.conf")
+ check_vrf_peer_remove_passwords()
+ clear_bgp()
+
+
+def test_default_peer_change_passwords():
+ "selectively change passwords checking state"
+
+ configure("bgpd.conf")
+ check_vrf_peer_change_passwords()
+ clear_bgp()
+
+
+def test_default_prefix_peer_established():
+ "default vrf 3 peers same password with prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+
+ configure("bgpd_prefix.conf")
+ check_all_peers_established()
+ clear_bgp()
+ # tgen.mininet_cli()
+
+
+def test_prefix_peer_remove_passwords():
+ "selectively remove passwords checking state with prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+ configure("bgpd_prefix.conf")
+ check_vrf_peer_remove_passwords(prefix="yes")
+ clear_bgp()
+
+
+def test_prefix_peer_change_passwords():
+ "selecively change passwords checkig state with prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+ configure("bgpd_prefix.conf")
+ check_vrf_peer_change_passwords(prefix="yes")
+ clear_bgp()
+ clear_ospf()
+
+
+def test_vrf_peer_established():
+ "default vrf 3 peers same password with VRF config"
+
+ # clean routers and load vrf config
+ configure("bgpd_vrf.conf")
+ configure("ospfd_vrf.conf")
+
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+ # tgen.mininet_cli()
+
+
+def test_vrf_peer_remove_passwords():
+ "selectively remove passwords checking state with VRF config"
+
+ configure("bgpd_vrf.conf")
+ check_vrf_peer_remove_passwords(vrf="blue")
+ clear_bgp("blue")
+
+
+def test_vrf_peer_change_passwords():
+ "selectively change passwords checking state with VRF config"
+
+ configure("bgpd_vrf.conf")
+ check_vrf_peer_change_passwords(vrf="blue")
+ clear_bgp("blue")
+
+
+def test_vrf_prefix_peer_established():
+ "default vrf 3 peers same password with VRF prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ clear_bgp("blue")
+ return
+
+ configure("bgpd_vrf_prefix.conf")
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+
+
+def test_vrf_prefix_peer_remove_passwords():
+ "selectively remove passwords checking state with VRF prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+
+ configure("bgpd_vrf_prefix.conf")
+ check_vrf_peer_remove_passwords(vrf="blue", prefix="yes")
+ clear_bgp("blue")
+
+
+def test_vrf_prefix_peer_change_passwords():
+ "selectively change passwords checking state with VRF prefix config"
+
+ tgen = get_topogen()
+ r1 = tgen.gears["R1"]
+ r2 = tgen.gears["R2"]
+ r3 = tgen.gears["R3"]
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ clear_ospf("blue")
+ return
+
+ configure("bgpd_vrf_prefix.conf")
+ check_vrf_peer_change_passwords(vrf="blue", prefix="yes")
+ clear_bgp("blue")
+ clear_ospf("blue")
+
+
+def test_multiple_vrf_peer_established():
+ "default vrf 3 peers same password with multiple VRFs"
+
+ configure("bgpd_multi_vrf.conf")
+ configure("ospfd_multi_vrf.conf")
+ check_all_peers_established("blue")
+ check_all_peers_established("red")
+ clear_bgp("blue")
+ clear_bgp("red")
+ # tgen.mininet_cli()
+
+
+def test_multiple_vrf_peer_remove_passwords():
+ "selectively remove passwords checking state with multiple VRFs"
+
+ configure("bgpd_multi_vrf.conf")
+ check_vrf_peer_remove_passwords("blue")
+ check_all_peers_established("red")
+ check_vrf_peer_remove_passwords("red")
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+ clear_bgp("red")
+ # tgen.mininet_cli()
+
+
+def test_multiple_vrf_peer_change_passwords():
+ "selectively change passwords checking state with multiple VRFs"
+
+ configure("bgpd_multi_vrf.conf")
+ check_vrf_peer_change_passwords("blue")
+ check_all_peers_established("red")
+ check_vrf_peer_change_passwords("red")
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+ clear_bgp("red")
+ # tgen.mininet_cli()
+
+
+def test_multiple_vrf_prefix_peer_established():
+ "default vrf 3 peers same password with multilpe VRFs and prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+
+ configure("bgpd_multi_vrf.conf")
+ configure("ospfd_multi_vrf.conf")
+ check_all_peers_established("blue")
+ check_all_peers_established("red")
+ clear_bgp("blue")
+ clear_bgp("red")
+ # tgen.mininet_cli()
+
+
+def test_multiple_vrf_prefix_peer_remove_passwords():
+ "selectively remove passwords checking state with multiple vrfs and prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ return
+
+ configure("bgpd_multi_vrf_prefix.conf")
+ tgen = get_topogen()
+ check_vrf_peer_remove_passwords(vrf="blue", prefix="yes")
+ check_all_peers_established("red")
+ check_vrf_peer_remove_passwords(vrf="red", prefix="yes")
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+ clear_bgp("red")
+ # tgen.mininet_cli()
+
+
+def test_multiple_vrf_prefix_peer_change_passwords():
+ "selectively change passwords checking state with multiple vrfs and prefix config"
+
+ # only supported in kernel > 5.3
+ if topotest.version_cmp(platform.release(), "5.3") < 0:
+ clear_bgp("blue")
+ clear_bgp("red")
+ clear_ospf("blue")
+ clear_ospf("red")
+ return
+
+ configure("bgpd_multi_vrf_prefix.conf")
+ check_vrf_peer_change_passwords(vrf="blue", prefix="yes")
+ check_all_peers_established("red")
+ check_vrf_peer_change_passwords(vrf="red", prefix="yes")
+ check_all_peers_established("blue")
+ clear_bgp("blue")
+ clear_bgp("red")
+ clear_ospf("blue")
+ clear_ospf("red")
+ # tgen.mininet_cli()
+
+
+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-basic-functionality-topo1/bgp_basic_functionality.json b/tests/topotests/bgp-basic-functionality-topo1/bgp_basic_functionality.json
index c778ae4bed..ee1f1b74c0 100644
--- a/tests/topotests/bgp-basic-functionality-topo1/bgp_basic_functionality.json
+++ b/tests/topotests/bgp-basic-functionality-topo1/bgp_basic_functionality.json
@@ -1,36 +1,17 @@
{
+ "address_types": ["ipv4", "ipv6"],
"ipv4base": "10.0.0.0",
"ipv4mask": 30,
"ipv6base": "fd00::",
"ipv6mask": 64,
- "link_ip_start": {
- "ipv4": "10.0.0.0",
- "v4mask": 30,
- "ipv6": "fd00::",
- "v6mask": 64
- },
- "lo_prefix": {
- "ipv4": "1.0.",
- "v4mask": 32,
- "ipv6": "2001:DB8:F::",
- "v6mask": 128
- },
+ "link_ip_start": {"ipv4": "10.0.0.0", "v4mask": 30, "ipv6": "fd00::", "v6mask": 64},
+ "lo_prefix": {"ipv4": "1.0.", "v4mask": 32, "ipv6": "2001:db8:f::", "v6mask": 128},
"routers": {
"r1": {
"links": {
- "lo": {
- "ipv4": "auto",
- "ipv6": "auto",
- "type": "loopback"
- },
- "r2": {
- "ipv4": "auto",
- "ipv6": "auto"
- },
- "r3": {
- "ipv4": "auto",
- "ipv6": "auto"
- }
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2": {"ipv4": "auto", "ipv6": "auto"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
},
"bgp": {
"local_as": "100",
@@ -38,16 +19,16 @@
"ipv4": {
"unicast": {
"neighbor": {
- "r2": {
- "dest_link": {
- "r1": {}
- }
- },
- "r3": {
- "dest_link": {
- "r1": {}
- }
- }
+ "r2": {"dest_link": {"r1": {}}},
+ "r3": {"dest_link": {"r1": {}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {"dest_link": {"r1": {}}},
+ "r3": {"dest_link": {"r1": {}}}
}
}
}
@@ -56,19 +37,9 @@
},
"r2": {
"links": {
- "lo": {
- "ipv4": "auto",
- "ipv6": "auto",
- "type": "loopback"
- },
- "r1": {
- "ipv4": "auto",
- "ipv6": "auto"
- },
- "r3": {
- "ipv4": "auto",
- "ipv6": "auto"
- }
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1": {"ipv4": "auto", "ipv6": "auto"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
},
"bgp": {
"local_as": "100",
@@ -76,16 +47,16 @@
"ipv4": {
"unicast": {
"neighbor": {
- "r1": {
- "dest_link": {
- "r2": {}
- }
- },
- "r3": {
- "dest_link": {
- "r2": {}
- }
- }
+ "r1": {"dest_link": {"r2": {}}},
+ "r3": {"dest_link": {"r2": {}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r2": {}}},
+ "r3": {"dest_link": {"r2": {}}}
}
}
}
@@ -94,23 +65,10 @@
},
"r3": {
"links": {
- "lo": {
- "ipv4": "auto",
- "ipv6": "auto",
- "type": "loopback"
- },
- "r1": {
- "ipv4": "auto",
- "ipv6": "auto"
- },
- "r2": {
- "ipv4": "auto",
- "ipv6": "auto"
- },
- "r4": {
- "ipv4": "auto",
- "ipv6": "auto"
- }
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2": {"ipv4": "auto", "ipv6": "auto"},
+ "r4": {"ipv4": "auto", "ipv6": "auto"}
},
"bgp": {
"local_as": "100",
@@ -118,21 +76,18 @@
"ipv4": {
"unicast": {
"neighbor": {
- "r1": {
- "dest_link": {
- "r3": {}
- }
- },
- "r2": {
- "dest_link": {
- "r3": {}
- }
- },
- "r4": {
- "dest_link": {
- "r3": {}
- }
- }
+ "r1": {"dest_link": {"r3": {}}},
+ "r2": {"dest_link": {"r3": {}}},
+ "r4": {"dest_link": {"r3": {}}}
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {"dest_link": {"r3": {}}},
+ "r2": {"dest_link": {"r3": {}}},
+ "r4": {"dest_link": {"r3": {}}}
}
}
}
@@ -141,29 +96,17 @@
},
"r4": {
"links": {
- "lo": {
- "ipv4": "auto",
- "ipv6": "auto",
- "type": "loopback"
- },
- "r3": {
- "ipv4": "auto",
- "ipv6": "auto"
- }
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
},
"bgp": {
"local_as": "200",
"address_family": {
"ipv4": {
- "unicast": {
- "neighbor": {
- "r3": {
- "dest_link": {
- "r4": {}
- }
- }
- }
- }
+ "unicast": {"neighbor": {"r3": {"dest_link": {"r4": {}}}}}
+ },
+ "ipv6": {
+ "unicast": {"neighbor": {"r3": {"dest_link": {"r4": {}}}}}
}
}
}
diff --git a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
index 3441d68731..41fa7c0a09 100755
--- a/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
+++ b/tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
@@ -37,6 +37,8 @@ Test steps
- Verify clear bgp
- Test bgp convergence with loopback interface
- Test advertise network using network command
+- Verify routes not installed in zebra when /32 routes received
+ with loopback BGP session subnet
"""
import os
@@ -59,6 +61,7 @@ from lib.topogen import Topogen, get_topogen
from mininet.topo import Topo
from lib.common_config import (
+ step,
start_topology,
write_test_header,
write_test_footer,
@@ -66,6 +69,14 @@ from lib.common_config import (
create_static_routes,
verify_rib,
verify_admin_distance_for_static_routes,
+ check_address_types,
+ apply_raw_config,
+ addKernelRoute,
+ verify_fib_routes,
+ create_prefix_lists,
+ create_route_maps,
+ verify_bgp_community,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import (
@@ -76,6 +87,7 @@ from lib.bgp import (
verify_as_numbers,
clear_bgp_and_verify,
verify_bgp_timers_and_functionality,
+ verify_bgp_rib,
)
from lib.topojson import build_topo_from_json, build_config_from_json
@@ -90,6 +102,18 @@ except IOError:
# Global Variable
KEEPALIVETIMER = 2
HOLDDOWNTIMER = 6
+r1_ipv4_loopback = "1.0.1.0/24"
+r2_ipv4_loopback = "1.0.2.0/24"
+r3_ipv4_loopback = "1.0.3.0/24"
+r4_ipv4_loopback = "1.0.4.0/24"
+r1_ipv6_loopback = "2001:db8:f::1:0/120"
+r2_ipv6_loopback = "2001:db8:f::2:0/120"
+r3_ipv6_loopback = "2001:db8:f::3:0/120"
+r4_ipv6_loopback = "2001:db8:f::4:0/120"
+NETWORK = {
+ "ipv4": ["100.1.1.1/32", "100.1.1.2/32"],
+ "ipv6": ["100::1/128", "100::2/128"],
+}
class CreateTopo(Topo):
@@ -114,6 +138,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
@@ -131,7 +160,9 @@ def setup_module(mod):
# Creating configuration from JSON
build_config_from_json(tgen, topo)
+ global ADDR_TYPES
global BGP_CONVERGENCE
+ ADDR_TYPES = check_address_types()
BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format(
BGP_CONVERGENCE
@@ -522,6 +553,243 @@ def test_clear_bgp_and_verify(request):
write_test_footer(tc_name)
+def test_BGP_attributes_with_vrf_default_keyword_p0(request):
+ """
+ TC_9:
+ Verify BGP functionality for default vrf with
+ "vrf default" keyword.
+ """
+
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ #reset_config_on_routers(tgen)
+
+ step("Configure static routes and redistribute in BGP on R3")
+ for addr_type in ADDR_TYPES:
+ input_dict = {
+ "r3": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type][0],
+ "no_of_ip": 4,
+ "next_hop": "Null0",
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ input_dict_2 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ "ipv6": {"unicast": {"redistribute": [{"redist_type": "static"}]}},
+ }
+ }
+ }
+ }
+ result = create_router_bgp(tgen, topo, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "Create a route-map to match a specific prefix and modify"
+ "BGP attributes for matched prefix"
+ )
+ input_dict_2 = {
+ "r3": {
+ "prefix_lists": {
+ "ipv4": {
+ "ABC": [
+ {
+ "seqid": 10,
+ "action": "permit",
+ "network": NETWORK["ipv4"][0],
+ }
+ ]
+ },
+ "ipv6": {
+ "XYZ": [
+ {
+ "seqid": 100,
+ "action": "permit",
+ "network": NETWORK["ipv6"][0],
+ }
+ ]
+ },
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_2)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ if addr_type == "ipv4":
+ pf_list = "ABC"
+ else:
+ pf_list = "XYZ"
+
+ input_dict_6 = {
+ "r3": {
+ "route_maps": {
+ "BGP_ATTR_{}".format(addr_type): [
+ {
+ "action": "permit",
+ "seq_id": 10,
+ "match": {addr_type: {"prefix_lists": pf_list}},
+ "set": {
+ "aspath": {"as_num": 500, "as_action": "prepend"},
+ "localpref": 500,
+ "origin": "egp",
+ "community": {"num": "500:500", "action": "additive"},
+ "large_community": {
+ "num": "500:500:500",
+ "action": "additive",
+ },
+ },
+ },
+ {"action": "permit", "seq_id": 20},
+ ]
+ },
+ "BGP_ATTR_{}".format(addr_type): [
+ {
+ "action": "permit",
+ "seq_id": 100,
+ "match": {addr_type: {"prefix_lists": pf_list}},
+ "set": {
+ "aspath": {"as_num": 500, "as_action": "prepend"},
+ "localpref": 500,
+ "origin": "egp",
+ "community": {"num": "500:500", "action": "additive"},
+ "large_community": {
+ "num": "500:500:500",
+ "action": "additive",
+ },
+ },
+ },
+ {"action": "permit", "seq_id": 200},
+ ],
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_6)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ step("Apply the route-map on R3 in outbound direction for peer R4")
+
+ input_dict_7 = {
+ "r3": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {
+ "name": "BGP_ATTR_ipv4",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r3": {
+ "route_maps": [
+ {
+ "name": "BGP_ATTR_ipv6",
+ "direction": "out",
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_7)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step(
+ "verify modified attributes for specific prefix with 'vrf default'"
+ "keyword on R4"
+ )
+ for addr_type in ADDR_TYPES:
+ dut = "r4"
+ input_dict = {
+ "r3": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type][0],
+ "vrf": "default",
+ "largeCommunity": "500:500:500",
+ }
+ ]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ dut = "r4"
+ input_dict = {
+ "r3": {
+ "static_routes": [
+ {
+ "network": NETWORK[addr_type][0],
+ "vrf": "default",
+ "community": "500:500",
+ }
+ ]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
+ result = verify_rib(tgen, addr_type, dut, input_dict)
+ assert result is True, "Testcase : Failed \n Error: {}".format(tc_name, result)
+
+ input_dict_4 = {"largeCommunity": "500:500:500", "community": "500:500"}
+
+ result = verify_bgp_community(
+ tgen, addr_type, dut, [NETWORK[addr_type][0]], input_dict_4
+ )
+ assert result is True, "Test case {} : Should fail \n Error: {}".format(
+ tc_name, result
+ )
+
+ write_test_footer(tc_name)
+
+
def test_bgp_with_loopback_interface(request):
"""
Test BGP with loopback interface
@@ -588,6 +856,298 @@ def test_bgp_with_loopback_interface(request):
write_test_footer(tc_name)
+def test_bgp_with_loopback_with_same_subnet_p1(request):
+ """
+ Verify routes not installed in zebra when /32 routes received
+ with loopback BGP session subnet
+ """
+
+ tgen = get_topogen()
+ if BGP_CONVERGENCE is not True:
+ pytest.skip("skipped because of BGP Convergence failure")
+
+ # test case name
+ tc_name = request.node.name
+ write_test_header(tc_name)
+
+ # Creating configuration from JSON
+ reset_config_on_routers(tgen)
+ step("Delete BGP seesion created initially")
+ input_dict_r1 = {
+ "r1": {"bgp": {"delete": True}},
+ "r2": {"bgp": {"delete": True}},
+ "r3": {"bgp": {"delete": True}},
+ "r4": {"bgp": {"delete": True}},
+ }
+ result = create_router_bgp(tgen, topo, input_dict_r1)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Create BGP session over loop address")
+ topo_modify = deepcopy(topo)
+
+ for routerN in sorted(topo["routers"].keys()):
+ for addr_type in ADDR_TYPES:
+ for bgp_neighbor in topo_modify["routers"][routerN]["bgp"][
+ "address_family"
+ ][addr_type]["unicast"]["neighbor"].keys():
+
+ # Adding ['source_link'] = 'lo' key:value pair
+ topo_modify["routers"][routerN]["bgp"]["address_family"][addr_type][
+ "unicast"
+ ]["neighbor"][bgp_neighbor]["dest_link"] = {
+ "lo": {"source_link": "lo", "ebgp_multihop": 2}
+ }
+
+ result = create_router_bgp(tgen, topo_modify["routers"])
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
+
+ step("Disable IPv6 BGP nbr from ipv4 address family")
+ raw_config = {
+ "r1": {
+ "raw_config": [
+ "router bgp {}".format(topo["routers"]["r1"]["bgp"]["local_as"]),
+ "address-family ipv4 unicast",
+ "no neighbor {} activate".format(
+ topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ "no neighbor {} activate".format(
+ topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ ]
+ },
+ "r2": {
+ "raw_config": [
+ "router bgp {}".format(topo["routers"]["r2"]["bgp"]["local_as"]),
+ "address-family ipv4 unicast",
+ "no neighbor {} activate".format(
+ topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ "no neighbor {} activate".format(
+ topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ ]
+ },
+ "r3": {
+ "raw_config": [
+ "router bgp {}".format(topo["routers"]["r3"]["bgp"]["local_as"]),
+ "address-family ipv4 unicast",
+ "no neighbor {} activate".format(
+ topo["routers"]["r1"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ "no neighbor {} activate".format(
+ topo["routers"]["r2"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ "no neighbor {} activate".format(
+ topo["routers"]["r4"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ ]
+ },
+ "r4": {
+ "raw_config": [
+ "router bgp {}".format(topo["routers"]["r4"]["bgp"]["local_as"]),
+ "address-family ipv4 unicast",
+ "no neighbor {} activate".format(
+ topo["routers"]["r3"]["links"]["lo"]["ipv6"].split("/")[0]
+ ),
+ ]
+ },
+ }
+
+ step("Configure kernel routes")
+ result = apply_raw_config(tgen, raw_config)
+ assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
+
+ r1_ipv4_lo = topo["routers"]["r1"]["links"]["lo"]["ipv4"]
+ r1_ipv6_lo = topo["routers"]["r1"]["links"]["lo"]["ipv6"]
+ r2_ipv4_lo = topo["routers"]["r2"]["links"]["lo"]["ipv4"]
+ r2_ipv6_lo = topo["routers"]["r2"]["links"]["lo"]["ipv6"]
+ r3_ipv4_lo = topo["routers"]["r3"]["links"]["lo"]["ipv4"]
+ r3_ipv6_lo = topo["routers"]["r3"]["links"]["lo"]["ipv6"]
+ r4_ipv4_lo = topo["routers"]["r4"]["links"]["lo"]["ipv4"]
+ r4_ipv6_lo = topo["routers"]["r4"]["links"]["lo"]["ipv6"]
+
+ r1_r2 = topo["routers"]["r1"]["links"]["r2"]["ipv6"].split("/")[0]
+ r2_r1 = topo["routers"]["r2"]["links"]["r1"]["ipv6"].split("/")[0]
+ r1_r3 = topo["routers"]["r1"]["links"]["r3"]["ipv6"].split("/")[0]
+ r3_r1 = topo["routers"]["r3"]["links"]["r1"]["ipv6"].split("/")[0]
+ r2_r3 = topo["routers"]["r2"]["links"]["r3"]["ipv6"].split("/")[0]
+ r3_r2 = topo["routers"]["r3"]["links"]["r2"]["ipv6"].split("/")[0]
+ r3_r4 = topo["routers"]["r3"]["links"]["r4"]["ipv6"].split("/")[0]
+ r4_r3 = topo["routers"]["r4"]["links"]["r3"]["ipv6"].split("/")[0]
+
+ r1_r2_ipv4 = topo["routers"]["r1"]["links"]["r2"]["ipv4"].split("/")[0]
+ r2_r1_ipv4 = topo["routers"]["r2"]["links"]["r1"]["ipv4"].split("/")[0]
+ r1_r3_ipv4 = topo["routers"]["r1"]["links"]["r3"]["ipv4"].split("/")[0]
+ r3_r1_ipv4 = topo["routers"]["r3"]["links"]["r1"]["ipv4"].split("/")[0]
+ r2_r3_ipv4 = topo["routers"]["r2"]["links"]["r3"]["ipv4"].split("/")[0]
+ r3_r2_ipv4 = topo["routers"]["r3"]["links"]["r2"]["ipv4"].split("/")[0]
+ r3_r4_ipv4 = topo["routers"]["r3"]["links"]["r4"]["ipv4"].split("/")[0]
+ r4_r3_ipv4 = topo["routers"]["r4"]["links"]["r3"]["ipv4"].split("/")[0]
+
+ r1_r2_intf = topo["routers"]["r1"]["links"]["r2"]["interface"]
+ r2_r1_intf = topo["routers"]["r2"]["links"]["r1"]["interface"]
+ r1_r3_intf = topo["routers"]["r1"]["links"]["r3"]["interface"]
+ r3_r1_intf = topo["routers"]["r3"]["links"]["r1"]["interface"]
+ r2_r3_intf = topo["routers"]["r2"]["links"]["r3"]["interface"]
+ r3_r2_intf = topo["routers"]["r3"]["links"]["r2"]["interface"]
+ r3_r4_intf = topo["routers"]["r3"]["links"]["r4"]["interface"]
+ r4_r3_intf = topo["routers"]["r4"]["links"]["r3"]["interface"]
+
+ ipv4_list = [
+ ("r1", r1_r2_intf, r2_ipv4_loopback),
+ ("r1", r1_r3_intf, r3_ipv4_loopback),
+ ("r2", r2_r1_intf, r1_ipv4_loopback),
+ ("r2", r2_r3_intf, r3_ipv4_loopback),
+ ("r3", r3_r1_intf, r1_ipv4_loopback),
+ ("r3", r3_r2_intf, r2_ipv4_loopback),
+ ("r3", r3_r4_intf, r4_ipv4_loopback),
+ ("r4", r4_r3_intf, r3_ipv4_loopback),
+ ]
+
+ ipv6_list = [
+ ("r1", r1_r2_intf, r2_ipv6_loopback, r2_r1),
+ ("r1", r1_r3_intf, r3_ipv6_loopback, r3_r1),
+ ("r2", r2_r1_intf, r1_ipv6_loopback, r1_r2),
+ ("r2", r2_r3_intf, r3_ipv6_loopback, r3_r2),
+ ("r3", r3_r1_intf, r1_ipv6_loopback, r1_r3),
+ ("r3", r3_r2_intf, r2_ipv6_loopback, r2_r3),
+ ("r3", r3_r4_intf, r4_ipv6_loopback, r4_r3),
+ ("r4", r4_r3_intf, r3_ipv6_loopback, r3_r4),
+ ]
+
+ for dut, intf, loop_addr in ipv4_list:
+ result = addKernelRoute(tgen, dut, intf, loop_addr)
+ assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
+
+ for dut, intf, loop_addr, next_hop in ipv6_list:
+ result = addKernelRoute(tgen, dut, intf, loop_addr, next_hop)
+ assert result is True, "Testcase {}:Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure static routes")
+
+ input_dict = {
+ "r1": {
+ "static_routes": [
+ {"network": r2_ipv4_loopback, "next_hop": r2_r1_ipv4},
+ {"network": r3_ipv4_loopback, "next_hop": r3_r1_ipv4},
+ {"network": r2_ipv6_loopback, "next_hop": r2_r1},
+ {"network": r3_ipv6_loopback, "next_hop": r3_r1},
+ ]
+ },
+ "r2": {
+ "static_routes": [
+ {"network": r1_ipv4_loopback, "next_hop": r1_r2_ipv4},
+ {"network": r3_ipv4_loopback, "next_hop": r3_r2_ipv4},
+ {"network": r1_ipv6_loopback, "next_hop": r1_r2},
+ {"network": r3_ipv6_loopback, "next_hop": r3_r2},
+ ]
+ },
+ "r3": {
+ "static_routes": [
+ {"network": r1_ipv4_loopback, "next_hop": r1_r3_ipv4},
+ {"network": r2_ipv4_loopback, "next_hop": r2_r3_ipv4},
+ {"network": r4_ipv4_loopback, "next_hop": r4_r3_ipv4},
+ {"network": r1_ipv6_loopback, "next_hop": r1_r3},
+ {"network": r2_ipv6_loopback, "next_hop": r2_r3},
+ {"network": r4_ipv6_loopback, "next_hop": r4_r3},
+ ]
+ },
+ "r4": {
+ "static_routes": [
+ {"network": r3_ipv4_loopback, "next_hop": r3_r4_ipv4},
+ {"network": r3_ipv6_loopback, "next_hop": r3_r4},
+ ]
+ },
+ }
+ result = create_static_routes(tgen, input_dict)
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify BGP session convergence")
+
+ result = verify_bgp_convergence(tgen, topo_modify)
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+ step("Configure redistribute connected on R2 and R4")
+ input_dict_1 = {
+ "r2": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {"redistribute": [{"redist_type": "connected"}]}
+ },
+ "ipv6": {
+ "unicast": {"redistribute": [{"redist_type": "connected"}]}
+ },
+ }
+ }
+ },
+ "r4": {
+ "bgp": {
+ "address_family": {
+ "ipv4": {
+ "unicast": {"redistribute": [{"redist_type": "connected"}]}
+ },
+ "ipv6": {
+ "unicast": {"redistribute": [{"redist_type": "connected"}]}
+ },
+ }
+ }
+ },
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
+
+ step("Verify Ipv4 and Ipv6 network installed in R1 RIB but not in FIB")
+ input_dict_r1 = {
+ "r1": {
+ "static_routes": [
+ {"network": "1.0.2.17/32"},
+ {"network": "2001:db8:f::2:17/128"},
+ ]
+ }
+ }
+
+ dut = "r1"
+ protocol = "bgp"
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(tgen, addr_type, dut, input_dict_r1, protocol=protocol)
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
+ assert result is not True, "Testcase {} : Failed \n"
+ "Expected behavior: routes should not present in fib \n"
+ "Error: {}".format(tc_name, result)
+
+ step("Verify Ipv4 and Ipv6 network installed in r3 RIB but not in FIB")
+ input_dict_r3 = {
+ "r3": {
+ "static_routes": [
+ {"network": "1.0.4.17/32"},
+ {"network": "2001:db8:f::4:17/128"},
+ ]
+ }
+ }
+ dut = "r3"
+ protocol = "bgp"
+ for addr_type in ADDR_TYPES:
+ result = verify_rib(
+ tgen, addr_type, dut, input_dict_r3, protocol=protocol, fib=None
+ )
+ assert result is True, "Testcase {} :Failed \n Error: {}".format(
+ tc_name, result
+ )
+
+ result = verify_fib_routes(tgen, addr_type, dut, input_dict_r1, expected=False)
+ assert result is not True, "Testcase {} : Failed \n"
+ "Expected behavior: routes should not present in fib \n"
+ "Error: {}".format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf
index d3beb2d320..49981ac589 100644
--- a/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf
+++ b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf
@@ -7,25 +7,45 @@ router bgp 100
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 10.0.1.101 remote-as 99
+ neighbor 10.0.1.101 timers 3 10
neighbor 10.0.1.102 remote-as 99
+ neighbor 10.0.1.102 timers 3 10
neighbor 10.0.1.103 remote-as 99
+ neighbor 10.0.1.103 timers 3 10
neighbor 10.0.1.104 remote-as 99
+ neighbor 10.0.1.104 timers 3 10
neighbor 10.0.1.105 remote-as 99
+ neighbor 10.0.1.105 timers 3 10
neighbor 10.0.2.106 remote-as 99
+ neighbor 10.0.2.106 timers 3 10
neighbor 10.0.2.107 remote-as 99
+ neighbor 10.0.2.107 timers 3 10
neighbor 10.0.2.108 remote-as 99
+ neighbor 10.0.2.108 timers 3 10
neighbor 10.0.2.109 remote-as 99
+ neighbor 10.0.2.109 timers 3 10
neighbor 10.0.2.110 remote-as 99
+ neighbor 10.0.2.110 timers 3 10
neighbor 10.0.3.111 remote-as 111
+ neighbor 10.0.3.111 timers 3 10
neighbor 10.0.3.112 remote-as 112
+ neighbor 10.0.3.112 timers 3 10
neighbor 10.0.3.113 remote-as 113
+ neighbor 10.0.3.113 timers 3 10
neighbor 10.0.3.114 remote-as 114
+ neighbor 10.0.3.114 timers 3 10
neighbor 10.0.3.115 remote-as 115
+ neighbor 10.0.3.115 timers 3 10
neighbor 10.0.4.116 remote-as 116
+ neighbor 10.0.4.116 timers 3 10
neighbor 10.0.4.117 remote-as 117
+ neighbor 10.0.4.117 timers 3 10
neighbor 10.0.4.118 remote-as 118
+ neighbor 10.0.4.118 timers 3 10
neighbor 10.0.4.119 remote-as 119
+ neighbor 10.0.4.119 timers 3 10
neighbor 10.0.4.120 remote-as 120
+ neighbor 10.0.4.120 timers 3 10
!
!
diff --git a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
index 948f641afb..6068f5f831 100755
--- a/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
+++ b/tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
@@ -61,6 +61,7 @@ from lib.common_config import (
check_address_types,
interface_status,
reset_config_on_routers,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
@@ -108,6 +109,11 @@ def setup_module(mod):
global NEXT_HOPS, INTF_LIST_R3, INTF_LIST_R2, TEST_STATIC
global ADDR_TYPES
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
index 5b997fdd16..ae54019a0f 100755
--- a/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
+++ b/tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
@@ -61,6 +61,7 @@ from lib.common_config import (
check_address_types,
interface_status,
reset_config_on_routers,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
@@ -108,6 +109,11 @@ def setup_module(mod):
global NEXT_HOPS, INTF_LIST_R3, INTF_LIST_R2, TEST_STATIC
global ADDR_TYPES
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/P1/ospfd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/P1/ospfd.conf
index 772675ddff..2db7edb806 100644
--- a/tests/topotests/bgp-evpn-vxlan_topo1/P1/ospfd.conf
+++ b/tests/topotests/bgp-evpn-vxlan_topo1/P1/ospfd.conf
@@ -2,3 +2,12 @@
router ospf
network 10.20.0.0/16 area 0
network 10.20.20.20/32 area 0
+!
+int P1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int P1-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf
index d337201f71..c7a76a98ed 100644
--- a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf
+++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf
@@ -4,6 +4,7 @@ router bgp 65000
no bgp default ipv4-unicast
neighbor 10.30.30.30 remote-as 65000
neighbor 10.30.30.30 update-source lo
+ neighbor 10.30.30.30 timers 3 10
address-family l2vpn evpn
neighbor 10.30.30.30 activate
advertise-all-vni
diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/ospfd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/ospfd.conf
index 31c7fc4188..f1c2b42dc1 100644
--- a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/ospfd.conf
+++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/ospfd.conf
@@ -2,3 +2,8 @@
router ospf
network 10.20.0.0/16 area 0
network 10.10.10.10/32 area 0
+!
+int PE1-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf
index d99e33fc06..0a24158bb8 100644
--- a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf
+++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf
@@ -4,6 +4,7 @@ router bgp 65000
no bgp default ipv4-unicast
neighbor 10.10.10.10 remote-as 65000
neighbor 10.10.10.10 update-source lo
+ neighbor 10.10.10.10 timers 3 10
!
address-family l2vpn evpn
neighbor 10.10.10.10 activate
diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/ospfd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/ospfd.conf
index c1a8308db5..065c993303 100644
--- a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/ospfd.conf
+++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/ospfd.conf
@@ -2,3 +2,8 @@
router ospf
network 10.20.0.0/16 area 0
network 10.30.30.30/32 area 0
+!
+int PE2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf b/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf
index 9d519fae88..3486c64c55 100644
--- a/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf
+++ b/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
redistribute connected
aggregate-address 172.16.255.0/24 origin igp
diff --git a/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf b/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf
index 38cf5aaca7..b2d945583c 100644
--- a/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf
+++ b/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
exit-address-family
!
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf
index 292f0e967f..7fb55cf001 100644
--- a/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf
+++ b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
redistribute connected
aggregate-address 172.16.255.0/24 route-map aggr-rmap
diff --git a/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf
index 38cf5aaca7..b2d945583c 100644
--- a/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf
+++ b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
exit-address-family
!
diff --git a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
index 89b15c46d3..f9d22a3a36 100755
--- a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
+++ b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
@@ -65,6 +65,7 @@ from lib.common_config import (
create_route_maps,
check_address_types,
step,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import (
@@ -112,6 +113,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf
index 75741a3c3e..cb04749b92 100644
--- a/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf
+++ b/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf
@@ -3,4 +3,5 @@ router bgp 65001
bgp router-id 10.10.10.10
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers 3 10
!
diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf
index 18a6c66f69..bed68858fd 100644
--- a/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf
+++ b/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf
@@ -3,5 +3,7 @@ router bgp 65002
bgp router-id 10.10.10.10
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.3 remote-as 65002
+ neighbor 192.168.255.3 timers 3 10
!
diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf
index 27bf126000..384e617d02 100644
--- a/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf
+++ b/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf
@@ -3,4 +3,5 @@ router bgp 65002
bgp router-id 10.10.10.10
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers 3 10
!
diff --git a/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf
index 9518894351..12161d2fa2 100644
--- a/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf
+++ b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
redistribute connected route-map r2-out
exit-address-family
diff --git a/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf
index e4c1167745..33231b5274 100644
--- a/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf
+++ b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4
neighbor 192.168.255.1 route-map r1-in in
exit-address-family
diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
index 7d960d6916..57e8e0d34a 100644
--- a/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
+++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities.py
@@ -54,6 +54,7 @@ from lib.common_config import (
create_route_maps,
create_prefix_lists,
create_route_maps,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import (
@@ -102,6 +103,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf
index 12e56e27c4..cb07ea9fdf 100644
--- a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf
+++ b/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
neighbor 192.168.255.2 default-originate route-map default
exit-address-family
diff --git a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf
index b6b560aa4d..00c96cc58b 100644
--- a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf
+++ b/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
diff --git a/tests/topotests/bgp_distance_change/r1/bgpd.conf b/tests/topotests/bgp_distance_change/r1/bgpd.conf
index cd2ef675fc..07cfe2e2f1 100644
--- a/tests/topotests/bgp_distance_change/r1/bgpd.conf
+++ b/tests/topotests/bgp_distance_change/r1/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
exit-address-family
!
diff --git a/tests/topotests/bgp_distance_change/r2/bgpd.conf b/tests/topotests/bgp_distance_change/r2/bgpd.conf
index 0faec85032..9cd86dc284 100644
--- a/tests/topotests/bgp_distance_change/r2/bgpd.conf
+++ b/tests/topotests/bgp_distance_change/r2/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4
redistribute connected
exit-address-family
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf
index aaa01ebcf9..add37ee58d 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65000
neighbor 192.168.255.2 remote-as 1000
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.2 local-as 500
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf
index 27427a9aaa..802c32714b 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf
@@ -1,3 +1,5 @@
router bgp 1000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 500
+ neighbor 192.168.255.1 timers 3 10
+!
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf
index 2deb4b663d..1280b427ad 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65000
neighbor 192.168.255.2 remote-as 1000
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.2 local-as 500
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf
index 27427a9aaa..802c32714b 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf
@@ -1,3 +1,5 @@
router bgp 1000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 500
+ neighbor 192.168.255.1 timers 3 10
+!
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf
index 92a2797921..60b29f6f1b 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65000
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
redistribute connected
!
diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf
index 342f53d4c7..7ad5d927a7 100644
--- a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf
+++ b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf
@@ -1,2 +1,4 @@
router bgp 65000
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
+!
diff --git a/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json
new file mode 100644
index 0000000000..70b70de1d1
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/bgp_shutdown_summary.json
@@ -0,0 +1,20 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.0.1",
+ "as":65000,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":2,
+ "peers":{
+ "192.168.0.2":{
+ "remoteAs":65000,
+ "state":"Idle (Admin)"
+ },
+ "192.168.101.2":{
+ "remoteAs":65100,
+ "state":"Idle (Admin)"
+ }
+ },
+ "totalPeers":2
+}
+}
diff --git a/tests/topotests/bgp_features/r1/bgp_summary.json b/tests/topotests/bgp_features/r1/bgp_summary.json
new file mode 100644
index 0000000000..57aa992fab
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/bgp_summary.json
@@ -0,0 +1,28 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.0.1",
+ "as":65000,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":2,
+ "peers":{
+ "192.168.0.2":{
+ "hostname":"r2",
+ "remoteAs":65000,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":7,
+ "state":"Established"
+ },
+ "192.168.101.2":{
+ "hostname":"r4",
+ "remoteAs":65100,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":3,
+ "state":"Established"
+ }
+ },
+ "totalPeers":2
+}
+}
diff --git a/tests/topotests/bgp_features/r1/bgpd.conf b/tests/topotests/bgp_features/r1/bgpd.conf
new file mode 100644
index 0000000000..74d1993af0
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/bgpd.conf
@@ -0,0 +1,41 @@
+!
+hostname r1
+log file bgpd.log
+!
+router bgp 65000
+ timers bgp 3 10
+ coalesce-time 0
+ bgp router-id 192.168.0.1
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 192.168.0.2 remote-as 65000
+ neighbor 192.168.0.2 timers 3 10
+ neighbor 192.168.0.2 description Router R2 (iBGP)
+ neighbor 192.168.0.2 update-source lo
+ neighbor 192.168.0.2 timers connect 5
+ neighbor 192.168.101.2 remote-as 65100
+ neighbor 192.168.101.2 timers 3 10
+ neighbor 192.168.101.2 description Router R4 (eBGP AS 65100)
+ neighbor 192.168.101.2 timers connect 5
+ !
+ address-family ipv4 unicast
+ network 192.168.0.0/24
+ network 192.168.1.0/24
+ network 192.168.2.0/24
+ network 192.168.3.0/24
+ network 192.168.6.0/24
+ network 192.168.8.0/24
+ neighbor 192.168.101.2 route-map testmap-in in
+ neighbor 192.168.101.2 route-map testmap-out out
+ exit-address-family
+!
+!
+!
+route-map testmap-in permit 999
+!
+route-map testmap-out permit 999
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/bgp_features/r1/ospf6d.conf b/tests/topotests/bgp_features/r1/ospf6d.conf
new file mode 100644
index 0000000000..532da39fb7
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/ospf6d.conf
@@ -0,0 +1,22 @@
+log file ospf6d.log
+!
+debug ospf6 neighbor
+!
+interface r1-lo
+!
+interface r1-eth0
+!
+interface r1-eth1
+!
+interface r1-eth2
+!
+router ospf6
+ ospf6 router-id 192.168.0.1
+ log-adjacency-changes
+ interface r1-lo area 0.0.0.0
+ interface r1-eth0 area 0.0.0.0
+ interface r1-eth1 area 0.0.0.0
+ interface r1-eth2 area 0.0.0.0
+!
+line vty
+!
diff --git a/tests/topotests/bgp_features/r1/ospf_neighbor.json b/tests/topotests/bgp_features/r1/ospf_neighbor.json
new file mode 100644
index 0000000000..ecb97d8d74
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/ospf_neighbor.json
@@ -0,0 +1,16 @@
+{
+ "neighbors":{
+ "192.168.0.2":[
+ {
+ "priority":1,
+ "state":"Full\/DR"
+ }
+ ],
+ "192.168.0.3":[
+ {
+ "priority":1,
+ "state":"Full\/DR"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_features/r1/ospfd.conf b/tests/topotests/bgp_features/r1/ospfd.conf
new file mode 100644
index 0000000000..8f1711db7b
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/ospfd.conf
@@ -0,0 +1,23 @@
+log file ospfd.log
+!
+debug ospf event
+debug ospf zebra
+!
+router ospf
+ ospf router-id 192.168.0.1
+ log-adjacency-changes
+ network 192.168.0.0/20 area 0.0.0.0
+ timers throttle spf 0 0 0
+ timers lsa min-arrival 10
+ timers throttle lsa all 0
+ refresh timer 10
+!
+line vty
+interface r1-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+interface r1-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_features/r1/zebra.conf b/tests/topotests/bgp_features/r1/zebra.conf
new file mode 100644
index 0000000000..61564f1a1a
--- /dev/null
+++ b/tests/topotests/bgp_features/r1/zebra.conf
@@ -0,0 +1,28 @@
+!
+hostname r1
+log file zebra.log
+!
+interface lo
+ ip address 192.168.0.1/32
+ ipv6 address fc00::1/128
+!
+interface r1-eth0
+ description SW6 Stub Network
+ ip address 192.168.6.1/24
+ ipv6 address fc00:0:0:6::1/64
+!
+interface r1-eth1
+ description SW0 R1-R2 OSPF & BGP Network
+ ip address 192.168.1.1/24
+ ipv6 address fc00:0:0:1::1/64
+!
+interface r1-eth2
+ description SW2 R1-R3 OSPF Network
+ ip address 192.168.3.1/24
+ ipv6 address fc00:0:0:3::1/64
+!
+interface r1-eth3
+ description SW4 R1-R4 eBGP Network
+ ip address 192.168.101.1/24
+ ipv6 address fc00:100:0:1::1/64
+!
diff --git a/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json
new file mode 100644
index 0000000000..95de3e3096
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/bgp_shutdown_summary.json
@@ -0,0 +1,20 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.0.2",
+ "as":65000,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":2,
+ "peers":{
+ "192.168.0.1":{
+ "remoteAs":65000,
+ "state":"Active"
+ },
+ "192.168.201.2":{
+ "remoteAs":65200,
+ "state":"Established"
+ }
+ },
+ "totalPeers":2
+}
+}
diff --git a/tests/topotests/bgp_features/r2/bgp_summary.json b/tests/topotests/bgp_features/r2/bgp_summary.json
new file mode 100644
index 0000000000..f29204116c
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/bgp_summary.json
@@ -0,0 +1,28 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.0.2",
+ "as":65000,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":2,
+ "peers":{
+ "192.168.0.1":{
+ "hostname":"r1",
+ "remoteAs":65000,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":8,
+ "state":"Established"
+ },
+ "192.168.201.2":{
+ "hostname":"r5",
+ "remoteAs":65200,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":2,
+ "state":"Established"
+ }
+ },
+ "totalPeers":2
+}
+}
diff --git a/tests/topotests/bgp_features/r2/bgpd.conf b/tests/topotests/bgp_features/r2/bgpd.conf
new file mode 100644
index 0000000000..99cec98811
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/bgpd.conf
@@ -0,0 +1,41 @@
+!
+hostname r2
+log file bgpd.log
+!
+router bgp 65000
+ bgp router-id 192.168.0.2
+ timers bgp 3 10
+ coalesce-time 0
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 192.168.0.1 remote-as 65000
+ neighbor 192.168.0.1 timers 3 10
+ neighbor 192.168.0.1 description Router R1 (iBGP)
+ neighbor 192.168.0.1 update-source lo
+ neighbor 192.168.0.1 timers connect 5
+ neighbor 192.168.201.2 remote-as 65200
+ neighbor 192.168.201.2 timers 3 10
+ neighbor 192.168.201.2 description Router R5 (eBGP AS 65200)
+ neighbor 192.168.201.2 timers connect 5
+ !
+ address-family ipv4 unicast
+ network 192.168.0.0/24
+ network 192.168.1.0/24
+ network 192.168.2.0/24
+ network 192.168.3.0/24
+ network 192.168.7.0/24
+ network 192.168.8.0/24
+ neighbor 192.168.201.2 route-map testmap-in in
+ neighbor 192.168.201.2 route-map testmap-out out
+ exit-address-family
+!
+!
+!
+route-map testmap-in permit 999
+!
+route-map testmap-out permit 999
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/bgp_features/r2/ospf6d.conf b/tests/topotests/bgp_features/r2/ospf6d.conf
new file mode 100644
index 0000000000..283d205489
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/ospf6d.conf
@@ -0,0 +1,22 @@
+log file ospf6d.log
+!
+debug ospf6 neighbor
+!
+interface r2-lo
+!
+interface r2-eth0
+!
+interface r2-eth1
+!
+interface r2-eth2
+!
+router ospf6
+ ospf6 router-id 192.168.0.2
+ log-adjacency-changes
+ interface r2-lo area 0.0.0.0
+ interface r2-eth0 area 0.0.0.0
+ interface r2-eth1 area 0.0.0.0
+ interface r2-eth2 area 0.0.0.0
+!
+line vty
+!
diff --git a/tests/topotests/bgp_features/r2/ospf_neighbor.json b/tests/topotests/bgp_features/r2/ospf_neighbor.json
new file mode 100644
index 0000000000..5fcbd82ee1
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/ospf_neighbor.json
@@ -0,0 +1,16 @@
+{
+ "neighbors":{
+ "192.168.0.1":[
+ {
+ "priority":1,
+ "state":"Full\/Backup"
+ }
+ ],
+ "192.168.0.3":[
+ {
+ "priority":1,
+ "state":"Full\/DR"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_features/r2/ospfd.conf b/tests/topotests/bgp_features/r2/ospfd.conf
new file mode 100644
index 0000000000..2174fddb11
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/ospfd.conf
@@ -0,0 +1,23 @@
+log file ospfd.log
+!
+debug ospf event
+debug ospf zebra
+!
+router ospf
+ ospf router-id 192.168.0.2
+ log-adjacency-changes
+ network 192.168.0.0/20 area 0.0.0.0
+ timers throttle spf 0 0 0
+ timers lsa min-arrival 10
+ timers throttle lsa all 0
+ refresh timer 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+line vty
+!
diff --git a/tests/topotests/bgp_features/r2/zebra.conf b/tests/topotests/bgp_features/r2/zebra.conf
new file mode 100644
index 0000000000..1d427da6f5
--- /dev/null
+++ b/tests/topotests/bgp_features/r2/zebra.conf
@@ -0,0 +1,28 @@
+!
+hostname r2
+log file zebra.log
+!
+interface lo
+ ip address 192.168.0.2/32
+ ipv6 address fc00::2/128
+!
+interface r2-eth0
+ description SW7 Stub Network
+ ip address 192.168.7.1/24
+ ipv6 address fc00:0:0:7::1/64
+!
+interface r2-eth1
+ description SW0 R1-R2 OSPF & BGP Network
+ ip address 192.168.1.2/24
+ ipv6 address fc00:0:0:1::2/64
+!
+interface r2-eth2
+ description SW1 R2-R3 OSPF Network
+ ip address 192.168.2.1/24
+ ipv6 address fc00:0:0:2::1/64
+!
+interface r2-eth3
+ description SW5 R2-R5 eBGP Network
+ ip address 192.168.201.1/24
+ ipv6 address fc00:200:0:1::1/64
+!
diff --git a/tests/topotests/bgp_features/r3/bgp_summary.json b/tests/topotests/bgp_features/r3/bgp_summary.json
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_features/r3/bgp_summary.json
diff --git a/tests/topotests/bgp_features/r3/ospf6d.conf b/tests/topotests/bgp_features/r3/ospf6d.conf
new file mode 100644
index 0000000000..7a6623f979
--- /dev/null
+++ b/tests/topotests/bgp_features/r3/ospf6d.conf
@@ -0,0 +1,22 @@
+log file ospf6d.log
+!
+debug ospf6 neighbor
+!
+interface r3-lo
+!
+interface r3-eth0
+!
+interface r3-eth1
+!
+interface r3-eth2
+!
+router ospf6
+ ospf6 router-id 192.168.0.3
+ log-adjacency-changes
+ interface r3-lo area 0.0.0.0
+ interface r3-eth0 area 0.0.0.0
+ interface r3-eth1 area 0.0.0.0
+ interface r3-eth2 area 0.0.0.0
+!
+line vty
+!
diff --git a/tests/topotests/bgp_features/r3/ospf_neighbor.json b/tests/topotests/bgp_features/r3/ospf_neighbor.json
new file mode 100644
index 0000000000..e90a70a8f6
--- /dev/null
+++ b/tests/topotests/bgp_features/r3/ospf_neighbor.json
@@ -0,0 +1,16 @@
+{
+ "neighbors":{
+ "192.168.0.1":[
+ {
+ "priority":1,
+ "state":"Full\/Backup"
+ }
+ ],
+ "192.168.0.2":[
+ {
+ "priority":1,
+ "state":"Full\/Backup"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/bgp_features/r3/ospfd.conf b/tests/topotests/bgp_features/r3/ospfd.conf
new file mode 100644
index 0000000000..795344fbe6
--- /dev/null
+++ b/tests/topotests/bgp_features/r3/ospfd.conf
@@ -0,0 +1,23 @@
+log file ospfd.log
+!
+debug ospf event
+debug ospf zebra
+!
+router ospf
+ ospf router-id 192.168.0.3
+ log-adjacency-changes
+ network 192.168.0.0/20 area 0.0.0.0
+ timers throttle spf 0 0 0
+ timers lsa min-arrival 10
+ timers throttle lsa all 0
+ refresh timer 10
+!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+int r3-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+line vty
+!
diff --git a/tests/topotests/bgp_features/r3/zebra.conf b/tests/topotests/bgp_features/r3/zebra.conf
new file mode 100644
index 0000000000..62ba04d81b
--- /dev/null
+++ b/tests/topotests/bgp_features/r3/zebra.conf
@@ -0,0 +1,23 @@
+!
+hostname r3
+log file zebra.log
+!
+interface lo
+ ip address 192.168.0.3/32
+ ipv6 address fc00::3/128
+!
+interface r3-eth0
+ description SW8 Stub Network
+ ip address 192.168.8.1/24
+ ipv6 address fc00:0:0:8::1/64
+!
+interface r3-eth1
+ description SW1 R2-R3 OSPF Network
+ ip address 192.168.2.2/24
+ ipv6 address fc00:0:0:2::2/64
+!
+interface r3-eth2
+ description SW2 R1-R3 OSPF Network
+ ip address 192.168.3.2/24
+ ipv6 address fc00:0:0:3::2/64
+!
diff --git a/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json b/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json
new file mode 100644
index 0000000000..c22cbdadcd
--- /dev/null
+++ b/tests/topotests/bgp_features/r4/bgp_shutdown_summary.json
@@ -0,0 +1,15 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.100.1",
+ "as":65100,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "192.168.101.1":{
+ "remoteAs":65000,
+ "state":"Active" }
+ },
+ "totalPeers":1
+}
+}
diff --git a/tests/topotests/bgp_features/r4/bgp_summary.json b/tests/topotests/bgp_features/r4/bgp_summary.json
new file mode 100644
index 0000000000..d147602c74
--- /dev/null
+++ b/tests/topotests/bgp_features/r4/bgp_summary.json
@@ -0,0 +1,19 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.100.1",
+ "as":65100,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "192.168.101.1":{
+ "hostname":"r1",
+ "remoteAs":65000,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":6,
+ "state":"Established" }
+ },
+ "totalPeers":1
+}
+}
diff --git a/tests/topotests/bgp_features/r4/bgpd.conf b/tests/topotests/bgp_features/r4/bgpd.conf
new file mode 100644
index 0000000000..cdf8f4e8f6
--- /dev/null
+++ b/tests/topotests/bgp_features/r4/bgpd.conf
@@ -0,0 +1,34 @@
+!
+hostname r4
+log file bgpd.log
+!
+router bgp 65100
+ bgp router-id 192.168.100.1
+ timers bgp 3 10
+ coalesce-time 0
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 192.168.101.1 remote-as 65000
+ neighbor 192.168.101.1 timers 3 10
+ neighbor 192.168.101.1 description Router R1 (eBGP AS 65000)
+ neighbor 192.168.101.1 timers connect 5
+ !
+ address-family ipv4 unicast
+ network 192.168.100.0/24
+ network 192.168.101.0/24
+ network 192.168.102.0/24
+ neighbor 192.168.101.1 default-originate
+ neighbor 192.168.101.1 route-map testmap-in in
+ neighbor 192.168.101.1 route-map testmap-out out
+ exit-address-family
+!
+!
+!
+route-map testmap-in permit 999
+!
+route-map testmap-out permit 999
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/bgp_features/r4/zebra.conf b/tests/topotests/bgp_features/r4/zebra.conf
new file mode 100644
index 0000000000..08e3e1aec9
--- /dev/null
+++ b/tests/topotests/bgp_features/r4/zebra.conf
@@ -0,0 +1,18 @@
+!
+hostname r4
+log file zebra.log
+!
+interface lo
+ ip address 192.168.100.1/32
+ ipv6 address fc00:100::1/128
+!
+interface r4-eth0
+ description SW5 Stub Network
+ ip address 192.168.102.1/24
+ ipv6 address fc00:100:0:2::1/64
+!
+interface r4-eth1
+ description SW0 R1-R2 OSPF & BGP Network
+ ip address 192.168.101.2/24
+ ipv6 address fc00:100:0:1::2/64
+!
diff --git a/tests/topotests/bgp_features/r5/bgp_summary.json b/tests/topotests/bgp_features/r5/bgp_summary.json
new file mode 100644
index 0000000000..f303aa6c72
--- /dev/null
+++ b/tests/topotests/bgp_features/r5/bgp_summary.json
@@ -0,0 +1,20 @@
+{
+"ipv4Unicast":{
+ "routerId":"192.168.200.1",
+ "as":65200,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "192.168.201.1":{
+ "hostname":"r2",
+ "remoteAs":65000,
+ "outq":0,
+ "inq":0,
+ "pfxRcd":6,
+ "state":"Established"
+ }
+ },
+ "totalPeers":1
+}
+}
diff --git a/tests/topotests/bgp_features/r5/bgpd.conf b/tests/topotests/bgp_features/r5/bgpd.conf
new file mode 100644
index 0000000000..6368fedd39
--- /dev/null
+++ b/tests/topotests/bgp_features/r5/bgpd.conf
@@ -0,0 +1,34 @@
+!
+hostname r5
+log file bgpd.log
+!
+router bgp 65200
+ bgp router-id 192.168.200.1
+ timers bgp 3 10
+ coalesce-time 0
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 192.168.201.1 remote-as 65000
+ neighbor 192.168.201.1 timers 3 10
+ neighbor 192.168.201.1 description Router R2 (eBGP AS 65000)
+ neighbor 192.168.201.1 timers connect 5
+ !
+ address-family ipv4 unicast
+ network 192.168.200.0/24
+ network 192.168.201.0/24
+ network 192.168.202.0/24
+ neighbor 192.168.101.1 default-originate
+ neighbor 192.168.201.1 route-map testmap-in in
+ neighbor 192.168.201.1 route-map testmap-out out
+ exit-address-family
+!
+!
+!
+route-map testmap-in permit 999
+!
+route-map testmap-out permit 999
+!
+!
+line vty
+!
+
diff --git a/tests/topotests/bgp_features/r5/zebra.conf b/tests/topotests/bgp_features/r5/zebra.conf
new file mode 100644
index 0000000000..4d9064a593
--- /dev/null
+++ b/tests/topotests/bgp_features/r5/zebra.conf
@@ -0,0 +1,18 @@
+!
+hostname r5
+log file zebra.log
+!
+interface lo
+ ip address 192.168.200.1/32
+ ipv6 address fc00:200::1/128
+!
+interface r5-eth0
+ description SW6 Stub Network
+ ip address 192.168.202.1/24
+ ipv6 address fc00:200:0:2::1/64
+!
+interface r5-eth1
+ description SW0 R1-R2 OSPF & BGP Network
+ ip address 192.168.201.2/24
+ ipv6 address fc00:200:0:1::2/64
+!
diff --git a/tests/topotests/bgp_features/test_bgp_features.dot b/tests/topotests/bgp_features/test_bgp_features.dot
new file mode 100644
index 0000000000..70b126ce8b
--- /dev/null
+++ b/tests/topotests/bgp_features/test_bgp_features.dot
@@ -0,0 +1,83 @@
+## GraphViz file for test_all_protocol_startup
+##
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## No protocol: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #33ff99 light green
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+## LDP IPv4 #fedbe2 light pink
+##### Colors (see http://www.color-hex.com/)
+
+graph test_all_protocol_startup {
+ overlap=false;
+ constraint=false;
+
+ // title
+ labelloc="t";
+ label="Test Topologoy BGP Features";
+ rankdir = TB;
+
+ ######################
+ # Routers
+ ######################
+
+ # Main FRR Router with all protocols
+ R4 [shape=doubleoctagon, label="R4 FRR\nAS 65100\nlo: 192.168.100.1/32\nfc00:100::1/128", fillcolor="#f08080", style=filled];
+ R5 [shape=doubleoctagon, label="R5 FRR\nAS 65200\nlo: 192.168.200.1/32\nfc00:200::1/128", fillcolor="#f08080", style=filled];
+ #{ rank = same {R4, R5}}
+
+ R1 [shape=doubleoctagon, label="R1 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled];
+ R2 [shape=doubleoctagon, label="R2 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled];
+ #{ rank = same { R1, R2}}
+
+ R3 [shape=doubleoctagon, label="R3 FRR\nAS 65000\nlo: 192.168.0.1/32\nfc00::1/128", fillcolor="#f08080", style=filled];
+
+ ######################
+ # Network Lists
+ ######################
+
+ SW1_R1_R2 [label="SW1 OSPF & iBGP\n192.168.1.0/24\nfc00:0:0:1::/64", fillcolor="#32b835", style=filled];
+ SW2_R2_R3 [label="SW2 OSPF\n192.168.2.0/24\nfc00:0:0:2::/64", fillcolor="#19e3d9", style=filled];
+ SW3_R3_R1 [label="SW3 OSPF\n192.168.3.0/24\nfc00:0:0:3::/64", fillcolor="#19e3d9", style=filled];
+
+ SW4_R4_R1 [label="SW4 eBGP\n192.168.101.0/24\nfc00:100:0:1::/64", fillcolor="#fedbe2", style=filled];
+ SW5_R5_R2 [label="SW5 eBGP\n192.168.201.0/24\nfc00:200:0:1::/64", fillcolor="#fedbe2", style=filled];
+ #{ rank = same {SW4_R4_R1, SW5_R5_R2}}
+
+ SW6_STUB_R1 [label="SW6\n192.168.6.0/24\nfc00:0:0:6::/64", fillcolor="#d0e0d0", style=filled];
+ SW7_STUB_R2 [label="SW7\n192.168.7.0/24\nfc00:0:0:7::/64", fillcolor="#d0e0d0", style=filled];
+ SW8_STUB_R3 [label="SW8\n192.168.8.0/24\nfc00:0:0:8::/64", fillcolor="#d0e0d0", style=filled];
+ SW9_STUB_R4 [label="SW9\n192.168.102.0/24\nfc00:100:0:2::/64", fillcolor="#d0e0d0", style=filled];
+ SW10_STUB_R5 [label="SW10\n192.168.202.0/24\nfc00:200:0:2::/64", fillcolor="#d0e0d0", style=filled];
+
+
+ ######################
+ # Network Connections
+ ######################
+
+ R1 -- SW6_STUB_R1 [label = "eth0\n.1\n::1"];
+ R2 -- SW7_STUB_R2 [label = "eth0\n.1\n::1"];
+ R3 -- SW8_STUB_R3 [label = "eth0\n.1\n::1"];
+ R4 -- SW9_STUB_R4 [label = "eth0\n.1\n::1"];
+ R5 -- SW10_STUB_R5 [label = "eth0\n.1\n::1"];
+
+ R1 -- SW1_R1_R2 [label = "eth1\n.1\n::1"];
+ R1 -- SW3_R3_R1 [label = "eth2\n.1\n::1"];
+ R2 -- SW1_R1_R2 [label = "eth1\n.2\n::2"];
+ R2 -- SW2_R2_R3 [label = "eth2\n.1\n::1"];
+ R3 -- SW2_R2_R3 [label = "eth1\n.2\n::2"];
+ R3 -- SW3_R3_R1 [label = "eth2\n.2\n::2"];
+
+ R1 -- SW4_R4_R1 [label = "eth3\n.1\n::1"];
+ R2 -- SW5_R5_R2 [label = "eth3\n.1\n::1"];
+ R4 -- SW4_R4_R1 [label = "eth1\n.2\n::2"];
+ R5 -- SW5_R5_R2 [label = "eth1\n.2\n::2"];
+
+}
diff --git a/tests/topotests/bgp_features/test_bgp_features.pdf b/tests/topotests/bgp_features/test_bgp_features.pdf
new file mode 100644
index 0000000000..cb52a54762
--- /dev/null
+++ b/tests/topotests/bgp_features/test_bgp_features.pdf
Binary files differ
diff --git a/tests/topotests/bgp_features/test_bgp_features.py b/tests/topotests/bgp_features/test_bgp_features.py
new file mode 100755
index 0000000000..a27aaf9ec7
--- /dev/null
+++ b/tests/topotests/bgp_features/test_bgp_features.py
@@ -0,0 +1,267 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_features.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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.
+#
+
+"""
+test_bgp_features.py: Test various BGP features.
+"""
+
+import json
+import functools
+import os
+import sys
+import pytest
+import re
+
+# Save the Current Working Directory to find configuration files.
+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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+#####################################################
+#
+# Network Topology Definition
+#
+#####################################################
+
+
+class BGPFeaturesTopo1(Topo):
+ "BGP Features Topology 1"
+
+ def build(self, **_opts):
+ tgen = get_topogen(self)
+
+ # Create the routers
+ for rtrNum in range(1, 6):
+ tgen.add_router("r{}".format(rtrNum))
+
+ # Setup Switches and connections
+ for swNum in range(1, 11):
+ tgen.add_switch("sw{}".format(swNum))
+
+ # Add connections to stub switches
+ tgen.gears["r1"].add_link(tgen.gears["sw6"])
+ tgen.gears["r2"].add_link(tgen.gears["sw7"])
+ tgen.gears["r3"].add_link(tgen.gears["sw8"])
+ tgen.gears["r4"].add_link(tgen.gears["sw9"])
+ tgen.gears["r5"].add_link(tgen.gears["sw10"])
+
+ # Add connections to R1-R2-R3 core
+ tgen.gears["r1"].add_link(tgen.gears["sw1"])
+ tgen.gears["r1"].add_link(tgen.gears["sw3"])
+ tgen.gears["r2"].add_link(tgen.gears["sw1"])
+ tgen.gears["r2"].add_link(tgen.gears["sw2"])
+ tgen.gears["r3"].add_link(tgen.gears["sw2"])
+ tgen.gears["r3"].add_link(tgen.gears["sw3"])
+
+ # Add connections to external R4/R5 Routers
+ tgen.gears["r1"].add_link(tgen.gears["sw4"])
+ tgen.gears["r4"].add_link(tgen.gears["sw4"])
+ tgen.gears["r2"].add_link(tgen.gears["sw5"])
+ tgen.gears["r5"].add_link(tgen.gears["sw5"])
+
+
+#####################################################
+#
+# Tests starting
+#
+#####################################################
+
+
+def setup_module(module):
+ tgen = Topogen(BGPFeaturesTopo1, module.__name__)
+ tgen.start_topology()
+
+ # Starting Routers
+ router_list = tgen.routers()
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ if os.path.exists(os.path.join(CWD, "{}/bgpd.conf".format(rname))):
+ logger.info("{} uses BGPd".format(rname))
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+ if os.path.exists(os.path.join(CWD, "{}/ospfd.conf".format(rname))):
+ logger.info("{} uses OSPFd".format(rname))
+ router.load_config(
+ TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
+ )
+ if os.path.exists(os.path.join(CWD, "{}/ospf6d.conf".format(rname))):
+ logger.info("{} uses OSPF6d".format(rname))
+ router.load_config(
+ TopoRouter.RD_OSPF6, os.path.join(CWD, "{}/ospf6d.conf".format(rname))
+ )
+ router.start()
+
+
+def teardown_module(module):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_ospf_convergence():
+ "Test for OSPFv2 topology convergence"
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Check Router r1, r2 & r3 OSPF
+ for rtrNum in range(1, 4):
+ logger.info("Checking OSPFv2 convergence on router r{}".format(rtrNum))
+
+ router = tgen.gears["r{}".format(rtrNum)]
+ reffile = os.path.join(CWD, "r{}/ospf_neighbor.json".format(rtrNum))
+ expected = json.loads(open(reffile).read())
+
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip ospf neighbor json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "OSPF router R{} did not converge".format(rtrNum)
+ assert res is None, assertmsg
+
+
+def test_bgp_convergence():
+ "Test for BGP topology convergence"
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Check Router r1 & r2 BGP
+ for rtrNum in [1, 2, 4, 5]:
+ logger.info("Checking BGP IPv4 convergence on router r{}".format(rtrNum))
+
+ router = tgen.gears["r{}".format(rtrNum)]
+ reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum))
+ expected = json.loads(open(reffile).read())
+
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp summary json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "BGP router R{} did not converge".format(rtrNum)
+ assert res is None, assertmsg
+
+ # tgen.mininet_cli()
+
+
+def test_bgp_shutdown():
+ "Test BGP instance shutdown"
+
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"bgp shutdown message ABCDabcd\"')
+
+ # Check BGP Summary on local and remote routers
+ for rtrNum in [1, 2, 4]:
+ logger.info("Checking BGP Summary after shutdown of R1 BGP on router r{}".format(rtrNum))
+
+ router = tgen.gears["r{}".format(rtrNum)]
+ reffile = os.path.join(CWD, "r{}/bgp_shutdown_summary.json".format(rtrNum))
+ expected = json.loads(open(reffile).read())
+
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp summary json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum)
+ assert res is None, assertmsg
+
+
+def test_bgp_shutdown_message():
+ "Test BGP Peer Shutdown Message"
+
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rtrNum in [2, 4]:
+ logger.info("Checking BGP shutdown received on router r{}".format(rtrNum))
+
+ shut_message = tgen.net['r{}'.format(rtrNum)].cmd(
+ 'tail bgpd.log | grep "NOTIFICATION.*Cease/Administratively Shutdown"')
+ assertmsg = "BGP shutdown message not received on router R{}".format(rtrNum)
+ assert shut_message != '', assertmsg
+
+ m = re.search('.*([0-9]+ bytes[ 0-9a-fA-F]+)', shut_message)
+ if m:
+ found = m.group(1)
+ else:
+ found = ''
+ assertmsg = "Incorrect BGP shutdown message received on router R{}".format(rtrNum)
+ assert found == '8 bytes 41 42 43 44 61 62 63 64', assertmsg
+
+ # tgen.mininet_cli()
+
+
+def test_bgp_no_shutdown():
+ "Test BGP instance no shutdown"
+
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"no bgp shutdown\"')
+
+ # Check BGP Summary on local and remote routers
+ for rtrNum in [1, 2, 4]:
+ logger.info("Checking BGP Summary after removing bgp shutdown on router r1 on router r{}".format(rtrNum))
+
+ router = tgen.gears["r{}".format(rtrNum)]
+ reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum))
+ expected = json.loads(open(reffile).read())
+
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show ip bgp summary json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
+ assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum)
+ assert res is None, assertmsg
+
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_flowspec/__init__.py b/tests/topotests/bgp_flowspec/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/__init__.py
diff --git a/tests/topotests/bgp_flowspec/exabgp.env b/tests/topotests/bgp_flowspec/exabgp.env
new file mode 100644
index 0000000000..a328e04962
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/exabgp.env
@@ -0,0 +1,54 @@
+
+[exabgp.api]
+encoder = text
+highres = false
+respawn = false
+socket = ''
+
+[exabgp.bgp]
+openwait = 60
+
+[exabgp.cache]
+attributes = true
+nexthops = true
+
+[exabgp.daemon]
+daemonize = true
+pid = '/var/run/exabgp/exabgp.pid'
+user = 'exabgp'
+##daemonize = false
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
diff --git a/tests/topotests/bgp_flowspec/peer1/exabgp.cfg b/tests/topotests/bgp_flowspec/peer1/exabgp.cfg
new file mode 100644
index 0000000000..cd1fae5aba
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/peer1/exabgp.cfg
@@ -0,0 +1,32 @@
+neighbor 10.0.1.1 {
+router-id 10.0.1.101;
+local-address 10.0.1.101;
+local-as 100;
+peer-as 100;
+flow {
+route {
+match {
+source 1.1.1.2/32;
+destination 3.3.3.3/32;
+packet-length <200;
+}
+then {
+redirect 50.0.0.2;
+rate-limit 55;
+}
+}
+#end route 1
+route {
+match {
+source 1::2/128/0;
+destination 3::3/128/0;
+packet-length <200;
+}
+then {
+redirect 50::2;
+rate-limit 55;
+}
+}
+#end route 2
+}
+}
diff --git a/tests/topotests/bgp_flowspec/r1/bgpd.conf b/tests/topotests/bgp_flowspec/r1/bgpd.conf
new file mode 100644
index 0000000000..4b7a20f958
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/r1/bgpd.conf
@@ -0,0 +1,19 @@
+!
+hostname r1
+password zebra
+log stdout debugging
+router bgp 100
+ bgp router-id 10.0.1.1
+ neighbor 10.0.1.101 remote-as 100
+ neighbor 10.0.1.101 timers 3 10
+ neighbor 10.0.1.101 update-source 10.0.1.1
+ address-family ipv6 flowspec
+ local-install r1-eth0
+ neighbor 10.0.1.101 activate
+ exit-address-family
+ address-family ipv4 flowspec
+ local-install r1-eth0
+ neighbor 10.0.1.101 activate
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_flowspec/r1/summary.txt b/tests/topotests/bgp_flowspec/r1/summary.txt
new file mode 100644
index 0000000000..d5dfe0b6c2
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/r1/summary.txt
@@ -0,0 +1,53 @@
+{
+"ipv4Unicast":{
+ "routerId":"10.0.1.1",
+ "as":100,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "10.0.1.101":{
+ "outq":0,
+ "inq":0,
+ "pfxRcd":0,
+ "pfxSnt":0,
+ "state":"Established"
+ }
+ },
+ "totalPeers":1
+},
+"ipv4Flowspec":{
+ "routerId":"10.0.1.1",
+ "as":100,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "10.0.1.101":{
+ "outq":0,
+ "inq":0,
+ "pfxRcd":1,
+ "pfxSnt":0,
+ "state":"Established"
+ }
+ },
+ "totalPeers":1
+},
+"ipv6Flowspec":{
+ "routerId":"10.0.1.1",
+ "as":100,
+ "vrfId":0,
+ "vrfName":"default",
+ "peerCount":1,
+ "peers":{
+ "10.0.1.101":{
+ "outq":0,
+ "inq":0,
+ "pfxRcd":1,
+ "pfxSnt":0,
+ "state":"Established"
+ }
+ },
+ "totalPeers":1
+}
+}
diff --git a/tests/topotests/bgp_flowspec/r1/zebra.conf b/tests/topotests/bgp_flowspec/r1/zebra.conf
new file mode 100644
index 0000000000..e4d5a21194
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/r1/zebra.conf
@@ -0,0 +1,8 @@
+!
+hostname r1
+password zebra
+interface r1-eth0
+ ip address 10.0.1.1/24
+ ipv6 address 1001::1/112
+!
+
diff --git a/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py b/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py
new file mode 100755
index 0000000000..a7e2c31cde
--- /dev/null
+++ b/tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_flowspec_topo.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by 6WIND
+#
+# 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.
+#
+
+"""
+test_bgp_flowspec_topo.py: Test BGP topology with Flowspec EBGP peering
+
+
+ +------+------+
+ | peer1 |
+ | BGP peer 1 |
+ |192.168.0.161|
+ | |
+ +------+------+
+ .2 | r1-eth0
+ |
+ ~~~~~~~~~
+ +---~~ s1 ~~------+
+ ~~ ~~
+ ~~~~~~~~~
+ | 10.0.1.1 r1-eth0
+ | 1001::1 r1-eth0
+ +--------+--------+
+ | r1 |
+ |BGP 192.168.0.162|
+ | |
+ | |
+ | |
+ +-----------------+
+
+"""
+
+import json
+import functools
+import os
+import sys
+import pytest
+import getopt
+
+# Save the Current Working Directory to find configuration files.
+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.lutil import lUtil
+from lib.lutil import luCommand
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+#####################################################
+##
+## Network Topology Definition
+##
+#####################################################
+
+
+class BGPFLOWSPECTopo1(Topo):
+ "BGP EBGP Flowspec Topology 1"
+
+ def build(self, **_opts):
+ tgen = get_topogen(self)
+
+ # Setup Routers
+ tgen.add_router("r1")
+
+ # Setup Control Path Switch 1. r1-eth0
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+
+ ## Add eBGP ExaBGP neighbors
+ peer_ip = "10.0.1.101" ## peer
+ peer_route = "via 10.0.1.1" ## router
+ peer = tgen.add_exabgp_peer("peer1", ip=peer_ip, defaultRoute=peer_route)
+ switch.add_link(peer)
+
+
+#####################################################
+##
+## Tests starting
+##
+#####################################################
+
+
+def setup_module(module):
+ tgen = Topogen(BGPFLOWSPECTopo1, module.__name__)
+
+ tgen.start_topology()
+ # check for zebra capability
+ router = tgen.gears["r1"]
+
+ # Get r1 reference and run Daemons
+ logger.info("Launching BGP and ZEBRA on r1")
+ router = tgen.gears["r1"]
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format("r1"))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format("r1"))
+ )
+ router.start()
+
+ peer_list = tgen.exabgp_peers()
+ for pname, peer in peer_list.iteritems():
+ peer_dir = os.path.join(CWD, pname)
+ env_file = os.path.join(CWD, "exabgp.env")
+ peer.start(peer_dir, env_file)
+ logger.info(pname)
+
+
+def teardown_module(module):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_convergence():
+ "Test for BGP topology convergence"
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("waiting for bgp convergence")
+
+ # Expected result
+ router = tgen.gears["r1"]
+ reffile = os.path.join(CWD, "r1/summary.txt")
+
+ expected = json.loads(open(reffile).read())
+
+ test_func = functools.partial(
+ topotest.router_json_cmp, router, "show bgp summary json", expected
+ )
+ _, res = topotest.run_and_expect(test_func, None, count=90, wait=0.5)
+ assertmsg = "BGP router network did not converge"
+ assert res is None, assertmsg
+
+
+def test_bgp_flowspec():
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router = tgen.gears["r1"]
+
+ logger.info("Check BGP FS entry for 3.3.3.3 with redirect IP")
+ output = router.vtysh_cmd(
+ "show bgp ipv4 flowspec 3.3.3.3", isjson=False, daemon="bgpd"
+ )
+ logger.info(output)
+ if (
+ "NH 50.0.0.2" not in output
+ or "FS:redirect IP" not in output
+ or "Packet Length < 200" not in output
+ ):
+ assertmsg = "traffic to 3.3.3.3 should have been detected as FS entry. NOK"
+ assert 0, assertmsg
+ else:
+ logger.info("Check BGP FS entry for 3.3.3.3 with redirect IP OK")
+
+ logger.info("Check BGP FS entry for 3::3 with redirect IP")
+ output = router.vtysh_cmd(
+ "show bgp ipv6 flowspec 3::3", isjson=False, daemon="bgpd"
+ )
+ logger.info(output)
+ if (
+ "NH 50::2" not in output
+ or "FS:redirect IP" not in output
+ or "Packet Length < 200" not in output
+ ):
+ assertmsg = "traffic to 3::3 should have been detected as FS entry. NOK"
+ assert 0, assertmsg
+ else:
+ logger.info("Check BGP FS entry for 3::3 with redirect IP OK")
+
+if __name__ == "__main__":
+
+ args = ["-s"] + sys.argv[1:]
+ ret = pytest.main(args)
+
+ sys.exit(ret)
diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py
index fdc1bed522..fdbd317093 100755
--- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py
+++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py
@@ -135,6 +135,7 @@ from lib.common_config import (
kill_mininet_routers_process,
get_frr_ipv6_linklocal,
create_route_maps,
+ required_linux_kernel_version
)
# Reading the data from JSON File for topology and configuration creation
@@ -186,6 +187,11 @@ def setup_module(mod):
global ADDR_TYPES
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
index 83a04f491f..e1ec0ea81b 100755
--- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
+++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
@@ -135,6 +135,7 @@ from lib.common_config import (
kill_mininet_routers_process,
get_frr_ipv6_linklocal,
create_route_maps,
+ required_linux_kernel_version
)
# Reading the data from JSON File for topology and configuration creation
@@ -183,6 +184,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
global ADDR_TYPES
testsuite_run_time = time.asctime(time.localtime(time.time()))
diff --git a/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf b/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf
index 4d96bec2cb..0918796e95 100644
--- a/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf
+++ b/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 101
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r1-eth0 interface peer-group r2g
+ neighbor r1-eth0 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
diff --git a/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf b/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf
index 4d02fc4f29..55d48560e7 100644
--- a/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf
+++ b/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 102
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r2-eth0 interface peer-group r2g
+ neighbor r2-eth0 timers 3 10
!
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf
index 2712e54f12..8b885341eb 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf
@@ -10,6 +10,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5226
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 5.1.0.0/24 route-map rm-nh
network 5.1.1.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf
index 69305512cb..2accaae163 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf
@@ -10,6 +10,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5226
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 5.1.0.0/24 route-map rm-nh
network 5.1.1.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf
index 3ad95c3612..42eff1b9b1 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf
@@ -10,6 +10,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5226
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 5.1.2.0/24 route-map rm-nh
network 5.1.3.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf
index 502c4c8b2f..a564da9411 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf
@@ -11,8 +11,10 @@ router bgp 5226
neighbor 192.168.1.2 remote-as 5226
neighbor 192.168.1.2 update-source 192.168.1.1
neighbor 192.168.1.2 route-reflector-client
+ neighbor 192.168.1.2 timers 3 10
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 1.1.1.1
+ neighbor 2.2.2.2 timers 3 10
!
address-family ipv4 unicast
redistribute vnc-direct
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/ospfd.conf
index c5097e214f..460a8fb016 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf
index 95890f25b9..3167306700 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf
@@ -10,10 +10,13 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 1.1.1.1 remote-as 5226
neighbor 1.1.1.1 update-source 2.2.2.2
+ neighbor 1.1.1.1 timers 3 10
neighbor 3.3.3.3 remote-as 5226
neighbor 3.3.3.3 update-source 2.2.2.2
+ neighbor 3.3.3.3 timers 3 10
neighbor 4.4.4.4 remote-as 5226
neighbor 4.4.4.4 update-source 2.2.2.2
+ neighbor 4.4.4.4 timers 3 10
address-family ipv4 unicast
no neighbor 1.1.1.1 activate
no neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/ospfd.conf
index 8678813665..dbed6189c8 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/ospfd.conf
@@ -5,3 +5,15 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf
index 2f7de073c3..445da08248 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf
@@ -11,8 +11,10 @@ router bgp 5226
neighbor 192.168.1.2 remote-as 5226
neighbor 192.168.1.2 update-source 192.168.1.2
neighbor 192.168.1.2 route-reflector-client
+ neighbor 192.168.1.2 timers 3 10
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 3.3.3.3
+ neighbor 2.2.2.2 timers 3 10
!
address-family ipv4 unicast
redistribute vnc-direct
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/ospfd.conf
index c7c358f9dc..0e64ed6fc5 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/ospfd.conf
@@ -7,3 +7,11 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf
index 720d06dbf1..1941352450 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf
@@ -11,8 +11,10 @@ router bgp 5226
neighbor 192.168.1.2 remote-as 5226
neighbor 192.168.1.2 update-source 192.168.1.1
neighbor 192.168.1.2 route-reflector-client
+ neighbor 192.168.1.2 timers 3 10
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 4.4.4.4
+ neighbor 2.2.2.2 timers 3 10
!
address-family ipv4 unicast
redistribute vnc-direct
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/ospfd.conf
index 83d09c09a4..89e37df479 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
index b81cd33c4f..6e6b9edde2 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
@@ -12,6 +12,7 @@ router bgp 5227
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5227
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 99.0.0.1/32
network 5.1.0.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
index f18e5b852e..618acabd9f 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
@@ -12,6 +12,7 @@ router bgp 5227
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5227
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 99.0.0.2/32
network 5.1.0.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf
index 54a0933588..85c5973e6f 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf
@@ -12,6 +12,7 @@ router bgp 5227
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as 5227
neighbor 192.168.1.1 update-source 192.168.1.2
+ neighbor 192.168.1.1 timers 3 10
address-family ipv4 unicast
network 99.0.0.3/32
network 5.1.2.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf
index 5289628480..6a5075a000 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf
@@ -12,6 +12,7 @@ router bgp 5228 vrf ce4-cust2
no bgp ebgp-requires-policy
neighbor 192.168.2.1 remote-as 5228
neighbor 192.168.2.1 update-source 192.168.2.2
+ neighbor 192.168.2.1 timers 3 10
address-family ipv4 unicast
network 99.0.0.4/32
network 5.4.2.0/24 route-map rm-nh
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf
index 5da53ae1e7..8d42cfc0d8 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf
@@ -18,6 +18,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 1.1.1.1
+ neighbor 2.2.2.2 timers 3 10
address-family ipv4 unicast
no neighbor 2.2.2.2 activate
@@ -35,6 +36,7 @@ router bgp 5227 vrf r1-cust1
neighbor 192.168.1.2 remote-as 5227
neighbor 192.168.1.2 update-source 192.168.1.1
+ neighbor 192.168.1.2 timers 3 10
address-family ipv4 unicast
neighbor 192.168.1.2 activate
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/ospfd.conf
index c5097e214f..460a8fb016 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf
index e4a6b8e32c..7b42b770b5 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf
@@ -12,10 +12,13 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 1.1.1.1 remote-as 5226
neighbor 1.1.1.1 update-source 2.2.2.2
+ neighbor 1.1.1.1 timers 3 10
neighbor 3.3.3.3 remote-as 5226
neighbor 3.3.3.3 update-source 2.2.2.2
+ neighbor 3.3.3.3 timers 3 10
neighbor 4.4.4.4 remote-as 5226
neighbor 4.4.4.4 update-source 2.2.2.2
+ neighbor 4.4.4.4 timers 3 10
address-family ipv4 unicast
no neighbor 1.1.1.1 activate
no neighbor 3.3.3.3 activate
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/ospfd.conf
index 8678813665..dbed6189c8 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/ospfd.conf
@@ -5,3 +5,15 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
index a861469c7a..6c9640eea0 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf
@@ -13,6 +13,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 3.3.3.3
+ neighbor 2.2.2.2 timers 3 10
address-family ipv4 unicast
no neighbor 2.2.2.2 activate
@@ -29,6 +30,7 @@ router bgp 5227 vrf r3-cust1
neighbor 192.168.1.2 remote-as 5227
neighbor 192.168.1.2 update-source 192.168.1.1
+ neighbor 192.168.1.2 timers 3 10
address-family ipv4 unicast
neighbor 192.168.1.2 activate
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/ospfd.conf
index c7c358f9dc..0e64ed6fc5 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/ospfd.conf
@@ -7,3 +7,11 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
index 480f95954e..ca9e627172 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf
@@ -16,6 +16,7 @@ router bgp 5226
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
neighbor 2.2.2.2 update-source 4.4.4.4
+ neighbor 2.2.2.2 timers 3 10
address-family ipv4 unicast
no neighbor 2.2.2.2 activate
@@ -32,6 +33,7 @@ router bgp 5227 vrf r4-cust1
neighbor 192.168.1.2 remote-as 5227
neighbor 192.168.1.2 update-source 192.168.1.1
+ neighbor 192.168.1.2 timers 3 10
address-family ipv4 unicast
neighbor 192.168.1.2 activate
@@ -52,6 +54,7 @@ router bgp 5228 vrf r4-cust2
neighbor 192.168.2.2 remote-as 5228
neighbor 192.168.2.2 update-source 192.168.2.1
+ neighbor 192.168.2.2 timers 3 10
address-family ipv4 unicast
neighbor 192.168.2.2 activate
diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/ospfd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/ospfd.conf
index 83d09c09a4..89e37df479 100644
--- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/ospfd.conf
+++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
index 334aaebb4b..dc06b7131a 100755
--- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
+++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
@@ -67,6 +67,7 @@ from lib.common_config import (
verify_bgp_community,
step,
check_address_types,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
@@ -142,6 +143,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
global ADDR_TYPES
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
diff --git a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
index 502a9a9ec4..bb88e47415 100755
--- a/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
+++ b/tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
@@ -91,6 +91,7 @@ from lib.common_config import (
verify_route_maps,
create_static_routes,
check_address_types,
+ required_linux_kernel_version
)
from lib.topolog import logger
from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
@@ -133,6 +134,11 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
logger.info("=" * 40)
diff --git a/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf
index 40c19062a2..0e46687100 100644
--- a/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf
@@ -5,5 +5,7 @@ router bgp 65101
no bgp ebgp-requires-policy
bgp bestpath as-path multipath-relax
neighbor 11.1.1.2 remote-as external
+ neighbor 11.1.1.2 timers 3 10
neighbor 11.1.1.6 remote-as external
+ neighbor 11.1.1.6 timers 3 10
!
diff --git a/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf
index 80588e7961..022270ff8a 100644
--- a/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 65354
bgp router-id 11.1.6.2
no bgp ebgp-requires-policy
neighbor 11.1.6.1 remote-as external
+ neighbor 11.1.6.1 timers 3 10
!
address-family ipv4 unicast
redistribute connected route-map redist
diff --git a/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf
index 6fec1913c8..0c0e859cab 100644
--- a/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf
@@ -5,6 +5,9 @@ router bgp 65201
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 11.1.1.1 remote-as external
+ neighbor 11.1.1.1 timers 3 10
neighbor 11.1.2.2 remote-as external
+ neighbor 11.1.2.2 timers 3 10
neighbor 11.1.2.6 remote-as external
+ neighbor 11.1.2.6 timers 3 10
!
diff --git a/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf
index 1c2ca88306..3f20eb10a3 100644
--- a/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf
@@ -5,5 +5,7 @@ router bgp 65202
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 11.1.1.5 remote-as external
+ neighbor 11.1.1.5 timers 3 10
neighbor 11.1.3.2 remote-as external
+ neighbor 11.1.3.2 timers 3 10
!
diff --git a/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf
index 022a230643..d34db982c9 100644
--- a/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf
@@ -20,8 +20,11 @@ router bgp 65301
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 11.1.2.1 remote-as external
+ neighbor 11.1.2.1 timers 3 10
neighbor 11.1.4.2 remote-as external
+ neighbor 11.1.4.2 timers 3 10
neighbor 11.1.4.6 remote-as external
+ neighbor 11.1.4.6 timers 3 10
!
address-family ipv4 unicast
neighbor 11.1.2.1 route-map anycast_ip out
diff --git a/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf
index fc4e3888d8..4014bfbc8b 100644
--- a/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf
@@ -13,7 +13,9 @@ router bgp 65302
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 11.1.2.5 remote-as external
+ neighbor 11.1.2.5 timers 3 10
neighbor 11.1.5.2 remote-as external
+ neighbor 11.1.5.2 timers 3 10
!
address-family ipv4 unicast
neighbor 11.1.2.5 route-map anycast_ip out
diff --git a/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf
index f08f6337f4..18e7eb9285 100644
--- a/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf
@@ -13,7 +13,9 @@ router bgp 65303
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 11.1.3.1 remote-as external
+ neighbor 11.1.3.1 timers 3 10
neighbor 11.1.6.2 remote-as external
+ neighbor 11.1.6.2 timers 3 10
!
address-family ipv4 unicast
neighbor 11.1.3.1 route-map anycast_ip out
diff --git a/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf
index 98dfe2471a..39c0c81950 100644
--- a/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 65351
bgp router-id 11.1.4.2
no bgp ebgp-requires-policy
neighbor 11.1.4.1 remote-as external
+ neighbor 11.1.4.1 timers 3 10
!
address-family ipv4 unicast
redistribute connected route-map redist
diff --git a/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf
index b4ba8e8a72..ea1d546017 100644
--- a/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 65352
bgp router-id 11.1.4.6
no bgp ebgp-requires-policy
neighbor 11.1.4.5 remote-as external
+ neighbor 11.1.4.5 timers 3 10
!
address-family ipv4 unicast
redistribute connected route-map redist
diff --git a/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf
index 31f971dd08..a6066ee766 100644
--- a/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf
+++ b/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 65353
bgp router-id 11.1.5.2
no bgp ebgp-requires-policy
neighbor 11.1.5.1 remote-as external
+ neighbor 11.1.5.1 timers 3 10
!
address-family ipv4 unicast
redistribute connected route-map redist
diff --git a/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf
index 6f8fcd753d..16a9eeadd1 100644
--- a/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf
+++ b/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 1000
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.2 local-as 500
address-family ipv4 unicast
neighbor 192.168.255.2 remove-private-AS
diff --git a/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf
index 27427a9aaa..802c32714b 100644
--- a/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf
+++ b/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf
@@ -1,3 +1,5 @@
router bgp 1000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 500
+ neighbor 192.168.255.1 timers 3 10
+!
diff --git a/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf
index f2050ddfdb..9a831270b4 100644
--- a/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf
+++ b/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 3000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 1000
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.2 local-as 500
address-family ipv4 unicast
neighbor 192.168.255.2 remove-private-AS
diff --git a/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf
index 27427a9aaa..802c32714b 100644
--- a/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf
+++ b/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf
@@ -1,3 +1,5 @@
router bgp 1000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 500
+ neighbor 192.168.255.1 timers 3 10
+!
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf
index f0df56e947..62110429cf 100644
--- a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf
+++ b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf
index ef50dd0d7f..005425e850 100644
--- a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf
+++ b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf
@@ -1,5 +1,6 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4
neighbor 192.168.255.1 maximum-prefix 1
diff --git a/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf b/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf
index 03e3eb6e08..adb594b3dd 100644
--- a/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf
+++ b/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4 unicast
redistribute connected
neighbor 192.168.255.1 maximum-prefix-out 2
diff --git a/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf b/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf
index 2d47b2f661..229de2e2f2 100644
--- a/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf
+++ b/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65002
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
exit-address-family
!
!
diff --git a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
index a37e3f36a3..c15b88d371 100755
--- a/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
+++ b/tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
@@ -132,6 +132,7 @@ from lib.common_config import (
create_bgp_community_lists,
check_router_status,
apply_raw_config,
+ required_linux_kernel_version
)
from lib.topolog import logger
@@ -209,6 +210,10 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
diff --git a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
index 27c4430a52..bb13d54019 100755
--- a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
+++ b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
@@ -70,7 +70,6 @@ from lib.common_config import (
create_route_maps,
shutdown_bringup_interface,
start_router_daemons,
- kill_router_daemons,
create_static_routes,
create_vrf_cfg,
create_interfaces_cfg,
@@ -79,6 +78,7 @@ from lib.common_config import (
get_frr_ipv6_linklocal,
check_router_status,
apply_raw_config,
+ required_linux_kernel_version
)
from lib.topolog import logger
@@ -142,6 +142,10 @@ def setup_module(mod):
* `mod`: module name
"""
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version('4.15')
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
testsuite_run_time = time.asctime(time.localtime(time.time()))
logger.info("Testsuite start time: {}".format(testsuite_run_time))
diff --git a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
index 5f65a54d7f..d44c3e18e6 100644
--- a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
+++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf
@@ -17,8 +17,11 @@ router bgp 100 view 1
network 172.20.0.0/28 route-map local1
timers bgp 60 180
neighbor 172.16.1.1 remote-as 65001
+ neighbor 172.16.1.1 timers 3 10
neighbor 172.16.1.2 remote-as 65002
+ neighbor 172.16.1.2 timers 3 10
neighbor 172.16.1.5 remote-as 65005
+ neighbor 172.16.1.5 timers 3 10
!
router bgp 100 view 2
bgp router-id 172.30.1.1
@@ -26,7 +29,9 @@ router bgp 100 view 2
network 172.20.0.0/28 route-map local2
timers bgp 60 180
neighbor 172.16.1.3 remote-as 65003
+ neighbor 172.16.1.3 timers 3 10
neighbor 172.16.1.4 remote-as 65004
+ neighbor 172.16.1.4 timers 3 10
!
router bgp 100 view 3
bgp router-id 172.30.1.1
@@ -34,8 +39,11 @@ router bgp 100 view 3
network 172.20.0.0/28
timers bgp 60 180
neighbor 172.16.1.6 remote-as 65006
+ neighbor 172.16.1.6 timers 3 10
neighbor 172.16.1.7 remote-as 65007
+ neighbor 172.16.1.7 timers 3 10
neighbor 172.16.1.8 remote-as 65008
+ neighbor 172.16.1.8 timers 3 10
!
route-map local1 permit 10
set community 100:9999 additive
diff --git a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf
index 06bdc31f8c..e02226f2fd 100644
--- a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf
+++ b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf
@@ -6,7 +6,9 @@ router bgp 1
no bgp default ipv4-unicast
no bgp ebgp-requires-policy
neighbor 10.0.0.101 remote-as 2
+ neighbor 10.0.0.101 timers 3 10
neighbor 10.0.0.102 remote-as 3
+ neighbor 10.0.0.102 timers 3 10
!
address-family ipv4 labeled-unicast
neighbor 10.0.0.101 activate
diff --git a/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf
index 94bfc5e561..a28b612e00 100644
--- a/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf
+++ b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
diff --git a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf
index f217b7f794..453961762a 100644
--- a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf
+++ b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf
@@ -3,7 +3,9 @@ router bgp 65002
bgp reject-as-sets
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.254.2 remote-as 65003
+ neighbor 192.168.254.2 timers 3 10
address-family ipv4 unicast
aggregate-address 172.16.0.0/16 as-set summary-only
exit-address-family
diff --git a/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf
index 8d085a0e4b..1dde4f0f69 100644
--- a/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf
+++ b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 192.168.254.1 remote-as 65002
+ neighbor 192.168.254.1 timers 3 10
address-family ipv4 unicast
neighbor 192.168.254.1 allowas-in
redistribute connected
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
index ada354bd62..f6e0baa43d 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 1.1.1.1
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 1.1.1.1
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r1/ospfd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r1/ospfd.conf
index c5097e214f..460a8fb016 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r1/ospfd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r1/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf
index 95890f25b9..19050e67f6 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf
@@ -9,10 +9,13 @@ router bgp 5226
bgp cluster-id 2.2.2.2
no bgp ebgp-requires-policy
neighbor 1.1.1.1 remote-as 5226
+ neighbor 1.1.1.1 timers 3 10
neighbor 1.1.1.1 update-source 2.2.2.2
neighbor 3.3.3.3 remote-as 5226
+ neighbor 3.3.3.3 timers 3 10
neighbor 3.3.3.3 update-source 2.2.2.2
neighbor 4.4.4.4 remote-as 5226
+ neighbor 4.4.4.4 timers 3 10
neighbor 4.4.4.4 update-source 2.2.2.2
address-family ipv4 unicast
no neighbor 1.1.1.1 activate
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r2/ospfd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r2/ospfd.conf
index 8678813665..dbed6189c8 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r2/ospfd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r2/ospfd.conf
@@ -5,3 +5,15 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
index 4932d63d4f..2210f24589 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 3.3.3.3
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 3.3.3.3
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/ospfd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/ospfd.conf
index c7c358f9dc..0e64ed6fc5 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r3/ospfd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/ospfd.conf
@@ -7,3 +7,11 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
index 1a5e41aae6..28b5f9cfc5 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 4.4.4.4
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 4.4.4.4
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r4/ospfd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r4/ospfd.conf
index 83d09c09a4..89e37df479 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r4/ospfd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r4/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
network 0.0.0.0/4 area 0
redistribute static
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
index a38afd632f..3196a16626 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 1.1.1.1
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 1.1.1.1
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf
index 95890f25b9..19050e67f6 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf
@@ -9,10 +9,13 @@ router bgp 5226
bgp cluster-id 2.2.2.2
no bgp ebgp-requires-policy
neighbor 1.1.1.1 remote-as 5226
+ neighbor 1.1.1.1 timers 3 10
neighbor 1.1.1.1 update-source 2.2.2.2
neighbor 3.3.3.3 remote-as 5226
+ neighbor 3.3.3.3 timers 3 10
neighbor 3.3.3.3 update-source 2.2.2.2
neighbor 4.4.4.4 remote-as 5226
+ neighbor 4.4.4.4 timers 3 10
neighbor 4.4.4.4 update-source 2.2.2.2
address-family ipv4 unicast
no neighbor 1.1.1.1 activate
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
index dbeb2c4665..e74fc0b3de 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 3.3.3.3
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 3.3.3.3
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
index ae1787718c..56474aad9c 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf
@@ -9,6 +9,7 @@ router bgp 5226
bgp cluster-id 4.4.4.4
no bgp ebgp-requires-policy
neighbor 2.2.2.2 remote-as 5226
+ neighbor 2.2.2.2 timers 3 10
neighbor 2.2.2.2 update-source 4.4.4.4
!
address-family ipv4 unicast
diff --git a/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf
index fa77cce073..cece3fc600 100644
--- a/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf
+++ b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf
@@ -2,7 +2,9 @@ hostname spine1
router bgp 99
no bgp ebgp-requires-policy
neighbor 192.168.2.1 remote-as internal
+ neighbor 192.168.2.1 timers 3 10
neighbor 192.168.4.2 remote-as internal
+ neighbor 192.168.4.2 timers 3 10
address-family ipv4 uni
redistribute connected
neighbor 192.168.2.1 route-reflector-client
diff --git a/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf
index b028ab4e8b..1b9f15010a 100644
--- a/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf
+++ b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf
@@ -2,4 +2,5 @@ hostname tor1
router bgp 99
no bgp ebgp-requires-policy
neighbor 192.168.2.3 remote-as internal
+ neighbor 192.168.2.3 timers 3 10
redistribute connected
diff --git a/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf
index 99c34158b9..3bdb35976c 100644
--- a/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf
+++ b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf
@@ -2,4 +2,5 @@ hostname tor2
router bgp 99
no bgp ebgp-requires-policy
neighbor 192.168.4.3 remote-as internal
+ neighbor 192.168.4.3 timers 3 10
redistribute connected
diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf
index b16e94d7c1..719d76392d 100644
--- a/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf
+++ b/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4 unicast
neighbor 192.168.255.1 route-map prepend out
redistribute connected
diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf
index 674877edd3..a4a654d7b5 100644
--- a/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf
+++ b/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf
@@ -2,8 +2,10 @@
router bgp 65002
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.2 solo
neighbor 192.168.254.2 remote-as 65003
+ neighbor 192.168.254.2 timers 3 10
neighbor 192.168.254.2 solo
neighbor 192.168.254.2 sender-as-path-loop-detection
!
diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf
index 4ee7a39ab2..2e24de0b2d 100644
--- a/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf
+++ b/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf
@@ -2,4 +2,5 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 192.168.254.1 remote-as 65002
+ neighbor 192.168.254.1 timers 3 10
!
diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf
index 7dab52fef0..57e2f5818a 100644
--- a/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf
+++ b/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf
@@ -1,6 +1,8 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65000
+ neighbor 192.168.255.2 timers 3 10
neighbor 192.168.255.3 remote-as 65000
+ neighbor 192.168.255.3 timers 3 10
exit-address-family
!
diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf
index a8a0384632..82a01d4570 100644
--- a/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf
+++ b/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4
redistribute connected
neighbor 192.168.255.1 route-map r1-out out
diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf
index 2f5dceede2..65e092b0f2 100644
--- a/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf
+++ b/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf
@@ -1,6 +1,7 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.1 remote-as 65000
+ neighbor 192.168.255.1 timers 3 10
address-family ipv4
redistribute connected
neighbor 192.168.255.1 route-map r1-out out
diff --git a/tests/topotests/bgp_update_delay/__init__.py b/tests/topotests/bgp_update_delay/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/__init__.py
diff --git a/tests/topotests/bgp_update_delay/r1/bgpd.conf b/tests/topotests/bgp_update_delay/r1/bgpd.conf
new file mode 100644
index 0000000000..8ebb509d6d
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r1/bgpd.conf
@@ -0,0 +1,10 @@
+! exit1
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.255.1 remote-as 65002
+ neighbor 192.168.255.1 timers connect 10
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_update_delay/r1/zebra.conf b/tests/topotests/bgp_update_delay/r1/zebra.conf
new file mode 100644
index 0000000000..9904bb4e16
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r1/zebra.conf
@@ -0,0 +1,9 @@
+! exit1
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.2/30
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_update_delay/r2/bgpd.conf b/tests/topotests/bgp_update_delay/r2/bgpd.conf
new file mode 100644
index 0000000000..438f9950a5
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r2/bgpd.conf
@@ -0,0 +1,18 @@
+! spine
+router bgp 65002
+ no bgp ebgp-requires-policy
+ timers bgp 3 9
+ neighbor 192.168.255.2 remote-as 65001
+ neighbor 192.168.254.2 remote-as 65003
+ neighbor 192.168.253.2 remote-as 65004
+ neighbor 192.168.255.2 timers connect 10
+ neighbor 192.168.254.2 timers connect 10
+ neighbor 192.168.253.2 timers connect 10
+!
+ router bgp 65002 vrf vrf1
+ no bgp ebgp-requires-policy
+ timers bgp 3 9
+ neighbor 192.168.252.2 remote-as 65005
+ neighbor 192.168.252.2 timers connect 10
+ !
+!
diff --git a/tests/topotests/bgp_update_delay/r2/zebra.conf b/tests/topotests/bgp_update_delay/r2/zebra.conf
new file mode 100644
index 0000000000..420f00d974
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r2/zebra.conf
@@ -0,0 +1,20 @@
+! spine
+interface r2-eth0
+ ip address 192.168.255.1/30
+!
+interface r2-eth1
+ ip address 192.168.254.1/30
+!
+interface r2-eth2
+ ip address 192.168.253.1/30
+!
+interface r2-eth3
+ ip address 192.168.252.1/30
+ vrf vrf1
+!
+auto vrf1
+iface vrf1
+ vrf-table auto
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_update_delay/r3/bgpd.conf b/tests/topotests/bgp_update_delay/r3/bgpd.conf
new file mode 100644
index 0000000000..53e51788f7
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r3/bgpd.conf
@@ -0,0 +1,10 @@
+! exit2
+router bgp 65003
+ no bgp ebgp-requires-policy
+ timers bgp 3 9
+ neighbor 192.168.254.1 remote-as 65002
+ neighbor 192.168.254.1 timers connect 10
+ address-family ipv4 unicast
+ redistribute connected
+ !
+!
diff --git a/tests/topotests/bgp_update_delay/r3/zebra.conf b/tests/topotests/bgp_update_delay/r3/zebra.conf
new file mode 100644
index 0000000000..f490d97afe
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r3/zebra.conf
@@ -0,0 +1,9 @@
+! exit2
+interface lo
+ ip address 172.16.254.254/32
+!
+interface r3-eth0
+ ip address 192.168.254.2/30
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_update_delay/r4/bgpd.conf b/tests/topotests/bgp_update_delay/r4/bgpd.conf
new file mode 100644
index 0000000000..34cb429c0a
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r4/bgpd.conf
@@ -0,0 +1,11 @@
+! exit2
+router bgp 65004
+ no bgp ebgp-requires-policy
+ timers bgp 3 9
+ neighbor 192.168.253.1 remote-as 65002
+ neighbor 192.168.253.1 timers connect 10
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_update_delay/r4/zebra.conf b/tests/topotests/bgp_update_delay/r4/zebra.conf
new file mode 100644
index 0000000000..baba04c160
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r4/zebra.conf
@@ -0,0 +1,9 @@
+! exit2
+interface lo
+ ip address 172.16.253.254/32
+!
+interface r4-eth0
+ ip address 192.168.253.2/30
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_update_delay/r5/bgpd.conf b/tests/topotests/bgp_update_delay/r5/bgpd.conf
new file mode 100644
index 0000000000..66ecc703cd
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r5/bgpd.conf
@@ -0,0 +1,11 @@
+! exit1
+router bgp 65005
+ no bgp ebgp-requires-policy
+ timers bgp 3 9
+ neighbor 192.168.252.1 remote-as 65002
+ neighbor 192.168.252.1 timers connect 10
+ address-family ipv4 unicast
+ redistribute connected
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_update_delay/r5/zebra.conf b/tests/topotests/bgp_update_delay/r5/zebra.conf
new file mode 100644
index 0000000000..8adf6f89e0
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/r5/zebra.conf
@@ -0,0 +1,9 @@
+! exit1
+interface lo
+ ip address 172.16.252.254/32
+!
+interface r1-eth0
+ ip address 192.168.252.2/30
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_update_delay/test_bgp_update_delay.py b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py
new file mode 100755
index 0000000000..9d2818b965
--- /dev/null
+++ b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_update_delay.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by
+# Don Slice <dslice@nvidia.com>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+Test the ability to define update-delay to delay bestpath, rib install
+and advertisement to peers when frr is started, restarted or "clear ip
+bgp *" is performed. Test both the vrf-specific and global configuration
+and operation.
+
+r1
+|
+r2----r3
+| \
+| \
+r5 r4
+
+
+r2 is UUT and peers with r1, r3, and r4 in default bgp instance.
+r2 peers with r5 in vrf vrf1.
+
+Check r2 initial convergence in default table
+Define update-delay with max-delay in the default bgp instance on r2
+Shutdown peering on r1 toward r2 so that delay timers can be exercised
+Clear bgp neighbors on r2 and then check for the 'in progress' indicator
+Check that r2 only installs route learned from r4 after the max-delay timer expires
+Define update-delay with max-delay and estabish-wait and check json output showing set
+Clear neighbors on r2 and check that r3 installs route from r4 after establish-wait time
+Remove update-delay timer on r2 to verify that it goes back to normal behavior
+Clear neighbors on r2 and check that route install time on r2 does not delay
+Define global bgp update-delay with max-delay and establish-wait on r2
+Check that r2 default instance and vrf1 have the max-delay and establish set
+Clear neighbors on r2 and check route-install time is after the establish-wait timer
+
+Note that the keepalive/hold times were changed to 3/9 and the connect retry timer
+to 10 to improve the odds the convergence timing in this test case is useful in the
+event of packet loss.
+"""
+
+import os
+import sys
+import json
+import time
+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.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+
+ for routern in range(1, 6):
+ tgen.add_router("r{}".format(routern))
+
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r4"])
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r5"])
+
+
+def setup_module(mod):
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ for i, (rname, router) in enumerate(router_list.iteritems(), 1):
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ tgen = get_topogen()
+ tgen.stop_topology()
+
+
+def test_bgp_update_delay():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ router1 = tgen.gears["r1"]
+ router2 = tgen.gears["r2"]
+ router3 = tgen.gears["r3"]
+
+ # initial convergence without update-delay defined
+ def _bgp_converge(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json"))
+ expected = {
+ "192.168.255.2": {
+ "bgpState": "Established",
+ "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}},
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_update_delay(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
+ expected = {"ipv4Unicast": {"updateDelayLimit": 20}}
+
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_update_delay_in_progress(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
+ expected = {"ipv4Unicast": {"updateDelayInProgress":True}}
+
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_route_install(router):
+ output = json.loads(router.vtysh_cmd("show ip route 172.16.253.254/32 json"))
+ expected = {"172.16.253.254/32": [ {"protocol": "bgp"}]}
+
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_update_delay_and_wait(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
+ expected = {
+ "ipv4Unicast": {
+ "updateDelayLimit": 20,
+ "updateDelayEstablishWait": 10}}
+
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_update_delay(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
+ expected = {"ipv4Unicast": {"updateDelayLimit": 20}}
+
+ return topotest.json_cmp(output, expected)
+
+ def _bgp_check_vrf_update_delay_and_wait(router):
+ output = json.loads(router.vtysh_cmd("show ip bgp vrf vrf1 sum json"))
+ expected = {
+ "ipv4Unicast": {
+ "updateDelayLimit": 20,
+ "updateDelayEstablishWait": 10}}
+
+
+ return topotest.json_cmp(output, expected)
+
+
+ # Check r2 initial convergence in default table
+ test_func = functools.partial(_bgp_converge, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed bgp convergence in "{}"'.format(router2)
+
+ # Define update-delay with max-delay in the default bgp instance on r2
+ router2.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65002
+ update-delay 20
+ """
+ )
+
+ # Shutdown peering on r1 toward r2 so that delay timers can be exercised
+ router1.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65001
+ neighbor 192.168.255.1 shut
+ """
+ )
+
+ # Clear bgp neighbors on r2 and then check for the 'in progress' indicator
+ router2.vtysh_cmd("""clear ip bgp *""")
+
+ test_func = functools.partial(_bgp_check_update_delay_in_progress, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format(router2)
+
+ # Check that r2 only installs route learned from r4 after the max-delay timer expires
+ test_func = functools.partial(_bgp_check_route_install, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to install route after update-delay "{}"'.format(router2)
+
+ # Define update-delay with max-delay and estabish-wait and check json output showing set
+ router2.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65002
+ update-delay 20 10
+ """
+ )
+
+ test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2)
+
+ # Define update-delay with max-delay and estabish-wait and check json output showing set
+ router2.vtysh_cmd("""clear ip bgp *""")
+
+ test_func = functools.partial(_bgp_check_route_install, router3)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
+
+ # Remove update-delay timer on r2 to verify that it goes back to normal behavior
+ router2.vtysh_cmd(
+ """
+ configure terminal
+ router bgp 65002
+ no update-delay
+ """
+ )
+
+ # Clear neighbors on r2 and check that route install time on r2 does not delay
+ router2.vtysh_cmd("""clear ip bgp *""")
+
+ test_func = functools.partial(_bgp_check_route_install, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to remove update-delay delay timing "{}"'.format(router2)
+
+ # Define global bgp update-delay with max-delay and establish-wait on r2
+ router2.vtysh_cmd(
+ """
+ configure terminal
+ bgp update-delay 20 10
+ """
+ )
+
+ # Check that r2 default instance and vrf1 have the max-delay and establish set
+ test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to set update-delay in default instance "{}"'.format(router2)
+
+ test_func = functools.partial(_bgp_check_vrf_update_delay_and_wait, router2)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to set update-delay in vrf1 "{}"'.format(router2)
+
+ # Clear neighbors on r2 and check route-install time is after the establish-wait timer
+ router2.vtysh_cmd("""clear ip bgp *""")
+
+ test_func = functools.partial(_bgp_check_route_install, router3)
+ success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+
+ assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo1.json b/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo1.json
new file mode 100644
index 0000000000..b1d7d09db8
--- /dev/null
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo1.json
@@ -0,0 +1,563 @@
+{
+ "address_types": ["ipv4","ipv6"],
+ "ipv4base": "10.0.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "10.0.0.0",
+ "v4mask": 30,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:db8:f::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "ISR"},
+ "r3-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r4-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "vrfs":[
+ {
+ "name": "ISR",
+ "id": "1"
+ }
+ ],
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["11.11.11.1/32", "11.11.11.11/32"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["11:11::1/128", "11:11::11/128"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["10.10.10.10/32", "10.10.10.100/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["10:10::10/128", "10:10::100/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r2": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "ISR"},
+ "r3-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r4-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "vrfs":[
+ {
+ "name": "ISR",
+ "id": "1"
+ }
+ ],
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["22.22.22.2/32", "22.22.22.22/32"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["22:22::2/128", "22:22::22/128"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["20.20.20.20/32", "20.20.20.200/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["20:20::20/128", "20:20::200/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r3": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp":
+ [
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["30.30.30.3/32", "30.30.30.30/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["30:30::3/128", "30:30::30/128"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50.50.50.5/32", "50.50.50.50/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50:50::5/128", "50:50::50/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r4": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp":
+ [
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["40.40.40.4/32", "40.40.40.40/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["40:40::4/128", "40:40::40/128"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50.50.50.5/32", "50.50.50.50/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50:50::5/128", "50:50::50/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo2.json b/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo2.json
new file mode 100644
index 0000000000..b1d7d09db8
--- /dev/null
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak/bgp_vrf_dynamic_route_leak_topo2.json
@@ -0,0 +1,563 @@
+{
+ "address_types": ["ipv4","ipv6"],
+ "ipv4base": "10.0.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {
+ "ipv4": "10.0.0.0",
+ "v4mask": 30,
+ "ipv6": "fd00::",
+ "v6mask": 64
+ },
+ "lo_prefix": {
+ "ipv4": "1.0.",
+ "v4mask": 32,
+ "ipv6": "2001:db8:f::",
+ "v6mask": 128
+ },
+ "routers": {
+ "r1": {
+ "links": {
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "ISR"},
+ "r3-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r4-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "vrfs":[
+ {
+ "name": "ISR",
+ "id": "1"
+ }
+ ],
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["11.11.11.1/32", "11.11.11.11/32"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["11:11::1/128", "11:11::11/128"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["10.10.10.10/32", "10.10.10.100/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["10:10::10/128", "10:10::100/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r2": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto", "vrf": "ISR"},
+ "r3-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r4-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "vrfs":[
+ {
+ "name": "ISR",
+ "id": "1"
+ }
+ ],
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "next_hop_self": true,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["22.22.22.2/32", "22.22.22.22/32"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["22:22::2/128", "22:22::22/128"],
+ "next_hop":"Null0",
+ "vrf": "ISR"
+ },
+ {
+ "network": ["20.20.20.20/32", "20.20.20.200/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["20:20::20/128", "20:20::200/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r3": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp":
+ [
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r3-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["30.30.30.3/32", "30.30.30.30/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["30:30::3/128", "30:30::30/128"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50.50.50.5/32", "50.50.50.50/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50:50::5/128", "50:50::50/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ },
+ "r4": {
+ "links": {
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp":
+ [
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3
+ }
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {
+ "keepalivetimer": 1,
+ "holddowntimer": 3,
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "static_routes":[
+ {
+ "network": ["40.40.40.4/32", "40.40.40.40/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["40:40::4/128", "40:40::40/128"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50.50.50.5/32", "50.50.50.50/32"],
+ "next_hop":"Null0"
+ },
+ {
+ "network": ["50:50::5/128", "50:50::50/128"],
+ "next_hop":"Null0"
+ }
+ ],
+ "route_maps": {
+ "rmap_global": [{
+ "action": "permit",
+ "set": {
+ "ipv6": {
+ "nexthop": "prefer-global"
+ }
+ }
+ }]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py
new file mode 100755
index 0000000000..1947548b3e
--- /dev/null
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py
@@ -0,0 +1,1848 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2020 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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 VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
+#
+
+"""
+Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking:
+
+1. Verify that dynamically imported routes are further advertised
+ to iBGP peers(peer in cluster).
+2. Verify matching a prefix based on community attribute and
+ importing it by stripping off this value
+3. Verify the route-map operation along with dynamic import command.
+4. Verifying the JSON outputs for all supported commands
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import platform
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+sys.path.append(os.path.join(CWD, '../lib/'))
+
+# Required to instantiate the topology builder class.
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topotest import version_cmp
+from mininet.topo import Topo
+
+from lib.common_config import (
+ start_topology, write_test_header, check_address_types,
+ write_test_footer, reset_config_on_routers,
+ verify_rib, step, create_route_maps,
+ shutdown_bringup_interface, create_static_routes,
+ create_prefix_lists, create_bgp_community_lists,
+ create_interface_in_kernel,
+ check_router_status, verify_cli_json,
+ get_frr_ipv6_linklocal, verify_fib_routes
+)
+
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ clear_bgp, verify_bgp_community, verify_bgp_rib
+)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+# Reading the data from JSON File for topology creation
+jsonFile = "{}/bgp_vrf_dynamic_route_leak_topo1.json".format(CWD)
+try:
+ with open(jsonFile, "r") as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"}
+NETWORK1_2 = {"ipv4": "11.11.11.11/32", "ipv6": "11:11::11/128"}
+NETWORK1_3 = {"ipv4": "10.10.10.10/32", "ipv6": "10:10::10/128"}
+NETWORK1_4 = {"ipv4": "10.10.10.100/32", "ipv6": "10:10::100/128"}
+
+NETWORK2_1 = {"ipv4": "22.22.22.2/32", "ipv6": "22:22::2/128"}
+NETWORK2_2 = {"ipv4": "22.22.22.22/32", "ipv6": "22:22::22/128"}
+NETWORK2_3 = {"ipv4": "20.20.20.20/32", "ipv6": "20:20::20/128"}
+NETWORK2_4 = {"ipv4": "20.20.20.200/32", "ipv6": "20:20::200/128"}
+
+NETWORK3_1 = {"ipv4": "30.30.30.3/32", "ipv6": "30:30::3/128"}
+NETWORK3_2 = {"ipv4": "30.30.30.30/32", "ipv6": "30:30::30/128"}
+NETWORK3_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"}
+NETWORK3_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"}
+
+NETWORK4_1 = {"ipv4": "40.40.40.4/32", "ipv6": "40:40::4/128"}
+NETWORK4_2 = {"ipv4": "40.40.40.40/32", "ipv6": "40:40::40/128"}
+NETWORK4_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"}
+NETWORK4_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"}
+
+NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"}
+LOOPBACK_1 = {"ipv4": "10.0.0.7/24", "ipv6": "fd00:0:0:1::7/64",
+ "ipv4_mask": "255.255.255.0", "ipv6_mask": None}
+LOOPBACK_2 = {"ipv4": "10.0.0.16/24", "ipv6": "fd00:0:0:3::5/64",
+ "ipv4_mask": "255.255.255.0", "ipv6_mask": None}
+PREFERRED_NEXT_HOP = "global"
+
+
+class CreateTopo(Topo):
+ """
+ Test BasicTopo - topology 1
+
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function"""
+ tgen = get_topogen(self)
+
+ # Building topology from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ global topo
+ testsuite_run_time = time.asctime(time.localtime(time.time()))
+ logger.info("Testsuite start time: {}".format(testsuite_run_time))
+ logger.info("=" * 40)
+
+ logger.info("Running setup_module to create topology")
+
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(CreateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Run these tests for kernel version 4.19 or above
+ if version_cmp(platform.release(), '4.19') < 0:
+ error_msg = ('BGP vrf dynamic route leak tests will not run '
+ '(have kernel "{}", but it requires >= 4.19)'.\
+ format(platform.release()))
+ pytest.skip(error_msg)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ global BGP_CONVERGENCE
+ global ADDR_TYPES
+ ADDR_TYPES = check_address_types()
+
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \
+ format(BGP_CONVERGENCE)
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """Teardown the pytest environment"""
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info("Testsuite end time: {}".
+ format(time.asctime(time.localtime(time.time()))))
+ logger.info("=" * 40)
+
+#####################################################
+#
+# Local APIs
+#
+#####################################################
+
+def disable_route_map_to_prefer_global_next_hop(tgen, topo):
+ """
+ This API is to remove prefer global route-map applied on neighbors
+
+ Parameter:
+ ----------
+ * `tgen` : Topogen object
+ * `topo` : Input JSON data
+
+ Returns:
+ --------
+ True/errormsg
+
+ """
+
+ logger.info("Remove prefer-global rmap applied on neighbors")
+ input_dict = {
+ "r1": {
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "r2": {
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "vrf": "ISR",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r2-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "100",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r4": {
+ "dest_link": {
+ "r2-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "r3": {
+ "bgp":
+ [
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r3-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "300",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r3-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ },
+ "r4": {
+ "bgp":
+ [
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "local_as": "400",
+ "address_family": {
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r4-link1": {
+ "route_maps": [{
+ "name": "rmap_global",
+ "direction": "in",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ return True
+
+
+#####################################################
+#
+# Testcases
+#
+#####################################################
+
+def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
+ """
+ TC5_FUNC_5:
+ 1.5.5. Verify that dynamically imported routes are further advertised
+ to iBGP peers(peer in cluster).
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Redistribute configured static routes into BGP process"
+ " on R1 and R3/R4")
+
+ input_dict_1={}
+ DUT = ["r1", "r3", "r4"]
+ VRFS = ["default", "default", "default"]
+ AS_NUM = [100, 300, 400]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static"
+ }]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that R1 receives BGP routes from R3 and R4 in "
+ "vrf default.")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_1[addr_type], \
+ NETWORK3_2[addr_type], \
+ NETWORK3_3[addr_type], \
+ NETWORK3_4[addr_type]
+ ]
+ }]
+ }
+ }
+
+ input_routes_r4 = {
+ "r4": {
+ "static_routes": [{
+ "network": [
+ NETWORK4_1[addr_type], \
+ NETWORK4_2[addr_type], \
+ NETWORK4_3[addr_type], \
+ NETWORK4_4[addr_type]
+ ]
+ }]
+ }
+ }
+
+ DUT = ["r1", "r2"]
+ INPUT_DICT = [input_routes_r3, input_routes_r4]
+
+ for dut, routes in zip(DUT, INPUT_DICT):
+ result = verify_bgp_rib(tgen, addr_type, dut, routes)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ result = verify_fib_routes(tgen, addr_type, dut, routes)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Import from default vrf into vrf ISR on R1")
+
+ input_dict_isr={}
+ DUT = ["r1", "r2"]
+ VRFS = ["ISR", "ISR"]
+ AS_NUM = [100, 100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "default"
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that default vrf's imported routes are installed "
+ "in RIB/FIB of vrf ISR on R1:")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_1[addr_type], \
+ NETWORK3_2[addr_type], \
+ NETWORK3_3[addr_type], \
+ NETWORK3_4[addr_type]
+ ],
+ "vrf": "ISR"
+ }]
+ }
+ }
+
+ input_routes_r4 = {
+ "r4": {
+ "static_routes": [{
+ "network": [
+ NETWORK4_1[addr_type], \
+ NETWORK4_2[addr_type], \
+ NETWORK4_3[addr_type], \
+ NETWORK4_4[addr_type]
+ ],
+ "vrf": "ISR"
+ }]
+ }
+ }
+
+ INPUT_DICT_VRF = [input_routes_r3, input_routes_r4]
+
+ for routes in INPUT_DICT_VRF:
+ result = verify_bgp_rib(tgen, addr_type, "r1", routes)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ result = verify_fib_routes(tgen, addr_type, "r1", routes)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ intf_r2_r1 = topo["routers"]["r2"]["links"]["r1-link1"]
+ for addr_type in ADDR_TYPES:
+
+ step("Create a loopback10 interface on R1 with below IP address and "
+ "associate with vrf ISR:")
+
+ create_interface_in_kernel(tgen, "r1", "loopback2",
+ LOOPBACK_2[addr_type],
+ "ISR",
+ LOOPBACK_2["{}_mask".\
+ format(addr_type)])
+
+ for addr_type in ADDR_TYPES:
+
+ step("On router R1 Change the next-hop of static routes in vrf "
+ "ISR to LOOPBACK_1")
+
+ input_routes_r1= {
+ "r1": {
+ "static_routes":[
+ {
+ "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
+ "next_hop":"Null0",
+ "delete": True
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_routes_r1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ input_routes_r1= {
+ "r1": {
+ "static_routes":[
+ {
+ "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
+ "next_hop": (intf_r2_r1[addr_type]).split("/")[0]
+ }
+ ]
+ }
+ }
+
+ result = create_static_routes(tgen, input_routes_r1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that, though R1 originating BGP routes with next-hop"
+ " 24.1.1.2/24::1:2, which is local to R2(but in default vrf)"
+ ", R2 must receives and install all routes from R1 in vrf ISR.")
+ step("Verify on R2, that it now rejects 10.10.10.x routes originated "
+ "from R1. As next-hop IP is local to R2's vrf ISR.")
+
+ input_routes_r1= {
+ "r1": {
+ "static_routes":[
+ {
+ "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
+ "vrf": "ISR"
+ }
+ ]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Routes are still present \n Error {}". \
+ format(tc_name, result))
+
+ write_test_footer(tc_name)
+
+
+def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
+ """
+ TC7_FUNC_7:
+ 1.5.7. Verify matching a prefix based on community attribute and
+ importing it by stripping off this value
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure route-map to set community attribute for a specific"
+ "prefix on R1 in vrf ISR")
+
+ input_dict_pf = {
+ "r1": {
+ "prefix_lists": {
+ addr_type: {
+ "pflist_ABC_{}".format(addr_type): [{
+ "seqid": 10,
+ "network": NETWORK1_1[addr_type],
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_cl = {
+ "r1": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "COMM",
+ "value": "100:100"
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_XYZ_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pflist_ABC_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "community": {"num": "100:100"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply this route-map on R1 to vrf ISR while redistributing the"
+ " prefixes into BGP")
+
+ input_dict_1={}
+ DUT = ["r1"]
+ VRFS = ["ISR"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static",
+ "attribute": {
+ "route-map" : "rmap_XYZ_{}".\
+ format(addr_type)
+ }
+ }
+ ]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure another route-map for filtering the prefixes based on"
+ " community attribute while importing into default vrf")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "community": {"num": "none"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply the route-map while Importing vrf ISR's prefixes into "
+ "default vrf on router R1:")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify on R1 that only prefixes with community value 100:100"
+ "in vrf ISR are imported to vrf default. While importing, the"
+ " community value has been stripped off:")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ input_dict_comm = {
+ "community": "100:100"
+ }
+
+ result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
+ input_dict_comm, expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error: Commnunity is not stipped off, {}".format(
+ tc_name, result))
+
+ for addr_type in ADDR_TYPES:
+
+ step("Remove/re-add route-map XYZ from redistribution.")
+
+ input_dict_1={}
+ DUT = ["r1"]
+ VRFS = ["ISR"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static",
+ "attribute": {
+ "route-map" : "rmap_XYZ_{}".\
+ format(addr_type)
+ },
+ "delete": True
+ }]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that all the routes disappear from vrf default when "
+ "route-map is removed from redistribution, and appear again "
+ "when route-map is re-added to redistribution in vrf ISR.")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ for addr_type in ADDR_TYPES:
+
+ input_dict_1={}
+ DUT = ["r1"]
+ VRFS = ["ISR"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static",
+ "attribute": {
+ "route-map" : "rmap_XYZ_{}".\
+ format(addr_type)
+ }
+ }]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Remove/re-add route-map IMP form import statement.")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type),
+ "delete": True
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that when route-map IMP is removed all the prefixes of"
+ " vrf ISR are imported to vrf default. However when route-map "
+ "IMP is re-added only 11.11.11.1 and 11:11::1 (with community "
+ "value) are imported.")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Delete/Re-add prefix-list ABC.")
+
+ input_dict_pf = {
+ "r1": {
+ "prefix_lists": {
+ addr_type: {
+ "pflist_ABC_{}".format(addr_type): [{
+ "seqid": 10,
+ "network": NETWORK1_1[addr_type],
+ "action": "permit",
+ "delete": True
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ input_dict_pf["r1"]["prefix_lists"][addr_type]["pflist_ABC_{}".\
+ format(addr_type)][0]["delete"]=False
+
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ step("Delete/Re-add community-list COMM.")
+
+ input_dict_cl = {
+ "r1": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "COMM",
+ "value": "100:100",
+ "delete": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ input_dict_cl["r1"]["bgp_community_lists"][0]["delete"]=False
+
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ step("Delete/Re-add route-map XYZ.")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_XYZ_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pflist_ABC_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "community": {"num": "100:100"}
+ },
+ "delete": True
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ input_dict_rm["r1"]["route_maps"]["rmap_XYZ_{}".format(addr_type)][0]["delete"]=False
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ step("Delete/Re-add route-map IMP.")
+
+ input_dict_rm2 = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "community": {"num": "none"}
+ },
+ "delete": True
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ input_dict_rm2["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0]["delete"]=False
+
+ result = create_route_maps(tgen, input_dict_rm2)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_routemap_operatons_with_dynamic_import_p0(request):
+ """
+ TC8_FUNC_8:
+ 1.5.8. Verify the route-map operation along with dynamic import command.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure route-map to set community attribute for a specific"
+ "prefix on R1 in vrf ISR")
+
+ input_dict_pf = {
+ "r1": {
+ "prefix_lists": {
+ addr_type: {
+ "pflist_ABC_{}".format(addr_type): [{
+ "seqid": 10,
+ "network": NETWORK1_1[addr_type],
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_cl = {
+ "r1": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "COMM",
+ "value": "100:100"
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_XYZ_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pflist_ABC_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "community": {"num": "100:100"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply this route-map on R1 to vrf ISR while redistributing the"
+ " prefixes into BGP")
+
+ input_dict_1={}
+ DUT = ["r1"]
+ VRFS = ["ISR"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static",
+ "attribute": {
+ "route-map" : "rmap_XYZ_{}".\
+ format(addr_type)
+ }
+ }
+ ]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure another route-map for filtering the prefixes based on"
+ " community attribute while importing into default vrf")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "community": {"num": "500:500"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply the route-map while Importing vrf ISR's prefixes into "
+ "default vrf on router R1:")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify on R1 that only prefixes with community value 100:100"
+ "in vrf ISR are imported to vrf default. While importing, the"
+ " community value has been stripped off:")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Applying route-map first followed by import VRF command.")
+ step("Apply the route-map while Importing vrf ISR's prefixes into "
+ "default vrf on router R1:")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR",
+ "delete": True
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that until 'import VRF command' is not configured, "
+ "routes are not imported. After configuring 'import VRF command'"
+ " repeat step-4 for verification")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still present \n {}".\
+ format(tc_name, result))
+
+ for addr_type in ADDR_TYPES:
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Delete/re-add import vrf ISR command multiple times in default"
+ "vrf.")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR",
+ "delete": True
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ step("Verify that when import vrf ISR command is deleted, "
+ "all routes of vrf ISR disappear from default vrf and "
+ "when it's re-configured, repeat step-4 for verification.")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Routes are still present, Error {}". \
+ format(tc_name, result))
+
+ input_dict_isr["r1"]["bgp"][0]["address_family"][addr_type]["unicast"][
+ "import"]["delete"]=False
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, (
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result))
+
+ for addr_type in ADDR_TYPES:
+
+ step("Delete and re-configure route-map IMP from global config when "
+ "import and route-maps are applied in a ISR vrf.")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "community": {"num": "500:500"}
+ },
+ "delete": True
+ }]
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Routes are still present, Error {}". \
+ format(tc_name, result))
+
+ input_dict_rm["r1"]["route_maps"]["rmap_IMP_{}".\
+ format(addr_type)][0]["delete"]=False
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ input_dict_comm = {
+ "community": "500:500"
+ }
+
+ result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
+ input_dict_comm)
+ assert result is True, (
+ "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result))
+
+ write_test_footer(tc_name)
+
+
+def test_verify_cli_json_p1(request):
+ """
+ TC8_FUNC_9:
+ 1.5.9. Verifying the JSON outputs for all supported commands:
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ input_dict = {
+ "r1":{
+ "cli": ["show bgp vrf default ipv4 summary",
+ "show bgp vrf all ipv6 summary",
+ "show bgp neighbors"
+ ]
+ }
+ }
+
+ result = verify_cli_json(tgen, input_dict)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
new file mode 100755
index 0000000000..6c106060b8
--- /dev/null
+++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
@@ -0,0 +1,962 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2020 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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 VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
+#
+
+"""
+Following tests are covered to test BGP Multi-VRF Dynamic Route Leaking:
+
+1. Verify that Changing route-map configurations(match/set clauses) on
+ the fly it takes immediate effect.
+2. Verify BGP best path selection algorithm works fine when
+ routes are imported from ISR to default vrf and vice versa.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import platform
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, '../'))
+sys.path.append(os.path.join(CWD, '../lib/'))
+
+# Required to instantiate the topology builder class.
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib.topogen import Topogen, get_topogen
+from lib.topotest import version_cmp
+from mininet.topo import Topo
+
+from lib.common_config import (
+ start_topology, write_test_header, check_address_types,
+ write_test_footer,
+ verify_rib, step, create_route_maps,
+ create_static_routes, stop_router, start_router,
+ create_prefix_lists,
+ create_bgp_community_lists,
+ check_router_status,
+ get_frr_ipv6_linklocal,
+ shutdown_bringup_interface
+)
+
+from lib.topolog import logger
+from lib.bgp import (
+ verify_bgp_convergence, create_router_bgp,
+ verify_bgp_community, verify_bgp_attributes,
+ verify_best_path_as_per_bgp_attribute, verify_bgp_rib
+)
+from lib.topojson import build_topo_from_json, build_config_from_json
+
+# Reading the data from JSON File for topology creation
+jsonFile = "{}/bgp_vrf_dynamic_route_leak_topo2.json".format(CWD)
+try:
+ with open(jsonFile, "r") as topoJson:
+ topo = json.load(topoJson)
+except IOError:
+ assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+NETWORK1_1 = {"ipv4": "11.11.11.1/32", "ipv6": "11:11::1/128"}
+NETWORK3_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"}
+NETWORK3_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"}
+
+PREFERRED_NEXT_HOP = "global"
+
+
+class CreateTopo(Topo):
+ """
+ Test BasicTopo - topology 1
+
+ * `Topo`: Topology object
+ """
+
+ def build(self, *_args, **_opts):
+ """Build function"""
+ tgen = get_topogen(self)
+
+ # Building topology from json file
+ build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+ """
+ Sets up the pytest environment
+
+ * `mod`: module name
+ """
+
+ global topo
+ testsuite_run_time = time.asctime(time.localtime(time.time()))
+ logger.info("Testsuite start time: {}".format(testsuite_run_time))
+ logger.info("=" * 40)
+
+ logger.info("Running setup_module to create topology")
+
+ # This function initiates the topology build with Topogen...
+ tgen = Topogen(CreateTopo, mod.__name__)
+ # ... and here it calls Mininet initialization functions.
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Run these tests for kernel version 4.19 or above
+ if version_cmp(platform.release(), '4.19') < 0:
+ error_msg = ('BGP vrf dynamic route leak tests will not run '
+ '(have kernel "{}", but it requires >= 4.19)'.\
+ format(platform.release()))
+ pytest.skip(error_msg)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ global BGP_CONVERGENCE
+ global ADDR_TYPES
+ ADDR_TYPES = check_address_types()
+
+ BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+ assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \
+ format(BGP_CONVERGENCE)
+
+ logger.info("Running setup_module() done")
+
+
+def teardown_module():
+ """Teardown the pytest environment"""
+
+ logger.info("Running teardown_module to delete topology")
+
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ tgen.stop_topology()
+
+ logger.info("Testsuite end time: {}".
+ format(time.asctime(time.localtime(time.time()))))
+ logger.info("=" * 40)
+
+
+#####################################################
+#
+# Testcases
+#
+#####################################################
+
+def test_bgp_best_path_with_dynamic_import_p0(request):
+ """
+ TC6_FUNC_6:
+ 1.5.6. Verify BGP best path selection algorithm works fine when
+ routes are imported from ISR to default vrf and vice versa.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Redistribute configured static routes into BGP process"
+ " on R1/R2 and R3")
+
+ input_dict_1={}
+ DUT = ["r1", "r2", "r3", "r4"]
+ VRFS = ["ISR", "ISR", "default", "default"]
+ AS_NUM = [100, 100, 300, 400]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static"
+ }]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Import from default vrf into vrf ISR on R1 and R2 as below")
+
+ input_dict_vrf={}
+ DUT = ["r1", "r2"]
+ VRFS = ["ISR", "ISR"]
+ AS_NUM = [100, 100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_vrf.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "default"
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_vrf)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ input_dict_default={}
+ DUT = ["r1", "r2"]
+ VRFS = ["default", "default"]
+ AS_NUM = [100, 100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_default.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_default)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ step("Verify ECMP/Next-hop/Imported routes Vs Locally originated "
+ "routes/eBGP routes vs iBGP routes --already covered in almost"
+ " all tests")
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify Pre-emption")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type]
+ ]
+ }]
+ }
+ }
+
+ intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
+ intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]
+
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
+ nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
+ else:
+ nh_r3_r1 = topo["routers"]["r3"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+ nh_r4_r1 = topo["routers"]["r4"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
+ next_hop=[nh_r4_r1])
+ assert result is True, (
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result))
+
+ step("Shutdown interface connected to r1 from r4:")
+ shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, False)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type]
+ ]
+ }]
+ }
+ }
+
+ intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
+ intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]
+
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
+ nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
+ else:
+ nh_r3_r1 = topo["routers"]["r3"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+ nh_r4_r1 = topo["routers"]["r4"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+
+ step("Verify next-hop is changed")
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
+ next_hop=[nh_r3_r1])
+ assert result is True, (
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result))
+
+ step("Bringup interface connected to r1 from r4:")
+ shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, True)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type]
+ ]
+ }]
+ }
+ }
+
+ intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
+ intf_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"]["interface"]
+
+ if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
+ nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
+ nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
+ else:
+ nh_r3_r1 = topo["routers"]["r3"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+ nh_r4_r1 = topo["routers"]["r4"]["links"]\
+ ["r1-link1"][addr_type].split("/")[0]
+
+ step("Verify next-hop is not chnaged aftr shutdown:")
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
+ next_hop=[nh_r3_r1])
+ assert result is True, (
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result))
+
+ step("Active-Standby scenario(as-path prepend and Local pref)")
+
+ for addr_type in ADDR_TYPES:
+
+ step("Create prefix-list")
+
+ input_dict_pf = {
+ "r1": {
+ "prefix_lists": {
+ addr_type: {
+ "pf_ls_{}".format(addr_type): [{
+ "seqid": 10,
+ "network": NETWORK3_4[addr_type],
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Create route-map to match prefix-list and set localpref 500")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_PATH1_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 10,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_ls_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "locPrf": 500
+ }
+ }]
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ step("Create route-map to match prefix-list and set localpref 600")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_PATH2_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 20,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_ls_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "locPrf": 600
+ }
+ }]
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ input_dict_rma={
+ "r1": {
+ "bgp":
+ [
+ {
+ "local_as": "100",
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [{
+ "name": "rmap_PATH1_{}".\
+ format(addr_type),
+ "direction": "in"
+ }]
+ }
+ }
+ },
+ "r4": {
+ "dest_link": {
+ "r1-link1": {
+ "route_maps": [{
+ "name": "rmap_PATH2_{}".\
+ format(addr_type),
+ "direction": "in"
+ }]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ]}
+ }
+
+ result = create_router_bgp(tgen, topo, input_dict_rma)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ dut = "r1"
+ attribute = "locPrf"
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify bestpath is installed as per highest localpref")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type], \
+ NETWORK3_4[addr_type]
+ ]
+ }]
+ }
+ }
+
+ result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
+ input_routes_r3,
+ attribute)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Create route-map to match prefix-list and set localpref 700")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_PATH1_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 10,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_ls_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "locPrf": 700
+ }
+ }]
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify bestpath is changed as per highest localpref")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type], \
+ NETWORK3_4[addr_type]
+ ]
+ }]
+ }
+ }
+
+ result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
+ input_routes_r3,
+ attribute)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Create route-map to match prefix-list and set as-path prepend")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_PATH2_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 20,
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pf_ls_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "localpref": 700,
+ "path": {
+ "as_num": "111",
+ "as_action": "prepend"
+ }
+ }
+ }]
+ }
+ }
+ }
+
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ attribute = "path"
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify bestpath is changed as per shortest as-path")
+
+ input_routes_r3 = {
+ "r3": {
+ "static_routes": [{
+ "network": [
+ NETWORK3_3[addr_type], \
+ NETWORK3_4[addr_type]
+ ]
+ }]
+ }
+ }
+
+ result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
+ input_routes_r3,
+ attribute)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ write_test_footer(tc_name)
+
+
+def test_modify_route_map_match_set_clauses_p1(request):
+ """
+ TC13_CHAOS_4:
+ 1.5.13. Verify that Changing route-map configurations(match/set clauses) on
+ the fly it takes immediate effect.
+ """
+
+ tgen = get_topogen()
+ tc_name = request.node.name
+ write_test_header(tc_name)
+ build_config_from_json(tgen, topo)
+
+ if tgen.routers_have_failure():
+ check_router_status(tgen)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure route-map to set community attribute for a specific"
+ "prefix on R1 in vrf ISR")
+
+ input_dict_pf = {
+ "r1": {
+ "prefix_lists": {
+ addr_type: {
+ "pflist_ABC_{}".format(addr_type): [{
+ "seqid": 10,
+ "network": NETWORK1_1[addr_type],
+ "action": "permit"
+ }]
+ }
+ }
+ }
+ }
+ result = create_prefix_lists(tgen, input_dict_pf)
+ assert result is True, "Testcase {} : Failed \n Error: {}".format(
+ tc_name, result)
+
+ input_dict_cl = {
+ "r1": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "COMM",
+ "value": "100:100"
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_XYZ_{}".format(addr_type): [{
+ "action": "permit",
+ "match": {
+ addr_type: {
+ "prefix_lists":
+ "pflist_ABC_{}".format(addr_type)
+ }
+ },
+ "set": {
+ "community": {"num": "100:100"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply this route-map on R1 to vrf ISR while redistributing the"
+ " prefixes into BGP")
+
+ input_dict_1={}
+ DUT = ["r1"]
+ VRFS = ["ISR"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_1.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "redistribute": [{
+ "redist_type": "static",
+ "attribute": {
+ "route-map" : "rmap_XYZ_{}".\
+ format(addr_type)
+ }
+ }
+ ]
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_1)
+ assert result is True, "Testcase {} :Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Configure another route-map for filtering the prefixes based on"
+ " community attribute while importing into default vrf")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 10,
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "community": {"num": "none"}
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Apply the route-map while Importing vrf ISR's prefixes into "
+ "default vrf on router R1:")
+
+ input_dict_isr={}
+ DUT = ["r1"]
+ VRFS = ["default"]
+ AS_NUM = [100]
+
+ for dut, vrf, as_num in zip(DUT, VRFS, AS_NUM):
+ temp = {dut: {"bgp": []}}
+ input_dict_isr.update(temp)
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "ISR"
+ }
+ }
+ }
+ }
+ })
+
+ temp[dut]["bgp"].append(
+ {
+ "local_as": as_num,
+ "vrf": vrf,
+ "address_family": {
+ addr_type: {
+ "unicast": {
+ "import": {
+ "vrf": "route-map rmap_IMP_{}".format(addr_type)
+ }
+ }
+ }
+ }
+ })
+
+ result = create_router_bgp(tgen, topo, input_dict_isr)
+ assert result is True, "Testcase {} : Failed \n Error: {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify on R1 that only prefixes with community value 100:100"
+ "in vrf ISR are imported to vrf default. While importing, the"
+ " community value has been stripped off:")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
+ assert result is True, \
+ "Testcase {} : Failed \n Error {}". \
+ format(tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Add set clause in route-map IMP:")
+
+ input_dict_rm = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [{
+ "action": "permit",
+ "seq_id": 10,
+ "match": {
+ "community_list": {"id": "COMM"}
+ },
+ "set": {
+ "large_community": {"num": "100:100:100"},
+ "locPrf": 500,
+ "path": {
+ "as_num": "100 100",
+ "as_action": "prepend"
+ }
+ }
+ }]
+ }
+ }
+ }
+ result = create_route_maps(tgen, input_dict_rm)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ step("Verify that as we continue adding different attributes "
+ "step-by-step in route-map IMP those attributes gets "
+ "attached to prefixes:")
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ input_dict_comm = {
+ "largeCommunity": "100:100:100"
+ }
+
+ result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
+ input_dict_comm)
+ assert result is True, (
+ "Testcase {} : Failed \n Error {}".format(
+ tc_name, result))
+
+ input_rmap = {
+ "r1": {
+ "route_maps": {
+ "rmap_IMP_{}".format(addr_type): [
+ {
+ "set": {
+ "locPrf": 500
+ }
+ }
+ ]
+ }
+ }
+ }
+
+ result = verify_bgp_attributes(tgen, addr_type, "r1",\
+ [NETWORK1_1[addr_type]],
+ rmap_name="rmap_IMP_{}".format(addr_type),\
+ input_dict=input_rmap)
+ assert result is True, "Testcase : Failed \n Error: {}".format(
+ tc_name, result)
+
+ step("Change community-list to match a different value then "
+ "100:100.")
+
+ input_dict_cl = {
+ "r1": {
+ "bgp_community_lists": [
+ {
+ "community_type": "expanded",
+ "action": "permit",
+ "name": "COMM",
+ "value": "100:100",
+ "delete": True
+ }
+ ]
+ }
+ }
+ result = create_bgp_community_lists(tgen, input_dict_cl)
+ assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
+ tc_name, result)
+
+ for addr_type in ADDR_TYPES:
+
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": [
+ NETWORK1_1[addr_type]
+ ],
+ "vrf": "default"
+ }]
+ }
+ }
+
+ result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
+ expected=False)
+ assert result is not True, (
+ "Testcase {} : Failed \n Error : Routes are still "
+ "present {}".\
+ format(tc_name, result))
+
+ write_test_footer(tc_name)
+
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf
index 002cecd1fa..0033bc2a7a 100644
--- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf
+++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 101 vrf r1-cust1
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r1-eth0 interface peer-group r2g
+ neighbor r1-eth0 timers 3 10
address-family ipv4 unicast
redistribute connected
exit-address-family
diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf
index 0878b9b995..183157eb46 100644
--- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf
+++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf
@@ -5,6 +5,7 @@ router bgp 102 vrf r2-cust1
neighbor r2g remote-as external
neighbor r2g bfd
neighbor r2-eth0 interface peer-group r2g
+ neighbor r2-eth0 timers 3 10
!
address-family ipv4 unicast
redistribute connected
diff --git a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf
index dabf9521ac..cfe3f2e2b5 100644
--- a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf
+++ b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf
@@ -4,6 +4,7 @@ router bgp 100 vrf r1-cust1
bgp bestpath as-path multipath-relax
no bgp ebgp-requires-policy
neighbor 10.0.1.101 remote-as 99
+ neighbor 10.0.1.101 timers 3 10
!
!
diff --git a/tests/topotests/evpn-pim-1/leaf1/bgpd.conf b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf
index 4dedfecd61..97fd8662f4 100644
--- a/tests/topotests/evpn-pim-1/leaf1/bgpd.conf
+++ b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65002
no bgp ebgp-requires-policy
neighbor 192.168.1.1 remote-as external
+ neighbor 192.168.1.1 timers 3 10
redistribute connected
address-family l2vpn evpn
neighbor 192.168.1.1 activate
diff --git a/tests/topotests/evpn-pim-1/leaf2/bgpd.conf b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf
index 5bc708240d..91d9bd8c8b 100644
--- a/tests/topotests/evpn-pim-1/leaf2/bgpd.conf
+++ b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf
@@ -2,6 +2,7 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 192.168.2.1 remote-as external
+ neighbor 192.168.2.1 timers 3 10
redistribute connected
address-family l2vpn evpn
neighbor 192.168.2.1 activate
diff --git a/tests/topotests/evpn-pim-1/spine/bgpd.conf b/tests/topotests/evpn-pim-1/spine/bgpd.conf
index 16c17b29cc..81ab802f35 100644
--- a/tests/topotests/evpn-pim-1/spine/bgpd.conf
+++ b/tests/topotests/evpn-pim-1/spine/bgpd.conf
@@ -2,7 +2,9 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 192.168.1.2 remote-as external
+ neighbor 192.168.1.2 timers 3 10
neighbor 192.168.2.3 remote-as external
+ neighbor 192.168.2.3 timers 3 10
redistribute connected
address-family l2vpn evpn
neighbor 192.168.1.2 activate
diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
index 941593e51f..e913105e43 100755
--- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
+++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
@@ -62,7 +62,6 @@ from lib.common_config import (
verify_rib,
step,
start_router_daemons,
- kill_router_daemons,
create_static_routes,
create_vrf_cfg,
create_route_maps,
diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
index 8892d13eff..9e385823fc 100755
--- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
+++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
@@ -68,7 +68,6 @@ from lib.common_config import (
create_route_maps,
verify_cli_json,
start_router_daemons,
- kill_router_daemons,
create_static_routes,
stop_router,
start_router,
diff --git a/tests/topotests/isis-topo1-vrf/__init__.py b/tests/topotests/isis-topo1-vrf/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/__init__.py
diff --git a/tests/topotests/isis-topo1-vrf/r1/isisd.conf b/tests/topotests/isis-topo1-vrf/r1/isisd.conf
new file mode 100755
index 0000000000..4ac4597015
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/isisd.conf
@@ -0,0 +1,15 @@
+hostname r1
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+interface r1-eth0
+ ip router isis 1 vrf r1-cust1
+ ipv6 router isis 1 vrf r1-cust1
+ isis circuit-type level-2-only
+!
+router isis 1 vrf r1-cust1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
+ metric-style wide
+ redistribute ipv4 connected level-2
+ redistribute ipv6 connected level-2
+!
diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route.json b/tests/topotests/isis-topo1-vrf/r1/r1_route.json
new file mode 100644
index 0000000000..790808f2cd
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/r1_route.json
@@ -0,0 +1,57 @@
+{
+ "10.0.10.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r1-eth0",
+ "ip": "10.0.20.1"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r1-cust1"
+ }
+ ],
+ "10.0.20.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 2,
+ "interfaceName": "r1-eth0",
+ "ip": "10.0.20.1"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "isis",
+ "vrfId": 3,
+ "vrfName": "r1-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r1-eth0"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r1-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route6.json b/tests/topotests/isis-topo1-vrf/r1/r1_route6.json
new file mode 100644
index 0000000000..332cbb3290
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/r1_route6.json
@@ -0,0 +1,40 @@
+{
+ "2001:db8:1:1::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r1-eth0"
+ }
+ ],
+ "prefix": "2001:db8:1:1::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r1-cust1"
+ }
+ ],
+ "2001:db8:2:1::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r1-eth0"
+ }
+ ],
+ "prefix": "2001:db8:2:1::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r1-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json b/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json
new file mode 100755
index 0000000000..d1ace402ba
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/r1_route6_linux.json
@@ -0,0 +1,14 @@
+{
+ "2001:db8:1:1::/64": {
+ "dev": "r1-eth0",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:2:1::/64": {
+ "dev": "r1-eth0",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json b/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json
new file mode 100755
index 0000000000..6af22297e9
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/r1_route_linux.json
@@ -0,0 +1,13 @@
+{
+ "10.0.10.0/24": {
+ "dev": "r1-eth0",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.20.1"
+ },
+ "10.0.20.0/24": {
+ "dev": "r1-eth0",
+ "proto": "kernel",
+ "scope": "link"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r1/r1_topology.json b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json
new file mode 100644
index 0000000000..8e3cdc7bd6
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/r1_topology.json
@@ -0,0 +1,80 @@
+{
+ "1": {
+ "level-1": {
+ "ipv4": [
+ {
+ "vertex": "r1"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r1"
+ }
+ ]
+ },
+ "level-2": {
+ "ipv4": [
+ {
+ "vertex": "r1"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ },
+ {
+ "interface": "r1-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r1(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ },
+ {
+ "interface": "r3",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r1-eth0",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ },
+ {
+ "interface": "r3",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r1-eth0",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r1"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:1:1::/64"
+ },
+ {
+ "interface": "r1-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r1(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ },
+ {
+ "interface": "r3",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r1-eth0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:1::/64"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r1/zebra.conf b/tests/topotests/isis-topo1-vrf/r1/zebra.conf
new file mode 100755
index 0000000000..fa1c02e5f8
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r1/zebra.conf
@@ -0,0 +1,9 @@
+hostname r1
+interface r1-eth0 vrf r1-cust1
+ ip address 10.0.20.2/24
+ ipv6 address 2001:db8:1:1::2/64
+!
+interface lo
+ ip address 10.254.0.1/32
+ ipv6 address 2001:db8:F::1/128
+!
diff --git a/tests/topotests/isis-topo1-vrf/r2/isisd.conf b/tests/topotests/isis-topo1-vrf/r2/isisd.conf
new file mode 100755
index 0000000000..4c68540265
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/isisd.conf
@@ -0,0 +1,15 @@
+hostname r2
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+interface r2-eth0
+ ip router isis 1 vrf r2-cust1
+ ipv6 router isis 1 vrf r2-cust1
+ isis circuit-type level-2-only
+!
+router isis 1 vrf r2-cust1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
+ metric-style wide
+ redistribute ipv4 connected level-2
+ redistribute ipv6 connected level-2
+!
diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route.json b/tests/topotests/isis-topo1-vrf/r2/r2_route.json
new file mode 100644
index 0000000000..b3ac86d218
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/r2_route.json
@@ -0,0 +1,57 @@
+{
+ "10.0.11.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r2-eth0",
+ "ip": "10.0.21.1"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r2-cust1"
+ }
+ ],
+ "10.0.21.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 2,
+ "interfaceName": "r2-eth0",
+ "ip": "10.0.21.1"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "isis",
+ "vrfId": 3,
+ "vrfName": "r2-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r2-eth0"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r2-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route6.json b/tests/topotests/isis-topo1-vrf/r2/r2_route6.json
new file mode 100644
index 0000000000..c8d11b4922
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/r2_route6.json
@@ -0,0 +1,40 @@
+{
+ "2001:db8:1:2::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r2-eth0"
+ }
+ ],
+ "prefix": "2001:db8:1:2::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r2-cust1"
+ }
+ ],
+ "2001:db8:2:2::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r2-eth0"
+ }
+ ],
+ "prefix": "2001:db8:2:2::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 3,
+ "vrfName": "r2-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json b/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json
new file mode 100755
index 0000000000..27423e1936
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/r2_route6_linux.json
@@ -0,0 +1,14 @@
+{
+ "2001:db8:1:2::/64": {
+ "dev": "r2-eth0",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:2:2::/64": {
+ "dev": "r2-eth0",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json b/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json
new file mode 100755
index 0000000000..744b0780f3
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/r2_route_linux.json
@@ -0,0 +1,13 @@
+{
+ "10.0.11.0/24": {
+ "dev": "r2-eth0",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.21.1"
+ },
+ "10.0.21.0/24": {
+ "dev": "r2-eth0",
+ "proto": "kernel",
+ "scope": "link"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r2/r2_topology.json b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json
new file mode 100644
index 0000000000..72022a8167
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/r2_topology.json
@@ -0,0 +1,80 @@
+{
+ "1": {
+ "level-1": {
+ "ipv4": [
+ {
+ "vertex": "r2"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r2"
+ }
+ ]
+ },
+ "level-2": {
+ "ipv4": [
+ {
+ "vertex": "r2"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ },
+ {
+ "interface": "r2-eth0",
+ "metric": "10",
+ "next-hop": "r4",
+ "parent": "r2(4)",
+ "type": "TE-IS",
+ "vertex": "r4"
+ },
+ {
+ "interface": "r4",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r2-eth0",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ },
+ {
+ "interface": "r4",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r2-eth0",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r2"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:1:2::/64"
+ },
+ {
+ "interface": "r2-eth0",
+ "metric": "10",
+ "next-hop": "r4",
+ "parent": "r2(4)",
+ "type": "TE-IS",
+ "vertex": "r4"
+ },
+ {
+ "interface": "r4",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r2-eth0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:2::/64"
+ }
+ ]
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/topotests/isis-topo1-vrf/r2/zebra.conf b/tests/topotests/isis-topo1-vrf/r2/zebra.conf
new file mode 100755
index 0000000000..a62af1749e
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r2/zebra.conf
@@ -0,0 +1,9 @@
+hostname r2
+interface r2-eth0 vrf r2-cust1
+ ip address 10.0.21.2/24
+ ipv6 address 2001:db8:1:2::2/64
+!
+interface lo
+ ip address 10.254.0.2/32
+ ipv6 address 2001:db8:F::2/128
+!
diff --git a/tests/topotests/isis-topo1-vrf/r3/isisd.conf b/tests/topotests/isis-topo1-vrf/r3/isisd.conf
new file mode 100755
index 0000000000..ca01876690
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/isisd.conf
@@ -0,0 +1,22 @@
+hostname r3
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+interface r3-eth0
+ ip router isis 1 vrf r3-cust1
+ ipv6 router isis 1 vrf r3-cust1
+ isis circuit-type level-2-only
+!
+interface r3-eth1
+ ip router isis 1 vrf r3-cust1
+ ipv6 router isis 1 vrf r3-cust1
+ isis circuit-type level-1
+!
+router isis 1 vrf r3-cust1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
+ metric-style wide
+ redistribute ipv4 connected level-1
+ redistribute ipv4 connected level-2
+ redistribute ipv6 connected level-1
+ redistribute ipv6 connected level-2
+!
diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route.json b/tests/topotests/isis-topo1-vrf/r3/r3_route.json
new file mode 100644
index 0000000000..709d6b9aeb
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/r3_route.json
@@ -0,0 +1,112 @@
+{
+ "10.0.10.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1",
+ "ip": "10.0.10.1"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "10.0.11.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1",
+ "ip": "10.0.10.1"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "10.0.20.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 2,
+ "interfaceName": "r3-eth0",
+ "ip": "10.0.20.2"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r3-eth0"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "10.0.21.0/24": [
+ {
+ "distance": 115,
+ "metric": 30,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1",
+ "ip": "10.0.10.1"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route6.json b/tests/topotests/isis-topo1-vrf/r3/r3_route6.json
new file mode 100644
index 0000000000..3a7c3861fa
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/r3_route6.json
@@ -0,0 +1,78 @@
+{
+ "2001:db8:1:1::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r3-eth0"
+ }
+ ],
+ "prefix": "2001:db8:1:1::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "2001:db8:1:2::/64": [
+ {
+ "distance": 115,
+ "metric": 30,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1"
+ }
+ ],
+ "prefix": "2001:db8:1:2::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "2001:db8:2:1::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1"
+ }
+ ],
+ "prefix": "2001:db8:2:1::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ],
+ "2001:db8:2:2::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r3-eth1"
+ }
+ ],
+ "prefix": "2001:db8:2:2::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r3-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json b/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json
new file mode 100755
index 0000000000..bc527d2e1e
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/r3_route6_linux.json
@@ -0,0 +1,26 @@
+{
+ "2001:db8:1:1::/64": {
+ "dev": "r3-eth0",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:1:2::/64": {
+ "dev": "r3-eth1",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ },
+ "2001:db8:2:1::/64": {
+ "dev": "r3-eth1",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:2:2::/64": {
+ "dev": "r3-eth1",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json b/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json
new file mode 100755
index 0000000000..515d376475
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/r3_route_linux.json
@@ -0,0 +1,24 @@
+{
+ "10.0.10.0/24": {
+ "dev": "r3-eth1",
+ "proto": "kernel",
+ "scope": "link"
+ },
+ "10.0.11.0/24": {
+ "dev": "r3-eth1",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.10.1"
+ },
+ "10.0.20.0/24": {
+ "dev": "r3-eth0",
+ "proto": "kernel",
+ "scope": "link"
+ },
+ "10.0.21.0/24": {
+ "dev": "r3-eth1",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.10.1"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r3/r3_topology.json b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json
new file mode 100644
index 0000000000..62b895766e
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/r3_topology.json
@@ -0,0 +1,132 @@
+{
+ "1": {
+ "level-1": {
+ "ipv4": [
+ {
+ "vertex": "r3"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ },
+ {
+ "interface": "r3-eth1",
+ "metric": "10",
+ "next-hop": "r5",
+ "parent": "r3(4)",
+ "type": "TE-IS",
+ "vertex": "r5"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r3-eth1",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r3-eth1",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "30",
+ "parent": "r3-eth1",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r3"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:1::/64"
+ },
+ {
+ "interface": "r3-eth1",
+ "metric": "10",
+ "next-hop": "r5",
+ "parent": "r3(4)",
+ "type": "TE-IS",
+ "vertex": "r5"
+ },
+ {
+ "interface": "r5",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r3-eth1",
+ "type": "IP6",
+ "vertex": "2001:db8:2:2::/64"
+ },
+ {
+ "interface": "r5",
+ "metric": "internal",
+ "next-hop": "30",
+ "parent": "r3-eth1",
+ "type": "IP6",
+ "vertex": "2001:db8:1:2::/64"
+ }
+ ]
+ },
+ "level-2": {
+ "ipv4": [
+ {
+ "vertex": "r3"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ },
+ {
+ "interface": "r3-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r3(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ },
+ {
+ "interface": "r3",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r3-eth0",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r3"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:1:1::/64"
+ },
+ {
+ "interface": "r3-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r3(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r3/zebra.conf b/tests/topotests/isis-topo1-vrf/r3/zebra.conf
new file mode 100755
index 0000000000..ac0b810fce
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r3/zebra.conf
@@ -0,0 +1,13 @@
+hostname r3
+interface r3-eth0 vrf r3-cust1
+ ip address 10.0.20.1/24
+ ipv6 address 2001:db8:1:1::1/64
+!
+interface r3-eth1 vrf r3-cust1
+ ip address 10.0.10.2/24
+ ipv6 address 2001:db8:2:1::2/64
+!
+interface lo
+ ip address 10.254.0.3/32
+ ipv6 address 2001:db8:F::3/128
+!
diff --git a/tests/topotests/isis-topo1-vrf/r4/isisd.conf b/tests/topotests/isis-topo1-vrf/r4/isisd.conf
new file mode 100755
index 0000000000..74b1603d85
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/isisd.conf
@@ -0,0 +1,25 @@
+hostname r4
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+debug isis lsp-gen
+debug isis lsp-sched
+
+interface r4-eth0
+ ip router isis 1 vrf r4-cust1
+ ipv6 router isis 1 vrf r4-cust1
+ isis circuit-type level-2-only
+!
+interface r4-eth1
+ ip router isis 1 vrf r4-cust1
+ ipv6 router isis 1 vrf r4-cust1
+ isis circuit-type level-1
+!
+router isis 1 vrf r4-cust1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00
+ metric-style wide
+ redistribute ipv4 connected level-1
+ redistribute ipv4 connected level-2
+ redistribute ipv6 connected level-1
+ redistribute ipv6 connected level-2
+!
diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route.json b/tests/topotests/isis-topo1-vrf/r4/r4_route.json
new file mode 100644
index 0000000000..c464607a2b
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/r4_route.json
@@ -0,0 +1,105 @@
+{
+ "10.0.10.0/24": [
+ {
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1",
+ "ip": "10.0.11.1"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "10.0.11.0/24": [
+ {
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1",
+ "ip": "10.0.11.1"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "10.0.20.0/24": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1",
+ "ip": "10.0.11.1"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "10.0.21.0/24": [
+ {
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 2,
+ "interfaceName": "r4-eth0",
+ "ip": "10.0.21.2"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r4-eth0"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route6.json b/tests/topotests/isis-topo1-vrf/r4/r4_route6.json
new file mode 100644
index 0000000000..8d3ea570f0
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/r4_route6.json
@@ -0,0 +1,78 @@
+{
+ "2001:db8:1:1::/64": [
+ {
+ "distance": 115,
+ "metric": 30,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1"
+ }
+ ],
+ "prefix": "2001:db8:1:1::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "2001:db8:1:2::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r4-eth0"
+ }
+ ],
+ "prefix": "2001:db8:1:2::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "2001:db8:2:1::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1"
+ }
+ ],
+ "prefix": "2001:db8:2:1::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ],
+ "2001:db8:2:2::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r4-eth1"
+ }
+ ],
+ "prefix": "2001:db8:2:2::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r4-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json b/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json
new file mode 100755
index 0000000000..b1cd5b9db9
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/r4_route6_linux.json
@@ -0,0 +1,26 @@
+{
+ "2001:db8:1:1::/64": {
+ "dev": "r4-eth1",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ },
+ "2001:db8:1:2::/64": {
+ "dev": "r4-eth0",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:2:1::/64": {
+ "dev": "r4-eth1",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ },
+ "2001:db8:2:2::/64": {
+ "dev": "r4-eth1",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json b/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json
new file mode 100755
index 0000000000..3198b85789
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/r4_route_linux.json
@@ -0,0 +1,24 @@
+{
+ "10.0.10.0/24": {
+ "dev": "r4-eth1",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.11.1"
+ },
+ "10.0.11.0/24": {
+ "dev": "r4-eth1",
+ "proto": "kernel",
+ "scope": "link"
+ },
+ "10.0.20.0/24": {
+ "dev": "r4-eth1",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.11.1"
+ },
+ "10.0.21.0/24": {
+ "dev": "r4-eth0",
+ "proto": "kernel",
+ "scope": "link"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r4/r4_topology.json b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json
new file mode 100644
index 0000000000..0d69550cad
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/r4_topology.json
@@ -0,0 +1,132 @@
+{
+ "1": {
+ "level-1": {
+ "ipv4": [
+ {
+ "vertex": "r4"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ },
+ {
+ "interface": "r4-eth1",
+ "metric": "10",
+ "next-hop": "r5",
+ "parent": "r4(4)",
+ "type": "TE-IS",
+ "vertex": "r5"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r4-eth1",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r4-eth1",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ },
+ {
+ "interface": "r5",
+ "metric": "TE",
+ "next-hop": "30",
+ "parent": "r4-eth1",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r4"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:2::/64"
+ },
+ {
+ "interface": "r4-eth1",
+ "metric": "10",
+ "next-hop": "r5",
+ "parent": "r4(4)",
+ "type": "TE-IS",
+ "vertex": "r5"
+ },
+ {
+ "interface": "r5",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r4-eth1",
+ "type": "IP6",
+ "vertex": "2001:db8:2:1::/64"
+ },
+ {
+ "interface": "r5",
+ "metric": "internal",
+ "next-hop": "30",
+ "parent": "r4-eth1",
+ "type": "IP6",
+ "vertex": "2001:db8:1:1::/64"
+ }
+ ]
+ },
+ "level-2": {
+ "ipv4": [
+ {
+ "vertex": "r4"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ },
+ {
+ "interface": "r4-eth0",
+ "metric": "10",
+ "next-hop": "r2",
+ "parent": "r4(4)",
+ "type": "TE-IS",
+ "vertex": "r2"
+ },
+ {
+ "interface": "r2",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r4-eth0",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r4"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:1:2::/64"
+ },
+ {
+ "interface": "r4-eth0",
+ "metric": "10",
+ "next-hop": "r2",
+ "parent": "r4(4)",
+ "type": "TE-IS",
+ "vertex": "r2"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r4/zebra.conf b/tests/topotests/isis-topo1-vrf/r4/zebra.conf
new file mode 100755
index 0000000000..9c8941f7a5
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r4/zebra.conf
@@ -0,0 +1,13 @@
+hostname r4
+interface r4-eth0 vrf r4-cust1
+ ip address 10.0.21.1/24
+ ipv6 address 2001:db8:1:2::1/64
+!
+interface r4-eth1 vrf r4-cust1
+ ip address 10.0.11.2/24
+ ipv6 address 2001:db8:2:2::2/64
+!
+interface lo
+ ip address 10.254.0.4/32
+ ipv6 address 2001:db8:F::4/128
+!
diff --git a/tests/topotests/isis-topo1-vrf/r5/isisd.conf b/tests/topotests/isis-topo1-vrf/r5/isisd.conf
new file mode 100755
index 0000000000..9e9b030455
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/isisd.conf
@@ -0,0 +1,21 @@
+hostname r5
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+interface r5-eth0
+ ip router isis 1 vrf r5-cust1
+ ipv6 router isis 1 vrf r5-cust1
+ isis circuit-type level-1
+!
+interface r5-eth1
+ ip router isis 1 vrf r5-cust1
+ ipv6 router isis 1 vrf r5-cust1
+ isis circuit-type level-1
+!
+router isis 1 vrf r5-cust1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00
+ metric-style wide
+ is-type level-1
+ redistribute ipv4 connected level-1
+ redistribute ipv6 connected level-1
+!
diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route.json b/tests/topotests/isis-topo1-vrf/r5/r5_route.json
new file mode 100644
index 0000000000..58aee5ddcc
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/r5_route.json
@@ -0,0 +1,106 @@
+{
+ "10.0.10.0/24": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 2,
+ "interfaceName": "r5-eth0",
+ "ip": "10.0.10.2"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r5-eth0"
+ }
+ ],
+ "prefix": "10.0.10.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "10.0.11.0/24": [
+ {
+ "nexthops": [
+ {
+ "afi": "ipv4",
+ "interfaceIndex": 3,
+ "interfaceName": "r5-eth1",
+ "ip": "10.0.11.2"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "isis",
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ },
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r5-eth1"
+ }
+ ],
+ "prefix": "10.0.11.0/24",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "10.0.20.0/24": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r5-eth0",
+ "ip": "10.0.10.2"
+ }
+ ],
+ "prefix": "10.0.20.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "10.0.21.0/24": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv4",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r5-eth1",
+ "ip": "10.0.11.2"
+ }
+ ],
+ "prefix": "10.0.21.0/24",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route6.json b/tests/topotests/isis-topo1-vrf/r5/r5_route6.json
new file mode 100644
index 0000000000..e32bbcc2c1
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/r5_route6.json
@@ -0,0 +1,78 @@
+{
+ "2001:db8:1:1::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r5-eth0"
+ }
+ ],
+ "prefix": "2001:db8:1:1::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "2001:db8:1:2::/64": [
+ {
+ "distance": 115,
+ "metric": 20,
+ "nexthops": [
+ {
+ "active": true,
+ "afi": "ipv6",
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r5-eth1"
+ }
+ ],
+ "prefix": "2001:db8:1:2::/64",
+ "protocol": "isis",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "2001:db8:2:1::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 2,
+ "interfaceName": "r5-eth0"
+ }
+ ],
+ "prefix": "2001:db8:2:1::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ],
+ "2001:db8:2:2::/64": [
+ {
+ "nexthops": [
+ {
+ "active": true,
+ "directlyConnected": true,
+ "fib": true,
+ "interfaceIndex": 3,
+ "interfaceName": "r5-eth1"
+ }
+ ],
+ "prefix": "2001:db8:2:2::/64",
+ "protocol": "connected",
+ "selected": true,
+ "vrfId": 4,
+ "vrfName": "r5-cust1"
+ }
+ ]
+}
diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json b/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json
new file mode 100755
index 0000000000..3db3c93ea6
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/r5_route6_linux.json
@@ -0,0 +1,26 @@
+{
+ "2001:db8:1:1::/64": {
+ "dev": "r5-eth0",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ },
+ "2001:db8:1:2::/64": {
+ "dev": "r5-eth1",
+ "metric": "20",
+ "pref": "medium",
+ "proto": "187"
+ },
+ "2001:db8:2:1::/64": {
+ "dev": "r5-eth0",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ },
+ "2001:db8:2:2::/64": {
+ "dev": "r5-eth1",
+ "metric": "256",
+ "pref": "medium",
+ "proto": "kernel"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json b/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json
new file mode 100755
index 0000000000..6a38ba864a
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/r5_route_linux.json
@@ -0,0 +1,24 @@
+{
+ "10.0.10.0/24": {
+ "dev": "r5-eth0",
+ "proto": "kernel",
+ "scope": "link"
+ },
+ "10.0.11.0/24": {
+ "dev": "r5-eth1",
+ "proto": "kernel",
+ "scope": "link"
+ },
+ "10.0.20.0/24": {
+ "dev": "r5-eth0",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.10.2"
+ },
+ "10.0.21.0/24": {
+ "dev": "r5-eth1",
+ "metric": "20",
+ "proto": "187",
+ "via": "10.0.11.2"
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/r5/r5_topology.json b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json
new file mode 100644
index 0000000000..b4ed6a069d
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/r5_topology.json
@@ -0,0 +1,124 @@
+{
+ "1": {
+ "level-1": {
+ "ipv4": [
+ {
+ "vertex": "r5"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ },
+ {
+ "interface": "r5-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r5(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ },
+ {
+ "interface": "r5-eth1",
+ "metric": "10",
+ "next-hop": "r4",
+ "parent": "r5(4)",
+ "type": "TE-IS",
+ "vertex": "r4"
+ },
+ {
+ "interface": "r3",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r5-eth0",
+ "type": "IP",
+ "vertex": "10.0.20.0/24"
+ },
+ {
+ "interface": "r3",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r5-eth0",
+ "type": "IP",
+ "vertex": "10.0.10.0/24"
+ },
+ {
+ "interface": "r4",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r5-eth1",
+ "type": "IP",
+ "vertex": "10.0.21.0/24"
+ },
+ {
+ "interface": "r4",
+ "metric": "TE",
+ "next-hop": "20",
+ "parent": "r5-eth1",
+ "type": "IP",
+ "vertex": "10.0.11.0/24"
+ }
+ ],
+ "ipv6": [
+ {
+ "vertex": "r5"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:1::/64"
+ },
+ {
+ "metric": "internal",
+ "parent": "0",
+ "type": "IP6",
+ "vertex": "2001:db8:2:2::/64"
+ },
+ {
+ "interface": "r5-eth0",
+ "metric": "10",
+ "next-hop": "r3",
+ "parent": "r5(4)",
+ "type": "TE-IS",
+ "vertex": "r3"
+ },
+ {
+ "interface": "r5-eth1",
+ "metric": "10",
+ "next-hop": "r4",
+ "parent": "r5(4)",
+ "type": "TE-IS",
+ "vertex": "r4"
+ },
+ {
+ "interface": "r3",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r5-eth0",
+ "type": "IP6",
+ "vertex": "2001:db8:1:1::/64"
+ },
+ {
+ "interface": "r4",
+ "metric": "internal",
+ "next-hop": "20",
+ "parent": "r5-eth1",
+ "type": "IP6",
+ "vertex": "2001:db8:1:2::/64"
+ }
+ ]
+ },
+ "level-2": {
+ "ipv4": [],
+ "ipv6": []
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/topotests/isis-topo1-vrf/r5/zebra.conf b/tests/topotests/isis-topo1-vrf/r5/zebra.conf
new file mode 100755
index 0000000000..c6bc6302fc
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/r5/zebra.conf
@@ -0,0 +1,13 @@
+hostname r5
+interface r5-eth0 vrf r5-cust1
+ ip address 10.0.10.1/24
+ ipv6 address 2001:db8:2:1::1/64
+!
+interface r5-eth1 vrf r5-cust1
+ ip address 10.0.11.1/24
+ ipv6 address 2001:db8:2:2::1/64
+!
+interface lo
+ ip address 10.254.0.5/32
+ ipv6 address 2001:db8:F::5/128
+!
diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot
new file mode 100755
index 0000000000..01f9ba780f
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.dot
@@ -0,0 +1,100 @@
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## Switches: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #fcb314 dark yellow
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+##### Colors (see http://www.color-hex.com/)
+
+graph template {
+ label="isis topo1";
+
+ # Routers
+ r1 [
+ shape=doubleoctagon,
+ label="r1\n10.254.0.1\n2001:DB8:F::1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r2 [
+ shape=doubleoctagon
+ label="r2\n10.254.0.2\n2001:DB8:F::2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r3 [
+ shape=doubleoctagon
+ label="r3\n10.254.0.3\n2001:DB8:F::3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r4 [
+ shape=doubleoctagon
+ label="r4\n10.254.0.4\n2001:DB8:F::4",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r5 [
+ shape=doubleoctagon
+ label="r5\n10.254.0.5\n2001:DB8:F::5",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+
+ # Switches
+ sw1 [
+ shape=oval,
+ label="sw1\n10.0.20.0/24\n2001:DB8:1:1::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw2 [
+ shape=oval,
+ label="sw2\n10.0.21.0/24\n2001:DB8:1:2::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw3 [
+ shape=oval,
+ label="sw3\n10.0.10.0/24\n2001:DB8:2:1::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ sw4 [
+ shape=oval,
+ label="sw4\n10.0.11.0/24\n2001:DB8:2:2::/64",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ subgraph cluster0 {
+ label="level 2";
+
+ r1 -- sw1 [label="eth0\n.2"];
+ r2 -- sw2 [label="eth0\n.2"];
+ }
+
+ subgraph cluster1 {
+ label="level 1/2";
+
+ r3 -- sw1 [label="eth0\n.1"];
+ r3 -- sw3 [label="eth1\n.2"];
+
+ r4 -- sw4 [label="eth1\n.2"];
+ r4 -- sw2 [label="eth0\n.1"];
+ }
+
+ subgraph cluster2 {
+ label="level 1";
+
+ r5 -- sw3 [label="eth0\n.1"];
+ r5 -- sw4 [label="eth1\n.1"];
+ }
+}
diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg
new file mode 100755
index 0000000000..4ad730f2a0
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.jpg
Binary files differ
diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py
new file mode 100755
index 0000000000..a0e34b71b0
--- /dev/null
+++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py
@@ -0,0 +1,455 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2020 by Niral Networks, Inc. ("Niral Networks")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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.
+#
+
+"""
+test_isis_topo1_vrf.py: Test ISIS vrf topology.
+"""
+
+import collections
+import functools
+import json
+import os
+import re
+import sys
+import pytest
+import platform
+
+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.topolog import logger
+
+from mininet.topo import Topo
+
+
+class ISISTopo1(Topo):
+ "Simple two layer ISIS vrf topology"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Add ISIS routers:
+ # r1 r2
+ # | sw1 | sw2
+ # r3 r4
+ # | |
+ # sw3 sw4
+ # \ /
+ # r5
+ for routern in range(1, 6):
+ tgen.add_router("r{}".format(routern))
+
+ # r1 <- sw1 -> r3
+ sw = tgen.add_switch("sw1")
+ sw.add_link(tgen.gears["r1"])
+ sw.add_link(tgen.gears["r3"])
+
+ # r2 <- sw2 -> r4
+ sw = tgen.add_switch("sw2")
+ sw.add_link(tgen.gears["r2"])
+ sw.add_link(tgen.gears["r4"])
+
+ # r3 <- sw3 -> r5
+ sw = tgen.add_switch("sw3")
+ sw.add_link(tgen.gears["r3"])
+ sw.add_link(tgen.gears["r5"])
+
+ # r4 <- sw4 -> r5
+ sw = tgen.add_switch("sw4")
+ sw.add_link(tgen.gears["r4"])
+ sw.add_link(tgen.gears["r5"])
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(ISISTopo1, mod.__name__)
+ tgen.start_topology()
+
+ logger.info("Testing with VRF Lite support")
+ krel = platform.release()
+
+ # May need to adjust handling of vrf traffic depending on kernel version
+ l3mdev_accept = 0
+ if (
+ topotest.version_cmp(krel, "4.15") >= 0
+ and topotest.version_cmp(krel, "4.18") <= 0
+ ):
+ l3mdev_accept = 1
+
+ if topotest.version_cmp(krel, "5.0") >= 0:
+ l3mdev_accept = 1
+
+ logger.info(
+ "krel '{0}' setting net.ipv4.tcp_l3mdev_accept={1}".format(krel, l3mdev_accept)
+ )
+
+ cmds = [
+ "ip link add {0}-cust1 type vrf table 1001",
+ "ip link add loop1 type dummy",
+ "ip link set {0}-eth0 master {0}-cust1",
+ "ip link set {0}-eth1 master {0}-cust1",
+ ]
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in tgen.routers().iteritems():
+ # create VRF rx-cust1 and link rx-eth0 to rx-cust1
+ for cmd in cmds:
+ output = tgen.net[rname].cmd(cmd.format(rname))
+ output = tgen.net[rname].cmd("sysctl -n net.ipv4.tcp_l3mdev_accept")
+ logger.info(
+ "router {0}: existing tcp_l3mdev_accept was {1}".format(rname, output)
+ )
+
+ if l3mdev_accept:
+ output = tgen.net[rname].cmd(
+ "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept)
+ )
+
+ for rname, router in tgen.routers().iteritems():
+ 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))
+ )
+ # After loading the configurations, this function loads configured daemons.
+ tgen.start_router()
+
+ has_version_20 = False
+ for router in tgen.routers().values():
+ if router.has_version("<", "4"):
+ has_version_20 = True
+
+ if has_version_20:
+ logger.info("Skipping ISIS vrf tests for FRR 2.0")
+ tgen.set_error("ISIS has convergence problems with IPv6")
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+ # move back rx-eth0 to default VRF
+ # delete rx-vrf
+ tgen.stop_topology()
+
+def test_isis_convergence():
+ "Wait for the protocol to converge before starting to test"
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("waiting for ISIS protocol to converge")
+
+ for rname, router in tgen.routers().iteritems():
+ filename = "{0}/{1}/{1}_topology.json".format(CWD, rname)
+ expected = json.loads(open(filename).read())
+ def compare_isis_topology(router, expected):
+ "Helper function to test ISIS vrf topology convergence."
+ actual = show_isis_topology(router)
+
+ return topotest.json_cmp(actual, expected)
+
+ test_func = functools.partial(compare_isis_topology, router, expected)
+ (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=120)
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+def test_isis_route_installation():
+ "Check whether all expected routes are present"
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Checking routers for installed ISIS vrf routes")
+ # Check for routes in 'show ip route vrf {}-cust1 json'
+ for rname, router in tgen.routers().iteritems():
+ filename = "{0}/{1}/{1}_route.json".format(CWD, rname)
+ expected = json.loads(open(filename, "r").read())
+ actual = router.vtysh_cmd("show ip route vrf {0}-cust1 json".format(rname) , isjson=True)
+ # Older FRR versions don't list interfaces in some ISIS routes
+ if router.has_version("<", "3.1"):
+ for network, routes in expected.iteritems():
+ for route in routes:
+ if route["protocol"] != "isis":
+ continue
+
+ for nexthop in route["nexthops"]:
+ nexthop.pop("interfaceIndex", None)
+ nexthop.pop("interfaceName", None)
+
+ assertmsg = "Router '{}' routes mismatch".format(rname)
+ assert topotest.json_cmp(actual, expected) is None, assertmsg
+
+
+def test_isis_linux_route_installation():
+
+ dist = platform.dist()
+
+ if (dist[1] == "16.04"):
+ pytest.skip("Kernel not supported for vrf")
+
+ "Check whether all expected routes are present and installed in the OS"
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Checking routers for installed ISIS vrf routes in OS")
+ # Check for routes in `ip route show vrf {}-cust1`
+ for rname, router in tgen.routers().iteritems():
+ filename = "{0}/{1}/{1}_route_linux.json".format(CWD, rname)
+ expected = json.loads(open(filename, "r").read())
+ actual = topotest.ip4_vrf_route(router)
+
+ # Older FRR versions install routes using different proto
+ if router.has_version("<", "3.1"):
+ for network, netoptions in expected.iteritems():
+ if "proto" in netoptions and netoptions["proto"] == "187":
+ netoptions["proto"] = "zebra"
+
+ assertmsg = "Router '{}' OS routes mismatch".format(rname)
+ assert topotest.json_cmp(actual, expected) is None, assertmsg
+
+def test_isis_route6_installation():
+ "Check whether all expected routes are present"
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Checking routers for installed ISIS vrf IPv6 routes")
+ # Check for routes in 'show ipv6 route vrf {}-cust1 json'
+ for rname, router in tgen.routers().iteritems():
+ filename = "{0}/{1}/{1}_route6.json".format(CWD, rname)
+ expected = json.loads(open(filename, "r").read())
+ actual = router.vtysh_cmd("show ipv6 route vrf {}-cust1 json".format(rname) , isjson=True)
+
+ # Older FRR versions don't list interfaces in some ISIS routes
+ if router.has_version("<", "3.1"):
+ for network, routes in expected.iteritems():
+ for route in routes:
+ if route["protocol"] != "isis":
+ continue
+
+ for nexthop in route["nexthops"]:
+ nexthop.pop("interfaceIndex", None)
+ nexthop.pop("interfaceName", None)
+
+ assertmsg = "Router '{}' routes mismatch".format(rname)
+ assert topotest.json_cmp(actual, expected) is None, assertmsg
+
+def test_isis_linux_route6_installation():
+
+ dist = platform.dist()
+
+ if (dist[1] == "16.04"):
+ pytest.skip("Kernel not supported for vrf")
+
+ "Check whether all expected routes are present and installed in the OS"
+ tgen = get_topogen()
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ logger.info("Checking routers for installed ISIS vrf IPv6 routes in OS")
+ # Check for routes in `ip -6 route show vrf {}-cust1`
+ for rname, router in tgen.routers().iteritems():
+ filename = "{0}/{1}/{1}_route6_linux.json".format(CWD, rname)
+ expected = json.loads(open(filename, "r").read())
+ actual = topotest.ip6_vrf_route(router)
+
+ # Older FRR versions install routes using different proto
+ if router.has_version("<", "3.1"):
+ for network, netoptions in expected.iteritems():
+ if "proto" in netoptions and netoptions["proto"] == "187":
+ netoptions["proto"] = "zebra"
+
+ assertmsg = "Router '{}' OS routes mismatch".format(rname)
+ assert topotest.json_cmp(actual, expected) is None, assertmsg
+
+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))
+
+
+#
+# Auxiliary functions
+#
+
+
+def dict_merge(dct, merge_dct):
+ """
+ Recursive dict merge. Inspired by :meth:``dict.update()``, instead of
+ updating only top-level keys, dict_merge recurses down into dicts nested
+ to an arbitrary depth, updating keys. The ``merge_dct`` is merged into
+ ``dct``.
+ :param dct: dict onto which the merge is executed
+ :param merge_dct: dct merged into dct
+ :return: None
+
+ Source:
+ https://gist.github.com/angstwad/bf22d1822c38a92ec0a9
+ """
+ for k, v in merge_dct.iteritems():
+ if (
+ k in dct
+ and isinstance(dct[k], dict)
+ and isinstance(merge_dct[k], collections.Mapping)
+ ):
+ dict_merge(dct[k], merge_dct[k])
+ else:
+ dct[k] = merge_dct[k]
+
+
+def parse_topology(lines, level):
+ """
+ Parse the output of 'show isis topology level-X' into a Python dict.
+ """
+ areas = {}
+ area = None
+ ipv = None
+
+ for line in lines:
+ area_match = re.match(r"Area (.+):", line)
+ if area_match:
+ area = area_match.group(1)
+ if area not in areas:
+ areas[area] = {level: {"ipv4": [], "ipv6": []}}
+ ipv = None
+ continue
+ elif area is None:
+ continue
+
+ if re.match(r"IS\-IS paths to level-. routers that speak IPv6", line):
+ ipv = "ipv6"
+ continue
+ if re.match(r"IS\-IS paths to level-. routers that speak IP", line):
+ ipv = "ipv4"
+ continue
+
+ item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line)
+ if item_match is not None:
+ # Skip header
+ if (
+ item_match.group(1) == "Vertex"
+ and item_match.group(2) == "Type"
+ and item_match.group(3) == "Metric"
+ and item_match.group(4) == "Next-Hop"
+ and item_match.group(5) == "Interface"
+ and item_match.group(6) == "Parent"
+ ):
+ continue
+
+ areas[area][level][ipv].append(
+ {
+ "vertex": item_match.group(1),
+ "type": item_match.group(2),
+ "metric": item_match.group(3),
+ "next-hop": item_match.group(4),
+ "interface": item_match.group(5),
+ "parent": item_match.group(6),
+ }
+ )
+ continue
+
+ item_match = re.match(r"([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)", line)
+ if item_match is not None:
+ areas[area][level][ipv].append(
+ {
+ "vertex": item_match.group(1),
+ "type": item_match.group(2),
+ "metric": item_match.group(3),
+ "parent": item_match.group(4),
+ }
+ )
+ continue
+
+ item_match = re.match(r"([^ ]+)", line)
+ if item_match is not None:
+ areas[area][level][ipv].append({"vertex": item_match.group(1)})
+ continue
+
+ return areas
+
+
+def show_isis_topology(router):
+ """
+ Get the ISIS vrf topology in a dictionary format.
+
+ Sample:
+ {
+ 'area-name': {
+ 'level-1': [
+ {
+ 'vertex': 'r1'
+ }
+ ],
+ 'level-2': [
+ {
+ 'vertex': '10.0.0.1/24',
+ 'type': 'IP',
+ 'parent': '0',
+ 'metric': 'internal'
+ }
+ ]
+ },
+ 'area-name-2': {
+ 'level-2': [
+ {
+ "interface": "rX-ethY",
+ "metric": "Z",
+ "next-hop": "rA",
+ "parent": "rC(B)",
+ "type": "TE-IS",
+ "vertex": "rD"
+ }
+ ]
+ }
+ }
+ """
+ l1out = topotest.normalize_text(
+ router.vtysh_cmd("show isis vrf {}-cust1 topology level-1".format(router.name))
+ ).splitlines()
+ l2out = topotest.normalize_text(
+ router.vtysh_cmd("show isis vrf {}-cust1 topology level-2".format(router.name))
+ ).splitlines()
+
+ l1 = parse_topology(l1out, "level-1")
+ l2 = parse_topology(l2out, "level-2")
+
+ dict_merge(l1, l2)
+ return l1
+
diff --git a/tests/topotests/ldp-oc-acl-topo1/r1/ospfd.conf b/tests/topotests/ldp-oc-acl-topo1/r1/ospfd.conf
index 6daf034d18..87d5703d9e 100644
--- a/tests/topotests/ldp-oc-acl-topo1/r1/ospfd.conf
+++ b/tests/topotests/ldp-oc-acl-topo1/r1/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 1.1.1.1
network 0.0.0.0/0 area 0
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-acl-topo1/r2/ospfd.conf b/tests/topotests/ldp-oc-acl-topo1/r2/ospfd.conf
index 8678813665..51317202bb 100644
--- a/tests/topotests/ldp-oc-acl-topo1/r2/ospfd.conf
+++ b/tests/topotests/ldp-oc-acl-topo1/r2/ospfd.conf
@@ -5,3 +5,11 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-acl-topo1/r3/ospfd.conf b/tests/topotests/ldp-oc-acl-topo1/r3/ospfd.conf
index 202be238ec..4566976b7b 100644
--- a/tests/topotests/ldp-oc-acl-topo1/r3/ospfd.conf
+++ b/tests/topotests/ldp-oc-acl-topo1/r3/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
router-id 3.3.3.3
network 0.0.0.0/0 area 0
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-acl-topo1/r4/ospfd.conf b/tests/topotests/ldp-oc-acl-topo1/r4/ospfd.conf
index 569dbc54e2..5aae885a12 100644
--- a/tests/topotests/ldp-oc-acl-topo1/r4/ospfd.conf
+++ b/tests/topotests/ldp-oc-acl-topo1/r4/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 4.4.4.4
network 0.0.0.0/0 area 0
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-topo1/r1/ospfd.conf b/tests/topotests/ldp-oc-topo1/r1/ospfd.conf
index 6daf034d18..87d5703d9e 100644
--- a/tests/topotests/ldp-oc-topo1/r1/ospfd.conf
+++ b/tests/topotests/ldp-oc-topo1/r1/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 1.1.1.1
network 0.0.0.0/0 area 0
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-topo1/r2/ospfd.conf b/tests/topotests/ldp-oc-topo1/r2/ospfd.conf
index 8678813665..51317202bb 100644
--- a/tests/topotests/ldp-oc-topo1/r2/ospfd.conf
+++ b/tests/topotests/ldp-oc-topo1/r2/ospfd.conf
@@ -5,3 +5,11 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-topo1/r3/ospfd.conf b/tests/topotests/ldp-oc-topo1/r3/ospfd.conf
index 202be238ec..4566976b7b 100644
--- a/tests/topotests/ldp-oc-topo1/r3/ospfd.conf
+++ b/tests/topotests/ldp-oc-topo1/r3/ospfd.conf
@@ -6,3 +6,7 @@ router ospf
router-id 3.3.3.3
network 0.0.0.0/0 area 0
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-oc-topo1/r4/ospfd.conf b/tests/topotests/ldp-oc-topo1/r4/ospfd.conf
index 569dbc54e2..5aae885a12 100644
--- a/tests/topotests/ldp-oc-topo1/r4/ospfd.conf
+++ b/tests/topotests/ldp-oc-topo1/r4/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 4.4.4.4
network 0.0.0.0/0 area 0
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/ce1/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/ce1/zebra.conf
new file mode 100644
index 0000000000..6f165e2724
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/ce1/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce1
+!
+interface ce1-eth0
+ ip address 172.16.1.1/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/ce2/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/ce2/zebra.conf
new file mode 100644
index 0000000000..ac02d0f9a4
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/ce2/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce2
+!
+interface ce2-eth0
+ ip address 172.16.1.2/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/ce3/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/ce3/zebra.conf
new file mode 100644
index 0000000000..c6a5824d15
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/ce3/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce3
+!
+interface ce3-eth0
+ ip address 172.16.1.3/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf
new file mode 100644
index 0000000000..af8d117bc1
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf
@@ -0,0 +1,26 @@
+hostname r1
+log file isisd.log
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+debug isis ldp-sync
+!
+router isis 1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
+ metric-style wide
+ redistribute ipv4 connected level-1
+ redistribute ipv6 connected level-1
+ mpls ldp-sync
+!
+interface r1-eth1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+!
+interface r1-eth2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/ldpd.conf b/tests/topotests/ldp-sync-isis-topo1/r1/ldpd.conf
new file mode 100644
index 0000000000..b9c32d3000
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/ldpd.conf
@@ -0,0 +1,33 @@
+hostname r1
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 1.1.1.1
+ !
+ address-family ipv4
+ discovery transport-address 1.1.1.1
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r1-eth1
+ !
+ interface r1-eth2
+ !
+ !
+!
+l2vpn CUST_A type vpls
+ member interface r1-eth0
+ !
+ member pseudowire r1-mpw0
+ neighbor lsr-id 2.2.2.2
+ pw-id 100
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ip_route.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ip_route.ref
new file mode 100644
index 0000000000..dc8f19dad0
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ip_route.ref
@@ -0,0 +1,143 @@
+{
+ "1.1.1.1\/32":[
+ {
+ "prefix":"1.1.1.1\/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2\/32":[
+ {
+ "prefix":"2.2.2.2\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3\/32":[
+ {
+ "prefix":"3.3.3.3\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0\/24":[
+ {
+ "prefix":"10.0.1.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0\/24":[
+ {
+ "prefix":"10.0.2.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.2.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0\/24":[
+ {
+ "prefix":"10.0.3.0\/24",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail.ref
new file mode 100644
index 0000000000..d8fb27af8c
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r1-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ],
+ "r1-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..f77d65ebc1
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r1-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "16777214"
+ }
+ ],
+ "r1-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..f77d65ebc1
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_interface_detail_r2_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r1-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "16777214"
+ }
+ ],
+ "r1-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync.ref
new file mode 100644
index 0000000000..b699e8c145
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync.ref
@@ -0,0 +1,13 @@
+{
+ "r1-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ },
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..c63bbea77f
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r1-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not achieved"
+ },
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..c63bbea77f
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_isis_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r1-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not achieved"
+ },
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..b3de7e2c66
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_binding.ref
@@ -0,0 +1,16 @@
+{
+ "2.2.2.2: 100":{
+ "destination":"2.2.2.2",
+ "vcId":100,
+ "localLabel":16,
+ "localControlWord":1,
+ "localVcType":"Ethernet",
+ "localGroupID":0,
+ "localIfMtu":1500,
+ "remoteLabel":16,
+ "remoteControlWord":1,
+ "remoteVcType":"Ethernet",
+ "remoteGroupID":0,
+ "remoteIfMtu":1500
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..29e9df1089
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_l2vpn_vc.ref
@@ -0,0 +1,8 @@
+{
+ "r1-mpw0":{
+ "peerId":"2.2.2.2",
+ "vcId":100,
+ "VpnName":"CUST_A",
+ "status":"up"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_binding.ref
new file mode 100644
index 0000000000..b3a12ec53f
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"2.2.2.2",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"3.3.3.3",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"2.2.2.2",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"3.3.3.3",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"2.2.2.2",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"3.3.3.3",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_discovery.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_discovery.ref
new file mode 100644
index 0000000000..9301e60c67
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_discovery.ref
@@ -0,0 +1,25 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"link",
+ "interface":"r1-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"targeted",
+ "peer":"2.2.2.2",
+ "helloHoldtime":45
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "type":"link",
+ "interface":"r1-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..54d015fef9
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r1-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ },
+ "r1-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..2232069f68
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r1-eth1":{
+ "state":"labelExchangeNotComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":""
+ },
+ "r1-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..40d8ebeb90
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "state":"OPERATIONAL",
+ "transportAddress":"2.2.2.2"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "state":"OPERATIONAL",
+ "transportAddress":"3.3.3.3"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/ldp-sync-isis-topo1/r1/show_yang_interface_isis_adjacencies.ref
new file mode 100644
index 0000000000..6138d03672
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/show_yang_interface_isis_adjacencies.ref
@@ -0,0 +1,42 @@
+{
+ "frr-interface:lib": {
+ "interface": [
+ {
+ "name": "r1-eth1",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0002",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "r1-eth2",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0003",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r1/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/r1/zebra.conf
new file mode 100644
index 0000000000..ea047355ad
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r1/zebra.conf
@@ -0,0 +1,29 @@
+log file zebra.log
+!
+hostname r1
+!
+debug zebra kernel
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra nht
+debug zebra pseudowires
+debug zebra mpls
+!
+interface lo
+ ip address 1.1.1.1/32
+!
+interface r1-eth0
+ description to s1
+!
+interface r1-eth1
+ description to s4
+ ip address 10.0.1.1/24
+!
+interface r1-eth2
+ description to s5
+ ip address 10.0.2.1/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf
new file mode 100644
index 0000000000..e477bce827
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf
@@ -0,0 +1,27 @@
+hostname r2
+log file isisd.log
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+debug isis ldp-sync
+!
+router isis 1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
+ metric-style wide
+ redistribute ipv4 connected level-1
+ redistribute ipv6 connected level-1
+ mpls ldp-sync
+!
+interface r2-eth1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+!
+interface r2-eth2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+ no isis mpls ldp-sync
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/ldpd.conf b/tests/topotests/ldp-sync-isis-topo1/r2/ldpd.conf
new file mode 100644
index 0000000000..52398b1b72
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/ldpd.conf
@@ -0,0 +1,33 @@
+hostname r2
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 2.2.2.2
+ !
+ address-family ipv4
+ discovery transport-address 2.2.2.2
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r2-eth1
+ !
+ interface r2-eth2
+ !
+ !
+!
+l2vpn CUST_A type vpls
+ member interface r2-eth0
+ !
+ member pseudowire r2-mpw0
+ neighbor lsr-id 1.1.1.1
+ pw-id 100
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/ospfd.conf b/tests/topotests/ldp-sync-isis-topo1/r2/ospfd.conf
new file mode 100644
index 0000000000..f93f6aed56
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/ospfd.conf
@@ -0,0 +1,19 @@
+hostname r2
+log file ospfd.log
+debug ospf zebra interface
+debug ospf ldp-sync
+!
+router ospf
+ router-id 2.2.2.2
+ network 0.0.0.0/0 area 0
+ mpls ldp-sync
+ mpls ldp-sync holddown 50
+!
+interface r2-eth1
+ ip ospf network point-to-point
+ ip ospf mpls ldp-sync holddown 300
+!
+interface r2-eth2
+ ip ospf network point-to-point
+ no ip ospf mpls ldp-sync
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ip_route.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ip_route.ref
new file mode 100644
index 0000000000..2bcee96064
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ip_route.ref
@@ -0,0 +1,143 @@
+{
+ "1.1.1.1\/32":[
+ {
+ "prefix":"1.1.1.1\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2\/32":[
+ {
+ "prefix":"2.2.2.2\/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3\/32":[
+ {
+ "prefix":"3.3.3.3\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.3.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0\/24":[
+ {
+ "prefix":"10.0.1.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.1.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0\/24":[
+ {
+ "prefix":"10.0.2.0\/24",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0\/24":[
+ {
+ "prefix":"10.0.3.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.3.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.3.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail.ref
new file mode 100644
index 0000000000..844aa9402a
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r2-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ],
+ "r2-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..821ec70ba5
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r2-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "16777214"
+ }
+ ],
+ "r2-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..821ec70ba5
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_interface_detail_r2_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r2-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "16777214"
+ }
+ ],
+ "r2-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync.ref
new file mode 100644
index 0000000000..433d89bd16
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync.ref
@@ -0,0 +1,13 @@
+{
+ "r2-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ },
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not required"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..2f3eae47c8
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r2-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not achieved"
+ },
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not required"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..2f3eae47c8
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_isis_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r2-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not achieved"
+ },
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not required"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..42c5a1cbd9
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_binding.ref
@@ -0,0 +1,16 @@
+{
+ "1.1.1.1: 100":{
+ "destination":"1.1.1.1",
+ "vcId":100,
+ "localLabel":16,
+ "localControlWord":1,
+ "localVcType":"Ethernet",
+ "localGroupID":0,
+ "localIfMtu":1500,
+ "remoteLabel":16,
+ "remoteControlWord":1,
+ "remoteVcType":"Ethernet",
+ "remoteGroupID":0,
+ "remoteIfMtu":1500
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..942ed23a1e
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_l2vpn_vc.ref
@@ -0,0 +1,8 @@
+{
+ "r2-mpw0":{
+ "peerId":"1.1.1.1",
+ "vcId":100,
+ "VpnName":"CUST_A",
+ "status":"up"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_binding.ref
new file mode 100644
index 0000000000..c641fb47e6
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"1.1.1.1",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"3.3.3.3",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"1.1.1.1",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"3.3.3.3",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"1.1.1.1",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"3.3.3.3",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_discovery.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_discovery.ref
new file mode 100644
index 0000000000..26801acade
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_discovery.ref
@@ -0,0 +1,25 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"link",
+ "interface":"r2-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"targeted",
+ "peer":"1.1.1.1",
+ "helloHoldtime":45
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "type":"link",
+ "interface":"r2-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..f2b24d7d62
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r2-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r2-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..b5508dd35c
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r2-eth1":{
+ "state":"labelExchangeNotComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":""
+ },
+ "r2-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..f2b24d7d62
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_igp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r2-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r2-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..eed35289ea
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "state":"OPERATIONAL",
+ "transportAddress":"1.1.1.1"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "state":"OPERATIONAL",
+ "transportAddress":"3.3.3.3"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/show_yang_interface_isis_adjacencies.ref b/tests/topotests/ldp-sync-isis-topo1/r2/show_yang_interface_isis_adjacencies.ref
new file mode 100644
index 0000000000..4dd6ddd76b
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/show_yang_interface_isis_adjacencies.ref
@@ -0,0 +1,42 @@
+{
+ "frr-interface:lib": {
+ "interface": [
+ {
+ "name": "r2-eth1",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0001",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "r2-eth2",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0003",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r2/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/r2/zebra.conf
new file mode 100644
index 0000000000..c244442876
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r2/zebra.conf
@@ -0,0 +1,28 @@
+log file zebra.log
+!
+hostname r2
+!
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
+debug zebra nht
+debug zebra pseudowires
+!
+interface lo
+ ip address 2.2.2.2/32
+!
+interface r2-eth0
+ description to s2
+!
+interface r2-eth1
+ description to s4
+ ip address 10.0.1.2/24
+!
+interface r2-eth2
+ description to s6
+ ip address 10.0.3.2/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf b/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf
new file mode 100644
index 0000000000..e50fb077ba
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf
@@ -0,0 +1,28 @@
+hostname r3
+log file isisd.log
+debug isis adj-packets
+debug isis events
+debug isis update-packets
+debug isis ldp-sync
+!
+router isis 1
+ net 10.0000.0000.0000.0000.0000.0000.0000.0000.0003.00
+ metric-style wide
+ redistribute ipv4 connected level-1
+ redistribute ipv6 connected level-1
+ mpls ldp-sync
+ mpls ldp-sync holddown 50
+!
+interface r3-eth1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+ no isis mpls ldp-sync
+!
+interface r3-eth2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis circuit-type level-1
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/ldpd.conf b/tests/topotests/ldp-sync-isis-topo1/r3/ldpd.conf
new file mode 100644
index 0000000000..2935caf13b
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/ldpd.conf
@@ -0,0 +1,25 @@
+hostname r3
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 3.3.3.3
+ !
+ address-family ipv4
+ discovery transport-address 3.3.3.3
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r3-eth1
+ !
+ interface r3-eth2
+ !
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ip_route.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ip_route.ref
new file mode 100644
index 0000000000..da46f1dfe2
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ip_route.ref
@@ -0,0 +1,143 @@
+{
+ "1.1.1.1\/32":[
+ {
+ "prefix":"1.1.1.1\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2\/32":[
+ {
+ "prefix":"2.2.2.2\/32",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3\/32":[
+ {
+ "prefix":"3.3.3.3\/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0\/24":[
+ {
+ "prefix":"10.0.1.0\/24",
+ "protocol":"isis",
+ "selected":true,
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0\/24":[
+ {
+ "prefix":"10.0.2.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.2.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0\/24":[
+ {
+ "prefix":"10.0.3.0\/24",
+ "protocol":"isis",
+ "distance":115,
+ "metric":10,
+ "nexthops":[
+ {
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2"
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.3.0\/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail.ref
new file mode 100644
index 0000000000..e323f61f25
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r3-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ],
+ "r3-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..e323f61f25
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r3-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ],
+ "r3-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..e323f61f25
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_interface_detail_r2_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "1": {
+ "r3-eth1": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ],
+ "r3-eth2": [
+ {
+ "level": "Level-1",
+ "metric": "10"
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref
new file mode 100644
index 0000000000..9cb70a4758
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync.ref
@@ -0,0 +1,13 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..9cb70a4758
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..9cb70a4758
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_isis_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,13 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_binding.ref
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_l2vpn_vc.ref
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_binding.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_binding.ref
new file mode 100644
index 0000000000..e54bd6e755
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"1.1.1.1",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"2.2.2.2",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"1.1.1.1",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"2.2.2.2",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"1.1.1.1",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"2.2.2.2",
+ "localLabel":"imp-null",
+ "inUse":0
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_discovery.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_discovery.ref
new file mode 100644
index 0000000000..42fa98d4da
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_discovery.ref
@@ -0,0 +1,18 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"link",
+ "interface":"r3-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"link",
+ "interface":"r3-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..73261830c9
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r3-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r3-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..73261830c9
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r3-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r3-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..5c482da697
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "state":"OPERATIONAL",
+ "transportAddress":"1.1.1.1"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "state":"OPERATIONAL",
+ "transportAddress":"2.2.2.2"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/show_yang_interface_isis_adjacencies.ref b/tests/topotests/ldp-sync-isis-topo1/r3/show_yang_interface_isis_adjacencies.ref
new file mode 100644
index 0000000000..0922192361
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/show_yang_interface_isis_adjacencies.ref
@@ -0,0 +1,42 @@
+{
+ "frr-interface:lib": {
+ "interface": [
+ {
+ "name": "r3-eth1",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0001",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "r3-eth2",
+ "vrf": "default",
+ "state": {
+ "frr-isisd:isis": {
+ "adjacencies": {
+ "adjacency": [
+ {
+ "neighbor-sys-type": "level-1",
+ "neighbor-sysid": "0000.0000.0002",
+ "neighbor-extended-circuit-id": 0,
+ "state": "up"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/r3/zebra.conf b/tests/topotests/ldp-sync-isis-topo1/r3/zebra.conf
new file mode 100644
index 0000000000..b1919bd296
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/r3/zebra.conf
@@ -0,0 +1,32 @@
+log file zebra.log
+!
+hostname r3
+!
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
+debug zebra nht
+debug zebra pseudowires
+!
+interface lo
+ ip address 3.3.3.3/32
+!
+interface r3-eth0
+ description to s3
+!
+interface r3-eth1
+ description to s5
+ ip address 10.0.2.3/24
+!
+interface r3-eth2
+ description to s6
+ ip address 10.0.3.3/24
+!
+!!interface r3-eth3
+!! description to s4
+!! ip address 10.0.1.3/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.dot b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.dot
new file mode 100644
index 0000000000..4f1bd22f7c
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.dot
@@ -0,0 +1,111 @@
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## Switches: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #fcb314 dark yellow
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+##### Colors (see http://www.color-hex.com/)
+
+graph template {
+ label="Test Topology - LDP-VPLS 1";
+
+ # Routers
+ ce1 [
+ shape=doubleoctagon,
+ label="ce1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ ce2 [
+ shape=doubleoctagon
+ label="ce2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ ce3 [
+ shape=doubleoctagon
+ label="ce3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r1 [
+ shape=doubleoctagon,
+ label="r1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r2 [
+ shape=doubleoctagon
+ label="r2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r3 [
+ shape=doubleoctagon
+ label="r3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+
+
+ # Switches
+ s1 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s2 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s3 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s4 [
+ shape=oval,
+ label="s4\n10.0.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s5 [
+ shape=oval,
+ label="s5\n10.0.2.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s6 [
+ shape=oval,
+ label="s6\n10.0.3.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ ce1 -- s1 [label="eth0\n.1"];
+ ce2 -- s2 [label="eth0\n.2"];
+ ce3 -- s3 [label="eth0\n.3"];
+
+ r1 -- s1 [label="eth0"];
+ r1 -- s4 [label="eth1\n.1"];
+ r1 -- s5 [label="eth2\n.1"];
+
+ r2 -- s2 [label="eth0"];
+ r2 -- s4 [label="eth1\n.2"];
+ r2 -- s6 [label="eth2\n.2"];
+
+ r3 -- s3 [label="eth0"];
+ r3 -- s5 [label="eth1\n.3"];
+ r3 -- s6 [label="eth2\n.3"];
+}
diff --git a/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py
new file mode 100755
index 0000000000..1dce698c17
--- /dev/null
+++ b/tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py
@@ -0,0 +1,625 @@
+#!/usr/bin/env python
+
+#
+# test_ldp_isis_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by Volta Networks
+#
+# 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.
+#
+
+"""
+test_ldp_vpls_topo1.py:
+
+ +---------+ +---------+
+ | | | |
+ | CE1 | | CE2 |
+ | | | |
+ +---------+ +---------+
+ce1-eth0 (172.16.1.1/24)| |ce2-eth0 (172.16.1.2/24)
+ | |
+ | |
+ rt1-eth0| |rt2-eth0
+ +---------+ 10.0.1.0/24 +---------+
+ | |rt1-eth1 | |
+ | RT1 +----------------+ RT2 |
+ | 1.1.1.1 | rt2-eth1| 2.2.2.2 |
+ | | | |
+ +---------+ +---------+
+ rt1-eth2| |rt2-eth2
+ | |
+ | |
+ 10.0.2.0/24| +---------+ |10.0.3.0/24
+ | | | |
+ | | RT3 | |
+ +--------+ 3.3.3.3 +-------+
+ rt3-eth2| |rt3-eth1
+ +---------+
+ |rt3-eth0
+ |
+ |
+ ce3-eth0 (172.16.1.3/24)|
+ +---------+
+ | |
+ | CE3 |
+ | |
+ +---------+
+"""
+
+import os
+import re
+import sys
+import pytest
+import json
+from time import sleep
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ #
+ # Define FRR Routers
+ #
+ for router in ["ce1", "ce2", "ce3", "r1", "r2", "r3"]:
+ tgen.add_router(router)
+
+ #
+ # Define connections
+ #
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["ce1"])
+ switch.add_link(tgen.gears["r1"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["ce2"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["ce3"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ # Don't start isisd and ldpd in the CE nodes
+ if router.name[0] == "r":
+ router.load_config(
+ TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ 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 80 seconds.
+ test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
+ _, diff = topotest.run_and_expect(test_func, None, count=160, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+ assert diff is None, assertmsg
+
+
+def test_isis_convergence():
+ logger.info("Test: check ISIS adjacencies")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname,
+ "show yang operational-data /frr-interface:lib isisd",
+ "show_yang_interface_isis_adjacencies.ref")
+
+def test_rib():
+ logger.info("Test: verify RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(rname, "show ip route json", "show_ip_route.ref")
+
+
+def test_ldp_adjacencies():
+ logger.info("Test: verify LDP adjacencies")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp discovery json", "show_ldp_discovery.ref"
+ )
+
+
+def test_ldp_neighbors():
+ logger.info("Test: verify LDP neighbors")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp neighbor json", "show_ldp_neighbor.ref"
+ )
+
+
+def test_ldp_bindings():
+ logger.info("Test: verify LDP bindings")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp binding json", "show_ldp_binding.ref"
+ )
+
+
+def test_ldp_pwid_bindings():
+ logger.info("Test: verify LDP PW-ID bindings")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom binding json", "show_l2vpn_binding.ref"
+ )
+
+
+def test_ldp_pseudowires():
+ logger.info("Test: verify LDP pseudowires")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
+ )
+
+def test_ldp_igp_sync():
+ logger.info("Test: verify LDP igp-sync")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+def test_isis_ldp_sync():
+ logger.info("Test: verify ISIS igp-sync")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_ldp_sync(
+ rname, "show_isis_ldp_sync.ref"
+ )
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_interface_detail(
+ rname, "show_isis_interface_detail.ref"
+ )
+ assert result, "ISIS interface did not converge on {}:\n{}".format(rname, diff)
+
+
+def test_r1_eth1_shutdown():
+ logger.info("Test: verify behaviour after r1-eth1 is shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Shut down r1-r2 link */
+ tgen = get_topogen()
+ tgen.gears["r1"].peer_link_enable("r1-eth1", False)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ # check if the pseudowire is still up (using an alternate path for nexthop resolution)
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_ldp_sync(
+ rname, "show_isis_ldp_sync_r1_eth1_shutdown.ref"
+ )
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_interface_detail(
+ rname, "show_isis_interface_detail_r1_eth1_shutdown.ref"
+ )
+ assert result, "ISIS interface did not converge on {}:\n{}".format(rname, diff)
+
+
+def test_r1_eth1_no_shutdown():
+ logger.info("Test: verify behaviour after r1-eth1 is no shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Run no shutdown on r1-eth1 interface */
+ tgen = get_topogen()
+ tgen.gears["r1"].peer_link_enable("r1-eth1", True)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_ldp_sync(
+ rname, "show_isis_ldp_sync.ref"
+ )
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_interface_detail(
+ rname, "show_isis_interface_detail.ref"
+ )
+ assert result, "ISIS interface did not converge on {}:\n{}".format(rname, diff)
+
+
+def test_r2_eth1_shutdown():
+ logger.info("Test: verify behaviour after r2-eth1 is shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Shut down r1-r2 link */
+ tgen = get_topogen()
+ tgen.gears["r2"].peer_link_enable("r2-eth1", False)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_ldp_sync(
+ rname, "show_isis_ldp_sync_r2_eth1_shutdown.ref"
+ )
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_interface_detail(
+ rname, "show_isis_interface_detail_r2_eth1_shutdown.ref"
+ )
+ assert result, "ISIS interface did not converge on {}:\n{}".format(rname, diff)
+
+
+def test_r2_eth1_no_shutdown():
+ logger.info("Test: verify behaviour after r2-eth1 is no shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Run no shutdown on r2-eth1 interface */
+ tgen = get_topogen()
+ tgen.gears["r2"].peer_link_enable("r2-eth1", True)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_ldp_sync(
+ rname, "show_isis_ldp_sync.ref"
+ )
+ assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
+
+ for rname in ["r1", "r2", "r3"]:
+ (result, diff) = validate_show_isis_interface_detail(
+ rname, "show_isis_interface_detail.ref"
+ )
+ assert result, "ISIS interface did not converge on {}:\n{}".format(rname, diff)
+
+
+# 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))
+
+
+#
+# Auxiliary functions
+#
+
+def parse_show_isis_ldp_sync(lines, rname):
+ """
+ Parse the output of 'show isis mpls ldp sync' into a Python dict.
+ """
+ interfaces = {}
+
+ it = iter(lines)
+
+ while True:
+ try:
+ interface = {}
+ interface_name = None
+
+ line = it.next();
+
+ if line.startswith(rname + "-eth"):
+ interface_name = line
+
+ line = it.next();
+
+ if line.startswith(" LDP-IGP Synchronization enabled: "):
+ interface["ldpIgpSyncEnabled"] = line.endswith("yes")
+
+ line = it.next();
+
+ if line.startswith(" holddown timer in seconds: "):
+ interface["holdDownTimeInSec"] = int(line.split(": ")[-1])
+
+ line = it.next();
+
+ if line.startswith(" State: "):
+ interface["ldpIgpSyncState"] = line.split(": ")[-1]
+
+ interfaces[interface_name] = interface
+
+ except StopIteration:
+ break
+
+ return interfaces
+
+
+def show_isis_ldp_sync(router, rname):
+ """
+ Get the show isis mpls ldp-sync info in a dictionary format.
+
+ """
+ out = topotest.normalize_text(
+ router.vtysh_cmd("show isis mpls ldp-sync")
+ ).splitlines()
+
+ parsed = parse_show_isis_ldp_sync(out, rname)
+
+ return parsed
+
+
+def validate_show_isis_ldp_sync(rname, fname):
+ tgen = get_topogen()
+
+ filename = "{0}/{1}/{2}".format(CWD, rname, fname)
+ expected = json.loads(open(filename).read())
+
+ router = tgen.gears[rname]
+
+ def compare_isis_ldp_sync(router, expected):
+ "Helper function to test show isis mpls ldp-sync"
+ actual = show_isis_ldp_sync(router, rname)
+ return topotest.json_cmp(actual, expected)
+
+ test_func = partial(compare_isis_ldp_sync, router, expected)
+ (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=160)
+
+ return (result, diff)
+
+
+def parse_show_isis_interface_detail(lines, rname):
+ """
+ Parse the output of 'show isis interface detail' into a Python dict.
+ """
+ areas = {}
+ area_id = None
+
+ it = iter(lines)
+
+ while True:
+ try:
+ line = it.next();
+
+ area_match = re.match(r"Area (.+):", line)
+ if not area_match:
+ continue
+
+ area_id = area_match.group(1)
+ area = {}
+
+ line = it.next();
+
+ while line.startswith(" Interface: "):
+ interface_name = re.split(':|,', line)[1].lstrip()
+
+ area[interface_name]= []
+
+ # Look for keyword: Level-1 or Level-2
+ while not line.startswith(" Level-"):
+ line = it.next();
+
+ while line.startswith(" Level-"):
+
+ level = {}
+
+ level_name = line.split()[0]
+ level['level'] = level_name
+
+ line = it.next();
+
+ if line.startswith(" Metric:"):
+ level['metric'] = re.split(':|,', line)[1].lstrip()
+
+ area[interface_name].append(level)
+
+ # Look for keyword: Level-1 or Level-2 or Interface:
+ while not line.startswith(" Level-") and not line.startswith(" Interface: "):
+ line = it.next();
+
+ if line.startswith(" Level-"):
+ continue
+
+ if line.startswith(" Interface: "):
+ break
+
+ areas[area_id] = area
+
+ except StopIteration:
+
+ areas[area_id] = area
+ break
+
+ return areas
+
+
+def show_isis_interface_detail(router, rname):
+ """
+ Get the show isis mpls ldp-sync info in a dictionary format.
+
+ """
+ out = topotest.normalize_text(
+ router.vtysh_cmd("show isis interface detail")
+ ).splitlines()
+
+ logger.warning(out)
+
+ parsed = parse_show_isis_interface_detail(out, rname)
+
+ logger.warning(parsed)
+
+ return parsed
+
+
+def validate_show_isis_interface_detail(rname, fname):
+ tgen = get_topogen()
+
+ filename = "{0}/{1}/{2}".format(CWD, rname, fname)
+ expected = json.loads(open(filename).read())
+
+ router = tgen.gears[rname]
+
+ def compare_isis_interface_detail(router, expected):
+ "Helper function to test show isis interface detail"
+ actual = show_isis_interface_detail(router, rname)
+ return topotest.json_cmp(actual, expected)
+
+ test_func = partial(compare_isis_interface_detail, router, expected)
+ (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=160)
+
+ return (result, diff)
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/ce1/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/ce1/zebra.conf
new file mode 100644
index 0000000000..6f165e2724
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/ce1/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce1
+!
+interface ce1-eth0
+ ip address 172.16.1.1/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/ce2/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/ce2/zebra.conf
new file mode 100644
index 0000000000..ac02d0f9a4
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/ce2/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce2
+!
+interface ce2-eth0
+ ip address 172.16.1.2/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/ce3/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/ce3/zebra.conf
new file mode 100644
index 0000000000..c6a5824d15
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/ce3/zebra.conf
@@ -0,0 +1,12 @@
+log file zebra.log
+!
+hostname ce3
+!
+interface ce3-eth0
+ ip address 172.16.1.3/24
+ no link-detect
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/ldpd.conf b/tests/topotests/ldp-sync-ospf-topo1/r1/ldpd.conf
new file mode 100644
index 0000000000..b9c32d3000
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/ldpd.conf
@@ -0,0 +1,33 @@
+hostname r1
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 1.1.1.1
+ !
+ address-family ipv4
+ discovery transport-address 1.1.1.1
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r1-eth1
+ !
+ interface r1-eth2
+ !
+ !
+!
+l2vpn CUST_A type vpls
+ member interface r1-eth0
+ !
+ member pseudowire r1-mpw0
+ neighbor lsr-id 2.2.2.2
+ pw-id 100
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/ospf-nbrs.txt b/tests/topotests/ldp-sync-ospf-topo1/r1/ospf-nbrs.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/ospf-nbrs.txt
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/ospfd.conf b/tests/topotests/ldp-sync-ospf-topo1/r1/ospfd.conf
new file mode 100644
index 0000000000..eefcd1e71c
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/ospfd.conf
@@ -0,0 +1,20 @@
+hostname r1
+log file ospfd.log
+debug ospf zebra interface
+debug ospf ldp-sync
+!
+router ospf
+ router-id 1.1.1.1
+ network 10.0.1.1/24 area 0
+ network 10.0.2.1/24 area 0
+ network 1.1.1.1/32 area 0
+ mpls ldp-sync
+ ! mpls ldp-sync holddown 50
+!
+interface r1-eth1
+ ip ospf network point-to-point
+ ! ip ospf mpls ldp-sync holddown 40
+!
+interface r1-eth2
+ ip ospf network point-to-point
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface.ref
new file mode 100644
index 0000000000..8b2884786d
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r1-eth1":{
+ "cost":10
+ },
+ "r1-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..b1a263e422
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r1_eth1_shutdown.ref
@@ -0,0 +1,8 @@
+{
+ "interfaces":{
+ "r1-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..0c147338e3
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_interface_r2_eth1_shutdown.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r1-eth1":{
+ "cost":65535
+ },
+ "r1-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_neighbor.json b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_neighbor.json
new file mode 100644
index 0000000000..3bfda39071
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_ospf_neighbor.json
@@ -0,0 +1,26 @@
+{
+ "neighbors": {
+ "2.2.2.2": [
+ {
+ "dbSummaryCounter": 0,
+ "retransmitCounter": 0,
+ "priority": 1,
+ "state": "Full/DROther",
+ "address": "10.0.1.2",
+ "ifaceName": "r1-eth1:10.0.1.1",
+ "requestCounter": 0
+ }
+ ],
+ "3.3.3.3": [
+ {
+ "dbSummaryCounter": 0,
+ "retransmitCounter": 0,
+ "priority": 1,
+ "state": "Full/DROther",
+ "address": "10.0.2.3",
+ "ifaceName": "r1-eth2:10.0.2.1",
+ "requestCounter": 0
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_route.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_route.ref
new file mode 100644
index 0000000000..8ccd60ca41
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ip_route.ref
@@ -0,0 +1,157 @@
+{
+ "1.1.1.1/32":[
+ {
+ "prefix":"1.1.1.1/32",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":0,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"1.1.1.1/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2/32":[
+ {
+ "prefix":"2.2.2.2/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3/32":[
+ {
+ "prefix":"3.3.3.3/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0/24":[
+ {
+ "prefix":"10.0.1.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0/24":[
+ {
+ "prefix":"10.0.2.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.2.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0/24":[
+ {
+ "prefix":"10.0.3.0/24",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":20,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.2",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r1-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.2.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r1-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..b3de7e2c66
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_binding.ref
@@ -0,0 +1,16 @@
+{
+ "2.2.2.2: 100":{
+ "destination":"2.2.2.2",
+ "vcId":100,
+ "localLabel":16,
+ "localControlWord":1,
+ "localVcType":"Ethernet",
+ "localGroupID":0,
+ "localIfMtu":1500,
+ "remoteLabel":16,
+ "remoteControlWord":1,
+ "remoteVcType":"Ethernet",
+ "remoteGroupID":0,
+ "remoteIfMtu":1500
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..29e9df1089
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_l2vpn_vc.ref
@@ -0,0 +1,8 @@
+{
+ "r1-mpw0":{
+ "peerId":"2.2.2.2",
+ "vcId":100,
+ "VpnName":"CUST_A",
+ "status":"up"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_binding.ref
new file mode 100644
index 0000000000..b3a12ec53f
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"2.2.2.2",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"3.3.3.3",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"2.2.2.2",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"3.3.3.3",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"2.2.2.2",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"3.3.3.3",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_discovery.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_discovery.ref
new file mode 100644
index 0000000000..9301e60c67
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_discovery.ref
@@ -0,0 +1,25 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"link",
+ "interface":"r1-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"targeted",
+ "peer":"2.2.2.2",
+ "helloHoldtime":45
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "type":"link",
+ "interface":"r1-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..54d015fef9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r1-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ },
+ "r1-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..2232069f68
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r1-eth1":{
+ "state":"labelExchangeNotComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":""
+ },
+ "r1-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..40d8ebeb90
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "state":"OPERATIONAL",
+ "transportAddress":"2.2.2.2"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "state":"OPERATIONAL",
+ "transportAddress":"3.3.3.3"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync.ref
new file mode 100644
index 0000000000..3782071bf9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync.ref
@@ -0,0 +1,12 @@
+{
+ "r1-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ },
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..c2642c6483
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,7 @@
+{
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..6f180b048a
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/show_ospf_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,12 @@
+{
+ "r1-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync not achieved"
+ },
+ "r1-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":0,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r1/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/r1/zebra.conf
new file mode 100644
index 0000000000..ea047355ad
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r1/zebra.conf
@@ -0,0 +1,29 @@
+log file zebra.log
+!
+hostname r1
+!
+debug zebra kernel
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra nht
+debug zebra pseudowires
+debug zebra mpls
+!
+interface lo
+ ip address 1.1.1.1/32
+!
+interface r1-eth0
+ description to s1
+!
+interface r1-eth1
+ description to s4
+ ip address 10.0.1.1/24
+!
+interface r1-eth2
+ description to s5
+ ip address 10.0.2.1/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/ldpd.conf b/tests/topotests/ldp-sync-ospf-topo1/r2/ldpd.conf
new file mode 100644
index 0000000000..52398b1b72
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/ldpd.conf
@@ -0,0 +1,33 @@
+hostname r2
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 2.2.2.2
+ !
+ address-family ipv4
+ discovery transport-address 2.2.2.2
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r2-eth1
+ !
+ interface r2-eth2
+ !
+ !
+!
+l2vpn CUST_A type vpls
+ member interface r2-eth0
+ !
+ member pseudowire r2-mpw0
+ neighbor lsr-id 1.1.1.1
+ pw-id 100
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/ospfd.conf b/tests/topotests/ldp-sync-ospf-topo1/r2/ospfd.conf
new file mode 100644
index 0000000000..f93f6aed56
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/ospfd.conf
@@ -0,0 +1,19 @@
+hostname r2
+log file ospfd.log
+debug ospf zebra interface
+debug ospf ldp-sync
+!
+router ospf
+ router-id 2.2.2.2
+ network 0.0.0.0/0 area 0
+ mpls ldp-sync
+ mpls ldp-sync holddown 50
+!
+interface r2-eth1
+ ip ospf network point-to-point
+ ip ospf mpls ldp-sync holddown 300
+!
+interface r2-eth2
+ ip ospf network point-to-point
+ no ip ospf mpls ldp-sync
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface.ref
new file mode 100644
index 0000000000..82806721e7
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r2-eth1":{
+ "cost":10
+ },
+ "r2-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..71e8af1778
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r1_eth1_shutdown.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r2-eth1":{
+ "cost":65535
+ },
+ "r2-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..af9a9c80e5
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_interface_r2_eth1_shutdown.ref
@@ -0,0 +1,8 @@
+{
+ "interfaces":{
+ "r2-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_neighbor.json b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_neighbor.json
new file mode 100644
index 0000000000..5b7a5ebbb9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_ospf_neighbor.json
@@ -0,0 +1,26 @@
+{
+ "neighbors": {
+ "1.1.1.1": [
+ {
+ "priority":1,
+ "state":"Full/DROther",
+ "address":"10.0.1.1",
+ "ifaceName":"r2-eth1:10.0.1.2",
+ "retransmitCounter":0,
+ "requestCounter":0,
+ "dbSummaryCounter":0
+ }
+ ],
+ "3.3.3.3": [
+ {
+ "priority":1,
+ "state":"Full/DROther",
+ "address":"10.0.3.3",
+ "ifaceName":"r2-eth2:10.0.3.2",
+ "retransmitCounter":0,
+ "requestCounter":0,
+ "dbSummaryCounter":0
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_route.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_route.ref
new file mode 100644
index 0000000000..7147c6a595
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ip_route.ref
@@ -0,0 +1,157 @@
+{
+ "1.1.1.1/32":[
+ {
+ "prefix":"1.1.1.1/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2/32":[
+ {
+ "prefix":"2.2.2.2/32",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":0,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"2.2.2.2/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3/32":[
+ {
+ "prefix":"3.3.3.3/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.3.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0/24":[
+ {
+ "prefix":"10.0.1.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.1.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0/24":[
+ {
+ "prefix":"10.0.2.0/24",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":20,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.1.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r2-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.3",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0/24":[
+ {
+ "prefix":"10.0.3.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.3.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r2-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..42c5a1cbd9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_binding.ref
@@ -0,0 +1,16 @@
+{
+ "1.1.1.1: 100":{
+ "destination":"1.1.1.1",
+ "vcId":100,
+ "localLabel":16,
+ "localControlWord":1,
+ "localVcType":"Ethernet",
+ "localGroupID":0,
+ "localIfMtu":1500,
+ "remoteLabel":16,
+ "remoteControlWord":1,
+ "remoteVcType":"Ethernet",
+ "remoteGroupID":0,
+ "remoteIfMtu":1500
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..942ed23a1e
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_l2vpn_vc.ref
@@ -0,0 +1,8 @@
+{
+ "r2-mpw0":{
+ "peerId":"1.1.1.1",
+ "vcId":100,
+ "VpnName":"CUST_A",
+ "status":"up"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_binding.ref
new file mode 100644
index 0000000000..c641fb47e6
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"1.1.1.1",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"3.3.3.3",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"1.1.1.1",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"3.3.3.3",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"1.1.1.1",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"3.3.3.3",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_discovery.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_discovery.ref
new file mode 100644
index 0000000000..26801acade
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_discovery.ref
@@ -0,0 +1,25 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"link",
+ "interface":"r2-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"targeted",
+ "peer":"1.1.1.1",
+ "helloHoldtime":45
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "type":"link",
+ "interface":"r2-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..f2b24d7d62
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r2-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r2-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..b5508dd35c
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r2-eth1":{
+ "state":"labelExchangeNotComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":""
+ },
+ "r2-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"3.3.3.3"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..eed35289ea
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "state":"OPERATIONAL",
+ "transportAddress":"1.1.1.1"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"3.3.3.3",
+ "state":"OPERATIONAL",
+ "transportAddress":"3.3.3.3"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync.ref
new file mode 100644
index 0000000000..6c27a10427
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync.ref
@@ -0,0 +1,12 @@
+{
+ "r2-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":300,
+ "ldpIgpSyncState":"Sync achieved"
+ },
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..889f69ed7f
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,12 @@
+{
+ "r2-eth1":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":300,
+ "ldpIgpSyncState":"Holding down until Sync"
+ },
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..d9036e124b
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,7 @@
+{
+ "r2-eth2":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r2/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/r2/zebra.conf
new file mode 100644
index 0000000000..c244442876
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r2/zebra.conf
@@ -0,0 +1,28 @@
+log file zebra.log
+!
+hostname r2
+!
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
+debug zebra nht
+debug zebra pseudowires
+!
+interface lo
+ ip address 2.2.2.2/32
+!
+interface r2-eth0
+ description to s2
+!
+interface r2-eth1
+ description to s4
+ ip address 10.0.1.2/24
+!
+interface r2-eth2
+ description to s6
+ ip address 10.0.3.2/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/ldpd.conf b/tests/topotests/ldp-sync-ospf-topo1/r3/ldpd.conf
new file mode 100644
index 0000000000..2935caf13b
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/ldpd.conf
@@ -0,0 +1,25 @@
+hostname r3
+log file ldpd.log
+!
+debug mpls ldp zebra
+debug mpls ldp event
+debug mpls ldp errors
+debug mpls ldp sync
+!
+mpls ldp
+ router-id 3.3.3.3
+ !
+ address-family ipv4
+ discovery transport-address 3.3.3.3
+ label local allocate host-routes
+ !
+ ttl-security disable
+ !
+ interface r3-eth1
+ !
+ interface r3-eth2
+ !
+ !
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/ospfd.conf b/tests/topotests/ldp-sync-ospf-topo1/r3/ospfd.conf
new file mode 100644
index 0000000000..09eea759ad
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/ospfd.conf
@@ -0,0 +1,18 @@
+hostname r3
+log file ospfd.log
+debug ospf zebra interface
+debug ospf ldp-sync
+!
+router ospf
+ router-id 3.3.3.3
+ network 0.0.0.0/0 area 0
+ mpls ldp-sync
+ mpls ldp-sync holddown 50
+!
+interface r3-eth1
+ ip ospf network point-to-point
+ no ip ospf mpls ldp-sync
+!
+interface r3-eth2
+ ip ospf network point-to-point
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface.ref
new file mode 100644
index 0000000000..aec97b30cb
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r3-eth1":{
+ "cost":10
+ },
+ "r3-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..aec97b30cb
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r1_eth1_shutdown.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r3-eth1":{
+ "cost":10
+ },
+ "r3-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..aec97b30cb
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_interface_r2_eth1_shutdown.ref
@@ -0,0 +1,11 @@
+{
+ "interfaces":{
+ "r3-eth1":{
+ "cost":10
+ },
+ "r3-eth2":{
+ "cost":10
+ }
+ }
+}
+
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_neighbor.json b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_neighbor.json
new file mode 100644
index 0000000000..1b29b9f947
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_ospf_neighbor.json
@@ -0,0 +1,26 @@
+{
+ "neighbors": {
+ "1.1.1.1": [
+ {
+ "priority":1,
+ "state":"Full/DROther",
+ "address":"10.0.2.1",
+ "ifaceName":"r3-eth1:10.0.2.3",
+ "retransmitCounter":0,
+ "requestCounter":0,
+ "dbSummaryCounter":0
+ }
+ ],
+ "2.2.2.2": [
+ {
+ "priority":1,
+ "state":"Full/DROther",
+ "address":"10.0.3.2",
+ "ifaceName":"r3-eth2:10.0.3.3",
+ "retransmitCounter":0,
+ "requestCounter":0,
+ "dbSummaryCounter":0
+ }
+ ]
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_route.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_route.ref
new file mode 100644
index 0000000000..d77de7c9e3
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ip_route.ref
@@ -0,0 +1,157 @@
+{
+ "1.1.1.1/32":[
+ {
+ "prefix":"1.1.1.1/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2.2.2.2/32":[
+ {
+ "prefix":"2.2.2.2/32",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "3.3.3.3/32":[
+ {
+ "prefix":"3.3.3.3/32",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":0,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"3.3.3.3/32",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":1,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.1.0/24":[
+ {
+ "prefix":"10.0.1.0/24",
+ "protocol":"ospf",
+ "selected":true,
+ "distance":110,
+ "metric":20,
+ "nexthops":[
+ {
+ "fib":true,
+ "ip":"10.0.2.1",
+ "afi":"ipv4",
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ },
+ {
+ "fib":true,
+ "ip":"10.0.3.2",
+ "afi":"ipv4",
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.2.0/24":[
+ {
+ "prefix":"10.0.2.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.2.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":3,
+ "interfaceName":"r3-eth1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "10.0.3.0/24":[
+ {
+ "prefix":"10.0.3.0/24",
+ "protocol":"ospf",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ },
+ {
+ "prefix":"10.0.3.0/24",
+ "protocol":"connected",
+ "selected":true,
+ "nexthops":[
+ {
+ "fib":true,
+ "directlyConnected":true,
+ "interfaceIndex":4,
+ "interfaceName":"r3-eth2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_binding.ref
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_binding.ref
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_vc.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_vc.ref
new file mode 100644
index 0000000000..2c63c08510
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_l2vpn_vc.ref
@@ -0,0 +1,2 @@
+{
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_binding.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_binding.ref
new file mode 100644
index 0000000000..e54bd6e755
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_binding.ref
@@ -0,0 +1,44 @@
+{
+ "bindings":[
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"1.1.1.1",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"1.1.1.1/32",
+ "neighborId":"2.2.2.2",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"1.1.1.1",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"2.2.2.2/32",
+ "neighborId":"2.2.2.2",
+ "remoteLabel":"imp-null",
+ "inUse":1
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"1.1.1.1",
+ "localLabel":"imp-null",
+ "inUse":0
+ },
+ {
+ "addressFamily":"ipv4",
+ "prefix":"3.3.3.3/32",
+ "neighborId":"2.2.2.2",
+ "localLabel":"imp-null",
+ "inUse":0
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_discovery.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_discovery.ref
new file mode 100644
index 0000000000..42fa98d4da
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_discovery.ref
@@ -0,0 +1,18 @@
+{
+ "adjacencies":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "type":"link",
+ "interface":"r3-eth1",
+ "helloHoldtime":15
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "type":"link",
+ "interface":"r3-eth2",
+ "helloHoldtime":15
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync.ref
new file mode 100644
index 0000000000..73261830c9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync.ref
@@ -0,0 +1,16 @@
+{
+ "r3-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r3-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..73261830c9
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_igp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,16 @@
+{
+ "r3-eth1":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"1.1.1.1"
+ },
+ "r3-eth2":{
+ "state":"labelExchangeComplete",
+ "waitTime":10,
+ "waitTimeRemaining":0,
+ "timerRunning":false,
+ "peerLdpId":"2.2.2.2"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_neighbor.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_neighbor.ref
new file mode 100644
index 0000000000..5c482da697
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ldp_neighbor.ref
@@ -0,0 +1,16 @@
+{
+ "neighbors":[
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"1.1.1.1",
+ "state":"OPERATIONAL",
+ "transportAddress":"1.1.1.1"
+ },
+ {
+ "addressFamily":"ipv4",
+ "neighborId":"2.2.2.2",
+ "state":"OPERATIONAL",
+ "transportAddress":"2.2.2.2"
+ }
+ ]
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync.ref
new file mode 100644
index 0000000000..b417ab040a
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync.ref
@@ -0,0 +1,12 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref
new file mode 100644
index 0000000000..b417ab040a
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref
@@ -0,0 +1,12 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref
new file mode 100644
index 0000000000..b417ab040a
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref
@@ -0,0 +1,12 @@
+{
+ "r3-eth1":{
+ "ldpIgpSyncEnabled":false,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync not required"
+ },
+ "r3-eth2":{
+ "ldpIgpSyncEnabled":true,
+ "holdDownTimeInSec":50,
+ "ldpIgpSyncState":"Sync achieved"
+ }
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/r3/zebra.conf b/tests/topotests/ldp-sync-ospf-topo1/r3/zebra.conf
new file mode 100644
index 0000000000..b1919bd296
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/r3/zebra.conf
@@ -0,0 +1,32 @@
+log file zebra.log
+!
+hostname r3
+!
+debug zebra rib detailed
+debug zebra dplane detailed
+debug zebra kernel
+debug zebra nht
+debug zebra pseudowires
+!
+interface lo
+ ip address 3.3.3.3/32
+!
+interface r3-eth0
+ description to s3
+!
+interface r3-eth1
+ description to s5
+ ip address 10.0.2.3/24
+!
+interface r3-eth2
+ description to s6
+ ip address 10.0.3.3/24
+!
+!!interface r3-eth3
+!! description to s4
+!! ip address 10.0.1.3/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.dot b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.dot
new file mode 100644
index 0000000000..4f1bd22f7c
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.dot
@@ -0,0 +1,111 @@
+## Color coding:
+#########################
+## Main FRR: #f08080 red
+## Switches: #d0e0d0 gray
+## RIP: #19e3d9 Cyan
+## RIPng: #fcb314 dark yellow
+## OSPFv2: #32b835 Green
+## OSPFv3: #19e3d9 Cyan
+## ISIS IPv4 #fcb314 dark yellow
+## ISIS IPv6 #9a81ec purple
+## BGP IPv4 #eee3d3 beige
+## BGP IPv6 #fdff00 yellow
+##### Colors (see http://www.color-hex.com/)
+
+graph template {
+ label="Test Topology - LDP-VPLS 1";
+
+ # Routers
+ ce1 [
+ shape=doubleoctagon,
+ label="ce1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ ce2 [
+ shape=doubleoctagon
+ label="ce2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ ce3 [
+ shape=doubleoctagon
+ label="ce3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r1 [
+ shape=doubleoctagon,
+ label="r1",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r2 [
+ shape=doubleoctagon
+ label="r2",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+ r3 [
+ shape=doubleoctagon
+ label="r3",
+ fillcolor="#f08080",
+ style=filled,
+ ];
+
+
+ # Switches
+ s1 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s2 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s3 [
+ shape=oval,
+ label="VPLS\n172.16.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s4 [
+ shape=oval,
+ label="s4\n10.0.1.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s5 [
+ shape=oval,
+ label="s5\n10.0.2.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+ s6 [
+ shape=oval,
+ label="s6\n10.0.3.0/24",
+ fillcolor="#d0e0d0",
+ style=filled,
+ ];
+
+ # Connections
+ ce1 -- s1 [label="eth0\n.1"];
+ ce2 -- s2 [label="eth0\n.2"];
+ ce3 -- s3 [label="eth0\n.3"];
+
+ r1 -- s1 [label="eth0"];
+ r1 -- s4 [label="eth1\n.1"];
+ r1 -- s5 [label="eth2\n.1"];
+
+ r2 -- s2 [label="eth0"];
+ r2 -- s4 [label="eth1\n.2"];
+ r2 -- s6 [label="eth2\n.2"];
+
+ r3 -- s3 [label="eth0"];
+ r3 -- s5 [label="eth1\n.3"];
+ r3 -- s6 [label="eth2\n.3"];
+}
diff --git a/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py
new file mode 100755
index 0000000000..dc6a76eb49
--- /dev/null
+++ b/tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py
@@ -0,0 +1,429 @@
+#!/usr/bin/env python
+
+#
+# test_ldp_ospf_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by Volta Networks
+#
+# 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.
+#
+
+"""
+test_ldp_vpls_topo1.py:
+
+ +---------+ +---------+
+ | | | |
+ | CE1 | | CE2 |
+ | | | |
+ +---------+ +---------+
+ce1-eth0 (172.16.1.1/24)| |ce2-eth0 (172.16.1.2/24)
+ | |
+ | |
+ rt1-eth0| |rt2-eth0
+ +---------+ 10.0.1.0/24 +---------+
+ | |rt1-eth1 | |
+ | RT1 +----------------+ RT2 |
+ | 1.1.1.1 | rt2-eth1| 2.2.2.2 |
+ | | | |
+ +---------+ +---------+
+ rt1-eth2| |rt2-eth2
+ | |
+ | |
+ 10.0.2.0/24| +---------+ |10.0.3.0/24
+ | | | |
+ | | RT3 | |
+ +--------+ 3.3.3.3 +-------+
+ rt3-eth2| |rt3-eth1
+ +---------+
+ |rt3-eth0
+ |
+ |
+ ce3-eth0 (172.16.1.3/24)|
+ +---------+
+ | |
+ | CE3 |
+ | |
+ +---------+
+"""
+
+import os
+import sys
+import pytest
+import json
+from time import sleep
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+ "Test topology builder"
+
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ #
+ # Define FRR Routers
+ #
+ for router in ["ce1", "ce2", "ce3", "r1", "r2", "r3"]:
+ tgen.add_router(router)
+
+ #
+ # Define connections
+ #
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["ce1"])
+ switch.add_link(tgen.gears["r1"])
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["ce2"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["ce3"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r2"])
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["r1"])
+ switch.add_link(tgen.gears["r3"])
+
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["r2"])
+ switch.add_link(tgen.gears["r3"])
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(TemplateTopo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in router_list.iteritems():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ # Don't start ospfd and ldpd in the CE nodes
+ if router.name[0] == "r":
+ router.load_config(
+ TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname))
+ )
+
+ tgen.start_router()
+
+
+def teardown_module(mod):
+ "Teardown the pytest environment"
+ tgen = get_topogen()
+
+ # This function tears down the whole topology.
+ 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 80 seconds.
+ test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
+ _, diff = topotest.run_and_expect(test_func, None, count=160, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+ assert diff is None, assertmsg
+
+
+def test_ospf_convergence():
+ logger.info("Test: check OSPF adjacencies")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json"
+ )
+
+
+def test_rib():
+ logger.info("Test: verify RIB")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(rname, "show ip route json", "show_ip_route.ref")
+
+
+def test_ldp_adjacencies():
+ logger.info("Test: verify LDP adjacencies")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp discovery json", "show_ldp_discovery.ref"
+ )
+
+
+def test_ldp_neighbors():
+ logger.info("Test: verify LDP neighbors")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp neighbor json", "show_ldp_neighbor.ref"
+ )
+
+
+def test_ldp_bindings():
+ logger.info("Test: verify LDP bindings")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp binding json", "show_ldp_binding.ref"
+ )
+
+
+def test_ldp_pwid_bindings():
+ logger.info("Test: verify LDP PW-ID bindings")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom binding json", "show_l2vpn_binding.ref"
+ )
+
+
+def test_ldp_pseudowires():
+ logger.info("Test: verify LDP pseudowires")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
+ )
+
+def test_ldp_igp_sync():
+ logger.info("Test: verify LDP igp-sync")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+def test_ospf_ldp_sync():
+ logger.info("Test: verify OSPF igp-sync")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf interface json", "show_ip_ospf_interface.ref"
+ )
+
+
+def test_r1_eth1_shutdown():
+ logger.info("Test: verify behaviour after r1-eth1 is shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Shut down r1-r2 link */
+ tgen = get_topogen()
+ tgen.gears["r1"].peer_link_enable("r1-eth1", False)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ # check if the pseudowire is still up (using an alternate path for nexthop resolution)
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r1_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf interface json", "show_ip_ospf_interface_r1_eth1_shutdown.ref"
+ )
+
+def test_r1_eth1_no_shutdown():
+ logger.info("Test: verify behaviour after r1-eth1 is no shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Run no shutdown on r1-eth1 interface */
+ tgen = get_topogen()
+ tgen.gears["r1"].peer_link_enable("r1-eth1", True)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf interface json", "show_ip_ospf_interface.ref"
+ )
+
+def test_r2_eth1_shutdown():
+ logger.info("Test: verify behaviour after r2-eth1 is shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Shut down r1-r2 link */
+ tgen = get_topogen()
+ tgen.gears["r2"].peer_link_enable("r2-eth1", False)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r2_eth1_shutdown.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf interface json", "show_ip_ospf_interface_r2_eth1_shutdown.ref"
+ )
+
+def test_r2_eth1_no_shutdown():
+ logger.info("Test: verify behaviour after r2-eth1 is no shutdown")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ # Run no shutdown on r2-eth1 interface */
+ tgen = get_topogen()
+ tgen.gears["r2"].peer_link_enable("r2-eth1", True)
+ topotest.sleep(5, "Waiting for the network to reconverge")
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync.ref"
+ )
+
+ for rname in ["r1", "r2", "r3"]:
+ router_compare_json_output(
+ rname, "show ip ospf interface json", "show_ip_ospf_interface.ref"
+ )
+
+# 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/ldp-topo1/r1/ospfd.conf b/tests/topotests/ldp-topo1/r1/ospfd.conf
index 6daf034d18..87d5703d9e 100644
--- a/tests/topotests/ldp-topo1/r1/ospfd.conf
+++ b/tests/topotests/ldp-topo1/r1/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 1.1.1.1
network 0.0.0.0/0 area 0
!
+int r1-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-topo1/r2/ospfd.conf b/tests/topotests/ldp-topo1/r2/ospfd.conf
index 8678813665..dbed6189c8 100644
--- a/tests/topotests/ldp-topo1/r2/ospfd.conf
+++ b/tests/topotests/ldp-topo1/r2/ospfd.conf
@@ -5,3 +5,15 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-topo1/r3/ospfd.conf b/tests/topotests/ldp-topo1/r3/ospfd.conf
index 202be238ec..bd86fe4f24 100644
--- a/tests/topotests/ldp-topo1/r3/ospfd.conf
+++ b/tests/topotests/ldp-topo1/r3/ospfd.conf
@@ -6,3 +6,11 @@ router ospf
router-id 3.3.3.3
network 0.0.0.0/0 area 0
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-topo1/r4/ospfd.conf b/tests/topotests/ldp-topo1/r4/ospfd.conf
index 569dbc54e2..5aae885a12 100644
--- a/tests/topotests/ldp-topo1/r4/ospfd.conf
+++ b/tests/topotests/ldp-topo1/r4/ospfd.conf
@@ -5,3 +5,7 @@ router ospf
router-id 4.4.4.4
network 0.0.0.0/0 area 0
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-vpls-topo1/r1/ospfd.conf b/tests/topotests/ldp-vpls-topo1/r1/ospfd.conf
index 6daf034d18..76ea32fb61 100644
--- a/tests/topotests/ldp-vpls-topo1/r1/ospfd.conf
+++ b/tests/topotests/ldp-vpls-topo1/r1/ospfd.conf
@@ -5,3 +5,11 @@ router ospf
router-id 1.1.1.1
network 0.0.0.0/0 area 0
!
+int r1-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r1-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-vpls-topo1/r2/ospfd.conf b/tests/topotests/ldp-vpls-topo1/r2/ospfd.conf
index 8678813665..7b3ddfe371 100644
--- a/tests/topotests/ldp-vpls-topo1/r2/ospfd.conf
+++ b/tests/topotests/ldp-vpls-topo1/r2/ospfd.conf
@@ -5,3 +5,11 @@ router ospf
router-id 2.2.2.2
network 0.0.0.0/0 area 0
!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r2-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ldp-vpls-topo1/r3/ospfd.conf b/tests/topotests/ldp-vpls-topo1/r3/ospfd.conf
index b6bafba205..b424f2e108 100644
--- a/tests/topotests/ldp-vpls-topo1/r3/ospfd.conf
+++ b/tests/topotests/ldp-vpls-topo1/r3/ospfd.conf
@@ -5,3 +5,11 @@ router ospf
router-id 3.3.3.3
network 0.0.0.0/0 area 0
!
+int r3-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index 7b1eead944..53257525c6 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -46,6 +46,7 @@ from lib.common_config import (
LOGDIR = "/tmp/topotests/"
TMPDIR = None
+
def create_router_bgp(tgen, topo, input_dict=None, build=False, load_config=True):
"""
API to configure bgp on router
@@ -455,6 +456,15 @@ def __create_bgp_unicast_neighbor(
cmd = "no {}".format(cmd)
config_data.append(cmd)
+ import_vrf_data = addr_data.setdefault("import", {})
+ if import_vrf_data:
+ cmd = "import vrf {}".format(import_vrf_data["vrf"])
+
+ del_action = import_vrf_data.setdefault("delete", False)
+ if del_action:
+ cmd = "no {}".format(cmd)
+ config_data.append(cmd)
+
if "neighbor" in addr_data:
neigh_data = __create_bgp_neighbor(
topo, input_dict, router, addr_type, add_neigh
@@ -1219,11 +1229,17 @@ def verify_bgp_convergence(tgen, topo, dut=None):
no_of_peer += 1
if no_of_peer == total_peer:
- logger.info("[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
- router, vrf, addr_type)
+ logger.info(
+ "[DUT: %s] VRF: %s, BGP is Converged for %s address-family",
+ router,
+ vrf,
+ addr_type,
+ )
else:
- errormsg = ("[DUT: %s] VRF: %s, BGP is not converged for %s address-family" %
- (router, vrf, addr_type))
+ errormsg = (
+ "[DUT: %s] VRF: %s, BGP is not converged for %s address-family"
+ % (router, vrf, addr_type)
+ )
return errormsg
logger.debug("Exiting API: verify_bgp_convergence()")
@@ -2182,7 +2198,7 @@ def verify_bgp_attributes(
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_best_path_as_per_bgp_attribute(
tgen, addr_type, router, input_dict, attribute
):
@@ -2497,7 +2513,7 @@ def verify_best_path_as_per_admin_distance(
return True
-@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=6, wait=2, return_is_str=True)
def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None):
"""
This API is to verify whether bgp rib has any
@@ -2553,10 +2569,19 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
missing_routes = []
st_found = False
nh_found = False
+
vrf = static_route.setdefault("vrf", None)
+ community = static_route.setdefault("community", None)
+ largeCommunity = static_route.setdefault("largeCommunity", None)
+
if vrf:
cmd = "{} vrf {} {}".format(command, vrf, addr_type)
+ if community:
+ cmd = "{} community {}".format(cmd, community)
+
+ if largeCommunity:
+ cmd = "{} large-community {}".format(cmd, largeCommunity)
else:
cmd = "{} {}".format(command, addr_type)
@@ -2594,6 +2619,7 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
if not isinstance(next_hop, list):
next_hop = [next_hop]
list1 = next_hop
+
found_hops = [
rib_r["ip"]
for rib_r in rib_routes_json["routes"][st_rt][0][
@@ -2601,6 +2627,7 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
]
]
list2 = found_hops
+
missing_list_of_nexthops = set(list2).difference(list1)
additional_nexthops_in_required_nhs = set(
list1
@@ -2746,7 +2773,7 @@ def verify_bgp_rib(tgen, addr_type, dut, input_dict, next_hop=None, aspath=None)
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify verify_graceful_restart configuration of DUT and
@@ -2995,7 +3022,7 @@ def verify_graceful_restart(tgen, topo, addr_type, input_dict, dut, peer):
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify r_bit in the BGP gr capability advertised
@@ -3113,7 +3140,7 @@ def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer):
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_eor(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify EOR
@@ -3276,7 +3303,7 @@ def verify_eor(tgen, topo, addr_type, input_dict, dut, peer):
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify f_bit in the BGP gr capability advertised
@@ -3416,7 +3443,7 @@ def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer):
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer):
"""
This API is to verify graceful restart timers, configured and recieved
@@ -3542,7 +3569,7 @@ def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer)
return True
-@retry(attempts=4, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=5, wait=2, return_is_str=True)
def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut):
"""
This API is to verify gr_address_family in the BGP gr capability advertised
@@ -3632,7 +3659,7 @@ def verify_gr_address_family(tgen, topo, addr_type, addr_family, dut):
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
-@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=6, wait=2, return_is_str=True)
def verify_attributes_for_evpn_routes(
tgen,
topo,
@@ -4033,7 +4060,7 @@ def verify_attributes_for_evpn_routes(
return False
-@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=6, wait=2, return_is_str=True)
def verify_evpn_routes(
tgen, topo, dut, input_dict, routeType=5, EthTag=0, next_hop=None
):
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index e4d72ea2d7..45a86c7a3f 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -30,17 +30,25 @@ from functools import wraps
from re import search as re_search
from tempfile import mkdtemp
-import StringIO
import os
import sys
import ConfigParser
import traceback
import socket
import ipaddress
+import platform
+
+
+if sys.version_info[0] > 2:
+ import io
+ import configparser
+else:
+ import StringIO
+ import ConfigParser as configparser
from lib.topolog import logger, logger_config
from lib.topogen import TopoRouter, get_topogen
-from lib.topotest import interface_set_status
+from lib.topotest import interface_set_status, version_cmp
FRRCFG_FILE = "frr_json.conf"
FRRCFG_BKUP_FILE = "frr_json_initial.conf"
@@ -61,7 +69,7 @@ TMPDIR = None
# NOTE: to save execution logs to log file frrtest_log_dir must be configured
# in `pytest.ini`.
-config = ConfigParser.ConfigParser()
+config = configparser.ConfigParser()
config.read(PYTESTINI_PATH)
config_section = "topogen"
@@ -393,6 +401,14 @@ def check_router_status(tgen):
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
return True
+def getStrIO():
+ """
+ Return a StringIO object appropriate for the current python version.
+ """
+ if sys.version_info[0] > 2:
+ return io.StringIO()
+ else:
+ return StringIO.StringIO()
def reset_config_on_routers(tgen, routerName=None):
"""
@@ -465,7 +481,7 @@ def reset_config_on_routers(tgen, routerName=None):
raise InvalidCLIError("Unknown error in %s", output)
f = open(dname, "r")
- delta = StringIO.StringIO()
+ delta = getStrIO()
delta.write("configure terminal\n")
t_delta = f.read()
@@ -499,7 +515,7 @@ def reset_config_on_routers(tgen, routerName=None):
output = router.vtysh_multicmd(delta.getvalue(), pretty_output=False)
delta.close()
- delta = StringIO.StringIO()
+ delta = getStrIO()
cfg = router.run("vtysh -c 'show running'")
for line in cfg.split("\n"):
line = line.strip()
@@ -713,8 +729,8 @@ def start_topology(tgen):
os.chdir("{}/{}".format(TMPDIR, rname))
os.system("touch zebra.conf bgpd.conf")
- except IOError as (errno, strerror):
- logger.error("I/O error({0}): {1}".format(errno, strerror))
+ except IOError as err:
+ logger.error("I/O error({0}): {1}".format(err.errno, err.strerror))
# Loading empty zebra.conf file to router, to start the zebra deamon
router.load_config(
@@ -1224,7 +1240,8 @@ def interface_status(tgen, topo, input_dict):
return True
-def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict=False):
+def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0,
+ return_is_dict=False):
"""
Retries function execution, if return is an errormsg or exception
@@ -1236,11 +1253,13 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict
"""
def _retry(func):
+
@wraps(func)
def func_retry(*args, **kwargs):
- _wait = kwargs.pop("wait", wait)
- _attempts = kwargs.pop("attempts", attempts)
+ _wait = kwargs.pop('wait', wait)
+ _attempts = kwargs.pop('attempts', attempts)
_attempts = int(_attempts)
+ expected = True
if _attempts < 0:
raise ValueError("attempts must be 0 or greater")
@@ -1248,40 +1267,40 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict
logger.info("Waiting for [%s]s as initial delay", initial_wait)
sleep(initial_wait)
- _return_is_str = kwargs.pop("return_is_str", return_is_str)
- _return_is_dict = kwargs.pop("return_is_str", return_is_dict)
+ _return_is_str = kwargs.pop('return_is_str', return_is_str)
+ _return_is_dict = kwargs.pop('return_is_str', return_is_dict)
for i in range(1, _attempts + 1):
try:
- _expected = kwargs.setdefault("expected", True)
- kwargs.pop("expected")
+ _expected = kwargs.setdefault('expected', True)
+ if _expected is False:
+ expected = _expected
+ kwargs.pop('expected')
ret = func(*args, **kwargs)
- logger.debug("Function returned %s" % ret)
+ logger.debug("Function returned %s", ret)
if _return_is_str and isinstance(ret, bool) and _expected:
return ret
- if (
- isinstance(ret, str) or isinstance(ret, unicode)
- ) and _expected is False:
+ if (isinstance(ret, str) or isinstance(ret, unicode)) and _expected is False:
return ret
if _return_is_dict and isinstance(ret, dict):
return ret
- if _attempts == i:
+ if _attempts == i and expected:
generate_support_bundle()
return ret
except Exception as err:
- if _attempts == i:
+ if _attempts == i and expected:
generate_support_bundle()
- logger.info("Max number of attempts (%r) reached", _attempts)
+ logger.info("Max number of attempts (%r) reached",
+ _attempts)
raise
else:
logger.info("Function returned %s", err)
if i < _attempts:
- logger.info("Retry [#%r] after sleeping for %ss" % (i, _wait))
+ logger.info("Retry [#%r] after sleeping for %ss"
+ % (i, _wait))
sleep(_wait)
-
func_retry._original = func
return func_retry
-
return _retry
@@ -2191,7 +2210,7 @@ def addKernelRoute(
if mask == "32" or mask == "128":
grp_addr = ip
- if not re_search(r"{}".format(grp_addr), result) and mask is not "0":
+ if not re_search(r"{}".format(grp_addr), result) and mask != "0":
errormsg = (
"[DUT: {}]: Kernal route is not added for group"
" address {} Config output: {}".format(router, grp_addr, output)
@@ -2352,7 +2371,9 @@ def configure_brctl(tgen, topo, input_dict):
):
ip_cmd_list = []
- cmd = "ip link add name {} type bridge stp_state {}".format(brctl_name, stp)
+ cmd = "ip link add name {} type bridge stp_state {}".format(
+ brctl_name, stp
+ )
logger.info("[DUT: %s]: Running command: %s", dut, cmd)
rnode.run(cmd)
@@ -2443,7 +2464,7 @@ def configure_interface_mac(tgen, input_dict):
#############################################
# Verification APIs
#############################################
-@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+@retry(attempts=6, wait=2, return_is_str=True)
def verify_rib(
tgen,
addr_type,
@@ -2502,7 +2523,7 @@ def verify_rib(
errormsg(str) or True
"""
- logger.info("Entering lib API: verify_rib()")
+ logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
router_list = tgen.routers()
additional_nexthops_in_required_nhs = []
@@ -2817,7 +2838,517 @@ def verify_rib(
" routes are: {}\n".format(addr_type, dut, found_routes)
)
- logger.info("Exiting lib API: verify_rib()")
+ logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
+ return True
+
+
+@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
+ """
+ Data will be read from input_dict or input JSON file, API will generate
+ same prefixes, which were redistributed by either create_static_routes() or
+ advertise_networks_using_network_command() and will verify next_hop and
+ each prefix/routes is present in "show ip/ipv6 fib json"
+ command o/p.
+
+ Parameters
+ ----------
+ * `tgen` : topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test, for which user wants to test the data
+ * `input_dict` : input dict, has details of static routes
+ * `next_hop`[optional]: next_hop which needs to be verified,
+ default: static
+
+ Usage
+ -----
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": ["1.1.1.1/32],
+ "next_hop": "Null0",
+ "vrf": "RED"
+ }]
+ }
+ }
+ result = result = verify_fib_routes(tgen, "ipv4, "r1", input_routes_r1)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
+
+ router_list = tgen.routers()
+ for routerInput in input_dict.keys():
+ for router, rnode in router_list.iteritems():
+ if router != dut:
+ continue
+
+ logger.info("Checking router %s FIB routes:", router)
+
+ # Verifying RIB routes
+ if addr_type == "ipv4":
+ command = "show ip fib"
+ else:
+ command = "show ipv6 fib"
+
+ found_routes = []
+ missing_routes = []
+
+ if "static_routes" in input_dict[routerInput]:
+ static_routes = input_dict[routerInput]["static_routes"]
+
+ for static_route in static_routes:
+ if "vrf" in static_route and static_route["vrf"] is not None:
+
+ logger.info(
+ "[DUT: {}]: Verifying routes for VRF:"
+ " {}".format(router, static_route["vrf"])
+ )
+
+ cmd = "{} vrf {}".format(command, static_route["vrf"])
+
+ else:
+ cmd = "{}".format(command)
+
+ cmd = "{} json".format(cmd)
+
+ rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
+
+ # Verifying output dictionary rib_routes_json is not empty
+ if bool(rib_routes_json) is False:
+ errormsg = "[DUT: {}]: No route found in fib".format(router)
+ return errormsg
+
+ network = static_route["network"]
+ if "no_of_ip" in static_route:
+ no_of_ip = static_route["no_of_ip"]
+ else:
+ no_of_ip = 1
+
+ # Generating IPs for verification
+ ip_list = generate_ips(network, no_of_ip)
+ st_found = False
+ nh_found = False
+
+ for st_rt in ip_list:
+ st_rt = str(ipaddress.ip_network(unicode(st_rt)))
+ #st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
+
+ _addr_type = validate_ip_address(st_rt)
+ if _addr_type != addr_type:
+ continue
+
+ if st_rt in rib_routes_json:
+ st_found = True
+ found_routes.append(st_rt)
+
+ if next_hop:
+ if type(next_hop) is not list:
+ next_hop = [next_hop]
+
+ count = 0
+ for nh in next_hop:
+ for nh_dict in rib_routes_json[st_rt][0][
+ "nexthops"
+ ]:
+ if nh_dict["ip"] != nh:
+ continue
+ else:
+ count += 1
+
+ if count == len(next_hop):
+ nh_found = True
+ else:
+ missing_routes.append(st_rt)
+ errormsg = (
+ "Nexthop {} is Missing"
+ " for route {} in "
+ "RIB of router {}\n".format(
+ next_hop, st_rt, dut
+ )
+ )
+ return errormsg
+
+ else:
+ missing_routes.append(st_rt)
+
+ if len(missing_routes) > 0:
+ errormsg = "[DUT: {}]: Missing route in FIB:" " {}".format(
+ dut, missing_routes
+ )
+ return errormsg
+
+ if nh_found:
+ logger.info(
+ "Found next_hop {} for all routes in RIB"
+ " of router {}\n".format(next_hop, dut)
+ )
+
+ if found_routes:
+ logger.info(
+ "[DUT: %s]: Verified routes in FIB, found" " routes are: %s\n",
+ dut,
+ found_routes,
+ )
+
+ continue
+
+ if "bgp" in input_dict[routerInput]:
+ if (
+ "advertise_networks"
+ not in input_dict[routerInput]["bgp"]["address_family"][addr_type][
+ "unicast"
+ ]
+ ):
+ continue
+
+ found_routes = []
+ missing_routes = []
+ advertise_network = input_dict[routerInput]["bgp"]["address_family"][
+ addr_type
+ ]["unicast"]["advertise_networks"]
+
+ # Continue if there are no network advertise
+ if len(advertise_network) == 0:
+ continue
+
+ for advertise_network_dict in advertise_network:
+ if "vrf" in advertise_network_dict:
+ cmd = "{} vrf {} json".format(command, static_route["vrf"])
+ else:
+ cmd = "{} json".format(command)
+
+ rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
+
+ # Verifying output dictionary rib_routes_json is not empty
+ if bool(rib_routes_json) is False:
+ errormsg = "No route found in rib of router {}..".format(router)
+ return errormsg
+
+ start_ip = advertise_network_dict["network"]
+ if "no_of_network" in advertise_network_dict:
+ no_of_network = advertise_network_dict["no_of_network"]
+ else:
+ no_of_network = 1
+
+ # Generating IPs for verification
+ ip_list = generate_ips(start_ip, no_of_network)
+ st_found = False
+ nh_found = False
+
+ for st_rt in ip_list:
+ #st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
+ st_rt = str(ipaddress.ip_network(unicode(st_rt)))
+
+ _addr_type = validate_ip_address(st_rt)
+ if _addr_type != addr_type:
+ continue
+
+ if st_rt in rib_routes_json:
+ st_found = True
+ found_routes.append(st_rt)
+
+ if next_hop:
+ if type(next_hop) is not list:
+ next_hop = [next_hop]
+
+ count = 0
+ for nh in next_hop:
+ for nh_dict in rib_routes_json[st_rt][0]["nexthops"]:
+ if nh_dict["ip"] != nh:
+ continue
+ else:
+ count += 1
+
+ if count == len(next_hop):
+ nh_found = True
+ else:
+ missing_routes.append(st_rt)
+ errormsg = (
+ "Nexthop {} is Missing"
+ " for route {} in "
+ "RIB of router {}\n".format(next_hop, st_rt, dut)
+ )
+ return errormsg
+ else:
+ missing_routes.append(st_rt)
+
+ if len(missing_routes) > 0:
+ errormsg = "[DUT: {}]: Missing route in FIB: " "{} \n".format(
+ dut, missing_routes
+ )
+ return errormsg
+
+ if nh_found:
+ logger.info(
+ "Found next_hop {} for all routes in RIB"
+ " of router {}\n".format(next_hop, dut)
+ )
+
+ if found_routes:
+ logger.info(
+ "[DUT: {}]: Verified routes FIB"
+ ", found routes are: {}\n".format(dut, found_routes)
+ )
+
+ logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
+ return True
+
+
+@retry(attempts=5, wait=2, return_is_str=True, initial_wait=2)
+def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
+ """
+ Data will be read from input_dict or input JSON file, API will generate
+ same prefixes, which were redistributed by either create_static_routes() or
+ advertise_networks_using_network_command() and will verify next_hop and
+ each prefix/routes is present in "show ip/ipv6 fib json"
+ command o/p.
+
+ Parameters
+ ----------
+ * `tgen` : topogen object
+ * `addr_type` : ip type, ipv4/ipv6
+ * `dut`: Device Under Test, for which user wants to test the data
+ * `input_dict` : input dict, has details of static routes
+ * `next_hop`[optional]: next_hop which needs to be verified,
+ default: static
+
+ Usage
+ -----
+ input_routes_r1 = {
+ "r1": {
+ "static_routes": [{
+ "network": ["1.1.1.1/32],
+ "next_hop": "Null0",
+ "vrf": "RED"
+ }]
+ }
+ }
+ result = result = verify_fib_routes(tgen, "ipv4, "r1", input_routes_r1)
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+
+ logger.debug("Entering lib API: {}".format(sys._getframe().f_code.co_name))
+
+ router_list = tgen.routers()
+ for routerInput in input_dict.keys():
+ for router, rnode in router_list.iteritems():
+ if router != dut:
+ continue
+
+ logger.info("Checking router %s FIB routes:", router)
+
+ # Verifying RIB routes
+ if addr_type == "ipv4":
+ command = "show ip fib"
+ else:
+ command = "show ipv6 fib"
+
+ found_routes = []
+ missing_routes = []
+
+ if "static_routes" in input_dict[routerInput]:
+ static_routes = input_dict[routerInput]["static_routes"]
+
+ for static_route in static_routes:
+ if "vrf" in static_route and static_route["vrf"] is not None:
+
+ logger.info(
+ "[DUT: {}]: Verifying routes for VRF:"
+ " {}".format(router, static_route["vrf"])
+ )
+
+ cmd = "{} vrf {}".format(command, static_route["vrf"])
+
+ else:
+ cmd = "{}".format(command)
+
+ cmd = "{} json".format(cmd)
+
+ rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
+
+ # Verifying output dictionary rib_routes_json is not empty
+ if bool(rib_routes_json) is False:
+ errormsg = "[DUT: {}]: No route found in fib".format(router)
+ return errormsg
+
+ network = static_route["network"]
+ if "no_of_ip" in static_route:
+ no_of_ip = static_route["no_of_ip"]
+ else:
+ no_of_ip = 1
+
+ # Generating IPs for verification
+ ip_list = generate_ips(network, no_of_ip)
+ st_found = False
+ nh_found = False
+
+ for st_rt in ip_list:
+ st_rt = str(ipaddress.ip_network(unicode(st_rt)))
+
+ _addr_type = validate_ip_address(st_rt)
+ if _addr_type != addr_type:
+ continue
+
+ if st_rt in rib_routes_json:
+ st_found = True
+ found_routes.append(st_rt)
+
+ if next_hop:
+ if type(next_hop) is not list:
+ next_hop = [next_hop]
+
+ count = 0
+ for nh in next_hop:
+ for nh_dict in rib_routes_json[st_rt][0][
+ "nexthops"
+ ]:
+ if nh_dict["ip"] != nh:
+ continue
+ else:
+ count += 1
+
+ if count == len(next_hop):
+ nh_found = True
+ else:
+ missing_routes.append(st_rt)
+ errormsg = (
+ "Nexthop {} is Missing"
+ " for route {} in "
+ "RIB of router {}\n".format(
+ next_hop, st_rt, dut
+ )
+ )
+ return errormsg
+
+ else:
+ missing_routes.append(st_rt)
+
+ if len(missing_routes) > 0:
+ errormsg = "[DUT: {}]: Missing route in FIB:" " {}".format(
+ dut, missing_routes
+ )
+ return errormsg
+
+ if nh_found:
+ logger.info(
+ "Found next_hop {} for all routes in RIB"
+ " of router {}\n".format(next_hop, dut)
+ )
+
+ if found_routes:
+ logger.info(
+ "[DUT: %s]: Verified routes in FIB, found" " routes are: %s\n",
+ dut,
+ found_routes,
+ )
+
+ continue
+
+ if "bgp" in input_dict[routerInput]:
+ if (
+ "advertise_networks"
+ not in input_dict[routerInput]["bgp"]["address_family"][addr_type][
+ "unicast"
+ ]
+ ):
+ continue
+
+ found_routes = []
+ missing_routes = []
+ advertise_network = input_dict[routerInput]["bgp"]["address_family"][
+ addr_type
+ ]["unicast"]["advertise_networks"]
+
+ # Continue if there are no network advertise
+ if len(advertise_network) == 0:
+ continue
+
+ for advertise_network_dict in advertise_network:
+ if "vrf" in advertise_network_dict:
+ cmd = "{} vrf {} json".format(command, static_route["vrf"])
+ else:
+ cmd = "{} json".format(command)
+
+ rib_routes_json = run_frr_cmd(rnode, cmd, isjson=True)
+
+ # Verifying output dictionary rib_routes_json is not empty
+ if bool(rib_routes_json) is False:
+ errormsg = "No route found in rib of router {}..".format(router)
+ return errormsg
+
+ start_ip = advertise_network_dict["network"]
+ if "no_of_network" in advertise_network_dict:
+ no_of_network = advertise_network_dict["no_of_network"]
+ else:
+ no_of_network = 1
+
+ # Generating IPs for verification
+ ip_list = generate_ips(start_ip, no_of_network)
+ st_found = False
+ nh_found = False
+
+ for st_rt in ip_list:
+ st_rt = str(ipaddress.ip_network(unicode(st_rt)))
+
+ _addr_type = validate_ip_address(st_rt)
+ if _addr_type != addr_type:
+ continue
+
+ if st_rt in rib_routes_json:
+ st_found = True
+ found_routes.append(st_rt)
+
+ if next_hop:
+ if type(next_hop) is not list:
+ next_hop = [next_hop]
+
+ count = 0
+ for nh in next_hop:
+ for nh_dict in rib_routes_json[st_rt][0]["nexthops"]:
+ if nh_dict["ip"] != nh:
+ continue
+ else:
+ count += 1
+
+ if count == len(next_hop):
+ nh_found = True
+ else:
+ missing_routes.append(st_rt)
+ errormsg = (
+ "Nexthop {} is Missing"
+ " for route {} in "
+ "RIB of router {}\n".format(next_hop, st_rt, dut)
+ )
+ return errormsg
+ else:
+ missing_routes.append(st_rt)
+
+ if len(missing_routes) > 0:
+ errormsg = "[DUT: {}]: Missing route in FIB: " "{} \n".format(
+ dut, missing_routes
+ )
+ return errormsg
+
+ if nh_found:
+ logger.info(
+ "Found next_hop {} for all routes in RIB"
+ " of router {}\n".format(next_hop, dut)
+ )
+
+ if found_routes:
+ logger.info(
+ "[DUT: {}]: Verified routes FIB"
+ ", found routes are: {}\n".format(dut, found_routes)
+ )
+
+ logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
return True
@@ -2966,7 +3497,7 @@ def verify_prefix_lists(tgen, input_dict):
return True
-@retry(attempts=2, wait=4, return_is_str=True, initial_wait=2)
+@retry(attempts=3, wait=4, return_is_str=True)
def verify_route_maps(tgen, input_dict):
"""
Running "show route-map" command and verifying given route-map
@@ -3217,7 +3748,7 @@ def verify_cli_json(tgen, input_dict):
return True
-@retry(attempts=2, wait=4, return_is_str=True, initial_wait=2)
+@retry(attempts=3, wait=4, return_is_str=True)
def verify_evpn_vni(tgen, input_dict):
"""
API to verify evpn vni details using "show evpn vni detail json"
@@ -3335,7 +3866,7 @@ def verify_evpn_vni(tgen, input_dict):
return False
-@retry(attempts=2, wait=4, return_is_str=True, initial_wait=2)
+@retry(attempts=3, wait=4, return_is_str=True)
def verify_vrf_vni(tgen, input_dict):
"""
API to verify vrf vni details using "show vrf vni json"
@@ -3444,3 +3975,30 @@ def verify_vrf_vni(tgen, input_dict):
logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
return False
+
+
+def required_linux_kernel_version(required_version):
+ """
+ This API is used to check linux version compatibility of the test suite.
+ If version mentioned in required_version is higher than the linux kernel
+ of the system, test suite will be skipped. This API returns true or errormsg.
+
+ Parameters
+ ----------
+ * `required_version` : Kernel version required for the suites to run.
+
+ Usage
+ -----
+ result = linux_kernel_version_lowerthan('4.15')
+
+ Returns
+ -------
+ errormsg(str) or True
+ """
+ system_kernel = platform.release()
+ if version_cmp(system_kernel, required_version) < 0:
+ error_msg = ('These tests will not run on kernel "{}", '
+ 'they require kernel >= {})'.format(system_kernel,
+ required_version ))
+ return error_msg
+ return True
diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py
index 37b9715010..a6cc5280ec 100644
--- a/tests/topotests/lib/topogen.py
+++ b/tests/topotests/lib/topogen.py
@@ -335,9 +335,7 @@ class Topogen(object):
logger.info("stopping topology: {}".format(self.modname))
errors = ""
for gear in self.gears.values():
- gear.stop(False, False)
- for gear in self.gears.values():
- errors += gear.stop(True, False)
+ errors += gear.stop()
if len(errors) > 0:
assert "Errors found post shutdown - details follow:" == 0, errors
@@ -703,14 +701,26 @@ class TopoRouter(TopoGear):
return result
- def stop(self, wait=True, assertOnError=True):
+ def __stop_internal(self, wait=True, assertOnError=True):
"""
- Stop router:
+ Stop router, private internal version
* Kill daemons
"""
- self.logger.debug("stopping")
+ self.logger.debug("stopping: wait {}, assert {}".format(
+ wait, assertOnError))
return self.tgen.net[self.name].stopRouter(wait, assertOnError)
+
+ def stop(self):
+ """
+ Stop router cleanly:
+ * Signal daemons twice, once without waiting, and then a second time
+ with a wait to ensure the daemons exit cleanly
+ """
+ self.logger.debug("stopping")
+ self.__stop_internal(False, False)
+ return self.__stop_internal()
+
def startDaemons(self, daemons):
"""
Start Daemons: to start specific daemon(user defined daemon only)
@@ -819,8 +829,7 @@ class TopoRouter(TopoGear):
if memleak_file is None:
return
- self.stop(False, False)
- self.stop(wait=True)
+ self.stop()
self.logger.info("running memory leak report")
self.tgen.net[self.name].report_memory_leaks(memleak_file, testname)
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index b5fa2ea59b..e34d1cf0be 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -29,7 +29,6 @@ import re
import sys
import functools
import glob
-import StringIO
import subprocess
import tempfile
import platform
@@ -721,6 +720,49 @@ def ip4_route(node):
return result
+def ip4_vrf_route(node):
+ """
+ Gets a structured return of the command 'ip route show vrf {0}-cust1'.
+ It can be used in conjuction with json_cmp() to provide accurate assert explanations.
+
+ Return example:
+ {
+ '10.0.1.0/24': {
+ 'dev': 'eth0',
+ 'via': '172.16.0.1',
+ 'proto': '188',
+ },
+ '10.0.2.0/24': {
+ 'dev': 'eth1',
+ 'proto': 'kernel',
+ }
+ }
+ """
+ output = normalize_text(
+ node.run("ip route show vrf {0}-cust1".format(node.name))).splitlines()
+
+ result = {}
+ for line in output:
+ columns = line.split(" ")
+ route = result[columns[0]] = {}
+ prev = None
+ for column in columns:
+ if prev == "dev":
+ route["dev"] = column
+ if prev == "via":
+ route["via"] = column
+ if prev == "proto":
+ # translate protocol names back to numbers
+ route["proto"] = proto_name_to_number(column)
+ if prev == "metric":
+ route["metric"] = column
+ if prev == "scope":
+ route["scope"] = column
+ prev = column
+
+ return result
+
+
def ip6_route(node):
"""
Gets a structured return of the command 'ip -6 route'. It can be used in
@@ -761,6 +803,47 @@ def ip6_route(node):
return result
+def ip6_vrf_route(node):
+ """
+ Gets a structured return of the command 'ip -6 route show vrf {0}-cust1'.
+ It can be used in conjuction with json_cmp() to provide accurate assert explanations.
+
+ Return example:
+ {
+ '2001:db8:1::/64': {
+ 'dev': 'eth0',
+ 'proto': '188',
+ },
+ '2001:db8:2::/64': {
+ 'dev': 'eth1',
+ 'proto': 'kernel',
+ }
+ }
+ """
+ output = normalize_text(
+ node.run("ip -6 route show vrf {0}-cust1".format(node.name))).splitlines()
+ result = {}
+ for line in output:
+ columns = line.split(" ")
+ route = result[columns[0]] = {}
+ prev = None
+ for column in columns:
+ if prev == "dev":
+ route["dev"] = column
+ if prev == "via":
+ route["via"] = column
+ if prev == "proto":
+ # translate protocol names back to numbers
+ route["proto"] = proto_name_to_number(column)
+ if prev == "metric":
+ route["metric"] = column
+ if prev == "pref":
+ route["pref"] = column
+ prev = column
+
+ return result
+
+
def ip_rules(node):
"""
Gets a structured return of the command 'ip rule'. It can be used in
@@ -1013,12 +1096,9 @@ class Router(Node):
self.cmd("chown {0}:{0}vty /etc/{0}".format(self.routertype))
def terminate(self):
- # Delete Running Quagga or FRR Daemons
+ # Stop running FRR daemons
self.stopRouter()
- # rundaemons = self.cmd('ls -1 /var/run/%s/*.pid' % self.routertype)
- # for d in StringIO.StringIO(rundaemons):
- # self.cmd('kill -7 `cat %s`' % d.rstrip())
- # self.waitOutput()
+
# Disable forwarding
set_sysctl(self, "net.ipv4.ip_forward", 0)
set_sysctl(self, "net.ipv6.conf.all.forwarding", 0)
@@ -1033,10 +1113,12 @@ class Router(Node):
if re.search(r"No such file or directory", rundaemons):
return 0
if rundaemons is not None:
- for d in StringIO.StringIO(rundaemons):
+ bet = rundaemons.split('\n')
+ for d in bet[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
ret.append(os.path.basename(d.rstrip().rsplit(".", 1)[0]))
+
return ret
def stopRouter(self, wait=True, assertOnError=True, minErrorVersion="5.1"):
@@ -1046,7 +1128,9 @@ class Router(Node):
if re.search(r"No such file or directory", rundaemons):
return errors
if rundaemons is not None:
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
daemonname = os.path.basename(d.rstrip().rsplit(".", 1)[0])
@@ -1080,7 +1164,9 @@ class Router(Node):
if running:
# 2nd round of kill if daemons didn't exit
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
logger.info(
@@ -1265,7 +1351,7 @@ class Router(Node):
zebra_path = os.path.join(self.daemondir, "zebra")
zebra_option = self.daemons_options["zebra"]
self.cmd(
- "{0} {1} --log stdout --log-level debug -d > zebra.out 2> zebra.err".format(
+ "{0} {1} --log stdout --log-level debug -s 90000000 -d > zebra.out 2> zebra.err".format(
zebra_path, zebra_option, self.logdir, self.name
)
)
@@ -1330,7 +1416,9 @@ class Router(Node):
for daemon in daemons:
if rundaemons is not None and daemon in rundaemons:
numRunning = 0
- for d in StringIO.StringIO(rundaemons):
+ dmns = rundaemons.split('\n')
+ # Exclude empty string at end of list
+ for d in dmns[:-1]:
if re.search(r"%s" % daemon, d):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(int(daemonpid)):
@@ -1351,8 +1439,9 @@ class Router(Node):
self.name, daemon
),
)
+
# 2nd round of kill if daemons didn't exit
- for d in StringIO.StringIO(rundaemons):
+ for d in dmns[:-1]:
if re.search(r"%s" % daemon, d):
daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
if daemonpid.isdigit() and pid_exists(
diff --git a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
index 0416bd6ce2..952a26ed10 100644
--- a/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r1/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -34,6 +36,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -47,12 +51,12 @@
"inputLabel":20400,
"prefixRoute":[
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r1-eth0",
"nexthop":"10.0.0.2"
},
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r1-eth1",
"nexthop":"10.0.1.2"
}
@@ -64,8 +68,14 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
@@ -73,12 +83,12 @@
"inputLabel":20300,
"prefixRoute":[
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r1-eth0",
"nexthop":"10.0.0.2"
},
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r1-eth1",
"nexthop":"10.0.1.2"
}
@@ -90,6 +100,8 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -100,10 +112,10 @@
{
"prefix":"10.0.255.1\/32",
"sid":100,
- "inputLabel":20100,
+ "inputLabel":0,
"prefixRoute":[
{
- "outputLabel":3,
+ "outputLabel":0,
"interface":"lo",
"nexthop":"10.0.255.1"
}
diff --git a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
index 292d4e6367..0773153a76 100644
--- a/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r1/ospfd.conf
@@ -1,13 +1,18 @@
+debug ospf sr
!
interface lo
ip ospf area 0.0.0.0
!
interface r1-eth0
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
interface r1-eth1
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
router ospf
@@ -17,6 +22,6 @@ router ospf
segment-routing on
segment-routing node-msd 16
segment-routing global-block 20000 29999
- segment-routing prefix 10.0.255.1/32 index 100 no-php-flag
+ segment-routing prefix 10.0.255.1/32 index 100 explicit-null
!
diff --git a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
index dd42e326ce..6c87596acb 100644
--- a/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r1/zebra_mpls.json
@@ -1,20 +1,5 @@
[
{
- "inLabel":20100,
- "installed":true,
- "nexthops":[
- {
- "type":"SR (OSPF)",
- "outLabel":3,
- "outLabelStack":[
- 3
- ],
- "distance":150,
- "installed":true
- }
- ]
- },
- {
"inLabel":20200,
"installed":true,
"nexthops":[
@@ -43,20 +28,13 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8300,
+ "outLabel":16300,
"outLabelStack":[
- 8300
+ 16300
],
"distance":150,
"installed":true,
"nexthop":"10.0.1.2"
- },
- {
- "type":"SR (OSPF)",
- "outLabel":8300,
- "distance":150,
- "installed":true,
- "nexthop":"10.0.0.2"
}
]
},
@@ -66,20 +44,13 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8400,
+ "outLabel":16400,
"outLabelStack":[
- 8400
+ 16400
],
"distance":150,
"installed":true,
"nexthop":"10.0.1.2"
- },
- {
- "type":"SR (OSPF)",
- "outLabel":8400,
- "distance":150,
- "installed":true,
- "nexthop":"10.0.0.2"
}
]
},
diff --git a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
index eb202b82cd..1de780d84e 100644
--- a/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r2/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -95,13 +97,19 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":12,
"extendedPrefix":[
{
"prefix":"10.0.255.4\/32",
"sid":400,
- "inputLabel":8400,
+ "inputLabel":16400,
"prefixRoute":[
{
"outputLabel":10400,
@@ -116,13 +124,19 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
"sid":300,
- "inputLabel":8300,
+ "inputLabel":16300,
"prefixRoute":[
{
"outputLabel":3,
@@ -137,21 +151,27 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":16,
"extendedPrefix":[
{
"prefix":"10.0.255.1\/32",
"sid":100,
- "inputLabel":8100,
+ "inputLabel":16100,
"prefixRoute":[
{
- "outputLabel":20100,
+ "outputLabel":0,
"interface":"r2-eth0",
"nexthop":"10.0.0.1"
},
{
- "outputLabel":20100,
+ "outputLabel":0,
"interface":"r2-eth1",
"nexthop":"10.0.1.1"
}
diff --git a/tests/topotests/ospf-sr-topo1/r2/ospfd.conf b/tests/topotests/ospf-sr-topo1/r2/ospfd.conf
index b8c7b999e8..92dc2f7cd1 100644
--- a/tests/topotests/ospf-sr-topo1/r2/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r2/ospfd.conf
@@ -6,17 +6,25 @@ interface lo
!
interface r2-eth0
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
interface r2-eth1
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
interface r2-eth2
ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
interface r2-eth3
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
router ospf
diff --git a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
index f3462e239e..a885e88fc5 100644
--- a/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r2/zebra_mpls.json
@@ -1,13 +1,13 @@
[
{
- "inLabel":8100,
+ "inLabel":16100,
"installed":true,
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":20100,
+ "outLabel":0,
"outLabelStack":[
- 20100
+ 0
],
"distance":150,
"installed":true,
@@ -15,7 +15,7 @@
},
{
"type":"SR (OSPF)",
- "outLabel":20100,
+ "outLabel":0,
"distance":150,
"installed":true,
"nexthop":"10.0.0.1"
@@ -23,7 +23,7 @@
]
},
{
- "inLabel":8300,
+ "inLabel":16300,
"installed":true,
"nexthops":[
{
@@ -39,7 +39,7 @@
]
},
{
- "inLabel":8400,
+ "inLabel":16400,
"installed":true,
"nexthops":[
{
diff --git a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
index b36fe674ad..e7371ff593 100644
--- a/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r3/ospf_srdb.json
@@ -3,8 +3,10 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -29,6 +31,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -42,7 +46,7 @@
"inputLabel":10400,
"prefixRoute":[
{
- "outputLabel":8400,
+ "outputLabel":16400,
"interface":"r3-eth0",
"nexthop":"10.0.3.2"
}
@@ -54,6 +58,8 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -97,6 +103,8 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
{
"0":"SPF"
@@ -110,7 +118,7 @@
"inputLabel":10100,
"prefixRoute":[
{
- "outputLabel":8100,
+ "outputLabel":16100,
"interface":"r3-eth0",
"nexthop":"10.0.3.2"
}
diff --git a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
index cf274bed2e..e2766f202d 100644
--- a/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r3/ospfd.conf
@@ -1,9 +1,13 @@
!
interface lo
ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
interface r3-eth0
ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
!
router ospf
@@ -11,6 +15,7 @@ router ospf
capability opaque
router-info area 0.0.0.0
segment-routing on
+ segment-routing local-block 5000 5999
segment-routing global-block 10000 19999
segment-routing node-msd 8
segment-routing prefix 10.0.255.3/32 index 300
diff --git a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
index 3d036801d5..1b98ff4756 100644
--- a/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r3/zebra_mpls.json
@@ -5,9 +5,9 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8100,
+ "outLabel":16100,
"outLabelStack":[
- 8100
+ 16100
],
"distance":150,
"installed":true,
@@ -37,9 +37,9 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8400,
+ "outLabel":16400,
"outLabelStack":[
- 8400
+ 16400
],
"distance":150,
"installed":true,
diff --git a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
index d92ec91c72..a241b32607 100644
--- a/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
+++ b/tests/topotests/ospf-sr-topo1/r4/ospf_srdb.json
@@ -3,9 +3,14 @@
"srNodes":[
{
"routerID":"10.0.255.2",
- "srgbSize":20000,
- "srgbLabel":8000,
+ "srgbSize":8000,
+ "srgbLabel":16000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
"extendedPrefix":[
{
@@ -26,6 +31,8 @@
"routerID":"10.0.255.4",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
{
"0":"SPF"
@@ -69,8 +76,14 @@
"routerID":"10.0.255.3",
"srgbSize":10000,
"srgbLabel":10000,
+ "srlbSize":1000,
+ "srlbLabel":5000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":8,
"extendedPrefix":[
{
"prefix":"10.0.255.3\/32",
@@ -78,7 +91,7 @@
"inputLabel":10300,
"prefixRoute":[
{
- "outputLabel":8300,
+ "outputLabel":16300,
"interface":"r4-eth0",
"nexthop":"10.0.4.2"
}
@@ -90,8 +103,14 @@
"routerID":"10.0.255.1",
"srgbSize":10000,
"srgbLabel":20000,
+ "srlbSize":1000,
+ "srlbLabel":15000,
"algorithms":[
+ {
+ "0":"SPF"
+ }
],
+ "nodeMsd":16,
"extendedPrefix":[
{
"prefix":"10.0.255.1\/32",
@@ -99,7 +118,7 @@
"inputLabel":10100,
"prefixRoute":[
{
- "outputLabel":8100,
+ "outputLabel":16100,
"interface":"r4-eth0",
"nexthop":"10.0.4.2"
}
diff --git a/tests/topotests/ospf-sr-topo1/r4/ospfd.conf b/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
index 65fdce69f7..e80880af88 100644
--- a/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
+++ b/tests/topotests/ospf-sr-topo1/r4/ospfd.conf
@@ -1,9 +1,13 @@
!
interface lo
ip ospf area 0.0.0.0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
interface r4-eth0
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
ip ospf area 0.0.0.0
!
!
@@ -12,6 +16,7 @@ router ospf
capability opaque
router-info area 0.0.0.0
segment-routing on
+ segment-routing local-block 5000 5999
segment-routing global-block 10000 19999
segment-routing node-msd 12
segment-routing prefix 10.0.255.4/32 index 400 no-php-flag
diff --git a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
index 86ad8721f8..b5758f29a0 100644
--- a/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
+++ b/tests/topotests/ospf-sr-topo1/r4/zebra_mpls.json
@@ -5,9 +5,9 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8100,
+ "outLabel":16100,
"outLabelStack":[
- 8100
+ 16100
],
"distance":150,
"installed":true,
@@ -37,9 +37,9 @@
"nexthops":[
{
"type":"SR (OSPF)",
- "outLabel":8300,
+ "outLabel":16300,
"outLabelStack":[
- 8300
+ 16300
],
"distance":150,
"installed":true,
diff --git a/tests/topotests/ospf-topo1/r1/ospf6d.conf b/tests/topotests/ospf-topo1/r1/ospf6d.conf
index 58c9e292a9..ca3497b4a5 100644
--- a/tests/topotests/ospf-topo1/r1/ospf6d.conf
+++ b/tests/topotests/ospf-topo1/r1/ospf6d.conf
@@ -7,3 +7,7 @@ router ospf6
interface r1-eth0 area 0.0.0.0
interface r1-eth1 area 0.0.0.0
!
+int r1-eth1
+ ipv6 ospf6 dead-interval 10
+ ipv6 ospf6 hello-interval 2
+!
diff --git a/tests/topotests/ospf-topo1/r1/ospfd.conf b/tests/topotests/ospf-topo1/r1/ospfd.conf
index 1226b72f2b..3b5aa192c5 100644
--- a/tests/topotests/ospf-topo1/r1/ospfd.conf
+++ b/tests/topotests/ospf-topo1/r1/ospfd.conf
@@ -7,3 +7,7 @@ router ospf
network 10.0.1.0/24 area 0
network 10.0.3.0/24 area 0
!
+int r1-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r2/ospf6d.conf b/tests/topotests/ospf-topo1/r2/ospf6d.conf
index a4ef1469a7..44047e1a4e 100644
--- a/tests/topotests/ospf-topo1/r2/ospf6d.conf
+++ b/tests/topotests/ospf-topo1/r2/ospf6d.conf
@@ -7,3 +7,11 @@ router ospf6
interface r2-eth0 area 0.0.0.0
interface r2-eth1 area 0.0.0.0
!
+int r2-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+int r2-eth1
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r2/ospfd.conf b/tests/topotests/ospf-topo1/r2/ospfd.conf
index 78d980315d..1a7ccdf728 100644
--- a/tests/topotests/ospf-topo1/r2/ospfd.conf
+++ b/tests/topotests/ospf-topo1/r2/ospfd.conf
@@ -7,3 +7,7 @@ router ospf
network 10.0.2.0/24 area 0
network 10.0.3.0/24 area 0
!
+int r2-eth1
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r3/ospf6d.conf b/tests/topotests/ospf-topo1/r3/ospf6d.conf
index 4ff53011cb..13ad9a7356 100644
--- a/tests/topotests/ospf-topo1/r3/ospf6d.conf
+++ b/tests/topotests/ospf-topo1/r3/ospf6d.conf
@@ -8,3 +8,15 @@ router ospf6
interface r3-eth1 area 0.0.0.0
interface r3-eth2 area 0.0.0.1
!
+int r3-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+int r3-eth1
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+int r3-eth2
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r3/ospfd.conf b/tests/topotests/ospf-topo1/r3/ospfd.conf
index dbb7215d10..3b378c0f27 100644
--- a/tests/topotests/ospf-topo1/r3/ospfd.conf
+++ b/tests/topotests/ospf-topo1/r3/ospfd.conf
@@ -8,3 +8,11 @@ router ospf
network 10.0.10.0/24 area 0
network 172.16.0.0/24 area 1
!
+int r3-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
+int r3-eth2
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r4/ospf6d.conf b/tests/topotests/ospf-topo1/r4/ospf6d.conf
index 32942ea189..f9bde0e83c 100644
--- a/tests/topotests/ospf-topo1/r4/ospf6d.conf
+++ b/tests/topotests/ospf-topo1/r4/ospf6d.conf
@@ -7,3 +7,11 @@ router ospf6
interface r4-eth0 area 0.0.0.1
interface r4-eth1 area 0.0.0.1
!
+int r4-eth0
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
+int r4-eth1
+ ipv6 ospf6 hello-interval 2
+ ipv6 ospf6 dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo1/r4/ospfd.conf b/tests/topotests/ospf-topo1/r4/ospfd.conf
index 01b29ca057..52d29322f8 100644
--- a/tests/topotests/ospf-topo1/r4/ospfd.conf
+++ b/tests/topotests/ospf-topo1/r4/ospfd.conf
@@ -7,3 +7,7 @@ router ospf
network 172.16.0.0/24 area 1
network 172.16.1.0/24 area 1
!
+int r4-eth0
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
+!
diff --git a/tests/topotests/ospf-topo2/r1/ospfd.conf b/tests/topotests/ospf-topo2/r1/ospfd.conf
index 1e1bfca569..65843cbb83 100644
--- a/tests/topotests/ospf-topo2/r1/ospfd.conf
+++ b/tests/topotests/ospf-topo2/r1/ospfd.conf
@@ -1,6 +1,8 @@
!
interface r1-eth1
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
router ospf
ospf router-id 10.0.255.1
diff --git a/tests/topotests/ospf-topo2/r2/ospfd.conf b/tests/topotests/ospf-topo2/r2/ospfd.conf
index af2acd8404..b032f1a8ac 100644
--- a/tests/topotests/ospf-topo2/r2/ospfd.conf
+++ b/tests/topotests/ospf-topo2/r2/ospfd.conf
@@ -1,6 +1,8 @@
!
interface r2-eth1
ip ospf network point-to-point
+ ip ospf hello-interval 2
+ ip ospf dead-interval 10
!
router ospf
ospf router-id 10.0.255.2
diff --git a/tests/topotests/pim-basic/r1/bgpd.conf b/tests/topotests/pim-basic/r1/bgpd.conf
index 1ca643f758..84d9598bc6 100644
--- a/tests/topotests/pim-basic/r1/bgpd.conf
+++ b/tests/topotests/pim-basic/r1/bgpd.conf
@@ -1,4 +1,5 @@
router bgp 65001
no bgp ebgp-requires-policy
neighbor 10.0.30.3 remote-as external
+ neighbor 10.0.30.3 timers 3 10
redistribute connected
diff --git a/tests/topotests/pim-basic/rp/bgpd.conf b/tests/topotests/pim-basic/rp/bgpd.conf
index 451799288a..1bfae6059b 100644
--- a/tests/topotests/pim-basic/rp/bgpd.conf
+++ b/tests/topotests/pim-basic/rp/bgpd.conf
@@ -1,4 +1,5 @@
router bgp 65003
no bgp ebgp-requires-policy
neighbor 10.0.30.1 remote-as external
+ neighbor 10.0.30.1 timers 3 10
redistribute connected