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