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