]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/lde.c
release: FRR 3.0-rc1
[mirror_frr.git] / ldpd / lde.c
1 /* $OpenBSD$ */
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 <zebra.h>
23
24 #include "ldp.h"
25 #include "ldpd.h"
26 #include "ldpe.h"
27 #include "log.h"
28 #include "lde.h"
29 #include "ldp_debug.h"
30
31 #include <lib/log.h>
32 #include "memory.h"
33 #include "privs.h"
34 #include "sigevent.h"
35 #include "mpls.h"
36 #include <lib/linklist.h>
37 #include "zclient.h"
38 #include "stream.h"
39 #include "network.h"
40
41 static void lde_shutdown(void);
42 static int lde_dispatch_imsg(struct thread *);
43 static int lde_dispatch_parent(struct thread *);
44 static __inline int lde_nbr_compare(struct lde_nbr *,
45 struct lde_nbr *);
46 static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *);
47 static void lde_nbr_del(struct lde_nbr *);
48 static struct lde_nbr *lde_nbr_find(uint32_t);
49 static void lde_nbr_clear(void);
50 static void lde_nbr_addr_update(struct lde_nbr *,
51 struct lde_addr *, int);
52 static __inline int lde_map_compare(struct lde_map *, struct lde_map *);
53 static void lde_map_free(void *);
54 static int lde_address_add(struct lde_nbr *, struct lde_addr *);
55 static int lde_address_del(struct lde_nbr *, struct lde_addr *);
56 static void lde_address_list_free(struct lde_nbr *);
57 static void zclient_sync_init (u_short instance);
58 static void lde_label_list_init(void);
59 static int lde_get_label_chunk (void);
60 static void on_get_label_chunk_response(uint32_t start, uint32_t end);
61 static uint32_t lde_get_next_label(void);
62
63 RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
64 RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
65
66 struct ldpd_conf *ldeconf;
67 struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
68
69 static struct imsgev *iev_ldpe;
70 static struct imsgev *iev_main, *iev_main_sync;
71
72 /* Master of threads. */
73 struct thread_master *master;
74
75 /* lde privileges */
76 static zebra_capabilities_t _caps_p [] =
77 {
78 /* none */
79 };
80
81 static struct zebra_privs_t lde_privs =
82 {
83 #if defined(VTY_GROUP)
84 .vty_group = VTY_GROUP,
85 #endif
86 .caps_p = _caps_p,
87 .cap_num_p = array_size(_caps_p),
88 .cap_num_i = 0
89 };
90
91 /* List of chunks of labels externally assigned by Zebra */
92 struct list *label_chunk_list;
93 struct listnode *current_label_chunk;
94
95 /* SIGINT / SIGTERM handler. */
96 static void
97 sigint(void)
98 {
99 lde_shutdown();
100 }
101
102 static struct quagga_signal_t lde_signals[] =
103 {
104 {
105 .signal = SIGHUP,
106 /* ignore */
107 },
108 {
109 .signal = SIGINT,
110 .handler = &sigint,
111 },
112 {
113 .signal = SIGTERM,
114 .handler = &sigint,
115 },
116 };
117
118 struct zclient *zclient_sync = NULL;
119 static void
120 zclient_sync_init(u_short instance)
121 {
122 /* Initialize special zclient for synchronous message exchanges. */
123 log_debug("Initializing synchronous zclient for label manager");
124 zclient_sync = zclient_new(master);
125 zclient_sync->sock = -1;
126 zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
127 zclient_sync->instance = instance;
128 while (zclient_socket_connect (zclient_sync) < 0) {
129 log_warnx("Error connecting synchronous zclient!");
130 sleep(1);
131 }
132 /* make socket non-blocking */
133 sock_set_nonblock(zclient_sync->sock);
134
135 /* Connect to label manager */
136 while (lm_label_manager_connect (zclient_sync) != 0) {
137 log_warnx("Error connecting to label manager!");
138 sleep(1);
139 }
140 }
141
142 /* label decision engine */
143 void
144 lde(void)
145 {
146 struct thread thread;
147
148 #ifdef HAVE_SETPROCTITLE
149 setproctitle("label decision engine");
150 #endif
151 ldpd_process = PROC_LDE_ENGINE;
152 log_procname = log_procnames[PROC_LDE_ENGINE];
153
154 master = thread_master_create();
155
156 /* setup signal handler */
157 signal_init(master, array_size(lde_signals), lde_signals);
158
159 /* setup pipes and event handlers to the parent process */
160 if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
161 fatal(NULL);
162 imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
163 iev_main->handler_read = lde_dispatch_parent;
164 iev_main->ev_read = thread_add_read(master, iev_main->handler_read,
165 iev_main, iev_main->ibuf.fd);
166 iev_main->handler_write = ldp_write_handler;
167
168 if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
169 fatal(NULL);
170 imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
171
172 /* create base configuration */
173 ldeconf = config_new_empty();
174
175 /* Fetch next active thread. */
176 while (thread_fetch(master, &thread))
177 thread_call(&thread);
178 }
179
180 void
181 lde_init(struct ldpd_init *init)
182 {
183 /* drop privileges */
184 lde_privs.user = init->user;
185 lde_privs.group = init->group;
186 zprivs_init(&lde_privs);
187
188 /* start the LIB garbage collector */
189 lde_gc_start_timer();
190
191 /* Init synchronous zclient and label list */
192 zclient_serv_path_set(init->zclient_serv_path);
193 zclient_sync_init(init->instance);
194 lde_label_list_init();
195 }
196
197 static void
198 lde_shutdown(void)
199 {
200 /* close pipes */
201 if (iev_ldpe) {
202 msgbuf_clear(&iev_ldpe->ibuf.w);
203 close(iev_ldpe->ibuf.fd);
204 }
205 msgbuf_clear(&iev_main->ibuf.w);
206 close(iev_main->ibuf.fd);
207 msgbuf_clear(&iev_main_sync->ibuf.w);
208 close(iev_main_sync->ibuf.fd);
209
210 lde_gc_stop_timer();
211 lde_nbr_clear();
212 fec_tree_clear();
213
214 config_clear(ldeconf);
215
216 if (iev_ldpe)
217 free(iev_ldpe);
218 free(iev_main);
219 free(iev_main_sync);
220
221 log_info("label decision engine exiting");
222 exit(0);
223 }
224
225 /* imesg */
226 int
227 lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
228 {
229 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
230 }
231
232 void
233 lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
234 {
235 imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
236 imsg_flush(&iev_main_sync->ibuf);
237 }
238
239 int
240 lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
241 uint16_t datalen)
242 {
243 return (imsg_compose_event(iev_ldpe, type, peerid, pid,
244 -1, data, datalen));
245 }
246
247 /* ARGSUSED */
248 static int
249 lde_dispatch_imsg(struct thread *thread)
250 {
251 struct imsgev *iev = THREAD_ARG(thread);
252 struct imsgbuf *ibuf = &iev->ibuf;
253 struct imsg imsg;
254 struct lde_nbr *ln;
255 struct map *map;
256 struct lde_addr *lde_addr;
257 struct notify_msg *nm;
258 ssize_t n;
259 int shut = 0;
260
261 iev->ev_read = NULL;
262
263 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
264 fatal("imsg_read error");
265 if (n == 0) /* connection closed */
266 shut = 1;
267
268 for (;;) {
269 if ((n = imsg_get(ibuf, &imsg)) == -1)
270 fatal("lde_dispatch_imsg: imsg_get error");
271 if (n == 0)
272 break;
273
274 switch (imsg.hdr.type) {
275 case IMSG_LABEL_MAPPING_FULL:
276 ln = lde_nbr_find(imsg.hdr.peerid);
277 if (ln == NULL) {
278 log_debug("%s: cannot find lde neighbor",
279 __func__);
280 break;
281 }
282
283 fec_snap(ln);
284 break;
285 case IMSG_LABEL_MAPPING:
286 case IMSG_LABEL_REQUEST:
287 case IMSG_LABEL_RELEASE:
288 case IMSG_LABEL_WITHDRAW:
289 case IMSG_LABEL_ABORT:
290 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
291 sizeof(struct map))
292 fatalx("lde_dispatch_imsg: wrong imsg len");
293 map = imsg.data;
294
295 ln = lde_nbr_find(imsg.hdr.peerid);
296 if (ln == NULL) {
297 log_debug("%s: cannot find lde neighbor",
298 __func__);
299 break;
300 }
301
302 switch (imsg.hdr.type) {
303 case IMSG_LABEL_MAPPING:
304 lde_check_mapping(map, ln);
305 break;
306 case IMSG_LABEL_REQUEST:
307 lde_check_request(map, ln);
308 break;
309 case IMSG_LABEL_RELEASE:
310 lde_check_release(map, ln);
311 break;
312 case IMSG_LABEL_WITHDRAW:
313 lde_check_withdraw(map, ln);
314 break;
315 case IMSG_LABEL_ABORT:
316 /* not necessary */
317 break;
318 }
319 break;
320 case IMSG_ADDRESS_ADD:
321 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
322 sizeof(struct lde_addr))
323 fatalx("lde_dispatch_imsg: wrong imsg len");
324 lde_addr = imsg.data;
325
326 ln = lde_nbr_find(imsg.hdr.peerid);
327 if (ln == NULL) {
328 log_debug("%s: cannot find lde neighbor",
329 __func__);
330 break;
331 }
332 if (lde_address_add(ln, lde_addr) < 0) {
333 log_debug("%s: cannot add address %s, it "
334 "already exists", __func__,
335 log_addr(lde_addr->af, &lde_addr->addr));
336 }
337 break;
338 case IMSG_ADDRESS_DEL:
339 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
340 sizeof(struct lde_addr))
341 fatalx("lde_dispatch_imsg: wrong imsg len");
342 lde_addr = imsg.data;
343
344 ln = lde_nbr_find(imsg.hdr.peerid);
345 if (ln == NULL) {
346 log_debug("%s: cannot find lde neighbor",
347 __func__);
348 break;
349 }
350 if (lde_address_del(ln, lde_addr) < 0) {
351 log_debug("%s: cannot delete address %s, it "
352 "does not exist", __func__,
353 log_addr(lde_addr->af, &lde_addr->addr));
354 }
355 break;
356 case IMSG_NOTIFICATION:
357 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
358 sizeof(struct notify_msg))
359 fatalx("lde_dispatch_imsg: wrong imsg len");
360 nm = imsg.data;
361
362 ln = lde_nbr_find(imsg.hdr.peerid);
363 if (ln == NULL) {
364 log_debug("%s: cannot find lde neighbor",
365 __func__);
366 break;
367 }
368
369 switch (nm->status_code) {
370 case S_PW_STATUS:
371 l2vpn_recv_pw_status(ln, nm);
372 break;
373 case S_ENDOFLIB:
374 /*
375 * Do nothing for now. Should be useful in
376 * the future when we implement LDP-IGP
377 * Synchronization (RFC 5443) and Graceful
378 * Restart (RFC 3478).
379 */
380 default:
381 break;
382 }
383 break;
384 case IMSG_NEIGHBOR_UP:
385 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
386 sizeof(struct lde_nbr))
387 fatalx("lde_dispatch_imsg: wrong imsg len");
388
389 if (lde_nbr_find(imsg.hdr.peerid))
390 fatalx("lde_dispatch_imsg: "
391 "neighbor already exists");
392 lde_nbr_new(imsg.hdr.peerid, imsg.data);
393 break;
394 case IMSG_NEIGHBOR_DOWN:
395 lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
396 break;
397 case IMSG_CTL_SHOW_LIB:
398 rt_dump(imsg.hdr.pid);
399
400 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
401 imsg.hdr.pid, NULL, 0);
402 break;
403 case IMSG_CTL_SHOW_L2VPN_PW:
404 l2vpn_pw_ctl(imsg.hdr.pid);
405
406 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
407 imsg.hdr.pid, NULL, 0);
408 break;
409 case IMSG_CTL_SHOW_L2VPN_BINDING:
410 l2vpn_binding_ctl(imsg.hdr.pid);
411
412 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
413 imsg.hdr.pid, NULL, 0);
414 break;
415 default:
416 log_debug("%s: unexpected imsg %d", __func__,
417 imsg.hdr.type);
418 break;
419 }
420 imsg_free(&imsg);
421 }
422 if (!shut)
423 imsg_event_add(iev);
424 else {
425 /* this pipe is dead, so remove the event handlers and exit */
426 THREAD_READ_OFF(iev->ev_read);
427 THREAD_WRITE_OFF(iev->ev_write);
428 lde_shutdown();
429 }
430
431 return (0);
432 }
433
434 /* ARGSUSED */
435 static int
436 lde_dispatch_parent(struct thread *thread)
437 {
438 static struct ldpd_conf *nconf;
439 struct iface *iface, *niface;
440 struct tnbr *ntnbr;
441 struct nbr_params *nnbrp;
442 static struct l2vpn *l2vpn, *nl2vpn;
443 struct l2vpn_if *lif, *nlif;
444 struct l2vpn_pw *pw, *npw;
445 struct imsg imsg;
446 struct kif *kif;
447 struct kroute *kr;
448 int fd = THREAD_FD(thread);
449 struct imsgev *iev = THREAD_ARG(thread);
450 struct imsgbuf *ibuf = &iev->ibuf;
451 ssize_t n;
452 int shut = 0;
453 struct fec fec;
454
455 iev->ev_read = NULL;
456
457 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
458 fatal("imsg_read error");
459 if (n == 0) /* connection closed */
460 shut = 1;
461
462 for (;;) {
463 if ((n = imsg_get(ibuf, &imsg)) == -1)
464 fatal("lde_dispatch_parent: imsg_get error");
465 if (n == 0)
466 break;
467
468 switch (imsg.hdr.type) {
469 case IMSG_IFSTATUS:
470 if (imsg.hdr.len != IMSG_HEADER_SIZE +
471 sizeof(struct kif))
472 fatalx("IFSTATUS imsg with wrong len");
473 kif = imsg.data;
474
475 iface = if_lookup_name(ldeconf, kif->ifname);
476 if (iface) {
477 if_update_info(iface, kif);
478 break;
479 }
480
481 RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
482 lif = l2vpn_if_find(l2vpn, kif->ifname);
483 if (lif) {
484 l2vpn_if_update_info(lif, kif);
485 break;
486 }
487 pw = l2vpn_pw_find(l2vpn, kif->ifname);
488 if (pw) {
489 l2vpn_pw_update_info(pw, kif);
490 break;
491 }
492 }
493 break;
494 case IMSG_PW_UPDATE:
495 if (imsg.hdr.len != IMSG_HEADER_SIZE +
496 sizeof(struct zapi_pw_status))
497 fatalx("PW_UPDATE imsg with wrong len");
498
499 if (l2vpn_pw_status_update(imsg.data) != 0)
500 log_warnx("%s: error updating PW status",
501 __func__);
502 break;
503 case IMSG_NETWORK_ADD:
504 case IMSG_NETWORK_UPDATE:
505 if (imsg.hdr.len != IMSG_HEADER_SIZE +
506 sizeof(struct kroute)) {
507 log_warnx("%s: wrong imsg len", __func__);
508 break;
509 }
510 kr = imsg.data;
511
512 switch (kr->af) {
513 case AF_INET:
514 fec.type = FEC_TYPE_IPV4;
515 fec.u.ipv4.prefix = kr->prefix.v4;
516 fec.u.ipv4.prefixlen = kr->prefixlen;
517 break;
518 case AF_INET6:
519 fec.type = FEC_TYPE_IPV6;
520 fec.u.ipv6.prefix = kr->prefix.v6;
521 fec.u.ipv6.prefixlen = kr->prefixlen;
522 break;
523 default:
524 fatalx("lde_dispatch_parent: unknown af");
525 }
526
527 switch (imsg.hdr.type) {
528 case IMSG_NETWORK_ADD:
529 lde_kernel_insert(&fec, kr->af, &kr->nexthop,
530 kr->ifindex, kr->priority,
531 kr->flags & F_CONNECTED, NULL);
532 break;
533 case IMSG_NETWORK_UPDATE:
534 lde_kernel_update(&fec);
535 break;
536 }
537 break;
538 case IMSG_SOCKET_IPC:
539 if (iev_ldpe) {
540 log_warnx("%s: received unexpected imsg fd "
541 "to ldpe", __func__);
542 break;
543 }
544 if ((fd = imsg.fd) == -1) {
545 log_warnx("%s: expected to receive imsg fd to "
546 "ldpe but didn't receive any", __func__);
547 break;
548 }
549
550 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
551 fatal(NULL);
552 imsg_init(&iev_ldpe->ibuf, fd);
553 iev_ldpe->handler_read = lde_dispatch_imsg;
554 iev_ldpe->ev_read = thread_add_read(master,
555 iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd);
556 iev_ldpe->handler_write = ldp_write_handler;
557 iev_ldpe->ev_write = NULL;
558 break;
559 case IMSG_INIT:
560 if (imsg.hdr.len != IMSG_HEADER_SIZE +
561 sizeof(struct ldpd_init))
562 fatalx("INIT imsg with wrong len");
563
564 memcpy(&init, imsg.data, sizeof(init));
565 lde_init(&init);
566 break;
567 case IMSG_RECONF_CONF:
568 if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
569 NULL)
570 fatal(NULL);
571 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
572
573 RB_INIT(&nconf->iface_tree);
574 RB_INIT(&nconf->tnbr_tree);
575 RB_INIT(&nconf->nbrp_tree);
576 RB_INIT(&nconf->l2vpn_tree);
577 break;
578 case IMSG_RECONF_IFACE:
579 if ((niface = malloc(sizeof(struct iface))) == NULL)
580 fatal(NULL);
581 memcpy(niface, imsg.data, sizeof(struct iface));
582
583 RB_INSERT(iface_head, &nconf->iface_tree, niface);
584 break;
585 case IMSG_RECONF_TNBR:
586 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
587 fatal(NULL);
588 memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
589
590 RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
591 break;
592 case IMSG_RECONF_NBRP:
593 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
594 fatal(NULL);
595 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
596
597 RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
598 break;
599 case IMSG_RECONF_L2VPN:
600 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
601 fatal(NULL);
602 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
603
604 RB_INIT(&nl2vpn->if_tree);
605 RB_INIT(&nl2vpn->pw_tree);
606 RB_INIT(&nl2vpn->pw_inactive_tree);
607
608 RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
609 break;
610 case IMSG_RECONF_L2VPN_IF:
611 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
612 fatal(NULL);
613 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
614
615 RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
616 break;
617 case IMSG_RECONF_L2VPN_PW:
618 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
619 fatal(NULL);
620 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
621
622 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
623 break;
624 case IMSG_RECONF_L2VPN_IPW:
625 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
626 fatal(NULL);
627 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
628
629 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
630 break;
631 case IMSG_RECONF_END:
632 merge_config(ldeconf, nconf);
633 ldp_clear_config(nconf);
634 nconf = NULL;
635 break;
636 case IMSG_DEBUG_UPDATE:
637 if (imsg.hdr.len != IMSG_HEADER_SIZE +
638 sizeof(ldp_debug)) {
639 log_warnx("%s: wrong imsg len", __func__);
640 break;
641 }
642 memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
643 break;
644 default:
645 log_debug("%s: unexpected imsg %d", __func__,
646 imsg.hdr.type);
647 break;
648 }
649 imsg_free(&imsg);
650 }
651 if (!shut)
652 imsg_event_add(iev);
653 else {
654 /* this pipe is dead, so remove the event handlers and exit */
655 THREAD_READ_OFF(iev->ev_read);
656 THREAD_WRITE_OFF(iev->ev_write);
657 lde_shutdown();
658 }
659
660 return (0);
661 }
662
663 int
664 lde_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
665 {
666 return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
667 }
668
669 uint32_t
670 lde_update_label(struct fec_node *fn)
671 {
672 struct fec_nh *fnh;
673 int connected = 0;
674
675 LIST_FOREACH(fnh, &fn->nexthops, entry) {
676 if (fnh->flags & F_FEC_NH_CONNECTED) {
677 connected = 1;
678 break;
679 }
680 }
681
682 /* should we allocate a label for this fec? */
683 switch (fn->fec.type) {
684 case FEC_TYPE_IPV4:
685 if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
686 fn->fec.u.ipv4.prefixlen != 32)
687 return (NO_LABEL);
688 if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
689 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
690 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
691 return (NO_LABEL);
692 break;
693 case FEC_TYPE_IPV6:
694 if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
695 fn->fec.u.ipv6.prefixlen != 128)
696 return (NO_LABEL);
697 if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
698 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
699 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
700 return (NO_LABEL);
701 break;
702 default:
703 break;
704 }
705
706 if (connected) {
707 /* choose implicit or explicit-null depending on configuration */
708 switch (fn->fec.type) {
709 case FEC_TYPE_IPV4:
710 if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
711 return (MPLS_LABEL_IMPLNULL);
712 if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
713 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
714 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
715 return (MPLS_LABEL_IMPLNULL);
716 return (MPLS_LABEL_IPV4NULL);
717 case FEC_TYPE_IPV6:
718 if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
719 return (MPLS_LABEL_IMPLNULL);
720 if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
721 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
722 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
723 return (MPLS_LABEL_IMPLNULL);
724 return (MPLS_LABEL_IPV6NULL);
725 default:
726 fatalx("lde_update_label: unexpected fec type");
727 break;
728 }
729 }
730
731 /* preserve current label if there's no need to update it */
732 if (fn->local_label != NO_LABEL &&
733 fn->local_label > MPLS_LABEL_RESERVED_MAX)
734 return (fn->local_label);
735
736 return lde_get_next_label ();
737 }
738
739 void
740 lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
741 {
742 struct kroute kr;
743 struct zapi_pw zpw;
744 struct l2vpn_pw *pw;
745
746 switch (fn->fec.type) {
747 case FEC_TYPE_IPV4:
748 memset(&kr, 0, sizeof(kr));
749 kr.af = AF_INET;
750 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
751 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
752 kr.nexthop.v4 = fnh->nexthop.v4;
753 kr.ifindex = fnh->ifindex;
754 kr.local_label = fn->local_label;
755 kr.remote_label = fnh->remote_label;
756 kr.priority = fnh->priority;
757
758 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
759 sizeof(kr));
760 break;
761 case FEC_TYPE_IPV6:
762 memset(&kr, 0, sizeof(kr));
763 kr.af = AF_INET6;
764 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
765 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
766 kr.nexthop.v6 = fnh->nexthop.v6;
767 kr.ifindex = fnh->ifindex;
768 kr.local_label = fn->local_label;
769 kr.remote_label = fnh->remote_label;
770 kr.priority = fnh->priority;
771
772 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
773 sizeof(kr));
774 break;
775 case FEC_TYPE_PWID:
776 if (fn->local_label == NO_LABEL ||
777 fnh->remote_label == NO_LABEL)
778 return;
779
780 pw = (struct l2vpn_pw *) fn->data;
781 pw2zpw(pw, &zpw);
782 zpw.local_label = fn->local_label;
783 zpw.remote_label = fnh->remote_label;
784 lde_imsg_compose_parent(IMSG_KPW_SET, 0, &zpw, sizeof(zpw));
785 break;
786 }
787 }
788
789 void
790 lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
791 {
792 struct kroute kr;
793 struct zapi_pw zpw;
794 struct l2vpn_pw *pw;
795
796 switch (fn->fec.type) {
797 case FEC_TYPE_IPV4:
798 memset(&kr, 0, sizeof(kr));
799 kr.af = AF_INET;
800 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
801 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
802 kr.nexthop.v4 = fnh->nexthop.v4;
803 kr.ifindex = fnh->ifindex;
804 kr.local_label = fn->local_label;
805 kr.remote_label = fnh->remote_label;
806 kr.priority = fnh->priority;
807
808 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
809 sizeof(kr));
810 break;
811 case FEC_TYPE_IPV6:
812 memset(&kr, 0, sizeof(kr));
813 kr.af = AF_INET6;
814 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
815 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
816 kr.nexthop.v6 = fnh->nexthop.v6;
817 kr.ifindex = fnh->ifindex;
818 kr.local_label = fn->local_label;
819 kr.remote_label = fnh->remote_label;
820 kr.priority = fnh->priority;
821
822 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
823 sizeof(kr));
824 break;
825 case FEC_TYPE_PWID:
826 pw = (struct l2vpn_pw *) fn->data;
827 pw2zpw(pw, &zpw);
828 zpw.local_label = fn->local_label;
829 zpw.remote_label = fnh->remote_label;
830 lde_imsg_compose_parent(IMSG_KPW_UNSET, 0, &zpw, sizeof(zpw));
831 break;
832 }
833 }
834
835 void
836 lde_fec2map(struct fec *fec, struct map *map)
837 {
838 memset(map, 0, sizeof(*map));
839
840 switch (fec->type) {
841 case FEC_TYPE_IPV4:
842 map->type = MAP_TYPE_PREFIX;
843 map->fec.prefix.af = AF_INET;
844 map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
845 map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
846 break;
847 case FEC_TYPE_IPV6:
848 map->type = MAP_TYPE_PREFIX;
849 map->fec.prefix.af = AF_INET6;
850 map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
851 map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
852 break;
853 case FEC_TYPE_PWID:
854 map->type = MAP_TYPE_PWID;
855 map->fec.pwid.type = fec->u.pwid.type;
856 map->fec.pwid.group_id = 0;
857 map->flags |= F_MAP_PW_ID;
858 map->fec.pwid.pwid = fec->u.pwid.pwid;
859 break;
860 }
861 }
862
863 void
864 lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
865 {
866 memset(fec, 0, sizeof(*fec));
867
868 switch (map->type) {
869 case MAP_TYPE_PREFIX:
870 switch (map->fec.prefix.af) {
871 case AF_INET:
872 fec->type = FEC_TYPE_IPV4;
873 fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
874 fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
875 break;
876 case AF_INET6:
877 fec->type = FEC_TYPE_IPV6;
878 fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
879 fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
880 break;
881 default:
882 fatalx("lde_map2fec: unknown af");
883 break;
884 }
885 break;
886 case MAP_TYPE_PWID:
887 fec->type = FEC_TYPE_PWID;
888 fec->u.pwid.type = map->fec.pwid.type;
889 fec->u.pwid.pwid = map->fec.pwid.pwid;
890 fec->u.pwid.lsr_id = lsr_id;
891 break;
892 }
893 }
894
895 void
896 lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
897 {
898 struct lde_wdraw *lw;
899 struct lde_map *me;
900 struct lde_req *lre;
901 struct map map;
902 struct l2vpn_pw *pw;
903
904 /*
905 * We shouldn't send a new label mapping if we have a pending
906 * label release to receive. In this case, schedule to send a
907 * label mapping as soon as a label release is received.
908 */
909 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
910 if (lw) {
911 if (!fec_find(&ln->sent_map_pending, &fn->fec)) {
912 debug_evt("%s: FEC %s: scheduling to send label "
913 "mapping later (waiting for pending label release)",
914 __func__, log_fec(&fn->fec));
915 lde_map_pending_add(ln, fn);
916 }
917 return;
918 }
919
920 /*
921 * This function skips SL.1 - 3 and SL.9 - 14 because the label
922 * allocation is done way earlier (because of the merging nature of
923 * ldpd).
924 */
925
926 lde_fec2map(&fn->fec, &map);
927 switch (fn->fec.type) {
928 case FEC_TYPE_IPV4:
929 if (!ln->v4_enabled)
930 return;
931 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_to,
932 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
933 return;
934 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_for,
935 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
936 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
937 return;
938 break;
939 case FEC_TYPE_IPV6:
940 if (!ln->v6_enabled)
941 return;
942 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_to,
943 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
944 return;
945 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_for,
946 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
947 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
948 return;
949 break;
950 case FEC_TYPE_PWID:
951 pw = (struct l2vpn_pw *) fn->data;
952 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
953 /* not the remote end of the pseudowire */
954 return;
955
956 map.flags |= F_MAP_PW_IFMTU;
957 map.fec.pwid.ifmtu = pw->l2vpn->mtu;
958 if (pw->flags & F_PW_CWORD)
959 map.flags |= F_MAP_PW_CWORD;
960 if (pw->flags & F_PW_STATUSTLV) {
961 map.flags |= F_MAP_PW_STATUS;
962 map.pw_status = pw->local_status;
963 }
964 break;
965 }
966 map.label = fn->local_label;
967
968 /* SL.6: is there a pending request for this mapping? */
969 lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
970 if (lre) {
971 /* set label request msg id in the mapping response. */
972 map.requestid = lre->msg_id;
973 map.flags = F_MAP_REQ_ID;
974
975 /* SL.7: delete record of pending request */
976 lde_req_del(ln, lre, 0);
977 }
978
979 /* SL.4: send label mapping */
980 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
981 &map, sizeof(map));
982 if (single)
983 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
984 NULL, 0);
985
986 /* SL.5: record sent label mapping */
987 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
988 if (me == NULL)
989 me = lde_map_add(ln, fn, 1);
990 me->map = map;
991 }
992
993 void
994 lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn,
995 struct map *wcard, struct status_tlv *st)
996 {
997 struct lde_wdraw *lw;
998 struct map map;
999 struct fec *f;
1000 struct l2vpn_pw *pw;
1001
1002 if (fn) {
1003 lde_fec2map(&fn->fec, &map);
1004 switch (fn->fec.type) {
1005 case FEC_TYPE_IPV4:
1006 if (!ln->v4_enabled)
1007 return;
1008 break;
1009 case FEC_TYPE_IPV6:
1010 if (!ln->v6_enabled)
1011 return;
1012 break;
1013 case FEC_TYPE_PWID:
1014 pw = (struct l2vpn_pw *) fn->data;
1015 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1016 /* not the remote end of the pseudowire */
1017 return;
1018
1019 if (pw->flags & F_PW_CWORD)
1020 map.flags |= F_MAP_PW_CWORD;
1021 break;
1022 }
1023 map.label = fn->local_label;
1024 } else
1025 memcpy(&map, wcard, sizeof(map));
1026
1027 if (st) {
1028 map.st.status_code = st->status_code;
1029 map.st.msg_id = st->msg_id;
1030 map.st.msg_type = st->msg_type;
1031 map.flags |= F_MAP_STATUS;
1032 }
1033
1034 /* SWd.1: send label withdraw. */
1035 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
1036 &map, sizeof(map));
1037 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
1038
1039 /* SWd.2: record label withdraw. */
1040 if (fn) {
1041 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
1042 if (lw == NULL)
1043 lw = lde_wdraw_add(ln, fn);
1044 lw->label = map.label;
1045 } else {
1046 struct lde_map *me;
1047
1048 RB_FOREACH(f, fec_tree, &ft) {
1049 fn = (struct fec_node *)f;
1050 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
1051 if (lde_wildcard_apply(wcard, &fn->fec, me) == 0)
1052 continue;
1053
1054 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
1055 &fn->fec);
1056 if (lw == NULL)
1057 lw = lde_wdraw_add(ln, fn);
1058 lw->label = map.label;
1059 }
1060 }
1061 }
1062
1063 void
1064 lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label)
1065 {
1066 struct map wcard;
1067
1068 memset(&wcard, 0, sizeof(wcard));
1069 wcard.type = MAP_TYPE_WILDCARD;
1070 wcard.label = label;
1071 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1072 }
1073
1074 void
1075 lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af,
1076 uint32_t label)
1077 {
1078 struct map wcard;
1079
1080 memset(&wcard, 0, sizeof(wcard));
1081 wcard.type = MAP_TYPE_TYPED_WCARD;
1082 wcard.fec.twcard.type = MAP_TYPE_PREFIX;
1083 wcard.fec.twcard.u.prefix_af = af;
1084 wcard.label = label;
1085 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1086 }
1087
1088 void
1089 lde_send_labelwithdraw_twcard_pwid(struct lde_nbr *ln, uint16_t pw_type,
1090 uint32_t label)
1091 {
1092 struct map wcard;
1093
1094 memset(&wcard, 0, sizeof(wcard));
1095 wcard.type = MAP_TYPE_TYPED_WCARD;
1096 wcard.fec.twcard.type = MAP_TYPE_PWID;
1097 wcard.fec.twcard.u.pw_type = pw_type;
1098 wcard.label = label;
1099 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1100 }
1101
1102 void
1103 lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type,
1104 uint32_t group_id)
1105 {
1106 struct map wcard;
1107
1108 memset(&wcard, 0, sizeof(wcard));
1109 wcard.type = MAP_TYPE_PWID;
1110 wcard.fec.pwid.type = pw_type;
1111 wcard.fec.pwid.group_id = group_id;
1112 /* we can not append a Label TLV when using PWid group wildcards. */
1113 wcard.label = NO_LABEL;
1114 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1115 }
1116
1117 void
1118 lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
1119 struct map *wcard, uint32_t label)
1120 {
1121 struct map map;
1122 struct l2vpn_pw *pw;
1123
1124 if (fn) {
1125 lde_fec2map(&fn->fec, &map);
1126 switch (fn->fec.type) {
1127 case FEC_TYPE_IPV4:
1128 if (!ln->v4_enabled)
1129 return;
1130 break;
1131 case FEC_TYPE_IPV6:
1132 if (!ln->v6_enabled)
1133 return;
1134 break;
1135 case FEC_TYPE_PWID:
1136 pw = (struct l2vpn_pw *) fn->data;
1137 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1138 /* not the remote end of the pseudowire */
1139 return;
1140
1141 if (pw->flags & F_PW_CWORD)
1142 map.flags |= F_MAP_PW_CWORD;
1143 break;
1144 }
1145 } else
1146 memcpy(&map, wcard, sizeof(map));
1147 map.label = label;
1148
1149 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
1150 &map, sizeof(map));
1151 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
1152 }
1153
1154 void
1155 lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
1156 uint16_t msg_type)
1157 {
1158 struct notify_msg nm;
1159
1160 memset(&nm, 0, sizeof(nm));
1161 nm.status_code = status_code;
1162 /* 'msg_id' and 'msg_type' should be in network byte order */
1163 nm.msg_id = msg_id;
1164 nm.msg_type = msg_type;
1165
1166 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1167 &nm, sizeof(nm));
1168 }
1169
1170 void
1171 lde_send_notification_eol_prefix(struct lde_nbr *ln, int af)
1172 {
1173 struct notify_msg nm;
1174
1175 memset(&nm, 0, sizeof(nm));
1176 nm.status_code = S_ENDOFLIB;
1177 nm.fec.type = MAP_TYPE_TYPED_WCARD;
1178 nm.fec.fec.twcard.type = MAP_TYPE_PREFIX;
1179 nm.fec.fec.twcard.u.prefix_af = af;
1180 nm.flags |= F_NOTIF_FEC;
1181
1182 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1183 &nm, sizeof(nm));
1184 }
1185
1186 void
1187 lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
1188 {
1189 struct notify_msg nm;
1190
1191 memset(&nm, 0, sizeof(nm));
1192 nm.status_code = S_ENDOFLIB;
1193 nm.fec.type = MAP_TYPE_TYPED_WCARD;
1194 nm.fec.fec.twcard.type = MAP_TYPE_PWID;
1195 nm.fec.fec.twcard.u.pw_type = pw_type;
1196 nm.flags |= F_NOTIF_FEC;
1197
1198 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1199 &nm, sizeof(nm));
1200 }
1201
1202 static __inline int
1203 lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
1204 {
1205 return (a->peerid - b->peerid);
1206 }
1207
1208 static struct lde_nbr *
1209 lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
1210 {
1211 struct lde_nbr *ln;
1212
1213 if ((ln = calloc(1, sizeof(*ln))) == NULL)
1214 fatal(__func__);
1215
1216 ln->id = new->id;
1217 ln->v4_enabled = new->v4_enabled;
1218 ln->v6_enabled = new->v6_enabled;
1219 ln->flags = new->flags;
1220 ln->peerid = peerid;
1221 fec_init(&ln->recv_map);
1222 fec_init(&ln->sent_map);
1223 fec_init(&ln->sent_map_pending);
1224 fec_init(&ln->recv_req);
1225 fec_init(&ln->sent_req);
1226 fec_init(&ln->sent_wdraw);
1227
1228 TAILQ_INIT(&ln->addr_list);
1229
1230 if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
1231 fatalx("lde_nbr_new: RB_INSERT failed");
1232
1233 return (ln);
1234 }
1235
1236 static void
1237 lde_nbr_del(struct lde_nbr *ln)
1238 {
1239 struct fec *f;
1240 struct fec_node *fn;
1241 struct fec_nh *fnh;
1242 struct l2vpn_pw *pw;
1243
1244 if (ln == NULL)
1245 return;
1246
1247 /* uninstall received mappings */
1248 RB_FOREACH(f, fec_tree, &ft) {
1249 fn = (struct fec_node *)f;
1250
1251 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1252 switch (f->type) {
1253 case FEC_TYPE_IPV4:
1254 case FEC_TYPE_IPV6:
1255 if (!lde_address_find(ln, fnh->af,
1256 &fnh->nexthop))
1257 continue;
1258 break;
1259 case FEC_TYPE_PWID:
1260 if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1261 continue;
1262 pw = (struct l2vpn_pw *) fn->data;
1263 if (pw)
1264 l2vpn_pw_reset(pw);
1265 break;
1266 default:
1267 break;
1268 }
1269
1270 lde_send_delete_klabel(fn, fnh);
1271 fnh->remote_label = NO_LABEL;
1272 }
1273 }
1274
1275 lde_address_list_free(ln);
1276
1277 fec_clear(&ln->recv_map, lde_map_free);
1278 fec_clear(&ln->sent_map, lde_map_free);
1279 fec_clear(&ln->sent_map_pending, free);
1280 fec_clear(&ln->recv_req, free);
1281 fec_clear(&ln->sent_req, free);
1282 fec_clear(&ln->sent_wdraw, free);
1283
1284 RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1285
1286 free(ln);
1287 }
1288
1289 static struct lde_nbr *
1290 lde_nbr_find(uint32_t peerid)
1291 {
1292 struct lde_nbr ln;
1293
1294 ln.peerid = peerid;
1295
1296 return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1297 }
1298
1299 struct lde_nbr *
1300 lde_nbr_find_by_lsrid(struct in_addr addr)
1301 {
1302 struct lde_nbr *ln;
1303
1304 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1305 if (ln->id.s_addr == addr.s_addr)
1306 return (ln);
1307
1308 return (NULL);
1309 }
1310
1311 struct lde_nbr *
1312 lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1313 {
1314 struct lde_nbr *ln;
1315
1316 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1317 if (lde_address_find(ln, af, addr) != NULL)
1318 return (ln);
1319
1320 return (NULL);
1321 }
1322
1323 static void
1324 lde_nbr_clear(void)
1325 {
1326 struct lde_nbr *ln;
1327
1328 while ((ln = RB_ROOT(&lde_nbrs)) != NULL)
1329 lde_nbr_del(ln);
1330 }
1331
1332 static void
1333 lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1334 {
1335 struct fec *fec;
1336 struct fec_node *fn;
1337 struct fec_nh *fnh;
1338 struct lde_map *me;
1339
1340 RB_FOREACH(fec, fec_tree, &ln->recv_map) {
1341 fn = (struct fec_node *)fec_find(&ft, fec);
1342 switch (fec->type) {
1343 case FEC_TYPE_IPV4:
1344 if (lde_addr->af != AF_INET)
1345 continue;
1346 break;
1347 case FEC_TYPE_IPV6:
1348 if (lde_addr->af != AF_INET6)
1349 continue;
1350 break;
1351 default:
1352 continue;
1353 }
1354
1355 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1356 if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1357 &lde_addr->addr))
1358 continue;
1359
1360 if (removed) {
1361 lde_send_delete_klabel(fn, fnh);
1362 fnh->remote_label = NO_LABEL;
1363 } else {
1364 me = (struct lde_map *)fec;
1365 fnh->remote_label = me->map.label;
1366 lde_send_change_klabel(fn, fnh);
1367 }
1368 break;
1369 }
1370 }
1371 }
1372
1373 static __inline int
1374 lde_map_compare(struct lde_map *a, struct lde_map *b)
1375 {
1376 return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
1377 (union ldpd_addr *)&b->nexthop->id));
1378 }
1379
1380 struct lde_map *
1381 lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1382 {
1383 struct lde_map *me;
1384
1385 me = calloc(1, sizeof(*me));
1386 if (me == NULL)
1387 fatal(__func__);
1388
1389 me->fec = fn->fec;
1390 me->nexthop = ln;
1391
1392 if (sent) {
1393 RB_INSERT(lde_map_head, &fn->upstream, me);
1394 me->head = &fn->upstream;
1395 if (fec_insert(&ln->sent_map, &me->fec))
1396 log_warnx("failed to add %s to sent map",
1397 log_fec(&me->fec));
1398 /* XXX on failure more cleanup is needed */
1399 } else {
1400 RB_INSERT(lde_map_head, &fn->downstream, me);
1401 me->head = &fn->downstream;
1402 if (fec_insert(&ln->recv_map, &me->fec))
1403 log_warnx("failed to add %s to recv map",
1404 log_fec(&me->fec));
1405 }
1406
1407 return (me);
1408 }
1409
1410 void
1411 lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1412 {
1413 if (sent)
1414 fec_remove(&ln->sent_map, &me->fec);
1415 else
1416 fec_remove(&ln->recv_map, &me->fec);
1417
1418 lde_map_free(me);
1419 }
1420
1421 static void
1422 lde_map_free(void *ptr)
1423 {
1424 struct lde_map *map = ptr;
1425
1426 RB_REMOVE(lde_map_head, map->head, map);
1427 free(map);
1428 }
1429
1430 struct fec *
1431 lde_map_pending_add(struct lde_nbr *ln, struct fec_node *fn)
1432 {
1433 struct fec *map;
1434
1435 map = calloc(1, sizeof(*map));
1436 if (map == NULL)
1437 fatal(__func__);
1438
1439 *map = fn->fec;
1440 if (fec_insert(&ln->sent_map_pending, map))
1441 log_warnx("failed to add %s to sent map (pending)",
1442 log_fec(map));
1443
1444 return (map);
1445 }
1446
1447 void
1448 lde_map_pending_del(struct lde_nbr *ln, struct fec *map)
1449 {
1450 fec_remove(&ln->sent_map_pending, map);
1451 free(map);
1452 }
1453
1454 struct lde_req *
1455 lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1456 {
1457 struct fec_tree *t;
1458 struct lde_req *lre;
1459
1460 t = sent ? &ln->sent_req : &ln->recv_req;
1461
1462 lre = calloc(1, sizeof(*lre));
1463 if (lre != NULL) {
1464 lre->fec = *fec;
1465
1466 if (fec_insert(t, &lre->fec)) {
1467 log_warnx("failed to add %s to %s req",
1468 log_fec(&lre->fec), sent ? "sent" : "recv");
1469 free(lre);
1470 return (NULL);
1471 }
1472 }
1473
1474 return (lre);
1475 }
1476
1477 void
1478 lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1479 {
1480 if (sent)
1481 fec_remove(&ln->sent_req, &lre->fec);
1482 else
1483 fec_remove(&ln->recv_req, &lre->fec);
1484
1485 free(lre);
1486 }
1487
1488 struct lde_wdraw *
1489 lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1490 {
1491 struct lde_wdraw *lw;
1492
1493 lw = calloc(1, sizeof(*lw));
1494 if (lw == NULL)
1495 fatal(__func__);
1496
1497 lw->fec = fn->fec;
1498
1499 if (fec_insert(&ln->sent_wdraw, &lw->fec))
1500 log_warnx("failed to add %s to sent wdraw",
1501 log_fec(&lw->fec));
1502
1503 return (lw);
1504 }
1505
1506 void
1507 lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1508 {
1509 fec_remove(&ln->sent_wdraw, &lw->fec);
1510 free(lw);
1511 }
1512
1513 void
1514 lde_change_egress_label(int af)
1515 {
1516 struct lde_nbr *ln;
1517 struct fec *f;
1518 struct fec_node *fn;
1519
1520 /* explicitly withdraw all null labels */
1521 RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1522 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL);
1523 if (ln->v4_enabled)
1524 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL);
1525 if (ln->v6_enabled)
1526 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL);
1527 }
1528
1529 /* update label of connected routes */
1530 RB_FOREACH(f, fec_tree, &ft) {
1531 fn = (struct fec_node *)f;
1532 if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1533 continue;
1534
1535 switch (af) {
1536 case AF_INET:
1537 if (fn->fec.type != FEC_TYPE_IPV4)
1538 continue;
1539 break;
1540 case AF_INET6:
1541 if (fn->fec.type != FEC_TYPE_IPV6)
1542 continue;
1543 break;
1544 default:
1545 fatalx("lde_change_egress_label: unknown af");
1546 }
1547
1548 fn->local_label = lde_update_label(fn);
1549 if (fn->local_label != NO_LABEL)
1550 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1551 lde_send_labelmapping(ln, fn, 0);
1552 }
1553 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1554 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1555 NULL, 0);
1556 }
1557
1558 static int
1559 lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
1560 {
1561 struct lde_addr *new;
1562
1563 if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
1564 return (-1);
1565
1566 if ((new = calloc(1, sizeof(*new))) == NULL)
1567 fatal(__func__);
1568
1569 new->af = lde_addr->af;
1570 new->addr = lde_addr->addr;
1571 TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
1572
1573 /* reevaluate the previously received mappings from this neighbor */
1574 lde_nbr_addr_update(ln, lde_addr, 0);
1575
1576 return (0);
1577 }
1578
1579 static int
1580 lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
1581 {
1582 lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
1583 if (lde_addr == NULL)
1584 return (-1);
1585
1586 /* reevaluate the previously received mappings from this neighbor */
1587 lde_nbr_addr_update(ln, lde_addr, 1);
1588
1589 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1590 free(lde_addr);
1591
1592 return (0);
1593 }
1594
1595 struct lde_addr *
1596 lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
1597 {
1598 struct lde_addr *lde_addr;
1599
1600 TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
1601 if (lde_addr->af == af &&
1602 ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
1603 return (lde_addr);
1604
1605 return (NULL);
1606 }
1607
1608 static void
1609 lde_address_list_free(struct lde_nbr *ln)
1610 {
1611 struct lde_addr *lde_addr;
1612
1613 while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
1614 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1615 free(lde_addr);
1616 }
1617 }
1618
1619 static void
1620 lde_del_label_chunk(void *val)
1621 {
1622 free(val);
1623 }
1624 static int
1625 lde_get_label_chunk(void)
1626 {
1627 int ret;
1628 uint32_t start, end;
1629
1630 log_debug("Getting label chunk");
1631 ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
1632 if (ret < 0)
1633 {
1634 log_warnx("Error getting label chunk!");
1635 return -1;
1636 }
1637
1638 on_get_label_chunk_response(start, end);
1639
1640 return 0;
1641 }
1642 static void
1643 lde_label_list_init(void)
1644 {
1645 label_chunk_list = list_new();
1646 label_chunk_list->del = lde_del_label_chunk;
1647
1648 /* get first chunk */
1649 while (lde_get_label_chunk () != 0) {
1650 log_warnx("Error getting first label chunk!");
1651 sleep(1);
1652 }
1653 }
1654
1655 static void
1656 on_get_label_chunk_response(uint32_t start, uint32_t end)
1657 {
1658 struct label_chunk *new_label_chunk;
1659
1660 log_debug("Label Chunk assign: %u - %u", start, end);
1661
1662 new_label_chunk = calloc(1, sizeof(struct label_chunk));
1663 if (!new_label_chunk) {
1664 log_warn("Error trying to allocate label chunk %u - %u", start, end);
1665 return;
1666 }
1667
1668 new_label_chunk->start = start;
1669 new_label_chunk->end = end;
1670 new_label_chunk->used_mask = 0;
1671
1672 listnode_add(label_chunk_list, (void *)new_label_chunk);
1673
1674 /* let's update current if needed */
1675 if (!current_label_chunk)
1676 current_label_chunk = listtail(label_chunk_list);
1677 }
1678
1679 static uint32_t
1680 lde_get_next_label(void)
1681 {
1682 struct label_chunk *label_chunk;
1683 uint32_t i, pos, size;
1684 uint32_t label = NO_LABEL;
1685
1686 while (current_label_chunk) {
1687 label_chunk = listgetdata(current_label_chunk);
1688 if (!label_chunk)
1689 goto end;
1690
1691 /* try to get next free label in currently used label chunk */
1692 size = label_chunk->end - label_chunk->start + 1;
1693 for (i = 0, pos = 1; i < size; i++, pos <<= 1) {
1694 if (!(pos & label_chunk->used_mask)) {
1695 label_chunk->used_mask |= pos;
1696 label = label_chunk->start + i;
1697 goto end;
1698 }
1699 }
1700 current_label_chunk = listnextnode(current_label_chunk);
1701 }
1702
1703 end:
1704 /* we moved till the last chunk, or were not able to find a label,
1705 so let's ask for another one */
1706 if (!current_label_chunk || current_label_chunk == listtail(label_chunk_list)
1707 || label == NO_LABEL) {
1708 if (lde_get_label_chunk() != 0)
1709 log_warn("%s: Error getting label chunk!", __func__);
1710
1711 }
1712
1713 return label;
1714 }