GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldpd/neighbor.c Lines: 0 341 0.0 %
Date: 2017-11-13 Branches: 0 726 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: neighbor.c,v 1.79 2017/03/04 00:15:35 renato Exp $ */
2
3
/*
4
 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5
 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
6
 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
7
 * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@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 <netinet/tcp.h>
25
#include <arpa/inet.h>
26
#include <errno.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#include "ldpd.h"
32
#include "ldpe.h"
33
#include "lde.h"
34
#include "log.h"
35
36
static __inline int	 nbr_id_compare(struct nbr *, struct nbr *);
37
static __inline int	 nbr_addr_compare(struct nbr *, struct nbr *);
38
static __inline int	 nbr_pid_compare(struct nbr *, struct nbr *);
39
static void		 nbr_update_peerid(struct nbr *);
40
static void		 nbr_ktimer(int, short, void *);
41
static void		 nbr_start_ktimer(struct nbr *);
42
static void		 nbr_ktimeout(int, short, void *);
43
static void		 nbr_start_ktimeout(struct nbr *);
44
static void		 nbr_itimeout(int, short, void *);
45
static void		 nbr_start_itimeout(struct nbr *);
46
static void		 nbr_idtimer(int, short, void *);
47
static int		 nbr_act_session_operational(struct nbr *);
48
static void		 nbr_send_labelmappings(struct nbr *);
49
50
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
51
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare)
52
RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare)
53
54
struct {
55
	int		state;
56
	enum nbr_event	event;
57
	enum nbr_action	action;
58
	int		new_state;
59
} nbr_fsm_tbl[] = {
60
    /* current state	event that happened	action to take		resulting state */
61
/* Passive Role */
62
    {NBR_STA_PRESENT,	NBR_EVT_MATCH_ADJ,	NBR_ACT_NOTHING,	NBR_STA_INITIAL},
63
    {NBR_STA_INITIAL,	NBR_EVT_INIT_RCVD,	NBR_ACT_PASSIVE_INIT,	NBR_STA_OPENREC},
64
    {NBR_STA_OPENREC,	NBR_EVT_KEEPALIVE_RCVD,	NBR_ACT_SESSION_EST,	NBR_STA_OPER},
65
/* Active Role */
66
    {NBR_STA_PRESENT,	NBR_EVT_CONNECT_UP,	NBR_ACT_CONNECT_SETUP,	NBR_STA_INITIAL},
67
    {NBR_STA_INITIAL,	NBR_EVT_INIT_SENT,	NBR_ACT_NOTHING,	NBR_STA_OPENSENT},
68
    {NBR_STA_OPENSENT,	NBR_EVT_INIT_RCVD,	NBR_ACT_KEEPALIVE_SEND,	NBR_STA_OPENREC},
69
/* Session Maintenance */
70
    {NBR_STA_OPER,	NBR_EVT_PDU_RCVD,	NBR_ACT_RST_KTIMEOUT,	0},
71
    {NBR_STA_SESSION,	NBR_EVT_PDU_RCVD,	NBR_ACT_NOTHING,	0},
72
    {NBR_STA_OPER,	NBR_EVT_PDU_SENT,	NBR_ACT_RST_KTIMER,	0},
73
    {NBR_STA_SESSION,	NBR_EVT_PDU_SENT,	NBR_ACT_NOTHING,	0},
74
/* Session Close */
75
    {NBR_STA_PRESENT,	NBR_EVT_CLOSE_SESSION,	NBR_ACT_NOTHING,	0},
76
    {NBR_STA_SESSION,	NBR_EVT_CLOSE_SESSION,	NBR_ACT_CLOSE_SESSION,	NBR_STA_PRESENT},
77
    {-1,		NBR_EVT_NOTHING,	NBR_ACT_NOTHING,	0},
78
};
79
80
const char * const nbr_event_names[] = {
81
	"NOTHING",
82
	"ADJACENCY MATCHED",
83
	"CONNECTION UP",
84
	"SESSION CLOSE",
85
	"INIT RECEIVED",
86
	"KEEPALIVE RECEIVED",
87
	"PDU RECEIVED",
88
	"PDU SENT",
89
	"INIT SENT"
90
};
91
92
const char * const nbr_action_names[] = {
93
	"NOTHING",
94
	"RESET KEEPALIVE TIMEOUT",
95
	"START NEIGHBOR SESSION",
96
	"RESET KEEPALIVE TIMER",
97
	"SETUP NEIGHBOR CONNECTION",
98
	"SEND INIT AND KEEPALIVE",
99
	"SEND KEEPALIVE",
100
	"CLOSE SESSION"
101
};
102
103
struct nbr_id_head nbrs_by_id = RB_INITIALIZER(&nbrs_by_id);
104
struct nbr_addr_head nbrs_by_addr = RB_INITIALIZER(&nbrs_by_addr);
105
struct nbr_pid_head nbrs_by_pid = RB_INITIALIZER(&nbrs_by_pid);
106
107
static __inline int
108
nbr_id_compare(struct nbr *a, struct nbr *b)
109
{
110
	return (ntohl(a->id.s_addr) - ntohl(b->id.s_addr));
111
}
112
113
static __inline int
114
nbr_addr_compare(struct nbr *a, struct nbr *b)
115
{
116
	if (a->af < b->af)
117
		return (-1);
118
	if (a->af > b->af)
119
		return (1);
120
121
	return (ldp_addrcmp(a->af, &a->raddr, &b->raddr));
122
}
123
124
static __inline int
125
nbr_pid_compare(struct nbr *a, struct nbr *b)
126
{
127
	return (a->peerid - b->peerid);
128
}
129
130
int
131
nbr_fsm(struct nbr *nbr, enum nbr_event event)
132
{
133
	struct timeval	now;
134
	int		old_state;
135
	int		new_state = 0;
136
	int		i;
137
138
	old_state = nbr->state;
139
	for (i = 0; nbr_fsm_tbl[i].state != -1; i++)
140
		if ((nbr_fsm_tbl[i].state & old_state) &&
141
		    (nbr_fsm_tbl[i].event == event)) {
142
			new_state = nbr_fsm_tbl[i].new_state;
143
			break;
144
		}
145
146
	if (nbr_fsm_tbl[i].state == -1) {
147
		/* event outside of the defined fsm, ignore it. */
148
		log_warnx("%s: lsr-id %s, event %s not expected in "
149
		    "state %s", __func__, inet_ntoa(nbr->id),
150
		    nbr_event_names[event], nbr_state_name(old_state));
151
		return (0);
152
	}
153
154
	if (new_state != 0)
155
		nbr->state = new_state;
156
157
	if (old_state != nbr->state) {
158
		log_debug("%s: event %s resulted in action %s and "
159
		    "changing state for lsr-id %s from %s to %s",
160
		    __func__, nbr_event_names[event],
161
		    nbr_action_names[nbr_fsm_tbl[i].action],
162
		    inet_ntoa(nbr->id), nbr_state_name(old_state),
163
		    nbr_state_name(nbr->state));
164
165
		if (nbr->state == NBR_STA_OPER) {
166
			gettimeofday(&now, NULL);
167
			nbr->uptime = now.tv_sec;
168
		}
169
	}
170
171
	if (nbr->state == NBR_STA_OPER || nbr->state == NBR_STA_PRESENT)
172
		nbr_stop_itimeout(nbr);
173
	else
174
		nbr_start_itimeout(nbr);
175
176
	switch (nbr_fsm_tbl[i].action) {
177
	case NBR_ACT_RST_KTIMEOUT:
178
		nbr_start_ktimeout(nbr);
179
		break;
180
	case NBR_ACT_RST_KTIMER:
181
		nbr_start_ktimer(nbr);
182
		break;
183
	case NBR_ACT_SESSION_EST:
184
		nbr_act_session_operational(nbr);
185
		nbr_start_ktimer(nbr);
186
		nbr_start_ktimeout(nbr);
187
		if (nbr->v4_enabled)
188
			send_address_all(nbr, AF_INET);
189
		if (nbr->v6_enabled)
190
			send_address_all(nbr, AF_INET6);
191
		nbr_send_labelmappings(nbr);
192
		break;
193
	case NBR_ACT_CONNECT_SETUP:
194
		nbr->tcp = tcp_new(nbr->fd, nbr);
195
196
		/* trigger next state */
197
		send_init(nbr);
198
		nbr_fsm(nbr, NBR_EVT_INIT_SENT);
199
		break;
200
	case NBR_ACT_PASSIVE_INIT:
201
		send_init(nbr);
202
		send_keepalive(nbr);
203
		break;
204
	case NBR_ACT_KEEPALIVE_SEND:
205
		nbr_start_ktimeout(nbr);
206
		send_keepalive(nbr);
207
		break;
208
	case NBR_ACT_CLOSE_SESSION:
209
		ldpe_imsg_compose_lde(IMSG_NEIGHBOR_DOWN, nbr->peerid, 0,
210
		    NULL, 0);
211
		session_close(nbr);
212
		break;
213
	case NBR_ACT_NOTHING:
214
		/* do nothing */
215
		break;
216
	}
217
218
	return (0);
219
}
220
221
struct nbr *
222
nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
223
    uint32_t scope_id)
224
{
225
	struct nbr		*nbr;
226
	struct nbr_params	*nbrp;
227
	struct adj		*adj;
228
	struct pending_conn	*pconn;
229
230
	log_debug("%s: lsr-id %s transport-address %s", __func__,
231
	    inet_ntoa(id), log_addr(af, addr));
232
233
	if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
234
		fatal(__func__);
235
236
	LIST_INIT(&nbr->adj_list);
237
	nbr->state = NBR_STA_PRESENT;
238
	nbr->peerid = 0;
239
	nbr->af = af;
240
	nbr->ds_tlv = ds_tlv;
241
	if (af == AF_INET || ds_tlv)
242
		nbr->v4_enabled = 1;
243
	if (af == AF_INET6 || ds_tlv)
244
		nbr->v6_enabled = 1;
245
	nbr->id = id;
246
	nbr->laddr = (ldp_af_conf_get(leconf, af))->trans_addr;
247
	nbr->raddr = *addr;
248
	nbr->raddr_scope = scope_id;
249
	nbr->conf_seqnum = 0;
250
251
	LIST_FOREACH(adj, &global.adj_list, global_entry) {
252
		if (adj->lsr_id.s_addr == nbr->id.s_addr) {
253
			adj->nbr = nbr;
254
			LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
255
		}
256
	}
257
258
	if (RB_INSERT(nbr_id_head, &nbrs_by_id, nbr) != NULL)
259
		fatalx("nbr_new: RB_INSERT(nbrs_by_id) failed");
260
	if (RB_INSERT(nbr_addr_head, &nbrs_by_addr, nbr) != NULL)
261
		fatalx("nbr_new: RB_INSERT(nbrs_by_addr) failed");
262
263
	TAILQ_INIT(&nbr->mapping_list);
264
	TAILQ_INIT(&nbr->withdraw_list);
265
	TAILQ_INIT(&nbr->request_list);
266
	TAILQ_INIT(&nbr->release_list);
267
	TAILQ_INIT(&nbr->abortreq_list);
268
269
	/* set event structures */
270
	evtimer_set(&nbr->keepalive_timeout, nbr_ktimeout, nbr);
271
	evtimer_set(&nbr->keepalive_timer, nbr_ktimer, nbr);
272
	evtimer_set(&nbr->init_timeout, nbr_itimeout, nbr);
273
	evtimer_set(&nbr->initdelay_timer, nbr_idtimer, nbr);
274
275
	nbrp = nbr_params_find(leconf, nbr->id);
276
	if (nbrp && pfkey_establish(nbr, nbrp) == -1)
277
		fatalx("pfkey setup failed");
278
279
	pconn = pending_conn_find(nbr->af, &nbr->raddr);
280
	if (pconn) {
281
		session_accept_nbr(nbr, pconn->fd);
282
		pending_conn_del(pconn);
283
	}
284
285
	return (nbr);
286
}
287
288
void
289
nbr_del(struct nbr *nbr)
290
{
291
	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
292
293
	nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
294
	pfkey_remove(nbr);
295
296
	if (nbr_pending_connect(nbr))
297
		event_del(&nbr->ev_connect);
298
	nbr_stop_ktimer(nbr);
299
	nbr_stop_ktimeout(nbr);
300
	nbr_stop_itimeout(nbr);
301
	nbr_stop_idtimer(nbr);
302
303
	mapping_list_clr(&nbr->mapping_list);
304
	mapping_list_clr(&nbr->withdraw_list);
305
	mapping_list_clr(&nbr->request_list);
306
	mapping_list_clr(&nbr->release_list);
307
	mapping_list_clr(&nbr->abortreq_list);
308
309
	if (nbr->peerid)
310
		RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
311
	RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr);
312
	RB_REMOVE(nbr_addr_head, &nbrs_by_addr, nbr);
313
314
	free(nbr);
315
}
316
317
static void
318
nbr_update_peerid(struct nbr *nbr)
319
{
320
	static uint32_t	 peercnt = 1;
321
322
	if (nbr->peerid)
323
		RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
324
325
	/* get next unused peerid */
326
	while (nbr_find_peerid(++peercnt))
327
		;
328
	nbr->peerid = peercnt;
329
330
	if (RB_INSERT(nbr_pid_head, &nbrs_by_pid, nbr) != NULL)
331
		fatalx("nbr_update_peerid: RB_INSERT(nbrs_by_pid) failed");
332
}
333
334
struct nbr *
335
nbr_find_ldpid(uint32_t lsr_id)
336
{
337
	struct nbr	n;
338
	n.id.s_addr = lsr_id;
339
	return (RB_FIND(nbr_id_head, &nbrs_by_id, &n));
340
}
341
342
struct nbr *
343
nbr_find_addr(int af, union ldpd_addr *addr)
344
{
345
	struct nbr	n;
346
	n.af = af;
347
	n.raddr = *addr;
348
	return (RB_FIND(nbr_addr_head, &nbrs_by_addr, &n));
349
}
350
351
struct nbr *
352
nbr_find_peerid(uint32_t peerid)
353
{
354
	struct nbr	n;
355
	n.peerid = peerid;
356
	return (RB_FIND(nbr_pid_head, &nbrs_by_pid, &n));
357
}
358
359
int
360
nbr_adj_count(struct nbr *nbr, int af)
361
{
362
	struct adj	*adj;
363
	int		 total = 0;
364
365
	LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
366
		if (adj_get_af(adj) == af)
367
			total++;
368
369
	return (total);
370
}
371
372
int
373
nbr_session_active_role(struct nbr *nbr)
374
{
375
	if (ldp_addrcmp(nbr->af, &nbr->laddr, &nbr->raddr) > 0)
376
		return (1);
377
378
	return (0);
379
}
380
381
/* timers */
382
383
/* Keepalive timer: timer to send keepalive message to neighbors */
384
385
static void
386
nbr_ktimer(int fd, short event, void *arg)
387
{
388
	struct nbr	*nbr = arg;
389
390
	send_keepalive(nbr);
391
	nbr_start_ktimer(nbr);
392
}
393
394
static void
395
nbr_start_ktimer(struct nbr *nbr)
396
{
397
	struct timeval	 tv;
398
399
	/* send three keepalives per period */
400
	timerclear(&tv);
401
	tv.tv_sec = (time_t)(nbr->keepalive / KEEPALIVE_PER_PERIOD);
402
	if (evtimer_add(&nbr->keepalive_timer, &tv) == -1)
403
		fatal(__func__);
404
}
405
406
void
407
nbr_stop_ktimer(struct nbr *nbr)
408
{
409
	if (evtimer_pending(&nbr->keepalive_timer, NULL) &&
410
	    evtimer_del(&nbr->keepalive_timer) == -1)
411
		fatal(__func__);
412
}
413
414
/* Keepalive timeout: if the nbr hasn't sent keepalive */
415
416
static void
417
nbr_ktimeout(int fd, short event, void *arg)
418
{
419
	struct nbr *nbr = arg;
420
421
	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
422
423
	session_shutdown(nbr, S_KEEPALIVE_TMR, 0, 0);
424
}
425
426
static void
427
nbr_start_ktimeout(struct nbr *nbr)
428
{
429
	struct timeval	tv;
430
431
	timerclear(&tv);
432
	tv.tv_sec = nbr->keepalive;
433
434
	if (evtimer_add(&nbr->keepalive_timeout, &tv) == -1)
435
		fatal(__func__);
436
}
437
438
void
439
nbr_stop_ktimeout(struct nbr *nbr)
440
{
441
	if (evtimer_pending(&nbr->keepalive_timeout, NULL) &&
442
	    evtimer_del(&nbr->keepalive_timeout) == -1)
443
		fatal(__func__);
444
}
445
446
/* Session initialization timeout: if nbr got stuck in the initialization FSM */
447
448
static void
449
nbr_itimeout(int fd, short event, void *arg)
450
{
451
	struct nbr *nbr = arg;
452
453
	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
454
455
	nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
456
}
457
458
static void
459
nbr_start_itimeout(struct nbr *nbr)
460
{
461
	struct timeval	 tv;
462
463
	timerclear(&tv);
464
	tv.tv_sec = INIT_FSM_TIMEOUT;
465
	if (evtimer_add(&nbr->init_timeout, &tv) == -1)
466
		fatal(__func__);
467
}
468
469
void
470
nbr_stop_itimeout(struct nbr *nbr)
471
{
472
	if (evtimer_pending(&nbr->init_timeout, NULL) &&
473
	    evtimer_del(&nbr->init_timeout) == -1)
474
		fatal(__func__);
475
}
476
477
/* Init delay timer: timer to retry to iniziatize session */
478
479
static void
480
nbr_idtimer(int fd, short event, void *arg)
481
{
482
	struct nbr *nbr = arg;
483
484
	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
485
486
	nbr_establish_connection(nbr);
487
}
488
489
void
490
nbr_start_idtimer(struct nbr *nbr)
491
{
492
	struct timeval	tv;
493
494
	timerclear(&tv);
495
496
	tv.tv_sec = INIT_DELAY_TMR;
497
	switch(nbr->idtimer_cnt) {
498
	default:
499
		/* do not further increase the counter */
500
		tv.tv_sec = MAX_DELAY_TMR;
501
		break;
502
	case 2:
503
		tv.tv_sec *= 2;
504
		/* FALLTHROUGH */
505
	case 1:
506
		tv.tv_sec *= 2;
507
		/* FALLTHROUGH */
508
	case 0:
509
		nbr->idtimer_cnt++;
510
		break;
511
	}
512
513
	if (evtimer_add(&nbr->initdelay_timer, &tv) == -1)
514
		fatal(__func__);
515
}
516
517
void
518
nbr_stop_idtimer(struct nbr *nbr)
519
{
520
	if (evtimer_pending(&nbr->initdelay_timer, NULL) &&
521
	    evtimer_del(&nbr->initdelay_timer) == -1)
522
		fatal(__func__);
523
}
524
525
int
526
nbr_pending_idtimer(struct nbr *nbr)
527
{
528
	if (evtimer_pending(&nbr->initdelay_timer, NULL))
529
		return (1);
530
531
	return (0);
532
}
533
534
int
535
nbr_pending_connect(struct nbr *nbr)
536
{
537
	if (event_initialized(&nbr->ev_connect) &&
538
	    event_pending(&nbr->ev_connect, EV_WRITE, NULL))
539
		return (1);
540
541
	return (0);
542
}
543
544
static void
545
nbr_connect_cb(int fd, short event, void *arg)
546
{
547
	struct nbr	*nbr = arg;
548
	int		 error;
549
	socklen_t	 len;
550
551
	len = sizeof(error);
552
	if (getsockopt(nbr->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
553
		log_warn("%s: getsockopt SOL_SOCKET SO_ERROR", __func__);
554
		return;
555
	}
556
557
	if (error) {
558
		close(nbr->fd);
559
		errno = error;
560
		log_debug("%s: error while connecting to %s: %s", __func__,
561
		    log_addr(nbr->af, &nbr->raddr), strerror(errno));
562
		return;
563
	}
564
565
	nbr_fsm(nbr, NBR_EVT_CONNECT_UP);
566
}
567
568
int
569
nbr_establish_connection(struct nbr *nbr)
570
{
571
	struct sockaddr_storage	 local_sa;
572
	struct sockaddr_storage	 remote_sa;
573
	struct adj		*adj;
574
	struct nbr_params	*nbrp;
575
	int			 opt = 1;
576
577
	nbr->fd = socket(nbr->af,
578
	    SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
579
	if (nbr->fd == -1) {
580
		log_warn("%s: error while creating socket", __func__);
581
		return (-1);
582
	}
583
584
	nbrp = nbr_params_find(leconf, nbr->id);
585
	if (nbrp && nbrp->auth.method == AUTH_MD5SIG) {
586
		if (sysdep.no_pfkey || sysdep.no_md5sig) {
587
			log_warnx("md5sig configured but not available");
588
			close(nbr->fd);
589
			return (-1);
590
		}
591
		if (setsockopt(nbr->fd, IPPROTO_TCP, TCP_MD5SIG,
592
		    &opt, sizeof(opt)) == -1) {
593
			log_warn("setsockopt md5sig");
594
			close(nbr->fd);
595
			return (-1);
596
		}
597
	}
598
599
	memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa));
600
	memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT),
601
	    sizeof(local_sa));
602
	if (nbr->af == AF_INET6 && nbr->raddr_scope)
603
		addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope);
604
605
	if (bind(nbr->fd, (struct sockaddr *)&local_sa,
606
	    local_sa.ss_len) == -1) {
607
		log_warn("%s: error while binding socket to %s", __func__,
608
		    log_sockaddr((struct sockaddr *)&local_sa));
609
		close(nbr->fd);
610
		return (-1);
611
	}
612
613
	if (nbr_gtsm_check(nbr->fd, nbr, nbrp)) {
614
		close(nbr->fd);
615
		return (-1);
616
	}
617
618
	/*
619
	 * Send an extra hello to guarantee that the remote peer has formed
620
	 * an adjacency as well.
621
	 */
622
	LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
623
		send_hello(adj->source.type, adj->source.link.ia,
624
		    adj->source.target);
625
626
	if (connect(nbr->fd, (struct sockaddr *)&remote_sa,
627
	    remote_sa.ss_len) == -1) {
628
		if (errno == EINPROGRESS) {
629
			event_set(&nbr->ev_connect, nbr->fd, EV_WRITE,
630
			    nbr_connect_cb, nbr);
631
			event_add(&nbr->ev_connect, NULL);
632
			return (0);
633
		}
634
		log_warn("%s: error while connecting to %s", __func__,
635
		    log_sockaddr((struct sockaddr *)&remote_sa));
636
		close(nbr->fd);
637
		return (-1);
638
	}
639
640
	/* connection completed immediately */
641
	nbr_fsm(nbr, NBR_EVT_CONNECT_UP);
642
643
	return (0);
644
}
645
646
int
647
nbr_gtsm_enabled(struct nbr *nbr, struct nbr_params *nbrp)
648
{
649
	/*
650
	 * RFC 6720 - Section 3:
651
	 * "This document allows for the implementation to provide an option to
652
	 * statically (e.g., via configuration) and/or dynamically override the
653
	 * default behavior and enable/disable GTSM on a per-peer basis".
654
	 */
655
	if (nbrp && (nbrp->flags & F_NBRP_GTSM))
656
		return (nbrp->gtsm_enabled);
657
658
	if ((ldp_af_conf_get(leconf, nbr->af))->flags & F_LDPD_AF_NO_GTSM)
659
		return (0);
660
661
	/* By default, GTSM support has to be negotiated for LDPv4 */
662
	if (nbr->af == AF_INET && !(nbr->flags & F_NBR_GTSM_NEGOTIATED))
663
		return (0);
664
665
	return (1);
666
}
667
668
int
669
nbr_gtsm_setup(int fd, int af, struct nbr_params *nbrp)
670
{
671
	int	 ttl = 255;
672
673
	if (nbrp && (nbrp->flags & F_NBRP_GTSM_HOPS))
674
		ttl = 256 - nbrp->gtsm_hops;
675
676
	switch (af) {
677
	case AF_INET:
678
		if (sock_set_ipv4_minttl(fd, ttl) == -1)
679
			return (-1);
680
		ttl = 255;
681
		if (sock_set_ipv4_ucast_ttl(fd, ttl) == -1)
682
			return (-1);
683
		break;
684
	case AF_INET6:
685
		if (sock_set_ipv6_minhopcount(fd, ttl) == -1)
686
			return (-1);
687
		ttl = 255;
688
		if (sock_set_ipv6_ucast_hops(fd, ttl) == -1)
689
			return (-1);
690
		break;
691
	default:
692
		fatalx("nbr_gtsm_setup: unknown af");
693
	}
694
695
	return (0);
696
}
697
698
int
699
nbr_gtsm_check(int fd, struct nbr *nbr, struct nbr_params *nbrp)
700
{
701
	if (!nbr_gtsm_enabled(nbr, nbrp)) {
702
		switch (nbr->af) {
703
		case AF_INET:
704
			sock_set_ipv4_ucast_ttl(fd, -1);
705
			break;
706
		case AF_INET6:
707
			/*
708
			 * Send packets with a Hop Limit of 255 even when GSTM
709
			 * is disabled to guarantee interoperability.
710
			 */
711
			sock_set_ipv6_ucast_hops(fd, 255);
712
			break;
713
		default:
714
			fatalx("nbr_gtsm_check: unknown af");
715
			break;
716
		}
717
		return (0);
718
	}
719
720
	if (nbr_gtsm_setup(fd, nbr->af, nbrp) == -1) {
721
		log_warnx("%s: error enabling GTSM for lsr-id %s", __func__,
722
		    inet_ntoa(nbr->id));
723
		return (-1);
724
	}
725
726
	return (0);
727
}
728
729
static int
730
nbr_act_session_operational(struct nbr *nbr)
731
{
732
	struct lde_nbr	 lde_nbr;
733
734
	nbr->idtimer_cnt = 0;
735
736
	/* this is necessary to avoid ipc synchronization issues */
737
	nbr_update_peerid(nbr);
738
739
	memset(&lde_nbr, 0, sizeof(lde_nbr));
740
	lde_nbr.id = nbr->id;
741
	lde_nbr.v4_enabled = nbr->v4_enabled;
742
	lde_nbr.v6_enabled = nbr->v6_enabled;
743
	lde_nbr.flags = nbr->flags;
744
	return (ldpe_imsg_compose_lde(IMSG_NEIGHBOR_UP, nbr->peerid, 0,
745
	    &lde_nbr, sizeof(lde_nbr)));
746
}
747
748
static void
749
nbr_send_labelmappings(struct nbr *nbr)
750
{
751
	ldpe_imsg_compose_lde(IMSG_LABEL_MAPPING_FULL, nbr->peerid, 0,
752
	    NULL, 0);
753
}
754
755
struct nbr_params *
756
nbr_params_new(struct in_addr lsr_id)
757
{
758
	struct nbr_params	*nbrp;
759
760
	if ((nbrp = calloc(1, sizeof(*nbrp))) == NULL)
761
		fatal(__func__);
762
763
	nbrp->lsr_id = lsr_id;
764
	nbrp->auth.method = AUTH_NONE;
765
766
	return (nbrp);
767
}
768
769
struct nbr_params *
770
nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
771
{
772
	struct nbr_params *nbrp;
773
774
	LIST_FOREACH(nbrp, &xconf->nbrp_list, entry)
775
		if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
776
			return (nbrp);
777
778
	return (NULL);
779
}
780
781
uint16_t
782
nbr_get_keepalive(int af, struct in_addr lsr_id)
783
{
784
	struct nbr_params	*nbrp;
785
786
	nbrp = nbr_params_find(leconf, lsr_id);
787
	if (nbrp && (nbrp->flags & F_NBRP_KEEPALIVE))
788
		return (nbrp->keepalive);
789
790
	return ((ldp_af_conf_get(leconf, af))->keepalive);
791
}
792
793
struct ctl_nbr *
794
nbr_to_ctl(struct nbr *nbr)
795
{
796
	static struct ctl_nbr	 nctl;
797
	struct timeval		 now;
798
799
	nctl.af = nbr->af;
800
	nctl.id = nbr->id;
801
	nctl.laddr = nbr->laddr;
802
	nctl.raddr = nbr->raddr;
803
	nctl.nbr_state = nbr->state;
804
805
	gettimeofday(&now, NULL);
806
	if (nbr->state == NBR_STA_OPER) {
807
		nctl.uptime = now.tv_sec - nbr->uptime;
808
	} else
809
		nctl.uptime = 0;
810
811
	return (&nctl);
812
}
813
814
void
815
nbr_clear_ctl(struct ctl_nbr *nctl)
816
{
817
	struct nbr		*nbr;
818
819
	RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
820
		if (ldp_addrisset(nctl->af, &nctl->raddr) &&
821
		    ldp_addrcmp(nctl->af, &nctl->raddr, &nbr->raddr))
822
			continue;
823
824
		log_debug("%s: neighbor %s manually cleared", __func__,
825
		    log_addr(nbr->af, &nbr->raddr));
826
		session_shutdown(nbr, S_SHUTDOWN, 0, 0);
827
	}
828
}