]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Refeed is done from export table when appropriate
authorMaria Matejka <mq@ucw.cz>
Fri, 14 May 2021 14:23:18 +0000 (16:23 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 9 Nov 2021 18:20:41 +0000 (19:20 +0100)
nest/route.h
nest/rt-table.c
proto/bgp/packets.c

index ade14857bf0c5b2fd0fb89eee417e96edb0b86a4..98d605c8f319685043e1299cfaac8128ad298003 100644 (file)
@@ -346,8 +346,9 @@ int rt_feed_channel(struct channel *c);
 void rt_feed_channel_abort(struct channel *c);
 int rt_reload_channel(struct channel *c);
 void rt_reload_channel_abort(struct channel *c);
+void rt_refeed_channel(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 *old, struct rte_storage **old_exported, int refeed);
+int rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old, struct rte_storage **old_exported);
 struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
 
 
index 837e0ab9fadc8156871dcb179db0f33e0ab01559..b005f6f30a52232508ea5c95356ce100f6f4ca1b 100644 (file)
@@ -451,8 +451,11 @@ do_rt_notify(struct channel *c, const net_addr *net, rte *new, rte *old, int ref
   struct rte_storage *old_exported = NULL;
   if (c->out_table)
   {
-    if (!rte_update_out(c, net, new, old, &old_exported, refeed))
+    if (!rte_update_out(c, net, new, old, &old_exported))
+    {
+      rte_trace_out(D_ROUTES, c, new, "idempotent");
       return;
+    }
   }
 
   if (new)
@@ -2406,7 +2409,7 @@ again:
  */
 
 int
-rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct rte_storage **old_exported, int refeed)
+rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct rte_storage **old_exported)
 {
   struct rtable *tab = c->out_table;
   struct rte_src *src;
@@ -2423,7 +2426,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
     src = old0->src;
 
     if (!net)
-      goto drop_withdraw;
+      goto drop;
   }
 
   /* Find the old rte */
@@ -2433,7 +2436,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
   if (old = *pos)
   {
     if (new && rte_same(&(*pos)->rte, new))
-      goto drop_update;
+      goto drop;
 
     /* Remove the old rte */
     *pos = old->next;
@@ -2444,7 +2447,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
   if (!new)
   {
     if (!old)
-      goto drop_withdraw;
+      goto drop;
 
     if (!net->routes)
       fib_delete(&tab->fib, net);
@@ -2460,13 +2463,36 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, struct
   tab->rt_count++;
   return 1;
 
-drop_update:
-  return refeed;
-
-drop_withdraw:
+drop:
   return 0;
 }
 
+void
+rt_refeed_channel(struct channel *c)
+{
+  if (!c->out_table)
+  {
+    channel_request_feeding(c);
+    return;
+  }
+
+  ASSERT_DIE(c->ra_mode != RA_ANY);
+
+  c->proto->feed_begin(c, 0);
+
+  FIB_WALK(&c->out_table->fib, net, n)
+  {
+    if (!n->routes)
+      continue;
+
+    rte e = n->routes->rte;
+    c->proto->rt_notify(c->proto, c, n->n.addr, &e, NULL);
+  }
+  FIB_WALK_END;
+
+  c->proto->feed_end(c);
+}
+
 
 /*
  *     Hostcache
index 647551e5f99c6e373fda547777a0ddb4354e5bb9..f1e6d7d25442a11838a7adcbb05d5d39edab54d4 100644 (file)
@@ -2695,7 +2695,7 @@ bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, uint len)
   {
   case BGP_RR_REQUEST:
     BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
-    channel_request_feeding(&c->c);
+    rt_refeed_channel(&c->c);
     break;
 
   case BGP_RR_BEGIN: