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