bgpd: add rpki source address configuration

Add the ability to configure the source address of rpki
connection. Proposed vty command is to add below parameter:

rpki cache <address> source <bindaddr> <port> preference <pref>
rpki cache <address> source <bindaddr> <port> <usernamessh> ...

This works for both tcp and ssh connections. In case the source
address is not available yet, the rpki retry interval will retry
in a defined amount of time.

Rtrlib library is the library in charge of the binding of the
tcp/ssh connection, and applies the getaddrinfo() and bind()
operations to the passed parameter bindaddr to the respective
tcp_config/ssh_config structures.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2021-09-02 17:12:06 +02:00
parent 3e324ff419
commit 7253a7bcd8
2 changed files with 56 additions and 31 deletions

View File

@ -111,12 +111,12 @@ static int add_ssh_cache(const char *host, const unsigned int port,
const char *username, const char *client_privkey_path,
const char *client_pubkey_path,
const char *server_pubkey_path,
const uint8_t preference);
const uint8_t preference, const char *bindaddr);
#endif
static struct rtr_socket *create_rtr_socket(struct tr_socket *tr_socket);
static struct cache *find_cache(const uint8_t preference);
static int add_tcp_cache(const char *host, const char *port,
const uint8_t preference);
const uint8_t preference, const char *bindaddr);
static void print_record(const struct pfx_record *record, struct vty *vty);
static int is_synchronized(void);
static int is_running(void);
@ -787,7 +787,7 @@ static int add_cache(struct cache *cache)
}
static int add_tcp_cache(const char *host, const char *port,
const uint8_t preference)
const uint8_t preference, const char *bindaddr)
{
struct rtr_socket *rtr_socket;
struct tr_tcp_config *tcp_config =
@ -799,6 +799,9 @@ static int add_tcp_cache(const char *host, const char *port,
tcp_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
tcp_config->port = XSTRDUP(MTYPE_BGP_RPKI_CACHE, port);
if (bindaddr)
tcp_config->bindaddr = XSTRDUP(MTYPE_BGP_RPKI_CACHE, bindaddr);
else
tcp_config->bindaddr = NULL;
rtr_socket = create_rtr_socket(tr_socket);
@ -822,7 +825,7 @@ static int add_ssh_cache(const char *host, const unsigned int port,
const char *username, const char *client_privkey_path,
const char *client_pubkey_path,
const char *server_pubkey_path,
const uint8_t preference)
const uint8_t preference, const char *bindaddr)
{
struct tr_ssh_config *ssh_config =
XCALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_ssh_config));
@ -834,6 +837,9 @@ static int add_ssh_cache(const char *host, const unsigned int port,
ssh_config->port = port;
ssh_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
if (bindaddr)
ssh_config->bindaddr = XSTRDUP(MTYPE_BGP_RPKI_CACHE, bindaddr);
else
ssh_config->bindaddr = NULL;
ssh_config->username = XSTRDUP(MTYPE_BGP_RPKI_CACHE, username);
@ -864,6 +870,9 @@ static void free_cache(struct cache *cache)
if (cache->type == TCP) {
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->host);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->port);
if (cache->tr_config.tcp_config->bindaddr)
XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.tcp_config->bindaddr);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config);
}
#if defined(FOUND_SSH)
@ -875,6 +884,9 @@ static void free_cache(struct cache *cache)
cache->tr_config.ssh_config->client_privkey_path);
XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.ssh_config->server_hostkey_path);
if (cache->tr_config.ssh_config->bindaddr)
XFREE(MTYPE_BGP_RPKI_CACHE,
cache->tr_config.ssh_config->bindaddr);
XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config);
}
#endif
@ -911,15 +923,21 @@ static int config_write(struct vty *vty)
#endif
case TCP:
tcp_config = cache->tr_config.tcp_config;
vty_out(vty, " rpki cache %s %s ", tcp_config->host,
vty_out(vty, " rpki cache %s%s%s %s ", tcp_config->host,
tcp_config->bindaddr ? " source " : "",
tcp_config->bindaddr ? tcp_config->bindaddr
: "",
tcp_config->port);
break;
#if defined(FOUND_SSH)
case SSH:
ssh_config = cache->tr_config.ssh_config;
vty_out(vty, " rpki cache %s %u %s %s %s ",
ssh_config->host, ssh_config->port,
ssh_config->username,
vty_out(vty, " rpki cache %s%s%s %u %s %s %s ",
ssh_config->host,
ssh_config->bindaddr ? "source " : "",
ssh_config->bindaddr ? ssh_config->bindaddr
: "",
ssh_config->port, ssh_config->username,
ssh_config->client_privkey_path,
ssh_config->server_hostkey_path != NULL
? ssh_config->server_hostkey_path
@ -1048,12 +1066,14 @@ DEFUN (no_rpki_retry_interval,
return CMD_SUCCESS;
}
DEFPY (rpki_cache,
rpki_cache_cmd,
"rpki cache <A.B.C.D|WORD><TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> preference (1-255)",
DEFPY(rpki_cache, rpki_cache_cmd,
"rpki cache <A.B.C.D|WORD> [source <A.B.C.D>$bindaddr] "
"<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> preference (1-255)",
RPKI_OUTPUT_STRING
"Install a cache server to current group\n"
"IP address of cache server\n Hostname of cache server\n"
"Configure source IP address of RPKI connection\n"
"Define a Source IP Address\n"
"TCP port number\n"
"SSH port number\n"
"SSH user name\n"
@ -1080,16 +1100,17 @@ DEFPY (rpki_cache,
// use ssh connection
if (ssh_uname) {
#if defined(FOUND_SSH)
return_value =
add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey,
ssh_pubkey, server_pubkey, preference);
return_value = add_ssh_cache(
cache, sshport, ssh_uname, ssh_privkey, ssh_pubkey,
server_pubkey, preference, bindaddr_str);
#else
return_value = SUCCESS;
vty_out(vty,
"ssh sockets are not supported. Please recompile rtrlib and frr with ssh support. If you want to use it\n");
#endif
} else { // use tcp connection
return_value = add_tcp_cache(cache, tcpport, preference);
return_value =
add_tcp_cache(cache, tcpport, preference, bindaddr_str);
}
if (return_value == ERROR) {

View File

@ -109,7 +109,7 @@ The following commands are independent of a specific cache server.
The following commands configure one or multiple cache servers.
.. clicmd:: rpki cache (A.B.C.D|WORD) PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [SSH_PUBKEY_PATH] [KNOWN_HOSTS_PATH] PREFERENCE
.. clicmd:: rpki cache (A.B.C.D|WORD) [source A.B.C.D] PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [SSH_PUBKEY_PATH] [KNOWN_HOSTS_PATH] PREFERENCE
Add a cache server to the socket. By default, the connection between router
@ -120,6 +120,9 @@ The following commands are independent of a specific cache server.
A.B.C.D|WORD
Address of the cache server.
source A.B.C.D
Source address of the RPKI connection to access cache server.
PORT
Port number to connect to the cache server
@ -230,7 +233,7 @@ RPKI Configuration Example
rpki polling_period 1000
rpki timeout 10
! SSH Example:
rpki cache example.com 22 rtr-ssh ./ssh_key/id_rsa ./ssh_key/id_rsa.pub preference 1
rpki cache example.com source 141.22.28.223 22 rtr-ssh ./ssh_key/id_rsa ./ssh_key/id_rsa.pub preference 1
! TCP Example:
rpki cache rpki-validator.realmv6.org 8282 preference 2
exit
@ -240,6 +243,7 @@ RPKI Configuration Example
network 192.168.0.0/16
neighbor 123.123.123.0 remote-as 60002
neighbor 123.123.123.0 route-map rpki in
neighbor 123.123.123.0 update-source 141.22.28.223
!
address-family ipv6
neighbor 123.123.123.0 activate