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 enum route_map_cmd_result_t
route_match(void *rule
,
133 const struct prefix
*prefix
,
134 route_map_object_t type
,
136 static void *route_match_compile(const char *arg
);
137 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
139 static void revalidate_all_routes(void);
141 static struct rtr_mgr_config
*rtr_config
;
142 static struct list
*cache_list
;
143 static int rtr_is_running
;
144 static int rtr_is_stopping
;
145 static _Atomic
int rtr_update_overflow
;
146 static int rpki_debug
;
147 static unsigned int polling_period
;
148 static unsigned int expire_interval
;
149 static unsigned int retry_interval
;
150 static unsigned int timeout
;
151 static unsigned int initial_synchronisation_timeout
;
152 static int rpki_sync_socket_rtr
;
153 static int rpki_sync_socket_bgpd
;
155 static struct cmd_node rpki_node
= {RPKI_NODE
, "%s(config-rpki)# ", 1};
156 static struct route_map_rule_cmd route_match_rpki_cmd
= {
157 "rpki", route_match
, route_match_compile
, route_match_free
};
159 static void *malloc_wrapper(size_t size
)
161 return XMALLOC(MTYPE_BGP_RPKI_CACHE
, size
);
164 static void *realloc_wrapper(void *ptr
, size_t size
)
166 return XREALLOC(MTYPE_BGP_RPKI_CACHE
, ptr
, size
);
169 static void free_wrapper(void *ptr
)
171 XFREE(MTYPE_BGP_RPKI_CACHE
, ptr
);
174 static void init_tr_socket(struct cache
*cache
)
176 if (cache
->type
== TCP
)
177 tr_tcp_init(cache
->tr_config
.tcp_config
,
179 #if defined(FOUND_SSH)
181 tr_ssh_init(cache
->tr_config
.ssh_config
,
186 static void free_tr_socket(struct cache
*cache
)
188 if (cache
->type
== TCP
)
189 tr_tcp_init(cache
->tr_config
.tcp_config
,
191 #if defined(FOUND_SSH)
193 tr_ssh_init(cache
->tr_config
.ssh_config
,
198 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
199 const struct prefix
*prefix
);
201 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
205 for (i
= 0; i
< 4; i
++)
206 dest
[i
] = htonl(src
[i
]);
209 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
213 for (i
= 0; i
< 4; i
++)
214 dest
[i
] = ntohl(src
[i
]);
217 static enum route_map_cmd_result_t
route_match(void *rule
,
218 const struct prefix
*prefix
,
219 route_map_object_t type
,
222 int *rpki_status
= rule
;
223 struct bgp_path_info
*path
;
225 if (type
== RMAP_BGP
) {
228 if (rpki_validate_prefix(path
->peer
, path
->attr
, prefix
)
236 static void *route_match_compile(const char *arg
)
240 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
242 if (strcmp(arg
, "valid") == 0)
243 *rpki_status
= RPKI_VALID
;
244 else if (strcmp(arg
, "invalid") == 0)
245 *rpki_status
= RPKI_INVALID
;
247 *rpki_status
= RPKI_NOTFOUND
;
252 static void route_match_free(void *rule
)
254 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
257 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
259 struct rtr_socket
*rtr_socket
=
260 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
261 rtr_socket
->tr_socket
= tr_socket
;
265 static struct cache
*find_cache(const uint8_t preference
)
267 struct listnode
*cache_node
;
270 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
271 if (cache
->preference
== preference
)
277 static void print_record(const struct pfx_record
*record
, struct vty
*vty
)
279 char ip
[INET6_ADDRSTRLEN
];
281 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
282 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
283 record
->max_len
, record
->asn
);
286 static void print_record_cb(const struct pfx_record
*record
, void *data
)
288 struct rpki_for_each_record_arg
*arg
= data
;
289 struct vty
*vty
= arg
->vty
;
291 (*arg
->prefix_amount
)++;
293 print_record(record
, vty
);
296 static struct rtr_mgr_group
*get_groups(void)
298 struct listnode
*cache_node
;
299 struct rtr_mgr_group
*rtr_mgr_groups
;
302 int group_count
= listcount(cache_list
);
304 if (group_count
== 0)
307 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
308 group_count
* sizeof(struct rtr_mgr_group
));
312 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
313 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
314 rtr_mgr_groups
[i
].sockets_len
= 1;
315 rtr_mgr_groups
[i
].preference
= cache
->preference
;
317 init_tr_socket(cache
);
322 return rtr_mgr_groups
;
325 inline int is_synchronized(void)
327 return rtr_is_running
&& rtr_mgr_conf_in_sync(rtr_config
);
330 inline int is_running(void)
332 return rtr_is_running
;
335 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
337 struct prefix
*prefix
= prefix_new();
339 prefix
->prefixlen
= record
->min_len
;
341 if (record
->prefix
.ver
== LRTR_IPV4
) {
342 prefix
->family
= AF_INET
;
343 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
345 prefix
->family
= AF_INET6
;
346 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
347 prefix
->u
.prefix6
.s6_addr32
);
353 static int bgpd_sync_callback(struct thread
*thread
)
356 struct listnode
*node
;
357 struct prefix
*prefix
;
358 struct pfx_record rec
;
360 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
361 rpki_sync_socket_bgpd
, NULL
);
363 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
364 while (read(rpki_sync_socket_bgpd
, &rec
,
365 sizeof(struct pfx_record
))
369 atomic_store_explicit(&rtr_update_overflow
, 0,
370 memory_order_seq_cst
);
371 revalidate_all_routes();
376 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
377 if (retval
!= sizeof(struct pfx_record
)) {
378 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
381 prefix
= pfx_record_to_prefix(&rec
);
383 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
385 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
387 struct listnode
*peer_listnode
;
389 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
392 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
393 if (!peer
->bgp
->rib
[afi
][safi
])
396 struct list
*matches
= list_new();
399 (void (*)(void *))bgp_unlock_node
;
401 bgp_table_range_lookup(
402 peer
->bgp
->rib
[afi
][safi
], prefix
,
403 rec
.max_len
, matches
);
406 struct bgp_node
*bgp_node
;
407 struct listnode
*bgp_listnode
;
409 for (ALL_LIST_ELEMENTS_RO(matches
, bgp_listnode
,
411 revalidate_bgp_node(bgp_node
, afi
,
414 list_delete(&matches
);
423 static void revalidate_bgp_node(struct bgp_node
*bgp_node
, afi_t afi
,
426 struct bgp_adj_in
*ain
;
428 for (ain
= bgp_node
->adj_in
; ain
; ain
= ain
->next
) {
430 struct bgp_path_info
*path
=
431 bgp_node_get_bgp_path_info(bgp_node
);
432 mpls_label_t
*label
= NULL
;
433 uint32_t num_labels
= 0;
435 if (path
&& path
->extra
) {
436 label
= path
->extra
->label
;
437 num_labels
= path
->extra
->num_labels
;
439 ret
= bgp_update(ain
->peer
, &bgp_node
->p
, ain
->addpath_rx_id
,
440 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
441 BGP_ROUTE_NORMAL
, NULL
, label
, num_labels
, 1,
449 static void revalidate_all_routes(void)
452 struct listnode
*node
;
454 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
456 struct listnode
*peer_listnode
;
458 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
460 for (size_t i
= 0; i
< 2; i
++) {
462 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
464 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
466 if (!peer
->bgp
->rib
[afi
][safi
])
469 bgp_soft_reconfig_in(peer
, afi
, safi
);
476 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
477 const struct pfx_record rec
,
478 const bool added
__attribute__((unused
)))
481 || atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
485 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
486 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
487 atomic_store_explicit(&rtr_update_overflow
, 1,
488 memory_order_seq_cst
);
490 else if (retval
!= sizeof(struct pfx_record
))
491 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
494 static void rpki_init_sync_socket(void)
499 RPKI_DEBUG("initializing sync socket");
500 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
501 msg
= "could not open rpki sync socketpair";
504 rpki_sync_socket_rtr
= fds
[0];
505 rpki_sync_socket_bgpd
= fds
[1];
507 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
508 msg
= "could not set rpki_sync_socket_rtr to non blocking";
512 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
513 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
518 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
519 rpki_sync_socket_bgpd
, NULL
);
524 zlog_err("RPKI: %s", msg
);
529 static int bgp_rpki_init(struct thread_master
*master
)
535 cache_list
= list_new();
536 cache_list
->del
= (void (*)(void *)) & free_cache
;
538 polling_period
= POLLING_PERIOD_DEFAULT
;
539 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
540 retry_interval
= RETRY_INTERVAL_DEFAULT
;
541 timeout
= TIMEOUT_DEFAULT
;
542 initial_synchronisation_timeout
=
543 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
544 install_cli_commands();
545 rpki_init_sync_socket();
549 static int bgp_rpki_fini(void)
552 list_delete(&cache_list
);
554 close(rpki_sync_socket_rtr
);
555 close(rpki_sync_socket_bgpd
);
560 static int bgp_rpki_module_init(void)
562 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
564 hook_register(frr_late_init
, bgp_rpki_init
);
565 hook_register(frr_early_fini
, &bgp_rpki_fini
);
570 static int start(void)
575 rtr_update_overflow
= 0;
577 if (list_isempty(cache_list
)) {
579 "No caches were found in config. Prefix validation is off.");
582 RPKI_DEBUG("Init rtr_mgr.");
583 int groups_len
= listcount(cache_list
);
584 struct rtr_mgr_group
*groups
= get_groups();
586 RPKI_DEBUG("Polling period: %d", polling_period
);
587 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
588 expire_interval
, retry_interval
,
589 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
590 if (ret
== RTR_ERROR
) {
591 RPKI_DEBUG("Init rtr_mgr failed.");
595 RPKI_DEBUG("Starting rtr_mgr.");
596 ret
= rtr_mgr_start(rtr_config
);
597 if (ret
== RTR_ERROR
) {
598 RPKI_DEBUG("Starting rtr_mgr failed.");
599 rtr_mgr_free(rtr_config
);
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_cb
, &arg
);
658 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
659 pfx_table_for_each_ipv6_record(pfx_table
, print_record_cb
, &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
724 prefix_string
= prefix2str(prefix
, buf
, sizeof(buf
));
726 case BGP_PFXV_STATE_VALID
:
728 "Validating Prefix %s from asn %u Result: VALID",
729 prefix_string
, as_number
);
731 case BGP_PFXV_STATE_NOT_FOUND
:
733 "Validating Prefix %s from asn %u Result: NOT FOUND",
734 prefix_string
, as_number
);
735 return RPKI_NOTFOUND
;
736 case BGP_PFXV_STATE_INVALID
:
738 "Validating Prefix %s from asn %u Result: INVALID",
739 prefix_string
, as_number
);
743 "Validating Prefix %s from asn %u Result: CANNOT VALIDATE",
744 prefix_string
, as_number
);
750 static int add_cache(struct cache
*cache
)
752 uint8_t preference
= cache
->preference
;
753 struct rtr_mgr_group group
;
755 group
.preference
= preference
;
756 group
.sockets_len
= 1;
757 group
.sockets
= &cache
->rtr_socket
;
759 listnode_add(cache_list
, cache
);
761 if (rtr_is_running
) {
762 init_tr_socket(cache
);
764 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
765 free_tr_socket(cache
);
773 static int add_tcp_cache(const char *host
, const char *port
,
774 const uint8_t preference
)
776 struct rtr_socket
*rtr_socket
;
777 struct tr_tcp_config
*tcp_config
=
778 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
779 struct tr_socket
*tr_socket
=
780 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
781 struct cache
*cache
=
782 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
784 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
785 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
786 tcp_config
->bindaddr
= NULL
;
788 rtr_socket
= create_rtr_socket(tr_socket
);
791 cache
->tr_socket
= tr_socket
;
792 cache
->tr_config
.tcp_config
= tcp_config
;
793 cache
->rtr_socket
= rtr_socket
;
794 cache
->preference
= preference
;
796 return add_cache(cache
);
799 #if defined(FOUND_SSH)
800 static int add_ssh_cache(const char *host
, const unsigned int port
,
801 const char *username
, const char *client_privkey_path
,
802 const char *client_pubkey_path
,
803 const char *server_pubkey_path
,
804 const uint8_t preference
)
806 struct tr_ssh_config
*ssh_config
=
807 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
808 struct cache
*cache
=
809 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
810 struct tr_socket
*tr_socket
=
811 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
812 struct rtr_socket
*rtr_socket
;
814 ssh_config
->port
= port
;
815 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
816 ssh_config
->bindaddr
= NULL
;
818 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
819 ssh_config
->client_privkey_path
=
820 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
821 ssh_config
->server_hostkey_path
=
822 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
824 rtr_socket
= create_rtr_socket(tr_socket
);
827 cache
->tr_socket
= tr_socket
;
828 cache
->tr_config
.ssh_config
= ssh_config
;
829 cache
->rtr_socket
= rtr_socket
;
830 cache
->preference
= preference
;
832 return add_cache(cache
);
836 static void free_cache(struct cache
*cache
)
838 if (cache
->type
== TCP
) {
839 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
840 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
841 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
843 #if defined(FOUND_SSH)
845 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
846 XFREE(MTYPE_BGP_RPKI_CACHE
,
847 cache
->tr_config
.ssh_config
->username
);
848 XFREE(MTYPE_BGP_RPKI_CACHE
,
849 cache
->tr_config
.ssh_config
->client_privkey_path
);
850 XFREE(MTYPE_BGP_RPKI_CACHE
,
851 cache
->tr_config
.ssh_config
->server_hostkey_path
);
852 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
855 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
856 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
857 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
860 static int config_write(struct vty
*vty
)
862 struct listnode
*cache_node
;
865 if (listcount(cache_list
)) {
867 vty_out(vty
, "debug rpki\n");
870 vty_out(vty
, "rpki\n");
871 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
872 vty_out(vty
, " rpki timeout %d\n", timeout
);
873 vty_out(vty
, " rpki initial-synchronisation-timeout %d\n",
874 initial_synchronisation_timeout
);
875 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
876 switch (cache
->type
) {
877 struct tr_tcp_config
*tcp_config
;
878 #if defined(FOUND_SSH)
879 struct tr_ssh_config
*ssh_config
;
882 tcp_config
= cache
->tr_config
.tcp_config
;
883 vty_out(vty
, " rpki cache %s %s ",
884 tcp_config
->host
, tcp_config
->port
);
886 #if defined(FOUND_SSH)
888 ssh_config
= cache
->tr_config
.ssh_config
;
889 vty_out(vty
, " rpki cache %s %u %s %s %s ",
890 ssh_config
->host
, ssh_config
->port
,
891 ssh_config
->username
,
892 ssh_config
->client_privkey_path
,
893 ssh_config
->server_hostkey_path
!= NULL
895 ->server_hostkey_path
903 vty_out(vty
, "preference %hhu\n", cache
->preference
);
905 vty_out(vty
, " exit\n");
915 "Enable rpki and enter rpki configuration mode\n")
917 vty
->node
= RPKI_NODE
;
921 DEFUN (bgp_rpki_start
,
925 "start rpki support\n")
927 if (listcount(cache_list
) == 0)
929 "Could not start rpki because no caches are configured\n");
932 if (start() == ERROR
) {
933 RPKI_DEBUG("RPKI failed to start");
940 DEFUN (bgp_rpki_stop
,
944 "start rpki support\n")
952 DEFPY (rpki_polling_period
,
953 rpki_polling_period_cmd
,
954 "rpki polling_period (1-86400)$pp",
956 "Set polling period\n"
957 "Polling period value\n")
963 DEFUN (no_rpki_polling_period
,
964 no_rpki_polling_period_cmd
,
965 "no rpki polling_period",
968 "Set polling period back to default\n")
970 polling_period
= POLLING_PERIOD_DEFAULT
;
974 DEFPY (rpki_expire_interval
,
975 rpki_expire_interval_cmd
,
976 "rpki expire_interval (600-172800)$tmp",
978 "Set expire interval\n"
979 "Expire interval value\n")
981 if ((unsigned int)tmp
>= polling_period
) {
982 expire_interval
= tmp
;
986 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
987 return CMD_WARNING_CONFIG_FAILED
;
990 DEFUN (no_rpki_expire_interval
,
991 no_rpki_expire_interval_cmd
,
992 "no rpki expire_interval",
995 "Set expire interval back to default\n")
997 expire_interval
= polling_period
* 2;
1001 DEFPY (rpki_retry_interval
,
1002 rpki_retry_interval_cmd
,
1003 "rpki retry_interval (1-7200)$tmp",
1005 "Set retry interval\n"
1006 "retry interval value\n")
1008 retry_interval
= tmp
;
1012 DEFUN (no_rpki_retry_interval
,
1013 no_rpki_retry_interval_cmd
,
1014 "no rpki retry_interval",
1017 "Set retry interval back to default\n")
1019 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1023 DEFPY (rpki_timeout
,
1025 "rpki timeout (1-4294967295)$to_arg",
1034 DEFUN (no_rpki_timeout
,
1035 no_rpki_timeout_cmd
,
1039 "Set timeout back to default\n")
1041 timeout
= TIMEOUT_DEFAULT
;
1045 DEFPY (rpki_synchronisation_timeout
,
1046 rpki_synchronisation_timeout_cmd
,
1047 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1049 "Set a timeout for the initial synchronisation of prefix validation data\n"
1052 initial_synchronisation_timeout
= ito_arg
;
1056 DEFUN (no_rpki_synchronisation_timeout
,
1057 no_rpki_synchronisation_timeout_cmd
,
1058 "no rpki initial-synchronisation-timeout",
1061 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1063 initial_synchronisation_timeout
=
1064 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT
;
1070 "rpki cache <A.B.C.D|WORD>"
1071 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1072 "preference (1-255)",
1074 "Install a cache server to current group\n"
1075 "IP address of cache server\n Hostname of cache server\n"
1079 "Path to own SSH private key\n"
1080 "Path to own SSH public key\n"
1081 "Path to Public key of cache server\n"
1082 "Preference of the cache server\n"
1083 "Preference value\n")
1087 // use ssh connection
1089 #if defined(FOUND_SSH)
1091 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1092 ssh_pubkey
, server_pubkey
, preference
);
1094 return_value
= SUCCESS
;
1096 "ssh sockets are not supported. "
1097 "Please recompile rtrlib and frr with ssh support. "
1098 "If you want to use it\n");
1100 } else { // use tcp connection
1101 return_value
= add_tcp_cache(cache
, tcpport
, preference
);
1104 if (return_value
== ERROR
) {
1105 vty_out(vty
, "Could not create new rpki cache\n");
1112 DEFPY (no_rpki_cache
,
1114 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1117 "Remove a cache server\n"
1118 "IP address of cache server\n Hostname of cache server\n"
1121 "Preference of the cache server\n"
1122 "Preference value\n")
1124 struct cache
*cache_p
= find_cache(preference
);
1127 vty_out(vty
, "Could not find cache %ld\n", preference
);
1131 if (rtr_is_running
) {
1132 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1133 vty_out(vty
, "Could not remove cache %ld", preference
);
1134 if (listcount(cache_list
) == 1)
1135 vty_out(vty
, " because it is the last cache");
1142 listnode_delete(cache_list
, cache_p
);
1143 free_cache(cache_p
);
1148 DEFUN (show_rpki_prefix_table
,
1149 show_rpki_prefix_table_cmd
,
1150 "show rpki prefix-table",
1153 "Show validated prefixes which were received from RPKI Cache\n")
1155 struct listnode
*cache_node
;
1156 struct cache
*cache
;
1158 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1159 vty_out(vty
, "host: %s port: %s\n",
1160 cache
->tr_config
.tcp_config
->host
,
1161 cache
->tr_config
.tcp_config
->port
);
1163 if (is_synchronized())
1164 print_prefix_table(vty
);
1166 vty_out(vty
, "No connection to RPKI cache server.\n");
1171 DEFPY (show_rpki_prefix
,
1172 show_rpki_prefix_cmd
,
1173 "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn]",
1176 "Lookup IP prefix and optionally ASN in prefix table\n"
1182 if (!is_synchronized()) {
1183 vty_out(vty
, "No Connection to RPKI cache server.\n");
1187 struct lrtr_ip_addr addr
;
1188 char addr_str
[INET6_ADDRSTRLEN
];
1189 size_t addr_len
= strchr(prefix_str
, '/') - prefix_str
;
1191 memset(addr_str
, 0, sizeof(addr_str
));
1192 memcpy(addr_str
, prefix_str
, addr_len
);
1194 if (lrtr_ip_str_to_addr(addr_str
, &addr
) != 0) {
1195 vty_out(vty
, "Invalid IP prefix\n");
1199 struct pfx_record
*matches
= NULL
;
1200 unsigned int match_count
= 0;
1201 enum pfxv_state result
;
1203 if (pfx_table_validate_r(rtr_config
->pfx_table
, &matches
, &match_count
,
1204 asn
, &addr
, prefix
->prefixlen
, &result
)
1206 vty_out(vty
, "Prefix lookup failed");
1210 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
1211 for (size_t i
= 0; i
< match_count
; ++i
) {
1212 const struct pfx_record
*record
= &matches
[i
];
1214 if (record
->max_len
>= prefix
->prefixlen
1215 && ((asn
!= 0 && asn
== record
->asn
) || asn
== 0)) {
1216 print_record(&matches
[i
], vty
);
1223 DEFUN (show_rpki_cache_server
,
1224 show_rpki_cache_server_cmd
,
1225 "show rpki cache-server",
1228 "SHOW configured cache server\n")
1230 struct listnode
*cache_node
;
1231 struct cache
*cache
;
1233 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1234 if (cache
->type
== TCP
) {
1235 vty_out(vty
, "host: %s port: %s\n",
1236 cache
->tr_config
.tcp_config
->host
,
1237 cache
->tr_config
.tcp_config
->port
);
1239 #if defined(FOUND_SSH)
1240 } else if (cache
->type
== SSH
) {
1242 "host: %s port: %d username: %s "
1243 "server_hostkey_path: %s client_privkey_path: %s\n",
1244 cache
->tr_config
.ssh_config
->host
,
1245 cache
->tr_config
.ssh_config
->port
,
1246 cache
->tr_config
.ssh_config
->username
,
1247 cache
->tr_config
.ssh_config
1248 ->server_hostkey_path
,
1249 cache
->tr_config
.ssh_config
1250 ->client_privkey_path
);
1258 DEFUN (show_rpki_cache_connection
,
1259 show_rpki_cache_connection_cmd
,
1260 "show rpki cache-connection",
1263 "Show to which RPKI Cache Servers we have a connection\n")
1265 if (is_synchronized()) {
1266 struct listnode
*cache_node
;
1267 struct cache
*cache
;
1268 struct rtr_mgr_group
*group
= get_connected_group();
1271 vty_out(vty
, "Cannot find a connected group.\n");
1274 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1275 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1276 if (cache
->preference
== group
->preference
) {
1277 struct tr_tcp_config
*tcp_config
;
1278 #if defined(FOUND_SSH)
1279 struct tr_ssh_config
*ssh_config
;
1282 switch (cache
->type
) {
1285 cache
->tr_config
.tcp_config
;
1287 "rpki tcp cache %s %s pref %hhu\n",
1293 #if defined(FOUND_SSH)
1296 cache
->tr_config
.ssh_config
;
1298 "rpki ssh cache %s %u pref %hhu\n",
1311 vty_out(vty
, "No connection to RPKI cache server.\n");
1317 DEFUN_NOSH (rpki_exit
,
1320 "Exit rpki configuration and restart rpki session\n")
1324 vty
->node
= CONFIG_NODE
;
1328 DEFUN_NOSH (rpki_quit
,
1331 "Exit rpki configuration mode\n")
1333 return rpki_exit(self
, vty
, argc
, argv
);
1336 DEFUN_NOSH (rpki_end
,
1339 "End rpki configuration, restart rpki session and change to enable mode.\n")
1341 int ret
= reset(false);
1343 vty_config_exit(vty
);
1344 vty
->node
= ENABLE_NODE
;
1345 return ret
== SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1354 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1361 "Enable debugging for rpki\n")
1367 DEFUN (no_debug_rpki
,
1372 "Disable debugging for rpki\n")
1380 "match rpki <valid|invalid|notfound>",
1385 "Prefix not found\n")
1387 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1388 enum rmap_compile_rets ret
;
1390 ret
= route_map_add_match(index
, "rpki", argv
[2]->arg
,
1391 RMAP_EVENT_MATCH_ADDED
);
1394 case RMAP_RULE_MISSING
:
1395 vty_out(vty
, "%% BGP Can't find rule.\n");
1396 return CMD_WARNING_CONFIG_FAILED
;
1397 case RMAP_COMPILE_ERROR
:
1398 vty_out(vty
, "%% BGP Argument is malformed.\n");
1399 return CMD_WARNING_CONFIG_FAILED
;
1400 case RMAP_COMPILE_SUCCESS
:
1401 case RMAP_DUPLICATE_RULE
:
1403 * Intentionally doing nothing here
1411 DEFUN (no_match_rpki
,
1413 "no match rpki <valid|invalid|notfound>",
1419 "Prefix not found\n")
1421 VTY_DECLVAR_CONTEXT(route_map_index
, index
);
1422 enum rmap_compile_rets ret
;
1424 ret
= route_map_delete_match(index
, "rpki", argv
[3]->arg
);
1427 case RMAP_RULE_MISSING
:
1428 vty_out(vty
, "%% BGP Can't find rule.\n");
1430 case RMAP_COMPILE_ERROR
:
1431 vty_out(vty
, "%% BGP Argument is malformed.\n");
1433 case RMAP_COMPILE_SUCCESS
:
1434 case RMAP_DUPLICATE_RULE
:
1436 * Nothing to do here
1440 return CMD_WARNING_CONFIG_FAILED
;
1446 static void overwrite_exit_commands(void)
1449 vector cmd_vector
= rpki_node
.cmd_vector
;
1451 for (i
= 0; i
< cmd_vector
->active
; ++i
) {
1452 struct cmd_element
*cmd
= vector_lookup(cmd_vector
, i
);
1454 if (strcmp(cmd
->string
, "exit") == 0
1455 || strcmp(cmd
->string
, "quit") == 0
1456 || strcmp(cmd
->string
, "end") == 0) {
1457 uninstall_element(RPKI_NODE
, cmd
);
1461 install_element(RPKI_NODE
, &rpki_exit_cmd
);
1462 install_element(RPKI_NODE
, &rpki_quit_cmd
);
1463 install_element(RPKI_NODE
, &rpki_end_cmd
);
1466 static void install_cli_commands(void)
1468 // TODO: make config write work
1469 install_node(&rpki_node
, &config_write
);
1470 install_default(RPKI_NODE
);
1471 overwrite_exit_commands();
1472 install_element(CONFIG_NODE
, &rpki_cmd
);
1473 install_element(ENABLE_NODE
, &rpki_cmd
);
1475 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1476 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1478 /* Install rpki reset command */
1479 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1481 /* Install rpki polling period commands */
1482 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1483 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1485 /* Install rpki expire interval commands */
1486 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1487 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1489 /* Install rpki retry interval commands */
1490 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1491 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1493 /* Install rpki timeout commands */
1494 install_element(RPKI_NODE
, &rpki_timeout_cmd
);
1495 install_element(RPKI_NODE
, &no_rpki_timeout_cmd
);
1497 /* Install rpki synchronisation timeout commands */
1498 install_element(RPKI_NODE
, &rpki_synchronisation_timeout_cmd
);
1499 install_element(RPKI_NODE
, &no_rpki_synchronisation_timeout_cmd
);
1501 /* Install rpki cache commands */
1502 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1503 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1505 /* Install show commands */
1506 install_element(VIEW_NODE
, &show_rpki_prefix_table_cmd
);
1507 install_element(VIEW_NODE
, &show_rpki_cache_connection_cmd
);
1508 install_element(VIEW_NODE
, &show_rpki_cache_server_cmd
);
1509 install_element(VIEW_NODE
, &show_rpki_prefix_cmd
);
1511 /* Install debug commands */
1512 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1513 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1514 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1515 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1517 /* Install route match */
1518 route_map_install_match(&route_match_rpki_cmd
);
1519 install_element(RMAP_NODE
, &match_rpki_cmd
);
1520 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1523 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1524 .description
= "Enable RPKI support for FRR.",
1525 .init
= bgp_rpki_module_init
)