xref: /openbsd-src/usr.sbin/bgpd/bgpd.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: bgpd.c,v 1.168 2011/08/20 19:02:28 sthen 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 int		check_child(pid_t, const char *);
43 int		send_filterset(struct imsgbuf *, struct filter_set_head *);
44 int		reconfigure(char *, struct bgpd_config *, struct mrt_head *,
45 		    struct peer **);
46 int		dispatch_imsg(struct imsgbuf *, int);
47 int		control_setup(struct bgpd_config *);
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	 sigchld;
54 volatile sig_atomic_t	 reconfig;
55 pid_t			 reconfpid;
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 SIGCHLD:
71 		sigchld = 1;
72 		break;
73 	case SIGHUP:
74 		reconfig = 1;
75 		break;
76 	case SIGALRM:
77 	case SIGUSR1:
78 		mrtdump = 1;
79 		break;
80 	}
81 }
82 
83 __dead void
84 usage(void)
85 {
86 	extern char *__progname;
87 
88 	fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n",
89 	    __progname);
90 	exit(1);
91 }
92 
93 #define PFD_PIPE_SESSION	0
94 #define PFD_PIPE_ROUTE		1
95 #define PFD_SOCK_ROUTE		2
96 #define POLL_MAX		3
97 #define MAX_TIMEOUT		3600
98 
99 int
100 main(int argc, char *argv[])
101 {
102 	struct bgpd_config	 conf;
103 	struct mrt_head		 mrt_l;
104 	struct peer		*peer_l, *p;
105 	struct mrt		*m;
106 	struct listen_addr	*la;
107 	struct pollfd		 pfd[POLL_MAX];
108 	pid_t			 io_pid = 0, rde_pid = 0, pid;
109 	char			*conffile;
110 	int			 debug = 0;
111 	int			 ch, timeout, nfds;
112 	int			 pipe_m2s[2];
113 	int			 pipe_m2r[2];
114 	int			 pipe_s2r[2];
115 	int			 pipe_s2r_c[2];
116 
117 	conffile = CONFFILE;
118 	bgpd_process = PROC_MAIN;
119 
120 	log_init(1);		/* log to stderr until daemonized */
121 	log_verbose(1);
122 
123 	bzero(&conf, sizeof(conf));
124 	LIST_INIT(&mrt_l);
125 	peer_l = NULL;
126 
127 	while ((ch = getopt(argc, argv, "cdD:f:nv")) != -1) {
128 		switch (ch) {
129 		case 'c':
130 			conf.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 			conf.opts |= BGPD_OPT_NOACTION;
145 			break;
146 		case 'v':
147 			if (conf.opts & BGPD_OPT_VERBOSE)
148 				conf.opts |= BGPD_OPT_VERBOSE2;
149 			conf.opts |= BGPD_OPT_VERBOSE;
150 			log_verbose(1);
151 			break;
152 		default:
153 			usage();
154 			/* NOTREACHED */
155 		}
156 	}
157 
158 	argc -= optind;
159 	argv += optind;
160 	if (argc > 0)
161 		usage();
162 
163 	if (conf.opts & BGPD_OPT_NOACTION) {
164 		struct network_head	net_l;
165 		struct rdomain_head	rdom_l;
166 		struct filter_head	rules_l;
167 
168 		if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l,
169 		    &rules_l, &rdom_l))
170 			exit(1);
171 
172 		if (conf.opts & BGPD_OPT_VERBOSE)
173 			print_config(&conf, &ribnames, &net_l, peer_l, &rules_l,
174 			    &mrt_l, &rdom_l);
175 		else
176 			fprintf(stderr, "configuration OK\n");
177 		exit(0);
178 	}
179 
180 	if (geteuid())
181 		errx(1, "need root privileges");
182 
183 	if (getpwnam(BGPD_USER) == NULL)
184 		errx(1, "unknown user %s", BGPD_USER);
185 
186 	log_init(debug);
187 	log_verbose(conf.opts & BGPD_OPT_VERBOSE);
188 
189 	if (!debug)
190 		daemon(1, 0);
191 
192 	log_info("startup");
193 
194 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_m2s) == -1)
195 		fatal("socketpair");
196 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_m2r) == -1)
197 		fatal("socketpair");
198 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_s2r) == -1)
199 		fatal("socketpair");
200 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_s2r_c) == -1)
201 		fatal("socketpair");
202 	session_socket_blockmode(pipe_m2s[0], BM_NONBLOCK);
203 	session_socket_blockmode(pipe_m2s[1], BM_NONBLOCK);
204 	session_socket_blockmode(pipe_m2r[0], BM_NONBLOCK);
205 	session_socket_blockmode(pipe_m2r[1], BM_NONBLOCK);
206 	session_socket_blockmode(pipe_s2r[0], BM_NONBLOCK);
207 	session_socket_blockmode(pipe_s2r[1], BM_NONBLOCK);
208 	session_socket_blockmode(pipe_s2r_c[0], BM_NONBLOCK);
209 	session_socket_blockmode(pipe_s2r_c[1], BM_NONBLOCK);
210 
211 	/* fork children */
212 	rde_pid = rde_main(pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug);
213 	io_pid = session_main(pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c);
214 
215 	setproctitle("parent");
216 
217 	signal(SIGTERM, sighdlr);
218 	signal(SIGINT, sighdlr);
219 	signal(SIGCHLD, sighdlr);
220 	signal(SIGHUP, sighdlr);
221 	signal(SIGALRM, sighdlr);
222 	signal(SIGUSR1, sighdlr);
223 	signal(SIGPIPE, SIG_IGN);
224 
225 	close(pipe_m2s[1]);
226 	close(pipe_m2r[1]);
227 	close(pipe_s2r[0]);
228 	close(pipe_s2r[1]);
229 
230 	if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL ||
231 	    (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL)
232 		fatal(NULL);
233 	imsg_init(ibuf_se, pipe_m2s[0]);
234 	imsg_init(ibuf_rde, pipe_m2r[0]);
235 	mrt_init(ibuf_rde, ibuf_se);
236 	if ((rfd = kr_init()) == -1)
237 		quit = 1;
238 	quit = reconfigure(conffile, &conf, &mrt_l, &peer_l);
239 	if (pftable_clear_all() != 0)
240 		quit = 1;
241 
242 	while (quit == 0) {
243 		bzero(pfd, sizeof(pfd));
244 		pfd[PFD_PIPE_SESSION].fd = ibuf_se->fd;
245 		pfd[PFD_PIPE_SESSION].events = POLLIN;
246 		if (ibuf_se->w.queued)
247 			pfd[PFD_PIPE_SESSION].events |= POLLOUT;
248 		pfd[PFD_PIPE_ROUTE].fd = ibuf_rde->fd;
249 		pfd[PFD_PIPE_ROUTE].events = POLLIN;
250 		if (ibuf_rde->w.queued)
251 			pfd[PFD_PIPE_ROUTE].events |= POLLOUT;
252 		pfd[PFD_SOCK_ROUTE].fd = rfd;
253 		pfd[PFD_SOCK_ROUTE].events = POLLIN;
254 
255 		timeout = mrt_timeout(&mrt_l);
256 		if (timeout > MAX_TIMEOUT)
257 			timeout = MAX_TIMEOUT;
258 
259 		if ((nfds = poll(pfd, POLL_MAX, timeout * 1000)) == -1)
260 			if (errno != EINTR) {
261 				log_warn("poll error");
262 				quit = 1;
263 			}
264 
265 		if (nfds > 0 && pfd[PFD_PIPE_SESSION].revents & POLLOUT)
266 			if (msgbuf_write(&ibuf_se->w) < 0) {
267 				log_warn("pipe write error (to SE)");
268 				quit = 1;
269 			}
270 
271 		if (nfds > 0 && pfd[PFD_PIPE_ROUTE].revents & POLLOUT)
272 			if (msgbuf_write(&ibuf_rde->w) < 0) {
273 				log_warn("pipe write error (to RDE)");
274 				quit = 1;
275 			}
276 
277 		if (nfds > 0 && pfd[PFD_PIPE_SESSION].revents & POLLIN) {
278 			if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION) == -1)
279 				quit = 1;
280 		}
281 
282 		if (nfds > 0 && pfd[PFD_PIPE_ROUTE].revents & POLLIN) {
283 			if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE) == -1)
284 				quit = 1;
285 		}
286 
287 		if (nfds > 0 && pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
288 			if (kr_dispatch_msg() == -1)
289 				quit = 1;
290 		}
291 
292 		if (reconfig) {
293 			u_int	error;
294 
295 			reconfig = 0;
296 			log_info("rereading config");
297 			switch (reconfigure(conffile, &conf, &mrt_l, &peer_l)) {
298 			case -1:	/* fatal error */
299 				quit = 1;
300 				break;
301 			case 0:		/* all OK */
302 				error = 0;
303 				break;
304 			default:	/* parse error */
305 				error = CTL_RES_PARSE_ERROR;
306 				break;
307 			}
308 			if (reconfpid != 0) {
309 				send_imsg_session(IMSG_CTL_RESULT, reconfpid,
310 				    &error, sizeof(error));
311 				reconfpid = 0;
312 			}
313 		}
314 
315 		if (sigchld) {
316 			sigchld = 0;
317 			if (check_child(io_pid, "session engine")) {
318 				quit = 1;
319 				io_pid = 0;
320 			}
321 			if (check_child(rde_pid, "route decision engine")) {
322 				quit = 1;
323 				rde_pid = 0;
324 			}
325 		}
326 
327 		if (mrtdump) {
328 			mrtdump = 0;
329 			mrt_handler(&mrt_l);
330 		}
331 	}
332 
333 	signal(SIGCHLD, SIG_IGN);
334 
335 	if (io_pid)
336 		kill(io_pid, SIGTERM);
337 
338 	if (rde_pid)
339 		kill(rde_pid, SIGTERM);
340 
341 	while ((p = peer_l) != NULL) {
342 		peer_l = p->next;
343 		free(p);
344 	}
345 	while ((m = LIST_FIRST(&mrt_l)) != NULL) {
346 		LIST_REMOVE(m, entry);
347 		free(m);
348 	}
349 	if (conf.listen_addrs)
350 		while ((la = TAILQ_FIRST(conf.listen_addrs)) != NULL) {
351 			TAILQ_REMOVE(conf.listen_addrs, la, entry);
352 			close(la->fd);
353 			free(la);
354 		}
355 
356 	control_cleanup(conf.csock);
357 	control_cleanup(conf.rcsock);
358 	carp_demote_shutdown();
359 	kr_shutdown();
360 	pftable_clear_all();
361 	free(conf.listen_addrs);
362 
363 	do {
364 		if ((pid = wait(NULL)) == -1 &&
365 		    errno != EINTR && errno != ECHILD)
366 			fatal("wait");
367 	} while (pid != -1 || (pid == -1 && errno == EINTR));
368 
369 	msgbuf_clear(&ibuf_se->w);
370 	free(ibuf_se);
371 	msgbuf_clear(&ibuf_rde->w);
372 	free(ibuf_rde);
373 	free(rcname);
374 	free(cname);
375 
376 	log_info("Terminating");
377 	return (0);
378 }
379 
380 int
381 check_child(pid_t pid, const char *pname)
382 {
383 	int	status;
384 
385 	if (waitpid(pid, &status, WNOHANG) > 0) {
386 		if (WIFEXITED(status)) {
387 			log_warnx("Lost child: %s exited", pname);
388 			return (1);
389 		}
390 		if (WIFSIGNALED(status)) {
391 			log_warnx("Lost child: %s terminated; signal %d",
392 			    pname, WTERMSIG(status));
393 			return (1);
394 		}
395 	}
396 
397 	return (0);
398 }
399 
400 int
401 send_filterset(struct imsgbuf *i, struct filter_set_head *set)
402 {
403 	struct filter_set	*s;
404 
405 	TAILQ_FOREACH(s, set, entry)
406 		if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s,
407 		    sizeof(struct filter_set)) == -1)
408 			return (-1);
409 	return (0);
410 }
411 
412 int
413 reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l,
414     struct peer **peer_l)
415 {
416 	struct network_head	 net_l;
417 	struct rdomain_head	 rdom_l;
418 	struct filter_head	 rules_l;
419 	struct peer		*p;
420 	struct filter_rule	*r;
421 	struct listen_addr	*la;
422 	struct rde_rib		*rr;
423 	struct rdomain		*rd;
424 
425 	if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, &rules_l,
426 	    &rdom_l)) {
427 		log_warnx("config file %s has errors, not reloading",
428 		    conffile);
429 		return (1);
430 	}
431 
432 	cflags = conf->flags;
433 	prepare_listeners(conf);
434 
435 	/* start reconfiguration */
436 	if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1,
437 	    conf, sizeof(struct bgpd_config)) == -1)
438 		return (-1);
439 	if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1,
440 	    conf, sizeof(struct bgpd_config)) == -1)
441 		return (-1);
442 
443 	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
444 		if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
445 		    la, sizeof(struct listen_addr)) == -1)
446 			return (-1);
447 		la->fd = -1;
448 	}
449 
450 	if (control_setup(conf) == -1)
451 		return (-1);
452 
453 	/* adjust fib syncing on reload */
454 	ktable_preload();
455 
456 	/* RIBs for the RDE */
457 	while ((rr = SIMPLEQ_FIRST(&ribnames))) {
458 		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
459 		if (ktable_update(rr->rtableid, rr->name, NULL,
460 		    rr->flags) == -1) {
461 			log_warnx("failed to load rdomain %d",
462 			    rr->rtableid);
463 			return (-1);
464 		}
465 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1,
466 		    rr, sizeof(struct rde_rib)) == -1)
467 			return (-1);
468 		free(rr);
469 	}
470 
471 	/* send peer list and listeners to the SE and RDE */
472 	for (p = *peer_l; p != NULL; p = p->next) {
473 		if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
474 		    &p->conf, sizeof(struct peer_config)) == -1)
475 			return (-1);
476 		if (imsg_compose(ibuf_rde, IMSG_RECONF_PEER, p->conf.id, 0, -1,
477 		    &p->conf, sizeof(struct peer_config)) == -1)
478 			return (-1);
479 	}
480 
481 	/* networks go via kroute to the RDE */
482 	if (kr_net_reload(0, &net_l))
483 		return (-1);
484 
485 	/* filters for the RDE */
486 	while ((r = TAILQ_FIRST(&rules_l)) != NULL) {
487 		TAILQ_REMOVE(&rules_l, r, entry);
488 		if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
489 		    r, sizeof(struct filter_rule)) == -1)
490 			return (-1);
491 		if (send_filterset(ibuf_rde, &r->set) == -1)
492 			return (-1);
493 		filterset_free(&r->set);
494 		free(r);
495 	}
496 
497 	while ((rd = SIMPLEQ_FIRST(&rdom_l)) != NULL) {
498 		SIMPLEQ_REMOVE_HEAD(&rdom_l, entry);
499 		if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe,
500 		    rd->flags) == -1) {
501 			log_warnx("failed to load rdomain %d",
502 			    rd->rtableid);
503 			return (-1);
504 		}
505 		/* networks go via kroute to the RDE */
506 		if (kr_net_reload(rd->rtableid, &rd->net_l))
507 			return (-1);
508 
509 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN, 0, 0, -1,
510 		    rd, sizeof(*rd)) == -1)
511 			return (-1);
512 
513 		/* export targets */
514 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_EXPORT, 0, 0,
515 		    -1, NULL, 0) == -1)
516 			return (-1);
517 		if (send_filterset(ibuf_rde, &rd->export) == -1)
518 			return (-1);
519 		filterset_free(&rd->export);
520 
521 		/* import targets */
522 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_IMPORT, 0, 0,
523 		    -1, NULL, 0) == -1)
524 			return (-1);
525 		if (send_filterset(ibuf_rde, &rd->import) == -1)
526 			return (-1);
527 		filterset_free(&rd->import);
528 
529 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RDOMAIN_DONE, 0, 0,
530 		    -1, NULL, 0) == -1)
531 			return (-1);
532 
533 		free(rd);
534 	}
535 
536 	/* signal both childs to replace their config */
537 	if (imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1 ||
538 	    imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0, 0, -1, NULL, 0) == -1)
539 		return (-1);
540 
541 	/* fix kroute information */
542 	ktable_postload();
543 
544 	/* redistribute list needs to be reloaded too */
545 	if (kr_reload() == -1)
546 		return (-1);
547 
548 	/* mrt changes can be sent out of bound */
549 	mrt_reconfigure(mrt_l);
550 	return (0);
551 }
552 
553 int
554 dispatch_imsg(struct imsgbuf *ibuf, int idx)
555 {
556 	struct imsg		 imsg;
557 	ssize_t			 n;
558 	int			 rv, verbose;
559 
560 	if ((n = imsg_read(ibuf)) == -1)
561 		return (-1);
562 
563 	if (n == 0) {	/* connection closed */
564 		log_warnx("dispatch_imsg in main: pipe closed");
565 		return (-1);
566 	}
567 
568 	rv = 0;
569 	for (;;) {
570 		if ((n = imsg_get(ibuf, &imsg)) == -1)
571 			return (-1);
572 
573 		if (n == 0)
574 			break;
575 
576 		switch (imsg.hdr.type) {
577 		case IMSG_KROUTE_CHANGE:
578 			if (idx != PFD_PIPE_ROUTE)
579 				log_warnx("route request not from RDE");
580 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
581 			    sizeof(struct kroute_full))
582 				log_warnx("wrong imsg len");
583 			else if (kr_change(imsg.hdr.peerid, imsg.data))
584 				rv = -1;
585 			break;
586 		case IMSG_KROUTE_DELETE:
587 			if (idx != PFD_PIPE_ROUTE)
588 				log_warnx("route request not from RDE");
589 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
590 			    sizeof(struct kroute_full))
591 				log_warnx("wrong imsg len");
592 			else if (kr_delete(imsg.hdr.peerid, imsg.data))
593 				rv = -1;
594 			break;
595 		case IMSG_NEXTHOP_ADD:
596 			if (idx != PFD_PIPE_ROUTE)
597 				log_warnx("nexthop request not from RDE");
598 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
599 			    sizeof(struct bgpd_addr))
600 				log_warnx("wrong imsg len");
601 			else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data) ==
602 			    -1)
603 				rv = -1;
604 			break;
605 		case IMSG_NEXTHOP_REMOVE:
606 			if (idx != PFD_PIPE_ROUTE)
607 				log_warnx("nexthop request not from RDE");
608 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
609 			    sizeof(struct bgpd_addr))
610 				log_warnx("wrong imsg len");
611 			else
612 				kr_nexthop_delete(imsg.hdr.peerid, imsg.data);
613 			break;
614 		case IMSG_PFTABLE_ADD:
615 			if (idx != PFD_PIPE_ROUTE)
616 				log_warnx("pftable request not from RDE");
617 			else
618 				if (imsg.hdr.len != IMSG_HEADER_SIZE +
619 				    sizeof(struct pftable_msg))
620 					log_warnx("wrong imsg len");
621 				else if (pftable_addr_add(imsg.data) != 0)
622 					rv = -1;
623 			break;
624 		case IMSG_PFTABLE_REMOVE:
625 			if (idx != PFD_PIPE_ROUTE)
626 				log_warnx("pftable request not from RDE");
627 			else
628 				if (imsg.hdr.len != IMSG_HEADER_SIZE +
629 				    sizeof(struct pftable_msg))
630 					log_warnx("wrong imsg len");
631 				else if (pftable_addr_remove(imsg.data) != 0)
632 					rv = -1;
633 			break;
634 		case IMSG_PFTABLE_COMMIT:
635 			if (idx != PFD_PIPE_ROUTE)
636 				log_warnx("pftable request not from RDE");
637 			else
638 				if (imsg.hdr.len != IMSG_HEADER_SIZE)
639 					log_warnx("wrong imsg len");
640 				else if (pftable_commit() != 0)
641 					rv = -1;
642 			break;
643 		case IMSG_CTL_RELOAD:
644 			if (idx != PFD_PIPE_SESSION)
645 				log_warnx("reload request not from SE");
646 			else
647 				reconfig = 1;
648 				reconfpid = imsg.hdr.pid;
649 			break;
650 		case IMSG_CTL_FIB_COUPLE:
651 			if (idx != PFD_PIPE_SESSION)
652 				log_warnx("couple request not from SE");
653 			else
654 				kr_fib_couple(imsg.hdr.peerid);
655 			break;
656 		case IMSG_CTL_FIB_DECOUPLE:
657 			if (idx != PFD_PIPE_SESSION)
658 				log_warnx("decouple request not from SE");
659 			else
660 				kr_fib_decouple(imsg.hdr.peerid);
661 			break;
662 		case IMSG_CTL_KROUTE:
663 		case IMSG_CTL_KROUTE_ADDR:
664 		case IMSG_CTL_SHOW_NEXTHOP:
665 		case IMSG_CTL_SHOW_INTERFACE:
666 		case IMSG_CTL_SHOW_FIB_TABLES:
667 			if (idx != PFD_PIPE_SESSION)
668 				log_warnx("kroute request not from SE");
669 			else
670 				kr_show_route(&imsg);
671 			break;
672 		case IMSG_IFINFO:
673 			if (idx != PFD_PIPE_SESSION)
674 				log_warnx("IFINFO request not from SE");
675 			else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ)
676 				log_warnx("IFINFO request with wrong len");
677 			else
678 				kr_ifinfo(imsg.data);
679 			break;
680 		case IMSG_DEMOTE:
681 			if (idx != PFD_PIPE_SESSION)
682 				log_warnx("demote request not from SE");
683 			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
684 			    sizeof(struct demote_msg))
685 				log_warnx("DEMOTE request with wrong len");
686 			else {
687 				struct demote_msg	*msg;
688 
689 				msg = imsg.data;
690 				carp_demote_set(msg->demote_group, msg->level);
691 			}
692 			break;
693 		case IMSG_CTL_LOG_VERBOSE:
694 			/* already checked by SE */
695 			memcpy(&verbose, imsg.data, sizeof(verbose));
696 			log_verbose(verbose);
697 			break;
698 		default:
699 			break;
700 		}
701 		imsg_free(&imsg);
702 		if (rv != 0)
703 			return (rv);
704 	}
705 	return (0);
706 }
707 
708 void
709 send_nexthop_update(struct kroute_nexthop *msg)
710 {
711 	char	*gw = NULL;
712 
713 	if (msg->gateway.aid)
714 		if (asprintf(&gw, ": via %s",
715 		    log_addr(&msg->gateway)) == -1) {
716 			log_warn("send_nexthop_update");
717 			quit = 1;
718 		}
719 
720 	log_info("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
721 	    msg->valid ? "valid" : "invalid",
722 	    msg->connected ? ": directly connected" : "",
723 	    msg->gateway.aid ? gw : "");
724 
725 	free(gw);
726 
727 	if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1,
728 	    msg, sizeof(struct kroute_nexthop)) == -1)
729 		quit = 1;
730 }
731 
732 void
733 send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen)
734 {
735 	imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen);
736 }
737 
738 int
739 send_network(int type, struct network_config *net, struct filter_set_head *h)
740 {
741 	if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
742 	    sizeof(struct network_config)) == -1)
743 		return (-1);
744 	/* networks that get deleted don't need to send the filter set */
745 	if (type == IMSG_NETWORK_REMOVE)
746 		return (0);
747 	if (send_filterset(ibuf_rde, h) == -1)
748 		return (-1);
749 	if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
750 		return (-1);
751 
752 	return (0);
753 }
754 
755 int
756 bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6)
757 {
758 	/* kernel routes are never filtered */
759 	if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0)
760 		return (0);
761 	if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0)
762 		return (0);
763 
764 	if (cflags & BGPD_FLAG_NEXTHOP_BGP) {
765 		if (kr && kr->flags & F_BGPD_INSERTED)
766 			return (0);
767 		if (kr6 && kr6->flags & F_BGPD_INSERTED)
768 			return (0);
769 	}
770 
771 	if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) {
772 		if (kr && kr->prefixlen == 0)
773 			return (0);
774 		if (kr6 && kr6->prefixlen == 0)
775 			return (0);
776 	}
777 
778 	return (1);
779 }
780 
781 int
782 control_setup(struct bgpd_config *conf)
783 {
784 	int fd, restricted;
785 
786 	/* control socket is outside chroot */
787 	if (!cname || strcmp(cname, conf->csock)) {
788 		if (cname) {
789 			control_cleanup(cname);
790 			free(cname);
791 		}
792 		if ((cname = strdup(conf->csock)) == NULL)
793 			fatal("strdup");
794 		if ((fd = control_init(0, cname)) == -1)
795 			fatalx("control socket setup failed");
796 		restricted = 0;
797 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
798 		    &restricted, sizeof(restricted)) == -1)
799 			return (-1);
800 	}
801 	if (!conf->rcsock) {
802 		/* remove restricted socket */
803 		control_cleanup(rcname);
804 		free(rcname);
805 		rcname = NULL;
806 	} else if (!rcname || strcmp(rcname, conf->rcsock)) {
807 		if (rcname) {
808 			control_cleanup(rcname);
809 			free(rcname);
810 		}
811 		if ((rcname = strdup(conf->rcsock)) == NULL)
812 			fatal("strdup");
813 		if ((fd = control_init(1, rcname)) == -1)
814 			fatalx("control socket setup failed");
815 		restricted = 1;
816 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
817 		    &restricted, sizeof(restricted)) == -1)
818 			return (-1);
819 	}
820 	return (0);
821 }
822