ldpd.c revision 1.33
1/*	$OpenBSD: ldpd.c,v 1.33 2016/05/23 15:55:45 renato Exp $ */
2
3/*
4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 2004, 2008 Esben Norby <norby@openbsd.org>
6 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <sys/queue.h>
24#include <sys/time.h>
25#include <sys/stat.h>
26#include <sys/wait.h>
27
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <netmpls/mpls.h>
31
32#include <event.h>
33#include <err.h>
34#include <errno.h>
35#include <pwd.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <signal.h>
40#include <unistd.h>
41
42#include "ldpd.h"
43#include "ldp.h"
44#include "ldpe.h"
45#include "control.h"
46#include "log.h"
47#include "lde.h"
48
49void		main_sig_handler(int, short, void *);
50__dead void	usage(void);
51void		ldpd_shutdown(void);
52int		check_child(pid_t, const char *);
53
54void	main_dispatch_ldpe(int, short, void *);
55void	main_dispatch_lde(int, short, void *);
56
57int	ldp_reload(void);
58int	ldp_sendboth(enum imsg_type, void *, u_int16_t);
59void	merge_l2vpns(struct ldpd_conf *, struct l2vpn *, struct l2vpn *);
60
61int	pipe_parent2ldpe[2];
62int	pipe_parent2lde[2];
63int	pipe_ldpe2lde[2];
64
65struct ldpd_conf	*ldpd_conf = NULL;
66struct imsgev		*iev_ldpe;
67struct imsgev		*iev_lde;
68char			*conffile;
69
70pid_t			 ldpe_pid = 0;
71pid_t			 lde_pid = 0;
72
73/* ARGSUSED */
74void
75main_sig_handler(int sig, short event, void *arg)
76{
77	/*
78	 * signal handler rules don't apply, libevent decouples for us
79	 */
80
81	int	die = 0;
82
83	switch (sig) {
84	case SIGTERM:
85	case SIGINT:
86		die = 1;
87		/* FALLTHROUGH */
88	case SIGCHLD:
89		if (check_child(ldpe_pid, "ldp engine")) {
90			ldpe_pid = 0;
91			die = 1;
92		}
93		if (check_child(lde_pid, "label decision engine")) {
94			lde_pid = 0;
95			die = 1;
96		}
97		if (die)
98			ldpd_shutdown();
99		break;
100	case SIGHUP:
101		if (ldp_reload() == -1)
102			log_warnx("configuration reload failed");
103		else
104			log_debug("configuration reloaded");
105		break;
106	default:
107		fatalx("unexpected signal");
108		/* NOTREACHED */
109	}
110}
111
112__dead void
113usage(void)
114{
115	extern char *__progname;
116
117	fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n",
118	    __progname);
119	exit(1);
120}
121
122int
123main(int argc, char *argv[])
124{
125	struct event		 ev_sigint, ev_sigterm, ev_sigchld, ev_sighup;
126	int			 ch, opts = 0;
127	int			 debug = 0;
128
129	conffile = CONF_FILE;
130	ldpd_process = PROC_MAIN;
131
132	log_init(1);	/* log to stderr until daemonized */
133	log_verbose(1);
134
135	while ((ch = getopt(argc, argv, "dD:f:nv")) != -1) {
136		switch (ch) {
137		case 'd':
138			debug = 1;
139			break;
140		case 'D':
141			if (cmdline_symset(optarg) < 0)
142				log_warnx("could not parse macro definition %s",
143				    optarg);
144			break;
145		case 'f':
146			conffile = optarg;
147			break;
148		case 'n':
149			opts |= LDPD_OPT_NOACTION;
150			break;
151		case 'v':
152			if (opts & LDPD_OPT_VERBOSE)
153				opts |= LDPD_OPT_VERBOSE2;
154			opts |= LDPD_OPT_VERBOSE;
155			break;
156		default:
157			usage();
158			/* NOTREACHED */
159		}
160	}
161
162	/* fetch interfaces early */
163	kif_init();
164
165	/* parse config file */
166	if ((ldpd_conf = parse_config(conffile, opts)) == NULL )
167		exit(1);
168
169	if (ldpd_conf->opts & LDPD_OPT_NOACTION) {
170		if (ldpd_conf->opts & LDPD_OPT_VERBOSE)
171			print_config(ldpd_conf);
172		else
173			fprintf(stderr, "configuration OK\n");
174		exit(0);
175	}
176
177	/* check for root privileges  */
178	if (geteuid())
179		errx(1, "need root privileges");
180
181	/* check for ldpd user */
182	if (getpwnam(LDPD_USER) == NULL)
183		errx(1, "unknown user %s", LDPD_USER);
184
185	log_init(debug);
186	log_verbose(opts & (LDPD_OPT_VERBOSE | LDPD_OPT_VERBOSE2));
187
188	if (!debug)
189		daemon(1, 0);
190
191	log_info("startup");
192
193	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
194	    PF_UNSPEC, pipe_parent2ldpe) == -1)
195		fatal("socketpair");
196	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
197	    PF_UNSPEC, pipe_parent2lde) == -1)
198		fatal("socketpair");
199	if (socketpair(AF_UNIX, SOCK_STREAM |SOCK_NONBLOCK | SOCK_CLOEXEC,
200	    PF_UNSPEC, pipe_ldpe2lde) == -1)
201		fatal("socketpair");
202
203	/* start children */
204	lde_pid = lde(ldpd_conf, pipe_parent2lde, pipe_ldpe2lde,
205	    pipe_parent2ldpe);
206	ldpe_pid = ldpe(ldpd_conf, pipe_parent2ldpe, pipe_ldpe2lde,
207	    pipe_parent2lde);
208
209	event_init();
210
211	/* setup signal handler */
212	signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL);
213	signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL);
214	signal_set(&ev_sigchld, SIGCHLD, main_sig_handler, NULL);
215	signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL);
216	signal_add(&ev_sigint, NULL);
217	signal_add(&ev_sigterm, NULL);
218	signal_add(&ev_sigchld, NULL);
219	signal_add(&ev_sighup, NULL);
220	signal(SIGPIPE, SIG_IGN);
221
222	/* setup pipes to children */
223	close(pipe_parent2ldpe[1]);
224	close(pipe_parent2lde[1]);
225	close(pipe_ldpe2lde[0]);
226	close(pipe_ldpe2lde[1]);
227
228	if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
229	    (iev_lde = malloc(sizeof(struct imsgev))) == NULL)
230		fatal(NULL);
231	imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
232	iev_ldpe->handler = main_dispatch_ldpe;
233	imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
234	iev_lde->handler = main_dispatch_lde;
235
236	/* setup event handler */
237	iev_ldpe->events = EV_READ;
238	event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events,
239	    iev_ldpe->handler, iev_ldpe);
240	event_add(&iev_ldpe->ev, NULL);
241
242	iev_lde->events = EV_READ;
243	event_set(&iev_lde->ev, iev_lde->ibuf.fd, iev_lde->events,
244	    iev_lde->handler, iev_lde);
245	event_add(&iev_lde->ev, NULL);
246
247	/* notify ldpe about existing interfaces and addresses */
248	kif_redistribute();
249
250	if (kr_init(!(ldpd_conf->flags & LDPD_FLAG_NO_FIB_UPDATE)) == -1)
251		fatalx("kr_init failed");
252
253	/* remove unneded stuff from config */
254		/* ... */
255
256	event_dispatch();
257
258	ldpd_shutdown();
259	/* NOTREACHED */
260	return (0);
261}
262
263void
264ldpd_shutdown(void)
265{
266	pid_t		 pid;
267
268	if (ldpe_pid)
269		kill(ldpe_pid, SIGTERM);
270
271	if (lde_pid)
272		kill(lde_pid, SIGTERM);
273
274	kr_shutdown();
275
276	do {
277		if ((pid = wait(NULL)) == -1 &&
278		    errno != EINTR && errno != ECHILD)
279			fatal("wait");
280	} while (pid != -1 || (pid == -1 && errno == EINTR));
281
282	config_clear(ldpd_conf);
283
284	msgbuf_clear(&iev_ldpe->ibuf.w);
285	free(iev_ldpe);
286	msgbuf_clear(&iev_lde->ibuf.w);
287	free(iev_lde);
288
289	log_info("terminating");
290	exit(0);
291}
292
293int
294check_child(pid_t pid, const char *pname)
295{
296	int	status;
297
298	if (waitpid(pid, &status, WNOHANG) > 0) {
299		if (WIFEXITED(status)) {
300			log_warnx("lost child: %s exited", pname);
301			return (1);
302		}
303		if (WIFSIGNALED(status)) {
304			log_warnx("lost child: %s terminated; signal %d",
305			    pname, WTERMSIG(status));
306			return (1);
307		}
308	}
309
310	return (0);
311}
312
313/* imsg handling */
314/* ARGSUSED */
315void
316main_dispatch_ldpe(int fd, short event, void *bula)
317{
318	struct imsgev		*iev = bula;
319	struct imsgbuf		*ibuf = &iev->ibuf;
320	struct imsg		 imsg;
321	ssize_t			 n;
322	int			 shut = 0, verbose;
323
324	if (event & EV_READ) {
325		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
326			fatal("imsg_read error");
327		if (n == 0)	/* connection closed */
328			shut = 1;
329	}
330	if (event & EV_WRITE) {
331		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
332			fatal("msgbuf_write");
333		if (n == 0)
334			shut = 1;
335	}
336
337	for (;;) {
338		if ((n = imsg_get(ibuf, &imsg)) == -1)
339			fatal("imsg_get");
340
341		if (n == 0)
342			break;
343
344		switch (imsg.hdr.type) {
345		case IMSG_CTL_RELOAD:
346			if (ldp_reload() == -1)
347				log_warnx("configuration reload failed");
348			else
349				log_debug("configuration reloaded");
350			break;
351		case IMSG_CTL_FIB_COUPLE:
352			kr_fib_couple();
353			break;
354		case IMSG_CTL_FIB_DECOUPLE:
355			kr_fib_decouple();
356			break;
357		case IMSG_CTL_KROUTE:
358		case IMSG_CTL_KROUTE_ADDR:
359			kr_show_route(&imsg);
360			break;
361		case IMSG_CTL_IFINFO:
362			if (imsg.hdr.len == IMSG_HEADER_SIZE)
363				kr_ifinfo(NULL, imsg.hdr.pid);
364			else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ)
365				kr_ifinfo(imsg.data, imsg.hdr.pid);
366			else
367				log_warnx("IFINFO request with wrong len");
368			break;
369		case IMSG_CTL_LOG_VERBOSE:
370			/* already checked by ldpe */
371			memcpy(&verbose, imsg.data, sizeof(verbose));
372			log_verbose(verbose);
373			break;
374		default:
375			log_debug("%s: error handling imsg %d", __func__,
376			    imsg.hdr.type);
377			break;
378		}
379		imsg_free(&imsg);
380	}
381	if (!shut)
382		imsg_event_add(iev);
383	else {
384		/* this pipe is dead, so remove the event handler */
385		event_del(&iev->ev);
386		event_loopexit(NULL);
387	}
388}
389
390/* ARGSUSED */
391void
392main_dispatch_lde(int fd, short event, void *bula)
393{
394	struct imsgev  *iev = bula;
395	struct imsgbuf *ibuf = &iev->ibuf;
396	struct imsg	 imsg;
397	ssize_t		 n;
398	int		 shut = 0;
399	struct kpw	*kpw;
400
401	if (event & EV_READ) {
402		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
403			fatal("imsg_read error");
404		if (n == 0)	/* connection closed */
405			shut = 1;
406	}
407	if (event & EV_WRITE) {
408		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
409			fatal("msgbuf_write");
410		if (n == 0)
411			shut = 1;
412	}
413
414	for (;;) {
415		if ((n = imsg_get(ibuf, &imsg)) == -1)
416			fatal("imsg_get");
417
418		if (n == 0)
419			break;
420
421		switch (imsg.hdr.type) {
422		case IMSG_KLABEL_CHANGE:
423			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
424			    sizeof(struct kroute))
425				fatalx("invalid size of IMSG_KLABEL_CHANGE");
426			if (kr_change(imsg.data))
427				log_warn("%s: error changing route", __func__);
428			break;
429		case IMSG_KLABEL_DELETE:
430			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
431			    sizeof(struct kroute))
432				fatalx("invalid size of IMSG_KLABEL_DELETE");
433			if (kr_delete(imsg.data))
434				log_warn("%s: error deleting route", __func__);
435			break;
436		case IMSG_KPWLABEL_CHANGE:
437			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
438			    sizeof(struct kpw))
439				fatalx("invalid size of IMSG_KPWLABEL_CHANGE");
440
441			kpw = imsg.data;
442			kmpw_set(kpw);
443			break;
444		case IMSG_KPWLABEL_DELETE:
445			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
446			    sizeof(struct kpw))
447				fatalx("invalid size of IMSG_KPWLABEL_DELETE");
448
449			kpw = imsg.data;
450			kmpw_unset(kpw);
451			break;
452		default:
453			log_debug("%s: error handling imsg %d", __func__,
454			    imsg.hdr.type);
455			break;
456		}
457		imsg_free(&imsg);
458	}
459	if (!shut)
460		imsg_event_add(iev);
461	else {
462		/* this pipe is dead, so remove the event handler */
463		event_del(&iev->ev);
464		event_loopexit(NULL);
465	}
466}
467
468void
469main_imsg_compose_ldpe(int type, pid_t pid, void *data, u_int16_t datalen)
470{
471	if (iev_ldpe == NULL)
472		return;
473	imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen);
474}
475
476void
477main_imsg_compose_lde(int type, pid_t pid, void *data, u_int16_t datalen)
478{
479	imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen);
480}
481
482int
483ldp_sendboth(enum imsg_type type, void *buf, uint16_t len)
484{
485	if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1)
486		return (-1);
487	if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1)
488		return (-1);
489	return (0);
490}
491
492void
493imsg_event_add(struct imsgev *iev)
494{
495	iev->events = EV_READ;
496	if (iev->ibuf.w.queued)
497		iev->events |= EV_WRITE;
498
499	event_del(&iev->ev);
500	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
501	event_add(&iev->ev, NULL);
502}
503
504int
505imsg_compose_event(struct imsgev *iev, u_int16_t type,
506    u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen)
507{
508	int	ret;
509
510	if ((ret = imsg_compose(&iev->ibuf, type, peerid,
511	    pid, fd, data, datalen)) != -1)
512		imsg_event_add(iev);
513	return (ret);
514}
515
516void
517evbuf_enqueue(struct evbuf *eb, struct ibuf *buf)
518{
519	ibuf_close(&eb->wbuf, buf);
520	evbuf_event_add(eb);
521}
522
523void
524evbuf_event_add(struct evbuf *eb)
525{
526	if (eb->wbuf.queued)
527		event_add(&eb->ev, NULL);
528}
529
530void
531evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *),
532    void *arg)
533{
534	msgbuf_init(&eb->wbuf);
535	eb->wbuf.fd = fd;
536	event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg);
537}
538
539void
540evbuf_clear(struct evbuf *eb)
541{
542	event_del(&eb->ev);
543	msgbuf_clear(&eb->wbuf);
544	eb->wbuf.fd = -1;
545}
546
547int
548ldp_reload(void)
549{
550	struct iface		*iface;
551	struct tnbr		*tnbr;
552	struct nbr_params	*nbrp;
553	struct l2vpn		*l2vpn;
554	struct l2vpn_if		*lif;
555	struct l2vpn_pw		*pw;
556	struct ldpd_conf	*xconf;
557
558	if ((xconf = parse_config(conffile, ldpd_conf->opts)) == NULL)
559		return (-1);
560
561	if (ldp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
562		return (-1);
563
564	LIST_FOREACH(iface, &xconf->iface_list, entry) {
565		if (ldp_sendboth(IMSG_RECONF_IFACE, iface,
566		    sizeof(*iface)) == -1)
567			return (-1);
568	}
569
570	LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
571		if (ldp_sendboth(IMSG_RECONF_TNBR, tnbr,
572		    sizeof(*tnbr)) == -1)
573			return (-1);
574	}
575
576	LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
577		if (ldp_sendboth(IMSG_RECONF_NBRP, nbrp,
578		    sizeof(*nbrp)) == -1)
579			return (-1);
580	}
581
582	LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
583		if (ldp_sendboth(IMSG_RECONF_L2VPN, l2vpn,
584		    sizeof(*l2vpn)) == -1)
585			return (-1);
586
587		LIST_FOREACH(lif, &l2vpn->if_list, entry) {
588			if (ldp_sendboth(IMSG_RECONF_L2VPN_IF, lif,
589			    sizeof(*lif)) == -1)
590				return (-1);
591		}
592		LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
593			if (ldp_sendboth(IMSG_RECONF_L2VPN_PW, pw,
594			    sizeof(*pw)) == -1)
595				return (-1);
596		}
597	}
598
599	if (ldp_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
600		return (-1);
601
602	merge_config(ldpd_conf, xconf);
603
604	return (0);
605}
606
607int
608ldp_sendboth(enum imsg_type type, void *buf, u_int16_t len)
609{
610	if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1)
611		return (-1);
612	if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1)
613		return (-1);
614	return (0);
615}
616
617void
618merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
619{
620	struct iface		*iface, *itmp, *xi;
621	struct tnbr		*tnbr, *ttmp, *xt;
622	struct nbr_params	*nbrp, *ntmp, *xn;
623	struct l2vpn		*l2vpn, *ltmp, *xl;
624	struct nbr		*nbr;
625
626	/* change of rtr_id needs a restart */
627	conf->flags = xconf->flags;
628	conf->keepalive = xconf->keepalive;
629	conf->thello_holdtime = xconf->thello_holdtime;
630	conf->thello_interval = xconf->thello_interval;
631	conf->trans_addr.s_addr = xconf->trans_addr.s_addr;
632
633	/* merge interfaces */
634	LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
635		/* find deleted interfaces */
636		if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) {
637			LIST_REMOVE(iface, entry);
638			if (ldpd_process == PROC_LDP_ENGINE)
639				if_del(iface);
640			else
641				free(iface);
642		}
643	}
644	LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
645		/* find new interfaces */
646		if ((iface = if_lookup(conf, xi->ifindex)) == NULL) {
647			LIST_REMOVE(xi, entry);
648			LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
649			if (ldpd_process == PROC_LDP_ENGINE)
650				if_init(conf, xi);
651			continue;
652		}
653
654		/* update existing interfaces */
655		iface->hello_holdtime = xi->hello_holdtime;
656		iface->hello_interval = xi->hello_interval;
657	}
658	/* resend addresses to activate new interfaces */
659	if (ldpd_process == PROC_MAIN)
660		kif_redistribute();
661}
662
663void
664merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
665{
666	struct tnbr		*tnbr, *ttmp, *xt;
667
668	LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
669		if (!(tnbr->flags & F_TNBR_CONFIGURED))
670			continue;
671
672		/* find deleted tnbrs */
673		if ((xt = tnbr_find(xconf, tnbr->addr)) == NULL) {
674			if (ldpd_process == PROC_LDP_ENGINE) {
675				tnbr->flags &= ~F_TNBR_CONFIGURED;
676				tnbr_check(tnbr);
677			} else {
678				LIST_REMOVE(tnbr, entry);
679				free(tnbr);
680			}
681		}
682	}
683	LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
684		/* find new tnbrs */
685		if ((tnbr = tnbr_find(conf, xt->addr)) == NULL) {
686			LIST_REMOVE(xt, entry);
687			LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
688			if (ldpd_process == PROC_LDP_ENGINE)
689				tnbr_init(conf, xt);
690			continue;
691		}
692
693		/* update existing tnbrs */
694		if (!(tnbr->flags & F_TNBR_CONFIGURED))
695			tnbr->flags |= F_TNBR_CONFIGURED;
696		tnbr->hello_holdtime = xt->hello_holdtime;
697		tnbr->hello_interval = xt->hello_interval;
698	}
699}
700
701void
702merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
703{
704	struct nbr_params	*nbrp, *ntmp, *xn;
705	struct nbr		*nbr;
706
707	LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
708		/* find deleted nbrps */
709		if ((xn = nbr_params_find(xconf, nbrp->addr)) == NULL) {
710			if (ldpd_process == PROC_LDP_ENGINE) {
711				nbr = nbr_find_ldpid(nbrp->addr.s_addr);
712				if (nbr) {
713					if (nbr->state == NBR_STA_OPER)
714						session_shutdown(nbr,
715						    S_SHUTDOWN, 0, 0);
716					pfkey_remove(nbr);
717				}
718			}
719			LIST_REMOVE(nbrp, entry);
720			free(nbrp);
721		}
722	}
723	LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
724		/* find new nbrps */
725		if ((nbrp = nbr_params_find(conf, xn->addr)) == NULL) {
726			LIST_REMOVE(xn, entry);
727			LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
728
729			if (ldpd_process == PROC_LDP_ENGINE) {
730				nbr = nbr_find_ldpid(xn->addr.s_addr);
731				if (nbr) {
732					if (nbr->state == NBR_STA_OPER)
733						session_shutdown(nbr,
734						    S_SHUTDOWN, 0, 0);
735					pfkey_remove(nbr);
736					if (pfkey_establish(nbr, xn) == -1)
737						fatalx("pfkey setup failed");
738				}
739			}
740			continue;
741		}
742
743		/* update existing nbrps */
744		nbrp->keepalive = xn->keepalive;
745		nbrp->auth.method = xn->auth.method;
746		strlcpy(nbrp->auth.md5key, xn->auth.md5key,
747		    sizeof(nbrp->auth.md5key));
748		nbrp->auth.md5key_len = xn->auth.md5key_len;
749
750		if (ldpd_process == PROC_LDP_ENGINE) {
751			nbr = nbr_find_ldpid(nbrp->addr.s_addr);
752			if (nbr &&
753			    (nbr->auth.method != nbrp->auth.method ||
754			    strcmp(nbr->auth.md5key, nbrp->auth.md5key) != 0)) {
755				if (nbr->state == NBR_STA_OPER)
756					session_shutdown(nbr, S_SHUTDOWN,
757					    0, 0);
758				pfkey_remove(nbr);
759				if (pfkey_establish(nbr, nbrp) == -1)
760					fatalx("pfkey setup failed");
761			}
762		}
763	}
764}
765
766void
767merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
768{
769	struct l2vpn		*l2vpn, *ltmp, *xl;
770
771	LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
772		/* find deleted l2vpns */
773		if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
774			LIST_REMOVE(l2vpn, entry);
775
776			switch (ldpd_process) {
777			case PROC_LDE_ENGINE:
778				l2vpn_del(l2vpn);
779				break;
780			case PROC_LDP_ENGINE:
781				ldpe_l2vpn_exit(l2vpn);
782				free(l2vpn);
783				break;
784			case PROC_MAIN:
785				free(l2vpn);
786				break;
787			}
788		}
789	}
790	LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
791		/* find new l2vpns */
792		if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
793			LIST_REMOVE(xl, entry);
794			LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
795
796			switch (ldpd_process) {
797			case PROC_LDE_ENGINE:
798				l2vpn_init(xl);
799				break;
800			case PROC_LDP_ENGINE:
801				ldpe_l2vpn_init(xl);
802				break;
803			case PROC_MAIN:
804				break;
805			}
806			continue;
807		}
808
809		/* update existing l2vpns */
810		merge_l2vpn(conf, l2vpn, xl);
811	}
812}
813
814void
815merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
816{
817	struct l2vpn_if		*lif, *ftmp, *xf;
818	struct l2vpn_pw		*pw, *ptmp, *xp;
819
820	/* merge intefaces */
821	LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
822		/* find deleted interfaces */
823		if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) {
824			LIST_REMOVE(lif, entry);
825			free(lif);
826		}
827	}
828	LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
829		/* find new interfaces */
830		if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) {
831			LIST_REMOVE(xf, entry);
832			LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
833			lif->l2vpn = l2vpn;
834			continue;
835		}
836
837		/* update existing interfaces */
838		lif->l2vpn = l2vpn;
839	}
840
841	/* merge pseudowires */
842	LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
843		/* find deleted pseudowires */
844		if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) {
845			LIST_REMOVE(pw, entry);
846
847			switch (ldpd_process) {
848			case PROC_LDE_ENGINE:
849				l2vpn_pw_del(pw);
850				break;
851			case PROC_LDP_ENGINE:
852				ldpe_l2vpn_pw_exit(pw);
853				free(pw);
854				break;
855			case PROC_MAIN:
856				free(pw);
857				break;
858			}
859		}
860	}
861	LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
862		/* find new pseudowires */
863		if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) {
864			LIST_REMOVE(xp, entry);
865			LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
866
867			switch (ldpd_process) {
868			case PROC_LDE_ENGINE:
869				l2vpn_pw_init(xp);
870				break;
871			case PROC_LDP_ENGINE:
872				ldpe_l2vpn_pw_init(xp);
873				break;
874			case PROC_MAIN:
875				break;
876			}
877			continue;
878		}
879
880		/* changes that require a full reset of the pseudowire */
881		if (l2vpn->pw_type != xl->pw_type ||
882		    l2vpn->mtu != xl->mtu ||
883		    pw->addr.s_addr != xp->addr.s_addr ||
884		    pw->pwid != xp->pwid ||
885		    ((pw->flags &
886		    (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)) !=
887		    (xp->flags &
888		    (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)))) {
889			LIST_REMOVE(pw, entry);
890			LIST_REMOVE(xp, entry);
891			LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
892
893			switch (ldpd_process) {
894			case PROC_LDE_ENGINE:
895				l2vpn_pw_del(pw);
896				l2vpn_pw_init(xp);
897				break;
898			case PROC_LDP_ENGINE:
899		    		if (pw->addr.s_addr != xp->addr.s_addr) {
900					ldpe_l2vpn_pw_exit(pw);
901					ldpe_l2vpn_pw_init(xp);
902				}
903				free(pw);
904				break;
905			case PROC_MAIN:
906				free(pw);
907				break;
908			}
909		}
910
911		/* update existing pseudowires */
912		pw->l2vpn = xp->l2vpn;
913	}
914
915	l2vpn->mtu = xl->mtu;
916	l2vpn->br_ifindex = xl->br_ifindex;
917}
918
919void
920config_clear(struct ldpd_conf *conf)
921{
922	struct ldpd_conf	*xconf;
923
924	/* merge current config with an empty config */
925	xconf = malloc(sizeof(*xconf));
926	memcpy(xconf, conf, sizeof(*xconf));
927	LIST_INIT(&xconf->iface_list);
928	LIST_INIT(&xconf->tnbr_list);
929	LIST_INIT(&xconf->nbrp_list);
930	LIST_INIT(&xconf->l2vpn_list);
931	merge_config(conf, xconf);
932
933	free(conf);
934}
935