4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
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.
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.
20 #include <sys/types.h>
21 #include <arpa/inet.h>
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 *);
37 send_hello(enum hello_type type
, struct iface_af
*ia
, struct tnbr
*tnbr
)
41 uint16_t size
, holdtime
= 0, flags
= 0;
49 holdtime
= ia
->hello_holdtime
;
51 fd
= (ldp_af_global_get(&global
, af
))->ldp_disc_socket
;
53 /* multicast destination address */
56 if (!(leconf
->ipv4
.flags
& F_LDPD_AF_NO_GTSM
))
57 flags
|= F_HELLO_GTSM
;
58 dst
.v4
= global
.mcast_addr_v4
;
61 dst
.v6
= global
.mcast_addr_v6
;
64 fatalx("send_hello: unknown 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
;
75 /* unicast destination address */
79 fatalx("send_hello: unknown hello type");
82 /* calculate message size */
83 size
= LDP_HDR_SIZE
+ LDP_MSG_SIZE
+ sizeof(struct hello_prms_tlv
);
86 size
+= sizeof(struct hello_prms_opt4_tlv
);
89 size
+= sizeof(struct hello_prms_opt16_tlv
);
92 fatalx("send_hello: unknown af");
94 size
+= sizeof(struct hello_prms_opt4_tlv
);
95 if (ldp_is_dual_stack(leconf
))
96 size
+= sizeof(struct hello_prms_opt4_tlv
);
98 /* generate message */
99 if ((buf
= ibuf_open(size
)) == NULL
)
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
);
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
115 err
|= gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_IPV4TRANSADDR
,
116 leconf
->ipv4
.trans_addr
.v4
.s_addr
);
119 err
|= gen_opt16_hello_prms_tlv(buf
, TLV_TYPE_IPV6TRANSADDR
,
120 leconf
->ipv6
.trans_addr
.v6
.s6_addr
);
123 fatalx("send_hello: unknown af");
126 err
|= gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_CONFIG
,
127 htonl(global
.conf_seqnum
));
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".
134 if (ldp_is_dual_stack(leconf
))
135 err
|= gen_ds_hello_prms_tlv(buf
, leconf
->trans_pref
);
142 send_packet(fd
, af
, &dst
, ia
, buf
->buf
, buf
->wpos
);
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
,
153 struct adj
*adj
= NULL
;
154 struct nbr
*nbr
, *nbrt
;
155 uint16_t holdtime
, flags
;
158 union ldpd_addr trans_addr
;
159 uint32_t scope_id
= 0;
160 uint32_t conf_seqnum
;
163 struct hello_source source
;
164 struct iface_af
*ia
= NULL
;
165 struct tnbr
*tnbr
= NULL
;
167 r
= tlv_decode_hello_prms(buf
, len
, &holdtime
, &flags
);
169 log_debug("%s: lsr-id %s: failed to decode params", __func__
,
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
);
179 if (multicast
&& (flags
& F_HELLO_TARGETED
)) {
180 log_debug("%s: lsr-id %s: multicast targeted hello", __func__
,
184 if (!multicast
&& !((flags
& F_HELLO_TARGETED
))) {
185 log_debug("%s: lsr-id %s: unicast link hello", __func__
,
192 r
= tlv_decode_opt_hello_prms(buf
, len
, &tlvs_rcvd
, af
, &trans_addr
,
193 &conf_seqnum
, &trans_pref
);
195 log_debug("%s: lsr-id %s: failed to decode optional params",
196 __func__
, inet_ntoa(lsr_id
));
200 log_debug("%s: lsr-id %s: unexpected data in message",
201 __func__
, inet_ntoa(lsr_id
));
205 /* implicit transport address */
206 if (!(tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
))
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
));
213 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&trans_addr
.v6
)) {
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
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
));
228 scope_id
= iface
->ifindex
;
231 memset(&source
, 0, sizeof(source
));
232 if (flags
& F_HELLO_TARGETED
) {
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".
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__
,
245 tnbr
= tnbr_find(leconf
, af
, src
);
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
);
255 if (!((flags
& F_HELLO_REQ_TARG
) &&
256 ((ldp_af_conf_get(leconf
, af
))->flags
&
257 F_LDPD_AF_THELLO_ACCEPT
)))
260 tnbr
= tnbr_new(leconf
, af
, src
);
261 tnbr
->flags
|= F_TNBR_DYNAMIC
;
263 LIST_INSERT_HEAD(&leconf
->tnbr_list
, tnbr
, entry
);
266 source
.type
= HELLO_TARGETED
;
267 source
.target
= tnbr
;
269 ia
= iface_af_get(iface
, af
);
270 source
.type
= HELLO_LINK
;
272 source
.link
.src_addr
= *src
;
275 adj
= adj_find(&source
);
276 nbr
= nbr_find_ldpid(lsr_id
.s_addr
);
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
) {
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
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".
291 log_debug("%s: lsr-id %s: remote transport preference does not "
292 "match the local preference", __func__
, inet_ntoa(lsr_id
));
294 session_shutdown(nbr
, S_TRANS_MISMTCH
, msg
->id
,
297 adj_del(adj
, S_SHUTDOWN
);
302 * Check for noncompliant dual-stack neighbor according to
303 * RFC 7552 section 6.1.1.
305 if (nbr
&& !ds_tlv
) {
308 if (nbr_adj_count(nbr
, AF_INET6
) > 0) {
309 session_shutdown(nbr
, S_DS_NONCMPLNCE
,
315 if (nbr_adj_count(nbr
, AF_INET
) > 0) {
316 session_shutdown(nbr
, S_DS_NONCMPLNCE
,
322 fatalx("recv_hello: unknown af");
327 * Protections against misconfigured networks and buggy implementations.
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
));
335 adj_del(adj
, S_SHUTDOWN
);
339 nbrt
= nbr_find_addr(af
, &trans_addr
);
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
));
345 adj_del(adj
, S_SHUTDOWN
);
351 adj
= adj_new(lsr_id
, &source
, &trans_addr
);
354 LIST_INSERT_HEAD(&nbr
->adj_list
, adj
, nbr_entry
);
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.
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
);
368 /* dynamic LDPv4 GTSM negotiation as per RFC 6720 */
370 if (flags
& F_HELLO_GTSM
)
371 nbr
->flags
|= F_NBR_GTSM_NEGOTIATED
;
373 nbr
->flags
&= ~F_NBR_GTSM_NEGOTIATED
;
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
;
384 /* always update the holdtime to properly handle runtime changes */
385 switch (source
.type
) {
388 holdtime
= LINK_DFLT_HOLDTIME
;
390 adj
->holdtime
= min(ia
->hello_holdtime
, holdtime
);
394 holdtime
= TARGETED_DFLT_HOLDTIME
;
396 adj
->holdtime
= min(tnbr
->hello_holdtime
, holdtime
);
398 if (adj
->holdtime
!= INFINITE_HOLDTIME
)
399 adj_start_itimer(adj
);
401 adj_stop_itimer(adj
);
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
);
409 gen_hello_prms_tlv(struct ibuf
*buf
, uint16_t holdtime
, uint16_t flags
)
411 struct hello_prms_tlv parms
;
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
);
419 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
423 gen_opt4_hello_prms_tlv(struct ibuf
*buf
, uint16_t type
, uint32_t value
)
425 struct hello_prms_opt4_tlv parms
;
427 memset(&parms
, 0, sizeof(parms
));
428 parms
.type
= htons(type
);
429 parms
.length
= htons(sizeof(parms
.value
));
432 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
436 gen_opt16_hello_prms_tlv(struct ibuf
*buf
, uint16_t type
, uint8_t *value
)
438 struct hello_prms_opt16_tlv parms
;
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
));
445 return (ibuf_add(buf
, &parms
, sizeof(parms
)));
449 gen_ds_hello_prms_tlv(struct ibuf
*buf
, uint32_t value
)
451 if (leconf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
452 value
= htonl(value
);
454 value
= htonl(value
<< 28);
456 return (gen_opt4_hello_prms_tlv(buf
, TLV_TYPE_DUALSTACK
, value
));
460 tlv_decode_hello_prms(char *buf
, uint16_t len
, uint16_t *holdtime
,
463 struct hello_prms_tlv tlv
;
465 if (len
< sizeof(tlv
))
467 memcpy(&tlv
, buf
, sizeof(tlv
));
469 if (tlv
.type
!= htons(TLV_TYPE_COMMONHELLO
))
471 if (ntohs(tlv
.length
) != sizeof(tlv
) - TLV_HDR_SIZE
)
474 *holdtime
= ntohs(tlv
.holdtime
);
475 *flags
= ntohs(tlv
.flags
);
477 return (sizeof(tlv
));
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
)
489 memset(addr
, 0, sizeof(*addr
));
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".
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
)
511 total
+= TLV_HDR_SIZE
;
513 switch (ntohs(tlv
.type
)) {
514 case TLV_TYPE_IPV4TRANSADDR
:
515 if (tlv_len
!= sizeof(addr
->v4
))
519 if (*tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
)
521 memcpy(&addr
->v4
, buf
, sizeof(addr
->v4
));
522 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_ADDR
;
524 case TLV_TYPE_IPV6TRANSADDR
:
525 if (tlv_len
!= sizeof(addr
->v6
))
529 if (*tlvs_rcvd
& F_HELLO_TLV_RCVD_ADDR
)
531 memcpy(&addr
->v6
, buf
, sizeof(addr
->v6
));
532 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_ADDR
;
534 case TLV_TYPE_CONFIG
:
535 if (tlv_len
!= sizeof(uint32_t))
537 memcpy(conf_number
, buf
, sizeof(uint32_t));
538 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_CONF
;
540 case TLV_TYPE_DUALSTACK
:
541 if (tlv_len
!= sizeof(uint32_t))
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".
549 if (!ldp_is_dual_stack(leconf
))
551 /* Shame on you, Cisco! */
552 if (leconf
->flags
& F_LDPD_DS_CISCO_INTEROP
) {
553 memcpy(trans_pref
, buf
+ sizeof(uint16_t),
555 *trans_pref
= ntohs(*trans_pref
);
557 memcpy(trans_pref
, buf
, sizeof(uint16_t));
558 *trans_pref
= ntohs(*trans_pref
) >> 12;
560 *tlvs_rcvd
|= F_HELLO_TLV_RCVD_DS
;
563 /* if unknown flag set, ignore TLV */
564 if (!(ntohs(tlv
.type
) & UNKNOWN_FLAG
))