xref: /openbsd-src/usr.sbin/ldpd/hello.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: hello.c,v 1.57 2016/07/16 19:20:16 renato Exp $ */
2 
3 /*
4  * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5  * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <arpa/inet.h>
22 #include <string.h>
23 
24 #include "ldpd.h"
25 #include "ldpe.h"
26 #include "log.h"
27 
28 static int	gen_hello_prms_tlv(struct ibuf *buf, uint16_t, uint16_t);
29 static int	gen_opt4_hello_prms_tlv(struct ibuf *, uint16_t, uint32_t);
30 static int	gen_opt16_hello_prms_tlv(struct ibuf *, uint16_t, uint8_t *);
31 static int	gen_ds_hello_prms_tlv(struct ibuf *, uint32_t);
32 static int	tlv_decode_hello_prms(char *, uint16_t, uint16_t *, uint16_t *);
33 static int	tlv_decode_opt_hello_prms(char *, uint16_t, int *, int,
34 		    union ldpd_addr *, uint32_t *, uint16_t *);
35 
36 int
37 send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
38 {
39 	int			 af;
40 	union ldpd_addr		 dst;
41 	uint16_t		 size, holdtime = 0, flags = 0;
42 	int			 fd = 0;
43 	struct ibuf		*buf;
44 	int			 err = 0;
45 
46 	switch (type) {
47 	case HELLO_LINK:
48 		af = ia->af;
49 		holdtime = ia->hello_holdtime;
50 		flags = 0;
51 		fd = (ldp_af_global_get(&global, af))->ldp_disc_socket;
52 
53 		/* multicast destination address */
54 		switch (af) {
55 		case AF_INET:
56 			if (!(leconf->ipv4.flags & F_LDPD_AF_NO_GTSM))
57 				flags |= F_HELLO_GTSM;
58 			dst.v4 = global.mcast_addr_v4;
59 			break;
60 		case AF_INET6:
61 			dst.v6 = global.mcast_addr_v6;
62 			break;
63 		default:
64 			fatalx("send_hello: unknown af");
65 		}
66 		break;
67 	case HELLO_TARGETED:
68 		af = tnbr->af;
69 		holdtime = tnbr->hello_holdtime;
70 		flags = F_HELLO_TARGETED;
71 		if ((tnbr->flags & F_TNBR_CONFIGURED) || tnbr->pw_count)
72 			flags |= F_HELLO_REQ_TARG;
73 		fd = (ldp_af_global_get(&global, af))->ldp_edisc_socket;
74 
75 		/* unicast destination address */
76 		dst = tnbr->addr;
77 		break;
78 	default:
79 		fatalx("send_hello: unknown hello type");
80 	}
81 
82 	/* calculate message size */
83 	size = LDP_HDR_SIZE + LDP_MSG_SIZE + sizeof(struct hello_prms_tlv);
84 	switch (af) {
85 	case AF_INET:
86 		size += sizeof(struct hello_prms_opt4_tlv);
87 		break;
88 	case AF_INET6:
89 		size += sizeof(struct hello_prms_opt16_tlv);
90 		break;
91 	default:
92 		fatalx("send_hello: unknown af");
93 	}
94 	size += sizeof(struct hello_prms_opt4_tlv);
95 	if (ldp_is_dual_stack(leconf))
96 		size += sizeof(struct hello_prms_opt4_tlv);
97 
98 	/* generate message */
99 	if ((buf = ibuf_open(size)) == NULL)
100 		fatal(__func__);
101 
102 	err |= gen_ldp_hdr(buf, size);
103 	size -= LDP_HDR_SIZE;
104 	err |= gen_msg_hdr(buf, MSG_TYPE_HELLO, size);
105 	err |= gen_hello_prms_tlv(buf, holdtime, flags);
106 
107 	/*
108 	 * RFC 7552 - Section 6.1:
109 	 * "An LSR MUST include only the transport address whose address
110 	 * family is the same as that of the IP packet carrying the Hello
111 	 * message".
112 	 */
113 	switch (af) {
114 	case AF_INET:
115 		err |= gen_opt4_hello_prms_tlv(buf, TLV_TYPE_IPV4TRANSADDR,
116 		    leconf->ipv4.trans_addr.v4.s_addr);
117 		break;
118 	case AF_INET6:
119 		err |= gen_opt16_hello_prms_tlv(buf, TLV_TYPE_IPV6TRANSADDR,
120 		    leconf->ipv6.trans_addr.v6.s6_addr);
121 		break;
122 	default:
123 		fatalx("send_hello: unknown af");
124 	}
125 
126 	err |= gen_opt4_hello_prms_tlv(buf, TLV_TYPE_CONFIG,
127 	    htonl(global.conf_seqnum));
128 
129    	/*
130 	 * RFC 7552 - Section 6.1.1:
131 	 * "A Dual-stack LSR (i.e., an LSR supporting Dual-stack LDP for a peer)
132 	 * MUST include the Dual-Stack capability TLV in all of its LDP Hellos".
133 	 */
134 	if (ldp_is_dual_stack(leconf))
135 		err |= gen_ds_hello_prms_tlv(buf, leconf->trans_pref);
136 
137 	if (err) {
138 		ibuf_free(buf);
139 		return (-1);
140 	}
141 
142 	send_packet(fd, af, &dst, ia, buf->buf, buf->wpos);
143 	ibuf_free(buf);
144 
145 	return (0);
146 }
147 
148 void
149 recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
150     union ldpd_addr *src, struct iface *iface, int multicast, char *buf,
151     uint16_t len)
152 {
153 	struct adj		*adj = NULL;
154 	struct nbr		*nbr, *nbrt;
155 	uint16_t		 holdtime, flags;
156 	int			 tlvs_rcvd;
157 	int			 ds_tlv;
158 	union ldpd_addr		 trans_addr;
159 	uint32_t		 scope_id = 0;
160 	uint32_t		 conf_seqnum;
161 	uint16_t		 trans_pref;
162 	int			 r;
163 	struct hello_source	 source;
164 	struct iface_af		*ia = NULL;
165 	struct tnbr		*tnbr = NULL;
166 
167 	r = tlv_decode_hello_prms(buf, len, &holdtime, &flags);
168 	if (r == -1) {
169 		log_debug("%s: lsr-id %s: failed to decode params", __func__,
170 		    inet_ntoa(lsr_id));
171 		return;
172 	}
173 	/* safety checks */
174 	if (holdtime != 0 && holdtime < MIN_HOLDTIME) {
175 		log_debug("%s: lsr-id %s: invalid hello holdtime (%u)",
176 		    __func__, inet_ntoa(lsr_id), holdtime);
177 		return;
178 	}
179 	if (multicast && (flags & F_HELLO_TARGETED)) {
180 		log_debug("%s: lsr-id %s: multicast targeted hello", __func__,
181 		    inet_ntoa(lsr_id));
182 		return;
183 	}
184 	if (!multicast && !((flags & F_HELLO_TARGETED))) {
185 		log_debug("%s: lsr-id %s: unicast link hello", __func__,
186 		    inet_ntoa(lsr_id));
187 		return;
188 	}
189 	buf += r;
190 	len -= r;
191 
192 	r = tlv_decode_opt_hello_prms(buf, len, &tlvs_rcvd, af, &trans_addr,
193 	    &conf_seqnum, &trans_pref);
194 	if (r == -1) {
195 		log_debug("%s: lsr-id %s: failed to decode optional params",
196 		    __func__, inet_ntoa(lsr_id));
197 		return;
198 	}
199 	if (r != len) {
200 		log_debug("%s: lsr-id %s: unexpected data in message",
201 		    __func__, inet_ntoa(lsr_id));
202 		return;
203 	}
204 
205 	/* implicit transport address */
206 	if (!(tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR))
207 		trans_addr = *src;
208 	if (bad_addr(af, &trans_addr)) {
209 		log_debug("%s: lsr-id %s: invalid transport address %s",
210 		    __func__, inet_ntoa(lsr_id), log_addr(af, &trans_addr));
211 		return;
212 	}
213 	if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&trans_addr.v6)) {
214 		/*
215 	 	 * RFC 7552 - Section 6.1:
216 		 * "An LSR MUST use a global unicast IPv6 address in an IPv6
217 		 * Transport Address optional object of outgoing targeted
218 		 * Hellos and check for the same in incoming targeted Hellos
219 		 * (i.e., MUST discard the targeted Hello if it failed the
220 		 * check)".
221 		 */
222 		if (flags & F_HELLO_TARGETED) {
223 			log_debug("%s: lsr-id %s: invalid targeted hello "
224 			    "transport address %s", __func__, inet_ntoa(lsr_id),
225 			     log_addr(af, &trans_addr));
226 			return;
227 		}
228 		scope_id = iface->ifindex;
229 	}
230 
231 	memset(&source, 0, sizeof(source));
232 	if (flags & F_HELLO_TARGETED) {
233 		/*
234 	 	 * RFC 7552 - Section 5.2:
235 		* "The link-local IPv6 addresses MUST NOT be used as the
236 		* targeted LDP Hello packet's source or destination addresses".
237 		*/
238 		if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&src->v6)) {
239 			log_debug("%s: lsr-id %s: targeted hello with "
240 			    "link-local source address", __func__,
241 			    inet_ntoa(lsr_id));
242 			return;
243 		}
244 
245 		tnbr = tnbr_find(leconf, af, src);
246 
247 		/* remove the dynamic tnbr if the 'R' bit was cleared */
248 		if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
249 		    !((flags & F_HELLO_REQ_TARG))) {
250 			tnbr->flags &= ~F_TNBR_DYNAMIC;
251 			tnbr = tnbr_check(tnbr);
252 		}
253 
254 		if (!tnbr) {
255 			if (!((flags & F_HELLO_REQ_TARG) &&
256 			    ((ldp_af_conf_get(leconf, af))->flags &
257 			    F_LDPD_AF_THELLO_ACCEPT)))
258 				return;
259 
260 			tnbr = tnbr_new(leconf, af, src);
261 			tnbr->flags |= F_TNBR_DYNAMIC;
262 			tnbr_update(tnbr);
263 			LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
264 		}
265 
266 		source.type = HELLO_TARGETED;
267 		source.target = tnbr;
268 	} else {
269 		ia = iface_af_get(iface, af);
270 		source.type = HELLO_LINK;
271 		source.link.ia = ia;
272 		source.link.src_addr = *src;
273 	}
274 
275 	adj = adj_find(&source);
276 	nbr = nbr_find_ldpid(lsr_id.s_addr);
277 
278 	/* check dual-stack tlv */
279 	ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
280 	if (ds_tlv && trans_pref != leconf->trans_pref) {
281 		/*
282 	 	 * RFC 7552 - Section 6.1.1:
283 		 * "If the Dual-Stack capability TLV is present and the remote
284 		 * preference does not match the local preference (or does not
285 		 * get recognized), then the LSR MUST discard the Hello message
286 		 * and log an error.
287 		 * If an LDP session was already in place, then the LSR MUST
288 		 * send a fatal Notification message with status code of
289 		 * 'Transport Connection Mismatch' and reset the session".
290 		 */
291 		log_debug("%s: lsr-id %s: remote transport preference does not "
292 		    "match the local preference", __func__, inet_ntoa(lsr_id));
293 		if (nbr)
294 			session_shutdown(nbr, S_TRANS_MISMTCH, msg->id,
295 			    msg->type);
296 		if (adj)
297 			adj_del(adj, S_SHUTDOWN);
298 		return;
299 	}
300 
301 	/*
302 	 * Check for noncompliant dual-stack neighbor according to
303 	 * RFC 7552 section 6.1.1.
304 	 */
305 	if (nbr && !ds_tlv) {
306 		switch (af) {
307 		case AF_INET:
308 			if (nbr_adj_count(nbr, AF_INET6) > 0) {
309 				session_shutdown(nbr, S_DS_NONCMPLNCE,
310 				    msg->id, msg->type);
311 				return;
312 			}
313 			break;
314 		case AF_INET6:
315 			if (nbr_adj_count(nbr, AF_INET) > 0) {
316 				session_shutdown(nbr, S_DS_NONCMPLNCE,
317 				    msg->id, msg->type);
318 				return;
319 			}
320 			break;
321 		default:
322 			fatalx("recv_hello: unknown af");
323 		}
324 	}
325 
326 	/*
327 	 * Protections against misconfigured networks and buggy implementations.
328 	 */
329 	if (nbr && nbr->af == af &&
330 	    (ldp_addrcmp(af, &nbr->raddr, &trans_addr) ||
331 	    nbr->raddr_scope != scope_id)) {
332 		log_warnx("%s: lsr-id %s: hello packet advertising a different "
333 		    "transport address", __func__, inet_ntoa(lsr_id));
334 		if (adj)
335 			adj_del(adj, S_SHUTDOWN);
336 		return;
337 	}
338 	if (nbr == NULL) {
339 		nbrt = nbr_find_addr(af, &trans_addr);
340 		if (nbrt) {
341 			log_debug("%s: transport address %s is already being "
342 			    "used by lsr-id %s", __func__, log_addr(af,
343 			    &trans_addr), inet_ntoa(nbrt->id));
344 			if (adj)
345 				adj_del(adj, S_SHUTDOWN);
346 			return;
347 		}
348 	}
349 
350 	if (adj == NULL) {
351 		adj = adj_new(lsr_id, &source, &trans_addr);
352 		if (nbr) {
353 			adj->nbr = nbr;
354 			LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
355 		}
356 	}
357 
358 	/*
359 	 * If the hello adjacency's address-family doesn't match the local
360 	 * preference, then an adjacency is still created but we don't attempt
361 	 * to start an LDP session.
362 	 */
363 	if (nbr == NULL && (!ds_tlv ||
364 	    ((trans_pref == DUAL_STACK_LDPOV4 && af == AF_INET) ||
365 	    (trans_pref == DUAL_STACK_LDPOV6 && af == AF_INET6))))
366 		nbr = nbr_new(lsr_id, af, ds_tlv, &trans_addr, scope_id);
367 
368 	/* dynamic LDPv4 GTSM negotiation as per RFC 6720 */
369 	if (nbr) {
370 		if (flags & F_HELLO_GTSM)
371 			nbr->flags |= F_NBR_GTSM_NEGOTIATED;
372 		else
373 			nbr->flags &= ~F_NBR_GTSM_NEGOTIATED;
374 	}
375 
376 	/* update neighbor's configuration sequence number */
377 	if (nbr && (tlvs_rcvd & F_HELLO_TLV_RCVD_CONF)) {
378 		if (conf_seqnum > nbr->conf_seqnum &&
379 		    nbr_pending_idtimer(nbr))
380 			nbr_stop_idtimer(nbr);
381 		nbr->conf_seqnum = conf_seqnum;
382 	}
383 
384 	/* always update the holdtime to properly handle runtime changes */
385 	switch (source.type) {
386 	case HELLO_LINK:
387 		if (holdtime == 0)
388 			holdtime = LINK_DFLT_HOLDTIME;
389 
390 		adj->holdtime = min(ia->hello_holdtime, holdtime);
391 		break;
392 	case HELLO_TARGETED:
393 		if (holdtime == 0)
394 			holdtime = TARGETED_DFLT_HOLDTIME;
395 
396 		adj->holdtime = min(tnbr->hello_holdtime, holdtime);
397 	}
398 	if (adj->holdtime != INFINITE_HOLDTIME)
399 		adj_start_itimer(adj);
400 	else
401 		adj_stop_itimer(adj);
402 
403 	if (nbr && nbr->state == NBR_STA_PRESENT && !nbr_pending_idtimer(nbr) &&
404 	    nbr_session_active_role(nbr) && !nbr_pending_connect(nbr))
405 		nbr_establish_connection(nbr);
406 }
407 
408 static int
409 gen_hello_prms_tlv(struct ibuf *buf, uint16_t holdtime, uint16_t flags)
410 {
411 	struct hello_prms_tlv	parms;
412 
413 	memset(&parms, 0, sizeof(parms));
414 	parms.type = htons(TLV_TYPE_COMMONHELLO);
415 	parms.length = htons(sizeof(parms.holdtime) + sizeof(parms.flags));
416 	parms.holdtime = htons(holdtime);
417 	parms.flags = htons(flags);
418 
419 	return (ibuf_add(buf, &parms, sizeof(parms)));
420 }
421 
422 static int
423 gen_opt4_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint32_t value)
424 {
425 	struct hello_prms_opt4_tlv	parms;
426 
427 	memset(&parms, 0, sizeof(parms));
428 	parms.type = htons(type);
429 	parms.length = htons(sizeof(parms.value));
430 	parms.value = value;
431 
432 	return (ibuf_add(buf, &parms, sizeof(parms)));
433 }
434 
435 static int
436 gen_opt16_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint8_t *value)
437 {
438 	struct hello_prms_opt16_tlv	parms;
439 
440 	memset(&parms, 0, sizeof(parms));
441 	parms.type = htons(type);
442 	parms.length = htons(sizeof(parms.value));
443 	memcpy(&parms.value, value, sizeof(parms.value));
444 
445 	return (ibuf_add(buf, &parms, sizeof(parms)));
446 }
447 
448 static int
449 gen_ds_hello_prms_tlv(struct ibuf *buf, uint32_t value)
450 {
451 	if (leconf->flags & F_LDPD_DS_CISCO_INTEROP)
452 		value = htonl(value);
453 	else
454 		value = htonl(value << 28);
455 
456 	return (gen_opt4_hello_prms_tlv(buf, TLV_TYPE_DUALSTACK, value));
457 }
458 
459 static int
460 tlv_decode_hello_prms(char *buf, uint16_t len, uint16_t *holdtime,
461     uint16_t *flags)
462 {
463 	struct hello_prms_tlv	tlv;
464 
465 	if (len < sizeof(tlv))
466 		return (-1);
467 	memcpy(&tlv, buf, sizeof(tlv));
468 
469 	if (tlv.type != htons(TLV_TYPE_COMMONHELLO))
470 		return (-1);
471 	if (ntohs(tlv.length) != sizeof(tlv) - TLV_HDR_SIZE)
472 		return (-1);
473 
474 	*holdtime = ntohs(tlv.holdtime);
475 	*flags = ntohs(tlv.flags);
476 
477 	return (sizeof(tlv));
478 }
479 
480 static int
481 tlv_decode_opt_hello_prms(char *buf, uint16_t len, int *tlvs_rcvd, int af,
482     union ldpd_addr *addr, uint32_t *conf_number, uint16_t *trans_pref)
483 {
484 	struct tlv	tlv;
485 	uint16_t	tlv_len;
486 	int		total = 0;
487 
488 	*tlvs_rcvd = 0;
489 	memset(addr, 0, sizeof(*addr));
490 	*conf_number = 0;
491 	*trans_pref = 0;
492 
493 	/*
494 	 * RFC 7552 - Section 6.1:
495 	 * "An LSR SHOULD accept the Hello message that contains both IPv4 and
496 	 * IPv6 Transport Address optional objects but MUST use only the
497 	 * transport address whose address family is the same as that of the
498 	 * IP packet carrying the Hello message.  An LSR SHOULD accept only
499 	 * the first Transport Address optional object for a given address
500 	 * family in the received Hello message and ignore the rest if the
501 	 * LSR receives more than one Transport Address optional object for a
502 	 * given address family".
503 	 */
504 	while (len >= sizeof(tlv)) {
505 		memcpy(&tlv, buf, TLV_HDR_SIZE);
506 		tlv_len = ntohs(tlv.length);
507 		if (tlv_len + TLV_HDR_SIZE > len)
508 			return (-1);
509 		buf += TLV_HDR_SIZE;
510 		len -= TLV_HDR_SIZE;
511 		total += TLV_HDR_SIZE;
512 
513 		switch (ntohs(tlv.type)) {
514 		case TLV_TYPE_IPV4TRANSADDR:
515 			if (tlv_len != sizeof(addr->v4))
516 				return (-1);
517 			if (af != AF_INET)
518 				return (-1);
519 			if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
520 				break;
521 			memcpy(&addr->v4, buf, sizeof(addr->v4));
522 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
523 			break;
524 		case TLV_TYPE_IPV6TRANSADDR:
525 			if (tlv_len != sizeof(addr->v6))
526 				return (-1);
527 			if (af != AF_INET6)
528 				return (-1);
529 			if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
530 				break;
531 			memcpy(&addr->v6, buf, sizeof(addr->v6));
532 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
533 			break;
534 		case TLV_TYPE_CONFIG:
535 			if (tlv_len != sizeof(uint32_t))
536 				return (-1);
537 			memcpy(conf_number, buf, sizeof(uint32_t));
538 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_CONF;
539 			break;
540 		case TLV_TYPE_DUALSTACK:
541 			if (tlv_len != sizeof(uint32_t))
542 				return (-1);
543    			/*
544 	 		 * RFC 7552 - Section 6.1:
545 			 * "A Single-stack LSR does not need to use the
546 			 * Dual-Stack capability in Hello messages and SHOULD
547 			 * ignore this capability if received".
548 			 */
549 			if (!ldp_is_dual_stack(leconf))
550 				break;
551 			/* Shame on you, Cisco! */
552 			if (leconf->flags & F_LDPD_DS_CISCO_INTEROP) {
553 				memcpy(trans_pref, buf + sizeof(uint16_t),
554 				    sizeof(uint16_t));
555 				*trans_pref = ntohs(*trans_pref);
556 			} else {
557 				memcpy(trans_pref, buf , sizeof(uint16_t));
558 				*trans_pref = ntohs(*trans_pref) >> 12;
559 			}
560 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_DS;
561 			break;
562 		default:
563 			/* if unknown flag set, ignore TLV */
564 			if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
565 				return (-1);
566 			break;
567 		}
568 		buf += tlv_len;
569 		len -= tlv_len;
570 		total += tlv_len;
571 	}
572 
573 	return (total);
574 }
575