]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rpki.c
Merge pull request #5686 from qlyoung/fix-bgp-fqdn-capability-leak
[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 const 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 && (uint32_t)asn == record->asn)
1238 || asn == 0)) {
1239 print_record(&matches[i], vty);
1240 }
1241 }
1242
1243 return CMD_SUCCESS;
1244 }
1245
1246 DEFUN (show_rpki_cache_server,
1247 show_rpki_cache_server_cmd,
1248 "show rpki cache-server",
1249 SHOW_STR
1250 RPKI_OUTPUT_STRING
1251 "SHOW configured cache server\n")
1252 {
1253 struct listnode *cache_node;
1254 struct cache *cache;
1255
1256 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1257 if (cache->type == TCP) {
1258 vty_out(vty, "host: %s port: %s\n",
1259 cache->tr_config.tcp_config->host,
1260 cache->tr_config.tcp_config->port);
1261
1262 #if defined(FOUND_SSH)
1263 } else if (cache->type == SSH) {
1264 vty_out(vty,
1265 "host: %s port: %d username: %s "
1266 "server_hostkey_path: %s client_privkey_path: %s\n",
1267 cache->tr_config.ssh_config->host,
1268 cache->tr_config.ssh_config->port,
1269 cache->tr_config.ssh_config->username,
1270 cache->tr_config.ssh_config
1271 ->server_hostkey_path,
1272 cache->tr_config.ssh_config
1273 ->client_privkey_path);
1274 #endif
1275 }
1276 }
1277
1278 return CMD_SUCCESS;
1279 }
1280
1281 DEFUN (show_rpki_cache_connection,
1282 show_rpki_cache_connection_cmd,
1283 "show rpki cache-connection",
1284 SHOW_STR
1285 RPKI_OUTPUT_STRING
1286 "Show to which RPKI Cache Servers we have a connection\n")
1287 {
1288 if (is_synchronized()) {
1289 struct listnode *cache_node;
1290 struct cache *cache;
1291 struct rtr_mgr_group *group = get_connected_group();
1292
1293 if (!group) {
1294 vty_out(vty, "Cannot find a connected group.\n");
1295 return CMD_SUCCESS;
1296 }
1297 vty_out(vty, "Connected to group %d\n", group->preference);
1298 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
1299 if (cache->preference == group->preference) {
1300 struct tr_tcp_config *tcp_config;
1301 #if defined(FOUND_SSH)
1302 struct tr_ssh_config *ssh_config;
1303 #endif
1304
1305 switch (cache->type) {
1306 case TCP:
1307 tcp_config =
1308 cache->tr_config.tcp_config;
1309 vty_out(vty,
1310 "rpki tcp cache %s %s pref %hhu\n",
1311 tcp_config->host,
1312 tcp_config->port,
1313 cache->preference);
1314 break;
1315
1316 #if defined(FOUND_SSH)
1317 case SSH:
1318 ssh_config =
1319 cache->tr_config.ssh_config;
1320 vty_out(vty,
1321 "rpki ssh cache %s %u pref %hhu\n",
1322 ssh_config->host,
1323 ssh_config->port,
1324 cache->preference);
1325 break;
1326 #endif
1327
1328 default:
1329 break;
1330 }
1331 }
1332 }
1333 } else {
1334 vty_out(vty, "No connection to RPKI cache server.\n");
1335 }
1336
1337 return CMD_SUCCESS;
1338 }
1339
1340 DEFUN_NOSH (rpki_exit,
1341 rpki_exit_cmd,
1342 "exit",
1343 "Exit rpki configuration and restart rpki session\n")
1344 {
1345 reset(false);
1346
1347 vty->node = CONFIG_NODE;
1348 return CMD_SUCCESS;
1349 }
1350
1351 DEFUN_NOSH (rpki_quit,
1352 rpki_quit_cmd,
1353 "quit",
1354 "Exit rpki configuration mode\n")
1355 {
1356 return rpki_exit(self, vty, argc, argv);
1357 }
1358
1359 DEFUN_NOSH (rpki_end,
1360 rpki_end_cmd,
1361 "end",
1362 "End rpki configuration, restart rpki session and change to enable mode.\n")
1363 {
1364 int ret = reset(false);
1365
1366 vty_config_exit(vty);
1367 vty->node = ENABLE_NODE;
1368 return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1369 }
1370
1371 DEFUN (rpki_reset,
1372 rpki_reset_cmd,
1373 "rpki reset",
1374 RPKI_OUTPUT_STRING
1375 "reset rpki\n")
1376 {
1377 return reset(true) == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1378 }
1379
1380 DEFUN (debug_rpki,
1381 debug_rpki_cmd,
1382 "debug rpki",
1383 DEBUG_STR
1384 "Enable debugging for rpki\n")
1385 {
1386 rpki_debug = 1;
1387 return CMD_SUCCESS;
1388 }
1389
1390 DEFUN (no_debug_rpki,
1391 no_debug_rpki_cmd,
1392 "no debug rpki",
1393 NO_STR
1394 DEBUG_STR
1395 "Disable debugging for rpki\n")
1396 {
1397 rpki_debug = 0;
1398 return CMD_SUCCESS;
1399 }
1400
1401 DEFUN (match_rpki,
1402 match_rpki_cmd,
1403 "match rpki <valid|invalid|notfound>",
1404 MATCH_STR
1405 RPKI_OUTPUT_STRING
1406 "Valid prefix\n"
1407 "Invalid prefix\n"
1408 "Prefix not found\n")
1409 {
1410 VTY_DECLVAR_CONTEXT(route_map_index, index);
1411 enum rmap_compile_rets ret;
1412
1413 ret = route_map_add_match(index, "rpki", argv[2]->arg,
1414 RMAP_EVENT_MATCH_ADDED);
1415 if (ret) {
1416 switch (ret) {
1417 case RMAP_RULE_MISSING:
1418 vty_out(vty, "%% BGP Can't find rule.\n");
1419 return CMD_WARNING_CONFIG_FAILED;
1420 case RMAP_COMPILE_ERROR:
1421 vty_out(vty, "%% BGP Argument is malformed.\n");
1422 return CMD_WARNING_CONFIG_FAILED;
1423 case RMAP_COMPILE_SUCCESS:
1424 /*
1425 * Intentionally doing nothing here
1426 */
1427 break;
1428 }
1429 }
1430 return CMD_SUCCESS;
1431 }
1432
1433 DEFUN (no_match_rpki,
1434 no_match_rpki_cmd,
1435 "no match rpki <valid|invalid|notfound>",
1436 NO_STR
1437 MATCH_STR
1438 RPKI_OUTPUT_STRING
1439 "Valid prefix\n"
1440 "Invalid prefix\n"
1441 "Prefix not found\n")
1442 {
1443 VTY_DECLVAR_CONTEXT(route_map_index, index);
1444 enum rmap_compile_rets ret;
1445
1446 ret = route_map_delete_match(index, "rpki", argv[3]->arg,
1447 RMAP_EVENT_MATCH_DELETED);
1448 if (ret) {
1449 switch (ret) {
1450 case RMAP_RULE_MISSING:
1451 vty_out(vty, "%% BGP Can't find rule.\n");
1452 break;
1453 case RMAP_COMPILE_ERROR:
1454 vty_out(vty, "%% BGP Argument is malformed.\n");
1455 break;
1456 case RMAP_COMPILE_SUCCESS:
1457 /*
1458 * Nothing to do here
1459 */
1460 break;
1461 }
1462 return CMD_WARNING_CONFIG_FAILED;
1463 }
1464
1465 return CMD_SUCCESS;
1466 }
1467
1468 static void overwrite_exit_commands(void)
1469 {
1470 unsigned int i;
1471 vector cmd_vector = rpki_node.cmd_vector;
1472
1473 for (i = 0; i < cmd_vector->active; ++i) {
1474 struct cmd_element *cmd = vector_lookup(cmd_vector, i);
1475
1476 if (strcmp(cmd->string, "exit") == 0
1477 || strcmp(cmd->string, "quit") == 0
1478 || strcmp(cmd->string, "end") == 0) {
1479 uninstall_element(RPKI_NODE, cmd);
1480 }
1481 }
1482
1483 install_element(RPKI_NODE, &rpki_exit_cmd);
1484 install_element(RPKI_NODE, &rpki_quit_cmd);
1485 install_element(RPKI_NODE, &rpki_end_cmd);
1486 }
1487
1488 static void install_cli_commands(void)
1489 {
1490 // TODO: make config write work
1491 install_node(&rpki_node, &config_write);
1492 install_default(RPKI_NODE);
1493 overwrite_exit_commands();
1494 install_element(CONFIG_NODE, &rpki_cmd);
1495 install_element(ENABLE_NODE, &rpki_cmd);
1496
1497 install_element(ENABLE_NODE, &bgp_rpki_start_cmd);
1498 install_element(ENABLE_NODE, &bgp_rpki_stop_cmd);
1499
1500 /* Install rpki reset command */
1501 install_element(RPKI_NODE, &rpki_reset_cmd);
1502
1503 /* Install rpki polling period commands */
1504 install_element(RPKI_NODE, &rpki_polling_period_cmd);
1505 install_element(RPKI_NODE, &no_rpki_polling_period_cmd);
1506
1507 /* Install rpki expire interval commands */
1508 install_element(RPKI_NODE, &rpki_expire_interval_cmd);
1509 install_element(RPKI_NODE, &no_rpki_expire_interval_cmd);
1510
1511 /* Install rpki retry interval commands */
1512 install_element(RPKI_NODE, &rpki_retry_interval_cmd);
1513 install_element(RPKI_NODE, &no_rpki_retry_interval_cmd);
1514
1515 /* Install rpki timeout commands */
1516 install_element(RPKI_NODE, &rpki_timeout_cmd);
1517 install_element(RPKI_NODE, &no_rpki_timeout_cmd);
1518
1519 /* Install rpki synchronisation timeout commands */
1520 install_element(RPKI_NODE, &rpki_synchronisation_timeout_cmd);
1521 install_element(RPKI_NODE, &no_rpki_synchronisation_timeout_cmd);
1522
1523 /* Install rpki cache commands */
1524 install_element(RPKI_NODE, &rpki_cache_cmd);
1525 install_element(RPKI_NODE, &no_rpki_cache_cmd);
1526
1527 /* Install show commands */
1528 install_element(VIEW_NODE, &show_rpki_prefix_table_cmd);
1529 install_element(VIEW_NODE, &show_rpki_cache_connection_cmd);
1530 install_element(VIEW_NODE, &show_rpki_cache_server_cmd);
1531 install_element(VIEW_NODE, &show_rpki_prefix_cmd);
1532
1533 /* Install debug commands */
1534 install_element(CONFIG_NODE, &debug_rpki_cmd);
1535 install_element(ENABLE_NODE, &debug_rpki_cmd);
1536 install_element(CONFIG_NODE, &no_debug_rpki_cmd);
1537 install_element(ENABLE_NODE, &no_debug_rpki_cmd);
1538
1539 /* Install route match */
1540 route_map_install_match(&route_match_rpki_cmd);
1541 install_element(RMAP_NODE, &match_rpki_cmd);
1542 install_element(RMAP_NODE, &no_match_rpki_cmd);
1543 }
1544
1545 FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6",
1546 .description = "Enable RPKI support for FRR.",
1547 .init = bgp_rpki_module_init)