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.
This commit is contained in:
Ondrej Zajicek (work) 2020-10-11 00:53:19 +02:00
parent 6c11dbcf28
commit fc1e3211b1
5 changed files with 46 additions and 15 deletions

View file

@ -4826,6 +4826,11 @@ specify both channels.
suppresses updating this value by a cache server.
Default: 7200 seconds
<tag>ignore max length <m/switch/</tag>
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.
<tag>transport tcp</tag> Unprotected transport over TCP. It's a default
transport. Should be used only on secure private networks.
Default: tcp

View file

@ -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 <i> 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:

View file

@ -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)

View file

@ -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_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)
return rpki_try_fast_reconnect(cache);
{
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;
}

View file

@ -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);