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"
59 #ifndef VTYSH_EXTRACT_PL
60 #include "bgpd/bgp_rpki_clippy.c"
63 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server")
64 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group")
67 #define RPKI_NOTFOUND 2
68 #define RPKI_INVALID 3
70 #define POLLING_PERIOD_DEFAULT 3600
71 #define EXPIRE_INTERVAL_DEFAULT 7200
72 #define RETRY_INTERVAL_DEFAULT 600
74 #define RPKI_DEBUG(...) \
76 zlog_debug("RPKI: " __VA_ARGS__); \
79 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
82 enum { TCP
, SSH
} type
;
83 struct tr_socket
*tr_socket
;
85 struct tr_tcp_config
*tcp_config
;
86 struct tr_ssh_config
*ssh_config
;
88 struct rtr_socket
*rtr_socket
;
92 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
94 struct rpki_for_each_record_arg
{
96 unsigned int *prefix_amount
;
99 static int start(void);
100 static void stop(void);
101 static int reset(bool force
);
102 static struct rtr_mgr_group
*get_connected_group(void);
103 static void print_prefix_table(struct vty
*vty
);
104 static void install_cli_commands(void);
105 static int config_write(struct vty
*vty
);
106 static void overwrite_exit_commands(void);
107 static void free_cache(struct cache
*cache
);
108 static struct rtr_mgr_group
*get_groups(void);
109 #if defined(FOUND_SSH)
110 static int add_ssh_cache(const char *host
, const unsigned int port
,
111 const char *username
, const char *client_privkey_path
,
112 const char *client_pubkey_path
,
113 const char *server_pubkey_path
,
114 const uint8_t preference
);
116 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
117 static struct cache
*find_cache(const uint8_t preference
);
118 static int add_tcp_cache(const char *host
, const char *port
,
119 const uint8_t preference
);
120 static void print_record(const struct pfx_record
*record
, struct vty
*vty
);
121 static int is_synchronized(void);
122 static int is_running(void);
123 static void route_match_free(void *rule
);
124 static enum route_map_cmd_result_t
route_match(void *rule
,
125 const struct prefix
*prefix
,
126 route_map_object_t type
,
128 static void *route_match_compile(const char *arg
);
129 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
131 static void revalidate_all_routes(void);
133 static struct rtr_mgr_config
*rtr_config
;
134 static struct list
*cache_list
;
135 static int rtr_is_running
;
136 static int rtr_is_stopping
;
137 static _Atomic
int rtr_update_overflow
;
138 static int rpki_debug
;
139 static unsigned int polling_period
;
140 static unsigned int expire_interval
;
141 static unsigned int retry_interval
;
142 static int rpki_sync_socket_rtr
;
143 static int rpki_sync_socket_bgpd
;
145 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
146 static struct route_map_rule_cmd route_match_rpki_cmd
= {
147 "rpki", route_match
, route_match_compile
, route_match_free
};
149 static void *malloc_wrapper(size_t size
)
151 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
154 static void *realloc_wrapper(void *ptr
, size_t size
)
156 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
159 static void free_wrapper(void *ptr
)
161 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
164 static void init_tr_socket(struct cache
*cache
)
166 if (cache
->type
== TCP
)
167 tr_tcp_init(cache
->tr_config
.tcp_config
,
169 #if defined(FOUND_SSH)
171 tr_ssh_init(cache
->tr_config
.ssh_config
,
176 static void free_tr_socket(struct cache
*cache
)
178 if (cache
->type
== TCP
)
179 tr_tcp_init(cache
->tr_config
.tcp_config
,
181 #if defined(FOUND_SSH)
183 tr_ssh_init(cache
->tr_config
.ssh_config
,
188 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
189 const struct prefix
*prefix
);
191 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
195 for (i
= 0; i
< 4; i
++)
196 dest
[i
] = htonl(src
[i
]);
199 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
203 for (i
= 0; i
< 4; i
++)
204 dest
[i
] = ntohl(src
[i
]);
207 static enum route_map_cmd_result_t
route_match(void *rule
,
208 const struct prefix
*prefix
,
209 route_map_object_t type
,
212 int *rpki_status
= rule
;
213 struct bgp_path_info
*path
;
215 if (type
== RMAP_BGP
) {
218 if (rpki_validate_prefix(path
->peer
, path
->attr
, prefix
)
226 static void *route_match_compile(const char *arg
)
230 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
232 if (strcmp(arg
, "valid") == 0)
233 *rpki_status
= RPKI_VALID
;
234 else if (strcmp(arg
, "invalid") == 0)
235 *rpki_status
= RPKI_INVALID
;
237 *rpki_status
= RPKI_NOTFOUND
;
242 static void route_match_free(void *rule
)
244 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
247 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
249 struct rtr_socket
*rtr_socket
=
250 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
251 rtr_socket
->tr_socket
= tr_socket
;
255 static struct cache
*find_cache(const uint8_t preference
)
257 struct listnode
*cache_node
;
260 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
261 if (cache
->preference
== preference
)
267 static void print_record(const struct pfx_record
*record
, struct vty
*vty
)
269 char ip
[INET6_ADDRSTRLEN
];
271 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
272 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
273 record
->max_len
, record
->asn
);
276 static void print_record_cb(const struct pfx_record
*record
, void *data
)
278 struct rpki_for_each_record_arg
*arg
= data
;
279 struct vty
*vty
= arg
->vty
;
281 (*arg
->prefix_amount
)++;
283 print_record(record
, vty
);
286 static struct rtr_mgr_group
*get_groups(void)
288 struct listnode
*cache_node
;
289 struct rtr_mgr_group
*rtr_mgr_groups
;
292 int group_count
= listcount(cache_list
);
294 if (group_count
== 0)
297 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
298 group_count
* sizeof(struct rtr_mgr_group
));
302 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
303 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
304 rtr_mgr_groups
[i
].sockets_len
= 1;
305 rtr_mgr_groups
[i
].preference
= cache
->preference
;
307 init_tr_socket(cache
);
312 return rtr_mgr_groups
;
315 inline int is_synchronized(void)
317 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
320 inline int is_running(void)
322 return rtr_is_running
;
325 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
327 struct prefix
*prefix
= prefix_new();
329 prefix
->prefixlen
= record
->min_len
;
331 if (record
->prefix
.ver
== LRTR_IPV4
) {
332 prefix
->family
= AF_INET
;
333 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
335 prefix
->family
= AF_INET6
;
336 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
337 prefix
->u
.prefix6
.s6_addr32
);
343 static int bgpd_sync_callback(struct thread
*thread
)
346 struct listnode
*node
;
347 struct prefix
*prefix
;
348 struct pfx_record rec
;
350 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
351 rpki_sync_socket_bgpd
, NULL
);
353 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
354 while (read(rpki_sync_socket_bgpd
, &rec
,
355 sizeof(struct pfx_record
))
359 atomic_store_explicit(&rtr_update_overflow
, 0,
360 memory_order_seq_cst
);
361 revalidate_all_routes();
366 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
367 if (retval
!= sizeof(struct pfx_record
)) {
368 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
371 prefix
= pfx_record_to_prefix(&rec
);
373 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
375 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
377 struct listnode
*peer_listnode
;
379 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
382 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
383 if (!peer
->bgp
->rib
[afi
][safi
])
386 struct list
*matches
= list_new();
389 (void (*)(void *))bgp_unlock_node
;
391 bgp_table_range_lookup(
392 peer
->bgp
->rib
[afi
][safi
], prefix
,
393 rec
.max_len
, matches
);
396 struct bgp_node
*bgp_node
;
397 struct listnode
*bgp_listnode
;
399 for (ALL_LIST_ELEMENTS_RO(matches
, bgp_listnode
,
401 revalidate_bgp_node(bgp_node
, afi
,
404 list_delete(&matches
);
413 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
416 struct bgp_adj_in
*ain
;
418 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
420 struct bgp_path_info
*path
=
421 bgp_node_get_bgp_path_info(bgp_node
);
422 mpls_label_t
*label
= NULL
;
423 uint32_t num_labels
= 0;
425 if (path
&& path
->extra
) {
426 label
= path
->extra
->label
;
427 num_labels
= path
->extra
->num_labels
;
429 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
430 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
431 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
439 static void revalidate_all_routes(void)
442 struct listnode
*node
;
444 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
446 struct listnode
*peer_listnode
;
448 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
450 for (size_t i
= 0; i
< 2; i
++) {
452 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
454 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
456 if (!peer
->bgp
->rib
[afi
][safi
])
459 bgp_soft_reconfig_in(peer
, afi
, safi
);
466 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
467 const struct pfx_record rec
,
468 const bool added
__attribute__((unused
)))
471 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
475 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
476 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
477 atomic_store_explicit(&rtr_update_overflow
, 1,
478 memory_order_seq_cst
);
480 else if (retval
!= sizeof(struct pfx_record
))
481 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
484 static void rpki_init_sync_socket(void)
489 RPKI_DEBUG("initializing sync socket");
490 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
491 msg
= "could not open rpki sync socketpair";
494 rpki_sync_socket_rtr
= fds
[0];
495 rpki_sync_socket_bgpd
= fds
[1];
497 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
498 msg
= "could not set rpki_sync_socket_rtr to non blocking";
502 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
503 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
508 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
509 rpki_sync_socket_bgpd
, NULL
);
514 zlog_err("RPKI: %s", msg
);
519 static int bgp_rpki_init(struct thread_master
*master
)
525 cache_list
= list_new();
526 cache_list
->del
= (void (*)(void *)) & free_cache
;
528 polling_period
= POLLING_PERIOD_DEFAULT
;
529 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
530 retry_interval
= RETRY_INTERVAL_DEFAULT
;
531 install_cli_commands();
532 rpki_init_sync_socket();
536 static int bgp_rpki_fini(void)
539 list_delete(&cache_list
);
541 close(rpki_sync_socket_rtr
);
542 close(rpki_sync_socket_bgpd
);
547 static int bgp_rpki_module_init(void)
549 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
551 hook_register(frr_late_init
, bgp_rpki_init
);
552 hook_register(frr_early_fini
, &bgp_rpki_fini
);
557 static int start(void)
562 rtr_update_overflow
= 0;
564 if (list_isempty(cache_list
)) {
566 "No caches were found in config. Prefix validation is off.");
569 RPKI_DEBUG("Init rtr_mgr.");
570 int groups_len
= listcount(cache_list
);
571 struct rtr_mgr_group
*groups
= get_groups();
573 RPKI_DEBUG("Polling period: %d", polling_period
);
574 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
575 expire_interval
, retry_interval
,
576 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
577 if (ret
== RTR_ERROR
) {
578 RPKI_DEBUG("Init rtr_mgr failed.");
582 RPKI_DEBUG("Starting rtr_mgr.");
583 ret
= rtr_mgr_start(rtr_config
);
584 if (ret
== RTR_ERROR
) {
585 RPKI_DEBUG("Starting rtr_mgr failed.");
586 rtr_mgr_free(rtr_config
);
591 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
596 static void stop(void)
599 if (rtr_is_running
) {
600 rtr_mgr_stop(rtr_config
);
601 rtr_mgr_free(rtr_config
);
606 static int reset(bool force
)
608 if (rtr_is_running
&& !force
)
611 RPKI_DEBUG("Resetting RPKI Session");
616 static struct rtr_mgr_group
*get_connected_group(void)
618 if (!cache_list
|| list_isempty(cache_list
))
621 return rtr_mgr_get_first_group(rtr_config
);
624 static void print_prefix_table(struct vty
*vty
)
626 struct rpki_for_each_record_arg arg
;
628 unsigned int number_of_ipv4_prefixes
= 0;
629 unsigned int number_of_ipv6_prefixes
= 0;
630 struct rtr_mgr_group
*group
= get_connected_group();
637 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
639 vty_out(vty
, "RPKI/RTR prefix table\n");
640 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
642 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
643 pfx_table_for_each_ipv4_record(pfx_table
, print_record_cb
, &arg
);
645 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
646 pfx_table_for_each_ipv6_record(pfx_table
, print_record_cb
, &arg
);
648 vty_out(vty
, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes
);
649 vty_out(vty
, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes
);
652 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
653 const struct prefix
*prefix
)
655 struct assegment
*as_segment
;
657 struct lrtr_ip_addr ip_addr_prefix
;
658 enum pfxv_state result
;
660 const char *prefix_string
;
662 if (!is_synchronized())
665 // No aspath means route comes from iBGP
666 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
668 as_number
= peer
->bgp
->as
;
670 as_segment
= attr
->aspath
->segments
;
671 // Find last AsSegment
672 while (as_segment
->next
)
673 as_segment
= as_segment
->next
;
675 if (as_segment
->type
== AS_SEQUENCE
) {
677 as_number
= as_segment
->as
[as_segment
->length
- 1];
678 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
679 || as_segment
->type
== AS_CONFED_SET
) {
681 as_number
= peer
->bgp
->as
;
683 // RFC says: "Take distinguished value NONE as asn"
684 // which means state is unknown
685 return RPKI_NOTFOUND
;
689 // Get the prefix in requested format
690 switch (prefix
->family
) {
692 ip_addr_prefix
.ver
= LRTR_IPV4
;
693 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
697 ip_addr_prefix
.ver
= LRTR_IPV6
;
698 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
699 ip_addr_prefix
.u
.addr6
.addr
);
706 // Do the actual validation
707 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
708 prefix
->prefixlen
, &result
);
710 // Print Debug output
711 prefix_string
= prefix2str(prefix
, buf
, sizeof(buf
));
713 case BGP_PFXV_STATE_VALID
:
715 "Validating Prefix %s from asn %u Result: VALID",
716 prefix_string
, as_number
);
718 case BGP_PFXV_STATE_NOT_FOUND
:
720 "Validating Prefix %s from asn %u Result: NOT FOUND",
721 prefix_string
, as_number
);
722 return RPKI_NOTFOUND
;
723 case BGP_PFXV_STATE_INVALID
:
725 "Validating Prefix %s from asn %u Result: INVALID",
726 prefix_string
, as_number
);
730 "Validating Prefix %s from asn %u Result: CANNOT VALIDATE",
731 prefix_string
, as_number
);
737 static int add_cache(struct cache
*cache
)
739 uint8_t preference
= cache
->preference
;
740 struct rtr_mgr_group group
;
742 group
.preference
= preference
;
743 group
.sockets_len
= 1;
744 group
.sockets
= &cache
->rtr_socket
;
746 if (rtr_is_running
) {
747 init_tr_socket(cache
);
749 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
750 free_tr_socket(cache
);
755 listnode_add(cache_list
, cache
);
760 static int add_tcp_cache(const char *host
, const char *port
,
761 const uint8_t preference
)
763 struct rtr_socket
*rtr_socket
;
764 struct tr_tcp_config
*tcp_config
=
765 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
766 struct tr_socket
*tr_socket
=
767 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
768 struct cache
*cache
=
769 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
771 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
772 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
773 tcp_config
->bindaddr
= NULL
;
775 rtr_socket
= create_rtr_socket(tr_socket
);
778 cache
->tr_socket
= tr_socket
;
779 cache
->tr_config
.tcp_config
= tcp_config
;
780 cache
->rtr_socket
= rtr_socket
;
781 cache
->preference
= preference
;
783 int ret
= add_cache(cache
);
784 if (ret
!= SUCCESS
) {
791 #if defined(FOUND_SSH)
792 static int add_ssh_cache(const char *host
, const unsigned int port
,
793 const char *username
, const char *client_privkey_path
,
794 const char *client_pubkey_path
,
795 const char *server_pubkey_path
,
796 const uint8_t preference
)
798 struct tr_ssh_config
*ssh_config
=
799 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
800 struct cache
*cache
=
801 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
802 struct tr_socket
*tr_socket
=
803 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
804 struct rtr_socket
*rtr_socket
;
806 ssh_config
->port
= port
;
807 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
808 ssh_config
->bindaddr
= NULL
;
810 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
811 ssh_config
->client_privkey_path
=
812 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
813 ssh_config
->server_hostkey_path
=
814 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
816 rtr_socket
= create_rtr_socket(tr_socket
);
819 cache
->tr_socket
= tr_socket
;
820 cache
->tr_config
.ssh_config
= ssh_config
;
821 cache
->rtr_socket
= rtr_socket
;
822 cache
->preference
= preference
;
824 int ret
= add_cache(cache
);
825 if (ret
!= SUCCESS
) {
833 static void free_cache(struct cache
*cache
)
835 if (cache
->type
== TCP
) {
836 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
837 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
838 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
840 #if defined(FOUND_SSH)
842 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
843 XFREE(MTYPE_BGP_RPKI_CACHE
,
844 cache
->tr_config
.ssh_config
->username
);
845 XFREE(MTYPE_BGP_RPKI_CACHE
,
846 cache
->tr_config
.ssh_config
->client_privkey_path
);
847 XFREE(MTYPE_BGP_RPKI_CACHE
,
848 cache
->tr_config
.ssh_config
->server_hostkey_path
);
849 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
852 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
853 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
854 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
857 static int config_write(struct vty
*vty
)
859 struct listnode
*cache_node
;
862 if (listcount(cache_list
)) {
864 vty_out(vty
, "debug rpki\n");
867 vty_out(vty
, "rpki\n");
868 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
869 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
870 switch (cache
->type
) {
871 struct tr_tcp_config
*tcp_config
;
872 #if defined(FOUND_SSH)
873 struct tr_ssh_config
*ssh_config
;
876 tcp_config
= cache
->tr_config
.tcp_config
;
877 vty_out(vty
, " rpki cache %s %s ",
878 tcp_config
->host
, tcp_config
->port
);
880 #if defined(FOUND_SSH)
882 ssh_config
= cache
->tr_config
.ssh_config
;
883 vty_out(vty
, " rpki cache %s %u %s %s %s ",
884 ssh_config
->host
, ssh_config
->port
,
885 ssh_config
->username
,
886 ssh_config
->client_privkey_path
,
887 ssh_config
->server_hostkey_path
!= NULL
889 ->server_hostkey_path
897 vty_out(vty
, "preference %hhu\n", cache
->preference
);
899 vty_out(vty
, " exit\n");
909 "Enable rpki and enter rpki configuration mode\n")
911 vty
->node
= RPKI_NODE
;
915 DEFUN (bgp_rpki_start
,
919 "start rpki support\n")
921 if (listcount(cache_list
) == 0)
923 "Could not start rpki because no caches are configured\n");
926 if (start() == ERROR
) {
927 RPKI_DEBUG("RPKI failed to start");
934 DEFUN (bgp_rpki_stop
,
938 "start rpki support\n")
946 DEFPY (rpki_polling_period
,
947 rpki_polling_period_cmd
,
948 "rpki polling_period (1-86400)$pp",
950 "Set polling period\n"
951 "Polling period value\n")
957 DEFUN (no_rpki_polling_period
,
958 no_rpki_polling_period_cmd
,
959 "no rpki polling_period",
962 "Set polling period back to default\n")
964 polling_period
= POLLING_PERIOD_DEFAULT
;
968 DEFPY (rpki_expire_interval
,
969 rpki_expire_interval_cmd
,
970 "rpki expire_interval (600-172800)$tmp",
972 "Set expire interval\n"
973 "Expire interval value\n")
975 if ((unsigned int)tmp
>= polling_period
) {
976 expire_interval
= tmp
;
980 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
981 return CMD_WARNING_CONFIG_FAILED
;
984 DEFUN (no_rpki_expire_interval
,
985 no_rpki_expire_interval_cmd
,
986 "no rpki expire_interval",
989 "Set expire interval back to default\n")
991 expire_interval
= polling_period
* 2;
995 DEFPY (rpki_retry_interval
,
996 rpki_retry_interval_cmd
,
997 "rpki retry_interval (1-7200)$tmp",
999 "Set retry interval\n"
1000 "retry interval value\n")
1002 retry_interval
= tmp
;
1006 DEFUN (no_rpki_retry_interval
,
1007 no_rpki_retry_interval_cmd
,
1008 "no rpki retry_interval",
1011 "Set retry interval back to default\n")
1013 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1017 #if (CONFDATE > 20200901)
1018 CPP_NOTICE("bgpd: time to remove rpki timeout")
1019 CPP_NOTICE("bgpd: this includes rpki_timeout and rpki_synchronisation_timeout")
1022 DEFPY_HIDDEN (rpki_timeout
,
1024 "rpki timeout (1-4294967295)$to_arg",
1030 "This config option is deprecated, and is scheduled for removal.\n");
1032 "This functionality has also already been removed because it caused bugs and was pointless\n");
1036 DEFUN_HIDDEN (no_rpki_timeout
,
1037 no_rpki_timeout_cmd
,
1041 "Set timeout back to default\n")
1044 "This config option is deprecated, and is scheduled for removal.\n");
1046 "This functionality has also already been removed because it caused bugs and was pointless\n");
1050 DEFPY_HIDDEN (rpki_synchronisation_timeout
,
1051 rpki_synchronisation_timeout_cmd
,
1052 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1054 "Set a timeout for the initial synchronisation of prefix validation data\n"
1058 "This config option is deprecated, and is scheduled for removal.\n");
1060 "This functionality has also already been removed because it caused bugs and was pointless\n");
1064 DEFUN_HIDDEN (no_rpki_synchronisation_timeout
,
1065 no_rpki_synchronisation_timeout_cmd
,
1066 "no rpki initial-synchronisation-timeout",
1069 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1072 "This config option is deprecated, and is scheduled for removal.\n");
1074 "This functionality has also already been removed because it caused bugs and was pointless\n");
1080 "rpki cache <A.B.C.D|WORD>"
1081 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1082 "preference (1-255)",
1084 "Install a cache server to current group\n"
1085 "IP address of cache server\n Hostname of cache server\n"
1089 "Path to own SSH private key\n"
1090 "Path to own SSH public key\n"
1091 "Path to Public key of cache server\n"
1092 "Preference of the cache server\n"
1093 "Preference value\n")
1096 struct listnode
*cache_node
;
1097 struct cache
*current_cache
;
1099 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, current_cache
)) {
1100 if (current_cache
->preference
== preference
) {
1102 "Cache with preference %ld is already configured\n",
1109 // use ssh connection
1111 #if defined(FOUND_SSH)
1113 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1114 ssh_pubkey
, server_pubkey
, preference
);
1116 return_value
= SUCCESS
;
1118 "ssh sockets are not supported. "
1119 "Please recompile rtrlib and frr with ssh support. "
1120 "If you want to use it\n");
1122 } else { // use tcp connection
1123 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1126 if (return_value
== ERROR
) {
1127 vty_out(vty
, "Could not create new rpki cache\n");
1134 DEFPY (no_rpki_cache
,
1136 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1139 "Remove a cache server\n"
1140 "IP address of cache server\n Hostname of cache server\n"
1143 "Preference of the cache server\n"
1144 "Preference value\n")
1146 struct cache
*cache_p
= find_cache(preference
);
1149 vty_out(vty
, "Could not find cache %ld\n", preference
);
1153 if (rtr_is_running
&& listcount(cache_list
) == 1) {
1155 } else if (rtr_is_running
) {
1156 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1157 vty_out(vty
, "Could not remove cache %ld", preference
);
1164 listnode_delete(cache_list
, cache_p
);
1165 free_cache(cache_p
);
1170 DEFUN (show_rpki_prefix_table
,
1171 show_rpki_prefix_table_cmd
,
1172 "show rpki prefix-table",
1175 "Show validated prefixes which were received from RPKI Cache\n")
1177 struct listnode
*cache_node
;
1178 struct cache
*cache
;
1180 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1181 vty_out(vty
, "host: %s port: %s\n",
1182 cache
->tr_config
.tcp_config
->host
,
1183 cache
->tr_config
.tcp_config
->port
);
1185 if (is_synchronized())
1186 print_prefix_table(vty
);
1188 vty_out(vty
, "No connection to RPKI cache server.\n");
1193 DEFPY (show_rpki_prefix
,
1194 show_rpki_prefix_cmd
,
1195 "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn]",
1198 "Lookup IP prefix and optionally ASN in prefix table\n"
1204 if (!is_synchronized()) {
1205 vty_out(vty
, "No Connection to RPKI cache server.\n");
1209 struct lrtr_ip_addr addr
;
1210 char addr_str
[INET6_ADDRSTRLEN
];
1211 size_t addr_len
= strchr(prefix_str
, '/') - prefix_str
;
1213 memset(addr_str
, 0, sizeof(addr_str
));
1214 memcpy(addr_str
, prefix_str
, addr_len
);
1216 if (lrtr_ip_str_to_addr(addr_str
, &addr
) != 0) {
1217 vty_out(vty
, "Invalid IP prefix\n");
1221 struct pfx_record
*matches
= NULL
;
1222 unsigned int match_count
= 0;
1223 enum pfxv_state result
;
1225 if (pfx_table_validate_r(rtr_config
->pfx_table
, &matches
, &match_count
,
1226 asn
, &addr
, prefix
->prefixlen
, &result
)
1228 vty_out(vty
, "Prefix lookup failed");
1232 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
1233 for (size_t i
= 0; i
< match_count
; ++i
) {
1234 const struct pfx_record
*record
= &matches
[i
];
1236 if (record
->max_len
>= prefix
->prefixlen
1237 && ((asn
!= 0 && asn
== record
->asn
) || asn
== 0)) {
1238 print_record(&matches
[i
], vty
);
1245 DEFUN (show_rpki_cache_server
,
1246 show_rpki_cache_server_cmd
,
1247 "show rpki cache-server",
1250 "SHOW configured cache server\n")
1252 struct listnode
*cache_node
;
1253 struct cache
*cache
;
1255 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1256 if (cache
->type
== TCP
) {
1257 vty_out(vty
, "host: %s port: %s\n",
1258 cache
->tr_config
.tcp_config
->host
,
1259 cache
->tr_config
.tcp_config
->port
);
1261 #if defined(FOUND_SSH)
1262 } else if (cache
->type
== SSH
) {
1264 "host: %s port: %d username: %s "
1265 "server_hostkey_path: %s client_privkey_path: %s\n",
1266 cache
->tr_config
.ssh_config
->host
,
1267 cache
->tr_config
.ssh_config
->port
,
1268 cache
->tr_config
.ssh_config
->username
,
1269 cache
->tr_config
.ssh_config
1270 ->server_hostkey_path
,
1271 cache
->tr_config
.ssh_config
1272 ->client_privkey_path
);
1280 DEFUN (show_rpki_cache_connection
,
1281 show_rpki_cache_connection_cmd
,
1282 "show rpki cache-connection",
1285 "Show to which RPKI Cache Servers we have a connection\n")
1287 if (is_synchronized()) {
1288 struct listnode
*cache_node
;
1289 struct cache
*cache
;
1290 struct rtr_mgr_group
*group
= get_connected_group();
1293 vty_out(vty
, "Cannot find a connected group.\n");
1296 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1297 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1298 if (cache
->preference
== group
->preference
) {
1299 struct tr_tcp_config
*tcp_config
;
1300 #if defined(FOUND_SSH)
1301 struct tr_ssh_config
*ssh_config
;
1304 switch (cache
->type
) {
1307 cache
->tr_config
.tcp_config
;
1309 "rpki tcp cache %s %s pref %hhu\n",
1315 #if defined(FOUND_SSH)
1318 cache
->tr_config
.ssh_config
;
1320 "rpki ssh cache %s %u pref %hhu\n",
1333 vty_out(vty
, "No connection to RPKI cache server.\n");
1339 DEFUN_NOSH (rpki_exit
,
1342 "Exit rpki configuration and restart rpki session\n")
1346 vty
->node
= CONFIG_NODE
;
1350 DEFUN_NOSH (rpki_quit
,
1353 "Exit rpki configuration mode\n")
1355 return rpki_exit(self
, vty
, argc
, argv
);
1358 DEFUN_NOSH (rpki_end
,
1361 "End rpki configuration, restart rpki session and change to enable mode.\n")
1363 int ret
= reset(false);
1365 vty_config_exit(vty
);
1366 vty
->node
= ENABLE_NODE
;
1367 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1376 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1383 "Enable debugging for rpki\n")
1389 DEFUN (no_debug_rpki
,
1394 "Disable debugging for rpki\n")
1402 "match rpki <valid|invalid|notfound>",
1407 "Prefix not found\n")
1409 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1410 enum rmap_compile_rets ret
;
1412 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
,
1413 RMAP_EVENT_MATCH_ADDED
);
1416 case RMAP_RULE_MISSING
:
1417 vty_out(vty
, "%% BGP Can't find rule.\n");
1418 return CMD_WARNING_CONFIG_FAILED
;
1419 case RMAP_COMPILE_ERROR
:
1420 vty_out(vty
, "%% BGP Argument is malformed.\n");
1421 return CMD_WARNING_CONFIG_FAILED
;
1422 case RMAP_COMPILE_SUCCESS
:
1424 * Intentionally doing nothing here
1432 DEFUN (no_match_rpki
,
1434 "no match rpki <valid|invalid|notfound>",
1440 "Prefix not found\n")
1442 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1443 enum rmap_compile_rets ret
;
1445 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
,
1446 RMAP_EVENT_MATCH_DELETED
);
1449 case RMAP_RULE_MISSING
:
1450 vty_out(vty
, "%% BGP Can't find rule.\n");
1452 case RMAP_COMPILE_ERROR
:
1453 vty_out(vty
, "%% BGP Argument is malformed.\n");
1455 case RMAP_COMPILE_SUCCESS
:
1457 * Nothing to do here
1461 return CMD_WARNING_CONFIG_FAILED
;
1467 static void overwrite_exit_commands(void)
1470 vector cmd_vector
= rpki_node
.cmd_vector
;
1472 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1473 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1475 if (strcmp(cmd
->string
, "exit") == 0
1476 || strcmp(cmd
->string
, "quit") == 0
1477 || strcmp(cmd
->string
, "end") == 0) {
1478 uninstall_element(RPKI_NODE
, cmd
);
1482 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1483 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1484 install_element(RPKI_NODE
, &rpki_end_cmd
);
1487 static void install_cli_commands(void)
1489 // TODO: make config write work
1490 install_node(&rpki_node
, &config_write
);
1491 install_default(RPKI_NODE
);
1492 overwrite_exit_commands();
1493 install_element(CONFIG_NODE
, &rpki_cmd
);
1494 install_element(ENABLE_NODE
, &rpki_cmd
);
1496 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1497 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1499 /* Install rpki reset command */
1500 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1502 /* Install rpki polling period commands */
1503 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1504 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1506 /* Install rpki expire interval commands */
1507 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1508 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1510 /* Install rpki retry interval commands */
1511 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1512 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1514 /* Install rpki timeout commands */
1515 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1516 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1518 /* Install rpki synchronisation timeout commands */
1519 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1520 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1522 /* Install rpki cache commands */
1523 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1524 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1526 /* Install show commands */
1527 install_element(VIEW_NODE
, &show_rpki_prefix_table_cmd
);
1528 install_element(VIEW_NODE
, &show_rpki_cache_connection_cmd
);
1529 install_element(VIEW_NODE
, &show_rpki_cache_server_cmd
);
1530 install_element(VIEW_NODE
, &show_rpki_prefix_cmd
);
1532 /* Install debug commands */
1533 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1534 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1535 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1536 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1538 /* Install route match */
1539 route_map_install_match(&route_match_rpki_cmd
);
1540 install_element(RMAP_NODE
, &match_rpki_cmd
);
1541 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1544 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1545 .description
= "Enable RPKI support for FRR.",
1546 .init
= bgp_rpki_module_init
)