]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Use 'old' route from export table
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 31 Oct 2019 00:26:40 +0000 (01:26 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 31 Oct 2019 00:26:40 +0000 (01:26 +0100)
When export table is enabled for channel, then use routes from
export table as 'old' for rt_notify() notifications.

nest/route.h
nest/rt-table.c

index cbc84934a886634c64cb28936ca4dcc6784ec8b8..510c661a3ec195e7296cb8d76a07ea786ee23e77 100644 (file)
@@ -329,7 +329,7 @@ int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src
 int rt_reload_channel(struct channel *c);
 void rt_reload_channel_abort(struct channel *c);
 void rt_prune_sync(rtable *t, int all);
-int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, int refeed);
+int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **old_free, int refeed);
 struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
 void cmd_show_table_stats(struct rtable_config *tab);
 
index 5d4a0ef26662373538257ffe11b982f171355068..fe402cbabfbd6527364e85efed34f5db288452d9 100644 (file)
@@ -565,6 +565,7 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int
 {
   struct proto *p = c->proto;
   struct proto_stats *stats = &c->stats;
+  rte *old_free = NULL;
 
   /*
    * First, apply export limit.
@@ -611,9 +612,13 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int
        }
     }
 
-  if (c->out_table && !rte_update_out(c, net->n.addr, new, old, refeed))
+  if (c->out_table && !rte_update_out(c, net->n.addr, new, old, &old_free, refeed))
     return;
 
+  /* Use route from export_table as old */
+  if (old_free)
+    old = old_free;
+
   if (new)
     stats->exp_updates_accepted++;
   else
@@ -648,6 +653,9 @@ do_rt_notify(struct channel *c, net *net, rte *new, rte *old, ea_list *tmpa, int
     }
   else
     p->rt_notify(p, c, net, new, old, new->attrs->eattrs);
+
+  if (old_free)
+    rte_free(old_free);
 }
 
 static void
@@ -2578,7 +2586,7 @@ rt_prune_sync(rtable *t, int all)
  */
 
 int
-rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, int refeed)
+rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte **old_free, int refeed)
 {
   struct rtable *tab = c->out_table;
   struct rte_src *src;
@@ -2621,8 +2629,8 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, int re
       }
 
       /* Remove the old rte */
+      *old_free = old;
       *pos = old->next;
-      rte_free_quick(old);
       tab->route_count--;
 
       break;