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,7 +799,10 @@ 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);
tcp_config->bindaddr = NULL;
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,7 +837,10 @@ 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);
ssh_config->bindaddr = NULL;
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);
ssh_config->client_privkey_path =
@ -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,20 +1066,22 @@ 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)",
RPKI_OUTPUT_STRING
"Install a cache server to current group\n"
"IP address of cache server\n Hostname of cache server\n"
"TCP port number\n"
"SSH port number\n"
"SSH user name\n"
"Path to own SSH private key\n"
"Path to own SSH public key\n"
"Path to Public key of cache server\n"
"Preference of the cache server\n"
"Preference value\n")
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"
"Path to own SSH private key\n"
"Path to own SSH public key\n"
"Path to Public key of cache server\n"
"Preference of the cache server\n"
"Preference value\n")
{
int return_value;
struct listnode *cache_node;
@ -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,10 +243,11 @@ 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
neighbor 123.123.123.0 route-map rpki in
neighbor 123.123.123.0 route-map rpki in
exit-address-family
!
route-map rpki permit 10