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_path_info
*path
;
222 if (type
== RMAP_BGP
) {
225 if (rpki_validate_prefix(path
->peer
, path
->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_path_info
*path
=
422 bgp_node_get_bgp_path_info(bgp_node
);
423 mpls_label_t
*label
= NULL
;
424 uint32_t num_labels
= 0;
426 if (path
&& path
->extra
) {
427 label
= path
->extra
->label
;
428 num_labels
= path
->extra
->num_labels
;
430 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
431 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
432 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
440 static void revalidate_all_routes(void)
443 struct listnode
*node
;
445 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
447 struct listnode
*peer_listnode
;
449 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
451 for (size_t i
= 0; i
< 2; i
++) {
453 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
455 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
457 if (!peer
->bgp
->rib
[afi
][safi
])
460 bgp_soft_reconfig_in(peer
, afi
, safi
);
467 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
468 const struct pfx_record rec
,
469 const bool added
__attribute__((unused
)))
471 if (rtr_is_stopping
|| rtr_is_starting
472 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
476 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
477 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
478 atomic_store_explicit(&rtr_update_overflow
, 1,
479 memory_order_seq_cst
);
481 else if (retval
!= sizeof(struct pfx_record
))
482 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
485 static void rpki_init_sync_socket(void)
490 RPKI_DEBUG("initializing sync socket");
491 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
492 msg
= "could not open rpki sync socketpair";
495 rpki_sync_socket_rtr
= fds
[0];
496 rpki_sync_socket_bgpd
= fds
[1];
498 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
499 msg
= "could not set rpki_sync_socket_rtr to non blocking";
503 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
504 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
509 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
510 rpki_sync_socket_bgpd
, NULL
);
515 zlog_err("RPKI: %s", msg
);
520 static int bgp_rpki_init(struct thread_master
*master
)
526 cache_list
= list_new();
527 cache_list
->del
= (void (*)(void *)) & free_cache
;
529 polling_period
= POLLING_PERIOD_DEFAULT
;
530 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
531 retry_interval
= RETRY_INTERVAL_DEFAULT
;
532 timeout
= TIMEOUT_DEFAULT
;
533 initial_synchronisation_timeout
=
534 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
535 install_cli_commands();
536 rpki_init_sync_socket();
540 static int bgp_rpki_fini(void)
543 list_delete(&cache_list
);
545 close(rpki_sync_socket_rtr
);
546 close(rpki_sync_socket_bgpd
);
551 static int bgp_rpki_module_init(void)
553 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
555 hook_register(frr_late_init
, bgp_rpki_init
);
556 hook_register(frr_early_fini
, &bgp_rpki_fini
);
561 static int start(void)
563 unsigned int waiting_time
= 0;
568 rtr_update_overflow
= 0;
570 if (list_isempty(cache_list
)) {
572 "No caches were found in config. Prefix validation is off.");
575 RPKI_DEBUG("Init rtr_mgr.");
576 int groups_len
= listcount(cache_list
);
577 struct rtr_mgr_group
*groups
= get_groups();
579 RPKI_DEBUG("Polling period: %d", polling_period
);
580 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
581 expire_interval
, retry_interval
,
582 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
583 if (ret
== RTR_ERROR
) {
584 RPKI_DEBUG("Init rtr_mgr failed.");
588 RPKI_DEBUG("Starting rtr_mgr.");
589 ret
= rtr_mgr_start(rtr_config
);
590 if (ret
== RTR_ERROR
) {
591 RPKI_DEBUG("Starting rtr_mgr failed.");
592 rtr_mgr_free(rtr_config
);
596 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
597 while (waiting_time
++ <= initial_synchronisation_timeout
) {
598 if (rtr_mgr_conf_in_sync(rtr_config
))
603 if (rtr_mgr_conf_in_sync(rtr_config
)) {
604 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
605 RPKI_DEBUG("Forcing revalidation.");
607 revalidate_all_routes();
610 "Timeout expired! Proceeding without RPKI validation data.");
614 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
619 static void stop(void)
622 if (rtr_is_running
) {
623 rtr_mgr_stop(rtr_config
);
624 rtr_mgr_free(rtr_config
);
629 static int reset(bool force
)
631 if (rtr_is_running
&& !force
)
634 RPKI_DEBUG("Resetting RPKI Session");
639 static struct rtr_mgr_group
*get_connected_group(void)
641 if (!cache_list
|| list_isempty(cache_list
))
644 return rtr_mgr_get_first_group(rtr_config
);
647 static void print_prefix_table(struct vty
*vty
)
649 struct rpki_for_each_record_arg arg
;
651 unsigned int number_of_ipv4_prefixes
= 0;
652 unsigned int number_of_ipv6_prefixes
= 0;
653 struct rtr_mgr_group
*group
= get_connected_group();
660 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
662 vty_out(vty
, "RPKI/RTR prefix table\n");
663 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
665 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
666 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
668 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
669 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
671 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
672 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
675 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
676 const struct prefix
*prefix
)
678 struct assegment
*as_segment
;
680 struct lrtr_ip_addr ip_addr_prefix
;
681 enum pfxv_state result
;
683 const char *prefix_string
;
685 if (!is_synchronized())
688 // No aspath means route comes from iBGP
689 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
691 as_number
= peer
->bgp
->as
;
693 as_segment
= attr
->aspath
->segments
;
694 // Find last AsSegment
695 while (as_segment
->next
)
696 as_segment
= as_segment
->next
;
698 if (as_segment
->type
== AS_SEQUENCE
) {
700 as_number
= as_segment
->as
[as_segment
->length
- 1];
701 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
702 || as_segment
->type
== AS_CONFED_SET
) {
704 as_number
= peer
->bgp
->as
;
706 // RFC says: "Take distinguished value NONE as asn"
707 // which means state is unknown
708 return RPKI_NOTFOUND
;
712 // Get the prefix in requested format
713 switch (prefix
->family
) {
715 ip_addr_prefix
.ver
= LRTR_IPV4
;
716 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
720 ip_addr_prefix
.ver
= LRTR_IPV6
;
721 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
722 ip_addr_prefix
.u
.addr6
.addr
);
729 // Do the actual validation
730 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
731 prefix
->prefixlen
, &result
);
733 // Print Debug output
735 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
737 case BGP_PFXV_STATE_VALID
:
739 "Validating Prefix %s/%hhu from asn %u Result: VALID",
740 prefix_string
, prefix
->prefixlen
, as_number
);
742 case BGP_PFXV_STATE_NOT_FOUND
:
744 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
745 prefix_string
, prefix
->prefixlen
, as_number
);
746 return RPKI_NOTFOUND
;
747 case BGP_PFXV_STATE_INVALID
:
749 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
750 prefix_string
, prefix
->prefixlen
, as_number
);
754 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
755 prefix_string
, prefix
->prefixlen
, as_number
);
761 static int add_cache(struct cache
*cache
)
763 uint8_t preference
= cache
->preference
;
764 struct rtr_mgr_group group
;
766 group
.preference
= preference
;
767 group
.sockets_len
= 1;
768 group
.sockets
= &cache
->rtr_socket
;
770 listnode_add(cache_list
, cache
);
772 if (rtr_is_running
) {
773 init_tr_socket(cache
);
775 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
776 free_tr_socket(cache
);
784 static int add_tcp_cache(const char *host
, const char *port
,
785 const uint8_t preference
)
787 struct rtr_socket
*rtr_socket
;
788 struct tr_tcp_config
*tcp_config
=
789 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
790 struct tr_socket
*tr_socket
=
791 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
792 struct cache
*cache
=
793 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
795 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
796 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
797 tcp_config
->bindaddr
= NULL
;
799 rtr_socket
= create_rtr_socket(tr_socket
);
802 cache
->tr_socket
= tr_socket
;
803 cache
->tr_config
.tcp_config
= tcp_config
;
804 cache
->rtr_socket
= rtr_socket
;
805 cache
->preference
= preference
;
807 return add_cache(cache
);
810 #if defined(FOUND_SSH)
811 static int add_ssh_cache(const char *host
, const unsigned int port
,
812 const char *username
, const char *client_privkey_path
,
813 const char *client_pubkey_path
,
814 const char *server_pubkey_path
,
815 const uint8_t preference
)
817 struct tr_ssh_config
*ssh_config
=
818 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
819 struct cache
*cache
=
820 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
821 struct tr_socket
*tr_socket
=
822 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
823 struct rtr_socket
*rtr_socket
;
825 ssh_config
->port
= port
;
826 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
827 ssh_config
->bindaddr
= NULL
;
829 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
830 ssh_config
->client_privkey_path
=
831 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
832 ssh_config
->server_hostkey_path
=
833 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
835 rtr_socket
= create_rtr_socket(tr_socket
);
838 cache
->tr_socket
= tr_socket
;
839 cache
->tr_config
.ssh_config
= ssh_config
;
840 cache
->rtr_socket
= rtr_socket
;
841 cache
->preference
= preference
;
843 return add_cache(cache
);
847 static void free_cache(struct cache
*cache
)
849 if (cache
->type
== TCP
) {
850 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
851 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
852 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
854 #if defined(FOUND_SSH)
856 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
857 XFREE(MTYPE_BGP_RPKI_CACHE
,
858 cache
->tr_config
.ssh_config
->username
);
859 XFREE(MTYPE_BGP_RPKI_CACHE
,
860 cache
->tr_config
.ssh_config
->client_privkey_path
);
861 XFREE(MTYPE_BGP_RPKI_CACHE
,
862 cache
->tr_config
.ssh_config
->server_hostkey_path
);
863 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
866 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
867 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
868 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
871 static int config_write(struct vty
*vty
)
873 struct listnode
*cache_node
;
876 if (listcount(cache_list
)) {
878 vty_out(vty
, "debug rpki\n");
881 vty_out(vty
, "rpki\n");
882 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
883 vty_out(vty
, " rpki timeout %d\n", timeout
);
884 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
885 initial_synchronisation_timeout
);
886 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
887 switch (cache
->type
) {
888 struct tr_tcp_config
*tcp_config
;
889 #if defined(FOUND_SSH)
890 struct tr_ssh_config
*ssh_config
;
893 tcp_config
= cache
->tr_config
.tcp_config
;
894 vty_out(vty
, " rpki cache %s %s ",
895 tcp_config
->host
, tcp_config
->port
);
897 #if defined(FOUND_SSH)
899 ssh_config
= cache
->tr_config
.ssh_config
;
900 vty_out(vty
, " rpki cache %s %u %s %s %s ",
901 ssh_config
->host
, ssh_config
->port
,
902 ssh_config
->username
,
903 ssh_config
->client_privkey_path
,
904 ssh_config
->server_hostkey_path
!= NULL
906 ->server_hostkey_path
914 vty_out(vty
, "preference %hhu\n", cache
->preference
);
916 vty_out(vty
, " exit\n");
926 "Enable rpki and enter rpki configuration mode\n")
928 vty
->node
= RPKI_NODE
;
932 DEFUN (bgp_rpki_start
,
936 "start rpki support\n")
938 if (listcount(cache_list
) == 0)
940 "Could not start rpki because no caches are configured\n");
943 if (start() == ERROR
) {
944 RPKI_DEBUG("RPKI failed to start");
951 DEFUN (bgp_rpki_stop
,
955 "start rpki support\n")
963 DEFPY (rpki_polling_period
,
964 rpki_polling_period_cmd
,
965 "rpki polling_period (1-86400)$pp",
967 "Set polling period\n"
968 "Polling period value\n")
974 DEFUN (no_rpki_polling_period
,
975 no_rpki_polling_period_cmd
,
976 "no rpki polling_period",
979 "Set polling period back to default\n")
981 polling_period
= POLLING_PERIOD_DEFAULT
;
985 DEFPY (rpki_expire_interval
,
986 rpki_expire_interval_cmd
,
987 "rpki expire_interval (600-172800)$tmp",
989 "Set expire interval\n"
990 "Expire interval value\n")
992 if ((unsigned int)tmp
>= polling_period
) {
993 expire_interval
= tmp
;
997 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
998 return CMD_WARNING_CONFIG_FAILED
;
1001 DEFUN (no_rpki_expire_interval
,
1002 no_rpki_expire_interval_cmd
,
1003 "no rpki expire_interval",
1006 "Set expire interval back to default\n")
1008 expire_interval
= polling_period
* 2;
1012 DEFPY (rpki_retry_interval
,
1013 rpki_retry_interval_cmd
,
1014 "rpki retry_interval (1-7200)$tmp",
1016 "Set retry interval\n"
1017 "retry interval value\n")
1019 retry_interval
= tmp
;
1023 DEFUN (no_rpki_retry_interval
,
1024 no_rpki_retry_interval_cmd
,
1025 "no rpki retry_interval",
1028 "Set retry interval back to default\n")
1030 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1034 DEFPY (rpki_timeout
,
1036 "rpki timeout (1-4294967295)$to_arg",
1045 DEFUN (no_rpki_timeout
,
1046 no_rpki_timeout_cmd
,
1050 "Set timeout back to default\n")
1052 timeout
= TIMEOUT_DEFAULT
;
1056 DEFPY (rpki_synchronisation_timeout
,
1057 rpki_synchronisation_timeout_cmd
,
1058 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1060 "Set a timeout for the initial synchronisation of prefix validation data\n"
1063 initial_synchronisation_timeout
= ito_arg
;
1067 DEFUN (no_rpki_synchronisation_timeout
,
1068 no_rpki_synchronisation_timeout_cmd
,
1069 "no rpki initial-synchronisation-timeout",
1072 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1074 initial_synchronisation_timeout
=
1075 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1081 "rpki cache <A.B.C.D|WORD>"
1082 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1083 "preference (1-255)",
1085 "Install a cache server to current group\n"
1086 "IP address of cache server\n Hostname of cache server\n"
1090 "Path to own SSH private key\n"
1091 "Path to own SSH public key\n"
1092 "Path to Public key of cache server\n"
1093 "Preference of the cache server\n"
1094 "Preference value\n")
1098 // use ssh connection
1100 #if defined(FOUND_SSH)
1102 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1103 ssh_pubkey
, server_pubkey
, preference
);
1105 return_value
= SUCCESS
;
1107 "ssh sockets are not supported. "
1108 "Please recompile rtrlib and frr with ssh support. "
1109 "If you want to use it");
1111 } else { // use tcp connection
1112 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1115 if (return_value
== ERROR
) {
1116 vty_out(vty
, "Could not create new rpki cache\n");
1123 DEFPY (no_rpki_cache
,
1125 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1128 "Remove a cache server\n"
1129 "IP address of cache server\n Hostname of cache server\n"
1132 "Preference of the cache server\n"
1133 "Preference value\n")
1135 struct cache
*cache_p
= find_cache(preference
);
1138 vty_out(vty
, "Could not find cache %ld\n", preference
);
1142 if (rtr_is_running
) {
1143 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1144 vty_out(vty
, "Could not remove cache %ld", preference
);
1145 if (listcount(cache_list
) == 1)
1146 vty_out(vty
, " because it is the last cache");
1153 listnode_delete(cache_list
, cache_p
);
1154 free_cache(cache_p
);
1159 DEFUN (show_rpki_prefix_table
,
1160 show_rpki_prefix_table_cmd
,
1161 "show rpki prefix-table",
1164 "Show validated prefixes which were received from RPKI Cache\n")
1166 struct listnode
*cache_node
;
1167 struct cache
*cache
;
1169 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1170 vty_out(vty
, "host: %s port: %s\n",
1171 cache
->tr_config
.tcp_config
->host
,
1172 cache
->tr_config
.tcp_config
->port
);
1174 if (is_synchronized())
1175 print_prefix_table(vty
);
1177 vty_out(vty
, "No connection to RPKI cache server.\n");
1182 DEFUN (show_rpki_cache_server
,
1183 show_rpki_cache_server_cmd
,
1184 "show rpki cache-server",
1187 "SHOW configured cache server\n")
1189 struct listnode
*cache_node
;
1190 struct cache
*cache
;
1192 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1193 vty_out(vty
, "host: %s port: %s\n",
1194 cache
->tr_config
.tcp_config
->host
,
1195 cache
->tr_config
.tcp_config
->port
);
1201 DEFUN (show_rpki_cache_connection
,
1202 show_rpki_cache_connection_cmd
,
1203 "show rpki cache-connection",
1206 "Show to which RPKI Cache Servers we have a connection\n")
1208 if (is_synchronized()) {
1209 struct listnode
*cache_node
;
1210 struct cache
*cache
;
1211 struct rtr_mgr_group
*group
= get_connected_group();
1214 vty_out(vty
, "Cannot find a connected group.\n");
1217 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1218 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1219 if (cache
->preference
== group
->preference
) {
1220 struct tr_tcp_config
*tcp_config
;
1221 #if defined(FOUND_SSH)
1222 struct tr_ssh_config
*ssh_config
;
1225 switch (cache
->type
) {
1228 cache
->tr_config
.tcp_config
;
1230 "rpki tcp cache %s %s pref %hhu\n",
1236 #if defined(FOUND_SSH)
1239 cache
->tr_config
.ssh_config
;
1241 "rpki ssh cache %s %u pref %hhu\n",
1254 vty_out(vty
, "No connection to RPKI cache server.\n");
1260 DEFUN_NOSH (rpki_exit
,
1263 "Exit rpki configuration and restart rpki session\n")
1267 vty
->node
= CONFIG_NODE
;
1271 DEFUN_NOSH (rpki_quit
,
1274 "Exit rpki configuration mode\n")
1276 return rpki_exit(self
, vty
, argc
, argv
);
1279 DEFUN_NOSH (rpki_end
,
1282 "End rpki configuration, restart rpki session and change to enable mode.\n")
1284 int ret
= reset(false);
1286 vty_config_exit(vty
);
1287 vty
->node
= ENABLE_NODE
;
1288 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1297 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1304 "Enable debugging for rpki\n")
1310 DEFUN (no_debug_rpki
,
1315 "Disable debugging for rpki\n")
1323 "match rpki <valid|invalid|notfound>",
1328 "Prefix not found\n")
1330 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1333 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1336 case RMAP_RULE_MISSING
:
1337 vty_out(vty
, "%% BGP Can't find rule.\n");
1338 return CMD_WARNING_CONFIG_FAILED
;
1339 case RMAP_COMPILE_ERROR
:
1340 vty_out(vty
, "%% BGP Argument is malformed.\n");
1341 return CMD_WARNING_CONFIG_FAILED
;
1347 DEFUN (no_match_rpki
,
1349 "no match rpki <valid|invalid|notfound>",
1355 "Prefix not found\n")
1357 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1360 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1363 case RMAP_RULE_MISSING
:
1364 vty_out(vty
, "%% BGP Can't find rule.\n");
1366 case RMAP_COMPILE_ERROR
:
1367 vty_out(vty
, "%% BGP Argument is malformed.\n");
1370 return CMD_WARNING_CONFIG_FAILED
;
1376 static void overwrite_exit_commands(void)
1379 vector cmd_vector
= rpki_node
.cmd_vector
;
1381 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1382 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1384 if (strcmp(cmd
->string
, "exit") == 0
1385 || strcmp(cmd
->string
, "quit") == 0
1386 || strcmp(cmd
->string
, "end") == 0) {
1387 uninstall_element(RPKI_NODE
, cmd
);
1391 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1392 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1393 install_element(RPKI_NODE
, &rpki_end_cmd
);
1396 static void install_cli_commands(void)
1398 // TODO: make config write work
1399 install_node(&rpki_node
, &config_write
);
1400 install_default(RPKI_NODE
);
1401 overwrite_exit_commands();
1402 install_element(CONFIG_NODE
, &rpki_cmd
);
1403 install_element(VIEW_NODE
, &rpki_cmd
);
1405 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1406 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1408 /* Install rpki reset command */
1409 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1411 /* Install rpki polling period commands */
1412 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1413 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1415 /* Install rpki expire interval commands */
1416 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1417 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1419 /* Install rpki retry interval commands */
1420 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1421 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1423 /* Install rpki timeout commands */
1424 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1425 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1427 /* Install rpki synchronisation timeout commands */
1428 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1429 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1431 /* Install rpki cache commands */
1432 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1433 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1435 /* Install show commands */
1436 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1437 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1438 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1440 /* Install debug commands */
1441 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1442 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1443 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1444 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1446 /* Install route match */
1447 route_map_install_match(&route_match_rpki_cmd
);
1448 install_element(RMAP_NODE
, &match_rpki_cmd
);
1449 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1452 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1453 .description
= "Enable RPKI support for FRR.",
1454 .init
= bgp_rpki_module_init
)