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