0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-08 12:18:42 +00:00

Fixed hostentry update for sorted tables

Best route recalculation after nexthop update completely ignored the
table's sortedness.
This commit is contained in:
Maria Matejka 2020-05-20 16:46:45 +02:00
parent 1ca7665fa4
commit 39534d74ff

View File

@ -2075,6 +2075,34 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
return e; return e;
} }
static struct rte *
rte_recalc_sort(struct rte *chain)
{
ASSERT(chain);
/* Single route -> nothing to do */
if (!chain->next)
return chain;
/* Simple insert sort (TODO: something faster for long chains) */
struct rte *best = chain, *next = chain->next, *cur;
chain->next = NULL;
while (cur = next)
{
next = cur->next;
for (struct rte **k = &best; *k; k = &((*k)->next))
if (rte_better(cur, *k))
{
cur->next = *k;
*k = cur;
break;
}
}
return best;
}
static inline int static inline int
rt_next_hop_update_net(rtable *tab, net *n) rt_next_hop_update_net(rtable *tab, net *n)
{ {
@ -2113,20 +2141,25 @@ rt_next_hop_update_net(rtable *tab, net *n)
return 0; return 0;
/* Find the new best route */ /* Find the new best route */
new_best = NULL; if (tab->config->sorted)
for (k = &n->routes; e = *k; k = &e->next) new = n->routes = rte_recalc_sort(n->routes);
else
{ {
if (!new_best || rte_better(e, *new_best)) new_best = NULL;
new_best = k; for (k = &n->routes; e = *k; k = &e->next)
} {
if (!new_best || rte_better(e, *new_best))
new_best = k;
}
/* Relink the new best route to the first position */ /* Relink the new best route to the first position */
new = *new_best; new = *new_best;
if (new != n->routes) if (new != n->routes)
{ {
*new_best = new->next; *new_best = new->next;
new->next = n->routes; new->next = n->routes;
n->routes = new; n->routes = new;
}
} }
/* Announce the new best route */ /* Announce the new best route */