1 /* SPDX-License-Identifier: BSD-2-Clause */
3 * dhcpcd - IPv6 ND handling
4 * Copyright (c) 2006-2020 Roy Marples <roy@marples.name>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/ioctl.h>
30 #include <sys/param.h>
31 #include <sys/socket.h>
33 #include <net/route.h>
34 #include <netinet/in.h>
35 #include <netinet/ip6.h>
36 #include <netinet/icmp6.h>
47 #define ELOOP_QUEUE ELOOP_IPV6ND
50 #include "dhcp-common.h"
61 /* Debugging Router Solicitations is a lot of spam, so disable it */
64 #ifndef ND_RA_FLAG_HOME_AGENT
65 #define ND_RA_FLAG_HOME_AGENT 0x20 /* Home Agent flag in RA */
67 #ifndef ND_RA_FLAG_PROXY
68 #define ND_RA_FLAG_PROXY 0x04 /* Proxy */
70 #ifndef ND_OPT_PI_FLAG_ROUTER
71 #define ND_OPT_PI_FLAG_ROUTER 0x20 /* Router flag in PI */
75 #define ND_OPT_RDNSS 25
76 struct nd_opt_rdnss
{ /* RDNSS option RFC 6106 */
77 uint8_t nd_opt_rdnss_type
;
78 uint8_t nd_opt_rdnss_len
;
79 uint16_t nd_opt_rdnss_reserved
;
80 uint32_t nd_opt_rdnss_lifetime
;
81 /* followed by list of IP prefixes */
83 __CTASSERT(sizeof(struct nd_opt_rdnss
) == 8);
87 #define ND_OPT_DNSSL 31
88 struct nd_opt_dnssl
{ /* DNSSL option RFC 6106 */
89 uint8_t nd_opt_dnssl_type
;
90 uint8_t nd_opt_dnssl_len
;
91 uint16_t nd_opt_dnssl_reserved
;
92 uint32_t nd_opt_dnssl_lifetime
;
93 /* followed by list of DNS servers */
95 __CTASSERT(sizeof(struct nd_opt_rdnss
) == 8);
98 /* Impossible options, so we can easily add extras */
99 #define _ND_OPT_PREFIX_ADDR 255 + 1
101 /* Minimal IPv6 MTU */
103 #define IPV6_MMTU 1280
106 #ifndef ND_RA_FLAG_RTPREF_HIGH
107 #define ND_RA_FLAG_RTPREF_MASK 0x18
108 #define ND_RA_FLAG_RTPREF_HIGH 0x08
109 #define ND_RA_FLAG_RTPREF_MEDIUM 0x00
110 #define ND_RA_FLAG_RTPREF_LOW 0x18
111 #define ND_RA_FLAG_RTPREF_RSV 0x10
114 #define EXPIRED_MAX 5 /* Remember 5 expired routers to avoid
117 #define MIN_RANDOM_FACTOR 500 /* millisecs */
118 #define MAX_RANDOM_FACTOR 1500 /* millisecs */
119 #define MIN_RANDOM_FACTOR_U MIN_RANDOM_FACTOR * 1000 /* usecs */
120 #define MAX_RANDOM_FACTOR_U MAX_RANDOM_FACTOR * 1000 /* usecs */
122 #if BYTE_ORDER == BIG_ENDIAN
123 #define IPV6_ADDR_INT32_ONE 1
124 #define IPV6_ADDR_INT16_MLL 0xff02
125 #elif BYTE_ORDER == LITTLE_ENDIAN
126 #define IPV6_ADDR_INT32_ONE 0x01000000
127 #define IPV6_ADDR_INT16_MLL 0x02ff
130 /* Debugging Neighbor Solicitations is a lot of spam, so disable it */
134 static void ipv6nd_handledata(void *);
137 * Android ships buggy ICMP6 filter headers.
138 * Supply our own until they fix their shit.
140 * https://android-review.googlesource.com/#/c/58438/
141 * http://code.google.com/p/android/issues/original?id=32621&seq=24
144 #undef ICMP6_FILTER_WILLPASS
145 #undef ICMP6_FILTER_WILLBLOCK
146 #undef ICMP6_FILTER_SETPASS
147 #undef ICMP6_FILTER_SETBLOCK
148 #undef ICMP6_FILTER_SETPASSALL
149 #undef ICMP6_FILTER_SETBLOCKALL
150 #define ICMP6_FILTER_WILLPASS(type, filterp) \
151 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
152 #define ICMP6_FILTER_WILLBLOCK(type, filterp) \
153 ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
154 #define ICMP6_FILTER_SETPASS(type, filterp) \
155 ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
156 #define ICMP6_FILTER_SETBLOCK(type, filterp) \
157 ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31))))
158 #define ICMP6_FILTER_SETPASSALL(filterp) \
159 memset(filterp, 0, sizeof(struct icmp6_filter));
160 #define ICMP6_FILTER_SETBLOCKALL(filterp) \
161 memset(filterp, 0xff, sizeof(struct icmp6_filter));
164 /* Support older systems with different defines */
165 #if !defined(IPV6_RECVHOPLIMIT) && defined(IPV6_HOPLIMIT)
166 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
168 #if !defined(IPV6_RECVPKTINFO) && defined(IPV6_PKTINFO)
169 #define IPV6_RECVPKTINFO IPV6_PKTINFO
173 #define ipv6nd_free_ra(ra) ipv6nd_freedrop_ra((ra), 0)
174 #define ipv6nd_drop_ra(ra) ipv6nd_freedrop_ra((ra), 1)
177 ipv6nd_printoptions(const struct dhcpcd_ctx
*ctx
,
178 const struct dhcp_opt
*opts
, size_t opts_len
)
181 const struct dhcp_opt
*opt
, *opt2
;
184 for (i
= 0, opt
= ctx
->nd_opts
;
185 i
< ctx
->nd_opts_len
; i
++, opt
++)
187 for (j
= 0, opt2
= opts
; j
< opts_len
; j
++, opt2
++)
188 if (opt2
->option
== opt
->option
)
191 cols
= printf("%03d %s", opt
->option
, opt
->var
);
192 dhcp_print_option_encoding(opt
, cols
);
195 for (i
= 0, opt
= opts
; i
< opts_len
; i
++, opt
++) {
196 cols
= printf("%03d %s", opt
->option
, opt
->var
);
197 dhcp_print_option_encoding(opt
, cols
);
202 ipv6nd_open(bool recv
)
205 struct icmp6_filter filt
;
207 fd
= xsocket(PF_INET6
, SOCK_RAW
| SOCK_CXNB
, IPPROTO_ICMPV6
);
211 ICMP6_FILTER_SETBLOCKALL(&filt
);
215 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
,
216 &on
, sizeof(on
)) == -1)
221 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
,
222 &on
, sizeof(on
)) == -1)
226 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVHOPLIMIT
,
227 &on
, sizeof(on
)) == -1)
230 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT
, &filt
);
234 if (setsockopt(fd
, SOL_SOCKET
, SO_RERROR
,
235 &on
, sizeof(on
)) == -1)
240 if (setsockopt(fd
, IPPROTO_ICMPV6
, ICMP6_FILTER
,
241 &filt
, sizeof(filt
)) == -1)
253 ipv6nd_openif(struct interface
*ifp
)
256 struct ipv6_mreq mreq
= {
257 .ipv6mr_multiaddr
= IN6ADDR_LINKLOCAL_ALLNODES_INIT
,
258 .ipv6mr_interface
= ifp
->index
260 struct rs_state
*state
= RS_STATE(ifp
);
261 uint_t ifindex
= ifp
->index
;
263 if (state
->nd_fd
!= -1)
266 fd
= ipv6nd_open(true);
270 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_BOUND_IF
,
271 &ifindex
, sizeof(ifindex
)) == -1)
277 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
278 &mreq
, sizeof(mreq
)) == -1)
285 eloop_event_add(ifp
->ctx
->eloop
, fd
, ipv6nd_handledata
, ifp
);
291 ipv6nd_makersprobe(struct interface
*ifp
)
293 struct rs_state
*state
;
294 struct nd_router_solicit
*rs
;
296 state
= RS_STATE(ifp
);
298 state
->rslen
= sizeof(*rs
);
300 state
->rslen
+= (size_t)ROUNDUP8(ifp
->hwlen
+ 2);
301 state
->rs
= calloc(1, state
->rslen
);
302 if (state
->rs
== NULL
)
305 rs
->nd_rs_type
= ND_ROUTER_SOLICIT
;
306 //rs->nd_rs_code = 0;
307 //rs->nd_rs_cksum = 0;
308 //rs->nd_rs_reserved = 0;
310 if (ifp
->hwlen
!= 0) {
311 struct nd_opt_hdr
*nd
;
313 nd
= (struct nd_opt_hdr
*)(state
->rs
+ 1);
314 nd
->nd_opt_type
= ND_OPT_SOURCE_LINKADDR
;
315 nd
->nd_opt_len
= (uint8_t)((ROUNDUP8(ifp
->hwlen
+ 2)) >> 3);
316 memcpy(nd
+ 1, ifp
->hwaddr
, ifp
->hwlen
);
322 ipv6nd_sendrsprobe(void *arg
)
324 struct interface
*ifp
= arg
;
325 struct rs_state
*state
= RS_STATE(ifp
);
326 struct sockaddr_in6 dst
= {
327 .sin6_family
= AF_INET6
,
328 .sin6_addr
= IN6ADDR_LINKLOCAL_ALLROUTERS_INIT
,
329 .sin6_scope_id
= ifp
->index
,
331 struct iovec iov
= { .iov_base
= state
->rs
, .iov_len
= state
->rslen
};
334 uint8_t buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
335 } cmsgbuf
= { .buf
= { 0 } };
336 struct msghdr msg
= {
337 .msg_name
= &dst
, .msg_namelen
= sizeof(dst
),
338 .msg_iov
= &iov
, .msg_iovlen
= 1,
339 .msg_control
= cmsgbuf
.buf
, .msg_controllen
= sizeof(cmsgbuf
.buf
),
342 struct in6_pktinfo pi
= { .ipi6_ifindex
= ifp
->index
};
345 struct dhcpcd_ctx
*ctx
= ifp
->ctx
;
348 if (ipv6_linklocal(ifp
) == NULL
) {
349 logdebugx("%s: delaying Router Solicitation for LL address",
351 ipv6_addlinklocalcallback(ifp
, ipv6nd_sendrsprobe
, ifp
);
356 dst
.sin6_len
= sizeof(dst
);
359 /* Set the outbound interface */
360 cm
= CMSG_FIRSTHDR(&msg
);
361 if (cm
== NULL
) /* unlikely */
363 cm
->cmsg_level
= IPPROTO_IPV6
;
364 cm
->cmsg_type
= IPV6_PKTINFO
;
365 cm
->cmsg_len
= CMSG_LEN(sizeof(pi
));
366 memcpy(CMSG_DATA(cm
), &pi
, sizeof(pi
));
368 logdebugx("%s: sending Router Solicitation", ifp
->name
);
370 if (IN_PRIVSEP(ifp
->ctx
)) {
371 if (ps_inet_sendnd(ifp
, &msg
) == -1)
377 if (state
->nd_fd
== -1) {
378 if (ipv6nd_openif(ifp
) == -1) {
385 if (ctx
->nd_fd
== -1) {
386 ctx
->nd_fd
= ipv6nd_open(true);
387 if (ctx
->nd_fd
== -1) {
391 eloop_event_add(ctx
->eloop
, ctx
->nd_fd
, ipv6nd_handledata
, ctx
);
395 if (sendmsg(s
, &msg
, 0) == -1) {
397 /* Allow IPv6ND to continue .... at most a few errors
399 * Generally the error is ENOBUFS when struggling to
400 * associate with an access point. */
406 if (state
->rsprobes
++ < MAX_RTR_SOLICITATIONS
)
407 eloop_timeout_add_sec(ifp
->ctx
->eloop
,
408 RTR_SOLICITATION_INTERVAL
, ipv6nd_sendrsprobe
, ifp
);
410 logwarnx("%s: no IPv6 Routers available", ifp
->name
);
415 ipv6nd_sendadvertisement(void *arg
)
417 struct ipv6_addr
*ia
= arg
;
418 struct interface
*ifp
= ia
->iface
;
419 struct dhcpcd_ctx
*ctx
= ifp
->ctx
;
420 struct sockaddr_in6 dst
= {
421 .sin6_family
= AF_INET6
,
422 .sin6_addr
= IN6ADDR_LINKLOCAL_ALLNODES_INIT
,
423 .sin6_scope_id
= ifp
->index
,
425 struct iovec iov
= { .iov_base
= ia
->na
, .iov_len
= ia
->na_len
};
428 uint8_t buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
429 } cmsgbuf
= { .buf
= { 0 } };
430 struct msghdr msg
= {
431 .msg_name
= &dst
, .msg_namelen
= sizeof(dst
),
432 .msg_iov
= &iov
, .msg_iovlen
= 1,
433 .msg_control
= cmsgbuf
.buf
, .msg_controllen
= sizeof(cmsgbuf
.buf
),
436 struct in6_pktinfo pi
= { .ipi6_ifindex
= ifp
->index
};
437 const struct rs_state
*state
= RS_CSTATE(ifp
);
440 if (state
== NULL
|| ifp
->carrier
<= LINK_DOWN
)
444 dst
.sin6_len
= sizeof(dst
);
447 /* Set the outbound interface. */
448 cm
= CMSG_FIRSTHDR(&msg
);
450 cm
->cmsg_level
= IPPROTO_IPV6
;
451 cm
->cmsg_type
= IPV6_PKTINFO
;
452 cm
->cmsg_len
= CMSG_LEN(sizeof(pi
));
453 memcpy(CMSG_DATA(cm
), &pi
, sizeof(pi
));
454 logdebugx("%s: sending NA for %s", ifp
->name
, ia
->saddr
);
457 if (IN_PRIVSEP(ifp
->ctx
)) {
458 if (ps_inet_sendnd(ifp
, &msg
) == -1)
468 if (sendmsg(s
, &msg
, 0) == -1)
474 if (++ia
->na_count
< MAX_NEIGHBOR_ADVERTISEMENT
) {
475 eloop_timeout_add_sec(ctx
->eloop
,
476 state
->retrans
/ 1000, ipv6nd_sendadvertisement
, ia
);
487 ipv6nd_advertise(struct ipv6_addr
*ia
)
489 struct dhcpcd_ctx
*ctx
;
490 struct interface
*ifp
;
491 struct ipv6_state
*state
;
492 struct ipv6_addr
*iap
, *iaf
;
493 struct nd_neighbor_advert
*na
;
495 if (IN6_IS_ADDR_MULTICAST(&ia
->addr
))
499 if (!(ia
->flags
& IPV6_AF_AUTOCONF
) && ia
->flags
& IPV6_AF_RAPFX
)
503 ctx
= ia
->iface
->ctx
;
504 /* Find the most preferred address to advertise. */
506 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
507 state
= IPV6_STATE(ifp
);
508 if (state
== NULL
|| ifp
->carrier
<= LINK_DOWN
)
511 TAILQ_FOREACH(iap
, &state
->addrs
, next
) {
512 if (!IN6_ARE_ADDR_EQUAL(&iap
->addr
, &ia
->addr
))
515 /* Cancel any current advertisement. */
516 eloop_timeout_delete(ctx
->eloop
,
517 ipv6nd_sendadvertisement
, iap
);
519 /* Don't advertise what we can't use. */
520 if (iap
->prefix_vltime
== 0 ||
521 iap
->addr_flags
& IN6_IFF_NOTUSEABLE
)
525 iaf
->iface
->metric
> iap
->iface
->metric
)
532 /* Make the packet. */
534 iaf
->na_len
= sizeof(*na
);
536 iaf
->na_len
+= (size_t)ROUNDUP8(ifp
->hwlen
+ 2);
537 na
= calloc(1, iaf
->na_len
);
543 na
->nd_na_type
= ND_NEIGHBOR_ADVERT
;
544 na
->nd_na_flags_reserved
= ND_NA_FLAG_OVERRIDE
;
545 #if defined(PRIVSEP) && (defined(__linux__) || defined(HAVE_PLEDGE))
546 if (IN_PRIVSEP(ctx
)) {
547 if (ps_root_ip6forwarding(ctx
, ifp
->name
) != 0)
548 na
->nd_na_flags_reserved
|= ND_NA_FLAG_ROUTER
;
551 if (ip6_forwarding(ifp
->name
) != 0)
552 na
->nd_na_flags_reserved
|= ND_NA_FLAG_ROUTER
;
553 na
->nd_na_target
= ia
->addr
;
555 if (ifp
->hwlen
!= 0) {
556 struct nd_opt_hdr
*opt
;
558 opt
= (struct nd_opt_hdr
*)(na
+ 1);
559 opt
->nd_opt_type
= ND_OPT_TARGET_LINKADDR
;
560 opt
->nd_opt_len
= (uint8_t)((ROUNDUP8(ifp
->hwlen
+ 2)) >> 3);
561 memcpy(opt
+ 1, ifp
->hwaddr
, ifp
->hwlen
);
567 eloop_timeout_delete(ctx
->eloop
, ipv6nd_sendadvertisement
, iaf
);
568 ipv6nd_sendadvertisement(iaf
);
570 #elif !defined(SMALL)
571 #warning kernel does not support userland sending ND6 advertisements
572 #endif /* ND6_ADVERTISE */
575 ipv6nd_expire(void *arg
)
577 struct interface
*ifp
= arg
;
580 if (ifp
->ctx
->ra_routers
== NULL
)
583 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
584 if (rap
->iface
== ifp
&& rap
->willexpire
)
585 rap
->doexpire
= true;
587 ipv6nd_expirera(ifp
);
591 ipv6nd_startexpire(struct interface
*ifp
)
595 if (ifp
->ctx
->ra_routers
== NULL
)
598 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
599 if (rap
->iface
== ifp
)
600 rap
->willexpire
= true;
602 eloop_q_timeout_add_sec(ifp
->ctx
->eloop
, ELOOP_IPV6RA_EXPIRE
,
603 RTR_CARRIER_EXPIRE
, ipv6nd_expire
, ifp
);
607 ipv6nd_rtpref(struct ra
*rap
)
610 switch (rap
->flags
& ND_RA_FLAG_RTPREF_MASK
) {
611 case ND_RA_FLAG_RTPREF_HIGH
:
613 case ND_RA_FLAG_RTPREF_MEDIUM
:
614 case ND_RA_FLAG_RTPREF_RSV
:
615 return RTPREF_MEDIUM
;
616 case ND_RA_FLAG_RTPREF_LOW
:
619 logerrx("%s: impossible RA flag %x", __func__
, rap
->flags
);
620 return RTPREF_INVALID
;
626 ipv6nd_sortrouters(struct dhcpcd_ctx
*ctx
)
628 struct ra_head sorted_routers
= TAILQ_HEAD_INITIALIZER(sorted_routers
);
629 struct ra
*ra1
, *ra2
;
631 while ((ra1
= TAILQ_FIRST(ctx
->ra_routers
)) != NULL
) {
632 TAILQ_REMOVE(ctx
->ra_routers
, ra1
, next
);
633 TAILQ_FOREACH(ra2
, &sorted_routers
, next
) {
634 if (ra1
->iface
->metric
> ra2
->iface
->metric
)
636 if (ra1
->expired
&& !ra2
->expired
)
638 if (ra1
->willexpire
&& !ra2
->willexpire
)
640 if (ra1
->lifetime
== 0 && ra2
->lifetime
!= 0)
642 if (!ra1
->isreachable
&& ra2
->reachable
)
644 if (ipv6nd_rtpref(ra1
) <= ipv6nd_rtpref(ra2
))
646 /* All things being equal, prefer older routers. */
647 /* We don't need to check time, becase newer
648 * routers are always added to the tail and then
650 TAILQ_INSERT_BEFORE(ra2
, ra1
, next
);
654 TAILQ_INSERT_TAIL(&sorted_routers
, ra1
, next
);
657 TAILQ_CONCAT(ctx
->ra_routers
, &sorted_routers
, next
);
661 ipv6nd_applyra(struct interface
*ifp
)
664 struct rs_state
*state
= RS_STATE(ifp
);
667 .hoplimit
= IPV6_DEFHLIM
,
668 .reachable
= REACHABLE_TIME
,
669 .retrans
= RETRANS_TIMER
,
672 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
673 if (rap
->iface
== ifp
)
677 /* If we have no Router Advertisement, then set default values. */
678 if (rap
== NULL
|| rap
->expired
|| rap
->willexpire
)
681 state
->retrans
= rap
->retrans
;
682 if (if_applyra(rap
) == -1 && errno
!= ENOENT
)
687 * Neighbour reachability.
689 * RFC 4681 6.2.5 says when a node is no longer a router it MUST
690 * send a RA with a zero lifetime.
691 * All OS's I know of set the NA router flag if they are a router
692 * or not and disregard that they are actively advertising or
693 * shutting down. If the interface is disabled, it cant't send a NA at all.
695 * As such we CANNOT rely on the NA Router flag and MUST use
696 * unreachability or receive a RA with a lifetime of zero to remove
697 * the node as a default router.
700 ipv6nd_neighbour(struct dhcpcd_ctx
*ctx
, struct in6_addr
*addr
, bool reachable
)
702 struct ra
*rap
, *rapr
;
704 if (ctx
->ra_routers
== NULL
)
707 TAILQ_FOREACH(rap
, ctx
->ra_routers
, next
) {
708 if (IN6_ARE_ADDR_EQUAL(&rap
->from
, addr
))
712 if (rap
== NULL
|| rap
->expired
|| rap
->isreachable
== reachable
)
715 rap
->isreachable
= reachable
;
716 loginfox("%s: %s is %s", rap
->iface
->name
, rap
->sfrom
,
717 reachable
? "reachable again" : "unreachable");
719 /* See if we can install a reachable default router. */
720 ipv6nd_sortrouters(ctx
);
721 ipv6nd_applyra(rap
->iface
);
722 rt_build(ctx
, AF_INET6
);
727 /* If we have no reachable default routers, try and solicit one. */
728 TAILQ_FOREACH(rapr
, ctx
->ra_routers
, next
) {
729 if (rap
== rapr
|| rap
->iface
!= rapr
->iface
)
731 if (rapr
->isreachable
&& !rapr
->expired
&& rapr
->lifetime
)
736 ipv6nd_startrs(rap
->iface
);
739 const struct ipv6_addr
*
740 ipv6nd_iffindaddr(const struct interface
*ifp
, const struct in6_addr
*addr
,
744 struct ipv6_addr
*ap
;
746 if (ifp
->ctx
->ra_routers
== NULL
)
749 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
750 if (rap
->iface
!= ifp
)
752 TAILQ_FOREACH(ap
, &rap
->addrs
, next
) {
753 if (ipv6_findaddrmatch(ap
, addr
, flags
))
761 ipv6nd_findaddr(struct dhcpcd_ctx
*ctx
, const struct in6_addr
*addr
,
765 struct ipv6_addr
*ap
;
767 if (ctx
->ra_routers
== NULL
)
770 TAILQ_FOREACH(rap
, ctx
->ra_routers
, next
) {
771 TAILQ_FOREACH(ap
, &rap
->addrs
, next
) {
772 if (ipv6_findaddrmatch(ap
, addr
, flags
))
779 static struct ipv6_addr
*
780 ipv6nd_rapfindprefix(struct ra
*rap
,
781 const struct in6_addr
*pfx
, uint8_t pfxlen
)
783 struct ipv6_addr
*ia
;
785 TAILQ_FOREACH(ia
, &rap
->addrs
, next
) {
786 if (ia
->prefix_vltime
== 0)
788 if (ia
->prefix_len
== pfxlen
&&
789 IN6_ARE_ADDR_EQUAL(&ia
->prefix
, pfx
))
796 ipv6nd_iffindprefix(struct interface
*ifp
,
797 const struct in6_addr
*pfx
, uint8_t pfxlen
)
800 struct ipv6_addr
*ia
;
803 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
804 if (rap
->iface
!= ifp
)
806 ia
= ipv6nd_rapfindprefix(rap
, pfx
, pfxlen
);
814 ipv6nd_removefreedrop_ra(struct ra
*rap
, int remove_ra
, int drop_ra
)
817 eloop_timeout_delete(rap
->iface
->ctx
->eloop
, NULL
, rap
->iface
);
818 eloop_timeout_delete(rap
->iface
->ctx
->eloop
, NULL
, rap
);
820 TAILQ_REMOVE(rap
->iface
->ctx
->ra_routers
, rap
, next
);
821 ipv6_freedrop_addrs(&rap
->addrs
, drop_ra
, NULL
);
827 ipv6nd_freedrop_ra(struct ra
*rap
, int drop
)
830 ipv6nd_removefreedrop_ra(rap
, 1, drop
);
834 ipv6nd_free(struct interface
*ifp
)
836 struct rs_state
*state
;
837 struct ra
*rap
, *ran
;
838 struct dhcpcd_ctx
*ctx
;
841 state
= RS_STATE(ifp
);
847 eloop_event_delete(ctx
->eloop
, state
->nd_fd
);
852 ifp
->if_data
[IF_DATA_IPV6ND
] = NULL
;
854 TAILQ_FOREACH_SAFE(rap
, ifp
->ctx
->ra_routers
, next
, ran
) {
855 if (rap
->iface
== ifp
) {
862 /* If we don't have any more IPv6 enabled interfaces,
863 * close the global socket and release resources */
864 TAILQ_FOREACH(ifp
, ctx
->ifaces
, next
) {
869 if (ctx
->nd_fd
!= -1) {
870 eloop_event_delete(ctx
->eloop
, ctx
->nd_fd
);
881 ipv6nd_scriptrun(struct ra
*rap
)
883 int hasdns
, hasaddress
;
884 struct ipv6_addr
*ap
;
887 /* If all addresses have completed DAD run the script */
888 TAILQ_FOREACH(ap
, &rap
->addrs
, next
) {
889 if ((ap
->flags
& (IPV6_AF_AUTOCONF
| IPV6_AF_ADDED
)) ==
890 (IPV6_AF_AUTOCONF
| IPV6_AF_ADDED
))
893 if (!(ap
->flags
& IPV6_AF_DADCOMPLETED
) &&
894 ipv6_iffindaddr(ap
->iface
, &ap
->addr
,
896 ap
->flags
|= IPV6_AF_DADCOMPLETED
;
897 if ((ap
->flags
& IPV6_AF_DADCOMPLETED
) == 0) {
898 logdebugx("%s: waiting for Router Advertisement"
906 /* If we don't require RDNSS then set hasdns = 1 so we fork */
907 if (!(rap
->iface
->options
->options
& DHCPCD_IPV6RA_REQRDNSS
))
910 hasdns
= rap
->hasdns
;
913 script_runreason(rap
->iface
, "ROUTERADVERT");
914 if (hasdns
&& (hasaddress
||
915 !(rap
->flags
& (ND_RA_FLAG_MANAGED
| ND_RA_FLAG_OTHER
))))
916 dhcpcd_daemonise(rap
->iface
->ctx
);
918 else if (options
& DHCPCD_DAEMONISE
&&
919 !(options
& DHCPCD_DAEMONISED
) && new_data
)
920 logwarnx("%s: did not fork due to an absent"
921 " RDNSS option in the RA",
927 ipv6nd_addaddr(void *arg
)
929 struct ipv6_addr
*ap
= arg
;
931 ipv6_addaddr(ap
, NULL
);
935 ipv6nd_dadcompleted(const struct interface
*ifp
)
937 const struct ra
*rap
;
938 const struct ipv6_addr
*ap
;
940 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
941 if (rap
->iface
!= ifp
)
943 TAILQ_FOREACH(ap
, &rap
->addrs
, next
) {
944 if (ap
->flags
& IPV6_AF_AUTOCONF
&&
945 ap
->flags
& IPV6_AF_ADDED
&&
946 !(ap
->flags
& IPV6_AF_DADCOMPLETED
))
954 ipv6nd_dadcallback(void *arg
)
956 struct ipv6_addr
*ia
= arg
, *rapap
;
957 struct interface
*ifp
;
959 int wascompleted
, found
;
960 char buf
[INET6_ADDRSTRLEN
];
965 wascompleted
= (ia
->flags
& IPV6_AF_DADCOMPLETED
);
966 ia
->flags
|= IPV6_AF_DADCOMPLETED
;
967 if (ia
->addr_flags
& IN6_IFF_DUPLICATED
) {
969 logwarnx("%s: DAD detected %s", ifp
->name
, ia
->saddr
);
971 /* Try and make another stable private address.
972 * Because ap->dadcounter is always increamented,
973 * a different address is generated. */
974 /* XXX Cache DAD counter per prefix/id/ssid? */
975 if (ifp
->options
->options
& DHCPCD_SLAACPRIVATE
&&
980 if (ia
->dadcounter
>= IDGEN_RETRIES
) {
981 logerrx("%s: unable to obtain a"
982 " stable private address",
986 loginfox("%s: deleting address %s",
987 ifp
->name
, ia
->saddr
);
988 if (if_address6(RTM_DELADDR
, ia
) == -1 &&
989 errno
!= EADDRNOTAVAIL
&& errno
!= ENXIO
)
991 dadcounter
= ia
->dadcounter
;
992 if (ipv6_makestableprivate(&ia
->addr
,
993 &ia
->prefix
, ia
->prefix_len
,
994 ifp
, &dadcounter
) == -1)
996 logerr("ipv6_makestableprivate");
999 ia
->dadcounter
= dadcounter
;
1000 ia
->flags
&= ~(IPV6_AF_ADDED
| IPV6_AF_DADCOMPLETED
);
1001 ia
->flags
|= IPV6_AF_NEW
;
1002 p
= inet_ntop(AF_INET6
, &ia
->addr
, buf
, sizeof(buf
));
1009 ia
->saddr
[0] = '\0';
1010 delay
= arc4random_uniform(IDGEN_DELAY
* MSEC_PER_SEC
);
1011 eloop_timeout_add_msec(ifp
->ctx
->eloop
, delay
,
1012 ipv6nd_addaddr
, ia
);
1018 if (!wascompleted
) {
1019 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
1020 if (rap
->iface
!= ifp
)
1024 TAILQ_FOREACH(rapap
, &rap
->addrs
, next
) {
1025 if (rapap
->flags
& IPV6_AF_AUTOCONF
&&
1026 rapap
->flags
& IPV6_AF_ADDED
&&
1027 (rapap
->flags
& IPV6_AF_DADCOMPLETED
) == 0)
1036 if (wascompleted
&& found
) {
1037 logdebugx("%s: Router Advertisement DAD "
1040 ipv6nd_scriptrun(rap
);
1043 #ifdef ND6_ADVERTISE
1044 ipv6nd_advertise(ia
);
1049 static struct ipv6_addr
*
1050 ipv6nd_findmarkstale(struct ra
*rap
, struct ipv6_addr
*ia
, bool mark
)
1052 struct dhcpcd_ctx
*ctx
= ia
->iface
->ctx
;
1054 struct ipv6_addr
*ia2
;
1056 TAILQ_FOREACH(rap2
, ctx
->ra_routers
, next
) {
1058 rap2
->iface
!= rap
->iface
||
1061 TAILQ_FOREACH(ia2
, &rap2
->addrs
, next
) {
1062 if (!IN6_ARE_ADDR_EQUAL(&ia
->prefix
, &ia2
->prefix
))
1064 if (!(ia2
->flags
& IPV6_AF_STALE
))
1067 ia2
->prefix_pltime
= 0;
1074 /* If DHCPv6 is compiled out, supply a shim to provide an error message
1075 * if IPv6RA requests DHCPv6. */
1081 dhcp6_start(__unused
struct interface
*ifp
, __unused
enum DH6S init_state
)
1090 ipv6nd_handlera(struct dhcpcd_ctx
*ctx
,
1091 const struct sockaddr_in6
*from
, const char *sfrom
,
1092 struct interface
*ifp
, struct icmp6_hdr
*icp
, size_t len
, int hoplimit
)
1095 struct nd_router_advert
*nd_ra
;
1096 struct nd_opt_hdr ndo
;
1097 struct nd_opt_prefix_info pi
;
1098 struct nd_opt_mtu mtu
;
1099 struct nd_opt_rdnss rdnss
;
1102 struct in6_addr pi_prefix
;
1103 struct ipv6_addr
*ia
;
1104 struct dhcp_opt
*dho
;
1105 bool new_rap
, new_data
, has_address
;
1106 uint32_t old_lifetime
;
1110 #ifdef IPV6_MANAGETEMPADDR
1114 if (ifp
== NULL
|| RS_STATE(ifp
) == NULL
) {
1116 logdebugx("RA for unexpected interface from %s", sfrom
);
1121 if (len
< sizeof(struct nd_router_advert
)) {
1122 logerrx("IPv6 RA packet too short from %s", sfrom
);
1126 /* RFC 4861 7.1.2 */
1127 if (hoplimit
!= 255) {
1128 logerrx("invalid hoplimit(%d) in RA from %s", hoplimit
, sfrom
);
1131 if (!IN6_IS_ADDR_LINKLOCAL(&from
->sin6_addr
)) {
1132 logerrx("RA from non local address %s", sfrom
);
1136 if (!(ifp
->options
->options
& DHCPCD_IPV6RS
)) {
1138 logerrx("%s: unexpected RA from %s", ifp
->name
, sfrom
);
1143 /* We could receive a RA before we sent a RS*/
1144 if (ipv6_linklocal(ifp
) == NULL
) {
1146 logdebugx("%s: received RA from %s (no link-local)",
1152 if (ipv6_iffindaddr(ifp
, &from
->sin6_addr
, IN6_IFF_TENTATIVE
)) {
1153 logdebugx("%s: ignoring RA from ourself %s",
1158 #ifdef NOCARRIER_PRESERVE_IP
1160 * Because we preserve RA's and expire them quickly after
1161 * carrier up, it's important to reset the kernels notion of
1162 * reachable timers back to default values before applying
1165 TAILQ_FOREACH(rap
, ctx
->ra_routers
, next
) {
1166 if (ifp
== rap
->iface
)
1169 if (rap
!= NULL
&& rap
->willexpire
)
1170 ipv6nd_applyra(ifp
);
1173 TAILQ_FOREACH(rap
, ctx
->ra_routers
, next
) {
1174 if (ifp
== rap
->iface
&&
1175 IN6_ARE_ADDR_EQUAL(&rap
->from
, &from
->sin6_addr
))
1179 nd_ra
= (struct nd_router_advert
*)icp
;
1181 /* We don't want to spam the log with the fact we got an RA every
1182 * 30 seconds or so, so only spam the log if it's different. */
1183 if (rap
== NULL
|| (rap
->data_len
!= len
||
1184 memcmp(rap
->data
, (unsigned char *)icp
, rap
->data_len
) != 0))
1194 rap
= calloc(1, sizeof(*rap
));
1200 rap
->from
= from
->sin6_addr
;
1201 strlcpy(rap
->sfrom
, sfrom
, sizeof(rap
->sfrom
));
1202 TAILQ_INIT(&rap
->addrs
);
1204 rap
->isreachable
= true;
1207 if (rap
->data_len
== 0) {
1208 rap
->data
= malloc(len
);
1209 if (rap
->data
== NULL
) {
1215 memcpy(rap
->data
, icp
, len
);
1216 rap
->data_len
= len
;
1219 /* We could change the debug level based on new_data, but some
1220 * routers like to decrease the advertised valid and preferred times
1221 * in accordance with the own prefix times which would result in too
1222 * much needless log spam. */
1223 if (rap
->willexpire
)
1225 loglevel
= new_rap
|| rap
->willexpire
|| !rap
->isreachable
?
1226 LOG_INFO
: LOG_DEBUG
,
1227 logmessage(loglevel
, "%s: Router Advertisement from %s",
1228 ifp
->name
, rap
->sfrom
);
1230 clock_gettime(CLOCK_MONOTONIC
, &rap
->acquired
);
1231 rap
->flags
= nd_ra
->nd_ra_flags_reserved
;
1232 old_lifetime
= rap
->lifetime
;
1233 rap
->lifetime
= ntohs(nd_ra
->nd_ra_router_lifetime
);
1234 if (!new_rap
&& rap
->lifetime
== 0 && old_lifetime
!= 0)
1235 logwarnx("%s: %s: no longer a default router",
1236 ifp
->name
, rap
->sfrom
);
1237 if (nd_ra
->nd_ra_curhoplimit
!= 0)
1238 rap
->hoplimit
= nd_ra
->nd_ra_curhoplimit
;
1240 rap
->hoplimit
= IPV6_DEFHLIM
;
1241 if (nd_ra
->nd_ra_reachable
!= 0) {
1242 rap
->reachable
= ntohl(nd_ra
->nd_ra_reachable
);
1243 if (rap
->reachable
> MAX_REACHABLE_TIME
)
1246 rap
->reachable
= REACHABLE_TIME
;
1247 if (nd_ra
->nd_ra_retransmit
!= 0)
1248 rap
->retrans
= ntohl(nd_ra
->nd_ra_retransmit
);
1250 rap
->retrans
= RETRANS_TIMER
;
1251 rap
->expired
= rap
->willexpire
= rap
->doexpire
= false;
1252 rap
->hasdns
= false;
1253 rap
->isreachable
= true;
1254 has_address
= false;
1257 #ifdef IPV6_AF_TEMPORARY
1258 ipv6_markaddrsstale(ifp
, IPV6_AF_TEMPORARY
);
1260 TAILQ_FOREACH(ia
, &rap
->addrs
, next
) {
1261 ia
->flags
|= IPV6_AF_STALE
;
1264 len
-= sizeof(struct nd_router_advert
);
1265 p
= ((uint8_t *)icp
) + sizeof(struct nd_router_advert
);
1266 for (; len
> 0; p
+= olen
, len
-= olen
) {
1267 if (len
< sizeof(ndo
)) {
1268 logerrx("%s: short option", ifp
->name
);
1271 memcpy(&ndo
, p
, sizeof(ndo
));
1272 olen
= (size_t)ndo
.nd_opt_len
* 8;
1274 logerrx("%s: zero length option", ifp
->name
);
1278 logerrx("%s: option length exceeds message",
1283 if (has_option_mask(ifp
->options
->rejectmasknd
,
1286 for (i
= 0, dho
= ctx
->nd_opts
;
1287 i
< ctx
->nd_opts_len
;
1290 if (dho
->option
== ndo
.nd_opt_type
)
1294 logwarnx("%s: reject RA (option %s) from %s",
1295 ifp
->name
, dho
->var
, rap
->sfrom
);
1297 logwarnx("%s: reject RA (option %d) from %s",
1298 ifp
->name
, ndo
.nd_opt_type
, rap
->sfrom
);
1300 ipv6nd_removefreedrop_ra(rap
, 0, 0);
1302 ipv6nd_free_ra(rap
);
1306 if (has_option_mask(ifp
->options
->nomasknd
, ndo
.nd_opt_type
))
1309 switch (ndo
.nd_opt_type
) {
1310 case ND_OPT_PREFIX_INFORMATION
:
1311 loglevel
= new_data
? LOG_ERR
: LOG_DEBUG
;
1312 if (ndo
.nd_opt_len
!= 4) {
1313 logmessage(loglevel
,
1314 "%s: invalid option len for prefix",
1318 memcpy(&pi
, p
, sizeof(pi
));
1319 if (pi
.nd_opt_pi_prefix_len
> 128) {
1320 logmessage(loglevel
, "%s: invalid prefix len",
1324 /* nd_opt_pi_prefix is not aligned. */
1325 memcpy(&pi_prefix
, &pi
.nd_opt_pi_prefix
,
1327 if (IN6_IS_ADDR_MULTICAST(&pi_prefix
) ||
1328 IN6_IS_ADDR_LINKLOCAL(&pi_prefix
))
1330 logmessage(loglevel
, "%s: invalid prefix in RA",
1334 if (ntohl(pi
.nd_opt_pi_preferred_time
) >
1335 ntohl(pi
.nd_opt_pi_valid_time
))
1337 logmessage(loglevel
, "%s: pltime > vltime",
1342 flags
= IPV6_AF_RAPFX
;
1343 /* If no flags are set, that means the prefix is
1344 * available via the router. */
1345 if (pi
.nd_opt_pi_flags_reserved
& ND_OPT_PI_FLAG_ONLINK
)
1346 flags
|= IPV6_AF_ONLINK
;
1347 if (pi
.nd_opt_pi_flags_reserved
& ND_OPT_PI_FLAG_AUTO
&&
1348 rap
->iface
->options
->options
&
1349 DHCPCD_IPV6RA_AUTOCONF
)
1350 flags
|= IPV6_AF_AUTOCONF
;
1351 if (pi
.nd_opt_pi_flags_reserved
& ND_OPT_PI_FLAG_ROUTER
)
1352 flags
|= IPV6_AF_ROUTER
;
1354 ia
= ipv6nd_rapfindprefix(rap
,
1355 &pi_prefix
, pi
.nd_opt_pi_prefix_len
);
1357 ia
= ipv6_newaddr(rap
->iface
,
1358 &pi_prefix
, pi
.nd_opt_pi_prefix_len
, flags
);
1361 ia
->prefix
= pi_prefix
;
1362 if (flags
& IPV6_AF_AUTOCONF
)
1363 ia
->dadcallback
= ipv6nd_dadcallback
;
1364 ia
->created
= ia
->acquired
= rap
->acquired
;
1365 TAILQ_INSERT_TAIL(&rap
->addrs
, ia
, next
);
1367 #ifdef IPV6_MANAGETEMPADDR
1368 /* New address to dhcpcd RA handling.
1369 * If the address already exists and a valid
1370 * temporary address also exists then
1371 * extend the existing one rather than
1372 * create a new one */
1373 if (flags
& IPV6_AF_AUTOCONF
&&
1374 ipv6_iffindaddr(ifp
, &ia
->addr
,
1375 IN6_IFF_NOTUSEABLE
) &&
1376 ipv6_settemptime(ia
, 0))
1382 #ifdef IPV6_MANAGETEMPADDR
1386 ia
->flags
&= ~IPV6_AF_STALE
;
1387 ia
->acquired
= rap
->acquired
;
1390 ntohl(pi
.nd_opt_pi_valid_time
);
1392 ntohl(pi
.nd_opt_pi_preferred_time
);
1393 if (ia
->prefix_vltime
!= 0 &&
1394 ia
->flags
& IPV6_AF_AUTOCONF
)
1397 #ifdef IPV6_MANAGETEMPADDR
1398 /* RFC4941 Section 3.3.3 */
1399 if (ia
->flags
& IPV6_AF_AUTOCONF
&&
1400 ia
->iface
->options
->options
& DHCPCD_SLAACTEMP
&&
1401 IA6_CANAUTOCONF(ia
))
1404 if (ipv6_settemptime(ia
, 1) == NULL
)
1407 if (new_ia
&& ia
->prefix_pltime
) {
1408 if (ipv6_createtempaddr(ia
,
1409 &ia
->acquired
) == NULL
)
1410 logerr("ipv6_createtempaddr");
1417 if (len
< sizeof(mtu
)) {
1418 logmessage(loglevel
, "%s: short MTU option", ifp
->name
);
1421 memcpy(&mtu
, p
, sizeof(mtu
));
1422 mtu
.nd_opt_mtu_mtu
= ntohl(mtu
.nd_opt_mtu_mtu
);
1423 if (mtu
.nd_opt_mtu_mtu
< IPV6_MMTU
) {
1424 logmessage(loglevel
, "%s: invalid MTU %d",
1425 ifp
->name
, mtu
.nd_opt_mtu_mtu
);
1428 ifmtu
= if_getmtu(ifp
);
1430 logerr("if_getmtu");
1431 else if (mtu
.nd_opt_mtu_mtu
> (uint32_t)ifmtu
) {
1432 logmessage(loglevel
, "%s: advertised MTU %d"
1433 " is greater than link MTU %d",
1434 ifp
->name
, mtu
.nd_opt_mtu_mtu
, ifmtu
);
1435 rap
->mtu
= (uint32_t)ifmtu
;
1437 rap
->mtu
= mtu
.nd_opt_mtu_mtu
;
1440 if (len
< sizeof(rdnss
)) {
1441 logmessage(loglevel
, "%s: short RDNSS option", ifp
->name
);
1444 memcpy(&rdnss
, p
, sizeof(rdnss
));
1445 if (rdnss
.nd_opt_rdnss_lifetime
&&
1446 rdnss
.nd_opt_rdnss_len
> 1)
1454 for (i
= 0, dho
= ctx
->nd_opts
;
1455 i
< ctx
->nd_opts_len
;
1458 if (has_option_mask(ifp
->options
->requiremasknd
,
1461 logwarnx("%s: reject RA (no option %s) from %s",
1462 ifp
->name
, dho
->var
, rap
->sfrom
);
1464 ipv6nd_removefreedrop_ra(rap
, 0, 0);
1466 ipv6nd_free_ra(rap
);
1471 TAILQ_FOREACH(ia
, &rap
->addrs
, next
) {
1472 if (!(ia
->flags
& IPV6_AF_STALE
) || ia
->prefix_pltime
== 0)
1474 if (ipv6nd_findmarkstale(rap
, ia
, false) != NULL
)
1476 ipv6nd_findmarkstale(rap
, ia
, true);
1477 logdebugx("%s: %s: became stale", ifp
->name
, ia
->saddr
);
1478 /* Technically this violates RFC 4861 6.3.4,
1479 * but we need a mechanism to tell the kernel to
1480 * try and prefer other addresses. */
1481 ia
->prefix_pltime
= 0;
1484 if (new_data
&& !has_address
&& rap
->lifetime
&& !ipv6_anyglobal(ifp
))
1485 logwarnx("%s: no global addresses for default route",
1489 TAILQ_INSERT_TAIL(ctx
->ra_routers
, rap
, next
);
1491 ipv6nd_sortrouters(ifp
->ctx
);
1493 if (ifp
->ctx
->options
& DHCPCD_TEST
) {
1494 script_runreason(ifp
, "TEST");
1497 ipv6nd_applyra(ifp
);
1498 ipv6_addaddrs(&rap
->addrs
);
1499 #ifdef IPV6_MANAGETEMPADDR
1500 ipv6_addtempaddrs(ifp
, &rap
->acquired
);
1503 rt_build(ifp
->ctx
, AF_INET6
);
1504 ipv6nd_scriptrun(rap
);
1506 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, ifp
);
1507 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, rap
); /* reachable timer */
1510 if (!(ifp
->options
->options
& DHCPCD_DHCP6
))
1512 /* Only log a DHCPv6 start error if compiled in or debugging is enabled. */
1514 #define LOG_DHCP6 logerr
1516 #define LOG_DHCP6 logdebug
1518 if (rap
->flags
& ND_RA_FLAG_MANAGED
) {
1519 if (new_data
&& dhcp6_start(ifp
, DH6S_REQUEST
) == -1)
1520 LOG_DHCP6("dhcp6_start: %s", ifp
->name
);
1521 } else if (rap
->flags
& ND_RA_FLAG_OTHER
) {
1522 if (new_data
&& dhcp6_start(ifp
, DH6S_INFORM
) == -1)
1523 LOG_DHCP6("dhcp6_start: %s", ifp
->name
);
1527 logdebugx("%s: No DHCPv6 instruction in RA", ifp
->name
);
1530 if (ifp
->ctx
->options
& DHCPCD_TEST
) {
1531 eloop_exit(ifp
->ctx
->eloop
, EXIT_SUCCESS
);
1536 /* Expire should be called last as the rap object could be destroyed */
1537 ipv6nd_expirera(ifp
);
1541 ipv6nd_hasralifetime(const struct interface
*ifp
, bool lifetime
)
1543 const struct ra
*rap
;
1545 if (ifp
->ctx
->ra_routers
) {
1546 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
)
1547 if (rap
->iface
== ifp
&&
1549 (!lifetime
||rap
->lifetime
))
1556 ipv6nd_hasradhcp(const struct interface
*ifp
, bool managed
)
1558 const struct ra
*rap
;
1560 if (ifp
->ctx
->ra_routers
) {
1561 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
1562 if (rap
->iface
== ifp
&&
1563 !rap
->expired
&& !rap
->willexpire
&&
1564 ((managed
&& rap
->flags
& ND_RA_FLAG_MANAGED
) ||
1565 (!managed
&& rap
->flags
& ND_RA_FLAG_OTHER
)))
1572 static const uint8_t *
1573 ipv6nd_getoption(struct dhcpcd_ctx
*ctx
,
1574 size_t *os
, unsigned int *code
, size_t *len
,
1575 const uint8_t *od
, size_t ol
, struct dhcp_opt
**oopt
)
1577 struct nd_opt_hdr ndo
;
1579 struct dhcp_opt
*opt
;
1587 memcpy(&ndo
, od
, sizeof(ndo
));
1588 i
= (size_t)(ndo
.nd_opt_len
* 8);
1594 *code
= ndo
.nd_opt_type
;
1597 for (i
= 0, opt
= ctx
->nd_opts
;
1598 i
< ctx
->nd_opts_len
; i
++, opt
++)
1600 if (opt
->option
== *code
) {
1607 return od
+ sizeof(ndo
);
1612 ipv6nd_env(FILE *fp
, const struct interface
*ifp
)
1614 size_t i
, j
, n
, len
, olen
;
1617 struct dhcp_opt
*opt
;
1619 struct nd_opt_hdr ndo
;
1620 struct ipv6_addr
*ia
;
1621 struct timespec now
;
1624 clock_gettime(CLOCK_MONOTONIC
, &now
);
1626 TAILQ_FOREACH(rap
, ifp
->ctx
->ra_routers
, next
) {
1627 if (rap
->iface
!= ifp
|| rap
->expired
)
1630 snprintf(ndprefix
, sizeof(ndprefix
), "nd%zu", i
);
1631 if (efprintf(fp
, "%s_from=%s", ndprefix
, rap
->sfrom
) == -1)
1633 if (efprintf(fp
, "%s_acquired=%lld", ndprefix
,
1634 (long long)rap
->acquired
.tv_sec
) == -1)
1636 if (efprintf(fp
, "%s_now=%lld", ndprefix
,
1637 (long long)now
.tv_sec
) == -1)
1639 if (efprintf(fp
, "%s_hoplimit=%u", ndprefix
, rap
->hoplimit
) == -1)
1641 pref
= ipv6nd_rtpref(rap
);
1642 if (efprintf(fp
, "%s_flags=%s%s%s%s%s", ndprefix
,
1643 rap
->flags
& ND_RA_FLAG_MANAGED
? "M" : "",
1644 rap
->flags
& ND_RA_FLAG_OTHER
? "O" : "",
1645 rap
->flags
& ND_RA_FLAG_HOME_AGENT
? "H" : "",
1646 pref
== RTPREF_HIGH
? "h" : pref
== RTPREF_LOW
? "l" : "",
1647 rap
->flags
& ND_RA_FLAG_PROXY
? "P" : "") == -1)
1649 if (efprintf(fp
, "%s_lifetime=%u", ndprefix
, rap
->lifetime
) == -1)
1652 /* Zero our indexes */
1653 for (j
= 0, opt
= rap
->iface
->ctx
->nd_opts
;
1654 j
< rap
->iface
->ctx
->nd_opts_len
;
1656 dhcp_zero_index(opt
);
1657 for (j
= 0, opt
= rap
->iface
->options
->nd_override
;
1658 j
< rap
->iface
->options
->nd_override_len
;
1660 dhcp_zero_index(opt
);
1662 /* Unlike DHCP, ND6 options *may* occur more than once.
1663 * There is also no provision for option concatenation
1665 len
= rap
->data_len
- sizeof(struct nd_router_advert
);
1666 for (p
= rap
->data
+ sizeof(struct nd_router_advert
);
1668 p
+= olen
, len
-= olen
)
1670 memcpy(&ndo
, p
, sizeof(ndo
));
1671 olen
= (size_t)(ndo
.nd_opt_len
* 8);
1676 if (has_option_mask(rap
->iface
->options
->nomasknd
,
1679 for (j
= 0, opt
= rap
->iface
->options
->nd_override
;
1680 j
< rap
->iface
->options
->nd_override_len
;
1682 if (opt
->option
== ndo
.nd_opt_type
)
1684 if (j
== rap
->iface
->options
->nd_override_len
) {
1685 for (j
= 0, opt
= rap
->iface
->ctx
->nd_opts
;
1686 j
< rap
->iface
->ctx
->nd_opts_len
;
1688 if (opt
->option
== ndo
.nd_opt_type
)
1690 if (j
== rap
->iface
->ctx
->nd_opts_len
)
1695 dhcp_envoption(rap
->iface
->ctx
, fp
,
1696 ndprefix
, rap
->iface
->name
,
1697 opt
, ipv6nd_getoption
,
1698 p
+ sizeof(ndo
), olen
- sizeof(ndo
));
1701 /* We need to output the addresses we actually made
1702 * from the prefix information options as well. */
1704 TAILQ_FOREACH(ia
, &rap
->addrs
, next
) {
1705 if (!(ia
->flags
& IPV6_AF_AUTOCONF
) ||
1706 #ifdef IPV6_AF_TEMPORARY
1707 ia
->flags
& IPV6_AF_TEMPORARY
||
1709 !(ia
->flags
& IPV6_AF_ADDED
) ||
1710 ia
->prefix_vltime
== 0)
1712 if (efprintf(fp
, "%s_addr%zu=%s",
1713 ndprefix
, ++j
, ia
->saddr
) == -1)
1721 ipv6nd_handleifa(int cmd
, struct ipv6_addr
*addr
, pid_t pid
)
1725 /* IPv6 init may not have happened yet if we are learning
1726 * existing addresses when dhcpcd starts. */
1727 if (addr
->iface
->ctx
->ra_routers
== NULL
)
1730 TAILQ_FOREACH(rap
, addr
->iface
->ctx
->ra_routers
, next
) {
1731 if (rap
->iface
!= addr
->iface
)
1733 ipv6_handleifa_addrs(cmd
, &rap
->addrs
, addr
, pid
);
1738 ipv6nd_expirera(void *arg
)
1740 struct interface
*ifp
;
1741 struct ra
*rap
, *ran
;
1742 struct timespec now
;
1744 bool expired
, valid
;
1745 struct ipv6_addr
*ia
;
1748 struct nd_opt_hdr ndo
;
1750 struct nd_opt_prefix_info pi
;
1752 struct nd_opt_dnssl dnssl
;
1753 struct nd_opt_rdnss rdnss
;
1754 unsigned int next
= 0, ltime
;
1755 size_t nexpired
= 0;
1758 clock_gettime(CLOCK_MONOTONIC
, &now
);
1761 TAILQ_FOREACH_SAFE(rap
, ifp
->ctx
->ra_routers
, next
, ran
) {
1762 if (rap
->iface
!= ifp
|| rap
->expired
)
1765 if (rap
->lifetime
) {
1766 elapsed
= (uint32_t)eloop_timespec_diff(&now
,
1767 &rap
->acquired
, NULL
);
1768 if (elapsed
>= rap
->lifetime
|| rap
->doexpire
) {
1769 if (!rap
->expired
) {
1770 logwarnx("%s: %s: router expired",
1771 ifp
->name
, rap
->sfrom
);
1777 ltime
= rap
->lifetime
- elapsed
;
1778 if (next
== 0 || ltime
< next
)
1783 /* Not every prefix is tied to an address which
1784 * the kernel can expire, so we need to handle it ourself.
1785 * Also, some OS don't support address lifetimes (Solaris). */
1786 TAILQ_FOREACH(ia
, &rap
->addrs
, next
) {
1787 if (ia
->prefix_vltime
== 0)
1789 if (ia
->prefix_vltime
== ND6_INFINITE_LIFETIME
&&
1795 elapsed
= (uint32_t)eloop_timespec_diff(&now
,
1796 &ia
->acquired
, NULL
);
1797 if (elapsed
>= ia
->prefix_vltime
|| rap
->doexpire
) {
1798 if (ia
->flags
& IPV6_AF_ADDED
) {
1799 logwarnx("%s: expired %s %s",
1801 ia
->flags
& IPV6_AF_AUTOCONF
?
1802 "address" : "prefix",
1804 if (if_address6(RTM_DELADDR
, ia
)== -1 &&
1805 errno
!= EADDRNOTAVAIL
&&
1809 ia
->prefix_vltime
= ia
->prefix_pltime
= 0;
1811 ~(IPV6_AF_ADDED
| IPV6_AF_DADCOMPLETED
);
1815 ltime
= ia
->prefix_vltime
- elapsed
;
1816 if (next
== 0 || ltime
< next
)
1821 /* Work out expiry for ND options */
1822 elapsed
= (uint32_t)eloop_timespec_diff(&now
,
1823 &rap
->acquired
, NULL
);
1824 len
= rap
->data_len
- sizeof(struct nd_router_advert
);
1825 for (p
= rap
->data
+ sizeof(struct nd_router_advert
);
1827 p
+= olen
, len
-= olen
)
1829 memcpy(&ndo
, p
, sizeof(ndo
));
1830 olen
= (size_t)(ndo
.nd_opt_len
* 8);
1836 if (has_option_mask(rap
->iface
->options
->nomasknd
,
1840 switch (ndo
.nd_opt_type
) {
1841 /* Prefix info is already checked in the above loop. */
1843 case ND_OPT_PREFIX_INFORMATION
:
1844 if (len
< sizeof(pi
))
1846 memcpy(&pi
, p
, sizeof(pi
));
1847 ltime
= pi
.nd_opt_pi_valid_time
;
1851 if (len
< sizeof(dnssl
))
1853 memcpy(&dnssl
, p
, sizeof(dnssl
));
1854 ltime
= dnssl
.nd_opt_dnssl_lifetime
;
1857 if (len
< sizeof(rdnss
))
1859 memcpy(&rdnss
, p
, sizeof(rdnss
));
1860 ltime
= rdnss
.nd_opt_rdnss_lifetime
;
1868 if (rap
->doexpire
) {
1872 if (ltime
== ND6_INFINITE_LIFETIME
) {
1877 ltime
= ntohl(ltime
);
1878 if (elapsed
>= ltime
) {
1885 if (next
== 0 || ltime
< next
)
1892 /* Router has expired. Let's not keep a lot of them. */
1893 rap
->expired
= true;
1894 if (++nexpired
> EXPIRED_MAX
)
1895 ipv6nd_free_ra(rap
);
1899 eloop_timeout_add_sec(ifp
->ctx
->eloop
,
1900 next
, ipv6nd_expirera
, ifp
);
1902 logwarnx("%s: part of a Router Advertisement expired",
1904 ipv6nd_sortrouters(ifp
->ctx
);
1905 ipv6nd_applyra(ifp
);
1906 rt_build(ifp
->ctx
, AF_INET6
);
1907 script_runreason(ifp
, "ROUTERADVERT");
1912 ipv6nd_drop(struct interface
*ifp
)
1914 struct ra
*rap
, *ran
;
1915 bool expired
= false;
1917 if (ifp
->ctx
->ra_routers
== NULL
)
1920 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, ifp
);
1921 TAILQ_FOREACH_SAFE(rap
, ifp
->ctx
->ra_routers
, next
, ran
) {
1922 if (rap
->iface
== ifp
) {
1923 rap
->expired
= expired
= true;
1924 ipv6nd_drop_ra(rap
);
1928 ipv6nd_applyra(ifp
);
1929 rt_build(ifp
->ctx
, AF_INET6
);
1930 if ((ifp
->options
->options
& DHCPCD_NODROP
) != DHCPCD_NODROP
)
1931 script_runreason(ifp
, "ROUTERADVERT");
1936 ipv6nd_recvmsg(struct dhcpcd_ctx
*ctx
, struct msghdr
*msg
)
1938 struct sockaddr_in6
*from
= (struct sockaddr_in6
*)msg
->msg_name
;
1939 char sfrom
[INET6_ADDRSTRLEN
];
1941 struct icmp6_hdr
*icp
;
1942 struct interface
*ifp
;
1943 size_t len
= msg
->msg_iov
[0].iov_len
;
1945 inet_ntop(AF_INET6
, &from
->sin6_addr
, sfrom
, sizeof(sfrom
));
1946 if ((size_t)len
< sizeof(struct icmp6_hdr
)) {
1947 logerrx("IPv6 ICMP packet too short from %s", sfrom
);
1951 ifp
= if_findifpfromcmsg(ctx
, msg
, &hoplimit
);
1957 /* Don't do anything if the user hasn't configured it. */
1958 if (ifp
->active
!= IF_ACTIVE_USER
||
1959 !(ifp
->options
->options
& DHCPCD_IPV6
))
1962 icp
= (struct icmp6_hdr
*)msg
->msg_iov
[0].iov_base
;
1963 if (icp
->icmp6_code
== 0) {
1964 switch(icp
->icmp6_type
) {
1965 case ND_ROUTER_ADVERT
:
1966 ipv6nd_handlera(ctx
, from
, sfrom
,
1967 ifp
, icp
, (size_t)len
, hoplimit
);
1972 logerrx("invalid IPv6 type %d or code %d from %s",
1973 icp
->icmp6_type
, icp
->icmp6_code
, sfrom
);
1977 ipv6nd_handledata(void *arg
)
1979 struct dhcpcd_ctx
*ctx
;
1981 struct sockaddr_in6 from
;
1983 struct icmp6_hdr hdr
;
1984 uint8_t buf
[64 * 1024]; /* Maximum ICMPv6 size */
1986 struct iovec iov
= {
1987 .iov_base
= iovbuf
.buf
, .iov_len
= sizeof(iovbuf
.buf
),
1991 uint8_t buf
[CMSG_SPACE(sizeof(struct in6_pktinfo
)) +
1992 CMSG_SPACE(sizeof(int))];
1993 } cmsgbuf
= { .buf
= { 0 } };
1994 struct msghdr msg
= {
1995 .msg_name
= &from
, .msg_namelen
= sizeof(from
),
1996 .msg_iov
= &iov
, .msg_iovlen
= 1,
1997 .msg_control
= cmsgbuf
.buf
, .msg_controllen
= sizeof(cmsgbuf
.buf
),
2002 struct interface
*ifp
;
2003 struct rs_state
*state
;
2006 state
= RS_STATE(ifp
);
2013 len
= recvmsg(fd
, &msg
, 0);
2019 iov
.iov_len
= (size_t)len
;
2020 ipv6nd_recvmsg(ctx
, &msg
);
2024 ipv6nd_startrs1(void *arg
)
2026 struct interface
*ifp
= arg
;
2027 struct rs_state
*state
;
2029 loginfox("%s: soliciting an IPv6 router", ifp
->name
);
2030 state
= RS_STATE(ifp
);
2031 if (state
== NULL
) {
2032 ifp
->if_data
[IF_DATA_IPV6ND
] = calloc(1, sizeof(*state
));
2033 state
= RS_STATE(ifp
);
2034 if (state
== NULL
) {
2043 /* Always make a new probe as the underlying hardware
2044 * address could have changed. */
2045 ipv6nd_makersprobe(ifp
);
2046 if (state
->rs
== NULL
) {
2051 state
->retrans
= RETRANS_TIMER
;
2052 state
->rsprobes
= 0;
2053 ipv6nd_sendrsprobe(ifp
);
2057 ipv6nd_startrs(struct interface
*ifp
)
2061 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, ifp
);
2062 if (!(ifp
->options
->options
& DHCPCD_INITIAL_DELAY
)) {
2063 ipv6nd_startrs1(ifp
);
2067 delay
= arc4random_uniform(MAX_RTR_SOLICITATION_DELAY
* MSEC_PER_SEC
);
2068 logdebugx("%s: delaying IPv6 router solicitation for %0.1f seconds",
2069 ifp
->name
, (float)delay
/ MSEC_PER_SEC
);
2070 eloop_timeout_add_msec(ifp
->ctx
->eloop
, delay
, ipv6nd_startrs1
, ifp
);