]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rpki.c
Merge pull request #3108 from dmbaturin/master
[mirror_frr.git] / bgpd / bgp_rpki.c
1 /*
2 * BGP RPKI
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
5 * Berlin
6 * Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW
7 * Hamburg
8 * Copyright (C) 2017-2018 Marcel Röthke (marcel.roethke@haw-hamburg.de),
9 * for HAW Hamburg
10 *
11 * This file is part of FRRouting.
12 *
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)
16 * any later version.
17 *
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
21 * more details.
22 *
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
26 */
27
28 /* If rtrlib compiled with ssh support, don`t fail build */
29 #define LIBSSH_LEGACY_0_4
30
31 #include <zebra.h>
32 #include <pthread.h>
33 #include <time.h>
34 #include <stdbool.h>
35 #include <stdlib.h>
36 #include "prefix.h"
37 #include "log.h"
38 #include "command.h"
39 #include "linklist.h"
40 #include "memory.h"
41 #include "thread.h"
42 #include "filter.h"
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"
59 #endif
60 #endif
61 #include "hook.h"
62 #include "libfrr.h"
63 #include "version.h"
64
65 #ifndef VTYSH_EXTRACT_PL
66 #include "bgpd/bgp_rpki_clippy.c"
67 #endif
68
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")
71
72 #define RPKI_VALID 1
73 #define RPKI_NOTFOUND 2
74 #define RPKI_INVALID 3
75
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
81
82 #define RPKI_DEBUG(...) \
83 if (rpki_debug) { \
84 zlog_debug("RPKI: " __VA_ARGS__); \
85 }
86
87 #define RPKI_OUTPUT_STRING "Control rpki specific settings\n"
88
89 struct cache {
90 enum { TCP, SSH } type;
91 struct tr_socket *tr_socket;
92 union {
93 struct tr_tcp_config *tcp_config;
94 struct tr_ssh_config *ssh_config;
95 } tr_config;
96 struct rtr_socket *rtr_socket;
97 uint8_t preference;
98 };
99
100 enum return_values { SUCCESS = 0, ERROR = -1 };
101
102 struct rpki_for_each_record_arg {
103 struct vty *vty;
104 unsigned int *prefix_amount;
105 };
106
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);
123 #endif
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, void *data);
129 static int is_synchronized(void);
130 static int is_running(void);
131 static void route_match_free(void *rule);
132 static route_map_result_t route_match(void *rule, const struct prefix *prefix,
133 route_map_object_t type, void *object);
134 static void *route_match_compile(const char *arg);
135 static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
136 safi_t safi);
137 static void revalidate_all_routes(void);
138
139 static struct rtr_mgr_config *rtr_config;
140 static struct list *cache_list;
141 static int rtr_is_running;
142 static int rtr_is_stopping;
143 static int rtr_is_starting;
144 static _Atomic int rtr_update_overflow;
145 static int rpki_debug;
146 static unsigned int polling_period;
147 static unsigned int expire_interval;
148 static unsigned int retry_interval;
149 static unsigned int timeout;
150 static unsigned int initial_synchronisation_timeout;
151 static int rpki_sync_socket_rtr;
152 static int rpki_sync_socket_bgpd;
153
154 static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1};
155 static struct route_map_rule_cmd route_match_rpki_cmd = {
156 "rpki", route_match, route_match_compile, route_match_free};
157
158 static void *malloc_wrapper(size_t size)
159 {
160 return XMALLOC(MTYPE_BGP_RPKI_CACHE, size);
161 }
162
163 static void *realloc_wrapper(void *ptr, size_t size)
164 {
165 return XREALLOC(MTYPE_BGP_RPKI_CACHE, ptr, size);
166 }
167
168 static void free_wrapper(void *ptr)
169 {
170 XFREE(MTYPE_BGP_RPKI_CACHE, ptr);
171 }
172
173 static void init_tr_socket(struct cache *cache)
174 {
175 if (cache->type == TCP)
176 tr_tcp_init(cache->tr_config.tcp_config,
177 cache->tr_socket);
178 #if defined(FOUND_SSH)
179 else
180 tr_ssh_init(cache->tr_config.ssh_config,
181 cache->tr_socket);
182 #endif
183 }
184
185 static void free_tr_socket(struct cache *cache)
186 {
187 if (cache->type == TCP)
188 tr_tcp_init(cache->tr_config.tcp_config,
189 cache->tr_socket);
190 #if defined(FOUND_SSH)
191 else
192 tr_ssh_init(cache->tr_config.ssh_config,
193 cache->tr_socket);
194 #endif
195 }
196
197 static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
198 const struct prefix *prefix);
199
200 static void ipv6_addr_to_network_byte_order(const uint32_t *src, uint32_t *dest)
201 {
202 int i;
203
204 for (i = 0; i < 4; i++)
205 dest[i] = htonl(src[i]);
206 }
207
208 static void ipv6_addr_to_host_byte_order(const uint32_t *src, uint32_t *dest)
209 {
210 int i;
211
212 for (i = 0; i < 4; i++)
213 dest[i] = ntohl(src[i]);
214 }
215
216 static route_map_result_t route_match(void *rule, const struct prefix *prefix,
217 route_map_object_t type, void *object)
218 {
219 int *rpki_status = rule;
220 struct bgp_info *bgp_info;
221
222 if (type == RMAP_BGP) {
223 bgp_info = object;
224
225 if (rpki_validate_prefix(bgp_info->peer, bgp_info->attr, prefix)
226 == *rpki_status) {
227 return RMAP_MATCH;
228 }
229 }
230 return RMAP_NOMATCH;
231 }
232
233 static void *route_match_compile(const char *arg)
234 {
235 int *rpki_status;
236
237 rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));
238
239 if (strcmp(arg, "valid") == 0)
240 *rpki_status = RPKI_VALID;
241 else if (strcmp(arg, "invalid") == 0)
242 *rpki_status = RPKI_INVALID;
243 else
244 *rpki_status = RPKI_NOTFOUND;
245
246 return rpki_status;
247 }
248
249 static void route_match_free(void *rule)
250 {
251 XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
252 }
253
254 static struct rtr_socket *create_rtr_socket(struct tr_socket *tr_socket)
255 {
256 struct rtr_socket *rtr_socket =
257 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct rtr_socket));
258 rtr_socket->tr_socket = tr_socket;
259 return rtr_socket;
260 }
261
262 static struct cache *find_cache(const uint8_t preference)
263 {
264 struct listnode *cache_node;
265 struct cache *cache;
266
267 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
268 if (cache->preference == preference)
269 return cache;
270 }
271 return NULL;
272 }
273
274 static void print_record(const struct pfx_record *record, void *data)
275 {
276 char ip[INET6_ADDRSTRLEN];
277 struct rpki_for_each_record_arg *arg = data;
278 struct vty *vty = arg->vty;
279
280 (*arg->prefix_amount)++;
281
282 lrtr_ip_addr_to_str(&record->prefix, ip, sizeof(ip));
283 vty_out(vty, "%-40s %3u - %3u %10u\n", ip, record->min_len,
284 record->max_len, record->asn);
285 }
286
287 static struct rtr_mgr_group *get_groups(void)
288 {
289 struct listnode *cache_node;
290 struct rtr_mgr_group *rtr_mgr_groups;
291 struct cache *cache;
292
293 int group_count = listcount(cache_list);
294
295 if (group_count == 0)
296 return NULL;
297
298 rtr_mgr_groups = XMALLOC(MTYPE_BGP_RPKI_CACHE_GROUP,
299 group_count * sizeof(struct rtr_mgr_group));
300
301 size_t i = 0;
302
303 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
304 rtr_mgr_groups[i].sockets = &cache->rtr_socket;
305 rtr_mgr_groups[i].sockets_len = 1;
306 rtr_mgr_groups[i].preference = cache->preference;
307
308 init_tr_socket(cache);
309
310 i++;
311 }
312
313 return rtr_mgr_groups;
314 }
315
316 inline int is_synchronized(void)
317 {
318 return rtr_is_running && rtr_mgr_conf_in_sync(rtr_config);
319 }
320
321 inline int is_running(void)
322 {
323 return rtr_is_running;
324 }
325
326 static struct prefix *pfx_record_to_prefix(struct pfx_record *record)
327 {
328 struct prefix *prefix = prefix_new();
329
330 prefix->prefixlen = record->min_len;
331
332 if (record->prefix.ver == LRTR_IPV4) {
333 prefix->family = AF_INET;
334 prefix->u.prefix4.s_addr = htonl(record->prefix.u.addr4.addr);
335 } else {
336 prefix->family = AF_INET6;
337 ipv6_addr_to_network_byte_order(record->prefix.u.addr6.addr,
338 prefix->u.prefix6.s6_addr32);
339 }
340
341 return prefix;
342 }
343
344 static int bgpd_sync_callback(struct thread *thread)
345 {
346 struct bgp *bgp;
347 struct listnode *node;
348 struct prefix *prefix;
349 struct pfx_record rec;
350
351 thread_add_read(bm->master, bgpd_sync_callback, NULL,
352 rpki_sync_socket_bgpd, NULL);
353
354 if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) {
355 while (read(rpki_sync_socket_bgpd, &rec,
356 sizeof(struct pfx_record))
357 != -1)
358 ;
359
360 atomic_store_explicit(&rtr_update_overflow, 0,
361 memory_order_seq_cst);
362 revalidate_all_routes();
363 return 0;
364 }
365
366 int retval =
367 read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
368 if (retval != sizeof(struct pfx_record)) {
369 RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
370 return retval;
371 }
372 prefix = pfx_record_to_prefix(&rec);
373
374 afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
375
376 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
377 struct peer *peer;
378 struct listnode *peer_listnode;
379
380 for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
381 safi_t safi;
382
383 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
384 if (!peer->bgp->rib[afi][safi])
385 continue;
386
387 struct list *matches = list_new();
388
389 matches->del =
390 (void (*)(void *))bgp_unlock_node;
391
392 bgp_table_range_lookup(
393 peer->bgp->rib[afi][safi], prefix,
394 rec.max_len, matches);
395
396
397 struct bgp_node *bgp_node;
398 struct listnode *bgp_listnode;
399
400 for (ALL_LIST_ELEMENTS_RO(matches, bgp_listnode,
401 bgp_node))
402 revalidate_bgp_node(bgp_node, afi,
403 safi);
404
405 list_delete(&matches);
406 }
407 }
408 }
409
410 prefix_free(prefix);
411 return 0;
412 }
413
414 static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
415 safi_t safi)
416 {
417 struct bgp_adj_in *ain;
418
419 for (ain = bgp_node->adj_in; ain; ain = ain->next) {
420 int ret;
421 struct bgp_info *bgp_info = bgp_node->info;
422 mpls_label_t *label = NULL;
423 uint32_t num_labels = 0;
424
425 if (bgp_info && bgp_info->extra) {
426 label = bgp_info->extra->label;
427 num_labels = bgp_info->extra->num_labels;
428 }
429 ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
430 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
431 BGP_ROUTE_NORMAL, NULL, label, num_labels, 1,
432 NULL);
433
434 if (ret < 0)
435 return;
436 }
437 }
438
439 static void revalidate_all_routes(void)
440 {
441 struct bgp *bgp;
442 struct listnode *node;
443
444 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
445 struct peer *peer;
446 struct listnode *peer_listnode;
447
448 for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
449
450 for (size_t i = 0; i < 2; i++) {
451 safi_t safi;
452 afi_t afi = (i == 0) ? AFI_IP : AFI_IP6;
453
454 for (safi = SAFI_UNICAST; safi < SAFI_MAX;
455 safi++) {
456 if (!peer->bgp->rib[afi][safi])
457 continue;
458
459 bgp_soft_reconfig_in(peer, afi, safi);
460 }
461 }
462 }
463 }
464 }
465
466 static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
467 const struct pfx_record rec,
468 const bool added __attribute__((unused)))
469 {
470 if (rtr_is_stopping || rtr_is_starting
471 || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
472 return;
473
474 int retval =
475 write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record));
476 if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
477 atomic_store_explicit(&rtr_update_overflow, 1,
478 memory_order_seq_cst);
479
480 else if (retval != sizeof(struct pfx_record))
481 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
482 }
483
484 static void rpki_init_sync_socket(void)
485 {
486 int fds[2];
487 const char *msg;
488
489 RPKI_DEBUG("initializing sync socket");
490 if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) {
491 msg = "could not open rpki sync socketpair";
492 goto err;
493 }
494 rpki_sync_socket_rtr = fds[0];
495 rpki_sync_socket_bgpd = fds[1];
496
497 if (set_nonblocking(rpki_sync_socket_rtr) != 0) {
498 msg = "could not set rpki_sync_socket_rtr to non blocking";
499 goto err;
500 }
501
502 if (set_nonblocking(rpki_sync_socket_bgpd) != 0) {
503 msg = "could not set rpki_sync_socket_bgpd to non blocking";
504 goto err;
505 }
506
507
508 thread_add_read(bm->master, bgpd_sync_callback, NULL,
509 rpki_sync_socket_bgpd, NULL);
510
511 return;
512
513 err:
514 zlog_err("RPKI: %s", msg);
515 abort();
516
517 }
518
519 static int bgp_rpki_init(struct thread_master *master)
520 {
521 rpki_debug = 0;
522 rtr_is_running = 0;
523 rtr_is_stopping = 0;
524
525 cache_list = list_new();
526 cache_list->del = (void (*)(void *)) & free_cache;
527
528 polling_period = POLLING_PERIOD_DEFAULT;
529 expire_interval = EXPIRE_INTERVAL_DEFAULT;
530 retry_interval = RETRY_INTERVAL_DEFAULT;
531 timeout = TIMEOUT_DEFAULT;
532 initial_synchronisation_timeout =
533 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT;
534 install_cli_commands();
535 rpki_init_sync_socket();
536 return 0;
537 }
538
539 static int bgp_rpki_fini(void)
540 {
541 stop();
542 list_delete(&cache_list);
543
544 close(rpki_sync_socket_rtr);
545 close(rpki_sync_socket_bgpd);
546
547 return 0;
548 }
549
550 static int bgp_rpki_module_init(void)
551 {
552 lrtr_set_alloc_functions(malloc_wrapper, realloc_wrapper, free_wrapper);
553
554 hook_register(frr_late_init, bgp_rpki_init);
555 hook_register(frr_early_fini, &bgp_rpki_fini);
556
557 return 0;
558 }
559
560 static int start(void)
561 {
562 unsigned int waiting_time = 0;
563 int ret;
564
565 rtr_is_stopping = 0;
566 rtr_is_starting = 1;
567 rtr_update_overflow = 0;
568
569 if (list_isempty(cache_list)) {
570 RPKI_DEBUG(
571 "No caches were found in config. Prefix validation is off.");
572 return ERROR;
573 }
574 RPKI_DEBUG("Init rtr_mgr.");
575 int groups_len = listcount(cache_list);
576 struct rtr_mgr_group *groups = get_groups();
577
578 RPKI_DEBUG("Polling period: %d", polling_period);
579 ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period,
580 expire_interval, retry_interval,
581 rpki_update_cb_sync_rtr, NULL, NULL, NULL);
582 if (ret == RTR_ERROR) {
583 RPKI_DEBUG("Init rtr_mgr failed.");
584 return ERROR;
585 }
586
587 RPKI_DEBUG("Starting rtr_mgr.");
588 ret = rtr_mgr_start(rtr_config);
589 if (ret == RTR_ERROR) {
590 RPKI_DEBUG("Starting rtr_mgr failed.");
591 rtr_mgr_free(rtr_config);
592 return ERROR;
593 }
594 rtr_is_running = 1;
595 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
596 while (waiting_time++ <= initial_synchronisation_timeout) {
597 if (rtr_mgr_conf_in_sync(rtr_config))
598 break;
599
600 sleep(1);
601 }
602 if (rtr_mgr_conf_in_sync(rtr_config)) {
603 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
604 RPKI_DEBUG("Forcing revalidation.");
605 rtr_is_starting = 0;
606 revalidate_all_routes();
607 } else {
608 RPKI_DEBUG(
609 "Timeout expired! Proceeding without RPKI validation data.");
610 rtr_is_starting = 0;
611 }
612
613 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups);
614
615 return SUCCESS;
616 }
617
618 static void stop(void)
619 {
620 rtr_is_stopping = 1;
621 if (rtr_is_running) {
622 rtr_mgr_stop(rtr_config);
623 rtr_mgr_free(rtr_config);
624 rtr_is_running = 0;
625 }
626 }
627
628 static int reset(bool force)
629 {
630 if (rtr_is_running && !force)
631 return SUCCESS;
632
633 RPKI_DEBUG("Resetting RPKI Session");
634 stop();
635 return start();
636 }
637
638 static struct rtr_mgr_group *get_connected_group(void)
639 {
640 if (!cache_list || list_isempty(cache_list))
641 return NULL;
642
643 return rtr_mgr_get_first_group(rtr_config);
644 }
645
646 static void print_prefix_table(struct vty *vty)
647 {
648 struct rpki_for_each_record_arg arg;
649
650 unsigned int number_of_ipv4_prefixes = 0;
651 unsigned int number_of_ipv6_prefixes = 0;
652 struct rtr_mgr_group *group = get_connected_group();
653
654 arg.vty = vty;
655
656 if (!group)
657 return;
658
659 struct pfx_table *pfx_table = group->sockets[0]->pfx_table;
660
661 vty_out(vty, "RPKI/RTR prefix table\n");
662 vty_out(vty, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
663
664 arg.prefix_amount = &number_of_ipv4_prefixes;
665 pfx_table_for_each_ipv4_record(pfx_table, print_record, &arg);
666
667 arg.prefix_amount = &number_of_ipv6_prefixes;
668 pfx_table_for_each_ipv6_record(pfx_table, print_record, &arg);
669
670 vty_out(vty, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes);
671 vty_out(vty, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes);
672 }
673
674 static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
675 const struct prefix *prefix)
676 {
677 struct assegment *as_segment;
678 as_t as_number = 0;
679 struct lrtr_ip_addr ip_addr_prefix;
680 enum pfxv_state result;
681 char buf[BUFSIZ];
682 const char *prefix_string;
683
684 if (!is_synchronized())
685 return 0;
686
687 // No aspath means route comes from iBGP
688 if (!attr->aspath || !attr->aspath->segments) {
689 // Set own as number
690 as_number = peer->bgp->as;
691 } else {
692 as_segment = attr->aspath->segments;
693 // Find last AsSegment
694 while (as_segment->next)
695 as_segment = as_segment->next;
696
697 if (as_segment->type == AS_SEQUENCE) {
698 // Get rightmost asn
699 as_number = as_segment->as[as_segment->length - 1];
700 } else if (as_segment->type == AS_CONFED_SEQUENCE
701 || as_segment->type == AS_CONFED_SET) {
702 // Set own as number
703 as_number = peer->bgp->as;
704 } else {
705 // RFC says: "Take distinguished value NONE as asn"
706 // which means state is unknown
707 return RPKI_NOTFOUND;
708 }
709 }
710
711 // Get the prefix in requested format
712 switch (prefix->family) {
713 case AF_INET:
714 ip_addr_prefix.ver = LRTR_IPV4;
715 ip_addr_prefix.u.addr4.addr = ntohl(prefix->u.prefix4.s_addr);
716 break;
717
718 case AF_INET6:
719 ip_addr_prefix.ver = LRTR_IPV6;
720 ipv6_addr_to_host_byte_order(prefix->u.prefix6.s6_addr32,
721 ip_addr_prefix.u.addr6.addr);
722 break;
723
724 default:
725 return 0;
726 }
727
728 // Do the actual validation
729 rtr_mgr_validate(rtr_config, as_number, &ip_addr_prefix,
730 prefix->prefixlen, &result);
731
732 // Print Debug output
733 prefix_string =
734 inet_ntop(prefix->family, &prefix->u.prefix, buf, BUFSIZ);
735 switch (result) {
736 case BGP_PFXV_STATE_VALID:
737 RPKI_DEBUG(
738 "Validating Prefix %s/%hhu from asn %u Result: VALID",
739 prefix_string, prefix->prefixlen, as_number);
740 return RPKI_VALID;
741 case BGP_PFXV_STATE_NOT_FOUND:
742 RPKI_DEBUG(
743 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
744 prefix_string, prefix->prefixlen, as_number);
745 return RPKI_NOTFOUND;
746 case BGP_PFXV_STATE_INVALID:
747 RPKI_DEBUG(
748 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
749 prefix_string, prefix->prefixlen, as_number);
750 return RPKI_INVALID;
751 default:
752 RPKI_DEBUG(
753 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
754 prefix_string, prefix->prefixlen, as_number);
755 break;
756 }
757 return 0;
758 }
759
760 static int add_cache(struct cache *cache)
761 {
762 uint8_t preference = cache->preference;
763 struct rtr_mgr_group group;
764
765 group.preference = preference;
766 group.sockets_len = 1;
767 group.sockets = &cache->rtr_socket;
768
769 listnode_add(cache_list, cache);
770
771 if (rtr_is_running) {
772 init_tr_socket(cache);
773
774 if (rtr_mgr_add_group(rtr_config, &group) != RTR_SUCCESS) {
775 free_tr_socket(cache);
776 return ERROR;
777 }
778 }
779
780 return SUCCESS;
781 }
782
783 static int add_tcp_cache(const char *host, const char *port,
784 const uint8_t preference)
785 {
786 struct rtr_socket *rtr_socket;
787 struct tr_tcp_config *tcp_config =
788 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_tcp_config));
789 struct tr_socket *tr_socket =
790 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_socket));
791 struct cache *cache =
792 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct cache));
793
794 tcp_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
795 tcp_config->port = XSTRDUP(MTYPE_BGP_RPKI_CACHE, port);
796 tcp_config->bindaddr = NULL;
797
798 rtr_socket = create_rtr_socket(tr_socket);
799
800 cache->type = TCP;
801 cache->tr_socket = tr_socket;
802 cache->tr_config.tcp_config = tcp_config;
803 cache->rtr_socket = rtr_socket;
804 cache->preference = preference;
805
806 return add_cache(cache);
807 }
808
809 #if defined(FOUND_SSH)
810 static int add_ssh_cache(const char *host, const unsigned int port,
811 const char *username, const char *client_privkey_path,
812 const char *client_pubkey_path,
813 const char *server_pubkey_path,
814 const uint8_t preference)
815 {
816 struct tr_ssh_config *ssh_config =
817 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_ssh_config));
818 struct cache *cache =
819 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct cache));
820 struct tr_socket *tr_socket =
821 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_socket));
822 struct rtr_socket *rtr_socket;
823
824 ssh_config->port = port;
825 ssh_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
826 ssh_config->bindaddr = NULL;
827
828 ssh_config->username = XSTRDUP(MTYPE_BGP_RPKI_CACHE, username);
829 ssh_config->client_privkey_path =
830 XSTRDUP(MTYPE_BGP_RPKI_CACHE, client_privkey_path);
831 ssh_config->server_hostkey_path =
832 XSTRDUP(MTYPE_BGP_RPKI_CACHE, server_pubkey_path);
833
834 rtr_socket = create_rtr_socket(tr_socket);
835
836 cache->type = SSH;
837 cache->tr_socket = tr_socket;
838 cache->tr_config.ssh_config = ssh_config;
839 cache->rtr_socket = rtr_socket;
840 cache->preference = preference;
841
842 return add_cache(cache);
843 }
844 #endif
845
846 static void free_cache(struct cache *cache)
847 {
848 if (cache->type == TCP) {
849 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->host);
850 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->port);
851 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config);
852 }
853 #if defined(FOUND_SSH)
854 else {
855 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config->host);
856 XFREE(MTYPE_BGP_RPKI_CACHE,
857 cache->tr_config.ssh_config->username);
858 XFREE(MTYPE_BGP_RPKI_CACHE,
859 cache->tr_config.ssh_config->client_privkey_path);
860 XFREE(MTYPE_BGP_RPKI_CACHE,
861 cache->tr_config.ssh_config->server_hostkey_path);
862 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config);
863 }
864 #endif
865 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_socket);
866 XFREE(MTYPE_BGP_RPKI_CACHE, cache->rtr_socket);
867 XFREE(MTYPE_BGP_RPKI_CACHE, cache);
868 }
869
870 static int config_write(struct vty *vty)
871 {
872 struct listnode *cache_node;
873 struct cache *cache;
874
875 if (listcount(cache_list)) {
876 if (rpki_debug)
877 vty_out(vty, "debug rpki\n");
878
879 vty_out(vty, "!\n");
880 vty_out(vty, "rpki\n");
881 vty_out(vty, " rpki polling_period %d\n", polling_period);
882 vty_out(vty, " rpki timeout %d\n", timeout);
883 vty_out(vty, " rpki initial-synchronisation-timeout %d\n",
884 initial_synchronisation_timeout);
885 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
886 switch (cache->type) {
887 struct tr_tcp_config *tcp_config;
888 #if defined(FOUND_SSH)
889 struct tr_ssh_config *ssh_config;
890 #endif
891 case TCP:
892 tcp_config = cache->tr_config.tcp_config;
893 vty_out(vty, " rpki cache %s %s ",
894 tcp_config->host, tcp_config->port);
895 break;
896 #if defined(FOUND_SSH)
897 case SSH:
898 ssh_config = cache->tr_config.ssh_config;
899 vty_out(vty, " rpki cache %s %u %s %s %s ",
900 ssh_config->host, ssh_config->port,
901 ssh_config->username,
902 ssh_config->client_privkey_path,
903 ssh_config->server_hostkey_path != NULL
904 ? ssh_config
905 ->server_hostkey_path
906 : " ");
907 break;
908 #endif
909 default:
910 break;
911 }
912
913 vty_out(vty, "preference %hhu\n", cache->preference);
914 }
915 vty_out(vty, " exit\n");
916 return 1;
917 } else {
918 return 0;
919 }
920 }
921
922 DEFUN_NOSH (rpki,
923 rpki_cmd,
924 "rpki",
925 "Enable rpki and enter rpki configuration mode\n")
926 {
927 vty->node = RPKI_NODE;
928 return CMD_SUCCESS;
929 }
930
931 DEFUN (bgp_rpki_start,
932 bgp_rpki_start_cmd,
933 "rpki start",
934 RPKI_OUTPUT_STRING
935 "start rpki support\n")
936 {
937 if (listcount(cache_list) == 0)
938 vty_out(vty,
939 "Could not start rpki because no caches are configured\n");
940
941 if (!is_running()) {
942 if (start() == ERROR) {
943 RPKI_DEBUG("RPKI failed to start");
944 return CMD_WARNING;
945 }
946 }
947 return CMD_SUCCESS;
948 }
949
950 DEFUN (bgp_rpki_stop,
951 bgp_rpki_stop_cmd,
952 "rpki stop",
953 RPKI_OUTPUT_STRING
954 "start rpki support\n")
955 {
956 if (is_running())
957 stop();
958
959 return CMD_SUCCESS;
960 }
961
962 DEFPY (rpki_polling_period,
963 rpki_polling_period_cmd,
964 "rpki polling_period (1-86400)$pp",
965 RPKI_OUTPUT_STRING
966 "Set polling period\n"
967 "Polling period value\n")
968 {
969 polling_period = pp;
970 return CMD_SUCCESS;
971 }
972
973 DEFUN (no_rpki_polling_period,
974 no_rpki_polling_period_cmd,
975 "no rpki polling_period",
976 NO_STR
977 RPKI_OUTPUT_STRING
978 "Set polling period back to default\n")
979 {
980 polling_period = POLLING_PERIOD_DEFAULT;
981 return CMD_SUCCESS;
982 }
983
984 DEFPY (rpki_expire_interval,
985 rpki_expire_interval_cmd,
986 "rpki expire_interval (600-172800)$tmp",
987 RPKI_OUTPUT_STRING
988 "Set expire interval\n"
989 "Expire interval value\n")
990 {
991 if ((unsigned int)tmp >= polling_period) {
992 expire_interval = tmp;
993 return CMD_SUCCESS;
994 }
995
996 vty_out(vty, "%% Expiry interval must be polling period or larger\n");
997 return CMD_WARNING_CONFIG_FAILED;
998 }
999
1000 DEFUN (no_rpki_expire_interval,
1001 no_rpki_expire_interval_cmd,
1002 "no rpki expire_interval",
1003 NO_STR
1004 RPKI_OUTPUT_STRING
1005 "Set expire interval back to default\n")
1006 {
1007 expire_interval = polling_period * 2;
1008 return CMD_SUCCESS;
1009 }
1010
1011 DEFPY (rpki_retry_interval,
1012 rpki_retry_interval_cmd,
1013 "rpki retry_interval (1-7200)$tmp",
1014 RPKI_OUTPUT_STRING
1015 "Set retry interval\n"
1016 "retry interval value\n")
1017 {
1018 retry_interval = tmp;
1019 return CMD_SUCCESS;
1020 }
1021
1022 DEFUN (no_rpki_retry_interval,
1023 no_rpki_retry_interval_cmd,
1024 "no rpki retry_interval",
1025 NO_STR
1026 RPKI_OUTPUT_STRING
1027 "Set retry interval back to default\n")
1028 {
1029 retry_interval = RETRY_INTERVAL_DEFAULT;
1030 return CMD_SUCCESS;
1031 }
1032
1033 DEFPY (rpki_timeout,
1034 rpki_timeout_cmd,
1035 "rpki timeout (1-4294967295)$to_arg",
1036 RPKI_OUTPUT_STRING
1037 "Set timeout\n"
1038 "Timeout value\n")
1039 {
1040 timeout = to_arg;
1041 return CMD_SUCCESS;
1042 }
1043
1044 DEFUN (no_rpki_timeout,
1045 no_rpki_timeout_cmd,
1046 "no rpki timeout",
1047 NO_STR
1048 RPKI_OUTPUT_STRING
1049 "Set timeout back to default\n")
1050 {
1051 timeout = TIMEOUT_DEFAULT;
1052 return CMD_SUCCESS;
1053 }
1054
1055 DEFPY (rpki_synchronisation_timeout,
1056 rpki_synchronisation_timeout_cmd,
1057 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1058 RPKI_OUTPUT_STRING
1059 "Set a timeout for the initial synchronisation of prefix validation data\n"
1060 "Timeout value\n")
1061 {
1062 initial_synchronisation_timeout = ito_arg;
1063 return CMD_SUCCESS;
1064 }
1065
1066 DEFUN (no_rpki_synchronisation_timeout,
1067 no_rpki_synchronisation_timeout_cmd,
1068 "no rpki initial-synchronisation-timeout",
1069 NO_STR
1070 RPKI_OUTPUT_STRING
1071 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1072 {
1073 initial_synchronisation_timeout =
1074 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT;
1075 return CMD_SUCCESS;
1076 }
1077
1078 DEFPY (rpki_cache,
1079 rpki_cache_cmd,
1080 "rpki cache <A.B.C.D|WORD>"
1081 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1082 "preference (1-255)",
1083 RPKI_OUTPUT_STRING
1084 "Install a cache server to current group\n"
1085 "IP address of cache server\n Hostname of cache server\n"
1086 "TCP port number\n"
1087 "SSH port number\n"
1088 "SSH user name\n"
1089 "Path to own SSH private key\n"
1090 "Path to own SSH public key\n"
1091 "Path to Public key of cache server\n"
1092 "Preference of the cache server\n"
1093 "Preference value\n")
1094 {
1095 int return_value;
1096
1097 // use ssh connection
1098 if (ssh_uname) {
1099 #if defined(FOUND_SSH)
1100 return_value =
1101 add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey,
1102 ssh_pubkey, server_pubkey, preference);
1103 #else
1104 return_value = SUCCESS;
1105 vty_out(vty,
1106 "ssh sockets are not supported. "
1107 "Please recompile rtrlib and frr with ssh support. "
1108 "If you want to use it");
1109 #endif
1110 } else { // use tcp connection
1111 return_value = add_tcp_cache(cache, tcpport, preference);
1112 }
1113
1114 if (return_value == ERROR) {
1115 vty_out(vty, "Could not create new rpki cache\n");
1116 return CMD_WARNING;
1117 }
1118
1119 return CMD_SUCCESS;
1120 }
1121
1122 DEFPY (no_rpki_cache,
1123 no_rpki_cache_cmd,
1124 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1125 NO_STR
1126 RPKI_OUTPUT_STRING
1127 "Remove a cache server\n"
1128 "IP address of cache server\n Hostname of cache server\n"
1129 "TCP port number\n"
1130 "SSH port number\n"
1131 "Preference of the cache server\n"
1132 "Preference value\n")
1133 {
1134 struct cache *cache_p = find_cache(preference);
1135
1136 if (!cache) {
1137 vty_out(vty, "Could not find cache %ld\n", preference);
1138 return CMD_WARNING;
1139 }
1140
1141 if (rtr_is_running) {
1142 if (rtr_mgr_remove_group(rtr_config, preference) == RTR_ERROR) {
1143 vty_out(vty, "Could not remove cache %ld", preference);
1144 if (listcount(cache_list) == 1)
1145 vty_out(vty, " because it is the last cache");
1146
1147 vty_out(vty, "\n");
1148 return CMD_WARNING;
1149 }
1150 }
1151
1152 listnode_delete(cache_list, cache_p);
1153 free_cache(cache_p);
1154
1155 return CMD_SUCCESS;
1156 }
1157
1158 DEFUN (show_rpki_prefix_table,
1159 show_rpki_prefix_table_cmd,
1160 "show rpki prefix-table",
1161 SHOW_STR
1162 RPKI_OUTPUT_STRING
1163 "Show validated prefixes which were received from RPKI Cache\n")
1164 {
1165 struct listnode *cache_node;
1166 struct cache *cache;
1167
1168 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1169 vty_out(vty, "host: %s port: %s\n",
1170 cache->tr_config.tcp_config->host,
1171 cache->tr_config.tcp_config->port);
1172 }
1173 if (is_synchronized())
1174 print_prefix_table(vty);
1175 else
1176 vty_out(vty, "No connection to RPKI cache server.\n");
1177
1178 return CMD_SUCCESS;
1179 }
1180
1181 DEFUN (show_rpki_cache_server,
1182 show_rpki_cache_server_cmd,
1183 "show rpki cache-server",
1184 SHOW_STR
1185 RPKI_OUTPUT_STRING
1186 "SHOW configured cache server\n")
1187 {
1188 struct listnode *cache_node;
1189 struct cache *cache;
1190
1191 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1192 vty_out(vty, "host: %s port: %s\n",
1193 cache->tr_config.tcp_config->host,
1194 cache->tr_config.tcp_config->port);
1195 }
1196
1197 return CMD_SUCCESS;
1198 }
1199
1200 DEFUN (show_rpki_cache_connection,
1201 show_rpki_cache_connection_cmd,
1202 "show rpki cache-connection",
1203 SHOW_STR
1204 RPKI_OUTPUT_STRING
1205 "Show to which RPKI Cache Servers we have a connection\n")
1206 {
1207 if (is_synchronized()) {
1208 struct listnode *cache_node;
1209 struct cache *cache;
1210 struct rtr_mgr_group *group = get_connected_group();
1211
1212 if (!group) {
1213 vty_out(vty, "Cannot find a connected group.\n");
1214 return CMD_SUCCESS;
1215 }
1216 vty_out(vty, "Connected to group %d\n", group->preference);
1217 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1218 if (cache->preference == group->preference) {
1219 struct tr_tcp_config *tcp_config;
1220 #if defined(FOUND_SSH)
1221 struct tr_ssh_config *ssh_config;
1222 #endif
1223
1224 switch (cache->type) {
1225 case TCP:
1226 tcp_config =
1227 cache->tr_config.tcp_config;
1228 vty_out(vty,
1229 "rpki tcp cache %s %s pref %hhu\n",
1230 tcp_config->host,
1231 tcp_config->port,
1232 cache->preference);
1233 break;
1234
1235 #if defined(FOUND_SSH)
1236 case SSH:
1237 ssh_config =
1238 cache->tr_config.ssh_config;
1239 vty_out(vty,
1240 "rpki ssh cache %s %u pref %hhu\n",
1241 ssh_config->host,
1242 ssh_config->port,
1243 cache->preference);
1244 break;
1245 #endif
1246
1247 default:
1248 break;
1249 }
1250 }
1251 }
1252 } else {
1253 vty_out(vty, "No connection to RPKI cache server.\n");
1254 }
1255
1256 return CMD_SUCCESS;
1257 }
1258
1259 DEFUN_NOSH (rpki_exit,
1260 rpki_exit_cmd,
1261 "exit",
1262 "Exit rpki configuration and restart rpki session\n")
1263 {
1264 reset(false);
1265
1266 vty->node = CONFIG_NODE;
1267 return CMD_SUCCESS;
1268 }
1269
1270 DEFUN_NOSH (rpki_quit,
1271 rpki_quit_cmd,
1272 "quit",
1273 "Exit rpki configuration mode\n")
1274 {
1275 return rpki_exit(self, vty, argc, argv);
1276 }
1277
1278 DEFUN_NOSH (rpki_end,
1279 rpki_end_cmd,
1280 "end",
1281 "End rpki configuration, restart rpki session and change to enable mode.\n")
1282 {
1283 int ret = reset(false);
1284
1285 vty_config_unlock(vty);
1286 vty->node = ENABLE_NODE;
1287 return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1288 }
1289
1290 DEFUN (rpki_reset,
1291 rpki_reset_cmd,
1292 "rpki reset",
1293 RPKI_OUTPUT_STRING
1294 "reset rpki\n")
1295 {
1296 return reset(true) == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1297 }
1298
1299 DEFUN (debug_rpki,
1300 debug_rpki_cmd,
1301 "debug rpki",
1302 DEBUG_STR
1303 "Enable debugging for rpki\n")
1304 {
1305 rpki_debug = 1;
1306 return CMD_SUCCESS;
1307 }
1308
1309 DEFUN (no_debug_rpki,
1310 no_debug_rpki_cmd,
1311 "no debug rpki",
1312 NO_STR
1313 DEBUG_STR
1314 "Disable debugging for rpki\n")
1315 {
1316 rpki_debug = 0;
1317 return CMD_SUCCESS;
1318 }
1319
1320 DEFUN (match_rpki,
1321 match_rpki_cmd,
1322 "match rpki <valid|invalid|notfound>",
1323 MATCH_STR
1324 RPKI_OUTPUT_STRING
1325 "Valid prefix\n"
1326 "Invalid prefix\n"
1327 "Prefix not found\n")
1328 {
1329 VTY_DECLVAR_CONTEXT(route_map_index, index);
1330 int ret;
1331
1332 ret = route_map_add_match(index, "rpki", argv[2]->arg);
1333 if (ret) {
1334 switch (ret) {
1335 case RMAP_RULE_MISSING:
1336 vty_out(vty, "%% BGP Can't find rule.\n");
1337 return CMD_WARNING_CONFIG_FAILED;
1338 case RMAP_COMPILE_ERROR:
1339 vty_out(vty, "%% BGP Argument is malformed.\n");
1340 return CMD_WARNING_CONFIG_FAILED;
1341 }
1342 }
1343 return CMD_SUCCESS;
1344 }
1345
1346 DEFUN (no_match_rpki,
1347 no_match_rpki_cmd,
1348 "no match rpki <valid|invalid|notfound>",
1349 NO_STR
1350 MATCH_STR
1351 RPKI_OUTPUT_STRING
1352 "Valid prefix\n"
1353 "Invalid prefix\n"
1354 "Prefix not found\n")
1355 {
1356 VTY_DECLVAR_CONTEXT(route_map_index, index);
1357 int ret;
1358
1359 ret = route_map_delete_match(index, "rpki", argv[3]->arg);
1360 if (ret) {
1361 switch (ret) {
1362 case RMAP_RULE_MISSING:
1363 vty_out(vty, "%% BGP Can't find rule.\n");
1364 break;
1365 case RMAP_COMPILE_ERROR:
1366 vty_out(vty, "%% BGP Argument is malformed.\n");
1367 break;
1368 }
1369 return CMD_WARNING_CONFIG_FAILED;
1370 }
1371
1372 return CMD_SUCCESS;
1373 }
1374
1375 static void overwrite_exit_commands(void)
1376 {
1377 unsigned int i;
1378 vector cmd_vector = rpki_node.cmd_vector;
1379
1380 for (i = 0; i < cmd_vector->active; ++i) {
1381 struct cmd_element *cmd = vector_lookup(cmd_vector, i);
1382
1383 if (strcmp(cmd->string, "exit") == 0
1384 || strcmp(cmd->string, "quit") == 0
1385 || strcmp(cmd->string, "end") == 0) {
1386 uninstall_element(RPKI_NODE, cmd);
1387 }
1388 }
1389
1390 install_element(RPKI_NODE, &rpki_exit_cmd);
1391 install_element(RPKI_NODE, &rpki_quit_cmd);
1392 install_element(RPKI_NODE, &rpki_end_cmd);
1393 }
1394
1395 static void install_cli_commands(void)
1396 {
1397 // TODO: make config write work
1398 install_node(&rpki_node, &config_write);
1399 install_default(RPKI_NODE);
1400 overwrite_exit_commands();
1401 install_element(CONFIG_NODE, &rpki_cmd);
1402 install_element(VIEW_NODE, &rpki_cmd);
1403
1404 install_element(ENABLE_NODE, &bgp_rpki_start_cmd);
1405 install_element(ENABLE_NODE, &bgp_rpki_stop_cmd);
1406
1407 /* Install rpki reset command */
1408 install_element(RPKI_NODE, &rpki_reset_cmd);
1409
1410 /* Install rpki polling period commands */
1411 install_element(RPKI_NODE, &rpki_polling_period_cmd);
1412 install_element(RPKI_NODE, &no_rpki_polling_period_cmd);
1413
1414 /* Install rpki expire interval commands */
1415 install_element(RPKI_NODE, &rpki_expire_interval_cmd);
1416 install_element(RPKI_NODE, &no_rpki_expire_interval_cmd);
1417
1418 /* Install rpki retry interval commands */
1419 install_element(RPKI_NODE, &rpki_retry_interval_cmd);
1420 install_element(RPKI_NODE, &no_rpki_retry_interval_cmd);
1421
1422 /* Install rpki timeout commands */
1423 install_element(RPKI_NODE, &rpki_timeout_cmd);
1424 install_element(RPKI_NODE, &no_rpki_timeout_cmd);
1425
1426 /* Install rpki synchronisation timeout commands */
1427 install_element(RPKI_NODE, &rpki_synchronisation_timeout_cmd);
1428 install_element(RPKI_NODE, &no_rpki_synchronisation_timeout_cmd);
1429
1430 /* Install rpki cache commands */
1431 install_element(RPKI_NODE, &rpki_cache_cmd);
1432 install_element(RPKI_NODE, &no_rpki_cache_cmd);
1433
1434 /* Install show commands */
1435 install_element(ENABLE_NODE, &show_rpki_prefix_table_cmd);
1436 install_element(ENABLE_NODE, &show_rpki_cache_connection_cmd);
1437 install_element(ENABLE_NODE, &show_rpki_cache_server_cmd);
1438
1439 /* Install debug commands */
1440 install_element(CONFIG_NODE, &debug_rpki_cmd);
1441 install_element(ENABLE_NODE, &debug_rpki_cmd);
1442 install_element(CONFIG_NODE, &no_debug_rpki_cmd);
1443 install_element(ENABLE_NODE, &no_debug_rpki_cmd);
1444
1445 /* Install route match */
1446 route_map_install_match(&route_match_rpki_cmd);
1447 install_element(RMAP_NODE, &match_rpki_cmd);
1448 install_element(RMAP_NODE, &no_match_rpki_cmd);
1449 }
1450
1451 FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6",
1452 .description = "Enable RPKI support for FRR.",
1453 .init = bgp_rpki_module_init)