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