xref: /openbsd/usr.sbin/bgpd/rtr_proto.c (revision eff7ddaf)
1 /*	$OpenBSD: rtr_proto.c,v 1.34 2024/03/22 15:41:34 claudio Exp $ */
2 
3 /*
4  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include <sys/tree.h>
19 #include <errno.h>
20 #include <stdint.h>
21 #include <poll.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "bgpd.h"
28 #include "session.h"
29 #include "log.h"
30 
31 struct rtr_header {
32 	uint8_t		version;
33 	uint8_t		type;
34 	uint16_t	session_id; /* or error code */
35 	uint32_t	length;
36 } __packed;
37 
38 #define RTR_MAX_VERSION		2
39 #define RTR_MAX_LEN		2048
40 #define RTR_DEFAULT_REFRESH	3600
41 #define RTR_DEFAULT_RETRY	600
42 #define RTR_DEFAULT_EXPIRE	7200
43 #define RTR_DEFAULT_ACTIVE	60
44 
45 enum rtr_pdu_type {
46 	SERIAL_NOTIFY = 0,
47 	SERIAL_QUERY,
48 	RESET_QUERY,
49 	CACHE_RESPONSE,
50 	IPV4_PREFIX,
51 	IPV6_PREFIX = 6,
52 	END_OF_DATA = 7,
53 	CACHE_RESET = 8,
54 	ROUTER_KEY = 9,
55 	ERROR_REPORT = 10,
56 	ASPA = 11,
57 };
58 
59 struct rtr_notify {
60 	struct rtr_header	hdr;
61 	uint32_t		serial;
62 } __packed;
63 
64 struct rtr_query {
65 	struct rtr_header	hdr;
66 	uint32_t		serial;
67 } __packed;
68 
69 struct rtr_reset {
70 	struct rtr_header	hdr;
71 } __packed;
72 
73 struct rtr_response {
74 	struct rtr_header	hdr;
75 } __packed;
76 
77 #define FLAG_ANNOUNCE	0x1
78 #define FLAG_MASK	FLAG_ANNOUNCE
79 struct rtr_ipv4 {
80 	struct rtr_header	hdr;
81 	uint8_t			flags;
82 	uint8_t			prefixlen;
83 	uint8_t			maxlen;
84 	uint8_t			zero;
85 	uint32_t		prefix;
86 	uint32_t		asnum;
87 } __packed;
88 
89 struct rtr_ipv6 {
90 	struct rtr_header	hdr;
91 	uint8_t			flags;
92 	uint8_t			prefixlen;
93 	uint8_t			maxlen;
94 	uint8_t			zero;
95 	uint32_t		prefix[4];
96 	uint32_t		asnum;
97 } __packed;
98 
99 struct rtr_routerkey {
100 	struct rtr_header	hdr;
101 	uint8_t			ski[20];
102 	uint32_t		asnum;
103 	/* followed by Subject Public Key Info */
104 } __packed;
105 
106 #define FLAG_AFI_V6	0x1
107 #define FLAG_AFI_MASK	FLAG_AFI_V6
108 struct rtr_aspa {
109 	struct rtr_header	hdr;
110 	uint8_t			flags;
111 	uint8_t			afi_flags;
112 	uint16_t		cnt;
113 	uint32_t		cas;
114 	/* array of spas with cnt elements follows */
115 } __packed;
116 
117 struct rtr_endofdata {
118 	struct rtr_header	hdr;
119 	uint32_t		serial;
120 	uint32_t		refresh;
121 	uint32_t		retry;
122 	uint32_t		expire;
123 } __packed;
124 
125 struct rtr_endofdata_v0 {
126 	struct rtr_header	hdr;
127 	uint32_t		serial;
128 } __packed;
129 
130 enum rtr_event {
131 	RTR_EVNT_START,
132 	RTR_EVNT_CON_OPEN,
133 	RTR_EVNT_CON_CLOSE,
134 	RTR_EVNT_TIMER_REFRESH,
135 	RTR_EVNT_TIMER_RETRY,
136 	RTR_EVNT_TIMER_EXPIRE,
137 	RTR_EVNT_TIMER_ACTIVE,
138 	RTR_EVNT_SEND_ERROR,
139 	RTR_EVNT_SERIAL_NOTIFY,
140 	RTR_EVNT_CACHE_RESPONSE,
141 	RTR_EVNT_END_OF_DATA,
142 	RTR_EVNT_CACHE_RESET,
143 	RTR_EVNT_NO_DATA,
144 	RTR_EVNT_RESET_AND_CLOSE,
145 	RTR_EVNT_UNSUPP_PROTO_VERSION,
146 	RTR_EVNT_NEGOTIATION_DONE,
147 };
148 
149 static const char *rtr_eventnames[] = {
150 	"start",
151 	"connection open",
152 	"connection closed",
153 	"refresh timer expired",
154 	"retry timer expired",
155 	"expire timer expired",
156 	"activity timer expired",
157 	"sent error",
158 	"serial notify received",
159 	"cache response received",
160 	"end of data received",
161 	"cache reset received",
162 	"no data",
163 	"connection closed with reset",
164 	"unsupported protocol version",
165 	"negotiation done",
166 };
167 
168 enum rtr_state {
169 	RTR_STATE_CLOSED,
170 	RTR_STATE_ERROR,
171 	/* sessions with a state below this line will poll for incoming data */
172 	RTR_STATE_ESTABLISHED,
173 	RTR_STATE_EXCHANGE,
174 	RTR_STATE_NEGOTIATION,
175 };
176 
177 static const char *rtr_statenames[] = {
178 	"closed",
179 	"error",
180 	"established",
181 	"exchange",
182 	"negotiation",
183 };
184 
185 struct rtr_session {
186 	TAILQ_ENTRY(rtr_session)	entry;
187 	char				descr[PEER_DESCR_LEN];
188 	struct roa_tree			roa_set;
189 	struct aspa_tree		aspa;
190 	struct aspa_tree		aspa_oldv6;
191 	struct ibuf_read		r;
192 	struct msgbuf			w;
193 	struct timer_head		timers;
194 	uint32_t			id;		/* rtr_config id */
195 	uint32_t			serial;
196 	uint32_t			refresh;
197 	uint32_t			retry;
198 	uint32_t			expire;
199 	uint32_t			active;
200 	int				session_id;
201 	int				fd;
202 	int				active_lock;
203 	enum rtr_state			state;
204 	enum reconf_action		reconf_action;
205 	enum rtr_error			last_sent_error;
206 	enum rtr_error			last_recv_error;
207 	char				last_sent_msg[REASON_LEN];
208 	char				last_recv_msg[REASON_LEN];
209 	uint8_t				version;
210 	uint8_t				prev_version;
211 };
212 
213 TAILQ_HEAD(, rtr_session) rtrs = TAILQ_HEAD_INITIALIZER(rtrs);
214 
215 static void	rtr_fsm(struct rtr_session *, enum rtr_event);
216 
217 static const char *
218 log_rtr(struct rtr_session *rs)
219 {
220 	return rs->descr;
221 }
222 
223 static const char *
224 log_rtr_type(enum rtr_pdu_type type)
225 {
226 	static char buf[20];
227 
228 	switch (type) {
229 	case SERIAL_NOTIFY:
230 		return "serial notify";
231 	case SERIAL_QUERY:
232 		return "serial query";
233 	case RESET_QUERY:
234 		return "reset query";
235 	case CACHE_RESPONSE:
236 		return "cache response";
237 	case IPV4_PREFIX:
238 		return "IPv4 prefix";
239 	case IPV6_PREFIX:
240 		return "IPv6 prefix";
241 	case END_OF_DATA:
242 		return "end of data";
243 	case CACHE_RESET:
244 		return "cache reset";
245 	case ROUTER_KEY:
246 		return "router key";
247 	case ERROR_REPORT:
248 		return "error report";
249 	case ASPA:
250 		return "aspa";
251 	default:
252 		snprintf(buf, sizeof(buf), "unknown %u", type);
253 		return buf;
254 	}
255 };
256 
257 static void
258 rtr_reset_cache(struct rtr_session *rs)
259 {
260 	/* reset session */
261 	rs->session_id = -1;
262 	timer_stop(&rs->timers, Timer_Rtr_Expire);
263 	free_roatree(&rs->roa_set);
264 	free_aspatree(&rs->aspa);
265 	free_aspatree(&rs->aspa_oldv6);
266 }
267 
268 static struct ibuf *
269 rtr_newmsg(struct rtr_session *rs, enum rtr_pdu_type type, uint32_t len,
270     uint16_t session_id)
271 {
272 	struct ibuf *buf;
273 	int saved_errno;
274 
275 	if (len > RTR_MAX_LEN) {
276 		errno = ERANGE;
277 		return NULL;
278 	}
279 	len += sizeof(struct rtr_header);
280 	if ((buf = ibuf_open(len)) == NULL)
281 		goto fail;
282 	if (ibuf_add_n8(buf, rs->version) == -1)
283 		goto fail;
284 	if (ibuf_add_n8(buf, type) == -1)
285 		goto fail;
286 	if (ibuf_add_n16(buf, session_id) == -1)
287 		goto fail;
288 	if (ibuf_add_n32(buf, len) == -1)
289 		goto fail;
290 
291 	return buf;
292 
293  fail:
294 	saved_errno = errno;
295 	ibuf_free(buf);
296 	errno = saved_errno;
297 	return NULL;
298 }
299 
300 static void rtr_send_error(struct rtr_session *, struct ibuf *, enum rtr_error,
301     const char *, ...) __attribute__((__format__ (printf, 4, 5)));
302 
303 /*
304  * Try to send an error PDU to cache, put connection into error
305  * state.
306  */
307 static void
308 rtr_send_error(struct rtr_session *rs, struct ibuf *pdu, enum rtr_error err,
309     const char *fmt, ...)
310 {
311 	struct ibuf *buf;
312 	va_list ap;
313 	size_t len = 0, mlen = 0;
314 
315 	rs->last_sent_error = err;
316 	memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg));
317 	if (fmt != NULL) {
318 		va_start(ap, fmt);
319 		vsnprintf(rs->last_sent_msg, sizeof(rs->last_sent_msg),
320 		    fmt, ap);
321 		mlen = strlen(rs->last_sent_msg);
322 		va_end(ap);
323 	}
324 
325 	log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs),
326 	    log_rtr_error(err), mlen > 0 ? ": " : "", rs->last_sent_msg);
327 
328 	if (pdu != NULL) {
329 		ibuf_rewind(pdu);
330 		len = ibuf_size(pdu);
331 	}
332 
333 	buf = rtr_newmsg(rs, ERROR_REPORT, 2 * sizeof(uint32_t) + len + mlen,
334 	    err);
335 	if (buf == NULL)
336 		goto fail;
337 	if (ibuf_add_n32(buf, len) == -1)
338 		goto fail;
339 	if (pdu != NULL) {
340 		if (ibuf_add_ibuf(buf, pdu) == -1)
341 			goto fail;
342 	}
343 	if (ibuf_add_n32(buf, mlen) == -1)
344 		goto fail;
345 	if (ibuf_add(buf, rs->last_sent_msg, mlen) == -1)
346 		goto fail;
347 	ibuf_close(&rs->w, buf);
348 
349 	rtr_fsm(rs, RTR_EVNT_SEND_ERROR);
350 	return;
351 
352  fail:
353 	log_warn("rtr %s: send error report", log_rtr(rs));
354 	ibuf_free(buf);
355 }
356 
357 static void
358 rtr_send_reset_query(struct rtr_session *rs)
359 {
360 	struct ibuf *buf;
361 
362 	buf = rtr_newmsg(rs, RESET_QUERY, 0, 0);
363 	if (buf == NULL)
364 		goto fail;
365 	ibuf_close(&rs->w, buf);
366 	return;
367 
368  fail:
369 	rtr_send_error(rs, NULL, INTERNAL_ERROR,
370 	    "send %s: %s", log_rtr_type(RESET_QUERY), strerror(errno));
371 	ibuf_free(buf);
372 }
373 
374 static void
375 rtr_send_serial_query(struct rtr_session *rs)
376 {
377 	struct ibuf *buf;
378 
379 	buf = rtr_newmsg(rs, SERIAL_QUERY, sizeof(uint32_t), rs->session_id);
380 	if (buf == NULL)
381 		goto fail;
382 	if (ibuf_add_n32(buf, rs->serial) == -1)
383 		goto fail;
384 	ibuf_close(&rs->w, buf);
385 	return;
386 
387  fail:
388 	rtr_send_error(rs, NULL, INTERNAL_ERROR,
389 	    "send %s: %s", log_rtr_type(SERIAL_QUERY), strerror(errno));
390 	ibuf_free(buf);
391 }
392 
393 /*
394  * Check the session_id of the rtr_header to match the expected value.
395  * Returns -1 on failure and 0 on success.
396  */
397 static int
398 rtr_check_session_id(struct rtr_session *rs, uint16_t session_id,
399     struct rtr_header *rh, struct ibuf *pdu)
400 {
401 	if (session_id != ntohs(rh->session_id)) {
402 		rtr_send_error(rs, pdu, CORRUPT_DATA,
403 		    "%s: bad session_id %d (expected %d)",
404 		    log_rtr_type(rh->type), ntohs(rh->session_id), session_id);
405 		return -1;
406 	}
407 	return 0;
408 }
409 
410 /*
411  * Parse the common rtr header (first 8 bytes) including the
412  * included length field.
413  * Returns -1 on failure. On success msgtype and msglen are set
414  * and the function return 0.
415  */
416 static int
417 rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr,
418     size_t *msglen, enum rtr_pdu_type *msgtype)
419 {
420 	struct rtr_header rh;
421 	size_t len;
422 	uint16_t errcode;
423 
424 	if (ibuf_get(hdr, &rh, sizeof(rh)) == -1)
425 		fatal("%s: ibuf_get", __func__);
426 
427 	len = ntohl(rh.length);
428 
429 	if (len > RTR_MAX_LEN) {
430 		rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: too big: %zu bytes",
431 		    log_rtr_type(rh.type), len);
432 		return -1;
433 	}
434 
435 	if (rs->state == RTR_STATE_NEGOTIATION) {
436 		switch (rh.type) {
437 		case CACHE_RESPONSE:
438 		case CACHE_RESET:
439 			/* implicit downgrade */
440 			if (rh.version < rs->version) {
441 				rs->prev_version = rs->version;
442 				rs->version = rh.version;
443 			}
444 			rtr_fsm(rs, RTR_EVNT_NEGOTIATION_DONE);
445 			break;
446 		case ERROR_REPORT:
447 			errcode = ntohs(rh.session_id);
448 			if (errcode == UNSUPP_PROTOCOL_VERS ||
449 			    errcode == NO_DATA_AVAILABLE) {
450 				if (rh.version < rs->version) {
451 					rs->prev_version = rs->version;
452 					rs->version = rh.version;
453 				}
454 			}
455 			break;
456 		case SERIAL_NOTIFY:
457 			/* ignore SERIAL_NOTIFY */
458 			break;
459 		default:
460 			rtr_send_error(rs, hdr, CORRUPT_DATA,
461 			    "%s: out of context", log_rtr_type(rh.type));
462 			return -1;
463 		}
464 	} else if (rh.version != rs->version && rh.type != ERROR_REPORT) {
465 		goto badversion;
466 	}
467 
468 	switch (rh.type) {
469 	case SERIAL_NOTIFY:
470 		if (len != sizeof(struct rtr_notify))
471 			goto badlen;
472 		break;
473 	case CACHE_RESPONSE:
474 		if (len != sizeof(struct rtr_response))
475 			goto badlen;
476 		break;
477 	case IPV4_PREFIX:
478 		if (len != sizeof(struct rtr_ipv4))
479 			goto badlen;
480 		break;
481 	case IPV6_PREFIX:
482 		if (len != sizeof(struct rtr_ipv6))
483 			goto badlen;
484 		break;
485 	case END_OF_DATA:
486 		if (rs->version == 0) {
487 			if (len != sizeof(struct rtr_endofdata_v0))
488 				goto badlen;
489 		} else {
490 			if (len != sizeof(struct rtr_endofdata))
491 				goto badlen;
492 		}
493 		break;
494 	case CACHE_RESET:
495 		if (len != sizeof(struct rtr_reset))
496 			goto badlen;
497 		break;
498 	case ROUTER_KEY:
499 		if (rs->version < 1)
500 			goto badversion;
501 		if (len < sizeof(struct rtr_routerkey))
502 			goto badlen;
503 		break;
504 	case ERROR_REPORT:
505 		if (len < 16)
506 			goto badlen;
507 		break;
508 	case ASPA:
509 		if (rs->version < 2)
510 			goto badversion;
511 		if (len < sizeof(struct rtr_aspa) || (len % 4) != 0)
512 			goto badlen;
513 		break;
514 	default:
515 		rtr_send_error(rs, hdr, UNSUPP_PDU_TYPE, "type %s",
516 		    log_rtr_type(rh.type));
517 		return -1;
518 	}
519 
520 	*msglen = len;
521 	*msgtype = rh.type;
522 
523 	return 0;
524 
525  badlen:
526 	rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: bad length: %zu bytes",
527 	    log_rtr_type(rh.type), len);
528 	return -1;
529 
530  badversion:
531 	rtr_send_error(rs, hdr, UNEXP_PROTOCOL_VERS, "%s: version %d",
532 	    log_rtr_type(rh.type), rh.version);
533 	return -1;
534 }
535 
536 static int
537 rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu)
538 {
539 	struct rtr_notify notify;
540 
541 	/* ignore SERIAL_NOTIFY during startup */
542 	if (rs->state == RTR_STATE_NEGOTIATION)
543 		return 0;
544 
545 	if (ibuf_get(pdu, &notify, sizeof(notify)) == -1)
546 		goto badlen;
547 
548 	/* set session_id if not yet happened */
549 	if (rs->session_id == -1)
550 		rs->session_id = ntohs(notify.hdr.session_id);
551 
552 	if (rtr_check_session_id(rs, rs->session_id, &notify.hdr, pdu) == -1)
553 		return -1;
554 
555 	if (rs->state != RTR_STATE_ESTABLISHED) {
556 		log_warnx("rtr %s: received %s: while in state %s (ignored)",
557 		    log_rtr(rs), log_rtr_type(SERIAL_NOTIFY),
558 		    rtr_statenames[rs->state]);
559 		return 0;
560 	}
561 
562 	rtr_fsm(rs, RTR_EVNT_SERIAL_NOTIFY);
563 	return 0;
564 
565  badlen:
566 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
567 	    log_rtr_type(SERIAL_NOTIFY));
568 	return -1;
569 }
570 
571 static int
572 rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu)
573 {
574 	struct rtr_response resp;
575 
576 	if (ibuf_get(pdu, &resp, sizeof(resp)) == -1)
577 		goto badlen;
578 
579 	/* set session_id if not yet happened */
580 	if (rs->session_id == -1)
581 		rs->session_id = ntohs(resp.hdr.session_id);
582 
583 	if (rtr_check_session_id(rs, rs->session_id, &resp.hdr, pdu) == -1)
584 		return -1;
585 
586 	if (rs->state != RTR_STATE_ESTABLISHED) {
587 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
588 		    log_rtr_type(CACHE_RESPONSE));
589 		return -1;
590 	}
591 
592 	rtr_fsm(rs, RTR_EVNT_CACHE_RESPONSE);
593 	return 0;
594 
595  badlen:
596 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
597 	    log_rtr_type(CACHE_RESPONSE));
598 	return -1;
599 }
600 
601 static int
602 rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu)
603 {
604 	struct rtr_ipv4 ip4;
605 	struct roa *roa;
606 
607 	if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1)
608 		goto badlen;
609 
610 	if (rtr_check_session_id(rs, 0, &ip4.hdr, pdu) == -1)
611 		return -1;
612 
613 	if (rs->state != RTR_STATE_EXCHANGE) {
614 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
615 		    log_rtr_type(IPV4_PREFIX));
616 		return -1;
617 	}
618 
619 	if (ip4.prefixlen > 32 || ip4.maxlen > 32 ||
620 	    ip4.prefixlen > ip4.maxlen) {
621 		rtr_send_error(rs, pdu, CORRUPT_DATA,
622 		    "%s: bad prefixlen / maxlen", log_rtr_type(IPV4_PREFIX));
623 		return -1;
624 	}
625 
626 	if ((roa = calloc(1, sizeof(*roa))) == NULL) {
627 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
628 		return -1;
629 	}
630 	roa->aid = AID_INET;
631 	roa->prefixlen = ip4.prefixlen;
632 	roa->maxlen = ip4.maxlen;
633 	roa->asnum = ntohl(ip4.asnum);
634 	roa->prefix.inet.s_addr = ip4.prefix;
635 
636 	if (ip4.flags & FLAG_ANNOUNCE) {
637 		if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) {
638 			rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s",
639 			    log_rtr_type(IPV4_PREFIX), log_roa(roa));
640 			free(roa);
641 			return -1;
642 		}
643 	} else {
644 		struct roa *r;
645 
646 		r = RB_FIND(roa_tree, &rs->roa_set, roa);
647 		if (r == NULL) {
648 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
649 			    log_rtr_type(IPV4_PREFIX), log_roa(roa));
650 			free(roa);
651 			return -1;
652 		}
653 		RB_REMOVE(roa_tree, &rs->roa_set, r);
654 		free(r);
655 		free(roa);
656 	}
657 
658 	return 0;
659 
660  badlen:
661 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
662 	    log_rtr_type(IPV4_PREFIX));
663 	return -1;
664 }
665 
666 static int
667 rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu)
668 {
669 	struct rtr_ipv6 ip6;
670 	struct roa *roa;
671 
672 	if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1)
673 		goto badlen;
674 
675 	if (rtr_check_session_id(rs, 0, &ip6.hdr, pdu) == -1)
676 		return -1;
677 
678 	if (rs->state != RTR_STATE_EXCHANGE) {
679 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
680 		    log_rtr_type(IPV6_PREFIX));
681 		return -1;
682 	}
683 
684 	if (ip6.prefixlen > 128 || ip6.maxlen > 128 ||
685 	    ip6.prefixlen > ip6.maxlen) {
686 		rtr_send_error(rs, pdu, CORRUPT_DATA,
687 		    "%s: bad prefixlen / maxlen", log_rtr_type(IPV6_PREFIX));
688 		return -1;
689 	}
690 
691 	if ((roa = calloc(1, sizeof(*roa))) == NULL) {
692 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
693 		return -1;
694 	}
695 	roa->aid = AID_INET6;
696 	roa->prefixlen = ip6.prefixlen;
697 	roa->maxlen = ip6.maxlen;
698 	roa->asnum = ntohl(ip6.asnum);
699 	memcpy(&roa->prefix.inet6, ip6.prefix, sizeof(roa->prefix.inet6));
700 
701 	if (ip6.flags & FLAG_ANNOUNCE) {
702 		if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) {
703 			rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s",
704 			    log_rtr_type(IPV6_PREFIX), log_roa(roa));
705 			free(roa);
706 			return -1;
707 		}
708 	} else {
709 		struct roa *r;
710 
711 		r = RB_FIND(roa_tree, &rs->roa_set, roa);
712 		if (r == NULL) {
713 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
714 			    log_rtr_type(IPV6_PREFIX), log_roa(roa));
715 			free(roa);
716 			return -1;
717 		}
718 		RB_REMOVE(roa_tree, &rs->roa_set, r);
719 		free(r);
720 		free(roa);
721 	}
722 	return 0;
723 
724  badlen:
725 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
726 	    log_rtr_type(IPV6_PREFIX));
727 	return -1;
728 }
729 
730 static int
731 rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu)
732 {
733 	struct rtr_aspa rtr_aspa;
734 	struct aspa_tree *aspatree;
735 	struct aspa_set *aspa, *a;
736 	uint16_t cnt, i;
737 
738 	if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1)
739 		goto badlen;
740 
741 	cnt = ntohs(rtr_aspa.cnt);
742 	if (ibuf_size(pdu) != cnt * sizeof(uint32_t))
743 		goto badlen;
744 
745 	if (rs->state != RTR_STATE_EXCHANGE) {
746 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
747 		    log_rtr_type(ASPA));
748 		return -1;
749 	}
750 
751 	if (rtr_aspa.afi_flags & FLAG_AFI_V6) {
752 		aspatree = &rs->aspa_oldv6;
753 	} else {
754 		aspatree = &rs->aspa;
755 	}
756 
757 	/* create aspa_set entry from the rtr aspa pdu */
758 	if ((aspa = calloc(1, sizeof(*aspa))) == NULL) {
759 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
760 		return -1;
761 	}
762 	aspa->as = ntohl(rtr_aspa.cas);
763 	aspa->num = cnt;
764 	if (cnt > 0) {
765 		if ((aspa->tas = calloc(cnt, sizeof(uint32_t))) == NULL) {
766 			free_aspa(aspa);
767 			rtr_send_error(rs, NULL, INTERNAL_ERROR,
768 			    "out of memory");
769 			return -1;
770 		}
771 		for (i = 0; i < cnt; i++) {
772 			if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1)
773 				goto badlen;
774 		}
775 	}
776 
777 	if (rtr_aspa.flags & FLAG_ANNOUNCE) {
778 		a = RB_INSERT(aspa_tree, aspatree, aspa);
779 		if (a != NULL) {
780 			RB_REMOVE(aspa_tree, aspatree, a);
781 			free_aspa(a);
782 
783 			if (RB_INSERT(aspa_tree, aspatree, aspa) != NULL) {
784 				rtr_send_error(rs, NULL, INTERNAL_ERROR,
785 				    "corrupt aspa tree");
786 				free_aspa(aspa);
787 				return -1;
788 			}
789 		}
790 	} else {
791 		a = RB_FIND(aspa_tree, aspatree, aspa);
792 		if (a == NULL) {
793 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
794 			    log_rtr_type(ASPA), log_aspa(aspa));
795 			free_aspa(aspa);
796 			return -1;
797 		}
798 		RB_REMOVE(aspa_tree, aspatree, a);
799 		free_aspa(a);
800 		free_aspa(aspa);
801 	}
802 
803 	return 0;
804 
805  badlen:
806 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
807 	    log_rtr_type(ASPA));
808 	return -1;
809 }
810 
811 static int
812 rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu)
813 {
814 	struct rtr_endofdata_v0 eod;
815 
816 	if (ibuf_get(pdu, &eod, sizeof(eod)) == -1)
817 		goto badlen;
818 
819 	if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1)
820 		return -1;
821 
822 	if (rs->state != RTR_STATE_EXCHANGE) {
823 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
824 		    log_rtr_type(END_OF_DATA));
825 		return -1;
826 	}
827 
828 	rs->serial = ntohl(eod.serial);
829 
830 	rtr_fsm(rs, RTR_EVNT_END_OF_DATA);
831 	return 0;
832 
833  badlen:
834 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
835 	    log_rtr_type(END_OF_DATA));
836 	return -1;
837 }
838 
839 static int
840 rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu)
841 {
842 	struct rtr_endofdata eod;
843 	uint32_t t;
844 
845 	/* version 0 does not have the timing values */
846 	if (rs->version == 0)
847 		return rtr_parse_end_of_data_v0(rs, pdu);
848 
849 	if (ibuf_get(pdu, &eod, sizeof(eod)) == -1)
850 		goto badlen;
851 
852 	if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1)
853 		return -1;
854 
855 	if (rs->state != RTR_STATE_EXCHANGE) {
856 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
857 		    log_rtr_type(END_OF_DATA));
858 		return -1;
859 	}
860 
861 	rs->serial = ntohl(eod.serial);
862 	/* validate timer values to be in the right range */
863 	t = ntohl(eod.refresh);
864 	if (t < 1 || t > 86400)
865 		goto bad;
866 	rs->refresh = t;
867 	t = ntohl(eod.retry);
868 	if (t < 1 || t > 7200)
869 		goto bad;
870 	rs->retry = t;
871 	t = ntohl(eod.expire);
872 	if (t < 600 || t > 172800)
873 		goto bad;
874 	if (t <= rs->retry || t <= rs->refresh)
875 		goto bad;
876 	rs->expire = t;
877 
878 	rtr_fsm(rs, RTR_EVNT_END_OF_DATA);
879 	return 0;
880 
881 bad:
882 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad timeout values",
883 	    log_rtr_type(END_OF_DATA));
884 	return -1;
885 
886 badlen:
887 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
888 	    log_rtr_type(END_OF_DATA));
889 	return -1;
890 }
891 
892 static int
893 rtr_parse_cache_reset(struct rtr_session *rs, struct ibuf *pdu)
894 {
895 	struct rtr_reset reset;
896 
897 	if (ibuf_get(pdu, &reset, sizeof(reset)) == -1)
898 		goto badlen;
899 
900 	if (rtr_check_session_id(rs, 0, &reset.hdr, pdu) == -1)
901 		return -1;
902 
903 	if (rs->state != RTR_STATE_ESTABLISHED) {
904 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
905 		    log_rtr_type(CACHE_RESET));
906 		return -1;
907 	}
908 
909 	rtr_fsm(rs, RTR_EVNT_CACHE_RESET);
910 	return 0;
911 
912  badlen:
913 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
914 	    log_rtr_type(CACHE_RESET));
915 	return -1;
916 }
917 
918 /*
919  * Parse an Error Response message. This function behaves a bit different
920  * from other parse functions since on error the connection needs to be
921  * dropped without sending an error response back.
922  */
923 static int
924 rtr_parse_error(struct rtr_session *rs, struct ibuf *pdu)
925 {
926 	struct rtr_header rh;
927 	struct ibuf err_pdu;
928 	uint32_t pdu_len, msg_len;
929 	char *str = NULL;
930 	uint16_t errcode;
931 	int rv = -1;
932 
933 	if (ibuf_get(pdu, &rh, sizeof(rh)) == -1)
934 		goto fail;
935 	errcode = ntohs(rh.session_id);
936 
937 	if (ibuf_get_n32(pdu, &pdu_len) == -1)
938 		goto fail;
939 
940 	/* for now just ignore the embedded pdu */
941 	if (ibuf_get_ibuf(pdu, pdu_len, &err_pdu) == -1)
942 		goto fail;
943 
944 	if (ibuf_get_n32(pdu, &msg_len) == -1)
945 		goto fail;
946 
947 	/* optional error msg */
948 	if (msg_len != 0)
949 		if ((str = ibuf_get_string(pdu, msg_len)) == NULL)
950 			goto fail;
951 
952 	log_warnx("rtr %s: received error: %s%s%s", log_rtr(rs),
953 	    log_rtr_error(errcode), str ? ": " : "", str ? str : "");
954 
955 	if (errcode == NO_DATA_AVAILABLE) {
956 		rtr_fsm(rs, RTR_EVNT_NO_DATA);
957 		rv = 0;
958 	} else if (errcode == UNSUPP_PROTOCOL_VERS) {
959 		rtr_fsm(rs, RTR_EVNT_UNSUPP_PROTO_VERSION);
960 		rv = 0;
961 	} else
962 		rtr_fsm(rs, RTR_EVNT_RESET_AND_CLOSE);
963 
964 	rs->last_recv_error = errcode;
965 	if (str)
966 		strlcpy(rs->last_recv_msg, str, sizeof(rs->last_recv_msg));
967 	else
968 		memset(rs->last_recv_msg, 0, sizeof(rs->last_recv_msg));
969 
970 	free(str);
971 	return rv;
972 
973  fail:
974 	log_warnx("rtr %s: received %s: bad encoding", log_rtr(rs),
975 	    log_rtr_type(ERROR_REPORT));
976 	rtr_fsm(rs, RTR_EVNT_RESET_AND_CLOSE);
977 	return -1;
978 }
979 
980 /*
981  * Try to process received rtr message, it is possible that not a full
982  * message is in the buffer. In that case stop, once new data is available
983  * a retry will be done.
984  */
985 static void
986 rtr_process_msg(struct rtr_session *rs)
987 {
988 	struct ibuf rbuf, hdr, msg;
989 	size_t msglen;
990 	enum rtr_pdu_type msgtype;
991 
992 	ibuf_from_buffer(&rbuf, rs->r.buf, rs->r.wpos);
993 
994 	for (;;) {
995 		if (ibuf_size(&rbuf) < sizeof(struct rtr_header))
996 			break;
997 
998 		/* parse header */
999 		ibuf_from_buffer(&hdr, ibuf_data(&rbuf),
1000 		    sizeof(struct rtr_header));
1001 		if (rtr_parse_header(rs, &hdr, &msglen, &msgtype) == -1)
1002 			return;
1003 
1004 		/* extract message */
1005 		if (ibuf_get_ibuf(&rbuf, msglen, &msg) == -1)
1006 			break;
1007 
1008 		switch (msgtype) {
1009 		case SERIAL_NOTIFY:
1010 			if (rtr_parse_notify(rs, &msg) == -1)
1011 				return;
1012 			break;
1013 		case CACHE_RESPONSE:
1014 			if (rtr_parse_cache_response(rs, &msg) == -1)
1015 				return;
1016 			break;
1017 		case IPV4_PREFIX:
1018 			if (rtr_parse_ipv4_prefix(rs, &msg) == -1)
1019 				return;
1020 			break;
1021 		case IPV6_PREFIX:
1022 			if (rtr_parse_ipv6_prefix(rs, &msg) == -1)
1023 				return;
1024 			break;
1025 		case END_OF_DATA:
1026 			if (rtr_parse_end_of_data(rs, &msg) == -1)
1027 				return;
1028 			break;
1029 		case CACHE_RESET:
1030 			if (rtr_parse_cache_reset(rs, &msg) == -1)
1031 				return;
1032 			break;
1033 		case ROUTER_KEY:
1034 			/* silently ignore router key */
1035 			break;
1036 		case ERROR_REPORT:
1037 			if (rtr_parse_error(rs, &msg) == -1) {
1038 				/* no need to send back an error */
1039 				return;
1040 			}
1041 			break;
1042 		case ASPA:
1043 			if (rtr_parse_aspa(rs, &msg) == -1)
1044 				return;
1045 			break;
1046 		default:
1047 			/* unreachable, checked in rtr_parse_header() */
1048 			rtr_send_error(rs, &msg, UNSUPP_PDU_TYPE, "type %s",
1049 			    log_rtr_type(msgtype));
1050 			return;
1051 		}
1052 	}
1053 
1054 	memmove(&rs->r.buf, ibuf_data(&rbuf), ibuf_size(&rbuf));
1055 	rs->r.wpos = ibuf_size(&rbuf);
1056 }
1057 
1058 /*
1059  * Simple FSM for RTR sessions
1060  */
1061 static void
1062 rtr_fsm(struct rtr_session *rs, enum rtr_event event)
1063 {
1064 	enum rtr_state prev_state = rs->state;
1065 
1066 	switch (event) {
1067 	case RTR_EVNT_UNSUPP_PROTO_VERSION:
1068 		if (rs->prev_version == rs->version) {
1069 			/*
1070 			 * Can't downgrade anymore, fail connection.
1071 			 * RFC requires sending the error with the
1072 			 * highest supported version number.
1073 			 */
1074 			rs->version = RTR_MAX_VERSION;
1075 			rtr_send_error(rs, NULL, UNSUPP_PROTOCOL_VERS,
1076 			    "negotiation failed");
1077 			return;
1078 		}
1079 		/* try again with new version */
1080 		if (rs->session_id == -1)
1081 			rtr_send_reset_query(rs);
1082 		else
1083 			rtr_send_serial_query(rs);
1084 		break;
1085 	case RTR_EVNT_RESET_AND_CLOSE:
1086 		rtr_reset_cache(rs);
1087 		rtr_recalc();
1088 		/* FALLTHROUGH */
1089 	case RTR_EVNT_CON_CLOSE:
1090 		if (rs->fd != -1) {
1091 			/* flush buffers */
1092 			msgbuf_clear(&rs->w);
1093 			rs->r.wpos = 0;
1094 			close(rs->fd);
1095 			rs->fd = -1;
1096 		}
1097 		/* try to reopen session */
1098 		timer_set(&rs->timers, Timer_Rtr_Retry,
1099 		    arc4random_uniform(10));
1100 		/*
1101 		 * A close event during version negotiation needs to remain
1102 		 * in the negotiation state else the same error will happen
1103 		 * over and over again. The RFC is utterly underspecified
1104 		 * and some RTR caches close the connection after sending
1105 		 * the error PDU.
1106 		 */
1107 		if (rs->state != RTR_STATE_NEGOTIATION)
1108 			rs->state = RTR_STATE_CLOSED;
1109 		break;
1110 	case RTR_EVNT_START:
1111 	case RTR_EVNT_TIMER_RETRY:
1112 		switch (rs->state) {
1113 		case RTR_STATE_ERROR:
1114 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1115 			break;
1116 		case RTR_STATE_CLOSED:
1117 		case RTR_STATE_NEGOTIATION:
1118 			timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
1119 			rtr_imsg_compose(IMSG_SOCKET_CONN, rs->id, 0, NULL, 0);
1120 			break;
1121 		case RTR_STATE_ESTABLISHED:
1122 			if (rs->session_id == -1)
1123 				rtr_send_reset_query(rs);
1124 			else
1125 				rtr_send_serial_query(rs);
1126 		default:
1127 			break;
1128 		}
1129 		break;
1130 	case RTR_EVNT_CON_OPEN:
1131 		timer_stop(&rs->timers, Timer_Rtr_Retry);
1132 		rs->state = RTR_STATE_NEGOTIATION;
1133 		if (rs->session_id == -1)
1134 			rtr_send_reset_query(rs);
1135 		else
1136 			rtr_send_serial_query(rs);
1137 		break;
1138 	case RTR_EVNT_SERIAL_NOTIFY:
1139 		/* schedule a refresh after a quick wait */
1140 		timer_set(&rs->timers, Timer_Rtr_Refresh,
1141 		    arc4random_uniform(10));
1142 		break;
1143 	case RTR_EVNT_TIMER_REFRESH:
1144 		rtr_send_serial_query(rs);
1145 		break;
1146 	case RTR_EVNT_TIMER_EXPIRE:
1147 		rtr_reset_cache(rs);
1148 		rtr_recalc();
1149 		break;
1150 	case RTR_EVNT_TIMER_ACTIVE:
1151 		log_warnx("rtr %s: activity timer fired", log_rtr(rs));
1152 		rtr_sem_release(rs->active_lock);
1153 		rtr_recalc();
1154 		rs->active_lock = 0;
1155 		break;
1156 	case RTR_EVNT_CACHE_RESPONSE:
1157 		rs->state = RTR_STATE_EXCHANGE;
1158 		timer_stop(&rs->timers, Timer_Rtr_Refresh);
1159 		timer_stop(&rs->timers, Timer_Rtr_Retry);
1160 		timer_set(&rs->timers, Timer_Rtr_Active, rs->active);
1161 		/* prevent rtr_recalc from running while active */
1162 		rs->active_lock = 1;
1163 		rtr_sem_acquire(rs->active_lock);
1164 		break;
1165 	case RTR_EVNT_END_OF_DATA:
1166 		/* start refresh and expire timers */
1167 		timer_set(&rs->timers, Timer_Rtr_Refresh, rs->refresh);
1168 		timer_set(&rs->timers, Timer_Rtr_Expire, rs->expire);
1169 		timer_stop(&rs->timers, Timer_Rtr_Active);
1170 		rs->state = RTR_STATE_ESTABLISHED;
1171 		rtr_sem_release(rs->active_lock);
1172 		rtr_recalc();
1173 		rs->active_lock = 0;
1174 		/* clear the last errors */
1175 		rs->last_sent_error = NO_ERROR;
1176 		rs->last_recv_error = NO_ERROR;
1177 		rs->last_sent_msg[0] = '\0';
1178 		rs->last_recv_msg[0] = '\0';
1179 		break;
1180 	case RTR_EVNT_CACHE_RESET:
1181 		rtr_reset_cache(rs);
1182 		rtr_recalc();
1183 		/* retry after a quick wait */
1184 		timer_set(&rs->timers, Timer_Rtr_Retry,
1185 		    arc4random_uniform(10));
1186 		break;
1187 	case RTR_EVNT_NO_DATA:
1188 		/* start retry timer */
1189 		timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
1190 		/* stop refresh timer just to be sure */
1191 		timer_stop(&rs->timers, Timer_Rtr_Refresh);
1192 		rs->state = RTR_STATE_ESTABLISHED;
1193 		break;
1194 	case RTR_EVNT_SEND_ERROR:
1195 		rtr_reset_cache(rs);
1196 		rtr_recalc();
1197 		rs->state = RTR_STATE_ERROR;
1198 		/* flush receive buffer */
1199 		rs->r.wpos = 0;
1200 		break;
1201 	case RTR_EVNT_NEGOTIATION_DONE:
1202 		rs->state = RTR_STATE_ESTABLISHED;
1203 		break;
1204 	}
1205 
1206 	log_debug("rtr %s: state change %s -> %s, reason: %s",
1207 	    log_rtr(rs), rtr_statenames[prev_state], rtr_statenames[rs->state],
1208 	    rtr_eventnames[event]);
1209 }
1210 
1211 /*
1212  * IO handler for RTR sessions
1213  */
1214 static void
1215 rtr_dispatch_msg(struct pollfd *pfd, struct rtr_session *rs)
1216 {
1217 	ssize_t n;
1218 	int error;
1219 
1220 	if (pfd->revents & POLLHUP) {
1221 		log_warnx("rtr %s: Connection closed, hangup", log_rtr(rs));
1222 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1223 		return;
1224 	}
1225 	if (pfd->revents & (POLLERR|POLLNVAL)) {
1226 		log_warnx("rtr %s: Connection closed, error", log_rtr(rs));
1227 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1228 		return;
1229 	}
1230 	if (pfd->revents & POLLOUT && rs->w.queued) {
1231 		if ((error = ibuf_write(&rs->w)) == -1) {
1232 			if (errno != EAGAIN) {
1233 				log_warn("rtr %s: write error", log_rtr(rs));
1234 				rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1235 			}
1236 		}
1237 		if (error == 0)
1238 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1239 		if (rs->w.queued == 0 && rs->state == RTR_STATE_ERROR)
1240 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1241 	}
1242 	if (pfd->revents & POLLIN) {
1243 		if ((n = read(rs->fd, rs->r.buf + rs->r.wpos,
1244 		    sizeof(rs->r.buf) - rs->r.wpos)) == -1) {
1245 			if (errno != EINTR && errno != EAGAIN) {
1246 				log_warn("rtr %s: read error", log_rtr(rs));
1247 				rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1248 			}
1249 			return;
1250 		}
1251 		if (n == 0) {
1252 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1253 			return;
1254 		}
1255 		rs->r.wpos += n;
1256 
1257 		/* new data arrived, try to process it */
1258 		rtr_process_msg(rs);
1259 	}
1260 
1261 }
1262 
1263 void
1264 rtr_check_events(struct pollfd *pfds, size_t npfds)
1265 {
1266 	struct rtr_session *rs;
1267 	struct timer *t;
1268 	time_t now;
1269 	size_t i = 0;
1270 
1271 	for (i = 0; i < npfds; i++) {
1272 		if (pfds[i].revents == 0)
1273 			continue;
1274 		TAILQ_FOREACH(rs, &rtrs, entry)
1275 			if (rs->fd == pfds[i].fd) {
1276 				rtr_dispatch_msg(&pfds[i], rs);
1277 				break;
1278 			}
1279 		if (rs == NULL)
1280 			log_warnx("%s: unknown fd in pollfds", __func__);
1281 	}
1282 
1283 	/* run all timers */
1284 	now = getmonotime();
1285 	TAILQ_FOREACH(rs, &rtrs, entry)
1286 		if ((t = timer_nextisdue(&rs->timers, now)) != NULL) {
1287 			/* stop timer so it does not trigger again */
1288 			timer_stop(&rs->timers, t->type);
1289 			switch (t->type) {
1290 			case Timer_Rtr_Refresh:
1291 				rtr_fsm(rs, RTR_EVNT_TIMER_REFRESH);
1292 				break;
1293 			case Timer_Rtr_Retry:
1294 				rtr_fsm(rs, RTR_EVNT_TIMER_RETRY);
1295 				break;
1296 			case Timer_Rtr_Expire:
1297 				rtr_fsm(rs, RTR_EVNT_TIMER_EXPIRE);
1298 				break;
1299 			case Timer_Rtr_Active:
1300 				rtr_fsm(rs, RTR_EVNT_TIMER_ACTIVE);
1301 				break;
1302 			default:
1303 				fatalx("King Bula lost in time");
1304 			}
1305 		}
1306 }
1307 
1308 size_t
1309 rtr_count(void)
1310 {
1311 	struct rtr_session *rs;
1312 	size_t count = 0;
1313 
1314 	TAILQ_FOREACH(rs, &rtrs, entry)
1315 		count++;
1316 	return count;
1317 }
1318 
1319 size_t
1320 rtr_poll_events(struct pollfd *pfds, size_t npfds, time_t *timeout)
1321 {
1322 	struct rtr_session *rs;
1323 	time_t now = getmonotime();
1324 	size_t i = 0;
1325 
1326 	TAILQ_FOREACH(rs, &rtrs, entry) {
1327 		time_t nextaction;
1328 		struct pollfd *pfd = pfds + i++;
1329 
1330 		if (i > npfds)
1331 			fatalx("%s: too many sessions for pollfd", __func__);
1332 
1333 		if ((nextaction = timer_nextduein(&rs->timers, now)) != -1 &&
1334 		    nextaction < *timeout)
1335 			*timeout = nextaction;
1336 
1337 		if (rs->state == RTR_STATE_CLOSED) {
1338 			pfd->fd = -1;
1339 			continue;
1340 		}
1341 
1342 		pfd->fd = rs->fd;
1343 		pfd->events = 0;
1344 
1345 		if (rs->w.queued)
1346 			pfd->events |= POLLOUT;
1347 		if (rs->state >= RTR_STATE_ESTABLISHED)
1348 			pfd->events |= POLLIN;
1349 	}
1350 
1351 	return i;
1352 }
1353 
1354 struct rtr_session *
1355 rtr_new(uint32_t id, char *descr)
1356 {
1357 	struct rtr_session *rs;
1358 
1359 	if ((rs = calloc(1, sizeof(*rs))) == NULL)
1360 		fatal("RTR session %s", descr);
1361 
1362 	RB_INIT(&rs->roa_set);
1363 	RB_INIT(&rs->aspa);
1364 	RB_INIT(&rs->aspa_oldv6);
1365 	TAILQ_INIT(&rs->timers);
1366 	msgbuf_init(&rs->w);
1367 
1368 	strlcpy(rs->descr, descr, sizeof(rs->descr));
1369 	rs->id = id;
1370 	rs->session_id = -1;
1371 	rs->version = RTR_MAX_VERSION;
1372 	rs->prev_version = RTR_MAX_VERSION;
1373 	rs->refresh = RTR_DEFAULT_REFRESH;
1374 	rs->retry = RTR_DEFAULT_RETRY;
1375 	rs->expire = RTR_DEFAULT_EXPIRE;
1376 	rs->active = RTR_DEFAULT_ACTIVE;
1377 	rs->state = RTR_STATE_CLOSED;
1378 	rs->reconf_action = RECONF_REINIT;
1379 	rs->last_recv_error = NO_ERROR;
1380 	rs->last_sent_error = NO_ERROR;
1381 
1382 	/* make sure that some timer is running to abort bad sessions */
1383 	timer_set(&rs->timers, Timer_Rtr_Expire, rs->expire);
1384 
1385 	log_debug("rtr %s: new session, start", log_rtr(rs));
1386 	TAILQ_INSERT_TAIL(&rtrs, rs, entry);
1387 	rtr_fsm(rs, RTR_EVNT_START);
1388 
1389 	return rs;
1390 }
1391 
1392 struct rtr_session *
1393 rtr_get(uint32_t id)
1394 {
1395 	struct rtr_session *rs;
1396 
1397 	TAILQ_FOREACH(rs, &rtrs, entry)
1398 		if (rs->id == id)
1399 			return rs;
1400 	return NULL;
1401 }
1402 
1403 void
1404 rtr_free(struct rtr_session *rs)
1405 {
1406 	if (rs == NULL)
1407 		return;
1408 
1409 	rtr_reset_cache(rs);
1410 	rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1411 	timer_remove_all(&rs->timers);
1412 	free(rs);
1413 }
1414 
1415 void
1416 rtr_open(struct rtr_session *rs, int fd)
1417 {
1418 	if (rs->state != RTR_STATE_CLOSED &&
1419 	    rs->state != RTR_STATE_NEGOTIATION) {
1420 		log_warnx("rtr %s: bad session state", log_rtr(rs));
1421 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1422 	}
1423 
1424 	if (rs->state == RTR_STATE_CLOSED) {
1425 		rs->version = RTR_MAX_VERSION;
1426 		rs->prev_version = RTR_MAX_VERSION;
1427 	}
1428 
1429 	rs->fd = rs->w.fd = fd;
1430 	rtr_fsm(rs, RTR_EVNT_CON_OPEN);
1431 }
1432 
1433 void
1434 rtr_config_prep(void)
1435 {
1436 	struct rtr_session *rs;
1437 
1438 	TAILQ_FOREACH(rs, &rtrs, entry)
1439 		rs->reconf_action = RECONF_DELETE;
1440 }
1441 
1442 void
1443 rtr_config_merge(void)
1444 {
1445 	struct rtr_session *rs, *nrs;
1446 
1447 	TAILQ_FOREACH_SAFE(rs, &rtrs, entry, nrs)
1448 		if (rs->reconf_action == RECONF_DELETE) {
1449 			TAILQ_REMOVE(&rtrs, rs, entry);
1450 			rtr_free(rs);
1451 		}
1452 }
1453 
1454 void
1455 rtr_config_keep(struct rtr_session *rs)
1456 {
1457 	rs->reconf_action = RECONF_KEEP;
1458 }
1459 
1460 void
1461 rtr_roa_merge(struct roa_tree *rt)
1462 {
1463 	struct rtr_session *rs;
1464 	struct roa *roa;
1465 
1466 	TAILQ_FOREACH(rs, &rtrs, entry) {
1467 		RB_FOREACH(roa, roa_tree, &rs->roa_set)
1468 			rtr_roa_insert(rt, roa);
1469 	}
1470 }
1471 
1472 void
1473 rtr_aspa_merge(struct aspa_tree *at)
1474 {
1475 	struct rtr_session *rs;
1476 	struct aspa_set *aspa;
1477 
1478 	TAILQ_FOREACH(rs, &rtrs, entry) {
1479 		RB_FOREACH(aspa, aspa_tree, &rs->aspa)
1480 			rtr_aspa_insert(at, aspa);
1481 		RB_FOREACH(aspa, aspa_tree, &rs->aspa_oldv6)
1482 			rtr_aspa_insert(at, aspa);
1483 	}
1484 }
1485 
1486 void
1487 rtr_shutdown(void)
1488 {
1489 	struct rtr_session *rs, *nrs;
1490 
1491 	TAILQ_FOREACH_SAFE(rs, &rtrs, entry, nrs)
1492 		rtr_free(rs);
1493 }
1494 
1495 void
1496 rtr_show(struct rtr_session *rs, pid_t pid)
1497 {
1498 	struct ctl_show_rtr msg;
1499 	struct ctl_timer ct;
1500 	u_int i;
1501 	time_t d;
1502 
1503 	memset(&msg, 0, sizeof(msg));
1504 
1505 	/* descr, remote_addr, local_addr and remote_port set by parent */
1506 	msg.version = rs->version;
1507 	msg.serial = rs->serial;
1508 	msg.refresh = rs->refresh;
1509 	msg.retry = rs->retry;
1510 	msg.expire = rs->expire;
1511 	msg.session_id = rs->session_id;
1512 	msg.last_sent_error = rs->last_sent_error;
1513 	msg.last_recv_error = rs->last_recv_error;
1514 	strlcpy(msg.state, rtr_statenames[rs->state], sizeof(msg.state));
1515 	strlcpy(msg.last_sent_msg, rs->last_sent_msg,
1516 	    sizeof(msg.last_sent_msg));
1517 	strlcpy(msg.last_recv_msg, rs->last_recv_msg,
1518 	    sizeof(msg.last_recv_msg));
1519 
1520 	/* send back imsg */
1521 	rtr_imsg_compose(IMSG_CTL_SHOW_RTR, rs->id, pid, &msg, sizeof(msg));
1522 
1523 	/* send back timer imsgs */
1524 	for (i = 1; i < Timer_Max; i++) {
1525 		if (!timer_running(&rs->timers, i, &d))
1526 			continue;
1527 		ct.type = i;
1528 		ct.val = d;
1529 		rtr_imsg_compose(IMSG_CTL_SHOW_TIMER, rs->id, pid,
1530 		    &ct, sizeof(ct));
1531 	}
1532 }
1533