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(uint8_t));
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
)) {
377 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
378 if (!bgp
->rib
[afi
][safi
])
381 struct list
*matches
= list_new();
383 matches
->del
= (void (*)(void *))bgp_unlock_node
;
385 bgp_table_range_lookup(bgp
->rib
[afi
][safi
], prefix
,
386 rec
.max_len
, matches
);
389 struct bgp_node
*bgp_node
;
391 for (ALL_LIST_ELEMENTS_RO(matches
, node
, bgp_node
))
392 revalidate_bgp_node(bgp_node
, afi
, safi
);
394 list_delete_and_null(&matches
);
402 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
405 struct bgp_adj_in
*ain
;
407 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
409 struct bgp_info
*bgp_info
= bgp_node
->info
;
410 mpls_label_t
*label
= NULL
;
411 uint32_t num_labels
= 0;
413 if (bgp_info
&& bgp_info
->extra
) {
414 label
= bgp_info
->extra
->label
;
415 num_labels
= bgp_info
->extra
->num_labels
;
417 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, 0, ain
->attr
, afi
,
418 safi
, ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
,
419 label
, num_labels
, 1, NULL
);
422 bgp_unlock_node(bgp_node
);
428 static void revalidate_all_routes(void)
431 struct listnode
*node
;
432 struct bgp_node
*bgp_node
;
434 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
435 for (size_t i
= 0; i
< 2; i
++) {
437 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
439 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
440 if (!bgp
->rib
[afi
][safi
])
444 bgp_table_top(bgp
->rib
[afi
][safi
]);
446 bgp_node
= bgp_route_next(bgp_node
)) {
447 if (bgp_node
->info
!= NULL
) {
448 revalidate_bgp_node(bgp_node
,
457 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
458 const struct pfx_record rec
,
459 const bool added
__attribute__((unused
)))
461 if (rtr_is_stopping
|| rtr_is_starting
462 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
466 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
467 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
468 atomic_store_explicit(&rtr_update_overflow
, 1,
469 memory_order_seq_cst
);
471 else if (retval
!= sizeof(struct pfx_record
))
472 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
475 static void rpki_init_sync_socket(void)
480 RPKI_DEBUG("initializing sync socket");
481 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
482 msg
= "could not open rpki sync socketpair";
485 rpki_sync_socket_rtr
= fds
[0];
486 rpki_sync_socket_bgpd
= fds
[1];
488 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
489 msg
= "could not set rpki_sync_socket_rtr to non blocking";
493 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
494 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
499 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
500 rpki_sync_socket_bgpd
, NULL
);
505 zlog_err("RPKI: %s", msg
);
510 static int bgp_rpki_init(struct thread_master
*master
)
516 cache_list
= list_new();
517 cache_list
->del
= (void (*)(void *)) & free_cache
;
519 polling_period
= POLLING_PERIOD_DEFAULT
;
520 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
521 retry_interval
= RETRY_INTERVAL_DEFAULT
;
522 timeout
= TIMEOUT_DEFAULT
;
523 initial_synchronisation_timeout
=
524 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
525 install_cli_commands();
526 rpki_init_sync_socket();
530 static int bgp_rpki_fini(void)
533 list_delete_and_null(&cache_list
);
535 close(rpki_sync_socket_rtr
);
536 close(rpki_sync_socket_bgpd
);
541 static int bgp_rpki_module_init(void)
543 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
545 hook_register(frr_late_init
, bgp_rpki_init
);
546 hook_register(frr_early_fini
, &bgp_rpki_fini
);
551 static int start(void)
553 unsigned int waiting_time
= 0;
558 rtr_update_overflow
= 0;
560 if (list_isempty(cache_list
)) {
562 "No caches were found in config. Prefix validation is off.");
565 RPKI_DEBUG("Init rtr_mgr.");
566 int groups_len
= listcount(cache_list
);
567 struct rtr_mgr_group
*groups
= get_groups();
569 RPKI_DEBUG("Polling period: %d", polling_period
);
570 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
571 expire_interval
, retry_interval
,
572 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
573 if (ret
== RTR_ERROR
) {
574 RPKI_DEBUG("Init rtr_mgr failed.");
578 RPKI_DEBUG("Starting rtr_mgr.");
579 ret
= rtr_mgr_start(rtr_config
);
580 if (ret
== RTR_ERROR
) {
581 RPKI_DEBUG("Starting rtr_mgr failed.");
582 rtr_mgr_free(rtr_config
);
586 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
587 while (waiting_time
++ <= initial_synchronisation_timeout
) {
588 if (rtr_mgr_conf_in_sync(rtr_config
))
593 if (rtr_mgr_conf_in_sync(rtr_config
)) {
594 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
595 RPKI_DEBUG("Forcing revalidation.");
597 revalidate_all_routes();
600 "Timeout expired! Proceeding without RPKI validation data.");
604 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
609 static void stop(void)
612 if (rtr_is_running
) {
613 rtr_mgr_stop(rtr_config
);
614 rtr_mgr_free(rtr_config
);
619 static int reset(bool force
)
621 if (rtr_is_running
&& !force
)
624 RPKI_DEBUG("Resetting RPKI Session");
629 static struct rtr_mgr_group
*get_connected_group(void)
631 if (!cache_list
|| list_isempty(cache_list
))
634 return rtr_mgr_get_first_group(rtr_config
);
637 static void print_prefix_table(struct vty
*vty
)
639 struct rpki_for_each_record_arg arg
;
641 unsigned int number_of_ipv4_prefixes
= 0;
642 unsigned int number_of_ipv6_prefixes
= 0;
643 struct rtr_mgr_group
*group
= get_connected_group();
650 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
652 vty_out(vty
, "RPKI/RTR prefix table\n");
653 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
655 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
656 pfx_table_for_each_ipv4_record(pfx_table
, print_record
, &arg
);
658 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
659 pfx_table_for_each_ipv6_record(pfx_table
, print_record
, &arg
);
661 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
662 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
665 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
666 const struct prefix
*prefix
)
668 struct assegment
*as_segment
;
670 struct lrtr_ip_addr ip_addr_prefix
;
671 enum pfxv_state result
;
673 const char *prefix_string
;
675 if (!is_synchronized())
678 // No aspath means route comes from iBGP
679 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
681 as_number
= peer
->bgp
->as
;
683 as_segment
= attr
->aspath
->segments
;
684 // Find last AsSegment
685 while (as_segment
->next
)
686 as_segment
= as_segment
->next
;
688 if (as_segment
->type
== AS_SEQUENCE
) {
690 as_number
= as_segment
->as
[as_segment
->length
- 1];
691 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
692 || as_segment
->type
== AS_CONFED_SET
) {
694 as_number
= peer
->bgp
->as
;
696 // RFC says: "Take distinguished value NONE as asn"
697 // which means state is unknown
698 return RPKI_NOTFOUND
;
702 // Get the prefix in requested format
703 switch (prefix
->family
) {
705 ip_addr_prefix
.ver
= LRTR_IPV4
;
706 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
710 ip_addr_prefix
.ver
= LRTR_IPV6
;
711 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
712 ip_addr_prefix
.u
.addr6
.addr
);
719 // Do the actual validation
720 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
721 prefix
->prefixlen
, &result
);
723 // Print Debug output
725 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
727 case BGP_PFXV_STATE_VALID
:
729 "Validating Prefix %s/%hhu from asn %u Result: VALID",
730 prefix_string
, prefix
->prefixlen
, as_number
);
732 case BGP_PFXV_STATE_NOT_FOUND
:
734 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
735 prefix_string
, prefix
->prefixlen
, as_number
);
736 return RPKI_NOTFOUND
;
737 case BGP_PFXV_STATE_INVALID
:
739 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
740 prefix_string
, prefix
->prefixlen
, as_number
);
744 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
745 prefix_string
, prefix
->prefixlen
, as_number
);
751 static int add_cache(struct cache
*cache
)
753 uint8_t preference
= cache
->preference
;
754 struct rtr_mgr_group group
;
756 group
.preference
= preference
;
757 group
.sockets_len
= 1;
758 group
.sockets
= &cache
->rtr_socket
;
760 listnode_add(cache_list
, cache
);
762 if (rtr_is_running
) {
763 init_tr_socket(cache
);
765 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
766 free_tr_socket(cache
);
774 static int add_tcp_cache(const char *host
, const char *port
,
775 const uint8_t preference
)
777 struct rtr_socket
*rtr_socket
;
778 struct tr_tcp_config
*tcp_config
=
779 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
780 struct tr_socket
*tr_socket
=
781 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
782 struct cache
*cache
=
783 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
785 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
786 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
787 tcp_config
->bindaddr
= NULL
;
789 rtr_socket
= create_rtr_socket(tr_socket
);
792 cache
->tr_socket
= tr_socket
;
793 cache
->tr_config
.tcp_config
= tcp_config
;
794 cache
->rtr_socket
= rtr_socket
;
795 cache
->preference
= preference
;
797 return add_cache(cache
);
800 #if defined(FOUND_SSH)
801 static int add_ssh_cache(const char *host
, const unsigned int port
,
802 const char *username
, const char *client_privkey_path
,
803 const char *client_pubkey_path
,
804 const char *server_pubkey_path
,
805 const uint8_t preference
)
807 struct tr_ssh_config
*ssh_config
=
808 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
809 struct cache
*cache
=
810 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
811 struct tr_socket
*tr_socket
=
812 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
813 struct rtr_socket
*rtr_socket
;
815 ssh_config
->port
= port
;
816 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
817 ssh_config
->bindaddr
= NULL
;
819 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
820 ssh_config
->client_privkey_path
=
821 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
822 ssh_config
->server_hostkey_path
=
823 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
825 rtr_socket
= create_rtr_socket(tr_socket
);
828 cache
->tr_socket
= tr_socket
;
829 cache
->tr_config
.ssh_config
= ssh_config
;
830 cache
->rtr_socket
= rtr_socket
;
831 cache
->preference
= preference
;
833 return add_cache(cache
);
837 static void free_cache(struct cache
*cache
)
839 if (cache
->type
== TCP
) {
840 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
841 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
842 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
844 #if defined(FOUND_SSH)
846 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
847 XFREE(MTYPE_BGP_RPKI_CACHE
,
848 cache
->tr_config
.ssh_config
->username
);
849 XFREE(MTYPE_BGP_RPKI_CACHE
,
850 cache
->tr_config
.ssh_config
->client_privkey_path
);
851 XFREE(MTYPE_BGP_RPKI_CACHE
,
852 cache
->tr_config
.ssh_config
->server_hostkey_path
);
853 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
856 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
857 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
858 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
861 static int config_write(struct vty
*vty
)
863 struct listnode
*cache_node
;
866 if (listcount(cache_list
)) {
868 vty_out(vty
, "debug rpki\n");
871 vty_out(vty
, "rpki\n");
872 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
873 vty_out(vty
, " rpki timeout %d\n", timeout
);
874 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
875 initial_synchronisation_timeout
);
876 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
877 switch (cache
->type
) {
878 struct tr_tcp_config
*tcp_config
;
879 #if defined(FOUND_SSH)
880 struct tr_ssh_config
*ssh_config
;
883 tcp_config
= cache
->tr_config
.tcp_config
;
884 vty_out(vty
, " rpki cache %s %s ",
885 tcp_config
->host
, tcp_config
->port
);
887 #if defined(FOUND_SSH)
889 ssh_config
= cache
->tr_config
.ssh_config
;
890 vty_out(vty
, " rpki cache %s %u %s %s %s ",
891 ssh_config
->host
, ssh_config
->port
,
892 ssh_config
->username
,
893 ssh_config
->client_privkey_path
,
894 ssh_config
->server_hostkey_path
!= NULL
896 ->server_hostkey_path
904 vty_out(vty
, "preference %hhu\n", cache
->preference
);
906 vty_out(vty
, " exit\n");
916 "Enable rpki and enter rpki configuration mode\n")
918 vty
->node
= RPKI_NODE
;
922 DEFUN (bgp_rpki_start
,
926 "start rpki support\n")
928 if (listcount(cache_list
) == 0)
930 "Could not start rpki because no caches are configured\n");
933 if (start() == ERROR
) {
934 RPKI_DEBUG("RPKI failed to start");
941 DEFUN (bgp_rpki_stop
,
945 "start rpki support\n")
953 DEFPY (rpki_polling_period
,
954 rpki_polling_period_cmd
,
955 "rpki polling_period (1-86400)$pp",
957 "Set polling period\n"
958 "Polling period value\n")
964 DEFUN (no_rpki_polling_period
,
965 no_rpki_polling_period_cmd
,
966 "no rpki polling_period",
969 "Set polling period back to default\n")
971 polling_period
= POLLING_PERIOD_DEFAULT
;
975 DEFPY (rpki_expire_interval
,
976 rpki_expire_interval_cmd
,
977 "rpki expire_interval (600-172800)$tmp",
979 "Set expire interval\n"
980 "Expire interval value\n")
982 if ((unsigned int)tmp
>= polling_period
) {
983 expire_interval
= tmp
;
987 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
988 return CMD_WARNING_CONFIG_FAILED
;
991 DEFUN (no_rpki_expire_interval
,
992 no_rpki_expire_interval_cmd
,
993 "no rpki expire_interval",
996 "Set expire interval back to default\n")
998 expire_interval
= polling_period
* 2;
1002 DEFPY (rpki_retry_interval
,
1003 rpki_retry_interval_cmd
,
1004 "rpki retry_interval (1-7200)$tmp",
1006 "Set retry interval\n"
1007 "retry interval value\n")
1009 retry_interval
= tmp
;
1013 DEFUN (no_rpki_retry_interval
,
1014 no_rpki_retry_interval_cmd
,
1015 "no rpki retry_interval",
1018 "Set retry interval back to default\n")
1020 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1024 DEFPY (rpki_timeout
,
1026 "rpki timeout (1-4294967295)$to_arg",
1035 DEFUN (no_rpki_timeout
,
1036 no_rpki_timeout_cmd
,
1040 "Set timeout back to default\n")
1042 timeout
= TIMEOUT_DEFAULT
;
1046 DEFPY (rpki_synchronisation_timeout
,
1047 rpki_synchronisation_timeout_cmd
,
1048 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1050 "Set a timeout for the initial synchronisation of prefix validation data\n"
1053 initial_synchronisation_timeout
= ito_arg
;
1057 DEFUN (no_rpki_synchronisation_timeout
,
1058 no_rpki_synchronisation_timeout_cmd
,
1059 "no rpki initial-synchronisation-timeout",
1062 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1064 initial_synchronisation_timeout
=
1065 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1071 "rpki cache <A.B.C.D|WORD>"
1072 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1073 "preference (1-255)",
1075 "Install a cache server to current group\n"
1076 "IP address of cache server\n Hostname of cache server\n"
1080 "Path to own SSH private key\n"
1081 "Path to own SSH public key\n"
1082 "Path to Public key of cache server\n"
1083 "Preference of the cache server\n"
1084 "Preference value\n")
1088 // use ssh connection
1090 #if defined(FOUND_SSH)
1092 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1093 ssh_pubkey
, server_pubkey
, preference
);
1095 return_value
= SUCCESS
;
1097 "ssh sockets are not supported. "
1098 "Please recompile rtrlib and frr with ssh support. "
1099 "If you want to use it");
1101 } else { // use tcp connection
1102 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1105 if (return_value
== ERROR
) {
1106 vty_out(vty
, "Could not create new rpki cache\n");
1113 DEFPY (no_rpki_cache
,
1115 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1118 "Remove a cache server\n"
1119 "IP address of cache server\n Hostname of cache server\n"
1122 "Preference of the cache server\n"
1123 "Preference value\n")
1125 struct cache
*cache_p
= find_cache(preference
);
1128 vty_out(vty
, "Could not find cache %ld\n", preference
);
1132 if (rtr_is_running
) {
1133 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1134 vty_out(vty
, "Could not remove cache %ld", preference
);
1135 if (listcount(cache_list
) == 1)
1136 vty_out(vty
, " because it is the last cache");
1143 listnode_delete(cache_list
, cache_p
);
1144 free_cache(cache_p
);
1149 DEFUN (show_rpki_prefix_table
,
1150 show_rpki_prefix_table_cmd
,
1151 "show rpki prefix-table",
1154 "Show validated prefixes which were received from RPKI Cache\n")
1156 struct listnode
*cache_node
;
1157 struct cache
*cache
;
1159 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1160 vty_out(vty
, "host: %s port: %s\n",
1161 cache
->tr_config
.tcp_config
->host
,
1162 cache
->tr_config
.tcp_config
->port
);
1164 if (is_synchronized())
1165 print_prefix_table(vty
);
1167 vty_out(vty
, "No connection to RPKI cache server.\n");
1172 DEFUN (show_rpki_cache_server
,
1173 show_rpki_cache_server_cmd
,
1174 "show rpki cache-server",
1177 "SHOW configured cache server\n")
1179 struct listnode
*cache_node
;
1180 struct cache
*cache
;
1182 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1183 vty_out(vty
, "host: %s port: %s\n",
1184 cache
->tr_config
.tcp_config
->host
,
1185 cache
->tr_config
.tcp_config
->port
);
1191 DEFUN (show_rpki_cache_connection
,
1192 show_rpki_cache_connection_cmd
,
1193 "show rpki cache-connection",
1196 "Show to which RPKI Cache Servers we have a connection\n")
1198 if (is_synchronized()) {
1199 struct listnode
*cache_node
;
1200 struct cache
*cache
;
1201 struct rtr_mgr_group
*group
= get_connected_group();
1204 vty_out(vty
, "Cannot find a connected group.\n");
1207 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1208 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1209 if (cache
->preference
== group
->preference
) {
1210 struct tr_tcp_config
*tcp_config
;
1211 #if defined(FOUND_SSH)
1212 struct tr_ssh_config
*ssh_config
;
1215 switch (cache
->type
) {
1218 cache
->tr_config
.tcp_config
;
1220 "rpki tcp cache %s %s pref %hhu\n",
1226 #if defined(FOUND_SSH)
1229 cache
->tr_config
.ssh_config
;
1231 "rpki ssh cache %s %u pref %hhu\n",
1244 vty_out(vty
, "No connection to RPKI cache server.\n");
1250 DEFUN_NOSH (rpki_exit
,
1253 "Exit rpki configuration and restart rpki session\n")
1255 int ret
= reset(false);
1257 vty
->node
= CONFIG_NODE
;
1258 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1261 DEFUN_NOSH (rpki_quit
,
1264 "Exit rpki configuration mode\n")
1266 return rpki_exit(self
, vty
, argc
, argv
);
1269 DEFUN_NOSH (rpki_end
,
1272 "End rpki configuration, restart rpki session and change to enable mode.\n")
1274 int ret
= reset(false);
1276 vty_config_unlock(vty
);
1277 vty
->node
= ENABLE_NODE
;
1278 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1287 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1294 "Enable debugging for rpki\n")
1300 DEFUN (no_debug_rpki
,
1305 "Disable debugging for rpki\n")
1313 "match rpki <valid|invalid|notfound>",
1318 "Prefix not found\n")
1320 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1323 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1326 case RMAP_RULE_MISSING
:
1327 vty_out(vty
, "%% BGP Can't find rule.\n");
1328 return CMD_WARNING_CONFIG_FAILED
;
1329 case RMAP_COMPILE_ERROR
:
1330 vty_out(vty
, "%% BGP Argument is malformed.\n");
1331 return CMD_WARNING_CONFIG_FAILED
;
1337 DEFUN (no_match_rpki
,
1339 "no match rpki <valid|invalid|notfound>",
1345 "Prefix not found\n")
1347 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1350 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1353 case RMAP_RULE_MISSING
:
1354 vty_out(vty
, "%% BGP Can't find rule.\n");
1356 case RMAP_COMPILE_ERROR
:
1357 vty_out(vty
, "%% BGP Argument is malformed.\n");
1360 return CMD_WARNING_CONFIG_FAILED
;
1366 static void overwrite_exit_commands(void)
1369 vector cmd_vector
= rpki_node
.cmd_vector
;
1371 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1372 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1374 if (strcmp(cmd
->string
, "exit") == 0
1375 || strcmp(cmd
->string
, "quit") == 0
1376 || strcmp(cmd
->string
, "end") == 0) {
1377 uninstall_element(RPKI_NODE
, cmd
);
1381 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1382 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1383 install_element(RPKI_NODE
, &rpki_end_cmd
);
1386 static void install_cli_commands(void)
1388 // TODO: make config write work
1389 install_node(&rpki_node
, &config_write
);
1390 install_default(RPKI_NODE
);
1391 overwrite_exit_commands();
1392 install_element(CONFIG_NODE
, &rpki_cmd
);
1393 install_element(VIEW_NODE
, &rpki_cmd
);
1395 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1396 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1398 /* Install rpki reset command */
1399 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1401 /* Install rpki polling period commands */
1402 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1403 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1405 /* Install rpki expire interval commands */
1406 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1407 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1409 /* Install rpki retry interval commands */
1410 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1411 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1413 /* Install rpki timeout commands */
1414 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1415 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1417 /* Install rpki synchronisation timeout commands */
1418 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1419 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1421 /* Install rpki cache commands */
1422 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1423 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1425 /* Install show commands */
1426 install_element(ENABLE_NODE
, &show_rpki_prefix_table_cmd
);
1427 install_element(ENABLE_NODE
, &show_rpki_cache_connection_cmd
);
1428 install_element(ENABLE_NODE
, &show_rpki_cache_server_cmd
);
1430 /* Install debug commands */
1431 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1432 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1433 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1434 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1436 /* Install route match */
1437 route_map_install_match(&route_match_rpki_cmd
);
1438 install_element(RMAP_NODE
, &match_rpki_cmd
);
1439 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1442 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1443 .description
= "Enable RPKI support for FRR.",
1444 .init
= bgp_rpki_module_init
)