]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldpd.c
ldpd: sun is a reserved word on Solaris
[mirror_frr.git] / ldpd / ldpd.c
CommitLineData
8429abe0
RW
1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004, 2008 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22#include <sys/types.h>
23#include <sys/wait.h>
24#include <err.h>
25#include <errno.h>
26#include <pwd.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <signal.h>
31#include <unistd.h>
32
33#include "ldpd.h"
34#include "ldpe.h"
35#include "lde.h"
36#include "log.h"
37
38static void main_sig_handler(int, short, void *);
39static __dead void usage(void);
40static __dead void ldpd_shutdown(void);
41static pid_t start_child(enum ldpd_process, char *, int, int, int);
42static void main_dispatch_ldpe(int, short, void *);
43static void main_dispatch_lde(int, short, void *);
44static int main_imsg_compose_both(enum imsg_type, void *,
45 uint16_t);
46static int main_imsg_send_ipc_sockets(struct imsgbuf *,
47 struct imsgbuf *);
48static void main_imsg_send_net_sockets(int);
49static void main_imsg_send_net_socket(int, enum socket_type);
50static int main_imsg_send_config(struct ldpd_conf *);
51static int ldp_reload(void);
52static void merge_global(struct ldpd_conf *, struct ldpd_conf *);
53static void merge_af(int, struct ldpd_af_conf *,
54 struct ldpd_af_conf *);
55static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *);
56static void merge_iface_af(struct iface_af *, struct iface_af *);
57static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *);
58static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *);
59static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *);
60static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *,
61 struct l2vpn *);
62
63struct ldpd_global global;
64struct ldpd_conf *ldpd_conf;
65
66static char *conffile;
67static struct imsgev *iev_ldpe;
68static struct imsgev *iev_lde;
69static pid_t ldpe_pid;
70static pid_t lde_pid;
71
72/* ARGSUSED */
73static void
74main_sig_handler(int sig, short event, void *arg)
75{
76 /* signal handler rules don't apply, libevent decouples for us */
77 switch (sig) {
78 case SIGTERM:
79 case SIGINT:
80 ldpd_shutdown();
81 /* NOTREACHED */
82 case SIGHUP:
83 if (ldp_reload() == -1)
84 log_warnx("configuration reload failed");
85 else
86 log_debug("configuration reloaded");
87 break;
88 default:
89 fatalx("unexpected signal");
90 /* NOTREACHED */
91 }
92}
93
94static __dead void
95usage(void)
96{
97 extern char *__progname;
98
99 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
100 __progname);
101 exit(1);
102}
103
104int
105main(int argc, char *argv[])
106{
107 struct event ev_sigint, ev_sigterm, ev_sighup;
108 char *saved_argv0;
109 int ch;
110 int debug = 0, lflag = 0, eflag = 0;
111 int pipe_parent2ldpe[2];
112 int pipe_parent2lde[2];
113
114 conffile = CONF_FILE;
115 ldpd_process = PROC_MAIN;
116
117 log_init(1); /* log to stderr until daemonized */
118 log_verbose(1);
119
120 saved_argv0 = argv[0];
121 if (saved_argv0 == NULL)
122 saved_argv0 = "ldpd";
123
124 while ((ch = getopt(argc, argv, "dD:f:nvLE")) != -1) {
125 switch (ch) {
126 case 'd':
127 debug = 1;
128 break;
129 case 'D':
130 if (cmdline_symset(optarg) < 0)
131 log_warnx("could not parse macro definition %s",
132 optarg);
133 break;
134 case 'f':
135 conffile = optarg;
136 break;
137 case 'n':
138 global.cmd_opts |= LDPD_OPT_NOACTION;
139 break;
140 case 'v':
141 if (global.cmd_opts & LDPD_OPT_VERBOSE)
142 global.cmd_opts |= LDPD_OPT_VERBOSE2;
143 global.cmd_opts |= LDPD_OPT_VERBOSE;
144 break;
145 case 'L':
146 lflag = 1;
147 break;
148 case 'E':
149 eflag = 1;
150 break;
151 default:
152 usage();
153 /* NOTREACHED */
154 }
155 }
156
157 argc -= optind;
158 argv += optind;
159 if (argc > 0 || (lflag && eflag))
160 usage();
161
162 if (lflag)
163 lde(debug, global.cmd_opts & LDPD_OPT_VERBOSE);
164 else if (eflag)
165 ldpe(debug, global.cmd_opts & LDPD_OPT_VERBOSE);
166
167 /* fetch interfaces early */
168 kif_init();
169
170 /* parse config file */
171 if ((ldpd_conf = parse_config(conffile)) == NULL ) {
172 kif_clear();
173 exit(1);
174 }
175
176 if (global.cmd_opts & LDPD_OPT_NOACTION) {
177 if (global.cmd_opts & LDPD_OPT_VERBOSE)
178 print_config(ldpd_conf);
179 else
180 fprintf(stderr, "configuration OK\n");
181 kif_clear();
182 exit(0);
183 }
184
185 /* check for root privileges */
186 if (geteuid())
187 errx(1, "need root privileges");
188
189 /* check for ldpd user */
190 if (getpwnam(LDPD_USER) == NULL)
191 errx(1, "unknown user %s", LDPD_USER);
192
193 log_init(debug);
194 log_verbose(global.cmd_opts & (LDPD_OPT_VERBOSE | LDPD_OPT_VERBOSE2));
195
196 if (!debug)
197 daemon(1, 0);
198
199 log_info("startup");
200
201 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
202 PF_UNSPEC, pipe_parent2ldpe) == -1)
203 fatal("socketpair");
204 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
205 PF_UNSPEC, pipe_parent2lde) == -1)
206 fatal("socketpair");
207
208 /* start children */
209 lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
210 pipe_parent2lde[1], debug, global.cmd_opts & LDPD_OPT_VERBOSE);
211 ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
212 pipe_parent2ldpe[1], debug, global.cmd_opts & LDPD_OPT_VERBOSE);
213
214 event_init();
215
216 /* setup signal handler */
217 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL);
218 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL);
219 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL);
220 signal_add(&ev_sigint, NULL);
221 signal_add(&ev_sigterm, NULL);
222 signal_add(&ev_sighup, NULL);
223 signal(SIGPIPE, SIG_IGN);
224
225 /* setup pipes to children */
226 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
227 (iev_lde = malloc(sizeof(struct imsgev))) == NULL)
228 fatal(NULL);
229 imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
230 iev_ldpe->handler = main_dispatch_ldpe;
231 imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
232 iev_lde->handler = main_dispatch_lde;
233
234 /* setup event handler */
235 iev_ldpe->events = EV_READ;
236 event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events,
237 iev_ldpe->handler, iev_ldpe);
238 event_add(&iev_ldpe->ev, NULL);
239
240 iev_lde->events = EV_READ;
241 event_set(&iev_lde->ev, iev_lde->ibuf.fd, iev_lde->events,
242 iev_lde->handler, iev_lde);
243 event_add(&iev_lde->ev, NULL);
244
245 if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
246 fatal("could not establish imsg links");
247 main_imsg_send_config(ldpd_conf);
248
249 /* notify ldpe about existing interfaces and addresses */
250 kif_redistribute(NULL);
251
252 if (kr_init(!(ldpd_conf->flags & F_LDPD_NO_FIB_UPDATE)) == -1)
253 fatalx("kr_init failed");
254
255 if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
256 main_imsg_send_net_sockets(AF_INET);
257 if (ldpd_conf->ipv6.flags & F_LDPD_AF_ENABLED)
258 main_imsg_send_net_sockets(AF_INET6);
259
260 /* remove unneded stuff from config */
261 /* ... */
262
263 event_dispatch();
264
265 ldpd_shutdown();
266 /* NOTREACHED */
267 return (0);
268}
269
270static __dead void
271ldpd_shutdown(void)
272{
273 pid_t pid;
274 int status;
275
276 /* close pipes */
277 msgbuf_clear(&iev_ldpe->ibuf.w);
278 close(iev_ldpe->ibuf.fd);
279 msgbuf_clear(&iev_lde->ibuf.w);
280 close(iev_lde->ibuf.fd);
281
282 kr_shutdown();
283 config_clear(ldpd_conf);
284
285 log_debug("waiting for children to terminate");
286 do {
287 pid = wait(&status);
288 if (pid == -1) {
289 if (errno != EINTR && errno != ECHILD)
290 fatal("wait");
291 } else if (WIFSIGNALED(status))
292 log_warnx("%s terminated; signal %d",
293 (pid == lde_pid) ? "label decision engine" :
294 "ldp engine", WTERMSIG(status));
295 } while (pid != -1 || (pid == -1 && errno == EINTR));
296
297 free(iev_ldpe);
298 free(iev_lde);
299
300 log_info("terminating");
301 exit(0);
302}
303
304static pid_t
305start_child(enum ldpd_process p, char *argv0, int fd, int debug, int verbose)
306{
307 char *argv[5];
308 int argc = 0;
309 pid_t pid;
310
311 switch (pid = fork()) {
312 case -1:
313 fatal("cannot fork");
314 case 0:
315 break;
316 default:
317 close(fd);
318 return (pid);
319 }
320
321 if (dup2(fd, 3) == -1)
322 fatal("cannot setup imsg fd");
323
324 argv[argc++] = argv0;
325 switch (p) {
326 case PROC_MAIN:
327 fatalx("Can not start main process");
328 case PROC_LDE_ENGINE:
329 argv[argc++] = "-L";
330 break;
331 case PROC_LDP_ENGINE:
332 argv[argc++] = "-E";
333 break;
334 }
335 if (debug)
336 argv[argc++] = "-d";
337 if (verbose)
338 argv[argc++] = "-v";
339 argv[argc++] = NULL;
340
341 execvp(argv0, argv);
342 fatal("execvp");
343}
344
345/* imsg handling */
346/* ARGSUSED */
347static void
348main_dispatch_ldpe(int fd, short event, void *bula)
349{
350 struct imsgev *iev = bula;
351 struct imsgbuf *ibuf = &iev->ibuf;
352 struct imsg imsg;
353 int af;
354 ssize_t n;
355 int shut = 0, verbose;
356
357 if (event & EV_READ) {
358 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
359 fatal("imsg_read error");
360 if (n == 0) /* connection closed */
361 shut = 1;
362 }
363 if (event & EV_WRITE) {
364 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
365 fatal("msgbuf_write");
366 if (n == 0)
367 shut = 1;
368 }
369
370 for (;;) {
371 if ((n = imsg_get(ibuf, &imsg)) == -1)
372 fatal("imsg_get");
373
374 if (n == 0)
375 break;
376
377 switch (imsg.hdr.type) {
378 case IMSG_REQUEST_SOCKETS:
379 af = imsg.hdr.pid;
380 main_imsg_send_net_sockets(af);
381 break;
382 case IMSG_CTL_RELOAD:
383 if (ldp_reload() == -1)
384 log_warnx("configuration reload failed");
385 else
386 log_debug("configuration reloaded");
387 break;
388 case IMSG_CTL_FIB_COUPLE:
389 kr_fib_couple();
390 break;
391 case IMSG_CTL_FIB_DECOUPLE:
392 kr_fib_decouple();
393 break;
394 case IMSG_CTL_KROUTE:
395 case IMSG_CTL_KROUTE_ADDR:
396 kr_show_route(&imsg);
397 break;
398 case IMSG_CTL_IFINFO:
399 if (imsg.hdr.len == IMSG_HEADER_SIZE)
400 kr_ifinfo(NULL, imsg.hdr.pid);
401 else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ)
402 kr_ifinfo(imsg.data, imsg.hdr.pid);
403 else
404 log_warnx("IFINFO request with wrong len");
405 break;
406 case IMSG_CTL_LOG_VERBOSE:
407 /* already checked by ldpe */
408 memcpy(&verbose, imsg.data, sizeof(verbose));
409 log_verbose(verbose);
410 break;
411 default:
412 log_debug("%s: error handling imsg %d", __func__,
413 imsg.hdr.type);
414 break;
415 }
416 imsg_free(&imsg);
417 }
418 if (!shut)
419 imsg_event_add(iev);
420 else {
421 /* this pipe is dead, so remove the event handler */
422 event_del(&iev->ev);
423 event_loopexit(NULL);
424 }
425}
426
427/* ARGSUSED */
428static void
429main_dispatch_lde(int fd, short event, void *bula)
430{
431 struct imsgev *iev = bula;
432 struct imsgbuf *ibuf = &iev->ibuf;
433 struct imsg imsg;
434 ssize_t n;
435 int shut = 0;
436
437 if (event & EV_READ) {
438 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
439 fatal("imsg_read error");
440 if (n == 0) /* connection closed */
441 shut = 1;
442 }
443 if (event & EV_WRITE) {
444 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
445 fatal("msgbuf_write");
446 if (n == 0)
447 shut = 1;
448 }
449
450 for (;;) {
451 if ((n = imsg_get(ibuf, &imsg)) == -1)
452 fatal("imsg_get");
453
454 if (n == 0)
455 break;
456
457 switch (imsg.hdr.type) {
458 case IMSG_KLABEL_CHANGE:
459 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
460 sizeof(struct kroute))
461 fatalx("invalid size of IMSG_KLABEL_CHANGE");
462 if (kr_change(imsg.data))
463 log_warnx("%s: error changing route", __func__);
464 break;
465 case IMSG_KLABEL_DELETE:
466 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
467 sizeof(struct kroute))
468 fatalx("invalid size of IMSG_KLABEL_DELETE");
469 if (kr_delete(imsg.data))
470 log_warnx("%s: error deleting route", __func__);
471 break;
472 case IMSG_KPWLABEL_CHANGE:
473 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
474 sizeof(struct kpw))
475 fatalx("invalid size of IMSG_KPWLABEL_CHANGE");
476 if (kmpw_set(imsg.data))
477 log_warnx("%s: error changing pseudowire",
478 __func__);
479 break;
480 case IMSG_KPWLABEL_DELETE:
481 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
482 sizeof(struct kpw))
483 fatalx("invalid size of IMSG_KPWLABEL_DELETE");
484 if (kmpw_unset(imsg.data))
485 log_warnx("%s: error unsetting pseudowire",
486 __func__);
487 break;
488 default:
489 log_debug("%s: error handling imsg %d", __func__,
490 imsg.hdr.type);
491 break;
492 }
493 imsg_free(&imsg);
494 }
495 if (!shut)
496 imsg_event_add(iev);
497 else {
498 /* this pipe is dead, so remove the event handler */
499 event_del(&iev->ev);
500 event_loopexit(NULL);
501 }
502}
503
504void
505main_imsg_compose_ldpe(int type, pid_t pid, void *data, uint16_t datalen)
506{
507 if (iev_ldpe == NULL)
508 return;
509 imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen);
510}
511
512void
513main_imsg_compose_lde(int type, pid_t pid, void *data, uint16_t datalen)
514{
515 imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen);
516}
517
518static int
519main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
520{
521 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1)
522 return (-1);
523 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1)
524 return (-1);
525 return (0);
526}
527
528void
529imsg_event_add(struct imsgev *iev)
530{
531 iev->events = EV_READ;
532 if (iev->ibuf.w.queued)
533 iev->events |= EV_WRITE;
534
535 event_del(&iev->ev);
536 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
537 event_add(&iev->ev, NULL);
538}
539
540int
541imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
542 pid_t pid, int fd, void *data, uint16_t datalen)
543{
544 int ret;
545
546 if ((ret = imsg_compose(&iev->ibuf, type, peerid,
547 pid, fd, data, datalen)) != -1)
548 imsg_event_add(iev);
549 return (ret);
550}
551
552void
553evbuf_enqueue(struct evbuf *eb, struct ibuf *buf)
554{
555 ibuf_close(&eb->wbuf, buf);
556 evbuf_event_add(eb);
557}
558
559void
560evbuf_event_add(struct evbuf *eb)
561{
562 if (eb->wbuf.queued)
563 event_add(&eb->ev, NULL);
564}
565
566void
567evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *),
568 void *arg)
569{
570 msgbuf_init(&eb->wbuf);
571 eb->wbuf.fd = fd;
572 event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg);
573}
574
575void
576evbuf_clear(struct evbuf *eb)
577{
578 event_del(&eb->ev);
579 msgbuf_clear(&eb->wbuf);
580 eb->wbuf.fd = -1;
581}
582
583static int
584main_imsg_send_ipc_sockets(struct imsgbuf *ldpe_buf, struct imsgbuf *lde_buf)
585{
586 int pipe_ldpe2lde[2];
587
588 if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
589 PF_UNSPEC, pipe_ldpe2lde) == -1)
590 return (-1);
591
592 if (imsg_compose(ldpe_buf, IMSG_SOCKET_IPC, 0, 0, pipe_ldpe2lde[0],
593 NULL, 0) == -1)
594 return (-1);
595 if (imsg_compose(lde_buf, IMSG_SOCKET_IPC, 0, 0, pipe_ldpe2lde[1],
596 NULL, 0) == -1)
597 return (-1);
598
599 return (0);
600}
601
602static void
603main_imsg_send_net_sockets(int af)
604{
605 main_imsg_send_net_socket(af, LDP_SOCKET_DISC);
606 main_imsg_send_net_socket(af, LDP_SOCKET_EDISC);
607 main_imsg_send_net_socket(af, LDP_SOCKET_SESSION);
608 imsg_compose_event(iev_ldpe, IMSG_SETUP_SOCKETS, af, 0, -1, NULL, 0);
609}
610
611static void
612main_imsg_send_net_socket(int af, enum socket_type type)
613{
614 int fd;
615
616 fd = ldp_create_socket(af, type);
617 if (fd == -1) {
618 log_warnx("%s: failed to create %s socket for address-family "
619 "%s", __func__, socket_name(type), af_name(af));
620 return;
621 }
622
623 imsg_compose_event(iev_ldpe, IMSG_SOCKET_NET, af, 0, fd, &type,
624 sizeof(type));
625}
626
627struct ldpd_af_conf *
628ldp_af_conf_get(struct ldpd_conf *xconf, int af)
629{
630 switch (af) {
631 case AF_INET:
632 return (&xconf->ipv4);
633 case AF_INET6:
634 return (&xconf->ipv6);
635 default:
636 fatalx("ldp_af_conf_get: unknown af");
637 }
638}
639
640struct ldpd_af_global *
641ldp_af_global_get(struct ldpd_global *xglobal, int af)
642{
643 switch (af) {
644 case AF_INET:
645 return (&xglobal->ipv4);
646 case AF_INET6:
647 return (&xglobal->ipv6);
648 default:
649 fatalx("ldp_af_global_get: unknown af");
650 }
651}
652
653int
654ldp_is_dual_stack(struct ldpd_conf *xconf)
655{
656 return ((xconf->ipv4.flags & F_LDPD_AF_ENABLED) &&
657 (xconf->ipv6.flags & F_LDPD_AF_ENABLED));
658}
659
660static int
661main_imsg_send_config(struct ldpd_conf *xconf)
662{
663 struct iface *iface;
664 struct tnbr *tnbr;
665 struct nbr_params *nbrp;
666 struct l2vpn *l2vpn;
667 struct l2vpn_if *lif;
668 struct l2vpn_pw *pw;
669
670 if (main_imsg_compose_both(IMSG_RECONF_CONF, xconf,
671 sizeof(*xconf)) == -1)
672 return (-1);
673
674 LIST_FOREACH(iface, &xconf->iface_list, entry) {
675 if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
676 sizeof(*iface)) == -1)
677 return (-1);
678 }
679
680 LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
681 if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
682 sizeof(*tnbr)) == -1)
683 return (-1);
684 }
685
686 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
687 if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp,
688 sizeof(*nbrp)) == -1)
689 return (-1);
690 }
691
692 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
693 if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
694 sizeof(*l2vpn)) == -1)
695 return (-1);
696
697 LIST_FOREACH(lif, &l2vpn->if_list, entry) {
698 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif,
699 sizeof(*lif)) == -1)
700 return (-1);
701 }
702 LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
703 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw,
704 sizeof(*pw)) == -1)
705 return (-1);
706 }
707 }
708
709 if (main_imsg_compose_both(IMSG_RECONF_END, NULL, 0) == -1)
710 return (-1);
711
712 return (0);
713}
714
715static int
716ldp_reload(void)
717{
718 struct ldpd_conf *xconf;
719
720 if ((xconf = parse_config(conffile)) == NULL)
721 return (-1);
722
723 if (main_imsg_send_config(xconf) == -1)
724 return (-1);
725
726 merge_config(ldpd_conf, xconf);
727
728 return (0);
729}
730
731void
732merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
733{
734 merge_global(conf, xconf);
735 merge_af(AF_INET, &conf->ipv4, &xconf->ipv4);
736 merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6);
737 merge_ifaces(conf, xconf);
738 merge_tnbrs(conf, xconf);
739 merge_nbrps(conf, xconf);
740 merge_l2vpns(conf, xconf);
741 free(xconf);
742}
743
744static void
745merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
746{
747 /* change of router-id requires resetting all neighborships */
748 if (conf->rtr_id.s_addr != xconf->rtr_id.s_addr) {
749 if (ldpd_process == PROC_LDP_ENGINE) {
750 ldpe_reset_nbrs(AF_INET);
751 ldpe_reset_nbrs(AF_INET6);
752 if (conf->rtr_id.s_addr == INADDR_ANY ||
753 xconf->rtr_id.s_addr == INADDR_ANY) {
754 if_update_all(AF_UNSPEC);
755 tnbr_update_all(AF_UNSPEC);
756 }
757 }
758 conf->rtr_id = xconf->rtr_id;
759 }
760
761 if (conf->trans_pref != xconf->trans_pref) {
762 if (ldpd_process == PROC_LDP_ENGINE)
763 ldpe_reset_ds_nbrs();
764 conf->trans_pref = xconf->trans_pref;
765 }
766
767 if ((conf->flags & F_LDPD_DS_CISCO_INTEROP) !=
768 (xconf->flags & F_LDPD_DS_CISCO_INTEROP)) {
769 if (ldpd_process == PROC_LDP_ENGINE)
770 ldpe_reset_ds_nbrs();
771 }
772
773 conf->flags = xconf->flags;
774}
775
776static void
777merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
778{
779 int egress_label_changed = 0;
780 int update_sockets = 0;
781
782 if (af_conf->keepalive != xa->keepalive) {
783 af_conf->keepalive = xa->keepalive;
784 if (ldpd_process == PROC_LDP_ENGINE)
785 ldpe_stop_init_backoff(af);
786 }
787 af_conf->thello_holdtime = xa->thello_holdtime;
788 af_conf->thello_interval = xa->thello_interval;
789
790 /* update flags */
791 if (ldpd_process == PROC_LDP_ENGINE &&
792 (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
793 !(xa->flags & F_LDPD_AF_THELLO_ACCEPT))
794 ldpe_remove_dynamic_tnbrs(af);
795
796 if ((af_conf->flags & F_LDPD_AF_NO_GTSM) !=
797 (xa->flags & F_LDPD_AF_NO_GTSM)) {
798 if (af == AF_INET6)
799 /* need to set/unset IPV6_MINHOPCOUNT */
800 update_sockets = 1;
801 else if (ldpd_process == PROC_LDP_ENGINE)
802 /* for LDPv4 just resetting the neighbors is enough */
803 ldpe_reset_nbrs(af);
804 }
805
806 if ((af_conf->flags & F_LDPD_AF_EXPNULL) !=
807 (xa->flags & F_LDPD_AF_EXPNULL))
808 egress_label_changed = 1;
809
810 af_conf->flags = xa->flags;
811
812 if (egress_label_changed) {
813 switch (ldpd_process) {
814 case PROC_LDE_ENGINE:
815 lde_change_egress_label(af, af_conf->flags &
816 F_LDPD_AF_EXPNULL);
817 break;
818 case PROC_MAIN:
819 kr_change_egress_label(af, af_conf->flags &
820 F_LDPD_AF_EXPNULL);
821 break;
822 default:
823 break;
824 }
825 }
826
827 if (ldp_addrcmp(af, &af_conf->trans_addr, &xa->trans_addr)) {
828 af_conf->trans_addr = xa->trans_addr;
829 update_sockets = 1;
830 }
831
832 if (ldpd_process == PROC_MAIN && update_sockets)
833 imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 0, -1,
834 NULL, 0);
835}
836
837static void
838merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf)
839{
840 struct iface *iface, *itmp, *xi;
841
842 LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
843 /* find deleted interfaces */
844 if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) {
845 LIST_REMOVE(iface, entry);
846 if (ldpd_process == PROC_LDP_ENGINE)
847 if_exit(iface);
848 free(iface);
849 }
850 }
851 LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
852 /* find new interfaces */
853 if ((iface = if_lookup(conf, xi->ifindex)) == NULL) {
854 LIST_REMOVE(xi, entry);
855 LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
856
857 /* resend addresses to activate new interfaces */
858 if (ldpd_process == PROC_MAIN)
859 kif_redistribute(xi->name);
860 continue;
861 }
862
863 /* update existing interfaces */
864 merge_iface_af(&iface->ipv4, &xi->ipv4);
865 merge_iface_af(&iface->ipv6, &xi->ipv6);
866 LIST_REMOVE(xi, entry);
867 free(xi);
868 }
869}
870
871static void
872merge_iface_af(struct iface_af *ia, struct iface_af *xi)
873{
874 if (ia->enabled != xi->enabled) {
875 ia->enabled = xi->enabled;
876 if (ldpd_process == PROC_LDP_ENGINE)
877 if_update(ia->iface, ia->af);
878 }
879 ia->hello_holdtime = xi->hello_holdtime;
880 ia->hello_interval = xi->hello_interval;
881}
882
883static void
884merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
885{
886 struct tnbr *tnbr, *ttmp, *xt;
887
888 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
889 if (!(tnbr->flags & F_TNBR_CONFIGURED))
890 continue;
891
892 /* find deleted tnbrs */
893 if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
894 if (ldpd_process == PROC_LDP_ENGINE) {
895 tnbr->flags &= ~F_TNBR_CONFIGURED;
896 tnbr_check(tnbr);
897 } else {
898 LIST_REMOVE(tnbr, entry);
899 free(tnbr);
900 }
901 }
902 }
903 LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
904 /* find new tnbrs */
905 if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
906 LIST_REMOVE(xt, entry);
907 LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
908
909 if (ldpd_process == PROC_LDP_ENGINE)
910 tnbr_update(xt);
911 continue;
912 }
913
914 /* update existing tnbrs */
915 if (!(tnbr->flags & F_TNBR_CONFIGURED))
916 tnbr->flags |= F_TNBR_CONFIGURED;
917 tnbr->hello_holdtime = xt->hello_holdtime;
918 tnbr->hello_interval = xt->hello_interval;
919 LIST_REMOVE(xt, entry);
920 free(xt);
921 }
922}
923
924static void
925merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
926{
927 struct nbr_params *nbrp, *ntmp, *xn;
928 struct nbr *nbr;
929 int nbrp_changed;
930
931 LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
932 /* find deleted nbrps */
933 if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
934 if (ldpd_process == PROC_LDP_ENGINE) {
935 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
936 if (nbr) {
937 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
938 pfkey_remove(nbr);
939 if (nbr_session_active_role(nbr))
940 nbr_establish_connection(nbr);
941 }
942 }
943 LIST_REMOVE(nbrp, entry);
944 free(nbrp);
945 }
946 }
947 LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
948 /* find new nbrps */
949 if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
950 LIST_REMOVE(xn, entry);
951 LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
952
953 if (ldpd_process == PROC_LDP_ENGINE) {
954 nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
955 if (nbr) {
956 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
957 if (pfkey_establish(nbr, xn) == -1)
958 fatalx("pfkey setup failed");
959 if (nbr_session_active_role(nbr))
960 nbr_establish_connection(nbr);
961 }
962 }
963 continue;
964 }
965
966 /* update existing nbrps */
967 if (nbrp->flags != xn->flags ||
968 nbrp->keepalive != xn->keepalive ||
969 nbrp->gtsm_enabled != xn->gtsm_enabled ||
970 nbrp->gtsm_hops != xn->gtsm_hops ||
971 nbrp->auth.method != xn->auth.method ||
972 strcmp(nbrp->auth.md5key, xn->auth.md5key) != 0)
973 nbrp_changed = 1;
974 else
975 nbrp_changed = 0;
976
977 nbrp->keepalive = xn->keepalive;
978 nbrp->gtsm_enabled = xn->gtsm_enabled;
979 nbrp->gtsm_hops = xn->gtsm_hops;
980 nbrp->auth.method = xn->auth.method;
981 strlcpy(nbrp->auth.md5key, xn->auth.md5key,
982 sizeof(nbrp->auth.md5key));
983 nbrp->auth.md5key_len = xn->auth.md5key_len;
984 nbrp->flags = xn->flags;
985
986 if (ldpd_process == PROC_LDP_ENGINE) {
987 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
988 if (nbr && nbrp_changed) {
989 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
990 pfkey_remove(nbr);
991 if (pfkey_establish(nbr, nbrp) == -1)
992 fatalx("pfkey setup failed");
993 if (nbr_session_active_role(nbr))
994 nbr_establish_connection(nbr);
995 }
996 }
997 LIST_REMOVE(xn, entry);
998 free(xn);
999 }
1000}
1001
1002static void
1003merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
1004{
1005 struct l2vpn *l2vpn, *ltmp, *xl;
1006
1007 LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
1008 /* find deleted l2vpns */
1009 if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
1010 LIST_REMOVE(l2vpn, entry);
1011
1012 switch (ldpd_process) {
1013 case PROC_LDE_ENGINE:
1014 l2vpn_exit(l2vpn);
1015 break;
1016 case PROC_LDP_ENGINE:
1017 ldpe_l2vpn_exit(l2vpn);
1018 break;
1019 case PROC_MAIN:
1020 break;
1021 }
1022 l2vpn_del(l2vpn);
1023 }
1024 }
1025 LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
1026 /* find new l2vpns */
1027 if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
1028 LIST_REMOVE(xl, entry);
1029 LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
1030
1031 switch (ldpd_process) {
1032 case PROC_LDE_ENGINE:
1033 l2vpn_init(xl);
1034 break;
1035 case PROC_LDP_ENGINE:
1036 ldpe_l2vpn_init(xl);
1037 break;
1038 case PROC_MAIN:
1039 break;
1040 }
1041 continue;
1042 }
1043
1044 /* update existing l2vpns */
1045 merge_l2vpn(conf, l2vpn, xl);
1046 LIST_REMOVE(xl, entry);
1047 free(xl);
1048 }
1049}
1050
1051static void
1052merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
1053{
1054 struct l2vpn_if *lif, *ftmp, *xf;
1055 struct l2vpn_pw *pw, *ptmp, *xp;
1056 struct nbr *nbr;
1057 int reset_nbr, reinstall_pwfec, reinstall_tnbr;
1058 int previous_pw_type, previous_mtu;
1059
1060 previous_pw_type = l2vpn->pw_type;
1061 previous_mtu = l2vpn->mtu;
1062
1063 /* merge intefaces */
1064 LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
1065 /* find deleted interfaces */
1066 if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) {
1067 LIST_REMOVE(lif, entry);
1068 free(lif);
1069 }
1070 }
1071 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
1072 /* find new interfaces */
1073 if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) {
1074 LIST_REMOVE(xf, entry);
1075 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
1076 xf->l2vpn = l2vpn;
1077 continue;
1078 }
1079
1080 LIST_REMOVE(xf, entry);
1081 free(xf);
1082 }
1083
1084 /* merge pseudowires */
1085 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
1086 /* find deleted pseudowires */
1087 if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) {
1088 switch (ldpd_process) {
1089 case PROC_LDE_ENGINE:
1090 l2vpn_pw_exit(pw);
1091 break;
1092 case PROC_LDP_ENGINE:
1093 ldpe_l2vpn_pw_exit(pw);
1094 break;
1095 case PROC_MAIN:
1096 break;
1097 }
1098
1099 LIST_REMOVE(pw, entry);
1100 free(pw);
1101 }
1102 }
1103 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
1104 /* find new pseudowires */
1105 if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) {
1106 LIST_REMOVE(xp, entry);
1107 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
1108 xp->l2vpn = l2vpn;
1109
1110 switch (ldpd_process) {
1111 case PROC_LDE_ENGINE:
1112 l2vpn_pw_init(xp);
1113 break;
1114 case PROC_LDP_ENGINE:
1115 ldpe_l2vpn_pw_init(xp);
1116 break;
1117 case PROC_MAIN:
1118 break;
1119 }
1120 continue;
1121 }
1122
1123 /* update existing pseudowire */
1124 if (pw->af != xp->af ||
1125 ldp_addrcmp(pw->af, &pw->addr, &xp->addr))
1126 reinstall_tnbr = 1;
1127 else
1128 reinstall_tnbr = 0;
1129
1130 /* changes that require a session restart */
1131 if ((pw->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)) !=
1132 (xp->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)))
1133 reset_nbr = 1;
1134 else
1135 reset_nbr = 0;
1136
1137 if (l2vpn->pw_type != xl->pw_type || l2vpn->mtu != xl->mtu ||
1138 pw->pwid != xp->pwid || reinstall_tnbr || reset_nbr ||
1139 pw->lsr_id.s_addr != xp->lsr_id.s_addr)
1140 reinstall_pwfec = 1;
1141 else
1142 reinstall_pwfec = 0;
1143
1144 if (ldpd_process == PROC_LDP_ENGINE) {
1145 if (reinstall_tnbr)
1146 ldpe_l2vpn_pw_exit(pw);
1147 if (reset_nbr) {
1148 nbr = nbr_find_ldpid(pw->lsr_id.s_addr);
1149 if (nbr && nbr->state == NBR_STA_OPER)
1150 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
1151 }
1152 }
1153 if (ldpd_process == PROC_LDE_ENGINE &&
1154 !reset_nbr && reinstall_pwfec)
1155 l2vpn_pw_exit(pw);
1156 pw->lsr_id = xp->lsr_id;
1157 pw->af = xp->af;
1158 pw->addr = xp->addr;
1159 pw->pwid = xp->pwid;
1160 strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname));
1161 pw->ifindex = xp->ifindex;
1162 if (xp->flags & F_PW_CWORD_CONF)
1163 pw->flags |= F_PW_CWORD_CONF;
1164 else
1165 pw->flags &= ~F_PW_CWORD_CONF;
1166 if (xp->flags & F_PW_STATUSTLV_CONF)
1167 pw->flags |= F_PW_STATUSTLV_CONF;
1168 else
1169 pw->flags &= ~F_PW_STATUSTLV_CONF;
1170 if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
1171 ldpe_l2vpn_pw_init(pw);
1172 if (ldpd_process == PROC_LDE_ENGINE &&
1173 !reset_nbr && reinstall_pwfec) {
1174 l2vpn->pw_type = xl->pw_type;
1175 l2vpn->mtu = xl->mtu;
1176 l2vpn_pw_init(pw);
1177 l2vpn->pw_type = previous_pw_type;
1178 l2vpn->mtu = previous_mtu;
1179 }
1180
1181 LIST_REMOVE(xp, entry);
1182 free(xp);
1183 }
1184
1185 l2vpn->pw_type = xl->pw_type;
1186 l2vpn->mtu = xl->mtu;
1187 strlcpy(l2vpn->br_ifname, xl->br_ifname, sizeof(l2vpn->br_ifname));
1188 l2vpn->br_ifindex = xl->br_ifindex;
1189}
1190
1191struct ldpd_conf *
1192config_new_empty(void)
1193{
1194 struct ldpd_conf *xconf;
1195
1196 xconf = calloc(1, sizeof(*xconf));
1197 if (xconf == NULL)
1198 fatal(NULL);
1199
1200 LIST_INIT(&xconf->iface_list);
1201 LIST_INIT(&xconf->tnbr_list);
1202 LIST_INIT(&xconf->nbrp_list);
1203 LIST_INIT(&xconf->l2vpn_list);
1204
1205 return (xconf);
1206}
1207
1208void
1209config_clear(struct ldpd_conf *conf)
1210{
1211 struct ldpd_conf *xconf;
1212
1213 /*
1214 * Merge current config with an empty config, this will deactivate
1215 * and deallocate all the interfaces, pseudowires and so on. Before
1216 * merging, copy the router-id and other variables to avoid some
1217 * unnecessary operations, like trying to reset the neighborships.
1218 */
1219 xconf = config_new_empty();
1220 xconf->ipv4 = conf->ipv4;
1221 xconf->ipv6 = conf->ipv6;
1222 xconf->rtr_id = conf->rtr_id;
1223 xconf->trans_pref = conf->trans_pref;
1224 xconf->flags = conf->flags;
1225 merge_config(conf, xconf);
1226 free(conf);
1227}