summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2021-10-22 19:43:55 +0200
committerMaria Matejka <mq@ucw.cz>2021-11-22 19:05:43 +0100
commitf18968f52f461946b64aaea6c4a0e88c5235fb07 (patch)
tree783241f77cdaa776e757f01d72ec6a9f8f56eaa6 /nest
parent44f26c49f966ca842ff9af55468de0b98c44b73e (diff)
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.
Diffstat (limited to 'nest')
-rw-r--r--nest/rt-table.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 2f480992..2dcb2e26 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -2649,9 +2649,10 @@ rt_update_hostentry(rtable *tab, struct hostentry *he)
{
struct rte_storage *e = n->routes;
rta *a = e->rte.attrs;
- pxlen = n->n.addr->pxlen;
+ word pref = a->pref;
- if (a->hostentry)
+ for (struct rte_storage *ee = n->routes; ee; ee = ee->next)
+ if ((ee->rte.attrs->pref >= pref) && ee->rte.attrs->hostentry)
{
/* Recursive route should not depend on another recursive route */
log(L_WARN "Next hop address %I resolvable through recursive route for %N",
@@ -2659,6 +2660,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)