summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--conf/conf.c1
-rw-r--r--conf/confbase.Y11
-rw-r--r--conf/flowspec.Y2
-rw-r--r--doc/bird.sgml15
-rw-r--r--misc/bird.spec2
-rw-r--r--nest/config.Y4
-rw-r--r--nest/rt-table.c54
-rw-r--r--nest/rt.h8
-rw-r--r--proto/babel/babel.c9
-rw-r--r--sysdep/config.h2
-rw-r--r--sysdep/unix/io.c8
12 files changed, 99 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index c1e51af2..e61a0b74 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+Version 2.0.10 (2022-06-16)
+ o BGP performance improvements
+ o BFD: New 'strict bind' option
+ o RPKI: VRF support
+ o Allow use of 240.0.0.0/4 as a private range
+ o BIRD client uses exit status to report errors
+ o Important bugfixes
+
Version 2.0.9 (2022-02-09)
o BGP: Flowspec validation procedure
o Babel: MAC authentication support
diff --git a/conf/conf.c b/conf/conf.c
index 580a6472..17424402 100644
--- a/conf/conf.c
+++ b/conf/conf.c
@@ -140,6 +140,7 @@ config_parse(struct config *c)
protos_preconfig(c);
rt_preconfig(c);
cf_parse();
+ rt_postconfig(c);
if (EMPTY_LIST(c->protos))
cf_error("No protocol is specified in the config file");
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 58890cd6..a603153c 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -111,7 +111,7 @@ CF_DECLS
%type <i> expr bool pxlen4
%type <time> expr_us time
%type <a> ipa
-%type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
+%type <net> net_ip4_ net_ip4 net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_mpls_
%type <ad> label_stack_start label_stack
@@ -307,6 +307,15 @@ net_:
/* Networks - regular */
+net_ip4:
+ net_ip4_
+ | CF_SYM_KNOWN {
+ if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP4))
+ cf_error("IPv4 network constant expected");
+ $$ = * SYM_VAL($1).net;
+ }
+ ;
+
net_ip6:
net_ip6_
| CF_SYM_KNOWN {
diff --git a/conf/flowspec.Y b/conf/flowspec.Y
index 56a7c5dc..dbdbdda5 100644
--- a/conf/flowspec.Y
+++ b/conf/flowspec.Y
@@ -142,7 +142,7 @@ flow_frag_opts:
;
flow4_item:
- flow_srcdst net_ip {
+ flow_srcdst net_ip4 {
flow_builder_set_type(this_flow, $1);
flow_builder4_add_pfx(this_flow, (net_addr_ip4 *) &($2));
}
diff --git a/doc/bird.sgml b/doc/bird.sgml
index c9ce670b..ea126fa2 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -684,6 +684,21 @@ to set options.
limit to the settle time from the initial ROA table change even if
there are consecutive updates gradually renewing the settle time.
Default: 20 s.
+
+ <tag><label id="rtable-gc-threshold">gc threshold <m/number/</tag>
+ Specify a minimum amount of removed networks that triggers a garbage
+ collection (GC) cycle. Default: 1000.
+
+ <tag><label id="rtable-gc-period">gc period <m/time/</tag>
+ Specify a period of time between consecutive GC cycles. When there is a
+ significant amount of route withdraws, GC cycles are executed repeatedly
+ with given period time (with some random factor). When there is just
+ small amount of changes, GC cycles are not executed. In extensive route
+ server setups, running GC on hundreds of full BGP routing tables can
+ take significant amount of time, therefore they should use higher GC
+ periods. Default: adaptive, based on number of routing tables in the
+ configuration. From 10 s (with <= 25 routing tables) up to 600 s (with
+ >= 1500 routing tables).
</descrip>
diff --git a/misc/bird.spec b/misc/bird.spec
index 425a6340..c3fdd7d6 100644
--- a/misc/bird.spec
+++ b/misc/bird.spec
@@ -1,6 +1,6 @@
Summary: BIRD Internet Routing Daemon
Name: bird
-Version: 2.0.9
+Version: 2.0.10
Release: 1
Copyright: GPL
Group: Networking/Daemons
diff --git a/nest/config.Y b/nest/config.Y
index edddfc2b..f193a4fb 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -125,7 +125,7 @@ CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, AS)
CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
CF_KEYWORDS(CHECK, LINK)
-CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME)
+CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD)
/* For r_args_channel */
CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
@@ -229,6 +229,8 @@ table_opt:
}
| MIN SETTLE TIME expr_us { this_table->min_settle_time = $4; }
| MAX SETTLE TIME expr_us { this_table->max_settle_time = $4; }
+ | GC THRESHOLD expr { this_table->gc_threshold = $3; }
+ | GC PERIOD expr_us { this_table->gc_period = (uint) $3; if ($3 > 3600 S_) cf_error("GC period must be at most 3600 s"); }
;
table_opts:
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 3f8c7a83..e7281b2e 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -126,6 +126,7 @@ static inline void rt_flowspec_resolve_rte(rte *r, struct channel *c);
static inline void rt_prune_table(rtable *tab);
static inline void rt_schedule_notify(rtable *tab);
static void rt_flowspec_notify(rtable *tab, net *net);
+static void rt_kick_prune_timer(rtable *tab);
static void rt_feed_by_fib(void *);
static void rt_feed_by_trie(void *);
static void rt_feed_equal(void *);
@@ -1485,9 +1486,8 @@ rte_recalculate(struct rt_import_hook *c, net *net, rte *new, struct rte_src *sr
net->routes, old_best_stored);
if (!net->routes &&
- (table->gc_counter++ >= table->config->gc_max_ops) &&
- (table->gc_time + table->config->gc_min_time <= current_time()))
- rt_schedule_prune(table);
+ (table->gc_counter++ >= table->config->gc_threshold))
+ rt_kick_prune_timer(table);
#if 0
/* Enable and reimplement these callbacks if anybody wants to use them */
@@ -2111,6 +2111,29 @@ rt_event(void *ptr)
}
+static void
+rt_prune_timer(timer *t)
+{
+ rtable *tab = t->data;
+
+ if (tab->gc_counter >= tab->config->gc_threshold)
+ rt_schedule_prune(tab);
+}
+
+static void
+rt_kick_prune_timer(rtable *tab)
+{
+ /* Return if prune is already scheduled */
+ if (tm_active(tab->prune_timer) || (tab->prune_state & 1))
+ return;
+
+ /* Randomize GC period to +/- 50% */
+ btime gc_period = tab->config->gc_period;
+ gc_period = (gc_period / 2) + (random_u32() % (uint) gc_period);
+ tm_start(tab->prune_timer, gc_period);
+}
+
+
static inline btime
rt_settled_time(rtable *tab)
{
@@ -2349,6 +2372,7 @@ rt_setup(pool *pp, struct rtable_config *cf)
init_list(&t->subscribers);
t->rt_event = ev_new_init(p, rt_event, t);
+ t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
t->last_rt_change = t->gc_time = current_time();
t->rl_pipe = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
@@ -2427,6 +2451,9 @@ rt_prune_table(rtable *tab)
FIB_ITERATE_INIT(fit, &tab->fib);
tab->prune_state = 2;
+ tab->gc_counter = 0;
+ tab->gc_time = current_time();
+
if (tab->prune_trie)
{
/* Init prefix trie pruning */
@@ -2479,9 +2506,6 @@ again:
fib_check(&tab->fib);
#endif
- tab->gc_counter = 0;
- tab->gc_time = current_time();
-
/* state change 2->0, 3->1 */
tab->prune_state &= 1;
@@ -2611,6 +2635,20 @@ rt_preconfig(struct config *c)
rt_new_table(cf_get_symbol("master6"), NET_IP6);
}
+void
+rt_postconfig(struct config *c)
+{
+ uint num_tables = list_length(&c->tables);
+ btime def_gc_period = 400 MS * num_tables;
+ def_gc_period = MAX(def_gc_period, 10 S);
+ def_gc_period = MIN(def_gc_period, 600 S);
+
+ struct rtable_config *rc;
+ WALK_LIST(rc, c->tables)
+ if (rc->gc_period == (uint) -1)
+ rc->gc_period = (uint) def_gc_period;
+}
+
/*
* Some functions for handing internal next hop updates
@@ -3093,8 +3131,8 @@ rt_new_table(struct symbol *s, uint addr_type)
cf_define_symbol(s, SYM_TABLE, table, c);
c->name = s->name;
c->addr_type = addr_type;
- c->gc_max_ops = 1000;
- c->gc_min_time = 5;
+ c->gc_threshold = 1000;
+ c->gc_period = (uint) -1; /* set in rt_postconfig() */
c->min_settle_time = 1 S;
c->max_settle_time = 20 S;
diff --git a/nest/rt.h b/nest/rt.h
index 4a7a087f..b13c06be 100644
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -47,8 +47,8 @@ struct rtable_config {
struct rtable *table;
struct proto_config *krt_attached; /* Kernel syncer attached to this table */
uint addr_type; /* Type of address data stored in table (NET_*) */
- int gc_max_ops; /* Maximum number of operations before GC is run */
- int gc_min_time; /* Minimum time between two consecutive GC runs */
+ uint gc_threshold; /* Maximum number of operations before GC is run */
+ uint gc_period; /* Approximate time between two consecutive GC runs */
byte sorted; /* Routes of network are sorted according to rte_better() */
byte trie_used; /* Rtable has attached trie */
btime min_settle_time; /* Minimum settle time for notifications */
@@ -89,10 +89,11 @@ typedef struct rtable {
* obstacle from this routing table.
*/
struct event *rt_event; /* Routing table event */
+ struct timer *prune_timer; /* Timer for periodic pruning / GC */
btime last_rt_change; /* Last time when route changed */
btime base_settle_time; /* Start time of rtable settling interval */
btime gc_time; /* Time of last GC */
- int gc_counter; /* Number of operations since last GC */
+ uint gc_counter; /* Number of operations since last GC */
byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte prune_trie; /* Prune prefix trie during next table prune */
byte hcu_scheduled; /* Hostcache update is scheduled */
@@ -364,6 +365,7 @@ struct config;
void rt_init(void);
void rt_preconfig(struct config *);
+void rt_postconfig(struct config *);
void rt_commit(struct config *new, struct config *old);
void rt_lock_table(rtable *);
void rt_unlock_table(rtable *);
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 4939619f..8b6abacb 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -315,7 +315,9 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
/* Found older */
rem_node(NODE sr);
- rem_node(&sr->nbr_node);
+
+ if (sr->nbr)
+ rem_node(&sr->nbr_node);
goto found;
}
@@ -455,10 +457,7 @@ babel_flush_neighbor(struct babel_proto *p, struct babel_neighbor *nbr)
struct babel_seqno_request *sr;
WALK_LIST_FIRST2(sr, nbr_node, nbr->requests)
- {
- sr->nbr = NULL;
- rem_node(&sr->nbr_node);
- }
+ babel_remove_seqno_request(p, sr);
nbr->ifa = NULL;
rem_node(NODE nbr);
diff --git a/sysdep/config.h b/sysdep/config.h
index b0531844..5cdadbb0 100644
--- a/sysdep/config.h
+++ b/sysdep/config.h
@@ -13,7 +13,7 @@
#ifdef GIT_LABEL
#define BIRD_VERSION XSTR1(GIT_LABEL)
#else
-#define BIRD_VERSION "2.0.9"
+#define BIRD_VERSION "2.0.10"
#endif
/* Include parameters determined by configure script */
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 8a116789..810e782d 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -2063,8 +2063,8 @@ io_update_time(void)
event_open->duration = last_time - event_open->timestamp;
if (event_open->duration > config->latency_limit)
- log(L_WARN "Event 0x%p 0x%p took %d ms",
- event_open->hook, event_open->data, (int) (event_open->duration TO_MS));
+ log(L_WARN "Event 0x%p 0x%p took %u.%03u ms",
+ event_open->hook, event_open->data, (uint) (event_open->duration TO_MS), (uint) (event_open->duration % 1000));
event_open = NULL;
}
@@ -2168,8 +2168,8 @@ watchdog_stop(void)
btime duration = last_time - loop_time;
if (duration > config->watchdog_warning)
- log(L_WARN "I/O loop cycle took %d ms for %d events",
- (int) (duration TO_MS), event_log_num);
+ log(L_WARN "I/O loop cycle took %u.%03u ms for %d events",
+ (uint) (duration TO_MS), (uint) (duration % 1000), event_log_num);
}