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