]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rpki.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[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_path_info *path;
221
222 if (type == RMAP_BGP) {
223 path = object;
224
225 if (rpki_validate_prefix(path->peer, path->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_path_info *path =
422 bgp_node_get_bgp_path_info(bgp_node);
423 mpls_label_t *label = NULL;
424 uint32_t num_labels = 0;
425
426 if (path && path->extra) {
427 label = path->extra->label;
428 num_labels = path->extra->num_labels;
429 }
430 ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
431 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
432 BGP_ROUTE_NORMAL, NULL, label, num_labels, 1,
433 NULL);
434
435 if (ret < 0)
436 return;
437 }
438 }
439
440 static void revalidate_all_routes(void)
441 {
442 struct bgp *bgp;
443 struct listnode *node;
444
445 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
446 struct peer *peer;
447 struct listnode *peer_listnode;
448
449 for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
450
451 for (size_t i = 0; i < 2; i++) {
452 safi_t safi;
453 afi_t afi = (i == 0) ? AFI_IP : AFI_IP6;
454
455 for (safi = SAFI_UNICAST; safi < SAFI_MAX;
456 safi++) {
457 if (!peer->bgp->rib[afi][safi])
458 continue;
459
460 bgp_soft_reconfig_in(peer, afi, safi);
461 }
462 }
463 }
464 }
465 }
466
467 static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
468 const struct pfx_record rec,
469 const bool added __attribute__((unused)))
470 {
471 if (rtr_is_stopping || rtr_is_starting
472 || atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
473 return;
474
475 int retval =
476 write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record));
477 if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
478 atomic_store_explicit(&rtr_update_overflow, 1,
479 memory_order_seq_cst);
480
481 else if (retval != sizeof(struct pfx_record))
482 RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
483 }
484
485 static void rpki_init_sync_socket(void)
486 {
487 int fds[2];
488 const char *msg;
489
490 RPKI_DEBUG("initializing sync socket");
491 if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) {
492 msg = "could not open rpki sync socketpair";
493 goto err;
494 }
495 rpki_sync_socket_rtr = fds[0];
496 rpki_sync_socket_bgpd = fds[1];
497
498 if (set_nonblocking(rpki_sync_socket_rtr) != 0) {
499 msg = "could not set rpki_sync_socket_rtr to non blocking";
500 goto err;
501 }
502
503 if (set_nonblocking(rpki_sync_socket_bgpd) != 0) {
504 msg = "could not set rpki_sync_socket_bgpd to non blocking";
505 goto err;
506 }
507
508
509 thread_add_read(bm->master, bgpd_sync_callback, NULL,
510 rpki_sync_socket_bgpd, NULL);
511
512 return;
513
514 err:
515 zlog_err("RPKI: %s", msg);
516 abort();
517
518 }
519
520 static int bgp_rpki_init(struct thread_master *master)
521 {
522 rpki_debug = 0;
523 rtr_is_running = 0;
524 rtr_is_stopping = 0;
525
526 cache_list = list_new();
527 cache_list->del = (void (*)(void *)) & free_cache;
528
529 polling_period = POLLING_PERIOD_DEFAULT;
530 expire_interval = EXPIRE_INTERVAL_DEFAULT;
531 retry_interval = RETRY_INTERVAL_DEFAULT;
532 timeout = TIMEOUT_DEFAULT;
533 initial_synchronisation_timeout =
534 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT;
535 install_cli_commands();
536 rpki_init_sync_socket();
537 return 0;
538 }
539
540 static int bgp_rpki_fini(void)
541 {
542 stop();
543 list_delete(&cache_list);
544
545 close(rpki_sync_socket_rtr);
546 close(rpki_sync_socket_bgpd);
547
548 return 0;
549 }
550
551 static int bgp_rpki_module_init(void)
552 {
553 lrtr_set_alloc_functions(malloc_wrapper, realloc_wrapper, free_wrapper);
554
555 hook_register(frr_late_init, bgp_rpki_init);
556 hook_register(frr_early_fini, &bgp_rpki_fini);
557
558 return 0;
559 }
560
561 static int start(void)
562 {
563 unsigned int waiting_time = 0;
564 int ret;
565
566 rtr_is_stopping = 0;
567 rtr_is_starting = 1;
568 rtr_update_overflow = 0;
569
570 if (list_isempty(cache_list)) {
571 RPKI_DEBUG(
572 "No caches were found in config. Prefix validation is off.");
573 return ERROR;
574 }
575 RPKI_DEBUG("Init rtr_mgr.");
576 int groups_len = listcount(cache_list);
577 struct rtr_mgr_group *groups = get_groups();
578
579 RPKI_DEBUG("Polling period: %d", polling_period);
580 ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period,
581 expire_interval, retry_interval,
582 rpki_update_cb_sync_rtr, NULL, NULL, NULL);
583 if (ret == RTR_ERROR) {
584 RPKI_DEBUG("Init rtr_mgr failed.");
585 return ERROR;
586 }
587
588 RPKI_DEBUG("Starting rtr_mgr.");
589 ret = rtr_mgr_start(rtr_config);
590 if (ret == RTR_ERROR) {
591 RPKI_DEBUG("Starting rtr_mgr failed.");
592 rtr_mgr_free(rtr_config);
593 return ERROR;
594 }
595 rtr_is_running = 1;
596 RPKI_DEBUG("Waiting for rtr connection to synchronize.");
597 while (waiting_time++ <= initial_synchronisation_timeout) {
598 if (rtr_mgr_conf_in_sync(rtr_config))
599 break;
600
601 sleep(1);
602 }
603 if (rtr_mgr_conf_in_sync(rtr_config)) {
604 RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
605 RPKI_DEBUG("Forcing revalidation.");
606 rtr_is_starting = 0;
607 revalidate_all_routes();
608 } else {
609 RPKI_DEBUG(
610 "Timeout expired! Proceeding without RPKI validation data.");
611 rtr_is_starting = 0;
612 }
613
614 XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups);
615
616 return SUCCESS;
617 }
618
619 static void stop(void)
620 {
621 rtr_is_stopping = 1;
622 if (rtr_is_running) {
623 rtr_mgr_stop(rtr_config);
624 rtr_mgr_free(rtr_config);
625 rtr_is_running = 0;
626 }
627 }
628
629 static int reset(bool force)
630 {
631 if (rtr_is_running && !force)
632 return SUCCESS;
633
634 RPKI_DEBUG("Resetting RPKI Session");
635 stop();
636 return start();
637 }
638
639 static struct rtr_mgr_group *get_connected_group(void)
640 {
641 if (!cache_list || list_isempty(cache_list))
642 return NULL;
643
644 return rtr_mgr_get_first_group(rtr_config);
645 }
646
647 static void print_prefix_table(struct vty *vty)
648 {
649 struct rpki_for_each_record_arg arg;
650
651 unsigned int number_of_ipv4_prefixes = 0;
652 unsigned int number_of_ipv6_prefixes = 0;
653 struct rtr_mgr_group *group = get_connected_group();
654
655 arg.vty = vty;
656
657 if (!group)
658 return;
659
660 struct pfx_table *pfx_table = group->sockets[0]->pfx_table;
661
662 vty_out(vty, "RPKI/RTR prefix table\n");
663 vty_out(vty, "%-40s %s %s\n", "Prefix", "Prefix Length", "Origin-AS");
664
665 arg.prefix_amount = &number_of_ipv4_prefixes;
666 pfx_table_for_each_ipv4_record(pfx_table, print_record, &arg);
667
668 arg.prefix_amount = &number_of_ipv6_prefixes;
669 pfx_table_for_each_ipv6_record(pfx_table, print_record, &arg);
670
671 vty_out(vty, "Number of IPv4 Prefixes: %u\n", number_of_ipv4_prefixes);
672 vty_out(vty, "Number of IPv6 Prefixes: %u\n", number_of_ipv6_prefixes);
673 }
674
675 static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
676 const struct prefix *prefix)
677 {
678 struct assegment *as_segment;
679 as_t as_number = 0;
680 struct lrtr_ip_addr ip_addr_prefix;
681 enum pfxv_state result;
682 char buf[BUFSIZ];
683 const char *prefix_string;
684
685 if (!is_synchronized())
686 return 0;
687
688 // No aspath means route comes from iBGP
689 if (!attr->aspath || !attr->aspath->segments) {
690 // Set own as number
691 as_number = peer->bgp->as;
692 } else {
693 as_segment = attr->aspath->segments;
694 // Find last AsSegment
695 while (as_segment->next)
696 as_segment = as_segment->next;
697
698 if (as_segment->type == AS_SEQUENCE) {
699 // Get rightmost asn
700 as_number = as_segment->as[as_segment->length - 1];
701 } else if (as_segment->type == AS_CONFED_SEQUENCE
702 || as_segment->type == AS_CONFED_SET) {
703 // Set own as number
704 as_number = peer->bgp->as;
705 } else {
706 // RFC says: "Take distinguished value NONE as asn"
707 // which means state is unknown
708 return RPKI_NOTFOUND;
709 }
710 }
711
712 // Get the prefix in requested format
713 switch (prefix->family) {
714 case AF_INET:
715 ip_addr_prefix.ver = LRTR_IPV4;
716 ip_addr_prefix.u.addr4.addr = ntohl(prefix->u.prefix4.s_addr);
717 break;
718
719 case AF_INET6:
720 ip_addr_prefix.ver = LRTR_IPV6;
721 ipv6_addr_to_host_byte_order(prefix->u.prefix6.s6_addr32,
722 ip_addr_prefix.u.addr6.addr);
723 break;
724
725 default:
726 return 0;
727 }
728
729 // Do the actual validation
730 rtr_mgr_validate(rtr_config, as_number, &ip_addr_prefix,
731 prefix->prefixlen, &result);
732
733 // Print Debug output
734 prefix_string =
735 inet_ntop(prefix->family, &prefix->u.prefix, buf, BUFSIZ);
736 switch (result) {
737 case BGP_PFXV_STATE_VALID:
738 RPKI_DEBUG(
739 "Validating Prefix %s/%hhu from asn %u Result: VALID",
740 prefix_string, prefix->prefixlen, as_number);
741 return RPKI_VALID;
742 case BGP_PFXV_STATE_NOT_FOUND:
743 RPKI_DEBUG(
744 "Validating Prefix %s/%hhu from asn %u Result: NOT FOUND",
745 prefix_string, prefix->prefixlen, as_number);
746 return RPKI_NOTFOUND;
747 case BGP_PFXV_STATE_INVALID:
748 RPKI_DEBUG(
749 "Validating Prefix %s/%hhu from asn %u Result: INVALID",
750 prefix_string, prefix->prefixlen, as_number);
751 return RPKI_INVALID;
752 default:
753 RPKI_DEBUG(
754 "Validating Prefix %s/%hhu from asn %u Result: CANNOT VALIDATE",
755 prefix_string, prefix->prefixlen, as_number);
756 break;
757 }
758 return 0;
759 }
760
761 static int add_cache(struct cache *cache)
762 {
763 uint8_t preference = cache->preference;
764 struct rtr_mgr_group group;
765
766 group.preference = preference;
767 group.sockets_len = 1;
768 group.sockets = &cache->rtr_socket;
769
770 listnode_add(cache_list, cache);
771
772 if (rtr_is_running) {
773 init_tr_socket(cache);
774
775 if (rtr_mgr_add_group(rtr_config, &group) != RTR_SUCCESS) {
776 free_tr_socket(cache);
777 return ERROR;
778 }
779 }
780
781 return SUCCESS;
782 }
783
784 static int add_tcp_cache(const char *host, const char *port,
785 const uint8_t preference)
786 {
787 struct rtr_socket *rtr_socket;
788 struct tr_tcp_config *tcp_config =
789 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_tcp_config));
790 struct tr_socket *tr_socket =
791 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_socket));
792 struct cache *cache =
793 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct cache));
794
795 tcp_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
796 tcp_config->port = XSTRDUP(MTYPE_BGP_RPKI_CACHE, port);
797 tcp_config->bindaddr = NULL;
798
799 rtr_socket = create_rtr_socket(tr_socket);
800
801 cache->type = TCP;
802 cache->tr_socket = tr_socket;
803 cache->tr_config.tcp_config = tcp_config;
804 cache->rtr_socket = rtr_socket;
805 cache->preference = preference;
806
807 return add_cache(cache);
808 }
809
810 #if defined(FOUND_SSH)
811 static int add_ssh_cache(const char *host, const unsigned int port,
812 const char *username, const char *client_privkey_path,
813 const char *client_pubkey_path,
814 const char *server_pubkey_path,
815 const uint8_t preference)
816 {
817 struct tr_ssh_config *ssh_config =
818 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_ssh_config));
819 struct cache *cache =
820 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct cache));
821 struct tr_socket *tr_socket =
822 XMALLOC(MTYPE_BGP_RPKI_CACHE, sizeof(struct tr_socket));
823 struct rtr_socket *rtr_socket;
824
825 ssh_config->port = port;
826 ssh_config->host = XSTRDUP(MTYPE_BGP_RPKI_CACHE, host);
827 ssh_config->bindaddr = NULL;
828
829 ssh_config->username = XSTRDUP(MTYPE_BGP_RPKI_CACHE, username);
830 ssh_config->client_privkey_path =
831 XSTRDUP(MTYPE_BGP_RPKI_CACHE, client_privkey_path);
832 ssh_config->server_hostkey_path =
833 XSTRDUP(MTYPE_BGP_RPKI_CACHE, server_pubkey_path);
834
835 rtr_socket = create_rtr_socket(tr_socket);
836
837 cache->type = SSH;
838 cache->tr_socket = tr_socket;
839 cache->tr_config.ssh_config = ssh_config;
840 cache->rtr_socket = rtr_socket;
841 cache->preference = preference;
842
843 return add_cache(cache);
844 }
845 #endif
846
847 static void free_cache(struct cache *cache)
848 {
849 if (cache->type == TCP) {
850 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->host);
851 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config->port);
852 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.tcp_config);
853 }
854 #if defined(FOUND_SSH)
855 else {
856 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config->host);
857 XFREE(MTYPE_BGP_RPKI_CACHE,
858 cache->tr_config.ssh_config->username);
859 XFREE(MTYPE_BGP_RPKI_CACHE,
860 cache->tr_config.ssh_config->client_privkey_path);
861 XFREE(MTYPE_BGP_RPKI_CACHE,
862 cache->tr_config.ssh_config->server_hostkey_path);
863 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_config.ssh_config);
864 }
865 #endif
866 XFREE(MTYPE_BGP_RPKI_CACHE, cache->tr_socket);
867 XFREE(MTYPE_BGP_RPKI_CACHE, cache->rtr_socket);
868 XFREE(MTYPE_BGP_RPKI_CACHE, cache);
869 }
870
871 static int config_write(struct vty *vty)
872 {
873 struct listnode *cache_node;
874 struct cache *cache;
875
876 if (listcount(cache_list)) {
877 if (rpki_debug)
878 vty_out(vty, "debug rpki\n");
879
880 vty_out(vty, "!\n");
881 vty_out(vty, "rpki\n");
882 vty_out(vty, " rpki polling_period %d\n", polling_period);
883 vty_out(vty, " rpki timeout %d\n", timeout);
884 vty_out(vty, " rpki initial-synchronisation-timeout %d\n",
885 initial_synchronisation_timeout);
886 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
887 switch (cache->type) {
888 struct tr_tcp_config *tcp_config;
889 #if defined(FOUND_SSH)
890 struct tr_ssh_config *ssh_config;
891 #endif
892 case TCP:
893 tcp_config = cache->tr_config.tcp_config;
894 vty_out(vty, " rpki cache %s %s ",
895 tcp_config->host, tcp_config->port);
896 break;
897 #if defined(FOUND_SSH)
898 case SSH:
899 ssh_config = cache->tr_config.ssh_config;
900 vty_out(vty, " rpki cache %s %u %s %s %s ",
901 ssh_config->host, ssh_config->port,
902 ssh_config->username,
903 ssh_config->client_privkey_path,
904 ssh_config->server_hostkey_path != NULL
905 ? ssh_config
906 ->server_hostkey_path
907 : " ");
908 break;
909 #endif
910 default:
911 break;
912 }
913
914 vty_out(vty, "preference %hhu\n", cache->preference);
915 }
916 vty_out(vty, " exit\n");
917 return 1;
918 } else {
919 return 0;
920 }
921 }
922
923 DEFUN_NOSH (rpki,
924 rpki_cmd,
925 "rpki",
926 "Enable rpki and enter rpki configuration mode\n")
927 {
928 vty->node = RPKI_NODE;
929 return CMD_SUCCESS;
930 }
931
932 DEFUN (bgp_rpki_start,
933 bgp_rpki_start_cmd,
934 "rpki start",
935 RPKI_OUTPUT_STRING
936 "start rpki support\n")
937 {
938 if (listcount(cache_list) == 0)
939 vty_out(vty,
940 "Could not start rpki because no caches are configured\n");
941
942 if (!is_running()) {
943 if (start() == ERROR) {
944 RPKI_DEBUG("RPKI failed to start");
945 return CMD_WARNING;
946 }
947 }
948 return CMD_SUCCESS;
949 }
950
951 DEFUN (bgp_rpki_stop,
952 bgp_rpki_stop_cmd,
953 "rpki stop",
954 RPKI_OUTPUT_STRING
955 "start rpki support\n")
956 {
957 if (is_running())
958 stop();
959
960 return CMD_SUCCESS;
961 }
962
963 DEFPY (rpki_polling_period,
964 rpki_polling_period_cmd,
965 "rpki polling_period (1-86400)$pp",
966 RPKI_OUTPUT_STRING
967 "Set polling period\n"
968 "Polling period value\n")
969 {
970 polling_period = pp;
971 return CMD_SUCCESS;
972 }
973
974 DEFUN (no_rpki_polling_period,
975 no_rpki_polling_period_cmd,
976 "no rpki polling_period",
977 NO_STR
978 RPKI_OUTPUT_STRING
979 "Set polling period back to default\n")
980 {
981 polling_period = POLLING_PERIOD_DEFAULT;
982 return CMD_SUCCESS;
983 }
984
985 DEFPY (rpki_expire_interval,
986 rpki_expire_interval_cmd,
987 "rpki expire_interval (600-172800)$tmp",
988 RPKI_OUTPUT_STRING
989 "Set expire interval\n"
990 "Expire interval value\n")
991 {
992 if ((unsigned int)tmp >= polling_period) {
993 expire_interval = tmp;
994 return CMD_SUCCESS;
995 }
996
997 vty_out(vty, "%% Expiry interval must be polling period or larger\n");
998 return CMD_WARNING_CONFIG_FAILED;
999 }
1000
1001 DEFUN (no_rpki_expire_interval,
1002 no_rpki_expire_interval_cmd,
1003 "no rpki expire_interval",
1004 NO_STR
1005 RPKI_OUTPUT_STRING
1006 "Set expire interval back to default\n")
1007 {
1008 expire_interval = polling_period * 2;
1009 return CMD_SUCCESS;
1010 }
1011
1012 DEFPY (rpki_retry_interval,
1013 rpki_retry_interval_cmd,
1014 "rpki retry_interval (1-7200)$tmp",
1015 RPKI_OUTPUT_STRING
1016 "Set retry interval\n"
1017 "retry interval value\n")
1018 {
1019 retry_interval = tmp;
1020 return CMD_SUCCESS;
1021 }
1022
1023 DEFUN (no_rpki_retry_interval,
1024 no_rpki_retry_interval_cmd,
1025 "no rpki retry_interval",
1026 NO_STR
1027 RPKI_OUTPUT_STRING
1028 "Set retry interval back to default\n")
1029 {
1030 retry_interval = RETRY_INTERVAL_DEFAULT;
1031 return CMD_SUCCESS;
1032 }
1033
1034 DEFPY (rpki_timeout,
1035 rpki_timeout_cmd,
1036 "rpki timeout (1-4294967295)$to_arg",
1037 RPKI_OUTPUT_STRING
1038 "Set timeout\n"
1039 "Timeout value\n")
1040 {
1041 timeout = to_arg;
1042 return CMD_SUCCESS;
1043 }
1044
1045 DEFUN (no_rpki_timeout,
1046 no_rpki_timeout_cmd,
1047 "no rpki timeout",
1048 NO_STR
1049 RPKI_OUTPUT_STRING
1050 "Set timeout back to default\n")
1051 {
1052 timeout = TIMEOUT_DEFAULT;
1053 return CMD_SUCCESS;
1054 }
1055
1056 DEFPY (rpki_synchronisation_timeout,
1057 rpki_synchronisation_timeout_cmd,
1058 "rpki initial-synchronisation-timeout (1-4294967295)$ito_arg",
1059 RPKI_OUTPUT_STRING
1060 "Set a timeout for the initial synchronisation of prefix validation data\n"
1061 "Timeout value\n")
1062 {
1063 initial_synchronisation_timeout = ito_arg;
1064 return CMD_SUCCESS;
1065 }
1066
1067 DEFUN (no_rpki_synchronisation_timeout,
1068 no_rpki_synchronisation_timeout_cmd,
1069 "no rpki initial-synchronisation-timeout",
1070 NO_STR
1071 RPKI_OUTPUT_STRING
1072 "Set the initial synchronisation timeout back to default (30 sec.)\n")
1073 {
1074 initial_synchronisation_timeout =
1075 INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT;
1076 return CMD_SUCCESS;
1077 }
1078
1079 DEFPY (rpki_cache,
1080 rpki_cache_cmd,
1081 "rpki cache <A.B.C.D|WORD>"
1082 "<TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY SSH_PUBKEY [SERVER_PUBKEY]> "
1083 "preference (1-255)",
1084 RPKI_OUTPUT_STRING
1085 "Install a cache server to current group\n"
1086 "IP address of cache server\n Hostname of cache server\n"
1087 "TCP port number\n"
1088 "SSH port number\n"
1089 "SSH user name\n"
1090 "Path to own SSH private key\n"
1091 "Path to own SSH public key\n"
1092 "Path to Public key of cache server\n"
1093 "Preference of the cache server\n"
1094 "Preference value\n")
1095 {
1096 int return_value;
1097
1098 // use ssh connection
1099 if (ssh_uname) {
1100 #if defined(FOUND_SSH)
1101 return_value =
1102 add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey,
1103 ssh_pubkey, server_pubkey, preference);
1104 #else
1105 return_value = SUCCESS;
1106 vty_out(vty,
1107 "ssh sockets are not supported. "
1108 "Please recompile rtrlib and frr with ssh support. "
1109 "If you want to use it");
1110 #endif
1111 } else { // use tcp connection
1112 return_value = add_tcp_cache(cache, tcpport, preference);
1113 }
1114
1115 if (return_value == ERROR) {
1116 vty_out(vty, "Could not create new rpki cache\n");
1117 return CMD_WARNING;
1118 }
1119
1120 return CMD_SUCCESS;
1121 }
1122
1123 DEFPY (no_rpki_cache,
1124 no_rpki_cache_cmd,
1125 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
1126 NO_STR
1127 RPKI_OUTPUT_STRING
1128 "Remove a cache server\n"
1129 "IP address of cache server\n Hostname of cache server\n"
1130 "TCP port number\n"
1131 "SSH port number\n"
1132 "Preference of the cache server\n"
1133 "Preference value\n")
1134 {
1135 struct cache *cache_p = find_cache(preference);
1136
1137 if (!cache) {
1138 vty_out(vty, "Could not find cache %ld\n", preference);
1139 return CMD_WARNING;
1140 }
1141
1142 if (rtr_is_running) {
1143 if (rtr_mgr_remove_group(rtr_config, preference) == RTR_ERROR) {
1144 vty_out(vty, "Could not remove cache %ld", preference);
1145 if (listcount(cache_list) == 1)
1146 vty_out(vty, " because it is the last cache");
1147
1148 vty_out(vty, "\n");
1149 return CMD_WARNING;
1150 }
1151 }
1152
1153 listnode_delete(cache_list, cache_p);
1154 free_cache(cache_p);
1155
1156 return CMD_SUCCESS;
1157 }
1158
1159 DEFUN (show_rpki_prefix_table,
1160 show_rpki_prefix_table_cmd,
1161 "show rpki prefix-table",
1162 SHOW_STR
1163 RPKI_OUTPUT_STRING
1164 "Show validated prefixes which were received from RPKI Cache\n")
1165 {
1166 struct listnode *cache_node;
1167 struct cache *cache;
1168
1169 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1170 vty_out(vty, "host: %s port: %s\n",
1171 cache->tr_config.tcp_config->host,
1172 cache->tr_config.tcp_config->port);
1173 }
1174 if (is_synchronized())
1175 print_prefix_table(vty);
1176 else
1177 vty_out(vty, "No connection to RPKI cache server.\n");
1178
1179 return CMD_SUCCESS;
1180 }
1181
1182 DEFUN (show_rpki_cache_server,
1183 show_rpki_cache_server_cmd,
1184 "show rpki cache-server",
1185 SHOW_STR
1186 RPKI_OUTPUT_STRING
1187 "SHOW configured cache server\n")
1188 {
1189 struct listnode *cache_node;
1190 struct cache *cache;
1191
1192 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1193 vty_out(vty, "host: %s port: %s\n",
1194 cache->tr_config.tcp_config->host,
1195 cache->tr_config.tcp_config->port);
1196 }
1197
1198 return CMD_SUCCESS;
1199 }
1200
1201 DEFUN (show_rpki_cache_connection,
1202 show_rpki_cache_connection_cmd,
1203 "show rpki cache-connection",
1204 SHOW_STR
1205 RPKI_OUTPUT_STRING
1206 "Show to which RPKI Cache Servers we have a connection\n")
1207 {
1208 if (is_synchronized()) {
1209 struct listnode *cache_node;
1210 struct cache *cache;
1211 struct rtr_mgr_group *group = get_connected_group();
1212
1213 if (!group) {
1214 vty_out(vty, "Cannot find a connected group.\n");
1215 return CMD_SUCCESS;
1216 }
1217 vty_out(vty, "Connected to group %d\n", group->preference);
1218 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1219 if (cache->preference == group->preference) {
1220 struct tr_tcp_config *tcp_config;
1221 #if defined(FOUND_SSH)
1222 struct tr_ssh_config *ssh_config;
1223 #endif
1224
1225 switch (cache->type) {
1226 case TCP:
1227 tcp_config =
1228 cache->tr_config.tcp_config;
1229 vty_out(vty,
1230 "rpki tcp cache %s %s pref %hhu\n",
1231 tcp_config->host,
1232 tcp_config->port,
1233 cache->preference);
1234 break;
1235
1236 #if defined(FOUND_SSH)
1237 case SSH:
1238 ssh_config =
1239 cache->tr_config.ssh_config;
1240 vty_out(vty,
1241 "rpki ssh cache %s %u pref %hhu\n",
1242 ssh_config->host,
1243 ssh_config->port,
1244 cache->preference);
1245 break;
1246 #endif
1247
1248 default:
1249 break;
1250 }
1251 }
1252 }
1253 } else {
1254 vty_out(vty, "No connection to RPKI cache server.\n");
1255 }
1256
1257 return CMD_SUCCESS;
1258 }
1259
1260 DEFUN_NOSH (rpki_exit,
1261 rpki_exit_cmd,
1262 "exit",
1263 "Exit rpki configuration and restart rpki session\n")
1264 {
1265 reset(false);
1266
1267 vty->node = CONFIG_NODE;
1268 return CMD_SUCCESS;
1269 }
1270
1271 DEFUN_NOSH (rpki_quit,
1272 rpki_quit_cmd,
1273 "quit",
1274 "Exit rpki configuration mode\n")
1275 {
1276 return rpki_exit(self, vty, argc, argv);
1277 }
1278
1279 DEFUN_NOSH (rpki_end,
1280 rpki_end_cmd,
1281 "end",
1282 "End rpki configuration, restart rpki session and change to enable mode.\n")
1283 {
1284 int ret = reset(false);
1285
1286 vty_config_exit(vty);
1287 vty->node = ENABLE_NODE;
1288 return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1289 }
1290
1291 DEFUN (rpki_reset,
1292 rpki_reset_cmd,
1293 "rpki reset",
1294 RPKI_OUTPUT_STRING
1295 "reset rpki\n")
1296 {
1297 return reset(true) == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1298 }
1299
1300 DEFUN (debug_rpki,
1301 debug_rpki_cmd,
1302 "debug rpki",
1303 DEBUG_STR
1304 "Enable debugging for rpki\n")
1305 {
1306 rpki_debug = 1;
1307 return CMD_SUCCESS;
1308 }
1309
1310 DEFUN (no_debug_rpki,
1311 no_debug_rpki_cmd,
1312 "no debug rpki",
1313 NO_STR
1314 DEBUG_STR
1315 "Disable debugging for rpki\n")
1316 {
1317 rpki_debug = 0;
1318 return CMD_SUCCESS;
1319 }
1320
1321 DEFUN (match_rpki,
1322 match_rpki_cmd,
1323 "match rpki <valid|invalid|notfound>",
1324 MATCH_STR
1325 RPKI_OUTPUT_STRING
1326 "Valid prefix\n"
1327 "Invalid prefix\n"
1328 "Prefix not found\n")
1329 {
1330 VTY_DECLVAR_CONTEXT(route_map_index, index);
1331 int ret;
1332
1333 ret = route_map_add_match(index, "rpki", argv[2]->arg);
1334 if (ret) {
1335 switch (ret) {
1336 case RMAP_RULE_MISSING:
1337 vty_out(vty, "%% BGP Can't find rule.\n");
1338 return CMD_WARNING_CONFIG_FAILED;
1339 case RMAP_COMPILE_ERROR:
1340 vty_out(vty, "%% BGP Argument is malformed.\n");
1341 return CMD_WARNING_CONFIG_FAILED;
1342 }
1343 }
1344 return CMD_SUCCESS;
1345 }
1346
1347 DEFUN (no_match_rpki,
1348 no_match_rpki_cmd,
1349 "no match rpki <valid|invalid|notfound>",
1350 NO_STR
1351 MATCH_STR
1352 RPKI_OUTPUT_STRING
1353 "Valid prefix\n"
1354 "Invalid prefix\n"
1355 "Prefix not found\n")
1356 {
1357 VTY_DECLVAR_CONTEXT(route_map_index, index);
1358 int ret;
1359
1360 ret = route_map_delete_match(index, "rpki", argv[3]->arg);
1361 if (ret) {
1362 switch (ret) {
1363 case RMAP_RULE_MISSING:
1364 vty_out(vty, "%% BGP Can't find rule.\n");
1365 break;
1366 case RMAP_COMPILE_ERROR:
1367 vty_out(vty, "%% BGP Argument is malformed.\n");
1368 break;
1369 }
1370 return CMD_WARNING_CONFIG_FAILED;
1371 }
1372
1373 return CMD_SUCCESS;
1374 }
1375
1376 static void overwrite_exit_commands(void)
1377 {
1378 unsigned int i;
1379 vector cmd_vector = rpki_node.cmd_vector;
1380
1381 for (i = 0; i < cmd_vector->active; ++i) {
1382 struct cmd_element *cmd = vector_lookup(cmd_vector, i);
1383
1384 if (strcmp(cmd->string, "exit") == 0
1385 || strcmp(cmd->string, "quit") == 0
1386 || strcmp(cmd->string, "end") == 0) {
1387 uninstall_element(RPKI_NODE, cmd);
1388 }
1389 }
1390
1391 install_element(RPKI_NODE, &rpki_exit_cmd);
1392 install_element(RPKI_NODE, &rpki_quit_cmd);
1393 install_element(RPKI_NODE, &rpki_end_cmd);
1394 }
1395
1396 static void install_cli_commands(void)
1397 {
1398 // TODO: make config write work
1399 install_node(&rpki_node, &config_write);
1400 install_default(RPKI_NODE);
1401 overwrite_exit_commands();
1402 install_element(CONFIG_NODE, &rpki_cmd);
1403 install_element(VIEW_NODE, &rpki_cmd);
1404
1405 install_element(ENABLE_NODE, &bgp_rpki_start_cmd);
1406 install_element(ENABLE_NODE, &bgp_rpki_stop_cmd);
1407
1408 /* Install rpki reset command */
1409 install_element(RPKI_NODE, &rpki_reset_cmd);
1410
1411 /* Install rpki polling period commands */
1412 install_element(RPKI_NODE, &rpki_polling_period_cmd);
1413 install_element(RPKI_NODE, &no_rpki_polling_period_cmd);
1414
1415 /* Install rpki expire interval commands */
1416 install_element(RPKI_NODE, &rpki_expire_interval_cmd);
1417 install_element(RPKI_NODE, &no_rpki_expire_interval_cmd);
1418
1419 /* Install rpki retry interval commands */
1420 install_element(RPKI_NODE, &rpki_retry_interval_cmd);
1421 install_element(RPKI_NODE, &no_rpki_retry_interval_cmd);
1422
1423 /* Install rpki timeout commands */
1424 install_element(RPKI_NODE, &rpki_timeout_cmd);
1425 install_element(RPKI_NODE, &no_rpki_timeout_cmd);
1426
1427 /* Install rpki synchronisation timeout commands */
1428 install_element(RPKI_NODE, &rpki_synchronisation_timeout_cmd);
1429 install_element(RPKI_NODE, &no_rpki_synchronisation_timeout_cmd);
1430
1431 /* Install rpki cache commands */
1432 install_element(RPKI_NODE, &rpki_cache_cmd);
1433 install_element(RPKI_NODE, &no_rpki_cache_cmd);
1434
1435 /* Install show commands */
1436 install_element(ENABLE_NODE, &show_rpki_prefix_table_cmd);
1437 install_element(ENABLE_NODE, &show_rpki_cache_connection_cmd);
1438 install_element(ENABLE_NODE, &show_rpki_cache_server_cmd);
1439
1440 /* Install debug commands */
1441 install_element(CONFIG_NODE, &debug_rpki_cmd);
1442 install_element(ENABLE_NODE, &debug_rpki_cmd);
1443 install_element(CONFIG_NODE, &no_debug_rpki_cmd);
1444 install_element(ENABLE_NODE, &no_debug_rpki_cmd);
1445
1446 /* Install route match */
1447 route_map_install_match(&route_match_rpki_cmd);
1448 install_element(RMAP_NODE, &match_rpki_cmd);
1449 install_element(RMAP_NODE, &no_match_rpki_cmd);
1450 }
1451
1452 FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6",
1453 .description = "Enable RPKI support for FRR.",
1454 .init = bgp_rpki_module_init)