1 // SPDX-License-Identifier: ISC
5 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
6 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
14 #include "ldp_debug.h"
16 static int gen_hello_prms_tlv(struct ibuf
*buf
, uint16_t, uint16_t);
17 static int gen_opt4_hello_prms_tlv(struct ibuf
*, uint16_t, uint32_t);
18 static int gen_opt16_hello_prms_tlv(struct ibuf
*, uint16_t, uint8_t *);
19 static int gen_ds_hello_prms_tlv(struct ibuf
*, uint32_t);
20 static int tlv_decode_hello_prms(char *, uint16_t, uint16_t *, uint16_t *);
21 static int tlv_decode_opt_hello_prms(char *, uint16_t, int *, int,
22 union ldpd_addr
*, uint32_t *, uint16_t *);
25 send_hello(enum hello_type type
, struct iface_af
*ia
, struct tnbr
*tnbr
)
29 uint16_t size
, holdtime
= 0, flags
= 0;
37 holdtime
= if_get_hello_holdtime(ia
);
39 fd
= (ldp_af_global_get(&global
, af
))->ldp_disc_socket
;
41 /* multicast destination address */
44 if (!(leconf
->ipv4
.flags
& F_LDPD_AF_NO_GTSM
))
45 flags
|= F_HELLO_GTSM
;
46 dst
.v4
= global
.mcast_addr_v4
;
49 dst
.v6
= global
.mcast_addr_v6
;
52 fatalx("send_hello: unknown af");
57 holdtime
= tnbr_get_hello_holdtime(tnbr
);
58 flags
= F_HELLO_TARGETED
;
59 if ((tnbr
->flags
& F_TNBR_CONFIGURED
) || tnbr
->pw_count
61 flags
|= F_HELLO_REQ_TARG
;
62 fd
= (ldp_af_global_get(&global
, af
))->ldp_edisc_socket
;
64 /* unicast destination address */
68 fatalx("send_hello: unknown hello type");
71 /* calculate message size */
72 size
= LDP_HDR_SIZE
+ LDP_MSG_SIZE
+ sizeof(struct hello_prms_tlv
);
75 size
+= sizeof(struct hello_prms_opt4_tlv
);
78 size
+= sizeof(struct hello_prms_opt16_tlv
);
81 fatalx("send_hello: unknown af");
83 size
+= sizeof(struct hello_prms_opt4_tlv
);
84 if (ldp_is_dual_stack(leconf
))
85 size
+= sizeof(struct hello_prms_opt4_tlv
);
87 /* generate message */
88 if ((buf
= ibuf_open(size
)) == NULL
)
91 err
|= gen_ldp_hdr(buf
, size
);
93 err
|= gen_msg_hdr(buf
, MSG_TYPE_HELLO
, size
);
94 err
|= gen_hello_prms_tlv(buf
, holdtime
, flags
);
97 * RFC 7552 - Section 6.1:
98 * "An LSR MUST include only the transport address whose address
99 * family is the same as that of the IP packet carrying the Hello
104 err
|= gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_IPV4TRANSADDR
,
105 leconf
->ipv4
.trans_addr
.v4
.s_addr
);
108 err
|= gen_opt16_hello_prms_tlv(buf
, TLV_TYPE_IPV6TRANSADDR
,
109 leconf
->ipv6
.trans_addr
.v6
.s6_addr
);
112 fatalx("send_hello: unknown af");
115 err
|= gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_CONFIG
,
116 htonl(global
.conf_seqnum
));
119 * RFC 7552 - Section 6.1.1:
120 * "A Dual-stack LSR (i.e., an LSR supporting Dual-stack LDP for a peer)
121 * MUST include the Dual-Stack capability TLV in all of its LDP Hellos".
123 if (ldp_is_dual_stack(leconf
))
124 err
|= gen_ds_hello_prms_tlv(buf
, leconf
->trans_pref
);
133 debug_hello_send("iface %s (%s) holdtime %u", ia
->iface
->name
,
134 af_name(ia
->af
), holdtime
);
137 debug_hello_send("targeted-neighbor %s (%s) holdtime %u",
138 log_addr(tnbr
->af
, &tnbr
->addr
), af_name(tnbr
->af
),
142 fatalx("send_hello: unknown hello type");
145 send_packet(fd
, af
, &dst
, ia
, buf
->buf
, buf
->wpos
);
152 recv_hello(struct in_addr lsr_id
, struct ldp_msg
*msg
, int af
,
153 union ldpd_addr
*src
, struct iface
*iface
, int multicast
, char *buf
,
156 struct adj
*adj
= NULL
;
157 struct nbr
*nbr
, *nbrt
;
158 uint16_t holdtime
= 0, flags
= 0;
161 union ldpd_addr trans_addr
;
162 ifindex_t scope_id
= 0;
163 uint32_t conf_seqnum
;
166 struct hello_source source
;
167 struct iface_af
*ia
= NULL
;
168 struct tnbr
*tnbr
= NULL
;
170 r
= tlv_decode_hello_prms(buf
, len
, &holdtime
, &flags
);
172 log_debug("%s: lsr-id %pI4: failed to decode params", __func__
,
177 if (holdtime
!= 0 && holdtime
< MIN_HOLDTIME
) {
178 log_debug("%s: lsr-id %pI4: invalid hello holdtime (%u)",
179 __func__
, &lsr_id
, holdtime
);
182 if (multicast
&& (flags
& F_HELLO_TARGETED
)) {
183 log_debug("%s: lsr-id %pI4: multicast targeted hello", __func__
,
187 if (!multicast
&& !((flags
& F_HELLO_TARGETED
))) {
188 log_debug("%s: lsr-id %pI4: unicast link hello", __func__
,
195 r
= tlv_decode_opt_hello_prms(buf
, len
, &tlvs_rcvd
, af
, &trans_addr
,
196 &conf_seqnum
, &trans_pref
);
198 log_debug("%s: lsr-id %pI4: failed to decode optional params",
203 log_debug("%s: lsr-id %pI4: unexpected data in message",
207 ds_tlv
= (tlvs_rcvd
& F_HELLO_TLV_RCVD_DS
) ? 1 : 0;
209 /* implicit transport address */
210 if (!(tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
))
212 if (bad_addr(af
, &trans_addr
)) {
213 log_debug("%s: lsr-id %pI4: invalid transport address %s",
214 __func__
, &lsr_id
, log_addr(af
, &trans_addr
));
217 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&trans_addr
.v6
)) {
219 * RFC 7552 - Section 6.1:
220 * "An LSR MUST use a global unicast IPv6 address in an IPv6
221 * Transport Address optional object of outgoing targeted
222 * Hellos and check for the same in incoming targeted Hellos
223 * (i.e., MUST discard the targeted Hello if it failed the
226 if (flags
& F_HELLO_TARGETED
) {
227 log_debug("%s: lsr-id %pI4: invalid targeted hello transport address %s", __func__
, &lsr_id
,
228 log_addr(af
, &trans_addr
));
231 scope_id
= iface
->ifindex
;
234 memset(&source
, 0, sizeof(source
));
235 if (flags
& F_HELLO_TARGETED
) {
237 * RFC 7552 - Section 5.2:
238 * "The link-local IPv6 addresses MUST NOT be used as the
239 * targeted LDP Hello packet's source or destination addresses".
241 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&src
->v6
)) {
242 log_debug("%s: lsr-id %pI4: targeted hello with link-local source address", __func__
,
247 tnbr
= tnbr_find(leconf
, af
, src
);
249 /* remove the dynamic tnbr if the 'R' bit was cleared */
250 if (tnbr
&& (tnbr
->flags
& F_TNBR_DYNAMIC
) &&
251 !((flags
& F_HELLO_REQ_TARG
))) {
252 tnbr
->flags
&= ~F_TNBR_DYNAMIC
;
253 tnbr
= tnbr_check(leconf
, tnbr
);
257 struct ldpd_af_conf
*af_conf
;
259 if (!(flags
& F_HELLO_REQ_TARG
))
261 af_conf
= ldp_af_conf_get(leconf
, af
);
262 if (!(af_conf
->flags
& F_LDPD_AF_THELLO_ACCEPT
))
264 if (ldpe_acl_check(af_conf
->acl_thello_accept_from
, af
,
265 src
, (af
== AF_INET
) ? 32 : 128) != FILTER_PERMIT
)
268 tnbr
= tnbr_new(af
, src
);
269 tnbr
->flags
|= F_TNBR_DYNAMIC
;
271 RB_INSERT(tnbr_head
, &leconf
->tnbr_tree
, tnbr
);
274 source
.type
= HELLO_TARGETED
;
275 source
.target
= tnbr
;
277 ia
= iface_af_get(iface
, af
);
278 source
.type
= HELLO_LINK
;
280 source
.link
.src_addr
= *src
;
283 debug_hello_recv("%s lsr-id %pI4 transport-address %s holdtime %u%s",
284 log_hello_src(&source
), &lsr_id
, log_addr(af
, &trans_addr
),
285 holdtime
, (ds_tlv
) ? " (dual stack TLV present)" : "");
287 adj
= adj_find(lsr_id
, &source
);
288 if (adj
&& adj
->ds_tlv
!= ds_tlv
) {
290 * Transient condition, ignore packet and wait until adjacency
295 nbr
= nbr_find_ldpid(lsr_id
.s_addr
);
297 /* check dual-stack tlv */
298 if (ds_tlv
&& trans_pref
!= leconf
->trans_pref
) {
300 * RFC 7552 - Section 6.1.1:
301 * "If the Dual-Stack capability TLV is present and the remote
302 * preference does not match the local preference (or does not
303 * get recognized), then the LSR MUST discard the Hello message
305 * If an LDP session was already in place, then the LSR MUST
306 * send a fatal Notification message with status code of
307 * 'Transport Connection Mismatch' and reset the session".
309 log_debug("%s: lsr-id %pI4: remote transport preference does not match the local preference", __func__
, &lsr_id
);
311 session_shutdown(nbr
, S_TRANS_MISMTCH
, msg
->id
,
314 adj_del(adj
, S_SHUTDOWN
);
319 * Check for noncompliant dual-stack neighbor according to
320 * RFC 7552 section 6.1.1.
322 if (nbr
&& !ds_tlv
) {
325 if (nbr_adj_count(nbr
, AF_INET6
) > 0) {
326 session_shutdown(nbr
, S_DS_NONCMPLNCE
,
332 if (nbr_adj_count(nbr
, AF_INET
) > 0) {
333 session_shutdown(nbr
, S_DS_NONCMPLNCE
,
339 fatalx("recv_hello: unknown af");
344 * Protections against misconfigured networks and buggy implementations.
346 if (nbr
&& nbr
->af
== af
&&
347 (ldp_addrcmp(af
, &nbr
->raddr
, &trans_addr
) ||
348 nbr
->raddr_scope
!= scope_id
)) {
349 log_warnx("%s: lsr-id %pI4: hello packet advertising a different transport address", __func__
, &lsr_id
);
351 adj_del(adj
, S_SHUTDOWN
);
355 nbrt
= nbr_find_addr(af
, &trans_addr
);
357 log_debug("%s: transport address %s is already being used by lsr-id %pI4", __func__
, log_addr(af
,
358 &trans_addr
), &nbrt
->id
);
360 adj_del(adj
, S_SHUTDOWN
);
366 adj
= adj_new(lsr_id
, &source
, &trans_addr
);
369 RB_INSERT(nbr_adj_head
, &nbr
->adj_tree
, adj
);
371 ldp_sync_fsm_adj_event(adj
, LDP_SYNC_EVT_ADJ_NEW
);
373 adj
->ds_tlv
= ds_tlv
;
376 * If the hello adjacency's address-family doesn't match the local
377 * preference, then an adjacency is still created but we don't attempt
378 * to start an LDP session.
380 if (nbr
== NULL
&& (!ds_tlv
||
381 ((trans_pref
== DUAL_STACK_LDPOV4
&& af
== AF_INET
) ||
382 (trans_pref
== DUAL_STACK_LDPOV6
&& af
== AF_INET6
))))
383 nbr
= nbr_new(lsr_id
, af
, ds_tlv
, &trans_addr
, scope_id
);
385 /* dynamic LDPv4 GTSM negotiation as per RFC 6720 */
387 if (flags
& F_HELLO_GTSM
)
388 nbr
->flags
|= F_NBR_GTSM_NEGOTIATED
;
390 nbr
->flags
&= ~F_NBR_GTSM_NEGOTIATED
;
393 /* update neighbor's configuration sequence number */
394 if (nbr
&& (tlvs_rcvd
& F_HELLO_TLV_RCVD_CONF
)) {
395 if (conf_seqnum
> nbr
->conf_seqnum
&&
396 nbr_pending_idtimer(nbr
))
397 nbr_stop_idtimer(nbr
);
398 nbr
->conf_seqnum
= conf_seqnum
;
401 /* always update the holdtime to properly handle runtime changes */
402 switch (source
.type
) {
405 holdtime
= LINK_DFLT_HOLDTIME
;
407 adj
->holdtime
= MIN(if_get_hello_holdtime(ia
), holdtime
);
411 holdtime
= TARGETED_DFLT_HOLDTIME
;
413 adj
->holdtime
= MIN(tnbr_get_hello_holdtime(tnbr
), holdtime
);
415 if (adj
->holdtime
!= INFINITE_HOLDTIME
)
416 adj_start_itimer(adj
);
418 adj_stop_itimer(adj
);
420 if (nbr
&& nbr
->state
== NBR_STA_PRESENT
&& !nbr_pending_idtimer(nbr
) &&
421 nbr_session_active_role(nbr
) && !nbr_pending_connect(nbr
))
422 nbr_establish_connection(nbr
);
426 gen_hello_prms_tlv(struct ibuf
*buf
, uint16_t holdtime
, uint16_t flags
)
428 struct hello_prms_tlv parms
;
430 memset(&parms
, 0, sizeof(parms
));
431 parms
.type
= htons(TLV_TYPE_COMMONHELLO
);
432 parms
.length
= htons(sizeof(parms
.holdtime
) + sizeof(parms
.flags
));
433 parms
.holdtime
= htons(holdtime
);
434 parms
.flags
= htons(flags
);
436 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
440 gen_opt4_hello_prms_tlv(struct ibuf
*buf
, uint16_t type
, uint32_t value
)
442 struct hello_prms_opt4_tlv parms
;
444 memset(&parms
, 0, sizeof(parms
));
445 parms
.type
= htons(type
);
446 parms
.length
= htons(sizeof(parms
.value
));
449 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
453 gen_opt16_hello_prms_tlv(struct ibuf
*buf
, uint16_t type
, uint8_t *value
)
455 struct hello_prms_opt16_tlv parms
;
457 memset(&parms
, 0, sizeof(parms
));
458 parms
.type
= htons(type
);
459 parms
.length
= htons(sizeof(parms
.value
));
460 memcpy(&parms
.value
, value
, sizeof(parms
.value
));
462 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
466 gen_ds_hello_prms_tlv(struct ibuf
*buf
, uint32_t value
)
468 if (leconf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
469 value
= htonl(value
);
471 value
= htonl(value
<< 28);
473 return (gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_DUALSTACK
, value
));
477 tlv_decode_hello_prms(char *buf
, uint16_t len
, uint16_t *holdtime
,
480 struct hello_prms_tlv tlv
;
482 if (len
< sizeof(tlv
))
484 memcpy(&tlv
, buf
, sizeof(tlv
));
486 if (tlv
.type
!= htons(TLV_TYPE_COMMONHELLO
))
488 if (ntohs(tlv
.length
) != sizeof(tlv
) - TLV_HDR_SIZE
)
491 *holdtime
= ntohs(tlv
.holdtime
);
492 *flags
= ntohs(tlv
.flags
);
494 return (sizeof(tlv
));
498 tlv_decode_opt_hello_prms(char *buf
, uint16_t len
, int *tlvs_rcvd
, int af
,
499 union ldpd_addr
*addr
, uint32_t *conf_number
, uint16_t *trans_pref
)
506 memset(addr
, 0, sizeof(*addr
));
511 * RFC 7552 - Section 6.1:
512 * "An LSR SHOULD accept the Hello message that contains both IPv4 and
513 * IPv6 Transport Address optional objects but MUST use only the
514 * transport address whose address family is the same as that of the
515 * IP packet carrying the Hello message. An LSR SHOULD accept only
516 * the first Transport Address optional object for a given address
517 * family in the received Hello message and ignore the rest if the
518 * LSR receives more than one Transport Address optional object for a
519 * given address family".
521 while (len
>= sizeof(tlv
)) {
522 memcpy(&tlv
, buf
, TLV_HDR_SIZE
);
523 tlv_len
= ntohs(tlv
.length
);
524 if (tlv_len
+ TLV_HDR_SIZE
> len
)
528 total
+= TLV_HDR_SIZE
;
530 switch (ntohs(tlv
.type
)) {
531 case TLV_TYPE_IPV4TRANSADDR
:
532 if (tlv_len
!= sizeof(addr
->v4
))
536 if (*tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
)
538 memcpy(&addr
->v4
, buf
, sizeof(addr
->v4
));
539 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_ADDR
;
541 case TLV_TYPE_IPV6TRANSADDR
:
542 if (tlv_len
!= sizeof(addr
->v6
))
546 if (*tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
)
548 memcpy(&addr
->v6
, buf
, sizeof(addr
->v6
));
549 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_ADDR
;
551 case TLV_TYPE_CONFIG
:
552 if (tlv_len
!= sizeof(uint32_t))
554 memcpy(conf_number
, buf
, sizeof(uint32_t));
555 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_CONF
;
557 case TLV_TYPE_DUALSTACK
:
558 if (tlv_len
!= sizeof(uint32_t))
561 * RFC 7552 - Section 6.1:
562 * "A Single-stack LSR does not need to use the
563 * Dual-Stack capability in Hello messages and SHOULD
564 * ignore this capability if received".
566 if (!ldp_is_dual_stack(leconf
))
568 /* Shame on you, Cisco! */
569 if (leconf
->flags
& F_LDPD_DS_CISCO_INTEROP
) {
570 memcpy(trans_pref
, buf
+ sizeof(uint16_t),
572 *trans_pref
= ntohs(*trans_pref
);
574 memcpy(trans_pref
, buf
, sizeof(uint16_t));
575 *trans_pref
= ntohs(*trans_pref
) >> 12;
577 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_DS
;
580 /* if unknown flag set, ignore TLV */
581 if (!(ntohs(tlv
.type
) & UNKNOWN_FLAG
))