3 * Copyright (C) 2013 Michael Mester (m.mester@fu-berlin.de), for FU Berlin
4 * Copyright (C) 2014-2017 Andreas Reuter (andreas.reuter@fu-berlin.de), for FU
6 * Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW
8 * Copyright (C) 2017 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW
11 * This file is part of FRRouting.
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23 * You should have received a copy of the GNU General Public License along
24 * with this program; see the file COPYING; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
40 #include "bgpd/bgpd.h"
41 #include "bgpd/bgp_table.h"
42 #include "bgp_advertise.h"
43 #include "bgpd/bgp_debug.h"
44 #include "bgpd/bgp_attr.h"
45 #include "bgpd/bgp_aspath.h"
46 #include "bgpd/bgp_route.h"
47 #include "rtrlib/rtrlib.h"
48 #include "rtrlib/rtr_mgr.h"
49 #include "rtrlib/lib/ip.h"
50 #include "rtrlib/transport/tcp/tcp_transport.h"
51 #if defined(FOUND_SSH)
52 #include "rtrlib/transport/ssh/ssh_transport.h"
58 #ifndef VTYSH_EXTRACT_PL
59 #include "bgpd/bgp_rpki_clippy.c"
62 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
63 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
66 #define RPKI_NOTFOUND 2
67 #define RPKI_INVALID 3
69 #define POLLING_PERIOD_DEFAULT 3600
70 #define EXPIRE_INTERVAL_DEFAULT 7200
71 #define RETRY_INTERVAL_DEFAULT 600
72 #define TIMEOUT_DEFAULT 600
73 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
75 #define RPKI_DEBUG(...) \
77 zlog_debug("RPKI: " __VA_ARGS__); \
80 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
83 enum { TCP
, SSH
} type
;
84 struct tr_socket
*tr_socket
;
86 struct tr_tcp_config
*tcp_config
;
87 struct tr_ssh_config
*ssh_config
;
89 struct rtr_socket
*rtr_socket
;
93 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
95 struct rpki_for_each_record_arg
{
97 unsigned int *prefix_amount
;
100 static int start(void);
101 static void stop(void);
102 static int reset(bool force
);
103 static struct rtr_mgr_group
*get_connected_group(void);
104 static void print_prefix_table(struct vty
*vty
);
105 static void install_cli_commands(void);
106 static int config_write(struct vty
*vty
);
107 static void overwrite_exit_commands(void);
108 static void free_cache(struct cache
*cache
);
109 static struct rtr_mgr_group
*get_groups(void);
110 #if defined(FOUND_SSH)
111 static int add_ssh_cache(const char *host
, const unsigned int port
,
112 const char *username
, const char *client_privkey_path
,
113 const char *client_pubkey_path
,
114 const char *server_pubkey_path
,
115 const uint8_t preference
);
117 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
118 static struct cache
*find_cache(const uint8_t preference
);
119 static int add_tcp_cache(const char *host
, const char *port
,
120 const uint8_t preference
);
121 static void print_record(const struct pfx_record
*record
, void *data
);
122 static int is_synchronized(void);
123 static int is_running(void);
124 static void route_match_free(void *rule
);
125 static route_map_result_t
route_match(void *rule
, struct prefix
*prefix
,
126 route_map_object_t type
, void *object
);
127 static void *route_match_compile(const char *arg
);
129 static struct rtr_mgr_config
*rtr_config
;
130 static struct list
*cache_list
;
131 static int rtr_is_running
;
132 static int rpki_debug
;
133 static unsigned int polling_period
;
134 static unsigned int expire_interval
;
135 static unsigned int retry_interval
;
136 static unsigned int timeout
;
137 static unsigned int initial_synchronisation_timeout
;
139 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
140 static struct route_map_rule_cmd route_match_rpki_cmd
= {
141 "rpki", route_match
, route_match_compile
, route_match_free
};
143 static void *malloc_wrapper(size_t size
)
145 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
148 static void *realloc_wrapper(void *ptr
, size_t size
)
150 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
153 static void free_wrapper(void *ptr
)
155 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
158 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
159 struct prefix
*prefix
);
161 static route_map_result_t
route_match(void *rule
, struct prefix
*prefix
,
162 route_map_object_t type
, void *object
)
164 int *rpki_status
= rule
;
165 struct bgp_info
*bgp_info
;
167 if (type
== RMAP_BGP
) {
170 if (rpki_validate_prefix(bgp_info
->peer
, bgp_info
->attr
, prefix
)
178 static void *route_match_compile(const char *arg
)
182 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
184 if (strcmp(arg
, "valid") == 0)
185 *rpki_status
= RPKI_VALID
;
186 else if (strcmp(arg
, "invalid") == 0)
187 *rpki_status
= RPKI_INVALID
;
189 *rpki_status
= RPKI_NOTFOUND
;
194 static void route_match_free(void *rule
)
196 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
199 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
201 struct rtr_socket
*rtr_socket
=
202 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
203 rtr_socket
->tr_socket
= tr_socket
;
207 static struct cache
*find_cache(const uint8_t preference
)
209 struct listnode
*cache_node
;
212 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
213 if (cache
->preference
== preference
)
219 static void print_record(const struct pfx_record
*record
, void *data
)
221 char ip
[INET6_ADDRSTRLEN
];
222 struct rpki_for_each_record_arg
*arg
= data
;
223 struct vty
*vty
= arg
->vty
;
225 (*arg
->prefix_amount
)++;
227 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
228 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
229 record
->max_len
, record
->asn
);
232 static struct rtr_mgr_group
*get_groups(void)
234 struct listnode
*cache_node
;
235 struct rtr_mgr_group
*rtr_mgr_groups
;
238 int group_count
= listcount(cache_list
);
240 if (group_count
== 0)
243 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
244 group_count
* sizeof(struct rtr_mgr_group
));
248 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
249 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
250 rtr_mgr_groups
[i
].sockets_len
= 1;
251 rtr_mgr_groups
[i
].preference
= cache
->preference
;
253 if (cache
->type
== TCP
)
254 tr_tcp_init(cache
->tr_config
.tcp_config
,
256 #if defined(FOUND_SSH)
258 tr_ssh_init(cache
->tr_config
.ssh_config
,
265 return rtr_mgr_groups
;
268 inline int is_synchronized(void)
270 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
273 inline int is_running(void)
275 return rtr_is_running
;
278 static int bgp_rpki_init(struct thread_master
*master
)
283 cache_list
= list_new();
284 cache_list
->del
= (void (*)(void *)) & free_cache
;
286 polling_period
= POLLING_PERIOD_DEFAULT
;
287 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
288 retry_interval
= RETRY_INTERVAL_DEFAULT
;
289 timeout
= TIMEOUT_DEFAULT
;
290 initial_synchronisation_timeout
=
291 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
292 install_cli_commands();
296 static int bgp_rpki_fini(void)
299 list_delete_and_null(&cache_list
);
304 static int bgp_rpki_module_init(void)
306 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
308 hook_register(frr_late_init
, bgp_rpki_init
);
309 hook_register(frr_early_fini
, &bgp_rpki_fini
);
314 static int start(void)
316 unsigned int waiting_time
= 0;
319 if (list_isempty(cache_list
)) {
321 "No caches were found in config. Prefix validation is off.");
324 RPKI_DEBUG("Init rtr_mgr.");
325 int groups_len
= listcount(cache_list
);
326 struct rtr_mgr_group
*groups
= get_groups();
328 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
329 expire_interval
, retry_interval
, NULL
, NULL
, NULL
,
331 if (ret
== RTR_ERROR
) {
332 RPKI_DEBUG("Init rtr_mgr failed.");
336 RPKI_DEBUG("Starting rtr_mgr.");
337 ret
= rtr_mgr_start(rtr_config
);
338 if (ret
== RTR_ERROR
) {
339 RPKI_DEBUG("Starting rtr_mgr failed.");
340 rtr_mgr_free(rtr_config
);
344 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
345 while (waiting_time
++ <= initial_synchronisation_timeout
) {
346 if (rtr_mgr_conf_in_sync(rtr_config
))
351 if (rtr_mgr_conf_in_sync(rtr_config
)) {
352 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
355 "Timeout expired! Proceeding without RPKI validation data.");
358 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
363 static void stop(void)
365 if (rtr_is_running
) {
366 rtr_mgr_stop(rtr_config
);
367 rtr_mgr_free(rtr_config
);
372 static int reset(bool force
)
374 if (rtr_is_running
&& !force
)
377 RPKI_DEBUG("Resetting RPKI Session");
382 static struct rtr_mgr_group
*get_connected_group(void)
384 if (list_isempty(cache_list
))
387 return rtr_mgr_get_first_group(rtr_config
);
390 static void print_prefix_table(struct vty
*vty
)
392 struct rpki_for_each_record_arg arg
;
394 unsigned int number_of_ipv4_prefixes
= 0;
395 unsigned int number_of_ipv6_prefixes
= 0;
396 struct rtr_mgr_group
*group
= get_connected_group();
403 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
405 vty_out(vty
, "RPKI/RTR prefix table\n");
406 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
408 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
409 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
411 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
412 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
414 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
415 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
418 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
419 struct prefix
*prefix
)
421 struct assegment
*as_segment
;
423 struct lrtr_ip_addr ip_addr_prefix
;
424 enum pfxv_state result
;
426 const char *prefix_string
;
428 if (!is_synchronized())
431 // No aspath means route comes from iBGP
432 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
434 as_number
= peer
->bgp
->as
;
436 as_segment
= attr
->aspath
->segments
;
437 // Find last AsSegment
438 while (as_segment
->next
)
439 as_segment
= as_segment
->next
;
441 if (as_segment
->type
== AS_SEQUENCE
) {
443 as_number
= as_segment
->as
[as_segment
->length
- 1];
444 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
445 || as_segment
->type
== AS_CONFED_SET
) {
447 as_number
= peer
->bgp
->as
;
449 // RFC says: "Take distinguished value NONE as asn"
450 // which means state is unknown
451 return RPKI_NOTFOUND
;
455 // Get the prefix in requested format
456 switch (prefix
->family
) {
458 ip_addr_prefix
.ver
= LRTR_IPV4
;
459 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
464 ip_addr_prefix
.ver
= LRTR_IPV6
;
465 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
466 ip_addr_prefix
.u
.addr6
.addr
);
468 #endif /* HAVE_IPV6 */
474 // Do the actual validation
475 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
476 prefix
->prefixlen
, &result
);
478 // Print Debug output
480 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
482 case BGP_PFXV_STATE_VALID
:
484 "Validating Prefix %s/%hhu from asn %u Result: VALID",
485 prefix_string
, prefix
->prefixlen
, as_number
);
487 case BGP_PFXV_STATE_NOT_FOUND
:
489 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
490 prefix_string
, prefix
->prefixlen
, as_number
);
491 return RPKI_NOTFOUND
;
492 case BGP_PFXV_STATE_INVALID
:
494 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
495 prefix_string
, prefix
->prefixlen
, as_number
);
499 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
500 prefix_string
, prefix
->prefixlen
, as_number
);
506 static int add_cache(struct cache
*cache
)
508 uint8_t preference
= cache
->preference
;
509 struct rtr_mgr_group group
;
511 group
.preference
= preference
;
512 group
.sockets_len
= 1;
513 group
.sockets
= &cache
->rtr_socket
;
515 listnode_add(cache_list
, cache
);
518 && rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
525 static int add_tcp_cache(const char *host
, const char *port
,
526 const uint8_t preference
)
528 struct rtr_socket
*rtr_socket
;
529 struct tr_tcp_config
*tcp_config
=
530 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
531 struct tr_socket
*tr_socket
=
532 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
533 struct cache
*cache
=
534 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
536 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
537 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
538 tcp_config
->bindaddr
= NULL
;
540 rtr_socket
= create_rtr_socket(tr_socket
);
543 cache
->tr_socket
= tr_socket
;
544 cache
->tr_config
.tcp_config
= tcp_config
;
545 cache
->rtr_socket
= rtr_socket
;
546 cache
->preference
= preference
;
548 return add_cache(cache
);
551 #if defined(FOUND_SSH)
552 static int add_ssh_cache(const char *host
, const unsigned int port
,
553 const char *username
, const char *client_privkey_path
,
554 const char *client_pubkey_path
,
555 const char *server_pubkey_path
,
556 const uint8_t preference
)
558 struct tr_ssh_config
*ssh_config
=
559 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
560 struct cache
*cache
=
561 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
562 struct tr_socket
*tr_socket
=
563 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
564 struct rtr_socket
*rtr_socket
;
566 ssh_config
->port
= port
;
567 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
568 ssh_config
->bindaddr
= NULL
;
570 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
571 ssh_config
->client_privkey_path
=
572 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
573 ssh_config
->server_hostkey_path
=
574 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
576 rtr_socket
= create_rtr_socket(tr_socket
);
579 cache
->tr_socket
= tr_socket
;
580 cache
->tr_config
.ssh_config
= ssh_config
;
581 cache
->rtr_socket
= rtr_socket
;
582 cache
->preference
= preference
;
584 return add_cache(cache
);
588 static void free_cache(struct cache
*cache
)
590 if (cache
->type
== TCP
) {
591 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
592 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
593 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
595 #if defined(FOUND_SSH)
597 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
598 XFREE(MTYPE_BGP_RPKI_CACHE
,
599 cache
->tr_config
.ssh_config
->username
);
600 XFREE(MTYPE_BGP_RPKI_CACHE
,
601 cache
->tr_config
.ssh_config
->client_privkey_path
);
602 XFREE(MTYPE_BGP_RPKI_CACHE
,
603 cache
->tr_config
.ssh_config
->server_hostkey_path
);
604 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
607 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
608 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
609 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
612 static int config_write(struct vty
*vty
)
614 struct listnode
*cache_node
;
617 if (listcount(cache_list
)) {
619 vty_out(vty
, "debug rpki\n");
622 vty_out(vty
, "rpki\n");
623 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
624 vty_out(vty
, " rpki timeout %d\n", timeout
);
625 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
626 initial_synchronisation_timeout
);
627 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
628 switch (cache
->type
) {
629 struct tr_tcp_config
*tcp_config
;
630 #if defined(FOUND_SSH)
631 struct tr_ssh_config
*ssh_config
;
634 tcp_config
= cache
->tr_config
.tcp_config
;
635 vty_out(vty
, " rpki cache %s %s ",
636 tcp_config
->host
, tcp_config
->port
);
638 #if defined(FOUND_SSH)
640 ssh_config
= cache
->tr_config
.ssh_config
;
641 vty_out(vty
, " rpki cache %s %u %s %s %s ",
642 ssh_config
->host
, ssh_config
->port
,
643 ssh_config
->username
,
644 ssh_config
->client_privkey_path
,
645 ssh_config
->server_hostkey_path
!= NULL
647 ->server_hostkey_path
655 vty_out(vty
, "preference %hhu\n", cache
->preference
);
657 vty_out(vty
, " exit\n");
667 "Enable rpki and enter rpki configuration mode\n")
669 vty
->node
= RPKI_NODE
;
673 DEFUN (bgp_rpki_start
,
677 "start rpki support\n")
679 if (listcount(cache_list
) == 0)
681 "Could not start rpki because no caches are configured\n");
684 if (start() == ERROR
) {
685 RPKI_DEBUG("RPKI failed to start");
692 DEFUN (bgp_rpki_stop
,
696 "start rpki support\n")
704 DEFPY (rpki_polling_period
,
705 rpki_polling_period_cmd
,
706 "rpki polling_period (1-86400)$pp",
708 "Set polling period\n"
709 "Polling period value\n")
715 DEFUN (no_rpki_polling_period
,
716 no_rpki_polling_period_cmd
,
717 "no rpki polling_period",
720 "Set polling period back to default\n")
722 polling_period
= POLLING_PERIOD_DEFAULT
;
726 DEFPY (rpki_expire_interval
,
727 rpki_expire_interval_cmd
,
728 "rpki expire_interval (600-172800)$tmp",
730 "Set expire interval\n"
731 "Expire interval value\n")
733 if ((unsigned int)tmp
>= polling_period
) {
734 expire_interval
= tmp
;
738 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
739 return CMD_WARNING_CONFIG_FAILED
;
742 DEFUN (no_rpki_expire_interval
,
743 no_rpki_expire_interval_cmd
,
744 "no rpki expire_interval",
747 "Set expire interval back to default\n")
749 expire_interval
= polling_period
* 2;
753 DEFPY (rpki_retry_interval
,
754 rpki_retry_interval_cmd
,
755 "rpki retry_interval (1-7200)$tmp",
757 "Set retry interval\n"
758 "retry interval value\n")
760 retry_interval
= tmp
;
764 DEFUN (no_rpki_retry_interval
,
765 no_rpki_retry_interval_cmd
,
766 "no rpki retry_interval",
769 "Set retry interval back to default\n")
771 retry_interval
= RETRY_INTERVAL_DEFAULT
;
777 "rpki timeout (1-4294967295)$to_arg",
786 DEFUN (no_rpki_timeout
,
791 "Set timeout back to default\n")
793 timeout
= TIMEOUT_DEFAULT
;
797 DEFPY (rpki_synchronisation_timeout
,
798 rpki_synchronisation_timeout_cmd
,
799 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
801 "Set a timeout for the initial synchronisation of prefix validation data\n"
804 initial_synchronisation_timeout
= ito_arg
;
808 DEFUN (no_rpki_synchronisation_timeout
,
809 no_rpki_synchronisation_timeout_cmd
,
810 "no rpki initial-synchronisation-timeout",
813 "Set the initial synchronisation timeout back to default (30 sec.)\n")
815 initial_synchronisation_timeout
=
816 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
822 "rpki cache <A.B.C.D|WORD>"
823 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
824 "preference (1-255)",
826 "Install a cache server to current group\n"
827 "IP address of cache server\n Hostname of cache server\n"
831 "Path to own SSH private key\n"
832 "Path to own SSH public key\n"
833 "Path to Public key of cache server\n"
834 "Preference of the cache server\n"
835 "Preference value\n")
837 int return_value
= SUCCESS
;
839 // use ssh connection
841 #if defined(FOUND_SSH)
843 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
844 ssh_pubkey
, server_pubkey
, preference
);
847 "ssh sockets are not supported. "
848 "Please recompile rtrlib and frr with ssh support. "
849 "If you want to use it");
851 } else { // use tcp connection
852 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
855 if (return_value
== ERROR
) {
856 vty_out(vty
, "Could not create new rpki cache\n");
863 DEFPY (no_rpki_cache
,
865 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
868 "Remove a cache server\n"
869 "IP address of cache server\n Hostname of cache server\n"
872 "Preference of the cache server\n"
873 "Preference value\n")
875 struct cache
*cache_p
= find_cache(preference
);
878 vty_out(vty
, "Could not find cache %ld\n", preference
);
882 if (rtr_is_running
) {
883 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
884 vty_out(vty
, "Could not remove cache %ld", preference
);
885 if (listcount(cache_list
) == 1)
886 vty_out(vty
, " because it is the last cache");
893 listnode_delete(cache_list
, cache_p
);
899 DEFUN (show_rpki_prefix_table
,
900 show_rpki_prefix_table_cmd
,
901 "show rpki prefix-table",
904 "Show validated prefixes which were received from RPKI Cache\n")
906 struct listnode
*cache_node
;
909 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
910 vty_out(vty
, "host: %s port: %s\n",
911 cache
->tr_config
.tcp_config
->host
,
912 cache
->tr_config
.tcp_config
->port
);
914 if (is_synchronized())
915 print_prefix_table(vty
);
917 vty_out(vty
, "No connection to RPKI cache server.\n");
922 DEFUN (show_rpki_cache_server
,
923 show_rpki_cache_server_cmd
,
924 "show rpki cache-server",
927 "SHOW configured cache server\n")
929 struct listnode
*cache_node
;
932 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
933 vty_out(vty
, "host: %s port: %s\n",
934 cache
->tr_config
.tcp_config
->host
,
935 cache
->tr_config
.tcp_config
->port
);
941 DEFUN (show_rpki_cache_connection
,
942 show_rpki_cache_connection_cmd
,
943 "show rpki cache-connection",
946 "Show to which RPKI Cache Servers we have a connection\n")
948 if (is_synchronized()) {
949 struct listnode
*cache_node
;
951 struct rtr_mgr_group
*group
= get_connected_group();
954 vty_out(vty
, "Cannot find a connected group.\n");
957 vty_out(vty
, "Connected to group %d\n", group
->preference
);
958 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
959 if (cache
->preference
== group
->preference
) {
960 struct tr_tcp_config
*tcp_config
;
961 #if defined(FOUND_SSH)
962 struct tr_ssh_config
*ssh_config
;
965 switch (cache
->type
) {
968 cache
->tr_config
.tcp_config
;
970 "rpki tcp cache %s %s pref %hhu\n",
976 #if defined(FOUND_SSH)
979 cache
->tr_config
.ssh_config
;
981 "rpki ssh cache %s %u pref %hhu\n",
994 vty_out(vty
, "No connection to RPKI cache server.\n");
1000 DEFUN_NOSH (rpki_exit
,
1003 "Exit rpki configuration and restart rpki session\n")
1005 int ret
= reset(false);
1007 vty
->node
= CONFIG_NODE
;
1008 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1011 DEFUN_NOSH (rpki_quit
,
1014 "Exit rpki configuration mode\n")
1016 return rpki_exit(self
, vty
, argc
, argv
);
1019 DEFUN_NOSH (rpki_end
,
1022 "End rpki configuration, restart rpki session and change to enable mode.\n")
1024 int ret
= reset(false);
1026 vty_config_unlock(vty
);
1027 vty
->node
= ENABLE_NODE
;
1028 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1037 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1044 "Enable debugging for rpki\n")
1050 DEFUN (no_debug_rpki
,
1055 "Disable debugging for rpki\n")
1063 "match rpki <valid|invalid|notfound>",
1068 "Prefix not found\n")
1070 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1073 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1076 case RMAP_RULE_MISSING
:
1077 vty_out(vty
, "%% BGP Can't find rule.\n");
1078 return CMD_WARNING_CONFIG_FAILED
;
1079 case RMAP_COMPILE_ERROR
:
1080 vty_out(vty
, "%% BGP Argument is malformed.\n");
1081 return CMD_WARNING_CONFIG_FAILED
;
1087 DEFUN (no_match_rpki
,
1089 "no match rpki <valid|invalid|notfound>",
1095 "Prefix not found\n")
1097 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1100 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1103 case RMAP_RULE_MISSING
:
1104 vty_out(vty
, "%% BGP Can't find rule.\n");
1106 case RMAP_COMPILE_ERROR
:
1107 vty_out(vty
, "%% BGP Argument is malformed.\n");
1110 return CMD_WARNING_CONFIG_FAILED
;
1116 static void overwrite_exit_commands(void)
1119 vector cmd_vector
= rpki_node
.cmd_vector
;
1121 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1122 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1124 if (strcmp(cmd
->string
, "exit") == 0
1125 || strcmp(cmd
->string
, "quit") == 0
1126 || strcmp(cmd
->string
, "end") == 0) {
1127 uninstall_element(RPKI_NODE
, cmd
);
1131 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1132 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1133 install_element(RPKI_NODE
, &rpki_end_cmd
);
1136 static void install_cli_commands(void)
1138 // TODO: make config write work
1139 install_node(&rpki_node
, &config_write
);
1140 install_default(RPKI_NODE
);
1141 overwrite_exit_commands();
1142 install_element(CONFIG_NODE
, &rpki_cmd
);
1143 install_element(VIEW_NODE
, &rpki_cmd
);
1145 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1146 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1148 /* Install rpki reset command */
1149 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1151 /* Install rpki polling period commands */
1152 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1153 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1155 /* Install rpki expire interval commands */
1156 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1157 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1159 /* Install rpki retry interval commands */
1160 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1161 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1163 /* Install rpki timeout commands */
1164 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1165 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1167 /* Install rpki synchronisation timeout commands */
1168 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1169 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1171 /* Install rpki cache commands */
1172 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1173 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1175 /* Install show commands */
1176 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1177 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1178 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1180 /* Install debug commands */
1181 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1182 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1183 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1184 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1186 /* Install route match */
1187 route_map_install_match(&route_match_rpki_cmd
);
1188 install_element(RMAP_NODE
, &match_rpki_cmd
);
1189 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1192 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1193 .description
= "Enable RPKI support for FRR.",
1194 .init
= bgp_rpki_module_init
)