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

Line Branch Exec Source
1
/*	$OpenBSD: lde.c,v 1.73 2017/03/04 00:15:35 renato Exp $ */
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
22
#include <sys/types.h>
23
#include <sys/time.h>
24
#include <sys/socket.h>
25
#include <netinet/in.h>
26
#include <netmpls/mpls.h>
27
#include <arpa/inet.h>
28
#include <errno.h>
29
#include <stdlib.h>
30
#include <signal.h>
31
#include <string.h>
32
#include <pwd.h>
33
#include <unistd.h>
34
#include <limits.h>
35
36
#include "ldp.h"
37
#include "ldpd.h"
38
#include "ldpe.h"
39
#include "log.h"
40
#include "lde.h"
41
42
static void		 lde_sig_handler(int sig, short, void *);
43
static __dead void	 lde_shutdown(void);
44
static int		 lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
45
static void		 lde_dispatch_imsg(int, short, void *);
46
static void		 lde_dispatch_parent(int, short, void *);
47
static __inline	int	 lde_nbr_compare(struct lde_nbr *,
48
			    struct lde_nbr *);
49
static struct lde_nbr	*lde_nbr_new(uint32_t, struct lde_nbr *);
50
static void		 lde_nbr_del(struct lde_nbr *);
51
static struct lde_nbr	*lde_nbr_find(uint32_t);
52
static void		 lde_nbr_clear(void);
53
static void		 lde_nbr_addr_update(struct lde_nbr *,
54
			    struct lde_addr *, int);
55
static void		 lde_map_free(void *);
56
static int		 lde_address_add(struct lde_nbr *, struct lde_addr *);
57
static int		 lde_address_del(struct lde_nbr *, struct lde_addr *);
58
static void		 lde_address_list_free(struct lde_nbr *);
59
60
RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
61
62
struct ldpd_conf	*ldeconf;
63
struct nbr_tree		 lde_nbrs = RB_INITIALIZER(&lde_nbrs);
64
65
static struct imsgev	*iev_ldpe;
66
static struct imsgev	*iev_main;
67
68
/* ARGSUSED */
69
static void
70
lde_sig_handler(int sig, short event, void *arg)
71
{
72
	/*
73
	 * signal handler rules don't apply, libevent decouples for us
74
	 */
75
76
	switch (sig) {
77
	case SIGINT:
78
	case SIGTERM:
79
		lde_shutdown();
80
		/* NOTREACHED */
81
	default:
82
		fatalx("unexpected signal");
83
	}
84
}
85
86
/* label decision engine */
87
void
88
lde(int debug, int verbose)
89
{
90
	struct event		 ev_sigint, ev_sigterm;
91
	struct timeval		 now;
92
	struct passwd		*pw;
93
94
	ldeconf = config_new_empty();
95
96
	log_init(debug);
97
	log_verbose(verbose);
98
99
	setproctitle("label decision engine");
100
	ldpd_process = PROC_LDE_ENGINE;
101
	log_procname = log_procnames[PROC_LDE_ENGINE];
102
103
	if ((pw = getpwnam(LDPD_USER)) == NULL)
104
		fatal("getpwnam");
105
106
	if (chroot(pw->pw_dir) == -1)
107
		fatal("chroot");
108
	if (chdir("/") == -1)
109
		fatal("chdir(\"/\")");
110
111
	if (setgroups(1, &pw->pw_gid) ||
112
	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
113
	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
114
		fatal("can't drop privileges");
115
116
	if (pledge("stdio recvfd flock rpath cpath wpath", NULL) == -1)
117
		fatal("pledge");
118
119
	event_init();
120
121
	/* setup signal handler */
122
	signal_set(&ev_sigint, SIGINT, lde_sig_handler, NULL);
123
	signal_set(&ev_sigterm, SIGTERM, lde_sig_handler, NULL);
124
	signal_add(&ev_sigint, NULL);
125
	signal_add(&ev_sigterm, NULL);
126
	signal(SIGPIPE, SIG_IGN);
127
	signal(SIGHUP, SIG_IGN);
128
129
	/* setup pipe and event handler to the parent process */
130
	if ((iev_main = malloc(sizeof(struct imsgev))) == NULL)
131
		fatal(NULL);
132
	imsg_init(&iev_main->ibuf, 3);
133
	iev_main->handler = lde_dispatch_parent;
134
	iev_main->events = EV_READ;
135
	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
136
	    iev_main->handler, iev_main);
137
	event_add(&iev_main->ev, NULL);
138
139
	/* setup and start the LIB garbage collector */
140
	evtimer_set(&gc_timer, lde_gc_timer, NULL);
141
	lde_gc_start_timer();
142
143
	gettimeofday(&now, NULL);
144
	global.uptime = now.tv_sec;
145
146
	event_dispatch();
147
148
	lde_shutdown();
149
}
150
151
static __dead void
152
lde_shutdown(void)
153
{
154
	/* close pipes */
155
	msgbuf_clear(&iev_ldpe->ibuf.w);
156
	close(iev_ldpe->ibuf.fd);
157
	msgbuf_clear(&iev_main->ibuf.w);
158
	close(iev_main->ibuf.fd);
159
160
	lde_gc_stop_timer();
161
	lde_nbr_clear();
162
	fec_tree_clear();
163
164
	config_clear(ldeconf);
165
166
	free(iev_ldpe);
167
	free(iev_main);
168
169
	log_info("label decision engine exiting");
170
	exit(0);
171
}
172
173
/* imesg */
174
static int
175
lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
176
{
177
	return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
178
}
179
180
int
181
lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
182
    uint16_t datalen)
183
{
184
	return (imsg_compose_event(iev_ldpe, type, peerid, pid,
185
	     -1, data, datalen));
186
}
187
188
/* ARGSUSED */
189
static void
190
lde_dispatch_imsg(int fd, short event, void *bula)
191
{
192
	struct imsgev		*iev = bula;
193
	struct imsgbuf		*ibuf = &iev->ibuf;
194
	struct imsg		 imsg;
195
	struct lde_nbr		*ln;
196
	struct map		 map;
197
	struct lde_addr		 lde_addr;
198
	struct notify_msg	 nm;
199
	ssize_t			 n;
200
	int			 shut = 0, verbose;
201
202
	if (event & EV_READ) {
203
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
204
			fatal("imsg_read error");
205
		if (n == 0)	/* connection closed */
206
			shut = 1;
207
	}
208
	if (event & EV_WRITE) {
209
		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
210
			fatal("msgbuf_write");
211
		if (n == 0)	/* connection closed */
212
			shut = 1;
213
	}
214
215
	for (;;) {
216
		if ((n = imsg_get(ibuf, &imsg)) == -1)
217
			fatal("lde_dispatch_imsg: imsg_get error");
218
		if (n == 0)
219
			break;
220
221
		switch (imsg.hdr.type) {
222
		case IMSG_LABEL_MAPPING_FULL:
223
			ln = lde_nbr_find(imsg.hdr.peerid);
224
			if (ln == NULL) {
225
				log_debug("%s: cannot find lde neighbor",
226
				    __func__);
227
				break;
228
			}
229
230
			fec_snap(ln);
231
			break;
232
		case IMSG_LABEL_MAPPING:
233
		case IMSG_LABEL_REQUEST:
234
		case IMSG_LABEL_RELEASE:
235
		case IMSG_LABEL_WITHDRAW:
236
		case IMSG_LABEL_ABORT:
237
			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map))
238
				fatalx("lde_dispatch_imsg: wrong imsg len");
239
			memcpy(&map, imsg.data, sizeof(map));
240
241
			ln = lde_nbr_find(imsg.hdr.peerid);
242
			if (ln == NULL) {
243
				log_debug("%s: cannot find lde neighbor",
244
				    __func__);
245
				break;
246
			}
247
248
			switch (imsg.hdr.type) {
249
			case IMSG_LABEL_MAPPING:
250
				lde_check_mapping(&map, ln);
251
				break;
252
			case IMSG_LABEL_REQUEST:
253
				lde_check_request(&map, ln);
254
				break;
255
			case IMSG_LABEL_RELEASE:
256
				lde_check_release(&map, ln);
257
				break;
258
			case IMSG_LABEL_WITHDRAW:
259
				lde_check_withdraw(&map, ln);
260
				break;
261
			case IMSG_LABEL_ABORT:
262
				/* not necessary */
263
				break;
264
			}
265
			break;
266
		case IMSG_ADDRESS_ADD:
267
			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
268
				fatalx("lde_dispatch_imsg: wrong imsg len");
269
			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
270
271
			ln = lde_nbr_find(imsg.hdr.peerid);
272
			if (ln == NULL) {
273
				log_debug("%s: cannot find lde neighbor",
274
				    __func__);
275
				break;
276
			}
277
			if (lde_address_add(ln, &lde_addr) < 0) {
278
				log_debug("%s: cannot add address %s, it "
279
				    "already exists", __func__,
280
				    log_addr(lde_addr.af, &lde_addr.addr));
281
			}
282
			break;
283
		case IMSG_ADDRESS_DEL:
284
			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lde_addr))
285
				fatalx("lde_dispatch_imsg: wrong imsg len");
286
			memcpy(&lde_addr, imsg.data, sizeof(lde_addr));
287
288
			ln = lde_nbr_find(imsg.hdr.peerid);
289
			if (ln == NULL) {
290
				log_debug("%s: cannot find lde neighbor",
291
				    __func__);
292
				break;
293
			}
294
			if (lde_address_del(ln, &lde_addr) < 0) {
295
				log_debug("%s: cannot delete address %s, it "
296
				    "does not exist", __func__,
297
				    log_addr(lde_addr.af, &lde_addr.addr));
298
			}
299
			break;
300
		case IMSG_NOTIFICATION:
301
			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(nm))
302
				fatalx("lde_dispatch_imsg: wrong imsg len");
303
			memcpy(&nm, imsg.data, sizeof(nm));
304
305
			ln = lde_nbr_find(imsg.hdr.peerid);
306
			if (ln == NULL) {
307
				log_debug("%s: cannot find lde neighbor",
308
				    __func__);
309
				break;
310
			}
311
312
			switch (nm.status_code) {
313
			case S_PW_STATUS:
314
				l2vpn_recv_pw_status(ln, &nm);
315
				break;
316
			case S_ENDOFLIB:
317
				/*
318
				 * Do nothing for now. Should be useful in
319
				 * the future when we implement LDP-IGP
320
				 * Synchronization (RFC 5443) and Graceful
321
				 * Restart (RFC 3478).
322
				 */
323
			default:
324
				break;
325
			}
326
			break;
327
		case IMSG_NEIGHBOR_UP:
328
			if (imsg.hdr.len - IMSG_HEADER_SIZE !=
329
			    sizeof(struct lde_nbr))
330
				fatalx("lde_dispatch_imsg: wrong imsg len");
331
332
			if (lde_nbr_find(imsg.hdr.peerid))
333
				fatalx("lde_dispatch_imsg: "
334
				    "neighbor already exists");
335
			lde_nbr_new(imsg.hdr.peerid, imsg.data);
336
			break;
337
		case IMSG_NEIGHBOR_DOWN:
338
			lde_nbr_del(lde_nbr_find(imsg.hdr.peerid));
339
			break;
340
		case IMSG_CTL_SHOW_LIB:
341
			rt_dump(imsg.hdr.pid);
342
343
			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
344
			    imsg.hdr.pid, NULL, 0);
345
			break;
346
		case IMSG_CTL_SHOW_L2VPN_PW:
347
			l2vpn_pw_ctl(imsg.hdr.pid);
348
349
			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
350
			    imsg.hdr.pid, NULL, 0);
351
			break;
352
		case IMSG_CTL_SHOW_L2VPN_BINDING:
353
			l2vpn_binding_ctl(imsg.hdr.pid);
354
355
			lde_imsg_compose_ldpe(IMSG_CTL_END, 0,
356
			    imsg.hdr.pid, NULL, 0);
357
			break;
358
		case IMSG_CTL_LOG_VERBOSE:
359
			/* already checked by ldpe */
360
			memcpy(&verbose, imsg.data, sizeof(verbose));
361
			log_verbose(verbose);
362
			break;
363
		default:
364
			log_debug("%s: unexpected imsg %d", __func__,
365
			    imsg.hdr.type);
366
			break;
367
		}
368
		imsg_free(&imsg);
369
	}
370
	if (!shut)
371
		imsg_event_add(iev);
372
	else {
373
		/* this pipe is dead, so remove the event handler */
374
		event_del(&iev->ev);
375
		event_loopexit(NULL);
376
	}
377
}
378
379
/* ARGSUSED */
380
static void
381
lde_dispatch_parent(int fd, short event, void *bula)
382
{
383
	static struct ldpd_conf	*nconf;
384
	struct iface		*niface;
385
	struct tnbr		*ntnbr;
386
	struct nbr_params	*nnbrp;
387
	static struct l2vpn	*nl2vpn;
388
	struct l2vpn_if		*nlif;
389
	struct l2vpn_pw		*npw;
390
	struct imsg		 imsg;
391
	struct kroute		 kr;
392
	struct imsgev		*iev = bula;
393
	struct imsgbuf		*ibuf = &iev->ibuf;
394
	ssize_t			 n;
395
	int			 shut = 0;
396
	struct fec		 fec;
397
398
	if (event & EV_READ) {
399
		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
400
			fatal("imsg_read error");
401
		if (n == 0)	/* connection closed */
402
			shut = 1;
403
	}
404
	if (event & EV_WRITE) {
405
		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
406
			fatal("msgbuf_write");
407
		if (n == 0)	/* connection closed */
408
			shut = 1;
409
	}
410
411
	for (;;) {
412
		if ((n = imsg_get(ibuf, &imsg)) == -1)
413
			fatal("lde_dispatch_parent: imsg_get error");
414
		if (n == 0)
415
			break;
416
417
		switch (imsg.hdr.type) {
418
		case IMSG_NETWORK_ADD:
419
		case IMSG_NETWORK_DEL:
420
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(kr)) {
421
				log_warnx("%s: wrong imsg len", __func__);
422
				break;
423
			}
424
			memcpy(&kr, imsg.data, sizeof(kr));
425
426
			switch (kr.af) {
427
			case AF_INET:
428
				fec.type = FEC_TYPE_IPV4;
429
				fec.u.ipv4.prefix = kr.prefix.v4;
430
				fec.u.ipv4.prefixlen = kr.prefixlen;
431
				break;
432
			case AF_INET6:
433
				fec.type = FEC_TYPE_IPV6;
434
				fec.u.ipv6.prefix = kr.prefix.v6;
435
				fec.u.ipv6.prefixlen = kr.prefixlen;
436
				break;
437
			default:
438
				fatalx("lde_dispatch_parent: unknown af");
439
			}
440
441
			switch (imsg.hdr.type) {
442
			case IMSG_NETWORK_ADD:
443
				lde_kernel_insert(&fec, kr.af, &kr.nexthop,
444
				    kr.priority, kr.flags & F_CONNECTED, NULL);
445
				break;
446
			case IMSG_NETWORK_DEL:
447
				lde_kernel_remove(&fec, kr.af, &kr.nexthop,
448
				    kr.priority);
449
				break;
450
			}
451
			break;
452
		case IMSG_SOCKET_IPC:
453
			if (iev_ldpe) {
454
				log_warnx("%s: received unexpected imsg fd "
455
				    "to ldpe", __func__);
456
				break;
457
			}
458
			if ((fd = imsg.fd) == -1) {
459
				log_warnx("%s: expected to receive imsg fd to "
460
				    "ldpe but didn't receive any", __func__);
461
				break;
462
			}
463
464
			if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL)
465
				fatal(NULL);
466
			imsg_init(&iev_ldpe->ibuf, fd);
467
			iev_ldpe->handler = lde_dispatch_imsg;
468
			iev_ldpe->events = EV_READ;
469
			event_set(&iev_ldpe->ev, iev_ldpe->ibuf.fd,
470
			    iev_ldpe->events, iev_ldpe->handler, iev_ldpe);
471
			event_add(&iev_ldpe->ev, NULL);
472
			break;
473
		case IMSG_RECONF_CONF:
474
			if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
475
			    NULL)
476
				fatal(NULL);
477
			memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
478
479
			LIST_INIT(&nconf->iface_list);
480
			LIST_INIT(&nconf->tnbr_list);
481
			LIST_INIT(&nconf->nbrp_list);
482
			LIST_INIT(&nconf->l2vpn_list);
483
			break;
484
		case IMSG_RECONF_IFACE:
485
			if ((niface = malloc(sizeof(struct iface))) == NULL)
486
				fatal(NULL);
487
			memcpy(niface, imsg.data, sizeof(struct iface));
488
489
			LIST_INIT(&niface->addr_list);
490
			LIST_INIT(&niface->ipv4.adj_list);
491
			LIST_INIT(&niface->ipv6.adj_list);
492
			niface->ipv4.iface = niface;
493
			niface->ipv6.iface = niface;
494
495
			LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
496
			break;
497
		case IMSG_RECONF_TNBR:
498
			if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
499
				fatal(NULL);
500
			memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
501
502
			LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry);
503
			break;
504
		case IMSG_RECONF_NBRP:
505
			if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
506
				fatal(NULL);
507
			memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
508
509
			LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry);
510
			break;
511
		case IMSG_RECONF_L2VPN:
512
			if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
513
				fatal(NULL);
514
			memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
515
516
			LIST_INIT(&nl2vpn->if_list);
517
			LIST_INIT(&nl2vpn->pw_list);
518
519
			LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
520
			break;
521
		case IMSG_RECONF_L2VPN_IF:
522
			if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
523
				fatal(NULL);
524
			memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
525
526
			nlif->l2vpn = nl2vpn;
527
			LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry);
528
			break;
529
		case IMSG_RECONF_L2VPN_PW:
530
			if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
531
				fatal(NULL);
532
			memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
533
534
			npw->l2vpn = nl2vpn;
535
			LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry);
536
			break;
537
		case IMSG_RECONF_END:
538
			merge_config(ldeconf, nconf);
539
			nconf = NULL;
540
			break;
541
		default:
542
			log_debug("%s: unexpected imsg %d", __func__,
543
			    imsg.hdr.type);
544
			break;
545
		}
546
		imsg_free(&imsg);
547
	}
548
	if (!shut)
549
		imsg_event_add(iev);
550
	else {
551
		/* this pipe is dead, so remove the event handler */
552
		event_del(&iev->ev);
553
		event_loopexit(NULL);
554
	}
555
}
556
557
uint32_t
558
lde_assign_label(void)
559
{
560
	static uint32_t label = MPLS_LABEL_RESERVED_MAX;
561
562
	/* XXX some checks needed */
563
	label++;
564
	return (label);
565
}
566
567
void
568
lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
569
{
570
	struct kroute	kr;
571
	struct kpw	kpw;
572
	struct l2vpn_pw	*pw;
573
574
	switch (fn->fec.type) {
575
	case FEC_TYPE_IPV4:
576
		memset(&kr, 0, sizeof(kr));
577
		kr.af = AF_INET;
578
		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
579
		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
580
		kr.nexthop.v4 = fnh->nexthop.v4;
581
		kr.local_label = fn->local_label;
582
		kr.remote_label = fnh->remote_label;
583
		kr.priority = fnh->priority;
584
585
		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
586
		    sizeof(kr));
587
588
		if (fn->fec.u.ipv4.prefixlen == 32)
589
			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
590
			    &fn->fec.u.ipv4.prefix);
591
		break;
592
	case FEC_TYPE_IPV6:
593
		memset(&kr, 0, sizeof(kr));
594
		kr.af = AF_INET6;
595
		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
596
		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
597
		kr.nexthop.v6 = fnh->nexthop.v6;
598
		kr.local_label = fn->local_label;
599
		kr.remote_label = fnh->remote_label;
600
		kr.priority = fnh->priority;
601
602
		lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
603
		    sizeof(kr));
604
605
		if (fn->fec.u.ipv6.prefixlen == 128)
606
			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
607
			    &fn->fec.u.ipv6.prefix);
608
		break;
609
	case FEC_TYPE_PWID:
610
		if (fn->local_label == NO_LABEL ||
611
		    fnh->remote_label == NO_LABEL)
612
			return;
613
614
		pw = (struct l2vpn_pw *) fn->data;
615
		pw->flags |= F_PW_STATUS_UP;
616
617
		memset(&kpw, 0, sizeof(kpw));
618
		kpw.ifindex = pw->ifindex;
619
		kpw.pw_type = fn->fec.u.pwid.type;
620
		kpw.af = pw->af;
621
		kpw.nexthop = pw->addr;
622
		kpw.local_label = fn->local_label;
623
		kpw.remote_label = fnh->remote_label;
624
		kpw.flags = pw->flags;
625
626
		lde_imsg_compose_parent(IMSG_KPWLABEL_CHANGE, 0, &kpw,
627
		    sizeof(kpw));
628
		break;
629
	}
630
}
631
632
void
633
lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
634
{
635
	struct kroute	 kr;
636
	struct kpw	 kpw;
637
	struct l2vpn_pw	*pw;
638
639
	switch (fn->fec.type) {
640
	case FEC_TYPE_IPV4:
641
		memset(&kr, 0, sizeof(kr));
642
		kr.af = AF_INET;
643
		kr.prefix.v4 = fn->fec.u.ipv4.prefix;
644
		kr.prefixlen = fn->fec.u.ipv4.prefixlen;
645
		kr.nexthop.v4 = fnh->nexthop.v4;
646
		kr.local_label = fn->local_label;
647
		kr.remote_label = fnh->remote_label;
648
		kr.priority = fnh->priority;
649
650
		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
651
		    sizeof(kr));
652
653
		if (fn->fec.u.ipv4.prefixlen == 32)
654
			l2vpn_sync_pws(AF_INET, (union ldpd_addr *)
655
			    &fn->fec.u.ipv4.prefix);
656
		break;
657
	case FEC_TYPE_IPV6:
658
		memset(&kr, 0, sizeof(kr));
659
		kr.af = AF_INET6;
660
		kr.prefix.v6 = fn->fec.u.ipv6.prefix;
661
		kr.prefixlen = fn->fec.u.ipv6.prefixlen;
662
		kr.nexthop.v6 = fnh->nexthop.v6;
663
		kr.local_label = fn->local_label;
664
		kr.remote_label = fnh->remote_label;
665
		kr.priority = fnh->priority;
666
667
		lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
668
		    sizeof(kr));
669
670
		if (fn->fec.u.ipv6.prefixlen == 128)
671
			l2vpn_sync_pws(AF_INET6, (union ldpd_addr *)
672
			    &fn->fec.u.ipv6.prefix);
673
		break;
674
	case FEC_TYPE_PWID:
675
		pw = (struct l2vpn_pw *) fn->data;
676
		if (!(pw->flags & F_PW_STATUS_UP))
677
			return;
678
		pw->flags &= ~F_PW_STATUS_UP;
679
680
		memset(&kpw, 0, sizeof(kpw));
681
		kpw.ifindex = pw->ifindex;
682
		kpw.pw_type = fn->fec.u.pwid.type;
683
		kpw.af = pw->af;
684
		kpw.nexthop = pw->addr;
685
		kpw.local_label = fn->local_label;
686
		kpw.remote_label = fnh->remote_label;
687
		kpw.flags = pw->flags;
688
689
		lde_imsg_compose_parent(IMSG_KPWLABEL_DELETE, 0, &kpw,
690
		    sizeof(kpw));
691
		break;
692
	}
693
}
694
695
void
696
lde_fec2map(struct fec *fec, struct map *map)
697
{
698
	memset(map, 0, sizeof(*map));
699
700
	switch (fec->type) {
701
	case FEC_TYPE_IPV4:
702
		map->type = MAP_TYPE_PREFIX;
703
		map->fec.prefix.af = AF_INET;
704
		map->fec.prefix.prefix.v4 = fec->u.ipv4.prefix;
705
		map->fec.prefix.prefixlen = fec->u.ipv4.prefixlen;
706
		break;
707
	case FEC_TYPE_IPV6:
708
		map->type = MAP_TYPE_PREFIX;
709
		map->fec.prefix.af = AF_INET6;
710
		map->fec.prefix.prefix.v6 = fec->u.ipv6.prefix;
711
		map->fec.prefix.prefixlen = fec->u.ipv6.prefixlen;
712
		break;
713
	case FEC_TYPE_PWID:
714
		map->type = MAP_TYPE_PWID;
715
		map->fec.pwid.type = fec->u.pwid.type;
716
		map->fec.pwid.group_id = 0;
717
		map->flags |= F_MAP_PW_ID;
718
		map->fec.pwid.pwid = fec->u.pwid.pwid;
719
		break;
720
	}
721
}
722
723
void
724
lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
725
{
726
	memset(fec, 0, sizeof(*fec));
727
728
	switch (map->type) {
729
	case MAP_TYPE_PREFIX:
730
		switch (map->fec.prefix.af) {
731
		case AF_INET:
732
			fec->type = FEC_TYPE_IPV4;
733
			fec->u.ipv4.prefix = map->fec.prefix.prefix.v4;
734
			fec->u.ipv4.prefixlen = map->fec.prefix.prefixlen;
735
			break;
736
		case AF_INET6:
737
			fec->type = FEC_TYPE_IPV6;
738
			fec->u.ipv6.prefix = map->fec.prefix.prefix.v6;
739
			fec->u.ipv6.prefixlen = map->fec.prefix.prefixlen;
740
			break;
741
		default:
742
			fatalx("lde_map2fec: unknown af");
743
			break;
744
		}
745
		break;
746
	case MAP_TYPE_PWID:
747
		fec->type = FEC_TYPE_PWID;
748
		fec->u.pwid.type = map->fec.pwid.type;
749
		fec->u.pwid.pwid = map->fec.pwid.pwid;
750
		fec->u.pwid.lsr_id = lsr_id;
751
		break;
752
	}
753
}
754
755
void
756
lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
757
{
758
	struct lde_req	*lre;
759
	struct lde_map	*me;
760
	struct map	 map;
761
	struct l2vpn_pw	*pw;
762
763
	/*
764
	 * This function skips SL.1 - 3 and SL.9 - 14 because the label
765
	 * allocation is done way earlier (because of the merging nature of
766
	 * ldpd).
767
	 */
768
769
	lde_fec2map(&fn->fec, &map);
770
	switch (fn->fec.type) {
771
	case FEC_TYPE_IPV4:
772
		if (!ln->v4_enabled)
773
			return;
774
		break;
775
	case FEC_TYPE_IPV6:
776
		if (!ln->v6_enabled)
777
			return;
778
		break;
779
	case FEC_TYPE_PWID:
780
		pw = (struct l2vpn_pw *) fn->data;
781
		if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
782
			/* not the remote end of the pseudowire */
783
			return;
784
785
		map.flags |= F_MAP_PW_IFMTU;
786
		map.fec.pwid.ifmtu = pw->l2vpn->mtu;
787
		if (pw->flags & F_PW_CWORD)
788
			map.flags |= F_MAP_PW_CWORD;
789
		if (pw->flags & F_PW_STATUSTLV) {
790
			map.flags |= F_MAP_PW_STATUS;
791
			/* VPLS are always up */
792
			map.pw_status = PW_FORWARDING;
793
		}
794
		break;
795
	}
796
	map.label = fn->local_label;
797
798
	/* SL.6: is there a pending request for this mapping? */
799
	lre = (struct lde_req *)fec_find(&ln->recv_req, &fn->fec);
800
	if (lre) {
801
		/* set label request msg id in the mapping response. */
802
		map.requestid = lre->msg_id;
803
		map.flags = F_MAP_REQ_ID;
804
805
		/* SL.7: delete record of pending request */
806
		lde_req_del(ln, lre, 0);
807
	}
808
809
	/* SL.4: send label mapping */
810
	lde_imsg_compose_ldpe(IMSG_MAPPING_ADD, ln->peerid, 0,
811
	    &map, sizeof(map));
812
	if (single)
813
		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
814
		    NULL, 0);
815
816
	/* SL.5: record sent label mapping */
817
	me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
818
	if (me == NULL)
819
		me = lde_map_add(ln, fn, 1);
820
	me->map = map;
821
}
822
823
void
824
lde_send_labelwithdraw(struct lde_nbr *ln, struct fec_node *fn,
825
    struct map *wcard, struct status_tlv *st)
826
{
827
	struct lde_wdraw	*lw;
828
	struct map		 map;
829
	struct fec		*f;
830
	struct l2vpn_pw		*pw;
831
832
	if (fn) {
833
		lde_fec2map(&fn->fec, &map);
834
		switch (fn->fec.type) {
835
		case FEC_TYPE_IPV4:
836
			if (!ln->v4_enabled)
837
				return;
838
			break;
839
		case FEC_TYPE_IPV6:
840
			if (!ln->v6_enabled)
841
				return;
842
			break;
843
		case FEC_TYPE_PWID:
844
			pw = (struct l2vpn_pw *) fn->data;
845
			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
846
				/* not the remote end of the pseudowire */
847
				return;
848
849
			if (pw->flags & F_PW_CWORD)
850
				map.flags |= F_MAP_PW_CWORD;
851
			break;
852
		}
853
		map.label = fn->local_label;
854
	} else
855
		memcpy(&map, wcard, sizeof(map));
856
857
	if (st) {
858
		map.st.status_code = st->status_code;
859
		map.st.msg_id = st->msg_id;
860
		map.st.msg_type = st->msg_type;
861
		map.flags |= F_MAP_STATUS;
862
	}
863
864
	/* SWd.1: send label withdraw. */
865
	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD, ln->peerid, 0,
866
 	    &map, sizeof(map));
867
	lde_imsg_compose_ldpe(IMSG_WITHDRAW_ADD_END, ln->peerid, 0, NULL, 0);
868
869
	/* SWd.2: record label withdraw. */
870
	if (fn) {
871
		lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
872
		if (lw == NULL)
873
			lw = lde_wdraw_add(ln, fn);
874
		lw->label = map.label;
875
	} else {
876
		struct lde_map *me;
877
878
		RB_FOREACH(f, fec_tree, &ft) {
879
			fn = (struct fec_node *)f;
880
			me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
881
			if (lde_wildcard_apply(wcard, &fn->fec, me) == 0)
882
				continue;
883
884
			lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw,
885
			    &fn->fec);
886
			if (lw == NULL)
887
				lw = lde_wdraw_add(ln, fn);
888
			lw->label = map.label;
889
		}
890
	}
891
}
892
893
void
894
lde_send_labelwithdraw_wcard(struct lde_nbr *ln, uint32_t label)
895
{
896
	struct map	 wcard;
897
898
	memset(&wcard, 0, sizeof(wcard));
899
	wcard.type = MAP_TYPE_WILDCARD;
900
	wcard.label = label;
901
	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
902
}
903
904
void
905
lde_send_labelwithdraw_twcard_prefix(struct lde_nbr *ln, uint16_t af,
906
    uint32_t label)
907
{
908
	struct map	 wcard;
909
910
	memset(&wcard, 0, sizeof(wcard));
911
	wcard.type = MAP_TYPE_TYPED_WCARD;
912
	wcard.fec.twcard.type = MAP_TYPE_PREFIX;
913
	wcard.fec.twcard.u.prefix_af = af;
914
	wcard.label = label;
915
	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
916
}
917
918
void
919
lde_send_labelwithdraw_twcard_pwid(struct lde_nbr *ln, uint16_t pw_type,
920
    uint32_t label)
921
{
922
	struct map	 wcard;
923
924
	memset(&wcard, 0, sizeof(wcard));
925
	wcard.type = MAP_TYPE_TYPED_WCARD;
926
	wcard.fec.twcard.type = MAP_TYPE_PWID;
927
	wcard.fec.twcard.u.pw_type = pw_type;
928
	wcard.label = label;
929
	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
930
}
931
932
void
933
lde_send_labelwithdraw_pwid_wcard(struct lde_nbr *ln, uint16_t pw_type,
934
    uint32_t group_id)
935
{
936
	struct map	 wcard;
937
938
	memset(&wcard, 0, sizeof(wcard));
939
	wcard.type = MAP_TYPE_PWID;
940
	wcard.fec.pwid.type = pw_type;
941
	wcard.fec.pwid.group_id = group_id;
942
	/* we can not append a Label TLV when using PWid group wildcards. */
943
	wcard.label = NO_LABEL;
944
	lde_send_labelwithdraw(ln, NULL, &wcard, NULL);
945
}
946
947
void
948
lde_send_labelrelease(struct lde_nbr *ln, struct fec_node *fn,
949
    struct map *wcard, uint32_t label)
950
{
951
	struct map		 map;
952
	struct l2vpn_pw		*pw;
953
954
	if (fn) {
955
		lde_fec2map(&fn->fec, &map);
956
		switch (fn->fec.type) {
957
		case FEC_TYPE_IPV4:
958
			if (!ln->v4_enabled)
959
				return;
960
			break;
961
		case FEC_TYPE_IPV6:
962
			if (!ln->v6_enabled)
963
				return;
964
			break;
965
		case FEC_TYPE_PWID:
966
			pw = (struct l2vpn_pw *) fn->data;
967
			if (pw == NULL || pw->lsr_id.s_addr != ln->id.s_addr)
968
				/* not the remote end of the pseudowire */
969
				return;
970
971
			if (pw->flags & F_PW_CWORD)
972
				map.flags |= F_MAP_PW_CWORD;
973
			break;
974
		}
975
	} else
976
		memcpy(&map, wcard, sizeof(map));
977
	map.label = label;
978
979
	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD, ln->peerid, 0,
980
	    &map, sizeof(map));
981
	lde_imsg_compose_ldpe(IMSG_RELEASE_ADD_END, ln->peerid, 0, NULL, 0);
982
}
983
984
void
985
lde_send_notification(struct lde_nbr *ln, uint32_t status_code, uint32_t msg_id,
986
    uint16_t msg_type)
987
{
988
	struct notify_msg nm;
989
990
	memset(&nm, 0, sizeof(nm));
991
	nm.status_code = status_code;
992
	/* 'msg_id' and 'msg_type' should be in network byte order */
993
	nm.msg_id = msg_id;
994
	nm.msg_type = msg_type;
995
996
	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
997
	    &nm, sizeof(nm));
998
}
999
1000
void
1001
lde_send_notification_eol_prefix(struct lde_nbr *ln, int af)
1002
{
1003
	struct notify_msg nm;
1004
1005
	memset(&nm, 0, sizeof(nm));
1006
	nm.status_code = S_ENDOFLIB;
1007
	nm.fec.type = MAP_TYPE_TYPED_WCARD;
1008
	nm.fec.fec.twcard.type = MAP_TYPE_PREFIX;
1009
	nm.fec.fec.twcard.u.prefix_af = af;
1010
	nm.flags |= F_NOTIF_FEC;
1011
1012
	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1013
	    &nm, sizeof(nm));
1014
}
1015
1016
void
1017
lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
1018
{
1019
	struct notify_msg nm;
1020
1021
	memset(&nm, 0, sizeof(nm));
1022
	nm.status_code = S_ENDOFLIB;
1023
	nm.fec.type = MAP_TYPE_TYPED_WCARD;
1024
	nm.fec.fec.twcard.type = MAP_TYPE_PWID;
1025
	nm.fec.fec.twcard.u.pw_type = pw_type;
1026
	nm.flags |= F_NOTIF_FEC;
1027
1028
	lde_imsg_compose_ldpe(IMSG_NOTIFICATION_SEND, ln->peerid, 0,
1029
	    &nm, sizeof(nm));
1030
}
1031
1032
static __inline int
1033
lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b)
1034
{
1035
	return (a->peerid - b->peerid);
1036
}
1037
1038
static struct lde_nbr *
1039
lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
1040
{
1041
	struct lde_nbr	*ln;
1042
1043
	if ((ln = calloc(1, sizeof(*ln))) == NULL)
1044
		fatal(__func__);
1045
1046
	ln->id = new->id;
1047
	ln->v4_enabled = new->v4_enabled;
1048
	ln->v6_enabled = new->v6_enabled;
1049
	ln->flags = new->flags;
1050
	ln->peerid = peerid;
1051
	fec_init(&ln->recv_map);
1052
	fec_init(&ln->sent_map);
1053
	fec_init(&ln->recv_req);
1054
	fec_init(&ln->sent_req);
1055
	fec_init(&ln->sent_wdraw);
1056
1057
	TAILQ_INIT(&ln->addr_list);
1058
1059
	if (RB_INSERT(nbr_tree, &lde_nbrs, ln) != NULL)
1060
		fatalx("lde_nbr_new: RB_INSERT failed");
1061
1062
	return (ln);
1063
}
1064
1065
static void
1066
lde_nbr_del(struct lde_nbr *ln)
1067
{
1068
	struct fec		*f;
1069
	struct fec_node		*fn;
1070
	struct fec_nh		*fnh;
1071
	struct l2vpn_pw		*pw;
1072
1073
	if (ln == NULL)
1074
		return;
1075
1076
	/* uninstall received mappings */
1077
	RB_FOREACH(f, fec_tree, &ft) {
1078
		fn = (struct fec_node *)f;
1079
1080
		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1081
			switch (f->type) {
1082
			case FEC_TYPE_IPV4:
1083
			case FEC_TYPE_IPV6:
1084
				if (!lde_address_find(ln, fnh->af,
1085
				    &fnh->nexthop))
1086
					continue;
1087
				break;
1088
			case FEC_TYPE_PWID:
1089
				if (f->u.pwid.lsr_id.s_addr != ln->id.s_addr)
1090
					continue;
1091
				pw = (struct l2vpn_pw *) fn->data;
1092
				if (pw)
1093
					l2vpn_pw_reset(pw);
1094
				break;
1095
			default:
1096
				break;
1097
			}
1098
1099
			lde_send_delete_klabel(fn, fnh);
1100
			fnh->remote_label = NO_LABEL;
1101
		}
1102
	}
1103
1104
	lde_address_list_free(ln);
1105
1106
	fec_clear(&ln->recv_map, lde_map_free);
1107
	fec_clear(&ln->sent_map, lde_map_free);
1108
	fec_clear(&ln->recv_req, free);
1109
	fec_clear(&ln->sent_req, free);
1110
	fec_clear(&ln->sent_wdraw, free);
1111
1112
	RB_REMOVE(nbr_tree, &lde_nbrs, ln);
1113
1114
	free(ln);
1115
}
1116
1117
static struct lde_nbr *
1118
lde_nbr_find(uint32_t peerid)
1119
{
1120
	struct lde_nbr		 ln;
1121
1122
	ln.peerid = peerid;
1123
1124
	return (RB_FIND(nbr_tree, &lde_nbrs, &ln));
1125
}
1126
1127
struct lde_nbr *
1128
lde_nbr_find_by_lsrid(struct in_addr addr)
1129
{
1130
	struct lde_nbr		*ln;
1131
1132
	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1133
		if (ln->id.s_addr == addr.s_addr)
1134
			return (ln);
1135
1136
	return (NULL);
1137
}
1138
1139
struct lde_nbr *
1140
lde_nbr_find_by_addr(int af, union ldpd_addr *addr)
1141
{
1142
	struct lde_nbr		*ln;
1143
1144
	RB_FOREACH(ln, nbr_tree, &lde_nbrs)
1145
		if (lde_address_find(ln, af, addr) != NULL)
1146
			return (ln);
1147
1148
	return (NULL);
1149
}
1150
1151
static void
1152
lde_nbr_clear(void)
1153
{
1154
	struct lde_nbr	*ln;
1155
1156
	 while ((ln = RB_ROOT(&lde_nbrs)) != NULL)
1157
		lde_nbr_del(ln);
1158
}
1159
1160
static void
1161
lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
1162
{
1163
	struct fec		*fec;
1164
	struct fec_node		*fn;
1165
	struct fec_nh		*fnh;
1166
	struct lde_map		*me;
1167
1168
	RB_FOREACH(fec, fec_tree, &ln->recv_map) {
1169
		fn = (struct fec_node *)fec_find(&ft, fec);
1170
		switch (fec->type) {
1171
		case FEC_TYPE_IPV4:
1172
			if (lde_addr->af != AF_INET)
1173
				continue;
1174
			break;
1175
		case FEC_TYPE_IPV6:
1176
			if (lde_addr->af != AF_INET6)
1177
				continue;
1178
			break;
1179
		default:
1180
			continue;
1181
		}
1182
1183
		LIST_FOREACH(fnh, &fn->nexthops, entry) {
1184
			if (ldp_addrcmp(fnh->af, &fnh->nexthop,
1185
			    &lde_addr->addr))
1186
				continue;
1187
1188
			if (removed) {
1189
				lde_send_delete_klabel(fn, fnh);
1190
				fnh->remote_label = NO_LABEL;
1191
			} else {
1192
				me = (struct lde_map *)fec;
1193
				fnh->remote_label = me->map.label;
1194
				lde_send_change_klabel(fn, fnh);
1195
			}
1196
			break;
1197
		}
1198
	}
1199
}
1200
1201
struct lde_map *
1202
lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
1203
{
1204
	struct lde_map  *me;
1205
1206
	me = calloc(1, sizeof(*me));
1207
	if (me == NULL)
1208
		fatal(__func__);
1209
1210
	me->fec = fn->fec;
1211
	me->nexthop = ln;
1212
1213
	if (sent) {
1214
		LIST_INSERT_HEAD(&fn->upstream, me, entry);
1215
		if (fec_insert(&ln->sent_map, &me->fec))
1216
			log_warnx("failed to add %s to sent map",
1217
			    log_fec(&me->fec));
1218
			/* XXX on failure more cleanup is needed */
1219
	} else {
1220
		LIST_INSERT_HEAD(&fn->downstream, me, entry);
1221
		if (fec_insert(&ln->recv_map, &me->fec))
1222
			log_warnx("failed to add %s to recv map",
1223
			    log_fec(&me->fec));
1224
	}
1225
1226
	return (me);
1227
}
1228
1229
void
1230
lde_map_del(struct lde_nbr *ln, struct lde_map *me, int sent)
1231
{
1232
	if (sent)
1233
		fec_remove(&ln->sent_map, &me->fec);
1234
	else
1235
		fec_remove(&ln->recv_map, &me->fec);
1236
1237
	lde_map_free(me);
1238
}
1239
1240
static void
1241
lde_map_free(void *ptr)
1242
{
1243
	struct lde_map	*map = ptr;
1244
1245
	LIST_REMOVE(map, entry);
1246
	free(map);
1247
}
1248
1249
struct lde_req *
1250
lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
1251
{
1252
	struct fec_tree	*t;
1253
	struct lde_req	*lre;
1254
1255
	t = sent ? &ln->sent_req : &ln->recv_req;
1256
1257
	lre = calloc(1, sizeof(*lre));
1258
	if (lre != NULL) {
1259
		lre->fec = *fec;
1260
1261
		if (fec_insert(t, &lre->fec)) {
1262
			log_warnx("failed to add %s to %s req",
1263
			    log_fec(&lre->fec), sent ? "sent" : "recv");
1264
			free(lre);
1265
			return (NULL);
1266
		}
1267
	}
1268
1269
	return (lre);
1270
}
1271
1272
void
1273
lde_req_del(struct lde_nbr *ln, struct lde_req *lre, int sent)
1274
{
1275
	if (sent)
1276
		fec_remove(&ln->sent_req, &lre->fec);
1277
	else
1278
		fec_remove(&ln->recv_req, &lre->fec);
1279
1280
	free(lre);
1281
}
1282
1283
struct lde_wdraw *
1284
lde_wdraw_add(struct lde_nbr *ln, struct fec_node *fn)
1285
{
1286
	struct lde_wdraw  *lw;
1287
1288
	lw = calloc(1, sizeof(*lw));
1289
	if (lw == NULL)
1290
		fatal(__func__);
1291
1292
	lw->fec = fn->fec;
1293
1294
	if (fec_insert(&ln->sent_wdraw, &lw->fec))
1295
		log_warnx("failed to add %s to sent wdraw",
1296
		    log_fec(&lw->fec));
1297
1298
	return (lw);
1299
}
1300
1301
void
1302
lde_wdraw_del(struct lde_nbr *ln, struct lde_wdraw *lw)
1303
{
1304
	fec_remove(&ln->sent_wdraw, &lw->fec);
1305
	free(lw);
1306
}
1307
1308
void
1309
lde_change_egress_label(int af, int was_implicit)
1310
{
1311
	struct lde_nbr	*ln;
1312
	struct fec	*f;
1313
	struct fec_node	*fn;
1314
1315
	RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
1316
		/* explicit withdraw */
1317
		if (was_implicit)
1318
			lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL);
1319
		else {
1320
			if (ln->v4_enabled)
1321
				lde_send_labelwithdraw_wcard(ln,
1322
				    MPLS_LABEL_IPV4NULL);
1323
			if (ln->v6_enabled)
1324
				lde_send_labelwithdraw_wcard(ln,
1325
				    MPLS_LABEL_IPV6NULL);
1326
		}
1327
1328
		/* advertise new label of connected prefixes */
1329
		RB_FOREACH(f, fec_tree, &ft) {
1330
			fn = (struct fec_node *)f;
1331
			if (fn->local_label > MPLS_LABEL_RESERVED_MAX)
1332
				continue;
1333
1334
			switch (af) {
1335
			case AF_INET:
1336
				if (fn->fec.type != FEC_TYPE_IPV4)
1337
					continue;
1338
				break;
1339
			case AF_INET6:
1340
				if (fn->fec.type != FEC_TYPE_IPV6)
1341
					continue;
1342
				break;
1343
			default:
1344
				fatalx("lde_change_egress_label: unknown af");
1345
			}
1346
1347
			fn->local_label = egress_label(fn->fec.type);
1348
			lde_send_labelmapping(ln, fn, 0);
1349
		}
1350
1351
		lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, ln->peerid, 0,
1352
		    NULL, 0);
1353
	}
1354
}
1355
1356
static int
1357
lde_address_add(struct lde_nbr *ln, struct lde_addr *lde_addr)
1358
{
1359
	struct lde_addr		*new;
1360
1361
	if (lde_address_find(ln, lde_addr->af, &lde_addr->addr) != NULL)
1362
		return (-1);
1363
1364
	if ((new = calloc(1, sizeof(*new))) == NULL)
1365
		fatal(__func__);
1366
1367
	new->af = lde_addr->af;
1368
	new->addr = lde_addr->addr;
1369
	TAILQ_INSERT_TAIL(&ln->addr_list, new, entry);
1370
1371
	/* reevaluate the previously received mappings from this neighbor */
1372
	lde_nbr_addr_update(ln, lde_addr, 0);
1373
1374
	return (0);
1375
}
1376
1377
static int
1378
lde_address_del(struct lde_nbr *ln, struct lde_addr *lde_addr)
1379
{
1380
	lde_addr = lde_address_find(ln, lde_addr->af, &lde_addr->addr);
1381
	if (lde_addr == NULL)
1382
		return (-1);
1383
1384
	/* reevaluate the previously received mappings from this neighbor */
1385
	lde_nbr_addr_update(ln, lde_addr, 1);
1386
1387
	TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1388
	free(lde_addr);
1389
1390
	return (0);
1391
}
1392
1393
struct lde_addr *
1394
lde_address_find(struct lde_nbr *ln, int af, union ldpd_addr *addr)
1395
{
1396
	struct lde_addr		*lde_addr;
1397
1398
	TAILQ_FOREACH(lde_addr, &ln->addr_list, entry)
1399
		if (lde_addr->af == af &&
1400
		    ldp_addrcmp(af, &lde_addr->addr, addr) == 0)
1401
			return (lde_addr);
1402
1403
	return (NULL);
1404
}
1405
1406
static void
1407
lde_address_list_free(struct lde_nbr *ln)
1408
{
1409
	struct lde_addr		*lde_addr;
1410
1411
	while ((lde_addr = TAILQ_FIRST(&ln->addr_list)) != NULL) {
1412
		TAILQ_REMOVE(&ln->addr_list, lde_addr, entry);
1413
		free(lde_addr);
1414
	}
1415
}