ldpd.c revision 1.30
1/*	$OpenBSD: ldpd.c,v 1.30 2016/05/23 15:41:04 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
482void
483imsg_event_add(struct imsgev *iev)
484{
485	iev->events = EV_READ;
486	if (iev->ibuf.w.queued)
487		iev->events |= EV_WRITE;
488
489	event_del(&iev->ev);
490	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
491	event_add(&iev->ev, NULL);
492}
493
494int
495imsg_compose_event(struct imsgev *iev, u_int16_t type,
496    u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen)
497{
498	int	ret;
499
500	if ((ret = imsg_compose(&iev->ibuf, type, peerid,
501	    pid, fd, data, datalen)) != -1)
502		imsg_event_add(iev);
503	return (ret);
504}
505
506void
507evbuf_enqueue(struct evbuf *eb, struct ibuf *buf)
508{
509	ibuf_close(&eb->wbuf, buf);
510	evbuf_event_add(eb);
511}
512
513void
514evbuf_event_add(struct evbuf *eb)
515{
516	if (eb->wbuf.queued)
517		event_add(&eb->ev, NULL);
518}
519
520void
521evbuf_init(struct evbuf *eb, int fd, void (*handler)(int, short, void *),
522    void *arg)
523{
524	msgbuf_init(&eb->wbuf);
525	eb->wbuf.fd = fd;
526	event_set(&eb->ev, eb->wbuf.fd, EV_WRITE, handler, arg);
527}
528
529void
530evbuf_clear(struct evbuf *eb)
531{
532	event_del(&eb->ev);
533	msgbuf_clear(&eb->wbuf);
534	eb->wbuf.fd = -1;
535}
536
537int
538ldp_reload(void)
539{
540	struct iface		*iface;
541	struct tnbr		*tnbr;
542	struct nbr_params	*nbrp;
543	struct l2vpn		*l2vpn;
544	struct l2vpn_if		*lif;
545	struct l2vpn_pw		*pw;
546	struct ldpd_conf	*xconf;
547
548	if ((xconf = parse_config(conffile, ldpd_conf->opts)) == NULL)
549		return (-1);
550
551	if (ldp_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
552		return (-1);
553
554	LIST_FOREACH(iface, &xconf->iface_list, entry) {
555		if (ldp_sendboth(IMSG_RECONF_IFACE, iface,
556		    sizeof(*iface)) == -1)
557			return (-1);
558	}
559
560	LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
561		if (ldp_sendboth(IMSG_RECONF_TNBR, tnbr,
562		    sizeof(*tnbr)) == -1)
563			return (-1);
564	}
565
566	LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
567		if (ldp_sendboth(IMSG_RECONF_NBRP, nbrp,
568		    sizeof(*nbrp)) == -1)
569			return (-1);
570	}
571
572	LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
573		if (ldp_sendboth(IMSG_RECONF_L2VPN, l2vpn,
574		    sizeof(*l2vpn)) == -1)
575			return (-1);
576
577		LIST_FOREACH(lif, &l2vpn->if_list, entry) {
578			if (ldp_sendboth(IMSG_RECONF_L2VPN_IF, lif,
579			    sizeof(*lif)) == -1)
580				return (-1);
581		}
582		LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
583			if (ldp_sendboth(IMSG_RECONF_L2VPN_PW, pw,
584			    sizeof(*pw)) == -1)
585				return (-1);
586		}
587	}
588
589	if (ldp_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
590		return (-1);
591
592	merge_config(ldpd_conf, xconf);
593
594	return (0);
595}
596
597int
598ldp_sendboth(enum imsg_type type, void *buf, u_int16_t len)
599{
600	if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1)
601		return (-1);
602	if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1)
603		return (-1);
604	return (0);
605}
606
607void
608merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
609{
610	struct iface		*iface, *itmp, *xi;
611	struct tnbr		*tnbr, *ttmp, *xt;
612	struct nbr_params	*nbrp, *ntmp, *xn;
613	struct l2vpn		*l2vpn, *ltmp, *xl;
614	struct nbr		*nbr;
615
616	/* change of rtr_id needs a restart */
617	conf->flags = xconf->flags;
618	conf->keepalive = xconf->keepalive;
619	conf->thello_holdtime = xconf->thello_holdtime;
620	conf->thello_interval = xconf->thello_interval;
621
622	/* merge interfaces */
623	LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
624		/* find deleted interfaces */
625		if ((xi = if_lookup(xconf, iface->ifindex)) == NULL) {
626			LIST_REMOVE(iface, entry);
627			if (ldpd_process == PROC_LDP_ENGINE)
628				if_del(iface);
629			else
630				free(iface);
631		}
632	}
633	LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
634		/* find new interfaces */
635		if ((iface = if_lookup(conf, xi->ifindex)) == NULL) {
636			LIST_REMOVE(xi, entry);
637			LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
638			if (ldpd_process == PROC_LDP_ENGINE)
639				if_init(conf, xi);
640			continue;
641		}
642
643		/* update existing interfaces */
644		iface->hello_holdtime = xi->hello_holdtime;
645		iface->hello_interval = xi->hello_interval;
646	}
647	/* resend addresses to activate new interfaces */
648	if (ldpd_process == PROC_MAIN)
649		kif_redistribute();
650
651	/* merge tnbrs */
652	LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
653		if (!(tnbr->flags & F_TNBR_CONFIGURED))
654			continue;
655
656		/* find deleted tnbrs */
657		if ((xt = tnbr_find(xconf, tnbr->addr)) == NULL) {
658			if (ldpd_process == PROC_LDP_ENGINE) {
659				tnbr->flags &= ~F_TNBR_CONFIGURED;
660				tnbr_check(tnbr);
661			} else {
662				LIST_REMOVE(tnbr, entry);
663				free(tnbr);
664			}
665		}
666	}
667	LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
668		/* find new tnbrs */
669		if ((tnbr = tnbr_find(conf, xt->addr)) == NULL) {
670			LIST_REMOVE(xt, entry);
671			LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
672			if (ldpd_process == PROC_LDP_ENGINE)
673				tnbr_init(conf, xt);
674			continue;
675		}
676
677		/* update existing tnbrs */
678		if (!(tnbr->flags & F_TNBR_CONFIGURED))
679			tnbr->flags |= F_TNBR_CONFIGURED;
680		tnbr->hello_holdtime = xt->hello_holdtime;
681		tnbr->hello_interval = xt->hello_interval;
682	}
683
684	/* merge neighbor parameters */
685	LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
686		/* find deleted nbrps */
687		if ((xn = nbr_params_find(xconf, nbrp->addr)) == NULL) {
688			if (ldpd_process == PROC_LDP_ENGINE) {
689				nbr = nbr_find_ldpid(nbrp->addr.s_addr);
690				if (nbr) {
691					if (nbr->state == NBR_STA_OPER)
692						session_shutdown(nbr,
693						    S_SHUTDOWN, 0, 0);
694					pfkey_remove(nbr);
695				}
696			}
697			LIST_REMOVE(nbrp, entry);
698			free(nbrp);
699		}
700	}
701	LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
702		/* find new nbrps */
703		if ((nbrp = nbr_params_find(conf, xn->addr)) == NULL) {
704			LIST_REMOVE(xn, entry);
705			LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
706
707			if (ldpd_process == PROC_LDP_ENGINE) {
708				nbr = nbr_find_ldpid(xn->addr.s_addr);
709				if (nbr) {
710					if (nbr->state == NBR_STA_OPER)
711						session_shutdown(nbr,
712						    S_SHUTDOWN, 0, 0);
713					pfkey_remove(nbr);
714					if (pfkey_establish(nbr, xn) == -1)
715						fatalx("pfkey setup failed");
716				}
717			}
718			continue;
719		}
720
721		/* update existing nbrps */
722		nbrp->keepalive = xn->keepalive;
723		nbrp->auth.method = xn->auth.method;
724		strlcpy(nbrp->auth.md5key, xn->auth.md5key,
725		    sizeof(nbrp->auth.md5key));
726		nbrp->auth.md5key_len = xn->auth.md5key_len;
727
728		if (ldpd_process == PROC_LDP_ENGINE) {
729			nbr = nbr_find_ldpid(nbrp->addr.s_addr);
730			if (nbr &&
731			    (nbr->auth.method != nbrp->auth.method ||
732			    strcmp(nbr->auth.md5key, nbrp->auth.md5key) != 0)) {
733				if (nbr->state == NBR_STA_OPER)
734					session_shutdown(nbr, S_SHUTDOWN,
735					    0, 0);
736				pfkey_remove(nbr);
737				if (pfkey_establish(nbr, nbrp) == -1)
738					fatalx("pfkey setup failed");
739			}
740		}
741	}
742
743	/* merge l2vpns */
744	LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
745		/* find deleted l2vpns */
746		if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
747			LIST_REMOVE(l2vpn, entry);
748
749			switch (ldpd_process) {
750			case PROC_LDE_ENGINE:
751				l2vpn_del(l2vpn);
752				break;
753			case PROC_LDP_ENGINE:
754				ldpe_l2vpn_exit(l2vpn);
755				free(l2vpn);
756				break;
757			case PROC_MAIN:
758				free(l2vpn);
759				break;
760			}
761		}
762	}
763	LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
764		/* find new l2vpns */
765		if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
766			LIST_REMOVE(xl, entry);
767			LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
768
769			switch (ldpd_process) {
770			case PROC_LDE_ENGINE:
771				l2vpn_init(xl);
772				break;
773			case PROC_LDP_ENGINE:
774				ldpe_l2vpn_init(xl);
775				break;
776			case PROC_MAIN:
777				break;
778			}
779			continue;
780		}
781
782		/* update existing l2vpns */
783		merge_l2vpns(conf, l2vpn, xl);
784	}
785
786	free(xconf);
787}
788
789void
790merge_l2vpns(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
791{
792	struct l2vpn_if		*lif, *ftmp, *xf;
793	struct l2vpn_pw		*pw, *ptmp, *xp;
794
795	/* merge intefaces */
796	LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
797		/* find deleted interfaces */
798		if ((xf = l2vpn_if_find(xl, lif->ifindex)) == NULL) {
799			LIST_REMOVE(lif, entry);
800			free(lif);
801		}
802	}
803	LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
804		/* find new interfaces */
805		if ((lif = l2vpn_if_find(l2vpn, xf->ifindex)) == NULL) {
806			LIST_REMOVE(xf, entry);
807			LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
808			lif->l2vpn = l2vpn;
809			continue;
810		}
811
812		/* update existing interfaces */
813		lif->l2vpn = l2vpn;
814	}
815
816	/* merge pseudowires */
817	LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
818		/* find deleted pseudowires */
819		if ((xp = l2vpn_pw_find(xl, pw->ifindex)) == NULL) {
820			LIST_REMOVE(pw, entry);
821
822			switch (ldpd_process) {
823			case PROC_LDE_ENGINE:
824				l2vpn_pw_del(pw);
825				break;
826			case PROC_LDP_ENGINE:
827				ldpe_l2vpn_pw_exit(pw);
828				free(pw);
829				break;
830			case PROC_MAIN:
831				free(pw);
832				break;
833			}
834		}
835	}
836	LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
837		/* find new pseudowires */
838		if ((pw = l2vpn_pw_find(l2vpn, xp->ifindex)) == NULL) {
839			LIST_REMOVE(xp, entry);
840			LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
841
842			switch (ldpd_process) {
843			case PROC_LDE_ENGINE:
844				l2vpn_pw_init(xp);
845				break;
846			case PROC_LDP_ENGINE:
847				ldpe_l2vpn_pw_init(xp);
848				break;
849			case PROC_MAIN:
850				break;
851			}
852			continue;
853		}
854
855		/* changes that require a full reset of the pseudowire */
856		if (l2vpn->pw_type != xl->pw_type ||
857		    l2vpn->mtu != xl->mtu ||
858		    pw->addr.s_addr != xp->addr.s_addr ||
859		    pw->pwid != xp->pwid ||
860		    ((pw->flags &
861		    (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)) !=
862		    (xp->flags &
863		    (F_PW_STATUSTLV_CONF|F_PW_CONTROLWORD_CONF)))) {
864			LIST_REMOVE(pw, entry);
865			LIST_REMOVE(xp, entry);
866			LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
867
868			switch (ldpd_process) {
869			case PROC_LDE_ENGINE:
870				l2vpn_pw_del(pw);
871				l2vpn_pw_init(xp);
872				break;
873			case PROC_LDP_ENGINE:
874		    		if (pw->addr.s_addr != xp->addr.s_addr) {
875					ldpe_l2vpn_pw_exit(pw);
876					ldpe_l2vpn_pw_init(xp);
877				}
878				free(pw);
879				break;
880			case PROC_MAIN:
881				free(pw);
882				break;
883			}
884		}
885
886		/* update existing pseudowires */
887		pw->l2vpn = xp->l2vpn;
888	}
889
890	l2vpn->mtu = xl->mtu;
891	l2vpn->br_ifindex = xl->br_ifindex;
892}
893
894void
895config_clear(struct ldpd_conf *conf)
896{
897	struct ldpd_conf	*xconf;
898
899	/* merge current config with an empty config */
900	xconf = malloc(sizeof(*xconf));
901	memcpy(xconf, conf, sizeof(*xconf));
902	LIST_INIT(&xconf->iface_list);
903	LIST_INIT(&xconf->tnbr_list);
904	LIST_INIT(&xconf->nbrp_list);
905	LIST_INIT(&xconf->l2vpn_list);
906	merge_config(conf, xconf);
907
908	free(conf);
909}
910