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