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