]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Channel refeed with import table splitting between routes for one prefix
authorMaria Matejka <mq@ucw.cz>
Mon, 26 Aug 2019 19:53:56 +0000 (21:53 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 27 Aug 2019 17:14:15 +0000 (19:14 +0200)
nest/protocol.h
nest/rt-table.c

index 17af2e17cc672c3e0e7c97194811601004902129..c664c1e6af40e499fe9bb31e5d0f2d734795edb0 100644 (file)
@@ -537,7 +537,8 @@ struct channel {
 
   struct rtable *in_table;             /* Internal table for received routes */
   struct event *reload_event;          /* Event responsible for reloading from in_table */
-  struct fib_iterator reload_fit;      /* Iterator in in_table used during reloading */
+  struct fib_iterator reload_fit;      /* FIB iterator in in_table used during reloading */
+  struct rte *reload_next_rte;         /* Route iterator in in_table used during reloading */
   u8 reload_active;                    /* Iterator reload_fit is linked */
 
   struct rtable *out_table;            /* Internal table for exported routes */
index ff995ccec5d728d50a3ea90933ff252f129157f0..318ec2eeee5bcac3e5643cfec577957e85e617d2 100644 (file)
@@ -2553,6 +2553,10 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr
        goto drop_update;
       }
 
+      /* Move iterator if needed */
+      if (old == c->reload_next_rte)
+       c->reload_next_rte = old->next;
+
       /* Remove the old rte */
       *pos = old->next;
       rte_free_quick(old);
@@ -2620,21 +2624,32 @@ rt_reload_channel(struct channel *c)
     c->reload_active = 1;
   }
 
-  FIB_ITERATE_START(&tab->fib, fit, net, n)
-  {
-    if (max_feed <= 0)
+  do {
+    for (rte *e = c->reload_next_rte; e; e = e->next)
     {
-      FIB_ITERATE_PUT(fit);
-      return 0;
+      if (max_feed-- <= 0)
+      {
+       c->reload_next_rte = e;
+       debug("%s channel reload burst split (max_feed=%d)", c->proto->name, max_feed);
+       return 0;
+      }
+
+      rte_update2(c, e->net->n.addr, rte_do_cow(e), e->attrs->src);
     }
 
-    for (rte *e = n->routes; e; e = e->next)
+    c->reload_next_rte = NULL;
+
+    FIB_ITERATE_START(&tab->fib, fit, net, n)
     {
-      rte_update2(c, n->n.addr, rte_do_cow(e), e->attrs->src);
-      max_feed--;
+      if (c->reload_next_rte = n->routes)
+      {
+       FIB_ITERATE_PUT_NEXT(fit, &tab->fib);
+       break;
+      }
     }
+    FIB_ITERATE_END;
   }
-  FIB_ITERATE_END;
+  while (c->reload_next_rte);
 
   c->reload_active = 0;
   return 1;
@@ -2647,6 +2662,7 @@ rt_reload_channel_abort(struct channel *c)
   {
     /* Unlink the iterator */
     fit_get(&c->in_table->fib, &c->reload_fit);
+    c->reload_next_rte = NULL;
     c->reload_active = 0;
   }
 }