diff options
author | Pat Ruddy <pat@voltanet.io> | 2021-05-19 13:11:03 +0200 |
---|---|---|
committer | Pat Ruddy <pat@voltanet.io> | 2021-07-20 12:19:48 +0200 |
commit | 0c7f982a383ff4a8baede943ed3095b8813de977 (patch) | |
tree | d68a30ff4d8b8fd6a2bdc79632769de57ea46c3f /ospf6d/ospf6_abr.c | |
parent | Merge pull request #8554 from mjstapp/evpn_workqueue (diff) | |
download | frr-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.c | 13 |
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)) { |