xref: /openbsd-src/usr.sbin/ldpd/neighbor.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: neighbor.c,v 1.78 2016/09/03 16:07:08 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 	return (ldpe_imsg_compose_lde(IMSG_NEIGHBOR_UP, nbr->peerid, 0,
744 	    &lde_nbr, sizeof(lde_nbr)));
745 }
746 
747 static void
748 nbr_send_labelmappings(struct nbr *nbr)
749 {
750 	ldpe_imsg_compose_lde(IMSG_LABEL_MAPPING_FULL, nbr->peerid, 0,
751 	    NULL, 0);
752 }
753 
754 struct nbr_params *
755 nbr_params_new(struct in_addr lsr_id)
756 {
757 	struct nbr_params	*nbrp;
758 
759 	if ((nbrp = calloc(1, sizeof(*nbrp))) == NULL)
760 		fatal(__func__);
761 
762 	nbrp->lsr_id = lsr_id;
763 	nbrp->auth.method = AUTH_NONE;
764 
765 	return (nbrp);
766 }
767 
768 struct nbr_params *
769 nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
770 {
771 	struct nbr_params *nbrp;
772 
773 	LIST_FOREACH(nbrp, &xconf->nbrp_list, entry)
774 		if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
775 			return (nbrp);
776 
777 	return (NULL);
778 }
779 
780 uint16_t
781 nbr_get_keepalive(int af, struct in_addr lsr_id)
782 {
783 	struct nbr_params	*nbrp;
784 
785 	nbrp = nbr_params_find(leconf, lsr_id);
786 	if (nbrp && (nbrp->flags & F_NBRP_KEEPALIVE))
787 		return (nbrp->keepalive);
788 
789 	return ((ldp_af_conf_get(leconf, af))->keepalive);
790 }
791 
792 struct ctl_nbr *
793 nbr_to_ctl(struct nbr *nbr)
794 {
795 	static struct ctl_nbr	 nctl;
796 	struct timeval		 now;
797 
798 	nctl.af = nbr->af;
799 	nctl.id = nbr->id;
800 	nctl.laddr = nbr->laddr;
801 	nctl.raddr = nbr->raddr;
802 	nctl.nbr_state = nbr->state;
803 
804 	gettimeofday(&now, NULL);
805 	if (nbr->state == NBR_STA_OPER) {
806 		nctl.uptime = now.tv_sec - nbr->uptime;
807 	} else
808 		nctl.uptime = 0;
809 
810 	return (&nctl);
811 }
812 
813 void
814 nbr_clear_ctl(struct ctl_nbr *nctl)
815 {
816 	struct nbr		*nbr;
817 
818 	RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
819 		if (ldp_addrisset(nctl->af, &nctl->raddr) &&
820 		    ldp_addrcmp(nctl->af, &nctl->raddr, &nbr->raddr))
821 			continue;
822 
823 		log_debug("%s: neighbor %s manually cleared", __func__,
824 		    log_addr(nbr->af, &nbr->raddr));
825 		session_shutdown(nbr, S_SHUTDOWN, 0, 0);
826 	}
827 }
828