xref: /openbsd/usr.sbin/ldpd/ldpe.c (revision 4bba3f27)
1 /*	$OpenBSD: ldpe.c,v 1.82 2023/12/14 11:10:19 claudio Exp $ */
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 <sys/types.h>
23 #include <stdlib.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <pwd.h>
27 #include <unistd.h>
28 #include <arpa/inet.h>
29 #include <errno.h>
30 
31 #include "ldpd.h"
32 #include "ldpe.h"
33 #include "lde.h"
34 #include "control.h"
35 #include "log.h"
36 
37 static void	 ldpe_sig_handler(int, short, void *);
38 static __dead void ldpe_shutdown(void);
39 static void	 ldpe_dispatch_main(int, short, void *);
40 static void	 ldpe_dispatch_lde(int, short, void *);
41 static void	 ldpe_dispatch_pfkey(int, short, void *);
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 struct ldpd_sysdep	 sysdep;
48 
49 static struct imsgev	*iev_main;
50 static struct imsgev	*iev_lde;
51 static struct event	 pfkey_ev;
52 
53 static void
ldpe_sig_handler(int sig,short event,void * bula)54 ldpe_sig_handler(int sig, short event, void *bula)
55 {
56 	switch (sig) {
57 	case SIGINT:
58 	case SIGTERM:
59 		ldpe_shutdown();
60 		/* NOTREACHED */
61 	default:
62 		fatalx("unexpected signal");
63 	}
64 }
65 
66 /* label distribution protocol engine */
67 void
ldpe(int debug,int verbose,char * sockname)68 ldpe(int debug, int verbose, char *sockname)
69 {
70 	struct passwd		*pw;
71 	struct event		 ev_sigint, ev_sigterm;
72 
73 	leconf = config_new_empty();
74 
75 	log_init(debug);
76 	log_verbose(verbose);
77 
78 	setproctitle("ldp engine");
79 	ldpd_process = PROC_LDP_ENGINE;
80 	log_procname = "ldpe";
81 
82 	/* create ldpd control socket outside chroot */
83 	global.csock = sockname;
84 	if (control_init(global.csock) == -1)
85 		fatalx("control socket setup failed");
86 
87 	LIST_INIT(&global.addr_list);
88 	LIST_INIT(&global.adj_list);
89 	TAILQ_INIT(&global.pending_conns);
90 	if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
91 		fatal("inet_pton");
92 	if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
93 		fatal("inet_pton");
94 	global.pfkeysock = pfkey_init();
95 
96 	if ((pw = getpwnam(LDPD_USER)) == NULL)
97 		fatal("getpwnam");
98 
99 	if (chroot(pw->pw_dir) == -1)
100 		fatal("chroot");
101 	if (chdir("/") == -1)
102 		fatal("chdir(\"/\")");
103 
104 	if (setgroups(1, &pw->pw_gid) ||
105 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
106 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
107 		fatal("can't drop privileges");
108 
109 	if (pledge("stdio inet mcast recvfd", NULL) == -1)
110 		fatal("pledge");
111 
112 	event_init();
113 	accept_init();
114 
115 	/* setup signal handler */
116 	signal_set(&ev_sigint, SIGINT, ldpe_sig_handler, NULL);
117 	signal_set(&ev_sigterm, SIGTERM, ldpe_sig_handler, NULL);
118 	signal_add(&ev_sigint, NULL);
119 	signal_add(&ev_sigterm, NULL);
120 	signal(SIGPIPE, SIG_IGN);
121 	signal(SIGHUP, SIG_IGN);
122 
123 	/* setup pipe and event handler to the parent process */
124 	if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
125 		fatal(NULL);
126 	imsg_init(&iev_main->ibuf, 3);
127 	iev_main->handler = ldpe_dispatch_main;
128 	iev_main->events = EV_READ;
129 	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
130 	    iev_main->handler, iev_main);
131 	event_add(&iev_main->ev, NULL);
132 
133 	if (sysdep.no_pfkey == 0) {
134 		event_set(&pfkey_ev, global.pfkeysock, EV_READ | EV_PERSIST,
135 		    ldpe_dispatch_pfkey, NULL);
136 		event_add(&pfkey_ev, NULL);
137 	}
138 
139 	/* mark sockets as closed */
140 	global.ipv4.ldp_disc_socket = -1;
141 	global.ipv4.ldp_edisc_socket = -1;
142 	global.ipv4.ldp_session_socket = -1;
143 	global.ipv6.ldp_disc_socket = -1;
144 	global.ipv6.ldp_edisc_socket = -1;
145 	global.ipv6.ldp_session_socket = -1;
146 
147 	/* listen on ldpd control socket */
148 	control_listen();
149 
150 	event_dispatch();
151 
152 	ldpe_shutdown();
153 }
154 
155 static __dead void
ldpe_shutdown(void)156 ldpe_shutdown(void)
157 {
158 	struct if_addr		*if_addr;
159 	struct adj		*adj;
160 
161 	/* close pipes */
162 	msgbuf_write(&iev_lde->ibuf.w);
163 	msgbuf_clear(&iev_lde->ibuf.w);
164 	close(iev_lde->ibuf.fd);
165 	msgbuf_write(&iev_main->ibuf.w);
166 	msgbuf_clear(&iev_main->ibuf.w);
167 	close(iev_main->ibuf.fd);
168 
169 	control_cleanup();
170 	config_clear(leconf);
171 
172 	if (sysdep.no_pfkey == 0) {
173 		event_del(&pfkey_ev);
174 		close(global.pfkeysock);
175 	}
176 	ldpe_close_sockets(AF_INET);
177 	ldpe_close_sockets(AF_INET6);
178 
179 	/* remove addresses from global list */
180 	while ((if_addr = LIST_FIRST(&global.addr_list)) != NULL) {
181 		LIST_REMOVE(if_addr, entry);
182 		free(if_addr);
183 	}
184 	while ((adj = LIST_FIRST(&global.adj_list)) != NULL)
185 		adj_del(adj, S_SHUTDOWN);
186 
187 	/* clean up */
188 	free(iev_lde);
189 	free(iev_main);
190 
191 	log_info("ldp engine exiting");
192 	exit(0);
193 }
194 
195 /* imesg */
196 int
ldpe_imsg_compose_parent(int type,pid_t pid,void * data,uint16_t datalen)197 ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
198 {
199 	return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
200 }
201 
202 int
ldpe_imsg_compose_lde(int type,uint32_t peerid,pid_t pid,void * data,uint16_t datalen)203 ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
204     uint16_t datalen)
205 {
206 	return (imsg_compose_event(iev_lde, type, peerid, pid, -1,
207 	    data, datalen));
208 }
209 
210 static void
ldpe_dispatch_main(int fd,short event,void * bula)211 ldpe_dispatch_main(int fd, short event, void *bula)
212 {
213 	static struct ldpd_conf	*nconf;
214 	struct iface		*niface;
215 	struct tnbr		*ntnbr;
216 	struct nbr_params	*nnbrp;
217 	static struct l2vpn	*l2vpn, *nl2vpn;
218 	struct l2vpn_if		*lif = NULL, *nlif;
219 	struct l2vpn_pw		*npw;
220 	struct imsg		 imsg;
221 	struct imsgev		*iev = bula;
222 	struct imsgbuf		*ibuf = &iev->ibuf;
223 	struct iface		*iface = NULL;
224 	struct kif		*kif;
225 	int			 af;
226 	enum socket_type	*socket_type;
227 	static int		 disc_socket = -1;
228 	static int		 edisc_socket = -1;
229 	static int		 session_socket = -1;
230 	struct nbr		*nbr;
231 	int			 n, shut = 0;
232 
233 	if (event & EV_READ) {
234 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
235 			fatal("imsg_read error");
236 		if (n == 0)	/* connection closed */
237 			shut = 1;
238 	}
239 	if (event & EV_WRITE) {
240 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
241 			fatal("ldpe_dispatch_main: msgbuf_write");
242 		if (n == 0)
243 			shut = 1;
244 	}
245 
246 	for (;;) {
247 		if ((n = imsg_get(ibuf, &imsg)) == -1)
248 			fatal("ldpe_dispatch_main: imsg_get error");
249 		if (n == 0)
250 			break;
251 
252 		switch (imsg.hdr.type) {
253 		case IMSG_IFSTATUS:
254 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
255 			    sizeof(struct kif))
256 				fatalx("IFSTATUS imsg with wrong len");
257 			kif = imsg.data;
258 
259 			iface = if_lookup(leconf, kif->ifindex);
260 			if (iface) {
261 				iface->flags = kif->flags;
262 				iface->linkstate = kif->link_state;
263 				if_update(iface, AF_UNSPEC);
264 				break;
265 			}
266 
267 			LIST_FOREACH(l2vpn, &leconf->l2vpn_list, entry) {
268 				lif = l2vpn_if_find(l2vpn, kif->ifindex);
269 				if (lif) {
270 					lif->flags = kif->flags;
271 					lif->linkstate = kif->link_state;
272 					memcpy(lif->mac, kif->mac,
273 					    sizeof(lif->mac));
274 					l2vpn_if_update(lif);
275 					break;
276 				}
277 			}
278 			break;
279 		case IMSG_NEWADDR:
280 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
281 			    sizeof(struct kaddr))
282 				fatalx("NEWADDR imsg with wrong len");
283 
284 			if_addr_add(imsg.data);
285 			break;
286 		case IMSG_DELADDR:
287 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
288 			    sizeof(struct kaddr))
289 				fatalx("DELADDR imsg with wrong len");
290 
291 			if_addr_del(imsg.data);
292 			break;
293 		case IMSG_SOCKET_IPC:
294 			if (iev_lde) {
295 				log_warnx("%s: received unexpected imsg fd "
296 				    "to lde", __func__);
297 				break;
298 			}
299 			if ((fd = imsg_get_fd(&imsg)) == -1) {
300 				log_warnx("%s: expected to receive imsg fd to "
301 				    "lde but didn't receive any", __func__);
302 				break;
303 			}
304 
305 			if ((iev_lde = malloc(sizeof(struct imsgev))) == NULL)
306 				fatal(NULL);
307 			imsg_init(&iev_lde->ibuf, fd);
308 			iev_lde->handler = ldpe_dispatch_lde;
309 			iev_lde->events = EV_READ;
310 			event_set(&iev_lde->ev, iev_lde->ibuf.fd,
311 			    iev_lde->events, iev_lde->handler, iev_lde);
312 			event_add(&iev_lde->ev, NULL);
313 			break;
314 		case IMSG_CLOSE_SOCKETS:
315 			af = imsg.hdr.peerid;
316 
317 			RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
318 				if (nbr->af != af)
319 					continue;
320 				session_shutdown(nbr, S_SHUTDOWN, 0, 0);
321 				pfkey_remove(nbr);
322 			}
323 			ldpe_close_sockets(af);
324 			if_update_all(af);
325 			tnbr_update_all(af);
326 
327 			disc_socket = -1;
328 			edisc_socket = -1;
329 			session_socket = -1;
330 			if ((ldp_af_conf_get(leconf, af))->flags &
331 			    F_LDPD_AF_ENABLED)
332 				ldpe_imsg_compose_parent(IMSG_REQUEST_SOCKETS,
333 				    af, NULL, 0);
334 			break;
335 		case IMSG_SOCKET_NET:
336 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
337 			    sizeof(enum socket_type))
338 				fatalx("SOCKET_NET imsg with wrong len");
339 			socket_type = imsg.data;
340 
341 			switch (*socket_type) {
342 			case LDP_SOCKET_DISC:
343 				disc_socket = imsg_get_fd(&imsg);
344 				break;
345 			case LDP_SOCKET_EDISC:
346 				edisc_socket = imsg_get_fd(&imsg);
347 				break;
348 			case LDP_SOCKET_SESSION:
349 				session_socket = imsg_get_fd(&imsg);
350 				break;
351 			}
352 			break;
353 		case IMSG_SETUP_SOCKETS:
354 			af = imsg.hdr.peerid;
355 			if (disc_socket == -1 || edisc_socket == -1 ||
356 			    session_socket == -1) {
357 				if (disc_socket != -1)
358 					close(disc_socket);
359 				if (edisc_socket != -1)
360 					close(edisc_socket);
361 				if (session_socket != -1)
362 					close(session_socket);
363 				break;
364 			}
365 
366 			ldpe_setup_sockets(af, disc_socket, edisc_socket,
367 			    session_socket);
368 			if_update_all(af);
369 			tnbr_update_all(af);
370 			RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
371 				if (nbr->af != af)
372 					continue;
373 				nbr->laddr = (ldp_af_conf_get(leconf,
374 				    af))->trans_addr;
375 				if (pfkey_establish(nconf, nbr) == -1)
376 					fatalx("pfkey setup failed");
377 				if (nbr_session_active_role(nbr))
378 					nbr_establish_connection(nbr);
379 			}
380 			break;
381 		case IMSG_RECONF_CONF:
382 			if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
383 			    NULL)
384 				fatal(NULL);
385 			memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
386 
387 			LIST_INIT(&nconf->iface_list);
388 			LIST_INIT(&nconf->tnbr_list);
389 			LIST_INIT(&nconf->nbrp_list);
390 			LIST_INIT(&nconf->l2vpn_list);
391 			LIST_INIT(&nconf->auth_list);
392 			break;
393 		case IMSG_RECONF_IFACE:
394 			if ((niface = malloc(sizeof(struct iface))) == NULL)
395 				fatal(NULL);
396 			memcpy(niface, imsg.data, sizeof(struct iface));
397 
398 			LIST_INIT(&niface->addr_list);
399 			LIST_INIT(&niface->ipv4.adj_list);
400 			LIST_INIT(&niface->ipv6.adj_list);
401 			niface->ipv4.iface = niface;
402 			niface->ipv6.iface = niface;
403 
404 			LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
405 			break;
406 		case IMSG_RECONF_TNBR:
407 			if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
408 				fatal(NULL);
409 			memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
410 
411 			LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
412 			break;
413 		case IMSG_RECONF_NBRP:
414 			if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
415 				fatal(NULL);
416 			memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
417 
418 			LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
419 			break;
420 		case IMSG_RECONF_L2VPN:
421 			if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
422 				fatal(NULL);
423 			memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
424 
425 			LIST_INIT(&nl2vpn->if_list);
426 			LIST_INIT(&nl2vpn->pw_list);
427 
428 			LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
429 			break;
430 		case IMSG_RECONF_L2VPN_IF:
431 			if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
432 				fatal(NULL);
433 			memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
434 
435 			nlif->l2vpn = nl2vpn;
436 			LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
437 			break;
438 		case IMSG_RECONF_L2VPN_PW:
439 			if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
440 				fatal(NULL);
441 			memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
442 
443 			npw->l2vpn = nl2vpn;
444 			LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
445 			break;
446 		case IMSG_RECONF_CONF_AUTH: {
447 			struct ldp_auth *auth;
448 
449 			auth = malloc(sizeof(*auth));
450 			if (auth == NULL)
451 				fatal(NULL);
452 
453 			memcpy(auth, imsg.data, sizeof(*auth));
454 
455 			LIST_INSERT_HEAD(&nconf->auth_list, auth, entry);
456 			break;
457 		}
458 
459 		case IMSG_RECONF_END:
460 			merge_config(leconf, nconf);
461 			nconf = NULL;
462 			global.conf_seqnum++;
463 			break;
464 		case IMSG_CTL_KROUTE:
465 		case IMSG_CTL_KROUTE_ADDR:
466 		case IMSG_CTL_IFINFO:
467 		case IMSG_CTL_END:
468 			control_imsg_relay(&imsg);
469 			break;
470 		default:
471 			log_debug("ldpe_dispatch_main: error handling imsg %d",
472 			    imsg.hdr.type);
473 			break;
474 		}
475 		imsg_free(&imsg);
476 	}
477 	if (!shut)
478 		imsg_event_add(iev);
479 	else {
480 		/* this pipe is dead, so remove the event handler */
481 		event_del(&iev->ev);
482 		event_loopexit(NULL);
483 	}
484 }
485 
486 static void
ldpe_dispatch_lde(int fd,short event,void * bula)487 ldpe_dispatch_lde(int fd, short event, void *bula)
488 {
489 	struct imsgev		*iev = bula;
490 	struct imsgbuf		*ibuf = &iev->ibuf;
491 	struct imsg		 imsg;
492 	struct map		 map;
493 	struct notify_msg	 nm;
494 	int			 n, shut = 0;
495 	struct nbr		*nbr = NULL;
496 
497 	if (event & EV_READ) {
498 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
499 			fatal("imsg_read error");
500 		if (n == 0)	/* connection closed */
501 			shut = 1;
502 	}
503 	if (event & EV_WRITE) {
504 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
505 			fatal("ldpe_dispatch_lde: msgbuf_write");
506 		if (n == 0)
507 			shut = 1;
508 	}
509 
510 	for (;;) {
511 		if ((n = imsg_get(ibuf, &imsg)) == -1)
512 			fatal("ldpe_dispatch_lde: imsg_get error");
513 		if (n == 0)
514 			break;
515 
516 		switch (imsg.hdr.type) {
517 		case IMSG_MAPPING_ADD:
518 		case IMSG_RELEASE_ADD:
519 		case IMSG_REQUEST_ADD:
520 		case IMSG_WITHDRAW_ADD:
521 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map))
522 				fatalx("invalid size of map request");
523 			memcpy(&map, imsg.data, sizeof(map));
524 
525 			nbr = nbr_find_peerid(imsg.hdr.peerid);
526 			if (nbr == NULL) {
527 				log_debug("ldpe_dispatch_lde: cannot find "
528 				    "neighbor");
529 				break;
530 			}
531 			if (nbr->state != NBR_STA_OPER)
532 				break;
533 
534 			switch (imsg.hdr.type) {
535 			case IMSG_MAPPING_ADD:
536 				mapping_list_add(&nbr->mapping_list, &map);
537 				break;
538 			case IMSG_RELEASE_ADD:
539 				mapping_list_add(&nbr->release_list, &map);
540 				break;
541 			case IMSG_REQUEST_ADD:
542 				mapping_list_add(&nbr->request_list, &map);
543 				break;
544 			case IMSG_WITHDRAW_ADD:
545 				mapping_list_add(&nbr->withdraw_list, &map);
546 				break;
547 			}
548 			break;
549 		case IMSG_MAPPING_ADD_END:
550 		case IMSG_RELEASE_ADD_END:
551 		case IMSG_REQUEST_ADD_END:
552 		case IMSG_WITHDRAW_ADD_END:
553 			nbr = nbr_find_peerid(imsg.hdr.peerid);
554 			if (nbr == NULL) {
555 				log_debug("ldpe_dispatch_lde: cannot find "
556 				    "neighbor");
557 				break;
558 			}
559 			if (nbr->state != NBR_STA_OPER)
560 				break;
561 
562 			switch (imsg.hdr.type) {
563 			case IMSG_MAPPING_ADD_END:
564 				send_labelmessage(nbr, MSG_TYPE_LABELMAPPING,
565 				    &nbr->mapping_list);
566 				break;
567 			case IMSG_RELEASE_ADD_END:
568 				send_labelmessage(nbr, MSG_TYPE_LABELRELEASE,
569 				    &nbr->release_list);
570 				break;
571 			case IMSG_REQUEST_ADD_END:
572 				send_labelmessage(nbr, MSG_TYPE_LABELREQUEST,
573 				    &nbr->request_list);
574 				break;
575 			case IMSG_WITHDRAW_ADD_END:
576 				send_labelmessage(nbr, MSG_TYPE_LABELWITHDRAW,
577 				    &nbr->withdraw_list);
578 				break;
579 			}
580 			break;
581 		case IMSG_NOTIFICATION_SEND:
582 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm))
583 				fatalx("invalid size of OE request");
584 			memcpy(&nm, imsg.data, sizeof(nm));
585 
586 			nbr = nbr_find_peerid(imsg.hdr.peerid);
587 			if (nbr == NULL) {
588 				log_debug("ldpe_dispatch_lde: cannot find "
589 				    "neighbor");
590 				break;
591 			}
592 			if (nbr->state != NBR_STA_OPER)
593 				break;
594 
595 			send_notification_full(nbr->tcp, &nm);
596 			break;
597 		case IMSG_CTL_END:
598 		case IMSG_CTL_SHOW_LIB:
599 		case IMSG_CTL_SHOW_L2VPN_PW:
600 		case IMSG_CTL_SHOW_L2VPN_BINDING:
601 			control_imsg_relay(&imsg);
602 			break;
603 		default:
604 			log_debug("ldpe_dispatch_lde: error handling imsg %d",
605 			    imsg.hdr.type);
606 			break;
607 		}
608 		imsg_free(&imsg);
609 	}
610 	if (!shut)
611 		imsg_event_add(iev);
612 	else {
613 		/* this pipe is dead, so remove the event handler */
614 		event_del(&iev->ev);
615 		event_loopexit(NULL);
616 	}
617 }
618 
619 static void
ldpe_dispatch_pfkey(int fd,short event,void * bula)620 ldpe_dispatch_pfkey(int fd, short event, void *bula)
621 {
622 	if (event & EV_READ) {
623 		if (pfkey_read(fd, NULL) == -1) {
624 			fatal("pfkey_read failed, exiting...");
625 		}
626 	}
627 }
628 
629 static void
ldpe_setup_sockets(int af,int disc_socket,int edisc_socket,int session_socket)630 ldpe_setup_sockets(int af, int disc_socket, int edisc_socket,
631     int session_socket)
632 {
633 	struct ldpd_af_global	*af_global;
634 
635 	af_global = ldp_af_global_get(&global, af);
636 
637 	/* discovery socket */
638 	af_global->ldp_disc_socket = disc_socket;
639 	event_set(&af_global->disc_ev, af_global->ldp_disc_socket,
640 	    EV_READ|EV_PERSIST, disc_recv_packet, NULL);
641 	event_add(&af_global->disc_ev, NULL);
642 
643 	/* extended discovery socket */
644 	af_global->ldp_edisc_socket = edisc_socket;
645 	event_set(&af_global->edisc_ev, af_global->ldp_edisc_socket,
646 	    EV_READ|EV_PERSIST, disc_recv_packet, NULL);
647 	event_add(&af_global->edisc_ev, NULL);
648 
649 	/* session socket */
650 	af_global->ldp_session_socket = session_socket;
651 	accept_add(af_global->ldp_session_socket, session_accept, NULL);
652 }
653 
654 static void
ldpe_close_sockets(int af)655 ldpe_close_sockets(int af)
656 {
657 	struct ldpd_af_global	*af_global;
658 
659 	af_global = ldp_af_global_get(&global, af);
660 
661 	/* discovery socket */
662 	if (event_initialized(&af_global->disc_ev))
663 		event_del(&af_global->disc_ev);
664 	if (af_global->ldp_disc_socket != -1) {
665 		close(af_global->ldp_disc_socket);
666 		af_global->ldp_disc_socket = -1;
667 	}
668 
669 	/* extended discovery socket */
670 	if (event_initialized(&af_global->edisc_ev))
671 		event_del(&af_global->edisc_ev);
672 	if (af_global->ldp_edisc_socket != -1) {
673 		close(af_global->ldp_edisc_socket);
674 		af_global->ldp_edisc_socket = -1;
675 	}
676 
677 	/* session socket */
678 	if (af_global->ldp_session_socket != -1) {
679 		accept_del(af_global->ldp_session_socket);
680 		close(af_global->ldp_session_socket);
681 		af_global->ldp_session_socket = -1;
682 	}
683 }
684 
685 void
ldpe_reset_nbrs(int af)686 ldpe_reset_nbrs(int af)
687 {
688 	struct nbr		*nbr;
689 
690 	RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
691 		if (nbr->af == af)
692 			session_shutdown(nbr, S_SHUTDOWN, 0, 0);
693 	}
694 }
695 
696 void
ldpe_reset_ds_nbrs(void)697 ldpe_reset_ds_nbrs(void)
698 {
699 	struct nbr		*nbr;
700 
701 	RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
702 		if (nbr->ds_tlv)
703 			session_shutdown(nbr, S_SHUTDOWN, 0, 0);
704 	}
705 }
706 
707 void
ldpe_remove_dynamic_tnbrs(int af)708 ldpe_remove_dynamic_tnbrs(int af)
709 {
710 	struct tnbr		*tnbr, *safe;
711 
712 	LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) {
713 		if (tnbr->af != af)
714 			continue;
715 
716 		tnbr->flags &= ~F_TNBR_DYNAMIC;
717 		tnbr_check(tnbr);
718 	}
719 }
720 
721 void
ldpe_stop_init_backoff(int af)722 ldpe_stop_init_backoff(int af)
723 {
724 	struct nbr		*nbr;
725 
726 	RB_FOREACH(nbr, nbr_id_head, &nbrs_by_id) {
727 		if (nbr->af == af && nbr_pending_idtimer(nbr)) {
728 			nbr_stop_idtimer(nbr);
729 			nbr_establish_connection(nbr);
730 		}
731 	}
732 }
733 
734 static void
ldpe_iface_af_ctl(struct ctl_conn * c,int af,unsigned int idx)735 ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx)
736 {
737 	struct iface		*iface;
738 	struct iface_af		*ia;
739 	struct ctl_iface	*ictl;
740 
741 	LIST_FOREACH(iface, &leconf->iface_list, entry) {
742 		if (idx == 0 || idx == iface->ifindex) {
743 			ia = iface_af_get(iface, af);
744 			if (!ia->enabled)
745 				continue;
746 
747 			ictl = if_to_ctl(ia);
748 			imsg_compose_event(&c->iev, IMSG_CTL_SHOW_INTERFACE,
749 			    0, 0, -1, ictl, sizeof(struct ctl_iface));
750 		}
751 	}
752 }
753 
754 void
ldpe_iface_ctl(struct ctl_conn * c,unsigned int idx)755 ldpe_iface_ctl(struct ctl_conn *c, unsigned int idx)
756 {
757 	ldpe_iface_af_ctl(c, AF_INET, idx);
758 	ldpe_iface_af_ctl(c, AF_INET6, idx);
759 }
760 
761 void
ldpe_adj_ctl(struct ctl_conn * c)762 ldpe_adj_ctl(struct ctl_conn *c)
763 {
764 	struct nbr	*nbr;
765 	struct adj	*adj;
766 	struct ctl_adj	*actl;
767 
768 	RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
769 		LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) {
770 			actl = adj_to_ctl(adj);
771 			imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY,
772 			    0, 0, -1, actl, sizeof(struct ctl_adj));
773 		}
774 	}
775 	/* show adjacencies not associated with any neighbor */
776 	LIST_FOREACH(adj, &global.adj_list, global_entry) {
777 		if (adj->nbr != NULL)
778 			continue;
779 
780 		actl = adj_to_ctl(adj);
781 		imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0,
782 		    -1, actl, sizeof(struct ctl_adj));
783 	}
784 
785 	imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
786 }
787 
788 void
ldpe_nbr_ctl(struct ctl_conn * c)789 ldpe_nbr_ctl(struct ctl_conn *c)
790 {
791 	struct nbr	*nbr;
792 	struct ctl_nbr	*nctl;
793 
794 	RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
795 		nctl = nbr_to_ctl(nbr);
796 		imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
797 		    sizeof(struct ctl_nbr));
798 	}
799 	imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
800 }
801 
802 void
mapping_list_add(struct mapping_head * mh,struct map * map)803 mapping_list_add(struct mapping_head *mh, struct map *map)
804 {
805 	struct mapping_entry	*me;
806 
807 	me = calloc(1, sizeof(*me));
808 	if (me == NULL)
809 		fatal(__func__);
810 	me->map = *map;
811 
812 	TAILQ_INSERT_TAIL(mh, me, entry);
813 }
814 
815 void
mapping_list_clr(struct mapping_head * mh)816 mapping_list_clr(struct mapping_head *mh)
817 {
818 	struct mapping_entry	*me;
819 
820 	while ((me = TAILQ_FIRST(mh)) != NULL) {
821 		TAILQ_REMOVE(mh, me, entry);
822 		free(me);
823 	}
824 }
825