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