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