3 * Copyright (C) 2013 Michael Mester (m.mester@fu-berlin.de), for FU Berlin
4 * Copyright (C) 2014-2017 Andreas Reuter (andreas.reuter@fu-berlin.de), for FU
6 * Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW
8 * Copyright (C) 2017-2018 Marcel Röthke (marcel.roethke@haw-hamburg.de),
11 * This file is part of FRRouting.
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23 * You should have received a copy of the GNU General Public License along
24 * with this program; see the file COPYING; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 /* If rtrlib compiled with ssh support, don`t fail build */
29 #define LIBSSH_LEGACY_0_4
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgp_advertise.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_attr.h"
48 #include "bgpd/bgp_aspath.h"
49 #include "bgpd/bgp_route.h"
50 #include "lib/network.h"
51 #include "lib/thread.h"
52 #ifndef VTYSH_EXTRACT_PL
53 #include "rtrlib/rtrlib.h"
54 #include "rtrlib/rtr_mgr.h"
55 #include "rtrlib/lib/ip.h"
56 #include "rtrlib/transport/tcp/tcp_transport.h"
57 #if defined(FOUND_SSH)
58 #include "rtrlib/transport/ssh/ssh_transport.h"
65 #ifndef VTYSH_EXTRACT_PL
66 #include "bgpd/bgp_rpki_clippy.c"
69 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
70 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
73 #define RPKI_NOTFOUND 2
74 #define RPKI_INVALID 3
76 #define POLLING_PERIOD_DEFAULT 3600
77 #define EXPIRE_INTERVAL_DEFAULT 7200
78 #define RETRY_INTERVAL_DEFAULT 600
79 #define TIMEOUT_DEFAULT 600
80 #define INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT 30
82 #define RPKI_DEBUG(...) \
84 zlog_debug("RPKI: " __VA_ARGS__); \
87 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
90 enum { TCP
, SSH
} type
;
91 struct tr_socket
*tr_socket
;
93 struct tr_tcp_config
*tcp_config
;
94 struct tr_ssh_config
*ssh_config
;
96 struct rtr_socket
*rtr_socket
;
100 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
102 struct rpki_for_each_record_arg
{
104 unsigned int *prefix_amount
;
107 static int start(void);
108 static void stop(void);
109 static int reset(bool force
);
110 static struct rtr_mgr_group
*get_connected_group(void);
111 static void print_prefix_table(struct vty
*vty
);
112 static void install_cli_commands(void);
113 static int config_write(struct vty
*vty
);
114 static void overwrite_exit_commands(void);
115 static void free_cache(struct cache
*cache
);
116 static struct rtr_mgr_group
*get_groups(void);
117 #if defined(FOUND_SSH)
118 static int add_ssh_cache(const char *host
, const unsigned int port
,
119 const char *username
, const char *client_privkey_path
,
120 const char *client_pubkey_path
,
121 const char *server_pubkey_path
,
122 const uint8_t preference
);
124 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
125 static struct cache
*find_cache(const uint8_t preference
);
126 static int add_tcp_cache(const char *host
, const char *port
,
127 const uint8_t preference
);
128 static void print_record(const struct pfx_record
*record
, struct vty
*vty
);
129 static int is_synchronized(void);
130 static int is_running(void);
131 static void route_match_free(void *rule
);
132 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
133 route_map_object_t type
, void *object
);
134 static void *route_match_compile(const char *arg
);
135 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
137 static void revalidate_all_routes(void);
139 static struct rtr_mgr_config
*rtr_config
;
140 static struct list
*cache_list
;
141 static int rtr_is_running
;
142 static int rtr_is_stopping
;
143 static int rtr_is_starting
;
144 static _Atomic
int rtr_update_overflow
;
145 static int rpki_debug
;
146 static unsigned int polling_period
;
147 static unsigned int expire_interval
;
148 static unsigned int retry_interval
;
149 static unsigned int timeout
;
150 static unsigned int initial_synchronisation_timeout
;
151 static int rpki_sync_socket_rtr
;
152 static int rpki_sync_socket_bgpd
;
154 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
155 static struct route_map_rule_cmd route_match_rpki_cmd
= {
156 "rpki", route_match
, route_match_compile
, route_match_free
};
158 static void *malloc_wrapper(size_t size
)
160 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
163 static void *realloc_wrapper(void *ptr
, size_t size
)
165 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
168 static void free_wrapper(void *ptr
)
170 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
173 static void init_tr_socket(struct cache
*cache
)
175 if (cache
->type
== TCP
)
176 tr_tcp_init(cache
->tr_config
.tcp_config
,
178 #if defined(FOUND_SSH)
180 tr_ssh_init(cache
->tr_config
.ssh_config
,
185 static void free_tr_socket(struct cache
*cache
)
187 if (cache
->type
== TCP
)
188 tr_tcp_init(cache
->tr_config
.tcp_config
,
190 #if defined(FOUND_SSH)
192 tr_ssh_init(cache
->tr_config
.ssh_config
,
197 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
198 const struct prefix
*prefix
);
200 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
204 for (i
= 0; i
< 4; i
++)
205 dest
[i
] = htonl(src
[i
]);
208 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
212 for (i
= 0; i
< 4; i
++)
213 dest
[i
] = ntohl(src
[i
]);
216 static route_map_result_t
route_match(void *rule
, const struct prefix
*prefix
,
217 route_map_object_t type
, void *object
)
219 int *rpki_status
= rule
;
220 struct bgp_path_info
*path
;
222 if (type
== RMAP_BGP
) {
225 if (rpki_validate_prefix(path
->peer
, path
->attr
, prefix
)
233 static void *route_match_compile(const char *arg
)
237 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
239 if (strcmp(arg
, "valid") == 0)
240 *rpki_status
= RPKI_VALID
;
241 else if (strcmp(arg
, "invalid") == 0)
242 *rpki_status
= RPKI_INVALID
;
244 *rpki_status
= RPKI_NOTFOUND
;
249 static void route_match_free(void *rule
)
251 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
254 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
256 struct rtr_socket
*rtr_socket
=
257 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
258 rtr_socket
->tr_socket
= tr_socket
;
262 static struct cache
*find_cache(const uint8_t preference
)
264 struct listnode
*cache_node
;
267 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
268 if (cache
->preference
== preference
)
274 static void print_record(const struct pfx_record
*record
, struct vty
*vty
)
276 char ip
[INET6_ADDRSTRLEN
];
278 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
279 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
280 record
->max_len
, record
->asn
);
283 static void print_record_cb(const struct pfx_record
*record
, void *data
)
285 struct rpki_for_each_record_arg
*arg
= data
;
286 struct vty
*vty
= arg
->vty
;
288 (*arg
->prefix_amount
)++;
290 print_record(record
, vty
);
293 static struct rtr_mgr_group
*get_groups(void)
295 struct listnode
*cache_node
;
296 struct rtr_mgr_group
*rtr_mgr_groups
;
299 int group_count
= listcount(cache_list
);
301 if (group_count
== 0)
304 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
305 group_count
* sizeof(struct rtr_mgr_group
));
309 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
310 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
311 rtr_mgr_groups
[i
].sockets_len
= 1;
312 rtr_mgr_groups
[i
].preference
= cache
->preference
;
314 init_tr_socket(cache
);
319 return rtr_mgr_groups
;
322 inline int is_synchronized(void)
324 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
327 inline int is_running(void)
329 return rtr_is_running
;
332 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
334 struct prefix
*prefix
= prefix_new();
336 prefix
->prefixlen
= record
->min_len
;
338 if (record
->prefix
.ver
== LRTR_IPV4
) {
339 prefix
->family
= AF_INET
;
340 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
342 prefix
->family
= AF_INET6
;
343 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
344 prefix
->u
.prefix6
.s6_addr32
);
350 static int bgpd_sync_callback(struct thread
*thread
)
353 struct listnode
*node
;
354 struct prefix
*prefix
;
355 struct pfx_record rec
;
357 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
358 rpki_sync_socket_bgpd
, NULL
);
360 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
361 while (read(rpki_sync_socket_bgpd
, &rec
,
362 sizeof(struct pfx_record
))
366 atomic_store_explicit(&rtr_update_overflow
, 0,
367 memory_order_seq_cst
);
368 revalidate_all_routes();
373 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
374 if (retval
!= sizeof(struct pfx_record
)) {
375 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
378 prefix
= pfx_record_to_prefix(&rec
);
380 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
382 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
384 struct listnode
*peer_listnode
;
386 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
389 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
390 if (!peer
->bgp
->rib
[afi
][safi
])
393 struct list
*matches
= list_new();
396 (void (*)(void *))bgp_unlock_node
;
398 bgp_table_range_lookup(
399 peer
->bgp
->rib
[afi
][safi
], prefix
,
400 rec
.max_len
, matches
);
403 struct bgp_node
*bgp_node
;
404 struct listnode
*bgp_listnode
;
406 for (ALL_LIST_ELEMENTS_RO(matches
, bgp_listnode
,
408 revalidate_bgp_node(bgp_node
, afi
,
411 list_delete(&matches
);
420 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
423 struct bgp_adj_in
*ain
;
425 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
427 struct bgp_path_info
*path
=
428 bgp_node_get_bgp_path_info(bgp_node
);
429 mpls_label_t
*label
= NULL
;
430 uint32_t num_labels
= 0;
432 if (path
&& path
->extra
) {
433 label
= path
->extra
->label
;
434 num_labels
= path
->extra
->num_labels
;
436 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
437 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
438 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
446 static void revalidate_all_routes(void)
449 struct listnode
*node
;
451 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
453 struct listnode
*peer_listnode
;
455 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
457 for (size_t i
= 0; i
< 2; i
++) {
459 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
461 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
463 if (!peer
->bgp
->rib
[afi
][safi
])
466 bgp_soft_reconfig_in(peer
, afi
, safi
);
473 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
474 const struct pfx_record rec
,
475 const bool added
__attribute__((unused
)))
477 if (rtr_is_stopping
|| rtr_is_starting
478 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
482 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
483 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
484 atomic_store_explicit(&rtr_update_overflow
, 1,
485 memory_order_seq_cst
);
487 else if (retval
!= sizeof(struct pfx_record
))
488 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
491 static void rpki_init_sync_socket(void)
496 RPKI_DEBUG("initializing sync socket");
497 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
498 msg
= "could not open rpki sync socketpair";
501 rpki_sync_socket_rtr
= fds
[0];
502 rpki_sync_socket_bgpd
= fds
[1];
504 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
505 msg
= "could not set rpki_sync_socket_rtr to non blocking";
509 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
510 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
515 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
516 rpki_sync_socket_bgpd
, NULL
);
521 zlog_err("RPKI: %s", msg
);
526 static int bgp_rpki_init(struct thread_master
*master
)
532 cache_list
= list_new();
533 cache_list
->del
= (void (*)(void *)) & free_cache
;
535 polling_period
= POLLING_PERIOD_DEFAULT
;
536 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
537 retry_interval
= RETRY_INTERVAL_DEFAULT
;
538 timeout
= TIMEOUT_DEFAULT
;
539 initial_synchronisation_timeout
=
540 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
541 install_cli_commands();
542 rpki_init_sync_socket();
546 static int bgp_rpki_fini(void)
549 list_delete(&cache_list
);
551 close(rpki_sync_socket_rtr
);
552 close(rpki_sync_socket_bgpd
);
557 static int bgp_rpki_module_init(void)
559 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
561 hook_register(frr_late_init
, bgp_rpki_init
);
562 hook_register(frr_early_fini
, &bgp_rpki_fini
);
567 static int start(void)
569 unsigned int waiting_time
= 0;
574 rtr_update_overflow
= 0;
576 if (list_isempty(cache_list
)) {
578 "No caches were found in config. Prefix validation is off.");
581 RPKI_DEBUG("Init rtr_mgr.");
582 int groups_len
= listcount(cache_list
);
583 struct rtr_mgr_group
*groups
= get_groups();
585 RPKI_DEBUG("Polling period: %d", polling_period
);
586 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
587 expire_interval
, retry_interval
,
588 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
589 if (ret
== RTR_ERROR
) {
590 RPKI_DEBUG("Init rtr_mgr failed.");
594 RPKI_DEBUG("Starting rtr_mgr.");
595 ret
= rtr_mgr_start(rtr_config
);
596 if (ret
== RTR_ERROR
) {
597 RPKI_DEBUG("Starting rtr_mgr failed.");
598 rtr_mgr_free(rtr_config
);
602 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
603 while (waiting_time
++ <= initial_synchronisation_timeout
) {
604 if (rtr_mgr_conf_in_sync(rtr_config
))
609 if (rtr_mgr_conf_in_sync(rtr_config
)) {
610 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
611 RPKI_DEBUG("Forcing revalidation.");
613 revalidate_all_routes();
616 "Timeout expired! Proceeding without RPKI validation data.");
620 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
625 static void stop(void)
628 if (rtr_is_running
) {
629 rtr_mgr_stop(rtr_config
);
630 rtr_mgr_free(rtr_config
);
635 static int reset(bool force
)
637 if (rtr_is_running
&& !force
)
640 RPKI_DEBUG("Resetting RPKI Session");
645 static struct rtr_mgr_group
*get_connected_group(void)
647 if (!cache_list
|| list_isempty(cache_list
))
650 return rtr_mgr_get_first_group(rtr_config
);
653 static void print_prefix_table(struct vty
*vty
)
655 struct rpki_for_each_record_arg arg
;
657 unsigned int number_of_ipv4_prefixes
= 0;
658 unsigned int number_of_ipv6_prefixes
= 0;
659 struct rtr_mgr_group
*group
= get_connected_group();
666 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
668 vty_out(vty
, "RPKI/RTR prefix table\n");
669 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
671 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
672 pfx_table_for_each_ipv4_record(pfx_table
, print_record_cb
, &arg
);
674 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
675 pfx_table_for_each_ipv6_record(pfx_table
, print_record_cb
, &arg
);
677 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
678 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
681 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
682 const struct prefix
*prefix
)
684 struct assegment
*as_segment
;
686 struct lrtr_ip_addr ip_addr_prefix
;
687 enum pfxv_state result
;
689 const char *prefix_string
;
691 if (!is_synchronized())
694 // No aspath means route comes from iBGP
695 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
697 as_number
= peer
->bgp
->as
;
699 as_segment
= attr
->aspath
->segments
;
700 // Find last AsSegment
701 while (as_segment
->next
)
702 as_segment
= as_segment
->next
;
704 if (as_segment
->type
== AS_SEQUENCE
) {
706 as_number
= as_segment
->as
[as_segment
->length
- 1];
707 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
708 || as_segment
->type
== AS_CONFED_SET
) {
710 as_number
= peer
->bgp
->as
;
712 // RFC says: "Take distinguished value NONE as asn"
713 // which means state is unknown
714 return RPKI_NOTFOUND
;
718 // Get the prefix in requested format
719 switch (prefix
->family
) {
721 ip_addr_prefix
.ver
= LRTR_IPV4
;
722 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
726 ip_addr_prefix
.ver
= LRTR_IPV6
;
727 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
728 ip_addr_prefix
.u
.addr6
.addr
);
735 // Do the actual validation
736 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
737 prefix
->prefixlen
, &result
);
739 // Print Debug output
741 inet_ntop(prefix
->family
, &prefix
->u
.prefix
, buf
, BUFSIZ
);
743 case BGP_PFXV_STATE_VALID
:
745 "Validating Prefix %s/%hhu from asn %u Result: VALID",
746 prefix_string
, prefix
->prefixlen
, as_number
);
748 case BGP_PFXV_STATE_NOT_FOUND
:
750 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
751 prefix_string
, prefix
->prefixlen
, as_number
);
752 return RPKI_NOTFOUND
;
753 case BGP_PFXV_STATE_INVALID
:
755 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
756 prefix_string
, prefix
->prefixlen
, as_number
);
760 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
761 prefix_string
, prefix
->prefixlen
, as_number
);
767 static int add_cache(struct cache
*cache
)
769 uint8_t preference
= cache
->preference
;
770 struct rtr_mgr_group group
;
772 group
.preference
= preference
;
773 group
.sockets_len
= 1;
774 group
.sockets
= &cache
->rtr_socket
;
776 listnode_add(cache_list
, cache
);
778 if (rtr_is_running
) {
779 init_tr_socket(cache
);
781 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
782 free_tr_socket(cache
);
790 static int add_tcp_cache(const char *host
, const char *port
,
791 const uint8_t preference
)
793 struct rtr_socket
*rtr_socket
;
794 struct tr_tcp_config
*tcp_config
=
795 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
796 struct tr_socket
*tr_socket
=
797 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
798 struct cache
*cache
=
799 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
801 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
802 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
803 tcp_config
->bindaddr
= NULL
;
805 rtr_socket
= create_rtr_socket(tr_socket
);
808 cache
->tr_socket
= tr_socket
;
809 cache
->tr_config
.tcp_config
= tcp_config
;
810 cache
->rtr_socket
= rtr_socket
;
811 cache
->preference
= preference
;
813 return add_cache(cache
);
816 #if defined(FOUND_SSH)
817 static int add_ssh_cache(const char *host
, const unsigned int port
,
818 const char *username
, const char *client_privkey_path
,
819 const char *client_pubkey_path
,
820 const char *server_pubkey_path
,
821 const uint8_t preference
)
823 struct tr_ssh_config
*ssh_config
=
824 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
825 struct cache
*cache
=
826 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
827 struct tr_socket
*tr_socket
=
828 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
829 struct rtr_socket
*rtr_socket
;
831 ssh_config
->port
= port
;
832 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
833 ssh_config
->bindaddr
= NULL
;
835 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
836 ssh_config
->client_privkey_path
=
837 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
838 ssh_config
->server_hostkey_path
=
839 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
841 rtr_socket
= create_rtr_socket(tr_socket
);
844 cache
->tr_socket
= tr_socket
;
845 cache
->tr_config
.ssh_config
= ssh_config
;
846 cache
->rtr_socket
= rtr_socket
;
847 cache
->preference
= preference
;
849 return add_cache(cache
);
853 static void free_cache(struct cache
*cache
)
855 if (cache
->type
== TCP
) {
856 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
857 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
858 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
860 #if defined(FOUND_SSH)
862 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
863 XFREE(MTYPE_BGP_RPKI_CACHE
,
864 cache
->tr_config
.ssh_config
->username
);
865 XFREE(MTYPE_BGP_RPKI_CACHE
,
866 cache
->tr_config
.ssh_config
->client_privkey_path
);
867 XFREE(MTYPE_BGP_RPKI_CACHE
,
868 cache
->tr_config
.ssh_config
->server_hostkey_path
);
869 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
872 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
873 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
874 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
877 static int config_write(struct vty
*vty
)
879 struct listnode
*cache_node
;
882 if (listcount(cache_list
)) {
884 vty_out(vty
, "debug rpki\n");
887 vty_out(vty
, "rpki\n");
888 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
889 vty_out(vty
, " rpki timeout %d\n", timeout
);
890 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
891 initial_synchronisation_timeout
);
892 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
893 switch (cache
->type
) {
894 struct tr_tcp_config
*tcp_config
;
895 #if defined(FOUND_SSH)
896 struct tr_ssh_config
*ssh_config
;
899 tcp_config
= cache
->tr_config
.tcp_config
;
900 vty_out(vty
, " rpki cache %s %s ",
901 tcp_config
->host
, tcp_config
->port
);
903 #if defined(FOUND_SSH)
905 ssh_config
= cache
->tr_config
.ssh_config
;
906 vty_out(vty
, " rpki cache %s %u %s %s %s ",
907 ssh_config
->host
, ssh_config
->port
,
908 ssh_config
->username
,
909 ssh_config
->client_privkey_path
,
910 ssh_config
->server_hostkey_path
!= NULL
912 ->server_hostkey_path
920 vty_out(vty
, "preference %hhu\n", cache
->preference
);
922 vty_out(vty
, " exit\n");
932 "Enable rpki and enter rpki configuration mode\n")
934 vty
->node
= RPKI_NODE
;
938 DEFUN (bgp_rpki_start
,
942 "start rpki support\n")
944 if (listcount(cache_list
) == 0)
946 "Could not start rpki because no caches are configured\n");
949 if (start() == ERROR
) {
950 RPKI_DEBUG("RPKI failed to start");
957 DEFUN (bgp_rpki_stop
,
961 "start rpki support\n")
969 DEFPY (rpki_polling_period
,
970 rpki_polling_period_cmd
,
971 "rpki polling_period (1-86400)$pp",
973 "Set polling period\n"
974 "Polling period value\n")
980 DEFUN (no_rpki_polling_period
,
981 no_rpki_polling_period_cmd
,
982 "no rpki polling_period",
985 "Set polling period back to default\n")
987 polling_period
= POLLING_PERIOD_DEFAULT
;
991 DEFPY (rpki_expire_interval
,
992 rpki_expire_interval_cmd
,
993 "rpki expire_interval (600-172800)$tmp",
995 "Set expire interval\n"
996 "Expire interval value\n")
998 if ((unsigned int)tmp
>= polling_period
) {
999 expire_interval
= tmp
;
1003 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
1004 return CMD_WARNING_CONFIG_FAILED
;
1007 DEFUN (no_rpki_expire_interval
,
1008 no_rpki_expire_interval_cmd
,
1009 "no rpki expire_interval",
1012 "Set expire interval back to default\n")
1014 expire_interval
= polling_period
* 2;
1018 DEFPY (rpki_retry_interval
,
1019 rpki_retry_interval_cmd
,
1020 "rpki retry_interval (1-7200)$tmp",
1022 "Set retry interval\n"
1023 "retry interval value\n")
1025 retry_interval
= tmp
;
1029 DEFUN (no_rpki_retry_interval
,
1030 no_rpki_retry_interval_cmd
,
1031 "no rpki retry_interval",
1034 "Set retry interval back to default\n")
1036 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1040 DEFPY (rpki_timeout
,
1042 "rpki timeout (1-4294967295)$to_arg",
1051 DEFUN (no_rpki_timeout
,
1052 no_rpki_timeout_cmd
,
1056 "Set timeout back to default\n")
1058 timeout
= TIMEOUT_DEFAULT
;
1062 DEFPY (rpki_synchronisation_timeout
,
1063 rpki_synchronisation_timeout_cmd
,
1064 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1066 "Set a timeout for the initial synchronisation of prefix validation data\n"
1069 initial_synchronisation_timeout
= ito_arg
;
1073 DEFUN (no_rpki_synchronisation_timeout
,
1074 no_rpki_synchronisation_timeout_cmd
,
1075 "no rpki initial-synchronisation-timeout",
1078 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1080 initial_synchronisation_timeout
=
1081 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1087 "rpki cache <A.B.C.D|WORD>"
1088 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1089 "preference (1-255)",
1091 "Install a cache server to current group\n"
1092 "IP address of cache server\n Hostname of cache server\n"
1096 "Path to own SSH private key\n"
1097 "Path to own SSH public key\n"
1098 "Path to Public key of cache server\n"
1099 "Preference of the cache server\n"
1100 "Preference value\n")
1104 // use ssh connection
1106 #if defined(FOUND_SSH)
1108 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1109 ssh_pubkey
, server_pubkey
, preference
);
1111 return_value
= SUCCESS
;
1113 "ssh sockets are not supported. "
1114 "Please recompile rtrlib and frr with ssh support. "
1115 "If you want to use it\n");
1117 } else { // use tcp connection
1118 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1121 if (return_value
== ERROR
) {
1122 vty_out(vty
, "Could not create new rpki cache\n");
1129 DEFPY (no_rpki_cache
,
1131 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1134 "Remove a cache server\n"
1135 "IP address of cache server\n Hostname of cache server\n"
1138 "Preference of the cache server\n"
1139 "Preference value\n")
1141 struct cache
*cache_p
= find_cache(preference
);
1144 vty_out(vty
, "Could not find cache %ld\n", preference
);
1148 if (rtr_is_running
) {
1149 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1150 vty_out(vty
, "Could not remove cache %ld", preference
);
1151 if (listcount(cache_list
) == 1)
1152 vty_out(vty
, " because it is the last cache");
1159 listnode_delete(cache_list
, cache_p
);
1160 free_cache(cache_p
);
1165 DEFUN (show_rpki_prefix_table
,
1166 show_rpki_prefix_table_cmd
,
1167 "show rpki prefix-table",
1170 "Show validated prefixes which were received from RPKI Cache\n")
1172 struct listnode
*cache_node
;
1173 struct cache
*cache
;
1175 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1176 vty_out(vty
, "host: %s port: %s\n",
1177 cache
->tr_config
.tcp_config
->host
,
1178 cache
->tr_config
.tcp_config
->port
);
1180 if (is_synchronized())
1181 print_prefix_table(vty
);
1183 vty_out(vty
, "No connection to RPKI cache server.\n");
1188 DEFPY (show_rpki_prefix
,
1189 show_rpki_prefix_cmd
,
1190 "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn]",
1193 "Lookup IP prefix and optionally ASN in prefix table\n"
1199 if (!is_synchronized()) {
1200 vty_out(vty
, "No Conection to RPKI cache server.\n");
1204 struct lrtr_ip_addr addr
;
1205 char addr_str
[INET6_ADDRSTRLEN
];
1206 size_t addr_len
= strchr(prefix_str
, '/') - prefix_str
;
1208 memset(addr_str
, 0, sizeof(addr_str
));
1209 memcpy(addr_str
, prefix_str
, addr_len
);
1211 if (lrtr_ip_str_to_addr(addr_str
, &addr
) != 0) {
1212 vty_out(vty
, "Invalid IP prefix\n");
1216 struct pfx_record
*matches
= NULL
;
1217 unsigned int match_count
= 0;
1218 enum pfxv_state result
;
1220 if (pfx_table_validate_r(rtr_config
->pfx_table
, &matches
, &match_count
,
1221 asn
, &addr
, prefix
->prefixlen
, &result
)
1223 vty_out(vty
, "Prefix lookup failed");
1227 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
1228 for (size_t i
= 0; i
< match_count
; ++i
) {
1229 const struct pfx_record
*record
= &matches
[i
];
1231 if (record
->max_len
>= prefix
->prefixlen
1232 && ((asn
!= 0 && asn
== record
->asn
) || asn
== 0)) {
1233 print_record(&matches
[i
], vty
);
1240 DEFUN (show_rpki_cache_server
,
1241 show_rpki_cache_server_cmd
,
1242 "show rpki cache-server",
1245 "SHOW configured cache server\n")
1247 struct listnode
*cache_node
;
1248 struct cache
*cache
;
1250 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1251 if (cache
->type
== TCP
) {
1252 vty_out(vty
, "host: %s port: %s\n",
1253 cache
->tr_config
.tcp_config
->host
,
1254 cache
->tr_config
.tcp_config
->port
);
1256 #if defined(FOUND_SSH)
1257 } else if (cache
->type
== SSH
) {
1259 "host: %s port: %d username: %s "
1260 "server_hostkey_path: %s client_privkey_path: %s\n",
1261 cache
->tr_config
.ssh_config
->host
,
1262 cache
->tr_config
.ssh_config
->port
,
1263 cache
->tr_config
.ssh_config
->username
,
1264 cache
->tr_config
.ssh_config
1265 ->server_hostkey_path
,
1266 cache
->tr_config
.ssh_config
1267 ->client_privkey_path
);
1275 DEFUN (show_rpki_cache_connection
,
1276 show_rpki_cache_connection_cmd
,
1277 "show rpki cache-connection",
1280 "Show to which RPKI Cache Servers we have a connection\n")
1282 if (is_synchronized()) {
1283 struct listnode
*cache_node
;
1284 struct cache
*cache
;
1285 struct rtr_mgr_group
*group
= get_connected_group();
1288 vty_out(vty
, "Cannot find a connected group.\n");
1291 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1292 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1293 if (cache
->preference
== group
->preference
) {
1294 struct tr_tcp_config
*tcp_config
;
1295 #if defined(FOUND_SSH)
1296 struct tr_ssh_config
*ssh_config
;
1299 switch (cache
->type
) {
1302 cache
->tr_config
.tcp_config
;
1304 "rpki tcp cache %s %s pref %hhu\n",
1310 #if defined(FOUND_SSH)
1313 cache
->tr_config
.ssh_config
;
1315 "rpki ssh cache %s %u pref %hhu\n",
1328 vty_out(vty
, "No connection to RPKI cache server.\n");
1334 DEFUN_NOSH (rpki_exit
,
1337 "Exit rpki configuration and restart rpki session\n")
1341 vty
->node
= CONFIG_NODE
;
1345 DEFUN_NOSH (rpki_quit
,
1348 "Exit rpki configuration mode\n")
1350 return rpki_exit(self
, vty
, argc
, argv
);
1353 DEFUN_NOSH (rpki_end
,
1356 "End rpki configuration, restart rpki session and change to enable mode.\n")
1358 int ret
= reset(false);
1360 vty_config_exit(vty
);
1361 vty
->node
= ENABLE_NODE
;
1362 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1371 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1378 "Enable debugging for rpki\n")
1384 DEFUN (no_debug_rpki
,
1389 "Disable debugging for rpki\n")
1397 "match rpki <valid|invalid|notfound>",
1402 "Prefix not found\n")
1404 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1407 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
);
1410 case RMAP_RULE_MISSING
:
1411 vty_out(vty
, "%% BGP Can't find rule.\n");
1412 return CMD_WARNING_CONFIG_FAILED
;
1413 case RMAP_COMPILE_ERROR
:
1414 vty_out(vty
, "%% BGP Argument is malformed.\n");
1415 return CMD_WARNING_CONFIG_FAILED
;
1421 DEFUN (no_match_rpki
,
1423 "no match rpki <valid|invalid|notfound>",
1429 "Prefix not found\n")
1431 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1434 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1437 case RMAP_RULE_MISSING
:
1438 vty_out(vty
, "%% BGP Can't find rule.\n");
1440 case RMAP_COMPILE_ERROR
:
1441 vty_out(vty
, "%% BGP Argument is malformed.\n");
1444 return CMD_WARNING_CONFIG_FAILED
;
1450 static void overwrite_exit_commands(void)
1453 vector cmd_vector
= rpki_node
.cmd_vector
;
1455 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1456 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1458 if (strcmp(cmd
->string
, "exit") == 0
1459 || strcmp(cmd
->string
, "quit") == 0
1460 || strcmp(cmd
->string
, "end") == 0) {
1461 uninstall_element(RPKI_NODE
, cmd
);
1465 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1466 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1467 install_element(RPKI_NODE
, &rpki_end_cmd
);
1470 static void install_cli_commands(void)
1472 // TODO: make config write work
1473 install_node(&rpki_node
, &config_write
);
1474 install_default(RPKI_NODE
);
1475 overwrite_exit_commands();
1476 install_element(CONFIG_NODE
, &rpki_cmd
);
1477 install_element(ENABLE_NODE
, &rpki_cmd
);
1479 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1480 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1482 /* Install rpki reset command */
1483 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1485 /* Install rpki polling period commands */
1486 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1487 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1489 /* Install rpki expire interval commands */
1490 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1491 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1493 /* Install rpki retry interval commands */
1494 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1495 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1497 /* Install rpki timeout commands */
1498 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1499 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1501 /* Install rpki synchronisation timeout commands */
1502 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1503 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1505 /* Install rpki cache commands */
1506 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1507 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1509 /* Install show commands */
1510 install_element(VIEW_NODE
, &show_rpki_prefix_table_cmd
);
1511 install_element(VIEW_NODE
, &show_rpki_cache_connection_cmd
);
1512 install_element(VIEW_NODE
, &show_rpki_cache_server_cmd
);
1513 install_element(VIEW_NODE
, &show_rpki_prefix_cmd
);
1515 /* Install debug commands */
1516 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1517 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1518 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1519 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1521 /* Install route match */
1522 route_map_install_match(&route_match_rpki_cmd
);
1523 install_element(RMAP_NODE
, &match_rpki_cmd
);
1524 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1527 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1528 .description
= "Enable RPKI support for FRR.",
1529 .init
= bgp_rpki_module_init
)