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/thread.h"
51 #include "rtrlib/rtrlib.h"
52 #include "rtrlib/rtr_mgr.h"
53 #include "rtrlib/lib/ip.h"
54 #include "rtrlib/transport/tcp/tcp_transport.h"
55 #if defined(FOUND_SSH)
56 #include "rtrlib/transport/ssh/ssh_transport.h"
62 #ifndef VTYSH_EXTRACT_PL
63 #include "bgpd/bgp_rpki_clippy.c"
66 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
67 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
70 #define RPKI_NOTFOUND 2
71 #define RPKI_INVALID 3
73 #define POLLING_PERIOD_DEFAULT 3600
74 #define EXPIRE_INTERVAL_DEFAULT 7200
75 #define RETRY_INTERVAL_DEFAULT 600
76 #define TIMEOUT_DEFAULT 600
77 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
79 #define RPKI_DEBUG(...) \
81 zlog_debug("RPKI: " __VA_ARGS__); \
84 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
87 enum { TCP
, SSH
} type
;
88 struct tr_socket
*tr_socket
;
90 struct tr_tcp_config
*tcp_config
;
91 struct tr_ssh_config
*ssh_config
;
93 struct rtr_socket
*rtr_socket
;
97 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
99 struct rpki_for_each_record_arg
{
101 unsigned int *prefix_amount
;
104 static int start(void);
105 static void stop(void);
106 static int reset(bool force
);
107 static struct rtr_mgr_group
*get_connected_group(void);
108 static void print_prefix_table(struct vty
*vty
);
109 static void install_cli_commands(void);
110 static int config_write(struct vty
*vty
);
111 static void overwrite_exit_commands(void);
112 static void free_cache(struct cache
*cache
);
113 static struct rtr_mgr_group
*get_groups(void);
114 #if defined(FOUND_SSH)
115 static int add_ssh_cache(const char *host
, const unsigned int port
,
116 const char *username
, const char *client_privkey_path
,
117 const char *client_pubkey_path
,
118 const char *server_pubkey_path
,
119 const uint8_t preference
);
121 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
122 static struct cache
*find_cache(const uint8_t preference
);
123 static int add_tcp_cache(const char *host
, const char *port
,
124 const uint8_t preference
);
125 static void print_record(const struct pfx_record
*record
, void *data
);
126 static int is_synchronized(void);
127 static int is_running(void);
128 static void route_match_free(void *rule
);
129 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
130 route_map_object_t type
, void *object
);
131 static void *route_match_compile(const char *arg
);
132 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
135 static struct rtr_mgr_config
*rtr_config
;
136 static struct list
*cache_list
;
137 static int rtr_is_running
;
138 static int rtr_is_stopping
;
139 static int rtr_is_starting
;
140 static int rpki_debug
;
141 static unsigned int polling_period
;
142 static unsigned int expire_interval
;
143 static unsigned int retry_interval
;
144 static unsigned int timeout
;
145 static unsigned int initial_synchronisation_timeout
;
146 static int rpki_sync_socket_rtr
;
147 static int rpki_sync_socket_bgpd
;
149 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
150 static struct route_map_rule_cmd route_match_rpki_cmd
= {
151 "rpki", route_match
, route_match_compile
, route_match_free
};
153 static void *malloc_wrapper(size_t size
)
155 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
158 static void *realloc_wrapper(void *ptr
, size_t size
)
160 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
163 static void free_wrapper(void *ptr
)
165 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
168 static void init_tr_socket(struct cache
*cache
)
170 if (cache
->type
== TCP
)
171 tr_tcp_init(cache
->tr_config
.tcp_config
,
173 #if defined(FOUND_SSH)
175 tr_ssh_init(cache
->tr_config
.ssh_config
,
180 static void free_tr_socket(struct cache
*cache
)
182 if (cache
->type
== TCP
)
183 tr_tcp_init(cache
->tr_config
.tcp_config
,
185 #if defined(FOUND_SSH)
187 tr_ssh_init(cache
->tr_config
.ssh_config
,
192 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
193 const struct prefix
*prefix
);
195 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
199 for (i
= 0; i
< 4; i
++)
200 dest
[i
] = htonl(src
[i
]);
203 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
207 for (i
= 0; i
< 4; i
++)
208 dest
[i
] = ntohl(src
[i
]);
211 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
212 route_map_object_t type
, void *object
)
214 int *rpki_status
= rule
;
215 struct bgp_info
*bgp_info
;
217 if (type
== RMAP_BGP
) {
220 if (rpki_validate_prefix(bgp_info
->peer
, bgp_info
->attr
, prefix
)
228 static void *route_match_compile(const char *arg
)
232 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(uint8_t));
234 if (strcmp(arg
, "valid") == 0)
235 *rpki_status
= RPKI_VALID
;
236 else if (strcmp(arg
, "invalid") == 0)
237 *rpki_status
= RPKI_INVALID
;
239 *rpki_status
= RPKI_NOTFOUND
;
244 static void route_match_free(void *rule
)
246 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
249 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
251 struct rtr_socket
*rtr_socket
=
252 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
253 rtr_socket
->tr_socket
= tr_socket
;
257 static struct cache
*find_cache(const uint8_t preference
)
259 struct listnode
*cache_node
;
262 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
263 if (cache
->preference
== preference
)
269 static void print_record(const struct pfx_record
*record
, void *data
)
271 char ip
[INET6_ADDRSTRLEN
];
272 struct rpki_for_each_record_arg
*arg
= data
;
273 struct vty
*vty
= arg
->vty
;
275 (*arg
->prefix_amount
)++;
277 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
278 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
279 record
->max_len
, record
->asn
);
282 static struct rtr_mgr_group
*get_groups(void)
284 struct listnode
*cache_node
;
285 struct rtr_mgr_group
*rtr_mgr_groups
;
288 int group_count
= listcount(cache_list
);
290 if (group_count
== 0)
293 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
294 group_count
* sizeof(struct rtr_mgr_group
));
298 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
299 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
300 rtr_mgr_groups
[i
].sockets_len
= 1;
301 rtr_mgr_groups
[i
].preference
= cache
->preference
;
303 init_tr_socket(cache
);
308 return rtr_mgr_groups
;
311 inline int is_synchronized(void)
313 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
316 inline int is_running(void)
318 return rtr_is_running
;
321 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
323 struct prefix
*prefix
= prefix_new();
325 prefix
->prefixlen
= record
->min_len
;
327 if (record
->prefix
.ver
== LRTR_IPV4
) {
328 prefix
->family
= AF_INET
;
329 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
331 prefix
->family
= AF_INET6
;
332 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
333 prefix
->u
.prefix6
.s6_addr32
);
339 static int bgpd_sync_callback(struct thread
*thread
)
342 struct listnode
*node
;
343 struct prefix
*prefix
;
344 struct pfx_record rec
;
346 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
347 rpki_sync_socket_bgpd
, NULL
);
349 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
350 if (retval
!= sizeof(struct pfx_record
)) {
351 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
354 prefix
= pfx_record_to_prefix(&rec
);
356 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
358 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
361 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
362 if (!bgp
->rib
[afi
][safi
])
365 struct list
*matches
= list_new();
367 matches
->del
= (void (*)(void *))bgp_unlock_node
;
369 bgp_table_range_lookup(bgp
->rib
[afi
][safi
], prefix
,
370 rec
.max_len
, matches
);
373 struct bgp_node
*bgp_node
;
375 for (ALL_LIST_ELEMENTS_RO(matches
, node
, bgp_node
))
376 revalidate_bgp_node(bgp_node
, afi
, safi
);
378 list_delete_and_null(&matches
);
386 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
389 struct bgp_adj_in
*ain
;
391 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
393 struct bgp_info
*bgp_info
= bgp_node
->info
;
394 mpls_label_t
*label
= NULL
;
395 uint32_t num_labels
= 0;
397 if (bgp_info
&& bgp_info
->extra
) {
398 label
= bgp_info
->extra
->label
;
399 num_labels
= bgp_info
->extra
->num_labels
;
401 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, 0, ain
->attr
, afi
,
402 safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
,
403 label
, num_labels
, 1, NULL
);
406 bgp_unlock_node(bgp_node
);
412 static void revalidate_all_routes(void)
415 struct listnode
*node
;
416 struct bgp_node
*bgp_node
;
418 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
419 for (size_t i
= 0; i
< 2; i
++) {
421 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
423 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
424 if (!bgp
->rib
[afi
][safi
])
428 bgp_table_top(bgp
->rib
[afi
][safi
]);
430 bgp_node
= bgp_route_next(bgp_node
)) {
431 if (bgp_node
->info
!= NULL
) {
432 revalidate_bgp_node(bgp_node
,
441 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
442 const struct pfx_record rec
,
443 const bool added
__attribute__((unused
)))
445 if (rtr_is_stopping
|| rtr_is_starting
)
449 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
450 if (retval
!= sizeof(struct pfx_record
))
451 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
454 static void rpki_init_sync_socket(void)
458 RPKI_DEBUG("initializing sync socket");
459 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
460 RPKI_DEBUG("Could not open rpki sync socket");
463 rpki_sync_socket_rtr
= fds
[0];
464 rpki_sync_socket_bgpd
= fds
[1];
465 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
466 rpki_sync_socket_bgpd
, NULL
);
469 static int bgp_rpki_init(struct thread_master
*master
)
475 cache_list
= list_new();
476 cache_list
->del
= (void (*)(void *)) & free_cache
;
478 polling_period
= POLLING_PERIOD_DEFAULT
;
479 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
480 retry_interval
= RETRY_INTERVAL_DEFAULT
;
481 timeout
= TIMEOUT_DEFAULT
;
482 initial_synchronisation_timeout
=
483 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
484 install_cli_commands();
485 rpki_init_sync_socket();
489 static int bgp_rpki_fini(void)
492 list_delete_and_null(&cache_list
);
494 close(rpki_sync_socket_rtr
);
495 close(rpki_sync_socket_bgpd
);
500 static int bgp_rpki_module_init(void)
502 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
504 hook_register(frr_late_init
, bgp_rpki_init
);
505 hook_register(frr_early_fini
, &bgp_rpki_fini
);
510 static int start(void)
512 unsigned int waiting_time
= 0;
518 if (list_isempty(cache_list
)) {
520 "No caches were found in config. Prefix validation is off.");
523 RPKI_DEBUG("Init rtr_mgr.");
524 int groups_len
= listcount(cache_list
);
525 struct rtr_mgr_group
*groups
= get_groups();
527 RPKI_DEBUG("Polling period: %d", polling_period
);
528 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
529 expire_interval
, retry_interval
,
530 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
531 if (ret
== RTR_ERROR
) {
532 RPKI_DEBUG("Init rtr_mgr failed.");
536 RPKI_DEBUG("Starting rtr_mgr.");
537 ret
= rtr_mgr_start(rtr_config
);
538 if (ret
== RTR_ERROR
) {
539 RPKI_DEBUG("Starting rtr_mgr failed.");
540 rtr_mgr_free(rtr_config
);
544 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
545 while (waiting_time
++ <= initial_synchronisation_timeout
) {
546 if (rtr_mgr_conf_in_sync(rtr_config
))
551 if (rtr_mgr_conf_in_sync(rtr_config
)) {
552 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
553 RPKI_DEBUG("Forcing revalidation.");
555 revalidate_all_routes();
558 "Timeout expired! Proceeding without RPKI validation data.");
562 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
567 static void stop(void)
570 if (rtr_is_running
) {
571 rtr_mgr_stop(rtr_config
);
572 rtr_mgr_free(rtr_config
);
577 static int reset(bool force
)
579 if (rtr_is_running
&& !force
)
582 RPKI_DEBUG("Resetting RPKI Session");
587 static struct rtr_mgr_group
*get_connected_group(void)
589 if (!cache_list
|| list_isempty(cache_list
))
592 return rtr_mgr_get_first_group(rtr_config
);
595 static void print_prefix_table(struct vty
*vty
)
597 struct rpki_for_each_record_arg arg
;
599 unsigned int number_of_ipv4_prefixes
= 0;
600 unsigned int number_of_ipv6_prefixes
= 0;
601 struct rtr_mgr_group
*group
= get_connected_group();
608 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
610 vty_out(vty
, "RPKI/RTR prefix table\n");
611 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
613 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
614 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
616 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
617 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
619 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
620 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
623 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
624 const struct prefix
*prefix
)
626 struct assegment
*as_segment
;
628 struct lrtr_ip_addr ip_addr_prefix
;
629 enum pfxv_state result
;
631 const char *prefix_string
;
633 if (!is_synchronized())
636 // No aspath means route comes from iBGP
637 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
639 as_number
= peer
->bgp
->as
;
641 as_segment
= attr
->aspath
->segments
;
642 // Find last AsSegment
643 while (as_segment
->next
)
644 as_segment
= as_segment
->next
;
646 if (as_segment
->type
== AS_SEQUENCE
) {
648 as_number
= as_segment
->as
[as_segment
->length
- 1];
649 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
650 || as_segment
->type
== AS_CONFED_SET
) {
652 as_number
= peer
->bgp
->as
;
654 // RFC says: "Take distinguished value NONE as asn"
655 // which means state is unknown
656 return RPKI_NOTFOUND
;
660 // Get the prefix in requested format
661 switch (prefix
->family
) {
663 ip_addr_prefix
.ver
= LRTR_IPV4
;
664 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
668 ip_addr_prefix
.ver
= LRTR_IPV6
;
669 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
670 ip_addr_prefix
.u
.addr6
.addr
);
677 // Do the actual validation
678 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
679 prefix
->prefixlen
, &result
);
681 // Print Debug output
683 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
685 case BGP_PFXV_STATE_VALID
:
687 "Validating Prefix %s/%hhu from asn %u Result: VALID",
688 prefix_string
, prefix
->prefixlen
, as_number
);
690 case BGP_PFXV_STATE_NOT_FOUND
:
692 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
693 prefix_string
, prefix
->prefixlen
, as_number
);
694 return RPKI_NOTFOUND
;
695 case BGP_PFXV_STATE_INVALID
:
697 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
698 prefix_string
, prefix
->prefixlen
, as_number
);
702 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
703 prefix_string
, prefix
->prefixlen
, as_number
);
709 static int add_cache(struct cache
*cache
)
711 uint8_t preference
= cache
->preference
;
712 struct rtr_mgr_group group
;
714 group
.preference
= preference
;
715 group
.sockets_len
= 1;
716 group
.sockets
= &cache
->rtr_socket
;
718 listnode_add(cache_list
, cache
);
720 if (rtr_is_running
) {
721 init_tr_socket(cache
);
723 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
724 free_tr_socket(cache
);
732 static int add_tcp_cache(const char *host
, const char *port
,
733 const uint8_t preference
)
735 struct rtr_socket
*rtr_socket
;
736 struct tr_tcp_config
*tcp_config
=
737 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
738 struct tr_socket
*tr_socket
=
739 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
740 struct cache
*cache
=
741 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
743 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
744 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
745 tcp_config
->bindaddr
= NULL
;
747 rtr_socket
= create_rtr_socket(tr_socket
);
750 cache
->tr_socket
= tr_socket
;
751 cache
->tr_config
.tcp_config
= tcp_config
;
752 cache
->rtr_socket
= rtr_socket
;
753 cache
->preference
= preference
;
755 return add_cache(cache
);
758 #if defined(FOUND_SSH)
759 static int add_ssh_cache(const char *host
, const unsigned int port
,
760 const char *username
, const char *client_privkey_path
,
761 const char *client_pubkey_path
,
762 const char *server_pubkey_path
,
763 const uint8_t preference
)
765 struct tr_ssh_config
*ssh_config
=
766 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
767 struct cache
*cache
=
768 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
769 struct tr_socket
*tr_socket
=
770 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
771 struct rtr_socket
*rtr_socket
;
773 ssh_config
->port
= port
;
774 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
775 ssh_config
->bindaddr
= NULL
;
777 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
778 ssh_config
->client_privkey_path
=
779 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
780 ssh_config
->server_hostkey_path
=
781 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
783 rtr_socket
= create_rtr_socket(tr_socket
);
786 cache
->tr_socket
= tr_socket
;
787 cache
->tr_config
.ssh_config
= ssh_config
;
788 cache
->rtr_socket
= rtr_socket
;
789 cache
->preference
= preference
;
791 return add_cache(cache
);
795 static void free_cache(struct cache
*cache
)
797 if (cache
->type
== TCP
) {
798 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
799 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
800 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
802 #if defined(FOUND_SSH)
804 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
805 XFREE(MTYPE_BGP_RPKI_CACHE
,
806 cache
->tr_config
.ssh_config
->username
);
807 XFREE(MTYPE_BGP_RPKI_CACHE
,
808 cache
->tr_config
.ssh_config
->client_privkey_path
);
809 XFREE(MTYPE_BGP_RPKI_CACHE
,
810 cache
->tr_config
.ssh_config
->server_hostkey_path
);
811 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
814 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
815 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
816 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
819 static int config_write(struct vty
*vty
)
821 struct listnode
*cache_node
;
824 if (listcount(cache_list
)) {
826 vty_out(vty
, "debug rpki\n");
829 vty_out(vty
, "rpki\n");
830 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
831 vty_out(vty
, " rpki timeout %d\n", timeout
);
832 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
833 initial_synchronisation_timeout
);
834 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
835 switch (cache
->type
) {
836 struct tr_tcp_config
*tcp_config
;
837 #if defined(FOUND_SSH)
838 struct tr_ssh_config
*ssh_config
;
841 tcp_config
= cache
->tr_config
.tcp_config
;
842 vty_out(vty
, " rpki cache %s %s ",
843 tcp_config
->host
, tcp_config
->port
);
845 #if defined(FOUND_SSH)
847 ssh_config
= cache
->tr_config
.ssh_config
;
848 vty_out(vty
, " rpki cache %s %u %s %s %s ",
849 ssh_config
->host
, ssh_config
->port
,
850 ssh_config
->username
,
851 ssh_config
->client_privkey_path
,
852 ssh_config
->server_hostkey_path
!= NULL
854 ->server_hostkey_path
862 vty_out(vty
, "preference %hhu\n", cache
->preference
);
864 vty_out(vty
, " exit\n");
874 "Enable rpki and enter rpki configuration mode\n")
876 vty
->node
= RPKI_NODE
;
880 DEFUN (bgp_rpki_start
,
884 "start rpki support\n")
886 if (listcount(cache_list
) == 0)
888 "Could not start rpki because no caches are configured\n");
891 if (start() == ERROR
) {
892 RPKI_DEBUG("RPKI failed to start");
899 DEFUN (bgp_rpki_stop
,
903 "start rpki support\n")
911 DEFPY (rpki_polling_period
,
912 rpki_polling_period_cmd
,
913 "rpki polling_period (1-86400)$pp",
915 "Set polling period\n"
916 "Polling period value\n")
922 DEFUN (no_rpki_polling_period
,
923 no_rpki_polling_period_cmd
,
924 "no rpki polling_period",
927 "Set polling period back to default\n")
929 polling_period
= POLLING_PERIOD_DEFAULT
;
933 DEFPY (rpki_expire_interval
,
934 rpki_expire_interval_cmd
,
935 "rpki expire_interval (600-172800)$tmp",
937 "Set expire interval\n"
938 "Expire interval value\n")
940 if ((unsigned int)tmp
>= polling_period
) {
941 expire_interval
= tmp
;
945 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
946 return CMD_WARNING_CONFIG_FAILED
;
949 DEFUN (no_rpki_expire_interval
,
950 no_rpki_expire_interval_cmd
,
951 "no rpki expire_interval",
954 "Set expire interval back to default\n")
956 expire_interval
= polling_period
* 2;
960 DEFPY (rpki_retry_interval
,
961 rpki_retry_interval_cmd
,
962 "rpki retry_interval (1-7200)$tmp",
964 "Set retry interval\n"
965 "retry interval value\n")
967 retry_interval
= tmp
;
971 DEFUN (no_rpki_retry_interval
,
972 no_rpki_retry_interval_cmd
,
973 "no rpki retry_interval",
976 "Set retry interval back to default\n")
978 retry_interval
= RETRY_INTERVAL_DEFAULT
;
984 "rpki timeout (1-4294967295)$to_arg",
993 DEFUN (no_rpki_timeout
,
998 "Set timeout back to default\n")
1000 timeout
= TIMEOUT_DEFAULT
;
1004 DEFPY (rpki_synchronisation_timeout
,
1005 rpki_synchronisation_timeout_cmd
,
1006 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1008 "Set a timeout for the initial synchronisation of prefix validation data\n"
1011 initial_synchronisation_timeout
= ito_arg
;
1015 DEFUN (no_rpki_synchronisation_timeout
,
1016 no_rpki_synchronisation_timeout_cmd
,
1017 "no rpki initial-synchronisation-timeout",
1020 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1022 initial_synchronisation_timeout
=
1023 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1029 "rpki cache <A.B.C.D|WORD>"
1030 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1031 "preference (1-255)",
1033 "Install a cache server to current group\n"
1034 "IP address of cache server\n Hostname of cache server\n"
1038 "Path to own SSH private key\n"
1039 "Path to own SSH public key\n"
1040 "Path to Public key of cache server\n"
1041 "Preference of the cache server\n"
1042 "Preference value\n")
1046 // use ssh connection
1048 #if defined(FOUND_SSH)
1050 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1051 ssh_pubkey
, server_pubkey
, preference
);
1053 return_value
= SUCCESS
;
1055 "ssh sockets are not supported. "
1056 "Please recompile rtrlib and frr with ssh support. "
1057 "If you want to use it");
1059 } else { // use tcp connection
1060 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1063 if (return_value
== ERROR
) {
1064 vty_out(vty
, "Could not create new rpki cache\n");
1071 DEFPY (no_rpki_cache
,
1073 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1076 "Remove a cache server\n"
1077 "IP address of cache server\n Hostname of cache server\n"
1080 "Preference of the cache server\n"
1081 "Preference value\n")
1083 struct cache
*cache_p
= find_cache(preference
);
1086 vty_out(vty
, "Could not find cache %ld\n", preference
);
1090 if (rtr_is_running
) {
1091 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1092 vty_out(vty
, "Could not remove cache %ld", preference
);
1093 if (listcount(cache_list
) == 1)
1094 vty_out(vty
, " because it is the last cache");
1101 listnode_delete(cache_list
, cache_p
);
1102 free_cache(cache_p
);
1107 DEFUN (show_rpki_prefix_table
,
1108 show_rpki_prefix_table_cmd
,
1109 "show rpki prefix-table",
1112 "Show validated prefixes which were received from RPKI Cache\n")
1114 struct listnode
*cache_node
;
1115 struct cache
*cache
;
1117 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1118 vty_out(vty
, "host: %s port: %s\n",
1119 cache
->tr_config
.tcp_config
->host
,
1120 cache
->tr_config
.tcp_config
->port
);
1122 if (is_synchronized())
1123 print_prefix_table(vty
);
1125 vty_out(vty
, "No connection to RPKI cache server.\n");
1130 DEFUN (show_rpki_cache_server
,
1131 show_rpki_cache_server_cmd
,
1132 "show rpki cache-server",
1135 "SHOW configured cache server\n")
1137 struct listnode
*cache_node
;
1138 struct cache
*cache
;
1140 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1141 vty_out(vty
, "host: %s port: %s\n",
1142 cache
->tr_config
.tcp_config
->host
,
1143 cache
->tr_config
.tcp_config
->port
);
1149 DEFUN (show_rpki_cache_connection
,
1150 show_rpki_cache_connection_cmd
,
1151 "show rpki cache-connection",
1154 "Show to which RPKI Cache Servers we have a connection\n")
1156 if (is_synchronized()) {
1157 struct listnode
*cache_node
;
1158 struct cache
*cache
;
1159 struct rtr_mgr_group
*group
= get_connected_group();
1162 vty_out(vty
, "Cannot find a connected group.\n");
1165 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1166 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1167 if (cache
->preference
== group
->preference
) {
1168 struct tr_tcp_config
*tcp_config
;
1169 #if defined(FOUND_SSH)
1170 struct tr_ssh_config
*ssh_config
;
1173 switch (cache
->type
) {
1176 cache
->tr_config
.tcp_config
;
1178 "rpki tcp cache %s %s pref %hhu\n",
1184 #if defined(FOUND_SSH)
1187 cache
->tr_config
.ssh_config
;
1189 "rpki ssh cache %s %u pref %hhu\n",
1202 vty_out(vty
, "No connection to RPKI cache server.\n");
1208 DEFUN_NOSH (rpki_exit
,
1211 "Exit rpki configuration and restart rpki session\n")
1213 int ret
= reset(false);
1215 vty
->node
= CONFIG_NODE
;
1216 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1219 DEFUN_NOSH (rpki_quit
,
1222 "Exit rpki configuration mode\n")
1224 return rpki_exit(self
, vty
, argc
, argv
);
1227 DEFUN_NOSH (rpki_end
,
1230 "End rpki configuration, restart rpki session and change to enable mode.\n")
1232 int ret
= reset(false);
1234 vty_config_unlock(vty
);
1235 vty
->node
= ENABLE_NODE
;
1236 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1245 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1252 "Enable debugging for rpki\n")
1258 DEFUN (no_debug_rpki
,
1263 "Disable debugging for rpki\n")
1271 "match rpki <valid|invalid|notfound>",
1276 "Prefix not found\n")
1278 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1281 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1284 case RMAP_RULE_MISSING
:
1285 vty_out(vty
, "%% BGP Can't find rule.\n");
1286 return CMD_WARNING_CONFIG_FAILED
;
1287 case RMAP_COMPILE_ERROR
:
1288 vty_out(vty
, "%% BGP Argument is malformed.\n");
1289 return CMD_WARNING_CONFIG_FAILED
;
1295 DEFUN (no_match_rpki
,
1297 "no match rpki <valid|invalid|notfound>",
1303 "Prefix not found\n")
1305 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1308 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1311 case RMAP_RULE_MISSING
:
1312 vty_out(vty
, "%% BGP Can't find rule.\n");
1314 case RMAP_COMPILE_ERROR
:
1315 vty_out(vty
, "%% BGP Argument is malformed.\n");
1318 return CMD_WARNING_CONFIG_FAILED
;
1324 static void overwrite_exit_commands(void)
1327 vector cmd_vector
= rpki_node
.cmd_vector
;
1329 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1330 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1332 if (strcmp(cmd
->string
, "exit") == 0
1333 || strcmp(cmd
->string
, "quit") == 0
1334 || strcmp(cmd
->string
, "end") == 0) {
1335 uninstall_element(RPKI_NODE
, cmd
);
1339 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1340 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1341 install_element(RPKI_NODE
, &rpki_end_cmd
);
1344 static void install_cli_commands(void)
1346 // TODO: make config write work
1347 install_node(&rpki_node
, &config_write
);
1348 install_default(RPKI_NODE
);
1349 overwrite_exit_commands();
1350 install_element(CONFIG_NODE
, &rpki_cmd
);
1351 install_element(VIEW_NODE
, &rpki_cmd
);
1353 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1354 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1356 /* Install rpki reset command */
1357 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1359 /* Install rpki polling period commands */
1360 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1361 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1363 /* Install rpki expire interval commands */
1364 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1365 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1367 /* Install rpki retry interval commands */
1368 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1369 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1371 /* Install rpki timeout commands */
1372 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1373 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1375 /* Install rpki synchronisation timeout commands */
1376 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1377 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1379 /* Install rpki cache commands */
1380 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1381 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1383 /* Install show commands */
1384 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1385 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1386 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1388 /* Install debug commands */
1389 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1390 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1391 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1392 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1394 /* Install route match */
1395 route_map_install_match(&route_match_rpki_cmd
);
1396 install_element(RMAP_NODE
, &match_rpki_cmd
);
1397 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1400 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1401 .description
= "Enable RPKI support for FRR.",
1402 .init
= bgp_rpki_module_init
)