GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ldpd/hello.c Lines: 0 281 0.0 %
Date: 2017-11-07 Branches: 0 213 0.0 %

Line Branch Exec Source
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
}