bgpd.c revision 1.252
1/*	$OpenBSD: bgpd.c,v 1.252 2022/07/23 10:24:00 claudio Exp $ */
2
3/*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@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
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/wait.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <err.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <poll.h>
28#include <pwd.h>
29#include <signal.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <syslog.h>
34#include <unistd.h>
35
36#include "bgpd.h"
37#include "session.h"
38#include "log.h"
39#include "version.h"
40
41void		sighdlr(int);
42__dead void	usage(void);
43int		main(int, char *[]);
44pid_t		start_child(enum bgpd_process, char *, int, int, int);
45int		send_filterset(struct imsgbuf *, struct filter_set_head *);
46int		reconfigure(char *, struct bgpd_config *);
47int		send_config(struct bgpd_config *);
48int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
49int		control_setup(struct bgpd_config *);
50static void	getsockpair(int [2]);
51int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *,
52		    struct imsgbuf *);
53void		bgpd_rtr_connect(struct rtr_config *);
54void		bgpd_rtr_connect_done(int, struct bgpd_config *);
55
56int			 cflags;
57volatile sig_atomic_t	 mrtdump;
58volatile sig_atomic_t	 quit;
59volatile sig_atomic_t	 reconfig;
60pid_t			 reconfpid;
61int			 reconfpending;
62struct imsgbuf		*ibuf_se;
63struct imsgbuf		*ibuf_rde;
64struct imsgbuf		*ibuf_rtr;
65struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
66char			*cname;
67char			*rcname;
68
69struct connect_elm {
70	TAILQ_ENTRY(connect_elm)	entry;
71	uint32_t			id;
72	int				fd;
73};
74
75TAILQ_HEAD( ,connect_elm)	connect_queue = \
76				    TAILQ_HEAD_INITIALIZER(connect_queue);
77u_int				connect_cnt;
78#define MAX_CONNECT_CNT		32
79
80void
81sighdlr(int sig)
82{
83	switch (sig) {
84	case SIGTERM:
85	case SIGINT:
86		quit = 1;
87		break;
88	case SIGHUP:
89		reconfig = 1;
90		break;
91	case SIGALRM:
92	case SIGUSR1:
93		mrtdump = 1;
94		break;
95	}
96}
97
98__dead void
99usage(void)
100{
101	extern char *__progname;
102
103	fprintf(stderr, "usage: %s [-cdnvV] [-D macro=value] [-f file]\n",
104	    __progname);
105	exit(1);
106}
107
108#define PFD_PIPE_SESSION	0
109#define PFD_PIPE_RDE		1
110#define PFD_PIPE_RTR		2
111#define PFD_SOCK_ROUTE		3
112#define PFD_SOCK_PFKEY		4
113#define PFD_CONNECT_START	5
114#define MAX_TIMEOUT		3600
115
116int	 cmd_opts;
117
118int
119main(int argc, char *argv[])
120{
121	struct bgpd_config	*conf;
122	enum bgpd_process	 proc = PROC_MAIN;
123	struct rde_rib		*rr;
124	struct peer		*p;
125	struct pollfd		*pfd = NULL;
126	struct connect_elm	*ce;
127	time_t			 timeout;
128	pid_t			 se_pid = 0, rde_pid = 0, rtr_pid = 0, pid;
129	char			*conffile;
130	char			*saved_argv0;
131	u_int			 pfd_elms = 0, npfd, i;
132	int			 debug = 0;
133	int			 rfd, keyfd;
134	int			 ch, status;
135	int			 pipe_m2s[2];
136	int			 pipe_m2r[2];
137	int			 pipe_m2roa[2];
138
139	conffile = CONFFILE;
140
141	log_init(1, LOG_DAEMON);	/* log to stderr until daemonized */
142	log_procinit(log_procnames[PROC_MAIN]);
143	log_setverbose(1);
144
145	saved_argv0 = argv[0];
146	if (saved_argv0 == NULL)
147		saved_argv0 = "bgpd";
148
149	while ((ch = getopt(argc, argv, "cdD:f:nRSTvV")) != -1) {
150		switch (ch) {
151		case 'c':
152			cmd_opts |= BGPD_OPT_FORCE_DEMOTE;
153			break;
154		case 'd':
155			debug = 1;
156			break;
157		case 'D':
158			if (cmdline_symset(optarg) < 0)
159				log_warnx("could not parse macro definition %s",
160				    optarg);
161			break;
162		case 'f':
163			conffile = optarg;
164			break;
165		case 'n':
166			cmd_opts |= BGPD_OPT_NOACTION;
167			break;
168		case 'v':
169			if (cmd_opts & BGPD_OPT_VERBOSE)
170				cmd_opts |= BGPD_OPT_VERBOSE2;
171			cmd_opts |= BGPD_OPT_VERBOSE;
172			break;
173		case 'R':
174			proc = PROC_RDE;
175			break;
176		case 'S':
177			proc = PROC_SE;
178			break;
179		case 'T':
180			proc = PROC_RTR;
181			break;
182		case 'V':
183			fprintf(stderr, "OpenBGPD %s\n", BGPD_VERSION);
184			return 0;
185		default:
186			usage();
187			/* NOTREACHED */
188		}
189	}
190
191	argc -= optind;
192	argv += optind;
193	if (argc > 0)
194		usage();
195
196	if (cmd_opts & BGPD_OPT_NOACTION) {
197		if ((conf = parse_config(conffile, NULL, NULL)) == NULL)
198			exit(1);
199
200		if (cmd_opts & BGPD_OPT_VERBOSE)
201			print_config(conf, &ribnames);
202		else
203			fprintf(stderr, "configuration OK\n");
204
205		while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
206			SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
207			free(rr);
208		}
209		free_config(conf);
210		exit(0);
211	}
212
213	switch (proc) {
214	case PROC_MAIN:
215		break;
216	case PROC_RDE:
217		rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
218		/* NOTREACHED */
219	case PROC_SE:
220		session_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
221		/* NOTREACHED */
222	case PROC_RTR:
223		rtr_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
224		/* NOTREACHED */
225	}
226
227	if (geteuid())
228		errx(1, "need root privileges");
229
230	if (getpwnam(BGPD_USER) == NULL)
231		errx(1, "unknown user %s", BGPD_USER);
232
233	if ((conf = parse_config(conffile, NULL, NULL)) == NULL) {
234		log_warnx("config file %s has errors", conffile);
235		exit(1);
236	}
237
238	if (prepare_listeners(conf) == -1)
239		exit(1);
240
241	log_init(debug, LOG_DAEMON);
242	log_setverbose(cmd_opts & BGPD_OPT_VERBOSE);
243
244	if (!debug)
245		daemon(1, 0);
246
247	log_info("startup");
248
249	getsockpair(pipe_m2s);
250	getsockpair(pipe_m2r);
251	getsockpair(pipe_m2roa);
252
253	/* fork children */
254	rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug,
255	    cmd_opts & BGPD_OPT_VERBOSE);
256	se_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug,
257	    cmd_opts & BGPD_OPT_VERBOSE);
258	rtr_pid = start_child(PROC_RTR, saved_argv0, pipe_m2roa[1], debug,
259	    cmd_opts & BGPD_OPT_VERBOSE);
260
261	signal(SIGTERM, sighdlr);
262	signal(SIGINT, sighdlr);
263	signal(SIGHUP, sighdlr);
264	signal(SIGALRM, sighdlr);
265	signal(SIGUSR1, sighdlr);
266	signal(SIGPIPE, SIG_IGN);
267
268	if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL ||
269	    (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL ||
270	    (ibuf_rtr = malloc(sizeof(struct imsgbuf))) == NULL)
271		fatal(NULL);
272	imsg_init(ibuf_se, pipe_m2s[0]);
273	imsg_init(ibuf_rde, pipe_m2r[0]);
274	imsg_init(ibuf_rtr, pipe_m2roa[0]);
275	mrt_init(ibuf_rde, ibuf_se);
276	if (kr_init(&rfd, conf->fib_priority) == -1)
277		quit = 1;
278	keyfd = pfkey_init();
279
280	/*
281	 * rpath, read config file
282	 * cpath, unlink control socket
283	 * fattr, chmod on control socket
284	 * wpath, needed if we are doing mrt dumps
285	 *
286	 * pledge placed here because kr_init() does a setsockopt on the
287	 * routing socket thats not allowed at all.
288	 */
289#if 0
290	/*
291	 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR
292	 * this needs some redesign of bgpd to be fixed.
293	 */
294BROKEN	if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd",
295	    NULL) == -1)
296		fatal("pledge");
297#endif
298
299	if (imsg_send_sockets(ibuf_se, ibuf_rde, ibuf_rtr))
300		fatal("could not establish imsg links");
301	/* control setup needs to happen late since it sends imsgs */
302	if (control_setup(conf) == -1)
303		quit = 1;
304	if (send_config(conf) != 0)
305		quit = 1;
306	if (pftable_clear_all() != 0)
307		quit = 1;
308
309	while (quit == 0) {
310		if (pfd_elms < PFD_CONNECT_START + connect_cnt) {
311			struct pollfd *newp;
312
313			if ((newp = reallocarray(pfd,
314			    PFD_CONNECT_START + connect_cnt,
315			    sizeof(struct pollfd))) == NULL) {
316				log_warn("could not resize pfd from %u -> %u"
317				    " entries", pfd_elms, PFD_CONNECT_START +
318				    connect_cnt);
319				fatalx("exiting");
320			}
321			pfd = newp;
322			pfd_elms = PFD_CONNECT_START + connect_cnt;
323		}
324		bzero(pfd, sizeof(struct pollfd) * pfd_elms);
325
326		timeout = mrt_timeout(conf->mrt);
327
328		pfd[PFD_SOCK_ROUTE].fd = rfd;
329		pfd[PFD_SOCK_ROUTE].events = POLLIN;
330
331		pfd[PFD_SOCK_PFKEY].fd = keyfd;
332		pfd[PFD_SOCK_PFKEY].events = POLLIN;
333
334		set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se);
335		set_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde);
336		set_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr);
337
338		npfd = PFD_CONNECT_START;
339		TAILQ_FOREACH(ce, &connect_queue, entry) {
340			pfd[npfd].fd = ce->fd;
341			pfd[npfd++].events = POLLOUT;
342			if (npfd > pfd_elms)
343				fatalx("polli pfd overflow");
344		}
345
346		if (timeout < 0 || timeout > MAX_TIMEOUT)
347			timeout = MAX_TIMEOUT;
348		if (poll(pfd, npfd, timeout * 1000) == -1) {
349			if (errno != EINTR) {
350				log_warn("poll error");
351				quit = 1;
352			}
353			goto next_loop;
354		}
355
356		if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) {
357			log_warnx("main: Lost connection to SE");
358			msgbuf_clear(&ibuf_se->w);
359			free(ibuf_se);
360			ibuf_se = NULL;
361			quit = 1;
362		} else {
363			if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) ==
364			    -1)
365				quit = 1;
366		}
367
368		if (handle_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde) == -1) {
369			log_warnx("main: Lost connection to RDE");
370			msgbuf_clear(&ibuf_rde->w);
371			free(ibuf_rde);
372			ibuf_rde = NULL;
373			quit = 1;
374		} else {
375			if (dispatch_imsg(ibuf_rde, PFD_PIPE_RDE, conf) == -1)
376				quit = 1;
377		}
378
379		if (handle_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr) == -1) {
380			log_warnx("main: Lost connection to RTR");
381			msgbuf_clear(&ibuf_rtr->w);
382			free(ibuf_rtr);
383			ibuf_rtr = NULL;
384			quit = 1;
385		} else {
386			if (dispatch_imsg(ibuf_rtr, PFD_PIPE_RTR, conf) == -1)
387				quit = 1;
388		}
389
390		if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
391			if (kr_dispatch_msg() == -1)
392				quit = 1;
393		}
394
395		if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) {
396			if (pfkey_read(keyfd, NULL) == -1) {
397				log_warnx("pfkey_read failed, exiting...");
398				quit = 1;
399			}
400		}
401
402		for (i = PFD_CONNECT_START; i < npfd; i++)
403			if (pfd[i].revents != 0)
404				bgpd_rtr_connect_done(pfd[i].fd, conf);
405
406 next_loop:
407		if (reconfig) {
408			u_int	error;
409
410			reconfig = 0;
411			switch (reconfigure(conffile, conf)) {
412			case -1:	/* fatal error */
413				quit = 1;
414				break;
415			case 0:		/* all OK */
416				error = 0;
417				break;
418			case 2:
419				log_info("previous reload still running");
420				error = CTL_RES_PENDING;
421				break;
422			default:	/* parse error */
423				log_warnx("config file %s has errors, "
424				    "not reloading", conffile);
425				error = CTL_RES_PARSE_ERROR;
426				break;
427			}
428			if (reconfpid != 0) {
429				send_imsg_session(IMSG_CTL_RESULT, reconfpid,
430				    &error, sizeof(error));
431				reconfpid = 0;
432			}
433		}
434
435		if (mrtdump) {
436			mrtdump = 0;
437			mrt_handler(conf->mrt);
438		}
439	}
440
441	/* close pipes */
442	if (ibuf_se) {
443		msgbuf_clear(&ibuf_se->w);
444		close(ibuf_se->fd);
445		free(ibuf_se);
446		ibuf_se = NULL;
447	}
448	if (ibuf_rde) {
449		msgbuf_clear(&ibuf_rde->w);
450		close(ibuf_rde->fd);
451		free(ibuf_rde);
452		ibuf_rde = NULL;
453	}
454	if (ibuf_rtr) {
455		msgbuf_clear(&ibuf_rtr->w);
456		close(ibuf_rtr->fd);
457		free(ibuf_rtr);
458		ibuf_rtr = NULL;
459	}
460
461	/* cleanup kernel data structures */
462	carp_demote_shutdown();
463	kr_shutdown();
464	pftable_clear_all();
465
466	RB_FOREACH(p, peer_head, &conf->peers)
467		pfkey_remove(p);
468
469	while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
470		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
471		free(rr);
472	}
473	free_config(conf);
474
475	log_debug("waiting for children to terminate");
476	do {
477		pid = wait(&status);
478		if (pid == -1) {
479			if (errno != EINTR && errno != ECHILD)
480				fatal("wait");
481		} else if (WIFSIGNALED(status)) {
482			char *name = "unknown process";
483			if (pid == rde_pid)
484				name = "route decision engine";
485			else if (pid == se_pid)
486				name = "session engine";
487			else if (pid == rtr_pid)
488				name = "rtr engine";
489			log_warnx("%s terminated; signal %d", name,
490				WTERMSIG(status));
491		}
492	} while (pid != -1 || (pid == -1 && errno == EINTR));
493
494	free(rcname);
495	free(cname);
496
497	log_info("terminating");
498	return (0);
499}
500
501pid_t
502start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose)
503{
504	char *argv[5];
505	int argc = 0;
506	pid_t pid;
507
508	switch (pid = fork()) {
509	case -1:
510		fatal("cannot fork");
511	case 0:
512		break;
513	default:
514		close(fd);
515		return (pid);
516	}
517
518	if (fd != 3) {
519		if (dup2(fd, 3) == -1)
520			fatal("cannot setup imsg fd");
521	} else if (fcntl(fd, F_SETFD, 0) == -1)
522		fatal("cannot setup imsg fd");
523
524	argv[argc++] = argv0;
525	switch (p) {
526	case PROC_MAIN:
527		fatalx("Can not start main process");
528	case PROC_RDE:
529		argv[argc++] = "-R";
530		break;
531	case PROC_SE:
532		argv[argc++] = "-S";
533		break;
534	case PROC_RTR:
535		argv[argc++] = "-T";
536		break;
537	}
538	if (debug)
539		argv[argc++] = "-d";
540	if (verbose)
541		argv[argc++] = "-v";
542	argv[argc++] = NULL;
543
544	execvp(argv0, argv);
545	fatal("execvp");
546}
547
548int
549send_filterset(struct imsgbuf *i, struct filter_set_head *set)
550{
551	struct filter_set	*s;
552
553	TAILQ_FOREACH(s, set, entry)
554		if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s,
555		    sizeof(struct filter_set)) == -1)
556			return (-1);
557	return (0);
558}
559
560int
561reconfigure(char *conffile, struct bgpd_config *conf)
562{
563	struct bgpd_config	*new_conf;
564
565	if (reconfpending)
566		return (2);
567
568	log_info("rereading config");
569	if ((new_conf = parse_config(conffile, &conf->peers,
570	    &conf->rtrs)) == NULL)
571		return (1);
572
573	merge_config(conf, new_conf);
574
575	if (prepare_listeners(conf) == -1) {
576		return (1);
577	}
578
579	if (control_setup(conf) == -1) {
580		return (1);
581	}
582
583	return send_config(conf);
584}
585
586int
587send_config(struct bgpd_config *conf)
588{
589	struct peer		*p;
590	struct filter_rule	*r;
591	struct listen_addr	*la;
592	struct rde_rib		*rr;
593	struct l3vpn		*vpn;
594	struct as_set		*aset;
595	struct prefixset	*ps;
596	struct prefixset_item	*psi, *npsi;
597	struct roa		*roa, *nroa;
598	struct rtr_config	*rtr;
599
600	reconfpending = 3;	/* one per child */
601
602	expand_networks(conf, &conf->networks);
603	SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry)
604		expand_networks(conf, &vpn->net_l);
605
606	cflags = conf->flags;
607
608	/* start reconfiguration */
609	if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1,
610	    conf, sizeof(*conf)) == -1)
611		return (-1);
612	if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1,
613	    conf, sizeof(*conf)) == -1)
614		return (-1);
615	if (imsg_compose(ibuf_rtr, IMSG_RECONF_CONF, 0, 0, -1,
616	    conf, sizeof(*conf)) == -1)
617		return (-1);
618
619	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
620		if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
621		    la, sizeof(*la)) == -1)
622			return (-1);
623		la->fd = -1;
624	}
625
626	/* adjust fib syncing on reload */
627	ktable_preload();
628
629	/* RIBs for the RDE */
630	while ((rr = SIMPLEQ_FIRST(&ribnames))) {
631		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
632		if (ktable_update(rr->rtableid, rr->name, rr->flags) == -1) {
633			log_warnx("failed to load routing table %d",
634			    rr->rtableid);
635			return (-1);
636		}
637		if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1,
638		    rr, sizeof(*rr)) == -1)
639			return (-1);
640		free(rr);
641	}
642
643	/* send peer list to the SE */
644	RB_FOREACH(p, peer_head, &conf->peers) {
645		if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
646		    &p->conf, sizeof(p->conf)) == -1)
647			return (-1);
648
649		if (p->reconf_action == RECONF_REINIT)
650			if (pfkey_establish(p) == -1)
651				log_peer_warnx(&p->conf, "pfkey setup failed");
652	}
653
654	/* networks go via kroute to the RDE */
655	kr_net_reload(conf->default_tableid, 0, &conf->networks);
656
657	/* prefixsets for filters in the RDE */
658	while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) {
659		SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry);
660		if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET, 0, 0, -1,
661		    ps->name, sizeof(ps->name)) == -1)
662			return (-1);
663		RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
664			RB_REMOVE(prefixset_tree, &ps->psitems, psi);
665			if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM,
666			    0, 0, -1, psi, sizeof(*psi)) == -1)
667				return (-1);
668			free(psi);
669		}
670		free(ps);
671	}
672
673	/* originsets for filters in the RDE */
674	while ((ps = SIMPLEQ_FIRST(&conf->originsets)) != NULL) {
675		SIMPLEQ_REMOVE_HEAD(&conf->originsets, entry);
676		if (imsg_compose(ibuf_rde, IMSG_RECONF_ORIGIN_SET, 0, 0, -1,
677		    ps->name, sizeof(ps->name)) == -1)
678			return (-1);
679		RB_FOREACH_SAFE(roa, roa_tree, &ps->roaitems, nroa) {
680			RB_REMOVE(roa_tree, &ps->roaitems, roa);
681			if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_ITEM, 0, 0,
682			    -1, roa, sizeof(*roa)) == -1)
683				return (-1);
684			free(roa);
685		}
686		free(ps);
687	}
688
689	/* roa table and rtr config are sent to the RTR engine */
690	RB_FOREACH_SAFE(roa, roa_tree, &conf->roa, nroa) {
691		RB_REMOVE(roa_tree, &conf->roa, roa);
692		if (imsg_compose(ibuf_rtr, IMSG_RECONF_ROA_ITEM, 0, 0,
693		    -1, roa, sizeof(*roa)) == -1)
694			return (-1);
695		free(roa);
696	}
697	SIMPLEQ_FOREACH(rtr, &conf->rtrs, entry) {
698		if (imsg_compose(ibuf_rtr, IMSG_RECONF_RTR_CONFIG, rtr->id,
699		    0, -1, rtr->descr, sizeof(rtr->descr)) == -1)
700			return (-1);
701	}
702
703	/* as-sets for filters in the RDE */
704	while ((aset = SIMPLEQ_FIRST(&conf->as_sets)) != NULL) {
705		struct ibuf *wbuf;
706		uint32_t *as;
707		size_t i, l, n;
708
709		SIMPLEQ_REMOVE_HEAD(&conf->as_sets, entry);
710
711		as = set_get(aset->set, &n);
712		if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0,
713		    sizeof(n) + sizeof(aset->name))) == NULL)
714			return -1;
715		if (imsg_add(wbuf, &n, sizeof(n)) == -1 ||
716		    imsg_add(wbuf, aset->name, sizeof(aset->name)) == -1)
717			return -1;
718		imsg_close(ibuf_rde, wbuf);
719
720		for (i = 0; i < n; i += l) {
721			l = (n - i > 1024 ? 1024 : n - i);
722			if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_ITEMS,
723			    0, 0, -1, as + i, l * sizeof(*as)) == -1)
724				return -1;
725		}
726
727		if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_DONE, 0, 0, -1,
728		    NULL, 0) == -1)
729			return -1;
730
731		set_free(aset->set);
732		free(aset);
733	}
734
735	/* filters for the RDE */
736	while ((r = TAILQ_FIRST(conf->filters)) != NULL) {
737		TAILQ_REMOVE(conf->filters, r, entry);
738		if (send_filterset(ibuf_rde, &r->set) == -1)
739			return (-1);
740		if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
741		    r, sizeof(struct filter_rule)) == -1)
742			return (-1);
743		filterset_free(&r->set);
744		free(r);
745	}
746
747	while ((vpn = SIMPLEQ_FIRST(&conf->l3vpns)) != NULL) {
748		SIMPLEQ_REMOVE_HEAD(&conf->l3vpns, entry);
749		if (ktable_update(vpn->rtableid, vpn->descr, vpn->flags) ==
750		    -1) {
751			log_warnx("failed to load routing table %d",
752			    vpn->rtableid);
753			return (-1);
754		}
755		/* networks go via kroute to the RDE */
756		kr_net_reload(vpn->rtableid, vpn->rd, &vpn->net_l);
757
758		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN, 0, 0, -1,
759		    vpn, sizeof(*vpn)) == -1)
760			return (-1);
761
762		/* export targets */
763		if (send_filterset(ibuf_rde, &vpn->export) == -1)
764			return (-1);
765		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_EXPORT, 0, 0,
766		    -1, NULL, 0) == -1)
767			return (-1);
768		filterset_free(&vpn->export);
769
770		/* import targets */
771		if (send_filterset(ibuf_rde, &vpn->import) == -1)
772			return (-1);
773		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_IMPORT, 0, 0,
774		    -1, NULL, 0) == -1)
775			return (-1);
776		filterset_free(&vpn->import);
777
778		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_DONE, 0, 0,
779		    -1, NULL, 0) == -1)
780			return (-1);
781
782		free(vpn);
783	}
784
785	/* send a drain message to know when all messages where processed */
786	if (imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
787		return (-1);
788	if (imsg_compose(ibuf_rde, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
789		return (-1);
790	if (imsg_compose(ibuf_rtr, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
791		return (-1);
792
793	/* mrt changes can be sent out of bound */
794	mrt_reconfigure(conf->mrt);
795	return (0);
796}
797
798int
799dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf)
800{
801	struct imsg		 imsg;
802	struct peer		*p;
803	struct rtr_config	*r;
804	ssize_t			 n;
805	u_int			 rtableid;
806	int			 rv, verbose;
807
808	rv = 0;
809	while (ibuf) {
810		if ((n = imsg_get(ibuf, &imsg)) == -1)
811			return (-1);
812
813		if (n == 0)
814			break;
815
816		switch (imsg.hdr.type) {
817		case IMSG_KROUTE_CHANGE:
818			if (idx != PFD_PIPE_RDE)
819				log_warnx("route request not from RDE");
820			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
821			    sizeof(struct kroute_full))
822				log_warnx("wrong imsg len");
823			else if (kr_change(imsg.hdr.peerid, imsg.data))
824				rv = -1;
825			break;
826		case IMSG_KROUTE_DELETE:
827			if (idx != PFD_PIPE_RDE)
828				log_warnx("route request not from RDE");
829			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
830			    sizeof(struct kroute_full))
831				log_warnx("wrong imsg len");
832			else if (kr_delete(imsg.hdr.peerid, imsg.data))
833				rv = -1;
834			break;
835		case IMSG_KROUTE_FLUSH:
836			if (idx != PFD_PIPE_RDE)
837				log_warnx("route request not from RDE");
838			else if (imsg.hdr.len != IMSG_HEADER_SIZE)
839				log_warnx("wrong imsg len");
840			else if (kr_flush(imsg.hdr.peerid))
841				rv = -1;
842			break;
843		case IMSG_NEXTHOP_ADD:
844			if (idx != PFD_PIPE_RDE)
845				log_warnx("nexthop request not from RDE");
846			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
847			    sizeof(struct bgpd_addr))
848				log_warnx("wrong imsg len");
849			else {
850				rtableid = conf->default_tableid;
851				if (kr_nexthop_add(rtableid, imsg.data) == -1)
852					rv = -1;
853			}
854			break;
855		case IMSG_NEXTHOP_REMOVE:
856			if (idx != PFD_PIPE_RDE)
857				log_warnx("nexthop request not from RDE");
858			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
859			    sizeof(struct bgpd_addr))
860				log_warnx("wrong imsg len");
861			else {
862				rtableid = conf->default_tableid;
863				kr_nexthop_delete(rtableid, imsg.data);
864			}
865			break;
866		case IMSG_PFTABLE_ADD:
867			if (idx != PFD_PIPE_RDE)
868				log_warnx("pftable request not from RDE");
869			else
870				if (imsg.hdr.len != IMSG_HEADER_SIZE +
871				    sizeof(struct pftable_msg))
872					log_warnx("wrong imsg len");
873				else if (pftable_addr_add(imsg.data) != 0)
874					rv = -1;
875			break;
876		case IMSG_PFTABLE_REMOVE:
877			if (idx != PFD_PIPE_RDE)
878				log_warnx("pftable request not from RDE");
879			else
880				if (imsg.hdr.len != IMSG_HEADER_SIZE +
881				    sizeof(struct pftable_msg))
882					log_warnx("wrong imsg len");
883				else if (pftable_addr_remove(imsg.data) != 0)
884					rv = -1;
885			break;
886		case IMSG_PFTABLE_COMMIT:
887			if (idx != PFD_PIPE_RDE)
888				log_warnx("pftable request not from RDE");
889			else if (imsg.hdr.len != IMSG_HEADER_SIZE)
890				log_warnx("wrong imsg len");
891			else if (pftable_commit() != 0)
892				rv = -1;
893			break;
894		case IMSG_PFKEY_RELOAD:
895			if (idx != PFD_PIPE_SESSION) {
896				log_warnx("pfkey reload request not from SE");
897				break;
898			}
899			p = getpeerbyid(conf, imsg.hdr.peerid);
900			if (p != NULL) {
901				if (pfkey_establish(p) == -1)
902					log_peer_warnx(&p->conf,
903					    "pfkey setup failed");
904			}
905			break;
906		case IMSG_CTL_RELOAD:
907			if (idx != PFD_PIPE_SESSION)
908				log_warnx("reload request not from SE");
909			else {
910				reconfig = 1;
911				reconfpid = imsg.hdr.pid;
912				if (imsg.hdr.len == IMSG_HEADER_SIZE +
913				    REASON_LEN && ((char *)imsg.data)[0])
914					log_info("reload due to: %s",
915					    log_reason(imsg.data));
916			}
917			break;
918		case IMSG_CTL_FIB_COUPLE:
919			if (idx != PFD_PIPE_SESSION)
920				log_warnx("couple request not from SE");
921			else
922				kr_fib_couple(imsg.hdr.peerid);
923			break;
924		case IMSG_CTL_FIB_DECOUPLE:
925			if (idx != PFD_PIPE_SESSION)
926				log_warnx("decouple request not from SE");
927			else
928				kr_fib_decouple(imsg.hdr.peerid);
929			break;
930		case IMSG_CTL_KROUTE:
931		case IMSG_CTL_KROUTE_ADDR:
932		case IMSG_CTL_SHOW_NEXTHOP:
933		case IMSG_CTL_SHOW_INTERFACE:
934		case IMSG_CTL_SHOW_FIB_TABLES:
935			if (idx != PFD_PIPE_SESSION)
936				log_warnx("kroute request not from SE");
937			else
938				kr_show_route(&imsg);
939			break;
940		case IMSG_SESSION_DEPENDON:
941			if (idx != PFD_PIPE_SESSION)
942				log_warnx("DEPENDON request not from SE");
943			else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ)
944				log_warnx("DEPENDON request with wrong len");
945			else
946				kr_ifinfo(imsg.data);
947			break;
948		case IMSG_DEMOTE:
949			if (idx != PFD_PIPE_SESSION)
950				log_warnx("demote request not from SE");
951			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
952			    sizeof(struct demote_msg))
953				log_warnx("DEMOTE request with wrong len");
954			else {
955				struct demote_msg	*msg;
956
957				msg = imsg.data;
958				carp_demote_set(msg->demote_group, msg->level);
959			}
960			break;
961		case IMSG_CTL_LOG_VERBOSE:
962			/* already checked by SE */
963			memcpy(&verbose, imsg.data, sizeof(verbose));
964			log_setverbose(verbose);
965			break;
966		case IMSG_RECONF_DONE:
967			if (reconfpending == 0) {
968				log_warnx("unexpected RECONF_DONE received");
969				break;
970			}
971			if (idx == PFD_PIPE_SESSION) {
972				imsg_compose(ibuf_rtr, IMSG_RECONF_DONE, 0,
973				    0, -1, NULL, 0);
974			} else if (idx == PFD_PIPE_RTR) {
975				imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0,
976				    0, -1, NULL, 0);
977
978				/* finally fix kroute information */
979				ktable_postload();
980
981				/* redistribute list needs to be reloaded too */
982				kr_reload();
983			}
984			reconfpending--;
985			break;
986		case IMSG_RECONF_DRAIN:
987			if (reconfpending == 0) {
988				log_warnx("unexpected RECONF_DRAIN received");
989				break;
990			}
991			reconfpending--;
992			if (reconfpending == 0) {
993				/*
994				 * SE goes first to bring templated neighbors
995				 * in sync.
996				 */
997				imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0,
998				    0, -1, NULL, 0);
999				reconfpending = 3; /* expecting 2 DONE msg */
1000			}
1001			break;
1002		case IMSG_SOCKET_CONN:
1003			if (idx != PFD_PIPE_RTR) {
1004				log_warnx("connect request not from RTR");
1005			} else {
1006				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1007					if (imsg.hdr.peerid == r->id)
1008						break;
1009				}
1010				if (r == NULL)
1011					log_warnx("unknown rtr id %d",
1012					    imsg.hdr.peerid);
1013				else
1014					bgpd_rtr_connect(r);
1015			}
1016			break;
1017		case IMSG_CTL_SHOW_RTR:
1018			if (idx == PFD_PIPE_SESSION) {
1019				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1020					imsg_compose(ibuf_rtr, imsg.hdr.type,
1021					    r->id, imsg.hdr.pid, -1, NULL, 0);
1022				}
1023				imsg_compose(ibuf_rtr, IMSG_CTL_END,
1024				    0, imsg.hdr.pid, -1, NULL, 0);
1025			} else if (imsg.hdr.len != IMSG_HEADER_SIZE +
1026			    sizeof(struct ctl_show_rtr)) {
1027				log_warnx("IMSG_CTL_SHOW_RTR with wrong len");
1028			} else if (idx == PFD_PIPE_RTR) {
1029				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1030					if (imsg.hdr.peerid == r->id)
1031						break;
1032				}
1033				if (r != NULL) {
1034					struct ctl_show_rtr *msg;
1035					msg = imsg.data;
1036					strlcpy(msg->descr, r->descr,
1037					    sizeof(msg->descr));
1038					msg->local_addr = r->local_addr;
1039					msg->remote_addr = r->remote_addr;
1040					msg->remote_port = r->remote_port;
1041
1042					imsg_compose(ibuf_se, imsg.hdr.type,
1043					    imsg.hdr.peerid, imsg.hdr.pid,
1044					    -1, imsg.data,
1045					    imsg.hdr.len - IMSG_HEADER_SIZE);
1046				}
1047			}
1048			break;
1049		case IMSG_CTL_END:
1050		case IMSG_CTL_SHOW_TIMER:
1051			if (idx != PFD_PIPE_RTR) {
1052				log_warnx("connect request not from RTR");
1053				break;
1054			}
1055			imsg_compose(ibuf_se, imsg.hdr.type, imsg.hdr.peerid,
1056			    imsg.hdr.pid, -1, imsg.data,
1057			    imsg.hdr.len - IMSG_HEADER_SIZE);
1058			break;
1059		default:
1060			break;
1061		}
1062		imsg_free(&imsg);
1063		if (rv != 0)
1064			return (rv);
1065	}
1066	return (0);
1067}
1068
1069void
1070send_nexthop_update(struct kroute_nexthop *msg)
1071{
1072	char	*gw = NULL;
1073
1074	if (msg->gateway.aid)
1075		if (asprintf(&gw, ": via %s",
1076		    log_addr(&msg->gateway)) == -1) {
1077			log_warn("send_nexthop_update");
1078			quit = 1;
1079		}
1080
1081	log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
1082	    msg->valid ? "valid" : "invalid",
1083	    msg->connected ? ": directly connected" : "",
1084	    msg->gateway.aid ? gw : "");
1085
1086	free(gw);
1087
1088	if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1,
1089	    msg, sizeof(struct kroute_nexthop)) == -1)
1090		quit = 1;
1091}
1092
1093void
1094send_imsg_session(int type, pid_t pid, void *data, uint16_t datalen)
1095{
1096	imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen);
1097}
1098
1099int
1100send_network(int type, struct network_config *net, struct filter_set_head *h)
1101{
1102	if (quit)
1103		return (0);
1104	if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
1105	    sizeof(struct network_config)) == -1)
1106		return (-1);
1107	/* networks that get deleted don't need to send the filter set */
1108	if (type == IMSG_NETWORK_REMOVE)
1109		return (0);
1110	if (send_filterset(ibuf_rde, h) == -1)
1111		return (-1);
1112	if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
1113		return (-1);
1114
1115	return (0);
1116}
1117
1118/*
1119 * Return true if a route can be used for nexthop resolution.
1120 */
1121int
1122bgpd_oknexthop(struct kroute_full *kf)
1123{
1124	if (kf->flags & F_BGPD)
1125		return ((cflags & BGPD_FLAG_NEXTHOP_BGP) != 0);
1126
1127	if (kf->prefixlen == 0)
1128		return ((cflags & BGPD_FLAG_NEXTHOP_DEFAULT) != 0);
1129
1130	/* any other route is fine */
1131	return (1);
1132}
1133
1134int
1135control_setup(struct bgpd_config *conf)
1136{
1137	int fd, restricted;
1138
1139	/* control socket is outside chroot */
1140	if (!cname || strcmp(cname, conf->csock)) {
1141		if (cname) {
1142			free(cname);
1143		}
1144		if ((cname = strdup(conf->csock)) == NULL)
1145			fatal("strdup");
1146		if (control_check(cname) == -1)
1147			return (-1);
1148		if ((fd = control_init(0, cname)) == -1)
1149			fatalx("control socket setup failed");
1150		if (control_listen(fd) == -1)
1151			fatalx("control socket setup failed");
1152		restricted = 0;
1153		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
1154		    &restricted, sizeof(restricted)) == -1)
1155			return (-1);
1156	}
1157	if (!conf->rcsock) {
1158		/* remove restricted socket */
1159		free(rcname);
1160		rcname = NULL;
1161	} else if (!rcname || strcmp(rcname, conf->rcsock)) {
1162		if (rcname) {
1163			free(rcname);
1164		}
1165		if ((rcname = strdup(conf->rcsock)) == NULL)
1166			fatal("strdup");
1167		if (control_check(rcname) == -1)
1168			return (-1);
1169		if ((fd = control_init(1, rcname)) == -1)
1170			fatalx("control socket setup failed");
1171		if (control_listen(fd) == -1)
1172			fatalx("control socket setup failed");
1173		restricted = 1;
1174		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
1175		    &restricted, sizeof(restricted)) == -1)
1176			return (-1);
1177	}
1178	return (0);
1179}
1180
1181void
1182set_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1183{
1184	if (i == NULL || i->fd == -1) {
1185		pfd->fd = -1;
1186		return;
1187	}
1188	pfd->fd = i->fd;
1189	pfd->events = POLLIN;
1190	if (i->w.queued > 0)
1191		pfd->events |= POLLOUT;
1192}
1193
1194int
1195handle_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1196{
1197	ssize_t n;
1198
1199	if (i == NULL)
1200		return (0);
1201
1202	if (pfd->revents & POLLOUT)
1203		if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) {
1204			log_warn("imsg write error");
1205			close(i->fd);
1206			i->fd = -1;
1207			return (-1);
1208		}
1209
1210	if (pfd->revents & POLLIN) {
1211		if ((n = imsg_read(i)) == -1 && errno != EAGAIN) {
1212			log_warn("imsg read error");
1213			close(i->fd);
1214			i->fd = -1;
1215			return (-1);
1216		}
1217		if (n == 0) {
1218			log_warnx("peer closed imsg connection");
1219			close(i->fd);
1220			i->fd = -1;
1221			return (-1);
1222		}
1223	}
1224	return (0);
1225}
1226
1227static void
1228getsockpair(int pipe[2])
1229{
1230	int bsize, i;
1231
1232	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1233	    PF_UNSPEC, pipe) == -1)
1234		fatal("socketpair");
1235
1236	for (i = 0; i < 2; i++) {
1237		for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) {
1238			if (setsockopt(pipe[i], SOL_SOCKET, SO_RCVBUF,
1239			    &bsize, sizeof(bsize)) == -1) {
1240				if (errno != ENOBUFS)
1241					fatal("setsockopt(SO_RCVBUF, %d)",
1242					    bsize);
1243				log_warn("setsockopt(SO_RCVBUF, %d)", bsize);
1244				continue;
1245			}
1246			break;
1247		}
1248	}
1249	for (i = 0; i < 2; i++) {
1250		for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) {
1251			if (setsockopt(pipe[i], SOL_SOCKET, SO_SNDBUF,
1252			    &bsize, sizeof(bsize)) == -1) {
1253				if (errno != ENOBUFS)
1254					fatal("setsockopt(SO_SNDBUF, %d)",
1255					    bsize);
1256				log_warn("setsockopt(SO_SNDBUF, %d)", bsize);
1257				continue;
1258			}
1259			break;
1260		}
1261	}
1262}
1263
1264int
1265imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde, struct imsgbuf *roa)
1266{
1267	int pipe_s2r[2];
1268	int pipe_s2r_ctl[2];
1269	int pipe_r2r[2];
1270
1271	getsockpair(pipe_s2r);
1272	getsockpair(pipe_s2r_ctl);
1273	getsockpair(pipe_r2r);
1274
1275	if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0],
1276	    NULL, 0) == -1)
1277		return (-1);
1278	if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1],
1279	    NULL, 0) == -1)
1280		return (-1);
1281
1282	if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0],
1283	    NULL, 0) == -1)
1284		return (-1);
1285	if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1],
1286	    NULL, 0) == -1)
1287		return (-1);
1288
1289	if (imsg_compose(roa, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[0],
1290	    NULL, 0) == -1)
1291		return (-1);
1292	if (imsg_compose(rde, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[1],
1293	    NULL, 0) == -1)
1294		return (-1);
1295
1296	return (0);
1297}
1298
1299void
1300bgpd_rtr_connect(struct rtr_config *r)
1301{
1302	struct connect_elm *ce;
1303	struct sockaddr *sa;
1304	socklen_t len;
1305
1306	if (connect_cnt >= MAX_CONNECT_CNT) {
1307		log_warnx("rtr %s: too many concurrent connection requests",
1308		    r->descr);
1309		return;
1310	}
1311
1312	if ((ce = calloc(1, sizeof(*ce))) == NULL) {
1313		log_warn("rtr %s", r->descr);
1314		return;
1315	}
1316
1317	ce->id = r->id;
1318	ce->fd = socket(aid2af(r->remote_addr.aid),
1319	     SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_TCP);
1320	if (ce->fd == -1) {
1321		log_warn("rtr %s", r->descr);
1322		free(ce);
1323		return;
1324	}
1325
1326	if ((sa = addr2sa(&r->local_addr, 0, &len)) != NULL) {
1327		if (bind(ce->fd, sa, len) == -1) {
1328			log_warn("rtr %s: bind to %s", r->descr,
1329			    log_addr(&r->local_addr));
1330			close(ce->fd);
1331			free(ce);
1332			return;
1333		}
1334	}
1335
1336	sa = addr2sa(&r->remote_addr, r->remote_port, &len);
1337	if (connect(ce->fd, sa, len) == -1) {
1338		if (errno != EINPROGRESS) {
1339			log_warn("rtr %s: connect to %s:%u", r->descr,
1340			    log_addr(&r->remote_addr), r->remote_port);
1341			close(ce->fd);
1342			free(ce);
1343			return;
1344		}
1345		TAILQ_INSERT_TAIL(&connect_queue, ce, entry);
1346		connect_cnt++;
1347		return;
1348	}
1349
1350	imsg_compose(ibuf_rtr, IMSG_SOCKET_CONN, ce->id, 0, ce->fd, NULL, 0);
1351	free(ce);
1352}
1353
1354void
1355bgpd_rtr_connect_done(int fd, struct bgpd_config *conf)
1356{
1357	struct rtr_config *r;
1358	struct connect_elm *ce;
1359	int error = 0;
1360	socklen_t len;
1361
1362	TAILQ_FOREACH(ce, &connect_queue, entry) {
1363		if (ce->fd == fd)
1364			break;
1365	}
1366	if (ce == NULL)
1367		fatalx("connect entry not found");
1368
1369	TAILQ_REMOVE(&connect_queue, ce, entry);
1370	connect_cnt--;
1371
1372	SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1373		if (ce->id == r->id)
1374			break;
1375	}
1376	if (r == NULL) {
1377		log_warnx("rtr id %d no longer exists", ce->id);
1378		goto fail;
1379	}
1380
1381	len = sizeof(error);
1382	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
1383		log_warn("rtr %s: getsockopt SO_ERROR", r->descr);
1384		goto fail;
1385	}
1386
1387	if (error != 0) {
1388		errno = error;
1389		log_warn("rtr %s: connect to %s:%u", r->descr,
1390		    log_addr(&r->remote_addr), r->remote_port);
1391		goto fail;
1392	}
1393
1394	imsg_compose(ibuf_rtr, IMSG_SOCKET_CONN, ce->id, 0, ce->fd, NULL, 0);
1395	free(ce);
1396	return;
1397
1398fail:
1399	close(fd);
1400	free(ce);
1401}
1402