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 #include "rtrlib/rtrlib.h"
53 #include "rtrlib/rtr_mgr.h"
54 #include "rtrlib/lib/ip.h"
55 #include "rtrlib/transport/tcp/tcp_transport.h"
56 #if defined(FOUND_SSH)
57 #include "rtrlib/transport/ssh/ssh_transport.h"
63 #ifndef VTYSH_EXTRACT_PL
64 #include "bgpd/bgp_rpki_clippy.c"
67 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
68 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
71 #define RPKI_NOTFOUND 2
72 #define RPKI_INVALID 3
74 #define POLLING_PERIOD_DEFAULT 3600
75 #define EXPIRE_INTERVAL_DEFAULT 7200
76 #define RETRY_INTERVAL_DEFAULT 600
77 #define TIMEOUT_DEFAULT 600
78 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
80 #define RPKI_DEBUG(...) \
82 zlog_debug("RPKI: " __VA_ARGS__); \
85 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
88 enum { TCP
, SSH
} type
;
89 struct tr_socket
*tr_socket
;
91 struct tr_tcp_config
*tcp_config
;
92 struct tr_ssh_config
*ssh_config
;
94 struct rtr_socket
*rtr_socket
;
98 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
100 struct rpki_for_each_record_arg
{
102 unsigned int *prefix_amount
;
105 static int start(void);
106 static void stop(void);
107 static int reset(bool force
);
108 static struct rtr_mgr_group
*get_connected_group(void);
109 static void print_prefix_table(struct vty
*vty
);
110 static void install_cli_commands(void);
111 static int config_write(struct vty
*vty
);
112 static void overwrite_exit_commands(void);
113 static void free_cache(struct cache
*cache
);
114 static struct rtr_mgr_group
*get_groups(void);
115 #if defined(FOUND_SSH)
116 static int add_ssh_cache(const char *host
, const unsigned int port
,
117 const char *username
, const char *client_privkey_path
,
118 const char *client_pubkey_path
,
119 const char *server_pubkey_path
,
120 const uint8_t preference
);
122 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
123 static struct cache
*find_cache(const uint8_t preference
);
124 static int add_tcp_cache(const char *host
, const char *port
,
125 const uint8_t preference
);
126 static void print_record(const struct pfx_record
*record
, void *data
);
127 static int is_synchronized(void);
128 static int is_running(void);
129 static void route_match_free(void *rule
);
130 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
131 route_map_object_t type
, void *object
);
132 static void *route_match_compile(const char *arg
);
133 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
135 static void revalidate_all_routes(void);
137 static struct rtr_mgr_config
*rtr_config
;
138 static struct list
*cache_list
;
139 static int rtr_is_running
;
140 static int rtr_is_stopping
;
141 static int rtr_is_starting
;
142 static _Atomic
int rtr_update_overflow
;
143 static int rpki_debug
;
144 static unsigned int polling_period
;
145 static unsigned int expire_interval
;
146 static unsigned int retry_interval
;
147 static unsigned int timeout
;
148 static unsigned int initial_synchronisation_timeout
;
149 static int rpki_sync_socket_rtr
;
150 static int rpki_sync_socket_bgpd
;
152 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
153 static struct route_map_rule_cmd route_match_rpki_cmd
= {
154 "rpki", route_match
, route_match_compile
, route_match_free
};
156 static void *malloc_wrapper(size_t size
)
158 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
161 static void *realloc_wrapper(void *ptr
, size_t size
)
163 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
166 static void free_wrapper(void *ptr
)
168 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
171 static void init_tr_socket(struct cache
*cache
)
173 if (cache
->type
== TCP
)
174 tr_tcp_init(cache
->tr_config
.tcp_config
,
176 #if defined(FOUND_SSH)
178 tr_ssh_init(cache
->tr_config
.ssh_config
,
183 static void free_tr_socket(struct cache
*cache
)
185 if (cache
->type
== TCP
)
186 tr_tcp_init(cache
->tr_config
.tcp_config
,
188 #if defined(FOUND_SSH)
190 tr_ssh_init(cache
->tr_config
.ssh_config
,
195 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
196 const struct prefix
*prefix
);
198 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
202 for (i
= 0; i
< 4; i
++)
203 dest
[i
] = htonl(src
[i
]);
206 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
210 for (i
= 0; i
< 4; i
++)
211 dest
[i
] = ntohl(src
[i
]);
214 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
215 route_map_object_t type
, void *object
)
217 int *rpki_status
= rule
;
218 struct bgp_info
*bgp_info
;
220 if (type
== RMAP_BGP
) {
223 if (rpki_validate_prefix(bgp_info
->peer
, bgp_info
->attr
, prefix
)
231 static void *route_match_compile(const char *arg
)
235 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
237 if (strcmp(arg
, "valid") == 0)
238 *rpki_status
= RPKI_VALID
;
239 else if (strcmp(arg
, "invalid") == 0)
240 *rpki_status
= RPKI_INVALID
;
242 *rpki_status
= RPKI_NOTFOUND
;
247 static void route_match_free(void *rule
)
249 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
252 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
254 struct rtr_socket
*rtr_socket
=
255 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
256 rtr_socket
->tr_socket
= tr_socket
;
260 static struct cache
*find_cache(const uint8_t preference
)
262 struct listnode
*cache_node
;
265 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
266 if (cache
->preference
== preference
)
272 static void print_record(const struct pfx_record
*record
, void *data
)
274 char ip
[INET6_ADDRSTRLEN
];
275 struct rpki_for_each_record_arg
*arg
= data
;
276 struct vty
*vty
= arg
->vty
;
278 (*arg
->prefix_amount
)++;
280 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
281 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
282 record
->max_len
, record
->asn
);
285 static struct rtr_mgr_group
*get_groups(void)
287 struct listnode
*cache_node
;
288 struct rtr_mgr_group
*rtr_mgr_groups
;
291 int group_count
= listcount(cache_list
);
293 if (group_count
== 0)
296 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
297 group_count
* sizeof(struct rtr_mgr_group
));
301 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
302 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
303 rtr_mgr_groups
[i
].sockets_len
= 1;
304 rtr_mgr_groups
[i
].preference
= cache
->preference
;
306 init_tr_socket(cache
);
311 return rtr_mgr_groups
;
314 inline int is_synchronized(void)
316 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
319 inline int is_running(void)
321 return rtr_is_running
;
324 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
326 struct prefix
*prefix
= prefix_new();
328 prefix
->prefixlen
= record
->min_len
;
330 if (record
->prefix
.ver
== LRTR_IPV4
) {
331 prefix
->family
= AF_INET
;
332 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
334 prefix
->family
= AF_INET6
;
335 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
336 prefix
->u
.prefix6
.s6_addr32
);
342 static int bgpd_sync_callback(struct thread
*thread
)
345 struct listnode
*node
;
346 struct prefix
*prefix
;
347 struct pfx_record rec
;
349 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
350 rpki_sync_socket_bgpd
, NULL
);
352 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
353 while (read(rpki_sync_socket_bgpd
, &rec
,
354 sizeof(struct pfx_record
))
358 atomic_store_explicit(&rtr_update_overflow
, 0,
359 memory_order_seq_cst
);
360 revalidate_all_routes();
365 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
366 if (retval
!= sizeof(struct pfx_record
)) {
367 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
370 prefix
= pfx_record_to_prefix(&rec
);
372 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
374 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
376 struct listnode
*peer_listnode
;
378 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
381 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
382 if (!peer
->bgp
->rib
[afi
][safi
])
385 struct list
*matches
= list_new();
388 (void (*)(void *))bgp_unlock_node
;
390 bgp_table_range_lookup(
391 peer
->bgp
->rib
[afi
][safi
], prefix
,
392 rec
.max_len
, matches
);
395 struct bgp_node
*bgp_node
;
396 struct listnode
*bgp_listnode
;
398 for (ALL_LIST_ELEMENTS_RO(matches
, bgp_listnode
,
400 revalidate_bgp_node(bgp_node
, afi
,
403 list_delete_and_null(&matches
);
412 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
415 struct bgp_adj_in
*ain
;
417 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
419 struct bgp_info
*bgp_info
= bgp_node
->info
;
420 mpls_label_t
*label
= NULL
;
421 uint32_t num_labels
= 0;
423 if (bgp_info
&& bgp_info
->extra
) {
424 label
= bgp_info
->extra
->label
;
425 num_labels
= bgp_info
->extra
->num_labels
;
427 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
428 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
429 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
437 static void revalidate_all_routes(void)
440 struct listnode
*node
;
442 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
444 struct listnode
*peer_listnode
;
446 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
448 for (size_t i
= 0; i
< 2; i
++) {
450 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
452 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
454 if (!peer
->bgp
->rib
[afi
][safi
])
457 bgp_soft_reconfig_in(peer
, afi
, safi
);
464 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
465 const struct pfx_record rec
,
466 const bool added
__attribute__((unused
)))
468 if (rtr_is_stopping
|| rtr_is_starting
469 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
473 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
474 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
475 atomic_store_explicit(&rtr_update_overflow
, 1,
476 memory_order_seq_cst
);
478 else if (retval
!= sizeof(struct pfx_record
))
479 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
482 static void rpki_init_sync_socket(void)
487 RPKI_DEBUG("initializing sync socket");
488 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
489 msg
= "could not open rpki sync socketpair";
492 rpki_sync_socket_rtr
= fds
[0];
493 rpki_sync_socket_bgpd
= fds
[1];
495 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
496 msg
= "could not set rpki_sync_socket_rtr to non blocking";
500 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
501 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
506 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
507 rpki_sync_socket_bgpd
, NULL
);
512 zlog_err("RPKI: %s", msg
);
517 static int bgp_rpki_init(struct thread_master
*master
)
523 cache_list
= list_new();
524 cache_list
->del
= (void (*)(void *)) & free_cache
;
526 polling_period
= POLLING_PERIOD_DEFAULT
;
527 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
528 retry_interval
= RETRY_INTERVAL_DEFAULT
;
529 timeout
= TIMEOUT_DEFAULT
;
530 initial_synchronisation_timeout
=
531 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
532 install_cli_commands();
533 rpki_init_sync_socket();
537 static int bgp_rpki_fini(void)
540 list_delete_and_null(&cache_list
);
542 close(rpki_sync_socket_rtr
);
543 close(rpki_sync_socket_bgpd
);
548 static int bgp_rpki_module_init(void)
550 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
552 hook_register(frr_late_init
, bgp_rpki_init
);
553 hook_register(frr_early_fini
, &bgp_rpki_fini
);
558 static int start(void)
560 unsigned int waiting_time
= 0;
565 rtr_update_overflow
= 0;
567 if (list_isempty(cache_list
)) {
569 "No caches were found in config. Prefix validation is off.");
572 RPKI_DEBUG("Init rtr_mgr.");
573 int groups_len
= listcount(cache_list
);
574 struct rtr_mgr_group
*groups
= get_groups();
576 RPKI_DEBUG("Polling period: %d", polling_period
);
577 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
578 expire_interval
, retry_interval
,
579 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
580 if (ret
== RTR_ERROR
) {
581 RPKI_DEBUG("Init rtr_mgr failed.");
585 RPKI_DEBUG("Starting rtr_mgr.");
586 ret
= rtr_mgr_start(rtr_config
);
587 if (ret
== RTR_ERROR
) {
588 RPKI_DEBUG("Starting rtr_mgr failed.");
589 rtr_mgr_free(rtr_config
);
593 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
594 while (waiting_time
++ <= initial_synchronisation_timeout
) {
595 if (rtr_mgr_conf_in_sync(rtr_config
))
600 if (rtr_mgr_conf_in_sync(rtr_config
)) {
601 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
602 RPKI_DEBUG("Forcing revalidation.");
604 revalidate_all_routes();
607 "Timeout expired! Proceeding without RPKI validation data.");
611 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
616 static void stop(void)
619 if (rtr_is_running
) {
620 rtr_mgr_stop(rtr_config
);
621 rtr_mgr_free(rtr_config
);
626 static int reset(bool force
)
628 if (rtr_is_running
&& !force
)
631 RPKI_DEBUG("Resetting RPKI Session");
636 static struct rtr_mgr_group
*get_connected_group(void)
638 if (!cache_list
|| list_isempty(cache_list
))
641 return rtr_mgr_get_first_group(rtr_config
);
644 static void print_prefix_table(struct vty
*vty
)
646 struct rpki_for_each_record_arg arg
;
648 unsigned int number_of_ipv4_prefixes
= 0;
649 unsigned int number_of_ipv6_prefixes
= 0;
650 struct rtr_mgr_group
*group
= get_connected_group();
657 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
659 vty_out(vty
, "RPKI/RTR prefix table\n");
660 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
662 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
663 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
665 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
666 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
668 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
669 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
672 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
673 const struct prefix
*prefix
)
675 struct assegment
*as_segment
;
677 struct lrtr_ip_addr ip_addr_prefix
;
678 enum pfxv_state result
;
680 const char *prefix_string
;
682 if (!is_synchronized())
685 // No aspath means route comes from iBGP
686 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
688 as_number
= peer
->bgp
->as
;
690 as_segment
= attr
->aspath
->segments
;
691 // Find last AsSegment
692 while (as_segment
->next
)
693 as_segment
= as_segment
->next
;
695 if (as_segment
->type
== AS_SEQUENCE
) {
697 as_number
= as_segment
->as
[as_segment
->length
- 1];
698 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
699 || as_segment
->type
== AS_CONFED_SET
) {
701 as_number
= peer
->bgp
->as
;
703 // RFC says: "Take distinguished value NONE as asn"
704 // which means state is unknown
705 return RPKI_NOTFOUND
;
709 // Get the prefix in requested format
710 switch (prefix
->family
) {
712 ip_addr_prefix
.ver
= LRTR_IPV4
;
713 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
717 ip_addr_prefix
.ver
= LRTR_IPV6
;
718 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
719 ip_addr_prefix
.u
.addr6
.addr
);
726 // Do the actual validation
727 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
728 prefix
->prefixlen
, &result
);
730 // Print Debug output
732 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
734 case BGP_PFXV_STATE_VALID
:
736 "Validating Prefix %s/%hhu from asn %u Result: VALID",
737 prefix_string
, prefix
->prefixlen
, as_number
);
739 case BGP_PFXV_STATE_NOT_FOUND
:
741 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
742 prefix_string
, prefix
->prefixlen
, as_number
);
743 return RPKI_NOTFOUND
;
744 case BGP_PFXV_STATE_INVALID
:
746 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
747 prefix_string
, prefix
->prefixlen
, as_number
);
751 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
752 prefix_string
, prefix
->prefixlen
, as_number
);
758 static int add_cache(struct cache
*cache
)
760 uint8_t preference
= cache
->preference
;
761 struct rtr_mgr_group group
;
763 group
.preference
= preference
;
764 group
.sockets_len
= 1;
765 group
.sockets
= &cache
->rtr_socket
;
767 listnode_add(cache_list
, cache
);
769 if (rtr_is_running
) {
770 init_tr_socket(cache
);
772 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
773 free_tr_socket(cache
);
781 static int add_tcp_cache(const char *host
, const char *port
,
782 const uint8_t preference
)
784 struct rtr_socket
*rtr_socket
;
785 struct tr_tcp_config
*tcp_config
=
786 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
787 struct tr_socket
*tr_socket
=
788 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
789 struct cache
*cache
=
790 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
792 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
793 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
794 tcp_config
->bindaddr
= NULL
;
796 rtr_socket
= create_rtr_socket(tr_socket
);
799 cache
->tr_socket
= tr_socket
;
800 cache
->tr_config
.tcp_config
= tcp_config
;
801 cache
->rtr_socket
= rtr_socket
;
802 cache
->preference
= preference
;
804 return add_cache(cache
);
807 #if defined(FOUND_SSH)
808 static int add_ssh_cache(const char *host
, const unsigned int port
,
809 const char *username
, const char *client_privkey_path
,
810 const char *client_pubkey_path
,
811 const char *server_pubkey_path
,
812 const uint8_t preference
)
814 struct tr_ssh_config
*ssh_config
=
815 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
816 struct cache
*cache
=
817 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
818 struct tr_socket
*tr_socket
=
819 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
820 struct rtr_socket
*rtr_socket
;
822 ssh_config
->port
= port
;
823 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
824 ssh_config
->bindaddr
= NULL
;
826 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
827 ssh_config
->client_privkey_path
=
828 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
829 ssh_config
->server_hostkey_path
=
830 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
832 rtr_socket
= create_rtr_socket(tr_socket
);
835 cache
->tr_socket
= tr_socket
;
836 cache
->tr_config
.ssh_config
= ssh_config
;
837 cache
->rtr_socket
= rtr_socket
;
838 cache
->preference
= preference
;
840 return add_cache(cache
);
844 static void free_cache(struct cache
*cache
)
846 if (cache
->type
== TCP
) {
847 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
848 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
849 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
851 #if defined(FOUND_SSH)
853 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
854 XFREE(MTYPE_BGP_RPKI_CACHE
,
855 cache
->tr_config
.ssh_config
->username
);
856 XFREE(MTYPE_BGP_RPKI_CACHE
,
857 cache
->tr_config
.ssh_config
->client_privkey_path
);
858 XFREE(MTYPE_BGP_RPKI_CACHE
,
859 cache
->tr_config
.ssh_config
->server_hostkey_path
);
860 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
863 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
864 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
865 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
868 static int config_write(struct vty
*vty
)
870 struct listnode
*cache_node
;
873 if (listcount(cache_list
)) {
875 vty_out(vty
, "debug rpki\n");
878 vty_out(vty
, "rpki\n");
879 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
880 vty_out(vty
, " rpki timeout %d\n", timeout
);
881 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
882 initial_synchronisation_timeout
);
883 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
884 switch (cache
->type
) {
885 struct tr_tcp_config
*tcp_config
;
886 #if defined(FOUND_SSH)
887 struct tr_ssh_config
*ssh_config
;
890 tcp_config
= cache
->tr_config
.tcp_config
;
891 vty_out(vty
, " rpki cache %s %s ",
892 tcp_config
->host
, tcp_config
->port
);
894 #if defined(FOUND_SSH)
896 ssh_config
= cache
->tr_config
.ssh_config
;
897 vty_out(vty
, " rpki cache %s %u %s %s %s ",
898 ssh_config
->host
, ssh_config
->port
,
899 ssh_config
->username
,
900 ssh_config
->client_privkey_path
,
901 ssh_config
->server_hostkey_path
!= NULL
903 ->server_hostkey_path
911 vty_out(vty
, "preference %hhu\n", cache
->preference
);
913 vty_out(vty
, " exit\n");
923 "Enable rpki and enter rpki configuration mode\n")
925 vty
->node
= RPKI_NODE
;
929 DEFUN (bgp_rpki_start
,
933 "start rpki support\n")
935 if (listcount(cache_list
) == 0)
937 "Could not start rpki because no caches are configured\n");
940 if (start() == ERROR
) {
941 RPKI_DEBUG("RPKI failed to start");
948 DEFUN (bgp_rpki_stop
,
952 "start rpki support\n")
960 DEFPY (rpki_polling_period
,
961 rpki_polling_period_cmd
,
962 "rpki polling_period (1-86400)$pp",
964 "Set polling period\n"
965 "Polling period value\n")
971 DEFUN (no_rpki_polling_period
,
972 no_rpki_polling_period_cmd
,
973 "no rpki polling_period",
976 "Set polling period back to default\n")
978 polling_period
= POLLING_PERIOD_DEFAULT
;
982 DEFPY (rpki_expire_interval
,
983 rpki_expire_interval_cmd
,
984 "rpki expire_interval (600-172800)$tmp",
986 "Set expire interval\n"
987 "Expire interval value\n")
989 if ((unsigned int)tmp
>= polling_period
) {
990 expire_interval
= tmp
;
994 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
995 return CMD_WARNING_CONFIG_FAILED
;
998 DEFUN (no_rpki_expire_interval
,
999 no_rpki_expire_interval_cmd
,
1000 "no rpki expire_interval",
1003 "Set expire interval back to default\n")
1005 expire_interval
= polling_period
* 2;
1009 DEFPY (rpki_retry_interval
,
1010 rpki_retry_interval_cmd
,
1011 "rpki retry_interval (1-7200)$tmp",
1013 "Set retry interval\n"
1014 "retry interval value\n")
1016 retry_interval
= tmp
;
1020 DEFUN (no_rpki_retry_interval
,
1021 no_rpki_retry_interval_cmd
,
1022 "no rpki retry_interval",
1025 "Set retry interval back to default\n")
1027 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1031 DEFPY (rpki_timeout
,
1033 "rpki timeout (1-4294967295)$to_arg",
1042 DEFUN (no_rpki_timeout
,
1043 no_rpki_timeout_cmd
,
1047 "Set timeout back to default\n")
1049 timeout
= TIMEOUT_DEFAULT
;
1053 DEFPY (rpki_synchronisation_timeout
,
1054 rpki_synchronisation_timeout_cmd
,
1055 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1057 "Set a timeout for the initial synchronisation of prefix validation data\n"
1060 initial_synchronisation_timeout
= ito_arg
;
1064 DEFUN (no_rpki_synchronisation_timeout
,
1065 no_rpki_synchronisation_timeout_cmd
,
1066 "no rpki initial-synchronisation-timeout",
1069 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1071 initial_synchronisation_timeout
=
1072 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1078 "rpki cache <A.B.C.D|WORD>"
1079 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1080 "preference (1-255)",
1082 "Install a cache server to current group\n"
1083 "IP address of cache server\n Hostname of cache server\n"
1087 "Path to own SSH private key\n"
1088 "Path to own SSH public key\n"
1089 "Path to Public key of cache server\n"
1090 "Preference of the cache server\n"
1091 "Preference value\n")
1095 // use ssh connection
1097 #if defined(FOUND_SSH)
1099 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1100 ssh_pubkey
, server_pubkey
, preference
);
1102 return_value
= SUCCESS
;
1104 "ssh sockets are not supported. "
1105 "Please recompile rtrlib and frr with ssh support. "
1106 "If you want to use it");
1108 } else { // use tcp connection
1109 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1112 if (return_value
== ERROR
) {
1113 vty_out(vty
, "Could not create new rpki cache\n");
1120 DEFPY (no_rpki_cache
,
1122 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1125 "Remove a cache server\n"
1126 "IP address of cache server\n Hostname of cache server\n"
1129 "Preference of the cache server\n"
1130 "Preference value\n")
1132 struct cache
*cache_p
= find_cache(preference
);
1135 vty_out(vty
, "Could not find cache %ld\n", preference
);
1139 if (rtr_is_running
) {
1140 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1141 vty_out(vty
, "Could not remove cache %ld", preference
);
1142 if (listcount(cache_list
) == 1)
1143 vty_out(vty
, " because it is the last cache");
1150 listnode_delete(cache_list
, cache_p
);
1151 free_cache(cache_p
);
1156 DEFUN (show_rpki_prefix_table
,
1157 show_rpki_prefix_table_cmd
,
1158 "show rpki prefix-table",
1161 "Show validated prefixes which were received from RPKI Cache\n")
1163 struct listnode
*cache_node
;
1164 struct cache
*cache
;
1166 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1167 vty_out(vty
, "host: %s port: %s\n",
1168 cache
->tr_config
.tcp_config
->host
,
1169 cache
->tr_config
.tcp_config
->port
);
1171 if (is_synchronized())
1172 print_prefix_table(vty
);
1174 vty_out(vty
, "No connection to RPKI cache server.\n");
1179 DEFUN (show_rpki_cache_server
,
1180 show_rpki_cache_server_cmd
,
1181 "show rpki cache-server",
1184 "SHOW configured cache server\n")
1186 struct listnode
*cache_node
;
1187 struct cache
*cache
;
1189 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1190 vty_out(vty
, "host: %s port: %s\n",
1191 cache
->tr_config
.tcp_config
->host
,
1192 cache
->tr_config
.tcp_config
->port
);
1198 DEFUN (show_rpki_cache_connection
,
1199 show_rpki_cache_connection_cmd
,
1200 "show rpki cache-connection",
1203 "Show to which RPKI Cache Servers we have a connection\n")
1205 if (is_synchronized()) {
1206 struct listnode
*cache_node
;
1207 struct cache
*cache
;
1208 struct rtr_mgr_group
*group
= get_connected_group();
1211 vty_out(vty
, "Cannot find a connected group.\n");
1214 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1215 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1216 if (cache
->preference
== group
->preference
) {
1217 struct tr_tcp_config
*tcp_config
;
1218 #if defined(FOUND_SSH)
1219 struct tr_ssh_config
*ssh_config
;
1222 switch (cache
->type
) {
1225 cache
->tr_config
.tcp_config
;
1227 "rpki tcp cache %s %s pref %hhu\n",
1233 #if defined(FOUND_SSH)
1236 cache
->tr_config
.ssh_config
;
1238 "rpki ssh cache %s %u pref %hhu\n",
1251 vty_out(vty
, "No connection to RPKI cache server.\n");
1257 DEFUN_NOSH (rpki_exit
,
1260 "Exit rpki configuration and restart rpki session\n")
1264 vty
->node
= CONFIG_NODE
;
1268 DEFUN_NOSH (rpki_quit
,
1271 "Exit rpki configuration mode\n")
1273 return rpki_exit(self
, vty
, argc
, argv
);
1276 DEFUN_NOSH (rpki_end
,
1279 "End rpki configuration, restart rpki session and change to enable mode.\n")
1281 int ret
= reset(false);
1283 vty_config_unlock(vty
);
1284 vty
->node
= ENABLE_NODE
;
1285 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1294 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1301 "Enable debugging for rpki\n")
1307 DEFUN (no_debug_rpki
,
1312 "Disable debugging for rpki\n")
1320 "match rpki <valid|invalid|notfound>",
1325 "Prefix not found\n")
1327 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1330 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1333 case RMAP_RULE_MISSING
:
1334 vty_out(vty
, "%% BGP Can't find rule.\n");
1335 return CMD_WARNING_CONFIG_FAILED
;
1336 case RMAP_COMPILE_ERROR
:
1337 vty_out(vty
, "%% BGP Argument is malformed.\n");
1338 return CMD_WARNING_CONFIG_FAILED
;
1344 DEFUN (no_match_rpki
,
1346 "no match rpki <valid|invalid|notfound>",
1352 "Prefix not found\n")
1354 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1357 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1360 case RMAP_RULE_MISSING
:
1361 vty_out(vty
, "%% BGP Can't find rule.\n");
1363 case RMAP_COMPILE_ERROR
:
1364 vty_out(vty
, "%% BGP Argument is malformed.\n");
1367 return CMD_WARNING_CONFIG_FAILED
;
1373 static void overwrite_exit_commands(void)
1376 vector cmd_vector
= rpki_node
.cmd_vector
;
1378 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1379 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1381 if (strcmp(cmd
->string
, "exit") == 0
1382 || strcmp(cmd
->string
, "quit") == 0
1383 || strcmp(cmd
->string
, "end") == 0) {
1384 uninstall_element(RPKI_NODE
, cmd
);
1388 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1389 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1390 install_element(RPKI_NODE
, &rpki_end_cmd
);
1393 static void install_cli_commands(void)
1395 // TODO: make config write work
1396 install_node(&rpki_node
, &config_write
);
1397 install_default(RPKI_NODE
);
1398 overwrite_exit_commands();
1399 install_element(CONFIG_NODE
, &rpki_cmd
);
1400 install_element(VIEW_NODE
, &rpki_cmd
);
1402 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1403 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1405 /* Install rpki reset command */
1406 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1408 /* Install rpki polling period commands */
1409 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1410 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1412 /* Install rpki expire interval commands */
1413 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1414 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1416 /* Install rpki retry interval commands */
1417 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1418 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1420 /* Install rpki timeout commands */
1421 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1422 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1424 /* Install rpki synchronisation timeout commands */
1425 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1426 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1428 /* Install rpki cache commands */
1429 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1430 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1432 /* Install show commands */
1433 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1434 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1435 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1437 /* Install debug commands */
1438 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1439 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1440 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1441 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1443 /* Install route match */
1444 route_map_install_match(&route_match_rpki_cmd
);
1445 install_element(RMAP_NODE
, &match_rpki_cmd
);
1446 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1449 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1450 .description
= "Enable RPKI support for FRR.",
1451 .init
= bgp_rpki_module_init
)