xref: /openbsd/usr.sbin/ldpd/hello.c (revision 3cab2bb3)
1 /*	$OpenBSD: hello.c,v 1.58 2019/12/12 00:10:29 yasuoka 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 	source.lsr_id = lsr_id;
233 	if (flags & F_HELLO_TARGETED) {
234 		/*
235 	 	 * RFC 7552 - Section 5.2:
236 		* "The link-local IPv6 addresses MUST NOT be used as the
237 		* targeted LDP Hello packet's source or destination addresses".
238 		*/
239 		if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&src->v6)) {
240 			log_debug("%s: lsr-id %s: targeted hello with "
241 			    "link-local source address", __func__,
242 			    inet_ntoa(lsr_id));
243 			return;
244 		}
245 
246 		tnbr = tnbr_find(leconf, af, src);
247 
248 		/* remove the dynamic tnbr if the 'R' bit was cleared */
249 		if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
250 		    !((flags & F_HELLO_REQ_TARG))) {
251 			tnbr->flags &= ~F_TNBR_DYNAMIC;
252 			tnbr = tnbr_check(tnbr);
253 		}
254 
255 		if (!tnbr) {
256 			if (!((flags & F_HELLO_REQ_TARG) &&
257 			    ((ldp_af_conf_get(leconf, af))->flags &
258 			    F_LDPD_AF_THELLO_ACCEPT)))
259 				return;
260 
261 			tnbr = tnbr_new(leconf, af, src);
262 			tnbr->flags |= F_TNBR_DYNAMIC;
263 			tnbr_update(tnbr);
264 			LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
265 		}
266 
267 		source.type = HELLO_TARGETED;
268 		source.target = tnbr;
269 	} else {
270 		ia = iface_af_get(iface, af);
271 		source.type = HELLO_LINK;
272 		source.link.ia = ia;
273 		source.link.src_addr = *src;
274 	}
275 
276 	adj = adj_find(&source);
277 	nbr = nbr_find_ldpid(lsr_id.s_addr);
278 
279 	/* check dual-stack tlv */
280 	ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
281 	if (ds_tlv && trans_pref != leconf->trans_pref) {
282 		/*
283 	 	 * RFC 7552 - Section 6.1.1:
284 		 * "If the Dual-Stack capability TLV is present and the remote
285 		 * preference does not match the local preference (or does not
286 		 * get recognized), then the LSR MUST discard the Hello message
287 		 * and log an error.
288 		 * If an LDP session was already in place, then the LSR MUST
289 		 * send a fatal Notification message with status code of
290 		 * 'Transport Connection Mismatch' and reset the session".
291 		 */
292 		log_debug("%s: lsr-id %s: remote transport preference does not "
293 		    "match the local preference", __func__, inet_ntoa(lsr_id));
294 		if (nbr)
295 			session_shutdown(nbr, S_TRANS_MISMTCH, msg->id,
296 			    msg->type);
297 		if (adj)
298 			adj_del(adj, S_SHUTDOWN);
299 		return;
300 	}
301 
302 	/*
303 	 * Check for noncompliant dual-stack neighbor according to
304 	 * RFC 7552 section 6.1.1.
305 	 */
306 	if (nbr && !ds_tlv) {
307 		switch (af) {
308 		case AF_INET:
309 			if (nbr_adj_count(nbr, AF_INET6) > 0) {
310 				session_shutdown(nbr, S_DS_NONCMPLNCE,
311 				    msg->id, msg->type);
312 				return;
313 			}
314 			break;
315 		case AF_INET6:
316 			if (nbr_adj_count(nbr, AF_INET) > 0) {
317 				session_shutdown(nbr, S_DS_NONCMPLNCE,
318 				    msg->id, msg->type);
319 				return;
320 			}
321 			break;
322 		default:
323 			fatalx("recv_hello: unknown af");
324 		}
325 	}
326 
327 	/*
328 	 * Protections against misconfigured networks and buggy implementations.
329 	 */
330 	if (nbr && nbr->af == af &&
331 	    (ldp_addrcmp(af, &nbr->raddr, &trans_addr) ||
332 	    nbr->raddr_scope != scope_id)) {
333 		log_warnx("%s: lsr-id %s: hello packet advertising a different "
334 		    "transport address", __func__, inet_ntoa(lsr_id));
335 		if (adj)
336 			adj_del(adj, S_SHUTDOWN);
337 		return;
338 	}
339 	if (nbr == NULL) {
340 		nbrt = nbr_find_addr(af, &trans_addr);
341 		if (nbrt) {
342 			log_debug("%s: transport address %s is already being "
343 			    "used by lsr-id %s", __func__, log_addr(af,
344 			    &trans_addr), inet_ntoa(nbrt->id));
345 			if (adj)
346 				adj_del(adj, S_SHUTDOWN);
347 			return;
348 		}
349 	}
350 
351 	if (adj == NULL) {
352 		adj = adj_new(lsr_id, &source, &trans_addr);
353 		if (nbr) {
354 			adj->nbr = nbr;
355 			LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry);
356 		}
357 	}
358 
359 	/*
360 	 * If the hello adjacency's address-family doesn't match the local
361 	 * preference, then an adjacency is still created but we don't attempt
362 	 * to start an LDP session.
363 	 */
364 	if (nbr == NULL && (!ds_tlv ||
365 	    ((trans_pref == DUAL_STACK_LDPOV4 && af == AF_INET) ||
366 	    (trans_pref == DUAL_STACK_LDPOV6 && af == AF_INET6))))
367 		nbr = nbr_new(lsr_id, af, ds_tlv, &trans_addr, scope_id);
368 
369 	/* dynamic LDPv4 GTSM negotiation as per RFC 6720 */
370 	if (nbr) {
371 		if (flags & F_HELLO_GTSM)
372 			nbr->flags |= F_NBR_GTSM_NEGOTIATED;
373 		else
374 			nbr->flags &= ~F_NBR_GTSM_NEGOTIATED;
375 	}
376 
377 	/* update neighbor's configuration sequence number */
378 	if (nbr && (tlvs_rcvd & F_HELLO_TLV_RCVD_CONF)) {
379 		if (conf_seqnum > nbr->conf_seqnum &&
380 		    nbr_pending_idtimer(nbr))
381 			nbr_stop_idtimer(nbr);
382 		nbr->conf_seqnum = conf_seqnum;
383 	}
384 
385 	/* always update the holdtime to properly handle runtime changes */
386 	switch (source.type) {
387 	case HELLO_LINK:
388 		if (holdtime == 0)
389 			holdtime = LINK_DFLT_HOLDTIME;
390 
391 		adj->holdtime = min(ia->hello_holdtime, holdtime);
392 		break;
393 	case HELLO_TARGETED:
394 		if (holdtime == 0)
395 			holdtime = TARGETED_DFLT_HOLDTIME;
396 
397 		adj->holdtime = min(tnbr->hello_holdtime, holdtime);
398 	}
399 	if (adj->holdtime != INFINITE_HOLDTIME)
400 		adj_start_itimer(adj);
401 	else
402 		adj_stop_itimer(adj);
403 
404 	if (nbr && nbr->state == NBR_STA_PRESENT && !nbr_pending_idtimer(nbr) &&
405 	    nbr_session_active_role(nbr) && !nbr_pending_connect(nbr))
406 		nbr_establish_connection(nbr);
407 }
408 
409 static int
410 gen_hello_prms_tlv(struct ibuf *buf, uint16_t holdtime, uint16_t flags)
411 {
412 	struct hello_prms_tlv	parms;
413 
414 	memset(&parms, 0, sizeof(parms));
415 	parms.type = htons(TLV_TYPE_COMMONHELLO);
416 	parms.length = htons(sizeof(parms.holdtime) + sizeof(parms.flags));
417 	parms.holdtime = htons(holdtime);
418 	parms.flags = htons(flags);
419 
420 	return (ibuf_add(buf, &parms, sizeof(parms)));
421 }
422 
423 static int
424 gen_opt4_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint32_t value)
425 {
426 	struct hello_prms_opt4_tlv	parms;
427 
428 	memset(&parms, 0, sizeof(parms));
429 	parms.type = htons(type);
430 	parms.length = htons(sizeof(parms.value));
431 	parms.value = value;
432 
433 	return (ibuf_add(buf, &parms, sizeof(parms)));
434 }
435 
436 static int
437 gen_opt16_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint8_t *value)
438 {
439 	struct hello_prms_opt16_tlv	parms;
440 
441 	memset(&parms, 0, sizeof(parms));
442 	parms.type = htons(type);
443 	parms.length = htons(sizeof(parms.value));
444 	memcpy(&parms.value, value, sizeof(parms.value));
445 
446 	return (ibuf_add(buf, &parms, sizeof(parms)));
447 }
448 
449 static int
450 gen_ds_hello_prms_tlv(struct ibuf *buf, uint32_t value)
451 {
452 	if (leconf->flags & F_LDPD_DS_CISCO_INTEROP)
453 		value = htonl(value);
454 	else
455 		value = htonl(value << 28);
456 
457 	return (gen_opt4_hello_prms_tlv(buf, TLV_TYPE_DUALSTACK, value));
458 }
459 
460 static int
461 tlv_decode_hello_prms(char *buf, uint16_t len, uint16_t *holdtime,
462     uint16_t *flags)
463 {
464 	struct hello_prms_tlv	tlv;
465 
466 	if (len < sizeof(tlv))
467 		return (-1);
468 	memcpy(&tlv, buf, sizeof(tlv));
469 
470 	if (tlv.type != htons(TLV_TYPE_COMMONHELLO))
471 		return (-1);
472 	if (ntohs(tlv.length) != sizeof(tlv) - TLV_HDR_SIZE)
473 		return (-1);
474 
475 	*holdtime = ntohs(tlv.holdtime);
476 	*flags = ntohs(tlv.flags);
477 
478 	return (sizeof(tlv));
479 }
480 
481 static int
482 tlv_decode_opt_hello_prms(char *buf, uint16_t len, int *tlvs_rcvd, int af,
483     union ldpd_addr *addr, uint32_t *conf_number, uint16_t *trans_pref)
484 {
485 	struct tlv	tlv;
486 	uint16_t	tlv_len;
487 	int		total = 0;
488 
489 	*tlvs_rcvd = 0;
490 	memset(addr, 0, sizeof(*addr));
491 	*conf_number = 0;
492 	*trans_pref = 0;
493 
494 	/*
495 	 * RFC 7552 - Section 6.1:
496 	 * "An LSR SHOULD accept the Hello message that contains both IPv4 and
497 	 * IPv6 Transport Address optional objects but MUST use only the
498 	 * transport address whose address family is the same as that of the
499 	 * IP packet carrying the Hello message.  An LSR SHOULD accept only
500 	 * the first Transport Address optional object for a given address
501 	 * family in the received Hello message and ignore the rest if the
502 	 * LSR receives more than one Transport Address optional object for a
503 	 * given address family".
504 	 */
505 	while (len >= sizeof(tlv)) {
506 		memcpy(&tlv, buf, TLV_HDR_SIZE);
507 		tlv_len = ntohs(tlv.length);
508 		if (tlv_len + TLV_HDR_SIZE > len)
509 			return (-1);
510 		buf += TLV_HDR_SIZE;
511 		len -= TLV_HDR_SIZE;
512 		total += TLV_HDR_SIZE;
513 
514 		switch (ntohs(tlv.type)) {
515 		case TLV_TYPE_IPV4TRANSADDR:
516 			if (tlv_len != sizeof(addr->v4))
517 				return (-1);
518 			if (af != AF_INET)
519 				return (-1);
520 			if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
521 				break;
522 			memcpy(&addr->v4, buf, sizeof(addr->v4));
523 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
524 			break;
525 		case TLV_TYPE_IPV6TRANSADDR:
526 			if (tlv_len != sizeof(addr->v6))
527 				return (-1);
528 			if (af != AF_INET6)
529 				return (-1);
530 			if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
531 				break;
532 			memcpy(&addr->v6, buf, sizeof(addr->v6));
533 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
534 			break;
535 		case TLV_TYPE_CONFIG:
536 			if (tlv_len != sizeof(uint32_t))
537 				return (-1);
538 			memcpy(conf_number, buf, sizeof(uint32_t));
539 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_CONF;
540 			break;
541 		case TLV_TYPE_DUALSTACK:
542 			if (tlv_len != sizeof(uint32_t))
543 				return (-1);
544    			/*
545 	 		 * RFC 7552 - Section 6.1:
546 			 * "A Single-stack LSR does not need to use the
547 			 * Dual-Stack capability in Hello messages and SHOULD
548 			 * ignore this capability if received".
549 			 */
550 			if (!ldp_is_dual_stack(leconf))
551 				break;
552 			/* Shame on you, Cisco! */
553 			if (leconf->flags & F_LDPD_DS_CISCO_INTEROP) {
554 				memcpy(trans_pref, buf + sizeof(uint16_t),
555 				    sizeof(uint16_t));
556 				*trans_pref = ntohs(*trans_pref);
557 			} else {
558 				memcpy(trans_pref, buf , sizeof(uint16_t));
559 				*trans_pref = ntohs(*trans_pref) >> 12;
560 			}
561 			*tlvs_rcvd |= F_HELLO_TLV_RCVD_DS;
562 			break;
563 		default:
564 			/* if unknown flag set, ignore TLV */
565 			if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
566 				return (-1);
567 			break;
568 		}
569 		buf += tlv_len;
570 		len -= tlv_len;
571 		total += tlv_len;
572 	}
573 
574 	return (total);
575 }
576