]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: Fix nexthop computation for inter-area multi-ABR ECMP
authorMartin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
Mon, 22 Apr 2024 15:13:23 +0000 (17:13 +0200)
committerMartin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
Fri, 3 May 2024 07:49:24 +0000 (09:49 +0200)
Pre-b74e965, we always merged nexthops of old (existing) and new (newly
generated, based on a LSA update) routes, making it impossible to remove
individual nexthops from a route. b74e965 replaced this by copying nexthops
from the new route to the old route. This works as long as the old and new
route are derived from the same LSA (e.g. multiple ECMP paths to the same
ABR). However, in case of multiple parallel ABRs, each of them originates a
LSA and the nexthops derived from them need to be combined to get the proper
route nexthops. So instead of trying to incrementally update the route
nexthops based on the old and new route nexthops, always recompute the route
nexthops by merging all of its path nexthops (which we're already updating
based on the LSA being processed).

Fixes #15777.

Signed-off-by: Martin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
ospf6d/ospf6_abr.c

index f4202a4a29e730f2045f0ea2a76c5296fe9e2ad8..d3ff759d33ed45e468cdeee6e59143c914afe5a7 100644 (file)
@@ -1275,8 +1275,6 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        continue;
                }
 
-               list_delete_all_node(old_route->nh_list);
-               ospf6_route_copy_nexthops(old_route, route);
                old_entry_updated = true;
 
                for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode,
@@ -1330,6 +1328,15 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        }
                }
 
+               /* We added a path or updated a path's nexthops above,
+                * recompute (old) route nexthops by merging all path nexthops
+                */
+               list_delete_all_node(old_route->nh_list);
+               for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode, o_path)) {
+                       ospf6_merge_nexthops(old_route->nh_list,
+                                            o_path->nh_list);
+               }
+
                if (is_debug)
                        zlog_debug(
                                "%s: Update route: %s %p old cost %u new cost %u nh %u",