1 /* $OpenBSD: hello.c,v 1.59 2023/07/03 11:51:27 claudio 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
send_hello(enum hello_type type,struct iface_af * ia,struct tnbr * tnbr)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, ibuf_data(buf), ibuf_size(buf));
143 ibuf_free(buf);
144
145 return (0);
146 }
147
148 void
recv_hello(struct in_addr lsr_id,struct ldp_msg * msg,int af,union ldpd_addr * src,struct iface * iface,int multicast,char * buf,uint16_t len)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
gen_hello_prms_tlv(struct ibuf * buf,uint16_t holdtime,uint16_t flags)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
gen_opt4_hello_prms_tlv(struct ibuf * buf,uint16_t type,uint32_t value)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
gen_opt16_hello_prms_tlv(struct ibuf * buf,uint16_t type,uint8_t * value)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
gen_ds_hello_prms_tlv(struct ibuf * buf,uint32_t value)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
tlv_decode_hello_prms(char * buf,uint16_t len,uint16_t * holdtime,uint16_t * flags)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
tlv_decode_opt_hello_prms(char * buf,uint16_t len,int * tlvs_rcvd,int af,union ldpd_addr * addr,uint32_t * conf_number,uint16_t * trans_pref)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