mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +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": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"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 dead-interval 10
|
||||
!
|
||||
interface r6-eth4
|
||||
ipv6 ospf6 area 1
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
router ospf6
|
||||
ospf6 router-id 10.254.254.6
|
||||
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
|
||||
#
|
||||
# Copyright (c) 2021, 2022, 2024 by Martin Buck
|
||||
# Copyright (c) 2021, 2022, 2024, 2025 by Martin Buck
|
||||
# Copyright (c) 2016 by
|
||||
# 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.
|
||||
|
||||
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:
|
||||
.
|
||||
Area 0 . Area 1
|
||||
.
|
||||
-- R2 ------ R5 -----
|
||||
/ .\ \
|
||||
/ . | \
|
||||
R1 --- R3 ------ R6 ------ R7
|
||||
\ / |. |
|
||||
\ / |. |
|
||||
-- R4 ---- |. |
|
||||
/ ./
|
||||
R8 --
|
||||
.
|
||||
.
|
||||
Area 0 . Area 1
|
||||
.
|
||||
-- R2 ------ R5 ---
|
||||
/ / . \
|
||||
/ R8 . R7
|
||||
/ \ . /
|
||||
R1 ---- R3 ------ R6 ---
|
||||
\ / .\
|
||||
\ / . \
|
||||
\ / . \
|
||||
-- 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
|
||||
and are used for reference. R7/R8 announce one internal and one external
|
||||
route each.
|
||||
and are used for reference. R7/8/9 announce one internal and one external
|
||||
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
|
||||
of R7/8. Then we bring down the R3-R6 link, causing only 2 remaining
|
||||
paths and 2 nexthops on R1. Then we bring down the R2-R5 link, causing only
|
||||
1 remaining path and 1 nexthop on R1.
|
||||
Then we bring down the R3-R6 link, causing only 2 remaining paths and 2
|
||||
nexthops on R1 towards R7/8 and 1 towards R9. Then we bring down the R2-R5
|
||||
link, causing only 1 remaining path and 1 nexthop towards R7/8/9 on R1.
|
||||
|
||||
The test is successful if the number of nexthops and their interfaces for
|
||||
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
|
||||
|
@ -73,8 +92,8 @@ pytestmark = [pytest.mark.ospf6d]
|
|||
def build_topo(tgen):
|
||||
"Build function"
|
||||
|
||||
# Create 8 routers
|
||||
for routern in range(1, 9):
|
||||
# Create 9 routers
|
||||
for routern in range(1, 10):
|
||||
tgen.add_router("r{}".format(routern))
|
||||
tgen.gears["r1"].add_link(tgen.gears["r2"])
|
||||
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["r6"].add_link(tgen.gears["r7"])
|
||||
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
|
||||
# hold an address we use to inject intra-/inter-area routes (the one on
|
||||
# the real "lo" loopback is used for external routes).
|
||||
tgen.gears["r7"].add_link(tgen.gears["r7"])
|
||||
tgen.gears["r8"].add_link(tgen.gears["r8"])
|
||||
tgen.gears["r9"].add_link(tgen.gears["r9"])
|
||||
|
||||
|
||||
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")
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue