xref: /openbsd-src/usr.sbin/bgpd/bgpd.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: bgpd.c,v 1.187 2016/09/03 16:22:17 renato 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 <unistd.h>
34 
35 #include "bgpd.h"
36 #include "mrt.h"
37 #include "session.h"
38 
39 void		sighdlr(int);
40 __dead void	usage(void);
41 int		main(int, char *[]);
42 pid_t		start_child(enum bgpd_process, char *, int, int, int);
43 int		send_filterset(struct imsgbuf *, struct filter_set_head *);
44 int		reconfigure(char *, struct bgpd_config *, struct peer **);
45 int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
46 int		control_setup(struct bgpd_config *);
47 int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *);
48 
49 int			 rfd = -1;
50 int			 cflags;
51 volatile sig_atomic_t	 mrtdump;
52 volatile sig_atomic_t	 quit;
53 volatile sig_atomic_t	 reconfig;
54 pid_t			 reconfpid;
55 int			 reconfpending;
56 struct imsgbuf		*ibuf_se;
57 struct imsgbuf		*ibuf_rde;
58 struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
59 char			*cname;
60 char			*rcname;
61 
62 void
63 sighdlr(int sig)
64 {
65 	switch (sig) {
66 	case SIGTERM:
67 	case SIGINT:
68 		quit = 1;
69 		break;
70 	case SIGHUP:
71 		reconfig = 1;
72 		break;
73 	case SIGALRM:
74 	case SIGUSR1:
75 		mrtdump = 1;
76 		break;
77 	}
78 }
79 
80 __dead void
81 usage(void)
82 {
83 	extern char *__progname;
84 
85 	fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n",
86 	    __progname);
87 	exit(1);
88 }
89 
90 #define PFD_PIPE_SESSION	0
91 #define PFD_PIPE_ROUTE		1
92 #define PFD_SOCK_ROUTE		2
93 #define POLL_MAX		3
94 #define MAX_TIMEOUT		3600
95 
96 int	 cmd_opts;
97 
98 int
99 main(int argc, char *argv[])
100 {
101 	struct bgpd_config	*conf;
102 	struct peer		*peer_l, *p;
103 	struct pollfd		 pfd[POLL_MAX];
104 	pid_t			 io_pid = 0, rde_pid = 0, pid;
105 	char			*conffile;
106 	char			*saved_argv0;
107 	int			 debug = 0;
108 	int			 rflag = 0, sflag = 0;
109 	int			 ch, timeout, status;
110 	int			 pipe_m2s[2];
111 	int			 pipe_m2r[2];
112 
113 	conffile = CONFFILE;
114 	bgpd_process = PROC_MAIN;
115 	log_procname = log_procnames[bgpd_process];
116 
117 	log_init(1);		/* log to stderr until daemonized */
118 	log_verbose(1);
119 
120 	saved_argv0 = argv[0];
121 	if (saved_argv0 == NULL)
122 		saved_argv0 = "bgpd";
123 
124 	conf = new_config();
125 	peer_l = NULL;
126 
127 	while ((ch = getopt(argc, argv, "cdD:f:nRSv")) != -1) {
128 		switch (ch) {
129 		case 'c':
130 			cmd_opts |= BGPD_OPT_FORCE_DEMOTE;
131 			break;
132 		case 'd':
133 			debug = 1;
134 			break;
135 		case 'D':
136 			if (cmdline_symset(optarg) < 0)
137 				log_warnx("could not parse macro definition %s",
138 				    optarg);
139 			break;
140 		case 'f':
141 			conffile = optarg;
142 			break;
143 		case 'n':
144 			cmd_opts |= BGPD_OPT_NOACTION;
145 			break;
146 		case 'v':
147 			if (cmd_opts & BGPD_OPT_VERBOSE)
148 				cmd_opts |= BGPD_OPT_VERBOSE2;
149 			cmd_opts |= BGPD_OPT_VERBOSE;
150 			log_verbose(1);
151 			break;
152 		case 'R':
153 			rflag = 1;
154 			break;
155 		case 'S':
156 			sflag = 1;
157 			break;
158 		default:
159 			usage();
160 			/* NOTREACHED */
161 		}
162 	}
163 
164 	argc -= optind;
165 	argv += optind;
166 	if (argc > 0 || (sflag && rflag))
167 		usage();
168 
169 	if (cmd_opts & BGPD_OPT_NOACTION) {
170 		if (parse_config(conffile, conf, &peer_l))
171 			exit(1);
172 
173 		if (cmd_opts & BGPD_OPT_VERBOSE)
174 			print_config(conf, &ribnames, &conf->networks, peer_l,
175 			    conf->filters, conf->mrt, &conf->rdomains);
176 		else
177 			fprintf(stderr, "configuration OK\n");
178 		exit(0);
179 	}
180 
181 	if (rflag)
182 		rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
183 	else if (sflag)
184 		session_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
185 
186 	if (geteuid())
187 		errx(1, "need root privileges");
188 
189 	if (getpwnam(BGPD_USER) == NULL)
190 		errx(1, "unknown user %s", BGPD_USER);
191 
192 	log_init(debug);
193 	log_verbose(cmd_opts & BGPD_OPT_VERBOSE);
194 
195 	if (!debug)
196 		daemon(1, 0);
197 
198 	log_info("startup");
199 
200 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
201 	    PF_UNSPEC, pipe_m2s) == -1)
202 		fatal("socketpair");
203 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
204 	    PF_UNSPEC, pipe_m2r) == -1)
205 		fatal("socketpair");
206 
207 	/* fork children */
208 	rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug,
209 	    cmd_opts & BGPD_OPT_VERBOSE);
210 	io_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug,
211 	    cmd_opts & BGPD_OPT_VERBOSE);
212 
213 	signal(SIGTERM, sighdlr);
214 	signal(SIGINT, sighdlr);
215 	signal(SIGHUP, sighdlr);
216 	signal(SIGALRM, sighdlr);
217 	signal(SIGUSR1, sighdlr);
218 	signal(SIGPIPE, SIG_IGN);
219 
220 	if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL ||
221 	    (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL)
222 		fatal(NULL);
223 	imsg_init(ibuf_se, pipe_m2s[0]);
224 	imsg_init(ibuf_rde, pipe_m2r[0]);
225 	mrt_init(ibuf_rde, ibuf_se);
226 	if ((rfd = kr_init()) == -1)
227 		quit = 1;
228 
229 	/*
230 	 * rpath, read config file
231 	 * cpath, unlink control socket
232 	 * fattr, chmod on control socket
233 	 * wpath, needed if we are doing mrt dumps
234 	 *
235 	 * pledge placed here because kr_init() does a setsockopt on the
236 	 * routing socket thats not allowed at all.
237 	 */
238 #if 0
239 	/*
240 	 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR
241 	 * this needs some redesign of bgpd to be fixed.
242 	 */
243 	if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd",
244 	    NULL) == -1)
245 		fatal("pledge");
246 #endif
247 
248 	if (imsg_send_sockets(ibuf_se, ibuf_rde))
249 		fatal("could not establish imsg links");
250 	quit = reconfigure(conffile, conf, &peer_l);
251 	if (pftable_clear_all() != 0)
252 		quit = 1;
253 
254 	while (quit == 0) {
255 		bzero(pfd, sizeof(pfd));
256 
257 		set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se);
258 		set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde);
259 
260 		pfd[PFD_SOCK_ROUTE].fd = rfd;
261 		pfd[PFD_SOCK_ROUTE].events = POLLIN;
262 
263 		timeout = mrt_timeout(conf->mrt);
264 		if (timeout > MAX_TIMEOUT)
265 			timeout = MAX_TIMEOUT;
266 
267 		if (poll(pfd, POLL_MAX, timeout * 1000) == -1)
268 			if (errno != EINTR) {
269 				log_warn("poll error");
270 				quit = 1;
271 			}
272 
273 		if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) {
274 			log_warnx("main: Lost connection to SE");
275 			msgbuf_clear(&ibuf_se->w);
276 			free(ibuf_se);
277 			ibuf_se = NULL;
278 			quit = 1;
279 		} else {
280 			if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) ==
281 			    -1)
282 				quit = 1;
283 		}
284 
285 		if (handle_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde) == -1) {
286 			log_warnx("main: Lost connection to RDE");
287 			msgbuf_clear(&ibuf_rde->w);
288 			free(ibuf_rde);
289 			ibuf_rde = NULL;
290 			quit = 1;
291 		} else {
292 			if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, conf) ==
293 			    -1)
294 				quit = 1;
295 		}
296 
297 		if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
298 			if (kr_dispatch_msg() == -1)
299 				quit = 1;
300 		}
301 
302 		if (reconfig) {
303 			u_int	error;
304 
305 			reconfig = 0;
306 			switch (reconfigure(conffile, conf, &peer_l)) {
307 			case -1:	/* fatal error */
308 				quit = 1;
309 				break;
310 			case 0:		/* all OK */
311 				error = 0;
312 				break;
313 			case 2:
314 				error = CTL_RES_PENDING;
315 				break;
316 			default:	/* parse error */
317 				error = CTL_RES_PARSE_ERROR;
318 				break;
319 			}
320 			if (reconfpid != 0) {
321 				send_imsg_session(IMSG_CTL_RESULT, reconfpid,
322 				    &error, sizeof(error));
323 				reconfpid = 0;
324 			}
325 		}
326 
327 		if (mrtdump) {
328 			mrtdump = 0;
329 			mrt_handler(conf->mrt);
330 		}
331 	}
332 
333 	/* close pipes */
334 	if (ibuf_se) {
335 		msgbuf_clear(&ibuf_se->w);
336 		close(ibuf_se->fd);
337 		free(ibuf_se);
338 	}
339 	if (ibuf_rde) {
340 		msgbuf_clear(&ibuf_rde->w);
341 		close(ibuf_rde->fd);
342 		free(ibuf_rde);
343 	}
344 
345 	while ((p = peer_l) != NULL) {
346 		peer_l = p->next;
347 		free(p);
348 	}
349 
350 	control_cleanup(conf->csock);
351 	control_cleanup(conf->rcsock);
352 	carp_demote_shutdown();
353 	kr_shutdown(conf->fib_priority);
354 	pftable_clear_all();
355 
356 	free_config(conf);
357 
358 	log_debug("waiting for children to terminate");
359 	do {
360 		pid = wait(&status);
361 		if (pid == -1) {
362 			if (errno != EINTR && errno != ECHILD)
363 				fatal("wait");
364 		} else if (WIFSIGNALED(status))
365 			log_warnx("%s terminated; signal %d",
366 			    (pid == rde_pid) ? "route decision engine" :
367 			    "session engine", WTERMSIG(status));
368 	} while (pid != -1 || (pid == -1 && errno == EINTR));
369 
370 	free(rcname);
371 	free(cname);
372 
373 	log_info("terminating");
374 	return (0);
375 }
376 
377 pid_t
378 start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose)
379 {
380 	char *argv[5];
381 	int argc = 0;
382 	pid_t pid;
383 
384 	switch (pid = fork()) {
385 	case -1:
386 		fatal("cannot fork");
387 	case 0:
388 		break;
389 	default:
390 		close(fd);
391 		return (pid);
392 	}
393 
394 	if (dup2(fd, 3) == -1)
395 		fatal("cannot setup imsg fd");
396 
397 	argv[argc++] = argv0;
398 	switch (p) {
399 	case PROC_MAIN:
400 		fatalx("Can not start main process");
401 	case PROC_RDE:
402 		argv[argc++] = "-R";
403 		break;
404 	case PROC_SE:
405 		argv[argc++] = "-S";
406 		break;
407 	}
408 	if (debug)
409 		argv[argc++] = "-d";
410 	if (verbose)
411 		argv[argc++] = "-v";
412 	argv[argc++] = NULL;
413 
414 	execvp(argv0, argv);
415 	fatal("execvp");
416 }
417 
418 int
419 send_filterset(struct imsgbuf *i, struct filter_set_head *set)
420 {
421 	struct filter_set	*s;
422 
423 	TAILQ_FOREACH(s, set, entry)
424 		if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s,
425 		    sizeof(struct filter_set)) == -1)
426 			return (-1);
427 	return (0);
428 }
429 
430 int
431 reconfigure(char *conffile, struct bgpd_config *conf, struct peer **peer_l)
432 {
433 	struct peer		*p;
434 	struct filter_rule	*r;
435 	struct listen_addr	*la;
436 	struct rde_rib		*rr;
437 	struct rdomain		*rd;
438 
439 	if (reconfpending) {
440 		log_info("previous reload still running");
441 		return (2);
442 	}
443 	reconfpending = 2;	/* one per child */
444 
445 	log_info("rereading config");
446 	if (parse_config(conffile, conf, peer_l)) {
447 		log_warnx("config file %s has errors, not reloading",
448 		    conffile);
449 		reconfpending = 0;
450 		return (1);
451 	}
452 
453 	cflags = conf->flags;
454 	prepare_listeners(conf);
455 
456 	/* start reconfiguration */
457 	if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1,
458 	    conf, sizeof(struct bgpd_config)) == -1)
459 		return (-1);
460 	if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1,
461 	    conf, sizeof(struct bgpd_config)) == -1)
462 		return (-1);
463 
464 	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
465 		if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
466 		    la, sizeof(struct listen_addr)) == -1)
467 			return (-1);
468 		la->fd = -1;
469 	}
470 
471 	if (control_setup(conf) == -1)
472 		return (-1);
473 
474 	/* adjust fib syncing on reload */
475 	ktable_preload();
476 
477 	/* RIBs for the RDE */
478 	while ((rr = SIMPLEQ_FIRST(&ribnames))) {
479 		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
480 		if (ktable_update(rr->rtableid, rr->name, NULL,
481 		    rr->flags, conf->fib_priority) == -1) {
482 			log_warnx("failed to load rdomain %d",
483 			    rr->rtableid);
484 			return (-1);
485 		}
486 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1,
487 		    rr, sizeof(struct rde_rib)) == -1)
488 			return (-1);
489 		free(rr);
490 	}
491 
492 	/* send peer list to the SE */
493 	for (p = *peer_l; p != NULL; p = p->next) {
494 		if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
495 		    &p->conf, sizeof(struct peer_config)) == -1)
496 			return (-1);
497 	}
498 
499 	/* networks go via kroute to the RDE */
500 	if (kr_net_reload(0, &conf->networks))
501 		return (-1);
502 
503 	/* filters for the RDE */
504 	while ((r = TAILQ_FIRST(conf->filters)) != NULL) {
505 		TAILQ_REMOVE(conf->filters, r, entry);
506 		if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
507 		    r, sizeof(struct filter_rule)) == -1)
508 			return (-1);
509 		if (send_filterset(ibuf_rde, &r->set) == -1)
510 			return (-1);
511 		filterset_free(&r->set);
512 		free(r);
513 	}
514 
515 	while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) {
516 		SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry);
517 		if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe,
518 		    rd->flags, conf->fib_priority) == -1) {
519 			log_warnx("failed to load rdomain %d",
520 			    rd->rtableid);
521 			return (-1);
522 		}
523 		/* networks go via kroute to the RDE */
524 		if (kr_net_reload(rd->rtableid, &rd->net_l))
525 			return (-1);
526 
527 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN, 0, 0, -1,
528 		    rd, sizeof(*rd)) == -1)
529 			return (-1);
530 
531 		/* export targets */
532 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_EXPORT, 0, 0,
533 		    -1, NULL, 0) == -1)
534 			return (-1);
535 		if (send_filterset(ibuf_rde, &rd->export) == -1)
536 			return (-1);
537 		filterset_free(&rd->export);
538 
539 		/* import targets */
540 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_IMPORT, 0, 0,
541 		    -1, NULL, 0) == -1)
542 			return (-1);
543 		if (send_filterset(ibuf_rde, &rd->import) == -1)
544 			return (-1);
545 		filterset_free(&rd->import);
546 
547 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_DONE, 0, 0,
548 		    -1, NULL, 0) == -1)
549 			return (-1);
550 
551 		free(rd);
552 	}
553 
554 	/* signal the SE first then the RDE to activate the new config */
555 	if (imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1)
556 		return (-1);
557 
558 	/* mrt changes can be sent out of bound */
559 	mrt_reconfigure(conf->mrt);
560 	return (0);
561 }
562 
563 int
564 dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf)
565 {
566 	struct imsg		 imsg;
567 	ssize_t			 n;
568 	int			 rv, verbose;
569 
570 	rv = 0;
571 	while (ibuf) {
572 		if ((n = imsg_get(ibuf, &imsg)) == -1)
573 			return (-1);
574 
575 		if (n == 0)
576 			break;
577 
578 		switch (imsg.hdr.type) {
579 		case IMSG_KROUTE_CHANGE:
580 			if (idx != PFD_PIPE_ROUTE)
581 				log_warnx("route request not from RDE");
582 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
583 			    sizeof(struct kroute_full))
584 				log_warnx("wrong imsg len");
585 			else if (kr_change(imsg.hdr.peerid, imsg.data,
586 			    conf->fib_priority))
587 				rv = -1;
588 			break;
589 		case IMSG_KROUTE_DELETE:
590 			if (idx != PFD_PIPE_ROUTE)
591 				log_warnx("route request not from RDE");
592 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
593 			    sizeof(struct kroute_full))
594 				log_warnx("wrong imsg len");
595 			else if (kr_delete(imsg.hdr.peerid, imsg.data,
596 			    conf->fib_priority))
597 				rv = -1;
598 			break;
599 		case IMSG_NEXTHOP_ADD:
600 			if (idx != PFD_PIPE_ROUTE)
601 				log_warnx("nexthop request not from RDE");
602 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
603 			    sizeof(struct bgpd_addr))
604 				log_warnx("wrong imsg len");
605 			else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data) ==
606 			    -1)
607 				rv = -1;
608 			break;
609 		case IMSG_NEXTHOP_REMOVE:
610 			if (idx != PFD_PIPE_ROUTE)
611 				log_warnx("nexthop request not from RDE");
612 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
613 			    sizeof(struct bgpd_addr))
614 				log_warnx("wrong imsg len");
615 			else
616 				kr_nexthop_delete(imsg.hdr.peerid, imsg.data);
617 			break;
618 		case IMSG_PFTABLE_ADD:
619 			if (idx != PFD_PIPE_ROUTE)
620 				log_warnx("pftable request not from RDE");
621 			else
622 				if (imsg.hdr.len != IMSG_HEADER_SIZE +
623 				    sizeof(struct pftable_msg))
624 					log_warnx("wrong imsg len");
625 				else if (pftable_addr_add(imsg.data) != 0)
626 					rv = -1;
627 			break;
628 		case IMSG_PFTABLE_REMOVE:
629 			if (idx != PFD_PIPE_ROUTE)
630 				log_warnx("pftable request not from RDE");
631 			else
632 				if (imsg.hdr.len != IMSG_HEADER_SIZE +
633 				    sizeof(struct pftable_msg))
634 					log_warnx("wrong imsg len");
635 				else if (pftable_addr_remove(imsg.data) != 0)
636 					rv = -1;
637 			break;
638 		case IMSG_PFTABLE_COMMIT:
639 			if (idx != PFD_PIPE_ROUTE)
640 				log_warnx("pftable request not from RDE");
641 			else
642 				if (imsg.hdr.len != IMSG_HEADER_SIZE)
643 					log_warnx("wrong imsg len");
644 				else if (pftable_commit() != 0)
645 					rv = -1;
646 			break;
647 		case IMSG_CTL_RELOAD:
648 			if (idx != PFD_PIPE_SESSION)
649 				log_warnx("reload request not from SE");
650 			else {
651 				reconfig = 1;
652 				reconfpid = imsg.hdr.pid;
653 			}
654 			break;
655 		case IMSG_CTL_FIB_COUPLE:
656 			if (idx != PFD_PIPE_SESSION)
657 				log_warnx("couple request not from SE");
658 			else
659 				kr_fib_couple(imsg.hdr.peerid,
660 				    conf->fib_priority);
661 			break;
662 		case IMSG_CTL_FIB_DECOUPLE:
663 			if (idx != PFD_PIPE_SESSION)
664 				log_warnx("decouple request not from SE");
665 			else
666 				kr_fib_decouple(imsg.hdr.peerid,
667 				    conf->fib_priority);
668 			break;
669 		case IMSG_CTL_KROUTE:
670 		case IMSG_CTL_KROUTE_ADDR:
671 		case IMSG_CTL_SHOW_NEXTHOP:
672 		case IMSG_CTL_SHOW_INTERFACE:
673 		case IMSG_CTL_SHOW_FIB_TABLES:
674 			if (idx != PFD_PIPE_SESSION)
675 				log_warnx("kroute request not from SE");
676 			else
677 				kr_show_route(&imsg);
678 			break;
679 		case IMSG_IFINFO:
680 			if (idx != PFD_PIPE_SESSION)
681 				log_warnx("IFINFO request not from SE");
682 			else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ)
683 				log_warnx("IFINFO request with wrong len");
684 			else
685 				kr_ifinfo(imsg.data);
686 			break;
687 		case IMSG_DEMOTE:
688 			if (idx != PFD_PIPE_SESSION)
689 				log_warnx("demote request not from SE");
690 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
691 			    sizeof(struct demote_msg))
692 				log_warnx("DEMOTE request with wrong len");
693 			else {
694 				struct demote_msg	*msg;
695 
696 				msg = imsg.data;
697 				carp_demote_set(msg->demote_group, msg->level);
698 			}
699 			break;
700 		case IMSG_CTL_LOG_VERBOSE:
701 			/* already checked by SE */
702 			memcpy(&verbose, imsg.data, sizeof(verbose));
703 			log_verbose(verbose);
704 			break;
705 		case IMSG_RECONF_DONE:
706 			if (reconfpending == 0)
707 				log_warnx("unexpected RECONF_DONE received");
708 			else if (reconfpending == 2) {
709 				imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0,
710 				    0, -1, NULL, 0);
711 
712 				/* finally fix kroute information */
713 				ktable_postload(conf->fib_priority);
714 
715 				/* redistribute list needs to be reloaded too */
716 				kr_reload();
717 			}
718 			reconfpending--;
719 			break;
720 		default:
721 			break;
722 		}
723 		imsg_free(&imsg);
724 		if (rv != 0)
725 			return (rv);
726 	}
727 	return (0);
728 }
729 
730 void
731 send_nexthop_update(struct kroute_nexthop *msg)
732 {
733 	char	*gw = NULL;
734 
735 	if (msg->gateway.aid)
736 		if (asprintf(&gw, ": via %s",
737 		    log_addr(&msg->gateway)) == -1) {
738 			log_warn("send_nexthop_update");
739 			quit = 1;
740 		}
741 
742 	log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
743 	    msg->valid ? "valid" : "invalid",
744 	    msg->connected ? ": directly connected" : "",
745 	    msg->gateway.aid ? gw : "");
746 
747 	free(gw);
748 
749 	if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1,
750 	    msg, sizeof(struct kroute_nexthop)) == -1)
751 		quit = 1;
752 }
753 
754 void
755 send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen)
756 {
757 	imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen);
758 }
759 
760 int
761 send_network(int type, struct network_config *net, struct filter_set_head *h)
762 {
763 	if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
764 	    sizeof(struct network_config)) == -1)
765 		return (-1);
766 	/* networks that get deleted don't need to send the filter set */
767 	if (type == IMSG_NETWORK_REMOVE)
768 		return (0);
769 	if (send_filterset(ibuf_rde, h) == -1)
770 		return (-1);
771 	if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
772 		return (-1);
773 
774 	return (0);
775 }
776 
777 int
778 bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6)
779 {
780 	/* kernel routes are never filtered */
781 	if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0)
782 		return (0);
783 	if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0)
784 		return (0);
785 
786 	if (cflags & BGPD_FLAG_NEXTHOP_BGP) {
787 		if (kr && kr->flags & F_BGPD_INSERTED)
788 			return (0);
789 		if (kr6 && kr6->flags & F_BGPD_INSERTED)
790 			return (0);
791 	}
792 
793 	if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) {
794 		if (kr && kr->prefixlen == 0)
795 			return (0);
796 		if (kr6 && kr6->prefixlen == 0)
797 			return (0);
798 	}
799 
800 	return (1);
801 }
802 
803 int
804 control_setup(struct bgpd_config *conf)
805 {
806 	int fd, restricted;
807 
808 	/* control socket is outside chroot */
809 	if (!cname || strcmp(cname, conf->csock)) {
810 		if (cname) {
811 			control_cleanup(cname);
812 			free(cname);
813 		}
814 		if ((cname = strdup(conf->csock)) == NULL)
815 			fatal("strdup");
816 		if ((fd = control_init(0, cname)) == -1)
817 			fatalx("control socket setup failed");
818 		if (control_listen(fd) == -1)
819 			fatalx("control socket setup failed");
820 		restricted = 0;
821 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
822 		    &restricted, sizeof(restricted)) == -1)
823 			return (-1);
824 	}
825 	if (!conf->rcsock) {
826 		/* remove restricted socket */
827 		control_cleanup(rcname);
828 		free(rcname);
829 		rcname = NULL;
830 	} else if (!rcname || strcmp(rcname, conf->rcsock)) {
831 		if (rcname) {
832 			control_cleanup(rcname);
833 			free(rcname);
834 		}
835 		if ((rcname = strdup(conf->rcsock)) == NULL)
836 			fatal("strdup");
837 		if ((fd = control_init(1, rcname)) == -1)
838 			fatalx("control socket setup failed");
839 		if (control_listen(fd) == -1)
840 			fatalx("control socket setup failed");
841 		restricted = 1;
842 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
843 		    &restricted, sizeof(restricted)) == -1)
844 			return (-1);
845 	}
846 	return (0);
847 }
848 
849 void
850 set_pollfd(struct pollfd *pfd, struct imsgbuf *i)
851 {
852 	if (i == NULL || i->fd == -1) {
853 		pfd->fd = -1;
854 		return;
855 	}
856 	pfd->fd = i->fd;
857 	pfd->events = POLLIN;
858 	if (i->w.queued > 0)
859 		pfd->events |= POLLOUT;
860 }
861 
862 int
863 handle_pollfd(struct pollfd *pfd, struct imsgbuf *i)
864 {
865 	ssize_t n;
866 
867 	if (i == NULL)
868 		return (0);
869 
870 	if (pfd->revents & POLLOUT)
871 		if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) {
872 			log_warn("imsg write error");
873 			close(i->fd);
874 			i->fd = -1;
875 			return (-1);
876 		}
877 
878 	if (pfd->revents & POLLIN) {
879 		if ((n = imsg_read(i)) == -1 && errno != EAGAIN) {
880 			log_warn("imsg read error");
881 			close(i->fd);
882 			i->fd = -1;
883 			return (-1);
884 		}
885 		if (n == 0) {
886 			log_warnx("peer closed imsg connection");
887 			close(i->fd);
888 			i->fd = -1;
889 			return (-1);
890 		}
891 	}
892 	return (0);
893 }
894 
895 int
896 imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde)
897 {
898 	int pipe_s2r[2];
899 	int pipe_s2r_ctl[2];
900 
901 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
902 	     PF_UNSPEC, pipe_s2r) == -1)
903 		return (-1);
904 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
905 	     PF_UNSPEC, pipe_s2r_ctl) == -1)
906 		return (-1);
907 
908 	if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0],
909 	    NULL, 0) == -1)
910 		return (-1);
911 	if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1],
912 	    NULL, 0) == -1)
913 		return (-1);
914 
915 	if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0],
916 	    NULL, 0) == -1)
917 		return (-1);
918 	if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1],
919 	    NULL, 0) == -1)
920 		return (-1);
921 
922 	return (0);
923 }
924