]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldpe.c
Merge pull request #5681 from opensourcerouting/manpage-rename
[mirror_frr.git] / ldpd / ldpe.c
1 /* $OpenBSD$ */
2
3 /*
4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004, 2008 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
22 #include <zebra.h>
23
24 #include "ldpd.h"
25 #include "ldpe.h"
26 #include "lde.h"
27 #include "control.h"
28 #include "log.h"
29 #include "ldp_debug.h"
30
31 #include <lib/log.h>
32 #include "memory.h"
33 #include "privs.h"
34 #include "sigevent.h"
35
36 static void ldpe_shutdown(void);
37 static int ldpe_dispatch_main(struct thread *);
38 static int ldpe_dispatch_lde(struct thread *);
39 #ifdef __OpenBSD__
40 static int ldpe_dispatch_pfkey(struct thread *);
41 #endif
42 static void ldpe_setup_sockets(int, int, int, int);
43 static void ldpe_close_sockets(int);
44 static void ldpe_iface_af_ctl(struct ctl_conn *, int, unsigned int);
45
46 struct ldpd_conf *leconf;
47 #ifdef __OpenBSD__
48 struct ldpd_sysdep sysdep;
49 #endif
50
51 static struct imsgev *iev_main, *iev_main_sync;
52 static struct imsgev *iev_lde;
53 #ifdef __OpenBSD__
54 static struct thread *pfkey_ev;
55 #endif
56
57 /* Master of threads. */
58 struct thread_master *master;
59
60 /* ldpe privileges */
61 static zebra_capabilities_t _caps_p [] =
62 {
63 ZCAP_BIND,
64 ZCAP_NET_ADMIN
65 };
66
67 struct zebra_privs_t ldpe_privs =
68 {
69 #if defined(VTY_GROUP)
70 .vty_group = VTY_GROUP,
71 #endif
72 .caps_p = _caps_p,
73 .cap_num_p = array_size(_caps_p),
74 .cap_num_i = 0
75 };
76
77 /* SIGINT / SIGTERM handler. */
78 static void
79 sigint(void)
80 {
81 ldpe_shutdown();
82 }
83
84 static struct quagga_signal_t ldpe_signals[] =
85 {
86 {
87 .signal = SIGHUP,
88 /* ignore */
89 },
90 {
91 .signal = SIGINT,
92 .handler = &sigint,
93 },
94 {
95 .signal = SIGTERM,
96 .handler = &sigint,
97 },
98 };
99
100 /* label distribution protocol engine */
101 void
102 ldpe(void)
103 {
104 struct thread thread;
105
106 #ifdef HAVE_SETPROCTITLE
107 setproctitle("ldp engine");
108 #endif
109 ldpd_process = PROC_LDP_ENGINE;
110 log_procname = log_procnames[ldpd_process];
111
112 master = thread_master_create(NULL);
113
114 /* setup signal handler */
115 signal_init(master, array_size(ldpe_signals), ldpe_signals);
116
117 /* setup pipes and event handlers to the parent process */
118 if ((iev_main = calloc(1, sizeof(struct imsgev))) == NULL)
119 fatal(NULL);
120 imsg_init(&iev_main->ibuf, LDPD_FD_ASYNC);
121 iev_main->handler_read = ldpe_dispatch_main;
122 iev_main->ev_read = NULL;
123 thread_add_read(master, iev_main->handler_read, iev_main, iev_main->ibuf.fd,
124 &iev_main->ev_read);
125 iev_main->handler_write = ldp_write_handler;
126
127 if ((iev_main_sync = calloc(1, sizeof(struct imsgev))) == NULL)
128 fatal(NULL);
129 imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
130
131 /* create base configuration */
132 leconf = config_new_empty();
133
134 /* Fetch next active thread. */
135 while (thread_fetch(master, &thread))
136 thread_call(&thread);
137 }
138
139 void
140 ldpe_init(struct ldpd_init *init)
141 {
142 #ifdef __OpenBSD__
143 /* This socket must be open before dropping privileges. */
144 global.pfkeysock = pfkey_init();
145 if (sysdep.no_pfkey == 0) {
146 pfkey_ev = NULL;
147 thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
148 &pfkey_ev);
149 }
150 #endif
151
152 /* drop privileges */
153 ldpe_privs.user = init->user;
154 ldpe_privs.group = init->group;
155 zprivs_preinit(&ldpe_privs);
156 zprivs_init(&ldpe_privs);
157
158 /* listen on ldpd control socket */
159 strlcpy(ctl_sock_path, init->ctl_sock_path, sizeof(ctl_sock_path));
160 if (control_init(ctl_sock_path) == -1)
161 fatalx("control socket setup failed");
162 TAILQ_INIT(&ctl_conns);
163 control_listen();
164
165 LIST_INIT(&global.addr_list);
166 RB_INIT(global_adj_head, &global.adj_tree);
167 TAILQ_INIT(&global.pending_conns);
168 if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
169 fatal("inet_pton");
170 if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
171 fatal("inet_pton");
172
173 /* mark sockets as closed */
174 global.ipv4.ldp_disc_socket = -1;
175 global.ipv4.ldp_edisc_socket = -1;
176 global.ipv4.ldp_session_socket = -1;
177 global.ipv6.ldp_disc_socket = -1;
178 global.ipv6.ldp_edisc_socket = -1;
179 global.ipv6.ldp_session_socket = -1;
180
181 if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
182 fatal(__func__);
183
184 accept_init();
185 }
186
187 static void
188 ldpe_shutdown(void)
189 {
190 struct if_addr *if_addr;
191 struct adj *adj;
192
193 /* close pipes */
194 if (iev_lde) {
195 msgbuf_clear(&iev_lde->ibuf.w);
196 close(iev_lde->ibuf.fd);
197 iev_lde->ibuf.fd = -1;
198 }
199 msgbuf_clear(&iev_main->ibuf.w);
200 close(iev_main->ibuf.fd);
201 iev_main->ibuf.fd = -1;
202 msgbuf_clear(&iev_main_sync->ibuf.w);
203 close(iev_main_sync->ibuf.fd);
204 iev_main_sync->ibuf.fd = -1;
205
206 control_cleanup(ctl_sock_path);
207 config_clear(leconf);
208
209 #ifdef __OpenBSD__
210 if (sysdep.no_pfkey == 0) {
211 THREAD_READ_OFF(pfkey_ev);
212 close(global.pfkeysock);
213 }
214 #endif
215 ldpe_close_sockets(AF_INET);
216 ldpe_close_sockets(AF_INET6);
217
218 /* remove addresses from global list */
219 while ((if_addr = LIST_FIRST(&global.addr_list)) != NULL) {
220 LIST_REMOVE(if_addr, entry);
221 assert(if_addr != LIST_FIRST(&global.addr_list));
222 free(if_addr);
223 }
224 while (!RB_EMPTY(global_adj_head, &global.adj_tree)) {
225 adj = RB_ROOT(global_adj_head, &global.adj_tree);
226
227 adj_del(adj, S_SHUTDOWN);
228 }
229
230 /* clean up */
231 if (iev_lde)
232 free(iev_lde);
233 free(iev_main);
234 free(iev_main_sync);
235 free(pkt_ptr);
236
237 log_info("ldp engine exiting");
238 exit(0);
239 }
240
241 /* imesg */
242 int
243 ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
244 {
245 if (iev_main->ibuf.fd == -1)
246 return (0);
247 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
248 }
249
250 void
251 ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
252 {
253 if (iev_main_sync->ibuf.fd == -1)
254 return;
255 imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
256 imsg_flush(&iev_main_sync->ibuf);
257 }
258
259 int
260 ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
261 uint16_t datalen)
262 {
263 if (iev_lde->ibuf.fd == -1)
264 return (0);
265 return (imsg_compose_event(iev_lde, type, peerid, pid, -1,
266 data, datalen));
267 }
268
269 /* ARGSUSED */
270 static int
271 ldpe_dispatch_main(struct thread *thread)
272 {
273 static struct ldpd_conf *nconf;
274 struct iface *niface;
275 struct tnbr *ntnbr;
276 struct nbr_params *nnbrp;
277 static struct l2vpn *l2vpn, *nl2vpn;
278 struct l2vpn_if *lif, *nlif;
279 struct l2vpn_pw *pw, *npw;
280 struct imsg imsg;
281 int fd;
282 struct imsgev *iev = THREAD_ARG(thread);
283 struct imsgbuf *ibuf = &iev->ibuf;
284 struct iface *iface = NULL;
285 struct kif *kif;
286 int af;
287 enum socket_type *socket_type;
288 static int disc_socket = -1;
289 static int edisc_socket = -1;
290 static int session_socket = -1;
291 struct nbr *nbr;
292 #ifdef __OpenBSD__
293 struct nbr_params *nbrp;
294 #endif
295 int n, shut = 0;
296
297 iev->ev_read = NULL;
298
299 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
300 fatal("imsg_read error");
301 if (n == 0) /* connection closed */
302 shut = 1;
303
304 for (;;) {
305 if ((n = imsg_get(ibuf, &imsg)) == -1)
306 fatal("ldpe_dispatch_main: imsg_get error");
307 if (n == 0)
308 break;
309
310 switch (imsg.hdr.type) {
311 case IMSG_IFSTATUS:
312 if (imsg.hdr.len != IMSG_HEADER_SIZE +
313 sizeof(struct kif))
314 fatalx("IFSTATUS imsg with wrong len");
315 kif = imsg.data;
316
317 iface = if_lookup_name(leconf, kif->ifname);
318 if (iface) {
319 if_update_info(iface, kif);
320 ldp_if_update(iface, AF_UNSPEC);
321 break;
322 }
323
324 RB_FOREACH(l2vpn, l2vpn_head, &leconf->l2vpn_tree) {
325 lif = l2vpn_if_find(l2vpn, kif->ifname);
326 if (lif) {
327 l2vpn_if_update_info(lif, kif);
328 l2vpn_if_update(lif);
329 break;
330 }
331 pw = l2vpn_pw_find(l2vpn, kif->ifname);
332 if (pw) {
333 l2vpn_pw_update_info(pw, kif);
334 break;
335 }
336 }
337 break;
338 case IMSG_NEWADDR:
339 if (imsg.hdr.len != IMSG_HEADER_SIZE +
340 sizeof(struct kaddr))
341 fatalx("NEWADDR imsg with wrong len");
342
343 if_addr_add(imsg.data);
344 break;
345 case IMSG_DELADDR:
346 if (imsg.hdr.len != IMSG_HEADER_SIZE +
347 sizeof(struct kaddr))
348 fatalx("DELADDR imsg with wrong len");
349
350 if_addr_del(imsg.data);
351 break;
352 case IMSG_SOCKET_IPC:
353 if (iev_lde) {
354 log_warnx("%s: received unexpected imsg fd "
355 "to lde", __func__);
356 break;
357 }
358 if ((fd = imsg.fd) == -1) {
359 log_warnx("%s: expected to receive imsg fd to "
360 "lde but didn't receive any", __func__);
361 break;
362 }
363
364 if ((iev_lde = malloc(sizeof(struct imsgev))) == NULL)
365 fatal(NULL);
366 imsg_init(&iev_lde->ibuf, fd);
367 iev_lde->handler_read = ldpe_dispatch_lde;
368 iev_lde->ev_read = NULL;
369 thread_add_read(master, iev_lde->handler_read, iev_lde, iev_lde->ibuf.fd,
370 &iev_lde->ev_read);
371 iev_lde->handler_write = ldp_write_handler;
372 iev_lde->ev_write = NULL;
373 break;
374 case IMSG_INIT:
375 if (imsg.hdr.len != IMSG_HEADER_SIZE +
376 sizeof(struct ldpd_init))
377 fatalx("INIT imsg with wrong len");
378
379 memcpy(&init, imsg.data, sizeof(init));
380 ldpe_init(&init);
381 break;
382 case IMSG_CLOSE_SOCKETS:
383 af = imsg.hdr.peerid;
384
385 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
386 if (nbr->af != af)
387 continue;
388 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
389 #ifdef __OpenBSD__
390 pfkey_remove(nbr);
391 #endif
392 nbr->auth.method = AUTH_NONE;
393 }
394 ldpe_close_sockets(af);
395 if_update_all(af);
396 tnbr_update_all(af);
397
398 disc_socket = -1;
399 edisc_socket = -1;
400 session_socket = -1;
401 if ((ldp_af_conf_get(leconf, af))->flags &
402 F_LDPD_AF_ENABLED)
403 ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS,
404 af, NULL, 0);
405 break;
406 case IMSG_SOCKET_NET:
407 if (imsg.hdr.len != IMSG_HEADER_SIZE +
408 sizeof(enum socket_type))
409 fatalx("SOCKET_NET imsg with wrong len");
410 socket_type = imsg.data;
411
412 switch (*socket_type) {
413 case LDP_SOCKET_DISC:
414 disc_socket = imsg.fd;
415 break;
416 case LDP_SOCKET_EDISC:
417 edisc_socket = imsg.fd;
418 break;
419 case LDP_SOCKET_SESSION:
420 session_socket = imsg.fd;
421 break;
422 }
423 break;
424 case IMSG_SETUP_SOCKETS:
425 af = imsg.hdr.peerid;
426 if (disc_socket == -1 || edisc_socket == -1 ||
427 session_socket == -1) {
428 if (disc_socket != -1)
429 close(disc_socket);
430 if (edisc_socket != -1)
431 close(edisc_socket);
432 if (session_socket != -1)
433 close(session_socket);
434 break;
435 }
436
437 ldpe_setup_sockets(af, disc_socket, edisc_socket,
438 session_socket);
439 if_update_all(af);
440 tnbr_update_all(af);
441 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
442 if (nbr->af != af)
443 continue;
444 nbr->laddr = (ldp_af_conf_get(leconf,
445 af))->trans_addr;
446 #ifdef __OpenBSD__
447 nbrp = nbr_params_find(leconf, nbr->id);
448 if (nbrp) {
449 nbr->auth.method = nbrp->auth.method;
450 if (pfkey_establish(nbr, nbrp) == -1)
451 fatalx("pfkey setup failed");
452 }
453 #endif
454 if (nbr_session_active_role(nbr))
455 nbr_establish_connection(nbr);
456 }
457 break;
458 case IMSG_RTRID_UPDATE:
459 memcpy(&global.rtr_id, imsg.data,
460 sizeof(global.rtr_id));
461 if (leconf->rtr_id.s_addr == INADDR_ANY) {
462 ldpe_reset_nbrs(AF_UNSPEC);
463 }
464 if_update_all(AF_UNSPEC);
465 tnbr_update_all(AF_UNSPEC);
466 break;
467 case IMSG_RECONF_CONF:
468 if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
469 NULL)
470 fatal(NULL);
471 memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
472
473 RB_INIT(iface_head, &nconf->iface_tree);
474 RB_INIT(tnbr_head, &nconf->tnbr_tree);
475 RB_INIT(nbrp_head, &nconf->nbrp_tree);
476 RB_INIT(l2vpn_head, &nconf->l2vpn_tree);
477 break;
478 case IMSG_RECONF_IFACE:
479 if ((niface = malloc(sizeof(struct iface))) == NULL)
480 fatal(NULL);
481 memcpy(niface, imsg.data, sizeof(struct iface));
482
483 RB_INSERT(iface_head, &nconf->iface_tree, niface);
484 break;
485 case IMSG_RECONF_TNBR:
486 if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
487 fatal(NULL);
488 memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
489
490 RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
491 break;
492 case IMSG_RECONF_NBRP:
493 if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
494 fatal(NULL);
495 memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
496
497 RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
498 break;
499 case IMSG_RECONF_L2VPN:
500 if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
501 fatal(NULL);
502 memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
503
504 RB_INIT(l2vpn_if_head, &nl2vpn->if_tree);
505 RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree);
506 RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree);
507
508 RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
509 break;
510 case IMSG_RECONF_L2VPN_IF:
511 if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
512 fatal(NULL);
513 memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
514
515 RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
516 break;
517 case IMSG_RECONF_L2VPN_PW:
518 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
519 fatal(NULL);
520 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
521
522 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
523 break;
524 case IMSG_RECONF_L2VPN_IPW:
525 if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
526 fatal(NULL);
527 memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
528
529 RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
530 break;
531 case IMSG_RECONF_END:
532 merge_config(leconf, nconf);
533 ldp_clear_config(nconf);
534 nconf = NULL;
535 global.conf_seqnum++;
536 break;
537 case IMSG_CTL_END:
538 control_imsg_relay(&imsg);
539 break;
540 case IMSG_DEBUG_UPDATE:
541 if (imsg.hdr.len != IMSG_HEADER_SIZE +
542 sizeof(ldp_debug)) {
543 log_warnx("%s: wrong imsg len", __func__);
544 break;
545 }
546 memcpy(&ldp_debug, imsg.data, sizeof(ldp_debug));
547 break;
548 default:
549 log_debug("ldpe_dispatch_main: error handling imsg %d",
550 imsg.hdr.type);
551 break;
552 }
553 imsg_free(&imsg);
554 }
555 if (!shut)
556 imsg_event_add(iev);
557 else {
558 /* this pipe is dead, so remove the event handlers and exit */
559 THREAD_READ_OFF(iev->ev_read);
560 THREAD_WRITE_OFF(iev->ev_write);
561 ldpe_shutdown();
562 }
563
564 return (0);
565 }
566
567 /* ARGSUSED */
568 static int
569 ldpe_dispatch_lde(struct thread *thread)
570 {
571 struct imsgev *iev = THREAD_ARG(thread);
572 struct imsgbuf *ibuf = &iev->ibuf;
573 struct imsg imsg;
574 struct map *map;
575 struct notify_msg *nm;
576 struct nbr *nbr;
577 int n, shut = 0;
578
579 iev->ev_read = NULL;
580
581 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
582 fatal("imsg_read error");
583 if (n == 0) /* connection closed */
584 shut = 1;
585
586 for (;;) {
587 if ((n = imsg_get(ibuf, &imsg)) == -1)
588 fatal("ldpe_dispatch_lde: imsg_get error");
589 if (n == 0)
590 break;
591
592 switch (imsg.hdr.type) {
593 case IMSG_MAPPING_ADD:
594 case IMSG_RELEASE_ADD:
595 case IMSG_REQUEST_ADD:
596 case IMSG_WITHDRAW_ADD:
597 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
598 sizeof(struct map))
599 fatalx("invalid size of map request");
600 map = imsg.data;
601
602 nbr = nbr_find_peerid(imsg.hdr.peerid);
603 if (nbr == NULL) {
604 log_debug("ldpe_dispatch_lde: cannot find "
605 "neighbor");
606 break;
607 }
608 if (nbr->state != NBR_STA_OPER)
609 break;
610
611 switch (imsg.hdr.type) {
612 case IMSG_MAPPING_ADD:
613 mapping_list_add(&nbr->mapping_list, map);
614 break;
615 case IMSG_RELEASE_ADD:
616 mapping_list_add(&nbr->release_list, map);
617 break;
618 case IMSG_REQUEST_ADD:
619 mapping_list_add(&nbr->request_list, map);
620 break;
621 case IMSG_WITHDRAW_ADD:
622 mapping_list_add(&nbr->withdraw_list, map);
623 break;
624 }
625 break;
626 case IMSG_MAPPING_ADD_END:
627 case IMSG_RELEASE_ADD_END:
628 case IMSG_REQUEST_ADD_END:
629 case IMSG_WITHDRAW_ADD_END:
630 nbr = nbr_find_peerid(imsg.hdr.peerid);
631 if (nbr == NULL) {
632 log_debug("ldpe_dispatch_lde: cannot find "
633 "neighbor");
634 break;
635 }
636 if (nbr->state != NBR_STA_OPER)
637 break;
638
639 switch (imsg.hdr.type) {
640 case IMSG_MAPPING_ADD_END:
641 send_labelmessage(nbr, MSG_TYPE_LABELMAPPING,
642 &nbr->mapping_list);
643 break;
644 case IMSG_RELEASE_ADD_END:
645 send_labelmessage(nbr, MSG_TYPE_LABELRELEASE,
646 &nbr->release_list);
647 break;
648 case IMSG_REQUEST_ADD_END:
649 send_labelmessage(nbr, MSG_TYPE_LABELREQUEST,
650 &nbr->request_list);
651 break;
652 case IMSG_WITHDRAW_ADD_END:
653 send_labelmessage(nbr, MSG_TYPE_LABELWITHDRAW,
654 &nbr->withdraw_list);
655 break;
656 }
657 break;
658 case IMSG_NOTIFICATION_SEND:
659 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
660 sizeof(struct notify_msg))
661 fatalx("invalid size of OE request");
662 nm = imsg.data;
663
664 nbr = nbr_find_peerid(imsg.hdr.peerid);
665 if (nbr == NULL) {
666 log_debug("ldpe_dispatch_lde: cannot find "
667 "neighbor");
668 break;
669 }
670 if (nbr->state != NBR_STA_OPER)
671 break;
672
673 send_notification_full(nbr->tcp, nm);
674 break;
675 case IMSG_CTL_END:
676 case IMSG_CTL_SHOW_LIB_BEGIN:
677 case IMSG_CTL_SHOW_LIB_RCVD:
678 case IMSG_CTL_SHOW_LIB_SENT:
679 case IMSG_CTL_SHOW_LIB_END:
680 case IMSG_CTL_SHOW_L2VPN_PW:
681 case IMSG_CTL_SHOW_L2VPN_BINDING:
682 control_imsg_relay(&imsg);
683 break;
684 default:
685 log_debug("ldpe_dispatch_lde: error handling imsg %d",
686 imsg.hdr.type);
687 break;
688 }
689 imsg_free(&imsg);
690 }
691 if (!shut)
692 imsg_event_add(iev);
693 else {
694 /* this pipe is dead, so remove the event handlers and exit */
695 THREAD_READ_OFF(iev->ev_read);
696 THREAD_WRITE_OFF(iev->ev_write);
697 ldpe_shutdown();
698 }
699
700 return (0);
701 }
702
703 #ifdef __OpenBSD__
704 /* ARGSUSED */
705 static int
706 ldpe_dispatch_pfkey(struct thread *thread)
707 {
708 int fd = THREAD_FD(thread);
709
710 pfkey_ev = NULL;
711 thread_add_read(master, ldpe_dispatch_pfkey, NULL, global.pfkeysock,
712 &pfkey_ev);
713
714 if (pfkey_read(fd, NULL) == -1)
715 fatal("pfkey_read failed, exiting...");
716
717 return (0);
718 }
719 #endif /* __OpenBSD__ */
720
721 static void
722 ldpe_setup_sockets(int af, int disc_socket, int edisc_socket,
723 int session_socket)
724 {
725 struct ldpd_af_global *af_global;
726
727 af_global = ldp_af_global_get(&global, af);
728
729 /* discovery socket */
730 af_global->ldp_disc_socket = disc_socket;
731 af_global->disc_ev = NULL;
732 thread_add_read(master, disc_recv_packet, &af_global->disc_ev, af_global->ldp_disc_socket,
733 &af_global->disc_ev);
734
735 /* extended discovery socket */
736 af_global->ldp_edisc_socket = edisc_socket;
737 af_global->edisc_ev = NULL;
738 thread_add_read(master, disc_recv_packet, &af_global->edisc_ev, af_global->ldp_edisc_socket,
739 &af_global->edisc_ev);
740
741 /* session socket */
742 af_global->ldp_session_socket = session_socket;
743 accept_add(af_global->ldp_session_socket, session_accept, NULL);
744 }
745
746 static void
747 ldpe_close_sockets(int af)
748 {
749 struct ldpd_af_global *af_global;
750
751 af_global = ldp_af_global_get(&global, af);
752
753 /* discovery socket */
754 THREAD_READ_OFF(af_global->disc_ev);
755 if (af_global->ldp_disc_socket != -1) {
756 close(af_global->ldp_disc_socket);
757 af_global->ldp_disc_socket = -1;
758 }
759
760 /* extended discovery socket */
761 THREAD_READ_OFF(af_global->edisc_ev);
762 if (af_global->ldp_edisc_socket != -1) {
763 close(af_global->ldp_edisc_socket);
764 af_global->ldp_edisc_socket = -1;
765 }
766
767 /* session socket */
768 if (af_global->ldp_session_socket != -1) {
769 accept_del(af_global->ldp_session_socket);
770 close(af_global->ldp_session_socket);
771 af_global->ldp_session_socket = -1;
772 }
773 }
774
775 int
776 ldpe_acl_check(char *acl_name, int af, union ldpd_addr *addr, uint8_t prefixlen)
777 {
778 return ldp_acl_request(iev_main_sync, acl_name, af, addr, prefixlen);
779 }
780
781 void
782 ldpe_reset_nbrs(int af)
783 {
784 struct nbr *nbr;
785
786 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
787 if (af == AF_UNSPEC || nbr->af == af)
788 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
789 }
790 }
791
792 void
793 ldpe_reset_ds_nbrs(void)
794 {
795 struct nbr *nbr;
796
797 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
798 if (nbr->ds_tlv)
799 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
800 }
801 }
802
803 void
804 ldpe_remove_dynamic_tnbrs(int af)
805 {
806 struct tnbr *tnbr, *safe;
807
808 RB_FOREACH_SAFE(tnbr, tnbr_head, &leconf->tnbr_tree, safe) {
809 if (tnbr->af != af)
810 continue;
811
812 tnbr->flags &= ~F_TNBR_DYNAMIC;
813 tnbr_check(leconf, tnbr);
814 }
815 }
816
817 void
818 ldpe_stop_init_backoff(int af)
819 {
820 struct nbr *nbr;
821
822 RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
823 if (nbr->af == af && nbr_pending_idtimer(nbr)) {
824 nbr_stop_idtimer(nbr);
825 nbr_establish_connection(nbr);
826 }
827 }
828 }
829
830 static void
831 ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx)
832 {
833 struct iface *iface;
834 struct iface_af *ia;
835 struct ctl_iface *ictl;
836
837 RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
838 if (idx == 0 || idx == iface->ifindex) {
839 ia = iface_af_get(iface, af);
840 if (!ia->enabled)
841 continue;
842
843 ictl = if_to_ctl(ia);
844 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_INTERFACE,
845 0, 0, -1, ictl, sizeof(struct ctl_iface));
846 }
847 }
848 }
849
850 void
851 ldpe_iface_ctl(struct ctl_conn *c, unsigned int idx)
852 {
853 ldpe_iface_af_ctl(c, AF_INET, idx);
854 ldpe_iface_af_ctl(c, AF_INET6, idx);
855 }
856
857 void
858 ldpe_adj_ctl(struct ctl_conn *c)
859 {
860 struct adj *adj;
861 struct ctl_adj *actl;
862
863 RB_FOREACH(adj, global_adj_head, &global.adj_tree) {
864 actl = adj_to_ctl(adj);
865 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0,
866 -1, actl, sizeof(struct ctl_adj));
867 }
868
869 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
870 }
871
872 void
873 ldpe_adj_detail_ctl(struct ctl_conn *c)
874 {
875 struct iface *iface;
876 struct tnbr *tnbr;
877 struct adj *adj;
878 struct ctl_adj *actl;
879 struct ctl_disc_if ictl;
880 struct ctl_disc_tnbr tctl;
881
882 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
883
884 RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
885 memset(&ictl, 0, sizeof(ictl));
886 ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE);
887 ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE);
888
889 if (!ictl.active_v4 && !ictl.active_v6)
890 continue;
891
892 strlcpy(ictl.name, iface->name, sizeof(ictl.name));
893 if (RB_EMPTY(ia_adj_head, &iface->ipv4.adj_tree) &&
894 RB_EMPTY(ia_adj_head, &iface->ipv6.adj_tree))
895 ictl.no_adj = 1;
896 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0,
897 -1, &ictl, sizeof(ictl));
898
899 RB_FOREACH(adj, ia_adj_head, &iface->ipv4.adj_tree) {
900 actl = adj_to_ctl(adj);
901 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
902 0, 0, -1, actl, sizeof(struct ctl_adj));
903 }
904 RB_FOREACH(adj, ia_adj_head, &iface->ipv6.adj_tree) {
905 actl = adj_to_ctl(adj);
906 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
907 0, 0, -1, actl, sizeof(struct ctl_adj));
908 }
909 }
910
911 RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree) {
912 memset(&tctl, 0, sizeof(tctl));
913 tctl.af = tnbr->af;
914 tctl.addr = tnbr->addr;
915 if (tnbr->adj == NULL)
916 tctl.no_adj = 1;
917
918 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_TNBR, 0, 0,
919 -1, &tctl, sizeof(tctl));
920
921 if (tnbr->adj == NULL)
922 continue;
923
924 actl = adj_to_ctl(tnbr->adj);
925 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ, 0, 0,
926 -1, actl, sizeof(struct ctl_adj));
927 }
928
929 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
930 }
931
932 void
933 ldpe_nbr_ctl(struct ctl_conn *c)
934 {
935 struct adj *adj;
936 struct ctl_adj *actl;
937 struct nbr *nbr;
938 struct ctl_nbr *nctl;
939
940 RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
941 if (nbr->state == NBR_STA_PRESENT)
942 continue;
943
944 nctl = nbr_to_ctl(nbr);
945 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
946 sizeof(struct ctl_nbr));
947
948 RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree) {
949 actl = adj_to_ctl(adj);
950 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_DISC,
951 0, 0, -1, actl, sizeof(struct ctl_adj));
952 }
953
954 imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_END, 0, 0, -1,
955 NULL, 0);
956 }
957 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
958 }
959
960 void
961 mapping_list_add(struct mapping_head *mh, struct map *map)
962 {
963 struct mapping_entry *me;
964
965 me = calloc(1, sizeof(*me));
966 if (me == NULL)
967 fatal(__func__);
968 me->map = *map;
969
970 TAILQ_INSERT_TAIL(mh, me, entry);
971 }
972
973 void
974 mapping_list_clr(struct mapping_head *mh)
975 {
976 struct mapping_entry *me;
977
978 while ((me = TAILQ_FIRST(mh)) != NULL) {
979 TAILQ_REMOVE(mh, me, entry);
980 assert(me != TAILQ_FIRST(mh));
981 free(me);
982 }
983 }