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