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