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