mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-31 14:11:54 +00:00
Settle timer generalization
Settle timer was moved from nest/rt-table.c to lib/timer.c.
This commit is contained in:
parent
f28713a0dd
commit
374ee57466
71
lib/timer.c
71
lib/timer.c
@ -376,3 +376,74 @@ tm_format_real_time(char *x, size_t max, const char *fmt, btime t)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Settle timer
|
||||
*/
|
||||
|
||||
static btime
|
||||
settled_time(struct settle_timer *st)
|
||||
{
|
||||
return MIN_(st->last_change + *(st->min_settle_time),
|
||||
st->base_settle_time + *(st->max_settle_time));
|
||||
}
|
||||
|
||||
void
|
||||
settle_timer_changed(struct settle_timer *st)
|
||||
{
|
||||
st->last_change = current_time();
|
||||
}
|
||||
|
||||
void
|
||||
settle_timer(timer *t)
|
||||
{
|
||||
log(L_INFO "settle_timer()");
|
||||
struct settle_timer *st = (void *) t;
|
||||
|
||||
if (!st->base_settle_time)
|
||||
return;
|
||||
|
||||
btime settled_t = settled_time(st);
|
||||
if (current_time() < settled_t)
|
||||
{
|
||||
tm_set((timer *) st, settled_t);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Settled */
|
||||
st->base_settle_time = 0;
|
||||
|
||||
if (st->class->action)
|
||||
st->class->action(st);
|
||||
}
|
||||
|
||||
struct settle_timer *
|
||||
stm_new_timer(pool *p, void *data, struct settle_timer_class *class)
|
||||
{
|
||||
log(L_INFO "stm_new_timer() creating new timer");
|
||||
struct settle_timer *st;
|
||||
st = mb_allocz(p, sizeof(struct settle_timer));
|
||||
st->class = class;
|
||||
|
||||
/* timer option randomize and recurrent are set to zero */
|
||||
timer *t = (void *) st;
|
||||
t->index = -1;
|
||||
t->hook = settle_timer;
|
||||
t->data = data;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void
|
||||
kick_settle_timer(struct settle_timer *st)
|
||||
{
|
||||
log(L_INFO "kick_settle_timer()");
|
||||
ASSUME(st != NULL);
|
||||
|
||||
st->base_settle_time = current_time();
|
||||
|
||||
timer *t = (void *) st;
|
||||
if (!tm_active(t))
|
||||
tm_set(t, settled_time(st));
|
||||
}
|
||||
|
22
lib/timer.h
22
lib/timer.h
@ -124,4 +124,26 @@ btime tm_parse_time(const char *x);
|
||||
void tm_format_time(char *x, struct timeformat *fmt, btime t);
|
||||
int tm_format_real_time(char *x, size_t max, const char *fmt, btime t);
|
||||
|
||||
/*
|
||||
* Settle timer
|
||||
*/
|
||||
|
||||
struct settle_timer {
|
||||
timer tm;
|
||||
btime *min_settle_time;
|
||||
btime *max_settle_time;
|
||||
btime base_settle_time;
|
||||
btime last_change;
|
||||
const struct settle_timer_class *class;
|
||||
};
|
||||
|
||||
struct settle_timer_class {
|
||||
void (*action)(struct settle_timer *st);
|
||||
void (*changed)(struct settle_timer *st);
|
||||
void (*kick)(struct settle_timer *st);
|
||||
};
|
||||
|
||||
struct settle_timer *stm_new_timer(pool *p, void *data, struct settle_timer_class *class);
|
||||
void kick_settle_timer(struct settle_timer *st);
|
||||
|
||||
#endif
|
||||
|
@ -1365,7 +1365,7 @@ rte_recalculate(struct rt_import_hook *c, net *net, rte *new, struct rte_src *sr
|
||||
stats->withdraws_ignored++;
|
||||
|
||||
if (old_ok || new_ok)
|
||||
table->last_rt_change = current_time();
|
||||
table->settle_timer->last_change = current_time();
|
||||
|
||||
if (table->config->sorted)
|
||||
{
|
||||
@ -2019,7 +2019,7 @@ rt_dump_hooks(rtable *tab)
|
||||
debug(" nhu_state=%u hcu_scheduled=%u use_count=%d rt_count=%u\n",
|
||||
tab->nhu_state, tab->hcu_scheduled, tab->use_count, tab->rt_count);
|
||||
debug(" last_rt_change=%t gc_time=%t gc_counter=%d prune_state=%u\n",
|
||||
tab->last_rt_change, tab->gc_time, tab->gc_counter, tab->prune_state);
|
||||
tab->settle_timer->last_change, tab->gc_time, tab->gc_counter, tab->prune_state);
|
||||
|
||||
struct rt_import_hook *ih;
|
||||
WALK_LIST(ih, tab->imports)
|
||||
@ -2133,50 +2133,21 @@ rt_kick_prune_timer(rtable *tab)
|
||||
tm_start(tab->prune_timer, gc_period);
|
||||
}
|
||||
|
||||
|
||||
static inline btime
|
||||
rt_settled_time(rtable *tab)
|
||||
{
|
||||
ASSUME(tab->base_settle_time != 0);
|
||||
|
||||
return MIN(tab->last_rt_change + tab->config->min_settle_time,
|
||||
tab->base_settle_time + tab->config->max_settle_time);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_settle_timer(timer *t)
|
||||
rt_settle_timer(struct settle_timer *st)
|
||||
{
|
||||
timer *t = (void *) st;
|
||||
rtable *tab = t->data;
|
||||
|
||||
if (!tab->base_settle_time)
|
||||
return;
|
||||
|
||||
btime settled_time = rt_settled_time(tab);
|
||||
if (current_time() < settled_time)
|
||||
{
|
||||
tm_set(tab->settle_timer, settled_time);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Settled */
|
||||
tab->base_settle_time = 0;
|
||||
|
||||
struct rt_subscription *s;
|
||||
WALK_LIST(s, tab->subscribers)
|
||||
s->hook(s);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_kick_settle_timer(rtable *tab)
|
||||
{
|
||||
tab->base_settle_time = current_time();
|
||||
|
||||
if (!tab->settle_timer)
|
||||
tab->settle_timer = tm_new_init(tab->rp, rt_settle_timer, tab, 0, 0);
|
||||
|
||||
if (!tm_active(tab->settle_timer))
|
||||
tm_set(tab->settle_timer, rt_settled_time(tab));
|
||||
}
|
||||
static struct settle_timer_class rt_settle_class = {
|
||||
.action = rt_settle_timer,
|
||||
.kick = NULL,
|
||||
};
|
||||
|
||||
static inline void
|
||||
rt_schedule_notify(rtable *tab)
|
||||
@ -2184,10 +2155,10 @@ rt_schedule_notify(rtable *tab)
|
||||
if (EMPTY_LIST(tab->subscribers))
|
||||
return;
|
||||
|
||||
if (tab->base_settle_time)
|
||||
if (tab->settle_timer->base_settle_time)
|
||||
return;
|
||||
|
||||
rt_kick_settle_timer(tab);
|
||||
kick_settle_timer(tab->settle_timer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2373,7 +2344,9 @@ rt_setup(pool *pp, struct rtable_config *cf)
|
||||
|
||||
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->settle_timer = stm_new_timer(p, t, &rt_settle_class);
|
||||
|
||||
t->settle_timer->last_change = t->gc_time = current_time();
|
||||
|
||||
t->rl_pipe = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "lib/type.h"
|
||||
#include "lib/fib.h"
|
||||
#include "lib/route.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
struct ea_list;
|
||||
struct protocol;
|
||||
@ -90,8 +91,6 @@ typedef struct rtable {
|
||||
*/
|
||||
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 */
|
||||
uint gc_counter; /* Number of operations since last GC */
|
||||
byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
|
||||
@ -107,7 +106,7 @@ typedef struct rtable {
|
||||
struct tbf rl_pipe; /* Rate limiting token buffer for pipe collisions */
|
||||
|
||||
list subscribers; /* Subscribers for notifications */
|
||||
struct timer *settle_timer; /* Settle time for notifications */
|
||||
struct settle_timer *settle_timer; /* Settle time for notifications */
|
||||
list flowspec_links; /* List of flowspec links, src for NET_IPx and dst for NET_FLOWx */
|
||||
struct f_trie *flowspec_trie; /* Trie for evaluation of flowspec notifications */
|
||||
} rtable;
|
||||
|
Loading…
Reference in New Issue
Block a user