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