xref: /openbsd/usr.sbin/bgpd/bgpd.c (revision cd16358e)
1 /*	$OpenBSD: bgpd.c,v 1.270 2024/10/08 12:28:09 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 <netinet/ip.h>
24 #include <netinet/tcp.h>
25 #include <arpa/inet.h>
26 #include <err.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <poll.h>
30 #include <pwd.h>
31 #include <signal.h>
32 #include <stddef.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <syslog.h>
37 #include <unistd.h>
38 
39 #include "bgpd.h"
40 #include "session.h"
41 #include "log.h"
42 #include "version.h"
43 
44 void		sighdlr(int);
45 __dead void	usage(void);
46 int		main(int, char *[]);
47 pid_t		start_child(enum bgpd_process, char *, int, int, int);
48 int		send_filterset(struct imsgbuf *, struct filter_set_head *);
49 int		reconfigure(char *, struct bgpd_config *);
50 int		send_config(struct bgpd_config *);
51 int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
52 int		control_setup(struct bgpd_config *);
53 static void	getsockpair(int [2]);
54 int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *,
55 		    struct imsgbuf *);
56 void		bgpd_rtr_conn_setup(struct rtr_config *);
57 void		bgpd_rtr_conn_setup_done(int, struct bgpd_config *);
58 void		bgpd_rtr_conn_teardown(uint32_t);
59 
60 int			 cflags;
61 volatile sig_atomic_t	 mrtdump;
62 volatile sig_atomic_t	 quit;
63 volatile sig_atomic_t	 reconfig;
64 pid_t			 reconfpid;
65 int			 reconfpending;
66 struct imsgbuf		*ibuf_se;
67 struct imsgbuf		*ibuf_rde;
68 struct imsgbuf		*ibuf_rtr;
69 struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
70 char			*cname;
71 char			*rcname;
72 
73 struct connect_elm {
74 	TAILQ_ENTRY(connect_elm)	entry;
75 	struct auth_state		auth_state;
76 	uint32_t			id;
77 	int				fd;
78 };
79 
80 TAILQ_HEAD(, connect_elm)	connect_queue = \
81 				    TAILQ_HEAD_INITIALIZER(connect_queue),
82 				socket_queue = \
83 				    TAILQ_HEAD_INITIALIZER(socket_queue);
84 u_int				connect_cnt;
85 #define MAX_CONNECT_CNT		32
86 
87 void
sighdlr(int sig)88 sighdlr(int sig)
89 {
90 	switch (sig) {
91 	case SIGTERM:
92 	case SIGINT:
93 		quit = 1;
94 		break;
95 	case SIGHUP:
96 		reconfig = 1;
97 		break;
98 	case SIGALRM:
99 	case SIGUSR1:
100 		mrtdump = 1;
101 		break;
102 	}
103 }
104 
105 __dead void
usage(void)106 usage(void)
107 {
108 	extern char *__progname;
109 
110 	fprintf(stderr, "usage: %s [-cdnvV] [-D macro=value] [-f file]\n",
111 	    __progname);
112 	exit(1);
113 }
114 
115 #define PFD_PIPE_SESSION	0
116 #define PFD_PIPE_RDE		1
117 #define PFD_PIPE_RTR		2
118 #define PFD_SOCK_ROUTE		3
119 #define PFD_SOCK_PFKEY		4
120 #define PFD_CONNECT_START	5
121 #define MAX_TIMEOUT		3600
122 
123 int	 cmd_opts;
124 
125 int
main(int argc,char * argv[])126 main(int argc, char *argv[])
127 {
128 	struct bgpd_config	*conf;
129 	enum bgpd_process	 proc = PROC_MAIN;
130 	struct rde_rib		*rr;
131 	struct peer		*p;
132 	struct pollfd		*pfd = NULL;
133 	struct connect_elm	*ce;
134 	time_t			 timeout;
135 	pid_t			 se_pid = 0, rde_pid = 0, rtr_pid = 0, pid;
136 	char			*conffile;
137 	char			*saved_argv0;
138 	u_int			 pfd_elms = 0, npfd, i;
139 	int			 debug = 0;
140 	int			 rfd, keyfd;
141 	int			 ch, status;
142 	int			 pipe_m2s[2];
143 	int			 pipe_m2r[2];
144 	int			 pipe_m2roa[2];
145 
146 	conffile = CONFFILE;
147 
148 	log_init(1, LOG_DAEMON);	/* log to stderr until daemonized */
149 	log_procinit(log_procnames[PROC_MAIN]);
150 	log_setverbose(1);
151 
152 	saved_argv0 = argv[0];
153 	if (saved_argv0 == NULL)
154 		saved_argv0 = "bgpd";
155 
156 	while ((ch = getopt(argc, argv, "cdD:f:nRSTvV")) != -1) {
157 		switch (ch) {
158 		case 'c':
159 			cmd_opts |= BGPD_OPT_FORCE_DEMOTE;
160 			break;
161 		case 'd':
162 			debug = 1;
163 			break;
164 		case 'D':
165 			if (cmdline_symset(optarg) < 0)
166 				log_warnx("could not parse macro definition %s",
167 				    optarg);
168 			break;
169 		case 'f':
170 			conffile = optarg;
171 			break;
172 		case 'n':
173 			cmd_opts |= BGPD_OPT_NOACTION;
174 			break;
175 		case 'v':
176 			if (cmd_opts & BGPD_OPT_VERBOSE)
177 				cmd_opts |= BGPD_OPT_VERBOSE2;
178 			cmd_opts |= BGPD_OPT_VERBOSE;
179 			break;
180 		case 'R':
181 			proc = PROC_RDE;
182 			break;
183 		case 'S':
184 			proc = PROC_SE;
185 			break;
186 		case 'T':
187 			proc = PROC_RTR;
188 			break;
189 		case 'V':
190 			fprintf(stderr, "OpenBGPD %s\n", BGPD_VERSION);
191 			return 0;
192 		default:
193 			usage();
194 			/* NOTREACHED */
195 		}
196 	}
197 
198 	argc -= optind;
199 	argv += optind;
200 	if (argc > 0)
201 		usage();
202 
203 	if (cmd_opts & BGPD_OPT_NOACTION) {
204 		if ((conf = parse_config(conffile, NULL, NULL)) == NULL)
205 			exit(1);
206 
207 		if (cmd_opts & BGPD_OPT_VERBOSE)
208 			print_config(conf, &ribnames);
209 		else
210 			fprintf(stderr, "configuration OK\n");
211 
212 		while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
213 			SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
214 			free(rr);
215 		}
216 		free_config(conf);
217 		exit(0);
218 	}
219 
220 	switch (proc) {
221 	case PROC_MAIN:
222 		break;
223 	case PROC_RDE:
224 		rde_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
225 		/* NOTREACHED */
226 	case PROC_SE:
227 		session_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
228 		/* NOTREACHED */
229 	case PROC_RTR:
230 		rtr_main(debug, cmd_opts & BGPD_OPT_VERBOSE);
231 		/* NOTREACHED */
232 	}
233 
234 	if (geteuid())
235 		errx(1, "need root privileges");
236 
237 	if (getpwnam(BGPD_USER) == NULL)
238 		errx(1, "unknown user %s", BGPD_USER);
239 
240 	if ((conf = parse_config(conffile, NULL, NULL)) == NULL) {
241 		log_warnx("config file %s has errors", conffile);
242 		exit(1);
243 	}
244 
245 	if (prepare_listeners(conf) == -1)
246 		exit(1);
247 
248 	log_init(debug, LOG_DAEMON);
249 	log_setverbose(cmd_opts & BGPD_OPT_VERBOSE);
250 
251 	if (!debug)
252 		daemon(1, 0);
253 
254 	log_info("startup");
255 
256 	getsockpair(pipe_m2s);
257 	getsockpair(pipe_m2r);
258 	getsockpair(pipe_m2roa);
259 
260 	/* fork children */
261 	rde_pid = start_child(PROC_RDE, saved_argv0, pipe_m2r[1], debug,
262 	    cmd_opts & BGPD_OPT_VERBOSE);
263 	se_pid = start_child(PROC_SE, saved_argv0, pipe_m2s[1], debug,
264 	    cmd_opts & BGPD_OPT_VERBOSE);
265 	rtr_pid = start_child(PROC_RTR, saved_argv0, pipe_m2roa[1], debug,
266 	    cmd_opts & BGPD_OPT_VERBOSE);
267 
268 	signal(SIGTERM, sighdlr);
269 	signal(SIGINT, sighdlr);
270 	signal(SIGHUP, sighdlr);
271 	signal(SIGALRM, sighdlr);
272 	signal(SIGUSR1, sighdlr);
273 	signal(SIGPIPE, SIG_IGN);
274 
275 	if ((ibuf_se = malloc(sizeof(struct imsgbuf))) == NULL ||
276 	    (ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL ||
277 	    (ibuf_rtr = malloc(sizeof(struct imsgbuf))) == NULL)
278 		fatal(NULL);
279 	imsg_init(ibuf_se, pipe_m2s[0]);
280 	imsg_init(ibuf_rde, pipe_m2r[0]);
281 	imsg_init(ibuf_rtr, pipe_m2roa[0]);
282 	mrt_init(ibuf_rde, ibuf_se);
283 	if (kr_init(&rfd, conf->fib_priority) == -1)
284 		quit = 1;
285 	keyfd = pfkey_init();
286 
287 	/*
288 	 * rpath, read config file
289 	 * cpath, unlink control socket
290 	 * fattr, chmod on control socket
291 	 * wpath, needed if we are doing mrt dumps
292 	 *
293 	 * pledge placed here because kr_init() does a setsockopt on the
294 	 * routing socket thats not allowed at all.
295 	 */
296 #if 0
297 	/*
298 	 * disabled because we do ioctls on /dev/pf and SIOCSIFGATTR
299 	 * this needs some redesign of bgpd to be fixed.
300 	 */
301 BROKEN	if (pledge("stdio rpath wpath cpath fattr unix route recvfd sendfd",
302 	    NULL) == -1)
303 		fatal("pledge");
304 #endif
305 
306 	if (imsg_send_sockets(ibuf_se, ibuf_rde, ibuf_rtr))
307 		fatal("could not establish imsg links");
308 	/* control setup needs to happen late since it sends imsgs */
309 	if (control_setup(conf) == -1)
310 		quit = 1;
311 	if (send_config(conf) != 0)
312 		quit = 1;
313 	if (pftable_clear_all() != 0)
314 		quit = 1;
315 
316 	while (quit == 0) {
317 		if (pfd_elms < PFD_CONNECT_START + connect_cnt) {
318 			struct pollfd *newp;
319 
320 			if ((newp = reallocarray(pfd,
321 			    PFD_CONNECT_START + connect_cnt,
322 			    sizeof(struct pollfd))) == NULL) {
323 				log_warn("could not resize pfd from %u -> %u"
324 				    " entries", pfd_elms, PFD_CONNECT_START +
325 				    connect_cnt);
326 				fatalx("exiting");
327 			}
328 			pfd = newp;
329 			pfd_elms = PFD_CONNECT_START + connect_cnt;
330 		}
331 		memset(pfd, 0, sizeof(struct pollfd) * pfd_elms);
332 
333 		timeout = mrt_timeout(conf->mrt);
334 
335 		pfd[PFD_SOCK_ROUTE].fd = rfd;
336 		pfd[PFD_SOCK_ROUTE].events = POLLIN;
337 
338 		pfd[PFD_SOCK_PFKEY].fd = keyfd;
339 		pfd[PFD_SOCK_PFKEY].events = POLLIN;
340 
341 		set_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se);
342 		set_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde);
343 		set_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr);
344 
345 		npfd = PFD_CONNECT_START;
346 		TAILQ_FOREACH(ce, &connect_queue, entry) {
347 			pfd[npfd].fd = ce->fd;
348 			pfd[npfd++].events = POLLOUT;
349 			if (npfd > pfd_elms)
350 				fatalx("polli pfd overflow");
351 		}
352 
353 		if (timeout < 0 || timeout > MAX_TIMEOUT)
354 			timeout = MAX_TIMEOUT;
355 		if (poll(pfd, npfd, timeout * 1000) == -1) {
356 			if (errno != EINTR) {
357 				log_warn("poll error");
358 				quit = 1;
359 			}
360 			goto next_loop;
361 		}
362 
363 		if (handle_pollfd(&pfd[PFD_PIPE_SESSION], ibuf_se) == -1) {
364 			log_warnx("main: Lost connection to SE");
365 			msgbuf_clear(&ibuf_se->w);
366 			free(ibuf_se);
367 			ibuf_se = NULL;
368 			quit = 1;
369 		} else {
370 			if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) ==
371 			    -1)
372 				quit = 1;
373 		}
374 
375 		if (handle_pollfd(&pfd[PFD_PIPE_RDE], ibuf_rde) == -1) {
376 			log_warnx("main: Lost connection to RDE");
377 			msgbuf_clear(&ibuf_rde->w);
378 			free(ibuf_rde);
379 			ibuf_rde = NULL;
380 			quit = 1;
381 		} else {
382 			if (dispatch_imsg(ibuf_rde, PFD_PIPE_RDE, conf) == -1)
383 				quit = 1;
384 		}
385 
386 		if (handle_pollfd(&pfd[PFD_PIPE_RTR], ibuf_rtr) == -1) {
387 			log_warnx("main: Lost connection to RTR");
388 			msgbuf_clear(&ibuf_rtr->w);
389 			free(ibuf_rtr);
390 			ibuf_rtr = NULL;
391 			quit = 1;
392 		} else {
393 			if (dispatch_imsg(ibuf_rtr, PFD_PIPE_RTR, conf) == -1)
394 				quit = 1;
395 		}
396 
397 		if (pfd[PFD_SOCK_ROUTE].revents & POLLIN) {
398 			if (kr_dispatch_msg() == -1)
399 				quit = 1;
400 		}
401 
402 		if (pfd[PFD_SOCK_PFKEY].revents & POLLIN) {
403 			if (pfkey_read(keyfd, NULL) == -1) {
404 				log_warnx("pfkey_read failed, exiting...");
405 				quit = 1;
406 			}
407 		}
408 
409 		for (i = PFD_CONNECT_START; i < npfd; i++)
410 			if (pfd[i].revents != 0)
411 				bgpd_rtr_conn_setup_done(pfd[i].fd, conf);
412 
413  next_loop:
414 		if (reconfig) {
415 			u_int	error;
416 
417 			reconfig = 0;
418 			switch (reconfigure(conffile, conf)) {
419 			case -1:	/* fatal error */
420 				quit = 1;
421 				break;
422 			case 0:		/* all OK */
423 				error = 0;
424 				break;
425 			case 2:
426 				log_info("previous reload still running");
427 				error = CTL_RES_PENDING;
428 				break;
429 			default:	/* parse error */
430 				log_warnx("config file %s has errors, "
431 				    "not reloading", conffile);
432 				error = CTL_RES_PARSE_ERROR;
433 				break;
434 			}
435 			if (reconfpid != 0) {
436 				send_imsg_session(IMSG_CTL_RESULT, reconfpid,
437 				    &error, sizeof(error));
438 				reconfpid = 0;
439 			}
440 		}
441 
442 		if (mrtdump) {
443 			mrtdump = 0;
444 			mrt_handler(conf->mrt);
445 		}
446 	}
447 
448 	/* close pipes */
449 	if (ibuf_se) {
450 		msgbuf_clear(&ibuf_se->w);
451 		close(ibuf_se->fd);
452 		free(ibuf_se);
453 		ibuf_se = NULL;
454 	}
455 	if (ibuf_rde) {
456 		msgbuf_clear(&ibuf_rde->w);
457 		close(ibuf_rde->fd);
458 		free(ibuf_rde);
459 		ibuf_rde = NULL;
460 	}
461 	if (ibuf_rtr) {
462 		msgbuf_clear(&ibuf_rtr->w);
463 		close(ibuf_rtr->fd);
464 		free(ibuf_rtr);
465 		ibuf_rtr = NULL;
466 	}
467 
468 	/* cleanup kernel data structures */
469 	carp_demote_shutdown();
470 	kr_shutdown();
471 	pftable_clear_all();
472 
473 	RB_FOREACH(p, peer_head, &conf->peers)
474 		pfkey_remove(&p->auth_state);
475 
476 	while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
477 		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
478 		free(rr);
479 	}
480 	free_config(conf);
481 
482 	log_debug("waiting for children to terminate");
483 	do {
484 		pid = wait(&status);
485 		if (pid == -1) {
486 			if (errno != EINTR && errno != ECHILD)
487 				fatal("wait");
488 		} else if (WIFSIGNALED(status)) {
489 			char *name = "unknown process";
490 			if (pid == rde_pid)
491 				name = "route decision engine";
492 			else if (pid == se_pid)
493 				name = "session engine";
494 			else if (pid == rtr_pid)
495 				name = "rtr engine";
496 			log_warnx("%s terminated; signal %d", name,
497 				WTERMSIG(status));
498 		}
499 	} while (pid != -1 || (pid == -1 && errno == EINTR));
500 
501 	free(rcname);
502 	free(cname);
503 
504 	log_info("terminating");
505 	return (0);
506 }
507 
508 pid_t
start_child(enum bgpd_process p,char * argv0,int fd,int debug,int verbose)509 start_child(enum bgpd_process p, char *argv0, int fd, int debug, int verbose)
510 {
511 	char *argv[5];
512 	int argc = 0;
513 	pid_t pid;
514 
515 	switch (pid = fork()) {
516 	case -1:
517 		fatal("cannot fork");
518 	case 0:
519 		break;
520 	default:
521 		close(fd);
522 		return (pid);
523 	}
524 
525 	if (fd != 3) {
526 		if (dup2(fd, 3) == -1)
527 			fatal("cannot setup imsg fd");
528 	} else if (fcntl(fd, F_SETFD, 0) == -1)
529 		fatal("cannot setup imsg fd");
530 
531 	argv[argc++] = argv0;
532 	switch (p) {
533 	case PROC_MAIN:
534 		fatalx("Can not start main process");
535 	case PROC_RDE:
536 		argv[argc++] = "-R";
537 		break;
538 	case PROC_SE:
539 		argv[argc++] = "-S";
540 		break;
541 	case PROC_RTR:
542 		argv[argc++] = "-T";
543 		break;
544 	}
545 	if (debug)
546 		argv[argc++] = "-d";
547 	if (verbose)
548 		argv[argc++] = "-v";
549 	argv[argc++] = NULL;
550 
551 	execvp(argv0, argv);
552 	fatal("execvp");
553 }
554 
555 int
send_filterset(struct imsgbuf * i,struct filter_set_head * set)556 send_filterset(struct imsgbuf *i, struct filter_set_head *set)
557 {
558 	struct filter_set	*s;
559 
560 	TAILQ_FOREACH(s, set, entry)
561 		if (imsg_compose(i, IMSG_FILTER_SET, 0, 0, -1, s,
562 		    sizeof(struct filter_set)) == -1)
563 			return (-1);
564 	return (0);
565 }
566 
567 int
reconfigure(char * conffile,struct bgpd_config * conf)568 reconfigure(char *conffile, struct bgpd_config *conf)
569 {
570 	struct bgpd_config	*new_conf;
571 
572 	if (reconfpending)
573 		return (2);
574 
575 	log_info("rereading config");
576 	if ((new_conf = parse_config(conffile, &conf->peers,
577 	    &conf->rtrs)) == NULL)
578 		return (1);
579 
580 	merge_config(conf, new_conf);
581 
582 	if (prepare_listeners(conf) == -1)
583 		return (1);
584 
585 	if (control_setup(conf) == -1)
586 		return (1);
587 
588 	return send_config(conf);
589 }
590 
591 int
send_config(struct bgpd_config * conf)592 send_config(struct bgpd_config *conf)
593 {
594 	struct peer		*p;
595 	struct filter_rule	*r;
596 	struct listen_addr	*la;
597 	struct rde_rib		*rr;
598 	struct l3vpn		*vpn;
599 	struct as_set		*aset;
600 	struct prefixset	*ps;
601 	struct prefixset_item	*psi, *npsi;
602 	struct roa		*roa;
603 	struct aspa_set		*aspa;
604 	struct rtr_config	*rtr;
605 	struct flowspec_config	*f, *nf;
606 
607 	reconfpending = 3;	/* one per child */
608 
609 	expand_networks(conf, &conf->networks);
610 	SIMPLEQ_FOREACH(vpn, &conf->l3vpns, entry)
611 		expand_networks(conf, &vpn->net_l);
612 
613 	cflags = conf->flags;
614 
615 	/* start reconfiguration */
616 	if (imsg_compose(ibuf_se, IMSG_RECONF_CONF, 0, 0, -1,
617 	    conf, sizeof(*conf)) == -1)
618 		return (-1);
619 	if (imsg_compose(ibuf_rde, IMSG_RECONF_CONF, 0, 0, -1,
620 	    conf, sizeof(*conf)) == -1)
621 		return (-1);
622 	if (imsg_compose(ibuf_rtr, IMSG_RECONF_CONF, 0, 0, -1,
623 	    conf, sizeof(*conf)) == -1)
624 		return (-1);
625 
626 	TAILQ_FOREACH(la, conf->listen_addrs, entry) {
627 		if (imsg_compose(ibuf_se, IMSG_RECONF_LISTENER, 0, 0, la->fd,
628 		    la, sizeof(*la)) == -1)
629 			return (-1);
630 		la->fd = -1;
631 	}
632 
633 	/* adjust fib syncing on reload */
634 	ktable_preload();
635 
636 	/* RIBs for the RDE */
637 	while ((rr = SIMPLEQ_FIRST(&ribnames))) {
638 		SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
639 		if (ktable_update(rr->rtableid, rr->name, rr->flags) == -1) {
640 			log_warnx("failed to load routing table %d",
641 			    rr->rtableid);
642 			return (-1);
643 		}
644 		if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1,
645 		    rr, sizeof(*rr)) == -1)
646 			return (-1);
647 		free(rr);
648 	}
649 
650 	/* send peer list to the SE */
651 	RB_FOREACH(p, peer_head, &conf->peers) {
652 		if (p->reconf_action == RECONF_DELETE)
653 			continue;
654 
655 		if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
656 		    &p->conf, sizeof(p->conf)) == -1)
657 			return (-1);
658 		if (pfkey_send_conf(ibuf_se, p->conf.id, &p->auth_conf) == -1)
659 			return (-1);
660 
661 		if (p->reconf_action == RECONF_REINIT)
662 			if (pfkey_establish(&p->auth_state, &p->auth_conf,
663 			    session_localaddr(p), &p->conf.remote_addr) == -1)
664 				log_peer_warnx(&p->conf, "auth setup failed");
665 	}
666 
667 	/* networks go via kroute to the RDE */
668 	kr_net_reload(conf->default_tableid, 0, &conf->networks);
669 
670 	/* flowspec goes directly to the RDE, also remove old objects */
671 	RB_FOREACH_SAFE(f, flowspec_tree, &conf->flowspecs, nf) {
672 		if (f->reconf_action != RECONF_DELETE) {
673 			if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_ADD, 0, 0, -1,
674 			    f->flow, FLOWSPEC_SIZE + f->flow->len) == -1)
675 				return (-1);
676 			if (send_filterset(ibuf_rde, &f->attrset) == -1)
677 				return (-1);
678 			if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_DONE, 0, 0, -1,
679 			    NULL, 0) == -1)
680 				return (-1);
681 		} else {
682 			if (imsg_compose(ibuf_rde, IMSG_FLOWSPEC_REMOVE, 0, 0,
683 			    -1, f->flow, FLOWSPEC_SIZE + f->flow->len) == -1)
684 				return (-1);
685 			RB_REMOVE(flowspec_tree, &conf->flowspecs, f);
686 			flowspec_free(f);
687 		}
688 	}
689 
690 	/* prefixsets for filters in the RDE */
691 	while ((ps = SIMPLEQ_FIRST(&conf->prefixsets)) != NULL) {
692 		SIMPLEQ_REMOVE_HEAD(&conf->prefixsets, entry);
693 		if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET, 0, 0, -1,
694 		    ps->name, sizeof(ps->name)) == -1)
695 			return (-1);
696 		RB_FOREACH_SAFE(psi, prefixset_tree, &ps->psitems, npsi) {
697 			RB_REMOVE(prefixset_tree, &ps->psitems, psi);
698 			if (imsg_compose(ibuf_rde, IMSG_RECONF_PREFIX_SET_ITEM,
699 			    0, 0, -1, psi, sizeof(*psi)) == -1)
700 				return (-1);
701 			free(psi);
702 		}
703 		free(ps);
704 	}
705 
706 	/* originsets for filters in the RDE */
707 	while ((ps = SIMPLEQ_FIRST(&conf->originsets)) != NULL) {
708 		SIMPLEQ_REMOVE_HEAD(&conf->originsets, entry);
709 		if (imsg_compose(ibuf_rde, IMSG_RECONF_ORIGIN_SET, 0, 0, -1,
710 		    ps->name, sizeof(ps->name)) == -1)
711 			return (-1);
712 		RB_FOREACH(roa, roa_tree, &ps->roaitems) {
713 			if (imsg_compose(ibuf_rde, IMSG_RECONF_ROA_ITEM, 0, 0,
714 			    -1, roa, sizeof(*roa)) == -1)
715 				return (-1);
716 		}
717 		free_roatree(&ps->roaitems);
718 		free(ps);
719 	}
720 
721 	/* roa table, aspa table and rtr config are sent to the RTR engine */
722 	RB_FOREACH(roa, roa_tree, &conf->roa) {
723 		if (imsg_compose(ibuf_rtr, IMSG_RECONF_ROA_ITEM, 0, 0,
724 		    -1, roa, sizeof(*roa)) == -1)
725 			return (-1);
726 	}
727 	free_roatree(&conf->roa);
728 	RB_FOREACH(aspa, aspa_tree, &conf->aspa) {
729 		/* XXX prevent oversized IMSG for now */
730 		if (aspa->num * sizeof(*aspa->tas) >
731 		    MAX_IMSGSIZE - IMSG_HEADER_SIZE) {
732 			log_warnx("oversized ASPA set for customer-as %s, %s",
733 			    log_as(aspa->as), "dropped");
734 			continue;
735 		}
736 
737 		if (imsg_compose(ibuf_rtr, IMSG_RECONF_ASPA, 0, 0,
738 		    -1, aspa, offsetof(struct aspa_set, tas)) == -1)
739 			return (-1);
740 		if (imsg_compose(ibuf_rtr, IMSG_RECONF_ASPA_TAS, 0, 0,
741 		    -1, aspa->tas, aspa->num * sizeof(*aspa->tas)) == -1)
742 			return (-1);
743 		if (imsg_compose(ibuf_rtr, IMSG_RECONF_ASPA_DONE, 0, 0, -1,
744 		    NULL, 0) == -1)
745 			return -1;
746 	}
747 	free_aspatree(&conf->aspa);
748 	SIMPLEQ_FOREACH(rtr, &conf->rtrs, entry) {
749 		struct rtr_config_msg rtrconf = { 0 };
750 
751 		strlcpy(rtrconf.descr, rtr->descr, sizeof(rtrconf.descr));
752 		rtrconf.min_version = rtr->min_version;
753 		if (imsg_compose(ibuf_rtr, IMSG_RECONF_RTR_CONFIG, rtr->id,
754 		    0, -1, &rtrconf, sizeof(rtrconf)) == -1)
755 			return (-1);
756 	}
757 
758 	/* as-sets for filters in the RDE */
759 	while ((aset = SIMPLEQ_FIRST(&conf->as_sets)) != NULL) {
760 		struct ibuf *wbuf;
761 		uint32_t *as;
762 		size_t i, l, n;
763 
764 		SIMPLEQ_REMOVE_HEAD(&conf->as_sets, entry);
765 
766 		as = set_get(aset->set, &n);
767 		if ((wbuf = imsg_create(ibuf_rde, IMSG_RECONF_AS_SET, 0, 0,
768 		    sizeof(n) + sizeof(aset->name))) == NULL)
769 			return -1;
770 		if (imsg_add(wbuf, &n, sizeof(n)) == -1 ||
771 		    imsg_add(wbuf, aset->name, sizeof(aset->name)) == -1)
772 			return -1;
773 		imsg_close(ibuf_rde, wbuf);
774 
775 		for (i = 0; i < n; i += l) {
776 			l = (n - i > 1024 ? 1024 : n - i);
777 			if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_ITEMS,
778 			    0, 0, -1, as + i, l * sizeof(*as)) == -1)
779 				return -1;
780 		}
781 
782 		if (imsg_compose(ibuf_rde, IMSG_RECONF_AS_SET_DONE, 0, 0, -1,
783 		    NULL, 0) == -1)
784 			return -1;
785 
786 		set_free(aset->set);
787 		free(aset);
788 	}
789 
790 	/* filters for the RDE */
791 	while ((r = TAILQ_FIRST(conf->filters)) != NULL) {
792 		TAILQ_REMOVE(conf->filters, r, entry);
793 		if (send_filterset(ibuf_rde, &r->set) == -1)
794 			return (-1);
795 		if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1,
796 		    r, sizeof(struct filter_rule)) == -1)
797 			return (-1);
798 		filterset_free(&r->set);
799 		free(r);
800 	}
801 
802 	while ((vpn = SIMPLEQ_FIRST(&conf->l3vpns)) != NULL) {
803 		SIMPLEQ_REMOVE_HEAD(&conf->l3vpns, entry);
804 		if (ktable_update(vpn->rtableid, vpn->descr, vpn->flags) ==
805 		    -1) {
806 			log_warnx("failed to load routing table %d",
807 			    vpn->rtableid);
808 			return (-1);
809 		}
810 		/* networks go via kroute to the RDE */
811 		kr_net_reload(vpn->rtableid, vpn->rd, &vpn->net_l);
812 
813 		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN, 0, 0, -1,
814 		    vpn, sizeof(*vpn)) == -1)
815 			return (-1);
816 
817 		/* export targets */
818 		if (send_filterset(ibuf_rde, &vpn->export) == -1)
819 			return (-1);
820 		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_EXPORT, 0, 0,
821 		    -1, NULL, 0) == -1)
822 			return (-1);
823 		filterset_free(&vpn->export);
824 
825 		/* import targets */
826 		if (send_filterset(ibuf_rde, &vpn->import) == -1)
827 			return (-1);
828 		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_IMPORT, 0, 0,
829 		    -1, NULL, 0) == -1)
830 			return (-1);
831 		filterset_free(&vpn->import);
832 
833 		if (imsg_compose(ibuf_rde, IMSG_RECONF_VPN_DONE, 0, 0,
834 		    -1, NULL, 0) == -1)
835 			return (-1);
836 
837 		free(vpn);
838 	}
839 
840 	/* send a drain message to know when all messages where processed */
841 	if (imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
842 		return (-1);
843 	if (imsg_compose(ibuf_rde, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
844 		return (-1);
845 	if (imsg_compose(ibuf_rtr, IMSG_RECONF_DRAIN, 0, 0, -1, NULL, 0) == -1)
846 		return (-1);
847 
848 	/* mrt changes can be sent out of bound */
849 	mrt_reconfigure(conf->mrt);
850 	return (0);
851 }
852 
853 int
dispatch_imsg(struct imsgbuf * imsgbuf,int idx,struct bgpd_config * conf)854 dispatch_imsg(struct imsgbuf *imsgbuf, int idx, struct bgpd_config *conf)
855 {
856 	struct imsg		 imsg;
857 	struct peer		*p;
858 	struct rtr_config	*r;
859 	struct kroute_full	 kf;
860 	struct bgpd_addr	 addr;
861 	struct pftable_msg	 pfmsg;
862 	struct demote_msg	 demote;
863 	char			 reason[REASON_LEN], ifname[IFNAMSIZ];
864 	ssize_t			 n;
865 	u_int			 rtableid;
866 	int			 rv, verbose;
867 
868 	rv = 0;
869 	while (imsgbuf) {
870 		if ((n = imsg_get(imsgbuf, &imsg)) == -1)
871 			return (-1);
872 
873 		if (n == 0)
874 			break;
875 
876 		switch (imsg_get_type(&imsg)) {
877 		case IMSG_KROUTE_CHANGE:
878 			if (idx != PFD_PIPE_RDE)
879 				log_warnx("route request not from RDE");
880 			else if (imsg_get_data(&imsg, &kf, sizeof(kf)) == -1)
881 				log_warn("wrong imsg len");
882 			else if (kr_change(imsg_get_id(&imsg), &kf))
883 				rv = -1;
884 			break;
885 		case IMSG_KROUTE_DELETE:
886 			if (idx != PFD_PIPE_RDE)
887 				log_warnx("route request not from RDE");
888 			else if (imsg_get_data(&imsg, &kf, sizeof(kf)) == -1)
889 				log_warn("wrong imsg len");
890 			else if (kr_delete(imsg_get_id(&imsg), &kf))
891 				rv = -1;
892 			break;
893 		case IMSG_KROUTE_FLUSH:
894 			if (idx != PFD_PIPE_RDE)
895 				log_warnx("route request not from RDE");
896 			else if (kr_flush(imsg_get_id(&imsg)))
897 				rv = -1;
898 			break;
899 		case IMSG_NEXTHOP_ADD:
900 			if (idx != PFD_PIPE_RDE)
901 				log_warnx("nexthop request not from RDE");
902 			else if (imsg_get_data(&imsg, &addr, sizeof(addr)) ==
903 			    -1)
904 				log_warn("wrong imsg len");
905 			else {
906 				rtableid = conf->default_tableid;
907 				if (kr_nexthop_add(rtableid, &addr) == -1)
908 					rv = -1;
909 			}
910 			break;
911 		case IMSG_NEXTHOP_REMOVE:
912 			if (idx != PFD_PIPE_RDE)
913 				log_warnx("nexthop request not from RDE");
914 			else if (imsg_get_data(&imsg, &addr, sizeof(addr)) ==
915 			    -1)
916 				log_warn("wrong imsg len");
917 			else {
918 				rtableid = conf->default_tableid;
919 				kr_nexthop_delete(rtableid, &addr);
920 			}
921 			break;
922 		case IMSG_PFTABLE_ADD:
923 			if (idx != PFD_PIPE_RDE)
924 				log_warnx("pftable request not from RDE");
925 			else if (imsg_get_data(&imsg, &pfmsg, sizeof(pfmsg)) ==
926 			    -1)
927 				log_warn("wrong imsg len");
928 			else if (pftable_addr_add(&pfmsg) != 0)
929 				rv = -1;
930 			break;
931 		case IMSG_PFTABLE_REMOVE:
932 			if (idx != PFD_PIPE_RDE)
933 				log_warnx("pftable request not from RDE");
934 			else if (imsg_get_data(&imsg, &pfmsg, sizeof(pfmsg)) ==
935 			    -1)
936 				log_warn("wrong imsg len");
937 			else if (pftable_addr_remove(&pfmsg) != 0)
938 				rv = -1;
939 			break;
940 		case IMSG_PFTABLE_COMMIT:
941 			if (idx != PFD_PIPE_RDE)
942 				log_warnx("pftable request not from RDE");
943 			else if (pftable_commit() != 0)
944 				rv = -1;
945 			break;
946 		case IMSG_PFKEY_RELOAD:
947 			if (idx != PFD_PIPE_SESSION) {
948 				log_warnx("pfkey reload request not from SE");
949 				break;
950 			}
951 			p = getpeerbyid(conf, imsg_get_id(&imsg));
952 			if (p != NULL) {
953 				if (pfkey_establish(&p->auth_state,
954 				    &p->auth_conf, session_localaddr(p),
955 				    &p->conf.remote_addr) == -1)
956 					log_peer_warnx(&p->conf,
957 					    "pfkey setup failed");
958 			}
959 			break;
960 		case IMSG_CTL_RELOAD:
961 			if (idx != PFD_PIPE_SESSION)
962 				log_warnx("reload request not from SE");
963 			else {
964 				reconfig = 1;
965 				reconfpid = imsg_get_pid(&imsg);
966 				if (imsg_get_data(&imsg, reason,
967 				    sizeof(reason)) == 0 && reason[0] != '\0')
968 					log_info("reload due to: %s",
969 					    log_reason(reason));
970 			}
971 			break;
972 		case IMSG_CTL_FIB_COUPLE:
973 			if (idx != PFD_PIPE_SESSION)
974 				log_warnx("couple request not from SE");
975 			else
976 				kr_fib_couple(imsg_get_id(&imsg));
977 			break;
978 		case IMSG_CTL_FIB_DECOUPLE:
979 			if (idx != PFD_PIPE_SESSION)
980 				log_warnx("decouple request not from SE");
981 			else
982 				kr_fib_decouple(imsg_get_id(&imsg));
983 			break;
984 		case IMSG_CTL_KROUTE:
985 		case IMSG_CTL_KROUTE_ADDR:
986 		case IMSG_CTL_SHOW_NEXTHOP:
987 		case IMSG_CTL_SHOW_INTERFACE:
988 		case IMSG_CTL_SHOW_FIB_TABLES:
989 			if (idx != PFD_PIPE_SESSION)
990 				log_warnx("kroute request not from SE");
991 			else
992 				kr_show_route(&imsg);
993 			break;
994 		case IMSG_SESSION_DEPENDON:
995 			if (idx != PFD_PIPE_SESSION)
996 				log_warnx("DEPENDON request not from SE");
997 			else if (imsg_get_data(&imsg, ifname, sizeof(ifname)) ==
998 			    -1)
999 				log_warn("wrong imsg len");
1000 			else
1001 				kr_ifinfo(ifname);
1002 			break;
1003 		case IMSG_DEMOTE:
1004 			if (idx != PFD_PIPE_SESSION)
1005 				log_warnx("demote request not from SE");
1006 			else if (imsg_get_data(&imsg, &demote, sizeof(demote))
1007 			    == -1)
1008 				log_warn("wrong imsg len");
1009 			else
1010 				carp_demote_set(demote.demote_group,
1011 				    demote.level);
1012 			break;
1013 		case IMSG_CTL_LOG_VERBOSE:
1014 			/* already checked by SE */
1015 			if (imsg_get_data(&imsg, &verbose, sizeof(verbose)) ==
1016 			    -1)
1017 				log_warn("wrong imsg len");
1018 			else
1019 				log_setverbose(verbose);
1020 			break;
1021 		case IMSG_RECONF_DONE:
1022 			if (reconfpending == 0) {
1023 				log_warnx("unexpected RECONF_DONE received");
1024 				break;
1025 			}
1026 			if (idx == PFD_PIPE_SESSION) {
1027 				/* RDE and RTR engine can reload concurrently */
1028 				imsg_compose(ibuf_rtr, IMSG_RECONF_DONE, 0,
1029 				    0, -1, NULL, 0);
1030 				imsg_compose(ibuf_rde, IMSG_RECONF_DONE, 0,
1031 				    0, -1, NULL, 0);
1032 
1033 				/* finally fix kroute information */
1034 				ktable_postload();
1035 
1036 				/* redistribute list needs to be reloaded too */
1037 				kr_reload();
1038 
1039 				/* also remove old peers */
1040 				free_deleted_peers(conf);
1041 			}
1042 			reconfpending--;
1043 			break;
1044 		case IMSG_RECONF_DRAIN:
1045 			if (reconfpending == 0) {
1046 				log_warnx("unexpected RECONF_DRAIN received");
1047 				break;
1048 			}
1049 			reconfpending--;
1050 			if (reconfpending == 0) {
1051 				/*
1052 				 * SE goes first to bring templated neighbors
1053 				 * in sync.
1054 				 */
1055 				imsg_compose(ibuf_se, IMSG_RECONF_DONE, 0,
1056 				    0, -1, NULL, 0);
1057 				reconfpending = 3; /* expecting 2 DONE msg */
1058 			}
1059 			break;
1060 		case IMSG_SOCKET_SETUP:
1061 			if (idx != PFD_PIPE_RTR) {
1062 				log_warnx("connect request not from RTR");
1063 			} else {
1064 				uint32_t rtrid = imsg_get_id(&imsg);
1065 				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1066 					if (rtrid == r->id)
1067 						break;
1068 				}
1069 				if (r == NULL)
1070 					log_warnx("unknown rtr id %d", rtrid);
1071 				else
1072 					bgpd_rtr_conn_setup(r);
1073 			}
1074 			break;
1075 		case IMSG_SOCKET_TEARDOWN:
1076 			if (idx != PFD_PIPE_RTR) {
1077 				log_warnx("connect request not from RTR");
1078 			} else {
1079 				uint32_t rtrid = imsg_get_id(&imsg);
1080 				bgpd_rtr_conn_teardown(rtrid);
1081 			}
1082 			break;
1083 		case IMSG_CTL_SHOW_RTR:
1084 			if (idx == PFD_PIPE_SESSION) {
1085 				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1086 					imsg_compose(ibuf_rtr,
1087 					    IMSG_CTL_SHOW_RTR, r->id,
1088 					    imsg_get_pid(&imsg), -1, NULL, 0);
1089 				}
1090 				imsg_compose(ibuf_rtr, IMSG_CTL_END,
1091 				    0, imsg_get_pid(&imsg), -1, NULL, 0);
1092 			} else if (idx == PFD_PIPE_RTR) {
1093 				struct ctl_show_rtr rtr;
1094 				if (imsg_get_data(&imsg, &rtr, sizeof(rtr)) ==
1095 				    -1) {
1096 					log_warn("wrong imsg len");
1097 					break;
1098 				}
1099 
1100 				SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1101 					if (imsg_get_id(&imsg) == r->id)
1102 						break;
1103 				}
1104 				if (r != NULL) {
1105 					strlcpy(rtr.descr, r->descr,
1106 					    sizeof(rtr.descr));
1107 					rtr.local_addr = r->local_addr;
1108 					rtr.remote_addr = r->remote_addr;
1109 					rtr.remote_port = r->remote_port;
1110 
1111 					imsg_compose(ibuf_se, IMSG_CTL_SHOW_RTR,
1112 					    imsg_get_id(&imsg),
1113 					    imsg_get_pid(&imsg), -1,
1114 					    &rtr, sizeof(rtr));
1115 				}
1116 			}
1117 			break;
1118 		case IMSG_CTL_END:
1119 		case IMSG_CTL_SHOW_TIMER:
1120 			if (idx != PFD_PIPE_RTR) {
1121 				log_warnx("connect request not from RTR");
1122 				break;
1123 			}
1124 			imsg_forward(ibuf_se, &imsg);
1125 			break;
1126 		default:
1127 			break;
1128 		}
1129 		imsg_free(&imsg);
1130 		if (rv != 0)
1131 			return (rv);
1132 	}
1133 	return (0);
1134 }
1135 
1136 void
send_nexthop_update(struct kroute_nexthop * msg)1137 send_nexthop_update(struct kroute_nexthop *msg)
1138 {
1139 	char	*gw = NULL;
1140 
1141 	if (msg->gateway.aid)
1142 		if (asprintf(&gw, ": via %s",
1143 		    log_addr(&msg->gateway)) == -1) {
1144 			log_warn("send_nexthop_update");
1145 			quit = 1;
1146 		}
1147 
1148 	log_debug("nexthop %s now %s%s%s", log_addr(&msg->nexthop),
1149 	    msg->valid ? "valid" : "invalid",
1150 	    msg->connected ? ": directly connected" : "",
1151 	    msg->gateway.aid ? gw : "");
1152 
1153 	free(gw);
1154 
1155 	if (imsg_compose(ibuf_rde, IMSG_NEXTHOP_UPDATE, 0, 0, -1,
1156 	    msg, sizeof(struct kroute_nexthop)) == -1)
1157 		quit = 1;
1158 }
1159 
1160 void
send_imsg_session(int type,pid_t pid,void * data,uint16_t datalen)1161 send_imsg_session(int type, pid_t pid, void *data, uint16_t datalen)
1162 {
1163 	imsg_compose(ibuf_se, type, 0, pid, -1, data, datalen);
1164 }
1165 
1166 int
send_network(int type,struct network_config * net,struct filter_set_head * h)1167 send_network(int type, struct network_config *net, struct filter_set_head *h)
1168 {
1169 	if (quit)
1170 		return (0);
1171 	if (imsg_compose(ibuf_rde, type, 0, 0, -1, net,
1172 	    sizeof(struct network_config)) == -1)
1173 		return (-1);
1174 	/* networks that get deleted don't need to send the filter set */
1175 	if (type == IMSG_NETWORK_REMOVE)
1176 		return (0);
1177 	if (send_filterset(ibuf_rde, h) == -1)
1178 		return (-1);
1179 	if (imsg_compose(ibuf_rde, IMSG_NETWORK_DONE, 0, 0, -1, NULL, 0) == -1)
1180 		return (-1);
1181 
1182 	return (0);
1183 }
1184 
1185 /*
1186  * Return true if a route can be used for nexthop resolution.
1187  */
1188 int
bgpd_oknexthop(struct kroute_full * kf)1189 bgpd_oknexthop(struct kroute_full *kf)
1190 {
1191 	if (kf->flags & F_BGPD)
1192 		return ((cflags & BGPD_FLAG_NEXTHOP_BGP) != 0);
1193 
1194 	if (kf->prefixlen == 0)
1195 		return ((cflags & BGPD_FLAG_NEXTHOP_DEFAULT) != 0);
1196 
1197 	/* any other route is fine */
1198 	return (1);
1199 }
1200 
1201 int
bgpd_has_bgpnh(void)1202 bgpd_has_bgpnh(void)
1203 {
1204 	return ((cflags & BGPD_FLAG_NEXTHOP_BGP) != 0);
1205 }
1206 
1207 int
control_setup(struct bgpd_config * conf)1208 control_setup(struct bgpd_config *conf)
1209 {
1210 	int fd, restricted;
1211 
1212 	/* control socket is outside chroot */
1213 	if (!cname || strcmp(cname, conf->csock)) {
1214 		if (cname) {
1215 			free(cname);
1216 		}
1217 		if ((cname = strdup(conf->csock)) == NULL)
1218 			fatal("strdup");
1219 		if (control_check(cname) == -1)
1220 			return (-1);
1221 		if ((fd = control_init(0, cname)) == -1)
1222 			fatalx("control socket setup failed");
1223 		if (control_listen(fd) == -1)
1224 			fatalx("control socket setup failed");
1225 		restricted = 0;
1226 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
1227 		    &restricted, sizeof(restricted)) == -1)
1228 			return (-1);
1229 	}
1230 	if (!conf->rcsock) {
1231 		/* remove restricted socket */
1232 		free(rcname);
1233 		rcname = NULL;
1234 	} else if (!rcname || strcmp(rcname, conf->rcsock)) {
1235 		if (rcname) {
1236 			free(rcname);
1237 		}
1238 		if ((rcname = strdup(conf->rcsock)) == NULL)
1239 			fatal("strdup");
1240 		if (control_check(rcname) == -1)
1241 			return (-1);
1242 		if ((fd = control_init(1, rcname)) == -1)
1243 			fatalx("control socket setup failed");
1244 		if (control_listen(fd) == -1)
1245 			fatalx("control socket setup failed");
1246 		restricted = 1;
1247 		if (imsg_compose(ibuf_se, IMSG_RECONF_CTRL, 0, 0, fd,
1248 		    &restricted, sizeof(restricted)) == -1)
1249 			return (-1);
1250 	}
1251 	return (0);
1252 }
1253 
1254 void
set_pollfd(struct pollfd * pfd,struct imsgbuf * i)1255 set_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1256 {
1257 	if (i == NULL || i->fd == -1) {
1258 		pfd->fd = -1;
1259 		return;
1260 	}
1261 	pfd->fd = i->fd;
1262 	pfd->events = POLLIN;
1263 	if (i->w.queued > 0)
1264 		pfd->events |= POLLOUT;
1265 }
1266 
1267 int
handle_pollfd(struct pollfd * pfd,struct imsgbuf * i)1268 handle_pollfd(struct pollfd *pfd, struct imsgbuf *i)
1269 {
1270 	ssize_t n;
1271 
1272 	if (i == NULL)
1273 		return (0);
1274 
1275 	if (pfd->revents & POLLOUT)
1276 		if (msgbuf_write(&i->w) <= 0 && errno != EAGAIN) {
1277 			log_warn("imsg write error");
1278 			close(i->fd);
1279 			i->fd = -1;
1280 			return (-1);
1281 		}
1282 
1283 	if (pfd->revents & POLLIN) {
1284 		if ((n = imsg_read(i)) == -1 && errno != EAGAIN) {
1285 			log_warn("imsg read error");
1286 			close(i->fd);
1287 			i->fd = -1;
1288 			return (-1);
1289 		}
1290 		if (n == 0) {
1291 			log_warnx("peer closed imsg connection");
1292 			close(i->fd);
1293 			i->fd = -1;
1294 			return (-1);
1295 		}
1296 	}
1297 	return (0);
1298 }
1299 
1300 static void
getsockpair(int pipe[2])1301 getsockpair(int pipe[2])
1302 {
1303 	int bsize, i;
1304 
1305 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
1306 	    PF_UNSPEC, pipe) == -1)
1307 		fatal("socketpair");
1308 
1309 	for (i = 0; i < 2; i++) {
1310 		for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) {
1311 			if (setsockopt(pipe[i], SOL_SOCKET, SO_RCVBUF,
1312 			    &bsize, sizeof(bsize)) == -1) {
1313 				if (errno != ENOBUFS)
1314 					fatal("setsockopt(SO_RCVBUF, %d)",
1315 					    bsize);
1316 				log_warn("setsockopt(SO_RCVBUF, %d)", bsize);
1317 				continue;
1318 			}
1319 			break;
1320 		}
1321 	}
1322 	for (i = 0; i < 2; i++) {
1323 		for (bsize = MAX_SOCK_BUF; bsize >= 16 * 1024; bsize /= 2) {
1324 			if (setsockopt(pipe[i], SOL_SOCKET, SO_SNDBUF,
1325 			    &bsize, sizeof(bsize)) == -1) {
1326 				if (errno != ENOBUFS)
1327 					fatal("setsockopt(SO_SNDBUF, %d)",
1328 					    bsize);
1329 				log_warn("setsockopt(SO_SNDBUF, %d)", bsize);
1330 				continue;
1331 			}
1332 			break;
1333 		}
1334 	}
1335 }
1336 
1337 int
imsg_send_sockets(struct imsgbuf * se,struct imsgbuf * rde,struct imsgbuf * rtr)1338 imsg_send_sockets(struct imsgbuf *se, struct imsgbuf *rde, struct imsgbuf *rtr)
1339 {
1340 	int pipe_s2r[2];
1341 	int pipe_s2r_ctl[2];
1342 	int pipe_r2r[2];
1343 
1344 	getsockpair(pipe_s2r);
1345 	getsockpair(pipe_s2r_ctl);
1346 	getsockpair(pipe_r2r);
1347 
1348 	if (imsg_compose(se, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[0],
1349 	    NULL, 0) == -1)
1350 		return (-1);
1351 	if (imsg_compose(rde, IMSG_SOCKET_CONN, 0, 0, pipe_s2r[1],
1352 	    NULL, 0) == -1)
1353 		return (-1);
1354 
1355 	if (imsg_compose(se, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[0],
1356 	    NULL, 0) == -1)
1357 		return (-1);
1358 	if (imsg_compose(rde, IMSG_SOCKET_CONN_CTL, 0, 0, pipe_s2r_ctl[1],
1359 	    NULL, 0) == -1)
1360 		return (-1);
1361 
1362 	if (imsg_compose(rtr, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[0],
1363 	    NULL, 0) == -1)
1364 		return (-1);
1365 	if (imsg_compose(rde, IMSG_SOCKET_CONN_RTR, 0, 0, pipe_r2r[1],
1366 	    NULL, 0) == -1)
1367 		return (-1);
1368 
1369 	return (0);
1370 }
1371 
1372 void
bgpd_rtr_conn_setup(struct rtr_config * r)1373 bgpd_rtr_conn_setup(struct rtr_config *r)
1374 {
1375 	struct connect_elm *ce;
1376 	struct sockaddr *sa;
1377 	socklen_t len;
1378 	int nodelay = 1;
1379 	int pre = IPTOS_PREC_INTERNETCONTROL;
1380 
1381 	if (connect_cnt >= MAX_CONNECT_CNT) {
1382 		log_warnx("rtr %s: too many concurrent connection requests",
1383 		    r->descr);
1384 		return;
1385 	}
1386 
1387 	if ((ce = calloc(1, sizeof(*ce))) == NULL) {
1388 		log_warn("rtr %s", r->descr);
1389 		return;
1390 	}
1391 
1392 	if (pfkey_establish(&ce->auth_state, &r->auth,
1393 	    &r->local_addr, &r->remote_addr) == -1)
1394 		log_warnx("rtr %s: pfkey setup failed", r->descr);
1395 
1396 	ce->id = r->id;
1397 	ce->fd = socket(aid2af(r->remote_addr.aid),
1398 	    SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_TCP);
1399 	if (ce->fd == -1) {
1400 		log_warn("rtr %s", r->descr);
1401 		goto fail;
1402 	}
1403 
1404 	switch (r->remote_addr.aid) {
1405 	case AID_INET:
1406 		if (setsockopt(ce->fd, IPPROTO_IP, IP_TOS, &pre, sizeof(pre)) ==
1407 		    -1) {
1408 			log_warn("rtr %s: setsockopt IP_TOS", r->descr);
1409 			return;
1410 		}
1411 		break;
1412 	case AID_INET6:
1413 		if (setsockopt(ce->fd, IPPROTO_IPV6, IPV6_TCLASS, &pre,
1414 		    sizeof(pre)) == -1) {
1415 			log_warn("rtr %s: setsockopt IP_TOS", r->descr);
1416 			return;
1417 		}
1418 		break;
1419 	}
1420 
1421 	if (setsockopt(ce->fd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
1422 	    sizeof(nodelay)) == -1) {
1423 		log_warn("rtr %s: setsockopt TCP_NODELAY", r->descr);
1424 		return;
1425 	}
1426 
1427 	if (tcp_md5_set(ce->fd, &r->auth, &r->remote_addr) == -1)
1428 		log_warn("rtr %s: setting md5sig", r->descr);
1429 
1430 	if ((sa = addr2sa(&r->local_addr, 0, &len)) != NULL) {
1431 		if (bind(ce->fd, sa, len) == -1) {
1432 			log_warn("rtr %s: bind to %s", r->descr,
1433 			    log_addr(&r->local_addr));
1434 			goto fail;
1435 		}
1436 	}
1437 
1438 	sa = addr2sa(&r->remote_addr, r->remote_port, &len);
1439 	if (connect(ce->fd, sa, len) == -1) {
1440 		if (errno != EINPROGRESS) {
1441 			log_warn("rtr %s: connect to %s:%u", r->descr,
1442 			    log_addr(&r->remote_addr), r->remote_port);
1443 			goto fail;
1444 		}
1445 		TAILQ_INSERT_TAIL(&connect_queue, ce, entry);
1446 		connect_cnt++;
1447 		return;
1448 	}
1449 
1450 	imsg_compose(ibuf_rtr, IMSG_SOCKET_SETUP, ce->id, 0, ce->fd, NULL, 0);
1451 	TAILQ_INSERT_TAIL(&socket_queue, ce, entry);
1452 	return;
1453 
1454  fail:
1455 	if (ce->fd != -1)
1456 		close(ce->fd);
1457 	free(ce);
1458 }
1459 
1460 void
bgpd_rtr_conn_setup_done(int fd,struct bgpd_config * conf)1461 bgpd_rtr_conn_setup_done(int fd, struct bgpd_config *conf)
1462 {
1463 	struct rtr_config *r;
1464 	struct connect_elm *ce;
1465 	int error = 0;
1466 	socklen_t len;
1467 
1468 	TAILQ_FOREACH(ce, &connect_queue, entry) {
1469 		if (ce->fd == fd)
1470 			break;
1471 	}
1472 	if (ce == NULL)
1473 		fatalx("connect entry not found");
1474 
1475 	TAILQ_REMOVE(&connect_queue, ce, entry);
1476 	connect_cnt--;
1477 
1478 	SIMPLEQ_FOREACH(r, &conf->rtrs, entry) {
1479 		if (ce->id == r->id)
1480 			break;
1481 	}
1482 	if (r == NULL) {
1483 		log_warnx("rtr id %d no longer exists", ce->id);
1484 		goto fail;
1485 	}
1486 
1487 	len = sizeof(error);
1488 	if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
1489 		log_warn("rtr %s: getsockopt SO_ERROR", r->descr);
1490 		goto fail;
1491 	}
1492 
1493 	if (error != 0) {
1494 		errno = error;
1495 		log_warn("rtr %s: connect to %s:%u", r->descr,
1496 		    log_addr(&r->remote_addr), r->remote_port);
1497 		goto fail;
1498 	}
1499 
1500 	imsg_compose(ibuf_rtr, IMSG_SOCKET_SETUP, ce->id, 0, ce->fd, NULL, 0);
1501 	TAILQ_INSERT_TAIL(&socket_queue, ce, entry);
1502 	return;
1503 
1504 fail:
1505 	close(fd);
1506 	free(ce);
1507 }
1508 
1509 void
bgpd_rtr_conn_teardown(uint32_t id)1510 bgpd_rtr_conn_teardown(uint32_t id)
1511 {
1512 	struct connect_elm *ce;
1513 
1514 	TAILQ_FOREACH(ce, &socket_queue, entry) {
1515 		if (ce->id == id) {
1516 			pfkey_remove(&ce->auth_state);
1517 			TAILQ_REMOVE(&socket_queue, ce, entry);
1518 			free(ce);
1519 			return;
1520 		}
1521 	}
1522 }
1523