From fc1e3211b109400c0e96f889829c9f5145ac7226 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Sun, 11 Oct 2020 00:53:19 +0200 Subject: [PATCH] RPKI: Add 'ignore max length' option Add 'ignore max length' option to RPKI protocol, which ignores received max length in ROA records and instead uses max value (32 or 128). This may be useful for implementing loose RPKI check for blackholes. --- doc/bird.sgml | 5 +++++ proto/rpki/config.Y | 3 ++- proto/rpki/packets.c | 10 ++++++++++ proto/rpki/rpki.c | 42 ++++++++++++++++++++++++++++-------------- proto/rpki/rpki.h | 1 + 5 files changed, 46 insertions(+), 15 deletions(-) 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);