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