static inline int
rt_next_hop_update_net(rtable *tab, net *n)
{
- struct rte_storage **k, *e, *new, *old_best, **new_best;
+ struct rte_storage *new;
int count = 0;
- int free_old_best = 0;
++ int is_flow = net_is_flow(n->n.addr);
- old_best = n->routes;
+ struct rte_storage *old_best = n->routes;
if (!old_best)
return 0;
- for (k = &n->routes; e = *k; k = &e->next)
- {
- if (!net_is_flow(n->n.addr))
- new = rt_next_hop_update_rte(tab, n, &e->rte);
- else
- new = rt_flowspec_update_rte(tab, n, &e->rte);
+ for (struct rte_storage *e, **k = &n->routes; e = *k; k = &e->next)
- if (rta_next_hop_outdated(e->rte.attrs))
++ if (is_flow || rta_next_hop_outdated(e->rte.attrs))
+ count++;
- if (new)
- {
- new->next = e->next;
- *k = new;
+ if (!count)
+ return 0;
+
+ struct rte_multiupdate {
+ struct rte_storage *old, *new;
+ } *updates = alloca(sizeof(struct rte_multiupdate) * count);
- rte_trace_in(D_ROUTES, new->rte.sender, &new->rte, "updated");
- rte_announce_i(tab, RA_ANY, n, new, e, NULL, NULL);
+ int pos = 0;
+ for (struct rte_storage *e, **k = &n->routes; e = *k; k = &e->next)
- if (rta_next_hop_outdated(e->rte.attrs))
++ if (is_flow || rta_next_hop_outdated(e->rte.attrs))
+ {
- struct rte_storage *new = rt_next_hop_update_rte(tab, n, &e->rte);
++ struct rte_storage *new = is_flow
++ ? rt_flowspec_update_rte(tab, n, &e->rte)
++ : rt_next_hop_update_rte(tab, n, &e->rte);
/* Call a pre-comparison hook */
/* Not really an efficient way to compute this */