xref: /openbsd/usr.sbin/ldpd/neighbor.c (revision df69c215)
1 /*	$OpenBSD: neighbor.c,v 1.81 2019/06/28 13:32:48 deraadt 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
nbr_id_compare(struct nbr * a,struct nbr * b)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
nbr_addr_compare(struct nbr * a,struct nbr * b)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
nbr_pid_compare(struct nbr * a,struct nbr * b)125 nbr_pid_compare(struct nbr *a, struct nbr *b)
126 {
127 	return (a->peerid - b->peerid);
128 }
129 
130 int
nbr_fsm(struct nbr * nbr,enum nbr_event event)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 *
nbr_new(struct in_addr id,int af,int ds_tlv,union ldpd_addr * addr,uint32_t scope_id)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 adj		*adj;
227 	struct pending_conn	*pconn;
228 
229 	log_debug("%s: lsr-id %s transport-address %s", __func__,
230 	    inet_ntoa(id), log_addr(af, addr));
231 
232 	if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
233 		fatal(__func__);
234 
235 	LIST_INIT(&nbr->adj_list);
236 	nbr->state = NBR_STA_PRESENT;
237 	nbr->peerid = 0;
238 	nbr->af = af;
239 	nbr->ds_tlv = ds_tlv;
240 	if (af == AF_INET || ds_tlv)
241 		nbr->v4_enabled = 1;
242 	if (af == AF_INET6 || ds_tlv)
243 		nbr->v6_enabled = 1;
244 	nbr->id = id;
245 	nbr->laddr = (ldp_af_conf_get(leconf, af))->trans_addr;
246 	nbr->raddr = *addr;
247 	nbr->raddr_scope = scope_id;
248 	nbr->conf_seqnum = 0;
249 
250 	LIST_FOREACH(adj, &global.adj_list, global_entry) {
251 		if (adj->lsr_id.s_addr == nbr->id.s_addr) {
252 			adj->nbr = nbr;
253 			LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
254 		}
255 	}
256 
257 	if (RB_INSERT(nbr_id_head, &nbrs_by_id, nbr) != NULL)
258 		fatalx("nbr_new: RB_INSERT(nbrs_by_id) failed");
259 	if (RB_INSERT(nbr_addr_head, &nbrs_by_addr, nbr) != NULL)
260 		fatalx("nbr_new: RB_INSERT(nbrs_by_addr) failed");
261 
262 	TAILQ_INIT(&nbr->mapping_list);
263 	TAILQ_INIT(&nbr->withdraw_list);
264 	TAILQ_INIT(&nbr->request_list);
265 	TAILQ_INIT(&nbr->release_list);
266 	TAILQ_INIT(&nbr->abortreq_list);
267 
268 	/* set event structures */
269 	evtimer_set(&nbr->keepalive_timeout, nbr_ktimeout, nbr);
270 	evtimer_set(&nbr->keepalive_timer, nbr_ktimer, nbr);
271 	evtimer_set(&nbr->init_timeout, nbr_itimeout, nbr);
272 	evtimer_set(&nbr->initdelay_timer, nbr_idtimer, nbr);
273 
274 	if (pfkey_establish(leconf, nbr) == -1)
275 		fatalx("pfkey setup failed");
276 
277 	pconn = pending_conn_find(nbr->af, &nbr->raddr);
278 	if (pconn) {
279 		session_accept_nbr(nbr, pconn->fd);
280 		pending_conn_del(pconn);
281 	}
282 
283 	return (nbr);
284 }
285 
286 void
nbr_del(struct nbr * nbr)287 nbr_del(struct nbr *nbr)
288 {
289 	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
290 
291 	nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
292 	pfkey_remove(nbr);
293 
294 	if (nbr_pending_connect(nbr))
295 		event_del(&nbr->ev_connect);
296 	nbr_stop_ktimer(nbr);
297 	nbr_stop_ktimeout(nbr);
298 	nbr_stop_itimeout(nbr);
299 	nbr_stop_idtimer(nbr);
300 
301 	mapping_list_clr(&nbr->mapping_list);
302 	mapping_list_clr(&nbr->withdraw_list);
303 	mapping_list_clr(&nbr->request_list);
304 	mapping_list_clr(&nbr->release_list);
305 	mapping_list_clr(&nbr->abortreq_list);
306 
307 	if (nbr->peerid)
308 		RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
309 	RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr);
310 	RB_REMOVE(nbr_addr_head, &nbrs_by_addr, nbr);
311 
312 	free(nbr);
313 }
314 
315 static void
nbr_update_peerid(struct nbr * nbr)316 nbr_update_peerid(struct nbr *nbr)
317 {
318 	static uint32_t	 peercnt = 1;
319 
320 	if (nbr->peerid)
321 		RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
322 
323 	/* get next unused peerid */
324 	while (nbr_find_peerid(++peercnt))
325 		;
326 	nbr->peerid = peercnt;
327 
328 	if (RB_INSERT(nbr_pid_head, &nbrs_by_pid, nbr) != NULL)
329 		fatalx("nbr_update_peerid: RB_INSERT(nbrs_by_pid) failed");
330 }
331 
332 struct nbr *
nbr_find_ldpid(uint32_t lsr_id)333 nbr_find_ldpid(uint32_t lsr_id)
334 {
335 	struct nbr	n;
336 	n.id.s_addr = lsr_id;
337 	return (RB_FIND(nbr_id_head, &nbrs_by_id, &n));
338 }
339 
340 struct nbr *
nbr_find_addr(int af,union ldpd_addr * addr)341 nbr_find_addr(int af, union ldpd_addr *addr)
342 {
343 	struct nbr	n;
344 	n.af = af;
345 	n.raddr = *addr;
346 	return (RB_FIND(nbr_addr_head, &nbrs_by_addr, &n));
347 }
348 
349 struct nbr *
nbr_find_peerid(uint32_t peerid)350 nbr_find_peerid(uint32_t peerid)
351 {
352 	struct nbr	n;
353 	n.peerid = peerid;
354 	return (RB_FIND(nbr_pid_head, &nbrs_by_pid, &n));
355 }
356 
357 int
nbr_adj_count(struct nbr * nbr,int af)358 nbr_adj_count(struct nbr *nbr, int af)
359 {
360 	struct adj	*adj;
361 	int		 total = 0;
362 
363 	LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
364 		if (adj_get_af(adj) == af)
365 			total++;
366 
367 	return (total);
368 }
369 
370 int
nbr_session_active_role(struct nbr * nbr)371 nbr_session_active_role(struct nbr *nbr)
372 {
373 	if (ldp_addrcmp(nbr->af, &nbr->laddr, &nbr->raddr) > 0)
374 		return (1);
375 
376 	return (0);
377 }
378 
379 /* timers */
380 
381 /* Keepalive timer: timer to send keepalive message to neighbors */
382 
383 static void
nbr_ktimer(int fd,short event,void * arg)384 nbr_ktimer(int fd, short event, void *arg)
385 {
386 	struct nbr	*nbr = arg;
387 
388 	send_keepalive(nbr);
389 	nbr_start_ktimer(nbr);
390 }
391 
392 static void
nbr_start_ktimer(struct nbr * nbr)393 nbr_start_ktimer(struct nbr *nbr)
394 {
395 	struct timeval	 tv;
396 
397 	/* send three keepalives per period */
398 	timerclear(&tv);
399 	tv.tv_sec = (time_t)(nbr->keepalive / KEEPALIVE_PER_PERIOD);
400 	if (evtimer_add(&nbr->keepalive_timer, &tv) == -1)
401 		fatal(__func__);
402 }
403 
404 void
nbr_stop_ktimer(struct nbr * nbr)405 nbr_stop_ktimer(struct nbr *nbr)
406 {
407 	if (evtimer_pending(&nbr->keepalive_timer, NULL) &&
408 	    evtimer_del(&nbr->keepalive_timer) == -1)
409 		fatal(__func__);
410 }
411 
412 /* Keepalive timeout: if the nbr hasn't sent keepalive */
413 
414 static void
nbr_ktimeout(int fd,short event,void * arg)415 nbr_ktimeout(int fd, short event, void *arg)
416 {
417 	struct nbr *nbr = arg;
418 
419 	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
420 
421 	session_shutdown(nbr, S_KEEPALIVE_TMR, 0, 0);
422 }
423 
424 static void
nbr_start_ktimeout(struct nbr * nbr)425 nbr_start_ktimeout(struct nbr *nbr)
426 {
427 	struct timeval	tv;
428 
429 	timerclear(&tv);
430 	tv.tv_sec = nbr->keepalive;
431 
432 	if (evtimer_add(&nbr->keepalive_timeout, &tv) == -1)
433 		fatal(__func__);
434 }
435 
436 void
nbr_stop_ktimeout(struct nbr * nbr)437 nbr_stop_ktimeout(struct nbr *nbr)
438 {
439 	if (evtimer_pending(&nbr->keepalive_timeout, NULL) &&
440 	    evtimer_del(&nbr->keepalive_timeout) == -1)
441 		fatal(__func__);
442 }
443 
444 /* Session initialization timeout: if nbr got stuck in the initialization FSM */
445 
446 static void
nbr_itimeout(int fd,short event,void * arg)447 nbr_itimeout(int fd, short event, void *arg)
448 {
449 	struct nbr *nbr = arg;
450 
451 	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
452 
453 	nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
454 }
455 
456 static void
nbr_start_itimeout(struct nbr * nbr)457 nbr_start_itimeout(struct nbr *nbr)
458 {
459 	struct timeval	 tv;
460 
461 	timerclear(&tv);
462 	tv.tv_sec = INIT_FSM_TIMEOUT;
463 	if (evtimer_add(&nbr->init_timeout, &tv) == -1)
464 		fatal(__func__);
465 }
466 
467 void
nbr_stop_itimeout(struct nbr * nbr)468 nbr_stop_itimeout(struct nbr *nbr)
469 {
470 	if (evtimer_pending(&nbr->init_timeout, NULL) &&
471 	    evtimer_del(&nbr->init_timeout) == -1)
472 		fatal(__func__);
473 }
474 
475 /* Init delay timer: timer to retry to iniziatize session */
476 
477 static void
nbr_idtimer(int fd,short event,void * arg)478 nbr_idtimer(int fd, short event, void *arg)
479 {
480 	struct nbr *nbr = arg;
481 
482 	log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
483 
484 	nbr_establish_connection(nbr);
485 }
486 
487 void
nbr_start_idtimer(struct nbr * nbr)488 nbr_start_idtimer(struct nbr *nbr)
489 {
490 	struct timeval	tv;
491 
492 	timerclear(&tv);
493 
494 	tv.tv_sec = INIT_DELAY_TMR;
495 	switch(nbr->idtimer_cnt) {
496 	default:
497 		/* do not further increase the counter */
498 		tv.tv_sec = MAX_DELAY_TMR;
499 		break;
500 	case 2:
501 		tv.tv_sec *= 2;
502 		/* FALLTHROUGH */
503 	case 1:
504 		tv.tv_sec *= 2;
505 		/* FALLTHROUGH */
506 	case 0:
507 		nbr->idtimer_cnt++;
508 		break;
509 	}
510 
511 	if (evtimer_add(&nbr->initdelay_timer, &tv) == -1)
512 		fatal(__func__);
513 }
514 
515 void
nbr_stop_idtimer(struct nbr * nbr)516 nbr_stop_idtimer(struct nbr *nbr)
517 {
518 	if (evtimer_pending(&nbr->initdelay_timer, NULL) &&
519 	    evtimer_del(&nbr->initdelay_timer) == -1)
520 		fatal(__func__);
521 }
522 
523 int
nbr_pending_idtimer(struct nbr * nbr)524 nbr_pending_idtimer(struct nbr *nbr)
525 {
526 	if (evtimer_pending(&nbr->initdelay_timer, NULL))
527 		return (1);
528 
529 	return (0);
530 }
531 
532 int
nbr_pending_connect(struct nbr * nbr)533 nbr_pending_connect(struct nbr *nbr)
534 {
535 	if (event_initialized(&nbr->ev_connect) &&
536 	    event_pending(&nbr->ev_connect, EV_WRITE, NULL))
537 		return (1);
538 
539 	return (0);
540 }
541 
542 static void
nbr_connect_cb(int fd,short event,void * arg)543 nbr_connect_cb(int fd, short event, void *arg)
544 {
545 	struct nbr	*nbr = arg;
546 	int		 error;
547 	socklen_t	 len;
548 
549 	len = sizeof(error);
550 	if (getsockopt(nbr->fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
551 		log_warn("%s: getsockopt SOL_SOCKET SO_ERROR", __func__);
552 		return;
553 	}
554 
555 	if (error) {
556 		close(nbr->fd);
557 		errno = error;
558 		log_debug("%s: error while connecting to %s: %s", __func__,
559 		    log_addr(nbr->af, &nbr->raddr), strerror(errno));
560 		return;
561 	}
562 
563 	nbr_fsm(nbr, NBR_EVT_CONNECT_UP);
564 }
565 
566 int
nbr_establish_connection(struct nbr * nbr)567 nbr_establish_connection(struct nbr *nbr)
568 {
569 	struct sockaddr_storage	 local_sa;
570 	struct sockaddr_storage	 remote_sa;
571 	struct adj		*adj;
572 	struct nbr_params	*nbrp;
573 	int			 opt = 1;
574 
575 	nbr->fd = socket(nbr->af,
576 	    SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
577 	if (nbr->fd == -1) {
578 		log_warn("%s: error while creating socket", __func__);
579 		return (-1);
580 	}
581 
582 	if (nbr->auth_established) {
583 		if (sysdep.no_pfkey || sysdep.no_md5sig) {
584 			log_warnx("md5sig configured but not available");
585 			close(nbr->fd);
586 			return (-1);
587 		}
588 		if (setsockopt(nbr->fd, IPPROTO_TCP, TCP_MD5SIG,
589 		    &opt, sizeof(opt)) == -1) {
590 			log_warn("setsockopt md5sig");
591 			close(nbr->fd);
592 			return (-1);
593 		}
594 	}
595 
596 	memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa));
597 	memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT),
598 	    sizeof(local_sa));
599 	if (nbr->af == AF_INET6 && nbr->raddr_scope)
600 		addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope);
601 
602 	if (bind(nbr->fd, (struct sockaddr *)&local_sa,
603 	    local_sa.ss_len) == -1) {
604 		log_warn("%s: error while binding socket to %s", __func__,
605 		    log_sockaddr((struct sockaddr *)&local_sa));
606 		close(nbr->fd);
607 		return (-1);
608 	}
609 
610 	nbrp = nbr_params_find(leconf, nbr->id);
611 	if (nbr_gtsm_check(nbr->fd, nbr, nbrp)) {
612 		close(nbr->fd);
613 		return (-1);
614 	}
615 
616 	/*
617 	 * Send an extra hello to guarantee that the remote peer has formed
618 	 * an adjacency as well.
619 	 */
620 	LIST_FOREACH(adj, &nbr->adj_list, nbr_entry)
621 		send_hello(adj->source.type, adj->source.link.ia,
622 		    adj->source.target);
623 
624 	if (connect(nbr->fd, (struct sockaddr *)&remote_sa,
625 	    remote_sa.ss_len) == -1) {
626 		if (errno == EINPROGRESS) {
627 			event_set(&nbr->ev_connect, nbr->fd, EV_WRITE,
628 			    nbr_connect_cb, nbr);
629 			event_add(&nbr->ev_connect, NULL);
630 			return (0);
631 		}
632 		log_warn("%s: error while connecting to %s", __func__,
633 		    log_sockaddr((struct sockaddr *)&remote_sa));
634 		close(nbr->fd);
635 		return (-1);
636 	}
637 
638 	/* connection completed immediately */
639 	nbr_fsm(nbr, NBR_EVT_CONNECT_UP);
640 
641 	return (0);
642 }
643 
644 int
nbr_gtsm_enabled(struct nbr * nbr,struct nbr_params * nbrp)645 nbr_gtsm_enabled(struct nbr *nbr, struct nbr_params *nbrp)
646 {
647 	/*
648 	 * RFC 6720 - Section 3:
649 	 * "This document allows for the implementation to provide an option to
650 	 * statically (e.g., via configuration) and/or dynamically override the
651 	 * default behavior and enable/disable GTSM on a per-peer basis".
652 	 */
653 	if (nbrp && (nbrp->flags & F_NBRP_GTSM))
654 		return (nbrp->gtsm_enabled);
655 
656 	if ((ldp_af_conf_get(leconf, nbr->af))->flags & F_LDPD_AF_NO_GTSM)
657 		return (0);
658 
659 	/* By default, GTSM support has to be negotiated for LDPv4 */
660 	if (nbr->af == AF_INET && !(nbr->flags & F_NBR_GTSM_NEGOTIATED))
661 		return (0);
662 
663 	return (1);
664 }
665 
666 int
nbr_gtsm_setup(int fd,int af,struct nbr_params * nbrp)667 nbr_gtsm_setup(int fd, int af, struct nbr_params *nbrp)
668 {
669 	int	 ttl = 255;
670 
671 	if (nbrp && (nbrp->flags & F_NBRP_GTSM_HOPS))
672 		ttl = 256 - nbrp->gtsm_hops;
673 
674 	switch (af) {
675 	case AF_INET:
676 		if (sock_set_ipv4_minttl(fd, ttl) == -1)
677 			return (-1);
678 		ttl = 255;
679 		if (sock_set_ipv4_ucast_ttl(fd, ttl) == -1)
680 			return (-1);
681 		break;
682 	case AF_INET6:
683 		if (sock_set_ipv6_minhopcount(fd, ttl) == -1)
684 			return (-1);
685 		ttl = 255;
686 		if (sock_set_ipv6_ucast_hops(fd, ttl) == -1)
687 			return (-1);
688 		break;
689 	default:
690 		fatalx("nbr_gtsm_setup: unknown af");
691 	}
692 
693 	return (0);
694 }
695 
696 int
nbr_gtsm_check(int fd,struct nbr * nbr,struct nbr_params * nbrp)697 nbr_gtsm_check(int fd, struct nbr *nbr, struct nbr_params *nbrp)
698 {
699 	if (!nbr_gtsm_enabled(nbr, nbrp)) {
700 		switch (nbr->af) {
701 		case AF_INET:
702 			sock_set_ipv4_ucast_ttl(fd, -1);
703 			break;
704 		case AF_INET6:
705 			/*
706 			 * Send packets with a Hop Limit of 255 even when GSTM
707 			 * is disabled to guarantee interoperability.
708 			 */
709 			sock_set_ipv6_ucast_hops(fd, 255);
710 			break;
711 		default:
712 			fatalx("nbr_gtsm_check: unknown af");
713 			break;
714 		}
715 		return (0);
716 	}
717 
718 	if (nbr_gtsm_setup(fd, nbr->af, nbrp) == -1) {
719 		log_warnx("%s: error enabling GTSM for lsr-id %s", __func__,
720 		    inet_ntoa(nbr->id));
721 		return (-1);
722 	}
723 
724 	return (0);
725 }
726 
727 static int
nbr_act_session_operational(struct nbr * nbr)728 nbr_act_session_operational(struct nbr *nbr)
729 {
730 	struct lde_nbr	 lde_nbr;
731 
732 	nbr->idtimer_cnt = 0;
733 
734 	/* this is necessary to avoid ipc synchronization issues */
735 	nbr_update_peerid(nbr);
736 
737 	memset(&lde_nbr, 0, sizeof(lde_nbr));
738 	lde_nbr.id = nbr->id;
739 	lde_nbr.v4_enabled = nbr->v4_enabled;
740 	lde_nbr.v6_enabled = nbr->v6_enabled;
741 	lde_nbr.flags = nbr->flags;
742 	return (ldpe_imsg_compose_lde(IMSG_NEIGHBOR_UP, nbr->peerid, 0,
743 	    &lde_nbr, sizeof(lde_nbr)));
744 }
745 
746 static void
nbr_send_labelmappings(struct nbr * nbr)747 nbr_send_labelmappings(struct nbr *nbr)
748 {
749 	ldpe_imsg_compose_lde(IMSG_LABEL_MAPPING_FULL, nbr->peerid, 0,
750 	    NULL, 0);
751 }
752 
753 struct nbr_params *
nbr_params_new(struct in_addr lsr_id)754 nbr_params_new(struct in_addr lsr_id)
755 {
756 	struct nbr_params	*nbrp;
757 
758 	if ((nbrp = calloc(1, sizeof(*nbrp))) == NULL)
759 		fatal(__func__);
760 
761 	nbrp->lsr_id = lsr_id;
762 
763 	return (nbrp);
764 }
765 
766 struct nbr_params *
nbr_params_find(struct ldpd_conf * xconf,struct in_addr lsr_id)767 nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
768 {
769 	struct nbr_params *nbrp;
770 
771 	LIST_FOREACH(nbrp, &xconf->nbrp_list, entry)
772 		if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
773 			return (nbrp);
774 
775 	return (NULL);
776 }
777 
778 uint16_t
nbr_get_keepalive(int af,struct in_addr lsr_id)779 nbr_get_keepalive(int af, struct in_addr lsr_id)
780 {
781 	struct nbr_params	*nbrp;
782 
783 	nbrp = nbr_params_find(leconf, lsr_id);
784 	if (nbrp && (nbrp->flags & F_NBRP_KEEPALIVE))
785 		return (nbrp->keepalive);
786 
787 	return ((ldp_af_conf_get(leconf, af))->keepalive);
788 }
789 
790 struct ctl_nbr *
nbr_to_ctl(struct nbr * nbr)791 nbr_to_ctl(struct nbr *nbr)
792 {
793 	static struct ctl_nbr	 nctl;
794 	struct timeval		 now;
795 
796 	nctl.af = nbr->af;
797 	nctl.id = nbr->id;
798 	nctl.laddr = nbr->laddr;
799 	nctl.raddr = nbr->raddr;
800 	nctl.nbr_state = nbr->state;
801 
802 	gettimeofday(&now, NULL);
803 	if (nbr->state == NBR_STA_OPER) {
804 		nctl.uptime = now.tv_sec - nbr->uptime;
805 	} else
806 		nctl.uptime = 0;
807 
808 	return (&nctl);
809 }
810 
811 void
nbr_clear_ctl(struct ctl_nbr * nctl)812 nbr_clear_ctl(struct ctl_nbr *nctl)
813 {
814 	struct nbr		*nbr;
815 
816 	RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) {
817 		if (ldp_addrisset(nctl->af, &nctl->raddr) &&
818 		    ldp_addrcmp(nctl->af, &nctl->raddr, &nbr->raddr))
819 			continue;
820 
821 		log_debug("%s: neighbor %s manually cleared", __func__,
822 		    log_addr(nbr->af, &nbr->raddr));
823 		session_shutdown(nbr, S_SHUTDOWN, 0, 0);
824 	}
825 }
826