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