bgpd.c revision 1.187
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
39void		sighdlr(int);
40__dead void	usage(void);
41int		main(int, char *[]);
42pid_t		start_child(enum bgpd_process, char *, int, int, int);
43int		send_filterset(struct imsgbuf *, struct filter_set_head *);
44int		reconfigure(char *, struct bgpd_config *, struct peer **);
45int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
46int		control_setup(struct bgpd_config *);
47int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *);
48
49int			 rfd = -1;
50int			 cflags;
51volatile sig_atomic_t	 mrtdump;
52volatile sig_atomic_t	 quit;
53volatile sig_atomic_t	 reconfig;
54pid_t			 reconfpid;
55int			 reconfpending;
56struct imsgbuf		*ibuf_se;
57struct imsgbuf		*ibuf_rde;
58struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
59char			*cname;
60char			*rcname;
61
62void
63sighdlr(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
81usage(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
96int	 cmd_opts;
97
98int
99main(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
377pid_t
378start_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
418int
419send_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
430int
431reconfigure(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
563int
564dispatch_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
730void
731send_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
754void
755send_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
760int
761send_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
777int
778bgpd_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
803int
804control_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
849void
850set_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
862int
863handle_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
895int
896imsg_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