]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Split `rpki cache` command into separate per SSH/TCP
authorDonatas Abraitis <donatas@opensourcerouting.org>
Thu, 16 May 2024 20:27:34 +0000 (23:27 +0300)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Tue, 21 May 2024 11:23:15 +0000 (14:23 +0300)
Current command (bundled two into one) is absolutely wrong.

When you configure TCP session with the source, the command thinks, that
it's a SSH session with a username.

It's much better to split this into two separate commands where it's much
easier to do the changes in the future (if more options comes in).

Yes, this is a breaking change, but there is no other proper way to overcome
this.

Bonus note how it looks, which also can lead to crashes (due to port 0x0):

```
(gdb) p *cache->tr_config.ssh_config
$11 = {host = 0x5555562f9cd0 "1.1.1.1", port = 0, bindaddr = 0x0,
  username = 0x55555629ad00 "",
  server_hostkey_path = 0x7ffff53667a0 <rpki_create_socket> "Uf\017\357\300H\211\345AWAVAUATSH\201", <incomplete sequence \354\230>, client_privkey_path = 0x0,
  data = 0x0, new_socket = 0x51, connect_timeout = 4143762592,
  password = 0x7ffff6fccca0 <main_arena+96> "\300\"0VUU"}
(gdb) p *cache->tr_config.tcp_config
$12 = {host = 0x5555562f9cd0 "1.1.1.1", port = 0x0, bindaddr = 0x0,
  data = 0x55555629ad00, new_socket = 0x7ffff53667a0 <rpki_create_socket>,
  connect_timeout = 0}
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
bgpd/bgp_rpki.c
doc/user/rpki.rst
tests/topotests/bgp_rpki_topo1/r2/bgpd.conf
tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py

index 67f59edb93077e1af9178e2447d8c70b784bdc04..08a7e1896ff7ae336e7a83604527cc6cbb7862c3 100644 (file)
@@ -1621,7 +1621,7 @@ static int bgp_rpki_write_vrf(struct vty *vty, struct vrf *vrf)
 #endif
                case TCP:
                        tcp_config = cache->tr_config.tcp_config;
-                       vty_out(vty, "%s rpki cache %s %s ", sep,
+                       vty_out(vty, "%s rpki cache tcp %s %s ", sep,
                                tcp_config->host, tcp_config->port);
                        if (tcp_config->bindaddr)
                                vty_out(vty, "source %s ",
@@ -1630,7 +1630,7 @@ static int bgp_rpki_write_vrf(struct vty *vty, struct vrf *vrf)
 #if defined(FOUND_SSH)
                case SSH:
                        ssh_config = cache->tr_config.ssh_config;
-                       vty_out(vty, "%s rpki cache %s %u %s %s %s ", sep,
+                       vty_out(vty, "%s rpki cache ssh %s %u %s %s %s ", sep,
                                ssh_config->host, ssh_config->port,
                                ssh_config->username,
                                ssh_config->client_privkey_path,
@@ -1918,6 +1918,9 @@ DEFUN (no_rpki_retry_interval,
        return CMD_SUCCESS;
 }
 
+#if CONFDATE > 20240916
+CPP_NOTICE("Remove rpki_cache_cmd")
+#endif
 DEFPY(rpki_cache, rpki_cache_cmd,
       "rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY]> [source <A.B.C.D>$bindaddr] preference (1-255)",
       RPKI_OUTPUT_STRING
@@ -1990,12 +1993,136 @@ DEFPY(rpki_cache, rpki_cache_cmd,
        return CMD_SUCCESS;
 }
 
+DEFPY(rpki_cache_tcp, rpki_cache_tcp_cmd,
+      "rpki cache tcp <A.B.C.D|WORD>$cache TCPPORT [source <A.B.C.D>$bindaddr] preference (1-255)",
+      RPKI_OUTPUT_STRING
+      "Install a cache server to current group\n"
+      "Use TCP\n"
+      "IP address of cache server\n"
+      "Hostname of cache server\n"
+      "TCP port number\n"
+      "Configure source IP address of RPKI connection\n"
+      "Define a Source IP Address\n"
+      "Preference of the cache server\n"
+      "Preference value\n")
+{
+       int return_value;
+       struct listnode *cache_node;
+       struct cache *current_cache;
+       struct rpki_vrf *rpki_vrf;
+       bool init;
+
+       if (vty->node == RPKI_VRF_NODE)
+               rpki_vrf = VTY_GET_CONTEXT_SUB(rpki_vrf);
+       else
+               rpki_vrf = VTY_GET_CONTEXT(rpki_vrf);
+
+       if (!rpki_vrf)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (!rpki_vrf || !rpki_vrf->cache_list)
+               return CMD_WARNING;
+
+       init = !!list_isempty(rpki_vrf->cache_list);
+
+       for (ALL_LIST_ELEMENTS_RO(rpki_vrf->cache_list, cache_node,
+                                 current_cache)) {
+               if (current_cache->preference == preference) {
+                       vty_out(vty,
+                               "Cache with preference %ld is already configured\n",
+                               preference);
+                       return CMD_WARNING;
+               }
+       }
+
+       return_value = add_tcp_cache(rpki_vrf, cache, tcpport, preference,
+                                    bindaddr_str);
+
+       if (return_value == ERROR) {
+               vty_out(vty, "Could not create new rpki cache\n");
+               return CMD_WARNING;
+       }
+
+       if (init)
+               start(rpki_vrf);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd,
+      "rpki cache ssh <A.B.C.D|WORD>$cache (1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY] [source <A.B.C.D>$bindaddr] preference (1-255)",
+      RPKI_OUTPUT_STRING
+      "Install a cache server to current group\n"
+      "Use SSH\n"
+      "IP address of cache server\n"
+      "Hostname of cache server\n"
+      "SSH port number\n"
+      "SSH user name\n"
+      "Path to own SSH private key\n"
+      "Path to Public key of cache server\n"
+      "Configure source IP address of RPKI connection\n"
+      "Define a Source IP Address\n"
+      "Preference of the cache server\n"
+      "Preference value\n")
+{
+       int return_value;
+       struct listnode *cache_node;
+       struct cache *current_cache;
+       struct rpki_vrf *rpki_vrf;
+       bool init;
+
+       if (vty->node == RPKI_VRF_NODE)
+               rpki_vrf = VTY_GET_CONTEXT_SUB(rpki_vrf);
+       else
+               rpki_vrf = VTY_GET_CONTEXT(rpki_vrf);
+
+       if (!rpki_vrf)
+               return CMD_WARNING_CONFIG_FAILED;
+
+       if (!rpki_vrf || !rpki_vrf->cache_list)
+               return CMD_WARNING;
+
+       init = !!list_isempty(rpki_vrf->cache_list);
+
+       for (ALL_LIST_ELEMENTS_RO(rpki_vrf->cache_list, cache_node,
+                                 current_cache)) {
+               if (current_cache->preference == preference) {
+                       vty_out(vty,
+                               "Cache with preference %ld is already configured\n",
+                               preference);
+                       return CMD_WARNING;
+               }
+       }
+
+#if defined(FOUND_SSH)
+       return_value = add_ssh_cache(rpki_vrf, cache, sshport, ssh_uname,
+                                    ssh_privkey, 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
+
+       if (return_value == ERROR) {
+               vty_out(vty, "Could not create new rpki cache\n");
+               return CMD_WARNING;
+       }
+
+       if (init)
+               start(rpki_vrf);
+
+       return CMD_SUCCESS;
+}
+
 DEFPY (no_rpki_cache,
        no_rpki_cache_cmd,
-       "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY]> [source <A.B.C.D>$bindaddr] preference (1-255)",
+       "no rpki cache <tcp|ssh> <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY]> [source <A.B.C.D>$bindaddr] preference (1-255)",
        NO_STR
        RPKI_OUTPUT_STRING
        "Install a cache server to current group\n"
+       "Use TCP\n"
+       "Use SSH\n"
        "IP address of cache server\n"
        "Hostname of cache server\n"
        "TCP port number\n"
@@ -2257,10 +2384,16 @@ DEFPY (show_rpki_cache_server,
                if (cache->type == TCP) {
                        if (!json) {
                                vty_out(vty,
-                                       "host: %s port: %s, preference: %hhu\n",
+                                       "host: %s port: %s, preference: %hhu, protocol: tcp",
                                        cache->tr_config.tcp_config->host,
                                        cache->tr_config.tcp_config->port,
                                        cache->preference);
+                               if (cache->tr_config.tcp_config->bindaddr)
+                                       vty_out(vty, ", source: %s\n",
+                                               cache->tr_config.tcp_config
+                                                       ->bindaddr);
+                               else
+                                       vty_out(vty, "\n");
                        } else {
                                json_server = json_object_new_object();
                                json_object_string_add(json_server, "mode",
@@ -2273,6 +2406,12 @@ DEFPY (show_rpki_cache_server,
                                        cache->tr_config.tcp_config->port);
                                json_object_int_add(json_server, "preference",
                                                    cache->preference);
+                               if (cache->tr_config.tcp_config->bindaddr)
+                                       json_object_string_add(json_server,
+                                                              "source",
+                                                              cache->tr_config
+                                                                      .tcp_config
+                                                                      ->bindaddr);
                                json_object_array_add(json_servers,
                                                      json_server);
                        }
@@ -2281,7 +2420,7 @@ DEFPY (show_rpki_cache_server,
                } else if (cache->type == SSH) {
                        if (!json) {
                                vty_out(vty,
-                                       "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s, preference: %hhu\n",
+                                       "host: %s, port: %d, username: %s, server_hostkey_path: %s, client_privkey_path: %s, preference: %hhu, protocol: ssh",
                                        cache->tr_config.ssh_config->host,
                                        cache->tr_config.ssh_config->port,
                                        cache->tr_config.ssh_config->username,
@@ -2290,6 +2429,12 @@ DEFPY (show_rpki_cache_server,
                                        cache->tr_config.ssh_config
                                                ->client_privkey_path,
                                        cache->preference);
+                               if (cache->tr_config.ssh_config->bindaddr)
+                                       vty_out(vty, ", source: %s\n",
+                                               cache->tr_config.ssh_config
+                                                       ->bindaddr);
+                               else
+                                       vty_out(vty, "\n");
                        } else {
                                json_server = json_object_new_object();
                                json_object_string_add(json_server, "mode",
@@ -2313,6 +2458,12 @@ DEFPY (show_rpki_cache_server,
                                                ->client_privkey_path);
                                json_object_int_add(json_server, "preference",
                                                    cache->preference);
+                               if (cache->tr_config.ssh_config->bindaddr)
+                                       json_object_string_add(json_server,
+                                                              "source",
+                                                              cache->tr_config
+                                                                      .ssh_config
+                                                                      ->bindaddr);
                                json_object_array_add(json_servers,
                                                      json_server);
                        }
@@ -2665,6 +2816,8 @@ static void install_cli_commands(void)
        install_element(RPKI_NODE, &no_rpki_retry_interval_cmd);
 
        /* Install rpki cache commands */
+       install_element(RPKI_NODE, &rpki_cache_tcp_cmd);
+       install_element(RPKI_NODE, &rpki_cache_ssh_cmd);
        install_element(RPKI_NODE, &rpki_cache_cmd);
        install_element(RPKI_NODE, &no_rpki_cache_cmd);
 
@@ -2687,6 +2840,8 @@ static void install_cli_commands(void)
        install_element(RPKI_VRF_NODE, &no_rpki_retry_interval_cmd);
 
        /* Install rpki cache commands */
+       install_element(RPKI_VRF_NODE, &rpki_cache_tcp_cmd);
+       install_element(RPKI_VRF_NODE, &rpki_cache_ssh_cmd);
        install_element(RPKI_VRF_NODE, &rpki_cache_cmd);
        install_element(RPKI_VRF_NODE, &no_rpki_cache_cmd);
 
index fe9e407ca9c0fbd5c2d9ee4dff8b5b089d356818..394327e2ff7710e5aa9db70926c5d72465f757e0 100644 (file)
@@ -131,19 +131,13 @@ The following commands are available for independent of a specific cache server.
 
    The default value is 600 seconds.
 
-.. clicmd:: rpki cache (A.B.C.D|WORD) PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [KNOWN_HOSTS_PATH] [source A.B.C.D] preference (1-255)
+.. clicmd:: rpki cache tcp HOST PORT [source A.B.C.D] preference (1-255)
 
+   Add a TCP cache server to the socket.
 
-   Add a cache server to the socket. By default, the connection between router
-   and cache server is based on plain TCP. Protecting the connection between
-   router and cache server by SSH is optional. Deleting a socket removes the
-   associated cache server and terminates the existing connection.
+.. clicmd:: rpki cache ssh HOST PORT SSH_USERNAME SSH_PRIVKEY_PATH [SERVER_PUBKEY] [source A.B.C.D] preference (1-255)
 
-   A.B.C.D|WORD
-      Address of the cache server.
-
-   PORT
-      Port number to connect to the cache server
+   Add a SSH cache server to the socket.
 
    SSH_USERNAME
       SSH username to establish an SSH connection to the cache server.
@@ -151,7 +145,7 @@ The following commands are available for independent of a specific cache server.
    SSH_PRIVKEY_PATH
       Local path that includes the private key file of the router.
 
-   KNOWN_HOSTS_PATH
+   SERVER_PUBKEY
       Local path that includes the known hosts file. The default value depends
       on the configuration of the operating system environment, usually
       :file:`~/.ssh/known_hosts`.
@@ -159,7 +153,6 @@ The following commands are available for independent of a specific cache server.
    source A.B.C.D
       Source address of the RPKI connection to access cache server.
 
-
 .. _validating-bgp-updates:
 
 Validating BGP Updates
@@ -267,9 +260,9 @@ RPKI Configuration Example
      rpki polling_period 1000
      rpki timeout 10
       ! SSH Example:
-      rpki cache example.com 22 rtr-ssh ./ssh_key/id_rsa preference 1
+      rpki cache ssh example.com 22 rtr-ssh ./ssh_key/id_rsa preference 1
       ! TCP Example:
-      rpki cache rpki-validator.realmv6.org 8282 preference 2
+      rpki cache tcp rpki-validator.realmv6.org 8282 preference 2
       exit
     !
     exit-vrf
@@ -278,9 +271,9 @@ RPKI Configuration Example
     rpki polling_period 1000
     rpki timeout 10
      ! SSH Example:
-     rpki cache example.com source 198.51.100.223 22 rtr-ssh ./ssh_key/id_rsa preference 1
+     rpki cache ssh example.com source 198.51.100.223 22 rtr-ssh ./ssh_key/id_rsa preference 1
      ! TCP Example:
-     rpki cache rpki-validator.realmv6.org 8282 preference 2
+     rpki cache tcp rpki-validator.realmv6.org 8282 preference 2
      exit
    !
    router bgp 65001
index 87d72149727560ae47936d264b9461f6a3dbd988..4de177dc25869895d59b8dac7a183c593d6d67b1 100644 (file)
@@ -21,5 +21,5 @@ router bgp 65002 vrf vrf10
 !
 rpki
  rpki retry_interval 5
- rpki cache 192.0.2.1 15432 preference 1
+ rpki cache tcp 192.0.2.1 15432 preference 1
 exit
index a12204f240a948e90149d055771bb14834cd991c..f52b28a0620c7fef959db9b8b8a70fdb11794bcb 100644 (file)
@@ -189,7 +189,7 @@ def test_show_bgp_rpki_prefixes_no_rpki_cache():
         """
 configure
 rpki
- no rpki cache 192.0.2.1 15432 preference 1
+ no rpki cache tcp 192.0.2.1 15432 preference 1
 exit
 """
     )
@@ -219,7 +219,7 @@ def test_show_bgp_rpki_prefixes_reconnect():
         """
 configure
 rpki
- rpki cache 192.0.2.1 15432 preference 1
+ rpki cache tcp 192.0.2.1 15432 preference 1
 exit
 """
     )
@@ -319,7 +319,7 @@ def test_show_bgp_rpki_prefixes_vrf():
 configure
 vrf vrf10
  rpki
-  rpki cache 192.0.2.3 15432 preference 1
+  rpki cache tcp 192.0.2.3 15432 preference 1
  exit
 exit
 """