From 71b3456eede17be6646b7deebff84f34ee5755f7 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Fri, 22 Oct 2021 19:43:55 +0200 Subject: Better profylaction recursive route loops In some specific configurations, it was possible to send BIRD into an infinite loop of recursive next hop resolution. This was caused by route priority inversion. To prevent priority inversions affecting other next hops, we simply refuse to resolve any next hop if the best route for the matching prefix is recursive or any other route with the same preference is recursive. Next hop resolution doesn't change route priority, therefore it is perfectly OK to resolve BGP next hops e.g. by an OSPF route, yet if the same (or covering) prefix is also announced by iBGP, by retraction of the OSPF route we would get a possible priority inversion. --- nest/rt-table.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nest/rt-table.c b/nest/rt-table.c index abb29fe1..4127912c 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -3529,9 +3529,10 @@ rt_update_hostentry(rtable *tab, struct hostentry *he) { rte *e = n->routes; rta *a = e->attrs; - pxlen = n->n.addr->pxlen; + word pref = a->pref; - if (a->hostentry) + for (rte *ee = n->routes; ee; ee = ee->next) + if ((ee->attrs->pref >= pref) && ee->attrs->hostentry) { /* Recursive route should not depend on another recursive route */ log(L_WARN "Next hop address %I resolvable through recursive route for %N", @@ -3539,6 +3540,8 @@ rt_update_hostentry(rtable *tab, struct hostentry *he) goto done; } + pxlen = n->n.addr->pxlen; + if (a->dest == RTD_UNICAST) { for (struct nexthop *nh = &(a->nh); nh; nh = nh->next) -- cgit v1.2.3