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