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
28 /* If rtrlib compiled with ssh support, don`t fail build */
29 #define LIBSSH_LEGACY_0_4
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgp_advertise.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_attr.h"
48 #include "bgpd/bgp_aspath.h"
49 #include "bgpd/bgp_route.h"
50 #include "rtrlib/rtrlib.h"
51 #include "rtrlib/rtr_mgr.h"
52 #include "rtrlib/lib/ip.h"
53 #include "rtrlib/transport/tcp/tcp_transport.h"
54 #if defined(FOUND_SSH)
55 #include "rtrlib/transport/ssh/ssh_transport.h"
61 #ifndef VTYSH_EXTRACT_PL
62 #include "bgpd/bgp_rpki_clippy.c"
65 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
66 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
69 #define RPKI_NOTFOUND 2
70 #define RPKI_INVALID 3
72 #define POLLING_PERIOD_DEFAULT 3600
73 #define EXPIRE_INTERVAL_DEFAULT 7200
74 #define RETRY_INTERVAL_DEFAULT 600
75 #define TIMEOUT_DEFAULT 600
76 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
78 #define RPKI_DEBUG(...) \
80 zlog_debug("RPKI: " __VA_ARGS__); \
83 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
86 enum { TCP
, SSH
} type
;
87 struct tr_socket
*tr_socket
;
89 struct tr_tcp_config
*tcp_config
;
90 struct tr_ssh_config
*ssh_config
;
92 struct rtr_socket
*rtr_socket
;
96 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
98 struct rpki_for_each_record_arg
{
100 unsigned int *prefix_amount
;
103 static int start(void);
104 static void stop(void);
105 static int reset(bool force
);
106 static struct rtr_mgr_group
*get_connected_group(void);
107 static void print_prefix_table(struct vty
*vty
);
108 static void install_cli_commands(void);
109 static int config_write(struct vty
*vty
);
110 static void overwrite_exit_commands(void);
111 static void free_cache(struct cache
*cache
);
112 static struct rtr_mgr_group
*get_groups(void);
113 #if defined(FOUND_SSH)
114 static int add_ssh_cache(const char *host
, const unsigned int port
,
115 const char *username
, const char *client_privkey_path
,
116 const char *client_pubkey_path
,
117 const char *server_pubkey_path
,
118 const uint8_t preference
);
120 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
121 static struct cache
*find_cache(const uint8_t preference
);
122 static int add_tcp_cache(const char *host
, const char *port
,
123 const uint8_t preference
);
124 static void print_record(const struct pfx_record
*record
, void *data
);
125 static int is_synchronized(void);
126 static int is_running(void);
127 static void route_match_free(void *rule
);
128 static route_map_result_t
route_match(void *rule
, struct prefix
*prefix
,
129 route_map_object_t type
, void *object
);
130 static void *route_match_compile(const char *arg
);
132 static struct rtr_mgr_config
*rtr_config
;
133 static struct list
*cache_list
;
134 static int rtr_is_running
;
135 static int rpki_debug
;
136 static unsigned int polling_period
;
137 static unsigned int expire_interval
;
138 static unsigned int retry_interval
;
139 static unsigned int timeout
;
140 static unsigned int initial_synchronisation_timeout
;
142 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
143 static struct route_map_rule_cmd route_match_rpki_cmd
= {
144 "rpki", route_match
, route_match_compile
, route_match_free
};
146 static void *malloc_wrapper(size_t size
)
148 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
151 static void *realloc_wrapper(void *ptr
, size_t size
)
153 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
156 static void free_wrapper(void *ptr
)
158 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
161 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
162 struct prefix
*prefix
);
164 static route_map_result_t
route_match(void *rule
, struct prefix
*prefix
,
165 route_map_object_t type
, void *object
)
167 int *rpki_status
= rule
;
168 struct bgp_info
*bgp_info
;
170 if (type
== RMAP_BGP
) {
173 if (rpki_validate_prefix(bgp_info
->peer
, bgp_info
->attr
, prefix
)
181 static void *route_match_compile(const char *arg
)
185 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
187 if (strcmp(arg
, "valid") == 0)
188 *rpki_status
= RPKI_VALID
;
189 else if (strcmp(arg
, "invalid") == 0)
190 *rpki_status
= RPKI_INVALID
;
192 *rpki_status
= RPKI_NOTFOUND
;
197 static void route_match_free(void *rule
)
199 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
202 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
204 struct rtr_socket
*rtr_socket
=
205 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
206 rtr_socket
->tr_socket
= tr_socket
;
210 static struct cache
*find_cache(const uint8_t preference
)
212 struct listnode
*cache_node
;
215 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
216 if (cache
->preference
== preference
)
222 static void print_record(const struct pfx_record
*record
, void *data
)
224 char ip
[INET6_ADDRSTRLEN
];
225 struct rpki_for_each_record_arg
*arg
= data
;
226 struct vty
*vty
= arg
->vty
;
228 (*arg
->prefix_amount
)++;
230 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
231 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
232 record
->max_len
, record
->asn
);
235 static struct rtr_mgr_group
*get_groups(void)
237 struct listnode
*cache_node
;
238 struct rtr_mgr_group
*rtr_mgr_groups
;
241 int group_count
= listcount(cache_list
);
243 if (group_count
== 0)
246 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
247 group_count
* sizeof(struct rtr_mgr_group
));
251 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
252 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
253 rtr_mgr_groups
[i
].sockets_len
= 1;
254 rtr_mgr_groups
[i
].preference
= cache
->preference
;
256 if (cache
->type
== TCP
)
257 tr_tcp_init(cache
->tr_config
.tcp_config
,
259 #if defined(FOUND_SSH)
261 tr_ssh_init(cache
->tr_config
.ssh_config
,
268 return rtr_mgr_groups
;
271 inline int is_synchronized(void)
273 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
276 inline int is_running(void)
278 return rtr_is_running
;
281 static int bgp_rpki_init(struct thread_master
*master
)
286 cache_list
= list_new();
287 cache_list
->del
= (void (*)(void *)) & free_cache
;
289 polling_period
= POLLING_PERIOD_DEFAULT
;
290 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
291 retry_interval
= RETRY_INTERVAL_DEFAULT
;
292 timeout
= TIMEOUT_DEFAULT
;
293 initial_synchronisation_timeout
=
294 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
295 install_cli_commands();
299 static int bgp_rpki_fini(void)
302 list_delete_and_null(&cache_list
);
307 static int bgp_rpki_module_init(void)
309 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
311 hook_register(frr_late_init
, bgp_rpki_init
);
312 hook_register(frr_early_fini
, &bgp_rpki_fini
);
317 static int start(void)
319 unsigned int waiting_time
= 0;
322 if (list_isempty(cache_list
)) {
324 "No caches were found in config. Prefix validation is off.");
327 RPKI_DEBUG("Init rtr_mgr.");
328 int groups_len
= listcount(cache_list
);
329 struct rtr_mgr_group
*groups
= get_groups();
331 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
332 expire_interval
, retry_interval
, NULL
, NULL
, NULL
,
334 if (ret
== RTR_ERROR
) {
335 RPKI_DEBUG("Init rtr_mgr failed.");
339 RPKI_DEBUG("Starting rtr_mgr.");
340 ret
= rtr_mgr_start(rtr_config
);
341 if (ret
== RTR_ERROR
) {
342 RPKI_DEBUG("Starting rtr_mgr failed.");
343 rtr_mgr_free(rtr_config
);
347 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
348 while (waiting_time
++ <= initial_synchronisation_timeout
) {
349 if (rtr_mgr_conf_in_sync(rtr_config
))
354 if (rtr_mgr_conf_in_sync(rtr_config
)) {
355 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
358 "Timeout expired! Proceeding without RPKI validation data.");
361 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
366 static void stop(void)
368 if (rtr_is_running
) {
369 rtr_mgr_stop(rtr_config
);
370 rtr_mgr_free(rtr_config
);
375 static int reset(bool force
)
377 if (rtr_is_running
&& !force
)
380 RPKI_DEBUG("Resetting RPKI Session");
385 static struct rtr_mgr_group
*get_connected_group(void)
387 if (!cache_list
|| list_isempty(cache_list
))
390 return rtr_mgr_get_first_group(rtr_config
);
393 static void print_prefix_table(struct vty
*vty
)
395 struct rpki_for_each_record_arg arg
;
397 unsigned int number_of_ipv4_prefixes
= 0;
398 unsigned int number_of_ipv6_prefixes
= 0;
399 struct rtr_mgr_group
*group
= get_connected_group();
406 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
408 vty_out(vty
, "RPKI/RTR prefix table\n");
409 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
411 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
412 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
414 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
415 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
417 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
418 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
421 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
422 struct prefix
*prefix
)
424 struct assegment
*as_segment
;
426 struct lrtr_ip_addr ip_addr_prefix
;
427 enum pfxv_state result
;
429 const char *prefix_string
;
431 if (!is_synchronized())
434 // No aspath means route comes from iBGP
435 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
437 as_number
= peer
->bgp
->as
;
439 as_segment
= attr
->aspath
->segments
;
440 // Find last AsSegment
441 while (as_segment
->next
)
442 as_segment
= as_segment
->next
;
444 if (as_segment
->type
== AS_SEQUENCE
) {
446 as_number
= as_segment
->as
[as_segment
->length
- 1];
447 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
448 || as_segment
->type
== AS_CONFED_SET
) {
450 as_number
= peer
->bgp
->as
;
452 // RFC says: "Take distinguished value NONE as asn"
453 // which means state is unknown
454 return RPKI_NOTFOUND
;
458 // Get the prefix in requested format
459 switch (prefix
->family
) {
461 ip_addr_prefix
.ver
= LRTR_IPV4
;
462 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
467 ip_addr_prefix
.ver
= LRTR_IPV6
;
468 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
469 ip_addr_prefix
.u
.addr6
.addr
);
471 #endif /* HAVE_IPV6 */
477 // Do the actual validation
478 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
479 prefix
->prefixlen
, &result
);
481 // Print Debug output
483 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
485 case BGP_PFXV_STATE_VALID
:
487 "Validating Prefix %s/%hhu from asn %u Result: VALID",
488 prefix_string
, prefix
->prefixlen
, as_number
);
490 case BGP_PFXV_STATE_NOT_FOUND
:
492 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
493 prefix_string
, prefix
->prefixlen
, as_number
);
494 return RPKI_NOTFOUND
;
495 case BGP_PFXV_STATE_INVALID
:
497 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
498 prefix_string
, prefix
->prefixlen
, as_number
);
502 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
503 prefix_string
, prefix
->prefixlen
, as_number
);
509 static int add_cache(struct cache
*cache
)
511 uint8_t preference
= cache
->preference
;
512 struct rtr_mgr_group group
;
514 group
.preference
= preference
;
515 group
.sockets_len
= 1;
516 group
.sockets
= &cache
->rtr_socket
;
518 listnode_add(cache_list
, cache
);
521 && rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
528 static int add_tcp_cache(const char *host
, const char *port
,
529 const uint8_t preference
)
531 struct rtr_socket
*rtr_socket
;
532 struct tr_tcp_config
*tcp_config
=
533 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
534 struct tr_socket
*tr_socket
=
535 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
536 struct cache
*cache
=
537 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
539 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
540 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
541 tcp_config
->bindaddr
= NULL
;
543 rtr_socket
= create_rtr_socket(tr_socket
);
546 cache
->tr_socket
= tr_socket
;
547 cache
->tr_config
.tcp_config
= tcp_config
;
548 cache
->rtr_socket
= rtr_socket
;
549 cache
->preference
= preference
;
551 return add_cache(cache
);
554 #if defined(FOUND_SSH)
555 static int add_ssh_cache(const char *host
, const unsigned int port
,
556 const char *username
, const char *client_privkey_path
,
557 const char *client_pubkey_path
,
558 const char *server_pubkey_path
,
559 const uint8_t preference
)
561 struct tr_ssh_config
*ssh_config
=
562 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
563 struct cache
*cache
=
564 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
565 struct tr_socket
*tr_socket
=
566 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
567 struct rtr_socket
*rtr_socket
;
569 ssh_config
->port
= port
;
570 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
571 ssh_config
->bindaddr
= NULL
;
573 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
574 ssh_config
->client_privkey_path
=
575 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
576 ssh_config
->server_hostkey_path
=
577 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
579 rtr_socket
= create_rtr_socket(tr_socket
);
582 cache
->tr_socket
= tr_socket
;
583 cache
->tr_config
.ssh_config
= ssh_config
;
584 cache
->rtr_socket
= rtr_socket
;
585 cache
->preference
= preference
;
587 return add_cache(cache
);
591 static void free_cache(struct cache
*cache
)
593 if (cache
->type
== TCP
) {
594 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
595 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
596 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
598 #if defined(FOUND_SSH)
600 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
601 XFREE(MTYPE_BGP_RPKI_CACHE
,
602 cache
->tr_config
.ssh_config
->username
);
603 XFREE(MTYPE_BGP_RPKI_CACHE
,
604 cache
->tr_config
.ssh_config
->client_privkey_path
);
605 XFREE(MTYPE_BGP_RPKI_CACHE
,
606 cache
->tr_config
.ssh_config
->server_hostkey_path
);
607 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
610 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
611 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
612 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
615 static int config_write(struct vty
*vty
)
617 struct listnode
*cache_node
;
620 if (listcount(cache_list
)) {
622 vty_out(vty
, "debug rpki\n");
625 vty_out(vty
, "rpki\n");
626 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
627 vty_out(vty
, " rpki timeout %d\n", timeout
);
628 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
629 initial_synchronisation_timeout
);
630 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
631 switch (cache
->type
) {
632 struct tr_tcp_config
*tcp_config
;
633 #if defined(FOUND_SSH)
634 struct tr_ssh_config
*ssh_config
;
637 tcp_config
= cache
->tr_config
.tcp_config
;
638 vty_out(vty
, " rpki cache %s %s ",
639 tcp_config
->host
, tcp_config
->port
);
641 #if defined(FOUND_SSH)
643 ssh_config
= cache
->tr_config
.ssh_config
;
644 vty_out(vty
, " rpki cache %s %u %s %s %s ",
645 ssh_config
->host
, ssh_config
->port
,
646 ssh_config
->username
,
647 ssh_config
->client_privkey_path
,
648 ssh_config
->server_hostkey_path
!= NULL
650 ->server_hostkey_path
658 vty_out(vty
, "preference %hhu\n", cache
->preference
);
660 vty_out(vty
, " exit\n");
670 "Enable rpki and enter rpki configuration mode\n")
672 vty
->node
= RPKI_NODE
;
676 DEFUN (bgp_rpki_start
,
680 "start rpki support\n")
682 if (listcount(cache_list
) == 0)
684 "Could not start rpki because no caches are configured\n");
687 if (start() == ERROR
) {
688 RPKI_DEBUG("RPKI failed to start");
695 DEFUN (bgp_rpki_stop
,
699 "start rpki support\n")
707 DEFPY (rpki_polling_period
,
708 rpki_polling_period_cmd
,
709 "rpki polling_period (1-86400)$pp",
711 "Set polling period\n"
712 "Polling period value\n")
718 DEFUN (no_rpki_polling_period
,
719 no_rpki_polling_period_cmd
,
720 "no rpki polling_period",
723 "Set polling period back to default\n")
725 polling_period
= POLLING_PERIOD_DEFAULT
;
729 DEFPY (rpki_expire_interval
,
730 rpki_expire_interval_cmd
,
731 "rpki expire_interval (600-172800)$tmp",
733 "Set expire interval\n"
734 "Expire interval value\n")
736 if ((unsigned int)tmp
>= polling_period
) {
737 expire_interval
= tmp
;
741 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
742 return CMD_WARNING_CONFIG_FAILED
;
745 DEFUN (no_rpki_expire_interval
,
746 no_rpki_expire_interval_cmd
,
747 "no rpki expire_interval",
750 "Set expire interval back to default\n")
752 expire_interval
= polling_period
* 2;
756 DEFPY (rpki_retry_interval
,
757 rpki_retry_interval_cmd
,
758 "rpki retry_interval (1-7200)$tmp",
760 "Set retry interval\n"
761 "retry interval value\n")
763 retry_interval
= tmp
;
767 DEFUN (no_rpki_retry_interval
,
768 no_rpki_retry_interval_cmd
,
769 "no rpki retry_interval",
772 "Set retry interval back to default\n")
774 retry_interval
= RETRY_INTERVAL_DEFAULT
;
780 "rpki timeout (1-4294967295)$to_arg",
789 DEFUN (no_rpki_timeout
,
794 "Set timeout back to default\n")
796 timeout
= TIMEOUT_DEFAULT
;
800 DEFPY (rpki_synchronisation_timeout
,
801 rpki_synchronisation_timeout_cmd
,
802 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
804 "Set a timeout for the initial synchronisation of prefix validation data\n"
807 initial_synchronisation_timeout
= ito_arg
;
811 DEFUN (no_rpki_synchronisation_timeout
,
812 no_rpki_synchronisation_timeout_cmd
,
813 "no rpki initial-synchronisation-timeout",
816 "Set the initial synchronisation timeout back to default (30 sec.)\n")
818 initial_synchronisation_timeout
=
819 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
825 "rpki cache <A.B.C.D|WORD>"
826 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
827 "preference (1-255)",
829 "Install a cache server to current group\n"
830 "IP address of cache server\n Hostname of cache server\n"
834 "Path to own SSH private key\n"
835 "Path to own SSH public key\n"
836 "Path to Public key of cache server\n"
837 "Preference of the cache server\n"
838 "Preference value\n")
840 int return_value
= SUCCESS
;
842 // use ssh connection
844 #if defined(FOUND_SSH)
846 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
847 ssh_pubkey
, server_pubkey
, preference
);
850 "ssh sockets are not supported. "
851 "Please recompile rtrlib and frr with ssh support. "
852 "If you want to use it");
854 } else { // use tcp connection
855 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
858 if (return_value
== ERROR
) {
859 vty_out(vty
, "Could not create new rpki cache\n");
866 DEFPY (no_rpki_cache
,
868 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
871 "Remove a cache server\n"
872 "IP address of cache server\n Hostname of cache server\n"
875 "Preference of the cache server\n"
876 "Preference value\n")
878 struct cache
*cache_p
= find_cache(preference
);
881 vty_out(vty
, "Could not find cache %ld\n", preference
);
885 if (rtr_is_running
) {
886 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
887 vty_out(vty
, "Could not remove cache %ld", preference
);
888 if (listcount(cache_list
) == 1)
889 vty_out(vty
, " because it is the last cache");
896 listnode_delete(cache_list
, cache_p
);
902 DEFUN (show_rpki_prefix_table
,
903 show_rpki_prefix_table_cmd
,
904 "show rpki prefix-table",
907 "Show validated prefixes which were received from RPKI Cache\n")
909 struct listnode
*cache_node
;
912 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
913 vty_out(vty
, "host: %s port: %s\n",
914 cache
->tr_config
.tcp_config
->host
,
915 cache
->tr_config
.tcp_config
->port
);
917 if (is_synchronized())
918 print_prefix_table(vty
);
920 vty_out(vty
, "No connection to RPKI cache server.\n");
925 DEFUN (show_rpki_cache_server
,
926 show_rpki_cache_server_cmd
,
927 "show rpki cache-server",
930 "SHOW configured cache server\n")
932 struct listnode
*cache_node
;
935 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
936 vty_out(vty
, "host: %s port: %s\n",
937 cache
->tr_config
.tcp_config
->host
,
938 cache
->tr_config
.tcp_config
->port
);
944 DEFUN (show_rpki_cache_connection
,
945 show_rpki_cache_connection_cmd
,
946 "show rpki cache-connection",
949 "Show to which RPKI Cache Servers we have a connection\n")
951 if (is_synchronized()) {
952 struct listnode
*cache_node
;
954 struct rtr_mgr_group
*group
= get_connected_group();
957 vty_out(vty
, "Cannot find a connected group.\n");
960 vty_out(vty
, "Connected to group %d\n", group
->preference
);
961 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
962 if (cache
->preference
== group
->preference
) {
963 struct tr_tcp_config
*tcp_config
;
964 #if defined(FOUND_SSH)
965 struct tr_ssh_config
*ssh_config
;
968 switch (cache
->type
) {
971 cache
->tr_config
.tcp_config
;
973 "rpki tcp cache %s %s pref %hhu\n",
979 #if defined(FOUND_SSH)
982 cache
->tr_config
.ssh_config
;
984 "rpki ssh cache %s %u pref %hhu\n",
997 vty_out(vty
, "No connection to RPKI cache server.\n");
1003 DEFUN_NOSH (rpki_exit
,
1006 "Exit rpki configuration and restart rpki session\n")
1008 int ret
= reset(false);
1010 vty
->node
= CONFIG_NODE
;
1011 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1014 DEFUN_NOSH (rpki_quit
,
1017 "Exit rpki configuration mode\n")
1019 return rpki_exit(self
, vty
, argc
, argv
);
1022 DEFUN_NOSH (rpki_end
,
1025 "End rpki configuration, restart rpki session and change to enable mode.\n")
1027 int ret
= reset(false);
1029 vty_config_unlock(vty
);
1030 vty
->node
= ENABLE_NODE
;
1031 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1040 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1047 "Enable debugging for rpki\n")
1053 DEFUN (no_debug_rpki
,
1058 "Disable debugging for rpki\n")
1066 "match rpki <valid|invalid|notfound>",
1071 "Prefix not found\n")
1073 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1076 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1079 case RMAP_RULE_MISSING
:
1080 vty_out(vty
, "%% BGP Can't find rule.\n");
1081 return CMD_WARNING_CONFIG_FAILED
;
1082 case RMAP_COMPILE_ERROR
:
1083 vty_out(vty
, "%% BGP Argument is malformed.\n");
1084 return CMD_WARNING_CONFIG_FAILED
;
1090 DEFUN (no_match_rpki
,
1092 "no match rpki <valid|invalid|notfound>",
1098 "Prefix not found\n")
1100 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1103 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1106 case RMAP_RULE_MISSING
:
1107 vty_out(vty
, "%% BGP Can't find rule.\n");
1109 case RMAP_COMPILE_ERROR
:
1110 vty_out(vty
, "%% BGP Argument is malformed.\n");
1113 return CMD_WARNING_CONFIG_FAILED
;
1119 static void overwrite_exit_commands(void)
1122 vector cmd_vector
= rpki_node
.cmd_vector
;
1124 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1125 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1127 if (strcmp(cmd
->string
, "exit") == 0
1128 || strcmp(cmd
->string
, "quit") == 0
1129 || strcmp(cmd
->string
, "end") == 0) {
1130 uninstall_element(RPKI_NODE
, cmd
);
1134 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1135 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1136 install_element(RPKI_NODE
, &rpki_end_cmd
);
1139 static void install_cli_commands(void)
1141 // TODO: make config write work
1142 install_node(&rpki_node
, &config_write
);
1143 install_default(RPKI_NODE
);
1144 overwrite_exit_commands();
1145 install_element(CONFIG_NODE
, &rpki_cmd
);
1146 install_element(VIEW_NODE
, &rpki_cmd
);
1148 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1149 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1151 /* Install rpki reset command */
1152 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1154 /* Install rpki polling period commands */
1155 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1156 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1158 /* Install rpki expire interval commands */
1159 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1160 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1162 /* Install rpki retry interval commands */
1163 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1164 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1166 /* Install rpki timeout commands */
1167 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1168 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1170 /* Install rpki synchronisation timeout commands */
1171 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1172 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1174 /* Install rpki cache commands */
1175 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1176 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1178 /* Install show commands */
1179 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1180 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1181 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1183 /* Install debug commands */
1184 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1185 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1186 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1187 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1189 /* Install route match */
1190 route_map_install_match(&route_match_rpki_cmd
);
1191 install_element(RMAP_NODE
, &match_rpki_cmd
);
1192 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1195 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1196 .description
= "Enable RPKI support for FRR.",
1197 .init
= bgp_rpki_module_init
)