diff --git a/doc/bird.sgml b/doc/bird.sgml index ffc22218..aa16c227 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -4826,6 +4826,11 @@ specify both channels. suppresses updating this value by a cache server. Default: 7200 seconds + ignore max length + Ignore received max length in ROA records and use max value (32 or 128) + instead. This may be useful for implementing loose RPKI check for + blackholes. Default: disabled. + transport tcp Unprotected transport over TCP. It's a default transport. Should be used only on secure private networks. Default: tcp diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y index 924066f8..d6d326b8 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -32,7 +32,7 @@ rpki_check_unused_transport(void) CF_DECLS CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER, - RETRY, REFRESH, EXPIRE, KEEP) + RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH) %type rpki_keep_interval @@ -79,6 +79,7 @@ rpki_proto_item: RPKI_CFG->expire_interval = $3; RPKI_CFG->keep_expire_interval = $2; } + | IGNORE MAX LENGTH bool { RPKI_CFG->ignore_max_length = $4; } ; rpki_keep_interval: diff --git a/proto/rpki/packets.c b/proto/rpki/packets.c index e9d24fb8..dd11f997 100644 --- a/proto/rpki/packets.c +++ b/proto/rpki/packets.c @@ -729,12 +729,22 @@ rpki_prefix_pdu_2_net_addr(const struct pdu_header *pdu, net_addr_union *n) static int rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu) { + const struct rpki_config *cf = (void *) cache->p->p.cf; + const enum pdu_type type = pdu->type; ASSERT(type == IPV4_PREFIX || type == IPV6_PREFIX); net_addr_union addr = {}; rpki_prefix_pdu_2_net_addr(pdu, &addr); + if (cf->ignore_max_length) + { + if (type == IPV4_PREFIX) + addr.roa4.max_pxlen = IP4_MAX_PREFIX_LENGTH; + else + addr.roa6.max_pxlen = IP6_MAX_PREFIX_LENGTH; + } + struct channel *channel = NULL; if (type == IPV4_PREFIX) diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 3e46b6d1..3ee46ae2 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -639,18 +639,6 @@ rpki_shutdown(struct proto *P) * RPKI Reconfiguration */ -static int -rpki_try_fast_reconnect(struct rpki_cache *cache) -{ - if (cache->state == RPKI_CS_ESTABLISHED) - { - rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT); - return SUCCESSFUL_RECONF; - } - - return NEED_RESTART; -} - /** * rpki_reconfigure_cache - a cache reconfiguration * @p: RPKI protocol instance @@ -666,6 +654,7 @@ rpki_try_fast_reconnect(struct rpki_cache *cache) static int rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, struct rpki_config *new, struct rpki_config *old) { + u8 try_reset = 0; u8 try_fast_reconnect = 0; if (strcmp(old->hostname, new->hostname) != 0) @@ -685,6 +674,13 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st CACHE_TRACE(D_EVENTS, cache, "Transport type changed"); return NEED_RESTART; } + + if (old->ignore_max_length != new->ignore_max_length) + { + CACHE_TRACE(D_EVENTS, cache, "Ignore max length changed"); + try_reset = 1; + } + #if HAVE_LIBSSH else if (new->tr_config.type == RPKI_TR_SSH) { @@ -713,8 +709,26 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st TEST_INTERVAL(expire, Expire); #undef TEST_INTERVAL - if (try_fast_reconnect) - return rpki_try_fast_reconnect(cache); + if (try_reset || try_fast_reconnect) + { + if (cache->state != RPKI_CS_ESTABLISHED) + return NEED_RESTART; + + if (try_reset && !try_fast_reconnect) + rpki_cache_change_state(cache, RPKI_CS_RESET); + + if (try_fast_reconnect) + { + if (try_reset) + { + /* Force reset during reconnect */ + cache->request_session_id = 1; + cache->serial_num = 0; + } + + rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT); + } + } return SUCCESSFUL_RECONF; } diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h index 8972b33a..8a5c38fd 100644 --- a/proto/rpki/rpki.h +++ b/proto/rpki/rpki.h @@ -125,6 +125,7 @@ struct rpki_config { u8 keep_refresh_interval:1; /* Do not overwrite refresh interval by cache server update */ u8 keep_retry_interval:1; /* Do not overwrite retry interval by cache server update */ u8 keep_expire_interval:1; /* Do not overwrite expire interval by cache server update */ + u8 ignore_max_length:1; /* Ignore received max length and use MAX_PREFIX_LENGTH instead */ }; void rpki_check_config(struct rpki_config *cf);