]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Channel: configurable feed block size
authorMaria Matejka <mq@ucw.cz>
Sun, 7 May 2023 21:04:47 +0000 (23:04 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 7 May 2023 21:04:47 +0000 (23:04 +0200)
doc/bird.sgml
nest/config.Y
nest/proto.c
nest/protocol.h
nest/rt-table.c
nest/rt.h
proto/bgp/bgp.c

index 3f6acaedc8732ce6d2d04d34d27b563bb9ece3fc..7c8e9895d69fbeccb1c0b0e74d3304255b2e008d 100644 (file)
@@ -1024,6 +1024,13 @@ inherited from templates can be updated by new definitions.
        counter ignores route blocking and block action also blocks route
        updates of already accepted routes -- and these details will probably
        change in the future. Default: <cf/off/.
+
+       <tag><label id="proto-export-block">export block <m/number/</tag>
+        Set the minimum amount of routes exported at once when feeding or
+       if `merge paths` or `secondary` is selected. This affects overall latency.
+       Basically, when your export filters are very expensive, processing
+       the whole block of routes may take too much time. In such cases, you may need to
+        shrink this value to improve responsiveness. Default: <cf/16384/.
 </descrip>
 
 <p>This is a trivial example of RIP configured for IPv6 on all interfaces:
index bce8b228244d00f5e7227ef82def29d25f81c545..e7347877c00f03c4e0e997b746e822e87d792d18 100644 (file)
@@ -320,6 +320,7 @@ channel_item_:
      this_channel->out_filter = $4;
    }
  | EXPORT imexport { this_channel->out_filter = $2; }
+ | EXPORT BLOCK expr { this_channel->feed_block_size = $3; }
  | RECEIVE LIMIT limit_spec { this_channel->rx_limit = $3; }
  | IMPORT LIMIT limit_spec { this_channel->in_limit = $3; }
  | EXPORT LIMIT limit_spec { this_channel->out_limit = $3; }
index e75afc9e91b7463024ad9dfaa710da1342c39bb6..dab56b6be08b18c0b51c1fcadd12d30405cd8491 100644 (file)
@@ -207,6 +207,8 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
   c->out_filter = cf->out_filter;
   c->out_subprefix = cf->out_subprefix;
 
+  c->feed_block_size = cf->feed_block_size;
+
   channel_init_limit(c, &c->rx_limit, PLD_RX, &cf->rx_limit);
   channel_init_limit(c, &c->in_limit, PLD_IN, &cf->in_limit);
   channel_init_limit(c, &c->out_limit, PLD_OUT, &cf->out_limit);
@@ -497,6 +499,7 @@ channel_start_export(struct channel *c)
     .name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
     .list = proto_work_list(c->proto),
     .pool = c->proto->pool,
+    .feed_block_size = c->feed_block_size,
     .addr = c->out_subprefix,
     .addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
     .trace_routes = c->debug | c->proto->debug,
@@ -688,6 +691,7 @@ channel_setup_in_table(struct channel *c)
     .name = mb_sprintf(c->proto->pool, "%s.%s.import", c->proto->name, c->name),
     .list = proto_work_list(c->proto),
     .pool = c->proto->pool,
+    .feed_block_size = c->feed_block_size,
     .trace_routes = c->debug | c->proto->debug,
     .export_bulk = channel_reload_export_bulk,
     .dump_req = channel_reload_dump_req,
@@ -913,6 +917,8 @@ channel_config_new(const struct channel_class *cc, const char *name, uint net_ty
   cf->table = tab;
   cf->out_filter = FILTER_REJECT;
 
+  cf->feed_block_size = 16384;
+
   cf->net_type = net_type;
   cf->ra_mode = RA_OPTIMAL;
   cf->preference = proto->protocol->preference;
index e8f19801e7ab421c9d28738a97067683e9a4740c..4916e75676389c7d3a1b0d3ade6cd9fb92fc2128 100644 (file)
@@ -502,6 +502,8 @@ struct channel_config {
 
   struct settle_config roa_settle;     /* Settle times for ROA-induced reload */
 
+  uint feed_block_size;                        /* How many routes to feed at once */
+
   u8 net_type;                         /* Routing table network type (NET_*), 0 for undefined */
   u8 ra_mode;                          /* Mode of received route advertisements (RA_*) */
   u16 preference;                      /* Default route preference */
@@ -560,6 +562,8 @@ struct channel {
 
   u32 refeed_count;                    /* Number of routes exported during refeed regardless of out_limit */
 
+  uint feed_block_size;                        /* How many routes to feed at once */
+
   u8 net_type;                         /* Routing table network type (NET_*), 0 for undefined */
   u8 ra_mode;                          /* Mode of received route advertisements (RA_*) */
   u16 preference;                      /* Default route preference */
index ef740562ab47837f798f4a01ace3999eff272d88..085d25989cc6b89ddb5c964942f6c2110716bc65 100644 (file)
@@ -4231,7 +4231,6 @@ rt_feed_done(struct rt_export_hook *c)
   rt_send_export_event(c);
 }
 
-#define MAX_FEED_BLOCK 1024
 typedef struct {
   uint cnt, pos;
   union {
@@ -4249,19 +4248,21 @@ typedef struct {
 static int
 rt_prepare_feed(struct rt_table_export_hook *c, net *n, rt_feed_block *b)
 {
+  uint bs = c->h.req->feed_block_size;
+
   if (n->routes)
   {
     if (c->h.req->export_bulk)
     {
       uint cnt = rte_feed_count(n);
-      if (b->cnt && (b->cnt + cnt > MAX_FEED_BLOCK))
+      if (b->cnt && (b->cnt + cnt > bs))
        return 0;
 
       if (!b->cnt)
       {
-       b->feed = tmp_alloc(sizeof(rte *) * MAX(MAX_FEED_BLOCK, cnt));
+       b->feed = tmp_alloc(sizeof(rte *) * MAX(bs, cnt));
 
-       uint aux_block_size = (cnt >= MAX_FEED_BLOCK) ? 2 : (MAX_FEED_BLOCK + 2 - cnt);
+       uint aux_block_size = (cnt >= bs) ? 2 : (bs + 2 - cnt);
        b->aux = tmp_alloc(sizeof(struct rt_feed_block_aux) * aux_block_size);
       }
 
@@ -4275,12 +4276,12 @@ rt_prepare_feed(struct rt_table_export_hook *c, net *n, rt_feed_block *b)
 
       b->cnt += cnt;
     }
-    else if (b->pos == MAX_FEED_BLOCK)
+    else if (b->pos == bs)
       return 0;
     else
     {
       if (!b->pos)
-       b->rpe = tmp_alloc(sizeof(struct rt_pending_export) * MAX_FEED_BLOCK);
+       b->rpe = tmp_alloc(sizeof(struct rt_pending_export) * bs);
 
       b->rpe[b->pos++] = (struct rt_pending_export) { .new = n->routes, .new_best = n->routes };
     }
index 4fe8eb53fd142f6fa76c803ac866230c54abcea2..76d33ec788415ac434642eb6efdf1cba4aa0887b 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -292,6 +292,7 @@ struct rt_export_request {
   const net_addr *addr;                        /* Network prefilter address */
   u8 trace_routes;
   u8 addr_mode;                                /* Network prefilter mode (TE_ADDR_*) */
+  uint feed_block_size;                        /* How many routes to feed at once */
 
   event_list *list;                    /* Where to schedule export events */
   pool *pool;                          /* Pool to use for allocations */
index 9d81b85b63748e7ed59ce4e4d13ac89e7df4c63f..e2a0d7df5d293ecb6763e5d1d7ff2c5275bd595a 100644 (file)
@@ -925,6 +925,7 @@ bgp_graceful_restart_feed(struct bgp_channel *c)
     .name = "BGP-GR",
     .list = proto_event_list(c->c.proto),
     .pool = c->c.proto->pool,
+    .feed_block_size = c->c.feed_block_size,
     .trace_routes = c->c.debug | c->c.proto->debug,
     .dump_req = bgp_graceful_restart_feed_dump_req,
     .log_state_change = bgp_graceful_restart_feed_log_state_change,