]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_rpki.c
Merge pull request #2614 from rtrlib/2018-07-02-master-bugfix
[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 = SUCCESS;
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 vty_out(vty,
877 "ssh sockets are not supported. "
878 "Please recompile rtrlib and frr with ssh support. "
879 "If you want to use it");
880 #endif
881 } else { // use tcp connection
882 return_value = add_tcp_cache(cache, tcpport, preference);
883 }
884
885 if (return_value == ERROR) {
886 vty_out(vty, "Could not create new rpki cache\n");
887 return CMD_WARNING;
888 }
889
890 return CMD_SUCCESS;
891 }
892
893 DEFPY (no_rpki_cache,
894 no_rpki_cache_cmd,
895 "no rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport> preference (1-255)$preference",
896 NO_STR
897 RPKI_OUTPUT_STRING
898 "Remove a cache server\n"
899 "IP address of cache server\n Hostname of cache server\n"
900 "TCP port number\n"
901 "SSH port number\n"
902 "Preference of the cache server\n"
903 "Preference value\n")
904 {
905 struct cache *cache_p = find_cache(preference);
906
907 if (!cache) {
908 vty_out(vty, "Could not find cache %ld\n", preference);
909 return CMD_WARNING;
910 }
911
912 if (rtr_is_running) {
913 if (rtr_mgr_remove_group(rtr_config, preference) == RTR_ERROR) {
914 vty_out(vty, "Could not remove cache %ld", preference);
915 if (listcount(cache_list) == 1)
916 vty_out(vty, " because it is the last cache");
917
918 vty_out(vty, "\n");
919 return CMD_WARNING;
920 }
921 }
922
923 listnode_delete(cache_list, cache_p);
924 free_cache(cache_p);
925
926 return CMD_SUCCESS;
927 }
928
929 DEFUN (show_rpki_prefix_table,
930 show_rpki_prefix_table_cmd,
931 "show rpki prefix-table",
932 SHOW_STR
933 RPKI_OUTPUT_STRING
934 "Show validated prefixes which were received from RPKI Cache\n")
935 {
936 struct listnode *cache_node;
937 struct cache *cache;
938
939 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
940 vty_out(vty, "host: %s port: %s\n",
941 cache->tr_config.tcp_config->host,
942 cache->tr_config.tcp_config->port);
943 }
944 if (is_synchronized())
945 print_prefix_table(vty);
946 else
947 vty_out(vty, "No connection to RPKI cache server.\n");
948
949 return CMD_SUCCESS;
950 }
951
952 DEFUN (show_rpki_cache_server,
953 show_rpki_cache_server_cmd,
954 "show rpki cache-server",
955 SHOW_STR
956 RPKI_OUTPUT_STRING
957 "SHOW configured cache server\n")
958 {
959 struct listnode *cache_node;
960 struct cache *cache;
961
962 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
963 vty_out(vty, "host: %s port: %s\n",
964 cache->tr_config.tcp_config->host,
965 cache->tr_config.tcp_config->port);
966 }
967
968 return CMD_SUCCESS;
969 }
970
971 DEFUN (show_rpki_cache_connection,
972 show_rpki_cache_connection_cmd,
973 "show rpki cache-connection",
974 SHOW_STR
975 RPKI_OUTPUT_STRING
976 "Show to which RPKI Cache Servers we have a connection\n")
977 {
978 if (is_synchronized()) {
979 struct listnode *cache_node;
980 struct cache *cache;
981 struct rtr_mgr_group *group = get_connected_group();
982
983 if (!group) {
984 vty_out(vty, "Cannot find a connected group.\n");
985 return CMD_SUCCESS;
986 }
987 vty_out(vty, "Connected to group %d\n", group->preference);
988 for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) {
989 if (cache->preference == group->preference) {
990 struct tr_tcp_config *tcp_config;
991 #if defined(FOUND_SSH)
992 struct tr_ssh_config *ssh_config;
993 #endif
994
995 switch (cache->type) {
996 case TCP:
997 tcp_config =
998 cache->tr_config.tcp_config;
999 vty_out(vty,
1000 "rpki tcp cache %s %s pref %hhu\n",
1001 tcp_config->host,
1002 tcp_config->port,
1003 cache->preference);
1004 break;
1005
1006 #if defined(FOUND_SSH)
1007 case SSH:
1008 ssh_config =
1009 cache->tr_config.ssh_config;
1010 vty_out(vty,
1011 "rpki ssh cache %s %u pref %hhu\n",
1012 ssh_config->host,
1013 ssh_config->port,
1014 cache->preference);
1015 break;
1016 #endif
1017
1018 default:
1019 break;
1020 }
1021 }
1022 }
1023 } else {
1024 vty_out(vty, "No connection to RPKI cache server.\n");
1025 }
1026
1027 return CMD_SUCCESS;
1028 }
1029
1030 DEFUN_NOSH (rpki_exit,
1031 rpki_exit_cmd,
1032 "exit",
1033 "Exit rpki configuration and restart rpki session\n")
1034 {
1035 int ret = reset(false);
1036
1037 vty->node = CONFIG_NODE;
1038 return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1039 }
1040
1041 DEFUN_NOSH (rpki_quit,
1042 rpki_quit_cmd,
1043 "quit",
1044 "Exit rpki configuration mode\n")
1045 {
1046 return rpki_exit(self, vty, argc, argv);
1047 }
1048
1049 DEFUN_NOSH (rpki_end,
1050 rpki_end_cmd,
1051 "end",
1052 "End rpki configuration, restart rpki session and change to enable mode.\n")
1053 {
1054 int ret = reset(false);
1055
1056 vty_config_unlock(vty);
1057 vty->node = ENABLE_NODE;
1058 return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1059 }
1060
1061 DEFUN (rpki_reset,
1062 rpki_reset_cmd,
1063 "rpki reset",
1064 RPKI_OUTPUT_STRING
1065 "reset rpki\n")
1066 {
1067 return reset(true) == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
1068 }
1069
1070 DEFUN (debug_rpki,
1071 debug_rpki_cmd,
1072 "debug rpki",
1073 DEBUG_STR
1074 "Enable debugging for rpki\n")
1075 {
1076 rpki_debug = 1;
1077 return CMD_SUCCESS;
1078 }
1079
1080 DEFUN (no_debug_rpki,
1081 no_debug_rpki_cmd,
1082 "no debug rpki",
1083 NO_STR
1084 DEBUG_STR
1085 "Disable debugging for rpki\n")
1086 {
1087 rpki_debug = 0;
1088 return CMD_SUCCESS;
1089 }
1090
1091 DEFUN (match_rpki,
1092 match_rpki_cmd,
1093 "match rpki <valid|invalid|notfound>",
1094 MATCH_STR
1095 RPKI_OUTPUT_STRING
1096 "Valid prefix\n"
1097 "Invalid prefix\n"
1098 "Prefix not found\n")
1099 {
1100 VTY_DECLVAR_CONTEXT(route_map_index, index);
1101 int ret;
1102
1103 ret = route_map_add_match(index, "rpki", argv[2]->arg);
1104 if (ret) {
1105 switch (ret) {
1106 case RMAP_RULE_MISSING:
1107 vty_out(vty, "%% BGP Can't find rule.\n");
1108 return CMD_WARNING_CONFIG_FAILED;
1109 case RMAP_COMPILE_ERROR:
1110 vty_out(vty, "%% BGP Argument is malformed.\n");
1111 return CMD_WARNING_CONFIG_FAILED;
1112 }
1113 }
1114 return CMD_SUCCESS;
1115 }
1116
1117 DEFUN (no_match_rpki,
1118 no_match_rpki_cmd,
1119 "no match rpki <valid|invalid|notfound>",
1120 NO_STR
1121 MATCH_STR
1122 RPKI_OUTPUT_STRING
1123 "Valid prefix\n"
1124 "Invalid prefix\n"
1125 "Prefix not found\n")
1126 {
1127 VTY_DECLVAR_CONTEXT(route_map_index, index);
1128 int ret;
1129
1130 ret = route_map_delete_match(index, "rpki", argv[3]->arg);
1131 if (ret) {
1132 switch (ret) {
1133 case RMAP_RULE_MISSING:
1134 vty_out(vty, "%% BGP Can't find rule.\n");
1135 break;
1136 case RMAP_COMPILE_ERROR:
1137 vty_out(vty, "%% BGP Argument is malformed.\n");
1138 break;
1139 }
1140 return CMD_WARNING_CONFIG_FAILED;
1141 }
1142
1143 return CMD_SUCCESS;
1144 }
1145
1146 static void overwrite_exit_commands(void)
1147 {
1148 unsigned int i;
1149 vector cmd_vector = rpki_node.cmd_vector;
1150
1151 for (i = 0; i < cmd_vector->active; ++i) {
1152 struct cmd_element *cmd = vector_lookup(cmd_vector, i);
1153
1154 if (strcmp(cmd->string, "exit") == 0
1155 || strcmp(cmd->string, "quit") == 0
1156 || strcmp(cmd->string, "end") == 0) {
1157 uninstall_element(RPKI_NODE, cmd);
1158 }
1159 }
1160
1161 install_element(RPKI_NODE, &rpki_exit_cmd);
1162 install_element(RPKI_NODE, &rpki_quit_cmd);
1163 install_element(RPKI_NODE, &rpki_end_cmd);
1164 }
1165
1166 static void install_cli_commands(void)
1167 {
1168 // TODO: make config write work
1169 install_node(&rpki_node, &config_write);
1170 install_default(RPKI_NODE);
1171 overwrite_exit_commands();
1172 install_element(CONFIG_NODE, &rpki_cmd);
1173 install_element(VIEW_NODE, &rpki_cmd);
1174
1175 install_element(ENABLE_NODE, &bgp_rpki_start_cmd);
1176 install_element(ENABLE_NODE, &bgp_rpki_stop_cmd);
1177
1178 /* Install rpki reset command */
1179 install_element(RPKI_NODE, &rpki_reset_cmd);
1180
1181 /* Install rpki polling period commands */
1182 install_element(RPKI_NODE, &rpki_polling_period_cmd);
1183 install_element(RPKI_NODE, &no_rpki_polling_period_cmd);
1184
1185 /* Install rpki expire interval commands */
1186 install_element(RPKI_NODE, &rpki_expire_interval_cmd);
1187 install_element(RPKI_NODE, &no_rpki_expire_interval_cmd);
1188
1189 /* Install rpki retry interval commands */
1190 install_element(RPKI_NODE, &rpki_retry_interval_cmd);
1191 install_element(RPKI_NODE, &no_rpki_retry_interval_cmd);
1192
1193 /* Install rpki timeout commands */
1194 install_element(RPKI_NODE, &rpki_timeout_cmd);
1195 install_element(RPKI_NODE, &no_rpki_timeout_cmd);
1196
1197 /* Install rpki synchronisation timeout commands */
1198 install_element(RPKI_NODE, &rpki_synchronisation_timeout_cmd);
1199 install_element(RPKI_NODE, &no_rpki_synchronisation_timeout_cmd);
1200
1201 /* Install rpki cache commands */
1202 install_element(RPKI_NODE, &rpki_cache_cmd);
1203 install_element(RPKI_NODE, &no_rpki_cache_cmd);
1204
1205 /* Install show commands */
1206 install_element(ENABLE_NODE, &show_rpki_prefix_table_cmd);
1207 install_element(ENABLE_NODE, &show_rpki_cache_connection_cmd);
1208 install_element(ENABLE_NODE, &show_rpki_cache_server_cmd);
1209
1210 /* Install debug commands */
1211 install_element(CONFIG_NODE, &debug_rpki_cmd);
1212 install_element(ENABLE_NODE, &debug_rpki_cmd);
1213 install_element(CONFIG_NODE, &no_debug_rpki_cmd);
1214 install_element(ENABLE_NODE, &no_debug_rpki_cmd);
1215
1216 /* Install route match */
1217 route_map_install_match(&route_match_rpki_cmd);
1218 install_element(RMAP_NODE, &match_rpki_cmd);
1219 install_element(RMAP_NODE, &no_match_rpki_cmd);
1220 }
1221
1222 FRR_MODULE_SETUP(.name = "bgpd_rpki", .version = "0.3.6",
1223 .description = "Enable RPKI support for FRR.",
1224 .init = bgp_rpki_module_init)