]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/hello.c
tools: improve explanation of 'wrap' options
[mirror_frr.git] / ldpd / hello.c
1 /* $OpenBSD$ */
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 <zebra.h>
21
22 #include "ldpd.h"
23 #include "ldpe.h"
24 #include "log.h"
25 #include "ldp_debug.h"
26
27 static int gen_hello_prms_tlv(struct ibuf *buf, uint16_t, uint16_t);
28 static int gen_opt4_hello_prms_tlv(struct ibuf *, uint16_t, uint32_t);
29 static int gen_opt16_hello_prms_tlv(struct ibuf *, uint16_t, uint8_t *);
30 static int gen_ds_hello_prms_tlv(struct ibuf *, uint32_t);
31 static int tlv_decode_hello_prms(char *, uint16_t, uint16_t *, uint16_t *);
32 static int tlv_decode_opt_hello_prms(char *, uint16_t, int *, int,
33 union ldpd_addr *, uint32_t *, uint16_t *);
34
35 int
36 send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
37 {
38 int af;
39 union ldpd_addr dst;
40 uint16_t size, holdtime = 0, flags = 0;
41 int fd = 0;
42 struct ibuf *buf;
43 int err = 0;
44
45 switch (type) {
46 case HELLO_LINK:
47 af = ia->af;
48 holdtime = if_get_hello_holdtime(ia);
49 flags = 0;
50 fd = (ldp_af_global_get(&global, af))->ldp_disc_socket;
51
52 /* multicast destination address */
53 switch (af) {
54 case AF_INET:
55 if (!(leconf->ipv4.flags & F_LDPD_AF_NO_GTSM))
56 flags |= F_HELLO_GTSM;
57 dst.v4 = global.mcast_addr_v4;
58 break;
59 case AF_INET6:
60 dst.v6 = global.mcast_addr_v6;
61 break;
62 default:
63 fatalx("send_hello: unknown af");
64 }
65 break;
66 case HELLO_TARGETED:
67 af = tnbr->af;
68 holdtime = tnbr_get_hello_holdtime(tnbr);
69 flags = F_HELLO_TARGETED;
70 if ((tnbr->flags & F_TNBR_CONFIGURED) || tnbr->pw_count
71 || tnbr->rlfa_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 switch (type) {
143 case HELLO_LINK:
144 debug_hello_send("iface %s (%s) holdtime %u", ia->iface->name,
145 af_name(ia->af), holdtime);
146 break;
147 case HELLO_TARGETED:
148 debug_hello_send("targeted-neighbor %s (%s) holdtime %u",
149 log_addr(tnbr->af, &tnbr->addr), af_name(tnbr->af),
150 holdtime);
151 break;
152 default:
153 fatalx("send_hello: unknown hello type");
154 }
155
156 send_packet(fd, af, &dst, ia, buf->buf, buf->wpos);
157 ibuf_free(buf);
158
159 return (0);
160 }
161
162 void
163 recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
164 union ldpd_addr *src, struct iface *iface, int multicast, char *buf,
165 uint16_t len)
166 {
167 struct adj *adj = NULL;
168 struct nbr *nbr, *nbrt;
169 uint16_t holdtime = 0, flags = 0;
170 int tlvs_rcvd;
171 int ds_tlv;
172 union ldpd_addr trans_addr;
173 ifindex_t scope_id = 0;
174 uint32_t conf_seqnum;
175 uint16_t trans_pref;
176 int r;
177 struct hello_source source;
178 struct iface_af *ia = NULL;
179 struct tnbr *tnbr = NULL;
180
181 r = tlv_decode_hello_prms(buf, len, &holdtime, &flags);
182 if (r == -1) {
183 log_debug("%s: lsr-id %pI4: failed to decode params", __func__,
184 &lsr_id);
185 return;
186 }
187 /* safety checks */
188 if (holdtime != 0 && holdtime < MIN_HOLDTIME) {
189 log_debug("%s: lsr-id %pI4: invalid hello holdtime (%u)",
190 __func__, &lsr_id, holdtime);
191 return;
192 }
193 if (multicast && (flags & F_HELLO_TARGETED)) {
194 log_debug("%s: lsr-id %pI4: multicast targeted hello", __func__,
195 &lsr_id);
196 return;
197 }
198 if (!multicast && !((flags & F_HELLO_TARGETED))) {
199 log_debug("%s: lsr-id %pI4: unicast link hello", __func__,
200 &lsr_id);
201 return;
202 }
203 buf += r;
204 len -= r;
205
206 r = tlv_decode_opt_hello_prms(buf, len, &tlvs_rcvd, af, &trans_addr,
207 &conf_seqnum, &trans_pref);
208 if (r == -1) {
209 log_debug("%s: lsr-id %pI4: failed to decode optional params",
210 __func__, &lsr_id);
211 return;
212 }
213 if (r != len) {
214 log_debug("%s: lsr-id %pI4: unexpected data in message",
215 __func__, &lsr_id);
216 return;
217 }
218 ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
219
220 /* implicit transport address */
221 if (!(tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR))
222 trans_addr = *src;
223 if (bad_addr(af, &trans_addr)) {
224 log_debug("%s: lsr-id %pI4: invalid transport address %s",
225 __func__, &lsr_id, log_addr(af, &trans_addr));
226 return;
227 }
228 if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&trans_addr.v6)) {
229 /*
230 * RFC 7552 - Section 6.1:
231 * "An LSR MUST use a global unicast IPv6 address in an IPv6
232 * Transport Address optional object of outgoing targeted
233 * Hellos and check for the same in incoming targeted Hellos
234 * (i.e., MUST discard the targeted Hello if it failed the
235 * check)".
236 */
237 if (flags & F_HELLO_TARGETED) {
238 log_debug("%s: lsr-id %pI4: invalid targeted hello transport address %s", __func__, &lsr_id,
239 log_addr(af, &trans_addr));
240 return;
241 }
242 scope_id = iface->ifindex;
243 }
244
245 memset(&source, 0, sizeof(source));
246 if (flags & F_HELLO_TARGETED) {
247 /*
248 * RFC 7552 - Section 5.2:
249 * "The link-local IPv6 addresses MUST NOT be used as the
250 * targeted LDP Hello packet's source or destination addresses".
251 */
252 if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&src->v6)) {
253 log_debug("%s: lsr-id %pI4: targeted hello with link-local source address", __func__,
254 &lsr_id);
255 return;
256 }
257
258 tnbr = tnbr_find(leconf, af, src);
259
260 /* remove the dynamic tnbr if the 'R' bit was cleared */
261 if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
262 !((flags & F_HELLO_REQ_TARG))) {
263 tnbr->flags &= ~F_TNBR_DYNAMIC;
264 tnbr = tnbr_check(leconf, tnbr);
265 }
266
267 if (!tnbr) {
268 struct ldpd_af_conf *af_conf;
269
270 if (!(flags & F_HELLO_REQ_TARG))
271 return;
272 af_conf = ldp_af_conf_get(leconf, af);
273 if (!(af_conf->flags & F_LDPD_AF_THELLO_ACCEPT))
274 return;
275 if (ldpe_acl_check(af_conf->acl_thello_accept_from, af,
276 src, (af == AF_INET) ? 32 : 128) != FILTER_PERMIT)
277 return;
278
279 tnbr = tnbr_new(af, src);
280 tnbr->flags |= F_TNBR_DYNAMIC;
281 tnbr_update(tnbr);
282 RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
283 }
284
285 source.type = HELLO_TARGETED;
286 source.target = tnbr;
287 } else {
288 ia = iface_af_get(iface, af);
289 source.type = HELLO_LINK;
290 source.link.ia = ia;
291 source.link.src_addr = *src;
292 }
293
294 debug_hello_recv("%s lsr-id %pI4 transport-address %s holdtime %u%s",
295 log_hello_src(&source), &lsr_id, log_addr(af, &trans_addr),
296 holdtime, (ds_tlv) ? " (dual stack TLV present)" : "");
297
298 adj = adj_find(lsr_id, &source);
299 if (adj && adj->ds_tlv != ds_tlv) {
300 /*
301 * Transient condition, ignore packet and wait until adjacency
302 * times out.
303 */
304 return;
305 }
306 nbr = nbr_find_ldpid(lsr_id.s_addr);
307
308 /* check dual-stack tlv */
309 if (ds_tlv && trans_pref != leconf->trans_pref) {
310 /*
311 * RFC 7552 - Section 6.1.1:
312 * "If the Dual-Stack capability TLV is present and the remote
313 * preference does not match the local preference (or does not
314 * get recognized), then the LSR MUST discard the Hello message
315 * and log an error.
316 * If an LDP session was already in place, then the LSR MUST
317 * send a fatal Notification message with status code of
318 * 'Transport Connection Mismatch' and reset the session".
319 */
320 log_debug("%s: lsr-id %pI4: remote transport preference does not match the local preference", __func__, &lsr_id);
321 if (nbr)
322 session_shutdown(nbr, S_TRANS_MISMTCH, msg->id,
323 msg->type);
324 if (adj)
325 adj_del(adj, S_SHUTDOWN);
326 return;
327 }
328
329 /*
330 * Check for noncompliant dual-stack neighbor according to
331 * RFC 7552 section 6.1.1.
332 */
333 if (nbr && !ds_tlv) {
334 switch (af) {
335 case AF_INET:
336 if (nbr_adj_count(nbr, AF_INET6) > 0) {
337 session_shutdown(nbr, S_DS_NONCMPLNCE,
338 msg->id, msg->type);
339 return;
340 }
341 break;
342 case AF_INET6:
343 if (nbr_adj_count(nbr, AF_INET) > 0) {
344 session_shutdown(nbr, S_DS_NONCMPLNCE,
345 msg->id, msg->type);
346 return;
347 }
348 break;
349 default:
350 fatalx("recv_hello: unknown af");
351 }
352 }
353
354 /*
355 * Protections against misconfigured networks and buggy implementations.
356 */
357 if (nbr && nbr->af == af &&
358 (ldp_addrcmp(af, &nbr->raddr, &trans_addr) ||
359 nbr->raddr_scope != scope_id)) {
360 log_warnx("%s: lsr-id %pI4: hello packet advertising a different transport address", __func__, &lsr_id);
361 if (adj)
362 adj_del(adj, S_SHUTDOWN);
363 return;
364 }
365 if (nbr == NULL) {
366 nbrt = nbr_find_addr(af, &trans_addr);
367 if (nbrt) {
368 log_debug("%s: transport address %s is already being used by lsr-id %pI4", __func__, log_addr(af,
369 &trans_addr), &nbrt->id);
370 if (adj)
371 adj_del(adj, S_SHUTDOWN);
372 return;
373 }
374 }
375
376 if (adj == NULL) {
377 adj = adj_new(lsr_id, &source, &trans_addr);
378 if (nbr) {
379 adj->nbr = nbr;
380 RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
381 }
382 ldp_sync_fsm_adj_event(adj, LDP_SYNC_EVT_ADJ_NEW);
383 }
384 adj->ds_tlv = ds_tlv;
385
386 /*
387 * If the hello adjacency's address-family doesn't match the local
388 * preference, then an adjacency is still created but we don't attempt
389 * to start an LDP session.
390 */
391 if (nbr == NULL && (!ds_tlv ||
392 ((trans_pref == DUAL_STACK_LDPOV4 && af == AF_INET) ||
393 (trans_pref == DUAL_STACK_LDPOV6 && af == AF_INET6))))
394 nbr = nbr_new(lsr_id, af, ds_tlv, &trans_addr, scope_id);
395
396 /* dynamic LDPv4 GTSM negotiation as per RFC 6720 */
397 if (nbr) {
398 if (flags & F_HELLO_GTSM)
399 nbr->flags |= F_NBR_GTSM_NEGOTIATED;
400 else
401 nbr->flags &= ~F_NBR_GTSM_NEGOTIATED;
402 }
403
404 /* update neighbor's configuration sequence number */
405 if (nbr && (tlvs_rcvd & F_HELLO_TLV_RCVD_CONF)) {
406 if (conf_seqnum > nbr->conf_seqnum &&
407 nbr_pending_idtimer(nbr))
408 nbr_stop_idtimer(nbr);
409 nbr->conf_seqnum = conf_seqnum;
410 }
411
412 /* always update the holdtime to properly handle runtime changes */
413 switch (source.type) {
414 case HELLO_LINK:
415 if (holdtime == 0)
416 holdtime = LINK_DFLT_HOLDTIME;
417
418 adj->holdtime = MIN(if_get_hello_holdtime(ia), holdtime);
419 break;
420 case HELLO_TARGETED:
421 if (holdtime == 0)
422 holdtime = TARGETED_DFLT_HOLDTIME;
423
424 adj->holdtime = MIN(tnbr_get_hello_holdtime(tnbr), holdtime);
425 }
426 if (adj->holdtime != INFINITE_HOLDTIME)
427 adj_start_itimer(adj);
428 else
429 adj_stop_itimer(adj);
430
431 if (nbr && nbr->state == NBR_STA_PRESENT && !nbr_pending_idtimer(nbr) &&
432 nbr_session_active_role(nbr) && !nbr_pending_connect(nbr))
433 nbr_establish_connection(nbr);
434 }
435
436 static int
437 gen_hello_prms_tlv(struct ibuf *buf, uint16_t holdtime, uint16_t flags)
438 {
439 struct hello_prms_tlv parms;
440
441 memset(&parms, 0, sizeof(parms));
442 parms.type = htons(TLV_TYPE_COMMONHELLO);
443 parms.length = htons(sizeof(parms.holdtime) + sizeof(parms.flags));
444 parms.holdtime = htons(holdtime);
445 parms.flags = htons(flags);
446
447 return (ibuf_add(buf, &parms, sizeof(parms)));
448 }
449
450 static int
451 gen_opt4_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint32_t value)
452 {
453 struct hello_prms_opt4_tlv parms;
454
455 memset(&parms, 0, sizeof(parms));
456 parms.type = htons(type);
457 parms.length = htons(sizeof(parms.value));
458 parms.value = value;
459
460 return (ibuf_add(buf, &parms, sizeof(parms)));
461 }
462
463 static int
464 gen_opt16_hello_prms_tlv(struct ibuf *buf, uint16_t type, uint8_t *value)
465 {
466 struct hello_prms_opt16_tlv parms;
467
468 memset(&parms, 0, sizeof(parms));
469 parms.type = htons(type);
470 parms.length = htons(sizeof(parms.value));
471 memcpy(&parms.value, value, sizeof(parms.value));
472
473 return (ibuf_add(buf, &parms, sizeof(parms)));
474 }
475
476 static int
477 gen_ds_hello_prms_tlv(struct ibuf *buf, uint32_t value)
478 {
479 if (leconf->flags & F_LDPD_DS_CISCO_INTEROP)
480 value = htonl(value);
481 else
482 value = htonl(value << 28);
483
484 return (gen_opt4_hello_prms_tlv(buf, TLV_TYPE_DUALSTACK, value));
485 }
486
487 static int
488 tlv_decode_hello_prms(char *buf, uint16_t len, uint16_t *holdtime,
489 uint16_t *flags)
490 {
491 struct hello_prms_tlv tlv;
492
493 if (len < sizeof(tlv))
494 return (-1);
495 memcpy(&tlv, buf, sizeof(tlv));
496
497 if (tlv.type != htons(TLV_TYPE_COMMONHELLO))
498 return (-1);
499 if (ntohs(tlv.length) != sizeof(tlv) - TLV_HDR_SIZE)
500 return (-1);
501
502 *holdtime = ntohs(tlv.holdtime);
503 *flags = ntohs(tlv.flags);
504
505 return (sizeof(tlv));
506 }
507
508 static int
509 tlv_decode_opt_hello_prms(char *buf, uint16_t len, int *tlvs_rcvd, int af,
510 union ldpd_addr *addr, uint32_t *conf_number, uint16_t *trans_pref)
511 {
512 struct tlv tlv;
513 uint16_t tlv_len;
514 int total = 0;
515
516 *tlvs_rcvd = 0;
517 memset(addr, 0, sizeof(*addr));
518 *conf_number = 0;
519 *trans_pref = 0;
520
521 /*
522 * RFC 7552 - Section 6.1:
523 * "An LSR SHOULD accept the Hello message that contains both IPv4 and
524 * IPv6 Transport Address optional objects but MUST use only the
525 * transport address whose address family is the same as that of the
526 * IP packet carrying the Hello message. An LSR SHOULD accept only
527 * the first Transport Address optional object for a given address
528 * family in the received Hello message and ignore the rest if the
529 * LSR receives more than one Transport Address optional object for a
530 * given address family".
531 */
532 while (len >= sizeof(tlv)) {
533 memcpy(&tlv, buf, TLV_HDR_SIZE);
534 tlv_len = ntohs(tlv.length);
535 if (tlv_len + TLV_HDR_SIZE > len)
536 return (-1);
537 buf += TLV_HDR_SIZE;
538 len -= TLV_HDR_SIZE;
539 total += TLV_HDR_SIZE;
540
541 switch (ntohs(tlv.type)) {
542 case TLV_TYPE_IPV4TRANSADDR:
543 if (tlv_len != sizeof(addr->v4))
544 return (-1);
545 if (af != AF_INET)
546 return (-1);
547 if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
548 break;
549 memcpy(&addr->v4, buf, sizeof(addr->v4));
550 *tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
551 break;
552 case TLV_TYPE_IPV6TRANSADDR:
553 if (tlv_len != sizeof(addr->v6))
554 return (-1);
555 if (af != AF_INET6)
556 return (-1);
557 if (*tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR)
558 break;
559 memcpy(&addr->v6, buf, sizeof(addr->v6));
560 *tlvs_rcvd |= F_HELLO_TLV_RCVD_ADDR;
561 break;
562 case TLV_TYPE_CONFIG:
563 if (tlv_len != sizeof(uint32_t))
564 return (-1);
565 memcpy(conf_number, buf, sizeof(uint32_t));
566 *tlvs_rcvd |= F_HELLO_TLV_RCVD_CONF;
567 break;
568 case TLV_TYPE_DUALSTACK:
569 if (tlv_len != sizeof(uint32_t))
570 return (-1);
571 /*
572 * RFC 7552 - Section 6.1:
573 * "A Single-stack LSR does not need to use the
574 * Dual-Stack capability in Hello messages and SHOULD
575 * ignore this capability if received".
576 */
577 if (!ldp_is_dual_stack(leconf))
578 break;
579 /* Shame on you, Cisco! */
580 if (leconf->flags & F_LDPD_DS_CISCO_INTEROP) {
581 memcpy(trans_pref, buf + sizeof(uint16_t),
582 sizeof(uint16_t));
583 *trans_pref = ntohs(*trans_pref);
584 } else {
585 memcpy(trans_pref, buf , sizeof(uint16_t));
586 *trans_pref = ntohs(*trans_pref) >> 12;
587 }
588 *tlvs_rcvd |= F_HELLO_TLV_RCVD_DS;
589 break;
590 default:
591 /* if unknown flag set, ignore TLV */
592 if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
593 return (-1);
594 break;
595 }
596 buf += tlv_len;
597 len -= tlv_len;
598 total += tlv_len;
599 }
600
601 return (total);
602 }