2 * Copyright (c) 2003-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $FreeBSD: src/sys/netinet6/nd6_rtr.c,v 1.11 2002/04/19 04:46:23 suz Exp $ */
30 /* $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $ */
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/malloc.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
69 #include <sys/kernel.h>
70 #include <sys/errno.h>
71 #include <sys/syslog.h>
72 #include <sys/queue.h>
73 #include <sys/mcache.h>
75 #include <kern/lock.h>
76 #include <kern/zalloc.h>
77 #include <machine/machine_routines.h>
80 #include <net/if_types.h>
81 #include <net/if_dl.h>
82 #include <net/route.h>
83 #include <net/radix.h>
85 #include <netinet/in.h>
86 #include <netinet6/in6_var.h>
87 #include <netinet6/in6_ifattach.h>
88 #include <netinet/ip6.h>
89 #include <netinet6/ip6_var.h>
90 #include <netinet6/nd6.h>
91 #include <netinet/icmp6.h>
92 #include <netinet6/scope6_var.h>
94 #include <net/net_osdep.h>
96 #define SDL(s) ((struct sockaddr_dl *)s)
98 static struct nd_defrouter
*defrtrlist_update_common(struct nd_defrouter
*,
100 static struct nd_defrouter
*defrtrlist_update(struct nd_defrouter
*);
102 static struct in6_ifaddr
*in6_ifadd(struct nd_prefix
*, int);
103 static void defrtrlist_sync(struct ifnet
*);
105 static void defrouter_select_common(struct ifnet
*, int);
107 static struct nd_pfxrouter
*pfxrtr_lookup(struct nd_prefix
*,
108 struct nd_defrouter
*);
109 static void pfxrtr_add(struct nd_prefix
*, struct nd_defrouter
*);
110 static void pfxrtr_del(struct nd_pfxrouter
*);
111 static struct nd_pfxrouter
*find_pfxlist_reachable_router(struct nd_prefix
*);
112 static void nd6_rtmsg(int, struct rtentry
*);
114 static int nd6_prefix_onlink_common(struct nd_prefix
*, boolean_t
,
116 static struct nd_prefix
*nd6_prefix_equal_lookup(struct nd_prefix
*, boolean_t
);
117 static void nd6_prefix_sync(struct ifnet
*);
119 static void in6_init_address_ltimes(struct nd_prefix
*,
120 struct in6_addrlifetime
*, boolean_t
);
122 static int rt6_deleteroute(struct radix_node
*, void *);
124 static struct nd_defrouter
*nddr_alloc(int);
125 static void nddr_free(struct nd_defrouter
*);
126 static void nddr_trace(struct nd_defrouter
*, int);
128 static struct nd_prefix
*ndpr_alloc(int);
129 static void ndpr_free(struct nd_prefix
*);
130 static void ndpr_trace(struct nd_prefix
*, int);
132 extern int nd6_recalc_reachtm_interval
;
134 static struct ifnet
*nd6_defifp
;
136 static unsigned int nd6_defrouter_genid
;
138 int ip6_use_tempaddr
= 1; /* use temp addr by default for testing now */
140 int nd6_accept_6to4
= 1;
142 int ip6_desync_factor
;
143 u_int32_t ip6_temp_preferred_lifetime
= DEF_TEMP_PREFERRED_LIFETIME
;
144 u_int32_t ip6_temp_valid_lifetime
= DEF_TEMP_VALID_LIFETIME
;
146 * shorter lifetimes for debugging purposes.
147 u_int32_t ip6_temp_preferred_lifetime = 800;
148 static u_int32_t ip6_temp_valid_lifetime = 1800;
150 int ip6_temp_regen_advance
= TEMPADDR_REGEN_ADVANCE
;
152 extern lck_mtx_t
*nd6_mutex
;
154 /* Serialization variables for single thread access to nd_prefix */
155 static boolean_t nd_prefix_busy
;
156 static void *nd_prefix_waitchan
= &nd_prefix_busy
;
157 static int nd_prefix_waiters
= 0;
159 /* Serialization variables for single thread access to nd_defrouter */
160 static boolean_t nd_defrouter_busy
;
161 static void *nd_defrouter_waitchan
= &nd_defrouter_busy
;
162 static int nd_defrouter_waiters
= 0;
164 /* RTPREF_MEDIUM has to be 0! */
165 #define RTPREF_HIGH 1
166 #define RTPREF_MEDIUM 0
167 #define RTPREF_LOW (-1)
168 #define RTPREF_RESERVED (-2)
169 #define RTPREF_INVALID (-3) /* internal */
171 #define NDPR_TRACE_HIST_SIZE 32 /* size of trace history */
174 __private_extern__
unsigned int ndpr_trace_hist_size
= NDPR_TRACE_HIST_SIZE
;
176 struct nd_prefix_dbg
{
177 struct nd_prefix ndpr_pr
; /* nd_prefix */
178 u_int16_t ndpr_refhold_cnt
; /* # of ref */
179 u_int16_t ndpr_refrele_cnt
; /* # of rele */
181 * Circular lists of ndpr_addref and ndpr_remref callers.
183 ctrace_t ndpr_refhold
[NDPR_TRACE_HIST_SIZE
];
184 ctrace_t ndpr_refrele
[NDPR_TRACE_HIST_SIZE
];
187 static unsigned int ndpr_debug
; /* debug flags */
188 static unsigned int ndpr_size
; /* size of zone element */
189 static struct zone
*ndpr_zone
; /* zone for nd_prefix */
191 #define NDPR_ZONE_MAX 64 /* maximum elements in zone */
192 #define NDPR_ZONE_NAME "nd6_prefix" /* zone name */
194 #define NDDR_TRACE_HIST_SIZE 32 /* size of trace history */
197 __private_extern__
unsigned int nddr_trace_hist_size
= NDDR_TRACE_HIST_SIZE
;
199 struct nd_defrouter_dbg
{
200 struct nd_defrouter nddr_dr
; /* nd_defrouter */
201 uint16_t nddr_refhold_cnt
; /* # of ref */
202 uint16_t nddr_refrele_cnt
; /* # of rele */
204 * Circular lists of ndpr_addref and ndpr_remref callers.
206 ctrace_t nddr_refhold
[NDDR_TRACE_HIST_SIZE
];
207 ctrace_t nddr_refrele
[NDDR_TRACE_HIST_SIZE
];
210 static unsigned int nddr_debug
; /* debug flags */
211 static unsigned int nddr_size
; /* size of zone element */
212 static struct zone
*nddr_zone
; /* zone for nd_defrouter */
214 #define NDDR_ZONE_MAX 64 /* maximum elements in zone */
215 #define NDDR_ZONE_NAME "nd6_defrouter" /* zone name */
217 static unsigned int ndprtr_size
; /* size of zone element */
218 static struct zone
*ndprtr_zone
; /* zone for nd_pfxrouter */
220 #define NDPRTR_ZONE_MAX 64 /* maximum elements in zone */
221 #define NDPRTR_ZONE_NAME "nd6_pfxrouter" /* zone name */
226 PE_parse_boot_argn("ifa_debug", &ndpr_debug
, sizeof (ndpr_debug
));
227 PE_parse_boot_argn("ifa_debug", &nddr_debug
, sizeof (nddr_debug
));
229 ndpr_size
= (ndpr_debug
== 0) ? sizeof (struct nd_prefix
) :
230 sizeof (struct nd_prefix_dbg
);
231 ndpr_zone
= zinit(ndpr_size
, NDPR_ZONE_MAX
* ndpr_size
, 0,
233 if (ndpr_zone
== NULL
) {
234 panic("%s: failed allocating %s", __func__
, NDPR_ZONE_NAME
);
237 zone_change(ndpr_zone
, Z_EXPAND
, TRUE
);
238 zone_change(ndpr_zone
, Z_CALLERACCT
, FALSE
);
240 nddr_size
= (nddr_debug
== 0) ? sizeof (struct nd_defrouter
) :
241 sizeof (struct nd_defrouter_dbg
);
242 nddr_zone
= zinit(nddr_size
, NDDR_ZONE_MAX
* nddr_size
, 0,
244 if (nddr_zone
== NULL
) {
245 panic("%s: failed allocating %s", __func__
, NDDR_ZONE_NAME
);
248 zone_change(nddr_zone
, Z_EXPAND
, TRUE
);
249 zone_change(nddr_zone
, Z_CALLERACCT
, FALSE
);
251 ndprtr_size
= sizeof (struct nd_pfxrouter
);
252 ndprtr_zone
= zinit(ndprtr_size
, NDPRTR_ZONE_MAX
* ndprtr_size
, 0,
254 if (ndprtr_zone
== NULL
) {
255 panic("%s: failed allocating %s", __func__
, NDPRTR_ZONE_NAME
);
258 zone_change(ndprtr_zone
, Z_EXPAND
, TRUE
);
259 zone_change(ndprtr_zone
, Z_CALLERACCT
, FALSE
);
263 * Receive Router Solicitation Message - just for routers.
264 * Router solicitation/advertisement is mostly managed by userland program
265 * (rtadvd) so here we have no function like nd6_ra_output().
275 struct ifnet
*ifp
= m
->m_pkthdr
.rcvif
;
276 struct ip6_hdr
*ip6
= mtod(m
, struct ip6_hdr
*);
277 struct nd_router_solicit
*nd_rs
;
278 struct in6_addr saddr6
= ip6
->ip6_src
;
281 union nd_opts ndopts
;
283 /* If I'm not a router, ignore it. */
284 if (ip6_accept_rtadv
!= 0 || (ifp
->if_eflags
& IFEF_ACCEPT_RTADVD
) || ip6_forwarding
!= 1)
288 if (ip6
->ip6_hlim
!= 255) {
290 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
291 ip6
->ip6_hlim
, ip6_sprintf(&ip6
->ip6_src
),
292 ip6_sprintf(&ip6
->ip6_dst
), if_name(ifp
)));
297 * Don't update the neighbor cache, if src = :: or a non-neighbor.
298 * The former case indicates that the src has no IP address assigned
299 * yet. See nd6_ns_input() for the latter case.
301 if (IN6_IS_ADDR_UNSPECIFIED(&ip6
->ip6_src
))
304 struct sockaddr_in6 src_sa6
;
306 bzero(&src_sa6
, sizeof(src_sa6
));
307 src_sa6
.sin6_family
= AF_INET6
;
308 src_sa6
.sin6_len
= sizeof(src_sa6
);
309 src_sa6
.sin6_addr
= ip6
->ip6_src
;
310 if (!nd6_is_addr_neighbor(&src_sa6
, ifp
, 0)) {
311 nd6log((LOG_INFO
, "nd6_rs_input: "
312 "RS packet from non-neighbor\n"));
317 #ifndef PULLDOWN_TEST
318 IP6_EXTHDR_CHECK(m
, off
, icmp6len
, return);
319 nd_rs
= (struct nd_router_solicit
*)((caddr_t
)ip6
+ off
);
321 IP6_EXTHDR_GET(nd_rs
, struct nd_router_solicit
*, m
, off
, icmp6len
);
323 icmp6stat
.icp6s_tooshort
++;
328 icmp6len
-= sizeof(*nd_rs
);
329 nd6_option_init(nd_rs
+ 1, icmp6len
, &ndopts
);
330 if (nd6_options(&ndopts
) < 0) {
332 "nd6_rs_input: invalid ND option, ignored\n"));
333 /* nd6_options have incremented stats */
337 if (ndopts
.nd_opts_src_lladdr
) {
338 lladdr
= (char *)(ndopts
.nd_opts_src_lladdr
+ 1);
339 lladdrlen
= ndopts
.nd_opts_src_lladdr
->nd_opt_len
<< 3;
342 if (lladdr
&& ((ifp
->if_addrlen
+ 2 + 7) & ~7) != lladdrlen
) {
344 "nd6_rs_input: lladdrlen mismatch for %s "
345 "(if %d, RS packet %d)\n",
346 ip6_sprintf(&saddr6
), ifp
->if_addrlen
, lladdrlen
- 2));
350 nd6_cache_lladdr(ifp
, &saddr6
, lladdr
, lladdrlen
, ND_ROUTER_SOLICIT
, 0);
357 icmp6stat
.icp6s_badrs
++;
362 * Receive Router Advertisement Message.
365 * TODO: on-link bit on prefix information
366 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing
374 struct ifnet
*ifp
= m
->m_pkthdr
.rcvif
;
375 struct nd_ifinfo
*ndi
= NULL
;
376 struct ip6_hdr
*ip6
= mtod(m
, struct ip6_hdr
*);
377 struct nd_router_advert
*nd_ra
;
378 struct in6_addr saddr6
= ip6
->ip6_src
;
380 union nd_opts ndopts
;
381 struct nd_defrouter
*dr
= NULL
;
382 struct timeval timenow
;
384 getmicrotime(&timenow
);
386 if (ip6_accept_rtadv
== 0 && ((ifp
->if_eflags
& IFEF_ACCEPT_RTADVD
) == 0))
389 if (ip6
->ip6_hlim
!= 255) {
391 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
392 ip6
->ip6_hlim
, ip6_sprintf(&ip6
->ip6_src
),
393 ip6_sprintf(&ip6
->ip6_dst
), if_name(ifp
)));
397 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6
)) {
399 "nd6_ra_input: src %s is not link-local\n",
400 ip6_sprintf(&saddr6
)));
404 #ifndef PULLDOWN_TEST
405 IP6_EXTHDR_CHECK(m
, off
, icmp6len
, return);
406 nd_ra
= (struct nd_router_advert
*)((caddr_t
)ip6
+ off
);
408 IP6_EXTHDR_GET(nd_ra
, struct nd_router_advert
*, m
, off
, icmp6len
);
410 icmp6stat
.icp6s_tooshort
++;
415 icmp6len
-= sizeof(*nd_ra
);
416 nd6_option_init(nd_ra
+ 1, icmp6len
, &ndopts
);
417 if (nd6_options(&ndopts
) < 0) {
419 "nd6_ra_input: invalid ND option, ignored\n"));
420 /* nd6_options have incremented stats */
425 struct nd_defrouter dr0
;
426 u_int32_t advreachable
= nd_ra
->nd_ra_reachable
;
428 /* remember if this is a multicasted advertisement */
429 if (IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
))
432 lck_rw_lock_shared(nd_if_rwlock
);
433 if (ifp
->if_index
>= nd_ifinfo_indexlim
) {
434 lck_rw_done(nd_if_rwlock
);
437 ndi
= &nd_ifinfo
[ifp
->if_index
];
438 bzero(&dr0
, sizeof (dr0
));
440 dr0
.flags
= nd_ra
->nd_ra_flags_reserved
;
441 dr0
.rtlifetime
= ntohs(nd_ra
->nd_ra_router_lifetime
);
442 dr0
.expire
= timenow
.tv_sec
+ dr0
.rtlifetime
;
444 /* unspecified or not? (RFC 2461 6.3.4) */
446 advreachable
= ntohl(advreachable
);
447 if (advreachable
<= MAX_REACHABLE_TIME
&&
448 ndi
->basereachable
!= advreachable
) {
449 ndi
->basereachable
= advreachable
;
450 ndi
->reachable
= ND_COMPUTE_RTIME(ndi
->basereachable
);
451 ndi
->recalctm
= nd6_recalc_reachtm_interval
; /* reset */
454 if (nd_ra
->nd_ra_retransmit
)
455 ndi
->retrans
= ntohl(nd_ra
->nd_ra_retransmit
);
456 if (nd_ra
->nd_ra_curhoplimit
)
457 ndi
->chlim
= nd_ra
->nd_ra_curhoplimit
;
458 lck_rw_done(nd_if_rwlock
);
460 lck_mtx_lock(nd6_mutex
);
461 dr
= defrtrlist_update(&dr0
);
462 lck_mtx_unlock(nd6_mutex
);
468 if (ndopts
.nd_opts_pi
) {
469 struct nd_opt_hdr
*pt
;
470 struct nd_opt_prefix_info
*pi
= NULL
;
473 for (pt
= (struct nd_opt_hdr
*)ndopts
.nd_opts_pi
;
474 pt
<= (struct nd_opt_hdr
*)ndopts
.nd_opts_pi_end
;
475 pt
= (struct nd_opt_hdr
*)((caddr_t
)pt
+
476 (pt
->nd_opt_len
<< 3))) {
477 if (pt
->nd_opt_type
!= ND_OPT_PREFIX_INFORMATION
)
479 pi
= (struct nd_opt_prefix_info
*)pt
;
481 if (pi
->nd_opt_pi_len
!= 4) {
483 "nd6_ra_input: invalid option "
484 "len %d for prefix information option, "
485 "ignored\n", pi
->nd_opt_pi_len
));
489 if (128 < pi
->nd_opt_pi_prefix_len
) {
491 "nd6_ra_input: invalid prefix "
492 "len %d for prefix information option, "
493 "ignored\n", pi
->nd_opt_pi_prefix_len
));
497 if (IN6_IS_ADDR_MULTICAST(&pi
->nd_opt_pi_prefix
)
498 || IN6_IS_ADDR_LINKLOCAL(&pi
->nd_opt_pi_prefix
)) {
500 "nd6_ra_input: invalid prefix "
502 ip6_sprintf(&pi
->nd_opt_pi_prefix
)));
506 bzero(&pr
, sizeof(pr
));
507 lck_mtx_init(&pr
.ndpr_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
509 pr
.ndpr_prefix
.sin6_family
= AF_INET6
;
510 pr
.ndpr_prefix
.sin6_len
= sizeof(pr
.ndpr_prefix
);
511 pr
.ndpr_prefix
.sin6_addr
= pi
->nd_opt_pi_prefix
;
512 pr
.ndpr_ifp
= m
->m_pkthdr
.rcvif
;
514 pr
.ndpr_raf_onlink
= (pi
->nd_opt_pi_flags_reserved
&
515 ND_OPT_PI_FLAG_ONLINK
) ? 1 : 0;
516 pr
.ndpr_raf_auto
= (pi
->nd_opt_pi_flags_reserved
&
517 ND_OPT_PI_FLAG_AUTO
) ? 1 : 0;
518 pr
.ndpr_plen
= pi
->nd_opt_pi_prefix_len
;
519 pr
.ndpr_vltime
= ntohl(pi
->nd_opt_pi_valid_time
);
521 ntohl(pi
->nd_opt_pi_preferred_time
);
524 * Exceptions to stateless autoconfiguration processing:
525 * + nd6_accept_6to4 == 0 && address has 6to4 prefix
526 * + ip6_only_allow_rfc4193_prefix != 0 && address not RFC 4193
528 if (ip6_only_allow_rfc4193_prefix
&&
529 !IN6_IS_ADDR_UNIQUE_LOCAL(&pi
->nd_opt_pi_prefix
)) {
531 "nd6_ra_input: no SLAAC on prefix %s [not RFC 4193]\n",
532 ip6_sprintf(&pi
->nd_opt_pi_prefix
)));
533 pr
.ndpr_raf_auto
= 0;
535 else if (!nd6_accept_6to4
&&
536 IN6_IS_ADDR_6TO4(&pi
->nd_opt_pi_prefix
)) {
538 "nd6_ra_input: no SLAAC on prefix %s [6to4]\n",
539 ip6_sprintf(&pi
->nd_opt_pi_prefix
)));
540 pr
.ndpr_raf_auto
= 0;
543 if (in6_init_prefix_ltimes(&pr
)) {
545 lck_mtx_destroy(&pr
.ndpr_lock
, ifa_mtx_grp
);
546 continue; /* prefix lifetime init failed */
550 (void)prelist_update(&pr
, dr
, m
, mcast
);
551 lck_mtx_destroy(&pr
.ndpr_lock
, ifa_mtx_grp
);
558 if (ndopts
.nd_opts_mtu
&& ndopts
.nd_opts_mtu
->nd_opt_mtu_len
== 1) {
559 u_int32_t mtu
= ntohl(ndopts
.nd_opts_mtu
->nd_opt_mtu_mtu
);
562 if (mtu
< IPV6_MMTU
) {
563 nd6log((LOG_INFO
, "nd6_ra_input: bogus mtu option "
564 "mtu=%d sent from %s, ignoring\n",
565 mtu
, ip6_sprintf(&ip6
->ip6_src
)));
569 lck_rw_lock_shared(nd_if_rwlock
);
570 if (ifp
->if_index
>= nd_ifinfo_indexlim
) {
571 lck_rw_done(nd_if_rwlock
);
574 ndi
= &nd_ifinfo
[ifp
->if_index
];
577 if (mtu
<= ndi
->maxmtu
) {
578 int change
= (ndi
->linkmtu
!= mtu
);
581 lck_rw_done(nd_if_rwlock
);
582 if (change
) /* in6_maxmtu may change */
585 nd6log((LOG_INFO
, "nd6_ra_input: bogus mtu "
586 "mtu=%d sent from %s; "
587 "exceeds maxmtu %d, ignoring\n",
588 mtu
, ip6_sprintf(&ip6
->ip6_src
),
590 lck_rw_done(nd_if_rwlock
);
593 lck_rw_done(nd_if_rwlock
);
594 nd6log((LOG_INFO
, "nd6_ra_input: mtu option "
595 "mtu=%d sent from %s; maxmtu unknown, "
597 mtu
, ip6_sprintf(&ip6
->ip6_src
)));
605 * Source link layer address
611 if (ndopts
.nd_opts_src_lladdr
) {
612 lladdr
= (char *)(ndopts
.nd_opts_src_lladdr
+ 1);
613 lladdrlen
= ndopts
.nd_opts_src_lladdr
->nd_opt_len
<< 3;
616 if (lladdr
&& ((ifp
->if_addrlen
+ 2 + 7) & ~7) != lladdrlen
) {
618 "nd6_ra_input: lladdrlen mismatch for %s "
619 "(if %d, RA packet %d)\n",
620 ip6_sprintf(&saddr6
), ifp
->if_addrlen
, lladdrlen
- 2));
624 nd6_cache_lladdr(ifp
, &saddr6
, lladdr
, lladdrlen
, ND_ROUTER_ADVERT
, 0);
627 * Installing a link-layer address might change the state of the
628 * router's neighbor cache, which might also affect our on-link
629 * detection of adveritsed prefixes.
631 lck_mtx_lock(nd6_mutex
);
632 pfxlist_onlink_check();
633 lck_mtx_unlock(nd6_mutex
);
643 icmp6stat
.icp6s_badra
++;
648 * default router list proccessing sub routines
651 /* tell the change to user processes watching the routing socket. */
657 struct rt_addrinfo info
;
658 struct ifnet
*ifp
= rt
->rt_ifp
;
660 RT_LOCK_ASSERT_HELD(rt
);
662 bzero((caddr_t
)&info
, sizeof(info
));
663 /* Lock ifp for if_lladdr */
664 ifnet_lock_shared(ifp
);
665 info
.rti_info
[RTAX_DST
] = rt_key(rt
);
666 info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
;
667 info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
);
669 * ifa_addr pointers for both should always be valid
670 * in this context; no need to hold locks.
672 info
.rti_info
[RTAX_IFP
] = ifp
->if_lladdr
->ifa_addr
;
673 info
.rti_info
[RTAX_IFA
] = rt
->rt_ifa
->ifa_addr
;
675 rt_missmsg(cmd
, &info
, rt
->rt_flags
, 0);
676 ifnet_lock_done(ifp
);
680 defrouter_addreq(struct nd_defrouter
*new, boolean_t scoped
)
682 struct sockaddr_in6 def
, mask
, gate
;
683 struct rtentry
*newrt
= NULL
;
684 unsigned int ifscope
;
687 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
689 if (new->stateflags
& NDDRF_INSTALLED
)
692 nd6log2((LOG_INFO
, "%s: adding default router %s, scoped=%d, "
693 "static=%d\n", if_name(new->ifp
), ip6_sprintf(&new->rtaddr
),
694 scoped
, (new->stateflags
& NDDRF_STATIC
) ? 1 : 0));
696 Bzero(&def
, sizeof(def
));
697 Bzero(&mask
, sizeof(mask
));
698 Bzero(&gate
, sizeof(gate
));
700 def
.sin6_len
= mask
.sin6_len
= gate
.sin6_len
701 = sizeof(struct sockaddr_in6
);
702 def
.sin6_family
= mask
.sin6_family
= gate
.sin6_family
= AF_INET6
;
703 gate
.sin6_addr
= new->rtaddr
;
705 ifscope
= scoped
? new->ifp
->if_index
: IFSCOPE_NONE
;
707 err
= rtrequest_scoped(RTM_ADD
, (struct sockaddr
*)&def
,
708 (struct sockaddr
*)&gate
, (struct sockaddr
*)&mask
,
709 RTF_GATEWAY
, &newrt
, ifscope
);
713 nd6_rtmsg(RTM_ADD
, newrt
); /* tell user process */
714 RT_REMREF_LOCKED(newrt
);
716 new->stateflags
|= NDDRF_INSTALLED
;
717 if (ifscope
!= IFSCOPE_NONE
)
718 new->stateflags
|= NDDRF_IFSCOPE
;
719 new->genid
= nd6_defrouter_genid
;
721 nd6log((LOG_ERR
, "%s: failed to add default router "
722 "%s on %s scoped %d (errno = %d)\n", __func__
,
723 ip6_sprintf(&gate
.sin6_addr
), if_name(new->ifp
),
724 (ifscope
!= IFSCOPE_NONE
), err
));
729 struct nd_defrouter
*
731 struct in6_addr
*addr
,
734 struct nd_defrouter
*dr
;
736 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
738 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
739 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
741 if (dr
->ifp
== ifp
&& IN6_ARE_ADDR_EQUAL(addr
, &dr
->rtaddr
)) {
742 NDDR_ADDREF_LOCKED(dr
);
749 return (NULL
); /* search failed */
753 * Remove the default route for a given router.
754 * This is just a subroutine function for defrouter_select(), and should
755 * not be called from anywhere else.
758 defrouter_delreq(struct nd_defrouter
*dr
)
760 struct sockaddr_in6 def
, mask
, gate
;
761 struct rtentry
*oldrt
= NULL
;
762 unsigned int ifscope
;
765 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
767 /* ifp would be NULL for the "drany" case */
768 if (dr
->ifp
!= NULL
&& !(dr
->stateflags
& NDDRF_INSTALLED
))
771 NDDR_LOCK_ASSERT_HELD(dr
);
773 nd6log2((LOG_INFO
, "%s: removing default router %s, scoped=%d, "
774 "static=%d\n", dr
->ifp
!= NULL
? if_name(dr
->ifp
) : "ANY",
775 ip6_sprintf(&dr
->rtaddr
), (dr
->stateflags
& NDDRF_IFSCOPE
) ? 1 : 0,
776 (dr
->stateflags
& NDDRF_STATIC
) ? 1 : 0));
778 Bzero(&def
, sizeof(def
));
779 Bzero(&mask
, sizeof(mask
));
780 Bzero(&gate
, sizeof(gate
));
782 def
.sin6_len
= mask
.sin6_len
= gate
.sin6_len
783 = sizeof(struct sockaddr_in6
);
784 def
.sin6_family
= mask
.sin6_family
= gate
.sin6_family
= AF_INET6
;
785 gate
.sin6_addr
= dr
->rtaddr
;
787 if (dr
->ifp
!= NULL
) {
788 ifscope
= (dr
->stateflags
& NDDRF_IFSCOPE
) ?
789 dr
->ifp
->if_index
: IFSCOPE_NONE
;
791 ifscope
= IFSCOPE_NONE
;
793 err
= rtrequest_scoped(RTM_DELETE
,
794 (struct sockaddr
*)&def
, (struct sockaddr
*)&gate
,
795 (struct sockaddr
*)&mask
, RTF_GATEWAY
, &oldrt
, ifscope
);
799 nd6_rtmsg(RTM_DELETE
, oldrt
);
802 } else if (err
!= ESRCH
) {
803 nd6log((LOG_ERR
, "%s: failed to delete default router "
804 "%s on %s scoped %d (errno = %d)\n", __func__
,
805 ip6_sprintf(&gate
.sin6_addr
), dr
->ifp
!= NULL
?
806 if_name(dr
->ifp
) : "ANY", (ifscope
!= IFSCOPE_NONE
), err
));
808 /* ESRCH means it's no longer in the routing table; ignore it */
809 if (oldrt
!= NULL
|| err
== ESRCH
) {
810 dr
->stateflags
&= ~NDDRF_INSTALLED
;
811 if (ifscope
!= IFSCOPE_NONE
)
812 dr
->stateflags
&= ~NDDRF_IFSCOPE
;
819 * remove all default routes from default router list
822 defrouter_reset(void)
824 struct nd_defrouter
*dr
, drany
;
826 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
828 dr
= TAILQ_FIRST(&nd_defrouter
);
831 if (dr
->stateflags
& NDDRF_INSTALLED
) {
832 NDDR_ADDREF_LOCKED(dr
);
834 lck_mtx_unlock(nd6_mutex
);
836 defrouter_delreq(dr
);
838 lck_mtx_lock(nd6_mutex
);
840 dr
= TAILQ_FIRST(&nd_defrouter
);
843 dr
= TAILQ_NEXT(dr
, dr_entry
);
847 /* Nuke primary (non-scoped) default router */
848 if (ip6_doscopedroute
) {
849 bzero(&drany
, sizeof (drany
));
850 lck_mtx_init(&drany
.nddr_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
851 lck_mtx_unlock(nd6_mutex
);
853 defrouter_delreq(&drany
);
855 lck_mtx_destroy(&drany
.nddr_lock
, ifa_mtx_grp
);
856 lck_mtx_lock(nd6_mutex
);
862 defrtrlist_ioctl(u_long cmd
, caddr_t data
)
864 struct in6_defrouter_32
*r_32
= (struct in6_defrouter_32
*)data
;
865 struct in6_defrouter_64
*r_64
= (struct in6_defrouter_64
*)data
;
866 struct nd_defrouter dr0
;
867 unsigned int ifindex
;
868 struct ifnet
*dr_ifp
;
869 int error
= 0, add
= 0;
872 case SIOCDRADD_IN6_32
:
873 case SIOCDRADD_IN6_64
:
876 case SIOCDRDEL_IN6_32
:
877 case SIOCDRDEL_IN6_64
:
878 bzero(&dr0
, sizeof (dr0
));
879 if (cmd
== SIOCDRADD_IN6_64
|| cmd
== SIOCDRDEL_IN6_64
) {
880 dr0
.rtaddr
= r_64
->rtaddr
.sin6_addr
;
881 dr0
.flags
= r_64
->flags
;
882 ifindex
= r_64
->if_index
;
884 dr0
.rtaddr
= r_32
->rtaddr
.sin6_addr
;
885 dr0
.flags
= r_32
->flags
;
886 ifindex
= r_32
->if_index
;
888 ifnet_head_lock_shared();
889 /* Don't need to check is ifindex is < 0 since it's unsigned */
890 if (if_index
< ifindex
||
891 (dr_ifp
= ifindex2ifnet
[ifindex
]) == NULL
) {
899 if (IN6_IS_SCOPE_EMBED(&dr0
.rtaddr
)) {
900 uint16_t *scope
= &dr0
.rtaddr
.s6_addr16
[1];
903 *scope
= htons(dr_ifp
->if_index
);
904 } else if (*scope
!= htons(dr_ifp
->if_index
)) {
911 error
= defrtrlist_add_static(&dr0
);
912 if (!add
|| error
!= 0) {
913 int err
= defrtrlist_del_static(&dr0
);
920 error
= EOPNOTSUPP
; /* check for safety */
928 defrtrlist_del(struct nd_defrouter
*dr
)
930 struct nd_defrouter
*deldr
= NULL
;
931 struct nd_prefix
*pr
;
932 struct ifnet
*ifp
= dr
->ifp
;
934 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
937 * Flush all the routing table entries that use the router
940 if (!ip6_forwarding
&&
941 (ip6_accept_rtadv
|| (ifp
->if_eflags
& IFEF_ACCEPT_RTADVD
))) {
942 /* above is a good condition? */
944 lck_mtx_unlock(nd6_mutex
);
945 rt6_flush(&dr
->rtaddr
, ifp
);
946 lck_mtx_lock(nd6_mutex
);
950 if (dr
== TAILQ_FIRST(&nd_defrouter
))
951 deldr
= dr
; /* The router is primary. */
953 TAILQ_REMOVE(&nd_defrouter
, dr
, dr_entry
);
954 ++nd6_defrouter_genid
;
956 nd6log2((LOG_INFO
, "%s: freeing defrouter %s\n", if_name(dr
->ifp
),
957 ip6_sprintf(&dr
->rtaddr
)));
960 * Delete it from the routing table.
963 lck_mtx_unlock(nd6_mutex
);
965 defrouter_delreq(dr
);
967 lck_mtx_lock(nd6_mutex
);
971 * Also delete all the pointers to the router in each prefix lists.
973 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
974 struct nd_pfxrouter
*pfxrtr
;
977 if ((pfxrtr
= pfxrtr_lookup(pr
, dr
)) != NULL
)
982 pfxlist_onlink_check();
985 * If the router is the primary one, choose a new one. If Scoped
986 * Routing is enabled, always try to pick another eligible router
989 if ((deldr
|| ip6_doscopedroute
) && !ip6_forwarding
&&
990 (ip6_accept_rtadv
|| (ifp
->if_eflags
& IFEF_ACCEPT_RTADVD
)))
991 defrouter_select(ifp
);
993 lck_rw_lock_shared(nd_if_rwlock
);
994 if (ifp
->if_index
< nd_ifinfo_indexlim
) {
995 struct nd_ifinfo
*ndi
= &nd_ifinfo
[ifp
->if_index
];
996 atomic_add_32(&ndi
->ndefrouters
, -1);
997 if (ndi
->ndefrouters
< 0) {
998 log(LOG_WARNING
, "defrtrlist_del: negative "
999 "count on %s\n", if_name(ifp
));
1002 lck_rw_done(nd_if_rwlock
);
1004 NDDR_REMREF(dr
); /* remove list reference */
1008 defrtrlist_add_static(struct nd_defrouter
*new)
1010 struct nd_defrouter
*dr
;
1013 new->rtlifetime
= -1;
1014 new->stateflags
|= NDDRF_STATIC
;
1016 /* we only want the preference level */
1017 new->flags
&= ND_RA_FLAG_RTPREF_MASK
;
1019 lck_mtx_lock(nd6_mutex
);
1020 dr
= defrouter_lookup(&new->rtaddr
, new->ifp
);
1021 if (dr
!= NULL
&& !(dr
->stateflags
& NDDRF_STATIC
)) {
1026 dr
= defrtrlist_update(new);
1034 lck_mtx_unlock(nd6_mutex
);
1040 defrtrlist_del_static(struct nd_defrouter
*new)
1042 struct nd_defrouter
*dr
;
1044 lck_mtx_lock(nd6_mutex
);
1045 dr
= defrouter_lookup(&new->rtaddr
, new->ifp
);
1046 if (dr
== NULL
|| !(dr
->stateflags
& NDDRF_STATIC
)) {
1054 lck_mtx_unlock(nd6_mutex
);
1056 return (dr
!= NULL
? 0 : EINVAL
);
1060 * for default router selection
1061 * regards router-preference field as a 2-bit signed integer
1064 rtpref(struct nd_defrouter
*dr
)
1066 switch (dr
->flags
& ND_RA_FLAG_RTPREF_MASK
) {
1067 case ND_RA_FLAG_RTPREF_HIGH
:
1068 return (RTPREF_HIGH
);
1069 case ND_RA_FLAG_RTPREF_MEDIUM
:
1070 case ND_RA_FLAG_RTPREF_RSV
:
1071 return (RTPREF_MEDIUM
);
1072 case ND_RA_FLAG_RTPREF_LOW
:
1073 return (RTPREF_LOW
);
1076 * This case should never happen. If it did, it would mean a
1077 * serious bug of kernel internal. We thus always bark here.
1078 * Or, can we even panic?
1080 log(LOG_ERR
, "rtpref: impossible RA flag %x\n", dr
->flags
);
1081 return (RTPREF_INVALID
);
1087 * Default Router Selection according to Section 6.3.6 of RFC 2461 and
1088 * draft-ietf-ipngwg-router-selection:
1090 * 1) Routers that are reachable or probably reachable should be preferred.
1091 * If we have more than one (probably) reachable router, prefer ones
1092 * with the highest router preference.
1093 * 2) When no routers on the list are known to be reachable or
1094 * probably reachable, routers SHOULD be selected in a round-robin
1095 * fashion, regardless of router preference values.
1096 * 3) If the Default Router List is empty, assume that all
1097 * destinations are on-link.
1099 * When Scoped Routing is enabled, the selection logic is amended as follows:
1101 * a) When a default interface is specified, the primary/non-scoped default
1102 * router will be set to the reachable router on that link (if any) with
1103 * the highest router preference.
1104 * b) When there are more than one routers on the same link, the one with
1105 * the highest router preference will be installed, either as scoped or
1106 * non-scoped route entry. If they all share the same preference value,
1107 * the one installed will be the static or the first encountered reachable
1108 * router, i.e. static one wins over dynamic.
1109 * c) When no routers on the list are known to be reachable, or probably
1110 * reachable, no round-robin selection will take place when the default
1113 * We assume nd_defrouter is sorted by router preference value.
1114 * Since the code below covers both with and without router preference cases,
1115 * we do not need to classify the cases by ifdef.
1118 defrouter_select_common(struct ifnet
*ifp
, int ignore
)
1120 struct nd_defrouter
*dr
, *selected_dr
= NULL
, *installed_dr
= NULL
;
1121 struct nd_defrouter
*installed_dr0
= NULL
;
1122 struct rtentry
*rt
= NULL
;
1123 struct llinfo_nd6
*ln
= NULL
;
1125 boolean_t found_installedrt
= FALSE
;
1127 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1130 * This function should be called only when acting as an autoconfigured
1131 * host. Although the remaining part of this function is not effective
1132 * if the node is not an autoconfigured host, we explicitly exclude
1133 * such cases here for safety.
1135 if (ip6_forwarding
|| (!ignore
&& !ip6_accept_rtadv
&&
1136 !(ifp
->if_eflags
& IFEF_ACCEPT_RTADVD
))) {
1137 nd6log((LOG_WARNING
,
1138 "defrouter_select: called unexpectedly (forwarding=%d, "
1139 "accept_rtadv=%d)\n", ip6_forwarding
, ip6_accept_rtadv
));
1144 * Let's handle easy case (3) first:
1145 * If default router list is empty, there's nothing to be done.
1147 if (!TAILQ_FIRST(&nd_defrouter
))
1151 * Due to the number of times we drop nd6_mutex, we need to
1152 * serialize this function.
1154 while (nd_defrouter_busy
) {
1155 nd_defrouter_waiters
++;
1156 msleep(nd_defrouter_waitchan
, nd6_mutex
, (PZERO
-1),
1158 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1160 nd_defrouter_busy
= TRUE
;
1163 * Search for a (probably) reachable router from the list.
1164 * We just pick up the first reachable one (if any), assuming that
1165 * the ordering rule of the list described in defrtrlist_update().
1167 * For all intents and purposes of Scoped Routing:
1168 * selected_dr = candidate for primary router
1169 * installed_dr = currently installed primary router
1171 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
1172 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
1173 boolean_t reachable
;
1175 /* Callee returns a locked route upon success */
1177 NDDR_ADDREF(dr
); /* for this for loop */
1178 lck_mtx_unlock(nd6_mutex
);
1179 if ((rt
= nd6_lookup(&dr
->rtaddr
, 0, dr
->ifp
, 0)) != NULL
) {
1180 RT_LOCK_ASSERT_HELD(rt
);
1181 if ((ln
= rt
->rt_llinfo
) != NULL
&&
1182 ND6_IS_LLINFO_PROBREACH(ln
)) {
1184 if (selected_dr
== NULL
&&
1185 (!ip6_doscopedroute
||
1186 dr
->ifp
== nd6_defifp
)) {
1188 NDDR_ADDREF(selected_dr
);
1191 RT_REMREF_LOCKED(rt
);
1195 lck_mtx_lock(nd6_mutex
);
1197 /* Handle case (b) */
1198 if (ip6_doscopedroute
&& dr
->ifp
== nd6_defifp
&&
1199 (selected_dr
== NULL
|| rtpref(dr
) > rtpref(selected_dr
) ||
1200 (rtpref(dr
) == rtpref(selected_dr
) &&
1201 (dr
->stateflags
& NDDRF_STATIC
) &&
1202 !(selected_dr
->stateflags
& NDDRF_STATIC
)))) {
1204 NDDR_REMREF(selected_dr
);
1206 NDDR_ADDREF(selected_dr
);
1209 if (!(dr
->stateflags
& NDDRF_INSTALLED
)) {
1211 * If the router hasn't been installed and it is
1212 * reachable, try to install it later on below.
1213 * If it's static, try to install it anyway.
1215 if (reachable
|| (dr
->stateflags
& NDDRF_STATIC
)) {
1218 nd6log2((LOG_INFO
, "%s: possible router %s, "
1219 "scoped=%d, static=%d\n", if_name(dr
->ifp
),
1220 ip6_sprintf(&dr
->rtaddr
),
1221 (dr
->stateflags
& NDDRF_IFSCOPE
) ? 1 : 0,
1222 (dr
->stateflags
& NDDRF_STATIC
) ? 1 : 0));
1224 NDDR_REMREF(dr
); /* for this for loop */
1228 /* Record the currently installed primary/non-scoped router */
1229 if (!ip6_doscopedroute
|| !(dr
->stateflags
& NDDRF_IFSCOPE
)) {
1230 if (installed_dr
== NULL
) {
1232 NDDR_ADDREF(installed_dr
);
1234 /* this should not happen; warn for diagnosis */
1235 log(LOG_ERR
, "defrouter_select: more than one "
1236 "%s default router is installed\n",
1237 ip6_doscopedroute
? "non-scoped" : "");
1240 NDDR_REMREF(dr
); /* for this for loop */
1243 /* If none was selected, use the currently installed one */
1244 if (ip6_doscopedroute
&& selected_dr
== NULL
&& installed_dr
!= NULL
) {
1245 selected_dr
= installed_dr
;
1246 NDDR_ADDREF(selected_dr
);
1250 * Install the unreachable one(s) if necesssary.
1252 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
1253 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
1254 struct nd_defrouter
*_dr
;
1256 if (!ip6_doscopedroute
)
1261 /* If already (or will be) installed, skip */
1262 if ((dr
->stateflags
& NDDRF_INSTALLED
) || dr
->genid
== -1) {
1267 /* See if there is already a default router for the link */
1268 for (_dr
= TAILQ_FIRST(&nd_defrouter
); _dr
;
1269 _dr
= TAILQ_NEXT(_dr
, dr_entry
)) {
1272 if (_dr
== dr
|| _dr
->ifp
!= dr
->ifp
) {
1278 if ((_dr
->stateflags
& NDDRF_INSTALLED
) ||
1288 /* If none so far, schedule it to be installed below */
1292 nd6log2((LOG_INFO
, "%s: possible router %s, "
1293 "static=%d (unreachable)\n", if_name(dr
->ifp
),
1294 ip6_sprintf(&dr
->rtaddr
),
1295 (dr
->stateflags
& NDDRF_STATIC
) ? 1 : 0));
1302 nd6log2((LOG_INFO
, "%s: considering primary default router %s, "
1303 "static=%d [round 1]\n", if_name(dr
->ifp
),
1304 ip6_sprintf(&dr
->rtaddr
),
1305 (dr
->stateflags
& NDDRF_STATIC
) ? 1 : 0));
1309 * If none of the default routers was found to be reachable,
1310 * round-robin the list regardless of preference, except when
1311 * Scoped Routing is enabled per case (c).
1313 * Otherwise, if we have an installed router, check if the selected
1314 * (reachable) router should really be preferred to the installed one.
1315 * We only prefer the new router when the old one is not reachable
1316 * or when the new one has a really higher preference value.
1318 if (!ip6_doscopedroute
&& selected_dr
== NULL
) {
1319 if (installed_dr
== NULL
||
1320 !TAILQ_NEXT(installed_dr
, dr_entry
)) {
1321 selected_dr
= TAILQ_FIRST(&nd_defrouter
);
1323 NDDR_ADDREF(selected_dr
);
1325 selected_dr
= TAILQ_NEXT(installed_dr
, dr_entry
);
1327 NDDR_ADDREF(selected_dr
);
1329 } else if (selected_dr
!= NULL
&& installed_dr
!= NULL
) {
1330 lck_mtx_unlock(nd6_mutex
);
1331 rt
= nd6_lookup(&installed_dr
->rtaddr
, 0, installed_dr
->ifp
, 0);
1333 RT_LOCK_ASSERT_HELD(rt
);
1334 if ((ln
= (struct llinfo_nd6
*)rt
->rt_llinfo
) &&
1335 ND6_IS_LLINFO_PROBREACH(ln
) &&
1336 (!ip6_doscopedroute
||
1337 installed_dr
->ifp
== nd6_defifp
) &&
1338 rtpref(selected_dr
) <= rtpref(installed_dr
)) {
1339 NDDR_REMREF(selected_dr
);
1340 selected_dr
= installed_dr
;
1341 NDDR_ADDREF(selected_dr
);
1343 RT_REMREF_LOCKED(rt
);
1346 found_installedrt
= TRUE
;
1348 lck_mtx_lock(nd6_mutex
);
1351 if (ip6_doscopedroute
) {
1353 * If the installed primary router is not on the current
1354 * IPv6 default interface, demote it to a scoped entry.
1356 if (installed_dr
!= NULL
&& installed_dr
->ifp
!= nd6_defifp
&&
1357 !(installed_dr
->stateflags
& NDDRF_IFSCOPE
)) {
1358 if (selected_dr
!= NULL
&&
1359 selected_dr
->ifp
!= nd6_defifp
) {
1360 NDDR_REMREF(selected_dr
);
1367 * If the selected router is currently scoped, make sure
1368 * we update (it needs to be promoted to primary.)
1370 if (selected_dr
!= NULL
&&
1371 (selected_dr
->stateflags
& NDDRF_IFSCOPE
))
1375 * If the installed router is no longe reachable, remove
1376 * it and install the selected router instead.
1378 if (installed_dr
!= NULL
&& selected_dr
!= NULL
&&
1379 installed_dr
!= selected_dr
&& found_installedrt
== FALSE
) {
1380 installed_dr0
= installed_dr
; /* skip it below */
1381 /* NB: we previousled referenced installed_dr */
1382 installed_dr
= NULL
;
1383 selected_dr
->genid
= -1;
1389 * If Scoped Routing is enabled and there's nothing to update,
1390 * just return. Otherwise, if Scoped Routing is disabled and if
1391 * the selected router is different than the installed one,
1392 * remove the installed router and install the selected one.
1395 VERIFY(dr
!= NULL
|| ip6_doscopedroute
);
1396 if (!ip6_doscopedroute
|| !update
) {
1400 if (dr
!= installed_dr
) {
1401 nd6log2((LOG_INFO
, "%s: no update, selected router %s, "
1402 "installed router %s\n", if_name(dr
->ifp
),
1403 ip6_sprintf(&dr
->rtaddr
), installed_dr
!= NULL
?
1404 ip6_sprintf(&installed_dr
->rtaddr
) : "NONE"));
1406 nd6log2((LOG_INFO
, "%s: no update, router is %s\n",
1407 if_name(dr
->ifp
), ip6_sprintf(&dr
->rtaddr
)));
1409 if (!ip6_doscopedroute
&& installed_dr
!= dr
) {
1411 * No need to ADDREF dr because at this point
1412 * dr points to selected_dr, which already holds
1415 lck_mtx_unlock(nd6_mutex
);
1417 NDDR_LOCK(installed_dr
);
1418 defrouter_delreq(installed_dr
);
1419 NDDR_UNLOCK(installed_dr
);
1422 defrouter_addreq(dr
, FALSE
);
1424 lck_mtx_lock(nd6_mutex
);
1430 * Scoped Routing is enabled and we need to update. The selected
1431 * router needs to be installed as primary/non-scoped entry. If
1432 * there is any existing entry that is non-scoped, remove it from
1433 * the routing table and reinstall it as scoped entry.
1436 nd6log2((LOG_INFO
, "%s: considering primary default router %s, "
1437 "static=%d [round 2]\n", if_name(dr
->ifp
),
1438 ip6_sprintf(&dr
->rtaddr
),
1439 (dr
->stateflags
& NDDRF_STATIC
) ? 1 : 0));
1443 * On the following while loops we use two flags:
1447 * genid is used to skip entries that are not to be added/removed on the
1448 * second while loop.
1449 * NDDRF_PROCESSED is used to skip entries that were already processed.
1450 * This is necessary because we drop the nd6_mutex and start the while
1453 TAILQ_FOREACH(dr
, &nd_defrouter
, dr_entry
) {
1455 VERIFY((dr
->stateflags
& NDDRF_PROCESSED
) == 0);
1458 /* Remove conflicting entries */
1459 dr
= TAILQ_FIRST(&nd_defrouter
);
1462 if (!(dr
->stateflags
& NDDRF_INSTALLED
) ||
1463 dr
->stateflags
& NDDRF_PROCESSED
) {
1465 dr
= TAILQ_NEXT(dr
, dr_entry
);
1468 dr
->stateflags
|= NDDRF_PROCESSED
;
1470 /* A NULL selected_dr will remove primary default route */
1471 if ((dr
== selected_dr
&& (dr
->stateflags
& NDDRF_IFSCOPE
)) ||
1472 (dr
!= selected_dr
&& !(dr
->stateflags
& NDDRF_IFSCOPE
))) {
1473 NDDR_ADDREF_LOCKED(dr
);
1475 lck_mtx_unlock(nd6_mutex
);
1477 defrouter_delreq(dr
);
1479 lck_mtx_lock(nd6_mutex
);
1481 if (dr
&& dr
!= installed_dr0
)
1486 * Since we lost nd6_mutex, we have to start over.
1488 dr
= TAILQ_FIRST(&nd_defrouter
);
1492 dr
= TAILQ_NEXT(dr
, dr_entry
);
1495 /* -1 is a special number, make sure we don't use it for genid */
1496 if (++nd6_defrouter_genid
== -1)
1497 nd6_defrouter_genid
= 1;
1499 TAILQ_FOREACH(dr
, &nd_defrouter
, dr_entry
) {
1501 dr
->stateflags
&= ~NDDRF_PROCESSED
;
1504 /* Add the entries back */
1505 dr
= TAILQ_FIRST(&nd_defrouter
);
1507 struct nd_defrouter
*_dr
;
1510 if (dr
->stateflags
& NDDRF_PROCESSED
||
1513 dr
= TAILQ_NEXT(dr
, dr_entry
);
1516 dr
->stateflags
|= NDDRF_PROCESSED
;
1518 /* Handle case (b) */
1519 for (_dr
= TAILQ_FIRST(&nd_defrouter
); _dr
;
1520 _dr
= TAILQ_NEXT(_dr
, dr_entry
)) {
1524 * This is safe because we previously checked if
1528 if (_dr
->ifp
== dr
->ifp
&& rtpref(_dr
) >= rtpref(dr
) &&
1529 (_dr
->stateflags
& NDDRF_INSTALLED
)) {
1530 NDDR_ADDREF_LOCKED(_dr
);
1537 /* If same preference and i/f, static entry takes precedence */
1538 if (_dr
!= NULL
&& rtpref(_dr
) == rtpref(dr
) &&
1539 !(_dr
->stateflags
& NDDRF_STATIC
) &&
1540 (dr
->stateflags
& NDDRF_STATIC
)) {
1541 lck_mtx_unlock(nd6_mutex
);
1543 defrouter_delreq(_dr
);
1545 lck_mtx_lock(nd6_mutex
);
1550 if (_dr
== NULL
&& !(dr
->stateflags
& NDDRF_INSTALLED
)) {
1551 NDDR_ADDREF_LOCKED(dr
);
1553 lck_mtx_unlock(nd6_mutex
);
1555 defrouter_addreq(dr
, (selected_dr
== NULL
||
1556 dr
->ifp
!= selected_dr
->ifp
));
1557 dr
->genid
= nd6_defrouter_genid
;
1559 lck_mtx_lock(nd6_mutex
);
1562 * Since we lost nd6_mutex, we have to start over.
1564 dr
= TAILQ_FIRST(&nd_defrouter
);
1568 dr
= TAILQ_NEXT(dr
, dr_entry
);
1571 TAILQ_FOREACH(dr
, &nd_defrouter
, dr_entry
) {
1573 dr
->stateflags
&= ~NDDRF_PROCESSED
;
1577 NDDR_REMREF(selected_dr
);
1579 NDDR_REMREF(installed_dr
);
1581 NDDR_REMREF(installed_dr0
);
1582 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1583 VERIFY(nd_defrouter_busy
);
1584 nd_defrouter_busy
= FALSE
;
1585 if (nd_defrouter_waiters
> 0) {
1586 nd_defrouter_waiters
= 0;
1587 wakeup(nd_defrouter_waitchan
);
1592 defrouter_select(struct ifnet
*ifp
)
1594 return (defrouter_select_common(ifp
, 0));
1597 static struct nd_defrouter
*
1598 defrtrlist_update_common(struct nd_defrouter
*new, boolean_t scoped
)
1600 struct nd_defrouter
*dr
, *n
;
1601 struct ifnet
*ifp
= new->ifp
;
1602 struct nd_ifinfo
*ndi
;
1604 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1606 if ((dr
= defrouter_lookup(&new->rtaddr
, ifp
)) != NULL
) {
1608 if (new->rtlifetime
== 0) {
1613 int oldpref
= rtpref(dr
);
1616 dr
->flags
= new->flags
; /* xxx flag check */
1617 dr
->rtlifetime
= new->rtlifetime
;
1618 dr
->expire
= new->expire
;
1621 * If the preference does not change, there's no need
1622 * to sort the entries. If Scoped Routing is enabled,
1623 * put the primary/non-scoped router at the top of the
1624 * list of routers in the same preference band, unless
1625 * it's already at that position.
1627 if (ip6_doscopedroute
) {
1628 struct nd_defrouter
*p
= NULL
;
1630 /* same preference and scoped; just return */
1631 if (rtpref(new) == oldpref
&& scoped
)
1634 n
= TAILQ_FIRST(&nd_defrouter
);
1636 /* preference changed; sort it */
1637 if (rtpref(new) != oldpref
)
1640 /* not at the top of band; sort it */
1641 if (n
!= dr
&& rtpref(n
) == oldpref
&&
1642 (!p
|| rtpref(p
) > rtpref(n
)))
1646 n
= TAILQ_NEXT(n
, dr_entry
);
1649 /* nothing has changed, just return */
1650 if (n
== NULL
&& (scoped
||
1651 !(dr
->stateflags
& NDDRF_IFSCOPE
)))
1653 } else if (rtpref(new) == oldpref
) {
1658 * preferred router may be changed, so relocate
1660 * XXX: calling TAILQ_REMOVE directly is a bad manner.
1661 * However, since defrtrlist_del() has many side
1662 * effects, we intentionally do so here.
1663 * defrouter_select() below will handle routing
1666 TAILQ_REMOVE(&nd_defrouter
, dr
, dr_entry
);
1667 new->stateflags
= dr
->stateflags
;
1668 new->stateflags
&= ~NDDRF_PROCESSED
;
1670 lck_rw_lock_shared(nd_if_rwlock
);
1671 VERIFY(ifp
->if_index
< nd_ifinfo_indexlim
);
1672 ndi
= &nd_ifinfo
[ifp
->if_index
];
1673 lck_rw_done(nd_if_rwlock
);
1682 /* entry does not exist */
1683 if (new->rtlifetime
== 0) {
1687 n
= nddr_alloc(M_WAITOK
);
1692 lck_rw_lock_shared(nd_if_rwlock
);
1693 ndi
= &nd_ifinfo
[ifp
->if_index
];
1694 if (ifp
->if_index
>= nd_ifinfo_indexlim
)
1696 if (ip6_maxifdefrouters
>= 0 &&
1697 ndi
->ndefrouters
>= ip6_maxifdefrouters
) {
1699 lck_rw_done(nd_if_rwlock
);
1704 NDDR_ADDREF(n
); /* for the nd_defrouter list */
1705 NDDR_ADDREF(n
); /* for the caller */
1707 ++nd6_defrouter_genid
;
1708 atomic_add_32(&ndi
->ndefrouters
, 1);
1709 lck_rw_done(nd_if_rwlock
);
1711 nd6log2((LOG_INFO
, "%s: allocating defrouter %s\n", if_name(ifp
),
1712 ip6_sprintf(&new->rtaddr
)));
1715 memcpy(&n
->rtaddr
, &new->rtaddr
, sizeof(n
->rtaddr
));
1716 n
->flags
= new->flags
;
1717 n
->stateflags
= new->stateflags
;
1718 n
->stateflags
&= ~NDDRF_PROCESSED
;
1719 n
->rtlifetime
= new->rtlifetime
;
1720 n
->expire
= new->expire
;
1722 n
->genid
= new->genid
;
1728 * Insert the new router in the Default Router List;
1729 * The Default Router List should be in the descending order
1730 * of router-preferece. When Scoped Routing is disabled, routers
1731 * with the same preference are sorted in the arriving time order;
1732 * otherwise, the first entry in the list of routers having the same
1733 * preference is the primary default router, when the interface used
1734 * by the entry is the default interface.
1737 /* insert at the end of the group */
1738 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
1739 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
1740 if (rtpref(n
) > rtpref(dr
) ||
1741 (ip6_doscopedroute
&& !scoped
&& rtpref(n
) == rtpref(dr
)))
1745 TAILQ_INSERT_BEFORE(dr
, n
, dr_entry
);
1747 TAILQ_INSERT_TAIL(&nd_defrouter
, n
, dr_entry
);
1749 /* Ignore auto-configuration checks for static route entries */
1750 defrouter_select_common(ifp
, (n
->stateflags
& NDDRF_STATIC
));
1755 static struct nd_defrouter
*
1756 defrtrlist_update(struct nd_defrouter
*new)
1758 struct nd_defrouter
*dr
;
1760 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1761 dr
= defrtrlist_update_common(new,
1762 (nd6_defifp
!= NULL
&& new->ifp
!= nd6_defifp
));
1768 defrtrlist_sync(struct ifnet
*ifp
)
1770 struct nd_defrouter
*dr
, new;
1772 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1774 if (!ip6_doscopedroute
) {
1775 defrouter_select(ifp
);
1779 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
1780 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
1782 if (dr
->ifp
== ifp
&& (dr
->stateflags
& NDDRF_INSTALLED
))
1789 * Set ignore flag; the chosen default interface might
1790 * not be configured to accept RAs.
1792 defrouter_select_common(ifp
, 1);
1794 memcpy(&new.rtaddr
, &dr
->rtaddr
, sizeof(new.rtaddr
));
1795 new.flags
= dr
->flags
;
1796 new.stateflags
= dr
->stateflags
;
1797 new.stateflags
&= ~NDDRF_PROCESSED
;
1798 new.rtlifetime
= dr
->rtlifetime
;
1799 new.expire
= dr
->expire
;
1801 new.genid
= dr
->genid
;
1804 dr
= defrtrlist_update_common(&new, FALSE
);
1810 static struct nd_pfxrouter
*
1811 pfxrtr_lookup(struct nd_prefix
*pr
, struct nd_defrouter
*dr
)
1813 struct nd_pfxrouter
*search
;
1815 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1816 NDPR_LOCK_ASSERT_HELD(pr
);
1818 for (search
= pr
->ndpr_advrtrs
.lh_first
; search
;
1819 search
= search
->pfr_next
) {
1820 if (search
->router
== dr
)
1828 pfxrtr_add(struct nd_prefix
*pr
, struct nd_defrouter
*dr
)
1830 struct nd_pfxrouter
*new;
1832 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1833 NDPR_LOCK_ASSERT_NOTHELD(pr
);
1835 new = zalloc(ndprtr_zone
);
1838 bzero(new, sizeof(*new));
1842 LIST_INSERT_HEAD(&pr
->ndpr_advrtrs
, new, pfr_entry
);
1845 pfxlist_onlink_check();
1850 struct nd_pfxrouter
*pfr
)
1852 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1853 LIST_REMOVE(pfr
, pfr_entry
);
1854 zfree(ndprtr_zone
, pfr
);
1858 nd6_prefix_lookup(struct nd_prefix
*pr
)
1860 struct nd_prefix
*search
;
1862 lck_mtx_lock(nd6_mutex
);
1863 for (search
= nd_prefix
.lh_first
; search
; search
= search
->ndpr_next
) {
1865 if (pr
->ndpr_ifp
== search
->ndpr_ifp
&&
1866 pr
->ndpr_plen
== search
->ndpr_plen
&&
1867 in6_are_prefix_equal(&pr
->ndpr_prefix
.sin6_addr
,
1868 &search
->ndpr_prefix
.sin6_addr
, pr
->ndpr_plen
)) {
1869 NDPR_ADDREF_LOCKED(search
);
1870 NDPR_UNLOCK(search
);
1873 NDPR_UNLOCK(search
);
1875 lck_mtx_unlock(nd6_mutex
);
1881 purge_detached(struct ifnet
*ifp
)
1883 struct nd_prefix
*pr
, *pr_next
;
1884 struct in6_ifaddr
*ia
;
1885 struct ifaddr
*ifa
, *ifa_next
;
1887 lck_mtx_lock(nd6_mutex
);
1889 pr
= nd_prefix
.lh_first
;
1892 pr_next
= pr
->ndpr_next
;
1894 if (pr
->ndpr_ifp
!= ifp
||
1895 IN6_IS_ADDR_LINKLOCAL(&pr
->ndpr_prefix
.sin6_addr
) ||
1896 ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) == 0 &&
1897 !LIST_EMPTY(&pr
->ndpr_advrtrs
))) {
1903 ifnet_lock_shared(ifp
);
1904 for (ifa
= ifp
->if_addrlist
.tqh_first
; ifa
; ifa
= ifa_next
) {
1905 ifa_next
= ifa
->ifa_list
.tqe_next
;
1907 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
) {
1911 ia
= (struct in6_ifaddr
*)ifa
;
1912 if ((ia
->ia6_flags
& IN6_IFF_AUTOCONF
) ==
1913 IN6_IFF_AUTOCONF
&& ia
->ia6_ndpr
== pr
) {
1914 IFA_ADDREF_LOCKED(ifa
); /* for us */
1917 * Purging the address requires writer access
1918 * to the address list, so drop the ifnet lock
1919 * now and repeat from beginning.
1921 ifnet_lock_done(ifp
);
1922 lck_mtx_unlock(nd6_mutex
);
1924 lck_mtx_lock(nd6_mutex
);
1925 IFA_REMREF(ifa
); /* drop ours */
1926 pr
= nd_prefix
.lh_first
;
1931 ifnet_lock_done(ifp
);
1933 if (pr
->ndpr_addrcnt
== 0) {
1934 NDPR_ADDREF_LOCKED(pr
);
1944 lck_mtx_unlock(nd6_mutex
);
1948 nd6_prelist_add(struct nd_prefix
*pr
, struct nd_defrouter
*dr
,
1949 struct nd_prefix
**newp
, boolean_t force_scoped
)
1951 struct nd_prefix
*new = NULL
;
1952 struct ifnet
*ifp
= pr
->ndpr_ifp
;
1953 struct nd_ifinfo
*ndi
= NULL
;
1955 struct timeval timenow
;
1957 getmicrotime(&timenow
);
1959 if (ip6_maxifprefixes
>= 0) {
1960 lck_rw_lock_shared(nd_if_rwlock
);
1961 if (ifp
->if_index
>= nd_ifinfo_indexlim
) {
1962 lck_rw_done(nd_if_rwlock
);
1965 ndi
= &nd_ifinfo
[ifp
->if_index
];
1966 if (ndi
->nprefixes
>= ip6_maxifprefixes
/ 2) {
1967 lck_rw_done(nd_if_rwlock
);
1968 purge_detached(ifp
);
1969 lck_rw_lock_shared(nd_if_rwlock
);
1971 * Refresh pointer since nd_ifinfo[] may have grown;
1972 * repeating the bounds check against nd_ifinfo_indexlim
1973 * isn't necessary since the array never shrinks.
1975 ndi
= &nd_ifinfo
[ifp
->if_index
];
1977 if (ndi
->nprefixes
>= ip6_maxifprefixes
) {
1978 lck_rw_done(nd_if_rwlock
);
1981 lck_rw_done(nd_if_rwlock
);
1984 new = ndpr_alloc(M_WAITOK
);
1990 new->ndpr_ifp
= pr
->ndpr_ifp
;
1991 new->ndpr_prefix
= pr
->ndpr_prefix
;
1992 new->ndpr_plen
= pr
->ndpr_plen
;
1993 new->ndpr_vltime
= pr
->ndpr_vltime
;
1994 new->ndpr_pltime
= pr
->ndpr_pltime
;
1995 new->ndpr_flags
= pr
->ndpr_flags
;
1996 if (pr
->ndpr_stateflags
& NDPRF_STATIC
)
1997 new->ndpr_stateflags
|= NDPRF_STATIC
;
1999 if ((error
= in6_init_prefix_ltimes(new)) != 0) {
2004 new->ndpr_lastupdate
= timenow
.tv_sec
;
2007 NDPR_ADDREF_LOCKED(new); /* for caller */
2009 /* initialization */
2010 LIST_INIT(&new->ndpr_advrtrs
);
2011 in6_prefixlen2mask(&new->ndpr_mask
, new->ndpr_plen
);
2012 /* make prefix in the canonical form */
2013 for (i
= 0; i
< 4; i
++)
2014 new->ndpr_prefix
.sin6_addr
.s6_addr32
[i
] &=
2015 new->ndpr_mask
.s6_addr32
[i
];
2019 lck_mtx_lock(nd6_mutex
);
2020 /* link ndpr_entry to nd_prefix list */
2021 LIST_INSERT_HEAD(&nd_prefix
, new, ndpr_entry
);
2022 new->ndpr_debug
|= IFD_ATTACHED
;
2023 NDPR_ADDREF(new); /* for nd_prefix list */
2025 /* ND_OPT_PI_FLAG_ONLINK processing */
2026 if (new->ndpr_raf_onlink
) {
2029 if ((e
= nd6_prefix_onlink_common(new, force_scoped
,
2030 new->ndpr_ifp
->if_index
)) != 0) {
2031 nd6log((LOG_ERR
, "nd6_prelist_add: failed to make "
2032 "the prefix %s/%d on-link %s on %s (errno=%d)\n",
2033 ip6_sprintf(&new->ndpr_prefix
.sin6_addr
),
2034 new->ndpr_plen
, force_scoped
? "scoped" :
2035 "non-scoped", if_name(ifp
), e
));
2036 /* proceed anyway. XXX: is it correct? */
2041 pfxrtr_add(new, dr
);
2044 lck_rw_lock_shared(nd_if_rwlock
);
2046 * Refresh pointer since nd_ifinfo[] may have grown;
2047 * repeating the bounds check against nd_ifinfo_indexlim
2048 * isn't necessary since the array never shrinks.
2050 ndi
= &nd_ifinfo
[ifp
->if_index
];
2051 atomic_add_32(&ndi
->nprefixes
, 1);
2052 lck_rw_done(nd_if_rwlock
);
2054 lck_mtx_unlock(nd6_mutex
);
2060 * Caller must have held an extra reference on nd_prefix.
2063 prelist_remove(struct nd_prefix
*pr
)
2065 struct nd_pfxrouter
*pfr
, *next
;
2066 struct ifnet
*ifp
= pr
->ndpr_ifp
;
2069 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2070 NDPR_LOCK_ASSERT_HELD(pr
);
2072 /* make sure to invalidate the prefix until it is really freed. */
2073 pr
->ndpr_vltime
= 0;
2074 pr
->ndpr_pltime
= 0;
2077 * Though these flags are now meaningless, we'd rather keep the value
2078 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users
2079 * when executing "ndp -p".
2082 if ((pr
->ndpr_stateflags
& NDPRF_ONLINK
)) {
2083 NDPR_ADDREF_LOCKED(pr
);
2085 lck_mtx_unlock(nd6_mutex
);
2086 if ((e
= nd6_prefix_offlink(pr
)) != 0) {
2087 nd6log((LOG_ERR
, "prelist_remove: failed to make "
2088 "%s/%d offlink on %s, errno=%d\n",
2089 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
2090 pr
->ndpr_plen
, if_name(ifp
), e
));
2091 /* what should we do? */
2093 lck_mtx_lock(nd6_mutex
);
2095 if (NDPR_REMREF_LOCKED(pr
) == NULL
)
2099 if (pr
->ndpr_addrcnt
> 0)
2100 return; /* notice here? */
2102 /* unlink ndpr_entry from nd_prefix list */
2103 LIST_REMOVE(pr
, ndpr_entry
);
2104 pr
->ndpr_debug
&= ~IFD_ATTACHED
;
2106 /* free list of routers that adversed the prefix */
2107 for (pfr
= pr
->ndpr_advrtrs
.lh_first
; pfr
; pfr
= next
) {
2108 next
= pfr
->pfr_next
;
2112 lck_rw_lock_shared(nd_if_rwlock
);
2113 if (ifp
->if_index
< nd_ifinfo_indexlim
) {
2114 struct nd_ifinfo
*ndi
= &nd_ifinfo
[ifp
->if_index
];
2115 atomic_add_32(&ndi
->nprefixes
, -1);
2116 if (ndi
->nprefixes
< 0) {
2117 log(LOG_WARNING
, "prelist_remove: negative "
2118 "count on %s\n", if_name(ifp
));
2121 lck_rw_done(nd_if_rwlock
);
2123 /* This must not be the last reference to the nd_prefix */
2124 if (NDPR_REMREF_LOCKED(pr
) == NULL
) {
2125 panic("%s: unexpected (missing) refcnt ndpr=%p", __func__
, pr
);
2129 pfxlist_onlink_check();
2134 struct nd_prefix
*new,
2135 struct nd_defrouter
*dr
, /* may be NULL */
2139 struct in6_ifaddr
*ia6
= NULL
, *ia6_match
= NULL
;
2141 struct ifnet
*ifp
= new->ndpr_ifp
;
2142 struct nd_prefix
*pr
;
2146 struct in6_addrlifetime lt6_tmp
;
2147 struct timeval timenow
;
2149 /* no need to lock "new" here, as it is local to the caller */
2150 NDPR_LOCK_ASSERT_NOTHELD(new);
2155 * Authenticity for NA consists authentication for
2156 * both IP header and IP datagrams, doesn't it ?
2158 #if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM)
2159 auth
= (m
->m_flags
& M_AUTHIPHDR
2160 && m
->m_flags
& M_AUTHIPDGM
) ? 1 : 0;
2165 if ((pr
= nd6_prefix_lookup(new)) != NULL
) {
2167 * nd6_prefix_lookup() ensures that pr and new have the same
2168 * prefix on a same interface.
2172 * Update prefix information. Note that the on-link (L) bit
2173 * and the autonomous (A) bit should NOT be changed from 1
2176 lck_mtx_lock(nd6_mutex
);
2178 if (new->ndpr_raf_onlink
== 1)
2179 pr
->ndpr_raf_onlink
= 1;
2180 if (new->ndpr_raf_auto
== 1)
2181 pr
->ndpr_raf_auto
= 1;
2182 if (new->ndpr_raf_onlink
) {
2183 pr
->ndpr_vltime
= new->ndpr_vltime
;
2184 pr
->ndpr_pltime
= new->ndpr_pltime
;
2185 pr
->ndpr_preferred
= new->ndpr_preferred
;
2186 pr
->ndpr_expire
= new->ndpr_expire
;
2189 if (new->ndpr_raf_onlink
&&
2190 (pr
->ndpr_stateflags
& NDPRF_ONLINK
) == 0) {
2194 if ((e
= nd6_prefix_onlink(pr
)) != 0) {
2196 "prelist_update: failed to make "
2197 "the prefix %s/%d on-link on %s "
2199 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
2200 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
), e
));
2201 /* proceed anyway. XXX: is it correct? */
2206 if (dr
&& pfxrtr_lookup(pr
, dr
) == NULL
) {
2212 lck_mtx_unlock(nd6_mutex
);
2214 struct nd_prefix
*newpr
= NULL
;
2218 if (new->ndpr_vltime
== 0)
2220 if (new->ndpr_raf_onlink
== 0 && new->ndpr_raf_auto
== 0)
2223 bzero(&new->ndpr_addr
, sizeof(struct in6_addr
));
2225 error
= nd6_prelist_add(new, dr
, &newpr
, FALSE
);
2226 if (error
!= 0 || newpr
== NULL
) {
2227 nd6log((LOG_NOTICE
, "prelist_update: "
2228 "nd6_prelist_add failed for %s/%d on %s "
2229 "errno=%d, returnpr=%p\n",
2230 ip6_sprintf(&new->ndpr_prefix
.sin6_addr
),
2231 new->ndpr_plen
, if_name(new->ndpr_ifp
),
2233 goto end
; /* we should just give up in this case. */
2237 * XXX: from the ND point of view, we can ignore a prefix
2238 * with the on-link bit being zero. However, we need a
2239 * prefix structure for references from autoconfigured
2240 * addresses. Thus, we explicitly make sure that the prefix
2241 * itself expires now.
2244 if (newpr
->ndpr_raf_onlink
== 0) {
2245 newpr
->ndpr_vltime
= 0;
2246 newpr
->ndpr_pltime
= 0;
2247 in6_init_prefix_ltimes(newpr
);
2255 * Address autoconfiguration based on Section 5.5.3 of RFC 2462.
2256 * Note that pr must be non NULL at this point.
2259 /* 5.5.3 (a). Ignore the prefix without the A bit set. */
2260 if (!new->ndpr_raf_auto
)
2264 * 5.5.3 (b). the link-local prefix should have been ignored in
2268 /* 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. */
2269 if (new->ndpr_pltime
> new->ndpr_vltime
) {
2270 error
= EINVAL
; /* XXX: won't be used */
2275 * 5.5.3 (d). If the prefix advertised is not equal to the prefix of
2276 * an address configured by stateless autoconfiguration already in the
2277 * list of addresses associated with the interface, and the Valid
2278 * Lifetime is not 0, form an address. We first check if we have
2279 * a matching prefix.
2280 * Note: we apply a clarification in rfc2462bis-02 here. We only
2281 * consider autoconfigured addresses while RFC2462 simply said
2285 getmicrotime(&timenow
);
2287 ifnet_lock_shared(ifp
);
2288 TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_list
)
2290 struct in6_ifaddr
*ifa6
;
2291 u_int32_t remaininglifetime
;
2294 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
) {
2298 ifa6
= (struct in6_ifaddr
*)ifa
;
2301 * We only consider autoconfigured addresses as per rfc2462bis.
2303 if (!(ifa6
->ia6_flags
& IN6_IFF_AUTOCONF
)) {
2308 * Spec is not clear here, but I believe we should concentrate
2309 * on unicast (i.e. not anycast) addresses.
2310 * XXX: other ia6_flags? detached or duplicated?
2312 if ((ifa6
->ia6_flags
& IN6_IFF_ANYCAST
) != 0) {
2317 * Ignore the address if it is not associated with a prefix
2318 * or is associated with a prefix that is different from this
2319 * one. (pr is never NULL here)
2321 if (ifa6
->ia6_ndpr
!= pr
) {
2326 if (ia6_match
== NULL
) { /* remember the first one */
2328 IFA_ADDREF_LOCKED(ifa
); /* for ia6_match */
2332 * An already autoconfigured address matched. Now that we
2333 * are sure there is at least one matched address, we can
2334 * proceed to 5.5.3. (e): update the lifetimes according to the
2335 * "two hours" rule and the privacy extension.
2336 * We apply some clarifications in rfc2462bis:
2337 * - use remaininglifetime instead of storedlifetime as a
2339 * - remove the dead code in the "two-hour" rule
2341 #define TWOHOUR (120*60)
2342 lt6_tmp
= ifa6
->ia6_lifetime
;
2344 if (lt6_tmp
.ia6t_vltime
== ND6_INFINITE_LIFETIME
)
2345 remaininglifetime
= ND6_INFINITE_LIFETIME
;
2346 else if (timenow
.tv_sec
- ifa6
->ia6_updatetime
>
2347 lt6_tmp
.ia6t_vltime
) {
2349 * The case of "invalid" address. We should usually
2350 * not see this case.
2352 remaininglifetime
= 0;
2354 remaininglifetime
= lt6_tmp
.ia6t_vltime
-
2355 (timenow
.tv_sec
- ifa6
->ia6_updatetime
);
2357 /* when not updating, keep the current stored lifetime. */
2358 lt6_tmp
.ia6t_vltime
= remaininglifetime
;
2360 if (TWOHOUR
< new->ndpr_vltime
||
2361 remaininglifetime
< new->ndpr_vltime
) {
2362 lt6_tmp
.ia6t_vltime
= new->ndpr_vltime
;
2363 } else if (remaininglifetime
<= TWOHOUR
) {
2365 lt6_tmp
.ia6t_vltime
= new->ndpr_vltime
;
2369 * new->ndpr_vltime <= TWOHOUR &&
2370 * TWOHOUR < remaininglifetime
2372 lt6_tmp
.ia6t_vltime
= TWOHOUR
;
2375 /* The 2 hour rule is not imposed for preferred lifetime. */
2376 lt6_tmp
.ia6t_pltime
= new->ndpr_pltime
;
2378 /* Special handling for lifetimes of temporary addresses. */
2379 if ((ifa6
->ia6_flags
& IN6_IFF_TEMPORARY
) != 0) {
2380 u_int32_t maxvltime
, maxpltime
;
2382 /* Constrain lifetimes to system limits. */
2383 if (lt6_tmp
.ia6t_vltime
> ip6_temp_valid_lifetime
)
2384 lt6_tmp
.ia6t_vltime
= ip6_temp_valid_lifetime
;
2385 if (lt6_tmp
.ia6t_pltime
> ip6_temp_preferred_lifetime
)
2386 lt6_tmp
.ia6t_pltime
=
2387 ip6_temp_preferred_lifetime
-
2391 * According to RFC 4941, section 3.3 (1), we only
2392 * update the lifetimes when they are in the maximum
2395 if (ip6_temp_valid_lifetime
>
2396 (u_int32_t
)((timenow
.tv_sec
- ifa6
->ia6_createtime
) +
2397 ip6_desync_factor
)) {
2398 maxvltime
= ip6_temp_valid_lifetime
-
2399 (timenow
.tv_sec
- ifa6
->ia6_createtime
) -
2403 if (ip6_temp_preferred_lifetime
>
2404 (u_int32_t
)((timenow
.tv_sec
- ifa6
->ia6_createtime
) +
2405 ip6_desync_factor
)) {
2406 maxpltime
= ip6_temp_preferred_lifetime
-
2407 (timenow
.tv_sec
- ifa6
->ia6_createtime
) -
2412 if (lt6_tmp
.ia6t_vltime
> maxvltime
)
2413 lt6_tmp
.ia6t_vltime
= maxvltime
;
2414 if (lt6_tmp
.ia6t_pltime
> maxpltime
)
2415 lt6_tmp
.ia6t_pltime
= maxpltime
;
2418 in6_init_address_ltimes(pr
, <6_tmp
,
2419 !!(ifa6
->ia6_flags
& IN6_IFF_TEMPORARY
));
2421 ifa6
->ia6_lifetime
= lt6_tmp
;
2422 ifa6
->ia6_updatetime
= timenow
.tv_sec
;
2425 ifnet_lock_done(ifp
);
2426 if (ia6_match
== NULL
&& new->ndpr_vltime
) {
2430 * 5.5.3 (d) (continued)
2431 * No address matched and the valid lifetime is non-zero.
2432 * Create a new address.
2436 * Prefix Length check:
2437 * If the sum of the prefix length and interface identifier
2438 * length does not equal 128 bits, the Prefix Information
2439 * option MUST be ignored. The length of the interface
2440 * identifier is defined in a separate link-type specific
2443 ifidlen
= in6_if2idlen(ifp
);
2445 /* this should not happen, so we always log it. */
2446 log(LOG_ERR
, "prelist_update: IFID undefined (%s)\n",
2451 if (ifidlen
+ pr
->ndpr_plen
!= 128) {
2453 "prelist_update: invalid prefixlen "
2454 "%d for %s, ignored\n",
2455 pr
->ndpr_plen
, if_name(ifp
)));
2461 if ((ia6
= in6_ifadd(new, mcast
)) != NULL
) {
2463 * note that we should use pr (not new) for reference.
2465 IFA_LOCK(&ia6
->ia_ifa
);
2468 NDPR_ADDREF_LOCKED(pr
); /* for addr reference */
2470 VERIFY(pr
->ndpr_addrcnt
!= 0);
2472 IFA_UNLOCK(&ia6
->ia_ifa
);
2476 * When a new public address is created as described
2477 * in RFC2462, also create a new temporary address.
2480 * When an interface connects to a new link, a new
2481 * randomized interface identifier should be generated
2482 * immediately together with a new set of temporary
2483 * addresses. Thus, we specifiy 1 as the 2nd arg of
2486 if (ip6_use_tempaddr
) {
2488 if ((e
= in6_tmpifadd(ia6
, 1, M_WAITOK
)) != 0) {
2489 nd6log((LOG_NOTICE
, "prelist_update: "
2490 "failed to create a temporary "
2491 "address, errno=%d\n",
2495 IFA_REMREF(&ia6
->ia_ifa
);
2499 * A newly added address might affect the status
2500 * of other addresses, so we check and update it.
2501 * XXX: what if address duplication happens?
2503 lck_mtx_lock(nd6_mutex
);
2504 pfxlist_onlink_check();
2505 lck_mtx_unlock(nd6_mutex
);
2507 /* just set an error. do not bark here. */
2508 error
= EADDRNOTAVAIL
; /* XXX: might be unused. */
2517 if (ia6_match
!= NULL
)
2518 IFA_REMREF(&ia6_match
->ia_ifa
);
2523 * Neighbor Discover Default Router structure reference counting routines.
2525 static struct nd_defrouter
*
2528 struct nd_defrouter
*dr
;
2530 dr
= (how
== M_WAITOK
) ? zalloc(nddr_zone
) : zalloc_noblock(nddr_zone
);
2532 bzero(dr
, nddr_size
);
2533 lck_mtx_init(&dr
->nddr_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2534 dr
->nddr_debug
|= IFD_ALLOC
;
2535 if (nddr_debug
!= 0) {
2536 dr
->nddr_debug
|= IFD_DEBUG
;
2537 dr
->nddr_trace
= nddr_trace
;
2544 nddr_free(struct nd_defrouter
*dr
)
2547 if (dr
->nddr_debug
& IFD_ATTACHED
) {
2548 panic("%s: attached nddr %p is being freed", __func__
, dr
);
2550 } else if (!(dr
->nddr_debug
& IFD_ALLOC
)) {
2551 panic("%s: nddr %p cannot be freed", __func__
, dr
);
2554 dr
->nddr_debug
&= ~IFD_ALLOC
;
2557 lck_mtx_destroy(&dr
->nddr_lock
, ifa_mtx_grp
);
2558 zfree(nddr_zone
, dr
);
2562 nddr_trace(struct nd_defrouter
*dr
, int refhold
)
2564 struct nd_defrouter_dbg
*dr_dbg
= (struct nd_defrouter_dbg
*)dr
;
2569 if (!(dr
->nddr_debug
& IFD_DEBUG
)) {
2570 panic("%s: nddr %p has no debug structure", __func__
, dr
);
2574 cnt
= &dr_dbg
->nddr_refhold_cnt
;
2575 tr
= dr_dbg
->nddr_refhold
;
2577 cnt
= &dr_dbg
->nddr_refrele_cnt
;
2578 tr
= dr_dbg
->nddr_refrele
;
2581 idx
= atomic_add_16_ov(cnt
, 1) % NDDR_TRACE_HIST_SIZE
;
2582 ctrace_record(&tr
[idx
]);
2586 nddr_addref(struct nd_defrouter
*nddr
, int locked
)
2590 NDDR_LOCK_SPIN(nddr
);
2592 NDDR_LOCK_ASSERT_HELD(nddr
);
2594 if (++nddr
->nddr_refcount
== 0) {
2595 panic("%s: nddr %p wraparound refcnt\n", __func__
, nddr
);
2597 } else if (nddr
->nddr_trace
!= NULL
) {
2598 (*nddr
->nddr_trace
)(nddr
, TRUE
);
2605 struct nd_defrouter
*
2606 nddr_remref(struct nd_defrouter
*nddr
, int locked
)
2610 NDDR_LOCK_SPIN(nddr
);
2612 NDDR_LOCK_ASSERT_HELD(nddr
);
2614 if (nddr
->nddr_refcount
== 0) {
2615 panic("%s: nddr %p negative refcnt\n", __func__
, nddr
);
2617 } else if (nddr
->nddr_trace
!= NULL
) {
2618 (*nddr
->nddr_trace
)(nddr
, FALSE
);
2621 if (--nddr
->nddr_refcount
== 0) {
2627 if (!locked
&& nddr
!= NULL
)
2634 * Neighbor Discover Prefix structure reference counting routines.
2636 static struct nd_prefix
*
2639 struct nd_prefix
*pr
;
2641 pr
= (how
== M_WAITOK
) ? zalloc(ndpr_zone
) : zalloc_noblock(ndpr_zone
);
2643 bzero(pr
, ndpr_size
);
2644 lck_mtx_init(&pr
->ndpr_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2645 pr
->ndpr_debug
|= IFD_ALLOC
;
2646 if (ndpr_debug
!= 0) {
2647 pr
->ndpr_debug
|= IFD_DEBUG
;
2648 pr
->ndpr_trace
= ndpr_trace
;
2655 ndpr_free(struct nd_prefix
*pr
)
2658 if (pr
->ndpr_debug
& IFD_ATTACHED
) {
2659 panic("%s: attached ndpr %p is being freed", __func__
, pr
);
2661 } else if (!(pr
->ndpr_debug
& IFD_ALLOC
)) {
2662 panic("%s: ndpr %p cannot be freed", __func__
, pr
);
2665 pr
->ndpr_debug
&= ~IFD_ALLOC
;
2668 lck_mtx_destroy(&pr
->ndpr_lock
, ifa_mtx_grp
);
2669 zfree(ndpr_zone
, pr
);
2673 ndpr_trace(struct nd_prefix
*pr
, int refhold
)
2675 struct nd_prefix_dbg
*pr_dbg
= (struct nd_prefix_dbg
*)pr
;
2680 if (!(pr
->ndpr_debug
& IFD_DEBUG
)) {
2681 panic("%s: ndpr %p has no debug structure", __func__
, pr
);
2685 cnt
= &pr_dbg
->ndpr_refhold_cnt
;
2686 tr
= pr_dbg
->ndpr_refhold
;
2688 cnt
= &pr_dbg
->ndpr_refrele_cnt
;
2689 tr
= pr_dbg
->ndpr_refrele
;
2692 idx
= atomic_add_16_ov(cnt
, 1) % NDPR_TRACE_HIST_SIZE
;
2693 ctrace_record(&tr
[idx
]);
2697 ndpr_addref(struct nd_prefix
*ndpr
, int locked
)
2700 NDPR_LOCK_SPIN(ndpr
);
2702 NDPR_LOCK_ASSERT_HELD(ndpr
);
2704 if (++ndpr
->ndpr_refcount
== 0) {
2705 panic("%s: ndpr %p wraparound refcnt\n", __func__
, ndpr
);
2707 } else if (ndpr
->ndpr_trace
!= NULL
) {
2708 (*ndpr
->ndpr_trace
)(ndpr
, TRUE
);
2716 ndpr_remref(struct nd_prefix
*ndpr
, int locked
)
2719 NDPR_LOCK_SPIN(ndpr
);
2721 NDPR_LOCK_ASSERT_HELD(ndpr
);
2723 if (ndpr
->ndpr_refcount
== 0) {
2724 panic("%s: ndpr %p negative refcnt\n", __func__
, ndpr
);
2726 } else if (ndpr
->ndpr_trace
!= NULL
) {
2727 (*ndpr
->ndpr_trace
)(ndpr
, FALSE
);
2730 if (--ndpr
->ndpr_refcount
== 0) {
2731 if (ndpr
->ndpr_addrcnt
!= 0) {
2732 panic("%s: freeing ndpr %p with outstanding address "
2733 "reference (%d)", __func__
, ndpr
,
2734 ndpr
->ndpr_addrcnt
);
2742 if (!locked
&& ndpr
!= NULL
)
2749 * A supplement function used in the on-link detection below;
2750 * detect if a given prefix has a (probably) reachable advertising router.
2751 * XXX: lengthy function name...
2753 static struct nd_pfxrouter
*
2754 find_pfxlist_reachable_router(struct nd_prefix
*pr
)
2756 struct nd_pfxrouter
*pfxrtr
;
2758 struct llinfo_nd6
*ln
;
2760 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2761 NDPR_LOCK_ASSERT_HELD(pr
);
2763 for (pfxrtr
= LIST_FIRST(&pr
->ndpr_advrtrs
); pfxrtr
;
2764 pfxrtr
= LIST_NEXT(pfxrtr
, pfr_entry
)) {
2766 lck_mtx_unlock(nd6_mutex
);
2767 /* Callee returns a locked route upon success */
2768 if ((rt
= nd6_lookup(&pfxrtr
->router
->rtaddr
, 0,
2769 pfxrtr
->router
->ifp
, 0)) != NULL
) {
2770 RT_LOCK_ASSERT_HELD(rt
);
2771 if ((ln
= rt
->rt_llinfo
) != NULL
&&
2772 ND6_IS_LLINFO_PROBREACH(ln
)) {
2773 RT_REMREF_LOCKED(rt
);
2775 lck_mtx_lock(nd6_mutex
);
2779 RT_REMREF_LOCKED(rt
);
2782 lck_mtx_lock(nd6_mutex
);
2785 NDPR_LOCK_ASSERT_HELD(pr
);
2792 * Check if each prefix in the prefix list has at least one available router
2793 * that advertised the prefix (a router is "available" if its neighbor cache
2794 * entry is reachable or probably reachable).
2795 * If the check fails, the prefix may be off-link, because, for example,
2796 * we have moved from the network but the lifetime of the prefix has not
2797 * expired yet. So we should not use the prefix if there is another prefix
2798 * that has an available router.
2799 * But, if there is no prefix that has an available router, we still regards
2800 * all the prefixes as on-link. This is because we can't tell if all the
2801 * routers are simply dead or if we really moved from the network and there
2802 * is no router around us.
2805 pfxlist_onlink_check(void)
2807 struct nd_prefix
*pr
, *prclear
;
2808 struct in6_ifaddr
*ifa
;
2809 struct nd_defrouter
*dr
;
2810 struct nd_pfxrouter
*pfxrtr
= NULL
;
2812 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2814 while (nd_prefix_busy
) {
2815 nd_prefix_waiters
++;
2816 msleep(nd_prefix_waitchan
, nd6_mutex
, (PZERO
-1),
2818 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2820 nd_prefix_busy
= TRUE
;
2823 * Check if there is a prefix that has a reachable advertising
2826 pr
= nd_prefix
.lh_first
;
2829 if (pr
->ndpr_stateflags
& NDPRF_PROCESSED
) {
2834 NDPR_ADDREF_LOCKED(pr
);
2835 if (pr
->ndpr_raf_onlink
&& find_pfxlist_reachable_router(pr
) &&
2836 (pr
->ndpr_debug
& IFD_ATTACHED
)) {
2841 pr
->ndpr_stateflags
|= NDPRF_PROCESSED
;
2845 * Since find_pfxlist_reachable_router() drops the nd6_mutex, we
2846 * have to start over, but the NDPRF_PROCESSED flag will stop
2847 * us from checking the same prefix twice.
2849 pr
= nd_prefix
.lh_first
;
2851 LIST_FOREACH(prclear
, &nd_prefix
, ndpr_entry
) {
2853 prclear
->ndpr_stateflags
&= ~NDPRF_PROCESSED
;
2854 NDPR_UNLOCK(prclear
);
2858 * If we have no such prefix, check whether we still have a router
2859 * that does not advertise any prefixes.
2862 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
;
2863 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
2864 struct nd_prefix
*pr0
;
2866 for (pr0
= nd_prefix
.lh_first
; pr0
;
2867 pr0
= pr0
->ndpr_next
) {
2869 if ((pfxrtr
= pfxrtr_lookup(pr0
, dr
)) != NULL
) {
2879 if (pr
!= NULL
|| (TAILQ_FIRST(&nd_defrouter
) && pfxrtr
== NULL
)) {
2881 * There is at least one prefix that has a reachable router,
2882 * or at least a router which probably does not advertise
2883 * any prefixes. The latter would be the case when we move
2884 * to a new link where we have a router that does not provide
2885 * prefixes and we configure an address by hand.
2886 * Detach prefixes which have no reachable advertising
2887 * router, and attach other prefixes.
2889 pr
= nd_prefix
.lh_first
;
2893 * We aren't interested prefixes already processed,
2894 * nor in prefixes without the L bit
2895 * set nor in static prefixes
2897 if (pr
->ndpr_raf_onlink
== 0 ||
2898 pr
->ndpr_stateflags
& NDPRF_PROCESSED
||
2899 pr
->ndpr_stateflags
& NDPRF_STATIC
) {
2904 NDPR_ADDREF_LOCKED(pr
);
2905 if ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) == 0 &&
2906 find_pfxlist_reachable_router(pr
) == NULL
&&
2907 (pr
->ndpr_debug
& IFD_ATTACHED
))
2908 pr
->ndpr_stateflags
|= NDPRF_DETACHED
;
2909 if ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) != 0 &&
2910 find_pfxlist_reachable_router(pr
) != NULL
&&
2911 (pr
->ndpr_debug
& IFD_ATTACHED
))
2912 pr
->ndpr_stateflags
&= ~NDPRF_DETACHED
;
2913 pr
->ndpr_stateflags
|= NDPRF_PROCESSED
;
2917 * Since find_pfxlist_reachable_router() drops the
2918 * nd6_mutex, we have to start over, but the
2919 * NDPRF_PROCESSED flag will stop us from checking
2920 * the same prefix twice.
2922 pr
= nd_prefix
.lh_first
;
2925 /* there is no prefix that has a reachable router */
2926 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
2928 if (pr
->ndpr_raf_onlink
== 0 ||
2929 pr
->ndpr_stateflags
& NDPRF_STATIC
) {
2933 if ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) != 0)
2934 pr
->ndpr_stateflags
&= ~NDPRF_DETACHED
;
2938 LIST_FOREACH(prclear
, &nd_prefix
, ndpr_entry
) {
2940 prclear
->ndpr_stateflags
&= ~NDPRF_PROCESSED
;
2941 NDPR_UNLOCK(prclear
);
2943 VERIFY(nd_prefix_busy
);
2944 nd_prefix_busy
= FALSE
;
2945 if (nd_prefix_waiters
> 0) {
2946 nd_prefix_waiters
= 0;
2947 wakeup(nd_prefix_waitchan
);
2951 * Remove each interface route associated with a (just) detached
2952 * prefix, and reinstall the interface route for a (just) attached
2953 * prefix. Note that all attempt of reinstallation does not
2954 * necessarily success, when a same prefix is shared among multiple
2955 * interfaces. Such cases will be handled in nd6_prefix_onlink,
2956 * so we don't have to care about them.
2958 pr
= nd_prefix
.lh_first
;
2963 if (pr
->ndpr_raf_onlink
== 0 ||
2964 pr
->ndpr_stateflags
& NDPRF_STATIC
) {
2969 if ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) != 0 &&
2970 (pr
->ndpr_stateflags
& NDPRF_ONLINK
) != 0) {
2972 lck_mtx_unlock(nd6_mutex
);
2973 if ((e
= nd6_prefix_offlink(pr
)) != 0) {
2975 "pfxlist_onlink_check: failed to "
2976 "make %s/%d offlink, errno=%d\n",
2977 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
2980 lck_mtx_lock(nd6_mutex
);
2981 pr
= nd_prefix
.lh_first
;
2984 if ((pr
->ndpr_stateflags
& NDPRF_DETACHED
) == 0 &&
2985 (pr
->ndpr_stateflags
& NDPRF_ONLINK
) == 0 &&
2986 pr
->ndpr_raf_onlink
) {
2988 if ((e
= nd6_prefix_onlink(pr
)) != 0) {
2990 "pfxlist_onlink_check: failed to "
2991 "make %s/%d offlink, errno=%d\n",
2992 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3002 * Changes on the prefix status might affect address status as well.
3003 * Make sure that all addresses derived from an attached prefix are
3004 * attached, and that all addresses derived from a detached prefix are
3005 * detached. Note, however, that a manually configured address should
3006 * always be attached.
3007 * The precise detection logic is same as the one for prefixes.
3009 lck_rw_lock_shared(&in6_ifaddr_rwlock
);
3010 for (ifa
= in6_ifaddrs
; ifa
; ifa
= ifa
->ia_next
) {
3011 struct nd_prefix
*ndpr
;
3013 IFA_LOCK(&ifa
->ia_ifa
);
3014 if ((ifa
->ia6_flags
& IN6_IFF_AUTOCONF
) == 0) {
3015 IFA_UNLOCK(&ifa
->ia_ifa
);
3018 if ((ndpr
= ifa
->ia6_ndpr
) == NULL
) {
3020 * This can happen when we first configure the address
3021 * (i.e. the address exists, but the prefix does not).
3022 * XXX: complicated relationships...
3024 IFA_UNLOCK(&ifa
->ia_ifa
);
3028 IFA_UNLOCK(&ifa
->ia_ifa
);
3031 if (find_pfxlist_reachable_router(ndpr
)) {
3040 for (ifa
= in6_ifaddrs
; ifa
; ifa
= ifa
->ia_next
) {
3041 struct nd_prefix
*ndpr
;
3043 IFA_LOCK(&ifa
->ia_ifa
);
3044 if ((ifa
->ia6_flags
& IN6_IFF_AUTOCONF
) == 0) {
3045 IFA_UNLOCK(&ifa
->ia_ifa
);
3048 if ((ndpr
= ifa
->ia6_ndpr
) == NULL
) {
3049 /* XXX: see above. */
3050 IFA_UNLOCK(&ifa
->ia_ifa
);
3054 IFA_UNLOCK(&ifa
->ia_ifa
);
3056 if (find_pfxlist_reachable_router(ndpr
)) {
3058 IFA_LOCK(&ifa
->ia_ifa
);
3059 if (ifa
->ia6_flags
& IN6_IFF_DETACHED
) {
3060 ifa
->ia6_flags
&= ~IN6_IFF_DETACHED
;
3061 ifa
->ia6_flags
|= IN6_IFF_TENTATIVE
;
3062 IFA_UNLOCK(&ifa
->ia_ifa
);
3063 nd6_dad_start((struct ifaddr
*)ifa
, 0);
3065 IFA_UNLOCK(&ifa
->ia_ifa
);
3069 IFA_LOCK(&ifa
->ia_ifa
);
3070 ifa
->ia6_flags
|= IN6_IFF_DETACHED
;
3071 IFA_UNLOCK(&ifa
->ia_ifa
);
3077 for (ifa
= in6_ifaddrs
; ifa
; ifa
= ifa
->ia_next
) {
3078 IFA_LOCK(&ifa
->ia_ifa
);
3079 if ((ifa
->ia6_flags
& IN6_IFF_AUTOCONF
) == 0) {
3080 IFA_UNLOCK(&ifa
->ia_ifa
);
3083 if (ifa
->ia6_flags
& IN6_IFF_DETACHED
) {
3084 ifa
->ia6_flags
&= ~IN6_IFF_DETACHED
;
3085 ifa
->ia6_flags
|= IN6_IFF_TENTATIVE
;
3086 IFA_UNLOCK(&ifa
->ia_ifa
);
3087 /* Do we need a delay in this case? */
3088 nd6_dad_start((struct ifaddr
*)ifa
, 0);
3090 IFA_UNLOCK(&ifa
->ia_ifa
);
3094 lck_rw_done(&in6_ifaddr_rwlock
);
3097 static struct nd_prefix
*
3098 nd6_prefix_equal_lookup(struct nd_prefix
*pr
, boolean_t primary_only
)
3100 struct nd_prefix
*opr
;
3102 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
3104 for (opr
= nd_prefix
.lh_first
; opr
; opr
= opr
->ndpr_next
) {
3109 if ((opr
->ndpr_stateflags
& NDPRF_ONLINK
) == 0) {
3113 if (opr
->ndpr_plen
== pr
->ndpr_plen
&&
3114 in6_are_prefix_equal(&pr
->ndpr_prefix
.sin6_addr
,
3115 &opr
->ndpr_prefix
.sin6_addr
, pr
->ndpr_plen
) &&
3117 !(opr
->ndpr_stateflags
& NDPRF_IFSCOPE
))) {
3118 NDPR_ADDREF_LOCKED(opr
);
3128 * Synchronize the interface routes of similar prefixes on different
3129 * interfaces; the one using the default interface would be (re)installed
3130 * as a primary/non-scoped entry, and the rest as scoped entri(es).
3133 nd6_prefix_sync(struct ifnet
*ifp
)
3135 struct nd_prefix
*pr
, *opr
;
3138 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
3140 if (!ip6_doscopedroute
|| ifp
== NULL
)
3143 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
3145 if (!(pr
->ndpr_stateflags
& NDPRF_ONLINK
)) {
3149 if (pr
->ndpr_ifp
== ifp
&&
3150 (pr
->ndpr_stateflags
& NDPRF_IFSCOPE
) &&
3151 !IN6_IS_ADDR_LINKLOCAL(&pr
->ndpr_prefix
.sin6_addr
)) {
3161 /* Remove conflicting entries */
3162 opr
= nd6_prefix_equal_lookup(pr
, TRUE
);
3164 lck_mtx_unlock(nd6_mutex
);
3165 err
= nd6_prefix_offlink(opr
);
3166 lck_mtx_lock(nd6_mutex
);
3169 "%s: failed to make %s/%d offlink on %s, "
3170 "errno=%d\n", __func__
,
3171 ip6_sprintf(&opr
->ndpr_prefix
.sin6_addr
),
3172 opr
->ndpr_plen
, if_name(opr
->ndpr_ifp
), err
));
3176 "%s: scoped %s/%d on %s has no matching unscoped prefix\n",
3177 __func__
, ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3178 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
)));
3181 lck_mtx_unlock(nd6_mutex
);
3182 err
= nd6_prefix_offlink(pr
);
3183 lck_mtx_lock(nd6_mutex
);
3186 "%s: failed to make %s/%d offlink on %s, errno=%d\n",
3187 __func__
, ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3188 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
), err
));
3191 /* Add the entries back */
3193 err
= nd6_prefix_onlink_scoped(opr
, opr
->ndpr_ifp
->if_index
);
3196 "%s: failed to make %s/%d scoped onlink on %s, "
3197 "errno=%d\n", __func__
,
3198 ip6_sprintf(&opr
->ndpr_prefix
.sin6_addr
),
3199 opr
->ndpr_plen
, if_name(opr
->ndpr_ifp
), err
));
3203 err
= nd6_prefix_onlink_scoped(pr
, IFSCOPE_NONE
);
3206 "%s: failed to make %s/%d onlink on %s, errno=%d\n",
3207 __func__
, ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3208 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
), err
));
3213 "%s: error promoting %s/%d to %s from %s\n",
3214 __func__
, ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3215 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
),
3216 (opr
!= NULL
) ? if_name(opr
->ndpr_ifp
) : "NONE"));
3219 "%s: %s/%d promoted, previously on %s\n",
3220 if_name(pr
->ndpr_ifp
),
3221 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
), pr
->ndpr_plen
,
3222 (opr
!= NULL
) ? if_name(opr
->ndpr_ifp
) : "NONE"));
3230 nd6_prefix_onlink_common(struct nd_prefix
*pr
, boolean_t force_scoped
,
3231 unsigned int ifscope
)
3234 struct ifnet
*ifp
= pr
->ndpr_ifp
;
3235 struct sockaddr_in6 mask6
, prefix
;
3236 struct nd_prefix
*opr
;
3239 struct rtentry
*rt
= NULL
;
3241 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
3245 if ((pr
->ndpr_stateflags
& NDPRF_ONLINK
) != 0) {
3247 "nd6_prefix_onlink: %s/%d on %s scoped=%d is already "
3248 "on-link\n", ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3249 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
),
3250 (pr
->ndpr_stateflags
& NDPRF_IFSCOPE
) ? 1 : 0);
3257 * Add the interface route associated with the prefix. Before
3258 * installing the route, check if there's the same prefix on another
3259 * interface, and the prefix has already installed the interface route.
3261 opr
= nd6_prefix_equal_lookup(pr
, FALSE
);
3265 if (!ip6_doscopedroute
) {
3266 /* if an interface route already exists, just return */
3269 ifscope
= IFSCOPE_NONE
;
3270 } else if (!force_scoped
) {
3272 * If a primary/non-scoped interface route already exists,
3273 * install the new one as a scoped entry. If the existing
3274 * interface route is scoped, install new as non-scoped.
3276 ifscope
= (opr
!= NULL
) ? ifp
->if_index
: IFSCOPE_NONE
;
3277 opr
= nd6_prefix_equal_lookup(pr
, TRUE
);
3280 else if (ifscope
!= IFSCOPE_NONE
)
3281 ifscope
= IFSCOPE_NONE
;
3285 * We prefer link-local addresses as the associated interface address.
3287 /* search for a link-local addr */
3288 ifa
= (struct ifaddr
*)in6ifa_ifpforlinklocal(ifp
,
3292 struct in6_ifaddr
*ia6
;
3293 ifnet_lock_shared(ifp
);
3294 IFP_TO_IA6(ifp
, ia6
);
3295 ifnet_lock_done(ifp
);
3298 /* should we care about ia6_flags? */
3303 * This can still happen, when, for example, we receive an RA
3304 * containing a prefix with the L bit set and the A bit clear,
3305 * after removing all IPv6 addresses on the receiving
3306 * interface. This should, of course, be rare though.
3309 "nd6_prefix_onlink: failed to find any ifaddr"
3310 " to add route for a prefix(%s/%d) on %s\n",
3311 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3312 pr
->ndpr_plen
, if_name(ifp
)));
3318 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs.
3319 * ifa->ifa_rtrequest = nd6_rtrequest;
3321 bzero(&mask6
, sizeof(mask6
));
3322 mask6
.sin6_len
= sizeof(mask6
);
3323 mask6
.sin6_addr
= pr
->ndpr_mask
;
3324 prefix
= pr
->ndpr_prefix
;
3328 rtflags
= ifa
->ifa_flags
| RTF_CLONING
| RTF_UP
;
3330 if (nd6_need_cache(ifp
)) {
3331 /* explicitly set in case ifa_flags does not set the flag. */
3332 rtflags
|= RTF_CLONING
;
3335 * explicitly clear the cloning bit in case ifa_flags sets it.
3337 rtflags
&= ~RTF_CLONING
;
3340 lck_mtx_unlock(nd6_mutex
);
3342 error
= rtrequest_scoped(RTM_ADD
, (struct sockaddr
*)&prefix
,
3343 ifa
->ifa_addr
, (struct sockaddr
*)&mask6
, rtflags
, &rt
,
3348 nd6_rtmsg(RTM_ADD
, rt
);
3353 nd6log((LOG_ERR
, "nd6_prefix_onlink: failed to add route for a"
3354 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx,"
3355 " scoped=%d, errno = %d\n",
3356 ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3357 pr
->ndpr_plen
, if_name(ifp
),
3358 ip6_sprintf(&((struct sockaddr_in6
*)ifa
->ifa_addr
)->sin6_addr
),
3359 ip6_sprintf(&mask6
.sin6_addr
), rtflags
,
3360 (ifscope
!= IFSCOPE_NONE
), error
));
3364 lck_mtx_lock(nd6_mutex
);
3367 pr
->ndpr_stateflags
&= ~NDPRF_IFSCOPE
;
3368 if (rt
!= NULL
|| error
== EEXIST
) {
3369 pr
->ndpr_stateflags
|= NDPRF_ONLINK
;
3370 if (ifscope
!= IFSCOPE_NONE
)
3371 pr
->ndpr_stateflags
|= NDPRF_IFSCOPE
;
3381 nd6_prefix_onlink(struct nd_prefix
*pr
)
3383 return (nd6_prefix_onlink_common(pr
, FALSE
, IFSCOPE_NONE
));
3387 nd6_prefix_onlink_scoped(struct nd_prefix
*pr
, unsigned int ifscope
)
3389 return (nd6_prefix_onlink_common(pr
, TRUE
, ifscope
));
3393 nd6_prefix_offlink(struct nd_prefix
*pr
)
3395 int plen
, error
= 0;
3396 struct ifnet
*ifp
= pr
->ndpr_ifp
;
3397 struct nd_prefix
*opr
;
3398 struct sockaddr_in6 sa6
, mask6
, prefix
;
3399 struct rtentry
*rt
= NULL
;
3400 unsigned int ifscope
;
3402 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3406 if ((pr
->ndpr_stateflags
& NDPRF_ONLINK
) == 0) {
3408 "nd6_prefix_offlink: %s/%d on %s scoped=%d is already "
3409 "off-link\n", ip6_sprintf(&pr
->ndpr_prefix
.sin6_addr
),
3410 pr
->ndpr_plen
, if_name(pr
->ndpr_ifp
),
3411 (pr
->ndpr_stateflags
& NDPRF_IFSCOPE
) ? 1 : 0));
3416 bzero(&sa6
, sizeof(sa6
));
3417 sa6
.sin6_family
= AF_INET6
;
3418 sa6
.sin6_len
= sizeof(sa6
);
3419 bcopy(&pr
->ndpr_prefix
.sin6_addr
, &sa6
.sin6_addr
,
3420 sizeof(struct in6_addr
));
3421 bzero(&mask6
, sizeof(mask6
));
3422 mask6
.sin6_family
= AF_INET6
;
3423 mask6
.sin6_len
= sizeof(sa6
);
3424 bcopy(&pr
->ndpr_mask
, &mask6
.sin6_addr
, sizeof(struct in6_addr
));
3425 prefix
= pr
->ndpr_prefix
;
3426 plen
= pr
->ndpr_plen
;
3429 ifscope
= (pr
->ndpr_stateflags
& NDPRF_IFSCOPE
) ?
3430 ifp
->if_index
: IFSCOPE_NONE
;
3432 error
= rtrequest_scoped(RTM_DELETE
, (struct sockaddr
*)&sa6
,
3433 NULL
, (struct sockaddr
*)&mask6
, 0, &rt
, ifscope
);
3436 /* report the route deletion to the routing socket. */
3438 nd6_rtmsg(RTM_DELETE
, rt
);
3443 * The following check takes place only when Scoped Routing
3444 * is not enabled. There might be the same prefix on another
3445 * interface, the prefix which could not be on-link just
3446 * because we have the interface route (see comments in
3447 * nd6_prefix_onlink). If there's one, try to make the prefix
3448 * on-link on the interface.
3450 lck_mtx_lock(nd6_mutex
);
3451 opr
= nd_prefix
.lh_first
;
3453 /* does not apply in the Scoped Routing case */
3454 if (ip6_doscopedroute
)
3458 opr
= opr
->ndpr_next
;
3463 if ((opr
->ndpr_stateflags
& NDPRF_ONLINK
) != 0) {
3465 opr
= opr
->ndpr_next
;
3469 * KAME specific: detached prefixes should not be
3472 if ((opr
->ndpr_stateflags
& NDPRF_DETACHED
) != 0) {
3474 opr
= opr
->ndpr_next
;
3477 if (opr
->ndpr_plen
== plen
&&
3478 in6_are_prefix_equal(&prefix
.sin6_addr
,
3479 &opr
->ndpr_prefix
.sin6_addr
, plen
)) {
3483 lck_mtx_unlock(nd6_mutex
);
3484 if ((e
= nd6_prefix_onlink(opr
)) != 0) {
3486 "nd6_prefix_offlink: failed to "
3487 "recover a prefix %s/%d from %s "
3488 "to %s (errno = %d)\n",
3489 ip6_sprintf(&opr
->ndpr_prefix
.sin6_addr
),
3490 opr
->ndpr_plen
, if_name(ifp
),
3491 if_name(opr
->ndpr_ifp
), e
));
3493 lck_mtx_lock(nd6_mutex
);
3494 opr
= nd_prefix
.lh_first
;
3497 opr
= opr
->ndpr_next
;
3500 lck_mtx_unlock(nd6_mutex
);
3503 "nd6_prefix_offlink: failed to delete route: "
3504 "%s/%d on %s, scoped %d, (errno = %d)\n",
3505 ip6_sprintf(&sa6
.sin6_addr
), plen
, if_name(ifp
),
3506 (ifscope
!= IFSCOPE_NONE
), error
));
3510 pr
->ndpr_stateflags
&= ~(NDPRF_ONLINK
| NDPRF_IFSCOPE
);
3516 static struct in6_ifaddr
*
3518 struct nd_prefix
*pr
,
3521 struct ifnet
*ifp
= pr
->ndpr_ifp
;
3522 struct in6_aliasreq ifra
;
3523 struct in6_ifaddr
*ia
, *ib
;
3526 struct in6_addr mask
;
3530 * find a link-local address (will be interface ID).
3531 * Is it really mandatory? Theoretically, a global or a site-local
3532 * address can be configured without a link-local address, if we
3533 * have a unique interface identifier...
3535 * it is not mandatory to have a link-local address, we can generate
3536 * interface identifier on the fly. we do this because:
3537 * (1) it should be the easiest way to find interface identifier.
3538 * (2) RFC2462 5.4 suggesting the use of the same interface identifier
3539 * for multiple addresses on a single interface, and possible shortcut
3540 * of DAD. we omitted DAD for this reason in the past.
3541 * (3) a user can prevent autoconfiguration of global address
3542 * by removing link-local address by hand (this is partly because we
3543 * don't have other way to control the use of IPv6 on an interface.
3544 * this has been our design choice - cf. NRL's "ifconfig auto").
3545 * (4) it is easier to manage when an interface has addresses
3546 * with the same interface identifier, than to have multiple addresses
3547 * with different interface identifiers.
3549 ib
= in6ifa_ifpforlinklocal(ifp
, 0);/* 0 is OK? */
3553 IFA_LOCK(&ib
->ia_ifa
);
3555 prefixlen
= pr
->ndpr_plen
;
3556 in6_len2mask(&mask
, prefixlen
);
3557 plen0
= in6_mask2len(&ib
->ia_prefixmask
.sin6_addr
, NULL
);
3558 /* prefixlen + ifidlen must be equal to 128 */
3559 if (prefixlen
!= plen0
) {
3560 nd6log((LOG_INFO
, "in6_ifadd: wrong prefixlen for %s "
3561 "(prefix=%d ifid=%d)\n",
3562 if_name(ifp
), prefixlen
, 128 - plen0
));
3564 IFA_UNLOCK(&ib
->ia_ifa
);
3565 IFA_REMREF(&ib
->ia_ifa
);
3571 bzero(&ifra
, sizeof(ifra
));
3573 * in6_update_ifa() does not use ifra_name, but we accurately set it
3576 strncpy(ifra
.ifra_name
, if_name(ifp
), sizeof(ifra
.ifra_name
));
3577 ifra
.ifra_addr
.sin6_family
= AF_INET6
;
3578 ifra
.ifra_addr
.sin6_len
= sizeof(struct sockaddr_in6
);
3580 bcopy(&pr
->ndpr_prefix
.sin6_addr
, &ifra
.ifra_addr
.sin6_addr
,
3581 sizeof(ifra
.ifra_addr
.sin6_addr
));
3582 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[0] &= mask
.s6_addr32
[0];
3583 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[1] &= mask
.s6_addr32
[1];
3584 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[2] &= mask
.s6_addr32
[2];
3585 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[3] &= mask
.s6_addr32
[3];
3588 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[0] |=
3589 (ib
->ia_addr
.sin6_addr
.s6_addr32
[0] & ~mask
.s6_addr32
[0]);
3590 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[1] |=
3591 (ib
->ia_addr
.sin6_addr
.s6_addr32
[1] & ~mask
.s6_addr32
[1]);
3592 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[2] |=
3593 (ib
->ia_addr
.sin6_addr
.s6_addr32
[2] & ~mask
.s6_addr32
[2]);
3594 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[3] |=
3595 (ib
->ia_addr
.sin6_addr
.s6_addr32
[3] & ~mask
.s6_addr32
[3]);
3597 /* new prefix mask. */
3598 ifra
.ifra_prefixmask
.sin6_len
= sizeof(struct sockaddr_in6
);
3599 ifra
.ifra_prefixmask
.sin6_family
= AF_INET6
;
3600 bcopy(&mask
, &ifra
.ifra_prefixmask
.sin6_addr
,
3601 sizeof(ifra
.ifra_prefixmask
.sin6_addr
));
3604 ifra
.ifra_lifetime
.ia6t_vltime
= pr
->ndpr_vltime
;
3605 ifra
.ifra_lifetime
.ia6t_pltime
= pr
->ndpr_pltime
;
3607 /* XXX: scope zone ID? */
3609 ifra
.ifra_flags
|= IN6_IFF_AUTOCONF
; /* obey autoconf */
3612 IFA_UNLOCK(&ib
->ia_ifa
);
3613 IFA_REMREF(&ib
->ia_ifa
);
3616 * Make sure that we do not have this address already. This should
3617 * usually not happen, but we can still see this case, e.g., if we
3618 * have manually configured the exact address to be configured.
3620 if ((ib
= in6ifa_ifpwithaddr(ifp
, &ifra
.ifra_addr
.sin6_addr
)) != NULL
) {
3621 IFA_REMREF(&ib
->ia_ifa
);
3622 /* this should be rare enough to make an explicit log */
3623 log(LOG_INFO
, "in6_ifadd: %s is already configured\n",
3624 ip6_sprintf(&ifra
.ifra_addr
.sin6_addr
));
3629 * Allocate ifaddr structure, link into chain, etc.
3630 * If we are going to create a new address upon receiving a multicasted
3631 * RA, we need to impose a random delay before starting DAD.
3632 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
3636 updateflags
|= IN6_IFAUPDATE_DADDELAY
;
3637 error
= in6_update_ifa(ifp
, &ifra
, NULL
, updateflags
, M_WAITOK
);
3640 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
3641 ip6_sprintf(&ifra
.ifra_addr
.sin6_addr
), if_name(ifp
),
3643 return(NULL
); /* ifaddr must not have been allocated. */
3646 ia
= in6ifa_ifpwithaddr(ifp
, &ifra
.ifra_addr
.sin6_addr
);
3648 in6_post_msg(ifp
, KEV_INET6_NEW_RTADV_ADDR
, ia
);
3650 return(ia
); /* this must NOT be NULL. */
3653 #define IA6_NONCONST(i) ((struct in6_ifaddr *)(uintptr_t)(i))
3657 const struct in6_ifaddr
*ia0
, /* corresponding public address */
3661 struct ifnet
*ifp
= ia0
->ia_ifa
.ifa_ifp
;
3662 struct in6_ifaddr
*ia
, *newia
;
3663 struct in6_aliasreq ifra
;
3665 int trylimit
= 3; /* XXX: adhoc value */
3667 u_int32_t randid
[2];
3668 time_t vltime0
, pltime0
;
3669 struct timeval timenow
;
3670 struct in6_addr addr
;
3671 struct nd_prefix
*ndpr
;
3673 getmicrotime(&timenow
);
3675 bzero(&ifra
, sizeof(ifra
));
3676 strncpy(ifra
.ifra_name
, if_name(ifp
), sizeof(ifra
.ifra_name
));
3677 IFA_LOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3678 ifra
.ifra_addr
= ia0
->ia_addr
;
3679 /* copy prefix mask */
3680 ifra
.ifra_prefixmask
= ia0
->ia_prefixmask
;
3681 /* clear the old IFID */
3682 for (i
= 0; i
< 4; i
++) {
3683 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[i
]
3684 &= ifra
.ifra_prefixmask
.sin6_addr
.s6_addr32
[i
];
3686 addr
= ia0
->ia_addr
.sin6_addr
;
3687 IFA_UNLOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3690 in6_get_tmpifid(ifp
, (u_int8_t
*)randid
,
3691 (const u_int8_t
*)&addr
.s6_addr
[8], forcegen
);
3693 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[2] |=
3694 (randid
[0] & ~(ifra
.ifra_prefixmask
.sin6_addr
.s6_addr32
[2]));
3695 ifra
.ifra_addr
.sin6_addr
.s6_addr32
[3] |=
3696 (randid
[1] & ~(ifra
.ifra_prefixmask
.sin6_addr
.s6_addr32
[3]));
3699 * in6_get_tmpifid() quite likely provided a unique interface ID.
3700 * However, we may still have a chance to see collision, because
3701 * there may be a time lag between generation of the ID and generation
3702 * of the address. So, we'll do one more sanity check.
3704 if ((ia
= in6ifa_ifpwithaddr(ifp
, &ifra
.ifra_addr
.sin6_addr
)) != NULL
) {
3705 IFA_REMREF(&ia
->ia_ifa
);
3706 if (trylimit
-- == 0) {
3707 nd6log((LOG_NOTICE
, "in6_tmpifadd: failed to find "
3708 "a unique random IFID\n"));
3716 * The Valid Lifetime is the lower of the Valid Lifetime of the
3717 * public address or TEMP_VALID_LIFETIME.
3718 * The Preferred Lifetime is the lower of the Preferred Lifetime
3719 * of the public address or TEMP_PREFERRED_LIFETIME -
3722 IFA_LOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3723 vltime0
= IFA6_IS_INVALID(ia0
)
3725 : (ia0
->ia6_lifetime
.ia6t_vltime
-
3726 (timenow
.tv_sec
- ia0
->ia6_updatetime
));
3727 if (vltime0
> ip6_temp_valid_lifetime
)
3728 vltime0
= ip6_temp_valid_lifetime
;
3729 pltime0
= IFA6_IS_DEPRECATED(ia0
)
3731 : (ia0
->ia6_lifetime
.ia6t_pltime
-
3732 (timenow
.tv_sec
- ia0
->ia6_updatetime
));
3733 if (pltime0
> ip6_temp_preferred_lifetime
- ip6_desync_factor
)
3734 pltime0
= ip6_temp_preferred_lifetime
- ip6_desync_factor
;
3735 ifra
.ifra_lifetime
.ia6t_vltime
= vltime0
;
3736 ifra
.ifra_lifetime
.ia6t_pltime
= pltime0
;
3737 IFA_UNLOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3739 * A temporary address is created only if this calculated Preferred
3740 * Lifetime is greater than REGEN_ADVANCE time units.
3742 if (ifra
.ifra_lifetime
.ia6t_pltime
<= ip6_temp_regen_advance
)
3745 /* XXX: scope zone ID? */
3747 ifra
.ifra_flags
|= (IN6_IFF_AUTOCONF
|IN6_IFF_TEMPORARY
);
3749 /* allocate ifaddr structure, link into chain, etc. */
3753 updateflags
|= IN6_IFAUPDATE_DADDELAY
;
3755 if ((error
= in6_update_ifa(ifp
, &ifra
, NULL
, updateflags
, how
)) != 0)
3758 newia
= in6ifa_ifpwithaddr(ifp
, &ifra
.ifra_addr
.sin6_addr
);
3759 if (newia
== NULL
) { /* XXX: can it happen? */
3761 "in6_tmpifadd: ifa update succeeded, but we got "
3763 return(EINVAL
); /* XXX */
3765 IFA_LOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3766 ndpr
= ia0
->ia6_ndpr
;
3769 * We lost the race with another thread that has purged
3770 * ia0 address; in this case, purge the tmp addr as well.
3772 nd6log((LOG_ERR
, "in6_tmpifadd: no public address\n"));
3773 VERIFY(!(ia0
->ia6_flags
& IN6_IFF_AUTOCONF
));
3774 IFA_UNLOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3775 in6_purgeaddr(&newia
->ia_ifa
);
3776 IFA_REMREF(&newia
->ia_ifa
);
3777 return (EADDRNOTAVAIL
);
3779 NDPR_ADDREF(ndpr
); /* for us */
3780 IFA_UNLOCK(&IA6_NONCONST(ia0
)->ia_ifa
);
3781 IFA_LOCK(&newia
->ia_ifa
);
3782 if (newia
->ia6_ndpr
!= NULL
) {
3783 NDPR_LOCK(newia
->ia6_ndpr
);
3784 VERIFY(newia
->ia6_ndpr
->ndpr_addrcnt
!= 0);
3785 newia
->ia6_ndpr
->ndpr_addrcnt
--;
3786 NDPR_UNLOCK(newia
->ia6_ndpr
);
3787 NDPR_REMREF(newia
->ia6_ndpr
); /* release addr reference */
3789 newia
->ia6_ndpr
= ndpr
;
3790 NDPR_LOCK(newia
->ia6_ndpr
);
3791 newia
->ia6_ndpr
->ndpr_addrcnt
++;
3792 VERIFY(newia
->ia6_ndpr
->ndpr_addrcnt
!= 0);
3793 NDPR_ADDREF_LOCKED(newia
->ia6_ndpr
); /* for addr reference */
3794 NDPR_UNLOCK(newia
->ia6_ndpr
);
3795 IFA_UNLOCK(&newia
->ia_ifa
);
3797 * A newly added address might affect the status of other addresses.
3798 * XXX: when the temporary address is generated with a new public
3799 * address, the onlink check is redundant. However, it would be safe
3800 * to do the check explicitly everywhere a new address is generated,
3801 * and, in fact, we surely need the check when we create a new
3802 * temporary address due to deprecation of an old temporary address.
3804 lck_mtx_lock(nd6_mutex
);
3805 pfxlist_onlink_check();
3806 lck_mtx_unlock(nd6_mutex
);
3807 IFA_REMREF(&newia
->ia_ifa
);
3809 /* remove our reference */
3817 in6_init_prefix_ltimes(struct nd_prefix
*ndpr
)
3819 struct timeval timenow
;
3821 NDPR_LOCK_ASSERT_HELD(ndpr
);
3823 getmicrotime(&timenow
);
3824 /* check if preferred lifetime > valid lifetime. RFC2462 5.5.3 (c) */
3825 if (ndpr
->ndpr_pltime
> ndpr
->ndpr_vltime
) {
3826 nd6log((LOG_INFO
, "in6_init_prefix_ltimes: preferred lifetime"
3827 "(%d) is greater than valid lifetime(%d)\n",
3828 (u_int
)ndpr
->ndpr_pltime
, (u_int
)ndpr
->ndpr_vltime
));
3831 if (ndpr
->ndpr_pltime
== ND6_INFINITE_LIFETIME
)
3832 ndpr
->ndpr_preferred
= 0;
3834 ndpr
->ndpr_preferred
= timenow
.tv_sec
+ ndpr
->ndpr_pltime
;
3835 if (ndpr
->ndpr_vltime
== ND6_INFINITE_LIFETIME
)
3836 ndpr
->ndpr_expire
= 0;
3838 ndpr
->ndpr_expire
= timenow
.tv_sec
+ ndpr
->ndpr_vltime
;
3844 in6_init_address_ltimes(__unused
struct nd_prefix
*new,
3845 struct in6_addrlifetime
*lt6
, boolean_t is_temporary
)
3847 struct timeval timenow
;
3849 getmicrotime(&timenow
);
3850 /* Valid lifetime must not be updated unless explicitly specified. */
3851 /* init ia6t_expire */
3852 if (!is_temporary
&& lt6
->ia6t_vltime
== ND6_INFINITE_LIFETIME
)
3853 lt6
->ia6t_expire
= 0;
3855 lt6
->ia6t_expire
= timenow
.tv_sec
;
3856 lt6
->ia6t_expire
+= lt6
->ia6t_vltime
;
3859 /* init ia6t_preferred */
3860 if (!is_temporary
&& lt6
->ia6t_pltime
== ND6_INFINITE_LIFETIME
)
3861 lt6
->ia6t_preferred
= 0;
3863 lt6
->ia6t_preferred
= timenow
.tv_sec
;
3864 lt6
->ia6t_preferred
+= lt6
->ia6t_pltime
;
3869 * Delete all the routing table entries that use the specified gateway.
3870 * XXX: this function causes search through all entries of routing table, so
3871 * it shouldn't be called when acting as a router.
3875 struct in6_addr
*gateway
,
3878 struct radix_node_head
*rnh
= rt_tables
[AF_INET6
];
3880 /* We'll care only link-local addresses */
3881 if (!IN6_IS_ADDR_LINKLOCAL(gateway
)) {
3884 lck_mtx_lock(rnh_lock
);
3885 /* XXX: hack for KAME's link-local address kludge */
3886 gateway
->s6_addr16
[1] = htons(ifp
->if_index
);
3888 rnh
->rnh_walktree(rnh
, rt6_deleteroute
, (void *)gateway
);
3889 lck_mtx_unlock(rnh_lock
);
3894 struct radix_node
*rn
,
3897 #define SIN6(s) ((struct sockaddr_in6 *)s)
3898 struct rtentry
*rt
= (struct rtentry
*)rn
;
3899 struct in6_addr
*gate
= (struct in6_addr
*)arg
;
3901 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
3904 if (rt
->rt_gateway
== NULL
|| rt
->rt_gateway
->sa_family
!= AF_INET6
) {
3909 if (!IN6_ARE_ADDR_EQUAL(gate
, &SIN6(rt
->rt_gateway
)->sin6_addr
)) {
3914 * Do not delete a static route.
3915 * XXX: this seems to be a bit ad-hoc. Should we consider the
3916 * 'cloned' bit instead?
3918 if ((rt
->rt_flags
& RTF_STATIC
) != 0) {
3923 * We delete only host route. This means, in particular, we don't
3924 * delete default route.
3926 if ((rt
->rt_flags
& RTF_HOST
) == 0) {
3932 * Safe to drop rt_lock and use rt_key, rt_gateway, since holding
3933 * rnh_lock here prevents another thread from calling rt_setgate()
3937 return (rtrequest_locked(RTM_DELETE
, rt_key(rt
), rt
->rt_gateway
,
3938 rt_mask(rt
), rt
->rt_flags
, 0));
3943 nd6_setdefaultiface(
3947 ifnet_t def_ifp
= NULL
;
3949 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
3951 ifnet_head_lock_shared();
3952 if (ifindex
< 0 || if_index
< ifindex
) {
3956 def_ifp
= ifindex2ifnet
[ifindex
];
3959 lck_mtx_lock(nd6_mutex
);
3960 if (nd6_defifindex
!= ifindex
) {
3961 struct ifnet
*odef_ifp
= nd6_defifp
;
3963 nd6_defifindex
= ifindex
;
3964 if (nd6_defifindex
> 0)
3965 nd6_defifp
= def_ifp
;
3969 if (nd6_defifp
!= NULL
)
3970 nd6log((LOG_INFO
, "%s: is now the default "
3971 "interface (was %s)\n", if_name(nd6_defifp
),
3972 odef_ifp
!= NULL
? if_name(odef_ifp
) : "NONE"));
3974 nd6log((LOG_INFO
, "No default interface set\n"));
3977 * If the Default Router List is empty, install a route
3978 * to the specified interface as default or remove the default
3979 * route when the default interface becomes canceled.
3980 * The check for the queue is actually redundant, but
3981 * we do this here to avoid re-install the default route
3982 * if the list is NOT empty.
3984 if (ip6_doscopedroute
|| TAILQ_FIRST(&nd_defrouter
) == NULL
) {
3985 defrtrlist_sync(nd6_defifp
);
3986 nd6_prefix_sync(nd6_defifp
);
3990 * Our current implementation assumes one-to-one maping between
3991 * interfaces and links, so it would be natural to use the
3992 * default interface as the default link.
3994 scope6_setdefault(nd6_defifp
);
3996 lck_mtx_unlock(nd6_mutex
);