mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 17:18:42 +00:00
Created a dedicated settle timer structure
This commit is contained in:
parent
31e881bcbd
commit
974f16b1f7
@ -14,6 +14,7 @@ CF_HDR
|
||||
#include "conf/conf.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/socket.h"
|
||||
#include "lib/settle.h"
|
||||
#include "lib/timer.h"
|
||||
#include "lib/string.h"
|
||||
#include "nest/protocol.h"
|
||||
@ -93,6 +94,7 @@ CF_DECLS
|
||||
struct proto_spec ps;
|
||||
struct channel_limit cl;
|
||||
struct timeformat *tf;
|
||||
struct settle_config settle;
|
||||
struct adata *ad;
|
||||
struct bytestring *bs;
|
||||
}
|
||||
@ -111,6 +113,7 @@ CF_DECLS
|
||||
|
||||
%type <i> expr bool pxlen4
|
||||
%type <time> expr_us time
|
||||
%type <settle> settle
|
||||
%type <a> 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_
|
||||
@ -386,6 +389,13 @@ time:
|
||||
}
|
||||
;
|
||||
|
||||
/* Settle timer configuration */
|
||||
settle: expr_us expr_us {
|
||||
if ($1 > $2) cf_error("Minimum settle time %t is bigger than maximum settle time %t", $1, $2);
|
||||
$$.min = $1;
|
||||
$$.max = $2;
|
||||
};
|
||||
|
||||
text:
|
||||
TEXT
|
||||
| CF_SYM_KNOWN {
|
||||
|
@ -965,14 +965,15 @@ inherited from templates can be updated by new definitions.
|
||||
<ref id="bgp-export-table" name="export table"> (for respective
|
||||
direction). Default: on.
|
||||
|
||||
<tag><label id="rtable-min-settle-time">min settle time <m/time/</tag>
|
||||
Minimum settle time is a delay from the last ROA table change to wait
|
||||
for more updates before triggering automatic reload. Default: 1 s.
|
||||
|
||||
<tag><label id="rtable-min-settle-time">min settle time <m/time/</tag>
|
||||
Maximum settle time is an upper 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-min-settle-time">roa settle time <m/time/ <m/time/</tag>
|
||||
Minimum and maximum settle times, respectively, for ROA table changes.
|
||||
The automatic reload is triggered after the minimum time after the last
|
||||
ROA table change has been received but not later than the maximum time after
|
||||
first unprocessed ROA table change. Therefore with default values, the
|
||||
automatic reload happens 1 second after the ROA table stops updating, yet if it
|
||||
were to be later than 20 seconds after the ROA table starts updating,
|
||||
the automatic reload is triggered anyway. Default values: <cf/1 s 20 s/.
|
||||
You have to always provide both values.
|
||||
|
||||
<tag><label id="proto-import-limit">import limit [<m/number/ | off ] [action warn | block | restart | disable]</tag>
|
||||
Specify an import route limit (a maximum number of routes imported from
|
||||
|
64
lib/settle.h
Normal file
64
lib/settle.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* BIRD -- Settle timer
|
||||
*
|
||||
* (c) 2022 Maria Matejka <mq@jmq.cz>
|
||||
* (c) 2022 CZ.NIC z.s.p.o.
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
#ifndef _BIRD_SETTLE_H_
|
||||
#define _BIRD_SETTLE_H_
|
||||
|
||||
#include "lib/birdlib.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
struct settle_config {
|
||||
btime min, max;
|
||||
};
|
||||
|
||||
struct settle {
|
||||
union {
|
||||
/* Timer hook polymorphism. */
|
||||
struct {
|
||||
resource _r;
|
||||
void (*hook)(struct settle *);
|
||||
};
|
||||
timer tm;
|
||||
};
|
||||
struct settle_config cf;
|
||||
btime started;
|
||||
};
|
||||
|
||||
STATIC_ASSERT(OFFSETOF(struct settle, hook) == OFFSETOF(struct settle, tm) + OFFSETOF(timer, hook));
|
||||
|
||||
#define SETTLE_INIT(_cfp, _hook, _data) (struct settle) { .tm = { .data = (_data), }, .hook = (_hook), .cf = ({ASSERT_DIE((_cfp)->min <= (_cfp)->max); *(_cfp); }), }
|
||||
|
||||
|
||||
static inline void settle_init(struct settle *s, struct settle_config *cf, void (*hook)(struct settle *), void *data)
|
||||
{
|
||||
*s = SETTLE_INIT(cf, hook, data);
|
||||
}
|
||||
|
||||
#define settle_active(s) tm_active(&(s)->tm)
|
||||
|
||||
static inline void settle_kick(struct settle *s, struct birdloop *loop)
|
||||
{
|
||||
if (!tm_active(&s->tm))
|
||||
{
|
||||
s->started = current_time();
|
||||
tm_set_in(&s->tm, s->started + s->cf.min, loop);
|
||||
}
|
||||
else
|
||||
{
|
||||
btime now = current_time();
|
||||
tm_set_in(&s->tm, MIN_(now + s->cf.min, s->started + s->cf.max), loop);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void settle_cancel(struct settle *s)
|
||||
{
|
||||
tm_stop(&s->tm);
|
||||
}
|
||||
|
||||
#endif
|
@ -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(CORK, SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD)
|
||||
CF_KEYWORDS(CORK, SORTED, TRIE, MIN, MAX, ROA, 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)
|
||||
@ -321,8 +321,7 @@ channel_item_:
|
||||
| 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; }
|
||||
| MIN SETTLE TIME expr_us { this_channel->min_settle_time = $4; }
|
||||
| MAX SETTLE TIME expr_us { this_channel->max_settle_time = $4; }
|
||||
| ROA SETTLE TIME settle { this_channel->roa_settle = $4; }
|
||||
| PREFERENCE expr { this_channel->preference = $2; check_u16($2); }
|
||||
| IMPORT KEEP FILTERED bool {
|
||||
if ($4)
|
||||
@ -424,7 +423,6 @@ timeformat_base:
|
||||
TIMEFORMAT timeformat_spec ';'
|
||||
;
|
||||
|
||||
|
||||
/* Interface patterns */
|
||||
|
||||
iface_patt_node_init:
|
||||
|
53
nest/proto.c
53
nest/proto.c
@ -315,16 +315,15 @@ proto_remove_channels(struct proto *p)
|
||||
|
||||
struct roa_subscription {
|
||||
node roa_node;
|
||||
timer t;
|
||||
btime base_settle_time; /* Start of settling interval */
|
||||
struct settle settle;
|
||||
struct channel *c;
|
||||
struct rt_export_request req;
|
||||
};
|
||||
|
||||
static void
|
||||
channel_roa_in_changed(struct timer *t)
|
||||
channel_roa_in_changed(struct settle *se)
|
||||
{
|
||||
struct roa_subscription *s = SKIP_BACK(struct roa_subscription, t, t);
|
||||
struct roa_subscription *s = SKIP_BACK(struct roa_subscription, settle, se);
|
||||
struct channel *c = s->c;
|
||||
int active = !!c->reload_req.hook;
|
||||
|
||||
@ -337,9 +336,9 @@ channel_roa_in_changed(struct timer *t)
|
||||
}
|
||||
|
||||
static void
|
||||
channel_roa_out_changed(struct timer *t)
|
||||
channel_roa_out_changed(struct settle *se)
|
||||
{
|
||||
struct roa_subscription *s = SKIP_BACK(struct roa_subscription, t, t);
|
||||
struct roa_subscription *s = SKIP_BACK(struct roa_subscription, settle, se);
|
||||
struct channel *c = s->c;
|
||||
|
||||
CD(c, "Feeding triggered by RPKI change");
|
||||
@ -356,17 +355,7 @@ channel_export_one_roa(struct rt_export_request *req, const net_addr *net UNUSED
|
||||
struct roa_subscription *s = SKIP_BACK(struct roa_subscription, req, req);
|
||||
|
||||
/* TODO: use the information about what roa has changed */
|
||||
|
||||
if (!tm_active(&s->t))
|
||||
{
|
||||
s->base_settle_time = current_time();
|
||||
tm_start(&s->t, s->base_settle_time + s->c->min_settle_time);
|
||||
}
|
||||
else
|
||||
tm_set(&s->t,
|
||||
MIN(s->base_settle_time + s->c->max_settle_time,
|
||||
current_time() + s->c->min_settle_time));
|
||||
|
||||
settle_kick(&s->settle, &main_birdloop);
|
||||
|
||||
rpe_mark_seen_all(req->hook, first, NULL);
|
||||
}
|
||||
@ -380,14 +369,14 @@ channel_dump_roa_req(struct rt_export_request *req)
|
||||
|
||||
debug(" Channel %s.%s ROA %s change notifier from table %s request %p\n",
|
||||
c->proto->name, c->name,
|
||||
(s->t.hook == channel_roa_in_changed) ? "import" : "export",
|
||||
(s->settle.hook == channel_roa_in_changed) ? "import" : "export",
|
||||
tab->name, req);
|
||||
}
|
||||
|
||||
static int
|
||||
channel_roa_is_subscribed(struct channel *c, rtable *tab, int dir)
|
||||
{
|
||||
void (*hook)(struct timer *) =
|
||||
void (*hook)(struct settle *) =
|
||||
dir ? channel_roa_in_changed : channel_roa_out_changed;
|
||||
|
||||
struct roa_subscription *s;
|
||||
@ -395,7 +384,7 @@ channel_roa_is_subscribed(struct channel *c, rtable *tab, int dir)
|
||||
|
||||
WALK_LIST2(s, n, c->roa_subscriptions, roa_node)
|
||||
if ((tab == SKIP_BACK(rtable, priv.exporter.e, s->req.hook->table))
|
||||
&& (s->t.hook == hook))
|
||||
&& (s->settle.hook == hook))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@ -410,7 +399,7 @@ channel_roa_subscribe(struct channel *c, rtable *tab, int dir)
|
||||
struct roa_subscription *s = mb_allocz(c->proto->pool, sizeof(struct roa_subscription));
|
||||
|
||||
*s = (struct roa_subscription) {
|
||||
.t = { .hook = dir ? channel_roa_in_changed : channel_roa_out_changed, },
|
||||
.settle = SETTLE_INIT(&c->roa_settle, dir ? channel_roa_in_changed : channel_roa_out_changed, NULL),
|
||||
.c = c,
|
||||
.req = {
|
||||
.name = mb_sprintf(c->proto->pool, "%s.%s.roa-%s.%s",
|
||||
@ -934,8 +923,10 @@ channel_config_new(const struct channel_class *cc, const char *name, uint net_ty
|
||||
cf->debug = new_config->channel_default_debug;
|
||||
cf->rpki_reload = 1;
|
||||
|
||||
cf->min_settle_time = 1 S;
|
||||
cf->max_settle_time = 20 S;
|
||||
cf->roa_settle = (struct settle_config) {
|
||||
.min = 1 S,
|
||||
.max = 20 S,
|
||||
};
|
||||
|
||||
add_tail(&proto->channels, &cf->n);
|
||||
|
||||
@ -1017,20 +1008,20 @@ channel_reconfigure(struct channel *c, struct channel_config *cf)
|
||||
c->in_req.trace_routes = c->out_req.trace_routes = c->debug | c->proto->debug;
|
||||
c->rpki_reload = cf->rpki_reload;
|
||||
|
||||
if ( (c->min_settle_time != cf->min_settle_time)
|
||||
|| (c->max_settle_time != cf->max_settle_time))
|
||||
if ( (c->roa_settle.min != cf->roa_settle.min)
|
||||
|| (c->roa_settle.max != cf->roa_settle.max))
|
||||
{
|
||||
c->min_settle_time = cf->min_settle_time;
|
||||
c->max_settle_time = cf->max_settle_time;
|
||||
c->roa_settle = cf->roa_settle;
|
||||
|
||||
struct roa_subscription *s;
|
||||
node *n;
|
||||
|
||||
WALK_LIST2(s, n, c->roa_subscriptions, roa_node)
|
||||
if (tm_active(&s->t))
|
||||
tm_set(&s->t,
|
||||
MIN(s->base_settle_time + c->max_settle_time,
|
||||
current_time() + c->min_settle_time));
|
||||
{
|
||||
s->settle.cf = cf->roa_settle;
|
||||
if (settle_active(&s->settle))
|
||||
settle_kick(&s->settle, &main_birdloop);
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute channel-specific reconfigure hook */
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "lib/lists.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/event.h"
|
||||
#include "lib/settle.h"
|
||||
#include "nest/rt.h"
|
||||
#include "nest/limit.h"
|
||||
#include "conf/conf.h"
|
||||
@ -462,8 +463,7 @@ struct channel_config {
|
||||
struct channel_limit in_limit; /* Limit for importing routes from protocol */
|
||||
struct channel_limit out_limit; /* Limit for exporting routes to protocol */
|
||||
|
||||
btime min_settle_time; /* Minimum settle time for ROA-induced reload */
|
||||
btime max_settle_time; /* Maximum settle time for ROA-induced reload */
|
||||
struct settle_config roa_settle; /* Settle times for ROA-induced reload */
|
||||
|
||||
u8 net_type; /* Routing table network type (NET_*), 0 for undefined */
|
||||
u8 ra_mode; /* Mode of received route advertisements (RA_*) */
|
||||
@ -492,8 +492,7 @@ struct channel {
|
||||
struct limit in_limit; /* Input limit */
|
||||
struct limit out_limit; /* Output limit */
|
||||
|
||||
btime min_settle_time; /* Minimum settle time for ROA-induced reload */
|
||||
btime max_settle_time; /* Maximum settle time for ROA-induced reload */
|
||||
struct settle_config roa_settle; /* Settle times for ROA-induced reload */
|
||||
|
||||
u8 limit_actions[PLD_MAX]; /* Limit actions enum */
|
||||
u8 limit_active; /* Flags for active limits */
|
||||
|
Loading…
Reference in New Issue
Block a user