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