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