name="rpki reload">. Or you can use a BIRD client command <cf>reload in
<m/bgp_protocol_name/</cf> for manual call of revalidation of all routes.
+<p>The same protocol, since version 2, also receives and maintains a set
+of ASPAs. You can then validate AS paths using function <cf/aspa_check()/
+in (import) filters.
+
<sect1>Supported transports
<p>
<itemize>
protocol rpki [<name>] {
roa4 { table <tab>; };
roa6 { table <tab>; };
+ aspa { table <tab>; };
remote <ip> | "<domain>" [port <num>];
port <num>;
local address <ip>;
remote public key "</path/to/known_host>";
user "<name>";
};
+ max version 2;
+ min version 2;
}
</code>
-<p>Alse note that you have to specify the ROA channel. If you want to import
+<p>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.
instead. This may be useful for implementing loose RPKI check for
blackholes. Default: disabled.
+ <tag>min version <m/num/</tag>
+ Minimal allowed version of the RTR protocol. BIRD will refuse to
+ downgrade a connection below this version and drop the session instead.
+ Default: 0
+
+ <tag>max version <m/num/</tag>
+ 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
+
<tag>transport tcp { <m/TCP transport options.../ }</tag> Transport over
TCP, it's the default transport. Cannot be combined with a SSH transport.
Default: TCP, no authentication.
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 <i> rpki_keep_interval
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); };
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:
}
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;
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;
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;
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");
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;
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 */
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);