]> git.ipfire.org Git - thirdparty/bird.git/blob - proto/rpki/rpki.c
36097dc515fa7ac295c2fec40dbeea23fecc5caf
[thirdparty/bird.git] / proto / rpki / rpki.c
1 /*
2 * BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
3 *
4 * (c) 2015 CZ.NIC
5 * (c) 2015 Pavel Tvrdik <pawel.tvrdik@gmail.com>
6 *
7 * Using RTRlib: http://rpki.realmv6.org/
8 *
9 * Can be freely distributed and used under the terms of the GNU GPL.
10 */
11
12 /**
13 * DOC: RPKI To Router (RPKI-RTR)
14 *
15 * The RPKI-RTR protocol is implemented in several files: |rpki.c| containing
16 * the routes handling, protocol logic, timer events, cache connection,
17 * reconfiguration, configuration and protocol glue with BIRD core, |packets.c|
18 * containing the RPKI packets handling and finally all transports files:
19 * |transport.c|, |tcp_transport.c| and |ssh_transport.c|.
20 *
21 * The |transport.c| is a middle layer and interface for each specific
22 * transport. Transport is a way how to wrap a communication with a cache
23 * server. There is supported an unprotected TCP transport and an encrypted
24 * SSHv2 transport. The SSH transport requires LibSSH library. LibSSH is
25 * loading dynamically using |dlopen()| function. SSH support is integrated in
26 * |sysdep/unix/io.c|. Each transport must implement an initialization
27 * function, an open function and a socket identification function. That's all.
28 *
29 * This implementation is based on the RTRlib (http://rpki.realmv6.org/). The
30 * BIRD takes over files |packets.c|, |rtr.c| (inside |rpki.c|), |transport.c|,
31 * |tcp_transport.c| and |ssh_transport.c| from RTRlib.
32 *
33 * A RPKI-RTR connection is described by a structure &rpki_cache. The main
34 * logic is located in |rpki_cache_change_state()| function. There is a state
35 * machine. The standard starting state flow looks like |Down| ~> |Connecting|
36 * ~> |Sync-Start| ~> |Sync-Running| ~> |Established| and then the last three
37 * states are periodically repeated.
38 *
39 * |Connecting| state establishes the transport connection. The state from a
40 * call |rpki_cache_change_state(CONNECTING)| to a call |rpki_connected_hook()|
41 *
42 * |Sync-Start| state starts with sending |Reset Query| or |Serial Query| and
43 * then waits for |Cache Response|. The state from |rpki_connected_hook()| to
44 * |rpki_handle_cache_response_pdu()|
45 *
46 * During |Sync-Running| BIRD receives data with IPv4/IPv6 Prefixes from cache
47 * server. The state starts from |rpki_handle_cache_response_pdu()| and ends
48 * in |rpki_handle_end_of_data_pdu()|.
49 *
50 * |Established| state means that BIRD has synced all data with cache server.
51 * Schedules a refresh timer event that invokes |Sync-Start|. Schedules Expire
52 * timer event and stops a Retry timer event.
53 *
54 * |Transport Error| state means that we have some troubles with a network
55 * connection. We cannot connect to a cache server or we wait too long for some
56 * expected PDU for received - |Cache Response| or |End of Data|. It closes
57 * current connection and schedules a Retry timer event.
58 *
59 * |Fatal Protocol Error| is occurred e.g. by received a bad Session ID. We
60 * restart a protocol, so all ROAs are flushed immediately.
61 *
62 * The RPKI-RTR protocol (RFC 6810 bis) defines configurable refresh, retry and
63 * expire intervals. For maintaining a connection are used timer events that
64 * are scheduled by |rpki_schedule_next_refresh()|,
65 * |rpki_schedule_next_retry()| and |rpki_schedule_next_expire()| functions.
66 *
67 * A Refresh timer event performs a sync of |Established| connection. So it
68 * shifts state to |Sync-Start|. If at the beginning of second call of a
69 * refresh event is connection in |Sync-Start| state then we didn't receive a
70 * |Cache Response| from a cache server and we invoke |Transport Error| state.
71 *
72 * A Retry timer event attempts to connect cache server. It is activated after
73 * |Transport Error| state and terminated by reaching |Established| state.
74 * If cache connection is still connecting to the cache server at the beginning
75 * of an event call then the Retry timer event invokes |Transport Error| state.
76 *
77 * An Expire timer event checks expiration of ROAs. If a last successful sync
78 * was more ago than the expire interval then the Expire timer event invokes a
79 * protocol restart thereby removes all ROAs learned from that cache server and
80 * continue trying to connect to cache server. The Expire event is activated
81 * by initial successful loading of ROAs, receiving End of Data PDU.
82 *
83 * A reconfiguration of cache connection works well without restarting when we
84 * change only intervals values.
85 *
86 * Supported standards:
87 * - RFC 6810 - main RPKI-RTR standard
88 * - RFC 6810 bis - an explicit timing parameters and protocol version number negotiation
89 */
90
91 #include <stdlib.h>
92 #include <netdb.h>
93
94 #undef LOCAL_DEBUG
95
96 #include "rpki.h"
97 #include "lib/string.h"
98 #include "nest/cli.h"
99
100 /* Return values for reconfiguration functions */
101 #define NEED_RESTART 0
102 #define SUCCESSFUL_RECONF 1
103
104 static int rpki_open_connection(struct rpki_cache *cache);
105 static void rpki_close_connection(struct rpki_cache *cache);
106 static void rpki_schedule_next_refresh(struct rpki_cache *cache);
107 static void rpki_schedule_next_retry(struct rpki_cache *cache);
108 static void rpki_schedule_next_expire_check(struct rpki_cache *cache);
109 static void rpki_stop_refresh_timer_event(struct rpki_cache *cache);
110 static void rpki_stop_retry_timer_event(struct rpki_cache *cache);
111 static void rpki_stop_expire_timer_event(struct rpki_cache *cache);
112
113
114 /*
115 * Routes handling
116 */
117
118 void
119 rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
120 {
121 struct rpki_proto *p = cache->p;
122
123 rta a0 = {
124 .src = p->p.main_source,
125 .source = RTS_RPKI,
126 .scope = SCOPE_UNIVERSE,
127 .dest = RTD_NONE,
128 };
129
130 rta *a = rta_lookup(&a0);
131 rte *e = rte_get_temp(a);
132
133 e->pflags = 0;
134
135 rte_update2(channel, &pfxr->n, e, a0.src);
136 }
137
138 void
139 rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
140 {
141 struct rpki_proto *p = cache->p;
142 rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
143 }
144
145
146 /*
147 * RPKI Protocol Logic
148 */
149
150 static const char *str_cache_states[] = {
151 [RPKI_CS_CONNECTING] = "Connecting",
152 [RPKI_CS_ESTABLISHED] = "Established",
153 [RPKI_CS_RESET] = "Reseting",
154 [RPKI_CS_SYNC_START] = "Sync-Start",
155 [RPKI_CS_SYNC_RUNNING] = "Sync-Running",
156 [RPKI_CS_FAST_RECONNECT] = "Fast-Reconnect",
157 [RPKI_CS_NO_INCR_UPDATE_AVAIL]= "No-Increment-Update-Available",
158 [RPKI_CS_ERROR_NO_DATA_AVAIL] = "Cache-Error-No-Data-Available",
159 [RPKI_CS_ERROR_FATAL] = "Fatal-Protocol-Error",
160 [RPKI_CS_ERROR_TRANSPORT] = "Transport-Error",
161 [RPKI_CS_SHUTDOWN] = "Down"
162 };
163
164 /**
165 * rpki_cache_state_to_str - give a text representation of cache state
166 * @state: A cache state
167 *
168 * The function converts logic cache state into string.
169 */
170 const char *
171 rpki_cache_state_to_str(enum rpki_cache_state state)
172 {
173 return str_cache_states[state];
174 }
175
176 /**
177 * rpki_start_cache - connect to a cache server
178 * @cache: RPKI connection instance
179 *
180 * This function is a high level method to kick up a connection to a cache server.
181 */
182 static void
183 rpki_start_cache(struct rpki_cache *cache)
184 {
185 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
186 }
187
188 /**
189 * rpki_force_restart_proto - force shutdown and start protocol again
190 * @p: RPKI protocol instance
191 *
192 * This function calls shutdown and frees all protocol resources as well.
193 * After calling this function should be no operations with protocol data,
194 * they could be freed already.
195 */
196 static void
197 rpki_force_restart_proto(struct rpki_proto *p)
198 {
199 if (p->cache)
200 {
201 CACHE_DBG(p->cache, "Connection object destroying");
202 }
203
204 /* Sign as freed */
205 p->cache = NULL;
206
207 proto_notify_state(&p->p, PS_DOWN);
208 }
209
210 /**
211 * rpki_cache_change_state - check and change cache state
212 * @cache: RPKI cache instance
213 * @new_state: suggested new state
214 *
215 * This function makes transitions between internal states.
216 * It represents the core of logic management of RPKI protocol.
217 * Cannot transit into the same state as cache is in already.
218 */
219 void
220 rpki_cache_change_state(struct rpki_cache *cache, const enum rpki_cache_state new_state)
221 {
222 const enum rpki_cache_state old_state = cache->state;
223
224 if (old_state == new_state)
225 return;
226
227 cache->state = new_state;
228 CACHE_TRACE(D_EVENTS, cache, "Changing from %s to %s state", rpki_cache_state_to_str(old_state), rpki_cache_state_to_str(new_state));
229
230 switch (new_state)
231 {
232 case RPKI_CS_CONNECTING:
233 {
234 sock *sk = cache->tr_sock->sk;
235
236 if (sk == NULL || sk->fd < 0)
237 rpki_open_connection(cache);
238 else
239 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
240
241 rpki_schedule_next_retry(cache);
242 break;
243 }
244
245 case RPKI_CS_ESTABLISHED:
246 rpki_schedule_next_refresh(cache);
247 rpki_schedule_next_expire_check(cache);
248 rpki_stop_retry_timer_event(cache);
249 break;
250
251 case RPKI_CS_RESET:
252 /* Resetting cache connection. */
253 cache->request_session_id = 1;
254 cache->serial_num = 0;
255 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
256 break;
257
258 case RPKI_CS_SYNC_START:
259 /* Requesting for receive ROAs from a cache server. */
260 if (cache->request_session_id)
261 {
262 /* Send request for Session ID */
263 if (rpki_send_reset_query(cache) != RPKI_SUCCESS)
264 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
265 }
266 else
267 {
268 /* We have already a session_id. So send a Serial Query and start an incremental sync */
269 if (rpki_send_serial_query(cache) != RPKI_SUCCESS)
270 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
271 }
272 break;
273
274 case RPKI_CS_SYNC_RUNNING:
275 /* The state between Cache Response and End of Data. Only waiting for
276 * receiving all IP Prefix PDUs and finally a End of Data PDU. */
277 break;
278
279 case RPKI_CS_NO_INCR_UPDATE_AVAIL:
280 /* Server was unable to answer the last Serial Query and sent Cache Reset. */
281 rpki_cache_change_state(cache, RPKI_CS_RESET);
282 break;
283
284 case RPKI_CS_ERROR_NO_DATA_AVAIL:
285 /* No validation records are available on the cache server. */
286 rpki_cache_change_state(cache, RPKI_CS_RESET);
287 break;
288
289 case RPKI_CS_ERROR_FATAL:
290 /* Fatal protocol error occurred. */
291 rpki_force_restart_proto(cache->p);
292 break;
293
294 case RPKI_CS_ERROR_TRANSPORT:
295 /* Error on the transport socket occurred. */
296 rpki_close_connection(cache);
297 rpki_schedule_next_retry(cache);
298 rpki_stop_refresh_timer_event(cache);
299 break;
300
301 case RPKI_CS_FAST_RECONNECT:
302 /* Reconnect without any waiting period */
303 rpki_close_connection(cache);
304 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
305 break;
306
307 case RPKI_CS_SHUTDOWN:
308 bug("This isn't never really called.");
309 break;
310 };
311 }
312
313
314 /*
315 * RPKI Timer Events
316 */
317
318 static void
319 rpki_schedule_next_refresh(struct rpki_cache *cache)
320 {
321 btime t = cache->refresh_interval S;
322
323 CACHE_DBG(cache, "after %t s", t);
324 tm_start(cache->refresh_timer, t);
325 }
326
327 static void
328 rpki_schedule_next_retry(struct rpki_cache *cache)
329 {
330 btime t = cache->retry_interval S;
331
332 CACHE_DBG(cache, "after %t s", t);
333 tm_start(cache->retry_timer, t);
334 }
335
336 static void
337 rpki_schedule_next_expire_check(struct rpki_cache *cache)
338 {
339 /* A minimum time to wait is 1 second */
340 btime t = cache->last_update + cache->expire_interval S - current_time();
341 t = MAX(t, 1 S);
342
343 CACHE_DBG(cache, "after %t s", t);
344 tm_start(cache->expire_timer, t);
345 }
346
347 static void
348 rpki_stop_refresh_timer_event(struct rpki_cache *cache)
349 {
350 CACHE_DBG(cache, "Stop");
351 tm_stop(cache->refresh_timer);
352 }
353
354 static void
355 rpki_stop_retry_timer_event(struct rpki_cache *cache)
356 {
357 CACHE_DBG(cache, "Stop");
358 tm_stop(cache->retry_timer);
359 }
360
361 static void UNUSED
362 rpki_stop_expire_timer_event(struct rpki_cache *cache)
363 {
364 CACHE_DBG(cache, "Stop");
365 tm_stop(cache->expire_timer);
366 }
367
368 static int
369 rpki_do_we_recv_prefix_pdu_in_last_seconds(struct rpki_cache *cache)
370 {
371 if (!cache->last_rx_prefix)
372 return 0;
373
374 return ((current_time() - cache->last_rx_prefix) <= 2 S);
375 }
376
377 /**
378 * rpki_refresh_hook - control a scheduling of downloading data from cache server
379 * @tm: refresh timer with cache connection instance in data
380 *
381 * This function is periodically called during &ESTABLISHED or &SYNC* state
382 * cache connection. The first refresh schedule is invoked after receiving a
383 * |End of Data| PDU and has run by some &ERROR is occurred.
384 */
385 static void
386 rpki_refresh_hook(timer *tm)
387 {
388 struct rpki_cache *cache = tm->data;
389
390 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
391
392 switch (cache->state)
393 {
394 case RPKI_CS_ESTABLISHED:
395 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
396 break;
397
398 case RPKI_CS_SYNC_START:
399 /* We sent Serial/Reset Query in last refresh hook call
400 * and didn't receive Cache Response yet. It is probably
401 * troubles with network. */
402 case RPKI_CS_SYNC_RUNNING:
403 /* We sent Serial/Reset Query in last refresh hook call
404 * and we got Cache Response but didn't get End-Of-Data yet.
405 * It could be a trouble with network or only too long synchronization. */
406 if (!rpki_do_we_recv_prefix_pdu_in_last_seconds(cache))
407 {
408 CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than refresh interval %us, resetting connection", cache->refresh_interval);
409 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
410 }
411 break;
412
413 default:
414 break;
415 }
416
417 if (cache->state != RPKI_CS_SHUTDOWN && cache->state != RPKI_CS_ERROR_TRANSPORT)
418 rpki_schedule_next_refresh(cache);
419 else
420 rpki_stop_refresh_timer_event(cache);
421 }
422
423 /**
424 * rpki_retry_hook - control a scheduling of retrying connection to cache server
425 * @tm: retry timer with cache connection instance in data
426 *
427 * This function is periodically called during &ERROR* state cache connection.
428 * The first retry schedule is invoked after any &ERROR* state occurred and
429 * ends by reaching of &ESTABLISHED state again.
430 */
431 static void
432 rpki_retry_hook(timer *tm)
433 {
434 struct rpki_cache *cache = tm->data;
435
436 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
437
438 switch (cache->state)
439 {
440 case RPKI_CS_ESTABLISHED:
441 case RPKI_CS_SHUTDOWN:
442 break;
443
444 case RPKI_CS_CONNECTING:
445 case RPKI_CS_SYNC_START:
446 case RPKI_CS_SYNC_RUNNING:
447 if (!rpki_do_we_recv_prefix_pdu_in_last_seconds(cache))
448 {
449 /* We tried to establish a connection in last retry hook call and haven't done
450 * yet. It looks like troubles with network. We are aggressive here. */
451 CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than retry interval %us, resetting connection.", cache->retry_interval);
452 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
453 }
454 break;
455
456 default:
457 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
458 break;
459 }
460
461 if (cache->state != RPKI_CS_ESTABLISHED)
462 rpki_schedule_next_retry(cache);
463 else
464 rpki_stop_retry_timer_event(cache);
465 }
466
467 /**
468 * rpki_expire_hook - control a expiration of ROA entries
469 * @tm: expire timer with cache connection instance in data
470 *
471 * This function is scheduled after received a |End of Data| PDU.
472 * A waiting interval is calculated dynamically by last update.
473 * If we reach an expiration time then we invoke a restarting
474 * of the protocol.
475 */
476 static void
477 rpki_expire_hook(timer *tm)
478 {
479 struct rpki_cache *cache = tm->data;
480
481 if (!cache->last_update)
482 return;
483
484 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
485
486 btime t = cache->last_update + cache->expire_interval S - current_time();
487 if (t <= 0)
488 {
489 CACHE_TRACE(D_EVENTS, cache, "All ROAs expired");
490 rpki_force_restart_proto(cache->p);
491 }
492 else
493 {
494 CACHE_DBG(cache, "Remains %t seconds to become ROAs obsolete", t);
495 rpki_schedule_next_expire_check(cache);
496 }
497 }
498
499 /**
500 * rpki_check_refresh_interval - check validity of refresh interval value
501 * @seconds: suggested value
502 *
503 * This function validates value and should return |NULL|.
504 * If the check doesn't pass then returns error message.
505 */
506 const char *
507 rpki_check_refresh_interval(uint seconds)
508 {
509 if (seconds < 1)
510 return "Minimum allowed refresh interval is 1 second";
511 if (seconds > 86400)
512 return "Maximum allowed refresh interval is 86400 seconds";
513 return NULL;
514 }
515
516 /**
517 * rpki_check_retry_interval - check validity of retry interval value
518 * @seconds: suggested value
519 *
520 * This function validates value and should return |NULL|.
521 * If the check doesn't pass then returns error message.
522 */
523 const char *
524 rpki_check_retry_interval(uint seconds)
525 {
526 if (seconds < 1)
527 return "Minimum allowed retry interval is 1 second";
528 if (seconds > 7200)
529 return "Maximum allowed retry interval is 7200 seconds";
530 return NULL;
531 }
532
533 /**
534 * rpki_check_expire_interval - check validity of expire interval value
535 * @seconds: suggested value
536 *
537 * This function validates value and should return |NULL|.
538 * If the check doesn't pass then returns error message.
539 */
540 const char *
541 rpki_check_expire_interval(uint seconds)
542 {
543 if (seconds < 600)
544 return "Minimum allowed expire interval is 600 seconds";
545 if (seconds > 172800)
546 return "Maximum allowed expire interval is 172800 seconds";
547 return NULL;
548 }
549
550
551 /*
552 * RPKI Cache
553 */
554
555 static struct rpki_cache *
556 rpki_init_cache(struct rpki_proto *p, struct rpki_config *cf)
557 {
558 pool *pool = rp_new(p->p.pool, cf->hostname);
559
560 struct rpki_cache *cache = mb_allocz(pool, sizeof(struct rpki_cache));
561
562 cache->pool = pool;
563 cache->p = p;
564
565 cache->state = RPKI_CS_SHUTDOWN;
566 cache->request_session_id = 1;
567 cache->version = RPKI_MAX_VERSION;
568
569 cache->refresh_interval = cf->refresh_interval;
570 cache->retry_interval = cf->retry_interval;
571 cache->expire_interval = cf->expire_interval;
572 cache->refresh_timer = tm_new_init(pool, &rpki_refresh_hook, cache, 0, 0);
573 cache->retry_timer = tm_new_init(pool, &rpki_retry_hook, cache, 0, 0);
574 cache->expire_timer = tm_new_init(pool, &rpki_expire_hook, cache, 0, 0);
575
576 cache->tr_sock = mb_allocz(pool, sizeof(struct rpki_tr_sock));
577 cache->tr_sock->cache = cache;
578
579 switch (cf->tr_config.type)
580 {
581 case RPKI_TR_TCP: rpki_tr_tcp_init(cache->tr_sock); break;
582 case RPKI_TR_SSH: rpki_tr_ssh_init(cache->tr_sock); break;
583 };
584
585 CACHE_DBG(cache, "Connection object created");
586
587 return cache;
588 }
589
590 /**
591 * rpki_get_cache_ident - give a text representation of cache server name
592 * @cache: RPKI connection instance
593 *
594 * The function converts cache connection into string.
595 */
596 const char *
597 rpki_get_cache_ident(struct rpki_cache *cache)
598 {
599 return rpki_tr_ident(cache->tr_sock);
600 }
601
602 static int
603 rpki_open_connection(struct rpki_cache *cache)
604 {
605 CACHE_TRACE(D_EVENTS, cache, "Opening a connection");
606
607 if (rpki_tr_open(cache->tr_sock) == RPKI_TR_ERROR)
608 {
609 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
610 return RPKI_TR_ERROR;
611 }
612
613 return RPKI_TR_SUCCESS;
614 }
615
616 static void
617 rpki_close_connection(struct rpki_cache *cache)
618 {
619 CACHE_TRACE(D_EVENTS, cache, "Closing a connection");
620 rpki_tr_close(cache->tr_sock);
621 proto_notify_state(&cache->p->p, PS_START);
622 }
623
624 static int
625 rpki_shutdown(struct proto *P)
626 {
627 struct rpki_proto *p = (void *) P;
628
629 rpki_force_restart_proto(p);
630
631 /* Protocol memory pool will be automatically freed */
632 return PS_DOWN;
633 }
634
635
636 /*
637 * RPKI Reconfiguration
638 */
639
640 static int
641 rpki_try_fast_reconnect(struct rpki_cache *cache)
642 {
643 if (cache->state == RPKI_CS_ESTABLISHED)
644 {
645 rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
646 return SUCCESSFUL_RECONF;
647 }
648
649 return NEED_RESTART;
650 }
651
652 /**
653 * rpki_reconfigure_cache - a cache reconfiguration
654 * @p: RPKI protocol instance
655 * @cache: a cache connection
656 * @new: new RPKI configuration
657 * @old: old RPKI configuration
658 *
659 * This function reconfigures existing single cache server connection with new
660 * existing configuration. Generally, a change of time intervals could be
661 * reconfigured without restarting and all others changes requires a restart of
662 * protocol. Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
663 */
664 static int
665 rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, struct rpki_config *new, struct rpki_config *old)
666 {
667 u8 try_fast_reconnect = 0;
668
669 if (strcmp(old->hostname, new->hostname) != 0)
670 {
671 CACHE_TRACE(D_EVENTS, cache, "Cache server address changed to %s", new->hostname);
672 return NEED_RESTART;
673 }
674
675 if (old->port != new->port)
676 {
677 CACHE_TRACE(D_EVENTS, cache, "Cache server port changed to %u", new->port);
678 return NEED_RESTART;
679 }
680
681 if (old->tr_config.type != new->tr_config.type)
682 {
683 CACHE_TRACE(D_EVENTS, cache, "Transport type changed");
684 return NEED_RESTART;
685 }
686 else if (new->tr_config.type == RPKI_TR_SSH)
687 {
688 struct rpki_tr_ssh_config *ssh_old = (void *) old->tr_config.spec;
689 struct rpki_tr_ssh_config *ssh_new = (void *) new->tr_config.spec;
690 if ((strcmp(ssh_old->bird_private_key, ssh_new->bird_private_key) != 0) ||
691 (strcmp(ssh_old->cache_public_key, ssh_new->cache_public_key) != 0) ||
692 (strcmp(ssh_old->user, ssh_new->user) != 0))
693 {
694 CACHE_TRACE(D_EVENTS, cache, "Settings of SSH transport configuration changed");
695 try_fast_reconnect = 1;
696 }
697 }
698
699 #define TEST_INTERVAL(name, Name) \
700 if (cache->name##_interval != new->name##_interval || \
701 old->keep_##name##_interval != new->keep_##name##_interval) \
702 { \
703 cache->name##_interval = new->name##_interval; \
704 CACHE_TRACE(D_EVENTS, cache, #Name " interval changed to %u seconds %s", cache->name##_interval, (new->keep_##name##_interval ? "and keep it" : "")); \
705 try_fast_reconnect = 1; \
706 }
707 TEST_INTERVAL(refresh, Refresh);
708 TEST_INTERVAL(retry, Retry);
709 TEST_INTERVAL(expire, Expire);
710 #undef TEST_INTERVAL
711
712 if (try_fast_reconnect)
713 return rpki_try_fast_reconnect(cache);
714
715 return SUCCESSFUL_RECONF;
716 }
717
718 /**
719 * rpki_reconfigure - a protocol reconfiguration hook
720 * @P: a protocol instance
721 * @CF: a new protocol configuration
722 *
723 * This function reconfigures whole protocol.
724 * It sets new protocol configuration into a protocol structure.
725 * Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
726 */
727 static int
728 rpki_reconfigure(struct proto *P, struct proto_config *CF)
729 {
730 struct rpki_proto *p = (void *) P;
731 struct rpki_config *new = (void *) CF;
732 struct rpki_config *old = (void *) p->p.cf;
733 struct rpki_cache *cache = p->cache;
734
735 if (!proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4)) ||
736 !proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6)))
737 return NEED_RESTART;
738
739 if (rpki_reconfigure_cache(p, cache, new, old) != SUCCESSFUL_RECONF)
740 return NEED_RESTART;
741
742 return SUCCESSFUL_RECONF;
743 }
744
745
746 /*
747 * RPKI Protocol Glue
748 */
749
750 static struct proto *
751 rpki_init(struct proto_config *CF)
752 {
753 struct proto *P = proto_new(CF);
754 struct rpki_proto *p = (void *) P;
755
756 proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4));
757 proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6));
758
759 return P;
760 }
761
762 static int
763 rpki_start(struct proto *P)
764 {
765 struct rpki_proto *p = (void *) P;
766 struct rpki_config *cf = (void *) P->cf;
767
768 p->cache = rpki_init_cache(p, cf);
769 rpki_start_cache(p->cache);
770
771 return PS_START;
772 }
773
774 static void
775 rpki_get_status(struct proto *P, byte *buf)
776 {
777 struct rpki_proto *p = (struct rpki_proto *) P;
778
779 if (P->proto_state == PS_DOWN)
780 {
781 *buf = 0;
782 return;
783 }
784
785 if (p->cache)
786 bsprintf(buf, "%s", rpki_cache_state_to_str(p->cache->state));
787 else
788 bsprintf(buf, "No cache server configured");
789 }
790
791 static void
792 rpki_show_proto_info_timer(const char *name, uint num, timer *t)
793 {
794 if (tm_active(t))
795 cli_msg(-1006, " %-16s: %t/%u", name, tm_remains(t), num);
796 else
797 cli_msg(-1006, " %-16s: ---", name);
798 }
799
800 static void
801 rpki_show_proto_info(struct proto *P)
802 {
803 struct rpki_proto *p = (struct rpki_proto *) P;
804 struct rpki_config *cf = (void *) p->p.cf;
805 struct rpki_cache *cache = p->cache;
806
807 if (P->proto_state == PS_DOWN)
808 return;
809
810 if (cache)
811 {
812 const char *transport_name = "---";
813
814 switch (cf->tr_config.type)
815 {
816 case RPKI_TR_SSH: transport_name = "SSHv2"; break;
817 case RPKI_TR_TCP: transport_name = "Unprotected over TCP"; break;
818 };
819
820 cli_msg(-1006, " Cache server: %s", rpki_get_cache_ident(cache));
821 cli_msg(-1006, " Status: %s", rpki_cache_state_to_str(cache->state));
822 cli_msg(-1006, " Transport: %s", transport_name);
823 cli_msg(-1006, " Protocol version: %u", cache->version);
824
825 if (cache->request_session_id)
826 cli_msg(-1006, " Session ID: ---");
827 else
828 cli_msg(-1006, " Session ID: %u", cache->session_id);
829
830 if (cache->last_update)
831 {
832 cli_msg(-1006, " Serial number: %u", cache->serial_num);
833 cli_msg(-1006, " Last update: before %t s", current_time() - cache->last_update);
834 }
835 else
836 {
837 cli_msg(-1006, " Serial number: ---");
838 cli_msg(-1006, " Last update: ---");
839 }
840
841 rpki_show_proto_info_timer("Refresh timer", cache->refresh_interval, cache->refresh_timer);
842 rpki_show_proto_info_timer("Retry timer", cache->retry_interval, cache->retry_timer);
843 rpki_show_proto_info_timer("Expire timer", cache->expire_interval, cache->expire_timer);
844
845 if (p->roa4_channel)
846 channel_show_info(p->roa4_channel);
847 else
848 cli_msg(-1006, " No roa4 channel");
849
850 if (p->roa6_channel)
851 channel_show_info(p->roa6_channel);
852 else
853 cli_msg(-1006, " No roa6 channel");
854 }
855 }
856
857
858 /*
859 * RPKI Protocol Configuration
860 */
861
862 /**
863 * rpki_check_config - check and complete configuration of RPKI protocol
864 * @cf: RPKI configuration
865 *
866 * This function is called at the end of parsing RPKI protocol configuration.
867 */
868 void
869 rpki_check_config(struct rpki_config *cf)
870 {
871 /* Do not check templates at all */
872 if (cf->c.class == SYM_TEMPLATE)
873 return;
874
875 if (ipa_zero(cf->ip) && cf->hostname == NULL)
876 cf_error("IP address or hostname of cache server must be set");
877
878 /* Set default transport type */
879 if (cf->tr_config.spec == NULL)
880 {
881 cf->tr_config.spec = cfg_allocz(sizeof(struct rpki_tr_tcp_config));
882 cf->tr_config.type = RPKI_TR_TCP;
883 }
884
885 if (cf->port == 0)
886 {
887 /* Set default port numbers */
888 switch (cf->tr_config.type)
889 {
890 case RPKI_TR_SSH:
891 cf->port = RPKI_SSH_PORT;
892 break;
893 default:
894 cf->port = RPKI_TCP_PORT;
895 }
896 }
897 }
898
899 static void
900 rpki_postconfig(struct proto_config *CF)
901 {
902 /* Define default channel */
903 if (EMPTY_LIST(CF->channels))
904 channel_config_new(NULL, net_label[CF->net_type], CF->net_type, CF);
905 }
906
907 static void
908 rpki_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED)
909 {
910 /* FIXME: Should copy transport */
911 }
912
913 struct protocol proto_rpki = {
914 .name = "RPKI",
915 .template = "rpki%d",
916 .class = PROTOCOL_RPKI,
917 .preference = DEF_PREF_RPKI,
918 .proto_size = sizeof(struct rpki_proto),
919 .config_size = sizeof(struct rpki_config),
920 .init = rpki_init,
921 .start = rpki_start,
922 .postconfig = rpki_postconfig,
923 .channel_mask = (NB_ROA4 | NB_ROA6),
924 .show_proto_info = rpki_show_proto_info,
925 .shutdown = rpki_shutdown,
926 .copy_config = rpki_copy_config,
927 .reconfigure = rpki_reconfigure,
928 .get_status = rpki_get_status,
929 };