GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldpd/ldpe.c Lines: 0 393 0.0 %
Date: 2017-11-07 Branches: 0 269 0.0 %

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