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