tests: OSPF6 point-to-multipoint topotest

* Check if FRR is running
* Check if OSPFv3 converges
* Check OSPFv3 Routing Tables
* Check Linux Kernel Routing Table

Signed-off-by: Adriano Marto Reis <adrianomarto@gmail.com>
This commit is contained in:
Adriano Marto Reis 2023-10-07 10:48:28 +10:00
parent 25dc0c1290
commit a5677ca1e0
22 changed files with 900 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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

View File

@ -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
!

View File

@ -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

View File

@ -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
!

View File

@ -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)