From d3782c72b9243f4609e61edf5f29e6adeaa41e9c Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Fri, 12 Feb 2021 05:05:18 +0100 Subject: [PATCH] Nest: Add option to control automatic RPKI reload Also, no automatic reload for BGP channels without import/export table. --- nest/config.Y | 1 + nest/proto.c | 36 +++++++++++++++++++++++++++++------- nest/protocol.h | 2 ++ proto/pipe/pipe.c | 6 ++++-- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/nest/config.Y b/nest/config.Y index 39bf6149..ef2d0d5f 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -265,6 +265,7 @@ channel_item_: | EXPORT LIMIT limit_spec { this_channel->out_limit = $3; } | PREFERENCE expr { this_channel->preference = $2; check_u16($2); } | IMPORT KEEP FILTERED bool { this_channel->in_keep_filtered = $4; } + | RPKI RELOAD bool { this_channel->rpki_reload = $3; } ; /* To avoid grammar collision in Pipe protocol */ diff --git a/nest/proto.c b/nest/proto.c index 6bd2427b..6c935426 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -175,6 +175,7 @@ proto_add_channel(struct proto *p, struct channel_config *cf) c->debug = cf->debug; c->merge_limit = cf->merge_limit; c->in_keep_filtered = cf->in_keep_filtered; + c->rpki_reload = cf->rpki_reload; c->channel_state = CS_DOWN; c->export_state = ES_DOWN; @@ -383,10 +384,15 @@ channel_roa_subscribe_filter(struct channel *c, int dir) { const struct filter *f = dir ? c->in_filter : c->out_filter; struct rtable *tab; + int valid = 1, found = 0; if ((f == FILTER_ACCEPT) || (f == FILTER_REJECT)) return; + /* No automatic reload for BGP channels without in_table / out_table */ + if (c->channel == &channel_bgp) + valid = dir ? !!c->in_table : !!c->out_table; + struct filter_iterator fit; FILTER_ITERATE_INIT(&fit, f, c->proto->pool); @@ -396,12 +402,14 @@ channel_roa_subscribe_filter(struct channel *c, int dir) { case FI_ROA_CHECK_IMPLICIT: tab = fi->i_FI_ROA_CHECK_IMPLICIT.rtc->table; - channel_roa_subscribe(c, tab, dir); + if (valid) channel_roa_subscribe(c, tab, dir); + found = 1; break; case FI_ROA_CHECK_EXPLICIT: tab = fi->i_FI_ROA_CHECK_EXPLICIT.rtc->table; - channel_roa_subscribe(c, tab, dir); + if (valid) channel_roa_subscribe(c, tab, dir); + found = 1; break; default: @@ -411,6 +419,10 @@ channel_roa_subscribe_filter(struct channel *c, int dir) FILTER_ITERATE_END; FILTER_ITERATE_CLEANUP(&fit); + + if (!valid && found) + log(L_WARN "%s.%s: Automatic RPKI reload not active for %s", + c->proto->name, c->name ?: "?", dir ? "import" : "export"); } static void @@ -542,8 +554,11 @@ static void channel_do_up(struct channel *c) { /* Register RPKI/ROA subscriptions */ - channel_roa_subscribe_filter(c, 1); - channel_roa_subscribe_filter(c, 0); + if (c->rpki_reload) + { + channel_roa_subscribe_filter(c, 1); + channel_roa_subscribe_filter(c, 0); + } } static void @@ -762,6 +777,7 @@ channel_config_new(const struct channel_class *cc, const char *name, uint net_ty cf->ra_mode = RA_OPTIMAL; cf->preference = proto->protocol->preference; cf->debug = new_config->channel_default_debug; + cf->rpki_reload = 1; add_tail(&proto->channels, &cf->n); @@ -814,6 +830,7 @@ channel_reconfigure(struct channel *c, struct channel_config *cf) /* Note that filter_same() requires arguments in (new, old) order */ int import_changed = !filter_same(cf->in_filter, c->in_filter); int export_changed = !filter_same(cf->out_filter, c->out_filter); + int rpki_reload_changed = (cf->rpki_reload != c->rpki_reload); if (c->preference != cf->preference) import_changed = 1; @@ -833,6 +850,7 @@ channel_reconfigure(struct channel *c, struct channel_config *cf) c->preference = cf->preference; c->debug = cf->debug; c->in_keep_filtered = cf->in_keep_filtered; + c->rpki_reload = cf->rpki_reload; channel_verify_limits(c); @@ -845,11 +863,15 @@ channel_reconfigure(struct channel *c, struct channel_config *cf) goto done; /* Update RPKI/ROA subscriptions */ - if (import_changed || export_changed) + if (import_changed || export_changed || rpki_reload_changed) { channel_roa_unsubscribe_all(c); - channel_roa_subscribe_filter(c, 1); - channel_roa_subscribe_filter(c, 0); + + if (c->rpki_reload) + { + channel_roa_subscribe_filter(c, 1); + channel_roa_subscribe_filter(c, 0); + } } if (reconfigure_type == RECONFIG_SOFT) diff --git a/nest/protocol.h b/nest/protocol.h index 17d10fcb..48eb01d2 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -500,6 +500,7 @@ struct channel_config { u32 debug; /* Debugging flags (D_*) */ u8 merge_limit; /* Maximal number of nexthops for RA_MERGED */ u8 in_keep_filtered; /* Routes rejected in import filter are kept */ + u8 rpki_reload; /* RPKI changes trigger channel reload */ }; struct channel { @@ -551,6 +552,7 @@ struct channel { u8 reload_pending; /* Reloading and another reload is scheduled */ u8 refeed_pending; /* Refeeding and another refeed is scheduled */ + u8 rpki_reload; /* RPKI changes trigger channel reload */ struct rtable *out_table; /* Internal table for exported routes */ diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index efb992ca..7b5de324 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -154,7 +154,8 @@ pipe_configure_channels(struct pipe_proto *p, struct pipe_config *cf) .table = cc->table, .out_filter = cc->out_filter, .in_limit = cc->in_limit, - .ra_mode = RA_ANY + .ra_mode = RA_ANY, + .rpki_reload = cc->rpki_reload, }; struct channel_config sec_cf = { @@ -163,7 +164,8 @@ pipe_configure_channels(struct pipe_proto *p, struct pipe_config *cf) .table = cf->peer, .out_filter = cc->in_filter, .in_limit = cc->out_limit, - .ra_mode = RA_ANY + .ra_mode = RA_ANY, + .rpki_reload = cc->rpki_reload, }; return