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