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