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-2018 Marcel Röthke (marcel.roethke@haw-hamburg.de),
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 "lib/network.h"
51 #include "lib/thread.h"
52 #ifndef VTYSH_EXTRACT_PL
53 #include "rtrlib/rtrlib.h"
54 #include "rtrlib/rtr_mgr.h"
55 #include "rtrlib/lib/ip.h"
56 #include "rtrlib/transport/tcp/tcp_transport.h"
57 #if defined(FOUND_SSH)
58 #include "rtrlib/transport/ssh/ssh_transport.h"
65 #ifndef VTYSH_EXTRACT_PL
66 #include "bgpd/bgp_rpki_clippy.c"
69 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
70 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
73 #define RPKI_NOTFOUND 2
74 #define RPKI_INVALID 3
76 #define POLLING_PERIOD_DEFAULT 3600
77 #define EXPIRE_INTERVAL_DEFAULT 7200
78 #define RETRY_INTERVAL_DEFAULT 600
79 #define TIMEOUT_DEFAULT 600
80 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
82 #define RPKI_DEBUG(...) \
84 zlog_debug("RPKI: " __VA_ARGS__); \
87 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
90 enum { TCP
, SSH
} type
;
91 struct tr_socket
*tr_socket
;
93 struct tr_tcp_config
*tcp_config
;
94 struct tr_ssh_config
*ssh_config
;
96 struct rtr_socket
*rtr_socket
;
100 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
102 struct rpki_for_each_record_arg
{
104 unsigned int *prefix_amount
;
107 static int start(void);
108 static void stop(void);
109 static int reset(bool force
);
110 static struct rtr_mgr_group
*get_connected_group(void);
111 static void print_prefix_table(struct vty
*vty
);
112 static void install_cli_commands(void);
113 static int config_write(struct vty
*vty
);
114 static void overwrite_exit_commands(void);
115 static void free_cache(struct cache
*cache
);
116 static struct rtr_mgr_group
*get_groups(void);
117 #if defined(FOUND_SSH)
118 static int add_ssh_cache(const char *host
, const unsigned int port
,
119 const char *username
, const char *client_privkey_path
,
120 const char *client_pubkey_path
,
121 const char *server_pubkey_path
,
122 const uint8_t preference
);
124 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
125 static struct cache
*find_cache(const uint8_t preference
);
126 static int add_tcp_cache(const char *host
, const char *port
,
127 const uint8_t preference
);
128 static void print_record(const struct pfx_record
*record
, void *data
);
129 static int is_synchronized(void);
130 static int is_running(void);
131 static void route_match_free(void *rule
);
132 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
133 route_map_object_t type
, void *object
);
134 static void *route_match_compile(const char *arg
);
135 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
137 static void revalidate_all_routes(void);
139 static struct rtr_mgr_config
*rtr_config
;
140 static struct list
*cache_list
;
141 static int rtr_is_running
;
142 static int rtr_is_stopping
;
143 static int rtr_is_starting
;
144 static _Atomic
int rtr_update_overflow
;
145 static int rpki_debug
;
146 static unsigned int polling_period
;
147 static unsigned int expire_interval
;
148 static unsigned int retry_interval
;
149 static unsigned int timeout
;
150 static unsigned int initial_synchronisation_timeout
;
151 static int rpki_sync_socket_rtr
;
152 static int rpki_sync_socket_bgpd
;
154 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
155 static struct route_map_rule_cmd route_match_rpki_cmd
= {
156 "rpki", route_match
, route_match_compile
, route_match_free
};
158 static void *malloc_wrapper(size_t size
)
160 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
163 static void *realloc_wrapper(void *ptr
, size_t size
)
165 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
168 static void free_wrapper(void *ptr
)
170 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
173 static void init_tr_socket(struct cache
*cache
)
175 if (cache
->type
== TCP
)
176 tr_tcp_init(cache
->tr_config
.tcp_config
,
178 #if defined(FOUND_SSH)
180 tr_ssh_init(cache
->tr_config
.ssh_config
,
185 static void free_tr_socket(struct cache
*cache
)
187 if (cache
->type
== TCP
)
188 tr_tcp_init(cache
->tr_config
.tcp_config
,
190 #if defined(FOUND_SSH)
192 tr_ssh_init(cache
->tr_config
.ssh_config
,
197 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
198 const struct prefix
*prefix
);
200 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
204 for (i
= 0; i
< 4; i
++)
205 dest
[i
] = htonl(src
[i
]);
208 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
212 for (i
= 0; i
< 4; i
++)
213 dest
[i
] = ntohl(src
[i
]);
216 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
217 route_map_object_t type
, void *object
)
219 int *rpki_status
= rule
;
220 struct bgp_info
*bgp_info
;
222 if (type
== RMAP_BGP
) {
225 if (rpki_validate_prefix(bgp_info
->peer
, bgp_info
->attr
, prefix
)
233 static void *route_match_compile(const char *arg
)
237 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
239 if (strcmp(arg
, "valid") == 0)
240 *rpki_status
= RPKI_VALID
;
241 else if (strcmp(arg
, "invalid") == 0)
242 *rpki_status
= RPKI_INVALID
;
244 *rpki_status
= RPKI_NOTFOUND
;
249 static void route_match_free(void *rule
)
251 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
254 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
256 struct rtr_socket
*rtr_socket
=
257 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
258 rtr_socket
->tr_socket
= tr_socket
;
262 static struct cache
*find_cache(const uint8_t preference
)
264 struct listnode
*cache_node
;
267 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
268 if (cache
->preference
== preference
)
274 static void print_record(const struct pfx_record
*record
, void *data
)
276 char ip
[INET6_ADDRSTRLEN
];
277 struct rpki_for_each_record_arg
*arg
= data
;
278 struct vty
*vty
= arg
->vty
;
280 (*arg
->prefix_amount
)++;
282 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
283 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
284 record
->max_len
, record
->asn
);
287 static struct rtr_mgr_group
*get_groups(void)
289 struct listnode
*cache_node
;
290 struct rtr_mgr_group
*rtr_mgr_groups
;
293 int group_count
= listcount(cache_list
);
295 if (group_count
== 0)
298 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
299 group_count
* sizeof(struct rtr_mgr_group
));
303 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
304 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
305 rtr_mgr_groups
[i
].sockets_len
= 1;
306 rtr_mgr_groups
[i
].preference
= cache
->preference
;
308 init_tr_socket(cache
);
313 return rtr_mgr_groups
;
316 inline int is_synchronized(void)
318 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
321 inline int is_running(void)
323 return rtr_is_running
;
326 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
328 struct prefix
*prefix
= prefix_new();
330 prefix
->prefixlen
= record
->min_len
;
332 if (record
->prefix
.ver
== LRTR_IPV4
) {
333 prefix
->family
= AF_INET
;
334 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
336 prefix
->family
= AF_INET6
;
337 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
338 prefix
->u
.prefix6
.s6_addr32
);
344 static int bgpd_sync_callback(struct thread
*thread
)
347 struct listnode
*node
;
348 struct prefix
*prefix
;
349 struct pfx_record rec
;
351 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
352 rpki_sync_socket_bgpd
, NULL
);
354 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
355 while (read(rpki_sync_socket_bgpd
, &rec
,
356 sizeof(struct pfx_record
))
360 atomic_store_explicit(&rtr_update_overflow
, 0,
361 memory_order_seq_cst
);
362 revalidate_all_routes();
367 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
368 if (retval
!= sizeof(struct pfx_record
)) {
369 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
372 prefix
= pfx_record_to_prefix(&rec
);
374 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
376 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
378 struct listnode
*peer_listnode
;
380 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
383 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
384 if (!peer
->bgp
->rib
[afi
][safi
])
387 struct list
*matches
= list_new();
390 (void (*)(void *))bgp_unlock_node
;
392 bgp_table_range_lookup(
393 peer
->bgp
->rib
[afi
][safi
], prefix
,
394 rec
.max_len
, matches
);
397 struct bgp_node
*bgp_node
;
398 struct listnode
*bgp_listnode
;
400 for (ALL_LIST_ELEMENTS_RO(matches
, bgp_listnode
,
402 revalidate_bgp_node(bgp_node
, afi
,
405 list_delete(&matches
);
414 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
417 struct bgp_adj_in
*ain
;
419 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
421 struct bgp_info
*bgp_info
= bgp_node
->info
;
422 mpls_label_t
*label
= NULL
;
423 uint32_t num_labels
= 0;
425 if (bgp_info
&& bgp_info
->extra
) {
426 label
= bgp_info
->extra
->label
;
427 num_labels
= bgp_info
->extra
->num_labels
;
429 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
430 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
431 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
439 static void revalidate_all_routes(void)
442 struct listnode
*node
;
444 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
446 struct listnode
*peer_listnode
;
448 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
450 for (size_t i
= 0; i
< 2; i
++) {
452 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
454 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
456 if (!peer
->bgp
->rib
[afi
][safi
])
459 bgp_soft_reconfig_in(peer
, afi
, safi
);
466 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
467 const struct pfx_record rec
,
468 const bool added
__attribute__((unused
)))
470 if (rtr_is_stopping
|| rtr_is_starting
471 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
475 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
476 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
477 atomic_store_explicit(&rtr_update_overflow
, 1,
478 memory_order_seq_cst
);
480 else if (retval
!= sizeof(struct pfx_record
))
481 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
484 static void rpki_init_sync_socket(void)
489 RPKI_DEBUG("initializing sync socket");
490 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
491 msg
= "could not open rpki sync socketpair";
494 rpki_sync_socket_rtr
= fds
[0];
495 rpki_sync_socket_bgpd
= fds
[1];
497 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
498 msg
= "could not set rpki_sync_socket_rtr to non blocking";
502 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
503 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
508 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
509 rpki_sync_socket_bgpd
, NULL
);
514 zlog_err("RPKI: %s", msg
);
519 static int bgp_rpki_init(struct thread_master
*master
)
525 cache_list
= list_new();
526 cache_list
->del
= (void (*)(void *)) & free_cache
;
528 polling_period
= POLLING_PERIOD_DEFAULT
;
529 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
530 retry_interval
= RETRY_INTERVAL_DEFAULT
;
531 timeout
= TIMEOUT_DEFAULT
;
532 initial_synchronisation_timeout
=
533 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
534 install_cli_commands();
535 rpki_init_sync_socket();
539 static int bgp_rpki_fini(void)
542 list_delete(&cache_list
);
544 close(rpki_sync_socket_rtr
);
545 close(rpki_sync_socket_bgpd
);
550 static int bgp_rpki_module_init(void)
552 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
554 hook_register(frr_late_init
, bgp_rpki_init
);
555 hook_register(frr_early_fini
, &bgp_rpki_fini
);
560 static int start(void)
562 unsigned int waiting_time
= 0;
567 rtr_update_overflow
= 0;
569 if (list_isempty(cache_list
)) {
571 "No caches were found in config. Prefix validation is off.");
574 RPKI_DEBUG("Init rtr_mgr.");
575 int groups_len
= listcount(cache_list
);
576 struct rtr_mgr_group
*groups
= get_groups();
578 RPKI_DEBUG("Polling period: %d", polling_period
);
579 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
580 expire_interval
, retry_interval
,
581 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
582 if (ret
== RTR_ERROR
) {
583 RPKI_DEBUG("Init rtr_mgr failed.");
587 RPKI_DEBUG("Starting rtr_mgr.");
588 ret
= rtr_mgr_start(rtr_config
);
589 if (ret
== RTR_ERROR
) {
590 RPKI_DEBUG("Starting rtr_mgr failed.");
591 rtr_mgr_free(rtr_config
);
595 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
596 while (waiting_time
++ <= initial_synchronisation_timeout
) {
597 if (rtr_mgr_conf_in_sync(rtr_config
))
602 if (rtr_mgr_conf_in_sync(rtr_config
)) {
603 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
604 RPKI_DEBUG("Forcing revalidation.");
606 revalidate_all_routes();
609 "Timeout expired! Proceeding without RPKI validation data.");
613 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
618 static void stop(void)
621 if (rtr_is_running
) {
622 rtr_mgr_stop(rtr_config
);
623 rtr_mgr_free(rtr_config
);
628 static int reset(bool force
)
630 if (rtr_is_running
&& !force
)
633 RPKI_DEBUG("Resetting RPKI Session");
638 static struct rtr_mgr_group
*get_connected_group(void)
640 if (!cache_list
|| list_isempty(cache_list
))
643 return rtr_mgr_get_first_group(rtr_config
);
646 static void print_prefix_table(struct vty
*vty
)
648 struct rpki_for_each_record_arg arg
;
650 unsigned int number_of_ipv4_prefixes
= 0;
651 unsigned int number_of_ipv6_prefixes
= 0;
652 struct rtr_mgr_group
*group
= get_connected_group();
659 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
661 vty_out(vty
, "RPKI/RTR prefix table\n");
662 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
664 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
665 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
667 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
668 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
670 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
671 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
674 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
675 const struct prefix
*prefix
)
677 struct assegment
*as_segment
;
679 struct lrtr_ip_addr ip_addr_prefix
;
680 enum pfxv_state result
;
682 const char *prefix_string
;
684 if (!is_synchronized())
687 // No aspath means route comes from iBGP
688 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
690 as_number
= peer
->bgp
->as
;
692 as_segment
= attr
->aspath
->segments
;
693 // Find last AsSegment
694 while (as_segment
->next
)
695 as_segment
= as_segment
->next
;
697 if (as_segment
->type
== AS_SEQUENCE
) {
699 as_number
= as_segment
->as
[as_segment
->length
- 1];
700 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
701 || as_segment
->type
== AS_CONFED_SET
) {
703 as_number
= peer
->bgp
->as
;
705 // RFC says: "Take distinguished value NONE as asn"
706 // which means state is unknown
707 return RPKI_NOTFOUND
;
711 // Get the prefix in requested format
712 switch (prefix
->family
) {
714 ip_addr_prefix
.ver
= LRTR_IPV4
;
715 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
719 ip_addr_prefix
.ver
= LRTR_IPV6
;
720 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
721 ip_addr_prefix
.u
.addr6
.addr
);
728 // Do the actual validation
729 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
730 prefix
->prefixlen
, &result
);
732 // Print Debug output
734 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
736 case BGP_PFXV_STATE_VALID
:
738 "Validating Prefix %s/%hhu from asn %u Result: VALID",
739 prefix_string
, prefix
->prefixlen
, as_number
);
741 case BGP_PFXV_STATE_NOT_FOUND
:
743 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
744 prefix_string
, prefix
->prefixlen
, as_number
);
745 return RPKI_NOTFOUND
;
746 case BGP_PFXV_STATE_INVALID
:
748 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
749 prefix_string
, prefix
->prefixlen
, as_number
);
753 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
754 prefix_string
, prefix
->prefixlen
, as_number
);
760 static int add_cache(struct cache
*cache
)
762 uint8_t preference
= cache
->preference
;
763 struct rtr_mgr_group group
;
765 group
.preference
= preference
;
766 group
.sockets_len
= 1;
767 group
.sockets
= &cache
->rtr_socket
;
769 listnode_add(cache_list
, cache
);
771 if (rtr_is_running
) {
772 init_tr_socket(cache
);
774 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
775 free_tr_socket(cache
);
783 static int add_tcp_cache(const char *host
, const char *port
,
784 const uint8_t preference
)
786 struct rtr_socket
*rtr_socket
;
787 struct tr_tcp_config
*tcp_config
=
788 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
789 struct tr_socket
*tr_socket
=
790 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
791 struct cache
*cache
=
792 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
794 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
795 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
796 tcp_config
->bindaddr
= NULL
;
798 rtr_socket
= create_rtr_socket(tr_socket
);
801 cache
->tr_socket
= tr_socket
;
802 cache
->tr_config
.tcp_config
= tcp_config
;
803 cache
->rtr_socket
= rtr_socket
;
804 cache
->preference
= preference
;
806 return add_cache(cache
);
809 #if defined(FOUND_SSH)
810 static int add_ssh_cache(const char *host
, const unsigned int port
,
811 const char *username
, const char *client_privkey_path
,
812 const char *client_pubkey_path
,
813 const char *server_pubkey_path
,
814 const uint8_t preference
)
816 struct tr_ssh_config
*ssh_config
=
817 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
818 struct cache
*cache
=
819 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
820 struct tr_socket
*tr_socket
=
821 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
822 struct rtr_socket
*rtr_socket
;
824 ssh_config
->port
= port
;
825 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
826 ssh_config
->bindaddr
= NULL
;
828 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
829 ssh_config
->client_privkey_path
=
830 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
831 ssh_config
->server_hostkey_path
=
832 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
834 rtr_socket
= create_rtr_socket(tr_socket
);
837 cache
->tr_socket
= tr_socket
;
838 cache
->tr_config
.ssh_config
= ssh_config
;
839 cache
->rtr_socket
= rtr_socket
;
840 cache
->preference
= preference
;
842 return add_cache(cache
);
846 static void free_cache(struct cache
*cache
)
848 if (cache
->type
== TCP
) {
849 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
850 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
851 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
853 #if defined(FOUND_SSH)
855 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
856 XFREE(MTYPE_BGP_RPKI_CACHE
,
857 cache
->tr_config
.ssh_config
->username
);
858 XFREE(MTYPE_BGP_RPKI_CACHE
,
859 cache
->tr_config
.ssh_config
->client_privkey_path
);
860 XFREE(MTYPE_BGP_RPKI_CACHE
,
861 cache
->tr_config
.ssh_config
->server_hostkey_path
);
862 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
865 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
866 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
867 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
870 static int config_write(struct vty
*vty
)
872 struct listnode
*cache_node
;
875 if (listcount(cache_list
)) {
877 vty_out(vty
, "debug rpki\n");
880 vty_out(vty
, "rpki\n");
881 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
882 vty_out(vty
, " rpki timeout %d\n", timeout
);
883 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
884 initial_synchronisation_timeout
);
885 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
886 switch (cache
->type
) {
887 struct tr_tcp_config
*tcp_config
;
888 #if defined(FOUND_SSH)
889 struct tr_ssh_config
*ssh_config
;
892 tcp_config
= cache
->tr_config
.tcp_config
;
893 vty_out(vty
, " rpki cache %s %s ",
894 tcp_config
->host
, tcp_config
->port
);
896 #if defined(FOUND_SSH)
898 ssh_config
= cache
->tr_config
.ssh_config
;
899 vty_out(vty
, " rpki cache %s %u %s %s %s ",
900 ssh_config
->host
, ssh_config
->port
,
901 ssh_config
->username
,
902 ssh_config
->client_privkey_path
,
903 ssh_config
->server_hostkey_path
!= NULL
905 ->server_hostkey_path
913 vty_out(vty
, "preference %hhu\n", cache
->preference
);
915 vty_out(vty
, " exit\n");
925 "Enable rpki and enter rpki configuration mode\n")
927 vty
->node
= RPKI_NODE
;
931 DEFUN (bgp_rpki_start
,
935 "start rpki support\n")
937 if (listcount(cache_list
) == 0)
939 "Could not start rpki because no caches are configured\n");
942 if (start() == ERROR
) {
943 RPKI_DEBUG("RPKI failed to start");
950 DEFUN (bgp_rpki_stop
,
954 "start rpki support\n")
962 DEFPY (rpki_polling_period
,
963 rpki_polling_period_cmd
,
964 "rpki polling_period (1-86400)$pp",
966 "Set polling period\n"
967 "Polling period value\n")
973 DEFUN (no_rpki_polling_period
,
974 no_rpki_polling_period_cmd
,
975 "no rpki polling_period",
978 "Set polling period back to default\n")
980 polling_period
= POLLING_PERIOD_DEFAULT
;
984 DEFPY (rpki_expire_interval
,
985 rpki_expire_interval_cmd
,
986 "rpki expire_interval (600-172800)$tmp",
988 "Set expire interval\n"
989 "Expire interval value\n")
991 if ((unsigned int)tmp
>= polling_period
) {
992 expire_interval
= tmp
;
996 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
997 return CMD_WARNING_CONFIG_FAILED
;
1000 DEFUN (no_rpki_expire_interval
,
1001 no_rpki_expire_interval_cmd
,
1002 "no rpki expire_interval",
1005 "Set expire interval back to default\n")
1007 expire_interval
= polling_period
* 2;
1011 DEFPY (rpki_retry_interval
,
1012 rpki_retry_interval_cmd
,
1013 "rpki retry_interval (1-7200)$tmp",
1015 "Set retry interval\n"
1016 "retry interval value\n")
1018 retry_interval
= tmp
;
1022 DEFUN (no_rpki_retry_interval
,
1023 no_rpki_retry_interval_cmd
,
1024 "no rpki retry_interval",
1027 "Set retry interval back to default\n")
1029 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1033 DEFPY (rpki_timeout
,
1035 "rpki timeout (1-4294967295)$to_arg",
1044 DEFUN (no_rpki_timeout
,
1045 no_rpki_timeout_cmd
,
1049 "Set timeout back to default\n")
1051 timeout
= TIMEOUT_DEFAULT
;
1055 DEFPY (rpki_synchronisation_timeout
,
1056 rpki_synchronisation_timeout_cmd
,
1057 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1059 "Set a timeout for the initial synchronisation of prefix validation data\n"
1062 initial_synchronisation_timeout
= ito_arg
;
1066 DEFUN (no_rpki_synchronisation_timeout
,
1067 no_rpki_synchronisation_timeout_cmd
,
1068 "no rpki initial-synchronisation-timeout",
1071 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1073 initial_synchronisation_timeout
=
1074 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1080 "rpki cache <A.B.C.D|WORD>"
1081 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1082 "preference (1-255)",
1084 "Install a cache server to current group\n"
1085 "IP address of cache server\n Hostname of cache server\n"
1089 "Path to own SSH private key\n"
1090 "Path to own SSH public key\n"
1091 "Path to Public key of cache server\n"
1092 "Preference of the cache server\n"
1093 "Preference value\n")
1097 // use ssh connection
1099 #if defined(FOUND_SSH)
1101 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1102 ssh_pubkey
, server_pubkey
, preference
);
1104 return_value
= SUCCESS
;
1106 "ssh sockets are not supported. "
1107 "Please recompile rtrlib and frr with ssh support. "
1108 "If you want to use it");
1110 } else { // use tcp connection
1111 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1114 if (return_value
== ERROR
) {
1115 vty_out(vty
, "Could not create new rpki cache\n");
1122 DEFPY (no_rpki_cache
,
1124 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1127 "Remove a cache server\n"
1128 "IP address of cache server\n Hostname of cache server\n"
1131 "Preference of the cache server\n"
1132 "Preference value\n")
1134 struct cache
*cache_p
= find_cache(preference
);
1137 vty_out(vty
, "Could not find cache %ld\n", preference
);
1141 if (rtr_is_running
) {
1142 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1143 vty_out(vty
, "Could not remove cache %ld", preference
);
1144 if (listcount(cache_list
) == 1)
1145 vty_out(vty
, " because it is the last cache");
1152 listnode_delete(cache_list
, cache_p
);
1153 free_cache(cache_p
);
1158 DEFUN (show_rpki_prefix_table
,
1159 show_rpki_prefix_table_cmd
,
1160 "show rpki prefix-table",
1163 "Show validated prefixes which were received from RPKI Cache\n")
1165 struct listnode
*cache_node
;
1166 struct cache
*cache
;
1168 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1169 vty_out(vty
, "host: %s port: %s\n",
1170 cache
->tr_config
.tcp_config
->host
,
1171 cache
->tr_config
.tcp_config
->port
);
1173 if (is_synchronized())
1174 print_prefix_table(vty
);
1176 vty_out(vty
, "No connection to RPKI cache server.\n");
1181 DEFUN (show_rpki_cache_server
,
1182 show_rpki_cache_server_cmd
,
1183 "show rpki cache-server",
1186 "SHOW configured cache server\n")
1188 struct listnode
*cache_node
;
1189 struct cache
*cache
;
1191 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1192 vty_out(vty
, "host: %s port: %s\n",
1193 cache
->tr_config
.tcp_config
->host
,
1194 cache
->tr_config
.tcp_config
->port
);
1200 DEFUN (show_rpki_cache_connection
,
1201 show_rpki_cache_connection_cmd
,
1202 "show rpki cache-connection",
1205 "Show to which RPKI Cache Servers we have a connection\n")
1207 if (is_synchronized()) {
1208 struct listnode
*cache_node
;
1209 struct cache
*cache
;
1210 struct rtr_mgr_group
*group
= get_connected_group();
1213 vty_out(vty
, "Cannot find a connected group.\n");
1216 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1217 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1218 if (cache
->preference
== group
->preference
) {
1219 struct tr_tcp_config
*tcp_config
;
1220 #if defined(FOUND_SSH)
1221 struct tr_ssh_config
*ssh_config
;
1224 switch (cache
->type
) {
1227 cache
->tr_config
.tcp_config
;
1229 "rpki tcp cache %s %s pref %hhu\n",
1235 #if defined(FOUND_SSH)
1238 cache
->tr_config
.ssh_config
;
1240 "rpki ssh cache %s %u pref %hhu\n",
1253 vty_out(vty
, "No connection to RPKI cache server.\n");
1259 DEFUN_NOSH (rpki_exit
,
1262 "Exit rpki configuration and restart rpki session\n")
1266 vty
->node
= CONFIG_NODE
;
1270 DEFUN_NOSH (rpki_quit
,
1273 "Exit rpki configuration mode\n")
1275 return rpki_exit(self
, vty
, argc
, argv
);
1278 DEFUN_NOSH (rpki_end
,
1281 "End rpki configuration, restart rpki session and change to enable mode.\n")
1283 int ret
= reset(false);
1285 vty_config_unlock(vty
);
1286 vty
->node
= ENABLE_NODE
;
1287 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1296 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1303 "Enable debugging for rpki\n")
1309 DEFUN (no_debug_rpki
,
1314 "Disable debugging for rpki\n")
1322 "match rpki <valid|invalid|notfound>",
1327 "Prefix not found\n")
1329 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1332 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1335 case RMAP_RULE_MISSING
:
1336 vty_out(vty
, "%% BGP Can't find rule.\n");
1337 return CMD_WARNING_CONFIG_FAILED
;
1338 case RMAP_COMPILE_ERROR
:
1339 vty_out(vty
, "%% BGP Argument is malformed.\n");
1340 return CMD_WARNING_CONFIG_FAILED
;
1346 DEFUN (no_match_rpki
,
1348 "no match rpki <valid|invalid|notfound>",
1354 "Prefix not found\n")
1356 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1359 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1362 case RMAP_RULE_MISSING
:
1363 vty_out(vty
, "%% BGP Can't find rule.\n");
1365 case RMAP_COMPILE_ERROR
:
1366 vty_out(vty
, "%% BGP Argument is malformed.\n");
1369 return CMD_WARNING_CONFIG_FAILED
;
1375 static void overwrite_exit_commands(void)
1378 vector cmd_vector
= rpki_node
.cmd_vector
;
1380 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1381 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1383 if (strcmp(cmd
->string
, "exit") == 0
1384 || strcmp(cmd
->string
, "quit") == 0
1385 || strcmp(cmd
->string
, "end") == 0) {
1386 uninstall_element(RPKI_NODE
, cmd
);
1390 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1391 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1392 install_element(RPKI_NODE
, &rpki_end_cmd
);
1395 static void install_cli_commands(void)
1397 // TODO: make config write work
1398 install_node(&rpki_node
, &config_write
);
1399 install_default(RPKI_NODE
);
1400 overwrite_exit_commands();
1401 install_element(CONFIG_NODE
, &rpki_cmd
);
1402 install_element(VIEW_NODE
, &rpki_cmd
);
1404 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1405 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1407 /* Install rpki reset command */
1408 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1410 /* Install rpki polling period commands */
1411 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1412 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1414 /* Install rpki expire interval commands */
1415 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1416 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1418 /* Install rpki retry interval commands */
1419 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1420 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1422 /* Install rpki timeout commands */
1423 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1424 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1426 /* Install rpki synchronisation timeout commands */
1427 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1428 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1430 /* Install rpki cache commands */
1431 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1432 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1434 /* Install show commands */
1435 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1436 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1437 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1439 /* Install debug commands */
1440 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1441 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1442 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1443 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1445 /* Install route match */
1446 route_map_install_match(&route_match_rpki_cmd
);
1447 install_element(RMAP_NODE
, &match_rpki_cmd
);
1448 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1451 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1452 .description
= "Enable RPKI support for FRR.",
1453 .init
= bgp_rpki_module_init
)