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 "bgpd/bgp_rpki.h"
51 #include "northbound_cli.h"
53 #include "lib/network.h"
54 #include "lib/thread.h"
55 #ifndef VTYSH_EXTRACT_PL
56 #include "rtrlib/rtrlib.h"
60 #include "lib/version.h"
62 #ifndef VTYSH_EXTRACT_PL
63 #include "bgpd/bgp_rpki_clippy.c"
66 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE
, "BGP RPKI Cache server");
67 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_CACHE_GROUP
, "BGP RPKI Cache server group");
68 DEFINE_MTYPE_STATIC(BGPD
, BGP_RPKI_RTRLIB
, "BGP RPKI RTRLib");
70 #define POLLING_PERIOD_DEFAULT 3600
71 #define EXPIRE_INTERVAL_DEFAULT 7200
72 #define RETRY_INTERVAL_DEFAULT 600
73 #define BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT 3
75 static struct thread
*t_rpki_sync
;
77 #define RPKI_DEBUG(...) \
79 zlog_debug("RPKI: " __VA_ARGS__); \
82 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
85 enum { TCP
, SSH
} type
;
86 struct tr_socket
*tr_socket
;
88 struct tr_tcp_config
*tcp_config
;
89 struct tr_ssh_config
*ssh_config
;
91 struct rtr_socket
*rtr_socket
;
95 enum return_values
{ SUCCESS
= 0, ERROR
= -1 };
97 struct rpki_for_each_record_arg
{
99 unsigned int *prefix_amount
;
104 static int start(void);
105 static void stop(void);
106 static int reset(bool force
);
107 static struct rtr_mgr_group
*get_connected_group(void);
108 static void print_prefix_table(struct vty
*vty
, json_object
*json
);
109 static void install_cli_commands(void);
110 static int config_write(struct vty
*vty
);
111 static int config_on_exit(struct vty
*vty
);
112 static void free_cache(struct cache
*cache
);
113 static struct rtr_mgr_group
*get_groups(void);
114 #if defined(FOUND_SSH)
115 static int add_ssh_cache(const char *host
, const unsigned int port
,
116 const char *username
, const char *client_privkey_path
,
117 const char *server_pubkey_path
,
118 const uint8_t preference
, const char *bindaddr
);
120 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
);
121 static struct cache
*find_cache(const uint8_t preference
);
122 static void rpki_delete_all_cache_nodes(void);
123 static int add_tcp_cache(const char *host
, const char *port
,
124 const uint8_t preference
, const char *bindaddr
);
125 static void print_record(const struct pfx_record
*record
, struct vty
*vty
,
127 static bool is_synchronized(void);
128 static bool is_running(void);
129 static bool is_stopping(void);
130 static void route_match_free(void *rule
);
131 static enum route_map_cmd_result_t
route_match(void *rule
,
132 const struct prefix
*prefix
,
135 static void *route_match_compile(const char *arg
);
136 static void revalidate_bgp_node(struct bgp_dest
*dest
, afi_t afi
, safi_t safi
);
137 static void revalidate_all_routes(void);
139 static struct rtr_mgr_config
*rtr_config
;
140 static struct list
*cache_list
;
141 static bool rtr_is_running
;
142 static bool rtr_is_stopping
;
143 static bool rtr_is_synced
;
144 static _Atomic
int rtr_update_overflow
;
145 static bool rpki_debug
;
146 static unsigned int polling_period
;
147 static unsigned int expire_interval
;
148 static unsigned int retry_interval
;
149 static int rpki_sync_socket_rtr
;
150 static int rpki_sync_socket_bgpd
;
152 static struct cmd_node rpki_node
= {
155 .parent_node
= CONFIG_NODE
,
156 .prompt
= "%s(config-rpki)# ",
157 .config_write
= config_write
,
158 .node_exit
= config_on_exit
,
160 static const struct route_map_rule_cmd route_match_rpki_cmd
= {
161 "rpki", route_match
, route_match_compile
, route_match_free
};
163 static void *malloc_wrapper(size_t size
)
165 return XMALLOC(MTYPE_BGP_RPKI_RTRLIB
, size
);
168 static void *realloc_wrapper(void *ptr
, size_t size
)
170 return XREALLOC(MTYPE_BGP_RPKI_RTRLIB
, ptr
, size
);
173 static void free_wrapper(void *ptr
)
175 XFREE(MTYPE_BGP_RPKI_RTRLIB
, ptr
);
178 static void init_tr_socket(struct cache
*cache
)
180 if (cache
->type
== TCP
)
181 tr_tcp_init(cache
->tr_config
.tcp_config
,
183 #if defined(FOUND_SSH)
185 tr_ssh_init(cache
->tr_config
.ssh_config
,
190 static void free_tr_socket(struct cache
*cache
)
192 if (cache
->type
== TCP
)
193 tr_tcp_init(cache
->tr_config
.tcp_config
,
195 #if defined(FOUND_SSH)
197 tr_ssh_init(cache
->tr_config
.ssh_config
,
202 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
203 const struct prefix
*prefix
);
205 static void ipv6_addr_to_network_byte_order(const uint32_t *src
, uint32_t *dest
)
209 for (i
= 0; i
< 4; i
++)
210 dest
[i
] = htonl(src
[i
]);
213 static void ipv6_addr_to_host_byte_order(const uint32_t *src
, uint32_t *dest
)
217 for (i
= 0; i
< 4; i
++)
218 dest
[i
] = ntohl(src
[i
]);
221 static enum route_map_cmd_result_t
route_match(void *rule
,
222 const struct prefix
*prefix
,
225 int *rpki_status
= rule
;
226 struct bgp_path_info
*path
;
230 if (rpki_validate_prefix(path
->peer
, path
->attr
, prefix
)
238 static void *route_match_compile(const char *arg
)
242 rpki_status
= XMALLOC(MTYPE_ROUTE_MAP_COMPILED
, sizeof(int));
244 if (strcmp(arg
, "valid") == 0)
245 *rpki_status
= RPKI_VALID
;
246 else if (strcmp(arg
, "invalid") == 0)
247 *rpki_status
= RPKI_INVALID
;
249 *rpki_status
= RPKI_NOTFOUND
;
254 static void route_match_free(void *rule
)
256 XFREE(MTYPE_ROUTE_MAP_COMPILED
, rule
);
259 static struct rtr_socket
*create_rtr_socket(struct tr_socket
*tr_socket
)
261 struct rtr_socket
*rtr_socket
=
262 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct rtr_socket
));
263 rtr_socket
->tr_socket
= tr_socket
;
267 static struct cache
*find_cache(const uint8_t preference
)
269 struct listnode
*cache_node
;
272 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
273 if (cache
->preference
== preference
)
279 static void rpki_delete_all_cache_nodes(void)
281 struct listnode
*cache_node
, *cache_next
;
284 for (ALL_LIST_ELEMENTS(cache_list
, cache_node
, cache_next
, cache
)) {
285 rtr_mgr_remove_group(rtr_config
, cache
->preference
);
286 listnode_delete(cache_list
, cache
);
290 static void print_record(const struct pfx_record
*record
, struct vty
*vty
,
293 char ip
[INET6_ADDRSTRLEN
];
294 json_object
*json_record
= NULL
;
296 lrtr_ip_addr_to_str(&record
->prefix
, ip
, sizeof(ip
));
299 vty_out(vty
, "%-40s %3u - %3u %10u\n", ip
, record
->min_len
,
300 record
->max_len
, record
->asn
);
302 json_record
= json_object_new_object();
303 json_object_string_add(json_record
, "prefix", ip
);
304 json_object_int_add(json_record
, "prefixLenMin",
306 json_object_int_add(json_record
, "prefixLenMax",
308 json_object_int_add(json_record
, "asn", record
->asn
);
309 json_object_array_add(json
, json_record
);
313 static void print_record_by_asn(const struct pfx_record
*record
, void *data
)
315 struct rpki_for_each_record_arg
*arg
= data
;
316 struct vty
*vty
= arg
->vty
;
318 if (record
->asn
== arg
->as
) {
319 (*arg
->prefix_amount
)++;
320 print_record(record
, vty
, arg
->json
);
324 static void print_record_cb(const struct pfx_record
*record
, void *data
)
326 struct rpki_for_each_record_arg
*arg
= data
;
327 struct vty
*vty
= arg
->vty
;
329 (*arg
->prefix_amount
)++;
331 print_record(record
, vty
, arg
->json
);
334 static struct rtr_mgr_group
*get_groups(void)
336 struct listnode
*cache_node
;
337 struct rtr_mgr_group
*rtr_mgr_groups
;
340 int group_count
= listcount(cache_list
);
342 if (group_count
== 0)
345 rtr_mgr_groups
= XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP
,
346 group_count
* sizeof(struct rtr_mgr_group
));
350 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
351 rtr_mgr_groups
[i
].sockets
= &cache
->rtr_socket
;
352 rtr_mgr_groups
[i
].sockets_len
= 1;
353 rtr_mgr_groups
[i
].preference
= cache
->preference
;
355 init_tr_socket(cache
);
360 return rtr_mgr_groups
;
363 inline bool is_synchronized(void)
365 return rtr_is_synced
;
368 inline bool is_running(void)
370 return rtr_is_running
;
373 inline bool is_stopping(void)
375 return rtr_is_stopping
;
378 static struct prefix
*pfx_record_to_prefix(struct pfx_record
*record
)
380 struct prefix
*prefix
= prefix_new();
382 prefix
->prefixlen
= record
->min_len
;
384 if (record
->prefix
.ver
== LRTR_IPV4
) {
385 prefix
->family
= AF_INET
;
386 prefix
->u
.prefix4
.s_addr
= htonl(record
->prefix
.u
.addr4
.addr
);
388 prefix
->family
= AF_INET6
;
389 ipv6_addr_to_network_byte_order(record
->prefix
.u
.addr6
.addr
,
390 prefix
->u
.prefix6
.s6_addr32
);
396 static void bgpd_sync_callback(struct thread
*thread
)
399 struct listnode
*node
;
400 struct prefix
*prefix
;
401 struct pfx_record rec
;
403 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
404 rpki_sync_socket_bgpd
, NULL
);
406 if (atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
)) {
407 while (read(rpki_sync_socket_bgpd
, &rec
,
408 sizeof(struct pfx_record
)) != -1)
411 atomic_store_explicit(&rtr_update_overflow
, 0,
412 memory_order_seq_cst
);
413 revalidate_all_routes();
418 read(rpki_sync_socket_bgpd
, &rec
, sizeof(struct pfx_record
));
419 if (retval
!= sizeof(struct pfx_record
)) {
420 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
423 prefix
= pfx_record_to_prefix(&rec
);
425 afi_t afi
= (rec
.prefix
.ver
== LRTR_IPV4
) ? AFI_IP
: AFI_IP6
;
427 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
430 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
431 if (!bgp
->rib
[afi
][safi
])
434 struct bgp_dest
*match
;
435 struct bgp_dest
*node
;
437 match
= bgp_table_subtree_lookup(bgp
->rib
[afi
][safi
],
442 if (bgp_dest_has_bgp_path_info_data(node
)) {
443 revalidate_bgp_node(node
, afi
, safi
);
446 node
= bgp_route_next_until(node
, match
);
451 prefix_free(&prefix
);
454 static void revalidate_bgp_node(struct bgp_dest
*bgp_dest
, afi_t afi
,
457 struct bgp_adj_in
*ain
;
459 for (ain
= bgp_dest
->adj_in
; ain
; ain
= ain
->next
) {
460 struct bgp_path_info
*path
=
461 bgp_dest_get_bgp_path_info(bgp_dest
);
462 mpls_label_t
*label
= NULL
;
463 uint32_t num_labels
= 0;
465 if (path
&& path
->extra
) {
466 label
= path
->extra
->label
;
467 num_labels
= path
->extra
->num_labels
;
469 (void)bgp_update(ain
->peer
, bgp_dest_get_prefix(bgp_dest
),
470 ain
->addpath_rx_id
, ain
->attr
, afi
, safi
,
471 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, label
,
472 num_labels
, 1, NULL
);
476 static void revalidate_all_routes(void)
479 struct listnode
*node
;
481 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
483 struct listnode
*peer_listnode
;
485 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
487 for (size_t i
= 0; i
< 2; i
++) {
489 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
491 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
493 if (!peer
->bgp
->rib
[afi
][safi
])
496 bgp_soft_reconfig_in(peer
, afi
, safi
);
503 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
504 const struct pfx_record rec
,
505 const bool added
__attribute__((unused
)))
508 atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
512 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
513 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
514 atomic_store_explicit(&rtr_update_overflow
, 1,
515 memory_order_seq_cst
);
517 else if (retval
!= sizeof(struct pfx_record
))
518 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
521 static void rpki_init_sync_socket(void)
526 RPKI_DEBUG("initializing sync socket");
527 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
528 msg
= "could not open rpki sync socketpair";
531 rpki_sync_socket_rtr
= fds
[0];
532 rpki_sync_socket_bgpd
= fds
[1];
534 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
535 msg
= "could not set rpki_sync_socket_rtr to non blocking";
539 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
540 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
545 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
546 rpki_sync_socket_bgpd
, NULL
);
551 zlog_err("RPKI: %s", msg
);
556 static int bgp_rpki_init(struct thread_master
*master
)
559 rtr_is_running
= false;
560 rtr_is_stopping
= false;
561 rtr_is_synced
= false;
563 cache_list
= list_new();
564 cache_list
->del
= (void (*)(void *)) & free_cache
;
566 polling_period
= POLLING_PERIOD_DEFAULT
;
567 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
568 retry_interval
= RETRY_INTERVAL_DEFAULT
;
569 install_cli_commands();
570 rpki_init_sync_socket();
574 static int bgp_rpki_fini(void)
577 list_delete(&cache_list
);
579 close(rpki_sync_socket_rtr
);
580 close(rpki_sync_socket_bgpd
);
585 static int bgp_rpki_module_init(void)
587 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
589 hook_register(bgp_rpki_prefix_status
, rpki_validate_prefix
);
590 hook_register(frr_late_init
, bgp_rpki_init
);
591 hook_register(frr_early_fini
, &bgp_rpki_fini
);
596 static void sync_expired(struct thread
*thread
)
598 if (!rtr_mgr_conf_in_sync(rtr_config
)) {
599 RPKI_DEBUG("rtr_mgr is not synced, retrying.");
600 thread_add_timer(bm
->master
, sync_expired
, NULL
,
601 BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT
,
606 RPKI_DEBUG("rtr_mgr sync is done.");
608 rtr_is_synced
= true;
611 static int start(void)
615 rtr_is_stopping
= false;
616 rtr_is_synced
= false;
617 rtr_update_overflow
= 0;
619 if (list_isempty(cache_list
)) {
621 "No caches were found in config. Prefix validation is off.");
624 RPKI_DEBUG("Init rtr_mgr.");
625 int groups_len
= listcount(cache_list
);
626 struct rtr_mgr_group
*groups
= get_groups();
628 RPKI_DEBUG("Polling period: %d", polling_period
);
629 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
630 expire_interval
, retry_interval
,
631 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
632 if (ret
== RTR_ERROR
) {
633 RPKI_DEBUG("Init rtr_mgr failed.");
637 RPKI_DEBUG("Starting rtr_mgr.");
638 ret
= rtr_mgr_start(rtr_config
);
639 if (ret
== RTR_ERROR
) {
640 RPKI_DEBUG("Starting rtr_mgr failed.");
641 rtr_mgr_free(rtr_config
);
645 thread_add_timer(bm
->master
, sync_expired
, NULL
, 0, &t_rpki_sync
);
647 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
649 rtr_is_running
= true;
654 static void stop(void)
656 rtr_is_stopping
= true;
658 THREAD_OFF(t_rpki_sync
);
659 rtr_mgr_stop(rtr_config
);
660 rtr_mgr_free(rtr_config
);
661 rtr_is_running
= false;
665 static int reset(bool force
)
667 if (is_running() && !force
)
670 RPKI_DEBUG("Resetting RPKI Session");
675 static struct rtr_mgr_group
*get_connected_group(void)
677 if (!cache_list
|| list_isempty(cache_list
))
680 return rtr_mgr_get_first_group(rtr_config
);
683 static void print_prefix_table_by_asn(struct vty
*vty
, as_t as
,
686 unsigned int number_of_ipv4_prefixes
= 0;
687 unsigned int number_of_ipv6_prefixes
= 0;
688 struct rtr_mgr_group
*group
= get_connected_group();
689 struct rpki_for_each_record_arg arg
;
690 json_object
*json_records
= NULL
;
698 vty_out(vty
, "Cannot find a connected group.\n");
702 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
705 vty_out(vty
, "RPKI/RTR prefix table\n");
706 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
709 json_records
= json_object_new_array();
710 json_object_object_add(json
, "prefixes", json_records
);
711 arg
.json
= json_records
;
714 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
715 pfx_table_for_each_ipv4_record(pfx_table
, print_record_by_asn
, &arg
);
717 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
718 pfx_table_for_each_ipv6_record(pfx_table
, print_record_by_asn
, &arg
);
721 vty_out(vty
, "Number of IPv4 Prefixes: %u\n",
722 number_of_ipv4_prefixes
);
723 vty_out(vty
, "Number of IPv6 Prefixes: %u\n",
724 number_of_ipv6_prefixes
);
726 json_object_int_add(json
, "ipv4PrefixCount",
727 number_of_ipv4_prefixes
);
728 json_object_int_add(json
, "ipv6PrefixCount",
729 number_of_ipv6_prefixes
);
736 static void print_prefix_table(struct vty
*vty
, json_object
*json
)
738 struct rpki_for_each_record_arg arg
;
740 unsigned int number_of_ipv4_prefixes
= 0;
741 unsigned int number_of_ipv6_prefixes
= 0;
742 struct rtr_mgr_group
*group
= get_connected_group();
743 json_object
*json_records
= NULL
;
750 vty_out(vty
, "Cannot find a connected group.\n");
754 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
757 vty_out(vty
, "RPKI/RTR prefix table\n");
758 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
761 json_records
= json_object_new_array();
762 json_object_object_add(json
, "prefixes", json_records
);
763 arg
.json
= json_records
;
766 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
767 pfx_table_for_each_ipv4_record(pfx_table
, print_record_cb
, &arg
);
769 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
770 pfx_table_for_each_ipv6_record(pfx_table
, print_record_cb
, &arg
);
773 vty_out(vty
, "Number of IPv4 Prefixes: %u\n",
774 number_of_ipv4_prefixes
);
775 vty_out(vty
, "Number of IPv6 Prefixes: %u\n",
776 number_of_ipv6_prefixes
);
778 json_object_int_add(json
, "ipv4PrefixCount",
779 number_of_ipv4_prefixes
);
780 json_object_int_add(json
, "ipv6PrefixCount",
781 number_of_ipv6_prefixes
);
788 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
789 const struct prefix
*prefix
)
791 struct assegment
*as_segment
;
793 struct lrtr_ip_addr ip_addr_prefix
;
794 enum pfxv_state result
;
796 if (!is_synchronized())
797 return RPKI_NOT_BEING_USED
;
799 // No aspath means route comes from iBGP
800 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
802 as_number
= peer
->bgp
->as
;
804 as_segment
= attr
->aspath
->segments
;
805 // Find last AsSegment
806 while (as_segment
->next
)
807 as_segment
= as_segment
->next
;
809 if (as_segment
->type
== AS_SEQUENCE
) {
811 as_number
= as_segment
->as
[as_segment
->length
- 1];
812 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
813 || as_segment
->type
== AS_CONFED_SET
) {
815 as_number
= peer
->bgp
->as
;
817 // RFC says: "Take distinguished value NONE as asn"
818 // which means state is unknown
819 return RPKI_NOTFOUND
;
823 // Get the prefix in requested format
824 switch (prefix
->family
) {
826 ip_addr_prefix
.ver
= LRTR_IPV4
;
827 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
831 ip_addr_prefix
.ver
= LRTR_IPV6
;
832 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
833 ip_addr_prefix
.u
.addr6
.addr
);
837 return RPKI_NOT_BEING_USED
;
840 // Do the actual validation
841 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
842 prefix
->prefixlen
, &result
);
844 // Print Debug output
846 case BGP_PFXV_STATE_VALID
:
848 "Validating Prefix %pFX from asn %u Result: VALID",
851 case BGP_PFXV_STATE_NOT_FOUND
:
853 "Validating Prefix %pFX from asn %u Result: NOT FOUND",
855 return RPKI_NOTFOUND
;
856 case BGP_PFXV_STATE_INVALID
:
858 "Validating Prefix %pFX from asn %u Result: INVALID",
863 "Validating Prefix %pFX from asn %u Result: CANNOT VALIDATE",
867 return RPKI_NOT_BEING_USED
;
870 static int add_cache(struct cache
*cache
)
872 uint8_t preference
= cache
->preference
;
873 struct rtr_mgr_group group
;
875 group
.preference
= preference
;
876 group
.sockets_len
= 1;
877 group
.sockets
= &cache
->rtr_socket
;
880 init_tr_socket(cache
);
882 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
883 free_tr_socket(cache
);
888 listnode_add(cache_list
, cache
);
893 static int add_tcp_cache(const char *host
, const char *port
,
894 const uint8_t preference
, const char *bindaddr
)
896 struct rtr_socket
*rtr_socket
;
897 struct tr_tcp_config
*tcp_config
=
898 XCALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
899 struct tr_socket
*tr_socket
=
900 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
901 struct cache
*cache
=
902 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
904 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
905 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
907 tcp_config
->bindaddr
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, bindaddr
);
909 tcp_config
->bindaddr
= NULL
;
911 rtr_socket
= create_rtr_socket(tr_socket
);
914 cache
->tr_socket
= tr_socket
;
915 cache
->tr_config
.tcp_config
= tcp_config
;
916 cache
->rtr_socket
= rtr_socket
;
917 cache
->preference
= preference
;
919 int ret
= add_cache(cache
);
920 if (ret
!= SUCCESS
) {
927 #if defined(FOUND_SSH)
928 static int add_ssh_cache(const char *host
, const unsigned int port
,
929 const char *username
, const char *client_privkey_path
,
930 const char *server_pubkey_path
,
931 const uint8_t preference
, const char *bindaddr
)
933 struct tr_ssh_config
*ssh_config
=
934 XCALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
935 struct cache
*cache
=
936 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
937 struct tr_socket
*tr_socket
=
938 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
939 struct rtr_socket
*rtr_socket
;
941 ssh_config
->port
= port
;
942 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
944 ssh_config
->bindaddr
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, bindaddr
);
946 ssh_config
->bindaddr
= NULL
;
948 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
949 ssh_config
->client_privkey_path
=
950 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
951 ssh_config
->server_hostkey_path
=
952 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
954 rtr_socket
= create_rtr_socket(tr_socket
);
957 cache
->tr_socket
= tr_socket
;
958 cache
->tr_config
.ssh_config
= ssh_config
;
959 cache
->rtr_socket
= rtr_socket
;
960 cache
->preference
= preference
;
962 int ret
= add_cache(cache
);
963 if (ret
!= SUCCESS
) {
971 static void free_cache(struct cache
*cache
)
973 if (cache
->type
== TCP
) {
974 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
975 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
976 XFREE(MTYPE_BGP_RPKI_CACHE
,
977 cache
->tr_config
.tcp_config
->bindaddr
);
978 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
980 #if defined(FOUND_SSH)
982 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
983 XFREE(MTYPE_BGP_RPKI_CACHE
,
984 cache
->tr_config
.ssh_config
->username
);
985 XFREE(MTYPE_BGP_RPKI_CACHE
,
986 cache
->tr_config
.ssh_config
->client_privkey_path
);
987 XFREE(MTYPE_BGP_RPKI_CACHE
,
988 cache
->tr_config
.ssh_config
->server_hostkey_path
);
989 XFREE(MTYPE_BGP_RPKI_CACHE
,
990 cache
->tr_config
.ssh_config
->bindaddr
);
991 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
994 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
995 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
996 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
999 static int config_write(struct vty
*vty
)
1001 struct listnode
*cache_node
;
1002 struct cache
*cache
;
1005 vty_out(vty
, "debug rpki\n");
1007 vty_out(vty
, "!\n");
1008 vty_out(vty
, "rpki\n");
1010 if (polling_period
!= POLLING_PERIOD_DEFAULT
)
1011 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
1012 if (retry_interval
!= RETRY_INTERVAL_DEFAULT
)
1013 vty_out(vty
, " rpki retry_interval %d\n", retry_interval
);
1014 if (expire_interval
!= EXPIRE_INTERVAL_DEFAULT
)
1015 vty_out(vty
, " rpki expire_interval %d\n", expire_interval
);
1017 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1018 switch (cache
->type
) {
1019 struct tr_tcp_config
*tcp_config
;
1020 #if defined(FOUND_SSH)
1021 struct tr_ssh_config
*ssh_config
;
1024 tcp_config
= cache
->tr_config
.tcp_config
;
1025 vty_out(vty
, " rpki cache %s %s ", tcp_config
->host
,
1027 if (tcp_config
->bindaddr
)
1028 vty_out(vty
, "source %s ",
1029 tcp_config
->bindaddr
);
1031 #if defined(FOUND_SSH)
1033 ssh_config
= cache
->tr_config
.ssh_config
;
1034 vty_out(vty
, " rpki cache %s %u %s %s %s ",
1035 ssh_config
->host
, ssh_config
->port
,
1036 ssh_config
->username
,
1037 ssh_config
->client_privkey_path
,
1038 ssh_config
->server_hostkey_path
!= NULL
1039 ? ssh_config
->server_hostkey_path
1041 if (ssh_config
->bindaddr
)
1042 vty_out(vty
, "source %s ",
1043 ssh_config
->bindaddr
);
1050 vty_out(vty
, "preference %hhu\n", cache
->preference
);
1052 vty_out(vty
, "exit\n");
1060 "Enable rpki and enter rpki configuration mode\n")
1062 vty
->node
= RPKI_NODE
;
1070 "Enable rpki and enter rpki configuration mode\n")
1072 rpki_delete_all_cache_nodes();
1077 DEFUN (bgp_rpki_start
,
1081 "start rpki support\n")
1083 if (listcount(cache_list
) == 0)
1085 "Could not start rpki because no caches are configured\n");
1087 if (!is_running()) {
1088 if (start() == ERROR
) {
1089 RPKI_DEBUG("RPKI failed to start");
1096 DEFUN (bgp_rpki_stop
,
1100 "start rpki support\n")
1108 DEFPY (rpki_polling_period
,
1109 rpki_polling_period_cmd
,
1110 "rpki polling_period (1-86400)$pp",
1112 "Set polling period\n"
1113 "Polling period value\n")
1115 polling_period
= pp
;
1119 DEFUN (no_rpki_polling_period
,
1120 no_rpki_polling_period_cmd
,
1121 "no rpki polling_period [(1-86400)]",
1124 "Set polling period back to default\n"
1125 "Polling period value\n")
1127 polling_period
= POLLING_PERIOD_DEFAULT
;
1131 DEFPY (rpki_expire_interval
,
1132 rpki_expire_interval_cmd
,
1133 "rpki expire_interval (600-172800)$tmp",
1135 "Set expire interval\n"
1136 "Expire interval value\n")
1138 if ((unsigned int)tmp
>= polling_period
) {
1139 expire_interval
= tmp
;
1143 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
1144 return CMD_WARNING_CONFIG_FAILED
;
1147 DEFUN (no_rpki_expire_interval
,
1148 no_rpki_expire_interval_cmd
,
1149 "no rpki expire_interval [(600-172800)]",
1152 "Set expire interval back to default\n"
1153 "Expire interval value\n")
1155 expire_interval
= polling_period
* 2;
1159 DEFPY (rpki_retry_interval
,
1160 rpki_retry_interval_cmd
,
1161 "rpki retry_interval (1-7200)$tmp",
1163 "Set retry interval\n"
1164 "retry interval value\n")
1166 retry_interval
= tmp
;
1170 DEFUN (no_rpki_retry_interval
,
1171 no_rpki_retry_interval_cmd
,
1172 "no rpki retry_interval [(1-7200)]",
1175 "Set retry interval back to default\n"
1176 "retry interval value\n")
1178 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1182 DEFPY(rpki_cache
, rpki_cache_cmd
,
1183 "rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY]> [source <A.B.C.D>$bindaddr] preference (1-255)",
1185 "Install a cache server to current group\n"
1186 "IP address of cache server\n"
1187 "Hostname of cache server\n"
1191 "Path to own SSH private key\n"
1192 "Path to Public key of cache server\n"
1193 "Configure source IP address of RPKI connection\n"
1194 "Define a Source IP Address\n"
1195 "Preference of the cache server\n"
1196 "Preference value\n")
1199 struct listnode
*cache_node
;
1200 struct cache
*current_cache
;
1202 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, current_cache
)) {
1203 if (current_cache
->preference
== preference
) {
1205 "Cache with preference %ld is already configured\n",
1212 // use ssh connection
1214 #if defined(FOUND_SSH)
1216 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1217 server_pubkey
, preference
, bindaddr_str
);
1219 return_value
= SUCCESS
;
1221 "ssh sockets are not supported. Please recompile rtrlib and frr with ssh support. If you want to use it\n");
1223 } else { // use tcp connection
1225 add_tcp_cache(cache
, tcpport
, preference
, bindaddr_str
);
1228 if (return_value
== ERROR
) {
1229 vty_out(vty
, "Could not create new rpki cache\n");
1236 DEFPY (no_rpki_cache
,
1238 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY]> [source <A.B.C.D>$bindaddr] preference (1-255)",
1241 "Install a cache server to current group\n"
1242 "IP address of cache server\n"
1243 "Hostname of cache server\n"
1247 "Path to own SSH private key\n"
1248 "Path to Public key of cache server\n"
1249 "Configure source IP address of RPKI connection\n"
1250 "Define a Source IP Address\n"
1251 "Preference of the cache server\n"
1252 "Preference value\n")
1254 struct cache
*cache_p
= find_cache(preference
);
1257 vty_out(vty
, "Could not find cache with preference %ld\n",
1262 if (is_running() && listcount(cache_list
) == 1) {
1264 } else if (is_running()) {
1265 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1267 "Could not remove cache with preference %ld\n",
1273 listnode_delete(cache_list
, cache_p
);
1274 free_cache(cache_p
);
1279 DEFPY (show_rpki_prefix_table
,
1280 show_rpki_prefix_table_cmd
,
1281 "show rpki prefix-table [json$uj]",
1284 "Show validated prefixes which were received from RPKI Cache\n"
1287 struct json_object
*json
= NULL
;
1289 if (!is_synchronized()) {
1291 vty_out(vty
, "No connection to RPKI cache server.\n");
1296 json
= json_object_new_object();
1298 print_prefix_table(vty
, json
);
1302 DEFPY (show_rpki_as_number
,
1303 show_rpki_as_number_cmd
,
1304 "show rpki as-number (1-4294967295)$by_asn [json$uj]",
1307 "Lookup by ASN in prefix table\n"
1311 struct json_object
*json
= NULL
;
1313 if (!is_synchronized()) {
1315 vty_out(vty
, "No Connection to RPKI cache server.\n");
1320 json
= json_object_new_object();
1322 print_prefix_table_by_asn(vty
, by_asn
, json
);
1326 DEFPY (show_rpki_prefix
,
1327 show_rpki_prefix_cmd
,
1328 "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn] [json$uj]",
1331 "Lookup IP prefix and optionally ASN in prefix table\n"
1337 json_object
*json
= NULL
;
1338 json_object
*json_records
= NULL
;
1340 if (!is_synchronized()) {
1342 vty_out(vty
, "No Connection to RPKI cache server.\n");
1346 struct lrtr_ip_addr addr
;
1347 char addr_str
[INET6_ADDRSTRLEN
];
1348 size_t addr_len
= strchr(prefix_str
, '/') - prefix_str
;
1350 memset(addr_str
, 0, sizeof(addr_str
));
1351 memcpy(addr_str
, prefix_str
, addr_len
);
1353 if (lrtr_ip_str_to_addr(addr_str
, &addr
) != 0) {
1355 vty_out(vty
, "Invalid IP prefix\n");
1359 struct pfx_record
*matches
= NULL
;
1360 unsigned int match_count
= 0;
1361 enum pfxv_state result
;
1363 if (pfx_table_validate_r(rtr_config
->pfx_table
, &matches
, &match_count
,
1364 asn
, &addr
, prefix
->prefixlen
, &result
)
1367 vty_out(vty
, "Prefix lookup failed\n");
1372 json
= json_object_new_object();
1375 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
1378 json_records
= json_object_new_array();
1379 json_object_object_add(json
, "prefixes", json_records
);
1382 for (size_t i
= 0; i
< match_count
; ++i
) {
1383 const struct pfx_record
*record
= &matches
[i
];
1385 if (record
->max_len
>= prefix
->prefixlen
1386 && ((asn
!= 0 && (uint32_t)asn
== record
->asn
)
1388 print_record(&matches
[i
], vty
, json_records
);
1393 vty_json(vty
, json
);
1398 DEFPY (show_rpki_cache_server
,
1399 show_rpki_cache_server_cmd
,
1400 "show rpki cache-server [json$uj]",
1403 "Show configured cache server\n"
1406 struct json_object
*json
= NULL
;
1407 struct json_object
*json_server
= NULL
;
1408 struct json_object
*json_servers
= NULL
;
1409 struct listnode
*cache_node
;
1410 struct cache
*cache
;
1413 json
= json_object_new_object();
1414 json_servers
= json_object_new_array();
1415 json_object_object_add(json
, "servers", json_servers
);
1418 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1419 if (cache
->type
== TCP
) {
1422 "host: %s port: %s, preference: %hhu\n",
1423 cache
->tr_config
.tcp_config
->host
,
1424 cache
->tr_config
.tcp_config
->port
,
1427 json_server
= json_object_new_object();
1428 json_object_string_add(json_server
, "mode",
1430 json_object_string_add(
1431 json_server
, "host",
1432 cache
->tr_config
.tcp_config
->host
);
1433 json_object_string_add(
1434 json_server
, "port",
1435 cache
->tr_config
.tcp_config
->port
);
1436 json_object_int_add(json_server
, "preference",
1438 json_object_array_add(json_servers
,
1442 #if defined(FOUND_SSH)
1443 } else if (cache
->type
== SSH
) {
1446 "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s, preference: %hhu\n",
1447 cache
->tr_config
.ssh_config
->host
,
1448 cache
->tr_config
.ssh_config
->port
,
1449 cache
->tr_config
.ssh_config
->username
,
1450 cache
->tr_config
.ssh_config
1451 ->server_hostkey_path
,
1452 cache
->tr_config
.ssh_config
1453 ->client_privkey_path
,
1456 json_server
= json_object_new_object();
1457 json_object_string_add(json_server
, "mode",
1459 json_object_string_add(
1460 json_server
, "host",
1461 cache
->tr_config
.ssh_config
->host
);
1462 json_object_int_add(
1463 json_server
, "port",
1464 cache
->tr_config
.ssh_config
->port
);
1465 json_object_string_add(
1466 json_server
, "username",
1467 cache
->tr_config
.ssh_config
->username
);
1468 json_object_string_add(
1469 json_server
, "serverHostkeyPath",
1470 cache
->tr_config
.ssh_config
1471 ->server_hostkey_path
);
1472 json_object_string_add(
1473 json_server
, "clientPrivkeyPath",
1474 cache
->tr_config
.ssh_config
1475 ->client_privkey_path
);
1476 json_object_int_add(json_server
, "preference",
1478 json_object_array_add(json_servers
,
1486 vty_json(vty
, json
);
1491 DEFPY (show_rpki_cache_connection
,
1492 show_rpki_cache_connection_cmd
,
1493 "show rpki cache-connection [json$uj]",
1496 "Show to which RPKI Cache Servers we have a connection\n"
1499 struct json_object
*json
= NULL
;
1500 struct json_object
*json_conn
= NULL
;
1501 struct json_object
*json_conns
= NULL
;
1502 struct listnode
*cache_node
;
1503 struct cache
*cache
;
1504 struct rtr_mgr_group
*group
;
1507 json
= json_object_new_object();
1509 if (!is_synchronized()) {
1511 vty_out(vty
, "No connection to RPKI cache server.\n");
1513 vty_json(vty
, json
);
1518 group
= get_connected_group();
1521 vty_out(vty
, "Cannot find a connected group.\n");
1523 vty_json(vty
, json
);
1529 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1531 json_conns
= json_object_new_array();
1532 json_object_int_add(json
, "connectedGroup", group
->preference
);
1533 json_object_object_add(json
, "connections", json_conns
);
1536 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1537 struct tr_tcp_config
*tcp_config
;
1538 #if defined(FOUND_SSH)
1539 struct tr_ssh_config
*ssh_config
;
1541 switch (cache
->type
) {
1543 tcp_config
= cache
->tr_config
.tcp_config
;
1547 "rpki tcp cache %s %s pref %hhu%s\n",
1548 tcp_config
->host
, tcp_config
->port
,
1550 cache
->rtr_socket
->state
==
1555 json_conn
= json_object_new_object();
1556 json_object_string_add(json_conn
, "mode",
1558 json_object_string_add(json_conn
, "host",
1560 json_object_string_add(json_conn
, "port",
1562 json_object_int_add(json_conn
, "preference",
1564 json_object_string_add(
1566 cache
->rtr_socket
->state
==
1570 json_object_array_add(json_conns
, json_conn
);
1573 #if defined(FOUND_SSH)
1575 ssh_config
= cache
->tr_config
.ssh_config
;
1579 "rpki ssh cache %s %u pref %hhu%s\n",
1580 ssh_config
->host
, ssh_config
->port
,
1582 cache
->rtr_socket
->state
==
1587 json_conn
= json_object_new_object();
1588 json_object_string_add(json_conn
, "mode",
1590 json_object_string_add(json_conn
, "host",
1592 json_object_int_add(json_conn
, "port",
1594 json_object_int_add(json_conn
, "preference",
1596 json_object_string_add(
1598 cache
->rtr_socket
->state
==
1602 json_object_array_add(json_conns
, json_conn
);
1612 vty_json(vty
, json
);
1617 static int config_on_exit(struct vty
*vty
)
1629 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1636 "Enable debugging for rpki\n")
1642 DEFUN (no_debug_rpki
,
1647 "Disable debugging for rpki\n")
1653 DEFUN_YANG (match_rpki
,
1655 "match rpki <valid|invalid|notfound>",
1660 "Prefix not found\n")
1663 "./match-condition[condition='frr-bgp-route-map:rpki']";
1664 char xpath_value
[XPATH_MAXLEN
];
1666 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
1667 snprintf(xpath_value
, sizeof(xpath_value
),
1668 "%s/rmap-match-condition/frr-bgp-route-map:rpki", xpath
);
1669 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[2]->arg
);
1671 return nb_cli_apply_changes(vty
, NULL
);
1674 DEFUN_YANG (no_match_rpki
,
1676 "no match rpki <valid|invalid|notfound>",
1682 "Prefix not found\n")
1685 "./match-condition[condition='frr-bgp-route-map:rpki']";
1687 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
1688 return nb_cli_apply_changes(vty
, NULL
);
1691 static void install_cli_commands(void)
1693 // TODO: make config write work
1694 install_node(&rpki_node
);
1695 install_default(RPKI_NODE
);
1696 install_element(CONFIG_NODE
, &rpki_cmd
);
1697 install_element(ENABLE_NODE
, &rpki_cmd
);
1698 install_element(CONFIG_NODE
, &no_rpki_cmd
);
1701 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1702 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1704 /* Install rpki reset command */
1705 install_element(ENABLE_NODE
, &rpki_reset_cmd
);
1706 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1708 /* Install rpki polling period commands */
1709 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1710 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1712 /* Install rpki expire interval commands */
1713 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1714 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1716 /* Install rpki retry interval commands */
1717 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1718 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1720 /* Install rpki cache commands */
1721 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1722 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1724 /* Install show commands */
1725 install_element(VIEW_NODE
, &show_rpki_prefix_table_cmd
);
1726 install_element(VIEW_NODE
, &show_rpki_cache_connection_cmd
);
1727 install_element(VIEW_NODE
, &show_rpki_cache_server_cmd
);
1728 install_element(VIEW_NODE
, &show_rpki_prefix_cmd
);
1729 install_element(VIEW_NODE
, &show_rpki_as_number_cmd
);
1731 /* Install debug commands */
1732 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1733 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1734 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1735 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1737 /* Install route match */
1738 route_map_install_match(&route_match_rpki_cmd
);
1739 install_element(RMAP_NODE
, &match_rpki_cmd
);
1740 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1743 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1744 .description
= "Enable RPKI support for FRR.",
1745 .init
= bgp_rpki_module_init
,