diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-05-16 23:27:34 +0300 |
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2024-05-21 14:23:15 +0300 |
| commit | 043cff5286f63dd62b7aaf9f4a0d7deaef5659db (patch) | |
| tree | 6309552a5e61e14bac57d248eafc31f043646436 /bgpd/bgp_rpki.c | |
| parent | 03e3da09a8521ef5aad82aad1635515d69e46ae0 (diff) | |
bgpd: Split `rpki cache` command into separate per SSH/TCP
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>
Diffstat (limited to 'bgpd/bgp_rpki.c')
| -rw-r--r-- | bgpd/bgp_rpki.c | 165 |
1 files changed, 160 insertions, 5 deletions
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 67f59edb93..08a7e1896f 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -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); |
