xref: /openbsd-src/usr.sbin/ldpd/lde.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: lde.c,v 1.67 2016/09/02 17:10:34 renato 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 
42 static void		 lde_sig_handler(int sig, short, void *);
43 static __dead void	 lde_shutdown(void);
44 static int		 lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
45 static void		 lde_dispatch_imsg(int, short, void *);
46 static void		 lde_dispatch_parent(int, short, void *);
47 static __inline		 int lde_nbr_compare(struct lde_nbr *,
48 			    struct lde_nbr *);
49 static struct lde_nbr	*lde_nbr_new(uint32_t, struct lde_nbr *);
50 static void		 lde_nbr_del(struct lde_nbr *);
51 static struct lde_nbr	*lde_nbr_find(uint32_t);
52 static void		 lde_nbr_clear(void);
53 static void		 lde_nbr_addr_update(struct lde_nbr *,
54 			    struct lde_addr *, int);
55 static void		 lde_map_free(void *);
56 static int		 lde_address_add(struct lde_nbr *, struct lde_addr *);
57 static int		 lde_address_del(struct lde_nbr *, struct lde_addr *);
58 static void		 lde_address_list_free(struct lde_nbr *);
59 
60 RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
61 
62 struct ldpd_conf	*ldeconf;
63 struct nbr_tree		 lde_nbrs = RB_INITIALIZER(&lde_nbrs);
64 
65 static struct imsgev	*iev_ldpe;
66 static struct imsgev	*iev_main;
67 
68 /* ARGSUSED */
69 static void
70 lde_sig_handler(int sig, short event, void *arg)
71 {
72 	/*
73 	 * signal handler rules don't apply, libevent decouples for us
74 	 */
75 
76 	switch (sig) {
77 	case SIGINT:
78 	case SIGTERM:
79 		lde_shutdown();
80 		/* NOTREACHED */
81 	default:
82 		fatalx("unexpected signal");
83 	}
84 }
85 
86 /* label decision engine */
87 void
88 lde(int debug, int verbose)
89 {
90 	struct event		 ev_sigint, ev_sigterm;
91 	struct timeval		 now;
92 	struct passwd		*pw;
93 
94 	ldeconf = config_new_empty();
95 
96 	log_init(debug);
97 	log_verbose(verbose);
98 
99 	setproctitle("label decision engine");
100 	ldpd_process = PROC_LDE_ENGINE;
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 
150 static __dead void
151 lde_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 */
173 static int
174 lde_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 
179 int
180 lde_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 
187 /* ARGSUSED */
188 static void
189 lde_dispatch_imsg(int fd, short event, void *bula)
190 {
191 	struct imsgev		*iev = bula;
192 	struct imsgbuf		*ibuf = &iev->ibuf;
193 	struct imsg		 imsg;
194 	struct lde_nbr		*ln;
195 	struct map		 map;
196 	struct lde_addr		 lde_addr;
197 	struct notify_msg	 nm;
198 	ssize_t			 n;
199 	int			 shut = 0, verbose;
200 
201 	if (event & EV_READ) {
202 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
203 			fatal("imsg_read error");
204 		if (n == 0)	/* connection closed */
205 			shut = 1;
206 	}
207 	if (event & EV_WRITE) {
208 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
209 			fatal("msgbuf_write");
210 		if (n == 0)	/* connection closed */
211 			shut = 1;
212 	}
213 
214 	for (;;) {
215 		if ((n = imsg_get(ibuf, &imsg)) == -1)
216 			fatal("lde_dispatch_imsg: imsg_get error");
217 		if (n == 0)
218 			break;
219 
220 		switch (imsg.hdr.type) {
221 		case IMSG_LABEL_MAPPING_FULL:
222 			ln = lde_nbr_find(imsg.hdr.peerid);
223 			if (ln == NULL) {
224 				log_debug("%s: cannot find lde neighbor",
225 				    __func__);
226 				break;
227 			}
228 
229 			fec_snap(ln);
230 			break;
231 		case IMSG_LABEL_MAPPING:
232 		case IMSG_LABEL_REQUEST:
233 		case IMSG_LABEL_RELEASE:
234 		case IMSG_LABEL_WITHDRAW:
235 		case IMSG_LABEL_ABORT:
236 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map))
237 				fatalx("lde_dispatch_imsg: wrong imsg len");
238 			memcpy(&map, imsg.data, sizeof(map));
239 
240 			ln = lde_nbr_find(imsg.hdr.peerid);
241 			if (ln == NULL) {
242 				log_debug("%s: cannot find lde neighbor",
243 				    __func__);
244 				break;
245 			}
246 
247 			switch (imsg.hdr.type) {
248 			case IMSG_LABEL_MAPPING:
249 				lde_check_mapping(&map, ln);
250 				break;
251 			case IMSG_LABEL_REQUEST:
252 				lde_check_request(&map, ln);
253 				break;
254 			case IMSG_LABEL_RELEASE:
255 				if (map.type == MAP_TYPE_WILDCARD)
256 					lde_check_release_wcard(&map, ln);
257 				else
258 					lde_check_release(&map, ln);
259 				break;
260 			case IMSG_LABEL_WITHDRAW:
261 				if (map.type == MAP_TYPE_WILDCARD)
262 					lde_check_withdraw_wcard(&map, ln);
263 				else
264 					lde_check_withdraw(&map, ln);
265 				break;
266 			case IMSG_LABEL_ABORT:
267 				/* not necessary */
268 				break;
269 			}
270 			break;
271 		case IMSG_ADDRESS_ADD:
272 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
273 				fatalx("lde_dispatch_imsg: wrong imsg len");
274 			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
275 
276 			ln = lde_nbr_find(imsg.hdr.peerid);
277 			if (ln == NULL) {
278 				log_debug("%s: cannot find lde neighbor",
279 				    __func__);
280 				break;
281 			}
282 			if (lde_address_add(ln, &lde_addr) < 0) {
283 				log_debug("%s: cannot add address %s, it "
284 				    "already exists", __func__,
285 				    log_addr(lde_addr.af, &lde_addr.addr));
286 			}
287 			break;
288 		case IMSG_ADDRESS_DEL:
289 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
290 				fatalx("lde_dispatch_imsg: wrong imsg len");
291 			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
292 
293 			ln = lde_nbr_find(imsg.hdr.peerid);
294 			if (ln == NULL) {
295 				log_debug("%s: cannot find lde neighbor",
296 				    __func__);
297 				break;
298 			}
299 			if (lde_address_del(ln, &lde_addr) < 0) {
300 				log_debug("%s: cannot delete address %s, it "
301 				    "does not exist", __func__,
302 				    log_addr(lde_addr.af, &lde_addr.addr));
303 			}
304 			break;
305 		case IMSG_NOTIFICATION:
306 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm))
307 				fatalx("lde_dispatch_imsg: wrong imsg len");
308 			memcpy(&nm, imsg.data, sizeof(nm));
309 
310 			ln = lde_nbr_find(imsg.hdr.peerid);
311 			if (ln == NULL) {
312 				log_debug("%s: cannot find lde neighbor",
313 				    __func__);
314 				break;
315 			}
316 
317 			switch (nm.status_code) {
318 			case S_PW_STATUS:
319 				l2vpn_recv_pw_status(ln, &nm);
320 				break;
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 
377 /* ARGSUSED */
378 static void
379 lde_dispatch_parent(int fd, short event, void *bula)
380 {
381 	static struct ldpd_conf	*nconf;
382 	struct iface		*niface;
383 	struct tnbr		*ntnbr;
384 	struct nbr_params	*nnbrp;
385 	static struct l2vpn	*nl2vpn;
386 	struct l2vpn_if		*nlif;
387 	struct l2vpn_pw		*npw;
388 	struct imsg		 imsg;
389 	struct kroute		 kr;
390 	struct imsgev		*iev = bula;
391 	struct imsgbuf		*ibuf = &iev->ibuf;
392 	ssize_t			 n;
393 	int			 shut = 0;
394 	struct fec		 fec;
395 
396 	if (event & EV_READ) {
397 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
398 			fatal("imsg_read error");
399 		if (n == 0)	/* connection closed */
400 			shut = 1;
401 	}
402 	if (event & EV_WRITE) {
403 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
404 			fatal("msgbuf_write");
405 		if (n == 0)	/* connection closed */
406 			shut = 1;
407 	}
408 
409 	for (;;) {
410 		if ((n = imsg_get(ibuf, &imsg)) == -1)
411 			fatal("lde_dispatch_parent: imsg_get error");
412 		if (n == 0)
413 			break;
414 
415 		switch (imsg.hdr.type) {
416 		case IMSG_NETWORK_ADD:
417 		case IMSG_NETWORK_DEL:
418 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
419 				log_warnx("%s: wrong imsg len", __func__);
420 				break;
421 			}
422 			memcpy(&kr, imsg.data, sizeof(kr));
423 
424 			switch (kr.af) {
425 			case AF_INET:
426 				fec.type = FEC_TYPE_IPV4;
427 				fec.u.ipv4.prefix = kr.prefix.v4;
428 				fec.u.ipv4.prefixlen = kr.prefixlen;
429 				break;
430 			case AF_INET6:
431 				fec.type = FEC_TYPE_IPV6;
432 				fec.u.ipv6.prefix = kr.prefix.v6;
433 				fec.u.ipv6.prefixlen = kr.prefixlen;
434 				break;
435 			default:
436 				fatalx("lde_dispatch_parent: unknown af");
437 			}
438 
439 			switch (imsg.hdr.type) {
440 			case IMSG_NETWORK_ADD:
441 				lde_kernel_insert(&fec, kr.af, &kr.nexthop,
442 				    kr.priority, kr.flags & F_CONNECTED, NULL);
443 				break;
444 			case IMSG_NETWORK_DEL:
445 				lde_kernel_remove(&fec, kr.af, &kr.nexthop,
446 				    kr.priority);
447 				break;
448 			}
449 			break;
450 		case IMSG_SOCKET_IPC:
451 			if (iev_ldpe) {
452 				log_warnx("%s: received unexpected imsg fd "
453 				    "to ldpe", __func__);
454 				break;
455 			}
456 			if ((fd = imsg.fd) == -1) {
457 				log_warnx("%s: expected to receive imsg fd to "
458 				    "ldpe but didn't receive any", __func__);
459 				break;
460 			}
461 
462 			if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
463 				fatal(NULL);
464 			imsg_init(&iev_ldpe->ibuf, fd);
465 			iev_ldpe->handler = lde_dispatch_imsg;
466 			iev_ldpe->events = EV_READ;
467 			event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd,
468 			    iev_ldpe->events, iev_ldpe->handler, iev_ldpe);
469 			event_add(&iev_ldpe->ev, NULL);
470 			break;
471 		case IMSG_RECONF_CONF:
472 			if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
473 			    NULL)
474 				fatal(NULL);
475 			memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
476 
477 			LIST_INIT(&nconf->iface_list);
478 			LIST_INIT(&nconf->tnbr_list);
479 			LIST_INIT(&nconf->nbrp_list);
480 			LIST_INIT(&nconf->l2vpn_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_END:
536 			merge_config(ldeconf, nconf);
537 			nconf = NULL;
538 			break;
539 		default:
540 			log_debug("%s: unexpected imsg %d", __func__,
541 			    imsg.hdr.type);
542 			break;
543 		}
544 		imsg_free(&imsg);
545 	}
546 	if (!shut)
547 		imsg_event_add(iev);
548 	else {
549 		/* this pipe is dead, so remove the event handler */
550 		event_del(&iev->ev);
551 		event_loopexit(NULL);
552 	}
553 }
554 
555 uint32_t
556 lde_assign_label(void)
557 {
558 	static uint32_t label = MPLS_LABEL_RESERVED_MAX;
559 
560 	/* XXX some checks needed */
561 	label++;
562 	return (label);
563 }
564 
565 void
566 lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
567 {
568 	struct kroute	kr;
569 	struct kpw	kpw;
570 	struct l2vpn_pw	*pw;
571 
572 	switch (fn->fec.type) {
573 	case FEC_TYPE_IPV4:
574 		memset(&kr, 0, sizeof(kr));
575 		kr.af = AF_INET;
576 		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
577 		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
578 		kr.nexthop.v4 = fnh->nexthop.v4;
579 		kr.local_label = fn->local_label;
580 		kr.remote_label = fnh->remote_label;
581 		kr.priority = fnh->priority;
582 
583 		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
584 		    sizeof(kr));
585 
586 		if (fn->fec.u.ipv4.prefixlen == 32)
587 			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
588 			    &fn->fec.u.ipv4.prefix);
589 		break;
590 	case FEC_TYPE_IPV6:
591 		memset(&kr, 0, sizeof(kr));
592 		kr.af = AF_INET6;
593 		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
594 		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
595 		kr.nexthop.v6 = fnh->nexthop.v6;
596 		kr.local_label = fn->local_label;
597 		kr.remote_label = fnh->remote_label;
598 		kr.priority = fnh->priority;
599 
600 		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
601 		    sizeof(kr));
602 
603 		if (fn->fec.u.ipv6.prefixlen == 128)
604 			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
605 			    &fn->fec.u.ipv6.prefix);
606 		break;
607 	case FEC_TYPE_PWID:
608 		if (fn->local_label == NO_LABEL ||
609 		    fnh->remote_label == NO_LABEL)
610 			return;
611 
612 		pw = (struct l2vpn_pw *) fn->data;
613 		pw->flags |= F_PW_STATUS_UP;
614 
615 		memset(&kpw, 0, sizeof(kpw));
616 		kpw.ifindex = pw->ifindex;
617 		kpw.pw_type = fn->fec.u.pwid.type;
618 		kpw.af = pw->af;
619 		kpw.nexthop = pw->addr;
620 		kpw.local_label = fn->local_label;
621 		kpw.remote_label = fnh->remote_label;
622 		kpw.flags = pw->flags;
623 
624 		lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
625 		    sizeof(kpw));
626 		break;
627 	}
628 }
629 
630 void
631 lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
632 {
633 	struct kroute	 kr;
634 	struct kpw	 kpw;
635 	struct l2vpn_pw	*pw;
636 
637 	switch (fn->fec.type) {
638 	case FEC_TYPE_IPV4:
639 		memset(&kr, 0, sizeof(kr));
640 		kr.af = AF_INET;
641 		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
642 		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
643 		kr.nexthop.v4 = fnh->nexthop.v4;
644 		kr.local_label = fn->local_label;
645 		kr.remote_label = fnh->remote_label;
646 		kr.priority = fnh->priority;
647 
648 		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
649 		    sizeof(kr));
650 
651 		if (fn->fec.u.ipv4.prefixlen == 32)
652 			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
653 			    &fn->fec.u.ipv4.prefix);
654 		break;
655 	case FEC_TYPE_IPV6:
656 		memset(&kr, 0, sizeof(kr));
657 		kr.af = AF_INET6;
658 		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
659 		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
660 		kr.nexthop.v6 = fnh->nexthop.v6;
661 		kr.local_label = fn->local_label;
662 		kr.remote_label = fnh->remote_label;
663 		kr.priority = fnh->priority;
664 
665 		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
666 		    sizeof(kr));
667 
668 		if (fn->fec.u.ipv6.prefixlen == 128)
669 			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
670 			    &fn->fec.u.ipv6.prefix);
671 		break;
672 	case FEC_TYPE_PWID:
673 		pw = (struct l2vpn_pw *) fn->data;
674 		if (!(pw->flags & F_PW_STATUS_UP))
675 			return;
676 		pw->flags &= ~F_PW_STATUS_UP;
677 
678 		memset(&kpw, 0, sizeof(kpw));
679 		kpw.ifindex = pw->ifindex;
680 		kpw.pw_type = fn->fec.u.pwid.type;
681 		kpw.af = pw->af;
682 		kpw.nexthop = pw->addr;
683 		kpw.local_label = fn->local_label;
684 		kpw.remote_label = fnh->remote_label;
685 		kpw.flags = pw->flags;
686 
687 		lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
688 		    sizeof(kpw));
689 		break;
690 	}
691 }
692 
693 void
694 lde_fec2map(struct fec *fec, struct map *map)
695 {
696 	memset(map, 0, sizeof(*map));
697 
698 	switch (fec->type) {
699 	case FEC_TYPE_IPV4:
700 		map->type = MAP_TYPE_PREFIX;
701 		map->fec.prefix.af = AF_INET;
702 		map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
703 		map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
704 		break;
705 	case FEC_TYPE_IPV6:
706 		map->type = MAP_TYPE_PREFIX;
707 		map->fec.prefix.af = AF_INET6;
708 		map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
709 		map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
710 		break;
711 	case FEC_TYPE_PWID:
712 		map->type = MAP_TYPE_PWID;
713 		map->fec.pwid.type = fec->u.pwid.type;
714 		map->fec.pwid.group_id = 0;
715 		map->flags |= F_MAP_PW_ID;
716 		map->fec.pwid.pwid = fec->u.pwid.pwid;
717 		break;
718 	}
719 }
720 
721 void
722 lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
723 {
724 	memset(fec, 0, sizeof(*fec));
725 
726 	switch (map->type) {
727 	case MAP_TYPE_PREFIX:
728 		switch (map->fec.prefix.af) {
729 		case AF_INET:
730 			fec->type = FEC_TYPE_IPV4;
731 			fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
732 			fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
733 			break;
734 		case AF_INET6:
735 			fec->type = FEC_TYPE_IPV6;
736 			fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
737 			fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
738 			break;
739 		default:
740 			fatalx("lde_map2fec: unknown af");
741 			break;
742 		}
743 		break;
744 	case MAP_TYPE_PWID:
745 		fec->type = FEC_TYPE_PWID;
746 		fec->u.pwid.type = map->fec.pwid.type;
747 		fec->u.pwid.pwid = map->fec.pwid.pwid;
748 		fec->u.pwid.lsr_id = lsr_id;
749 		break;
750 	}
751 }
752 
753 void
754 lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
755 {
756 	struct lde_req	*lre;
757 	struct lde_map	*me;
758 	struct map	 map;
759 	struct l2vpn_pw	*pw;
760 
761 	/*
762 	 * This function skips SL.1 - 3 and SL.9 - 14 because the label
763 	 * allocation is done way earlier (because of the merging nature of
764 	 * ldpd).
765 	 */
766 
767 	lde_fec2map(&fn->fec, &map);
768 	switch (fn->fec.type) {
769 	case FEC_TYPE_IPV4:
770 		if (!ln->v4_enabled)
771 			return;
772 		break;
773 	case FEC_TYPE_IPV6:
774 		if (!ln->v6_enabled)
775 			return;
776 		break;
777 	case FEC_TYPE_PWID:
778 		pw = (struct l2vpn_pw *) fn->data;
779 		if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
780 			/* not the remote end of the pseudowire */
781 			return;
782 
783 		map.flags |= F_MAP_PW_IFMTU;
784 		map.fec.pwid.ifmtu = pw->l2vpn->mtu;
785 		if (pw->flags & F_PW_CWORD)
786 			map.flags |= F_MAP_PW_CWORD;
787 		if (pw->flags & F_PW_STATUSTLV) {
788 			map.flags |= F_MAP_PW_STATUS;
789 			/* VPLS are always up */
790 			map.pw_status = PW_FORWARDING;
791 		}
792 		break;
793 	}
794 	map.label = fn->local_label;
795 
796 	/* SL.6: is there a pending request for this mapping? */
797 	lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
798 	if (lre) {
799 		/* set label request msg id in the mapping response. */
800 		map.requestid = lre->msg_id;
801 		map.flags = F_MAP_REQ_ID;
802 
803 		/* SL.7: delete record of pending request */
804 		lde_req_del(ln, lre, 0);
805 	}
806 
807 	/* SL.4: send label mapping */
808 	lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
809 	    &map, sizeof(map));
810 	if (single)
811 		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
812 		    NULL, 0);
813 
814 	/* SL.5: record sent label mapping */
815 	me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
816 	if (me == NULL)
817 		me = lde_map_add(ln, fn, 1);
818 	me->map = map;
819 }
820 
821 void
822 lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn, uint32_t label,
823     struct status_tlv *st)
824 {
825 	struct lde_wdraw	*lw;
826 	struct map		 map;
827 	struct fec		*f;
828 	struct l2vpn_pw		*pw;
829 
830 	if (fn) {
831 		lde_fec2map(&fn->fec, &map);
832 		switch (fn->fec.type) {
833 		case FEC_TYPE_IPV4:
834 			if (!ln->v4_enabled)
835 				return;
836 			break;
837 		case FEC_TYPE_IPV6:
838 			if (!ln->v6_enabled)
839 				return;
840 			break;
841 		case FEC_TYPE_PWID:
842 			pw = (struct l2vpn_pw *) fn->data;
843 			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
844 				/* not the remote end of the pseudowire */
845 				return;
846 
847 			if (pw->flags & F_PW_CWORD)
848 				map.flags |= F_MAP_PW_CWORD;
849 			break;
850 		}
851 		map.label = fn->local_label;
852 	} else {
853 		memset(&map, 0, sizeof(map));
854 		map.type = MAP_TYPE_WILDCARD;
855 		map.label = label;
856 	}
857 
858 	if (st) {
859 		map.st.status_code = st->status_code;
860 		map.st.msg_id = st->msg_id;
861 		map.st.msg_type = st->msg_type;
862 		map.flags |= F_MAP_STATUS;
863 	}
864 
865 	/* SWd.1: send label withdraw. */
866 	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
867  	    &map, sizeof(map));
868 	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
869 
870 	/* SWd.2: record label withdraw. */
871 	if (fn) {
872 		lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
873 		if (lw == NULL)
874 			lw = lde_wdraw_add(ln, fn);
875 		lw->label = map.label;
876 	} else {
877 		RB_FOREACH(f, fec_tree, &ft) {
878 			fn = (struct fec_node *)f;
879 
880 			lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
881 			    &fn->fec);
882 			if (lw == NULL)
883 				lw = lde_wdraw_add(ln, fn);
884 			lw->label = map.label;
885 		}
886 	}
887 }
888 
889 void
890 lde_send_labelwithdraw_all(struct fec_node *fn, uint32_t label)
891 {
892 	struct lde_nbr		*ln;
893 
894 	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
895 		lde_send_labelwithdraw(ln, fn, label, NULL);
896 }
897 
898 void
899 lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn, uint32_t label)
900 {
901 	struct map		 map;
902 	struct l2vpn_pw		*pw;
903 
904 	if (fn) {
905 		lde_fec2map(&fn->fec, &map);
906 		switch (fn->fec.type) {
907 		case FEC_TYPE_IPV4:
908 			if (!ln->v4_enabled)
909 				return;
910 			break;
911 		case FEC_TYPE_IPV6:
912 			if (!ln->v6_enabled)
913 				return;
914 			break;
915 		case FEC_TYPE_PWID:
916 			pw = (struct l2vpn_pw *) fn->data;
917 			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
918 				/* not the remote end of the pseudowire */
919 				return;
920 
921 			if (pw->flags & F_PW_CWORD)
922 				map.flags |= F_MAP_PW_CWORD;
923 			break;
924 		}
925 	} else {
926 		memset(&map, 0, sizeof(map));
927 		map.type = MAP_TYPE_WILDCARD;
928 	}
929 	map.label = label;
930 
931 	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
932 	    &map, sizeof(map));
933 	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
934 }
935 
936 void
937 lde_send_notification(uint32_t peerid, uint32_t status_code, uint32_t msg_id,
938     uint16_t msg_type)
939 {
940 	struct notify_msg nm;
941 
942 	memset(&nm, 0, sizeof(nm));
943 	nm.status_code = status_code;
944 	/* 'msg_id' and 'msg_type' should be in network byte order */
945 	nm.msg_id = msg_id;
946 	nm.msg_type = msg_type;
947 
948 	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, peerid, 0,
949 	    &nm, sizeof(nm));
950 }
951 
952 static __inline int
953 lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
954 {
955 	return (a->peerid - b->peerid);
956 }
957 
958 static struct lde_nbr *
959 lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
960 {
961 	struct lde_nbr	*ln;
962 
963 	if ((ln = calloc(1, sizeof(*ln))) == NULL)
964 		fatal(__func__);
965 
966 	ln->id = new->id;
967 	ln->v4_enabled = new->v4_enabled;
968 	ln->v6_enabled = new->v6_enabled;
969 	ln->peerid = peerid;
970 	fec_init(&ln->recv_map);
971 	fec_init(&ln->sent_map);
972 	fec_init(&ln->recv_req);
973 	fec_init(&ln->sent_req);
974 	fec_init(&ln->sent_wdraw);
975 
976 	TAILQ_INIT(&ln->addr_list);
977 
978 	if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
979 		fatalx("lde_nbr_new: RB_INSERT failed");
980 
981 	return (ln);
982 }
983 
984 static void
985 lde_nbr_del(struct lde_nbr *ln)
986 {
987 	struct fec		*f;
988 	struct fec_node		*fn;
989 	struct fec_nh		*fnh;
990 	struct l2vpn_pw		*pw;
991 
992 	if (ln == NULL)
993 		return;
994 
995 	/* uninstall received mappings */
996 	RB_FOREACH(f, fec_tree, &ft) {
997 		fn = (struct fec_node *)f;
998 
999 		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1000 			switch (f->type) {
1001 			case FEC_TYPE_IPV4:
1002 			case FEC_TYPE_IPV6:
1003 				if (!lde_address_find(ln, fnh->af,
1004 				    &fnh->nexthop))
1005 					continue;
1006 				break;
1007 			case FEC_TYPE_PWID:
1008 				if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1009 					continue;
1010 				pw = (struct l2vpn_pw *) fn->data;
1011 				if (pw)
1012 					l2vpn_pw_reset(pw);
1013 				break;
1014 			default:
1015 				break;
1016 			}
1017 
1018 			lde_send_delete_klabel(fn, fnh);
1019 			fnh->remote_label = NO_LABEL;
1020 		}
1021 	}
1022 
1023 	lde_address_list_free(ln);
1024 
1025 	fec_clear(&ln->recv_map, lde_map_free);
1026 	fec_clear(&ln->sent_map, lde_map_free);
1027 	fec_clear(&ln->recv_req, free);
1028 	fec_clear(&ln->sent_req, free);
1029 	fec_clear(&ln->sent_wdraw, free);
1030 
1031 	RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1032 
1033 	free(ln);
1034 }
1035 
1036 static struct lde_nbr *
1037 lde_nbr_find(uint32_t peerid)
1038 {
1039 	struct lde_nbr		 ln;
1040 
1041 	ln.peerid = peerid;
1042 
1043 	return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1044 }
1045 
1046 struct lde_nbr *
1047 lde_nbr_find_by_lsrid(struct in_addr addr)
1048 {
1049 	struct lde_nbr		*ln;
1050 
1051 	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1052 		if (ln->id.s_addr == addr.s_addr)
1053 			return (ln);
1054 
1055 	return (NULL);
1056 }
1057 
1058 struct lde_nbr *
1059 lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1060 {
1061 	struct lde_nbr		*ln;
1062 
1063 	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1064 		if (lde_address_find(ln, af, addr) != NULL)
1065 			return (ln);
1066 
1067 	return (NULL);
1068 }
1069 
1070 static void
1071 lde_nbr_clear(void)
1072 {
1073 	struct lde_nbr	*ln;
1074 
1075 	 while ((ln = RB_ROOT(&lde_nbrs)) != NULL)
1076 		lde_nbr_del(ln);
1077 }
1078 
1079 static void
1080 lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1081 {
1082 	struct fec		*fec;
1083 	struct fec_node		*fn;
1084 	struct fec_nh		*fnh;
1085 	struct lde_map		*me;
1086 
1087 	RB_FOREACH(fec, fec_tree, &ln->recv_map) {
1088 		fn = (struct fec_node *)fec_find(&ft, fec);
1089 		switch (fec->type) {
1090 		case FEC_TYPE_IPV4:
1091 			if (lde_addr->af != AF_INET)
1092 				continue;
1093 			break;
1094 		case FEC_TYPE_IPV6:
1095 			if (lde_addr->af != AF_INET6)
1096 				continue;
1097 			break;
1098 		default:
1099 			continue;
1100 		}
1101 
1102 		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1103 			if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1104 			    &lde_addr->addr))
1105 				continue;
1106 
1107 			if (removed) {
1108 				lde_send_delete_klabel(fn, fnh);
1109 				fnh->remote_label = NO_LABEL;
1110 			} else {
1111 				me = (struct lde_map *)fec;
1112 				fnh->remote_label = me->map.label;
1113 				lde_send_change_klabel(fn, fnh);
1114 			}
1115 			break;
1116 		}
1117 	}
1118 }
1119 
1120 struct lde_map *
1121 lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1122 {
1123 	struct lde_map  *me;
1124 
1125 	me = calloc(1, sizeof(*me));
1126 	if (me == NULL)
1127 		fatal(__func__);
1128 
1129 	me->fec = fn->fec;
1130 	me->nexthop = ln;
1131 
1132 	if (sent) {
1133 		LIST_INSERT_HEAD(&fn->upstream, me, entry);
1134 		if (fec_insert(&ln->sent_map, &me->fec))
1135 			log_warnx("failed to add %s to sent map",
1136 			    log_fec(&me->fec));
1137 			/* XXX on failure more cleanup is needed */
1138 	} else {
1139 		LIST_INSERT_HEAD(&fn->downstream, me, entry);
1140 		if (fec_insert(&ln->recv_map, &me->fec))
1141 			log_warnx("failed to add %s to recv map",
1142 			    log_fec(&me->fec));
1143 	}
1144 
1145 	return (me);
1146 }
1147 
1148 void
1149 lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1150 {
1151 	if (sent)
1152 		fec_remove(&ln->sent_map, &me->fec);
1153 	else
1154 		fec_remove(&ln->recv_map, &me->fec);
1155 
1156 	lde_map_free(me);
1157 }
1158 
1159 static void
1160 lde_map_free(void *ptr)
1161 {
1162 	struct lde_map	*map = ptr;
1163 
1164 	LIST_REMOVE(map, entry);
1165 	free(map);
1166 }
1167 
1168 struct lde_req *
1169 lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1170 {
1171 	struct fec_tree	*t;
1172 	struct lde_req	*lre;
1173 
1174 	t = sent ? &ln->sent_req : &ln->recv_req;
1175 
1176 	lre = calloc(1, sizeof(*lre));
1177 	if (lre != NULL) {
1178 		lre->fec = *fec;
1179 
1180 		if (fec_insert(t, &lre->fec)) {
1181 			log_warnx("failed to add %s to %s req",
1182 			    log_fec(&lre->fec), sent ? "sent" : "recv");
1183 			free(lre);
1184 			return (NULL);
1185 		}
1186 	}
1187 
1188 	return (lre);
1189 }
1190 
1191 void
1192 lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1193 {
1194 	if (sent)
1195 		fec_remove(&ln->sent_req, &lre->fec);
1196 	else
1197 		fec_remove(&ln->recv_req, &lre->fec);
1198 
1199 	free(lre);
1200 }
1201 
1202 struct lde_wdraw *
1203 lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1204 {
1205 	struct lde_wdraw  *lw;
1206 
1207 	lw = calloc(1, sizeof(*lw));
1208 	if (lw == NULL)
1209 		fatal(__func__);
1210 
1211 	lw->fec = fn->fec;
1212 
1213 	if (fec_insert(&ln->sent_wdraw, &lw->fec))
1214 		log_warnx("failed to add %s to sent wdraw",
1215 		    log_fec(&lw->fec));
1216 
1217 	return (lw);
1218 }
1219 
1220 void
1221 lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1222 {
1223 	fec_remove(&ln->sent_wdraw, &lw->fec);
1224 	free(lw);
1225 }
1226 
1227 void
1228 lde_change_egress_label(int af, int was_implicit)
1229 {
1230 	struct lde_nbr	*ln;
1231 	struct fec	*f;
1232 	struct fec_node	*fn;
1233 
1234 	RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1235 		/* explicit withdraw */
1236 		if (was_implicit)
1237 			lde_send_labelwithdraw(ln, NULL, MPLS_LABEL_IMPLNULL,
1238 			    NULL);
1239 		else {
1240 			if (ln->v4_enabled)
1241 				lde_send_labelwithdraw(ln, NULL,
1242 				    MPLS_LABEL_IPV4NULL, NULL);
1243 			if (ln->v6_enabled)
1244 				lde_send_labelwithdraw(ln, NULL,
1245 				    MPLS_LABEL_IPV6NULL, NULL);
1246 		}
1247 
1248 		/* advertise new label of connected prefixes */
1249 		RB_FOREACH(f, fec_tree, &ft) {
1250 			fn = (struct fec_node *)f;
1251 			if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1252 				continue;
1253 
1254 			switch (af) {
1255 			case AF_INET:
1256 				if (fn->fec.type != FEC_TYPE_IPV4)
1257 					continue;
1258 				break;
1259 			case AF_INET6:
1260 				if (fn->fec.type != FEC_TYPE_IPV6)
1261 					continue;
1262 				break;
1263 			default:
1264 				fatalx("lde_change_egress_label: unknown af");
1265 			}
1266 
1267 			fn->local_label = egress_label(fn->fec.type);
1268 			lde_send_labelmapping(ln, fn, 0);
1269 		}
1270 
1271 		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1272 		    NULL, 0);
1273 	}
1274 }
1275 
1276 static int
1277 lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
1278 {
1279 	struct lde_addr		*new;
1280 
1281 	if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
1282 		return (-1);
1283 
1284 	if ((new = calloc(1, sizeof(*new))) == NULL)
1285 		fatal(__func__);
1286 
1287 	new->af = lde_addr->af;
1288 	new->addr = lde_addr->addr;
1289 	TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
1290 
1291 	/* reevaluate the previously received mappings from this neighbor */
1292 	lde_nbr_addr_update(ln, lde_addr, 0);
1293 
1294 	return (0);
1295 }
1296 
1297 static int
1298 lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
1299 {
1300 	lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
1301 	if (lde_addr == NULL)
1302 		return (-1);
1303 
1304 	/* reevaluate the previously received mappings from this neighbor */
1305 	lde_nbr_addr_update(ln, lde_addr, 1);
1306 
1307 	TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1308 	free(lde_addr);
1309 
1310 	return (0);
1311 }
1312 
1313 struct lde_addr *
1314 lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
1315 {
1316 	struct lde_addr		*lde_addr;
1317 
1318 	TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
1319 		if (lde_addr->af == af &&
1320 		    ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
1321 			return (lde_addr);
1322 
1323 	return (NULL);
1324 }
1325 
1326 static void
1327 lde_address_list_free(struct lde_nbr *ln)
1328 {
1329 	struct lde_addr		*lde_addr;
1330 
1331 	while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
1332 		TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1333 		free(lde_addr);
1334 	}
1335 }
1336