1/*	$OpenBSD: lde.c,v 1.78 2024/04/23 13:34:51 jsg Exp $ */
2
3/*
4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004 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/time.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26#include <netmpls/mpls.h>
27#include <arpa/inet.h>
28#include <errno.h>
29#include <stdlib.h>
30#include <signal.h>
31#include <string.h>
32#include <pwd.h>
33#include <unistd.h>
34#include <limits.h>
35
36#include "ldp.h"
37#include "ldpd.h"
38#include "ldpe.h"
39#include "log.h"
40#include "lde.h"
41
42static void		 lde_sig_handler(int sig, short, void *);
43static __dead void	 lde_shutdown(void);
44static int		 lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
45static void		 lde_dispatch_imsg(int, short, void *);
46static void		 lde_dispatch_parent(int, short, void *);
47static __inline	int	 lde_nbr_compare(struct lde_nbr *,
48			    struct lde_nbr *);
49static struct lde_nbr	*lde_nbr_new(uint32_t, struct lde_nbr *);
50static void		 lde_nbr_del(struct lde_nbr *);
51static struct lde_nbr	*lde_nbr_find(uint32_t);
52static void		 lde_nbr_clear(void);
53static void		 lde_nbr_addr_update(struct lde_nbr *,
54			    struct lde_addr *, int);
55static void		 lde_map_free(void *);
56static int		 lde_address_add(struct lde_nbr *, struct lde_addr *);
57static int		 lde_address_del(struct lde_nbr *, struct lde_addr *);
58static void		 lde_address_list_free(struct lde_nbr *);
59
60RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
61
62struct ldpd_conf	*ldeconf;
63struct nbr_tree		 lde_nbrs = RB_INITIALIZER(&lde_nbrs);
64
65static struct imsgev	*iev_ldpe;
66static struct imsgev	*iev_main;
67
68static void
69lde_sig_handler(int sig, short event, void *arg)
70{
71	/*
72	 * signal handler rules don't apply, libevent decouples for us
73	 */
74
75	switch (sig) {
76	case SIGINT:
77	case SIGTERM:
78		lde_shutdown();
79		/* NOTREACHED */
80	default:
81		fatalx("unexpected signal");
82	}
83}
84
85/* label decision engine */
86void
87lde(int debug, int verbose)
88{
89	struct event		 ev_sigint, ev_sigterm;
90	struct timeval		 now;
91	struct passwd		*pw;
92
93	ldeconf = config_new_empty();
94
95	log_init(debug);
96	log_verbose(verbose);
97
98	setproctitle("label decision engine");
99	ldpd_process = PROC_LDE_ENGINE;
100	log_procname = "lde";
101
102	if ((pw = getpwnam(LDPD_USER)) == NULL)
103		fatal("getpwnam");
104
105	if (chroot(pw->pw_dir) == -1)
106		fatal("chroot");
107	if (chdir("/") == -1)
108		fatal("chdir(\"/\")");
109
110	if (setgroups(1, &pw->pw_gid) ||
111	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
112	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
113		fatal("can't drop privileges");
114
115	if (pledge("stdio recvfd", NULL) == -1)
116		fatal("pledge");
117
118	event_init();
119
120	/* setup signal handler */
121	signal_set(&ev_sigint, SIGINT, lde_sig_handler, NULL);
122	signal_set(&ev_sigterm, SIGTERM, lde_sig_handler, NULL);
123	signal_add(&ev_sigint, NULL);
124	signal_add(&ev_sigterm, NULL);
125	signal(SIGPIPE, SIG_IGN);
126	signal(SIGHUP, SIG_IGN);
127
128	/* setup pipe and event handler to the parent process */
129	if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
130		fatal(NULL);
131	imsg_init(&iev_main->ibuf, 3);
132	iev_main->handler = lde_dispatch_parent;
133	iev_main->events = EV_READ;
134	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
135	    iev_main->handler, iev_main);
136	event_add(&iev_main->ev, NULL);
137
138	/* setup and start the LIB garbage collector */
139	evtimer_set(&gc_timer, lde_gc_timer, NULL);
140	lde_gc_start_timer();
141
142	gettimeofday(&now, NULL);
143	global.uptime = now.tv_sec;
144
145	event_dispatch();
146
147	lde_shutdown();
148}
149
150static __dead void
151lde_shutdown(void)
152{
153	/* close pipes */
154	msgbuf_clear(&iev_ldpe->ibuf.w);
155	close(iev_ldpe->ibuf.fd);
156	msgbuf_clear(&iev_main->ibuf.w);
157	close(iev_main->ibuf.fd);
158
159	lde_gc_stop_timer();
160	lde_nbr_clear();
161	fec_tree_clear();
162
163	config_clear(ldeconf);
164
165	free(iev_ldpe);
166	free(iev_main);
167
168	log_info("label decision engine exiting");
169	exit(0);
170}
171
172/* imesg */
173static int
174lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
175{
176	return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
177}
178
179int
180lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
181    uint16_t datalen)
182{
183	return (imsg_compose_event(iev_ldpe, type, peerid, pid,
184	     -1, data, datalen));
185}
186
187static void
188lde_dispatch_imsg(int fd, short event, void *bula)
189{
190	struct imsgev		*iev = bula;
191	struct imsgbuf		*ibuf = &iev->ibuf;
192	struct imsg		 imsg;
193	struct lde_nbr		*ln;
194	struct map		 map;
195	struct lde_addr		 lde_addr;
196	struct notify_msg	 nm;
197	ssize_t			 n;
198	int			 shut = 0, verbose;
199
200	if (event & EV_READ) {
201		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
202			fatal("imsg_read error");
203		if (n == 0)	/* connection closed */
204			shut = 1;
205	}
206	if (event & EV_WRITE) {
207		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
208			fatal("msgbuf_write");
209		if (n == 0)	/* connection closed */
210			shut = 1;
211	}
212
213	for (;;) {
214		if ((n = imsg_get(ibuf, &imsg)) == -1)
215			fatal("lde_dispatch_imsg: imsg_get error");
216		if (n == 0)
217			break;
218
219		switch (imsg.hdr.type) {
220		case IMSG_LABEL_MAPPING_FULL:
221			ln = lde_nbr_find(imsg.hdr.peerid);
222			if (ln == NULL) {
223				log_debug("%s: cannot find lde neighbor",
224				    __func__);
225				break;
226			}
227
228			fec_snap(ln);
229			break;
230		case IMSG_LABEL_MAPPING:
231		case IMSG_LABEL_REQUEST:
232		case IMSG_LABEL_RELEASE:
233		case IMSG_LABEL_WITHDRAW:
234		case IMSG_LABEL_ABORT:
235			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map))
236				fatalx("lde_dispatch_imsg: wrong imsg len");
237			memcpy(&map, imsg.data, sizeof(map));
238
239			ln = lde_nbr_find(imsg.hdr.peerid);
240			if (ln == NULL) {
241				log_debug("%s: cannot find lde neighbor",
242				    __func__);
243				break;
244			}
245
246			switch (imsg.hdr.type) {
247			case IMSG_LABEL_MAPPING:
248				lde_check_mapping(&map, ln);
249				break;
250			case IMSG_LABEL_REQUEST:
251				lde_check_request(&map, ln);
252				break;
253			case IMSG_LABEL_RELEASE:
254				lde_check_release(&map, ln);
255				break;
256			case IMSG_LABEL_WITHDRAW:
257				lde_check_withdraw(&map, ln);
258				break;
259			case IMSG_LABEL_ABORT:
260				/* not necessary */
261				break;
262			}
263			break;
264		case IMSG_ADDRESS_ADD:
265			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
266				fatalx("lde_dispatch_imsg: wrong imsg len");
267			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
268
269			ln = lde_nbr_find(imsg.hdr.peerid);
270			if (ln == NULL) {
271				log_debug("%s: cannot find lde neighbor",
272				    __func__);
273				break;
274			}
275			if (lde_address_add(ln, &lde_addr) < 0) {
276				log_debug("%s: cannot add address %s, it "
277				    "already exists", __func__,
278				    log_addr(lde_addr.af, &lde_addr.addr));
279			}
280			break;
281		case IMSG_ADDRESS_DEL:
282			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
283				fatalx("lde_dispatch_imsg: wrong imsg len");
284			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
285
286			ln = lde_nbr_find(imsg.hdr.peerid);
287			if (ln == NULL) {
288				log_debug("%s: cannot find lde neighbor",
289				    __func__);
290				break;
291			}
292			if (lde_address_del(ln, &lde_addr) < 0) {
293				log_debug("%s: cannot delete address %s, it "
294				    "does not exist", __func__,
295				    log_addr(lde_addr.af, &lde_addr.addr));
296			}
297			break;
298		case IMSG_NOTIFICATION:
299			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm))
300				fatalx("lde_dispatch_imsg: wrong imsg len");
301			memcpy(&nm, imsg.data, sizeof(nm));
302
303			ln = lde_nbr_find(imsg.hdr.peerid);
304			if (ln == NULL) {
305				log_debug("%s: cannot find lde neighbor",
306				    __func__);
307				break;
308			}
309
310			switch (nm.status_code) {
311			case S_PW_STATUS:
312				l2vpn_recv_pw_status(ln, &nm);
313				break;
314			case S_ENDOFLIB:
315				/*
316				 * Do nothing for now. Should be useful in
317				 * the future when we implement LDP-IGP
318				 * Synchronization (RFC 5443) and Graceful
319				 * Restart (RFC 3478).
320				 */
321			default:
322				break;
323			}
324			break;
325		case IMSG_NEIGHBOR_UP:
326			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
327			    sizeof(struct lde_nbr))
328				fatalx("lde_dispatch_imsg: wrong imsg len");
329
330			if (lde_nbr_find(imsg.hdr.peerid))
331				fatalx("lde_dispatch_imsg: "
332				    "neighbor already exists");
333			lde_nbr_new(imsg.hdr.peerid, imsg.data);
334			break;
335		case IMSG_NEIGHBOR_DOWN:
336			lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
337			break;
338		case IMSG_CTL_SHOW_LIB:
339			rt_dump(imsg.hdr.pid);
340
341			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
342			    imsg.hdr.pid, NULL, 0);
343			break;
344		case IMSG_CTL_SHOW_L2VPN_PW:
345			l2vpn_pw_ctl(imsg.hdr.pid);
346
347			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
348			    imsg.hdr.pid, NULL, 0);
349			break;
350		case IMSG_CTL_SHOW_L2VPN_BINDING:
351			l2vpn_binding_ctl(imsg.hdr.pid);
352
353			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
354			    imsg.hdr.pid, NULL, 0);
355			break;
356		case IMSG_CTL_LOG_VERBOSE:
357			/* already checked by ldpe */
358			memcpy(&verbose, imsg.data, sizeof(verbose));
359			log_verbose(verbose);
360			break;
361		default:
362			log_debug("%s: unexpected imsg %d", __func__,
363			    imsg.hdr.type);
364			break;
365		}
366		imsg_free(&imsg);
367	}
368	if (!shut)
369		imsg_event_add(iev);
370	else {
371		/* this pipe is dead, so remove the event handler */
372		event_del(&iev->ev);
373		event_loopexit(NULL);
374	}
375}
376
377static void
378lde_dispatch_parent(int fd, short event, void *bula)
379{
380	static struct ldpd_conf	*nconf;
381	struct iface		*niface;
382	struct tnbr		*ntnbr;
383	struct nbr_params	*nnbrp;
384	static struct l2vpn	*nl2vpn;
385	struct l2vpn_if		*nlif;
386	struct l2vpn_pw		*npw;
387	struct imsg		 imsg;
388	struct kroute		 kr;
389	struct imsgev		*iev = bula;
390	struct imsgbuf		*ibuf = &iev->ibuf;
391	ssize_t			 n;
392	int			 shut = 0;
393	struct fec		 fec;
394
395	if (event & EV_READ) {
396		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
397			fatal("imsg_read error");
398		if (n == 0)	/* connection closed */
399			shut = 1;
400	}
401	if (event & EV_WRITE) {
402		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
403			fatal("msgbuf_write");
404		if (n == 0)	/* connection closed */
405			shut = 1;
406	}
407
408	for (;;) {
409		if ((n = imsg_get(ibuf, &imsg)) == -1)
410			fatal("lde_dispatch_parent: imsg_get error");
411		if (n == 0)
412			break;
413
414		switch (imsg.hdr.type) {
415		case IMSG_NETWORK_ADD:
416		case IMSG_NETWORK_DEL:
417			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
418				log_warnx("%s: wrong imsg len", __func__);
419				break;
420			}
421			memcpy(&kr, imsg.data, sizeof(kr));
422
423			switch (kr.af) {
424			case AF_INET:
425				fec.type = FEC_TYPE_IPV4;
426				fec.u.ipv4.prefix = kr.prefix.v4;
427				fec.u.ipv4.prefixlen = kr.prefixlen;
428				break;
429			case AF_INET6:
430				fec.type = FEC_TYPE_IPV6;
431				fec.u.ipv6.prefix = kr.prefix.v6;
432				fec.u.ipv6.prefixlen = kr.prefixlen;
433				break;
434			default:
435				fatalx("lde_dispatch_parent: unknown af");
436			}
437
438			switch (imsg.hdr.type) {
439			case IMSG_NETWORK_ADD:
440				lde_kernel_insert(&fec, kr.af, &kr.nexthop,
441				    kr.priority, kr.flags & F_CONNECTED, NULL);
442				break;
443			case IMSG_NETWORK_DEL:
444				lde_kernel_remove(&fec, kr.af, &kr.nexthop,
445				    kr.priority);
446				break;
447			}
448			break;
449		case IMSG_SOCKET_IPC:
450			if (iev_ldpe) {
451				log_warnx("%s: received unexpected imsg fd "
452				    "to ldpe", __func__);
453				break;
454			}
455			if ((fd = imsg_get_fd(&imsg)) == -1) {
456				log_warnx("%s: expected to receive imsg fd to "
457				    "ldpe but didn't receive any", __func__);
458				break;
459			}
460
461			if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
462				fatal(NULL);
463			imsg_init(&iev_ldpe->ibuf, fd);
464			iev_ldpe->handler = lde_dispatch_imsg;
465			iev_ldpe->events = EV_READ;
466			event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd,
467			    iev_ldpe->events, iev_ldpe->handler, iev_ldpe);
468			event_add(&iev_ldpe->ev, NULL);
469			break;
470		case IMSG_RECONF_CONF:
471			if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
472			    NULL)
473				fatal(NULL);
474			memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
475
476			LIST_INIT(&nconf->iface_list);
477			LIST_INIT(&nconf->tnbr_list);
478			LIST_INIT(&nconf->nbrp_list);
479			LIST_INIT(&nconf->l2vpn_list);
480			LIST_INIT(&nconf->auth_list);
481			break;
482		case IMSG_RECONF_IFACE:
483			if ((niface = malloc(sizeof(struct iface))) == NULL)
484				fatal(NULL);
485			memcpy(niface, imsg.data, sizeof(struct iface));
486
487			LIST_INIT(&niface->addr_list);
488			LIST_INIT(&niface->ipv4.adj_list);
489			LIST_INIT(&niface->ipv6.adj_list);
490			niface->ipv4.iface = niface;
491			niface->ipv6.iface = niface;
492
493			LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
494			break;
495		case IMSG_RECONF_TNBR:
496			if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
497				fatal(NULL);
498			memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
499
500			LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
501			break;
502		case IMSG_RECONF_NBRP:
503			if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
504				fatal(NULL);
505			memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
506
507			LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
508			break;
509		case IMSG_RECONF_L2VPN:
510			if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
511				fatal(NULL);
512			memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
513
514			LIST_INIT(&nl2vpn->if_list);
515			LIST_INIT(&nl2vpn->pw_list);
516
517			LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
518			break;
519		case IMSG_RECONF_L2VPN_IF:
520			if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
521				fatal(NULL);
522			memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
523
524			nlif->l2vpn = nl2vpn;
525			LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
526			break;
527		case IMSG_RECONF_L2VPN_PW:
528			if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
529				fatal(NULL);
530			memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
531
532			npw->l2vpn = nl2vpn;
533			LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
534			break;
535		case IMSG_RECONF_CONF_AUTH: {
536			struct ldp_auth *auth;
537
538			auth = malloc(sizeof(*auth));
539			if (auth == NULL)
540				fatal(NULL);
541
542			memcpy(auth, imsg.data, sizeof(*auth));
543
544			LIST_INSERT_HEAD(&nconf->auth_list, auth, entry);
545			break;
546		}
547		case IMSG_RECONF_END:
548			merge_config(ldeconf, nconf);
549			nconf = NULL;
550			break;
551		default:
552			log_debug("%s: unexpected imsg %d", __func__,
553			    imsg.hdr.type);
554			break;
555		}
556		imsg_free(&imsg);
557	}
558	if (!shut)
559		imsg_event_add(iev);
560	else {
561		/* this pipe is dead, so remove the event handler */
562		event_del(&iev->ev);
563		event_loopexit(NULL);
564	}
565}
566
567uint32_t
568lde_assign_label(void)
569{
570	static uint32_t label = MPLS_LABEL_RESERVED_MAX;
571
572	/* XXX some checks needed */
573	label++;
574	return (label);
575}
576
577void
578lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
579{
580	struct kroute	kr;
581	struct kpw	kpw;
582	struct l2vpn_pw	*pw;
583
584	switch (fn->fec.type) {
585	case FEC_TYPE_IPV4:
586		memset(&kr, 0, sizeof(kr));
587		kr.af = AF_INET;
588		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
589		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
590		kr.nexthop.v4 = fnh->nexthop.v4;
591		kr.local_label = fn->local_label;
592		kr.remote_label = fnh->remote_label;
593		kr.priority = fnh->priority;
594
595		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
596		    sizeof(kr));
597
598		if (fn->fec.u.ipv4.prefixlen == 32)
599			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
600			    &fn->fec.u.ipv4.prefix);
601		break;
602	case FEC_TYPE_IPV6:
603		memset(&kr, 0, sizeof(kr));
604		kr.af = AF_INET6;
605		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
606		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
607		kr.nexthop.v6 = fnh->nexthop.v6;
608		kr.local_label = fn->local_label;
609		kr.remote_label = fnh->remote_label;
610		kr.priority = fnh->priority;
611
612		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
613		    sizeof(kr));
614
615		if (fn->fec.u.ipv6.prefixlen == 128)
616			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
617			    &fn->fec.u.ipv6.prefix);
618		break;
619	case FEC_TYPE_PWID:
620		if (fn->local_label == NO_LABEL ||
621		    fnh->remote_label == NO_LABEL)
622			return;
623
624		pw = (struct l2vpn_pw *) fn->data;
625		pw->flags |= F_PW_STATUS_UP;
626
627		memset(&kpw, 0, sizeof(kpw));
628		kpw.ifindex = pw->ifindex;
629		kpw.pw_type = fn->fec.u.pwid.type;
630		kpw.af = pw->af;
631		kpw.nexthop = pw->addr;
632		kpw.local_label = fn->local_label;
633		kpw.remote_label = fnh->remote_label;
634		kpw.flags = pw->flags;
635
636		lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
637		    sizeof(kpw));
638		break;
639	}
640}
641
642void
643lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
644{
645	struct kroute	 kr;
646	struct kpw	 kpw;
647	struct l2vpn_pw	*pw;
648
649	switch (fn->fec.type) {
650	case FEC_TYPE_IPV4:
651		memset(&kr, 0, sizeof(kr));
652		kr.af = AF_INET;
653		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
654		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
655		kr.nexthop.v4 = fnh->nexthop.v4;
656		kr.local_label = fn->local_label;
657		kr.remote_label = fnh->remote_label;
658		kr.priority = fnh->priority;
659
660		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
661		    sizeof(kr));
662
663		if (fn->fec.u.ipv4.prefixlen == 32)
664			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
665			    &fn->fec.u.ipv4.prefix);
666		break;
667	case FEC_TYPE_IPV6:
668		memset(&kr, 0, sizeof(kr));
669		kr.af = AF_INET6;
670		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
671		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
672		kr.nexthop.v6 = fnh->nexthop.v6;
673		kr.local_label = fn->local_label;
674		kr.remote_label = fnh->remote_label;
675		kr.priority = fnh->priority;
676
677		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
678		    sizeof(kr));
679
680		if (fn->fec.u.ipv6.prefixlen == 128)
681			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
682			    &fn->fec.u.ipv6.prefix);
683		break;
684	case FEC_TYPE_PWID:
685		pw = (struct l2vpn_pw *) fn->data;
686		if (!(pw->flags & F_PW_STATUS_UP))
687			return;
688		pw->flags &= ~F_PW_STATUS_UP;
689
690		memset(&kpw, 0, sizeof(kpw));
691		kpw.ifindex = pw->ifindex;
692		kpw.pw_type = fn->fec.u.pwid.type;
693		kpw.af = pw->af;
694		kpw.nexthop = pw->addr;
695		kpw.local_label = fn->local_label;
696		kpw.remote_label = fnh->remote_label;
697		kpw.flags = pw->flags;
698
699		lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
700		    sizeof(kpw));
701		break;
702	}
703}
704
705void
706lde_fec2map(struct fec *fec, struct map *map)
707{
708	memset(map, 0, sizeof(*map));
709
710	switch (fec->type) {
711	case FEC_TYPE_IPV4:
712		map->type = MAP_TYPE_PREFIX;
713		map->fec.prefix.af = AF_INET;
714		map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
715		map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
716		break;
717	case FEC_TYPE_IPV6:
718		map->type = MAP_TYPE_PREFIX;
719		map->fec.prefix.af = AF_INET6;
720		map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
721		map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
722		break;
723	case FEC_TYPE_PWID:
724		map->type = MAP_TYPE_PWID;
725		map->fec.pwid.type = fec->u.pwid.type;
726		map->fec.pwid.group_id = 0;
727		map->flags |= F_MAP_PW_ID;
728		map->fec.pwid.pwid = fec->u.pwid.pwid;
729		break;
730	}
731}
732
733void
734lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
735{
736	memset(fec, 0, sizeof(*fec));
737
738	switch (map->type) {
739	case MAP_TYPE_PREFIX:
740		switch (map->fec.prefix.af) {
741		case AF_INET:
742			fec->type = FEC_TYPE_IPV4;
743			fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
744			fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
745			break;
746		case AF_INET6:
747			fec->type = FEC_TYPE_IPV6;
748			fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
749			fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
750			break;
751		default:
752			fatalx("lde_map2fec: unknown af");
753			break;
754		}
755		break;
756	case MAP_TYPE_PWID:
757		fec->type = FEC_TYPE_PWID;
758		fec->u.pwid.type = map->fec.pwid.type;
759		fec->u.pwid.pwid = map->fec.pwid.pwid;
760		fec->u.pwid.lsr_id = lsr_id;
761		break;
762	}
763}
764
765void
766lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
767{
768	struct lde_req	*lre;
769	struct lde_map	*me;
770	struct map	 map;
771	struct l2vpn_pw	*pw;
772
773	/*
774	 * This function skips SL.1 - 3 and SL.9 - 14 because the label
775	 * allocation is done way earlier (because of the merging nature of
776	 * ldpd).
777	 */
778
779	lde_fec2map(&fn->fec, &map);
780	switch (fn->fec.type) {
781	case FEC_TYPE_IPV4:
782		if (!ln->v4_enabled)
783			return;
784		break;
785	case FEC_TYPE_IPV6:
786		if (!ln->v6_enabled)
787			return;
788		break;
789	case FEC_TYPE_PWID:
790		pw = (struct l2vpn_pw *) fn->data;
791		if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
792			/* not the remote end of the pseudowire */
793			return;
794
795		map.flags |= F_MAP_PW_IFMTU;
796		map.fec.pwid.ifmtu = pw->l2vpn->mtu;
797		if (pw->flags & F_PW_CWORD)
798			map.flags |= F_MAP_PW_CWORD;
799		if (pw->flags & F_PW_STATUSTLV) {
800			map.flags |= F_MAP_PW_STATUS;
801			/* VPLS are always up */
802			map.pw_status = PW_FORWARDING;
803		}
804		break;
805	}
806	map.label = fn->local_label;
807
808	/* SL.6: is there a pending request for this mapping? */
809	lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
810	if (lre) {
811		/* set label request msg id in the mapping response. */
812		map.requestid = lre->msg_id;
813		map.flags = F_MAP_REQ_ID;
814
815		/* SL.7: delete record of pending request */
816		lde_req_del(ln, lre, 0);
817	}
818
819	/* SL.4: send label mapping */
820	lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
821	    &map, sizeof(map));
822	if (single)
823		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
824		    NULL, 0);
825
826	/* SL.5: record sent label mapping */
827	me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
828	if (me == NULL)
829		me = lde_map_add(ln, fn, 1);
830	me->map = map;
831}
832
833void
834lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn,
835    struct map *wcard, struct status_tlv *st)
836{
837	struct lde_wdraw	*lw;
838	struct map		 map;
839	struct fec		*f;
840	struct l2vpn_pw		*pw;
841
842	if (fn) {
843		lde_fec2map(&fn->fec, &map);
844		switch (fn->fec.type) {
845		case FEC_TYPE_IPV4:
846			if (!ln->v4_enabled)
847				return;
848			break;
849		case FEC_TYPE_IPV6:
850			if (!ln->v6_enabled)
851				return;
852			break;
853		case FEC_TYPE_PWID:
854			pw = (struct l2vpn_pw *) fn->data;
855			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
856				/* not the remote end of the pseudowire */
857				return;
858
859			if (pw->flags & F_PW_CWORD)
860				map.flags |= F_MAP_PW_CWORD;
861			break;
862		}
863		map.label = fn->local_label;
864	} else
865		memcpy(&map, wcard, sizeof(map));
866
867	if (st) {
868		map.st.status_code = st->status_code;
869		map.st.msg_id = st->msg_id;
870		map.st.msg_type = st->msg_type;
871		map.flags |= F_MAP_STATUS;
872	}
873
874	/* SWd.1: send label withdraw. */
875	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
876 	    &map, sizeof(map));
877	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
878
879	/* SWd.2: record label withdraw. */
880	if (fn) {
881		lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
882		if (lw == NULL)
883			lw = lde_wdraw_add(ln, fn);
884		lw->label = map.label;
885	} else {
886		struct lde_map *me;
887
888		RB_FOREACH(f, fec_tree, &ft) {
889			fn = (struct fec_node *)f;
890			me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
891			if (lde_wildcard_apply(wcard, &fn->fec, me) == 0)
892				continue;
893
894			lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
895			    &fn->fec);
896			if (lw == NULL)
897				lw = lde_wdraw_add(ln, fn);
898			lw->label = map.label;
899		}
900	}
901}
902
903void
904lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label)
905{
906	struct map	 wcard;
907
908	memset(&wcard, 0, sizeof(wcard));
909	wcard.type = MAP_TYPE_WILDCARD;
910	wcard.label = label;
911	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
912}
913
914void
915lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af,
916    uint32_t label)
917{
918	struct map	 wcard;
919
920	memset(&wcard, 0, sizeof(wcard));
921	wcard.type = MAP_TYPE_TYPED_WCARD;
922	wcard.fec.twcard.type = MAP_TYPE_PREFIX;
923	wcard.fec.twcard.u.prefix_af = af;
924	wcard.label = label;
925	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
926}
927
928void
929lde_send_labelwithdraw_twcard_pwid(struct lde_nbr *ln, uint16_t pw_type,
930    uint32_t label)
931{
932	struct map	 wcard;
933
934	memset(&wcard, 0, sizeof(wcard));
935	wcard.type = MAP_TYPE_TYPED_WCARD;
936	wcard.fec.twcard.type = MAP_TYPE_PWID;
937	wcard.fec.twcard.u.pw_type = pw_type;
938	wcard.label = label;
939	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
940}
941
942void
943lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type,
944    uint32_t group_id)
945{
946	struct map	 wcard;
947
948	memset(&wcard, 0, sizeof(wcard));
949	wcard.type = MAP_TYPE_PWID;
950	wcard.fec.pwid.type = pw_type;
951	wcard.fec.pwid.group_id = group_id;
952	/* we can not append a Label TLV when using PWid group wildcards. */
953	wcard.label = NO_LABEL;
954	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
955}
956
957void
958lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
959    struct map *wcard, uint32_t label)
960{
961	struct map		 map;
962	struct l2vpn_pw		*pw;
963
964	if (fn) {
965		lde_fec2map(&fn->fec, &map);
966		switch (fn->fec.type) {
967		case FEC_TYPE_IPV4:
968			if (!ln->v4_enabled)
969				return;
970			break;
971		case FEC_TYPE_IPV6:
972			if (!ln->v6_enabled)
973				return;
974			break;
975		case FEC_TYPE_PWID:
976			pw = (struct l2vpn_pw *) fn->data;
977			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
978				/* not the remote end of the pseudowire */
979				return;
980
981			if (pw->flags & F_PW_CWORD)
982				map.flags |= F_MAP_PW_CWORD;
983			break;
984		}
985	} else
986		memcpy(&map, wcard, sizeof(map));
987	map.label = label;
988
989	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
990	    &map, sizeof(map));
991	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
992}
993
994void
995lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
996    uint16_t msg_type)
997{
998	struct notify_msg nm;
999
1000	memset(&nm, 0, sizeof(nm));
1001	nm.status_code = status_code;
1002	/* 'msg_id' and 'msg_type' should be in network byte order */
1003	nm.msg_id = msg_id;
1004	nm.msg_type = msg_type;
1005
1006	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1007	    &nm, sizeof(nm));
1008}
1009
1010void
1011lde_send_notification_eol_prefix(struct lde_nbr *ln, int af)
1012{
1013	struct notify_msg nm;
1014
1015	memset(&nm, 0, sizeof(nm));
1016	nm.status_code = S_ENDOFLIB;
1017	nm.fec.type = MAP_TYPE_TYPED_WCARD;
1018	nm.fec.fec.twcard.type = MAP_TYPE_PREFIX;
1019	nm.fec.fec.twcard.u.prefix_af = af;
1020	nm.flags |= F_NOTIF_FEC;
1021
1022	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1023	    &nm, sizeof(nm));
1024}
1025
1026void
1027lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
1028{
1029	struct notify_msg nm;
1030
1031	memset(&nm, 0, sizeof(nm));
1032	nm.status_code = S_ENDOFLIB;
1033	nm.fec.type = MAP_TYPE_TYPED_WCARD;
1034	nm.fec.fec.twcard.type = MAP_TYPE_PWID;
1035	nm.fec.fec.twcard.u.pw_type = pw_type;
1036	nm.flags |= F_NOTIF_FEC;
1037
1038	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1039	    &nm, sizeof(nm));
1040}
1041
1042static __inline int
1043lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
1044{
1045	return (a->peerid - b->peerid);
1046}
1047
1048static struct lde_nbr *
1049lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
1050{
1051	struct lde_nbr	*ln;
1052
1053	if ((ln = calloc(1, sizeof(*ln))) == NULL)
1054		fatal(__func__);
1055
1056	ln->id = new->id;
1057	ln->v4_enabled = new->v4_enabled;
1058	ln->v6_enabled = new->v6_enabled;
1059	ln->flags = new->flags;
1060	ln->peerid = peerid;
1061	fec_init(&ln->recv_map);
1062	fec_init(&ln->sent_map);
1063	fec_init(&ln->recv_req);
1064	fec_init(&ln->sent_req);
1065	fec_init(&ln->sent_wdraw);
1066
1067	TAILQ_INIT(&ln->addr_list);
1068
1069	if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
1070		fatalx("lde_nbr_new: RB_INSERT failed");
1071
1072	return (ln);
1073}
1074
1075static void
1076lde_nbr_del(struct lde_nbr *ln)
1077{
1078	struct fec		*f;
1079	struct fec_node		*fn;
1080	struct fec_nh		*fnh;
1081	struct l2vpn_pw		*pw;
1082
1083	if (ln == NULL)
1084		return;
1085
1086	/* uninstall received mappings */
1087	RB_FOREACH(f, fec_tree, &ft) {
1088		fn = (struct fec_node *)f;
1089
1090		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1091			switch (f->type) {
1092			case FEC_TYPE_IPV4:
1093			case FEC_TYPE_IPV6:
1094				if (!lde_address_find(ln, fnh->af,
1095				    &fnh->nexthop))
1096					continue;
1097				break;
1098			case FEC_TYPE_PWID:
1099				if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1100					continue;
1101				pw = (struct l2vpn_pw *) fn->data;
1102				if (pw)
1103					l2vpn_pw_reset(pw);
1104				break;
1105			default:
1106				break;
1107			}
1108
1109			lde_send_delete_klabel(fn, fnh);
1110			fnh->remote_label = NO_LABEL;
1111		}
1112	}
1113
1114	lde_address_list_free(ln);
1115
1116	fec_clear(&ln->recv_map, lde_map_free);
1117	fec_clear(&ln->sent_map, lde_map_free);
1118	fec_clear(&ln->recv_req, free);
1119	fec_clear(&ln->sent_req, free);
1120	fec_clear(&ln->sent_wdraw, free);
1121
1122	RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1123
1124	free(ln);
1125}
1126
1127static struct lde_nbr *
1128lde_nbr_find(uint32_t peerid)
1129{
1130	struct lde_nbr		 ln;
1131
1132	ln.peerid = peerid;
1133
1134	return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1135}
1136
1137struct lde_nbr *
1138lde_nbr_find_by_lsrid(struct in_addr addr)
1139{
1140	struct lde_nbr		*ln;
1141
1142	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1143		if (ln->id.s_addr == addr.s_addr)
1144			return (ln);
1145
1146	return (NULL);
1147}
1148
1149struct lde_nbr *
1150lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1151{
1152	struct lde_nbr		*ln;
1153
1154	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1155		if (lde_address_find(ln, af, addr) != NULL)
1156			return (ln);
1157
1158	return (NULL);
1159}
1160
1161static void
1162lde_nbr_clear(void)
1163{
1164	struct lde_nbr	*ln;
1165
1166	while ((ln = RB_ROOT(&lde_nbrs)) != NULL)
1167		lde_nbr_del(ln);
1168}
1169
1170static void
1171lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1172{
1173	struct fec		*fec;
1174	struct fec_node		*fn;
1175	struct fec_nh		*fnh;
1176	struct lde_map		*me;
1177
1178	RB_FOREACH(fec, fec_tree, &ln->recv_map) {
1179		fn = (struct fec_node *)fec_find(&ft, fec);
1180		switch (fec->type) {
1181		case FEC_TYPE_IPV4:
1182			if (lde_addr->af != AF_INET)
1183				continue;
1184			break;
1185		case FEC_TYPE_IPV6:
1186			if (lde_addr->af != AF_INET6)
1187				continue;
1188			break;
1189		default:
1190			continue;
1191		}
1192
1193		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1194			if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1195			    &lde_addr->addr))
1196				continue;
1197
1198			if (removed) {
1199				lde_send_delete_klabel(fn, fnh);
1200				fnh->remote_label = NO_LABEL;
1201			} else {
1202				me = (struct lde_map *)fec;
1203				fnh->remote_label = me->map.label;
1204				lde_send_change_klabel(fn, fnh);
1205			}
1206			break;
1207		}
1208	}
1209}
1210
1211struct lde_map *
1212lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1213{
1214	struct lde_map  *me;
1215
1216	me = calloc(1, sizeof(*me));
1217	if (me == NULL)
1218		fatal(__func__);
1219
1220	me->fec = fn->fec;
1221	me->nexthop = ln;
1222
1223	if (sent) {
1224		LIST_INSERT_HEAD(&fn->upstream, me, entry);
1225		if (fec_insert(&ln->sent_map, &me->fec))
1226			log_warnx("failed to add %s to sent map",
1227			    log_fec(&me->fec));
1228			/* XXX on failure more cleanup is needed */
1229	} else {
1230		LIST_INSERT_HEAD(&fn->downstream, me, entry);
1231		if (fec_insert(&ln->recv_map, &me->fec))
1232			log_warnx("failed to add %s to recv map",
1233			    log_fec(&me->fec));
1234	}
1235
1236	return (me);
1237}
1238
1239void
1240lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1241{
1242	if (sent)
1243		fec_remove(&ln->sent_map, &me->fec);
1244	else
1245		fec_remove(&ln->recv_map, &me->fec);
1246
1247	lde_map_free(me);
1248}
1249
1250static void
1251lde_map_free(void *ptr)
1252{
1253	struct lde_map	*map = ptr;
1254
1255	LIST_REMOVE(map, entry);
1256	free(map);
1257}
1258
1259struct lde_req *
1260lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1261{
1262	struct fec_tree	*t;
1263	struct lde_req	*lre;
1264
1265	t = sent ? &ln->sent_req : &ln->recv_req;
1266
1267	lre = calloc(1, sizeof(*lre));
1268	if (lre != NULL) {
1269		lre->fec = *fec;
1270
1271		if (fec_insert(t, &lre->fec)) {
1272			log_warnx("failed to add %s to %s req",
1273			    log_fec(&lre->fec), sent ? "sent" : "recv");
1274			free(lre);
1275			return (NULL);
1276		}
1277	}
1278
1279	return (lre);
1280}
1281
1282void
1283lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1284{
1285	if (sent)
1286		fec_remove(&ln->sent_req, &lre->fec);
1287	else
1288		fec_remove(&ln->recv_req, &lre->fec);
1289
1290	free(lre);
1291}
1292
1293struct lde_wdraw *
1294lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1295{
1296	struct lde_wdraw  *lw;
1297
1298	lw = calloc(1, sizeof(*lw));
1299	if (lw == NULL)
1300		fatal(__func__);
1301
1302	lw->fec = fn->fec;
1303
1304	if (fec_insert(&ln->sent_wdraw, &lw->fec))
1305		log_warnx("failed to add %s to sent wdraw",
1306		    log_fec(&lw->fec));
1307
1308	return (lw);
1309}
1310
1311void
1312lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1313{
1314	fec_remove(&ln->sent_wdraw, &lw->fec);
1315	free(lw);
1316}
1317
1318void
1319lde_change_egress_label(int af, int was_implicit)
1320{
1321	struct lde_nbr	*ln;
1322	struct fec	*f;
1323	struct fec_node	*fn;
1324
1325	RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1326		/* explicit withdraw */
1327		if (was_implicit)
1328			lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL);
1329		else {
1330			if (ln->v4_enabled)
1331				lde_send_labelwithdraw_wcard(ln,
1332				    MPLS_LABEL_IPV4NULL);
1333			if (ln->v6_enabled)
1334				lde_send_labelwithdraw_wcard(ln,
1335				    MPLS_LABEL_IPV6NULL);
1336		}
1337
1338		/* advertise new label of connected prefixes */
1339		RB_FOREACH(f, fec_tree, &ft) {
1340			fn = (struct fec_node *)f;
1341			if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1342				continue;
1343
1344			switch (af) {
1345			case AF_INET:
1346				if (fn->fec.type != FEC_TYPE_IPV4)
1347					continue;
1348				break;
1349			case AF_INET6:
1350				if (fn->fec.type != FEC_TYPE_IPV6)
1351					continue;
1352				break;
1353			default:
1354				fatalx("lde_change_egress_label: unknown af");
1355			}
1356
1357			fn->local_label = egress_label(fn->fec.type);
1358			lde_send_labelmapping(ln, fn, 0);
1359		}
1360
1361		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1362		    NULL, 0);
1363	}
1364}
1365
1366static int
1367lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
1368{
1369	struct lde_addr		*new;
1370
1371	if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
1372		return (-1);
1373
1374	if ((new = calloc(1, sizeof(*new))) == NULL)
1375		fatal(__func__);
1376
1377	new->af = lde_addr->af;
1378	new->addr = lde_addr->addr;
1379	TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
1380
1381	/* reevaluate the previously received mappings from this neighbor */
1382	lde_nbr_addr_update(ln, lde_addr, 0);
1383
1384	return (0);
1385}
1386
1387static int
1388lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
1389{
1390	lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
1391	if (lde_addr == NULL)
1392		return (-1);
1393
1394	/* reevaluate the previously received mappings from this neighbor */
1395	lde_nbr_addr_update(ln, lde_addr, 1);
1396
1397	TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1398	free(lde_addr);
1399
1400	return (0);
1401}
1402
1403struct lde_addr *
1404lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
1405{
1406	struct lde_addr		*lde_addr;
1407
1408	TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
1409		if (lde_addr->af == af &&
1410		    ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
1411			return (lde_addr);
1412
1413	return (NULL);
1414}
1415
1416static void
1417lde_address_list_free(struct lde_nbr *ln)
1418{
1419	struct lde_addr		*lde_addr;
1420
1421	while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
1422		TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1423		free(lde_addr);
1424	}
1425}
1426