0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

Channel: configurable feed block size

This commit is contained in:
Maria Matejka 2023-05-07 23:04:47 +02:00
parent 6572aff669
commit dd1f1c46cc
7 changed files with 27 additions and 6 deletions

View File

@ -1024,6 +1024,13 @@ inherited from templates can be updated by new definitions.
counter ignores route blocking and block action also blocks route counter ignores route blocking and block action also blocks route
updates of already accepted routes -- and these details will probably updates of already accepted routes -- and these details will probably
change in the future. Default: <cf/off/. 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> </descrip>
<p>This is a trivial example of RIP configured for IPv6 on all interfaces: <p>This is a trivial example of RIP configured for IPv6 on all interfaces:

View File

@ -320,6 +320,7 @@ channel_item_:
this_channel->out_filter = $4; this_channel->out_filter = $4;
} }
| EXPORT imexport { this_channel->out_filter = $2; } | 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; } | RECEIVE LIMIT limit_spec { this_channel->rx_limit = $3; }
| IMPORT LIMIT limit_spec { this_channel->in_limit = $3; } | IMPORT LIMIT limit_spec { this_channel->in_limit = $3; }
| EXPORT LIMIT limit_spec { this_channel->out_limit = $3; } | EXPORT LIMIT limit_spec { this_channel->out_limit = $3; }

View File

@ -207,6 +207,8 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
c->out_filter = cf->out_filter; c->out_filter = cf->out_filter;
c->out_subprefix = cf->out_subprefix; 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->rx_limit, PLD_RX, &cf->rx_limit);
channel_init_limit(c, &c->in_limit, PLD_IN, &cf->in_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); 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), .name = mb_sprintf(c->proto->pool, "%s.%s", c->proto->name, c->name),
.list = proto_work_list(c->proto), .list = proto_work_list(c->proto),
.pool = c->proto->pool, .pool = c->proto->pool,
.feed_block_size = c->feed_block_size,
.addr = c->out_subprefix, .addr = c->out_subprefix,
.addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE, .addr_mode = c->out_subprefix ? TE_ADDR_IN : TE_ADDR_NONE,
.trace_routes = c->debug | c->proto->debug, .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), .name = mb_sprintf(c->proto->pool, "%s.%s.import", c->proto->name, c->name),
.list = proto_work_list(c->proto), .list = proto_work_list(c->proto),
.pool = c->proto->pool, .pool = c->proto->pool,
.feed_block_size = c->feed_block_size,
.trace_routes = c->debug | c->proto->debug, .trace_routes = c->debug | c->proto->debug,
.export_bulk = channel_reload_export_bulk, .export_bulk = channel_reload_export_bulk,
.dump_req = channel_reload_dump_req, .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->table = tab;
cf->out_filter = FILTER_REJECT; cf->out_filter = FILTER_REJECT;
cf->feed_block_size = 16384;
cf->net_type = net_type; cf->net_type = net_type;
cf->ra_mode = RA_OPTIMAL; cf->ra_mode = RA_OPTIMAL;
cf->preference = proto->protocol->preference; cf->preference = proto->protocol->preference;

View File

@ -502,6 +502,8 @@ struct channel_config {
struct settle_config roa_settle; /* Settle times for ROA-induced reload */ 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 net_type; /* Routing table network type (NET_*), 0 for undefined */
u8 ra_mode; /* Mode of received route advertisements (RA_*) */ u8 ra_mode; /* Mode of received route advertisements (RA_*) */
u16 preference; /* Default route preference */ u16 preference; /* Default route preference */
@ -560,6 +562,8 @@ struct channel {
u32 refeed_count; /* Number of routes exported during refeed regardless of out_limit */ 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 net_type; /* Routing table network type (NET_*), 0 for undefined */
u8 ra_mode; /* Mode of received route advertisements (RA_*) */ u8 ra_mode; /* Mode of received route advertisements (RA_*) */
u16 preference; /* Default route preference */ u16 preference; /* Default route preference */

View File

@ -4231,7 +4231,6 @@ rt_feed_done(struct rt_export_hook *c)
rt_send_export_event(c); rt_send_export_event(c);
} }
#define MAX_FEED_BLOCK 1024
typedef struct { typedef struct {
uint cnt, pos; uint cnt, pos;
union { union {
@ -4249,19 +4248,21 @@ typedef struct {
static int static int
rt_prepare_feed(struct rt_table_export_hook *c, net *n, rt_feed_block *b) 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 (n->routes)
{ {
if (c->h.req->export_bulk) if (c->h.req->export_bulk)
{ {
uint cnt = rte_feed_count(n); uint cnt = rte_feed_count(n);
if (b->cnt && (b->cnt + cnt > MAX_FEED_BLOCK)) if (b->cnt && (b->cnt + cnt > bs))
return 0; return 0;
if (!b->cnt) 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); 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; b->cnt += cnt;
} }
else if (b->pos == MAX_FEED_BLOCK) else if (b->pos == bs)
return 0; return 0;
else else
{ {
if (!b->pos) 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 }; b->rpe[b->pos++] = (struct rt_pending_export) { .new = n->routes, .new_best = n->routes };
} }

View File

@ -292,6 +292,7 @@ struct rt_export_request {
const net_addr *addr; /* Network prefilter address */ const net_addr *addr; /* Network prefilter address */
u8 trace_routes; u8 trace_routes;
u8 addr_mode; /* Network prefilter mode (TE_ADDR_*) */ 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 */ event_list *list; /* Where to schedule export events */
pool *pool; /* Pool to use for allocations */ pool *pool; /* Pool to use for allocations */

View File

@ -925,6 +925,7 @@ bgp_graceful_restart_feed(struct bgp_channel *c)
.name = "BGP-GR", .name = "BGP-GR",
.list = proto_event_list(c->c.proto), .list = proto_event_list(c->c.proto),
.pool = c->c.proto->pool, .pool = c->c.proto->pool,
.feed_block_size = c->c.feed_block_size,
.trace_routes = c->c.debug | c->c.proto->debug, .trace_routes = c->c.debug | c->c.proto->debug,
.dump_req = bgp_graceful_restart_feed_dump_req, .dump_req = bgp_graceful_restart_feed_dump_req,
.log_state_change = bgp_graceful_restart_feed_log_state_change, .log_state_change = bgp_graceful_restart_feed_log_state_change,