mirror of
https://github.com/FRRouting/frr.git
synced 2025-05-01 05:57:15 +02:00
tests: Add regression test for #16197 to ospf6_ecmp_inter_area topotest
The new test_multipath_inter_area() function reliably checks for #16197 and will fail until it is fixed. Signed-off-by: Martin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
This commit is contained in:
parent
e011376398
commit
a6556075dc
|
@ -108,6 +108,23 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"2001:db8:9::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 2,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth1",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"2001:db8:8007::/64": [
|
"2001:db8:8007::/64": [
|
||||||
{
|
{
|
||||||
"internalNextHopActiveNum": 3,
|
"internalNextHopActiveNum": 3,
|
||||||
|
@ -151,5 +168,22 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8009::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 2,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth1",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,18 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"2001:db8:9::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"2001:db8:8007::/64": [
|
"2001:db8:8007::/64": [
|
||||||
{
|
{
|
||||||
"internalNextHopActiveNum": 2,
|
"internalNextHopActiveNum": 2,
|
||||||
|
@ -126,5 +138,17 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8009::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,18 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"2001:db8:9::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"2001:db8:8007::/64": [
|
"2001:db8:8007::/64": [
|
||||||
{
|
{
|
||||||
"internalNextHopActiveNum": 1,
|
"internalNextHopActiveNum": 1,
|
||||||
|
@ -106,5 +118,17 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8009::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"2001:db8:2::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:4::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:5::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:6::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:7::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:9::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8007::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8009::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
{
|
||||||
|
"2001:db8:2::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:4::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:5::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:6::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:7::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 2,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:9::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8007::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 2,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth0",
|
||||||
|
"active": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2001:db8:8009::/64": [
|
||||||
|
{
|
||||||
|
"internalNextHopActiveNum": 1,
|
||||||
|
"nexthops": [
|
||||||
|
{
|
||||||
|
"fib": true,
|
||||||
|
"interfaceName": "r1-eth2",
|
||||||
|
"active": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -25,6 +25,11 @@ interface r6-eth3
|
||||||
ipv6 ospf6 hello-interval 2
|
ipv6 ospf6 hello-interval 2
|
||||||
ipv6 ospf6 dead-interval 10
|
ipv6 ospf6 dead-interval 10
|
||||||
!
|
!
|
||||||
|
interface r6-eth4
|
||||||
|
ipv6 ospf6 area 1
|
||||||
|
ipv6 ospf6 hello-interval 2
|
||||||
|
ipv6 ospf6 dead-interval 10
|
||||||
|
!
|
||||||
router ospf6
|
router ospf6
|
||||||
ospf6 router-id 10.254.254.6
|
ospf6 router-id 10.254.254.6
|
||||||
redistribute connected
|
redistribute connected
|
||||||
|
|
22
tests/topotests/ospf6_ecmp_inter_area/r9/frr.conf
Normal file
22
tests/topotests/ospf6_ecmp_inter_area/r9/frr.conf
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
hostname r9
|
||||||
|
!
|
||||||
|
ipv6 forwarding
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ipv6 address 2001:db8:9::1/64
|
||||||
|
!
|
||||||
|
interface r9-eth0
|
||||||
|
ipv6 ospf6 area 1
|
||||||
|
ipv6 ospf6 hello-interval 2
|
||||||
|
ipv6 ospf6 dead-interval 10
|
||||||
|
!
|
||||||
|
interface r9-eth1
|
||||||
|
ipv6 address 2001:db8:8009::1/64
|
||||||
|
ipv6 ospf6 area 1
|
||||||
|
ipv6 ospf6 hello-interval 2
|
||||||
|
ipv6 ospf6 dead-interval 10
|
||||||
|
!
|
||||||
|
router ospf6
|
||||||
|
ospf6 router-id 10.254.254.9
|
||||||
|
redistribute connected
|
||||||
|
!
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
# test_ospf6_ecmp_inter_area.py
|
# test_ospf6_ecmp_inter_area.py
|
||||||
#
|
#
|
||||||
# Copyright (c) 2021, 2022, 2024 by Martin Buck
|
# Copyright (c) 2021, 2022, 2024, 2025 by Martin Buck
|
||||||
# Copyright (c) 2016 by
|
# Copyright (c) 2016 by
|
||||||
# Network Device Education Foundation, Inc. ("NetDEF")
|
# Network Device Education Foundation, Inc. ("NetDEF")
|
||||||
#
|
#
|
||||||
|
@ -20,33 +20,52 @@ without ospf6d having to do anything.
|
||||||
|
|
||||||
Useful as a regression test for #9720 and #15777.
|
Useful as a regression test for #9720 and #15777.
|
||||||
|
|
||||||
|
Also checks summary LSA origination/updates in case of topology changes in
|
||||||
|
remote areas via route nexthop checks.
|
||||||
|
|
||||||
|
Useful as a regression test for #16197.
|
||||||
|
|
||||||
Topology:
|
Topology:
|
||||||
.
|
.
|
||||||
Area 0 . Area 1
|
Area 0 . Area 1
|
||||||
.
|
.
|
||||||
-- R2 ------ R5 -----
|
-- R2 ------ R5 ---
|
||||||
/ .\ \
|
/ / . \
|
||||||
/ . | \
|
/ R8 . R7
|
||||||
R1 --- R3 ------ R6 ------ R7
|
/ \ . /
|
||||||
\ / |. |
|
R1 ---- R3 ------ R6 ---
|
||||||
\ / |. |
|
\ / .\
|
||||||
-- R4 ---- |. |
|
\ / . \
|
||||||
/ ./
|
\ / . \
|
||||||
R8 --
|
-- R4 ---- . R9
|
||||||
.
|
.
|
||||||
|
|
||||||
We check routes on R1, primarily those towards R7/8. Those to R7 are
|
We check routes on R1, primarily those towards R7/8/9. Those to R7/9 are
|
||||||
inter-area routes with R5/6 being ABRs, those to R8 are intra-area routes
|
inter-area routes with R5/6 being ABRs, those to R8 are intra-area routes
|
||||||
and are used for reference. R7/R8 announce one internal and one external
|
and are used for reference. R7/8/9 announce one internal and one external
|
||||||
route each.
|
route each. With all links up, we expect 3 ECMP paths and 3 nexthops on R1
|
||||||
|
towards R7/8 and 2 ECMP paths/nexthops towards R9.
|
||||||
|
|
||||||
With all links up, we expect 3 ECMP paths and 3 nexthops on R1 towards each
|
Then we bring down the R3-R6 link, causing only 2 remaining paths and 2
|
||||||
of R7/8. Then we bring down the R3-R6 link, causing only 2 remaining
|
nexthops on R1 towards R7/8 and 1 towards R9. Then we bring down the R2-R5
|
||||||
paths and 2 nexthops on R1. Then we bring down the R2-R5 link, causing only
|
link, causing only 1 remaining path and 1 nexthop towards R7/8/9 on R1.
|
||||||
1 remaining path and 1 nexthop on R1.
|
|
||||||
|
|
||||||
The test is successful if the number of nexthops and their interfaces for
|
The test is successful if the number of nexthops and their interfaces for
|
||||||
the routes on R1 is as expected.
|
the routes on R1 is as expected.
|
||||||
|
|
||||||
|
|
||||||
|
To check summary LSA origination after topology changes, we start again with
|
||||||
|
the original topology and disconnect R3 and R8 from it to simplify it and to
|
||||||
|
avoid unwanted shortcuts (LSAs between R5 and R6 via area 0 should travel
|
||||||
|
via R2/1/4 and not take the shortcut via R8). We also bring down the R6-R7
|
||||||
|
link initially so R5 and R6 can't exchange their area 1 LSAs. Initially, we
|
||||||
|
expect 1 path/nexthop on R1 towards R7 (via R2) and R9 (via R4).
|
||||||
|
|
||||||
|
Then we bring up the R6-R7 link, causing 2 paths/nexthops on R1 towards R7
|
||||||
|
(via R2 and R4) and still 1 path/nexthop towards R9 (still via R4). With
|
||||||
|
#16197, we would see 1 path/nexthop towards R9 but via R2 instead of R4,
|
||||||
|
because R6 doesn't re-originate the summary LSAs towards area 0 properly
|
||||||
|
after the topology change.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
@ -73,8 +92,8 @@ pytestmark = [pytest.mark.ospf6d]
|
||||||
def build_topo(tgen):
|
def build_topo(tgen):
|
||||||
"Build function"
|
"Build function"
|
||||||
|
|
||||||
# Create 8 routers
|
# Create 9 routers
|
||||||
for routern in range(1, 9):
|
for routern in range(1, 10):
|
||||||
tgen.add_router("r{}".format(routern))
|
tgen.add_router("r{}".format(routern))
|
||||||
tgen.gears["r1"].add_link(tgen.gears["r2"])
|
tgen.gears["r1"].add_link(tgen.gears["r2"])
|
||||||
tgen.gears["r1"].add_link(tgen.gears["r3"])
|
tgen.gears["r1"].add_link(tgen.gears["r3"])
|
||||||
|
@ -86,11 +105,13 @@ def build_topo(tgen):
|
||||||
tgen.gears["r5"].add_link(tgen.gears["r8"])
|
tgen.gears["r5"].add_link(tgen.gears["r8"])
|
||||||
tgen.gears["r6"].add_link(tgen.gears["r7"])
|
tgen.gears["r6"].add_link(tgen.gears["r7"])
|
||||||
tgen.gears["r6"].add_link(tgen.gears["r8"])
|
tgen.gears["r6"].add_link(tgen.gears["r8"])
|
||||||
|
tgen.gears["r6"].add_link(tgen.gears["r9"])
|
||||||
# Additional "loopback" interfaces. Not used for communication, just to
|
# Additional "loopback" interfaces. Not used for communication, just to
|
||||||
# hold an address we use to inject intra-/inter-area routes (the one on
|
# hold an address we use to inject intra-/inter-area routes (the one on
|
||||||
# the real "lo" loopback is used for external routes).
|
# the real "lo" loopback is used for external routes).
|
||||||
tgen.gears["r7"].add_link(tgen.gears["r7"])
|
tgen.gears["r7"].add_link(tgen.gears["r7"])
|
||||||
tgen.gears["r8"].add_link(tgen.gears["r8"])
|
tgen.gears["r8"].add_link(tgen.gears["r8"])
|
||||||
|
tgen.gears["r9"].add_link(tgen.gears["r9"])
|
||||||
|
|
||||||
|
|
||||||
def setup_module(mod):
|
def setup_module(mod):
|
||||||
|
@ -200,6 +221,46 @@ def test_ecmp_inter_area(request):
|
||||||
|
|
||||||
expect_routes_json("r1", "show_ipv6_routes_ospf6-3.json", "post-R2-R5-link-down")
|
expect_routes_json("r1", "show_ipv6_routes_ospf6-3.json", "post-R2-R5-link-down")
|
||||||
|
|
||||||
|
step("restoring links R2-R5/R3-R6")
|
||||||
|
tgen.gears["r3"].run("ip link set r3-eth1 up")
|
||||||
|
tgen.gears["r2"].run("ip link set r2-eth1 up")
|
||||||
|
|
||||||
|
expect_routes_json(
|
||||||
|
"r1", "show_ipv6_routes_ospf6-1.json", "post-R2-R5/R3-R6-link-up"
|
||||||
|
)
|
||||||
|
|
||||||
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_multipath_inter_area(request):
|
||||||
|
"""
|
||||||
|
Test OSPFv3 routes with (non-equal) multipath and topology changes in
|
||||||
|
non-backbone area requiring summary LSA updates
|
||||||
|
"""
|
||||||
|
tc_name = request.node.name
|
||||||
|
write_test_header(tc_name)
|
||||||
|
|
||||||
|
tgen = get_topogen()
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
step("links R1-R3/R3-R6/R5-R8/R6-R8 down (simplify topology, disconnect R3/R8)")
|
||||||
|
tgen.gears["r3"].run("ip link set r3-eth0 down")
|
||||||
|
tgen.gears["r3"].run("ip link set r3-eth1 down")
|
||||||
|
tgen.gears["r8"].run("ip link set r8-eth0 down")
|
||||||
|
tgen.gears["r8"].run("ip link set r8-eth1 down")
|
||||||
|
step("link R6-R7 down (initial summary LSAs)")
|
||||||
|
tgen.gears["r6"].run("ip link set r6-eth2 down")
|
||||||
|
|
||||||
|
expect_routes_json(
|
||||||
|
"r1", "show_ipv6_routes_ospf6-4.json", "post-R3-R6/R6-R7-link-down"
|
||||||
|
)
|
||||||
|
|
||||||
|
step("triggering R6-R7 link up")
|
||||||
|
tgen.gears["r6"].run("ip link set r6-eth2 up")
|
||||||
|
|
||||||
|
expect_routes_json("r1", "show_ipv6_routes_ospf6-5.json", "post-R6-R7-link-up")
|
||||||
|
|
||||||
write_test_footer(tc_name)
|
write_test_footer(tc_name)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue