From: Maria Matejka Date: Mon, 25 Nov 2024 08:35:33 +0000 (+0100) Subject: RPKI: added documentation and RTR version config options X-Git-Tag: v2.16~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e330fb1614d83e3529f4405d0875160d425f8bb3;p=thirdparty%2Fbird.git RPKI: added documentation and RTR version config options --- diff --git a/doc/bird.sgml b/doc/bird.sgml index 0d1e6f490..ed45f6054 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -5728,6 +5728,10 @@ affected routes after RPKI update, see option . Or you can use a BIRD client command reload in for manual call of revalidation of all routes. +

The same protocol, since version 2, also receives and maintains a set +of ASPAs. You can then validate AS paths using function Supported transports

@@ -5747,6 +5751,7 @@ define more RPKI protocols generally. protocol rpki [<name>] { roa4 { table <tab>; }; roa6 { table <tab>; }; + aspa { table <tab>; }; remote <ip> | "<domain>" [port <num>]; port <num>; local address <ip>; @@ -5762,10 +5767,12 @@ protocol rpki [<name>] { remote public key "</path/to/known_host>"; user "<name>"; }; + max version 2; + min version 2; } -

Alse note that you have to specify the ROA channel. If you want to import +

Alse note that you have to specify the ROA and ASPA channels. If you want to import only IPv4 prefixes you have to specify only roa4 channel. Similarly with IPv6 prefixes only. If you want to fetch both IPv4 and even IPv6 ROAs you have to specify both channels. @@ -5812,6 +5819,16 @@ specify both channels. instead. This may be useful for implementing loose RPKI check for blackholes. Default: disabled. + min version + Minimal allowed version of the RTR protocol. BIRD will refuse to + downgrade a connection below this version and drop the session instead. + Default: 0 + + max version + Maximal allowed version of the RTR protocol. BIRD will start with this + version. Use this option if sending version 2 to your cache causes + problems. Default: 2 + transport tcp { Transport over TCP, it's the default transport. Cannot be combined with a SSH transport. Default: TCP, no authentication. diff --git a/proto/rpki/config.Y b/proto/rpki/config.Y index 60a4b9f07..68e0ebfdc 100644 --- a/proto/rpki/config.Y +++ b/proto/rpki/config.Y @@ -33,8 +33,8 @@ rpki_check_unused_transport(void) CF_DECLS CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER, - RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH, LOCAL, ADDRESS, - AUTHENTICATION, NONE, MD5, PASSWORD) + RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, MIN, LENGTH, LOCAL, ADDRESS, + AUTHENTICATION, NONE, MD5, PASSWORD, VERSION) %type rpki_keep_interval @@ -47,6 +47,8 @@ rpki_proto_start: proto_start RPKI { RPKI_CFG->retry_interval = RPKI_RETRY_INTERVAL; RPKI_CFG->refresh_interval = RPKI_REFRESH_INTERVAL; RPKI_CFG->expire_interval = RPKI_EXPIRE_INTERVAL; + RPKI_CFG->min_version = 0; + RPKI_CFG->max_version = RPKI_MAX_VERSION; }; rpki_proto: rpki_proto_start proto_name '{' rpki_proto_opts '}' { rpki_check_config(RPKI_CFG); }; @@ -83,6 +85,14 @@ rpki_proto_item: RPKI_CFG->keep_expire_interval = $2; } | IGNORE MAX LENGTH bool { RPKI_CFG->ignore_max_length = $4; } + | MIN VERSION expr { + if ($3 > RPKI_MAX_VERSION) cf_error("RPKI version %u unsupported, min version must be in range 0-%u", $3, RPKI_MAX_VERSION); + RPKI_CFG->min_version = $3; + } + | MAX VERSION expr { + if ($3 > RPKI_MAX_VERSION) cf_error("RPKI version %u unsupported, max version must be in range 0-%u", $3, RPKI_MAX_VERSION); + RPKI_CFG->max_version = $3; + } ; rpki_keep_interval: diff --git a/proto/rpki/packets.c b/proto/rpki/packets.c index de9e86195..c26c46d12 100644 --- a/proto/rpki/packets.c +++ b/proto/rpki/packets.c @@ -628,7 +628,9 @@ rpki_check_receive_packet(struct rpki_cache *cache, const struct pdu_header *pdu } else if (!cache->last_update && (pdu->ver <= RPKI_MAX_VERSION) && - (pdu->ver < cache->version)) + (pdu->ver < cache->version) && + (pdu->ver >= cache->min_version) + ) { CACHE_TRACE(D_EVENTS, cache, "Downgrade session to %s from %u to %u version", rpki_get_cache_ident(cache), cache->version, pdu->ver); cache->version = pdu->ver; @@ -679,7 +681,8 @@ rpki_handle_error_pdu(struct rpki_cache *cache, const struct pdu_error *pdu) case UNSUPPORTED_PROTOCOL_VER: CACHE_TRACE(D_PACKETS, cache, "Client uses unsupported protocol version"); if (pdu->ver <= RPKI_MAX_VERSION && - pdu->ver < cache->version) + pdu->ver < cache->version && + pdu->ver >= cache->min_version) { CACHE_TRACE(D_EVENTS, cache, "Downgrading from protocol version %d to version %d", cache->version, pdu->ver); cache->version = pdu->ver; diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index e9d2a60aa..327c6215b 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -599,7 +599,8 @@ rpki_init_cache(struct rpki_proto *p, struct rpki_config *cf) cache->state = RPKI_CS_SHUTDOWN; cache->request_session_id = 1; - cache->version = RPKI_MAX_VERSION; + cache->version = cf->max_version; + cache->min_version = cf->min_version; cache->refresh_interval = cf->refresh_interval; cache->retry_interval = cf->retry_interval; @@ -704,6 +705,23 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st return NEED_RESTART; } + if (new->min_version > cache->version) + { + CACHE_TRACE(D_EVENTS, cache, "Protocol min version %u higher than current version %u", + new->min_version, cache->version); + return NEED_RESTART; + } + else + cache->min_version = new->min_version; + + if (new->max_version < cache->version) + { + CACHE_TRACE(D_EVENTS, cache, "Protocol max version %u lower than current version %u", + new->max_version, cache->version); + cache->version = new->max_version; + try_reset = 1; + } + if (old->tr_config.type != new->tr_config.type) { CACHE_TRACE(D_EVENTS, cache, "Transport type changed"); @@ -963,6 +981,9 @@ rpki_show_proto_info(struct proto *P) void rpki_check_config(struct rpki_config *cf) { + if (cf->min_version > cf->max_version) + cf_error("Impossible min/max version for RPKI: %u/%u", cf->min_version, cf->max_version); + /* Do not check templates at all */ if (cf->c.class == SYM_TEMPLATE) return; diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h index 307ec315a..1f5f978e2 100644 --- a/proto/rpki/rpki.h +++ b/proto/rpki/rpki.h @@ -61,6 +61,7 @@ struct rpki_cache { u8 request_session_id; /* 1: have to request new session id; 0: we have already received session id */ u32 serial_num; /* Serial number denotes the logical version of data from cache server */ u8 version; /* Protocol version */ + u8 min_version; /* Minimum allowed protocol version */ btime last_update; /* Last successful synchronization with cache server */ btime last_rx_prefix; /* Last received prefix PDU */ @@ -132,6 +133,8 @@ struct rpki_config { 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 */ + u8 min_version; /* Minimum version allowed */ + u8 max_version; /* Maximum version allowed (to start with) */ }; void rpki_check_config(struct rpki_config *cf);