]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/lde.c
ldpd: implement RFC 5918 (Typed Wildcard FEC)
[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 *);
05aac414 40static __inline int lde_nbr_compare(struct lde_nbr *,
8429abe0
RW
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:
0bcc2916 262 lde_check_release(&map, ln);
8429abe0
RW
263 break;
264 case IMSG_LABEL_WITHDRAW:
0bcc2916 265 lde_check_withdraw(&map, ln);
8429abe0
RW
266 break;
267 case IMSG_LABEL_ABORT:
268 /* not necessary */
269 break;
270 }
271 break;
272 case IMSG_ADDRESS_ADD:
273 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
274 fatalx("lde_dispatch_imsg: wrong imsg len");
275 memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
276
277 ln = lde_nbr_find(imsg.hdr.peerid);
278 if (ln == NULL) {
279 log_debug("%s: cannot find lde neighbor",
280 __func__);
281 break;
282 }
283 if (lde_address_add(ln, &lde_addr) < 0) {
284 log_debug("%s: cannot add address %s, it "
285 "already exists", __func__,
286 log_addr(lde_addr.af, &lde_addr.addr));
287 }
288 break;
289 case IMSG_ADDRESS_DEL:
290 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
291 fatalx("lde_dispatch_imsg: wrong imsg len");
292 memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
293
294 ln = lde_nbr_find(imsg.hdr.peerid);
295 if (ln == NULL) {
296 log_debug("%s: cannot find lde neighbor",
297 __func__);
298 break;
299 }
300 if (lde_address_del(ln, &lde_addr) < 0) {
301 log_debug("%s: cannot delete address %s, it "
302 "does not exist", __func__,
303 log_addr(lde_addr.af, &lde_addr.addr));
304 }
305 break;
306 case IMSG_NOTIFICATION:
307 if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm))
308 fatalx("lde_dispatch_imsg: wrong imsg len");
309 memcpy(&nm, imsg.data, sizeof(nm));
310
311 ln = lde_nbr_find(imsg.hdr.peerid);
312 if (ln == NULL) {
313 log_debug("%s: cannot find lde neighbor",
314 __func__);
315 break;
316 }
317
318 switch (nm.status_code) {
319 case S_PW_STATUS:
320 l2vpn_recv_pw_status(ln, &nm);
321 break;
322 default:
323 break;
324 }
325 break;
326 case IMSG_NEIGHBOR_UP:
327 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
328 sizeof(struct lde_nbr))
329 fatalx("lde_dispatch_imsg: wrong imsg len");
330
331 if (lde_nbr_find(imsg.hdr.peerid))
332 fatalx("lde_dispatch_imsg: "
333 "neighbor already exists");
334 lde_nbr_new(imsg.hdr.peerid, imsg.data);
335 break;
336 case IMSG_NEIGHBOR_DOWN:
337 lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
338 break;
339 case IMSG_CTL_SHOW_LIB:
340 rt_dump(imsg.hdr.pid);
341
342 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
343 imsg.hdr.pid, NULL, 0);
344 break;
345 case IMSG_CTL_SHOW_L2VPN_PW:
346 l2vpn_pw_ctl(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_BINDING:
352 l2vpn_binding_ctl(imsg.hdr.pid);
353
354 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
355 imsg.hdr.pid, NULL, 0);
356 break;
8429abe0
RW
357 default:
358 log_debug("%s: unexpected imsg %d", __func__,
359 imsg.hdr.type);
360 break;
361 }
362 imsg_free(&imsg);
363 }
364 if (!shut)
365 imsg_event_add(iev);
366 else {
eac6e3f0
RW
367 /* this pipe is dead, so remove the event handlers and exit */
368 THREAD_READ_OFF(iev->ev_read);
369 THREAD_WRITE_OFF(iev->ev_write);
370 lde_shutdown();
8429abe0 371 }
eac6e3f0
RW
372
373 return (0);
8429abe0
RW
374}
375
376/* ARGSUSED */
eac6e3f0
RW
377static int
378lde_dispatch_parent(struct thread *thread)
8429abe0
RW
379{
380 static struct ldpd_conf *nconf;
381 struct iface *niface;
382 struct tnbr *ntnbr;
383 struct nbr_params *nnbrp;
384 static struct l2vpn *nl2vpn;
385 struct l2vpn_if *nlif;
386 struct l2vpn_pw *npw;
387 struct imsg imsg;
388 struct kroute kr;
eac6e3f0
RW
389 int fd = THREAD_FD(thread);
390 struct imsgev *iev = THREAD_ARG(thread);
8429abe0
RW
391 struct imsgbuf *ibuf = &iev->ibuf;
392 ssize_t n;
393 int shut = 0;
394 struct fec fec;
395
eac6e3f0
RW
396 iev->ev_read = NULL;
397
398 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
399 fatal("imsg_read error");
400 if (n == 0) /* connection closed */
401 shut = 1;
8429abe0
RW
402
403 for (;;) {
404 if ((n = imsg_get(ibuf, &imsg)) == -1)
405 fatal("lde_dispatch_parent: imsg_get error");
406 if (n == 0)
407 break;
408
409 switch (imsg.hdr.type) {
410 case IMSG_NETWORK_ADD:
8cb1fc45 411 case IMSG_NETWORK_UPDATE:
8429abe0
RW
412 if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
413 log_warnx("%s: wrong imsg len", __func__);
414 break;
415 }
416 memcpy(&kr, imsg.data, sizeof(kr));
417
418 switch (kr.af) {
419 case AF_INET:
420 fec.type = FEC_TYPE_IPV4;
421 fec.u.ipv4.prefix = kr.prefix.v4;
422 fec.u.ipv4.prefixlen = kr.prefixlen;
423 break;
424 case AF_INET6:
425 fec.type = FEC_TYPE_IPV6;
426 fec.u.ipv6.prefix = kr.prefix.v6;
427 fec.u.ipv6.prefixlen = kr.prefixlen;
428 break;
429 default:
430 fatalx("lde_dispatch_parent: unknown af");
431 }
432
433 switch (imsg.hdr.type) {
434 case IMSG_NETWORK_ADD:
435 lde_kernel_insert(&fec, kr.af, &kr.nexthop,
88d88a9c
RW
436 kr.ifindex, kr.priority,
437 kr.flags & F_CONNECTED, NULL);
8429abe0 438 break;
8cb1fc45
RW
439 case IMSG_NETWORK_UPDATE:
440 lde_kernel_update(&fec);
8429abe0
RW
441 break;
442 }
443 break;
444 case IMSG_SOCKET_IPC:
445 if (iev_ldpe) {
446 log_warnx("%s: received unexpected imsg fd "
447 "to ldpe", __func__);
448 break;
449 }
450 if ((fd = imsg.fd) == -1) {
451 log_warnx("%s: expected to receive imsg fd to "
452 "ldpe but didn't receive any", __func__);
453 break;
454 }
455
456 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
457 fatal(NULL);
458 imsg_init(&iev_ldpe->ibuf, fd);
eac6e3f0
RW
459 iev_ldpe->handler_read = lde_dispatch_imsg;
460 iev_ldpe->ev_read = thread_add_read(master,
461 iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd);
462 iev_ldpe->handler_write = ldp_write_handler;
463 iev_ldpe->ev_write = NULL;
8429abe0
RW
464 break;
465 case IMSG_RECONF_CONF:
466 if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
467 NULL)
468 fatal(NULL);
469 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
470
7d3d7491 471 RB_INIT(&nconf->iface_tree);
7989cdba 472 RB_INIT(&nconf->tnbr_tree);
76c4abd1 473 RB_INIT(&nconf->nbrp_tree);
90d7e7bd 474 RB_INIT(&nconf->l2vpn_tree);
8429abe0
RW
475 break;
476 case IMSG_RECONF_IFACE:
477 if ((niface = malloc(sizeof(struct iface))) == NULL)
478 fatal(NULL);
479 memcpy(niface, imsg.data, sizeof(struct iface));
480
481 LIST_INIT(&niface->addr_list);
057d48bd
RW
482 RB_INIT(&niface->ipv4.adj_tree);
483 RB_INIT(&niface->ipv6.adj_tree);
8429abe0
RW
484 niface->ipv4.iface = niface;
485 niface->ipv6.iface = niface;
486
7d3d7491 487 RB_INSERT(iface_head, &nconf->iface_tree, niface);
8429abe0
RW
488 break;
489 case IMSG_RECONF_TNBR:
490 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
491 fatal(NULL);
492 memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
493
7989cdba 494 RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
8429abe0
RW
495 break;
496 case IMSG_RECONF_NBRP:
497 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
498 fatal(NULL);
499 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
500
76c4abd1 501 RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
8429abe0
RW
502 break;
503 case IMSG_RECONF_L2VPN:
504 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
505 fatal(NULL);
506 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
507
029c1958 508 RB_INIT(&nl2vpn->if_tree);
20bacaeb
RW
509 RB_INIT(&nl2vpn->pw_tree);
510 RB_INIT(&nl2vpn->pw_inactive_tree);
8429abe0 511
90d7e7bd 512 RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
8429abe0
RW
513 break;
514 case IMSG_RECONF_L2VPN_IF:
515 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
516 fatal(NULL);
517 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
518
519 nlif->l2vpn = nl2vpn;
029c1958 520 RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
8429abe0
RW
521 break;
522 case IMSG_RECONF_L2VPN_PW:
523 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
524 fatal(NULL);
525 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
526
527 npw->l2vpn = nl2vpn;
20bacaeb 528 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
8429abe0 529 break;
eac6e3f0
RW
530 case IMSG_RECONF_L2VPN_IPW:
531 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
532 fatal(NULL);
533 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
534
535 npw->l2vpn = nl2vpn;
20bacaeb 536 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
eac6e3f0 537 break;
8429abe0
RW
538 case IMSG_RECONF_END:
539 merge_config(ldeconf, nconf);
540 nconf = NULL;
541 break;
eac6e3f0
RW
542 case IMSG_DEBUG_UPDATE:
543 if (imsg.hdr.len != IMSG_HEADER_SIZE +
544 sizeof(ldp_debug)) {
545 log_warnx("%s: wrong imsg len", __func__);
546 break;
547 }
548 memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
549 break;
8429abe0
RW
550 default:
551 log_debug("%s: unexpected imsg %d", __func__,
552 imsg.hdr.type);
553 break;
554 }
555 imsg_free(&imsg);
556 }
557 if (!shut)
558 imsg_event_add(iev);
559 else {
eac6e3f0
RW
560 /* this pipe is dead, so remove the event handlers and exit */
561 THREAD_READ_OFF(iev->ev_read);
562 THREAD_WRITE_OFF(iev->ev_write);
563 lde_shutdown();
8429abe0 564 }
eac6e3f0
RW
565
566 return (0);
8429abe0
RW
567}
568
45a8eba9
RW
569int
570lde_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
571{
572 return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
573}
574
8429abe0 575uint32_t
8cb1fc45 576lde_update_label(struct fec_node *fn)
8429abe0 577{
8cb1fc45
RW
578 static uint32_t label = MPLS_LABEL_RESERVED_MAX;
579 struct fec_nh *fnh;
580 int connected = 0;
581
582 LIST_FOREACH(fnh, &fn->nexthops, entry) {
583 if (fnh->flags & F_FEC_NH_CONNECTED) {
584 connected = 1;
585 break;
586 }
587 }
8429abe0 588
45a8eba9 589 /* should we allocate a label for this fec? */
8cb1fc45 590 switch (fn->fec.type) {
45a8eba9
RW
591 case FEC_TYPE_IPV4:
592 if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
8cb1fc45 593 fn->fec.u.ipv4.prefixlen != 32)
45a8eba9
RW
594 return (NO_LABEL);
595 if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
8cb1fc45
RW
596 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
597 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
598 return (NO_LABEL);
599 break;
600 case FEC_TYPE_IPV6:
601 if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
8cb1fc45 602 fn->fec.u.ipv6.prefixlen != 128)
45a8eba9
RW
603 return (NO_LABEL);
604 if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
8cb1fc45
RW
605 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
606 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
607 return (NO_LABEL);
608 break;
609 default:
45a8eba9
RW
610 break;
611 }
612
613 if (connected) {
614 /* choose implicit or explicit-null depending on configuration */
8cb1fc45 615 switch (fn->fec.type) {
45a8eba9
RW
616 case FEC_TYPE_IPV4:
617 if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
618 return (MPLS_LABEL_IMPLNULL);
619 if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
8cb1fc45
RW
620 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
621 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
622 return (MPLS_LABEL_IMPLNULL);
623 return (MPLS_LABEL_IPV4NULL);
624 case FEC_TYPE_IPV6:
625 if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
626 return (MPLS_LABEL_IMPLNULL);
627 if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
8cb1fc45
RW
628 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
629 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
630 return (MPLS_LABEL_IMPLNULL);
631 return (MPLS_LABEL_IPV6NULL);
632 default:
8cb1fc45 633 fatalx("lde_update_label: unexpected fec type");
45a8eba9
RW
634 break;
635 }
636 }
637
8cb1fc45
RW
638 /* preserve current label if there's no need to update it */
639 if (fn->local_label != NO_LABEL &&
640 fn->local_label > MPLS_LABEL_RESERVED_MAX)
641 return (fn->local_label);
642
eac6e3f0
RW
643 /*
644 * TODO: request label to zebra or define a range of labels for ldpd.
645 */
646
8429abe0
RW
647 label++;
648 return (label);
649}
650
651void
652lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
653{
654 struct kroute kr;
655 struct kpw kpw;
656 struct l2vpn_pw *pw;
657
658 switch (fn->fec.type) {
659 case FEC_TYPE_IPV4:
660 memset(&kr, 0, sizeof(kr));
661 kr.af = AF_INET;
662 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
663 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
664 kr.nexthop.v4 = fnh->nexthop.v4;
88d88a9c 665 kr.ifindex = fnh->ifindex;
8429abe0
RW
666 kr.local_label = fn->local_label;
667 kr.remote_label = fnh->remote_label;
668 kr.priority = fnh->priority;
669
670 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
671 sizeof(kr));
672
673 if (fn->fec.u.ipv4.prefixlen == 32)
674 l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
675 &fn->fec.u.ipv4.prefix);
676 break;
677 case FEC_TYPE_IPV6:
678 memset(&kr, 0, sizeof(kr));
679 kr.af = AF_INET6;
680 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
681 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
682 kr.nexthop.v6 = fnh->nexthop.v6;
88d88a9c 683 kr.ifindex = fnh->ifindex;
8429abe0
RW
684 kr.local_label = fn->local_label;
685 kr.remote_label = fnh->remote_label;
686 kr.priority = fnh->priority;
687
688 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
689 sizeof(kr));
690
691 if (fn->fec.u.ipv6.prefixlen == 128)
692 l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
693 &fn->fec.u.ipv6.prefix);
694 break;
695 case FEC_TYPE_PWID:
696 if (fn->local_label == NO_LABEL ||
697 fnh->remote_label == NO_LABEL)
698 return;
699
700 pw = (struct l2vpn_pw *) fn->data;
701 pw->flags |= F_PW_STATUS_UP;
702
703 memset(&kpw, 0, sizeof(kpw));
704 kpw.ifindex = pw->ifindex;
705 kpw.pw_type = fn->fec.u.pwid.type;
706 kpw.af = pw->af;
707 kpw.nexthop = pw->addr;
708 kpw.local_label = fn->local_label;
709 kpw.remote_label = fnh->remote_label;
710 kpw.flags = pw->flags;
711
712 lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
713 sizeof(kpw));
714 break;
715 }
716}
717
718void
719lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
720{
721 struct kroute kr;
722 struct kpw kpw;
723 struct l2vpn_pw *pw;
724
725 switch (fn->fec.type) {
726 case FEC_TYPE_IPV4:
727 memset(&kr, 0, sizeof(kr));
728 kr.af = AF_INET;
729 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
730 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
731 kr.nexthop.v4 = fnh->nexthop.v4;
88d88a9c 732 kr.ifindex = fnh->ifindex;
8429abe0
RW
733 kr.local_label = fn->local_label;
734 kr.remote_label = fnh->remote_label;
735 kr.priority = fnh->priority;
736
737 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
738 sizeof(kr));
739
740 if (fn->fec.u.ipv4.prefixlen == 32)
741 l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
742 &fn->fec.u.ipv4.prefix);
743 break;
744 case FEC_TYPE_IPV6:
745 memset(&kr, 0, sizeof(kr));
746 kr.af = AF_INET6;
747 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
748 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
749 kr.nexthop.v6 = fnh->nexthop.v6;
88d88a9c 750 kr.ifindex = fnh->ifindex;
8429abe0
RW
751 kr.local_label = fn->local_label;
752 kr.remote_label = fnh->remote_label;
753 kr.priority = fnh->priority;
754
755 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
756 sizeof(kr));
757
758 if (fn->fec.u.ipv6.prefixlen == 128)
759 l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
760 &fn->fec.u.ipv6.prefix);
761 break;
762 case FEC_TYPE_PWID:
763 pw = (struct l2vpn_pw *) fn->data;
764 if (!(pw->flags & F_PW_STATUS_UP))
765 return;
766 pw->flags &= ~F_PW_STATUS_UP;
767
768 memset(&kpw, 0, sizeof(kpw));
769 kpw.ifindex = pw->ifindex;
770 kpw.pw_type = fn->fec.u.pwid.type;
771 kpw.af = pw->af;
772 kpw.nexthop = pw->addr;
773 kpw.local_label = fn->local_label;
774 kpw.remote_label = fnh->remote_label;
775 kpw.flags = pw->flags;
776
777 lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
778 sizeof(kpw));
779 break;
780 }
781}
782
783void
784lde_fec2map(struct fec *fec, struct map *map)
785{
786 memset(map, 0, sizeof(*map));
787
788 switch (fec->type) {
789 case FEC_TYPE_IPV4:
790 map->type = MAP_TYPE_PREFIX;
791 map->fec.prefix.af = AF_INET;
792 map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
793 map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
794 break;
795 case FEC_TYPE_IPV6:
796 map->type = MAP_TYPE_PREFIX;
797 map->fec.prefix.af = AF_INET6;
798 map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
799 map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
800 break;
801 case FEC_TYPE_PWID:
802 map->type = MAP_TYPE_PWID;
803 map->fec.pwid.type = fec->u.pwid.type;
804 map->fec.pwid.group_id = 0;
805 map->flags |= F_MAP_PW_ID;
806 map->fec.pwid.pwid = fec->u.pwid.pwid;
807 break;
808 }
809}
810
811void
812lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
813{
814 memset(fec, 0, sizeof(*fec));
815
816 switch (map->type) {
817 case MAP_TYPE_PREFIX:
818 switch (map->fec.prefix.af) {
819 case AF_INET:
820 fec->type = FEC_TYPE_IPV4;
821 fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
822 fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
823 break;
824 case AF_INET6:
825 fec->type = FEC_TYPE_IPV6;
826 fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
827 fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
828 break;
829 default:
830 fatalx("lde_map2fec: unknown af");
831 break;
832 }
833 break;
834 case MAP_TYPE_PWID:
835 fec->type = FEC_TYPE_PWID;
836 fec->u.pwid.type = map->fec.pwid.type;
837 fec->u.pwid.pwid = map->fec.pwid.pwid;
838 fec->u.pwid.lsr_id = lsr_id;
839 break;
840 }
841}
842
843void
844lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
845{
846 struct lde_req *lre;
847 struct lde_map *me;
848 struct map map;
849 struct l2vpn_pw *pw;
850
851 /*
852 * This function skips SL.1 - 3 and SL.9 - 14 because the label
853 * allocation is done way earlier (because of the merging nature of
854 * ldpd).
855 */
856
857 lde_fec2map(&fn->fec, &map);
858 switch (fn->fec.type) {
859 case FEC_TYPE_IPV4:
860 if (!ln->v4_enabled)
861 return;
45a8eba9
RW
862 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_to,
863 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
864 return;
865 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_for,
866 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
867 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
868 return;
8429abe0
RW
869 break;
870 case FEC_TYPE_IPV6:
871 if (!ln->v6_enabled)
872 return;
45a8eba9
RW
873 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_to,
874 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
875 return;
876 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_for,
877 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
878 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
879 return;
8429abe0
RW
880 break;
881 case FEC_TYPE_PWID:
882 pw = (struct l2vpn_pw *) fn->data;
883 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
884 /* not the remote end of the pseudowire */
885 return;
886
887 map.flags |= F_MAP_PW_IFMTU;
888 map.fec.pwid.ifmtu = pw->l2vpn->mtu;
889 if (pw->flags & F_PW_CWORD)
890 map.flags |= F_MAP_PW_CWORD;
891 if (pw->flags & F_PW_STATUSTLV) {
892 map.flags |= F_MAP_PW_STATUS;
893 /* VPLS are always up */
894 map.pw_status = PW_FORWARDING;
895 }
896 break;
897 }
898 map.label = fn->local_label;
899
900 /* SL.6: is there a pending request for this mapping? */
901 lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
902 if (lre) {
903 /* set label request msg id in the mapping response. */
904 map.requestid = lre->msg_id;
905 map.flags = F_MAP_REQ_ID;
906
907 /* SL.7: delete record of pending request */
908 lde_req_del(ln, lre, 0);
909 }
910
911 /* SL.4: send label mapping */
912 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
913 &map, sizeof(map));
914 if (single)
915 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
916 NULL, 0);
917
918 /* SL.5: record sent label mapping */
919 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
920 if (me == NULL)
921 me = lde_map_add(ln, fn, 1);
922 me->map = map;
923}
924
925void
0bcc2916
RW
926lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn,
927 struct map *wcard, struct status_tlv *st)
8429abe0
RW
928{
929 struct lde_wdraw *lw;
930 struct map map;
931 struct fec *f;
932 struct l2vpn_pw *pw;
933
934 if (fn) {
935 lde_fec2map(&fn->fec, &map);
936 switch (fn->fec.type) {
937 case FEC_TYPE_IPV4:
938 if (!ln->v4_enabled)
939 return;
940 break;
941 case FEC_TYPE_IPV6:
942 if (!ln->v6_enabled)
943 return;
944 break;
945 case FEC_TYPE_PWID:
946 pw = (struct l2vpn_pw *) fn->data;
947 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
948 /* not the remote end of the pseudowire */
949 return;
950
951 if (pw->flags & F_PW_CWORD)
952 map.flags |= F_MAP_PW_CWORD;
953 break;
954 }
955 map.label = fn->local_label;
0bcc2916
RW
956 } else
957 memcpy(&map, wcard, sizeof(map));
8429abe0
RW
958
959 if (st) {
960 map.st.status_code = st->status_code;
961 map.st.msg_id = st->msg_id;
962 map.st.msg_type = st->msg_type;
963 map.flags |= F_MAP_STATUS;
964 }
965
966 /* SWd.1: send label withdraw. */
967 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
968 &map, sizeof(map));
969 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
970
971 /* SWd.2: record label withdraw. */
972 if (fn) {
973 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
974 if (lw == NULL)
975 lw = lde_wdraw_add(ln, fn);
976 lw->label = map.label;
977 } else {
0bcc2916
RW
978 struct lde_map *me;
979
8429abe0
RW
980 RB_FOREACH(f, fec_tree, &ft) {
981 fn = (struct fec_node *)f;
0bcc2916
RW
982 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
983 if (lde_wildcard_apply(wcard, &fn->fec, me) == 0)
984 continue;
8429abe0
RW
985
986 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
987 &fn->fec);
988 if (lw == NULL)
989 lw = lde_wdraw_add(ln, fn);
990 lw->label = map.label;
991 }
992 }
993}
994
995void
0bcc2916 996lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label)
8429abe0 997{
0bcc2916 998 struct map wcard;
8429abe0 999
0bcc2916
RW
1000 memset(&wcard, 0, sizeof(wcard));
1001 wcard.type = MAP_TYPE_WILDCARD;
1002 wcard.label = label;
1003 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
8429abe0
RW
1004}
1005
d4afb819
RW
1006void
1007lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af,
1008 uint32_t label)
1009{
1010 struct map wcard;
1011
1012 memset(&wcard, 0, sizeof(wcard));
1013 wcard.type = MAP_TYPE_TYPED_WCARD;
1014 wcard.fec.twcard.type = MAP_TYPE_PREFIX;
1015 wcard.fec.twcard.u.prefix_af = af;
1016 wcard.label = label;
1017 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1018}
1019
8429abe0 1020void
0bcc2916
RW
1021lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type,
1022 uint32_t group_id)
1023{
1024 struct map wcard;
1025
1026 memset(&wcard, 0, sizeof(wcard));
1027 wcard.type = MAP_TYPE_PWID;
1028 wcard.fec.pwid.type = pw_type;
1029 wcard.fec.pwid.group_id = group_id;
1030 /* we can not append a Label TLV when using PWid group wildcards. */
1031 wcard.label = NO_LABEL;
1032 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1033}
1034
1035void
1036lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
1037 struct map *wcard, uint32_t label)
8429abe0
RW
1038{
1039 struct map map;
1040 struct l2vpn_pw *pw;
1041
1042 if (fn) {
1043 lde_fec2map(&fn->fec, &map);
1044 switch (fn->fec.type) {
1045 case FEC_TYPE_IPV4:
1046 if (!ln->v4_enabled)
1047 return;
1048 break;
1049 case FEC_TYPE_IPV6:
1050 if (!ln->v6_enabled)
1051 return;
1052 break;
1053 case FEC_TYPE_PWID:
1054 pw = (struct l2vpn_pw *) fn->data;
1055 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1056 /* not the remote end of the pseudowire */
1057 return;
1058
1059 if (pw->flags & F_PW_CWORD)
1060 map.flags |= F_MAP_PW_CWORD;
1061 break;
1062 }
0bcc2916
RW
1063 } else
1064 memcpy(&map, wcard, sizeof(map));
8429abe0
RW
1065 map.label = label;
1066
1067 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
1068 &map, sizeof(map));
1069 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
1070}
1071
1072void
05aac414 1073lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
8429abe0
RW
1074 uint16_t msg_type)
1075{
1076 struct notify_msg nm;
1077
1078 memset(&nm, 0, sizeof(nm));
1079 nm.status_code = status_code;
1080 /* 'msg_id' and 'msg_type' should be in network byte order */
1081 nm.msg_id = msg_id;
1082 nm.msg_type = msg_type;
1083
05aac414 1084 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
8429abe0
RW
1085 &nm, sizeof(nm));
1086}
1087
1088static __inline int
1089lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
1090{
1091 return (a->peerid - b->peerid);
1092}
1093
1094static struct lde_nbr *
1095lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
1096{
1097 struct lde_nbr *ln;
1098
1099 if ((ln = calloc(1, sizeof(*ln))) == NULL)
1100 fatal(__func__);
1101
1102 ln->id = new->id;
1103 ln->v4_enabled = new->v4_enabled;
1104 ln->v6_enabled = new->v6_enabled;
1105 ln->peerid = peerid;
1106 fec_init(&ln->recv_map);
1107 fec_init(&ln->sent_map);
1108 fec_init(&ln->recv_req);
1109 fec_init(&ln->sent_req);
1110 fec_init(&ln->sent_wdraw);
1111
1112 TAILQ_INIT(&ln->addr_list);
1113
1114 if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
1115 fatalx("lde_nbr_new: RB_INSERT failed");
1116
1117 return (ln);
1118}
1119
1120static void
1121lde_nbr_del(struct lde_nbr *ln)
1122{
1123 struct fec *f;
1124 struct fec_node *fn;
1125 struct fec_nh *fnh;
1126 struct l2vpn_pw *pw;
1127
1128 if (ln == NULL)
1129 return;
1130
1131 /* uninstall received mappings */
1132 RB_FOREACH(f, fec_tree, &ft) {
1133 fn = (struct fec_node *)f;
1134
1135 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1136 switch (f->type) {
1137 case FEC_TYPE_IPV4:
1138 case FEC_TYPE_IPV6:
1139 if (!lde_address_find(ln, fnh->af,
1140 &fnh->nexthop))
1141 continue;
1142 break;
1143 case FEC_TYPE_PWID:
1144 if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1145 continue;
1146 pw = (struct l2vpn_pw *) fn->data;
1147 if (pw)
1148 l2vpn_pw_reset(pw);
1149 break;
1150 default:
1151 break;
1152 }
1153
1154 lde_send_delete_klabel(fn, fnh);
1155 fnh->remote_label = NO_LABEL;
1156 }
1157 }
1158
1159 lde_address_list_free(ln);
1160
1161 fec_clear(&ln->recv_map, lde_map_free);
1162 fec_clear(&ln->sent_map, lde_map_free);
1163 fec_clear(&ln->recv_req, free);
1164 fec_clear(&ln->sent_req, free);
1165 fec_clear(&ln->sent_wdraw, free);
1166
1167 RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1168
1169 free(ln);
1170}
1171
1172static struct lde_nbr *
1173lde_nbr_find(uint32_t peerid)
1174{
1175 struct lde_nbr ln;
1176
1177 ln.peerid = peerid;
1178
1179 return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1180}
1181
1182struct lde_nbr *
1183lde_nbr_find_by_lsrid(struct in_addr addr)
1184{
1185 struct lde_nbr *ln;
1186
1187 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1188 if (ln->id.s_addr == addr.s_addr)
1189 return (ln);
1190
1191 return (NULL);
1192}
1193
1194struct lde_nbr *
1195lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1196{
1197 struct lde_nbr *ln;
1198
1199 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1200 if (lde_address_find(ln, af, addr) != NULL)
1201 return (ln);
1202
1203 return (NULL);
1204}
1205
1206static void
1207lde_nbr_clear(void)
1208{
1209 struct lde_nbr *ln;
1210
1211 while ((ln = RB_ROOT(&lde_nbrs)) != NULL)
1212 lde_nbr_del(ln);
1213}
1214
1215static void
1216lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1217{
1218 struct fec *fec;
1219 struct fec_node *fn;
1220 struct fec_nh *fnh;
1221 struct lde_map *me;
1222
1223 RB_FOREACH(fec, fec_tree, &ln->recv_map) {
1224 fn = (struct fec_node *)fec_find(&ft, fec);
1225 switch (fec->type) {
1226 case FEC_TYPE_IPV4:
1227 if (lde_addr->af != AF_INET)
1228 continue;
1229 break;
1230 case FEC_TYPE_IPV6:
1231 if (lde_addr->af != AF_INET6)
1232 continue;
1233 break;
1234 default:
1235 continue;
1236 }
1237
1238 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1239 if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1240 &lde_addr->addr))
1241 continue;
1242
1243 if (removed) {
1244 lde_send_delete_klabel(fn, fnh);
1245 fnh->remote_label = NO_LABEL;
1246 } else {
1247 me = (struct lde_map *)fec;
1248 fnh->remote_label = me->map.label;
1249 lde_send_change_klabel(fn, fnh);
1250 }
1251 break;
1252 }
1253 }
1254}
1255
d3e1887a
RW
1256static __inline int
1257lde_map_compare(struct lde_map *a, struct lde_map *b)
1258{
1259 return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
1260 (union ldpd_addr *)&b->nexthop->id));
1261}
1262
8429abe0
RW
1263struct lde_map *
1264lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1265{
1266 struct lde_map *me;
1267
1268 me = calloc(1, sizeof(*me));
1269 if (me == NULL)
1270 fatal(__func__);
1271
1272 me->fec = fn->fec;
1273 me->nexthop = ln;
1274
1275 if (sent) {
d3e1887a
RW
1276 RB_INSERT(lde_map_head, &fn->upstream, me);
1277 me->head = &fn->upstream;
8429abe0
RW
1278 if (fec_insert(&ln->sent_map, &me->fec))
1279 log_warnx("failed to add %s to sent map",
1280 log_fec(&me->fec));
1281 /* XXX on failure more cleanup is needed */
1282 } else {
d3e1887a
RW
1283 RB_INSERT(lde_map_head, &fn->downstream, me);
1284 me->head = &fn->downstream;
8429abe0
RW
1285 if (fec_insert(&ln->recv_map, &me->fec))
1286 log_warnx("failed to add %s to recv map",
1287 log_fec(&me->fec));
1288 }
1289
1290 return (me);
1291}
1292
1293void
1294lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1295{
1296 if (sent)
1297 fec_remove(&ln->sent_map, &me->fec);
1298 else
1299 fec_remove(&ln->recv_map, &me->fec);
1300
1301 lde_map_free(me);
1302}
1303
1304static void
1305lde_map_free(void *ptr)
1306{
1307 struct lde_map *map = ptr;
1308
d3e1887a 1309 RB_REMOVE(lde_map_head, map->head, map);
8429abe0
RW
1310 free(map);
1311}
1312
1313struct lde_req *
1314lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1315{
1316 struct fec_tree *t;
1317 struct lde_req *lre;
1318
1319 t = sent ? &ln->sent_req : &ln->recv_req;
1320
1321 lre = calloc(1, sizeof(*lre));
1322 if (lre != NULL) {
1323 lre->fec = *fec;
1324
1325 if (fec_insert(t, &lre->fec)) {
1326 log_warnx("failed to add %s to %s req",
1327 log_fec(&lre->fec), sent ? "sent" : "recv");
1328 free(lre);
1329 return (NULL);
1330 }
1331 }
1332
1333 return (lre);
1334}
1335
1336void
1337lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1338{
1339 if (sent)
1340 fec_remove(&ln->sent_req, &lre->fec);
1341 else
1342 fec_remove(&ln->recv_req, &lre->fec);
1343
1344 free(lre);
1345}
1346
1347struct lde_wdraw *
1348lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1349{
1350 struct lde_wdraw *lw;
1351
1352 lw = calloc(1, sizeof(*lw));
1353 if (lw == NULL)
1354 fatal(__func__);
1355
1356 lw->fec = fn->fec;
1357
1358 if (fec_insert(&ln->sent_wdraw, &lw->fec))
1359 log_warnx("failed to add %s to sent wdraw",
1360 log_fec(&lw->fec));
1361
1362 return (lw);
1363}
1364
1365void
1366lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1367{
1368 fec_remove(&ln->sent_wdraw, &lw->fec);
1369 free(lw);
1370}
1371
1372void
45a8eba9 1373lde_change_egress_label(int af)
8429abe0
RW
1374{
1375 struct lde_nbr *ln;
1376 struct fec *f;
1377 struct fec_node *fn;
1378
be54d744 1379 /* explicitly withdraw all null labels */
8429abe0 1380 RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
0bcc2916 1381 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL);
45a8eba9 1382 if (ln->v4_enabled)
0bcc2916 1383 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL);
45a8eba9 1384 if (ln->v6_enabled)
0bcc2916 1385 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL);
be54d744 1386 }
8429abe0 1387
be54d744
RW
1388 /* update label of connected routes */
1389 RB_FOREACH(f, fec_tree, &ft) {
1390 fn = (struct fec_node *)f;
1391 if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1392 continue;
8429abe0 1393
be54d744
RW
1394 switch (af) {
1395 case AF_INET:
1396 if (fn->fec.type != FEC_TYPE_IPV4)
1397 continue;
1398 break;
1399 case AF_INET6:
1400 if (fn->fec.type != FEC_TYPE_IPV6)
1401 continue;
1402 break;
1403 default:
1404 fatalx("lde_change_egress_label: unknown af");
8429abe0
RW
1405 }
1406
8cb1fc45 1407 fn->local_label = lde_update_label(fn);
45a8eba9
RW
1408 if (fn->local_label != NO_LABEL)
1409 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1410 lde_send_labelmapping(ln, fn, 0);
be54d744
RW
1411 }
1412 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
8429abe0
RW
1413 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1414 NULL, 0);
8429abe0
RW
1415}
1416
1417static int
1418lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
1419{
1420 struct lde_addr *new;
1421
1422 if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
1423 return (-1);
1424
1425 if ((new = calloc(1, sizeof(*new))) == NULL)
1426 fatal(__func__);
1427
1428 new->af = lde_addr->af;
1429 new->addr = lde_addr->addr;
1430 TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
1431
1432 /* reevaluate the previously received mappings from this neighbor */
1433 lde_nbr_addr_update(ln, lde_addr, 0);
1434
1435 return (0);
1436}
1437
1438static int
1439lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
1440{
1441 lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
1442 if (lde_addr == NULL)
1443 return (-1);
1444
1445 /* reevaluate the previously received mappings from this neighbor */
1446 lde_nbr_addr_update(ln, lde_addr, 1);
1447
1448 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1449 free(lde_addr);
1450
1451 return (0);
1452}
1453
1454struct lde_addr *
1455lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
1456{
1457 struct lde_addr *lde_addr;
1458
1459 TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
1460 if (lde_addr->af == af &&
1461 ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
1462 return (lde_addr);
1463
1464 return (NULL);
1465}
1466
1467static void
1468lde_address_list_free(struct lde_nbr *ln)
1469{
1470 struct lde_addr *lde_addr;
1471
1472 while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
1473 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1474 free(lde_addr);
1475 }
1476}