xref: /openbsd-src/usr.sbin/ldpd/lde.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: lde.c,v 1.29 2014/07/12 20:16:38 krw Exp $ */
2 
3 /*
4  * Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
6  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/queue.h>
24 #include <netinet/in.h>
25 #include <netmpls/mpls.h>
26 #include <arpa/inet.h>
27 #include <err.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 <event.h>
35 
36 #include "ldp.h"
37 #include "ldpd.h"
38 #include "ldpe.h"
39 #include "log.h"
40 #include "lde.h"
41 
42 void		 lde_sig_handler(int sig, short, void *);
43 void		 lde_shutdown(void);
44 void		 lde_dispatch_imsg(int, short, void *);
45 void		 lde_dispatch_parent(int, short, void *);
46 
47 struct lde_nbr	*lde_nbr_find(u_int32_t);
48 struct lde_nbr	*lde_nbr_new(u_int32_t, struct in_addr *);
49 void		 lde_nbr_del(struct lde_nbr *);
50 void		 lde_nbr_clear(void);
51 
52 void		 lde_map_free(void *);
53 void		 lde_address_list_free(struct lde_nbr *);
54 
55 struct ldpd_conf	*ldeconf = NULL, *nconf = NULL;
56 struct imsgev		*iev_ldpe;
57 struct imsgev		*iev_main;
58 
59 /* ARGSUSED */
60 void
61 lde_sig_handler(int sig, short event, void *arg)
62 {
63 	/*
64 	 * signal handler rules don't apply, libevent decouples for us
65 	 */
66 
67 	switch (sig) {
68 	case SIGINT:
69 	case SIGTERM:
70 		lde_shutdown();
71 		/* NOTREACHED */
72 	default:
73 		fatalx("unexpected signal");
74 	}
75 }
76 
77 /* label decision engine */
78 pid_t
79 lde(struct ldpd_conf *xconf, int pipe_parent2lde[2], int pipe_ldpe2lde[2],
80     int pipe_parent2ldpe[2])
81 {
82 	struct event		 ev_sigint, ev_sigterm;
83 	struct timeval		 now;
84 	struct passwd		*pw;
85 	pid_t			 pid;
86 
87 	switch (pid = fork()) {
88 	case -1:
89 		fatal("cannot fork");
90 		/* NOTREACHED */
91 	case 0:
92 		break;
93 	default:
94 		return (pid);
95 	}
96 
97 	ldeconf = xconf;
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 	event_init();
116 
117 	/* setup signal handler */
118 	signal_set(&ev_sigint, SIGINT, lde_sig_handler, NULL);
119 	signal_set(&ev_sigterm, SIGTERM, lde_sig_handler, NULL);
120 	signal_add(&ev_sigint, NULL);
121 	signal_add(&ev_sigterm, NULL);
122 	signal(SIGPIPE, SIG_IGN);
123 	signal(SIGHUP, SIG_IGN);
124 
125 	/* setup pipes */
126 	close(pipe_ldpe2lde[0]);
127 	close(pipe_parent2lde[0]);
128 	close(pipe_parent2ldpe[0]);
129 	close(pipe_parent2ldpe[1]);
130 
131 	if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
132 	    (iev_main = malloc(sizeof(struct imsgev))) == NULL)
133 		fatal(NULL);
134 	imsg_init(&iev_ldpe->ibuf, pipe_ldpe2lde[1]);
135 	iev_ldpe->handler = lde_dispatch_imsg;
136 	imsg_init(&iev_main->ibuf, pipe_parent2lde[1]);
137 	iev_main->handler = lde_dispatch_parent;
138 
139 	/* setup event handler */
140 	iev_ldpe->events = EV_READ;
141 	event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd, iev_ldpe->events,
142 	    iev_ldpe->handler, iev_ldpe);
143 	event_add(&iev_ldpe->ev, NULL);
144 
145 	iev_main->events = EV_READ;
146 	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
147 	    iev_main->handler, iev_main);
148 	event_add(&iev_main->ev, NULL);
149 
150 	gettimeofday(&now, NULL);
151 	ldeconf->uptime = now.tv_sec;
152 
153 	event_dispatch();
154 
155 	lde_shutdown();
156 	/* NOTREACHED */
157 
158 	return (0);
159 }
160 
161 void
162 lde_shutdown(void)
163 {
164 	lde_nbr_clear();
165 	rt_clear();
166 
167 	msgbuf_clear(&iev_ldpe->ibuf.w);
168 	free(iev_ldpe);
169 	msgbuf_clear(&iev_main->ibuf.w);
170 	free(iev_main);
171 	free(ldeconf);
172 
173 	log_info("label decision engine exiting");
174 	_exit(0);
175 }
176 
177 /* imesg */
178 int
179 lde_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen)
180 {
181 	return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
182 }
183 
184 int
185 lde_imsg_compose_ldpe(int type, u_int32_t peerid, pid_t pid, void *data,
186     u_int16_t datalen)
187 {
188 	return (imsg_compose_event(iev_ldpe, type, peerid, pid,
189 	     -1, data, datalen));
190 }
191 
192 /* ARGSUSED */
193 void
194 lde_dispatch_imsg(int fd, short event, void *bula)
195 {
196 	struct imsgev		*iev = bula;
197 	struct imsgbuf		*ibuf = &iev->ibuf;
198 	struct imsg		 imsg;
199 	struct lde_nbr		 *nbr;
200 	struct map		 map;
201 	struct timespec		 tp;
202 	struct in_addr		 addr;
203 	ssize_t			 n;
204 	time_t			 now;
205 	int			 shut = 0, verbose;
206 
207 	if (event & EV_READ) {
208 		if ((n = imsg_read(ibuf)) == -1)
209 			fatal("imsg_read error");
210 		if (n == 0)	/* connection closed */
211 			shut = 1;
212 	}
213 	if (event & EV_WRITE) {
214 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
215 			fatal("msgbuf_write");
216 		if (n == 0)	/* connection closed */
217 			shut = 1;
218 	}
219 
220 	clock_gettime(CLOCK_MONOTONIC, &tp);
221 	now = tp.tv_sec;
222 
223 	for (;;) {
224 		if ((n = imsg_get(ibuf, &imsg)) == -1)
225 			fatal("lde_dispatch_imsg: imsg_read error");
226 		if (n == 0)
227 			break;
228 
229 		switch (imsg.hdr.type) {
230 		case IMSG_LABEL_MAPPING_FULL:
231 			nbr = lde_nbr_find(imsg.hdr.peerid);
232 			if (nbr == NULL) {
233 				log_debug("lde_dispatch_imsg: cannot find "
234 				    "lde neighbor");
235 				return;
236 			}
237 
238 			rt_snap(nbr);
239 			lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END,
240 			    imsg.hdr.peerid, 0, NULL, 0);
241 			break;
242 		case IMSG_LABEL_MAPPING:
243 		case IMSG_LABEL_REQUEST:
244 		case IMSG_LABEL_RELEASE:
245 		case IMSG_LABEL_WITHDRAW:
246 		case IMSG_LABEL_ABORT:
247 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map))
248 				fatalx("invalid size of OE request");
249 			memcpy(&map, imsg.data, sizeof(map));
250 
251 			nbr = lde_nbr_find(imsg.hdr.peerid);
252 			if (nbr == NULL) {
253 				log_debug("lde_dispatch_imsg: cannot find "
254 				    "lde neighbor");
255 				return;
256 			}
257 
258 			switch (imsg.hdr.type) {
259 			case IMSG_LABEL_MAPPING:
260 				lde_check_mapping(&map, nbr);
261 				break;
262 			case IMSG_LABEL_REQUEST:
263 				lde_check_request(&map, nbr);
264 				break;
265 			case IMSG_LABEL_RELEASE:
266 				lde_check_release(&map, nbr);
267 				break;
268 			case IMSG_LABEL_WITHDRAW:
269 				lde_check_withdraw(&map, nbr);
270 				break;
271 			default:
272 				log_warnx("type %d not yet handled. nbr %s",
273 				    imsg.hdr.type, inet_ntoa(nbr->id));
274 			}
275 			break;
276 		case IMSG_ADDRESS_ADD:
277 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr))
278 				fatalx("invalid size of OE request");
279 			memcpy(&addr, imsg.data, sizeof(addr));
280 
281 			nbr = lde_nbr_find(imsg.hdr.peerid);
282 			if (nbr == NULL) {
283 				log_debug("lde_dispatch_imsg: cannot find "
284 				    "lde neighbor");
285 				return;
286 			}
287 
288 			if (lde_address_add(nbr, &addr) < 0) {
289 				log_debug("lde_dispatch_imsg: cannot add "
290 				    "address %s, it already exists",
291 				    inet_ntoa(addr));
292 			}
293 
294 			break;
295 		case IMSG_ADDRESS_DEL:
296 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr))
297 				fatalx("invalid size of OE request");
298 			memcpy(&addr, imsg.data, sizeof(addr));
299 
300 			nbr = lde_nbr_find(imsg.hdr.peerid);
301 			if (nbr == NULL) {
302 				log_debug("lde_dispatch_imsg: cannot find "
303 				    "lde neighbor");
304 				return;
305 			}
306 
307 			if (lde_address_del(nbr, &addr) < 0) {
308 				log_debug("lde_dispatch_imsg: cannot delete "
309 				    "address %s, it does not exists",
310 				    inet_ntoa(addr));
311 			}
312 
313 			break;
314 		case IMSG_NEIGHBOR_UP:
315 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr))
316 				fatalx("invalid size of OE request");
317 			memcpy(&addr, imsg.data, sizeof(addr));
318 
319 			if (lde_nbr_find(imsg.hdr.peerid))
320 				fatalx("lde_dispatch_imsg: "
321 				    "neighbor already exists");
322 			lde_nbr_new(imsg.hdr.peerid, &addr);
323 			break;
324 		case IMSG_NEIGHBOR_DOWN:
325 			lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
326 			break;
327 		case IMSG_CTL_SHOW_LIB:
328 			rt_dump(imsg.hdr.pid);
329 
330 			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
331 			    imsg.hdr.pid, NULL, 0);
332 			break;
333 		case IMSG_CTL_LOG_VERBOSE:
334 			/* already checked by ldpe */
335 			memcpy(&verbose, imsg.data, sizeof(verbose));
336 			log_verbose(verbose);
337 			break;
338 		default:
339 			log_debug("lde_dispatch_imsg: unexpected imsg %d",
340 			    imsg.hdr.type);
341 			break;
342 		}
343 		imsg_free(&imsg);
344 	}
345 	if (!shut)
346 		imsg_event_add(iev);
347 	else {
348 		/* this pipe is dead, so remove the event handler */
349 		event_del(&iev->ev);
350 		event_loopexit(NULL);
351 	}
352 }
353 
354 /* ARGSUSED */
355 void
356 lde_dispatch_parent(int fd, short event, void *bula)
357 {
358 	struct imsg		 imsg;
359 	struct kroute		 kr;
360 	struct imsgev		*iev = bula;
361 	struct imsgbuf		*ibuf = &iev->ibuf;
362 	ssize_t			 n;
363 	int			 shut = 0;
364 
365 	if (event & EV_READ) {
366 		if ((n = imsg_read(ibuf)) == -1)
367 			fatal("imsg_read error");
368 		if (n == 0)	/* connection closed */
369 			shut = 1;
370 	}
371 	if (event & EV_WRITE) {
372 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
373 			fatal("msgbuf_write");
374 		if (n == 0)	/* connection closed */
375 			shut = 1;
376 	}
377 
378 	for (;;) {
379 		if ((n = imsg_get(ibuf, &imsg)) == -1)
380 			fatal("lde_dispatch_parent: imsg_read error");
381 		if (n == 0)
382 			break;
383 
384 		switch (imsg.hdr.type) {
385 		case IMSG_NETWORK_ADD:
386 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
387 				log_warnx("lde_dispatch_parent: "
388 				    "wrong imsg len");
389 				break;
390 			}
391 			memcpy(&kr, imsg.data, sizeof(kr));
392 
393 			lde_kernel_insert(&kr);
394 			break;
395 		case IMSG_NETWORK_DEL:
396 			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
397 				log_warnx("lde_dispatch_parent: "
398 				    "wrong imsg len");
399 				break;
400 			}
401 			memcpy(&kr, imsg.data, sizeof(kr));
402 
403 			lde_kernel_remove(&kr);
404 			break;
405 		case IMSG_RECONF_CONF:
406 			if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
407 			    NULL)
408 				fatal(NULL);
409 			memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
410 
411 			break;
412 		case IMSG_RECONF_IFACE:
413 			break;
414 		case IMSG_RECONF_END:
415 			break;
416 		default:
417 			log_debug("lde_dispatch_parent: unexpected imsg %d",
418 			    imsg.hdr.type);
419 			break;
420 		}
421 		imsg_free(&imsg);
422 	}
423 	if (!shut)
424 		imsg_event_add(iev);
425 	else {
426 		/* this pipe is dead, so remove the event handler */
427 		event_del(&iev->ev);
428 		event_loopexit(NULL);
429 	}
430 }
431 
432 u_int32_t
433 lde_assign_label(void)
434 {
435 	static u_int32_t label = MPLS_LABEL_RESERVED_MAX;
436 
437 	/* XXX some checks needed */
438 	label++;
439 	return label;
440 }
441 
442 void
443 lde_send_change_klabel(struct rt_node *rr, struct rt_lsp *rl)
444 {
445 	struct kroute	kr;
446 
447 	bzero(&kr, sizeof(kr));
448 	kr.prefix.s_addr = rr->fec.prefix.s_addr;
449 	kr.prefixlen = rr->fec.prefixlen;
450 	kr.local_label = rr->local_label;
451 
452 	kr.nexthop.s_addr = rl->nexthop.s_addr;
453 	kr.remote_label = rl->remote_label;
454 
455 	lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, sizeof(kr));
456 }
457 
458 void
459 lde_send_delete_klabel(struct rt_node *rr, struct rt_lsp *rl)
460 {
461 	struct kroute	 kr;
462 
463 	bzero(&kr, sizeof(kr));
464 	kr.prefix.s_addr = rr->fec.prefix.s_addr;
465 	kr.prefixlen = rr->fec.prefixlen;
466 	kr.local_label = rr->local_label;
467 
468 	kr.nexthop.s_addr = rl->nexthop.s_addr;
469 	kr.remote_label = rl->remote_label;
470 
471 	lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, sizeof(kr));
472 }
473 
474 void
475 lde_send_labelrequest(struct lde_nbr *ln, struct rt_node *rn)
476 {
477 	struct map	 map;
478 
479 	/* TODO check if status of peer is OK to send requests (SLRq.2 & 6)
480 	 * For now assume no peer will send no-label-resource notifications */
481 
482 	/* check if request is already pending */
483 	if (fec_find(&ln->sent_req, &rn->fec) != NULL)
484 		return;
485 	/* and try to add request to pending list */
486 	lde_req_add(ln, &rn->fec, 1);
487 	/* msgid does not matter since only one req can be pending */
488 
489 	bzero(&map, sizeof(map));
490 	map.prefix = rn->fec.prefix;
491 	map.prefixlen = rn->fec.prefixlen;
492 
493 	lde_imsg_compose_ldpe(IMSG_REQUEST_ADD, ln->peerid, 0,
494 	    &map, sizeof(map));
495 	lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END, ln->peerid, 0,
496 	    NULL, 0);
497 }
498 
499 void
500 lde_send_labelmapping(struct lde_nbr *ln, struct rt_node *rn)
501 {
502 	struct lde_req	*lre;
503 	struct lde_map	*me;
504 	struct map	 map;
505 
506 	/*
507 	 * This function skips SL.1 - 3 and SL.9 - 14 because the lable
508 	 * allocation is done way earlier (because of the merging nature of
509 	 * ldpd).
510 	 */
511 
512 	bzero(&map, sizeof(map));
513 	map.label = rn->local_label;
514 	map.prefix = rn->fec.prefix;
515 	map.prefixlen = rn->fec.prefixlen;
516 
517 	/* is there a pending request for this mapping? */
518 	lre = (struct lde_req *)fec_find(&ln->recv_req, &rn->fec);
519 	if (lre) {
520 		/* set label request msg id in the mapping response. */
521 		map.requestid = lre->msgid;
522 		map.flags = F_MAP_REQ_ID;
523 		lde_req_del(ln, lre, 0);
524 	}
525 
526 	me = (struct lde_map *)fec_find(&ln->sent_map, &rn->fec);
527 	if (me == NULL)
528 		me = lde_map_add(ln, rn, 1);
529 	me->label = map.label;
530 
531 	lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
532 	    &map, sizeof(map));
533 	lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
534 	    NULL, 0);
535 }
536 
537 void
538 lde_send_labelrelease(struct lde_nbr *ln, struct rt_node *rn, u_int32_t label)
539 {
540 	struct map	 map;
541 
542 	bzero(&map, sizeof(map));
543 	map.prefix = rn->fec.prefix;
544 	map.prefixlen = rn->fec.prefixlen;
545 	if (label != NO_LABEL) {
546 		map.flags = F_MAP_OPTLABEL;
547 		map.label = label;
548 	}
549 
550 	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
551 	    &map, sizeof(map));
552 	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0,
553 	    NULL, 0);
554 }
555 
556 void
557 lde_send_notification(u_int32_t peerid, u_int32_t code, u_int32_t msgid,
558     u_int32_t type)
559 {
560 	struct notify_msg nm;
561 
562 	bzero(&nm, sizeof(nm));
563 
564 	/* Every field is in host byte order, to keep things clear */
565 	nm.status = code;
566 	nm.messageid = ntohl(msgid);
567 	nm.type = type;
568 
569 	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, peerid, 0,
570 	    &nm, sizeof(nm));
571 }
572 
573 static __inline int lde_nbr_compare(struct lde_nbr *, struct lde_nbr *);
574 
575 RB_HEAD(nbr_tree, lde_nbr);
576 RB_PROTOTYPE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
577 RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
578 
579 struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
580 
581 static __inline int
582 lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
583 {
584 	return (a->peerid - b->peerid);
585 }
586 
587 struct lde_nbr *
588 lde_nbr_find(u_int32_t peerid)
589 {
590 	struct lde_nbr	n;
591 
592 	n.peerid = peerid;
593 
594 	return (RB_FIND(nbr_tree, &lde_nbrs, &n));
595 }
596 
597 struct lde_nbr *
598 lde_nbr_new(u_int32_t peerid, struct in_addr *id)
599 {
600 	struct lde_nbr	*nbr;
601 
602 	if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
603 		fatal("lde_nbr_new");
604 
605 	nbr->id.s_addr = id->s_addr;
606 	nbr->peerid = peerid;
607 	fec_init(&nbr->recv_map);
608 	fec_init(&nbr->sent_map);
609 	fec_init(&nbr->recv_req);
610 	fec_init(&nbr->sent_req);
611 	fec_init(&nbr->sent_wdraw);
612 
613 	TAILQ_INIT(&nbr->addr_list);
614 
615 	if (RB_INSERT(nbr_tree, &lde_nbrs, nbr) != NULL)
616 		fatalx("lde_nbr_new: RB_INSERT failed");
617 
618 	return (nbr);
619 }
620 
621 void
622 lde_nbr_del(struct lde_nbr *nbr)
623 {
624 	if (nbr == NULL)
625 		return;
626 
627 	lde_address_list_free(nbr);
628 
629 	fec_clear(&nbr->recv_map, lde_map_free);
630 	fec_clear(&nbr->sent_map, lde_map_free);
631 	fec_clear(&nbr->recv_req, free);
632 	fec_clear(&nbr->sent_req, free);
633 	fec_clear(&nbr->sent_wdraw, free);
634 
635 	RB_REMOVE(nbr_tree, &lde_nbrs, nbr);
636 
637 	free(nbr);
638 }
639 
640 void
641 lde_nbr_clear(void)
642 {
643 	struct lde_nbr	*nbr;
644 
645 	 while ((nbr = RB_ROOT(&lde_nbrs)) != NULL)
646 		lde_nbr_del(nbr);
647 }
648 
649 void
650 lde_nbr_do_mappings(struct rt_node *rn)
651 {
652 	struct lde_nbr	*ln;
653 	struct lde_map	*me;
654 	struct lde_req	*lre;
655 
656 	/* This handles LMp.17-31 for lde_check_mapping() */
657 
658 	RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
659 		/* LMp.18 Did we already send a mapping to this peer? */
660 		me = (struct lde_map *)fec_find(&ln->sent_map, &rn->fec);
661 		if (me && me->label == rn->local_label)
662 			/* same mapping already sent, skip */
663 			/* TODO LMp.22-27 Loop detection check */
664 			continue;
665 
666 		/* LMp.28 Is this from a pending request? */
667 		lre = (struct lde_req *)fec_find(&ln->recv_req, &rn->fec);
668 
669 		/* Check for the only case where no mapping should be sent.
670 		 * This is the On Demand case of LMp.29  */
671 		if (ldeconf->mode & MODE_ADV_ONDEMAND && lre == NULL)
672 			/* adv. on demand but no req pending, skip */
673 			continue;
674 
675 		lde_send_labelmapping(ln, rn);
676 		/* LMp.30 & 31 are not needed because labels are always added */
677 	}
678 }
679 
680 struct lde_map *
681 lde_map_add(struct lde_nbr *ln, struct rt_node *rn, int sent)
682 {
683 	struct lde_map  *me;
684 
685 	me = calloc(1, sizeof(*me));
686 	if (me == NULL)
687 		fatal("lde_map_add");
688 
689 	me->fec = rn->fec;
690 	me->nexthop = ln;
691 
692 	if (sent) {
693 		LIST_INSERT_HEAD(&rn->upstream, me, entry);
694 		if (fec_insert(&ln->sent_map, &me->fec))
695 			log_warnx("failed to add %s/%u to sent map",
696 			    inet_ntoa(me->fec.prefix), me->fec.prefixlen);
697 			/* XXX on failure more cleanup is needed */
698 	} else {
699 		LIST_INSERT_HEAD(&rn->downstream, me, entry);
700 		if (fec_insert(&ln->recv_map, &me->fec))
701 			log_warnx("failed to add %s/%u to recv map",
702 			    inet_ntoa(me->fec.prefix), me->fec.prefixlen);
703 	}
704 
705 	return (me);
706 }
707 
708 void
709 lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
710 {
711 	if (sent)
712 		fec_remove(&ln->sent_map, &me->fec);
713 	else
714 		fec_remove(&ln->recv_map, &me->fec);
715 
716 	lde_map_free(me);
717 }
718 
719 void
720 lde_map_free(void *ptr)
721 {
722 	struct lde_map	*map = ptr;
723 
724 	LIST_REMOVE(map, entry);
725 	free(map);
726 }
727 
728 struct lde_req *
729 lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
730 {
731 	struct fec_tree	*ft;
732 	struct lde_req	*lre;
733 
734 	ft = sent ? &ln->sent_req : &ln->recv_req;
735 
736 	lre = calloc(1, sizeof(*lre));
737 	if (lre != NULL) {
738 		lre->fec = *fec;
739 
740 		if (fec_insert(ft, &lre->fec)) {
741 			log_warnx("failed to add %s/%u to %s req",
742 			    inet_ntoa(lre->fec.prefix), lre->fec.prefixlen,
743 			    sent ? "sent" : "recv");
744 			free(lre);
745 			return (NULL);
746 		}
747 	}
748 
749 	return (lre);
750 }
751 
752 void
753 lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
754 {
755 	if (sent)
756 		fec_remove(&ln->sent_req, &lre->fec);
757 	else
758 		fec_remove(&ln->recv_req, &lre->fec);
759 
760 	free(lre);
761 }
762 
763 int
764 lde_address_add(struct lde_nbr *lr, struct in_addr *addr)
765 {
766 	struct lde_nbr_address	*address;
767 
768 	if (lde_address_find(lr, addr) != NULL)
769 		return (-1);
770 
771 	if ((address = calloc(1, sizeof(*address))) == NULL)
772 		fatal("lde_address_add");
773 
774 	address->addr.s_addr = addr->s_addr;
775 
776 	TAILQ_INSERT_TAIL(&lr->addr_list, address, entry);
777 
778 	log_debug("lde_address_add: added %s", inet_ntoa(*addr));
779 
780 	return (0);
781 }
782 
783 struct lde_nbr_address *
784 lde_address_find(struct lde_nbr *lr, struct in_addr *addr)
785 {
786 	struct lde_nbr_address	*address = NULL;
787 
788 	TAILQ_FOREACH(address, &lr->addr_list, entry) {
789 		if (address->addr.s_addr == addr->s_addr)
790 			return (address);
791 	}
792 
793 	return (NULL);
794 }
795 
796 int
797 lde_address_del(struct lde_nbr *lr, struct in_addr *addr)
798 {
799 	struct lde_nbr_address	*address;
800 
801 	address = lde_address_find(lr, addr);
802 	if (address == NULL)
803 		return (-1);
804 
805 	TAILQ_REMOVE(&lr->addr_list, address, entry);
806 
807 	free(address);
808 
809 	log_debug("lde_address_del: deleted %s", inet_ntoa(*addr));
810 
811 	return (0);
812 }
813 
814 void
815 lde_address_list_free(struct lde_nbr *nbr)
816 {
817 	struct lde_nbr_address	*addr;
818 
819 	while ((addr = TAILQ_FIRST(&nbr->addr_list)) != NULL) {
820 		TAILQ_REMOVE(&nbr->addr_list, addr, entry);
821 		free(addr);
822 	}
823 }
824 
825 struct lde_nbr *
826 lde_find_address(struct in_addr address)
827 {
828 	struct lde_nbr	*ln;
829 
830 	RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
831 		if (lde_address_find(ln, &address) != NULL)
832 			return (ln);
833 	}
834 
835 	return (NULL);
836 }
837