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