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 struct bgp_table
*table
= bgp
->rib
[afi
][safi
];
436 struct bgp_dest
*match
;
437 struct bgp_dest
*node
;
439 match
= bgp_table_subtree_lookup(table
, prefix
);
443 if (bgp_dest_has_bgp_path_info_data(node
)) {
444 revalidate_bgp_node(node
, afi
, safi
);
447 node
= bgp_route_next_until(node
, match
);
451 bgp_dest_unlock_node(match
);
455 prefix_free(&prefix
);
458 static void revalidate_bgp_node(struct bgp_dest
*bgp_dest
, afi_t afi
,
461 struct bgp_adj_in
*ain
;
463 for (ain
= bgp_dest
->adj_in
; ain
; ain
= ain
->next
) {
464 struct bgp_path_info
*path
=
465 bgp_dest_get_bgp_path_info(bgp_dest
);
466 mpls_label_t
*label
= NULL
;
467 uint32_t num_labels
= 0;
469 if (path
&& path
->extra
) {
470 label
= path
->extra
->label
;
471 num_labels
= path
->extra
->num_labels
;
473 (void)bgp_update(ain
->peer
, bgp_dest_get_prefix(bgp_dest
),
474 ain
->addpath_rx_id
, ain
->attr
, afi
, safi
,
475 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
, NULL
, label
,
476 num_labels
, 1, NULL
);
480 static void revalidate_all_routes(void)
483 struct listnode
*node
;
485 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, node
, bgp
)) {
487 struct listnode
*peer_listnode
;
489 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, peer_listnode
, peer
)) {
491 for (size_t i
= 0; i
< 2; i
++) {
493 afi_t afi
= (i
== 0) ? AFI_IP
: AFI_IP6
;
495 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
;
497 if (!peer
->bgp
->rib
[afi
][safi
])
500 bgp_soft_reconfig_in(peer
, afi
, safi
);
507 static void rpki_update_cb_sync_rtr(struct pfx_table
*p
__attribute__((unused
)),
508 const struct pfx_record rec
,
509 const bool added
__attribute__((unused
)))
512 atomic_load_explicit(&rtr_update_overflow
, memory_order_seq_cst
))
516 write(rpki_sync_socket_rtr
, &rec
, sizeof(struct pfx_record
));
517 if (retval
== -1 && (errno
== EAGAIN
|| errno
== EWOULDBLOCK
))
518 atomic_store_explicit(&rtr_update_overflow
, 1,
519 memory_order_seq_cst
);
521 else if (retval
!= sizeof(struct pfx_record
))
522 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
525 static void rpki_init_sync_socket(void)
530 RPKI_DEBUG("initializing sync socket");
531 if (socketpair(PF_LOCAL
, SOCK_DGRAM
, 0, fds
) != 0) {
532 msg
= "could not open rpki sync socketpair";
535 rpki_sync_socket_rtr
= fds
[0];
536 rpki_sync_socket_bgpd
= fds
[1];
538 if (set_nonblocking(rpki_sync_socket_rtr
) != 0) {
539 msg
= "could not set rpki_sync_socket_rtr to non blocking";
543 if (set_nonblocking(rpki_sync_socket_bgpd
) != 0) {
544 msg
= "could not set rpki_sync_socket_bgpd to non blocking";
549 thread_add_read(bm
->master
, bgpd_sync_callback
, NULL
,
550 rpki_sync_socket_bgpd
, NULL
);
555 zlog_err("RPKI: %s", msg
);
560 static int bgp_rpki_init(struct thread_master
*master
)
563 rtr_is_running
= false;
564 rtr_is_stopping
= false;
565 rtr_is_synced
= false;
567 cache_list
= list_new();
568 cache_list
->del
= (void (*)(void *)) & free_cache
;
570 polling_period
= POLLING_PERIOD_DEFAULT
;
571 expire_interval
= EXPIRE_INTERVAL_DEFAULT
;
572 retry_interval
= RETRY_INTERVAL_DEFAULT
;
573 install_cli_commands();
574 rpki_init_sync_socket();
578 static int bgp_rpki_fini(void)
581 list_delete(&cache_list
);
583 close(rpki_sync_socket_rtr
);
584 close(rpki_sync_socket_bgpd
);
589 static int bgp_rpki_module_init(void)
591 lrtr_set_alloc_functions(malloc_wrapper
, realloc_wrapper
, free_wrapper
);
593 hook_register(bgp_rpki_prefix_status
, rpki_validate_prefix
);
594 hook_register(frr_late_init
, bgp_rpki_init
);
595 hook_register(frr_early_fini
, &bgp_rpki_fini
);
600 static void sync_expired(struct thread
*thread
)
602 if (!rtr_mgr_conf_in_sync(rtr_config
)) {
603 RPKI_DEBUG("rtr_mgr is not synced, retrying.");
604 thread_add_timer(bm
->master
, sync_expired
, NULL
,
605 BGP_RPKI_CACHE_SERVER_SYNC_RETRY_TIMEOUT
,
610 RPKI_DEBUG("rtr_mgr sync is done.");
612 rtr_is_synced
= true;
615 static int start(void)
619 rtr_is_stopping
= false;
620 rtr_is_synced
= false;
621 rtr_update_overflow
= 0;
623 if (list_isempty(cache_list
)) {
625 "No caches were found in config. Prefix validation is off.");
628 RPKI_DEBUG("Init rtr_mgr.");
629 int groups_len
= listcount(cache_list
);
630 struct rtr_mgr_group
*groups
= get_groups();
632 RPKI_DEBUG("Polling period: %d", polling_period
);
633 ret
= rtr_mgr_init(&rtr_config
, groups
, groups_len
, polling_period
,
634 expire_interval
, retry_interval
,
635 rpki_update_cb_sync_rtr
, NULL
, NULL
, NULL
);
636 if (ret
== RTR_ERROR
) {
637 RPKI_DEBUG("Init rtr_mgr failed.");
641 RPKI_DEBUG("Starting rtr_mgr.");
642 ret
= rtr_mgr_start(rtr_config
);
643 if (ret
== RTR_ERROR
) {
644 RPKI_DEBUG("Starting rtr_mgr failed.");
645 rtr_mgr_free(rtr_config
);
649 thread_add_timer(bm
->master
, sync_expired
, NULL
, 0, &t_rpki_sync
);
651 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP
, groups
);
653 rtr_is_running
= true;
658 static void stop(void)
660 rtr_is_stopping
= true;
662 THREAD_OFF(t_rpki_sync
);
663 rtr_mgr_stop(rtr_config
);
664 rtr_mgr_free(rtr_config
);
665 rtr_is_running
= false;
669 static int reset(bool force
)
671 if (is_running() && !force
)
674 RPKI_DEBUG("Resetting RPKI Session");
679 static struct rtr_mgr_group
*get_connected_group(void)
681 if (!cache_list
|| list_isempty(cache_list
))
684 return rtr_mgr_get_first_group(rtr_config
);
687 static void print_prefix_table_by_asn(struct vty
*vty
, as_t as
,
690 unsigned int number_of_ipv4_prefixes
= 0;
691 unsigned int number_of_ipv6_prefixes
= 0;
692 struct rtr_mgr_group
*group
= get_connected_group();
693 struct rpki_for_each_record_arg arg
;
694 json_object
*json_records
= NULL
;
702 vty_out(vty
, "Cannot find a connected group.\n");
706 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
709 vty_out(vty
, "RPKI/RTR prefix table\n");
710 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
713 json_records
= json_object_new_array();
714 json_object_object_add(json
, "prefixes", json_records
);
715 arg
.json
= json_records
;
718 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
719 pfx_table_for_each_ipv4_record(pfx_table
, print_record_by_asn
, &arg
);
721 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
722 pfx_table_for_each_ipv6_record(pfx_table
, print_record_by_asn
, &arg
);
725 vty_out(vty
, "Number of IPv4 Prefixes: %u\n",
726 number_of_ipv4_prefixes
);
727 vty_out(vty
, "Number of IPv6 Prefixes: %u\n",
728 number_of_ipv6_prefixes
);
730 json_object_int_add(json
, "ipv4PrefixCount",
731 number_of_ipv4_prefixes
);
732 json_object_int_add(json
, "ipv6PrefixCount",
733 number_of_ipv6_prefixes
);
740 static void print_prefix_table(struct vty
*vty
, json_object
*json
)
742 struct rpki_for_each_record_arg arg
;
744 unsigned int number_of_ipv4_prefixes
= 0;
745 unsigned int number_of_ipv6_prefixes
= 0;
746 struct rtr_mgr_group
*group
= get_connected_group();
747 json_object
*json_records
= NULL
;
754 vty_out(vty
, "Cannot find a connected group.\n");
758 struct pfx_table
*pfx_table
= group
->sockets
[0]->pfx_table
;
761 vty_out(vty
, "RPKI/RTR prefix table\n");
762 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
765 json_records
= json_object_new_array();
766 json_object_object_add(json
, "prefixes", json_records
);
767 arg
.json
= json_records
;
770 arg
.prefix_amount
= &number_of_ipv4_prefixes
;
771 pfx_table_for_each_ipv4_record(pfx_table
, print_record_cb
, &arg
);
773 arg
.prefix_amount
= &number_of_ipv6_prefixes
;
774 pfx_table_for_each_ipv6_record(pfx_table
, print_record_cb
, &arg
);
777 vty_out(vty
, "Number of IPv4 Prefixes: %u\n",
778 number_of_ipv4_prefixes
);
779 vty_out(vty
, "Number of IPv6 Prefixes: %u\n",
780 number_of_ipv6_prefixes
);
782 json_object_int_add(json
, "ipv4PrefixCount",
783 number_of_ipv4_prefixes
);
784 json_object_int_add(json
, "ipv6PrefixCount",
785 number_of_ipv6_prefixes
);
792 static int rpki_validate_prefix(struct peer
*peer
, struct attr
*attr
,
793 const struct prefix
*prefix
)
795 struct assegment
*as_segment
;
797 struct lrtr_ip_addr ip_addr_prefix
;
798 enum pfxv_state result
;
800 if (!is_synchronized())
801 return RPKI_NOT_BEING_USED
;
803 // No aspath means route comes from iBGP
804 if (!attr
->aspath
|| !attr
->aspath
->segments
) {
806 as_number
= peer
->bgp
->as
;
808 as_segment
= attr
->aspath
->segments
;
809 // Find last AsSegment
810 while (as_segment
->next
)
811 as_segment
= as_segment
->next
;
813 if (as_segment
->type
== AS_SEQUENCE
) {
815 as_number
= as_segment
->as
[as_segment
->length
- 1];
816 } else if (as_segment
->type
== AS_CONFED_SEQUENCE
817 || as_segment
->type
== AS_CONFED_SET
) {
819 as_number
= peer
->bgp
->as
;
821 // RFC says: "Take distinguished value NONE as asn"
822 // which means state is unknown
823 return RPKI_NOTFOUND
;
827 // Get the prefix in requested format
828 switch (prefix
->family
) {
830 ip_addr_prefix
.ver
= LRTR_IPV4
;
831 ip_addr_prefix
.u
.addr4
.addr
= ntohl(prefix
->u
.prefix4
.s_addr
);
835 ip_addr_prefix
.ver
= LRTR_IPV6
;
836 ipv6_addr_to_host_byte_order(prefix
->u
.prefix6
.s6_addr32
,
837 ip_addr_prefix
.u
.addr6
.addr
);
841 return RPKI_NOT_BEING_USED
;
844 // Do the actual validation
845 rtr_mgr_validate(rtr_config
, as_number
, &ip_addr_prefix
,
846 prefix
->prefixlen
, &result
);
848 // Print Debug output
850 case BGP_PFXV_STATE_VALID
:
852 "Validating Prefix %pFX from asn %u Result: VALID",
855 case BGP_PFXV_STATE_NOT_FOUND
:
857 "Validating Prefix %pFX from asn %u Result: NOT FOUND",
859 return RPKI_NOTFOUND
;
860 case BGP_PFXV_STATE_INVALID
:
862 "Validating Prefix %pFX from asn %u Result: INVALID",
867 "Validating Prefix %pFX from asn %u Result: CANNOT VALIDATE",
871 return RPKI_NOT_BEING_USED
;
874 static int add_cache(struct cache
*cache
)
876 uint8_t preference
= cache
->preference
;
877 struct rtr_mgr_group group
;
879 group
.preference
= preference
;
880 group
.sockets_len
= 1;
881 group
.sockets
= &cache
->rtr_socket
;
884 init_tr_socket(cache
);
886 if (rtr_mgr_add_group(rtr_config
, &group
) != RTR_SUCCESS
) {
887 free_tr_socket(cache
);
892 listnode_add(cache_list
, cache
);
897 static int add_tcp_cache(const char *host
, const char *port
,
898 const uint8_t preference
, const char *bindaddr
)
900 struct rtr_socket
*rtr_socket
;
901 struct tr_tcp_config
*tcp_config
=
902 XCALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_tcp_config
));
903 struct tr_socket
*tr_socket
=
904 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
905 struct cache
*cache
=
906 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
908 tcp_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
909 tcp_config
->port
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, port
);
911 tcp_config
->bindaddr
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, bindaddr
);
913 tcp_config
->bindaddr
= NULL
;
915 rtr_socket
= create_rtr_socket(tr_socket
);
918 cache
->tr_socket
= tr_socket
;
919 cache
->tr_config
.tcp_config
= tcp_config
;
920 cache
->rtr_socket
= rtr_socket
;
921 cache
->preference
= preference
;
923 int ret
= add_cache(cache
);
924 if (ret
!= SUCCESS
) {
931 #if defined(FOUND_SSH)
932 static int add_ssh_cache(const char *host
, const unsigned int port
,
933 const char *username
, const char *client_privkey_path
,
934 const char *server_pubkey_path
,
935 const uint8_t preference
, const char *bindaddr
)
937 struct tr_ssh_config
*ssh_config
=
938 XCALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_ssh_config
));
939 struct cache
*cache
=
940 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct cache
));
941 struct tr_socket
*tr_socket
=
942 XMALLOC(MTYPE_BGP_RPKI_CACHE
, sizeof(struct tr_socket
));
943 struct rtr_socket
*rtr_socket
;
945 ssh_config
->port
= port
;
946 ssh_config
->host
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, host
);
948 ssh_config
->bindaddr
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, bindaddr
);
950 ssh_config
->bindaddr
= NULL
;
952 ssh_config
->username
= XSTRDUP(MTYPE_BGP_RPKI_CACHE
, username
);
953 ssh_config
->client_privkey_path
=
954 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, client_privkey_path
);
955 ssh_config
->server_hostkey_path
=
956 XSTRDUP(MTYPE_BGP_RPKI_CACHE
, server_pubkey_path
);
958 rtr_socket
= create_rtr_socket(tr_socket
);
961 cache
->tr_socket
= tr_socket
;
962 cache
->tr_config
.ssh_config
= ssh_config
;
963 cache
->rtr_socket
= rtr_socket
;
964 cache
->preference
= preference
;
966 int ret
= add_cache(cache
);
967 if (ret
!= SUCCESS
) {
975 static void free_cache(struct cache
*cache
)
977 if (cache
->type
== TCP
) {
978 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->host
);
979 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
->port
);
980 XFREE(MTYPE_BGP_RPKI_CACHE
,
981 cache
->tr_config
.tcp_config
->bindaddr
);
982 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.tcp_config
);
984 #if defined(FOUND_SSH)
986 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
->host
);
987 XFREE(MTYPE_BGP_RPKI_CACHE
,
988 cache
->tr_config
.ssh_config
->username
);
989 XFREE(MTYPE_BGP_RPKI_CACHE
,
990 cache
->tr_config
.ssh_config
->client_privkey_path
);
991 XFREE(MTYPE_BGP_RPKI_CACHE
,
992 cache
->tr_config
.ssh_config
->server_hostkey_path
);
993 XFREE(MTYPE_BGP_RPKI_CACHE
,
994 cache
->tr_config
.ssh_config
->bindaddr
);
995 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_config
.ssh_config
);
998 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->tr_socket
);
999 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
->rtr_socket
);
1000 XFREE(MTYPE_BGP_RPKI_CACHE
, cache
);
1003 static int config_write(struct vty
*vty
)
1005 struct listnode
*cache_node
;
1006 struct cache
*cache
;
1009 vty_out(vty
, "debug rpki\n");
1011 vty_out(vty
, "!\n");
1012 vty_out(vty
, "rpki\n");
1014 if (polling_period
!= POLLING_PERIOD_DEFAULT
)
1015 vty_out(vty
, " rpki polling_period %d\n", polling_period
);
1016 if (retry_interval
!= RETRY_INTERVAL_DEFAULT
)
1017 vty_out(vty
, " rpki retry_interval %d\n", retry_interval
);
1018 if (expire_interval
!= EXPIRE_INTERVAL_DEFAULT
)
1019 vty_out(vty
, " rpki expire_interval %d\n", expire_interval
);
1021 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1022 switch (cache
->type
) {
1023 struct tr_tcp_config
*tcp_config
;
1024 #if defined(FOUND_SSH)
1025 struct tr_ssh_config
*ssh_config
;
1028 tcp_config
= cache
->tr_config
.tcp_config
;
1029 vty_out(vty
, " rpki cache %s %s ", tcp_config
->host
,
1031 if (tcp_config
->bindaddr
)
1032 vty_out(vty
, "source %s ",
1033 tcp_config
->bindaddr
);
1035 #if defined(FOUND_SSH)
1037 ssh_config
= cache
->tr_config
.ssh_config
;
1038 vty_out(vty
, " rpki cache %s %u %s %s %s ",
1039 ssh_config
->host
, ssh_config
->port
,
1040 ssh_config
->username
,
1041 ssh_config
->client_privkey_path
,
1042 ssh_config
->server_hostkey_path
!= NULL
1043 ? ssh_config
->server_hostkey_path
1045 if (ssh_config
->bindaddr
)
1046 vty_out(vty
, "source %s ",
1047 ssh_config
->bindaddr
);
1054 vty_out(vty
, "preference %hhu\n", cache
->preference
);
1056 vty_out(vty
, "exit\n");
1064 "Enable rpki and enter rpki configuration mode\n")
1066 vty
->node
= RPKI_NODE
;
1074 "Enable rpki and enter rpki configuration mode\n")
1076 rpki_delete_all_cache_nodes();
1081 DEFUN (bgp_rpki_start
,
1085 "start rpki support\n")
1087 if (listcount(cache_list
) == 0)
1089 "Could not start rpki because no caches are configured\n");
1091 if (!is_running()) {
1092 if (start() == ERROR
) {
1093 RPKI_DEBUG("RPKI failed to start");
1100 DEFUN (bgp_rpki_stop
,
1104 "start rpki support\n")
1112 DEFPY (rpki_polling_period
,
1113 rpki_polling_period_cmd
,
1114 "rpki polling_period (1-86400)$pp",
1116 "Set polling period\n"
1117 "Polling period value\n")
1119 polling_period
= pp
;
1123 DEFUN (no_rpki_polling_period
,
1124 no_rpki_polling_period_cmd
,
1125 "no rpki polling_period [(1-86400)]",
1128 "Set polling period back to default\n"
1129 "Polling period value\n")
1131 polling_period
= POLLING_PERIOD_DEFAULT
;
1135 DEFPY (rpki_expire_interval
,
1136 rpki_expire_interval_cmd
,
1137 "rpki expire_interval (600-172800)$tmp",
1139 "Set expire interval\n"
1140 "Expire interval value\n")
1142 if ((unsigned int)tmp
>= polling_period
) {
1143 expire_interval
= tmp
;
1147 vty_out(vty
, "%% Expiry interval must be polling period or larger\n");
1148 return CMD_WARNING_CONFIG_FAILED
;
1151 DEFUN (no_rpki_expire_interval
,
1152 no_rpki_expire_interval_cmd
,
1153 "no rpki expire_interval [(600-172800)]",
1156 "Set expire interval back to default\n"
1157 "Expire interval value\n")
1159 expire_interval
= polling_period
* 2;
1163 DEFPY (rpki_retry_interval
,
1164 rpki_retry_interval_cmd
,
1165 "rpki retry_interval (1-7200)$tmp",
1167 "Set retry interval\n"
1168 "retry interval value\n")
1170 retry_interval
= tmp
;
1174 DEFUN (no_rpki_retry_interval
,
1175 no_rpki_retry_interval_cmd
,
1176 "no rpki retry_interval [(1-7200)]",
1179 "Set retry interval back to default\n"
1180 "retry interval value\n")
1182 retry_interval
= RETRY_INTERVAL_DEFAULT
;
1186 DEFPY(rpki_cache
, rpki_cache_cmd
,
1187 "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)",
1189 "Install a cache server to current group\n"
1190 "IP address of cache server\n"
1191 "Hostname of cache server\n"
1195 "Path to own SSH private key\n"
1196 "Path to Public key of cache server\n"
1197 "Configure source IP address of RPKI connection\n"
1198 "Define a Source IP Address\n"
1199 "Preference of the cache server\n"
1200 "Preference value\n")
1203 struct listnode
*cache_node
;
1204 struct cache
*current_cache
;
1206 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, current_cache
)) {
1207 if (current_cache
->preference
== preference
) {
1209 "Cache with preference %ld is already configured\n",
1216 // use ssh connection
1218 #if defined(FOUND_SSH)
1220 add_ssh_cache(cache
, sshport
, ssh_uname
, ssh_privkey
,
1221 server_pubkey
, preference
, bindaddr_str
);
1223 return_value
= SUCCESS
;
1225 "ssh sockets are not supported. Please recompile rtrlib and frr with ssh support. If you want to use it\n");
1227 } else { // use tcp connection
1229 add_tcp_cache(cache
, tcpport
, preference
, bindaddr_str
);
1232 if (return_value
== ERROR
) {
1233 vty_out(vty
, "Could not create new rpki cache\n");
1240 DEFPY (no_rpki_cache
,
1242 "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)",
1245 "Install a cache server to current group\n"
1246 "IP address of cache server\n"
1247 "Hostname of cache server\n"
1251 "Path to own SSH private key\n"
1252 "Path to Public key of cache server\n"
1253 "Configure source IP address of RPKI connection\n"
1254 "Define a Source IP Address\n"
1255 "Preference of the cache server\n"
1256 "Preference value\n")
1258 struct cache
*cache_p
= find_cache(preference
);
1261 vty_out(vty
, "Could not find cache with preference %ld\n",
1266 if (is_running() && listcount(cache_list
) == 1) {
1268 } else if (is_running()) {
1269 if (rtr_mgr_remove_group(rtr_config
, preference
) == RTR_ERROR
) {
1271 "Could not remove cache with preference %ld\n",
1277 listnode_delete(cache_list
, cache_p
);
1278 free_cache(cache_p
);
1283 DEFPY (show_rpki_prefix_table
,
1284 show_rpki_prefix_table_cmd
,
1285 "show rpki prefix-table [json$uj]",
1288 "Show validated prefixes which were received from RPKI Cache\n"
1291 struct json_object
*json
= NULL
;
1293 if (!is_synchronized()) {
1295 vty_out(vty
, "No connection to RPKI cache server.\n");
1300 json
= json_object_new_object();
1302 print_prefix_table(vty
, json
);
1306 DEFPY (show_rpki_as_number
,
1307 show_rpki_as_number_cmd
,
1308 "show rpki as-number (1-4294967295)$by_asn [json$uj]",
1311 "Lookup by ASN in prefix table\n"
1315 struct json_object
*json
= NULL
;
1317 if (!is_synchronized()) {
1319 vty_out(vty
, "No Connection to RPKI cache server.\n");
1324 json
= json_object_new_object();
1326 print_prefix_table_by_asn(vty
, by_asn
, json
);
1330 DEFPY (show_rpki_prefix
,
1331 show_rpki_prefix_cmd
,
1332 "show rpki prefix <A.B.C.D/M|X:X::X:X/M> [(1-4294967295)$asn] [json$uj]",
1335 "Lookup IP prefix and optionally ASN in prefix table\n"
1341 json_object
*json
= NULL
;
1342 json_object
*json_records
= NULL
;
1344 if (!is_synchronized()) {
1346 vty_out(vty
, "No Connection to RPKI cache server.\n");
1350 struct lrtr_ip_addr addr
;
1351 char addr_str
[INET6_ADDRSTRLEN
];
1352 size_t addr_len
= strchr(prefix_str
, '/') - prefix_str
;
1354 memset(addr_str
, 0, sizeof(addr_str
));
1355 memcpy(addr_str
, prefix_str
, addr_len
);
1357 if (lrtr_ip_str_to_addr(addr_str
, &addr
) != 0) {
1359 vty_out(vty
, "Invalid IP prefix\n");
1363 struct pfx_record
*matches
= NULL
;
1364 unsigned int match_count
= 0;
1365 enum pfxv_state result
;
1367 if (pfx_table_validate_r(rtr_config
->pfx_table
, &matches
, &match_count
,
1368 asn
, &addr
, prefix
->prefixlen
, &result
)
1371 vty_out(vty
, "Prefix lookup failed\n");
1376 json
= json_object_new_object();
1379 vty_out(vty
, "%-40s %s %s\n", "Prefix", "Prefix Length",
1382 json_records
= json_object_new_array();
1383 json_object_object_add(json
, "prefixes", json_records
);
1386 for (size_t i
= 0; i
< match_count
; ++i
) {
1387 const struct pfx_record
*record
= &matches
[i
];
1389 if (record
->max_len
>= prefix
->prefixlen
1390 && ((asn
!= 0 && (uint32_t)asn
== record
->asn
)
1392 print_record(&matches
[i
], vty
, json_records
);
1397 vty_json(vty
, json
);
1402 DEFPY (show_rpki_cache_server
,
1403 show_rpki_cache_server_cmd
,
1404 "show rpki cache-server [json$uj]",
1407 "Show configured cache server\n"
1410 struct json_object
*json
= NULL
;
1411 struct json_object
*json_server
= NULL
;
1412 struct json_object
*json_servers
= NULL
;
1413 struct listnode
*cache_node
;
1414 struct cache
*cache
;
1417 json
= json_object_new_object();
1418 json_servers
= json_object_new_array();
1419 json_object_object_add(json
, "servers", json_servers
);
1422 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1423 if (cache
->type
== TCP
) {
1426 "host: %s port: %s, preference: %hhu\n",
1427 cache
->tr_config
.tcp_config
->host
,
1428 cache
->tr_config
.tcp_config
->port
,
1431 json_server
= json_object_new_object();
1432 json_object_string_add(json_server
, "mode",
1434 json_object_string_add(
1435 json_server
, "host",
1436 cache
->tr_config
.tcp_config
->host
);
1437 json_object_string_add(
1438 json_server
, "port",
1439 cache
->tr_config
.tcp_config
->port
);
1440 json_object_int_add(json_server
, "preference",
1442 json_object_array_add(json_servers
,
1446 #if defined(FOUND_SSH)
1447 } else if (cache
->type
== SSH
) {
1450 "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s, preference: %hhu\n",
1451 cache
->tr_config
.ssh_config
->host
,
1452 cache
->tr_config
.ssh_config
->port
,
1453 cache
->tr_config
.ssh_config
->username
,
1454 cache
->tr_config
.ssh_config
1455 ->server_hostkey_path
,
1456 cache
->tr_config
.ssh_config
1457 ->client_privkey_path
,
1460 json_server
= json_object_new_object();
1461 json_object_string_add(json_server
, "mode",
1463 json_object_string_add(
1464 json_server
, "host",
1465 cache
->tr_config
.ssh_config
->host
);
1466 json_object_int_add(
1467 json_server
, "port",
1468 cache
->tr_config
.ssh_config
->port
);
1469 json_object_string_add(
1470 json_server
, "username",
1471 cache
->tr_config
.ssh_config
->username
);
1472 json_object_string_add(
1473 json_server
, "serverHostkeyPath",
1474 cache
->tr_config
.ssh_config
1475 ->server_hostkey_path
);
1476 json_object_string_add(
1477 json_server
, "clientPrivkeyPath",
1478 cache
->tr_config
.ssh_config
1479 ->client_privkey_path
);
1480 json_object_int_add(json_server
, "preference",
1482 json_object_array_add(json_servers
,
1490 vty_json(vty
, json
);
1495 DEFPY (show_rpki_cache_connection
,
1496 show_rpki_cache_connection_cmd
,
1497 "show rpki cache-connection [json$uj]",
1500 "Show to which RPKI Cache Servers we have a connection\n"
1503 struct json_object
*json
= NULL
;
1504 struct json_object
*json_conn
= NULL
;
1505 struct json_object
*json_conns
= NULL
;
1506 struct listnode
*cache_node
;
1507 struct cache
*cache
;
1508 struct rtr_mgr_group
*group
;
1511 json
= json_object_new_object();
1513 if (!is_synchronized()) {
1515 vty_out(vty
, "No connection to RPKI cache server.\n");
1517 vty_json(vty
, json
);
1522 group
= get_connected_group();
1525 vty_out(vty
, "Cannot find a connected group.\n");
1527 vty_json(vty
, json
);
1533 vty_out(vty
, "Connected to group %d\n", group
->preference
);
1535 json_conns
= json_object_new_array();
1536 json_object_int_add(json
, "connectedGroup", group
->preference
);
1537 json_object_object_add(json
, "connections", json_conns
);
1540 for (ALL_LIST_ELEMENTS_RO(cache_list
, cache_node
, cache
)) {
1541 struct tr_tcp_config
*tcp_config
;
1542 #if defined(FOUND_SSH)
1543 struct tr_ssh_config
*ssh_config
;
1545 switch (cache
->type
) {
1547 tcp_config
= cache
->tr_config
.tcp_config
;
1551 "rpki tcp cache %s %s pref %hhu%s\n",
1552 tcp_config
->host
, tcp_config
->port
,
1554 cache
->rtr_socket
->state
==
1559 json_conn
= json_object_new_object();
1560 json_object_string_add(json_conn
, "mode",
1562 json_object_string_add(json_conn
, "host",
1564 json_object_string_add(json_conn
, "port",
1566 json_object_int_add(json_conn
, "preference",
1568 json_object_string_add(
1570 cache
->rtr_socket
->state
==
1574 json_object_array_add(json_conns
, json_conn
);
1577 #if defined(FOUND_SSH)
1579 ssh_config
= cache
->tr_config
.ssh_config
;
1583 "rpki ssh cache %s %u pref %hhu%s\n",
1584 ssh_config
->host
, ssh_config
->port
,
1586 cache
->rtr_socket
->state
==
1591 json_conn
= json_object_new_object();
1592 json_object_string_add(json_conn
, "mode",
1594 json_object_string_add(json_conn
, "host",
1596 json_object_int_add(json_conn
, "port",
1598 json_object_int_add(json_conn
, "preference",
1600 json_object_string_add(
1602 cache
->rtr_socket
->state
==
1606 json_object_array_add(json_conns
, json_conn
);
1616 vty_json(vty
, json
);
1621 static int config_on_exit(struct vty
*vty
)
1633 return reset(true) == SUCCESS
? CMD_SUCCESS
: CMD_WARNING
;
1640 "Enable debugging for rpki\n")
1646 DEFUN (no_debug_rpki
,
1651 "Disable debugging for rpki\n")
1657 DEFUN_YANG (match_rpki
,
1659 "match rpki <valid|invalid|notfound>",
1664 "Prefix not found\n")
1667 "./match-condition[condition='frr-bgp-route-map:rpki']";
1668 char xpath_value
[XPATH_MAXLEN
];
1670 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
1671 snprintf(xpath_value
, sizeof(xpath_value
),
1672 "%s/rmap-match-condition/frr-bgp-route-map:rpki", xpath
);
1673 nb_cli_enqueue_change(vty
, xpath_value
, NB_OP_MODIFY
, argv
[2]->arg
);
1675 return nb_cli_apply_changes(vty
, NULL
);
1678 DEFUN_YANG (no_match_rpki
,
1680 "no match rpki <valid|invalid|notfound>",
1686 "Prefix not found\n")
1689 "./match-condition[condition='frr-bgp-route-map:rpki']";
1691 nb_cli_enqueue_change(vty
, xpath
, NB_OP_CREATE
, NULL
);
1692 return nb_cli_apply_changes(vty
, NULL
);
1695 static void install_cli_commands(void)
1697 // TODO: make config write work
1698 install_node(&rpki_node
);
1699 install_default(RPKI_NODE
);
1700 install_element(CONFIG_NODE
, &rpki_cmd
);
1701 install_element(ENABLE_NODE
, &rpki_cmd
);
1702 install_element(CONFIG_NODE
, &no_rpki_cmd
);
1705 install_element(ENABLE_NODE
, &bgp_rpki_start_cmd
);
1706 install_element(ENABLE_NODE
, &bgp_rpki_stop_cmd
);
1708 /* Install rpki reset command */
1709 install_element(ENABLE_NODE
, &rpki_reset_cmd
);
1710 install_element(RPKI_NODE
, &rpki_reset_cmd
);
1712 /* Install rpki polling period commands */
1713 install_element(RPKI_NODE
, &rpki_polling_period_cmd
);
1714 install_element(RPKI_NODE
, &no_rpki_polling_period_cmd
);
1716 /* Install rpki expire interval commands */
1717 install_element(RPKI_NODE
, &rpki_expire_interval_cmd
);
1718 install_element(RPKI_NODE
, &no_rpki_expire_interval_cmd
);
1720 /* Install rpki retry interval commands */
1721 install_element(RPKI_NODE
, &rpki_retry_interval_cmd
);
1722 install_element(RPKI_NODE
, &no_rpki_retry_interval_cmd
);
1724 /* Install rpki cache commands */
1725 install_element(RPKI_NODE
, &rpki_cache_cmd
);
1726 install_element(RPKI_NODE
, &no_rpki_cache_cmd
);
1728 /* Install show commands */
1729 install_element(VIEW_NODE
, &show_rpki_prefix_table_cmd
);
1730 install_element(VIEW_NODE
, &show_rpki_cache_connection_cmd
);
1731 install_element(VIEW_NODE
, &show_rpki_cache_server_cmd
);
1732 install_element(VIEW_NODE
, &show_rpki_prefix_cmd
);
1733 install_element(VIEW_NODE
, &show_rpki_as_number_cmd
);
1735 /* Install debug commands */
1736 install_element(CONFIG_NODE
, &debug_rpki_cmd
);
1737 install_element(ENABLE_NODE
, &debug_rpki_cmd
);
1738 install_element(CONFIG_NODE
, &no_debug_rpki_cmd
);
1739 install_element(ENABLE_NODE
, &no_debug_rpki_cmd
);
1741 /* Install route match */
1742 route_map_install_match(&route_match_rpki_cmd
);
1743 install_element(RMAP_NODE
, &match_rpki_cmd
);
1744 install_element(RMAP_NODE
, &no_match_rpki_cmd
);
1747 FRR_MODULE_SETUP(.name
= "bgpd_rpki", .version
= "0.3.6",
1748 .description
= "Enable RPKI support for FRR.",
1749 .init
= bgp_rpki_module_init
,