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