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