diff --git a/tests/topotests/ospf6_point_to_multipoint/README.md b/tests/topotests/ospf6_point_to_multipoint/README.md new file mode 100644 index 000000000000..59c9837aea97 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/README.md @@ -0,0 +1,137 @@ +# OSPFv3 (IPv6) Topology Test (point-to-multipoint) + +## Topology + -----\ + SW1 - Stub Net 1 SW2 - Stub Net 2 \ + fc00:1:1:1::/64 fc00:2:2:2::/64 \ + \___________________/ \___________________/ | + | | | + | | | + | ::1 | ::2 | + +---------+---------+ +---------+---------+ | + | R1 | | R2 | | + | FRRouting | | FRRouting | | + | Rtr-ID: 10.0.0.1 | | Rtr-ID: 10.0.0.2 | | + +---------+---------+ +---------+---------+ | + | ::1 | ::2 \ + \______ ___________/ OSPFv3 + \ / Area 0.0.0.0 + \ / / + ~~~~~~~~~~~~~~~~~~ | + ~~ SW5 ~~ | + ~~ Switch ~~ | + ~~ fc00:A:A:A::/64 ~~ | + ~~~~~~~~~~~~~~~~~~ | + | /---- | + | ::3 | SW3 - Stub Net 3 | + +---------+---------+ /-+ fc00:3:3:3::/64 | + | R3 | / | / + | FRRouting +--/ \---- / + | Rtr-ID: 10.0.0.3 | ::3 ___________/ + +---------+---------+ \ + | ::3 \ + | \ + ~~~~~~~~~~~~~~~~~~ | + ~~ SW6 ~~ | + ~~ Switch ~~ | + ~~ fc00:B:B:B::/64 ~~ \ + ~~~~~~~~~~~~~~~~~~ OSPFv3 + | Area 0.0.0.1 + | ::4 / + +---------+---------+ /---- | + | R4 | | SW4 - Stub Net 4 | + | FRRouting +------+ fc00:4:4:4::/64 | + | Rtr-ID: 10.0.0.4 | ::4 | / + +-------------------+ \---- / + -----/ + +## FRR Configuration + +Full config as used is in r1 / r2 / r3 / r4 / r5 subdirectories + +Simplified `R1` config (R1 is similar) + + hostname r1 + ! + interface r1-stubnet + ipv6 address fc00:1:1:1::1/64 + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.0 + ! + interface r1-sw5 + ipv6 address fc00:a:a:a::1/64 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.0 + ! + router ospf6 + router-id 10.0.0.1 + log-adjacency-changes detail + redistribute static + ! + ipv6 route fc00:1111:1111:1111::/64 fc00:1:1:1::1234 + +Simplified `R3` config + + hostname r3 + ! + interface r3-stubnet + ipv6 address fc00:3:3:3::3/64 + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.0 + ! + interface r3-sw5 + ipv6 address fc00:a:a:a::3/64 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.0 + ipv6 ospf6 p2p-p2mp connected-prefixes include + ! + interface r3-sw6 + ipv6 address fc00:b:b:b::3/64 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.1 + ipv6 ospf6 p2p-p2mp connected-prefixes include + ! + router ospf6 + router-id 10.0.0.3 + log-adjacency-changes detail + redistribute static + ! + ipv6 route fc00:3333:3333:3333::/64 fc00:3:3:3::1234 + +## Tests executed + +### Check if FRR is running + +Test is executed by running + + vtysh -c "show logging" | grep "Logging configuration for" + +on each FRR router. This should return the logging information for all daemons registered +to Zebra and the list of running daemons is compared to the daemons started for this test (`zebra` and `ospf6d`) + +### Check if OSPFv3 to converge + +OSPFv3 is expected to converge on each view within 60s total time. Convergence is verified by executing (on each node) + + vtysh -c "show ipv6 ospf neigh" + +and checking for "Full" neighbor status in the output. An additional 15 seconds after the full converge is waited for +routes to populate before the following routing table checks are executed + +### Check OSPFv3 Routing Tables + +Routing table is verified by running + + vtysh -c "show ipv6 route" + +on each node and comparing the result to the stored example config (see `show_ipv6_route.ref` in r1 / r2 / r3 / r4 directories). +Link-Local addresses are masked out before the compare. + +### Check Linux Kernel Routing Table + +Linux Kernel IPv6 Routing table is verified on each FRR node with + + ip -6 route + +Tables are compared with reference routing table (see `ip_6_address.ref` in r1 / r2 / r3 / r4 directories). +Link-Local addresses are translated after getting collected on each node with interface name to make them consistent diff --git a/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.nhg.ref b/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.nhg.ref new file mode 100644 index 000000000000..203f2def5e9e --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.nhg.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 nhid XXXX via fc00:1:1:1::1234 dev r1-stubnet proto XXXX metric 20 pref medium +fc00:1:1:1::/64 dev r1-stubnet proto XXXX metric 256 pref medium +fc00:2222:2222:2222::/64 nhid XXXX via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 nhid XXXX via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r1-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::2 nhid XXXX via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::3 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::3 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::4 nhid XXXX via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.ref b/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.ref new file mode 100644 index 000000000000..b77c99674000 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r1/ip_6_address.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 via fc00:1:1:1::1234 dev r1-stubnet proto XXXX metric 20 pref medium +fc00:1:1:1::/64 dev r1-stubnet proto XXXX metric 256 pref medium +fc00:2222:2222:2222::/64 via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r1-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::2 via fe80::__(r2-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::3 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::3 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::4 via fe80::__(r3-sw5)__ dev r1-sw5 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r1/ospf6d.conf b/tests/topotests/ospf6_point_to_multipoint/r1/ospf6d.conf new file mode 100644 index 000000000000..79a9dcae116b --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r1/ospf6d.conf @@ -0,0 +1,30 @@ +hostname r1 +log file ospf6d.log +! +! debug ospf6 message all +! debug ospf6 lsa unknown +! debug ospf6 zebra +! debug ospf6 interface +! debug ospf6 neighbor +! debug ospf6 route table +! debug ospf6 flooding +! +interface r1-sw5 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 p2p-p2mp connected-prefixes include +! +interface r1-stubnet + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.0 +! +router ospf6 + ospf6 router-id 10.0.0.1 + log-adjacency-changes detail + redistribute static +! +line vty + exec-timeout 0 0 +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r1/show_ipv6_route.ref b/tests/topotests/ospf6_point_to_multipoint/r1/show_ipv6_route.ref new file mode 100644 index 000000000000..911b3e40d68c --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r1/show_ipv6_route.ref @@ -0,0 +1,13 @@ +O fc00:1:1:1::/64 [110/10] is directly connected, r1-stubnet, weight 1, XX:XX:XX +O>* fc00:2:2:2::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:3:3:3::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:4:4:4::/64 [110/30] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O fc00:a:a:a::/64 [110/10] is directly connected, r1-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::2/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::4/128 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:2222:2222:2222::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:3333:3333:3333::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX +O>* fc00:4444:4444:4444::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r1-sw5, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf6_point_to_multipoint/r1/zebra.conf b/tests/topotests/ospf6_point_to_multipoint/r1/zebra.conf new file mode 100644 index 000000000000..3a7db9f25e36 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r1/zebra.conf @@ -0,0 +1,20 @@ +! +hostname r1 +log file zebra.log +! +! debug zebra events +! debug zebra rib +! +interface r1-stubnet + ipv6 address fc00:1:1:1::1/64 +! +interface r1-sw5 + ipv6 address fc00:a:a:a::1/64 +! +interface lo +! +ipv6 route fc00:1111:1111:1111::/64 fc00:1:1:1::1234 +! +! +line vty +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.nhg.ref b/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.nhg.ref new file mode 100644 index 000000000000..d4534b10bb6d --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.nhg.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 nhid XXXX via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 nhid XXXX via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 nhid XXXX via fc00:2:2:2::1234 dev r2-stubnet proto XXXX metric 20 pref medium +fc00:2:2:2::/64 dev r2-stubnet proto XXXX metric 256 pref medium +fc00:3333:3333:3333::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r2-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::1 nhid XXXX via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::3 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::3 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::4 nhid XXXX via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.ref b/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.ref new file mode 100644 index 000000000000..330b696c3a18 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r2/ip_6_address.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 via fc00:2:2:2::1234 dev r2-stubnet proto XXXX metric 20 pref medium +fc00:2:2:2::/64 dev r2-stubnet proto XXXX metric 256 pref medium +fc00:3333:3333:3333::/64 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r2-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::1 via fe80::__(r1-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::3 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::3 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::4 via fe80::__(r3-sw5)__ dev r2-sw5 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r2/ospf6d.conf b/tests/topotests/ospf6_point_to_multipoint/r2/ospf6d.conf new file mode 100644 index 000000000000..751d8d84e7db --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r2/ospf6d.conf @@ -0,0 +1,30 @@ +hostname r2 +log file ospf6d.log +! +! debug ospf6 message all +! debug ospf6 lsa unknown +! debug ospf6 zebra +! debug ospf6 interface +! debug ospf6 neighbor +! debug ospf6 route table +! debug ospf6 flooding +! +interface r2-sw5 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 p2p-p2mp connected-prefixes include +! +interface r2-stubnet + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.0 +! +router ospf6 + ospf6 router-id 10.0.0.2 + log-adjacency-changes detail + redistribute static +! +line vty + exec-timeout 0 0 +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r2/show_ipv6_route.ref b/tests/topotests/ospf6_point_to_multipoint/r2/show_ipv6_route.ref new file mode 100644 index 000000000000..2eff0291ad97 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r2/show_ipv6_route.ref @@ -0,0 +1,13 @@ +O>* fc00:1:1:1::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O fc00:2:2:2::/64 [110/10] is directly connected, r2-stubnet, weight 1, XX:XX:XX +O>* fc00:3:3:3::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:4:4:4::/64 [110/30] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O fc00:a:a:a::/64 [110/10] is directly connected, r2-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::1/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:b:b:b::4/128 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:1111:1111:1111::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:3333:3333:3333::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX +O>* fc00:4444:4444:4444::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r2-sw5, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf6_point_to_multipoint/r2/zebra.conf b/tests/topotests/ospf6_point_to_multipoint/r2/zebra.conf new file mode 100644 index 000000000000..5571dc979c70 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r2/zebra.conf @@ -0,0 +1,20 @@ +! +hostname r2 +log file zebra.log +! +! debug zebra events +! debug zebra rib +! +interface r2-stubnet + ipv6 address fc00:2:2:2::2/64 +! +interface r2-sw5 + ipv6 address fc00:a:a:a::2/64 +! +interface lo +! +ipv6 route fc00:2222:2222:2222::/64 fc00:2:2:2::1234 +! +! +line vty +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.nhg.ref b/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.nhg.ref new file mode 100644 index 000000000000..903c1d962fb8 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.nhg.ref @@ -0,0 +1,13 @@ +fc00:1111:1111:1111::/64 nhid XXXX via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 nhid XXXX via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 nhid XXXX via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 nhid XXXX via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 nhid XXXX via fc00:3:3:3::1234 dev r3-stubnet proto XXXX metric 20 pref medium +fc00:3:3:3::/64 dev r3-stubnet proto XXXX metric 256 pref medium +fc00:4444:4444:4444::/64 nhid XXXX via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 nhid XXXX via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r3-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::1 nhid XXXX via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::2 nhid XXXX via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 dev r3-sw6 proto XXXX metric 256 pref medium +fc00:b:b:b::4 nhid XXXX via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.ref b/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.ref new file mode 100644 index 000000000000..3dbcf36b4806 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r3/ip_6_address.ref @@ -0,0 +1,13 @@ +fc00:1111:1111:1111::/64 via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 via fc00:3:3:3::1234 dev r3-stubnet proto XXXX metric 20 pref medium +fc00:3:3:3::/64 dev r3-stubnet proto XXXX metric 256 pref medium +fc00:4444:4444:4444::/64 via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium +fc00:4:4:4::/64 via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::/64 dev r3-sw5 proto XXXX metric 256 pref medium +fc00:a:a:a::1 via fe80::__(r1-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:a:a:a::2 via fe80::__(r2-sw5)__ dev r3-sw5 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 dev r3-sw6 proto XXXX metric 256 pref medium +fc00:b:b:b::4 via fe80::__(r4-sw6)__ dev r3-sw6 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r3/ospf6d.conf b/tests/topotests/ospf6_point_to_multipoint/r3/ospf6d.conf new file mode 100644 index 000000000000..74e8ddf00f7c --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r3/ospf6d.conf @@ -0,0 +1,37 @@ +hostname r3 +log file ospf6d.log +! +! debug ospf6 message all +! debug ospf6 lsa unknown +! debug ospf6 zebra +! debug ospf6 interface +! debug ospf6 neighbor +! debug ospf6 route table +! debug ospf6 flooding +! +interface r3-sw5 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 p2p-p2mp connected-prefixes include +! +interface r3-sw6 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 p2p-p2mp connected-prefixes include +! +interface r3-stubnet + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.0 +! +router ospf6 + ospf6 router-id 10.0.0.3 + log-adjacency-changes detail + redistribute static +! +line vty + exec-timeout 0 0 +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r3/show_ipv6_route.ref b/tests/topotests/ospf6_point_to_multipoint/r3/show_ipv6_route.ref new file mode 100644 index 000000000000..df949e64ea11 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r3/show_ipv6_route.ref @@ -0,0 +1,12 @@ +O>* fc00:1:1:1::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O>* fc00:2:2:2::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O fc00:3:3:3::/64 [110/10] is directly connected, r3-stubnet, weight 1, XX:XX:XX +O>* fc00:4:4:4::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw6, weight 1, XX:XX:XX +O fc00:a:a:a::/64 [110/10] is directly connected, r3-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::1/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O>* fc00:a:a:a::2/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O fc00:b:b:b::/64 [110/10] is directly connected, r3-sw6, weight 1, XX:XX:XX +O>* fc00:b:b:b::4/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw6, weight 1, XX:XX:XX +O>* fc00:1111:1111:1111::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O>* fc00:2222:2222:2222::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw5, weight 1, XX:XX:XX +O>* fc00:4444:4444:4444::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r3-sw6, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf6_point_to_multipoint/r3/zebra.conf b/tests/topotests/ospf6_point_to_multipoint/r3/zebra.conf new file mode 100644 index 000000000000..3cc5626bd7e5 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r3/zebra.conf @@ -0,0 +1,23 @@ +! +hostname r3 +log file zebra.log +! +! debug zebra events +! debug zebra rib +! +interface r3-stubnet + ipv6 address fc00:3:3:3::3/64 +! +interface r3-sw5 + ipv6 address fc00:a:a:a::3/64 +! +interface r3-sw6 + ipv6 address fc00:b:b:b::3/64 +! +interface lo +! +ipv6 route fc00:3333:3333:3333::/64 fc00:3:3:3::1234 +! +! +line vty +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.nhg.ref b/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.nhg.ref new file mode 100644 index 000000000000..ca1e2f0d7866 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.nhg.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 nhid XXXX via fc00:4:4:4::1234 dev r4-stubnet proto XXXX metric 20 pref medium +fc00:4:4:4::/64 dev r4-stubnet proto XXXX metric 256 pref medium +fc00:a:a:a::/64 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::1 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::2 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::3 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 dev r4-sw6 proto XXXX metric 256 pref medium +fc00:b:b:b::3 nhid XXXX via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.ref b/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.ref new file mode 100644 index 000000000000..4f4e72fc27be --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r4/ip_6_address.ref @@ -0,0 +1,14 @@ +fc00:1111:1111:1111::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:1:1:1::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:2222:2222:2222::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:2:2:2::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:3333:3333:3333::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:3:3:3::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:4444:4444:4444::/64 via fc00:4:4:4::1234 dev r4-stubnet proto XXXX metric 20 pref medium +fc00:4:4:4::/64 dev r4-stubnet proto XXXX metric 256 pref medium +fc00:a:a:a::/64 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::1 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::2 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:a:a:a::3 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium +fc00:b:b:b::/64 dev r4-sw6 proto XXXX metric 256 pref medium +fc00:b:b:b::3 via fe80::__(r3-sw6)__ dev r4-sw6 proto XXXX metric 20 pref medium diff --git a/tests/topotests/ospf6_point_to_multipoint/r4/ospf6d.conf b/tests/topotests/ospf6_point_to_multipoint/r4/ospf6d.conf new file mode 100644 index 000000000000..25b8551dd792 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r4/ospf6d.conf @@ -0,0 +1,30 @@ +hostname r4 +log file ospf6d.log +! +! debug ospf6 message all +! debug ospf6 lsa unknown +! debug ospf6 zebra +! debug ospf6 interface +! debug ospf6 neighbor +! debug ospf6 route table +! debug ospf6 flooding +! +interface r4-sw6 + ipv6 ospf6 network point-to-multipoint + ipv6 ospf6 area 0.0.0.1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 + ipv6 ospf6 p2p-p2mp connected-prefixes include +! +interface r4-stubnet + ipv6 ospf6 passive + ipv6 ospf6 area 0.0.0.1 +! +router ospf6 + ospf6 router-id 10.0.0.4 + log-adjacency-changes detail + redistribute static +! +line vty + exec-timeout 0 0 +! diff --git a/tests/topotests/ospf6_point_to_multipoint/r4/show_ipv6_route.ref b/tests/topotests/ospf6_point_to_multipoint/r4/show_ipv6_route.ref new file mode 100644 index 000000000000..f377ca3a8882 --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r4/show_ipv6_route.ref @@ -0,0 +1,13 @@ +O>* fc00:1:1:1::/64 [110/30] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:2:2:2::/64 [110/30] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:3:3:3::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O fc00:4:4:4::/64 [110/10] is directly connected, r4-stubnet, weight 1, XX:XX:XX +O>* fc00:a:a:a::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:a:a:a::1/128 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:a:a:a::2/128 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:a:a:a::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O fc00:b:b:b::/64 [110/10] is directly connected, r4-sw6, weight 1, XX:XX:XX +O>* fc00:b:b:b::3/128 [110/10] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:1111:1111:1111::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:2222:2222:2222::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX +O>* fc00:3333:3333:3333::/64 [110/20] via fe80::XXXX:XXXX:XXXX:XXXX, r4-sw6, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf6_point_to_multipoint/r4/zebra.conf b/tests/topotests/ospf6_point_to_multipoint/r4/zebra.conf new file mode 100644 index 000000000000..20e27cea46ae --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/r4/zebra.conf @@ -0,0 +1,20 @@ +! +hostname r4 +log file zebra.log +! +! debug zebra events +! debug zebra rib +! +interface r4-stubnet + ipv6 address fc00:4:4:4::4/64 +! +interface r4-sw6 + ipv6 address fc00:b:b:b::4/64 +! +interface lo +! +ipv6 route fc00:4444:4444:4444::/64 fc00:4:4:4::1234 +! +! +line vty +! diff --git a/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py b/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py new file mode 100644 index 000000000000..142acf1eb47d --- /dev/null +++ b/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_ospf6_point_to_multipoint.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2023 by +# Network Device Education Foundation, Inc. ("NetDEF") +# + +r""" +test_ospf6_point_to_multipoint.py: + + -----\ + SW1 - Stub Net 1 SW2 - Stub Net 2 \ + fc00:1:1:1::/64 fc00:2:2:2::/64 \ +\___________________/ \___________________/ | + | | | + | | | + | ::1 | ::2 | ++---------+---------+ +---------+---------+ | +| R1 | | R2 | | +| FRRouting | | FRRouting | | +| Rtr-ID: 10.0.0.1 | | Rtr-ID: 10.0.0.2 | | ++---------+---------+ +---------+---------+ | + | ::1 | ::2 \ + \______ ___________/ OSPFv3 + \ / Area 0.0.0.0 + \ / / + ~~~~~~~~~~~~~~~~~~ | + ~~ SW5 ~~ | + ~~ Switch ~~ | + ~~ fc00:A:A:A::/64 ~~ | + ~~~~~~~~~~~~~~~~~~ | + | /---- | + | ::3 | SW3 - Stub Net 3 | + +---------+---------+ /-+ fc00:3:3:3::/64 | + | R3 | / | / + | FRRouting +--/ \---- / + | Rtr-ID: 10.0.0.3 | ::3 ___________/ + +---------+---------+ \ + | ::3 \ + | \ + ~~~~~~~~~~~~~~~~~~ | + ~~ SW6 ~~ | + ~~ Switch ~~ | + ~~ fc00:B:B:B::/64 ~~ \ + ~~~~~~~~~~~~~~~~~~ OSPFv3 + | Area 0.0.0.1 + | ::4 / + +---------+---------+ /---- | + | R4 | | SW4 - Stub Net 4 | + | FRRouting +------+ fc00:4:4:4::/64 | + | Rtr-ID: 10.0.0.4 | ::4 | / + +-------------------+ \---- / + -----/ +""" + +import os +import re +import sys +import pytest + +from functools import partial + + +# Save the Current Working Directory to find configuration files later. +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 + + +pytestmark = [pytest.mark.ospfd] + + +def build_topo(tgen): + # Create 4 routers + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + # + # Wire up the switches and routers + # Note that we specify the link names so we match the config files + # + + # Create a empty network for router 1 + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"], nodeif="r1-stubnet") + + # Create a empty network for router 2 + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"], nodeif="r2-stubnet") + + # Create a empty network for router 3 + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r3"], nodeif="r3-stubnet") + + # Create a empty network for router 4 + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r4"], nodeif="r4-stubnet") + + # Interconnect routers 1, 2, and 3 + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["r1"], nodeif="r1-sw5") + switch.add_link(tgen.gears["r2"], nodeif="r2-sw5") + switch.add_link(tgen.gears["r3"], nodeif="r3-sw5") + + # Interconnect routers 3 and 4 + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["r3"], nodeif="r3-sw6") + switch.add_link(tgen.gears["r4"], nodeif="r4-sw6") + + +##################################################### +## +## Tests starting +## +##################################################### + + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + logger.info("** %s: Setup Topology" % mod.__name__) + logger.info("******************************************") + + # For debugging after starting net, but before starting FRR, + # uncomment the next line + # tgen.mininet_cli() + + 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_OSPF6, os.path.join(CWD, "{}/ospf6d.conf".format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + + # For debugging after starting FRR daemons, uncomment the next line + # tgen.mininet_cli() + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_wait_protocol_convergence(): + "Wait for OSPFv3 to converge" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for protocols to converge") + + def expect_neighbor_full(router, neighbor): + "Wait until OSPFv3 convergence." + logger.info("waiting OSPFv3 router '{}'".format(router)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ipv6 ospf6 neighbor json", + {"neighbors": [{"neighborId": neighbor, "state": "Full"}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" convergence failure'.format(router) + assert result is None, assertmsg + + expect_neighbor_full("r1", "10.0.0.2") + expect_neighbor_full("r1", "10.0.0.3") + + expect_neighbor_full("r2", "10.0.0.1") + expect_neighbor_full("r2", "10.0.0.3") + + expect_neighbor_full("r3", "10.0.0.1") + expect_neighbor_full("r3", "10.0.0.2") + expect_neighbor_full("r3", "10.0.0.4") + + expect_neighbor_full("r4", "10.0.0.3") + + +def compare_show_ipv6(rname, expected): + """ + Calls 'show ipv6 route' for router `rname` and compare the obtained + result with the expected output. + """ + tgen = get_topogen() + + # Use the vtysh output, with some masking to make comparison easy + current = topotest.ip6_route_zebra(tgen.gears[rname]) + + # Use just the 'O'spf lines of the output + linearr = [] + for line in current.splitlines(): + if re.match("^O", line): + linearr.append(line) + + current = "\n".join(linearr) + + return topotest.difflines( + topotest.normalize_text(current), + topotest.normalize_text(expected), + title1="Current output", + title2="Expected output", + ) + + +def test_ospfv3_routingTable(): + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # For debugging, uncomment the next line + # tgen.mininet_cli() + + # Verify OSPFv3 Routing Table + for router, rnode in tgen.routers().items(): + logger.info('Waiting for router "%s" convergence', router) + + # Load expected results from the command + reffile = os.path.join(CWD, "{}/show_ipv6_route.ref".format(router)) + expected = open(reffile).read() + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(compare_show_ipv6, router, expected) + result, diff = topotest.run_and_expect(test_func, "", count=120, wait=0.5) + assert result, "OSPFv3 did not converge on {}:\n{}".format(router, diff) + + +def test_linux_ipv6_kernel_routingTable(): + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + # Verify Linux Kernel Routing Table + logger.info("Verifying Linux IPv6 Kernel Routing Table") + + failures = 0 + + # Get a list of all current link-local addresses first as they change for + # each run and we need to translate them + linklocals = [] + for i in range(1, 5): + linklocals += tgen.net["r{}".format(i)].get_ipv6_linklocal() + + # Now compare the routing tables (after substituting link-local addresses) + + for i in range(1, 5): + # Actual output from router + actual = tgen.gears["r{}".format(i)].run("ip -6 route").rstrip() + if "nhid" in actual: + refTableFile = os.path.join(CWD, "r{}/ip_6_address.nhg.ref".format(i)) + else: + refTableFile = os.path.join(CWD, "r{}/ip_6_address.ref".format(i)) + + if os.path.isfile(refTableFile): + expected = open(refTableFile).read().rstrip() + # Fix newlines (make them all the same) + expected = ("\n".join(expected.splitlines())).splitlines(1) + + # Mask out Link-Local mac addresses + for ll in linklocals: + actual = actual.replace(ll[1], "fe80::__(%s)__" % ll[0]) + # Mask out protocol name or number + actual = re.sub(r"[ ]+proto [0-9a-z]+ +", " proto XXXX ", actual) + actual = re.sub(r"[ ]+nhid [0-9]+ +", " nhid XXXX ", actual) + # Remove ff00::/8 routes (seen on some kernels - not from FRR) + actual = re.sub(r"ff00::/8.*", "", actual) + + # Strip empty lines + actual = actual.lstrip() + actual = actual.rstrip() + actual = re.sub(r" +", " ", actual) + + filtered_lines = [] + for line in sorted(actual.splitlines()): + if line.startswith("fe80::/64 ") or line.startswith( + "unreachable fe80::/64 " + ): + continue + filtered_lines.append(line) + actual = "\n".join(filtered_lines).splitlines(1) + + # Print Actual table + # logger.info("Router r%s table" % i) + # for line in actual: + # logger.info(line.rstrip()) + + # Generate Diff + diff = topotest.get_textdiff( + actual, + expected, + title1="actual OSPFv3 IPv6 routing table", + title2="expected OSPFv3 IPv6 routing table", + ) + + # Empty string if it matches, otherwise diff contains unified diff + if diff: + sys.stderr.write( + "r%s failed Linux IPv6 Kernel Routing Table Check:\n%s\n" + % (i, diff) + ) + failures += 1 + else: + logger.info("r%s ok" % i) + + assert failures == 0, ( + "Linux Kernel IPv6 Routing Table verification failed for router r%s:\n%s" + % (i, diff) + ) + else: + logger.error("r{} failed - no nhid ref file: {}".format(i, refTableFile)) + + assert False, ( + "Linux Kernel IPv6 Routing Table verification failed for router r%s\n" + % (i) + ) + + +def test_shutdown_check_stderr(): + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip("skipped because of router(s) failure") + + if os.environ.get("TOPOTESTS_CHECK_STDERR") is None: + logger.info( + "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n" + ) + pytest.skip("Skipping test for Stderr output") + + net = tgen.net + + logger.info("\n\n** Verifying unexpected STDERR output from daemons") + logger.info("******************************************") + + for i in range(1, 5): + net["r%s" % i].stopRouter() + log = net["r%s" % i].getStdErr("ospf6d") + if log: + logger.info("\nRouter r%s OSPF6d StdErr Log:\n%s" % (i, log)) + log = net["r%s" % i].getStdErr("zebra") + if log: + logger.info("\nRouter r%s Zebra StdErr Log:\n%s" % (i, log)) + + +def test_shutdown_check_memleak(): + "Run the memory leak test and report results." + + if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None: + logger.info( + "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)" + ) + pytest.skip("Skipping test for memory leaks") + + tgen = get_topogen() + + net = tgen.net + + for i in range(1, 5): + net["r%s" % i].stopRouter() + net["r%s" % i].report_memory_leaks( + os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__) + ) + + +if __name__ == "__main__": + + # To suppress tracebacks, either use the following pytest call or + # add "--tb=no" to cli + # retval = pytest.main(["-s", "--tb=no"]) + + retval = pytest.main(["-s"]) + sys.exit(retval)