GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/bgpd/bgpd.c Lines: 0 466 0.0 %
Date: 2016-12-06 Branches: 0 391 0.0 %

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