summaryrefslogtreecommitdiff
path: root/nest/rt-table.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-07-13 12:02:34 +0200
committerMaria Matejka <mq@ucw.cz>2022-07-13 12:02:34 +0200
commit5be34f5ab4aa0c8852db6bf19cad5e81f46640e3 (patch)
tree8a935db40e88b3e79200bc6a8b1b730ea8fe1439 /nest/rt-table.c
parent4ec443b5c283fc4f37629bc38ef3730e0a7cc932 (diff)
parent7e9cede1fd1878fb4c00e793bccd0ca6c18ad452 (diff)
Merge commit '7e9cede1fd1878fb4c00e793bccd0ca6c18ad452' into thread-next
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r--nest/rt-table.c54
1 files changed, 46 insertions, 8 deletions
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;