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