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