From 7253a7bcd82e36e5be9447471b97b7686716df5e Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 2 Sep 2021 17:12:06 +0200 Subject: [PATCH] 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
source preference rpki cache
source ... 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 --- bgpd/bgp_rpki.c | 77 ++++++++++++++++++++++++++++++----------------- doc/user/rpki.rst | 10 ++++-- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 286612da15..2800d4fb92 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -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 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 [source $bindaddr] " + " 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) { diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index d496d437d3..8d836bfc4b 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -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 -- 2.39.5