GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/bgpd/bgpd.c Lines: 31 489 6.3 %
Date: 2017-11-13 Branches: 12 378 3.2 %

Line Branch Exec Source
1
/*	$OpenBSD: bgpd.c,v 1.191 2017/08/12 16:31:09 florian 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
41
void		sighdlr(int);
42
__dead void	usage(void);
43
int		main(int, char *[]);
44
pid_t		start_child(enum bgpd_process, char *, int, int, int);
45
int		send_filterset(struct imsgbuf *, struct filter_set_head *);
46
int		reconfigure(char *, struct bgpd_config *, struct peer **);
47
int		dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *);
48
int		control_setup(struct bgpd_config *);
49
int		imsg_send_sockets(struct imsgbuf *, struct imsgbuf *);
50
51
int			 cflags;
52
volatile sig_atomic_t	 mrtdump;
53
volatile sig_atomic_t	 quit;
54
volatile sig_atomic_t	 reconfig;
55
pid_t			 reconfpid;
56
int			 reconfpending;
57
struct imsgbuf		*ibuf_se;
58
struct imsgbuf		*ibuf_rde;
59
struct rib_names	 ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
60
char			*cname;
61
char			*rcname;
62
63
void
64
sighdlr(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
82
usage(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
97
int	 cmd_opts;
98
99
int
100
main(int argc, char *argv[])
101
{
102
	struct bgpd_config	*conf;
103
24
	struct peer		*peer_l, *p;
104
12
	struct pollfd		 pfd[POLL_MAX];
105
	pid_t			 io_pid = 0, rde_pid = 0, pid;
106
	char			*conffile;
107
	char			*saved_argv0;
108
	int			 debug = 0;
109
	int			 rflag = 0, sflag = 0;
110
	int			 rfd = -1;
111
12
	int			 ch, timeout, status;
112
12
	int			 pipe_m2s[2];
113
12
	int			 pipe_m2r[2];
114
115
	conffile = CONFFILE;
116
12
	bgpd_process = PROC_MAIN;
117
118
12
	log_init(1, LOG_DAEMON);	/* log to stderr until daemonized */
119
12
	log_procinit(log_procnames[bgpd_process]);
120
12
	log_setverbose(1);
121
122
12
	saved_argv0 = argv[0];
123
12
	if (saved_argv0 == NULL)
124
		saved_argv0 = "bgpd";
125
126
12
	conf = new_config();
127
12
	peer_l = NULL;
128
129
104
	while ((ch = getopt(argc, argv, "cdD:f:nRSv")) != -1) {
130


40
		switch (ch) {
131
		case 'c':
132
			cmd_opts |= BGPD_OPT_FORCE_DEMOTE;
133
			break;
134
		case 'd':
135
			debug = 1;
136
			break;
137
		case 'D':
138
			if (cmdline_symset(optarg) < 0)
139
				log_warnx("could not parse macro definition %s",
140
				    optarg);
141
			break;
142
		case 'f':
143
12
			conffile = optarg;
144
12
			break;
145
		case 'n':
146
12
			cmd_opts |= BGPD_OPT_NOACTION;
147
12
			break;
148
		case 'v':
149
16
			if (cmd_opts & BGPD_OPT_VERBOSE)
150
4
				cmd_opts |= BGPD_OPT_VERBOSE2;
151
16
			cmd_opts |= BGPD_OPT_VERBOSE;
152
16
			break;
153
		case 'R':
154
			rflag = 1;
155
			break;
156
		case 'S':
157
			sflag = 1;
158
			break;
159
		default:
160
			usage();
161
			/* NOTREACHED */
162
		}
163
	}
164
165
12
	argc -= optind;
166
12
	argv += optind;
167

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