]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/lde.c
lib: hard-fail creating threads before fork()
[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"
077d336a 30#include "rlfa.h"
8429abe0 31
eac6e3f0
RW
32#include <lib/log.h>
33#include "memory.h"
34#include "privs.h"
35#include "sigevent.h"
36#include "mpls.h"
fea12efb 37#include <lib/linklist.h>
38#include "zclient.h"
39#include "stream.h"
40#include "network.h"
689f5a8c 41#include "libfrr.h"
eac6e3f0
RW
42
43static void lde_shutdown(void);
44static int lde_dispatch_imsg(struct thread *);
45static int lde_dispatch_parent(struct thread *);
45926e58
RZ
46static __inline int lde_nbr_compare(const struct lde_nbr *,
47 const struct lde_nbr *);
8429abe0
RW
48static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *);
49static void lde_nbr_del(struct lde_nbr *);
50static struct lde_nbr *lde_nbr_find(uint32_t);
51static void lde_nbr_clear(void);
52static void lde_nbr_addr_update(struct lde_nbr *,
53 struct lde_addr *, int);
45926e58
RZ
54static __inline int lde_map_compare(const struct lde_map *,
55 const struct lde_map *);
8429abe0
RW
56static void lde_map_free(void *);
57static int lde_address_add(struct lde_nbr *, struct lde_addr *);
58static int lde_address_del(struct lde_nbr *, struct lde_addr *);
59static void lde_address_list_free(struct lde_nbr *);
9d694b0b 60static void zclient_sync_init(void);
fea12efb 61static void lde_label_list_init(void);
5afba51d 62static int lde_get_label_chunk(void);
fea12efb 63static void on_get_label_chunk_response(uint32_t start, uint32_t end);
64static uint32_t lde_get_next_label(void);
aff1743c
KS
65static bool lde_fec_connected(const struct fec_node *);
66static bool lde_fec_outside_mpls_network(const struct fec_node *);
2d1aa1e8 67static void lde_check_filter_af(int, struct ldpd_af_conf *,
68 const char *);
8429abe0
RW
69
70RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
d3e1887a 71RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
8429abe0
RW
72
73struct ldpd_conf *ldeconf;
74struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
75
76static struct imsgev *iev_ldpe;
59c5b83b 77static struct imsgev iev_main_sync_data;
28e8294c 78static struct imsgev *iev_main, *iev_main_sync;
8429abe0 79
eac6e3f0
RW
80/* lde privileges */
81static zebra_capabilities_t _caps_p [] =
8429abe0 82{
342213ea 83 ZCAP_NET_ADMIN
eac6e3f0 84};
8429abe0 85
eac6e3f0
RW
86static struct zebra_privs_t lde_privs =
87{
eac6e3f0
RW
88#if defined(VTY_GROUP)
89 .vty_group = VTY_GROUP,
90#endif
91 .caps_p = _caps_p,
92 .cap_num_p = array_size(_caps_p),
93 .cap_num_i = 0
94};
95
fea12efb 96/* List of chunks of labels externally assigned by Zebra */
5afba51d
RW
97static struct list *label_chunk_list;
98static struct listnode *current_label_chunk;
99
100/* Synchronous zclient to request labels */
101static struct zclient *zclient_sync;
fea12efb 102
eac6e3f0
RW
103/* SIGINT / SIGTERM handler. */
104static void
105sigint(void)
106{
107 lde_shutdown();
8429abe0
RW
108}
109
eac6e3f0
RW
110static struct quagga_signal_t lde_signals[] =
111{
1e7e440f
RW
112 {
113 .signal = SIGHUP,
114 /* ignore */
115 },
eac6e3f0
RW
116 {
117 .signal = SIGINT,
118 .handler = &sigint,
119 },
120 {
121 .signal = SIGTERM,
122 .handler = &sigint,
123 },
124};
125
8429abe0
RW
126/* label decision engine */
127void
274f5abf 128lde(void)
8429abe0 129{
eac6e3f0 130#ifdef HAVE_SETPROCTITLE
8429abe0 131 setproctitle("label decision engine");
eac6e3f0 132#endif
8429abe0 133 ldpd_process = PROC_LDE_ENGINE;
fa68f9da 134 log_procname = log_procnames[PROC_LDE_ENGINE];
8429abe0 135
f9a4d683 136 master = frr_init();
8429abe0
RW
137
138 /* setup signal handler */
eac6e3f0 139 signal_init(master, array_size(lde_signals), lde_signals);
8429abe0 140
28e8294c
RW
141 /* setup pipes and event handlers to the parent process */
142 if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
8429abe0 143 fatal(NULL);
28e8294c 144 imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
eac6e3f0 145 iev_main->handler_read = lde_dispatch_parent;
66e78ae6
QY
146 iev_main->ev_read = NULL;
147 thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
148 &iev_main->ev_read);
eac6e3f0 149 iev_main->handler_write = ldp_write_handler;
28e8294c 150
59c5b83b
DS
151 memset(&iev_main_sync_data, 0, sizeof(iev_main_sync_data));
152 iev_main_sync = &iev_main_sync_data;
28e8294c 153 imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
eac6e3f0 154
274f5abf
RW
155 /* create base configuration */
156 ldeconf = config_new_empty();
157
f9a4d683 158 struct thread thread;
274f5abf
RW
159 while (thread_fetch(master, &thread))
160 thread_call(&thread);
f9a4d683
KS
161
162 /* NOTREACHED */
163 return;
274f5abf
RW
164}
165
166void
167lde_init(struct ldpd_init *init)
168{
169 /* drop privileges */
af7e63a3
RW
170 lde_privs.user = init->user;
171 lde_privs.group = init->group;
37a1f2fb 172 zprivs_preinit(&lde_privs);
274f5abf
RW
173 zprivs_init(&lde_privs);
174
eac6e3f0 175 /* start the LIB garbage collector */
8429abe0
RW
176 lde_gc_start_timer();
177
fea12efb 178 /* Init synchronous zclient and label list */
689f5a8c
DL
179 frr_zclient_addr(&zclient_addr, &zclient_addr_len,
180 init->zclient_serv_path);
9d694b0b 181 zclient_sync_init();
8429abe0
RW
182}
183
eac6e3f0 184static void
8429abe0
RW
185lde_shutdown(void)
186{
187 /* close pipes */
835a7376
RW
188 if (iev_ldpe) {
189 msgbuf_clear(&iev_ldpe->ibuf.w);
190 close(iev_ldpe->ibuf.fd);
50732983 191 iev_ldpe->ibuf.fd = -1;
835a7376 192 }
8429abe0
RW
193 msgbuf_clear(&iev_main->ibuf.w);
194 close(iev_main->ibuf.fd);
50732983 195 iev_main->ibuf.fd = -1;
28e8294c
RW
196 msgbuf_clear(&iev_main_sync->ibuf.w);
197 close(iev_main_sync->ibuf.fd);
50732983 198 iev_main_sync->ibuf.fd = -1;
8429abe0
RW
199
200 lde_gc_stop_timer();
201 lde_nbr_clear();
202 fec_tree_clear();
203
204 config_clear(ldeconf);
205
835a7376
RW
206 if (iev_ldpe)
207 free(iev_ldpe);
8429abe0
RW
208 free(iev_main);
209
210 log_info("label decision engine exiting");
b12a63f1
MS
211
212 zlog_fini();
8429abe0
RW
213 exit(0);
214}
215
216/* imesg */
eac6e3f0 217int
8429abe0
RW
218lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
219{
50732983
RW
220 if (iev_main->ibuf.fd == -1)
221 return (0);
8429abe0
RW
222 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
223}
224
f2232fdf
RW
225void
226lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
227{
50732983
RW
228 if (iev_main_sync->ibuf.fd == -1)
229 return;
f2232fdf
RW
230 imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
231 imsg_flush(&iev_main_sync->ibuf);
232}
233
8429abe0
RW
234int
235lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
236 uint16_t datalen)
237{
50732983
RW
238 if (iev_ldpe->ibuf.fd == -1)
239 return (0);
8429abe0
RW
240 return (imsg_compose_event(iev_ldpe, type, peerid, pid,
241 -1, data, datalen));
242}
243
244/* ARGSUSED */
eac6e3f0
RW
245static int
246lde_dispatch_imsg(struct thread *thread)
8429abe0 247{
eac6e3f0 248 struct imsgev *iev = THREAD_ARG(thread);
8429abe0
RW
249 struct imsgbuf *ibuf = &iev->ibuf;
250 struct imsg imsg;
251 struct lde_nbr *ln;
236c6935
RW
252 struct map *map;
253 struct lde_addr *lde_addr;
254 struct notify_msg *nm;
8429abe0 255 ssize_t n;
eac6e3f0 256 int shut = 0;
8429abe0 257
eac6e3f0
RW
258 iev->ev_read = NULL;
259
260 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
261 fatal("imsg_read error");
262 if (n == 0) /* connection closed */
263 shut = 1;
8429abe0
RW
264
265 for (;;) {
266 if ((n = imsg_get(ibuf, &imsg)) == -1)
267 fatal("lde_dispatch_imsg: imsg_get error");
268 if (n == 0)
269 break;
270
271 switch (imsg.hdr.type) {
272 case IMSG_LABEL_MAPPING_FULL:
273 ln = lde_nbr_find(imsg.hdr.peerid);
274 if (ln == NULL) {
275 log_debug("%s: cannot find lde neighbor",
276 __func__);
277 break;
278 }
279
280 fec_snap(ln);
281 break;
282 case IMSG_LABEL_MAPPING:
283 case IMSG_LABEL_REQUEST:
284 case IMSG_LABEL_RELEASE:
285 case IMSG_LABEL_WITHDRAW:
286 case IMSG_LABEL_ABORT:
236c6935
RW
287 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
288 sizeof(struct map))
8429abe0 289 fatalx("lde_dispatch_imsg: wrong imsg len");
236c6935 290 map = imsg.data;
8429abe0
RW
291
292 ln = lde_nbr_find(imsg.hdr.peerid);
293 if (ln == NULL) {
294 log_debug("%s: cannot find lde neighbor",
295 __func__);
296 break;
297 }
298
299 switch (imsg.hdr.type) {
300 case IMSG_LABEL_MAPPING:
4272a064 301 lde_check_mapping(map, ln, 1);
8429abe0
RW
302 break;
303 case IMSG_LABEL_REQUEST:
236c6935 304 lde_check_request(map, ln);
8429abe0
RW
305 break;
306 case IMSG_LABEL_RELEASE:
236c6935 307 lde_check_release(map, ln);
8429abe0
RW
308 break;
309 case IMSG_LABEL_WITHDRAW:
236c6935 310 lde_check_withdraw(map, ln);
8429abe0
RW
311 break;
312 case IMSG_LABEL_ABORT:
313 /* not necessary */
314 break;
315 }
316 break;
317 case IMSG_ADDRESS_ADD:
236c6935
RW
318 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
319 sizeof(struct lde_addr))
8429abe0 320 fatalx("lde_dispatch_imsg: wrong imsg len");
236c6935 321 lde_addr = imsg.data;
8429abe0
RW
322
323 ln = lde_nbr_find(imsg.hdr.peerid);
324 if (ln == NULL) {
325 log_debug("%s: cannot find lde neighbor",
326 __func__);
327 break;
328 }
236c6935 329 if (lde_address_add(ln, lde_addr) < 0) {
3efd0893 330 log_debug("%s: cannot add address %s, it already exists", __func__,
236c6935 331 log_addr(lde_addr->af, &lde_addr->addr));
8429abe0
RW
332 }
333 break;
334 case IMSG_ADDRESS_DEL:
236c6935
RW
335 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
336 sizeof(struct lde_addr))
8429abe0 337 fatalx("lde_dispatch_imsg: wrong imsg len");
236c6935 338 lde_addr = imsg.data;
8429abe0
RW
339
340 ln = lde_nbr_find(imsg.hdr.peerid);
341 if (ln == NULL) {
342 log_debug("%s: cannot find lde neighbor",
343 __func__);
344 break;
345 }
236c6935 346 if (lde_address_del(ln, lde_addr) < 0) {
3efd0893 347 log_debug("%s: cannot delete address %s, it does not exist", __func__,
236c6935 348 log_addr(lde_addr->af, &lde_addr->addr));
8429abe0
RW
349 }
350 break;
351 case IMSG_NOTIFICATION:
236c6935
RW
352 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
353 sizeof(struct notify_msg))
8429abe0 354 fatalx("lde_dispatch_imsg: wrong imsg len");
236c6935 355 nm = imsg.data;
8429abe0
RW
356
357 ln = lde_nbr_find(imsg.hdr.peerid);
358 if (ln == NULL) {
359 log_debug("%s: cannot find lde neighbor",
360 __func__);
361 break;
362 }
363
236c6935 364 switch (nm->status_code) {
8429abe0 365 case S_PW_STATUS:
236c6935 366 l2vpn_recv_pw_status(ln, nm);
8429abe0 367 break;
257799cd
RW
368 case S_ENDOFLIB:
369 /*
370 * Do nothing for now. Should be useful in
371 * the future when we implement LDP-IGP
372 * Synchronization (RFC 5443) and Graceful
373 * Restart (RFC 3478).
374 */
8429abe0
RW
375 default:
376 break;
377 }
378 break;
379 case IMSG_NEIGHBOR_UP:
380 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
381 sizeof(struct lde_nbr))
382 fatalx("lde_dispatch_imsg: wrong imsg len");
383
384 if (lde_nbr_find(imsg.hdr.peerid))
3efd0893 385 fatalx("lde_dispatch_imsg: neighbor already exists");
8429abe0
RW
386 lde_nbr_new(imsg.hdr.peerid, imsg.data);
387 break;
388 case IMSG_NEIGHBOR_DOWN:
389 lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
390 break;
391 case IMSG_CTL_SHOW_LIB:
392 rt_dump(imsg.hdr.pid);
393
394 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
395 imsg.hdr.pid, NULL, 0);
396 break;
397 case IMSG_CTL_SHOW_L2VPN_PW:
398 l2vpn_pw_ctl(imsg.hdr.pid);
399
400 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
401 imsg.hdr.pid, NULL, 0);
402 break;
403 case IMSG_CTL_SHOW_L2VPN_BINDING:
404 l2vpn_binding_ctl(imsg.hdr.pid);
405
406 lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
407 imsg.hdr.pid, NULL, 0);
408 break;
8429abe0
RW
409 default:
410 log_debug("%s: unexpected imsg %d", __func__,
411 imsg.hdr.type);
412 break;
413 }
414 imsg_free(&imsg);
415 }
416 if (!shut)
417 imsg_event_add(iev);
418 else {
eac6e3f0 419 /* this pipe is dead, so remove the event handlers and exit */
50478845
MS
420 thread_cancel(&iev->ev_read);
421 thread_cancel(&iev->ev_write);
eac6e3f0 422 lde_shutdown();
8429abe0 423 }
eac6e3f0
RW
424
425 return (0);
8429abe0
RW
426}
427
428/* ARGSUSED */
eac6e3f0
RW
429static int
430lde_dispatch_parent(struct thread *thread)
8429abe0
RW
431{
432 static struct ldpd_conf *nconf;
52b530fc 433 struct iface *iface, *niface;
8429abe0
RW
434 struct tnbr *ntnbr;
435 struct nbr_params *nnbrp;
52b530fc
RW
436 static struct l2vpn *l2vpn, *nl2vpn;
437 struct l2vpn_if *lif, *nlif;
438 struct l2vpn_pw *pw, *npw;
8429abe0 439 struct imsg imsg;
52b530fc 440 struct kif *kif;
236c6935 441 struct kroute *kr;
11bf8e13 442 int fd;
eac6e3f0 443 struct imsgev *iev = THREAD_ARG(thread);
8429abe0
RW
444 struct imsgbuf *ibuf = &iev->ibuf;
445 ssize_t n;
446 int shut = 0;
447 struct fec fec;
2d1aa1e8 448 struct ldp_access *laccess;
077d336a
RW
449 struct ldp_rlfa_node *rnode, *rntmp;
450 struct ldp_rlfa_client *rclient;
451 struct zapi_rlfa_request *rlfa_req;
452 struct zapi_rlfa_igp *rlfa_igp;
8429abe0 453
eac6e3f0
RW
454 iev->ev_read = NULL;
455
456 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
457 fatal("imsg_read error");
458 if (n == 0) /* connection closed */
459 shut = 1;
8429abe0
RW
460
461 for (;;) {
462 if ((n = imsg_get(ibuf, &imsg)) == -1)
463 fatal("lde_dispatch_parent: imsg_get error");
464 if (n == 0)
465 break;
466
467 switch (imsg.hdr.type) {
52b530fc
RW
468 case IMSG_IFSTATUS:
469 if (imsg.hdr.len != IMSG_HEADER_SIZE +
470 sizeof(struct kif))
471 fatalx("IFSTATUS imsg with wrong len");
472 kif = imsg.data;
473
474 iface = if_lookup_name(ldeconf, kif->ifname);
475 if (iface) {
476 if_update_info(iface, kif);
95535717 477
478 /* if up see if any labels need to be updated */
479 if (kif->operative)
480 lde_route_update(iface, AF_UNSPEC);
52b530fc
RW
481 break;
482 }
483
484 RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
485 lif = l2vpn_if_find(l2vpn, kif->ifname);
486 if (lif) {
487 l2vpn_if_update_info(lif, kif);
488 break;
489 }
490 pw = l2vpn_pw_find(l2vpn, kif->ifname);
491 if (pw) {
492 l2vpn_pw_update_info(pw, kif);
493 break;
494 }
495 }
496 break;
87b5f1b7
RW
497 case IMSG_PW_UPDATE:
498 if (imsg.hdr.len != IMSG_HEADER_SIZE +
499 sizeof(struct zapi_pw_status))
500 fatalx("PW_UPDATE imsg with wrong len");
501
502 if (l2vpn_pw_status_update(imsg.data) != 0)
503 log_warnx("%s: error updating PW status",
504 __func__);
505 break;
8429abe0 506 case IMSG_NETWORK_ADD:
8cb1fc45 507 case IMSG_NETWORK_UPDATE:
236c6935
RW
508 if (imsg.hdr.len != IMSG_HEADER_SIZE +
509 sizeof(struct kroute)) {
8429abe0
RW
510 log_warnx("%s: wrong imsg len", __func__);
511 break;
512 }
236c6935 513 kr = imsg.data;
8429abe0 514
236c6935 515 switch (kr->af) {
8429abe0
RW
516 case AF_INET:
517 fec.type = FEC_TYPE_IPV4;
236c6935
RW
518 fec.u.ipv4.prefix = kr->prefix.v4;
519 fec.u.ipv4.prefixlen = kr->prefixlen;
8429abe0
RW
520 break;
521 case AF_INET6:
522 fec.type = FEC_TYPE_IPV6;
236c6935
RW
523 fec.u.ipv6.prefix = kr->prefix.v6;
524 fec.u.ipv6.prefixlen = kr->prefixlen;
8429abe0
RW
525 break;
526 default:
527 fatalx("lde_dispatch_parent: unknown af");
528 }
529
530 switch (imsg.hdr.type) {
531 case IMSG_NETWORK_ADD:
236c6935 532 lde_kernel_insert(&fec, kr->af, &kr->nexthop,
e132dea0
RW
533 kr->ifindex, kr->route_type,
534 kr->route_instance,
236c6935 535 kr->flags & F_CONNECTED, NULL);
8429abe0 536 break;
8cb1fc45
RW
537 case IMSG_NETWORK_UPDATE:
538 lde_kernel_update(&fec);
8429abe0
RW
539 break;
540 }
541 break;
542 case IMSG_SOCKET_IPC:
543 if (iev_ldpe) {
3efd0893 544 log_warnx("%s: received unexpected imsg fd to ldpe", __func__);
8429abe0
RW
545 break;
546 }
547 if ((fd = imsg.fd) == -1) {
3efd0893 548 log_warnx("%s: expected to receive imsg fd to ldpe but didn't receive any", __func__);
8429abe0
RW
549 break;
550 }
551
552 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
553 fatal(NULL);
554 imsg_init(&iev_ldpe->ibuf, fd);
eac6e3f0 555 iev_ldpe->handler_read = lde_dispatch_imsg;
66e78ae6
QY
556 iev_ldpe->ev_read = NULL;
557 thread_add_read(master, iev_ldpe->handler_read, iev_ldpe, iev_ldpe->ibuf.fd,
558 &iev_ldpe->ev_read);
eac6e3f0
RW
559 iev_ldpe->handler_write = ldp_write_handler;
560 iev_ldpe->ev_write = NULL;
8429abe0 561 break;
274f5abf
RW
562 case IMSG_INIT:
563 if (imsg.hdr.len != IMSG_HEADER_SIZE +
564 sizeof(struct ldpd_init))
565 fatalx("INIT imsg with wrong len");
566
567 memcpy(&init, imsg.data, sizeof(init));
568 lde_init(&init);
569 break;
f9a4d683
KS
570 case IMSG_AGENTX_ENABLED:
571 ldp_agentx_enabled();
572 break;
8429abe0
RW
573 case IMSG_RECONF_CONF:
574 if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
575 NULL)
576 fatal(NULL);
577 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
578
45926e58
RZ
579 RB_INIT(iface_head, &nconf->iface_tree);
580 RB_INIT(tnbr_head, &nconf->tnbr_tree);
581 RB_INIT(nbrp_head, &nconf->nbrp_tree);
582 RB_INIT(l2vpn_head, &nconf->l2vpn_tree);
8429abe0
RW
583 break;
584 case IMSG_RECONF_IFACE:
585 if ((niface = malloc(sizeof(struct iface))) == NULL)
586 fatal(NULL);
587 memcpy(niface, imsg.data, sizeof(struct iface));
588
7d3d7491 589 RB_INSERT(iface_head, &nconf->iface_tree, niface);
8429abe0
RW
590 break;
591 case IMSG_RECONF_TNBR:
592 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
593 fatal(NULL);
594 memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
595
7989cdba 596 RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
8429abe0
RW
597 break;
598 case IMSG_RECONF_NBRP:
599 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
600 fatal(NULL);
601 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
602
76c4abd1 603 RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
8429abe0
RW
604 break;
605 case IMSG_RECONF_L2VPN:
606 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
607 fatal(NULL);
608 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
609
45926e58
RZ
610 RB_INIT(l2vpn_if_head, &nl2vpn->if_tree);
611 RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree);
612 RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree);
8429abe0 613
90d7e7bd 614 RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
8429abe0
RW
615 break;
616 case IMSG_RECONF_L2VPN_IF:
617 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
618 fatal(NULL);
619 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
620
029c1958 621 RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
8429abe0
RW
622 break;
623 case IMSG_RECONF_L2VPN_PW:
624 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
625 fatal(NULL);
626 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
627
20bacaeb 628 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
8429abe0 629 break;
eac6e3f0
RW
630 case IMSG_RECONF_L2VPN_IPW:
631 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
632 fatal(NULL);
633 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
634
20bacaeb 635 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
eac6e3f0 636 break;
8429abe0
RW
637 case IMSG_RECONF_END:
638 merge_config(ldeconf, nconf);
1d75a89d 639 ldp_clear_config(nconf);
8429abe0
RW
640 nconf = NULL;
641 break;
eac6e3f0
RW
642 case IMSG_DEBUG_UPDATE:
643 if (imsg.hdr.len != IMSG_HEADER_SIZE +
644 sizeof(ldp_debug)) {
645 log_warnx("%s: wrong imsg len", __func__);
646 break;
647 }
648 memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
649 break;
2d1aa1e8 650 case IMSG_FILTER_UPDATE:
651 if (imsg.hdr.len != IMSG_HEADER_SIZE +
652 sizeof(struct ldp_access)) {
653 log_warnx("%s: wrong imsg len", __func__);
654 break;
655 }
656 laccess = imsg.data;
657 lde_check_filter_af(AF_INET, &ldeconf->ipv4,
658 laccess->name);
659 lde_check_filter_af(AF_INET6, &ldeconf->ipv6,
660 laccess->name);
661 break;
077d336a
RW
662 case IMSG_RLFA_REG:
663 if (imsg.hdr.len != IMSG_HEADER_SIZE +
664 sizeof(struct zapi_rlfa_request)) {
665 log_warnx("%s: wrong imsg len", __func__);
666 break;
667 }
668 rlfa_req = imsg.data;
669 rnode = rlfa_node_find(&rlfa_req->destination,
670 rlfa_req->pq_address);
671 if (!rnode)
672 rnode = rlfa_node_new(&rlfa_req->destination,
673 rlfa_req->pq_address);
674 rclient = rlfa_client_find(rnode, &rlfa_req->igp);
675 if (rclient)
676 /* RLFA already registered - do nothing */
677 break;
678 rclient = rlfa_client_new(rnode, &rlfa_req->igp);
679 lde_rlfa_check(rclient);
680 break;
681 case IMSG_RLFA_UNREG_ALL:
682 if (imsg.hdr.len != IMSG_HEADER_SIZE +
683 sizeof(struct zapi_rlfa_igp)) {
684 log_warnx("%s: wrong imsg len", __func__);
685 break;
686 }
687 rlfa_igp = imsg.data;
688
689 RB_FOREACH_SAFE (rnode, ldp_rlfa_node_head,
690 &rlfa_node_tree, rntmp) {
691 rclient = rlfa_client_find(rnode, rlfa_igp);
692 if (!rclient)
693 continue;
694
695 rlfa_client_del(rclient);
696 }
697 break;
8429abe0
RW
698 default:
699 log_debug("%s: unexpected imsg %d", __func__,
700 imsg.hdr.type);
701 break;
702 }
703 imsg_free(&imsg);
704 }
705 if (!shut)
706 imsg_event_add(iev);
707 else {
eac6e3f0 708 /* this pipe is dead, so remove the event handlers and exit */
50478845
MS
709 thread_cancel(&iev->ev_read);
710 thread_cancel(&iev->ev_write);
eac6e3f0 711 lde_shutdown();
8429abe0 712 }
eac6e3f0
RW
713
714 return (0);
8429abe0
RW
715}
716
45a8eba9
RW
717int
718lde_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
719{
720 return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
721}
722
aff1743c
KS
723static bool lde_fec_connected(const struct fec_node *fn)
724{
725 struct fec_nh *fnh;
726
727 LIST_FOREACH(fnh, &fn->nexthops, entry)
728 if (fnh->flags & F_FEC_NH_CONNECTED)
729 return true;
730
731 return false;
732}
733
734static bool lde_fec_outside_mpls_network(const struct fec_node *fn)
735{
736 struct fec_nh *fnh;
737
738 LIST_FOREACH(fnh, &fn->nexthops, entry)
739 if (!(fnh->flags & F_FEC_NH_NO_LDP))
740 return false;
741
742 return true;
743}
744
8429abe0 745uint32_t
8cb1fc45 746lde_update_label(struct fec_node *fn)
8429abe0 747{
8429abe0 748
45a8eba9 749 /* should we allocate a label for this fec? */
8cb1fc45 750 switch (fn->fec.type) {
45a8eba9
RW
751 case FEC_TYPE_IPV4:
752 if ((ldeconf->ipv4.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
8cb1fc45 753 fn->fec.u.ipv4.prefixlen != 32)
45a8eba9
RW
754 return (NO_LABEL);
755 if (lde_acl_check(ldeconf->ipv4.acl_label_allocate_for,
8cb1fc45
RW
756 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
757 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
758 return (NO_LABEL);
759 break;
760 case FEC_TYPE_IPV6:
761 if ((ldeconf->ipv6.flags & F_LDPD_AF_ALLOCHOSTONLY) &&
8cb1fc45 762 fn->fec.u.ipv6.prefixlen != 128)
45a8eba9
RW
763 return (NO_LABEL);
764 if (lde_acl_check(ldeconf->ipv6.acl_label_allocate_for,
8cb1fc45
RW
765 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
766 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
45a8eba9
RW
767 return (NO_LABEL);
768 break;
769 default:
45a8eba9
RW
770 break;
771 }
772
aff1743c
KS
773 /*
774 * If connected interface act as egress for fec.
775 * If LDP is not configured on an interface but there
776 * are other NHs with interfaces configured with LDP
777 * then don't act as an egress for the fec, otherwise
778 * act as an egress for the fec
779 */
780 if (lde_fec_connected(fn) || lde_fec_outside_mpls_network(fn)) {
45a8eba9 781 /* choose implicit or explicit-null depending on configuration */
8cb1fc45 782 switch (fn->fec.type) {
45a8eba9
RW
783 case FEC_TYPE_IPV4:
784 if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
70e98a7f 785 return (MPLS_LABEL_IMPLICIT_NULL);
45a8eba9 786 if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
8cb1fc45
RW
787 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
788 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
70e98a7f
DS
789 return (MPLS_LABEL_IMPLICIT_NULL);
790 return MPLS_LABEL_IPV4_EXPLICIT_NULL;
45a8eba9
RW
791 case FEC_TYPE_IPV6:
792 if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
70e98a7f 793 return (MPLS_LABEL_IMPLICIT_NULL);
45a8eba9 794 if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
8cb1fc45
RW
795 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
796 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
70e98a7f
DS
797 return (MPLS_LABEL_IMPLICIT_NULL);
798 return MPLS_LABEL_IPV6_EXPLICIT_NULL;
45a8eba9 799 default:
45a8eba9
RW
800 break;
801 }
802 }
803
8cb1fc45
RW
804 /* preserve current label if there's no need to update it */
805 if (fn->local_label != NO_LABEL &&
806 fn->local_label > MPLS_LABEL_RESERVED_MAX)
807 return (fn->local_label);
808
5afba51d 809 return (lde_get_next_label());
8429abe0
RW
810}
811
812void
813lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
814{
87b5f1b7
RW
815 struct kroute kr;
816 struct zapi_pw zpw;
8429abe0
RW
817 struct l2vpn_pw *pw;
818
aff1743c
KS
819 /*
820 * Ordered Control: don't program label into HW until a
821 * labelmap msg has been received from upstream router
822 */
823 if (fnh->flags & F_FEC_NH_DEFER)
824 return;
825
8429abe0
RW
826 switch (fn->fec.type) {
827 case FEC_TYPE_IPV4:
828 memset(&kr, 0, sizeof(kr));
829 kr.af = AF_INET;
830 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
831 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
832 kr.nexthop.v4 = fnh->nexthop.v4;
88d88a9c 833 kr.ifindex = fnh->ifindex;
8429abe0
RW
834 kr.local_label = fn->local_label;
835 kr.remote_label = fnh->remote_label;
e132dea0
RW
836 kr.route_type = fnh->route_type;
837 kr.route_instance = fnh->route_instance;
8429abe0
RW
838 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
839 sizeof(kr));
8429abe0
RW
840 break;
841 case FEC_TYPE_IPV6:
842 memset(&kr, 0, sizeof(kr));
843 kr.af = AF_INET6;
844 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
845 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
846 kr.nexthop.v6 = fnh->nexthop.v6;
88d88a9c 847 kr.ifindex = fnh->ifindex;
8429abe0
RW
848 kr.local_label = fn->local_label;
849 kr.remote_label = fnh->remote_label;
e132dea0
RW
850 kr.route_type = fnh->route_type;
851 kr.route_instance = fnh->route_instance;
8429abe0
RW
852
853 lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
854 sizeof(kr));
8429abe0
RW
855 break;
856 case FEC_TYPE_PWID:
3c5b5220
RW
857 pw = (struct l2vpn_pw *) fn->data;
858 if (!pw || fn->local_label == NO_LABEL ||
8429abe0
RW
859 fnh->remote_label == NO_LABEL)
860 return;
861
3c5b5220 862 pw->enabled = true;
87b5f1b7
RW
863 pw2zpw(pw, &zpw);
864 zpw.local_label = fn->local_label;
865 zpw.remote_label = fnh->remote_label;
866 lde_imsg_compose_parent(IMSG_KPW_SET, 0, &zpw, sizeof(zpw));
8429abe0
RW
867 break;
868 }
869}
870
871void
872lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
873{
874 struct kroute kr;
87b5f1b7 875 struct zapi_pw zpw;
8429abe0
RW
876 struct l2vpn_pw *pw;
877
878 switch (fn->fec.type) {
879 case FEC_TYPE_IPV4:
880 memset(&kr, 0, sizeof(kr));
881 kr.af = AF_INET;
882 kr.prefix.v4 = fn->fec.u.ipv4.prefix;
883 kr.prefixlen = fn->fec.u.ipv4.prefixlen;
884 kr.nexthop.v4 = fnh->nexthop.v4;
88d88a9c 885 kr.ifindex = fnh->ifindex;
8429abe0
RW
886 kr.local_label = fn->local_label;
887 kr.remote_label = fnh->remote_label;
e132dea0
RW
888 kr.route_type = fnh->route_type;
889 kr.route_instance = fnh->route_instance;
8429abe0
RW
890
891 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
892 sizeof(kr));
8429abe0
RW
893 break;
894 case FEC_TYPE_IPV6:
895 memset(&kr, 0, sizeof(kr));
896 kr.af = AF_INET6;
897 kr.prefix.v6 = fn->fec.u.ipv6.prefix;
898 kr.prefixlen = fn->fec.u.ipv6.prefixlen;
899 kr.nexthop.v6 = fnh->nexthop.v6;
88d88a9c 900 kr.ifindex = fnh->ifindex;
8429abe0
RW
901 kr.local_label = fn->local_label;
902 kr.remote_label = fnh->remote_label;
e132dea0
RW
903 kr.route_type = fnh->route_type;
904 kr.route_instance = fnh->route_instance;
8429abe0
RW
905
906 lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
907 sizeof(kr));
8429abe0
RW
908 break;
909 case FEC_TYPE_PWID:
910 pw = (struct l2vpn_pw *) fn->data;
3c5b5220
RW
911 if (!pw)
912 return;
913
914 pw->enabled = false;
87b5f1b7
RW
915 pw2zpw(pw, &zpw);
916 zpw.local_label = fn->local_label;
917 zpw.remote_label = fnh->remote_label;
918 lde_imsg_compose_parent(IMSG_KPW_UNSET, 0, &zpw, sizeof(zpw));
8429abe0
RW
919 break;
920 }
921}
922
077d336a
RW
923void
924lde_fec2prefix(const struct fec *fec, struct prefix *prefix)
925{
926 memset(prefix, 0, sizeof(*prefix));
927 switch (fec->type) {
928 case FEC_TYPE_IPV4:
929 prefix->family = AF_INET;
930 prefix->u.prefix4 = fec->u.ipv4.prefix;
931 prefix->prefixlen = fec->u.ipv4.prefixlen;
932 break;
933 case FEC_TYPE_IPV6:
934 prefix->family = AF_INET6;
935 prefix->u.prefix6 = fec->u.ipv6.prefix;
936 prefix->prefixlen = fec->u.ipv6.prefixlen;
937 break;
938 default:
939 prefix->family = AF_UNSPEC;
940 break;
941 }
942}
943
944void
945lde_prefix2fec(const struct prefix *prefix, struct fec *fec)
946{
947 memset(fec, 0, sizeof(*fec));
948 switch (prefix->family) {
949 case AF_INET:
950 fec->type = FEC_TYPE_IPV4;
951 fec->u.ipv4.prefix = prefix->u.prefix4;
952 fec->u.ipv4.prefixlen = prefix->prefixlen;
953 break;
954 case AF_INET6:
955 fec->type = FEC_TYPE_IPV6;
956 fec->u.ipv6.prefix = prefix->u.prefix6;
957 fec->u.ipv6.prefixlen = prefix->prefixlen;
958 break;
959 default:
960 fatalx("lde_prefix2fec: unknown af");
961 break;
962 }
963}
964
8429abe0
RW
965void
966lde_fec2map(struct fec *fec, struct map *map)
967{
968 memset(map, 0, sizeof(*map));
969
970 switch (fec->type) {
971 case FEC_TYPE_IPV4:
972 map->type = MAP_TYPE_PREFIX;
973 map->fec.prefix.af = AF_INET;
974 map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
975 map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
976 break;
977 case FEC_TYPE_IPV6:
978 map->type = MAP_TYPE_PREFIX;
979 map->fec.prefix.af = AF_INET6;
980 map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
981 map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
982 break;
983 case FEC_TYPE_PWID:
984 map->type = MAP_TYPE_PWID;
985 map->fec.pwid.type = fec->u.pwid.type;
986 map->fec.pwid.group_id = 0;
987 map->flags |= F_MAP_PW_ID;
988 map->fec.pwid.pwid = fec->u.pwid.pwid;
989 break;
990 }
991}
992
993void
994lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
995{
996 memset(fec, 0, sizeof(*fec));
997
998 switch (map->type) {
999 case MAP_TYPE_PREFIX:
1000 switch (map->fec.prefix.af) {
1001 case AF_INET:
1002 fec->type = FEC_TYPE_IPV4;
1003 fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
1004 fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
1005 break;
1006 case AF_INET6:
1007 fec->type = FEC_TYPE_IPV6;
1008 fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
1009 fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
1010 break;
1011 default:
1012 fatalx("lde_map2fec: unknown af");
1013 break;
1014 }
1015 break;
1016 case MAP_TYPE_PWID:
1017 fec->type = FEC_TYPE_PWID;
1018 fec->u.pwid.type = map->fec.pwid.type;
1019 fec->u.pwid.pwid = map->fec.pwid.pwid;
1020 fec->u.pwid.lsr_id = lsr_id;
1021 break;
1022 }
1023}
1024
1025void
1026lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
1027{
7c2abbd7
RW
1028 struct lde_wdraw *lw;
1029 struct lde_map *me;
1030 struct lde_req *lre;
1031 struct map map;
1032 struct l2vpn_pw *pw;
aff1743c
KS
1033 struct fec_nh *fnh;
1034 bool allow = false;
1035
1036 /*
1037 * Ordered Control: do not send a labelmap msg until
1038 * a labelmap message is received from downstream router
1039 * and don't send labelmap back to downstream router
1040 */
1041 if (ldeconf->flags & F_LDPD_ORDERED_CONTROL) {
1042 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1043 if (fnh->flags & F_FEC_NH_DEFER)
1044 continue;
1045
1046 if (lde_address_find(ln, fnh->af, &fnh->nexthop))
1047 return;
1048 allow = true;
1049 break;
1050 }
1051 if (!allow)
1052 return;
1053 }
7c2abbd7
RW
1054
1055 /*
1056 * We shouldn't send a new label mapping if we have a pending
1057 * label release to receive. In this case, schedule to send a
1058 * label mapping as soon as a label release is received.
1059 */
1060 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
1061 if (lw) {
b4fcca6b 1062 if (!fec_find(&ln->sent_map_pending, &fn->fec)) {
3efd0893 1063 debug_evt("%s: FEC %s: scheduling to send label mapping later (waiting for pending label release)",
b4fcca6b 1064 __func__, log_fec(&fn->fec));
7c2abbd7 1065 lde_map_pending_add(ln, fn);
b4fcca6b 1066 }
7c2abbd7
RW
1067 return;
1068 }
8429abe0
RW
1069
1070 /*
1071 * This function skips SL.1 - 3 and SL.9 - 14 because the label
1072 * allocation is done way earlier (because of the merging nature of
1073 * ldpd).
1074 */
1075
1076 lde_fec2map(&fn->fec, &map);
1077 switch (fn->fec.type) {
1078 case FEC_TYPE_IPV4:
1079 if (!ln->v4_enabled)
1080 return;
45a8eba9
RW
1081 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_to,
1082 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
1083 return;
1084 if (lde_acl_check(ldeconf->ipv4.acl_label_advertise_for,
1085 AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
1086 fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
1087 return;
8429abe0
RW
1088 break;
1089 case FEC_TYPE_IPV6:
1090 if (!ln->v6_enabled)
1091 return;
45a8eba9
RW
1092 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_to,
1093 AF_INET, (union ldpd_addr *)&ln->id, 32) != FILTER_PERMIT)
1094 return;
1095 if (lde_acl_check(ldeconf->ipv6.acl_label_advertise_for,
1096 AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
1097 fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
1098 return;
8429abe0
RW
1099 break;
1100 case FEC_TYPE_PWID:
1101 pw = (struct l2vpn_pw *) fn->data;
1102 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1103 /* not the remote end of the pseudowire */
1104 return;
1105
1106 map.flags |= F_MAP_PW_IFMTU;
1107 map.fec.pwid.ifmtu = pw->l2vpn->mtu;
1108 if (pw->flags & F_PW_CWORD)
1109 map.flags |= F_MAP_PW_CWORD;
1110 if (pw->flags & F_PW_STATUSTLV) {
1111 map.flags |= F_MAP_PW_STATUS;
87b5f1b7 1112 map.pw_status = pw->local_status;
8429abe0
RW
1113 }
1114 break;
1115 }
1116 map.label = fn->local_label;
1117
1118 /* SL.6: is there a pending request for this mapping? */
1119 lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
1120 if (lre) {
1121 /* set label request msg id in the mapping response. */
1122 map.requestid = lre->msg_id;
1123 map.flags = F_MAP_REQ_ID;
1124
1125 /* SL.7: delete record of pending request */
1126 lde_req_del(ln, lre, 0);
1127 }
1128
1129 /* SL.4: send label mapping */
1130 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
1131 &map, sizeof(map));
1132 if (single)
1133 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1134 NULL, 0);
1135
1136 /* SL.5: record sent label mapping */
1137 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
1138 if (me == NULL)
1139 me = lde_map_add(ln, fn, 1);
1140 me->map = map;
1141}
1142
1143void
0bcc2916
RW
1144lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn,
1145 struct map *wcard, struct status_tlv *st)
8429abe0
RW
1146{
1147 struct lde_wdraw *lw;
1148 struct map map;
1149 struct fec *f;
1150 struct l2vpn_pw *pw;
1151
1152 if (fn) {
1153 lde_fec2map(&fn->fec, &map);
1154 switch (fn->fec.type) {
1155 case FEC_TYPE_IPV4:
1156 if (!ln->v4_enabled)
1157 return;
1158 break;
1159 case FEC_TYPE_IPV6:
1160 if (!ln->v6_enabled)
1161 return;
1162 break;
1163 case FEC_TYPE_PWID:
1164 pw = (struct l2vpn_pw *) fn->data;
1165 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1166 /* not the remote end of the pseudowire */
1167 return;
1168
1169 if (pw->flags & F_PW_CWORD)
1170 map.flags |= F_MAP_PW_CWORD;
1171 break;
1172 }
1173 map.label = fn->local_label;
0bcc2916
RW
1174 } else
1175 memcpy(&map, wcard, sizeof(map));
8429abe0
RW
1176
1177 if (st) {
1178 map.st.status_code = st->status_code;
1179 map.st.msg_id = st->msg_id;
1180 map.st.msg_type = st->msg_type;
1181 map.flags |= F_MAP_STATUS;
1182 }
1183
1184 /* SWd.1: send label withdraw. */
1185 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
1186 &map, sizeof(map));
1187 lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
1188
1189 /* SWd.2: record label withdraw. */
1190 if (fn) {
1191 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
1192 if (lw == NULL)
1193 lw = lde_wdraw_add(ln, fn);
1194 lw->label = map.label;
1195 } else {
0bcc2916
RW
1196 struct lde_map *me;
1197
8429abe0
RW
1198 RB_FOREACH(f, fec_tree, &ft) {
1199 fn = (struct fec_node *)f;
0bcc2916
RW
1200 me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
1201 if (lde_wildcard_apply(wcard, &fn->fec, me) == 0)
1202 continue;
8429abe0
RW
1203
1204 lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
1205 &fn->fec);
1206 if (lw == NULL)
1207 lw = lde_wdraw_add(ln, fn);
1208 lw->label = map.label;
1209 }
1210 }
1211}
1212
1213void
0bcc2916 1214lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label)
8429abe0 1215{
0bcc2916 1216 struct map wcard;
8429abe0 1217
0bcc2916
RW
1218 memset(&wcard, 0, sizeof(wcard));
1219 wcard.type = MAP_TYPE_WILDCARD;
1220 wcard.label = label;
1221 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
8429abe0
RW
1222}
1223
d4afb819
RW
1224void
1225lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af,
1226 uint32_t label)
1227{
1228 struct map wcard;
1229
1230 memset(&wcard, 0, sizeof(wcard));
1231 wcard.type = MAP_TYPE_TYPED_WCARD;
1232 wcard.fec.twcard.type = MAP_TYPE_PREFIX;
1233 wcard.fec.twcard.u.prefix_af = af;
1234 wcard.label = label;
1235 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1236}
1237
aba50a83
RW
1238void
1239lde_send_labelwithdraw_twcard_pwid(struct lde_nbr *ln, uint16_t pw_type,
1240 uint32_t label)
1241{
1242 struct map wcard;
1243
1244 memset(&wcard, 0, sizeof(wcard));
1245 wcard.type = MAP_TYPE_TYPED_WCARD;
1246 wcard.fec.twcard.type = MAP_TYPE_PWID;
1247 wcard.fec.twcard.u.pw_type = pw_type;
1248 wcard.label = label;
1249 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1250}
1251
8429abe0 1252void
0bcc2916
RW
1253lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type,
1254 uint32_t group_id)
1255{
1256 struct map wcard;
1257
1258 memset(&wcard, 0, sizeof(wcard));
1259 wcard.type = MAP_TYPE_PWID;
1260 wcard.fec.pwid.type = pw_type;
1261 wcard.fec.pwid.group_id = group_id;
1262 /* we can not append a Label TLV when using PWid group wildcards. */
1263 wcard.label = NO_LABEL;
1264 lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
1265}
1266
1267void
1268lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
1269 struct map *wcard, uint32_t label)
8429abe0
RW
1270{
1271 struct map map;
1272 struct l2vpn_pw *pw;
1273
1274 if (fn) {
1275 lde_fec2map(&fn->fec, &map);
1276 switch (fn->fec.type) {
1277 case FEC_TYPE_IPV4:
1278 if (!ln->v4_enabled)
1279 return;
1280 break;
1281 case FEC_TYPE_IPV6:
1282 if (!ln->v6_enabled)
1283 return;
1284 break;
1285 case FEC_TYPE_PWID:
1286 pw = (struct l2vpn_pw *) fn->data;
1287 if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
1288 /* not the remote end of the pseudowire */
1289 return;
1290
1291 if (pw->flags & F_PW_CWORD)
1292 map.flags |= F_MAP_PW_CWORD;
1293 break;
1294 }
0bcc2916
RW
1295 } else
1296 memcpy(&map, wcard, sizeof(map));
8429abe0
RW
1297 map.label = label;
1298
1299 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
1300 &map, sizeof(map));
1301 lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
1302}
1303
2d1aa1e8 1304void
1305lde_send_labelrequest(struct lde_nbr *ln, struct fec_node *fn,
1306 struct map *wcard, int single)
1307{
1308 struct map map;
1309 struct fec *f;
1310 struct lde_req *lre;
1311
1312 if (fn) {
1313 lde_fec2map(&fn->fec, &map);
1314 switch (fn->fec.type) {
1315 case FEC_TYPE_IPV4:
1316 if (!ln->v4_enabled)
1317 return;
1318 break;
1319 case FEC_TYPE_IPV6:
1320 if (!ln->v6_enabled)
1321 return;
1322 break;
1323 default:
1324 fatalx("lde_send_labelrequest: unknown af");
1325 }
1326 } else
1327 memcpy(&map, wcard, sizeof(map));
1328
1329 map.label = NO_LABEL;
1330
1331 if (fn) {
1332 /* SLR1.1: has label request for FEC been previously sent
1333 * and still outstanding just return,
1334 */
1335 lre = (struct lde_req *)fec_find(&ln->sent_req, &fn->fec);
1336 if (lre == NULL) {
1337 /* SLRq.3: send label request */
1338 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD, ln->peerid, 0,
1339 &map, sizeof(map));
1340 if (single)
1341 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END,
1342 ln->peerid, 0, NULL, 0);
1343
1344 /* SLRq.4: record sent request */
1345 lde_req_add(ln, &fn->fec, 1);
1346 }
1347 } else {
1348 /* if Wilcard just send label request */
1349 /* SLRq.3: send label request */
1350 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD,
1351 ln->peerid, 0, &map, sizeof(map));
1352 if (single)
1353 lde_imsg_compose_ldpe(IMSG_REQUEST_ADD_END,
1354 ln->peerid, 0, NULL, 0);
1355
1356 /* SLRq.4: record sent request */
1357 RB_FOREACH(f, fec_tree, &ft) {
1358 fn = (struct fec_node *)f;
1359 lre = (struct lde_req *)fec_find(&ln->sent_req, &fn->fec);
1360 if (lde_wildcard_apply(wcard, &fn->fec, NULL) == 0)
1361 continue;
1362 if (lre == NULL)
1363 lde_req_add(ln, f, 1);
1364 }
1365 }
1366}
1367
1368void
1369lde_send_labelrequest_wcard(struct lde_nbr *ln, uint16_t af)
1370{
1371 struct map wcard;
1372
1373 memset(&wcard, 0, sizeof(wcard));
1374 wcard.type = MAP_TYPE_TYPED_WCARD;
1375 wcard.fec.twcard.type = MAP_TYPE_PREFIX;
1376 wcard.fec.twcard.u.prefix_af = af;
1377 lde_send_labelrequest(ln, NULL, &wcard, 1);
1378}
1379
8429abe0 1380void
05aac414 1381lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
8429abe0
RW
1382 uint16_t msg_type)
1383{
1384 struct notify_msg nm;
1385
1386 memset(&nm, 0, sizeof(nm));
1387 nm.status_code = status_code;
1388 /* 'msg_id' and 'msg_type' should be in network byte order */
1389 nm.msg_id = msg_id;
1390 nm.msg_type = msg_type;
1391
05aac414 1392 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
8429abe0
RW
1393 &nm, sizeof(nm));
1394}
1395
257799cd
RW
1396void
1397lde_send_notification_eol_prefix(struct lde_nbr *ln, int af)
1398{
1399 struct notify_msg nm;
1400
1401 memset(&nm, 0, sizeof(nm));
1402 nm.status_code = S_ENDOFLIB;
1403 nm.fec.type = MAP_TYPE_TYPED_WCARD;
1404 nm.fec.fec.twcard.type = MAP_TYPE_PREFIX;
1405 nm.fec.fec.twcard.u.prefix_af = af;
1406 nm.flags |= F_NOTIF_FEC;
1407
1408 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1409 &nm, sizeof(nm));
1410}
1411
1412void
1413lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
1414{
1415 struct notify_msg nm;
1416
1417 memset(&nm, 0, sizeof(nm));
1418 nm.status_code = S_ENDOFLIB;
1419 nm.fec.type = MAP_TYPE_TYPED_WCARD;
1420 nm.fec.fec.twcard.type = MAP_TYPE_PWID;
1421 nm.fec.fec.twcard.u.pw_type = pw_type;
1422 nm.flags |= F_NOTIF_FEC;
1423
1424 lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1425 &nm, sizeof(nm));
1426}
1427
8429abe0 1428static __inline int
45926e58 1429lde_nbr_compare(const struct lde_nbr *a, const struct lde_nbr *b)
8429abe0
RW
1430{
1431 return (a->peerid - b->peerid);
1432}
1433
1434static struct lde_nbr *
1435lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
1436{
1437 struct lde_nbr *ln;
1438
1439 if ((ln = calloc(1, sizeof(*ln))) == NULL)
1440 fatal(__func__);
1441
1442 ln->id = new->id;
1443 ln->v4_enabled = new->v4_enabled;
1444 ln->v6_enabled = new->v6_enabled;
257799cd 1445 ln->flags = new->flags;
8429abe0
RW
1446 ln->peerid = peerid;
1447 fec_init(&ln->recv_map);
1448 fec_init(&ln->sent_map);
7c2abbd7 1449 fec_init(&ln->sent_map_pending);
8429abe0
RW
1450 fec_init(&ln->recv_req);
1451 fec_init(&ln->sent_req);
1452 fec_init(&ln->sent_wdraw);
1453
1454 TAILQ_INIT(&ln->addr_list);
1455
1456 if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
1457 fatalx("lde_nbr_new: RB_INSERT failed");
1458
1459 return (ln);
1460}
1461
1462static void
1463lde_nbr_del(struct lde_nbr *ln)
1464{
1465 struct fec *f;
1466 struct fec_node *fn;
1467 struct fec_nh *fnh;
1468 struct l2vpn_pw *pw;
aff1743c 1469 struct lde_nbr *lnbr;
8429abe0
RW
1470
1471 if (ln == NULL)
1472 return;
1473
1474 /* uninstall received mappings */
1475 RB_FOREACH(f, fec_tree, &ft) {
1476 fn = (struct fec_node *)f;
1477
077d336a
RW
1478 /* Update RLFA clients. */
1479 lde_rlfa_update_clients(f, ln, MPLS_INVALID_LABEL);
1480
8429abe0
RW
1481 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1482 switch (f->type) {
1483 case FEC_TYPE_IPV4:
1484 case FEC_TYPE_IPV6:
1485 if (!lde_address_find(ln, fnh->af,
1486 &fnh->nexthop))
1487 continue;
aff1743c
KS
1488
1489 /*
1490 * Ordered Control: must mark any non-connected
1491 * NH to wait until we receive a labelmap msg
1492 * before installing in kernel and sending to
1493 * peer, must do this as NHs are not removed
1494 * when lsps go down. Also send label withdraw
1495 * to other neighbors for all fecs from neighbor
1496 * going down
1497 */
1498 if (ldeconf->flags & F_LDPD_ORDERED_CONTROL) {
1499 fnh->flags |= F_FEC_NH_DEFER;
1500
1501 RB_FOREACH(lnbr, nbr_tree, &lde_nbrs) {
1502 if (ln->peerid == lnbr->peerid)
1503 continue;
1504 lde_send_labelwithdraw(lnbr, fn, NULL, NULL);
1505 }
1506 }
8429abe0
RW
1507 break;
1508 case FEC_TYPE_PWID:
1509 if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1510 continue;
1511 pw = (struct l2vpn_pw *) fn->data;
6bbdd9e9 1512 if (pw) {
1513 pw->reason = F_PW_NO_REMOTE_LABEL;
8429abe0 1514 l2vpn_pw_reset(pw);
6bbdd9e9 1515 }
8429abe0
RW
1516 break;
1517 default:
1518 break;
1519 }
1520
1521 lde_send_delete_klabel(fn, fnh);
1522 fnh->remote_label = NO_LABEL;
1523 }
1524 }
1525
1526 lde_address_list_free(ln);
1527
1528 fec_clear(&ln->recv_map, lde_map_free);
1529 fec_clear(&ln->sent_map, lde_map_free);
7c2abbd7 1530 fec_clear(&ln->sent_map_pending, free);
8429abe0
RW
1531 fec_clear(&ln->recv_req, free);
1532 fec_clear(&ln->sent_req, free);
1533 fec_clear(&ln->sent_wdraw, free);
1534
1535 RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1536
1537 free(ln);
1538}
1539
1540static struct lde_nbr *
1541lde_nbr_find(uint32_t peerid)
1542{
1543 struct lde_nbr ln;
1544
1545 ln.peerid = peerid;
1546
1547 return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1548}
1549
1550struct lde_nbr *
1551lde_nbr_find_by_lsrid(struct in_addr addr)
1552{
1553 struct lde_nbr *ln;
1554
1555 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1556 if (ln->id.s_addr == addr.s_addr)
1557 return (ln);
1558
1559 return (NULL);
1560}
1561
1562struct lde_nbr *
1563lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1564{
1565 struct lde_nbr *ln;
1566
1567 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1568 if (lde_address_find(ln, af, addr) != NULL)
1569 return (ln);
1570
1571 return (NULL);
1572}
1573
1574static void
1575lde_nbr_clear(void)
1576{
1577 struct lde_nbr *ln;
1578
55cd0f61
DS
1579 while (!RB_EMPTY(nbr_tree, &lde_nbrs)) {
1580 ln = RB_ROOT(nbr_tree, &lde_nbrs);
1581
8429abe0 1582 lde_nbr_del(ln);
55cd0f61 1583 }
8429abe0
RW
1584}
1585
1586static void
1587lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1588{
1589 struct fec *fec;
1590 struct fec_node *fn;
1591 struct fec_nh *fnh;
1592 struct lde_map *me;
1593
1594 RB_FOREACH(fec, fec_tree, &ln->recv_map) {
8429abe0
RW
1595 switch (fec->type) {
1596 case FEC_TYPE_IPV4:
1597 if (lde_addr->af != AF_INET)
1598 continue;
1599 break;
1600 case FEC_TYPE_IPV6:
1601 if (lde_addr->af != AF_INET6)
1602 continue;
1603 break;
1604 default:
1605 continue;
1606 }
1607
1e4c8673
RW
1608 fn = (struct fec_node *)fec_find(&ft, fec);
1609 if (fn == NULL)
1610 /* shouldn't happen */
1611 continue;
1612
8429abe0
RW
1613 LIST_FOREACH(fnh, &fn->nexthops, entry) {
1614 if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1615 &lde_addr->addr))
1616 continue;
1617
1618 if (removed) {
1619 lde_send_delete_klabel(fn, fnh);
1620 fnh->remote_label = NO_LABEL;
1621 } else {
1622 me = (struct lde_map *)fec;
1623 fnh->remote_label = me->map.label;
1624 lde_send_change_klabel(fn, fnh);
1625 }
1626 break;
1627 }
1628 }
1629}
1630
d3e1887a 1631static __inline int
45926e58 1632lde_map_compare(const struct lde_map *a, const struct lde_map *b)
d3e1887a
RW
1633{
1634 return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
1635 (union ldpd_addr *)&b->nexthop->id));
1636}
1637
8429abe0
RW
1638struct lde_map *
1639lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1640{
1641 struct lde_map *me;
1642
1643 me = calloc(1, sizeof(*me));
1644 if (me == NULL)
1645 fatal(__func__);
1646
1647 me->fec = fn->fec;
1648 me->nexthop = ln;
1649
1650 if (sent) {
d3e1887a
RW
1651 RB_INSERT(lde_map_head, &fn->upstream, me);
1652 me->head = &fn->upstream;
8429abe0
RW
1653 if (fec_insert(&ln->sent_map, &me->fec))
1654 log_warnx("failed to add %s to sent map",
1655 log_fec(&me->fec));
1656 /* XXX on failure more cleanup is needed */
1657 } else {
d3e1887a
RW
1658 RB_INSERT(lde_map_head, &fn->downstream, me);
1659 me->head = &fn->downstream;
8429abe0
RW
1660 if (fec_insert(&ln->recv_map, &me->fec))
1661 log_warnx("failed to add %s to recv map",
1662 log_fec(&me->fec));
1663 }
1664
1665 return (me);
1666}
1667
1668void
1669lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1670{
1671 if (sent)
1672 fec_remove(&ln->sent_map, &me->fec);
1673 else
1674 fec_remove(&ln->recv_map, &me->fec);
1675
1676 lde_map_free(me);
1677}
1678
1679static void
1680lde_map_free(void *ptr)
1681{
1682 struct lde_map *map = ptr;
1683
d3e1887a 1684 RB_REMOVE(lde_map_head, map->head, map);
8429abe0
RW
1685 free(map);
1686}
1687
7c2abbd7
RW
1688struct fec *
1689lde_map_pending_add(struct lde_nbr *ln, struct fec_node *fn)
1690{
1691 struct fec *map;
1692
1693 map = calloc(1, sizeof(*map));
1694 if (map == NULL)
1695 fatal(__func__);
1696
1697 *map = fn->fec;
1698 if (fec_insert(&ln->sent_map_pending, map))
1699 log_warnx("failed to add %s to sent map (pending)",
1700 log_fec(map));
1701
1702 return (map);
1703}
1704
1705void
1706lde_map_pending_del(struct lde_nbr *ln, struct fec *map)
1707{
1708 fec_remove(&ln->sent_map_pending, map);
1709 free(map);
1710}
1711
8429abe0
RW
1712struct lde_req *
1713lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1714{
1715 struct fec_tree *t;
1716 struct lde_req *lre;
1717
1718 t = sent ? &ln->sent_req : &ln->recv_req;
1719
1720 lre = calloc(1, sizeof(*lre));
1721 if (lre != NULL) {
1722 lre->fec = *fec;
1723
1724 if (fec_insert(t, &lre->fec)) {
1725 log_warnx("failed to add %s to %s req",
1726 log_fec(&lre->fec), sent ? "sent" : "recv");
1727 free(lre);
1728 return (NULL);
1729 }
1730 }
1731
1732 return (lre);
1733}
1734
1735void
1736lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1737{
1738 if (sent)
1739 fec_remove(&ln->sent_req, &lre->fec);
1740 else
1741 fec_remove(&ln->recv_req, &lre->fec);
1742
1743 free(lre);
1744}
1745
1746struct lde_wdraw *
1747lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1748{
1749 struct lde_wdraw *lw;
1750
1751 lw = calloc(1, sizeof(*lw));
1752 if (lw == NULL)
1753 fatal(__func__);
1754
1755 lw->fec = fn->fec;
1756
1757 if (fec_insert(&ln->sent_wdraw, &lw->fec))
1758 log_warnx("failed to add %s to sent wdraw",
1759 log_fec(&lw->fec));
1760
1761 return (lw);
1762}
1763
1764void
1765lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1766{
1767 fec_remove(&ln->sent_wdraw, &lw->fec);
1768 free(lw);
1769}
1770
1771void
45a8eba9 1772lde_change_egress_label(int af)
8429abe0
RW
1773{
1774 struct lde_nbr *ln;
1775 struct fec *f;
1776 struct fec_node *fn;
1777
be54d744 1778 /* explicitly withdraw all null labels */
8429abe0 1779 RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
70e98a7f 1780 lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLICIT_NULL);
45a8eba9 1781 if (ln->v4_enabled)
70e98a7f
DS
1782 lde_send_labelwithdraw_wcard(
1783 ln,
1784 MPLS_LABEL_IPV4_EXPLICIT_NULL);
45a8eba9 1785 if (ln->v6_enabled)
70e98a7f
DS
1786 lde_send_labelwithdraw_wcard(
1787 ln,
1788 MPLS_LABEL_IPV6_EXPLICIT_NULL);
be54d744 1789 }
8429abe0 1790
be54d744
RW
1791 /* update label of connected routes */
1792 RB_FOREACH(f, fec_tree, &ft) {
1793 fn = (struct fec_node *)f;
1794 if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1795 continue;
8429abe0 1796
be54d744
RW
1797 switch (af) {
1798 case AF_INET:
1799 if (fn->fec.type != FEC_TYPE_IPV4)
1800 continue;
1801 break;
1802 case AF_INET6:
1803 if (fn->fec.type != FEC_TYPE_IPV6)
1804 continue;
1805 break;
1806 default:
1807 fatalx("lde_change_egress_label: unknown af");
8429abe0
RW
1808 }
1809
8cb1fc45 1810 fn->local_label = lde_update_label(fn);
45a8eba9
RW
1811 if (fn->local_label != NO_LABEL)
1812 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1813 lde_send_labelmapping(ln, fn, 0);
be54d744
RW
1814 }
1815 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
8429abe0
RW
1816 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1817 NULL, 0);
8429abe0
RW
1818}
1819
86753560 1820void
2d1aa1e8 1821lde_change_allocate_filter(int af)
86753560 1822{
1823 struct lde_nbr *ln;
1824 struct fec *f;
1825 struct fec_node *fn;
1826 uint32_t new_label;
1827
2d1aa1e8 1828 /* reallocate labels for fecs that match this filter */
86753560 1829 RB_FOREACH(f, fec_tree, &ft) {
1830 fn = (struct fec_node *)f;
1831
1832 switch (af) {
1833 case AF_INET:
1834 if (fn->fec.type != FEC_TYPE_IPV4)
1835 continue;
1836 break;
1837 case AF_INET6:
1838 if (fn->fec.type != FEC_TYPE_IPV6)
1839 continue;
1840 break;
1841 default:
2d1aa1e8 1842 fatalx("lde_change_allocate_filter: unknown af");
86753560 1843 }
1844
1845 /*
1846 * If the local label has changed to NO_LABEL, send a label
1847 * withdraw to all peers.
1848 * If the local label has changed and it's different from
1849 * NO_LABEL, send a label mapping to all peers advertising
1850 * the new label.
1851 * If the local label hasn't changed, do nothing
1852 */
1853 new_label = lde_update_label(fn);
1854 if (fn->local_label != new_label) {
1855 if (new_label == NO_LABEL)
1856 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1857 lde_send_labelwithdraw(ln, fn,
1858 NULL, NULL);
1859
1860 fn->local_label = new_label;
1861 if (fn->local_label != NO_LABEL)
1862 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1863 lde_send_labelmapping(ln, fn, 0);
1864 }
1865 }
1866 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1867 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1868 NULL, 0);
1869}
1870
2d1aa1e8 1871void
1872lde_change_advertise_filter(int af)
1873{
1874 struct lde_nbr *ln;
1875 struct fec *f;
1876 struct fec_node *fn;
1877 char *acl_to_filter;
1878 char *acl_for_filter;
1879 union ldpd_addr *prefix;
1880 uint8_t plen;
1881 struct lde_map *me;
1882
1883 /* advertise label for fecs to neighbors if matches advertise filters */
1884 switch (af) {
1885 case AF_INET:
1886 acl_to_filter = ldeconf->ipv4.acl_label_advertise_to;
1887 acl_for_filter = ldeconf->ipv4.acl_label_advertise_for;
1888 break;
1889 case AF_INET6:
1890 acl_to_filter = ldeconf->ipv6.acl_label_advertise_to;
1891 acl_for_filter = ldeconf->ipv6.acl_label_advertise_for;
1892 break;
1893 default:
1894 fatalx("lde_change_advertise_filter: unknown af");
1895 }
1896
1897 RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1898 if (lde_acl_check(acl_to_filter, af, (union ldpd_addr *)&ln->id,
1899 IPV4_MAX_BITLEN) != FILTER_PERMIT)
1900 lde_send_labelwithdraw_wcard(ln, NO_LABEL);
1901 else {
1902 /* This neighbor is allowed in to_filter, so
1903 * send labels if fec also matches for_filter
1904 */
1905 RB_FOREACH(f, fec_tree, &ft) {
1906 fn = (struct fec_node *)f;
1907 switch (af) {
1908 case AF_INET:
1909 if (fn->fec.type != FEC_TYPE_IPV4)
1910 continue;
1911 prefix = (union ldpd_addr *)
1912 &fn->fec.u.ipv4.prefix;
1913 plen = fn->fec.u.ipv4.prefixlen;
1914 break;
1915 case FEC_TYPE_IPV6:
1916 if (fn->fec.type != FEC_TYPE_IPV6)
1917 continue;
1918 prefix = (union ldpd_addr *)
1919 &fn->fec.u.ipv6.prefix;
1920 plen = fn->fec.u.ipv6.prefixlen;
1921 break;
1922 default:
1923 continue;
1924 }
1925 if (lde_acl_check(acl_for_filter, af,
1926 prefix, plen) != FILTER_PERMIT) {
1927 me = (struct lde_map *)fec_find(
1928 &ln->sent_map, &fn->fec);
1929 if (me)
1930 /* fec filtered withdraw */
1931 lde_send_labelwithdraw(ln, fn,
1932 NULL, NULL);
1933 } else
1934 /* fec allowed send map */
1935 lde_send_labelmapping(ln, fn, 0);
1936 }
1937 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END,
1938 ln->peerid, 0, NULL, 0);
1939 }
1940 }
1941}
1942
1943
1944void
1945lde_change_accept_filter(int af)
1946{
1947 struct lde_nbr *ln;
1948 struct fec *f;
1949 struct fec_node *fn;
1950 char *acl_for_filter;
1951 char *acl_from_filter;
1952 union ldpd_addr *prefix;
1953 uint8_t plen;
1954 struct lde_map *me;
1955 enum fec_type type;
1956
1957 /* accept labels from neighbors specified in the from_filter and for
1958 * fecs defined in the for_filter
1959 */
1960 switch (af) {
1961 case AF_INET:
1962 acl_for_filter = ldeconf->ipv4.acl_label_accept_for;
1963 acl_from_filter = ldeconf->ipv4.acl_label_accept_from;
1964 type = FEC_TYPE_IPV4;
1965 break;
1966 case AF_INET6:
1967 acl_for_filter = ldeconf->ipv6.acl_label_accept_for;
1968 acl_from_filter = ldeconf->ipv6.acl_label_accept_from;
1969 type = FEC_TYPE_IPV6;
1970 break;
1971 default:
1972 fatalx("lde_change_accept_filter: unknown af");
1973 }
1974
1975 RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1976 if (lde_acl_check(acl_from_filter, AF_INET, (union ldpd_addr *)
1977 &ln->id, IPV4_MAX_BITLEN) != FILTER_PERMIT) {
1978 /* This neighbor is now filtered so remove fecs from
1979 * recv list
1980 */
1981 RB_FOREACH(f, fec_tree, &ft) {
1982 fn = (struct fec_node *)f;
1983 if (fn->fec.type == type) {
1984 me = (struct lde_map *)fec_find(
1985 &ln->recv_map, &fn->fec);
1986 if (me)
1987 lde_map_del(ln, me, 0);
1988 }
1989 }
1990 } else if (ln->flags & F_NBR_CAP_TWCARD) {
1991 /* This neighbor is allowed and supports type
1992 * wildcard so send a labelrequest
1993 * to get any new labels from neighbor
1994 * and make sure any fecs we currently have
1995 * match for_filter.
1996 */
1997 RB_FOREACH(f, fec_tree, &ft) {
1998 fn = (struct fec_node *)f;
1999 switch (af) {
2000 case AF_INET:
2001 if (fn->fec.type != FEC_TYPE_IPV4)
2002 continue;
2003 prefix = (union ldpd_addr *)
2004 &fn->fec.u.ipv4.prefix;
2005 plen = fn->fec.u.ipv4.prefixlen;
2006 break;
2007 case AF_INET6:
2008 if (fn->fec.type != FEC_TYPE_IPV6)
2009 continue;
2010 prefix = (union ldpd_addr *)
2011 &fn->fec.u.ipv6.prefix;
2012 plen = fn->fec.u.ipv6.prefixlen;
2013 break;
2014 default:
2015 continue;
2016 }
2017 if (lde_acl_check(acl_for_filter, af,
2018 prefix, plen) != FILTER_PERMIT) {
2019 me = (struct lde_map *)fec_find(
2020 &ln->recv_map, &fn->fec);
2021 if (me)
2022 lde_map_del(ln, me, 0);
2023 }
2024 }
2025 lde_send_labelrequest_wcard(ln, af);
2026 } else
2027 /* Type Wildcard is not supported so restart session */
2028 lde_imsg_compose_ldpe(IMSG_NBR_SHUTDOWN, ln->peerid, 0,
2029 NULL, 0);
2030 }
2031}
2032
2033void
2034lde_change_expnull_for_filter(int af)
2035{
2036 struct lde_nbr *ln;
2037 struct fec *f;
2038 struct fec_node *fn;
2039 char *acl_name;
2040 uint32_t exp_label;
2041 union ldpd_addr *prefix;
2042 uint8_t plen;
2043
2044 /* Configure explicit-null advertisement for all fecs in this filter */
2045 RB_FOREACH(f, fec_tree, &ft) {
2046 fn = (struct fec_node *)f;
2047
2048 switch (af) {
2049 case AF_INET:
2050 if (fn->fec.type != FEC_TYPE_IPV4)
2051 continue;
2052 acl_name = ldeconf->ipv4.acl_label_expnull_for;
2053 prefix = (union ldpd_addr *)&fn->fec.u.ipv4.prefix;
2054 plen = fn->fec.u.ipv4.prefixlen;
2055 exp_label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
2056 break;
2057 case AF_INET6:
2058 if (fn->fec.type != FEC_TYPE_IPV6)
2059 continue;
2060 acl_name = ldeconf->ipv6.acl_label_expnull_for;
2061 prefix = (union ldpd_addr *)&fn->fec.u.ipv6.prefix;
2062 plen = fn->fec.u.ipv6.prefixlen;
2063 exp_label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
2064 break;
2065 default:
2066 fatalx("lde_change_expnull_for_filter: unknown af");
2067 }
2068
2069 if (lde_acl_check(acl_name, af, prefix, plen) == FILTER_PERMIT) {
2070 /* for this fec change any imp-null to exp-null */
2071 if (fn->local_label == MPLS_LABEL_IMPLICIT_NULL) {
2072 fn->local_label= lde_update_label(fn);
2073 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2074 lde_send_labelmapping(ln, fn, 0);
2075 }
2076 } else {
2077 /* for this fec change any exp-null back to imp-null */
2078 if (fn->local_label == exp_label) {
2079 fn->local_label = lde_update_label(fn);
2080 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2081 lde_send_labelmapping(ln, fn, 0);
2082 }
2083 }
2084 }
2085 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2086 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
2087 NULL, 0);
2088}
2089
8429abe0
RW
2090static int
2091lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
2092{
2093 struct lde_addr *new;
2094
2095 if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
2096 return (-1);
2097
2098 if ((new = calloc(1, sizeof(*new))) == NULL)
2099 fatal(__func__);
2100
2101 new->af = lde_addr->af;
2102 new->addr = lde_addr->addr;
2103 TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
2104
2105 /* reevaluate the previously received mappings from this neighbor */
2106 lde_nbr_addr_update(ln, lde_addr, 0);
2107
2108 return (0);
2109}
2110
2111static int
2112lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
2113{
2114 lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
2115 if (lde_addr == NULL)
2116 return (-1);
2117
2118 /* reevaluate the previously received mappings from this neighbor */
2119 lde_nbr_addr_update(ln, lde_addr, 1);
2120
2121 TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
2122 free(lde_addr);
2123
2124 return (0);
2125}
2126
2127struct lde_addr *
2128lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
2129{
2130 struct lde_addr *lde_addr;
2131
2132 TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
2133 if (lde_addr->af == af &&
2134 ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
2135 return (lde_addr);
2136
2137 return (NULL);
2138}
2139
2140static void
2141lde_address_list_free(struct lde_nbr *ln)
2142{
2143 struct lde_addr *lde_addr;
2144
a43ad4fe 2145 while ((lde_addr = TAILQ_POP_FIRST(&ln->addr_list, entry)) != NULL)
8429abe0 2146 free(lde_addr);
8429abe0 2147}
fea12efb 2148
9d694b0b
MS
2149/*
2150 * Event callback used to retry the label-manager sync zapi session.
2151 */
2152static int zclient_sync_retry(struct thread *thread)
2153{
2154 zclient_sync_init();
2155
2156 return 0;
2157}
2158
2159/*
2160 * Initialize and open a synchronous zapi session. This is used by label chunk
2161 * management code, which acquires and releases blocks of labels from the
2162 * zebra label-manager module.
2163 */
2164static void zclient_sync_init(void)
5afba51d 2165{
17da84a4 2166 struct zclient_options options = zclient_options_default;
9d694b0b 2167
17da84a4
KS
2168 options.synchronous = true;
2169
5afba51d 2170 /* Initialize special zclient for synchronous message exchanges. */
17da84a4 2171 zclient_sync = zclient_new(master, &options);
5afba51d
RW
2172 zclient_sync->sock = -1;
2173 zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
4cebdb9b 2174 zclient_sync->session_id = 1; /* Distinguish from main session */
342213ea
DS
2175 zclient_sync->privs = &lde_privs;
2176
9d694b0b 2177 if (zclient_socket_connect(zclient_sync) < 0) {
5afba51d 2178 log_warnx("Error connecting synchronous zclient!");
9d694b0b 2179 goto retry;
5afba51d 2180 }
fa84d193
DL
2181 /* make socket non-blocking */
2182 sock_set_nonblock(zclient_sync->sock);
5afba51d 2183
17da84a4 2184 /* Send hello to notify zebra this is a synchronous client */
7cfdb485 2185 if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
17da84a4 2186 log_warnx("Error sending hello for synchronous zclient!");
9d694b0b 2187 goto retry;
17da84a4
KS
2188 }
2189
5afba51d 2190 /* Connect to label manager */
9d694b0b 2191 if (lm_label_manager_connect(zclient_sync, 0) != 0) {
5afba51d 2192 log_warnx("Error connecting to label manager!");
9d694b0b 2193 goto retry;
5afba51d 2194 }
9d694b0b
MS
2195
2196 /* Finish label-manager init once the LM session is running */
2197 lde_label_list_init();
2198
2199 return;
2200
2201retry:
2202
2203 /* Discard failed zclient object */
2204 zclient_stop(zclient_sync);
2205 zclient_free(zclient_sync);
2206 zclient_sync = NULL;
2207
2208 /* Retry using a timer */
2209 thread_add_timer(master, zclient_sync_retry, NULL, 1, NULL);
5afba51d
RW
2210}
2211
fea12efb 2212static void
2213lde_del_label_chunk(void *val)
2214{
2215 free(val);
2216}
5afba51d 2217
f4ec681c
BA
2218static int
2219lde_release_label_chunk(uint32_t start, uint32_t end)
2220{
2221 int ret;
2222
2223 ret = lm_release_label_chunk(zclient_sync, start, end);
2224 if (ret < 0) {
2225 log_warnx("Error releasing label chunk!");
2226 return (-1);
2227 }
2228 return (0);
2229}
2230
fea12efb 2231static int
2232lde_get_label_chunk(void)
2233{
5afba51d
RW
2234 int ret;
2235 uint32_t start, end;
fea12efb 2236
08e4b244 2237 debug_labels("getting label chunk (size %u)", CHUNK_SIZE);
0e3b6a92
EDP
2238 ret = lm_get_label_chunk(zclient_sync, 0, MPLS_LABEL_BASE_ANY,
2239 CHUNK_SIZE, &start, &end);
5afba51d 2240 if (ret < 0) {
fea12efb 2241 log_warnx("Error getting label chunk!");
fea12efb 2242 return -1;
2243 }
2244
2245 on_get_label_chunk_response(start, end);
2246
5afba51d 2247 return (0);
fea12efb 2248}
5afba51d 2249
fea12efb 2250static void
2251lde_label_list_init(void)
2252{
2253 label_chunk_list = list_new();
2254 label_chunk_list->del = lde_del_label_chunk;
2255
2256 /* get first chunk */
73be9aeb 2257 while (lde_get_label_chunk () != 0) {
f2232fdf 2258 log_warnx("Error getting first label chunk!");
d1fcf957 2259 sleep(1);
fea12efb 2260 }
2261}
2262
2263static void
2264on_get_label_chunk_response(uint32_t start, uint32_t end)
2265{
2266 struct label_chunk *new_label_chunk;
2267
08e4b244 2268 debug_labels("label chunk assign: %u - %u", start, end);
fea12efb 2269
2270 new_label_chunk = calloc(1, sizeof(struct label_chunk));
66749b59 2271 if (!new_label_chunk) {
2272 log_warn("Error trying to allocate label chunk %u - %u", start, end);
2273 return;
2274 }
fea12efb 2275
2276 new_label_chunk->start = start;
2277 new_label_chunk->end = end;
2278 new_label_chunk->used_mask = 0;
2279
2280 listnode_add(label_chunk_list, (void *)new_label_chunk);
2281
2282 /* let's update current if needed */
2283 if (!current_label_chunk)
2284 current_label_chunk = listtail(label_chunk_list);
2285}
2286
f4ec681c
BA
2287void
2288lde_free_label(uint32_t label)
2289{
2290 struct listnode *node;
2291 struct label_chunk *label_chunk;
2292 uint64_t pos;
2293
2294 for (ALL_LIST_ELEMENTS_RO(label_chunk_list, node, label_chunk)) {
2295 if (label <= label_chunk->end && label >= label_chunk->start) {
2296 pos = 1ULL << (label - label_chunk->start);
2297 label_chunk->used_mask &= ~pos;
2298 /* if nobody is using this chunk and it's not current_label_chunk, then free it */
2299 if (!label_chunk->used_mask && (current_label_chunk != node)) {
2300 if (lde_release_label_chunk(label_chunk->start, label_chunk->end) != 0)
2301 log_warnx("%s: Error releasing label chunk!", __func__);
2302 else {
2303 listnode_delete(label_chunk_list, label_chunk);
2304 lde_del_label_chunk(label_chunk);
2305 }
2306 }
2307 break;
2308 }
2309 }
2310 return;
2311}
2312
fea12efb 2313static uint32_t
2314lde_get_next_label(void)
2315{
5afba51d 2316 struct label_chunk *label_chunk;
2a178cdd
RW
2317 uint32_t i, size;
2318 uint64_t pos;
5afba51d 2319 uint32_t label = NO_LABEL;
fea12efb 2320
2321 while (current_label_chunk) {
2322 label_chunk = listgetdata(current_label_chunk);
2323 if (!label_chunk)
2324 goto end;
2325
2326 /* try to get next free label in currently used label chunk */
2327 size = label_chunk->end - label_chunk->start + 1;
2328 for (i = 0, pos = 1; i < size; i++, pos <<= 1) {
2329 if (!(pos & label_chunk->used_mask)) {
2330 label_chunk->used_mask |= pos;
2331 label = label_chunk->start + i;
2332 goto end;
2333 }
2334 }
2335 current_label_chunk = listnextnode(current_label_chunk);
2336 }
2337
2338end:
2339 /* we moved till the last chunk, or were not able to find a label,
2340 so let's ask for another one */
5afba51d
RW
2341 if (!current_label_chunk ||
2342 current_label_chunk == listtail(label_chunk_list) ||
2343 label == NO_LABEL) {
fea12efb 2344 if (lde_get_label_chunk() != 0)
2345 log_warn("%s: Error getting label chunk!", __func__);
2346
2347 }
2348
5afba51d 2349 return (label);
fea12efb 2350}
2d1aa1e8 2351
2352static void
2353lde_check_filter_af(int af, struct ldpd_af_conf *af_conf,
2354 const char *filter_name)
2355{
2356 if (strcmp(af_conf->acl_label_allocate_for, filter_name) == 0)
2357 lde_change_allocate_filter(af);
2358 if ((strcmp(af_conf->acl_label_advertise_to, filter_name) == 0)
2359 || (strcmp(af_conf->acl_label_advertise_for, filter_name) == 0))
2360 lde_change_advertise_filter(af);
2361 if ((strcmp(af_conf->acl_label_accept_for, filter_name) == 0)
2362 || (strcmp(af_conf->acl_label_accept_from, filter_name) == 0))
2363 lde_change_accept_filter(af);
2364 if (strcmp(af_conf->acl_label_expnull_for, filter_name) == 0)
2365 lde_change_expnull_for_filter(af);
2366}
95535717 2367
2368void lde_route_update(struct iface *iface, int af)
2369{
2370 struct fec *f;
2371 struct fec_node *fn;
2372 struct fec_nh *fnh;
2373 struct lde_nbr *ln;
2374
2375 /* update label of non-connected routes */
2376 log_debug("update labels for interface %s", iface->name);
2377 RB_FOREACH(f, fec_tree, &ft) {
2378 fn = (struct fec_node *)f;
2379 if (IS_MPLS_UNRESERVED_LABEL(fn->local_label))
2380 continue;
2381
2382 switch (af) {
2383 case AF_INET:
2384 if (fn->fec.type != FEC_TYPE_IPV4)
2385 continue;
2386 break;
2387 case AF_INET6:
2388 if (fn->fec.type != FEC_TYPE_IPV6)
2389 continue;
2390 break;
2391 default:
2392 /* unspecified so process both address families */
2393 break;
2394 }
2395
2396 LIST_FOREACH(fnh, &fn->nexthops, entry) {
2397 /*
2398 * If connected leave existing label. If LDP
2399 * configured on interface or a static route
2400 * may need new label. If no LDP configured
2401 * treat fec as a connected route
2402 */
2403 if (fnh->flags & F_FEC_NH_CONNECTED)
2404 break;
2405
2406 if (fnh->ifindex != iface->ifindex)
2407 continue;
2408
2409 fnh->flags &= ~F_FEC_NH_NO_LDP;
2410 if (IS_MPLS_RESERVED_LABEL(fn->local_label)) {
2411 fn->local_label = NO_LABEL;
2412 fn->local_label = lde_update_label(fn);
2413 if (fn->local_label != NO_LABEL)
2414 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2415 lde_send_labelmapping(
2416 ln, fn, 0);
2417 }
2418 break;
2419 }
2420 }
2421 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2422 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid,
2423 0, NULL, 0);
2424}
2425
2426void lde_route_update_release(struct iface *iface, int af)
2427{
2428 struct lde_nbr *ln;
2429 struct fec *f;
2430 struct fec_node *fn;
2431 struct fec_nh *fnh;
2432
2433 /* update label of interfaces no longer running LDP */
2434 log_debug("release all labels for interface %s af %s", iface->name,
2435 af == AF_INET ? "ipv4" : "ipv6");
2436 RB_FOREACH(f, fec_tree, &ft) {
2437 fn = (struct fec_node *)f;
2438
2439 switch (af) {
2440 case AF_INET:
2441 if (fn->fec.type != FEC_TYPE_IPV4)
2442 continue;
2443 break;
2444 case AF_INET6:
2445 if (fn->fec.type != FEC_TYPE_IPV6)
2446 continue;
2447 break;
2448 default:
2449 fatalx("lde_route_update_release: unknown af");
2450 }
2451
2452 if (fn->local_label == NO_LABEL)
2453 continue;
2454
2455 LIST_FOREACH(fnh, &fn->nexthops, entry) {
2456 /*
2457 * If connected leave existing label. If LDP
2458 * removed from interface may need new label
2459 * and would be treated as a connected route
2460 */
2461 if (fnh->flags & F_FEC_NH_CONNECTED)
2462 break;
2463
2464 if (fnh->ifindex != iface->ifindex)
2465 continue;
2466
2467 fnh->flags |= F_FEC_NH_NO_LDP;
2468 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2469 lde_send_labelwithdraw(ln, fn, NULL, NULL);
2470 lde_free_label(fn->local_label);
2471 fn->local_label = NO_LABEL;
2472 fn->local_label = lde_update_label(fn);
2473 if (fn->local_label != NO_LABEL)
2474 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2475 lde_send_labelmapping(ln, fn, 0);
2476 break;
2477 }
2478 }
2479 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2480 lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid,
2481 0, NULL, 0);
2482}
2483
2484void lde_route_update_release_all(int af)
2485{
2486 struct lde_nbr *ln;
2487 struct fec *f;
2488 struct fec_node *fn;
2489 struct fec_nh *fnh;
2490
2491 /* remove labels from all interfaces as LDP is no longer running for
2492 * this address family
2493 */
2494 log_debug("release all labels for address family %s",
2495 af == AF_INET ? "ipv4" : "ipv6");
2496 RB_FOREACH(f, fec_tree, &ft) {
2497 fn = (struct fec_node *)f;
2498 switch (af) {
2499 case AF_INET:
2500 if (fn->fec.type != FEC_TYPE_IPV4)
2501 continue;
2502 break;
2503 case AF_INET6:
2504 if (fn->fec.type != FEC_TYPE_IPV6)
2505 continue;
2506 break;
2507 default:
2508 fatalx("lde_route_update_release: unknown af");
2509 }
2510
2511 RB_FOREACH(ln, nbr_tree, &lde_nbrs)
2512 lde_send_labelwithdraw(ln, fn, NULL, NULL);
2513
2514 LIST_FOREACH(fnh, &fn->nexthops, entry) {
2515 fnh->flags |= F_FEC_NH_NO_LDP;
2516 lde_send_delete_klabel(fn, fnh);
2517 }
2518 }
2519}