summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_abr.c
diff options
context:
space:
mode:
authorPat Ruddy <pat@voltanet.io>2021-05-19 13:11:03 +0200
committerPat Ruddy <pat@voltanet.io>2021-07-20 12:19:48 +0200
commit0c7f982a383ff4a8baede943ed3095b8813de977 (patch)
treed68a30ff4d8b8fd6a2bdc79632769de57ea46c3f /ospf6d/ospf6_abr.c
parentMerge pull request #8554 from mjstapp/evpn_workqueue (diff)
downloadfrr-0c7f982a383ff4a8baede943ed3095b8813de977.tar.xz
frr-0c7f982a383ff4a8baede943ed3095b8813de977.zip
ospf6d: break early on route prefix mismatch
The route linked list in ospf6d is ordered in prefix batches which are associated with a the route node denoting the prefix. So if you look up the prefix in the tree and start walking the list, if you find a prefix which differs from the one you are interested in then you have gone beyond the batch of routes for that prefix. In some cases the route database linked list is used on a per-prefix basis. The existing code simply does a continue when the prefix does not match and continues to walk. This works with small numbers of routes because the walk continues through unrelated prefix batches and never finds anything to operate on. However if we have many thousands of routes these walks become expensive and can cause the SPF thread (amongst others) to run very long, causing issues with adjacencies where the dead timer is short. Add a break to these prefix-based loops to exit early if we get a prefix mismatch to avoid continuing down the route list if we have overshot. Signed-off-by: Pat Ruddy <pat@voltanet.io>
Diffstat (limited to 'ospf6d/ospf6_abr.c')
-rw-r--r--ospf6d/ospf6_abr.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index f289bf26b..08d2ef070 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -1194,9 +1194,16 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
__func__, &prefix, listcount(old->paths));
}
for (old_route = old; old_route; old_route = old_route->next) {
- if (!ospf6_route_is_same(old_route, route) ||
- (old_route->type != route->type) ||
- (old_route->path.type != route->path.type))
+
+ /* The route linked-list is grouped in batches of prefix.
+ * If the new prefix is not the same as the one of interest
+ * then we have walked over the end of the batch and so we
+ * should break rather than continuing unnecessarily.
+ */
+ if (!ospf6_route_is_same(old_route, route))
+ break;
+ if ((old_route->type != route->type)
+ || (old_route->path.type != route->path.type))
continue;
if ((ospf6_route_cmp(route, old_route) != 0)) {