bgpd.c revision 1.213
1/*	$OpenBSD: bgpd.c,v 1.213 2019/03/07 07:42:36 claudio Exp $ */
2
3/*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/wait.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <err.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <poll.h>
28#include <pwd.h>
29#include <signal.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <syslog.h>
34#include <unistd.h>
35
36#include "bgpd.h"
37#include "mrt.h"
38#include "session.h"
39#include "log.h"
40
41void		sighdlr(int);
42__dead void	usage(void);
43int		main(int, char *[]);
44pid_t		start_child(enum bgpd_process, char *, int, int, int);
45int		send_filterset(struct imsgbuf *, struct filter_set_head *);
46int		reconfigure(char *, struct bgpd_config *, struct peer **);
47int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
48int		control_setup(struct bgpd_config *);
49int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *);
50
51int			 cflags;
52volatile sig_atomic_t	 mrtdump;
53volatile sig_atomic_t	 quit;
54volatile sig_atomic_t	 reconfig;
55pid_t			 reconfpid;
56int			 reconfpending;
57struct imsgbuf		*ibuf_se;
58struct imsgbuf		*ibuf_rde;
59struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
60char			*cname;
61char			*rcname;
62
63void
64sighdlr(int sig)
65{
66	switch (sig) {
67	case SIGTERM:
68	case SIGINT:
69		quit = 1;
70		break;
71	case SIGHUP:
72		reconfig = 1;
73		break;
74	case SIGALRM:
75	case SIGUSR1:
76		mrtdump = 1;
77		break;
78	}
79}
80
81__dead void
82usage(void)
83{
84	extern char *__progname;
85
86	fprintf(stderr, "usage: %s [-cdnv] [-D macro=value] [-f file]\n",
87	    __progname);
88	exit(1);
89}
90
91#define PFD_PIPE_SESSION	0
92#define PFD_PIPE_ROUTE		1
93#define PFD_SOCK_ROUTE		2
94#define POLL_MAX		3
95#define MAX_TIMEOUT		3600
96
97int	 cmd_opts;
98
99int
100main(int argc, char *argv[])
101{
102	struct bgpd_config	*conf;
103	struct peer		*peer_l, *p;
104	struct rde_rib		*rr;
105	struct pollfd		 pfd[POLL_MAX];
106	time_t			 timeout;
107	pid_t			 se_pid = 0, rde_pid = 0, pid;
108	char			*conffile;
109	char			*saved_argv0;
110	int			 debug = 0;
111	int			 rflag = 0, sflag = 0;
112	int			 rfd = -1;
113	int			 ch, status;
114	int			 pipe_m2s[2];
115	int			 pipe_m2r[2];
116
117	conffile = CONFFILE;
118	bgpd_process = PROC_MAIN;
119
120	log_init(1, LOG_DAEMON);	/* log to stderr until daemonized */
121	log_procinit(log_procnames[bgpd_process]);
122	log_setverbose(1);
123
124	saved_argv0 = argv[0];
125	if (saved_argv0 == NULL)
126		saved_argv0 = "bgpd";
127
128	peer_l = NULL;
129
130	while ((ch = getopt(argc, argv, "cdD:f:nRSv")) != -1) {
131		switch (ch) {
132		case 'c':
133			cmd_opts |= BGPD_OPT_FORCE_DEMOTE;
134			break;
135		case 'd':
136			debug = 1;
137			break;
138		case 'D':
139			if (cmdline_symset(optarg) < 0)
140				log_warnx("could not parse macro definition %s",
141				    optarg);
142			break;
143		case 'f':
144			conffile = optarg;
145			break;
146		case 'n':
147			cmd_opts |= BGPD_OPT_NOACTION;
148			break;
149		case 'v':
150			if (cmd_opts & BGPD_OPT_VERBOSE)
151				cmd_opts |= BGPD_OPT_VERBOSE2;
152			cmd_opts |= BGPD_OPT_VERBOSE;
153			break;
154		case 'R':
155			rflag = 1;
156			break;
157		case 'S':
158			sflag = 1;
159			break;
160		default:
161			usage();
162			/* NOTREACHED */
163		}
164	}
165
166	argc -= optind;
167	argv += optind;
168	if (argc > 0 || (sflag && rflag))
169		usage();
170
171	if (cmd_opts & BGPD_OPT_NOACTION) {
172		conf = new_config();
173		if (parse_config(conffile, conf, &peer_l))
174			exit(1);
175
176		if (cmd_opts & BGPD_OPT_VERBOSE)
177			print_config(conf, &ribnames, &conf->networks, peer_l,
178			    conf->filters, conf->mrt, &conf->l3vpns);
179		else
180			fprintf(stderr, "configuration OK\n");
181
182		while ((p = peer_l) != NULL) {
183			peer_l = p->next;
184			free(p);
185		}
186		while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
187			SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
188			free(rr);
189		}
190		free_config(conf);
191		exit(0);
192	}
193
194	if (rflag)
195		rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
196	else if (sflag)
197		session_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
198
199	if (geteuid())
200		errx(1, "need root privileges");
201
202	if (getpwnam(BGPD_USER) == NULL)
203		errx(1, "unknown user %s", BGPD_USER);
204
205	log_init(debug, LOG_DAEMON);
206	log_setverbose(cmd_opts & BGPD_OPT_VERBOSE);
207
208	if (!debug)
209		daemon(1, 0);
210
211	log_info("startup");
212
213	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
214	    PF_UNSPEC, pipe_m2s) == -1)
215		fatal("socketpair");
216	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
217	    PF_UNSPEC, pipe_m2r) == -1)
218		fatal("socketpair");
219
220	/* fork children */
221	rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug,
222	    cmd_opts & BGPD_OPT_VERBOSE);
223	se_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug,
224	    cmd_opts & BGPD_OPT_VERBOSE);
225
226	signal(SIGTERM, sighdlr);
227	signal(SIGINT, sighdlr);
228	signal(SIGHUP, sighdlr);
229	signal(SIGALRM, sighdlr);
230	signal(SIGUSR1, sighdlr);
231	signal(SIGPIPE, SIG_IGN);
232
233	if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL ||
234	    (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL)
235		fatal(NULL);
236	imsg_init(ibuf_se, pipe_m2s[0]);
237	imsg_init(ibuf_rde, pipe_m2r[0]);
238	mrt_init(ibuf_rde, ibuf_se);
239	if ((rfd = kr_init()) == -1)
240		quit = 1;
241
242	/*
243	 * rpath, read config file
244	 * cpath, unlink control socket
245	 * fattr, chmod on control socket
246	 * wpath, needed if we are doing mrt dumps
247	 *
248	 * pledge placed here because kr_init() does a setsockopt on the
249	 * routing socket thats not allowed at all.
250	 */
251#if 0
252	/*
253	 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR
254	 * this needs some redesign of bgpd to be fixed.
255	 */
256BROKEN	if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd",
257	    NULL) == -1)
258		fatal("pledge");
259#endif
260
261	if (imsg_send_sockets(ibuf_se, ibuf_rde))
262		fatal("could not establish imsg links");
263	conf = new_config();
264	quit = reconfigure(conffile, conf, &peer_l);
265	if (pftable_clear_all() != 0)
266		quit = 1;
267
268	while (quit == 0) {
269		bzero(pfd, sizeof(pfd));
270
271		timeout = mrt_timeout(conf->mrt);
272
273		pfd[PFD_SOCK_ROUTE].fd = rfd;
274		pfd[PFD_SOCK_ROUTE].events = POLLIN;
275
276		set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se);
277		set_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde);
278
279		if (timeout < 0 || timeout > MAX_TIMEOUT)
280			timeout = MAX_TIMEOUT;
281		if (poll(pfd, POLL_MAX, timeout * 1000) == -1)
282			if (errno != EINTR) {
283				log_warn("poll error");
284				quit = 1;
285			}
286
287		if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) {
288			log_warnx("main: Lost connection to SE");
289			msgbuf_clear(&ibuf_se->w);
290			free(ibuf_se);
291			ibuf_se = NULL;
292			quit = 1;
293		} else {
294			if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) ==
295			    -1)
296				quit = 1;
297		}
298
299		if (handle_pollfd(&pfd[PFD_PIPE_ROUTE], ibuf_rde) == -1) {
300			log_warnx("main: Lost connection to RDE");
301			msgbuf_clear(&ibuf_rde->w);
302			free(ibuf_rde);
303			ibuf_rde = NULL;
304			quit = 1;
305		} else {
306			if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, conf) ==
307			    -1)
308				quit = 1;
309		}
310
311		if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
312			if (kr_dispatch_msg(conf->default_tableid) == -1)
313				quit = 1;
314		}
315
316		if (reconfig) {
317			u_int	error;
318
319			reconfig = 0;
320			switch (reconfigure(conffile, conf, &peer_l)) {
321			case -1:	/* fatal error */
322				quit = 1;
323				break;
324			case 0:		/* all OK */
325				error = 0;
326				break;
327			case 2:
328				error = CTL_RES_PENDING;
329				break;
330			default:	/* parse error */
331				error = CTL_RES_PARSE_ERROR;
332				break;
333			}
334			if (reconfpid != 0) {
335				send_imsg_session(IMSG_CTL_RESULT, reconfpid,
336				    &error, sizeof(error));
337				reconfpid = 0;
338			}
339		}
340
341		if (mrtdump) {
342			mrtdump = 0;
343			mrt_handler(conf->mrt);
344		}
345	}
346
347	/* close pipes */
348	if (ibuf_se) {
349		msgbuf_clear(&ibuf_se->w);
350		close(ibuf_se->fd);
351		free(ibuf_se);
352		ibuf_se = NULL;
353	}
354	if (ibuf_rde) {
355		msgbuf_clear(&ibuf_rde->w);
356		close(ibuf_rde->fd);
357		free(ibuf_rde);
358		ibuf_rde = NULL;
359	}
360
361	while ((p = peer_l) != NULL) {
362		peer_l = p->next;
363		free(p);
364	}
365	while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
366		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
367		free(rr);
368	}
369
370	carp_demote_shutdown();
371	kr_shutdown(conf->fib_priority, conf->default_tableid);
372	pftable_clear_all();
373
374	free_config(conf);
375
376	log_debug("waiting for children to terminate");
377	do {
378		pid = wait(&status);
379		if (pid == -1) {
380			if (errno != EINTR && errno != ECHILD)
381				fatal("wait");
382		} else if (WIFSIGNALED(status)) {
383			char *name = "unknown process";
384			if (pid == rde_pid)
385				name = "route decision engine";
386			else if (pid == se_pid)
387				name = "session engine";
388			log_warnx("%s terminated; signal %d", name,
389				WTERMSIG(status));
390		}
391	} while (pid != -1 || (pid == -1 && errno == EINTR));
392
393	free(rcname);
394	free(cname);
395
396	log_info("terminating");
397	return (0);
398}
399
400pid_t
401start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose)
402{
403	char *argv[5];
404	int argc = 0;
405	pid_t pid;
406
407	switch (pid = fork()) {
408	case -1:
409		fatal("cannot fork");
410	case 0:
411		break;
412	default:
413		close(fd);
414		return (pid);
415	}
416
417	if (dup2(fd, 3) == -1)
418		fatal("cannot setup imsg fd");
419
420	argv[argc++] = argv0;
421	switch (p) {
422	case PROC_MAIN:
423		fatalx("Can not start main process");
424	case PROC_RDE:
425		argv[argc++] = "-R";
426		break;
427	case PROC_SE:
428		argv[argc++] = "-S";
429		break;
430	}
431	if (debug)
432		argv[argc++] = "-d";
433	if (verbose)
434		argv[argc++] = "-v";
435	argv[argc++] = NULL;
436
437	execvp(argv0, argv);
438	fatal("execvp");
439}
440
441int
442send_filterset(struct imsgbuf *i, struct filter_set_head *set)
443{
444	struct filter_set	*s;
445
446	TAILQ_FOREACH(s, set, entry)
447		if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s,
448		    sizeof(struct filter_set)) == -1)
449			return (-1);
450	return (0);
451}
452
453int
454reconfigure(char *conffile, struct bgpd_config *conf, struct peer **peer_l)
455{
456	struct peer		*p;
457	struct filter_rule	*r;
458	struct listen_addr	*la;
459	struct rde_rib		*rr;
460	struct l3vpn		*vpn;
461	struct as_set		*aset;
462	struct prefixset	*ps;
463	struct prefixset_item	*psi, *npsi;
464
465	if (reconfpending) {
466		log_info("previous reload still running");
467		return (2);
468	}
469	reconfpending = 2;	/* one per child */
470
471	log_info("rereading config");
472	if (parse_config(conffile, conf, peer_l)) {
473		log_warnx("config file %s has errors, not reloading",
474		    conffile);
475		reconfpending = 0;
476		return (1);
477	}
478
479	if (prepare_listeners(conf) == -1) {
480		reconfpending = 0;
481		return (1);
482	}
483
484	if (control_setup(conf) == -1) {
485		reconfpending = 0;
486		return (1);
487	}
488
489	expand_networks(conf);
490
491	cflags = conf->flags;
492
493	/* start reconfiguration */
494	if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1,
495	    conf, sizeof(struct bgpd_config)) == -1)
496		return (-1);
497	if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1,
498	    conf, sizeof(struct bgpd_config)) == -1)
499		return (-1);
500
501	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
502		if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
503		    la, sizeof(struct listen_addr)) == -1)
504			return (-1);
505		la->fd = -1;
506	}
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, rr->flags,
515		    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	kr_net_reload(conf->default_tableid, 0, &conf->networks);
535
536	/* prefixsets for filters in the RDE */
537	while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) {
538		SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry);
539		if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET, 0, 0, -1,
540		    ps->name, sizeof(ps->name)) == -1)
541			return (-1);
542		RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
543			RB_REMOVE(prefixset_tree, &ps->psitems, psi);
544			if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM,
545			    0, 0, -1, psi, sizeof(*psi)) == -1)
546				return (-1);
547			set_free(psi->set);
548			free(psi);
549		}
550		free(ps);
551	}
552
553	/* originsets for filters in the RDE */
554	while ((ps = SIMPLEQ_FIRST(&conf->originsets)) != NULL) {
555		SIMPLEQ_REMOVE_HEAD(&conf->originsets, entry);
556		if (imsg_compose(ibuf_rde, IMSG_RECONF_ORIGIN_SET, 0, 0, -1,
557		    ps->name, sizeof(ps->name)) == -1)
558			return (-1);
559		RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
560			struct roa_set *rs;
561			size_t i, l, n;
562			RB_REMOVE(prefixset_tree, &ps->psitems, psi);
563			rs = set_get(psi->set, &n);
564			for (i = 0; i < n; i += l) {
565				l = (n - i > 1024 ? 1024 : n - i);
566				if (imsg_compose(ibuf_rde,
567				    IMSG_RECONF_ROA_SET_ITEMS,
568				    0, 0, -1, rs + i, l * sizeof(*rs)) == -1)
569					return -1;
570			}
571			if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM,
572			    0, 0, -1, psi, sizeof(*psi)) == -1)
573				return (-1);
574			set_free(psi->set);
575			free(psi);
576		}
577		free(ps);
578	}
579
580	if (!RB_EMPTY(&conf->roa)) {
581		if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_SET, 0, 0, -1,
582		    NULL, 0) == -1)
583			return (-1);
584		RB_FOREACH_SAFE(psi, prefixset_tree, &conf->roa, npsi) {
585			struct roa_set *rs;
586			size_t i, l, n;
587			RB_REMOVE(prefixset_tree, &conf->roa, psi);
588			rs = set_get(psi->set, &n);
589			for (i = 0; i < n; i += l) {
590				l = (n - i > 1024 ? 1024 : n - i);
591				if (imsg_compose(ibuf_rde,
592				    IMSG_RECONF_ROA_SET_ITEMS,
593				    0, 0, -1, rs + i, l * sizeof(*rs)) == -1)
594					return -1;
595			}
596			if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM,
597			    0, 0, -1, psi, sizeof(*psi)) == -1)
598				return (-1);
599			set_free(psi->set);
600			free(psi);
601		}
602	}
603
604	/* as-sets for filters in the RDE */
605	while ((aset = SIMPLEQ_FIRST(conf->as_sets)) != NULL) {
606		struct ibuf *wbuf;
607		u_int32_t *as;
608		size_t i, l, n;
609
610		SIMPLEQ_REMOVE_HEAD(conf->as_sets, entry);
611
612		as = set_get(aset->set, &n);
613		if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0,
614		    sizeof(n) + sizeof(aset->name))) == NULL)
615			return -1;
616		if (imsg_add(wbuf, &n, sizeof(n)) == -1 ||
617		    imsg_add(wbuf, aset->name, sizeof(aset->name)) == -1)
618			return -1;
619		imsg_close(ibuf_rde, wbuf);
620
621		for (i = 0; i < n; i += l) {
622			l = (n - i > 1024 ? 1024 : n - i);
623			if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_ITEMS,
624			    0, 0, -1, as + i, l * sizeof(*as)) == -1)
625				return -1;
626		}
627
628		if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_DONE, 0, 0, -1,
629		    NULL, 0) == -1)
630			return -1;
631
632		set_free(aset->set);
633		free(aset);
634	}
635
636	/* filters for the RDE */
637	while ((r = TAILQ_FIRST(conf->filters)) != NULL) {
638		TAILQ_REMOVE(conf->filters, r, entry);
639		if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
640		    r, sizeof(struct filter_rule)) == -1)
641			return (-1);
642		if (send_filterset(ibuf_rde, &r->set) == -1)
643			return (-1);
644		filterset_free(&r->set);
645		free(r);
646	}
647
648	while ((vpn = SIMPLEQ_FIRST(&conf->l3vpns)) != NULL) {
649		SIMPLEQ_REMOVE_HEAD(&conf->l3vpns, entry);
650		if (ktable_update(vpn->rtableid, vpn->descr, vpn->flags,
651		    conf->fib_priority) == -1) {
652			log_warnx("failed to load rdomain %d",
653			    vpn->rtableid);
654			return (-1);
655		}
656		/* networks go via kroute to the RDE */
657		kr_net_reload(vpn->rtableid, vpn->rd, &vpn->net_l);
658
659		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN, 0, 0, -1,
660		    vpn, sizeof(*vpn)) == -1)
661			return (-1);
662
663		/* export targets */
664		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_EXPORT, 0, 0,
665		    -1, NULL, 0) == -1)
666			return (-1);
667		if (send_filterset(ibuf_rde, &vpn->export) == -1)
668			return (-1);
669		filterset_free(&vpn->export);
670
671		/* import targets */
672		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_IMPORT, 0, 0,
673		    -1, NULL, 0) == -1)
674			return (-1);
675		if (send_filterset(ibuf_rde, &vpn->import) == -1)
676			return (-1);
677		filterset_free(&vpn->import);
678
679		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_DONE, 0, 0,
680		    -1, NULL, 0) == -1)
681			return (-1);
682
683		free(vpn);
684	}
685
686	/* send a drain message to know when all messages where processed */
687	if (imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
688		return (-1);
689	if (imsg_compose(ibuf_rde, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
690		return (-1);
691
692	/* mrt changes can be sent out of bound */
693	mrt_reconfigure(conf->mrt);
694	return (0);
695}
696
697int
698dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf)
699{
700	struct imsg		 imsg;
701	ssize_t			 n;
702	int			 rv, verbose;
703
704	rv = 0;
705	while (ibuf) {
706		if ((n = imsg_get(ibuf, &imsg)) == -1)
707			return (-1);
708
709		if (n == 0)
710			break;
711
712		switch (imsg.hdr.type) {
713		case IMSG_KROUTE_CHANGE:
714			if (idx != PFD_PIPE_ROUTE)
715				log_warnx("route request not from RDE");
716			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
717			    sizeof(struct kroute_full))
718				log_warnx("wrong imsg len");
719			else if (kr_change(imsg.hdr.peerid, imsg.data,
720			    conf->fib_priority))
721				rv = -1;
722			break;
723		case IMSG_KROUTE_DELETE:
724			if (idx != PFD_PIPE_ROUTE)
725				log_warnx("route request not from RDE");
726			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
727			    sizeof(struct kroute_full))
728				log_warnx("wrong imsg len");
729			else if (kr_delete(imsg.hdr.peerid, imsg.data,
730			    conf->fib_priority))
731				rv = -1;
732			break;
733		case IMSG_NEXTHOP_ADD:
734			if (idx != PFD_PIPE_ROUTE)
735				log_warnx("nexthop request not from RDE");
736			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
737			    sizeof(struct bgpd_addr))
738				log_warnx("wrong imsg len");
739			else if (kr_nexthop_add(imsg.hdr.peerid, imsg.data,
740			    conf) == -1)
741				rv = -1;
742			break;
743		case IMSG_NEXTHOP_REMOVE:
744			if (idx != PFD_PIPE_ROUTE)
745				log_warnx("nexthop request not from RDE");
746			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
747			    sizeof(struct bgpd_addr))
748				log_warnx("wrong imsg len");
749			else
750				kr_nexthop_delete(imsg.hdr.peerid, imsg.data,
751				    conf);
752			break;
753		case IMSG_PFTABLE_ADD:
754			if (idx != PFD_PIPE_ROUTE)
755				log_warnx("pftable request not from RDE");
756			else
757				if (imsg.hdr.len != IMSG_HEADER_SIZE +
758				    sizeof(struct pftable_msg))
759					log_warnx("wrong imsg len");
760				else if (pftable_addr_add(imsg.data) != 0)
761					rv = -1;
762			break;
763		case IMSG_PFTABLE_REMOVE:
764			if (idx != PFD_PIPE_ROUTE)
765				log_warnx("pftable request not from RDE");
766			else
767				if (imsg.hdr.len != IMSG_HEADER_SIZE +
768				    sizeof(struct pftable_msg))
769					log_warnx("wrong imsg len");
770				else if (pftable_addr_remove(imsg.data) != 0)
771					rv = -1;
772			break;
773		case IMSG_PFTABLE_COMMIT:
774			if (idx != PFD_PIPE_ROUTE)
775				log_warnx("pftable request not from RDE");
776			else
777				if (imsg.hdr.len != IMSG_HEADER_SIZE)
778					log_warnx("wrong imsg len");
779				else if (pftable_commit() != 0)
780					rv = -1;
781			break;
782		case IMSG_CTL_RELOAD:
783			if (idx != PFD_PIPE_SESSION)
784				log_warnx("reload request not from SE");
785			else {
786				reconfig = 1;
787				reconfpid = imsg.hdr.pid;
788			}
789			break;
790		case IMSG_CTL_FIB_COUPLE:
791			if (idx != PFD_PIPE_SESSION)
792				log_warnx("couple request not from SE");
793			else
794				kr_fib_couple(imsg.hdr.peerid,
795				    conf->fib_priority);
796			break;
797		case IMSG_CTL_FIB_DECOUPLE:
798			if (idx != PFD_PIPE_SESSION)
799				log_warnx("decouple request not from SE");
800			else
801				kr_fib_decouple(imsg.hdr.peerid,
802				    conf->fib_priority);
803			break;
804		case IMSG_CTL_KROUTE:
805		case IMSG_CTL_KROUTE_ADDR:
806		case IMSG_CTL_SHOW_NEXTHOP:
807		case IMSG_CTL_SHOW_INTERFACE:
808		case IMSG_CTL_SHOW_FIB_TABLES:
809			if (idx != PFD_PIPE_SESSION)
810				log_warnx("kroute request not from SE");
811			else
812				kr_show_route(&imsg);
813			break;
814		case IMSG_IFINFO:
815			if (idx != PFD_PIPE_SESSION)
816				log_warnx("IFINFO request not from SE");
817			else if (imsg.hdr.len != IMSG_HEADER_SIZE + IFNAMSIZ)
818				log_warnx("IFINFO request with wrong len");
819			else
820				kr_ifinfo(imsg.data);
821			break;
822		case IMSG_DEMOTE:
823			if (idx != PFD_PIPE_SESSION)
824				log_warnx("demote request not from SE");
825			else if (imsg.hdr.len != IMSG_HEADER_SIZE +
826			    sizeof(struct demote_msg))
827				log_warnx("DEMOTE request with wrong len");
828			else {
829				struct demote_msg	*msg;
830
831				msg = imsg.data;
832				carp_demote_set(msg->demote_group, msg->level);
833			}
834			break;
835		case IMSG_CTL_LOG_VERBOSE:
836			/* already checked by SE */
837			memcpy(&verbose, imsg.data, sizeof(verbose));
838			log_setverbose(verbose);
839			break;
840		case IMSG_RECONF_DONE:
841			if (reconfpending == 0) {
842				log_warnx("unexpected RECONF_DONE received");
843				break;
844			}
845			if (idx == PFD_PIPE_SESSION) {
846				imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0,
847				    0, -1, NULL, 0);
848
849				/* finally fix kroute information */
850				ktable_postload(conf->fib_priority);
851
852				/* redistribute list needs to be reloaded too */
853				kr_reload();
854			}
855			reconfpending--;
856			break;
857		case IMSG_RECONF_DRAIN:
858			if (reconfpending == 0) {
859				log_warnx("unexpected RECONF_DRAIN received");
860				break;
861			}
862			reconfpending--;
863			if (reconfpending == 0) {
864				/*
865				 * SE goes first to bring templated neighbors
866				 * in sync.
867				 */
868				imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0,
869				    0, -1, NULL, 0);
870				reconfpending = 2; /* expecting 2 DONE msg */
871			}
872			break;
873		default:
874			break;
875		}
876		imsg_free(&imsg);
877		if (rv != 0)
878			return (rv);
879	}
880	return (0);
881}
882
883void
884send_nexthop_update(struct kroute_nexthop *msg)
885{
886	char	*gw = NULL;
887
888	if (msg->gateway.aid)
889		if (asprintf(&gw, ": via %s",
890		    log_addr(&msg->gateway)) == -1) {
891			log_warn("send_nexthop_update");
892			quit = 1;
893		}
894
895	log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
896	    msg->valid ? "valid" : "invalid",
897	    msg->connected ? ": directly connected" : "",
898	    msg->gateway.aid ? gw : "");
899
900	free(gw);
901
902	if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1,
903	    msg, sizeof(struct kroute_nexthop)) == -1)
904		quit = 1;
905}
906
907void
908send_imsg_session(int type, pid_t pid, void *data, u_int16_t datalen)
909{
910	imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen);
911}
912
913int
914send_network(int type, struct network_config *net, struct filter_set_head *h)
915{
916	if (quit)
917		return (0);
918	if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
919	    sizeof(struct network_config)) == -1)
920		return (-1);
921	/* networks that get deleted don't need to send the filter set */
922	if (type == IMSG_NETWORK_REMOVE)
923		return (0);
924	if (send_filterset(ibuf_rde, h) == -1)
925		return (-1);
926	if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
927		return (-1);
928
929	return (0);
930}
931
932int
933bgpd_filternexthop(struct kroute *kr, struct kroute6 *kr6)
934{
935	/* kernel routes are never filtered */
936	if (kr && kr->flags & F_KERNEL && kr->prefixlen != 0)
937		return (0);
938	if (kr6 && kr6->flags & F_KERNEL && kr6->prefixlen != 0)
939		return (0);
940
941	if (cflags & BGPD_FLAG_NEXTHOP_BGP) {
942		if (kr && kr->flags & F_BGPD_INSERTED)
943			return (0);
944		if (kr6 && kr6->flags & F_BGPD_INSERTED)
945			return (0);
946	}
947
948	if (cflags & BGPD_FLAG_NEXTHOP_DEFAULT) {
949		if (kr && kr->prefixlen == 0)
950			return (0);
951		if (kr6 && kr6->prefixlen == 0)
952			return (0);
953	}
954
955	return (1);
956}
957
958int
959control_setup(struct bgpd_config *conf)
960{
961	int fd, restricted;
962
963	/* control socket is outside chroot */
964	if (!cname || strcmp(cname, conf->csock)) {
965		if (cname) {
966			free(cname);
967		}
968		if ((cname = strdup(conf->csock)) == NULL)
969			fatal("strdup");
970		if (control_check(cname) == -1)
971			return (-1);
972		if ((fd = control_init(0, cname)) == -1)
973			fatalx("control socket setup failed");
974		if (control_listen(fd) == -1)
975			fatalx("control socket setup failed");
976		restricted = 0;
977		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
978		    &restricted, sizeof(restricted)) == -1)
979			return (-1);
980	}
981	if (!conf->rcsock) {
982		/* remove restricted socket */
983		free(rcname);
984		rcname = NULL;
985	} else if (!rcname || strcmp(rcname, conf->rcsock)) {
986		if (rcname) {
987			free(rcname);
988		}
989		if ((rcname = strdup(conf->rcsock)) == NULL)
990			fatal("strdup");
991		if (control_check(rcname) == -1)
992			return (-1);
993		if ((fd = control_init(1, rcname)) == -1)
994			fatalx("control socket setup failed");
995		if (control_listen(fd) == -1)
996			fatalx("control socket setup failed");
997		restricted = 1;
998		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
999		    &restricted, sizeof(restricted)) == -1)
1000			return (-1);
1001	}
1002	return (0);
1003}
1004
1005void
1006set_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1007{
1008	if (i == NULL || i->fd == -1) {
1009		pfd->fd = -1;
1010		return;
1011	}
1012	pfd->fd = i->fd;
1013	pfd->events = POLLIN;
1014	if (i->w.queued > 0)
1015		pfd->events |= POLLOUT;
1016}
1017
1018int
1019handle_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1020{
1021	ssize_t n;
1022
1023	if (i == NULL)
1024		return (0);
1025
1026	if (pfd->revents & POLLOUT)
1027		if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) {
1028			log_warn("imsg write error");
1029			close(i->fd);
1030			i->fd = -1;
1031			return (-1);
1032		}
1033
1034	if (pfd->revents & POLLIN) {
1035		if ((n = imsg_read(i)) == -1 && errno != EAGAIN) {
1036			log_warn("imsg read error");
1037			close(i->fd);
1038			i->fd = -1;
1039			return (-1);
1040		}
1041		if (n == 0) {
1042			log_warnx("peer closed imsg connection");
1043			close(i->fd);
1044			i->fd = -1;
1045			return (-1);
1046		}
1047	}
1048	return (0);
1049}
1050
1051int
1052imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde)
1053{
1054	int pipe_s2r[2];
1055	int pipe_s2r_ctl[2];
1056
1057	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1058	     PF_UNSPEC, pipe_s2r) == -1)
1059		return (-1);
1060	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1061	     PF_UNSPEC, pipe_s2r_ctl) == -1)
1062		return (-1);
1063
1064	if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0],
1065	    NULL, 0) == -1)
1066		return (-1);
1067	if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1],
1068	    NULL, 0) == -1)
1069		return (-1);
1070
1071	if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0],
1072	    NULL, 0) == -1)
1073		return (-1);
1074	if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1],
1075	    NULL, 0) == -1)
1076		return (-1);
1077
1078	return (0);
1079}
1080