summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/bgpd/test_mpath.c2
-rw-r--r--tests/lib/cli/test_cli.c4
-rw-r--r--tests/lib/cli/test_cli.in17
-rw-r--r--tests/lib/cli/test_cli.refout.in96
-rw-r--r--tests/lib/test_nexthop.c6
-rw-r--r--tests/lib/test_printfrr.c21
-rw-r--r--tests/subdir.am2
-rw-r--r--tests/topotests/all_protocol_startup/test_all_protocol_startup.py6
-rw-r--r--tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py8
-rw-r--r--tests/topotests/bgp_evpn_overlay_index_gateway/host2/zebra.conf2
-rw-r--r--tests/topotests/bgp_prefix_sid2/peer1/exabgp.cfg4
-rwxr-xr-xtests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json160
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json169
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json5
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json10
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf2
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json93
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json169
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json10
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json5
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf2
-rwxr-xr-xtests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py183
-rwxr-xr-xtests/topotests/conftest.py70
-rw-r--r--tests/topotests/example_test/r1/zebra.conf8
-rw-r--r--tests/topotests/example_test/r2/zebra.conf4
-rwxr-xr-xtests/topotests/example_test/test_example.py1
-rw-r--r--tests/topotests/example_test/test_template.py140
-rw-r--r--tests/topotests/example_test/test_template_json.json188
-rw-r--r--tests/topotests/example_test/test_template_json.py68
-rw-r--r--tests/topotests/lib/bgp.py2
-rw-r--r--tests/topotests/lib/common_config.py3
-rw-r--r--tests/topotests/lib/micronet.py12
-rw-r--r--tests/topotests/lib/micronet_compat.py26
-rw-r--r--tests/topotests/lib/topotest.py25
-rw-r--r--tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py16
-rwxr-xr-xtests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py26
-rw-r--r--tests/topotests/ospf6_gr_topo1/__init__.py (renamed from tests/topotests/zebra_netlink/r1/sharpd.conf)0
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf30
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_database.json95
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_neighbor.json12
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt1/zebra.conf22
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/ospf6d.conf35
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_database.json183
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_neighbor.json20
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt2/zebra.conf22
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/ospf6d.conf41
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_database.json144
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_neighbor.json28
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt3/zebra.conf24
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/ospf6d.conf35
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_database.json188
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_neighbor.json20
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt4/zebra.conf22
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/ospf6d.conf29
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_database.json100
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_neighbor.json12
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt5/zebra.conf20
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/ospf6d.conf35
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_database.json183
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_neighbor.json20
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt6/zebra.conf22
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/ospf6d.conf30
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_database.json95
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_neighbor.json12
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_route.json74
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_route.json139
-rw-r--r--tests/topotests/ospf6_gr_topo1/rt7/zebra.conf22
-rwxr-xr-xtests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py381
-rw-r--r--tests/topotests/ospf6_topo2/test_ospf6_topo2.py162
-rw-r--r--tests/topotests/route_scale/scale_test_common.py (renamed from tests/topotests/route_scale/test_route_scale.py)68
-rw-r--r--tests/topotests/route_scale/test_route_scale1.py77
-rw-r--r--tests/topotests/route_scale/test_route_scale2.py77
-rw-r--r--tests/topotests/srv6_locator/expected_chunks4.json4
-rw-r--r--tests/topotests/srv6_locator/expected_chunks5.json6
-rw-r--r--tests/topotests/srv6_locator/expected_chunks6.json2
-rw-r--r--tests/topotests/srv6_locator/expected_locators4.json10
-rw-r--r--tests/topotests/srv6_locator/expected_locators5.json13
-rw-r--r--tests/topotests/srv6_locator/expected_locators6.json5
-rwxr-xr-xtests/topotests/srv6_locator/test_srv6_locator.py33
-rw-r--r--tests/topotests/zebra_netlink/r1/v4_route.json2302
-rw-r--r--tests/topotests/zebra_netlink/test_zebra_netlink.py95
-rw-r--r--tests/zebra/test_lm_plugin.c6
95 files changed, 5177 insertions, 2628 deletions
diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c
index 92efd4c3d6..77fd876594 100644
--- a/tests/bgpd/test_mpath.c
+++ b/tests/bgpd/test_mpath.c
@@ -310,7 +310,7 @@ static int setup_bgp_path_info_mpath_update(testcase_t *t)
str2prefix("42.1.1.0/24", &test_rn.p);
rt_node = bgp_dest_to_rnode(&test_rn);
memcpy((struct route_table *)&rt_node->table, &rt->route_table,
- sizeof(struct route_table *));
+ sizeof(struct route_table));
setup_bgp_mp_list(t);
for (i = 0; i < test_mp_list_info_count; i++)
bgp_path_info_add(&test_rn, &test_mp_list_info[i]);
diff --git a/tests/lib/cli/test_cli.c b/tests/lib/cli/test_cli.c
index 8dba1e29f0..f8d74018dd 100644
--- a/tests/lib/cli/test_cli.c
+++ b/tests/lib/cli/test_cli.c
@@ -40,6 +40,8 @@ DUMMY_DEFUN(cmd12, "alt a A.B.C.D");
DUMMY_DEFUN(cmd13, "alt a X:X::X:X");
DUMMY_DEFUN(cmd14,
"pat g { foo A.B.C.D$foo|foo|bar X:X::X:X$bar| baz } [final]");
+DUMMY_DEFUN(cmd15, "no pat g ![ WORD ]");
+DUMMY_DEFUN(cmd16, "[no] pat h {foo ![A.B.C.D$foo]|bar X:X::X:X$bar} final");
#include "tests/lib/cli/test_cli_clippy.c"
@@ -81,5 +83,7 @@ void test_init(int argc, char **argv)
install_element(ENABLE_NODE, &cmd13_cmd);
}
install_element(ENABLE_NODE, &cmd14_cmd);
+ install_element(ENABLE_NODE, &cmd15_cmd);
+ install_element(ENABLE_NODE, &cmd16_cmd);
install_element(ENABLE_NODE, &magic_test_cmd);
}
diff --git a/tests/lib/cli/test_cli.in b/tests/lib/cli/test_cli.in
index 5c146ef984..bd685a6231 100644
--- a/tests/lib/cli/test_cli.in
+++ b/tests/lib/cli/test_cli.in
@@ -74,6 +74,23 @@ pat f
pat f foo
pat f key
+no pat g
+no pat g test
+no pat g test more
+
+pat h foo ?1.2.3.4 final
+no pat h foo ?1.2.3.4 final
+pat h foo final
+no pat h foo final
+pat h bar final
+no pat h bar final
+pat h bar 1::2 final
+no pat h bar 1::2 final
+pat h bar 1::2 foo final
+no pat h bar 1::2 foo final
+pat h bar 1::2 foo 1.2.3.4 final
+no pat h bar 1::2 foo 1.2.3.4 final
+
alt a a?b
alt a 1 .2?.3.4
alt a 1 :2? ::?3
diff --git a/tests/lib/cli/test_cli.refout.in b/tests/lib/cli/test_cli.refout.in
index 1f38e08b20..84365810d5 100644
--- a/tests/lib/cli/test_cli.refout.in
+++ b/tests/lib/cli/test_cli.refout.in
@@ -147,7 +147,7 @@ test# papat
% Command incomplete.
test# pat
a b c d e f
-g
+g h
test# pat
% Command incomplete.
test#
@@ -263,6 +263,100 @@ cmd10 with 3 args.
[01] f@(null): f
[02] key@(null): key
test#
+test# no pat g
+cmd15 with 3 args.
+[00] no@(null): no
+[01] pat@(null): pat
+[02] g@(null): g
+test# no pat g test
+cmd15 with 4 args.
+[00] no@(null): no
+[01] pat@(null): pat
+[02] g@(null): g
+[03] WORD@g: test
+test# no pat g test more
+% [NONE] Unknown command: no pat g test more
+test#
+test# pat h foo
+ A.B.C.D 04
+test# pat h foo 1.2.3.4 final
+cmd16 with 5 args.
+[00] pat@(null): pat
+[01] h@(null): h
+[02] foo@(null): foo
+[03] A.B.C.D@foo: 1.2.3.4
+[04] final@(null): final
+test# no pat h foo
+ A.B.C.D 04
+ bar 05
+ final 07
+test# no pat h foo 1.2.3.4 final
+cmd16 with 6 args.
+[00] no@no: no
+[01] pat@(null): pat
+[02] h@(null): h
+[03] foo@(null): foo
+[04] A.B.C.D@foo: 1.2.3.4
+[05] final@(null): final
+test# pat h foo final
+% [NONE] Unknown command: pat h foo final
+test# no pat h foo final
+cmd16 with 5 args.
+[00] no@no: no
+[01] pat@(null): pat
+[02] h@(null): h
+[03] foo@(null): foo
+[04] final@(null): final
+test# pat h bar final
+% [NONE] Unknown command: pat h bar final
+test# no pat h bar final
+% [NONE] Unknown command: no pat h bar final
+test# pat h bar 1::2 final
+cmd16 with 5 args.
+[00] pat@(null): pat
+[01] h@(null): h
+[02] bar@(null): bar
+[03] X:X::X:X@bar: 1::2
+[04] final@(null): final
+test# no pat h bar 1::2 final
+cmd16 with 6 args.
+[00] no@no: no
+[01] pat@(null): pat
+[02] h@(null): h
+[03] bar@(null): bar
+[04] X:X::X:X@bar: 1::2
+[05] final@(null): final
+test# pat h bar 1::2 foo final
+% [NONE] Unknown command: pat h bar 1::2 foo final
+test# no pat h bar 1::2 foo final
+cmd16 with 7 args.
+[00] no@no: no
+[01] pat@(null): pat
+[02] h@(null): h
+[03] bar@(null): bar
+[04] X:X::X:X@bar: 1::2
+[05] foo@(null): foo
+[06] final@(null): final
+test# pat h bar 1::2 foo 1.2.3.4 final
+cmd16 with 7 args.
+[00] pat@(null): pat
+[01] h@(null): h
+[02] bar@(null): bar
+[03] X:X::X:X@bar: 1::2
+[04] foo@(null): foo
+[05] A.B.C.D@foo: 1.2.3.4
+[06] final@(null): final
+test# no pat h bar 1::2 foo 1.2.3.4 final
+cmd16 with 8 args.
+[00] no@no: no
+[01] pat@(null): pat
+[02] h@(null): h
+[03] bar@(null): bar
+[04] X:X::X:X@bar: 1::2
+[05] foo@(null): foo
+[06] A.B.C.D@foo: 1.2.3.4
+[07] final@(null): final
+test#
test# alt a
test# alt a a
WORD 02
diff --git a/tests/lib/test_nexthop.c b/tests/lib/test_nexthop.c
index 659d207b4e..7cf687dffe 100644
--- a/tests/lib/test_nexthop.c
+++ b/tests/lib/test_nexthop.c
@@ -112,15 +112,15 @@ static void test_run_first(void)
nexthop_free(nh2);
/* Blackhole */
- nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT);
- nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT);
+ nh1 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
+ nh2 = nexthop_from_blackhole(BLACKHOLE_REJECT, 0);
ret = nexthop_cmp_basic(nh1, nh2);
assert(ret == 0);
nexthop_free(nh2);
- nh2 = nexthop_from_blackhole(BLACKHOLE_NULL);
+ nh2 = nexthop_from_blackhole(BLACKHOLE_NULL, 0);
ret = nexthop_cmp_basic(nh1, nh2);
assert(ret != 0);
diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c
index 21b3a916b8..06996a2f13 100644
--- a/tests/lib/test_printfrr.c
+++ b/tests/lib/test_printfrr.c
@@ -24,6 +24,7 @@
#include "lib/printfrr.h"
#include "lib/memory.h"
#include "lib/prefix.h"
+#include "lib/nexthop.h"
static int errors;
@@ -253,5 +254,25 @@ int main(int argc, char **argv)
printchk("\"\"", "%pSQqn", (char *)NULL);
printchk("(null)", "%pSQq", (char *)NULL);
+ /*
+ * %pNH<foo> tests
+ *
+ * gateway addresses only for now: interfaces require more setup
+ */
+ printchk("(null)", "%pNHcg", NULL);
+ printchk("(null)", "%pNHci", NULL);
+
+ struct nexthop nh;
+
+ memset(&nh, 0, sizeof(nh));
+
+ nh.type = NEXTHOP_TYPE_IPV4;
+ inet_aton("3.2.1.0", &nh.gate.ipv4);
+ printchk("3.2.1.0", "%pNHcg", &nh);
+
+ nh.type = NEXTHOP_TYPE_IPV6;
+ inet_pton(AF_INET6, "fe2c::34", &nh.gate.ipv6);
+ printchk("fe2c::34", "%pNHcg", &nh);
+
return !!errors;
}
diff --git a/tests/subdir.am b/tests/subdir.am
index b0be63c695..1edfda9bc2 100644
--- a/tests/subdir.am
+++ b/tests/subdir.am
@@ -183,7 +183,7 @@ TESTS_CXXFLAGS = \
# note no -Werror
ALL_TESTS_LDADD = lib/libfrr.la $(LIBCAP)
-BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) -lm
+BGP_TEST_LDADD = bgpd/libbgp.a $(RFPLDADD) $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) $(UST_LIBS) -lm
ISISD_TEST_LDADD = isisd/libisis.a $(ALL_TESTS_LDADD)
if GRPC
GRPC_TESTS_LDADD = staticd/libstatic.a grpc/libfrrgrpc_pb.la -lgrpc++ -lprotobuf $(ALL_TESTS_LDADD) $(LIBYANG_LIBS) -lm
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 b1203570a1..1b99fcea1f 100644
--- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
+++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
@@ -932,6 +932,9 @@ def test_bgp_summary():
# Remove Unknown Summary (all of it)
actual = re.sub(r"Unknown Summary \(VRF default\):", "", actual)
actual = re.sub(r"No Unknown neighbor is configured", "", actual)
+ # Make Connect/Active/Idle the same (change them all to Active)
+ actual = re.sub(r" Connect ", " Active ", actual)
+ actual = re.sub(r" Idle ", " Active ", actual)
actual = re.sub(
r"IPv4 labeled-unicast Summary \(VRF default\):", "", actual
@@ -1089,6 +1092,9 @@ def test_bgp_ipv6_summary():
# Remove Unknown Summary (all of it)
actual = re.sub(r"Unknown Summary \(VRF default\):", "", actual)
actual = re.sub(r"No Unknown neighbor is configured", "", actual)
+ # Make Connect/Active/Idle the same (change them all to Active)
+ actual = re.sub(r" Connect ", " Active ", actual)
+ actual = re.sub(r" Idle ", " Active ", actual)
# Remove Labeled Unicast Summary (all of it)
actual = re.sub(
diff --git a/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py b/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py
index 27451ec7b3..c890b0d7dc 100644
--- a/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py
+++ b/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py
@@ -92,7 +92,13 @@ def test_bgp_default_originate_route_map():
def _bgp_default_route_has_metric(router):
output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
expected = {
- "paths": [{"aspath": {"string": "65000 65000 65000 65000"}, "metric": 123}]
+ "paths": [
+ {
+ "aspath": {"string": "65000 65000 65000 65000"},
+ "metric": 123,
+ "community": None,
+ }
+ ]
}
return topotest.json_cmp(output, expected)
diff --git a/tests/topotests/bgp_evpn_overlay_index_gateway/host2/zebra.conf b/tests/topotests/bgp_evpn_overlay_index_gateway/host2/zebra.conf
index 9135545c58..b9f80f112d 100644
--- a/tests/topotests/bgp_evpn_overlay_index_gateway/host2/zebra.conf
+++ b/tests/topotests/bgp_evpn_overlay_index_gateway/host2/zebra.conf
@@ -1,4 +1,4 @@
!
-int host1-eth0
+int host2-eth0
ip address 50.0.1.21/24
ipv6 address 50:0:1::21/48
diff --git a/tests/topotests/bgp_prefix_sid2/peer1/exabgp.cfg b/tests/topotests/bgp_prefix_sid2/peer1/exabgp.cfg
index ad1b15a26c..3819179570 100644
--- a/tests/topotests/bgp_prefix_sid2/peer1/exabgp.cfg
+++ b/tests/topotests/bgp_prefix_sid2/peer1/exabgp.cfg
@@ -15,14 +15,14 @@ group controller {
next-hop 2001::2;
extended-community [ target:2:10 ];
label 3;
- attribute [0x28 0xc0 0x0500150020010db800010001000000000000000100ffff00 ];
+ attribute [0x28 0xc0 0x050019000100150020010db800010001000000000000000100ffff00 ];
}
route 2001:2::/64 {
rd 2:10;
next-hop 2001::2;
extended-community [ target:2:10 ];
label 3;
- attribute [0x28 0xc0 0x0500150020010db800010001000000000000000100ffff00 ];
+ attribute [0x28 0xc0 0x050019000100150020010db800010001000000000000000100ffff00 ];
}
}
}
diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py b/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py
index 3e6e417211..0d27474cbd 100755
--- a/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py
+++ b/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py
@@ -151,13 +151,6 @@ def setup_module(mod):
r1.run("sysctl -w net.mpls.conf.r1-eth0.input=1")
r1.run("sysctl -w net.mpls.conf.r1-eth1.input=1")
r1.run("sysctl -w net.mpls.conf.r1-eth2.input=1")
- r2.run("sysctl -w net.mpls.conf.r1-eth0.input=1")
- r2.run("sysctl -w net.mpls.conf.r1-eth1.input=1")
- r3.run("sysctl -w net.mpls.conf.r1-eth0.input=1")
- r3.run("sysctl -w net.mpls.conf.r1-eth1.input=1")
- r3.run("sysctl -w net.mpls.conf.r1-eth2.input=1")
- r4.run("sysctl -w net.mpls.conf.r1-eth0.input=1")
- r4.run("sysctl -w net.mpls.conf.r1-eth1.input=1")
router_list = tgen.routers()
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json
new file mode 100644
index 0000000000..f2df9be49d
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json
@@ -0,0 +1,160 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "1.1.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 1,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:3::/64": [
+ {
+ "pathFrom": "external",
+ "prefix": "2001:3::",
+ "prefixLen": 64,
+ "network": "2001:3::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "1:20": {
+ "2001:5::/64": [
+ {
+ "pathFrom": "external",
+ "prefix": "2001:5::",
+ "prefixLen": 64,
+ "network": "2001:5::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:20": {
+ "2001:4::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:4::",
+ "prefixLen": 64,
+ "network": "2001:4::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:6::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:6::",
+ "prefixLen": 64,
+ "network": "2001:6::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json
new file mode 100644
index 0000000000..0fdd3d6dc0
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json
@@ -0,0 +1,169 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "1.1.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 1,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:3::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:3::",
+ "prefixLen": 64,
+ "network": "2001:3::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "1:20": {
+ "2001:5::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:5::",
+ "prefixLen": 64,
+ "network": "2001:5::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:20": {
+ "2001:4::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:4::",
+ "prefixLen": 64,
+ "network": "2001:4::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:6::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:6::",
+ "prefixLen": 64,
+ "network": "2001:6::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
index fa05972a35..141c1cb957 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
@@ -48,12 +48,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:2:2::100"
+ "segs": "2001:db8:2:2:100::"
}
}
],
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
index 0155557242..e20998061f 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
@@ -22,12 +22,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:2:2::200"
+ "segs": "2001:db8:2:2:200::"
}
}
],
@@ -83,12 +80,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:2:2::200"
+ "segs": "2001:db8:2:2:200::"
}
}
],
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf
index ec36870369..68b5730a63 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf
@@ -34,7 +34,9 @@ segment-routing
ip forwarding
ipv6 forwarding
!
+ipv6 route 2001:db8:2:1::/64 2001::2
ipv6 route 2001:db8:2:2::/64 2001::2
+ipv6 route 2001:db8:2:3::/64 2001::2
!
line vty
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json
new file mode 100644
index 0000000000..25cdf031c3
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json
@@ -0,0 +1,93 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "2.2.2.2",
+ "defaultLocPrf": 100,
+ "localAS": 2,
+ "routes": {
+ "routeDistinguishers": {
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:20": {
+ "2001:4::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:4::",
+ "prefixLen": 64,
+ "network": "2001:4::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:6::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:6::",
+ "prefixLen": 64,
+ "network": "2001:6::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json
new file mode 100644
index 0000000000..03bbcc008d
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json
@@ -0,0 +1,169 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "2.2.2.2",
+ "defaultLocPrf": 100,
+ "localAS": 2,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "1",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:3::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:3::",
+ "prefixLen": 64,
+ "network": "2001:3::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "1",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "1:20": {
+ "2001:5::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:5::",
+ "prefixLen": 64,
+ "network": "2001:5::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "1",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:20": {
+ "2001:4::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:4::",
+ "prefixLen": 64,
+ "network": "2001:4::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:6::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:6::",
+ "prefixLen": 64,
+ "network": "2001:6::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf20",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
index 887eb24386..7f8a930d00 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
@@ -22,12 +22,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:1:1::100"
+ "segs": "2001:db8:1:1:100::"
}
}
],
@@ -83,12 +80,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:1:1::100"
+ "segs": "2001:db8:1:1:100::"
}
}
],
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
index c118518423..104bdc30d2 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
@@ -48,12 +48,9 @@
"interfaceName": "eth0",
"vrf": "default",
"active": true,
- "labels": [
- 3
- ],
"weight": 1,
"seg6": {
- "segs": "2001:db8:1:1::200"
+ "segs": "2001:db8:1:1:200::"
}
}
],
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf
index f3e025d23a..91fd92d422 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf
@@ -35,6 +35,8 @@ ip forwarding
ipv6 forwarding
!
ipv6 route 2001:db8:1:1::/64 2001::1
+ipv6 route 2001:db8:1:2::/64 2001::1
+ipv6 route 2001:db8:1:3::/64 2001::1
!
line vty
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
index 2d544c1ccf..e0cf8c88e6 100755
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
@@ -129,6 +129,10 @@ def setup_module(mod):
tgen.gears["r2"].run("ip link set eth3 master vrf20")
tgen.start_router()
+ # FOR DEVELOPER:
+ # If you want to stop some specific line and start interactive shell,
+ # please use tgen.mininet_cli() to start it.
+
def teardown_module(mod):
tgen = get_topogen()
@@ -143,7 +147,22 @@ def open_json_file(filename):
assert False, "Could not read file {}".format(filename)
-def test_rib():
+def check_ping(name, dest_addr, expect_connected):
+ def _check(name, dest_addr, match):
+ tgen = get_topogen()
+ output = tgen.gears[name].run("ping6 {} -c 1 -w 1".format(dest_addr))
+ logger.info(output)
+ assert match in output, "ping fail"
+
+ match = "{} packet loss".format("0%" if expect_connected else "100%")
+ logger.info("[+] check {} {} {}".format(name, dest_addr, match))
+ tgen = get_topogen()
+ func = functools.partial(_check, name, dest_addr, match)
+ success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
+ assert result is None, "Failed"
+
+
+def check_rib(name, cmd, expected_file):
def _check(name, cmd, expected_file):
logger.info("polling")
tgen = get_topogen()
@@ -152,51 +171,131 @@ def test_rib():
expected = open_json_file("{}/{}".format(CWD, expected_file))
return topotest.json_cmp(output, expected)
- def check(name, cmd, expected_file):
- logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
- tgen = get_topogen()
- func = functools.partial(_check, name, cmd, expected_file)
- success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
- assert result is None, "Failed"
-
- check("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
- check("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
- check("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10_rib.json")
- check("r1", "show ipv6 route vrf vrf20 json", "r1/vrf20_rib.json")
- check("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10_rib.json")
- check("r2", "show ipv6 route vrf vrf20 json", "r2/vrf20_rib.json")
- check("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
- check("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
- check("ce3", "show ipv6 route json", "ce3/ipv6_rib.json")
- check("ce4", "show ipv6 route json", "ce4/ipv6_rib.json")
- check("ce5", "show ipv6 route json", "ce5/ipv6_rib.json")
- check("ce6", "show ipv6 route json", "ce6/ipv6_rib.json")
+ logger.info("[+] check {} \"{}\" {}".format(name, cmd, expected_file))
+ tgen = get_topogen()
+ func = functools.partial(_check, name, cmd, expected_file)
+ success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
+ assert result is None, "Failed"
+
+
+def test_rib():
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
+ check_rib("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10_rib.json")
+ check_rib("r1", "show ipv6 route vrf vrf20 json", "r1/vrf20_rib.json")
+ check_rib("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10_rib.json")
+ check_rib("r2", "show ipv6 route vrf vrf20 json", "r2/vrf20_rib.json")
+ check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
+ check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
+ check_rib("ce3", "show ipv6 route json", "ce3/ipv6_rib.json")
+ check_rib("ce4", "show ipv6 route json", "ce4/ipv6_rib.json")
+ check_rib("ce5", "show ipv6 route json", "ce5/ipv6_rib.json")
+ check_rib("ce6", "show ipv6 route json", "ce6/ipv6_rib.json")
def test_ping():
- def _check(name, dest_addr, match):
- tgen = get_topogen()
- output = tgen.gears[name].run("ping6 {} -c 1 -w 1".format(dest_addr))
- logger.info(output)
- assert match in output, "ping fail"
+ check_ping("ce1", "2001:2::2", True)
+ check_ping("ce1", "2001:3::2", True)
+ check_ping("ce1", "2001:4::2", False)
+ check_ping("ce1", "2001:5::2", False)
+ check_ping("ce1", "2001:6::2", False)
+ check_ping("ce4", "2001:1::2", False)
+ check_ping("ce4", "2001:2::2", False)
+ check_ping("ce4", "2001:3::2", False)
+ check_ping("ce4", "2001:5::2", True)
+ check_ping("ce4", "2001:6::2", True)
- def check(name, dest_addr, match):
- logger.info("[+] check {} {} {}".format(name, dest_addr, match))
- tgen = get_topogen()
- func = functools.partial(_check, name, dest_addr, match)
- success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
- assert result is None, "Failed"
-
- check("ce1", "2001:2::2", " 0% packet loss")
- check("ce1", "2001:3::2", " 0% packet loss")
- check("ce1", "2001:4::2", " 100% packet loss")
- check("ce1", "2001:5::2", " 100% packet loss")
- check("ce1", "2001:6::2", " 100% packet loss")
- check("ce4", "2001:1::2", " 100% packet loss")
- check("ce4", "2001:2::2", " 100% packet loss")
- check("ce4", "2001:3::2", " 100% packet loss")
- check("ce4", "2001:5::2", " 0% packet loss")
- check("ce4", "2001:6::2", " 0% packet loss")
+
+def test_locator_delete():
+ check_ping("ce1", "2001:2::2", True)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ segment-routing
+ srv6
+ locators
+ no locator loc1
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
+ check_ping("ce1", "2001:2::2", False)
+
+
+def test_locator_recreate():
+ check_ping("ce1", "2001:2::2", False)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ segment-routing
+ srv6
+ locators
+ locator loc1
+ prefix 2001:db8:1:1::/64
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
+ check_ping("ce1", "2001:2::2", True)
+
+
+def test_bgp_locator_unset():
+ check_ping("ce1", "2001:2::2", True)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 1
+ segment-routing srv6
+ no locator loc1
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
+ check_ping("ce1", "2001:2::2", False)
+
+
+def test_bgp_locator_reset():
+ check_ping("ce1", "2001:2::2", False)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 1
+ segment-routing srv6
+ locator loc1
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
+ check_ping("ce1", "2001:2::2", True)
+
+
+def test_bgp_srv6_unset():
+ check_ping("ce1", "2001:2::2", True)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 1
+ no segment-routing srv6
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
+ check_ping("ce1", "2001:2::2", False)
+
+
+def test_bgp_srv6_reset():
+ check_ping("ce1", "2001:2::2", False)
+ get_topogen().gears["r1"].vtysh_cmd(
+ """
+ configure terminal
+ router bgp 1
+ segment-routing srv6
+ locator loc1
+ """
+ )
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
+ check_ping("ce1", "2001:2::2", True)
if __name__ == "__main__":
diff --git a/tests/topotests/conftest.py b/tests/topotests/conftest.py
index ed55490c09..7fe6a5aea1 100755
--- a/tests/topotests/conftest.py
+++ b/tests/topotests/conftest.py
@@ -6,13 +6,14 @@ import glob
import os
import pdb
import re
+import subprocess
import sys
import time
import pytest
import lib.fixtures
from lib import topolog
-from lib.micronet import Commander
+from lib.micronet import Commander, proc_error
from lib.micronet_cli import cli
from lib.micronet_compat import Mininet, cleanup_current, cleanup_previous
from lib.topogen import diagnose_env, get_topogen
@@ -256,6 +257,23 @@ def pytest_configure(config):
if cli_level is not None:
config.option.log_cli_level = cli_level
+ have_tmux = bool(os.getenv("TMUX", ""))
+ have_screen = not have_tmux and bool(os.getenv("STY", ""))
+ have_xterm = not have_tmux and not have_screen and bool(os.getenv("DISPLAY", ""))
+ have_windows = have_tmux or have_screen or have_xterm
+ have_windows_pause = have_tmux or have_xterm
+ xdist_no_windows = is_xdist and not is_worker and not have_windows_pause
+
+ def assert_feature_windows(b, feature):
+ if b and xdist_no_windows:
+ pytest.exit(
+ "{} use requires byobu/TMUX/XTerm under dist {}".format(
+ feature, os.environ["PYTEST_XDIST_MODE"]
+ )
+ )
+ elif b and not is_xdist and not have_windows:
+ pytest.exit("{} use requires byobu/TMUX/SCREEN/XTerm".format(feature))
+
# ---------------------------------------
# Record our options in global dictionary
# ---------------------------------------
@@ -272,6 +290,7 @@ def pytest_configure(config):
gdb_daemons = config.getoption("--gdb-daemons")
gdb_daemons = gdb_daemons.split(",") if gdb_daemons else []
topotest_extra_config["gdb_daemons"] = gdb_daemons
+ assert_feature_windows(gdb_routers or gdb_daemons, "GDB")
gdb_breakpoints = config.getoption("--gdb-breakpoints")
gdb_breakpoints = gdb_breakpoints.split(",") if gdb_breakpoints else []
@@ -279,31 +298,40 @@ def pytest_configure(config):
cli_on_error = config.getoption("--cli-on-error")
topotest_extra_config["cli_on_error"] = cli_on_error
+ assert_feature_windows(cli_on_error, "--cli-on-error")
shell = config.getoption("--shell")
topotest_extra_config["shell"] = shell.split(",") if shell else []
+ assert_feature_windows(shell, "--shell")
strace = config.getoption("--strace-daemons")
topotest_extra_config["strace_daemons"] = strace.split(",") if strace else []
shell_on_error = config.getoption("--shell-on-error")
topotest_extra_config["shell_on_error"] = shell_on_error
+ assert_feature_windows(shell_on_error, "--shell-on-error")
topotest_extra_config["valgrind_extra"] = config.getoption("--valgrind-extra")
topotest_extra_config["valgrind_memleaks"] = config.getoption("--valgrind-memleaks")
vtysh = config.getoption("--vtysh")
topotest_extra_config["vtysh"] = vtysh.split(",") if vtysh else []
+ assert_feature_windows(vtysh, "--vtysh")
vtysh_on_error = config.getoption("--vtysh-on-error")
topotest_extra_config["vtysh_on_error"] = vtysh_on_error
+ assert_feature_windows(vtysh_on_error, "--vtysh-on-error")
pause_on_error = vtysh or shell or config.getoption("--pause-on-error")
if config.getoption("--no-pause-on-error"):
pause_on_error = False
topotest_extra_config["pause_on_error"] = pause_on_error
- topotest_extra_config["pause"] = config.getoption("--pause")
+ assert_feature_windows(pause_on_error, "--pause-on-error")
+
+ pause = config.getoption("--pause")
+ topotest_extra_config["pause"] = pause
+ assert_feature_windows(pause, "--pause")
topotest_extra_config["topology_only"] = config.getoption("--topology-only")
@@ -403,20 +431,27 @@ def pytest_runtest_makereport(item, call):
error_cmd = os.getenv("SHELL", commander.get_exec_path(["bash"]))
if error_cmd:
- # Really would like something better than using this global here.
- # Not all tests use topogen though so get_topogen() won't work.
+ is_tmux = bool(os.getenv("TMUX", ""))
+ is_screen = not is_tmux and bool(os.getenv("STY", ""))
+ is_xterm = not is_tmux and not is_screen and bool(os.getenv("DISPLAY", ""))
+
+ channel = None
win_info = None
wait_for_channels = []
+ wait_for_procs = []
+ # Really would like something better than using this global here.
+ # Not all tests use topogen though so get_topogen() won't work.
for node in Mininet.g_mnet_inst.hosts.values():
pause = True
- channel = (
- "{}-{}".format(os.getpid(), Commander.tmux_wait_gen)
- if not isatty
- else None
- )
- Commander.tmux_wait_gen += 1
- wait_for_channels.append(channel)
+ if is_tmux:
+ channel = (
+ "{}-{}".format(os.getpid(), Commander.tmux_wait_gen)
+ if not isatty
+ else None
+ )
+ Commander.tmux_wait_gen += 1
+ wait_for_channels.append(channel)
pane_info = node.run_in_window(
error_cmd,
@@ -427,13 +462,22 @@ def pytest_runtest_makereport(item, call):
tmux_target=win_info,
wait_for=channel,
)
- if win_info is None:
- win_info = pane_info
+ if is_tmux:
+ if win_info is None:
+ win_info = pane_info
+ elif is_xterm:
+ assert isinstance(pane_info, subprocess.Popen)
+ wait_for_procs.append(pane_info)
# Now wait on any channels
for channel in wait_for_channels:
logger.debug("Waiting on TMUX channel %s", channel)
commander.cmd_raises([commander.get_exec_path("tmux"), "wait", channel])
+ for p in wait_for_procs:
+ logger.debug("Waiting on TMUX xterm process %s", p)
+ o, e = p.communicate()
+ if p.wait():
+ logger.warning("xterm proc failed: %s:", proc_error(p, o, e))
if error and topotest_extra_config["cli_on_error"]:
# Really would like something better than using this global here.
diff --git a/tests/topotests/example_test/r1/zebra.conf b/tests/topotests/example_test/r1/zebra.conf
new file mode 100644
index 0000000000..b733b7b03c
--- /dev/null
+++ b/tests/topotests/example_test/r1/zebra.conf
@@ -0,0 +1,8 @@
+interface r1-eth0
+ ip address 192.168.1.1/24
+
+interface r1-eth1
+ ip address 192.168.2.1/24
+
+interface r1-eth2
+ ip address 192.168.3.1/24 \ No newline at end of file
diff --git a/tests/topotests/example_test/r2/zebra.conf b/tests/topotests/example_test/r2/zebra.conf
new file mode 100644
index 0000000000..c0921f54c9
--- /dev/null
+++ b/tests/topotests/example_test/r2/zebra.conf
@@ -0,0 +1,4 @@
+interface r2-eth0
+ ip address 192.168.1.2/24
+interface r2-eth1
+ ip address 192.168.3.2/24
diff --git a/tests/topotests/example_test/test_example.py b/tests/topotests/example_test/test_example.py
index 72eceee612..30c3d248f7 100755
--- a/tests/topotests/example_test/test_example.py
+++ b/tests/topotests/example_test/test_example.py
@@ -36,6 +36,7 @@ def test_fail_example():
assert True, "Some Text with explaination in case of failure"
+@pytest.mark.xfail
def test_ls_exits_zero():
"Tests for ls command on invalid file"
diff --git a/tests/topotests/example_test/test_template.py b/tests/topotests/example_test/test_template.py
index e94bb905a5..4c073f259c 100644
--- a/tests/topotests/example_test/test_template.py
+++ b/tests/topotests/example_test/test_template.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-
+# -*- coding: utf-8 eval: (blacken-mode 1) -*-
#
# <template>.py
# Part of NetDEF Topology Tests
@@ -29,54 +29,69 @@
import sys
import pytest
-# Import topogen and topotest helpers
-from lib.topogen import Topogen, TopoRouter, get_topogen
-
+from lib.topogen import Topogen, TopoRouter
+from lib.topolog import logger
# TODO: select markers based on daemons used during test
# pytest module level markers
-"""
-pytestmark = pytest.mark.bfdd # single marker
pytestmark = [
- pytest.mark.bgpd,
- pytest.mark.ospfd,
- pytest.mark.ospf6d
-] # multiple markers
-"""
-
-
+ # pytest.mark.babeld,
+ # pytest.mark.bfdd,
+ # pytest.mark.bgpd,
+ # pytest.mark.eigrpd,
+ # pytest.mark.isisd,
+ # pytest.mark.ldpd,
+ # pytest.mark.nhrpd,
+ # pytest.mark.ospf6d,
+ pytest.mark.ospfd,
+ # pytest.mark.pathd,
+ # pytest.mark.pbrd,
+ # pytest.mark.pimd,
+ # pytest.mark.ripd,
+ # pytest.mark.ripngd,
+ # pytest.mark.sharpd,
+ # pytest.mark.staticd,
+ # pytest.mark.vrrpd,
+]
+
+# Function we pass to Topogen to create the topology
def build_topo(tgen):
"Build function"
# Create 2 routers
- for routern in range(1, 3):
- tgen.add_router("r{}".format(routern))
+ r1 = tgen.add_router("r1")
+ r2 = tgen.add_router("r2")
- # Create a switch with just one router connected to it to simulate a
- # empty network.
+ # Create a p2p connection between r1 and r2
+ tgen.add_link(r1, r2)
+
+ # Create a switch with one router connected to it to simulate a empty network.
switch = tgen.add_switch("s1")
- switch.add_link(tgen.gears["r1"])
+ switch.add_link(r1)
- # Create a connection between r1 and r2
+ # Create a p2p connection between r1 and r2
switch = tgen.add_switch("s2")
- switch.add_link(tgen.gears["r1"])
- switch.add_link(tgen.gears["r2"])
+ switch.add_link(r1)
+ switch.add_link(r2)
-def setup_module(mod):
- "Sets up the pytest environment"
+# New form of setup/teardown using pytest fixture
+@pytest.fixture(scope="module")
+def tgen(request):
+ "Setup/Teardown the environment and provide tgen argument to tests"
# This function initiates the topology build with Topogen...
- tgen = Topogen(build_topo, mod.__name__)
+ tgen = Topogen(build_topo, request.module.__name__)
- # The basic topology above could also have be more easily specified using a
- # dictionary, remove the build_topo function and use the following instead:
+ # A basic topology similar to the above could also have be more easily specified
+ # using a # dictionary, remove the build_topo function and use the following
+ # instead:
#
# topodef = {
# "s1": "r1"
# "s2": ("r1", "r2")
# }
- # tgen = Topogen(topodef, mod.__name__)
+ # tgen = Topogen(topodef, request.module.__name__)
# ... and here it calls initialization functions.
tgen.start_topology()
@@ -84,42 +99,69 @@ def setup_module(mod):
# This is a sample of configuration loading.
router_list = tgen.routers()
- # For all registred routers, load the zebra configuration file
- # CWD = os.path.dirname(os.path.realpath(__file__))
+ # For all routers arrange for:
+ # - starting zebra using config file from <rtrname>/zebra.conf
+ # - starting ospfd using an empty config file.
for rname, router in router_list.items():
- router.load_config(
- TopoRouter.RD_ZEBRA,
- # Uncomment next line to load configuration from ./router/zebra.conf
- # os.path.join(CWD, '{}/zebra.conf'.format(rname))
- )
+ router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
+ router.load_config(TopoRouter.RD_OSPF)
- # After loading the configurations, this function loads configured daemons.
+ # Start and configure the router daemons
tgen.start_router()
+ # Provide tgen as argument to each test function
+ yield tgen
-def teardown_module(mod):
- "Teardown the pytest environment"
- tgen = get_topogen()
-
- # This function tears down the whole topology.
+ # Teardown after last test runs
tgen.stop_topology()
-def test_call_cli():
- "Dummy test that just calls tgen.cli() so we can interact with the build."
- tgen = get_topogen()
- # Don't run this test if we have any failure.
+# Fixture that executes before each test
+@pytest.fixture(autouse=True)
+def skip_on_failure(tgen):
if tgen.routers_have_failure():
- pytest.skip(tgen.errors)
+ pytest.skip("skipped because of previous test failure")
+
+
+# ===================
+# The tests functions
+# ===================
+
- # logger.info("calling CLI")
- # tgen.cli()
+def test_get_version(tgen):
+ "Test the logs the FRR version"
+
+ r1 = tgen.gears["r1"]
+ version = r1.vtysh_cmd("show version")
+ logger.info("FRR version is: " + version)
+
+
+def test_connectivity(tgen):
+ "Test the logs the FRR version"
+
+ r1 = tgen.gears["r1"]
+ r2 = tgen.gears["r2"]
+ output = r1.cmd_raises("ping -c1 192.168.1.2")
+ output = r2.cmd_raises("ping -c1 192.168.3.1")
+
+
+@pytest.mark.xfail
+def test_expect_failure(tgen):
+ "A test that is current expected to fail but should be fixed"
+
+ assert False, "Example of temporary expected failure that will eventually be fixed"
+
+
+@pytest.mark.skip
+def test_will_be_skipped(tgen):
+ "A test that will be skipped"
+ assert False
# Memory leak test template
-def test_memory_leak():
+def test_memory_leak(tgen):
"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")
diff --git a/tests/topotests/example_test/test_template_json.json b/tests/topotests/example_test/test_template_json.json
new file mode 100644
index 0000000000..1ed4a9df6f
--- /dev/null
+++ b/tests/topotests/example_test/test_template_json.json
@@ -0,0 +1,188 @@
+
+{
+ "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":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2":{
+ "links":{
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1":{"ipv4":"auto", "ipv6":"auto"},
+ "r3":{"ipv4":"auto", "ipv6":"auto"}
+ },
+ "bgp":{
+ "local_as":"100",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r3":{
+ "links":{
+ "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",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "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": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r4":{
+ "links":{
+ "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": {}
+ }
+ }
+ }
+ }
+ },
+ "ipv6": {
+ "unicast": {
+ "neighbor": {
+ "r3": {
+ "dest_link": {
+ "r4": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/topotests/example_test/test_template_json.py b/tests/topotests/example_test/test_template_json.py
new file mode 100644
index 0000000000..42e8bc6e7a
--- /dev/null
+++ b/tests/topotests/example_test/test_template_json.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+# September 5 2021, Christian Hopps <chopps@labn.net>
+#
+# Copyright (c) 2021, LabN Consulting, L.L.C.
+# Copyright (c) 2017 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.
+#
+
+"""
+<template>.py: Test <template>.
+"""
+
+import pytest
+
+# Import topogen and topotest helpers
+from lib import bgp
+from lib import fixtures
+
+
+# TODO: select markers based on daemons used during test
+pytestmark = [
+ pytest.mark.bgpd,
+ # pytest.mark.ospfd,
+ # pytest.mark.ospf6d
+ # ...
+]
+
+# Use tgen_json fixture (invoked by use test arg of same name) to
+# setup/teardown standard JSON topotest
+tgen = pytest.fixture(fixtures.tgen_json, scope="module")
+
+
+# tgen is defined above
+# topo is a fixture defined in ../conftest.py
+def test_bgp_convergence(tgen, topo):
+ "Test for BGP convergence."
+
+ # Don't run this test if we have any failure.
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ bgp_convergence = bgp.verify_bgp_convergence(tgen, topo)
+ assert bgp_convergence
+
+
+# Memory leak test template
+def test_memory_leak(tgen):
+ "Run the memory leak test and report results."
+
+ if not tgen.is_memleak_enabled():
+ pytest.skip("Memory leak test/report is disabled")
+
+ tgen.report_memory_leaks()
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index d05332388e..556240bfb5 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -2672,7 +2672,7 @@ def verify_best_path_as_per_admin_distance(
return True
-@retry(retry_timeout=10, initial_wait=2)
+@retry(retry_timeout=30)
def verify_bgp_rib(
tgen,
addr_type,
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index bfb6cd1ef2..1bce3c6bb2 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -44,6 +44,7 @@ from lib.micronet import comm_error
from lib.topogen import TopoRouter, get_topogen
from lib.topolog import get_logger, logger
from lib.topotest import frr_unicode, interface_set_status, version_cmp
+from lib import topotest
FRRCFG_FILE = "frr_json.conf"
FRRCFG_BKUP_FILE = "frr_json_initial.conf"
@@ -2971,6 +2972,8 @@ def addKernelRoute(
ip, mask = grp_addr.split("/")
if mask == "32" or mask == "128":
grp_addr = ip
+ else:
+ mask = "32" if addr_type == "ipv4" else "128"
if not re_search(r"{}".format(grp_addr), result) and mask != "0":
errormsg = (
diff --git a/tests/topotests/lib/micronet.py b/tests/topotests/lib/micronet.py
index 0416c53c48..8567bd3b4b 100644
--- a/tests/topotests/lib/micronet.py
+++ b/tests/topotests/lib/micronet.py
@@ -369,13 +369,13 @@ class Commander(object): # pylint: disable=R0205
cmd = [self.get_exec_path("xterm")]
if "SUDO_USER" in os.environ:
cmd = [self.get_exec_path("sudo"), "-u", os.environ["SUDO_USER"]] + cmd
- # if title:
- # cmd.append("-T")
- # cmd.append(title)
+ if title:
+ cmd.append("-T")
+ cmd.append(title)
cmd.append("-e")
cmd.append(sudo_path)
cmd.extend(self.pre_cmd)
- cmd.append(user_cmd)
+ cmd.extend(["bash", "-c", user_cmd])
# if channel:
# return self.cmd_raises(cmd, skip_pre_cmd=True)
# else:
@@ -384,13 +384,11 @@ class Commander(object): # pylint: disable=R0205
skip_pre_cmd=True,
stdin=None,
shell=False,
- # stdout=open("/dev/null", "w"),
- # stderr=open("/dev/null", "w"),
)
time_mod.sleep(2)
if p.poll() is not None:
self.logger.error("%s: Failed to launch xterm: %s", self, comm_error(p))
- return ""
+ return p
else:
self.logger.error(
"DISPLAY, STY, and TMUX not in environment, can't open window"
diff --git a/tests/topotests/lib/micronet_compat.py b/tests/topotests/lib/micronet_compat.py
index 31a76aca55..a3d3f4c685 100644
--- a/tests/topotests/lib/micronet_compat.py
+++ b/tests/topotests/lib/micronet_compat.py
@@ -33,16 +33,22 @@ def get_pids_with_env(has_var, has_val=None):
result = {}
for pidenv in glob.iglob("/proc/*/environ"):
pid = pidenv.split("/")[2]
- with open(pidenv, "rb") as rfb:
- envlist = [x.decode("utf-8").split("=", 1) for x in rfb.read().split(b"\0")]
- envlist = [[x[0], ""] if len(x) == 1 else x for x in envlist]
- envdict = dict(envlist)
- if has_var not in envdict:
- continue
- if has_val is None:
- result[pid] = envdict
- elif envdict[has_var] == str(has_val):
- result[pid] = envdict
+ try:
+ with open(pidenv, "rb") as rfb:
+ envlist = [
+ x.decode("utf-8").split("=", 1) for x in rfb.read().split(b"\0")
+ ]
+ envlist = [[x[0], ""] if len(x) == 1 else x for x in envlist]
+ envdict = dict(envlist)
+ if has_var not in envdict:
+ continue
+ if has_val is None:
+ result[pid] = envdict
+ elif envdict[has_var] == str(has_val):
+ result[pid] = envdict
+ except Exception:
+ # E.g., process exited and files are gone
+ pass
return result
diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py
index b6f55664a6..b98698185c 100644
--- a/tests/topotests/lib/topotest.py
+++ b/tests/topotests/lib/topotest.py
@@ -439,6 +439,19 @@ def run_and_expect_type(func, etype, count=20, wait=3, avalue=None):
return (False, result)
+def router_json_cmp_retry(router, cmd, data, exact=False, retry_timeout=10.0):
+ """
+ Runs `cmd` that returns JSON data (normally the command ends with 'json')
+ and compare with `data` contents. Retry by default for 10 seconds
+ """
+
+ def test_func():
+ return router_json_cmp(router, cmd, data, exact)
+
+ ok, _ = run_and_expect(test_func, None, int(retry_timeout), 1)
+ return ok
+
+
def int2dpid(dpid):
"Converting Integer to DPID"
@@ -1603,10 +1616,6 @@ class Router(Node):
if "all" in shell_routers or self.name in shell_routers:
self.run_in_window(os.getenv("SHELL", "bash"))
- vtysh_routers = g_extra_config["vtysh"]
- if "all" in vtysh_routers or self.name in vtysh_routers:
- self.run_in_window("vtysh")
-
if self.daemons["eigrpd"] == 1:
eigrpd_path = os.path.join(self.daemondir, "eigrpd")
if not os.path.isfile(eigrpd_path):
@@ -1619,7 +1628,13 @@ class Router(Node):
logger.info("BFD Test, but no bfdd compiled or installed")
return "BFD Test, but no bfdd compiled or installed"
- return self.startRouterDaemons(tgen=tgen)
+ status = self.startRouterDaemons(tgen=tgen)
+
+ vtysh_routers = g_extra_config["vtysh"]
+ if "all" in vtysh_routers or self.name in vtysh_routers:
+ self.run_in_window("vtysh")
+
+ return status
def getStdErr(self, daemon):
return self.getLog("err", daemon)
diff --git a/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py
index f1b13cbd02..a94dcb505a 100644
--- a/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py
+++ b/tests/topotests/multicast_pim_bsm_topo1/test_mcast_pim_bsmp_01.py
@@ -306,12 +306,6 @@ def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr,
result = create_static_routes(tgen, input_dict)
assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
- # Add kernal route for source
- group = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["pkt_dst"]
- bsr_interface = topo["routers"][bsr]["links"][fhr]["interface"]
- result = addKernelRoute(tgen, bsr, bsr_interface, group)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
# RP Mapping
rp_mapping = topo["routers"][bsr]["bsm"]["bsr_packets"][packet]["rp_mapping"]
@@ -325,16 +319,6 @@ def pre_config_to_bsm(tgen, topo, tc_name, bsr, sender, receiver, fhr, rp, lhr,
if int(mask) == 32:
group = group.split("/")[0]
- # Add kernal routes for sender
- s_interface = topo["routers"][sender]["links"][fhr]["interface"]
- result = addKernelRoute(tgen, sender, s_interface, group)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
- # Add kernal routes for receiver
- r_interface = topo["routers"][receiver]["links"][lhr]["interface"]
- result = addKernelRoute(tgen, receiver, r_interface, group)
- assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
-
# Add static routes for RPs in FHR and LHR
next_hop_fhr = topo["routers"][rp]["links"][fhr]["ipv4"].split("/")[0]
next_hop_lhr = topo["routers"][rp]["links"][lhr]["ipv4"].split("/")[0]
diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
index 3e14ab7164..dc14bc6468 100755
--- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
+++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py
@@ -90,7 +90,6 @@ from lib.pim import (
clear_ip_mroute,
clear_ip_pim_interface_traffic,
verify_igmp_config,
- clear_ip_mroute_verify,
McastTesterHelper,
)
from lib.topolog import logger
@@ -549,17 +548,11 @@ def test_clear_pim_neighbors_and_mroute_p0(request):
result = app_helper.run_traffic("i2", IGMP_JOIN_RANGE_1, "f1")
assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
- step("Clear the mroute on l1, wait for 5 sec")
- result = clear_ip_mroute_verify(tgen, "l1")
- assert result is True, "Testcase {}: Failed Error: {}".format(tc_name, result)
-
step(
- "After clear ip mroute (*,g) entries are re-populated again"
- " with same OIL and IIF, verify using 'show ip mroute' and "
- " 'show ip pim upstream' "
+ "Verify clear ip mroute (*,g) entries are populated by using "
+ "'show ip mroute' cli"
)
- source = topo["routers"]["i2"]["links"]["f1"]["ipv4"].split("/")[0]
input_dict = [
{"dut": "l1", "src_address": "*", "iif": "l1-c1-eth0", "oil": "l1-i1-eth1"}
]
@@ -570,6 +563,21 @@ def test_clear_pim_neighbors_and_mroute_p0(request):
)
assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
+ step("Clear mroutes on l1")
+ clear_ip_mroute(tgen, "l1")
+
+ step(
+ "After clear ip mroute (*,g) entries are re-populated again"
+ " with same OIL and IIF, verify using 'show ip mroute' and "
+ " 'show ip pim upstream' "
+ )
+
+ for data in input_dict:
+ result = verify_ip_mroutes(
+ tgen, data["dut"], data["src_address"], IGMP_JOIN, data["iif"], data["oil"]
+ )
+ assert result is True, "Testcase{} : Failed Error: {}".format(tc_name, result)
+
step(
"Verify 'show ip pim upstream' showing correct OIL and IIF" " on all the nodes"
)
diff --git a/tests/topotests/zebra_netlink/r1/sharpd.conf b/tests/topotests/ospf6_gr_topo1/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/topotests/zebra_netlink/r1/sharpd.conf
+++ b/tests/topotests/ospf6_gr_topo1/__init__.py
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf
new file mode 100644
index 0000000000..1ee1189766
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/ospf6d.conf
@@ -0,0 +1,30 @@
+:assword 1
+hostname rt1
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 1
+ ipv6 ospf network point-to-point
+!
+interface eth-rt2
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 1
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 1.1.1.1
+ redistribute connected
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..58fc114a44
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_database.json
@@ -0,0 +1,95 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"1",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"1.1.1.1"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"1",
+ "interface":"eth-rt2",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"1.1.1.1"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"2.2.2.2"
+ }
+ ]
+ },
+ {
+ "areaId":"1",
+ "interface":"lo",
+ "lsa":[
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..cb88358639
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,12 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"2.2.2.2",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt2",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..0c69310eb4
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_route.json
new file mode 100644
index 0000000000..66ee57ce84
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt1/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt1/zebra.conf
new file mode 100644
index 0000000000..f29f5b73fb
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt1/zebra.conf
@@ -0,0 +1,22 @@
+password 1
+hostname rt1
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 1.1.1.1/32
+ ipv6 address 2001:db8:1000::1/128
+!
+interface stub1
+!
+interface eth-rt2
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt2/ospf6d.conf
new file mode 100644
index 0000000000..6cd8d1a8e3
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/ospf6d.conf
@@ -0,0 +1,35 @@
+password 1
+hostname rt2
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 0
+ ipv6 ospf network point-to-point
+!
+interface eth-rt1
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 1
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+interface eth-rt3
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 2.2.2.2
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..fb16326196
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_database.json
@@ -0,0 +1,183 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"3.3.3.3",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ }
+ ]
+ },
+ {
+ "areaId":"1",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"1.1.1.1"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "interface":"eth-rt3",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"lo",
+ "lsa":[
+ ]
+ },
+ {
+ "areaId":"1",
+ "interface":"eth-rt1",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"1.1.1.1"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"2.2.2.2"
+ }
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..e4f27bf37f
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,20 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"3.3.3.3",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt3",
+ "interfaceState":"PointToPoint"
+ },
+ {
+ "neighborId":"1.1.1.1",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt1",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..34013a19de
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt1"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_route.json
new file mode 100644
index 0000000000..624ff709e3
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt1",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt2/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt2/zebra.conf
new file mode 100644
index 0000000000..e4fe7620da
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt2/zebra.conf
@@ -0,0 +1,22 @@
+password 1
+hostname rt2
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 2.2.2.2/32
+ ipv6 address 2001:db8:1000::2/128
+!
+interface eth-rt1
+!
+interface eth-rt3
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt3/ospf6d.conf
new file mode 100644
index 0000000000..6a63d8f788
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/ospf6d.conf
@@ -0,0 +1,41 @@
+password 1
+hostname rt3
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 0
+ ipv6 ospf network point-to-point
+!
+interface eth-rt2
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+interface eth-rt4
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+interface eth-rt6
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 3.3.3.3
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..f8a8f76093
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_database.json
@@ -0,0 +1,144 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"3.3.3.3",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "interface":"eth-rt2",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"eth-rt4",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"4.4.4.4"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"eth-rt6",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"6.6.6.6"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"lo",
+ "lsa":[
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..d0d7f45b0e
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,28 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"2.2.2.2",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt2",
+ "interfaceState":"PointToPoint"
+ },
+ {
+ "neighborId":"4.4.4.4",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt4",
+ "interfaceState":"PointToPoint"
+ },
+ {
+ "neighborId":"6.6.6.6",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt6",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..ee516b9d66
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt2"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_route.json
new file mode 100644
index 0000000000..f9b43dcdb9
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt2",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt3/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt3/zebra.conf
new file mode 100644
index 0000000000..3a9de21d30
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt3/zebra.conf
@@ -0,0 +1,24 @@
+password 1
+hostname rt3
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 3.3.3.3/32
+ ipv6 address 2001:db8:1000::3/128
+!
+interface eth-rt2
+!
+interface eth-rt4
+!
+interface eth-rt6
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt4/ospf6d.conf
new file mode 100644
index 0000000000..dff33d4094
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/ospf6d.conf
@@ -0,0 +1,35 @@
+password 1
+hostname rt4
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 0
+ ipv6 ospf network point-to-point
+!
+interface eth-rt3
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+interface eth-rt5
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 2
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 4.4.4.4
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..0954d1b8eb
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_database.json
@@ -0,0 +1,188 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"3.3.3.3",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ }
+ ]
+ },
+ {
+ "areaId":"2",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"5.5.5.5"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"4.4.4.4",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"4.4.4.4",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"5.5.5.5",
+ "payload":"2001:db8:1000::5\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "interface":"eth-rt3",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"4.4.4.4"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"lo",
+ "lsa":[
+ ]
+ },
+ {
+ "areaId":"2",
+ "interface":"eth-rt5",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"5.5.5.5"
+ }
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..36abba4f87
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,20 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"3.3.3.3",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt3",
+ "interfaceState":"PointToPoint"
+ },
+ {
+ "neighborId":"5.5.5.5",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt5",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..3e5f17f491
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt5"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_route.json
new file mode 100644
index 0000000000..f5212da4f6
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt5",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt4/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt4/zebra.conf
new file mode 100644
index 0000000000..eeea417b70
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt4/zebra.conf
@@ -0,0 +1,22 @@
+password 1
+hostname rt4
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 4.4.4.4/32
+ ipv6 address 2001:db8:1000::4/128
+!
+interface eth-rt3
+!
+interface eth-rt5
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt5/ospf6d.conf
new file mode 100644
index 0000000000..49c3a8b86f
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/ospf6d.conf
@@ -0,0 +1,29 @@
+password 1
+hostname rt5
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 2
+ ipv6 ospf network point-to-point
+!
+interface eth-rt4
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 2
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 5.5.5.5
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..4a163b984e
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_database.json
@@ -0,0 +1,100 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"2",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"5.5.5.5"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"4.4.4.4",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"4.4.4.4",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"5.5.5.5",
+ "payload":"2001:db8:1000::5\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"2",
+ "interface":"eth-rt4",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"5.5.5.5"
+ }
+ ]
+ },
+ {
+ "areaId":"2",
+ "interface":"lo",
+ "lsa":[
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..9b6ac911d1
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,12 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"4.4.4.4",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt4",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..a56c3262c6
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt4"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_route.json
new file mode 100644
index 0000000000..5ea4f699fe
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt4",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt5/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt5/zebra.conf
new file mode 100644
index 0000000000..0cdb90b129
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt5/zebra.conf
@@ -0,0 +1,20 @@
+password 1
+hostname rt5
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 5.5.5.5/32
+ ipv6 address 2001:db8:1000::5/128
+!
+interface eth-rt4
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt6/ospf6d.conf
new file mode 100644
index 0000000000..5d6d3280b9
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/ospf6d.conf
@@ -0,0 +1,35 @@
+password 1
+hostname rt6
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 0
+ ipv6 ospf network point-to-point
+!
+interface eth-rt3
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 0
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+interface eth-rt7
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 3
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 6.6.6.6
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..71872d19d0
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_database.json
@@ -0,0 +1,183 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"2.2.2.2"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"4.4.4.4"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::7\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"2.2.2.2",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"7.7.7.7"
+ },
+ {
+ "type":"INP",
+ "advRouter":"2.2.2.2",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"3.3.3.3",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"4.4.4.4",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"INP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ }
+ ]
+ },
+ {
+ "areaId":"3",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"7.7.7.7"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"INP",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"0",
+ "interface":"eth-rt3",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"3.3.3.3"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"6.6.6.6"
+ }
+ ]
+ },
+ {
+ "areaId":"0",
+ "interface":"lo",
+ "lsa":[
+ ]
+ },
+ {
+ "areaId":"3",
+ "interface":"eth-rt7",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"7.7.7.7"
+ }
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..aba181ba3f
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,20 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"3.3.3.3",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt3",
+ "interfaceState":"PointToPoint"
+ },
+ {
+ "neighborId":"7.7.7.7",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt7",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..c9494a9d57
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt3"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt7"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_route.json
new file mode 100644
index 0000000000..862f1baffb
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt3",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt7",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt6/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt6/zebra.conf
new file mode 100644
index 0000000000..3c2312da8a
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt6/zebra.conf
@@ -0,0 +1,22 @@
+password 1
+hostname rt6
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 6.6.6.6/32
+ ipv6 address 2001:db8:1000::6/128
+!
+interface eth-rt3
+!
+interface eth-rt7
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/ospf6d.conf b/tests/topotests/ospf6_gr_topo1/rt7/ospf6d.conf
new file mode 100644
index 0000000000..f504fba4de
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/ospf6d.conf
@@ -0,0 +1,30 @@
+password 1
+hostname rt7
+log file ospf6d.log
+log commands
+!
+debug ospf6 lsa router originate
+debug ospf6 lsa router flooding
+debug ospf6 zebra
+debug ospf6 interface
+debug ospf6 neighbor
+debug ospf6 flooding
+debug ospf6 graceful-restart
+debug ospf6 spf process
+!
+interface lo
+ ipv6 ospf area 3
+ ipv6 ospf network point-to-point
+!
+interface eth-rt6
+ ipv6 ospf network point-to-point
+ ipv6 ospf area 3
+ ipv6 ospf hello-interval 3
+ ipv6 ospf dead-interval 9
+!
+router ospf6
+ ospf6 router-id 7.7.7.7
+ redistribute connected
+ graceful-restart grace-period 120
+ graceful-restart helper-only
+!
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_database.json b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_database.json
new file mode 100644
index 0000000000..e70eb57b29
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_database.json
@@ -0,0 +1,95 @@
+{
+ "areaScopedLinkStateDb":[
+ {
+ "areaId":"3",
+ "lsa":[
+ {
+ "type":"Rtr",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"Rtr",
+ "advRouter":"7.7.7.7"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::6\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::2\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::3\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::4\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"IAP",
+ "advRouter":"6.6.6.6",
+ "payload":"2001:db8:1000::5\/128"
+ },
+ {
+ "type":"IAR",
+ "advRouter":"6.6.6.6",
+ "payload":"1.1.1.1"
+ },
+ {
+ "type":"INP",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ],
+ "interfaceScopedLinkStateDb":[
+ {
+ "areaId":"3",
+ "interface":"eth-rt6",
+ "lsa":[
+ {
+ "type":"Lnk",
+ "advRouter":"6.6.6.6"
+ },
+ {
+ "type":"Lnk",
+ "advRouter":"7.7.7.7"
+ }
+ ]
+ },
+ {
+ "areaId":"3",
+ "interface":"lo",
+ "lsa":[
+ ]
+ }
+ ],
+ "asScopedLinkStateDb":[
+ {
+ "lsa":[
+ {
+ "type":"ASE",
+ "advRouter":"1.1.1.1",
+ "payload":"2001:db8:1000::1\/128"
+ },
+ {
+ "type":"ASE",
+ "advRouter":"7.7.7.7",
+ "payload":"2001:db8:1000::7\/128"
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_neighbor.json b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_neighbor.json
new file mode 100644
index 0000000000..5548691ef3
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_neighbor.json
@@ -0,0 +1,12 @@
+{
+ "neighbors":[
+ {
+ "neighborId":"6.6.6.6",
+ "priority":1,
+ "state":"Full",
+ "ifState":"PointToPoint",
+ "interfaceName":"eth-rt6",
+ "interfaceState":"PointToPoint"
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_route.json b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_route.json
new file mode 100644
index 0000000000..42ca54fded
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_ospf_route.json
@@ -0,0 +1,74 @@
+{
+ "routes":{
+ "2001:db8:1000::1\/128":{
+ "isBestRoute":false,
+ "destinationType":"N",
+ "pathType":"E2",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::2\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::3\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::4\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::5\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::6\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IE",
+ "nextHops":[
+ {
+ "interfaceName":"eth-rt6"
+ }
+ ]
+ },
+ "2001:db8:1000::7\/128":{
+ "isBestRoute":true,
+ "destinationType":"N",
+ "pathType":"IA",
+ "nextHops":[
+ {
+ "interfaceName":"lo"
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_route.json b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_route.json
new file mode 100644
index 0000000000..f5f8f710e5
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/show_ipv6_route.json
@@ -0,0 +1,139 @@
+{
+ "2001:db8:1000::1\/128":[
+ {
+ "prefix":"2001:db8:1000::1\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::2\/128":[
+ {
+ "prefix":"2001:db8:1000::2\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::3\/128":[
+ {
+ "prefix":"2001:db8:1000::3\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":30,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::4\/128":[
+ {
+ "prefix":"2001:db8:1000::4\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":40,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::5\/128":[
+ {
+ "prefix":"2001:db8:1000::5\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":50,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::6\/128":[
+ {
+ "prefix":"2001:db8:1000::6\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "selected":true,
+ "destSelected":true,
+ "distance":110,
+ "metric":20,
+ "installed":true,
+ "nexthops":[
+ {
+ "afi":"ipv6",
+ "interfaceName":"eth-rt6",
+ "active":true
+ }
+ ]
+ }
+ ],
+ "2001:db8:1000::7\/128":[
+ {
+ "prefix":"2001:db8:1000::7\/128",
+ "protocol":"ospf6",
+ "vrfId":0,
+ "vrfName":"default",
+ "distance":110,
+ "metric":10,
+ "nexthops":[
+ {
+ "directlyConnected":true,
+ "interfaceName":"lo",
+ "active":true
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/ospf6_gr_topo1/rt7/zebra.conf b/tests/topotests/ospf6_gr_topo1/rt7/zebra.conf
new file mode 100644
index 0000000000..9cc8c29c1e
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/rt7/zebra.conf
@@ -0,0 +1,22 @@
+password 1
+hostname rt7
+log file zebra.log
+log commands
+!
+debug zebra event
+debug zebra packet
+debug zebra rib
+debug zebra kernel
+!
+interface lo
+ ip address 7.7.7.7/32
+ ipv6 address 2001:db8:1000::7/128
+!
+interface stub1
+!
+interface eth-rt6
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py
new file mode 100755
index 0000000000..ccbcadb8b1
--- /dev/null
+++ b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py
@@ -0,0 +1,381 @@
+#!/usr/bin/env python
+
+#
+# test_ospf6_gr_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2021 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_ospf6_gr_topo1.py:
+
+ +---------+
+ | RT1 |
+ | 1.1.1.1 |
+ +---------+
+ |eth-rt2
+ |
+ |eth-rt1
+ +---------+
+ | RT2 |
+ | 2.2.2.2 |
+ +---------+
+ |eth-rt3
+ |
+ |eth-rt2
+ +---------+
+ | RT3 |
+ | 3.3.3.3 |
+ +---------+
+ eth-rt4| |eth-rt6
+ | |
+ +---------+ +--------+
+ | |
+ |eth-rt3 |eth-rt3
+ +---------+ +---------+
+ | RT4 | | RT6 |
+ | 4.4.4.4 | | 6.6.6.6 |
+ +---------+ +---------+
+ |eth-rt5 |eth-rt7
+ | |
+ |eth-rt4 |eth-rt6
+ +---------+ +---------+
+ | RT5 | | RT7 |
+ | 5.5.5.5 | | 7.7.7.7 |
+ +---------+ +---------+
+"""
+
+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
+from lib.common_config import (
+ kill_router_daemons,
+ start_router_daemons,
+)
+
+pytestmark = [pytest.mark.ospf6d]
+
+# Global multi-dimensional dictionary containing all expected outputs
+outputs = {}
+
+
+def build_topo(tgen):
+ #
+ # Define FRR Routers
+ #
+ for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
+ tgen.add_router(router)
+
+ #
+ # Define connections
+ #
+ switch = tgen.add_switch("s1")
+ switch.add_link(tgen.gears["rt1"], nodeif="eth-rt2")
+ switch.add_link(tgen.gears["rt2"], nodeif="eth-rt1")
+
+ switch = tgen.add_switch("s2")
+ switch.add_link(tgen.gears["rt1"], nodeif="stub1")
+
+ switch = tgen.add_switch("s3")
+ switch.add_link(tgen.gears["rt2"], nodeif="eth-rt3")
+ switch.add_link(tgen.gears["rt3"], nodeif="eth-rt2")
+
+ switch = tgen.add_switch("s4")
+ switch.add_link(tgen.gears["rt3"], nodeif="eth-rt4")
+ switch.add_link(tgen.gears["rt4"], nodeif="eth-rt3")
+
+ switch = tgen.add_switch("s5")
+ switch.add_link(tgen.gears["rt3"], nodeif="eth-rt6")
+ switch.add_link(tgen.gears["rt6"], nodeif="eth-rt3")
+
+ switch = tgen.add_switch("s6")
+ switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
+ switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
+
+ switch = tgen.add_switch("s7")
+ switch.add_link(tgen.gears["rt6"], nodeif="eth-rt7")
+ switch.add_link(tgen.gears["rt7"], nodeif="eth-rt6")
+
+ switch = tgen.add_switch("s8")
+ switch.add_link(tgen.gears["rt7"], nodeif="stub1")
+
+
+def setup_module(mod):
+ "Sets up the pytest environment"
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+
+ # For all registered routers, load the zebra configuration file
+ for rname, router in router_list.items():
+ router.load_config(
+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF6, os.path.join(CWD, "{}/ospf6d.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, tries):
+ "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())
+
+ test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
+ _, diff = topotest.run_and_expect(test_func, None, count=tries, wait=0.5)
+ assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+ assert diff is None, assertmsg
+
+
+def check_routers(initial_convergence=False, exiting=None, restarting=None):
+ for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
+ # Check the RIB first, which should be preserved across restarts in
+ # all routers of the routing domain.
+ if initial_convergence == True:
+ tries = 240
+ else:
+ tries = 1
+ router_compare_json_output(
+ rname, "show ipv6 route ospf json", "show_ipv6_route.json", tries
+ )
+
+ # Check that all adjacencies are up and running (except when there's
+ # an OSPF instance that is shutting down).
+ if exiting == None:
+ tries = 240
+ router_compare_json_output(
+ rname,
+ "show ipv6 ospf neighbor json",
+ "show_ipv6_ospf_neighbor.json",
+ tries,
+ )
+
+ # Check the OSPF RIB and LSDB.
+ # In the restarting router, wait up to one minute for the LSDB to converge.
+ if exiting != rname:
+ if initial_convergence == True or restarting == rname:
+ tries = 240
+ else:
+ tries = 1
+ router_compare_json_output(
+ rname,
+ "show ipv6 ospf database json",
+ "show_ipv6_ospf_database.json",
+ tries,
+ )
+ router_compare_json_output(
+ rname, "show ipv6 ospf route json", "show_ipv6_ospf_route.json", tries
+ )
+
+
+#
+# Test initial network convergence
+#
+def test_initial_convergence():
+ logger.info("Test: verify initial network convergence")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ check_routers(initial_convergence=True)
+
+
+#
+# Test rt1 performing a graceful restart
+#
+def test_gr_rt1():
+ logger.info("Test: verify rt1 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt1"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt1", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt1")
+
+ start_router_daemons(tgen, "rt1", ["ospf6d"])
+ check_routers(restarting="rt1")
+
+
+#
+# Test rt2 performing a graceful restart
+#
+def test_gr_rt2():
+ logger.info("Test: verify rt2 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt2"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt2", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt2")
+
+ start_router_daemons(tgen, "rt2", ["ospf6d"])
+ check_routers(restarting="rt2")
+
+
+#
+# Test rt3 performing a graceful restart
+#
+def test_gr_rt3():
+ logger.info("Test: verify rt3 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt3"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt3", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt3")
+
+ start_router_daemons(tgen, "rt3", ["ospf6d"])
+ check_routers(restarting="rt3")
+
+
+#
+# Test rt4 performing a graceful restart
+#
+def test_gr_rt4():
+ logger.info("Test: verify rt4 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt4"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt4", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt4")
+
+ start_router_daemons(tgen, "rt4", ["ospf6d"])
+ check_routers(restarting="rt4")
+
+
+#
+# Test rt5 performing a graceful restart
+#
+def test_gr_rt5():
+ logger.info("Test: verify rt5 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt5"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt5", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt5")
+
+ start_router_daemons(tgen, "rt5", ["ospf6d"])
+ check_routers(restarting="rt5")
+
+
+#
+# Test rt6 performing a graceful restart
+#
+def test_gr_rt6():
+ logger.info("Test: verify rt6 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt6"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt6", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt6")
+
+ start_router_daemons(tgen, "rt6", ["ospf6d"])
+ check_routers(restarting="rt6")
+
+
+#
+# Test rt7 performing a graceful restart
+#
+def test_gr_rt7():
+ logger.info("Test: verify rt7 performing a graceful restart")
+ tgen = get_topogen()
+
+ # Skip if previous fatal error condition is raised
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.net["rt7"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
+ sleep(5)
+ kill_router_daemons(tgen, "rt7", ["ospf6d"], save_config=False)
+ check_routers(exiting="rt7")
+
+ start_router_daemons(tgen, "rt7", ["ospf6d"])
+ check_routers(restarting="rt7")
+
+
+# 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/ospf6_topo2/test_ospf6_topo2.py b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py
index 3738a0c33e..acaa3b8a9b 100644
--- a/tests/topotests/ospf6_topo2/test_ospf6_topo2.py
+++ b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py
@@ -72,14 +72,20 @@ def expect_lsas(router, area, lsas, wait=5, extra_params=""):
assert result is None, assertmsg
-def expect_ospfv3_routes(router, routes, wait=5, detail=False):
+def expect_ospfv3_routes(router, routes, wait=5, type=None, detail=False):
"Run command `ipv6 ospf6 route` and expect route with type."
tgen = get_topogen()
if detail == False:
- cmd = "show ipv6 ospf6 route json"
+ if type == None:
+ cmd = "show ipv6 ospf6 route json"
+ else:
+ cmd = "show ipv6 ospf6 route {} json".format(type)
else:
- cmd = "show ipv6 ospf6 route detail json"
+ if type == None:
+ cmd = "show ipv6 ospf6 route detail json"
+ else:
+ cmd = "show ipv6 ospf6 route {} detail json".format(type)
logger.info("waiting OSPFv3 router '{}' route".format(router))
test_func = partial(
@@ -91,6 +97,21 @@ def expect_ospfv3_routes(router, routes, wait=5, detail=False):
assert result is None, assertmsg
+def dont_expect_route(router, unexpected_route, type=None):
+ "Specialized test function to expect route go missing"
+ tgen = get_topogen()
+
+ if type == None:
+ cmd = "show ipv6 ospf6 route json"
+ else:
+ cmd = "show ipv6 ospf6 route {} json".format(type)
+
+ output = tgen.gears[router].vtysh_cmd(cmd, isjson=True)
+ if unexpected_route in output["routes"]:
+ return output["routes"][unexpected_route]
+ return None
+
+
def build_topo(tgen):
"Build function"
@@ -338,13 +359,6 @@ def test_nssa_lsa_type7():
return lsa
return None
- def dont_expect_route(unexpected_route):
- "Specialized test function to expect route go missing"
- output = tgen.gears["r4"].vtysh_cmd("show ipv6 ospf6 route json", isjson=True)
- if unexpected_route in output["routes"]:
- return output["routes"][unexpected_route]
- return None
-
logger.info("Expecting LSA type-7 and OSPFv3 route 2001:db8:100::/64 to go away")
# Test that LSA doesn't exist.
@@ -354,12 +368,138 @@ def test_nssa_lsa_type7():
assert result is None, assertmsg
# Test that route doesn't exist.
- test_func = partial(dont_expect_route, "2001:db8:100::/64")
+ test_func = partial(dont_expect_route, "r4", "2001:db8:100::/64")
_, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
assertmsg = '"{}" route still exists'.format("r4")
assert result is None, assertmsg
+def test_nssa_no_summary():
+ """
+ Test the following:
+ * Type-3 inter-area routes should be removed when the NSSA no-summary option
+ is configured;
+ * A type-3 inter-area default route should be originated into the NSSA area
+ when the no-summary option is configured;
+ * Once the no-summary option is unconfigured, all previously existing
+ Type-3 inter-area routes should be re-added, and the inter-area default
+ route removed.
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ #
+ # Configure area 1 as a NSSA totally stub area.
+ #
+ config = """
+ configure terminal
+ router ospf6
+ area 2 nssa no-summary
+ """
+ tgen.gears["r2"].vtysh_cmd(config)
+
+ logger.info("Expecting inter-area routes to be removed")
+ for route in ["2001:db8:1::/64", "2001:db8:2::/64"]:
+ test_func = partial(dont_expect_route, "r4", route, type="inter-area")
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = "{}'s {} inter-area route still exists".format("r4", route)
+ assert result is None, assertmsg
+
+ logger.info("Expecting inter-area default-route to be added")
+ routes = {"::/0": {}}
+ expect_ospfv3_routes("r4", routes, wait=30, type="inter-area")
+
+ #
+ # Configure area 1 as a regular NSSA area.
+ #
+ config = """
+ configure terminal
+ router ospf6
+ area 2 nssa
+ """
+ tgen.gears["r2"].vtysh_cmd(config)
+
+ logger.info("Expecting inter-area routes to be re-added")
+ routes = {"2001:db8:1::/64": {}, "2001:db8:2::/64": {}}
+ expect_ospfv3_routes("r4", routes, wait=30, type="inter-area")
+
+ logger.info("Expecting inter-area default route to be removed")
+ test_func = partial(dont_expect_route, "r4", "::/0", type="inter-area")
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = "{}'s inter-area default route still exists".format("r4")
+ assert result is None, assertmsg
+
+
+def test_area_filters():
+ """
+ Test ABR import/export filters.
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ #
+ # Configure import/export filters on r2 (ABR for area 1).
+ #
+ config = """
+ configure terminal
+ ipv6 access-list ACL_IMPORT seq 5 permit 2001:db8:2::/64
+ ipv6 access-list ACL_IMPORT seq 10 deny any
+ ipv6 access-list ACL_EXPORT seq 10 deny any
+ router ospf6
+ area 1 import-list ACL_IMPORT
+ area 1 export-list ACL_EXPORT
+ """
+ tgen.gears["r2"].vtysh_cmd(config)
+
+ logger.info("Expecting inter-area routes to be removed on r1")
+ for route in ["::/0", "2001:db8:3::/64"]:
+ test_func = partial(dont_expect_route, "r1", route, type="inter-area")
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = "{}'s {} inter-area route still exists".format("r1", route)
+ assert result is None, assertmsg
+
+ logger.info("Expecting inter-area routes to be removed on r3")
+ for route in ["2001:db8:1::/64"]:
+ test_func = partial(dont_expect_route, "r3", route, type="inter-area")
+ _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+ assertmsg = "{}'s {} inter-area route still exists".format("r3", route)
+ assert result is None, assertmsg
+
+ #
+ # Update the ACLs used by the import/export filters.
+ #
+ config = """
+ configure terminal
+ ipv6 access-list ACL_IMPORT seq 6 permit 2001:db8:3::/64
+ ipv6 access-list ACL_EXPORT seq 5 permit 2001:db8:1::/64
+ """
+ tgen.gears["r2"].vtysh_cmd(config)
+
+ logger.info("Expecting 2001:db8:3::/64 to be re-added on r1")
+ routes = {"2001:db8:3::/64": {}}
+ expect_ospfv3_routes("r1", routes, wait=30, type="inter-area")
+ logger.info("Expecting 2001:db8:1::/64 to be re-added on r3")
+ routes = {"2001:db8:1::/64": {}}
+ expect_ospfv3_routes("r3", routes, wait=30, type="inter-area")
+
+ #
+ # Unconfigure r2's ABR import/export filters.
+ #
+ config = """
+ configure terminal
+ router ospf6
+ no area 1 import-list ACL_IMPORT
+ no area 1 export-list ACL_EXPORT
+ """
+ tgen.gears["r2"].vtysh_cmd(config)
+
+ logger.info("Expecting ::/0 to be re-added on r1")
+ routes = {"::/0": {}}
+ expect_ospfv3_routes("r1", routes, wait=30, type="inter-area")
+
+
def teardown_module(_mod):
"Teardown the pytest environment"
tgen = get_topogen()
diff --git a/tests/topotests/route_scale/test_route_scale.py b/tests/topotests/route_scale/scale_test_common.py
index fefeccd5e7..3557cb4413 100644
--- a/tests/topotests/route_scale/test_route_scale.py
+++ b/tests/topotests/route_scale/scale_test_common.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
-# test_route_scale.py
+# scale_test_common.py
#
# Copyright (c) 2020 by
# Cumulus Networks, Inc.
@@ -23,7 +23,7 @@
#
"""
-test_route_scale.py: Testing route scale
+scale_test_common.py: Common routines for testing route scale
"""
@@ -45,9 +45,6 @@ from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
-pytestmark = [pytest.mark.sharpd]
-
-
#####################################################
##
## Network Topology Definition
@@ -55,7 +52,7 @@ pytestmark = [pytest.mark.sharpd]
#####################################################
-def build(tgen):
+def scale_build_common(tgen):
"Build function"
# Populate routers
@@ -68,16 +65,9 @@ def build(tgen):
switch.add_link(tgen.gears["r1"])
-#####################################################
-##
-## Tests starting
-##
-#####################################################
-
-
-def setup_module(module):
+def scale_setup_module(module):
"Setup topology"
- tgen = Topogen(build, module.__name__)
+ tgen = Topogen(scale_build_common, module.__name__)
tgen.start_topology()
router_list = tgen.routers()
@@ -93,7 +83,7 @@ def setup_module(module):
# tgen.mininet_cli()
-def teardown_module(_mod):
+def scale_teardown_module(_mod):
"Teardown the pytest environment"
tgen = get_topogen()
@@ -101,7 +91,7 @@ def teardown_module(_mod):
tgen.stop_topology()
-def test_converge_protocols():
+def scale_converge_protocols():
"Wait for protocol convergence"
tgen = get_topogen()
@@ -156,7 +146,7 @@ def run_one_setup(r1, s):
logger.info(output)
-def test_route_install():
+def route_install_helper(iter):
"Test route install for a variety of ecmp"
tgen = get_topogen()
@@ -166,6 +156,16 @@ def test_route_install():
r1 = tgen.gears["r1"]
+ # Avoid top ecmp case for runs with < 4G memory
+ output = tgen.net.cmd_raises("free")
+ m = re.search("Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", output)
+ total_mem = int(m.group(2))
+ if total_mem < 4000000 and iter == 5:
+ logger.info(
+ "Limited memory available: {}, skipping x32 testcase".format(total_mem)
+ )
+ return;
+
installed_file = "{}/r1/installed.routes.json".format(CWD)
expected_installed = json.loads(open(installed_file).read())
@@ -196,38 +196,20 @@ def test_route_install():
# Build up a list of dicts with params for each step of the test;
# use defaults where the step doesn't supply a value
scale_setups = []
- for s in scale_steps:
- d = dict(zip(scale_keys, s))
- for k in scale_keys:
- if k not in d:
- d[k] = scale_defaults[k]
+ s = scale_steps[iter]
- scale_setups.append(d)
+ d = dict(zip(scale_keys, s))
+ for k in scale_keys:
+ if k not in d:
+ d[k] = scale_defaults[k]
- # Avoid top ecmp case for runs with < 4G memory
- output = tgen.net.cmd_raises("free")
- m = re.search("Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", output)
- total_mem = int(m.group(2))
- if total_mem < 4000000:
- logger.info(
- "Limited memory available: {}, skipping x32 testcase".format(total_mem)
- )
- scale_setups = scale_setups[0:-1]
-
- # Run each step using the dicts we've built
- for s in scale_setups:
- run_one_setup(r1, s)
+ run_one_setup(r1, d)
# Mem leak testcase
-def test_memory_leak():
+def scale_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/route_scale/test_route_scale1.py b/tests/topotests/route_scale/test_route_scale1.py
new file mode 100644
index 0000000000..b563883b45
--- /dev/null
+++ b/tests/topotests/route_scale/test_route_scale1.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+#
+# test_route_scale1.py
+#
+# Copyright (c) 2021 by
+# Nvidia, Inc.
+# Donald Sharp
+#
+# 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_route_scale1.py: Testing route scale
+
+"""
+import os
+import re
+import sys
+import pytest
+import json
+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
+
+from scale_test_common import scale_build_common, scale_setup_module, route_install_helper, scale_test_memory_leak, scale_converge_protocols, scale_teardown_module
+
+
+pytestmark = [pytest.mark.sharpd]
+
+def build(tgen):
+ scale_build_common(tgen)
+
+def setup_module(module):
+ scale_setup_module(module)
+
+def teardown_module(_mod):
+ scale_teardown_module(_mod)
+
+def test_converge_protocols():
+ scale_converge_protocols()
+
+def test_route_install_2nh():
+ route_install_helper(1)
+
+def test_route_install_4nh():
+ route_install_helper(2)
+
+def test_route_install_16nh():
+ route_install_helper(4)
+
+def test_memory_leak():
+ scale_test_memory_leak()
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/route_scale/test_route_scale2.py b/tests/topotests/route_scale/test_route_scale2.py
new file mode 100644
index 0000000000..7045995f26
--- /dev/null
+++ b/tests/topotests/route_scale/test_route_scale2.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+#
+# test_route_scale2.py
+#
+# Copyright (c) 2022 by
+# Nvidia, Inc.
+# Donald Sharp
+#
+# 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 NVIDIA DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NVIDIA 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_route_scale2.py: Testing route scale
+
+"""
+import os
+import re
+import sys
+import pytest
+import json
+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
+
+from scale_test_common import scale_build_common, scale_setup_module, route_install_helper, scale_test_memory_leak, scale_converge_protocols, scale_teardown_module
+
+
+pytestmark = [pytest.mark.sharpd]
+
+def build(tgen):
+ scale_build_common(tgen)
+
+def setup_module(module):
+ scale_setup_module(module)
+
+def teardown_module(_mod):
+ scale_teardown_module(_mod)
+
+def test_converge_protocols():
+ scale_converge_protocols()
+
+def test_route_install_1nh():
+ route_install_helper(0)
+
+def test_route_install_8nh():
+ route_install_helper(3)
+
+def test_route_install_32nh():
+ route_install_helper(5)
+
+def test_memory_leak():
+ scale_test_memory_leak()
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/srv6_locator/expected_chunks4.json b/tests/topotests/srv6_locator/expected_chunks4.json
index 6e49738f37..0d4f101c7a 100644
--- a/tests/topotests/srv6_locator/expected_chunks4.json
+++ b/tests/topotests/srv6_locator/expected_chunks4.json
@@ -1,6 +1,2 @@
[
- {
- "name": "loc3",
- "chunks": []
- }
]
diff --git a/tests/topotests/srv6_locator/expected_chunks5.json b/tests/topotests/srv6_locator/expected_chunks5.json
index a18221859e..0d4f101c7a 100644
--- a/tests/topotests/srv6_locator/expected_chunks5.json
+++ b/tests/topotests/srv6_locator/expected_chunks5.json
@@ -1,8 +1,2 @@
[
- {
- "name": "loc3",
- "chunks": [
- "2001:db8:3:3::/64"
- ]
- }
]
diff --git a/tests/topotests/srv6_locator/expected_chunks6.json b/tests/topotests/srv6_locator/expected_chunks6.json
new file mode 100644
index 0000000000..0d4f101c7a
--- /dev/null
+++ b/tests/topotests/srv6_locator/expected_chunks6.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/tests/topotests/srv6_locator/expected_locators4.json b/tests/topotests/srv6_locator/expected_locators4.json
index 7989f9021b..4b0f95f7be 100644
--- a/tests/topotests/srv6_locator/expected_locators4.json
+++ b/tests/topotests/srv6_locator/expected_locators4.json
@@ -23,11 +23,13 @@
]
},
{
- "name":"loc3",
- "statusUp":false,
- "chunks":[
+ "name": "loc3",
+ "prefix": "2001:db8:3:3::/64",
+ "statusUp": true,
+ "chunks": [
{
- "proto":"sharp"
+ "prefix": "2001:db8:3:3::/64",
+ "proto": "system"
}
]
}
diff --git a/tests/topotests/srv6_locator/expected_locators5.json b/tests/topotests/srv6_locator/expected_locators5.json
index 8c512ebc46..bcffa004bd 100644
--- a/tests/topotests/srv6_locator/expected_locators5.json
+++ b/tests/topotests/srv6_locator/expected_locators5.json
@@ -1,17 +1,6 @@
{
"locators":[
{
- "name": "loc1",
- "prefix": "2001:db8:1:1::/64",
- "statusUp": true,
- "chunks": [
- {
- "prefix": "2001:db8:1:1::/64",
- "proto": "system"
- }
- ]
- },
- {
"name": "loc2",
"prefix": "2001:db8:2:2::/64",
"statusUp": true,
@@ -29,7 +18,7 @@
"chunks":[
{
"prefix": "2001:db8:3:3::/64",
- "proto": "sharp"
+ "proto": "system"
}
]
}
diff --git a/tests/topotests/srv6_locator/expected_locators6.json b/tests/topotests/srv6_locator/expected_locators6.json
new file mode 100644
index 0000000000..66d23d5556
--- /dev/null
+++ b/tests/topotests/srv6_locator/expected_locators6.json
@@ -0,0 +1,5 @@
+{
+ "locators":[
+ ]
+}
+
diff --git a/tests/topotests/srv6_locator/test_srv6_locator.py b/tests/topotests/srv6_locator/test_srv6_locator.py
index b48cd09bf9..bc5fa409d2 100755
--- a/tests/topotests/srv6_locator/test_srv6_locator.py
+++ b/tests/topotests/srv6_locator/test_srv6_locator.py
@@ -102,6 +102,10 @@ def test_srv6():
success, result = topotest.run_and_expect(func, None, count=5, wait=0.5)
assert result is None, "Failed"
+ # FOR DEVELOPER:
+ # If you want to stop some specific line and start interactive shell,
+ # please use tgen.mininet_cli() to start it.
+
logger.info("Test1 for Locator Configuration")
check_srv6_locator(router, "expected_locators1.json")
check_sharpd_chunk(router, "expected_chunks1.json")
@@ -116,25 +120,44 @@ def test_srv6():
check_srv6_locator(router, "expected_locators3.json")
check_sharpd_chunk(router, "expected_chunks3.json")
- logger.info("Test4 get chunk for non-exist locator by zclient")
- router.vtysh_cmd("sharp srv6-manager get-locator-chunk loc3")
+ logger.info("Test4 additional locator loc3")
+ router.vtysh_cmd(
+ """
+ configure terminal
+ segment-routing
+ srv6
+ locators
+ locator loc3
+ prefix 2001:db8:3:3::/64
+ """
+ )
check_srv6_locator(router, "expected_locators4.json")
check_sharpd_chunk(router, "expected_chunks4.json")
- logger.info("Test5 Test for Zclient. after locator loc3 was configured")
+ logger.info("Test5 delete locator and chunk is released automatically")
router.vtysh_cmd(
"""
configure terminal
segment-routing
srv6
locators
- locator loc3
- prefix 2001:db8:3:3::/64
+ no locator loc1
"""
)
check_srv6_locator(router, "expected_locators5.json")
check_sharpd_chunk(router, "expected_chunks5.json")
+ logger.info("Test6 delete srv6 all configuration")
+ router.vtysh_cmd(
+ """
+ configure terminal
+ segment-routing
+ no srv6
+ """
+ )
+ check_srv6_locator(router, "expected_locators6.json")
+ check_sharpd_chunk(router, "expected_chunks6.json")
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
diff --git a/tests/topotests/zebra_netlink/r1/v4_route.json b/tests/topotests/zebra_netlink/r1/v4_route.json
deleted file mode 100644
index 39041ebc95..0000000000
--- a/tests/topotests/zebra_netlink/r1/v4_route.json
+++ /dev/null
@@ -1,2302 +0,0 @@
-{
- "2.1.3.7\/32":[
- {
- "prefix":"2.1.3.7\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.8\/32":[
- {
- "prefix":"2.1.3.8\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.9\/32":[
- {
- "prefix":"2.1.3.9\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.10\/32":[
- {
- "prefix":"2.1.3.10\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.11\/32":[
- {
- "prefix":"2.1.3.11\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.12\/32":[
- {
- "prefix":"2.1.3.12\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.13\/32":[
- {
- "prefix":"2.1.3.13\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.14\/32":[
- {
- "prefix":"2.1.3.14\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.15\/32":[
- {
- "prefix":"2.1.3.15\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.16\/32":[
- {
- "prefix":"2.1.3.16\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.17\/32":[
- {
- "prefix":"2.1.3.17\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.18\/32":[
- {
- "prefix":"2.1.3.18\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.19\/32":[
- {
- "prefix":"2.1.3.19\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.20\/32":[
- {
- "prefix":"2.1.3.20\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.21\/32":[
- {
- "prefix":"2.1.3.21\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.22\/32":[
- {
- "prefix":"2.1.3.22\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.23\/32":[
- {
- "prefix":"2.1.3.23\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.24\/32":[
- {
- "prefix":"2.1.3.24\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.25\/32":[
- {
- "prefix":"2.1.3.25\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.26\/32":[
- {
- "prefix":"2.1.3.26\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.27\/32":[
- {
- "prefix":"2.1.3.27\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.28\/32":[
- {
- "prefix":"2.1.3.28\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.29\/32":[
- {
- "prefix":"2.1.3.29\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.30\/32":[
- {
- "prefix":"2.1.3.30\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.31\/32":[
- {
- "prefix":"2.1.3.31\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.32\/32":[
- {
- "prefix":"2.1.3.32\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.33\/32":[
- {
- "prefix":"2.1.3.33\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.34\/32":[
- {
- "prefix":"2.1.3.34\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.35\/32":[
- {
- "prefix":"2.1.3.35\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.36\/32":[
- {
- "prefix":"2.1.3.36\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.37\/32":[
- {
- "prefix":"2.1.3.37\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.38\/32":[
- {
- "prefix":"2.1.3.38\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.39\/32":[
- {
- "prefix":"2.1.3.39\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.40\/32":[
- {
- "prefix":"2.1.3.40\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.41\/32":[
- {
- "prefix":"2.1.3.41\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.42\/32":[
- {
- "prefix":"2.1.3.42\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.43\/32":[
- {
- "prefix":"2.1.3.43\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.44\/32":[
- {
- "prefix":"2.1.3.44\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.45\/32":[
- {
- "prefix":"2.1.3.45\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.46\/32":[
- {
- "prefix":"2.1.3.46\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.47\/32":[
- {
- "prefix":"2.1.3.47\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.48\/32":[
- {
- "prefix":"2.1.3.48\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.49\/32":[
- {
- "prefix":"2.1.3.49\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.50\/32":[
- {
- "prefix":"2.1.3.50\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.51\/32":[
- {
- "prefix":"2.1.3.51\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.52\/32":[
- {
- "prefix":"2.1.3.52\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.53\/32":[
- {
- "prefix":"2.1.3.53\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.54\/32":[
- {
- "prefix":"2.1.3.54\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.55\/32":[
- {
- "prefix":"2.1.3.55\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.56\/32":[
- {
- "prefix":"2.1.3.56\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.57\/32":[
- {
- "prefix":"2.1.3.57\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.58\/32":[
- {
- "prefix":"2.1.3.58\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.59\/32":[
- {
- "prefix":"2.1.3.59\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.60\/32":[
- {
- "prefix":"2.1.3.60\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.61\/32":[
- {
- "prefix":"2.1.3.61\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.62\/32":[
- {
- "prefix":"2.1.3.62\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.63\/32":[
- {
- "prefix":"2.1.3.63\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.64\/32":[
- {
- "prefix":"2.1.3.64\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.65\/32":[
- {
- "prefix":"2.1.3.65\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.66\/32":[
- {
- "prefix":"2.1.3.66\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.67\/32":[
- {
- "prefix":"2.1.3.67\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.68\/32":[
- {
- "prefix":"2.1.3.68\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.69\/32":[
- {
- "prefix":"2.1.3.69\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.70\/32":[
- {
- "prefix":"2.1.3.70\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.71\/32":[
- {
- "prefix":"2.1.3.71\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.72\/32":[
- {
- "prefix":"2.1.3.72\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.73\/32":[
- {
- "prefix":"2.1.3.73\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.74\/32":[
- {
- "prefix":"2.1.3.74\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.75\/32":[
- {
- "prefix":"2.1.3.75\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.76\/32":[
- {
- "prefix":"2.1.3.76\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.77\/32":[
- {
- "prefix":"2.1.3.77\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.78\/32":[
- {
- "prefix":"2.1.3.78\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.79\/32":[
- {
- "prefix":"2.1.3.79\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.80\/32":[
- {
- "prefix":"2.1.3.80\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.81\/32":[
- {
- "prefix":"2.1.3.81\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.82\/32":[
- {
- "prefix":"2.1.3.82\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.83\/32":[
- {
- "prefix":"2.1.3.83\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.84\/32":[
- {
- "prefix":"2.1.3.84\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.85\/32":[
- {
- "prefix":"2.1.3.85\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.86\/32":[
- {
- "prefix":"2.1.3.86\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.87\/32":[
- {
- "prefix":"2.1.3.87\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.88\/32":[
- {
- "prefix":"2.1.3.88\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.89\/32":[
- {
- "prefix":"2.1.3.89\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.90\/32":[
- {
- "prefix":"2.1.3.90\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.91\/32":[
- {
- "prefix":"2.1.3.91\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.92\/32":[
- {
- "prefix":"2.1.3.92\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.93\/32":[
- {
- "prefix":"2.1.3.93\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.94\/32":[
- {
- "prefix":"2.1.3.94\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.95\/32":[
- {
- "prefix":"2.1.3.95\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.96\/32":[
- {
- "prefix":"2.1.3.96\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.97\/32":[
- {
- "prefix":"2.1.3.97\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.98\/32":[
- {
- "prefix":"2.1.3.98\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.99\/32":[
- {
- "prefix":"2.1.3.99\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.100\/32":[
- {
- "prefix":"2.1.3.100\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.101\/32":[
- {
- "prefix":"2.1.3.101\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.102\/32":[
- {
- "prefix":"2.1.3.102\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.103\/32":[
- {
- "prefix":"2.1.3.103\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.104\/32":[
- {
- "prefix":"2.1.3.104\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.105\/32":[
- {
- "prefix":"2.1.3.105\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ],
- "2.1.3.106\/32":[
- {
- "prefix":"2.1.3.106\/32",
- "protocol":"sharp",
- "selected":true,
- "destSelected":true,
- "distance":150,
- "metric":0,
- "installed":true,
- "table":254,
- "nexthops":[
- {
- "flags":3,
- "fib":true,
- "ip":"192.168.1.1",
- "afi":"ipv4",
- "interfaceName":"r1-eth0",
- "active":true,
- "weight":1
- }
- ]
- }
- ]
-}
diff --git a/tests/topotests/zebra_netlink/test_zebra_netlink.py b/tests/topotests/zebra_netlink/test_zebra_netlink.py
index 05cc0ae4a1..ca90c5cb15 100644
--- a/tests/topotests/zebra_netlink/test_zebra_netlink.py
+++ b/tests/topotests/zebra_netlink/test_zebra_netlink.py
@@ -24,21 +24,15 @@
test_zebra_netlink.py: Test some basic interactions with kernel using Netlink
"""
-
-import os
-import sys
-import pytest
+# pylint: disable=C0413
+import ipaddress
import json
+import sys
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
+import pytest
from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topogen import Topogen, TopoRouter
from lib.topolog import logger
@@ -52,62 +46,73 @@ pytestmark = [pytest.mark.sharpd]
#####################################################
-def setup_module(mod):
+@pytest.fixture(scope="module")
+def tgen(request):
"Sets up the pytest environment"
topodef = {"s1": ("r1")}
- tgen = Topogen(topodef, mod.__name__)
+ tgen = Topogen(topodef, request.module.__name__)
tgen.start_topology()
+ # Initialize all routers.
router_list = tgen.routers()
for rname, router in router_list.items():
- router.load_config(
- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
- )
-
- router.load_config(
- TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname))
- )
+ router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
+ router.load_config(TopoRouter.RD_SHARP)
- # Initialize all routers.
tgen.start_router()
+ yield tgen
+ tgen.stop_topology()
-def teardown_module(_mod):
- "Teardown the pytest environment"
- tgen = get_topogen()
-
- # This function tears down the whole topology.
- tgen.stop_topology()
+@pytest.fixture(autouse=True)
+def skip_on_failure(tgen):
+ if tgen.routers_have_failure():
+ pytest.skip("skipped because of previous test failure")
-def test_zebra_netlink_batching():
+def test_zebra_netlink_batching(tgen):
"Test the situation where dataplane fills netlink send buffer entirely."
logger.info(
"Test the situation where dataplane fills netlink send buffer entirely."
)
- tgen = get_topogen()
- if tgen.routers_have_failure():
- pytest.skip("skipped because of previous test failure")
r1 = tgen.gears["r1"]
# Reduce the size of the buffer to hit the limit.
r1.vtysh_cmd("conf t\nzebra kernel netlink batch-tx-buf 256 256")
- r1.vtysh_cmd("sharp install routes 2.1.3.7 nexthop 192.168.1.1 100")
- json_file = "{}/r1/v4_route.json".format(CWD)
- expected = json.loads(open(json_file).read())
- test_func = partial(
- topotest.router_json_cmp,
- r1,
- "show ip route json",
- expected,
- )
- _, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5)
- assertmsg = '"r1" JSON output mismatches'
- assert result is None, assertmsg
-
- r1.vtysh_cmd("sharp remove routes 2.1.3.7 100")
+ count = 100
+ r1.vtysh_cmd("sharp install routes 2.1.3.7 nexthop 192.168.1.1 " + str(count))
+
+ # Generate expected results
+ entry = {
+ "protocol": "sharp",
+ "distance": 150,
+ "metric": 0,
+ "installed": True,
+ "table": 254,
+ "nexthops": [
+ {
+ "fib": True,
+ "ip": "192.168.1.1",
+ "afi": "ipv4",
+ "interfaceName": "r1-eth0",
+ "active": True,
+ "weight": 1,
+ }
+ ],
+ }
+
+ match = {}
+ base = int(ipaddress.ip_address(u"2.1.3.7"))
+ for i in range(base, base + count):
+ pfx = str(ipaddress.ip_network((i, 32)))
+ match[pfx] = [dict(entry, prefix=pfx)]
+
+ ok = topotest.router_json_cmp_retry(r1, "show ip route json", match)
+ assert ok, '"r1" JSON output mismatches'
+
+ r1.vtysh_cmd("sharp remove routes 2.1.3.7 " + str(count))
if __name__ == "__main__":
diff --git a/tests/zebra/test_lm_plugin.c b/tests/zebra/test_lm_plugin.c
index 4a9344fee4..ecfb085793 100644
--- a/tests/zebra/test_lm_plugin.c
+++ b/tests/zebra/test_lm_plugin.c
@@ -77,7 +77,7 @@ static int lm_release_chunk_pi(struct zserv *client, uint32_t start,
/* use external allocations */
-static void lp_plugin_init()
+static void lp_plugin_init(void)
{
/* register our own hooks */
hook_register(lm_client_connect, test_client_connect);
@@ -86,7 +86,7 @@ static void lp_plugin_init()
hook_register(lm_release_chunk, lm_release_chunk_pi);
}
-static void lp_plugin_cleanup()
+static void lp_plugin_cleanup(void)
{
/* register our own hooks */
hook_unregister(lm_client_connect, test_client_connect);
@@ -98,7 +98,7 @@ static void lp_plugin_cleanup()
/* tests */
-static void test_lp_plugin()
+static void test_lp_plugin(void)
{
struct label_manager_chunk *lmc;