1/*
2 * Copyright (c) 2003-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
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 $	*/
31
32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
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.
47 *
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
58 * SUCH DAMAGE.
59 */
60
61
62#include <sys/param.h>
63#include <sys/systm.h>
64#include <sys/malloc.h>
65#include <sys/mbuf.h>
66#include <sys/socket.h>
67#include <sys/sockio.h>
68#include <sys/time.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>
74
75#include <kern/lock.h>
76#include <kern/zalloc.h>
77#include <machine/machine_routines.h>
78
79#include <net/if.h>
80#include <net/if_types.h>
81#include <net/if_dl.h>
82#include <net/route.h>
83#include <net/radix.h>
84
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>
93
94#include <net/net_osdep.h>
95
96static void defrouter_addreq(struct nd_defrouter *, boolean_t);
97static void defrouter_delreq(struct nd_defrouter *);
98static struct nd_defrouter *defrtrlist_update_common(struct nd_defrouter *,
99    boolean_t);
100static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
101
102static struct in6_ifaddr *in6_ifadd(struct nd_prefix *, int);
103static void defrtrlist_sync(struct ifnet *);
104
105static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *,
106	struct nd_defrouter *);
107static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
108static void pfxrtr_del(struct nd_pfxrouter *);
109static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
110static void nd6_rtmsg(int, struct rtentry *);
111
112static int nd6_prefix_onlink_common(struct nd_prefix *, boolean_t,
113    unsigned int);
114static struct nd_prefix *nd6_prefix_equal_lookup(struct nd_prefix *, boolean_t);
115static void nd6_prefix_sync(struct ifnet *);
116
117static void in6_init_address_ltimes(struct nd_prefix *,
118    struct in6_addrlifetime *, boolean_t);
119
120static int rt6_deleteroute(struct radix_node *, void *);
121
122static struct nd_defrouter *nddr_alloc(int);
123static void nddr_free(struct nd_defrouter *);
124static void nddr_trace(struct nd_defrouter *, int);
125
126static struct nd_prefix *ndpr_alloc(int);
127static void ndpr_free(struct nd_prefix *);
128static void ndpr_trace(struct nd_prefix *, int);
129
130extern int nd6_recalc_reachtm_interval;
131
132static struct ifnet *nd6_defifp;
133int nd6_defifindex;
134static unsigned int nd6_defrouter_genid;
135
136int ip6_use_tempaddr = 1; /* use temp addr by default for testing now */
137
138int nd6_accept_6to4 = 1;
139
140int ip6_desync_factor;
141u_int32_t ip6_temp_preferred_lifetime = DEF_TEMP_PREFERRED_LIFETIME;
142u_int32_t ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME;
143/*
144 * shorter lifetimes for debugging purposes.
145u_int32_t ip6_temp_preferred_lifetime = 800;
146static u_int32_t ip6_temp_valid_lifetime = 1800;
147*/
148int ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE;
149
150extern lck_mtx_t *nd6_mutex;
151
152/* Serialization variables for single thread access to nd_prefix */
153static boolean_t nd_prefix_busy;
154static void *nd_prefix_waitchan = &nd_prefix_busy;
155static int nd_prefix_waiters = 0;
156
157/* Serialization variables for single thread access to nd_defrouter */
158static boolean_t nd_defrouter_busy;
159static void *nd_defrouter_waitchan = &nd_defrouter_busy;
160static int nd_defrouter_waiters = 0;
161
162/* RTPREF_MEDIUM has to be 0! */
163#define RTPREF_HIGH	1
164#define RTPREF_MEDIUM	0
165#define RTPREF_LOW	(-1)
166#define RTPREF_RESERVED	(-2)
167#define RTPREF_INVALID	(-3)	/* internal */
168
169#define	NDPR_TRACE_HIST_SIZE	32		/* size of trace history */
170
171/* For gdb */
172__private_extern__ unsigned int ndpr_trace_hist_size = NDPR_TRACE_HIST_SIZE;
173
174struct nd_prefix_dbg {
175	struct nd_prefix	ndpr_pr;		/* nd_prefix */
176	u_int16_t		ndpr_refhold_cnt;	/* # of ref */
177	u_int16_t		ndpr_refrele_cnt;	/* # of rele */
178	/*
179	 * Circular lists of ndpr_addref and ndpr_remref callers.
180	 */
181	ctrace_t		ndpr_refhold[NDPR_TRACE_HIST_SIZE];
182	ctrace_t		ndpr_refrele[NDPR_TRACE_HIST_SIZE];
183};
184
185static unsigned int ndpr_debug;			/* debug flags */
186static unsigned int ndpr_size;			/* size of zone element */
187static struct zone *ndpr_zone;			/* zone for nd_prefix */
188
189#define	NDPR_ZONE_MAX	64			/* maximum elements in zone */
190#define	NDPR_ZONE_NAME	"nd6_prefix"		/* zone name */
191
192#define	NDDR_TRACE_HIST_SIZE	32              /* size of trace history */
193
194/* For gdb */
195__private_extern__ unsigned int nddr_trace_hist_size = NDDR_TRACE_HIST_SIZE;
196
197struct nd_defrouter_dbg {
198	struct nd_defrouter	nddr_dr;		/* nd_defrouter */
199	uint16_t		nddr_refhold_cnt;	/* # of ref */
200	uint16_t		nddr_refrele_cnt;	/* # of rele */
201	/*
202	 * Circular lists of ndpr_addref and ndpr_remref callers.
203	 */
204	ctrace_t		nddr_refhold[NDDR_TRACE_HIST_SIZE];
205	ctrace_t		nddr_refrele[NDDR_TRACE_HIST_SIZE];
206};
207
208static unsigned int nddr_debug;			/* debug flags */
209static unsigned int nddr_size;			/* size of zone element */
210static struct zone *nddr_zone;			/* zone for nd_defrouter */
211
212#define	NDDR_ZONE_MAX	64			/* maximum elements in zone */
213#define	NDDR_ZONE_NAME	"nd6_defrouter"		/* zone name */
214
215static unsigned int ndprtr_size;		/* size of zone element */
216static struct zone *ndprtr_zone;		/* zone for nd_pfxrouter */
217
218#define	NDPRTR_ZONE_MAX	64			/* maximum elements in zone */
219#define	NDPRTR_ZONE_NAME "nd6_pfxrouter"	/* zone name */
220
221void
222nd6_rtr_init(void)
223{
224	PE_parse_boot_argn("ifa_debug", &ndpr_debug, sizeof (ndpr_debug));
225	PE_parse_boot_argn("ifa_debug", &nddr_debug, sizeof (nddr_debug));
226
227	ndpr_size = (ndpr_debug == 0) ? sizeof (struct nd_prefix) :
228	    sizeof (struct nd_prefix_dbg);
229	ndpr_zone = zinit(ndpr_size, NDPR_ZONE_MAX * ndpr_size, 0,
230	    NDPR_ZONE_NAME);
231	if (ndpr_zone == NULL) {
232		panic("%s: failed allocating %s", __func__, NDPR_ZONE_NAME);
233		/* NOTREACHED */
234	}
235	zone_change(ndpr_zone, Z_EXPAND, TRUE);
236	zone_change(ndpr_zone, Z_CALLERACCT, FALSE);
237
238	nddr_size = (nddr_debug == 0) ? sizeof (struct nd_defrouter) :
239	    sizeof (struct nd_defrouter_dbg);
240	nddr_zone = zinit(nddr_size, NDDR_ZONE_MAX * nddr_size, 0,
241	    NDDR_ZONE_NAME);
242	if (nddr_zone == NULL) {
243		panic("%s: failed allocating %s", __func__, NDDR_ZONE_NAME);
244		/* NOTREACHED */
245	}
246	zone_change(nddr_zone, Z_EXPAND, TRUE);
247	zone_change(nddr_zone, Z_CALLERACCT, FALSE);
248
249	ndprtr_size = sizeof (struct nd_pfxrouter);
250	ndprtr_zone = zinit(ndprtr_size, NDPRTR_ZONE_MAX * ndprtr_size, 0,
251	    NDPRTR_ZONE_NAME);
252	if (ndprtr_zone == NULL) {
253		panic("%s: failed allocating %s", __func__, NDPRTR_ZONE_NAME);
254		/* NOTREACHED */
255	}
256	zone_change(ndprtr_zone, Z_EXPAND, TRUE);
257	zone_change(ndprtr_zone, Z_CALLERACCT, FALSE);
258}
259
260/*
261 * Receive Router Solicitation Message - just for routers.
262 * Router solicitation/advertisement is mostly managed by userland program
263 * (rtadvd) so here we have no function like nd6_ra_output().
264 *
265 * Based on RFC 2461
266 */
267void
268nd6_rs_input(
269	struct	mbuf *m,
270	int off,
271	int icmp6len)
272{
273	struct ifnet *ifp = m->m_pkthdr.rcvif;
274	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
275	struct nd_router_solicit *nd_rs;
276	struct in6_addr saddr6 = ip6->ip6_src;
277	char *lladdr = NULL;
278	int lladdrlen = 0;
279	union nd_opts ndopts;
280
281	/* Expect 32-bit aligned data pointer on strict-align platforms */
282	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
283
284	/* If I'm not a router, ignore it. */
285	if (!ip6_forwarding || !(ifp->if_eflags & IFEF_IPV6_ROUTER))
286		goto freeit;
287
288	/* Sanity checks */
289	if (ip6->ip6_hlim != 255) {
290		nd6log((LOG_ERR,
291		    "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
292		    ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
293		    ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
294		goto bad;
295	}
296
297	/*
298	 * Don't update the neighbor cache, if src = :: or a non-neighbor.
299	 * The former case indicates that the src has no IP address assigned
300	 * yet.  See nd6_ns_input() for the latter case.
301	 */
302	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
303		goto freeit;
304	} else {
305		struct sockaddr_in6 src_sa6;
306
307		bzero(&src_sa6, sizeof(src_sa6));
308		src_sa6.sin6_family = AF_INET6;
309		src_sa6.sin6_len = sizeof(src_sa6);
310		src_sa6.sin6_addr = ip6->ip6_src;
311		if (!nd6_is_addr_neighbor(&src_sa6, ifp, 0)) {
312			nd6log((LOG_INFO, "nd6_rs_input: "
313				"RS packet from non-neighbor\n"));
314			goto freeit;
315		}
316	}
317
318#ifndef PULLDOWN_TEST
319	IP6_EXTHDR_CHECK(m, off, icmp6len, return);
320	nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
321#else
322	IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len);
323	if (nd_rs == NULL) {
324		icmp6stat.icp6s_tooshort++;
325		return;
326	}
327#endif
328
329	icmp6len -= sizeof(*nd_rs);
330	nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
331	if (nd6_options(&ndopts) < 0) {
332		nd6log((LOG_INFO,
333		    "nd6_rs_input: invalid ND option, ignored\n"));
334		/* nd6_options have incremented stats */
335		goto freeit;
336	}
337
338	if (ndopts.nd_opts_src_lladdr) {
339		lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
340		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
341	}
342
343	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
344		nd6log((LOG_INFO,
345		    "nd6_rs_input: lladdrlen mismatch for %s "
346		    "(if %d, RS packet %d)\n",
347			ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
348		goto bad;
349	}
350
351	nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0);
352
353 freeit:
354	m_freem(m);
355	return;
356
357 bad:
358	icmp6stat.icp6s_badrs++;
359	m_freem(m);
360}
361
362/*
363 * Receive Router Advertisement Message.
364 *
365 * Based on RFC 2461
366 * TODO: on-link bit on prefix information
367 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing
368 */
369void
370nd6_ra_input(
371	struct	mbuf *m,
372	int off,
373	int icmp6len)
374{
375	struct ifnet *ifp = m->m_pkthdr.rcvif;
376	struct nd_ifinfo *ndi = NULL;
377	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
378	struct nd_router_advert *nd_ra;
379	struct in6_addr saddr6 = ip6->ip6_src;
380	int mcast = 0;
381	union nd_opts ndopts;
382	struct nd_defrouter *dr = NULL;
383	struct timeval timenow;
384	u_int32_t mtu = 0;
385	char *lladdr = NULL;
386	u_int32_t lladdrlen = 0;
387	struct nd_prefix_list *nd_prefix_list_head = NULL;
388	u_int32_t nd_prefix_list_length = 0;
389	struct in6_ifaddr *ia6 = NULL;
390
391	/* Expect 32-bit aligned data pointer on strict-align platforms */
392	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
393
394	getmicrotime(&timenow);
395
396	/*
397	 * Discard RA unless IFEF_ACCEPT_RTADV is set (as host), or when
398	 * IFEF_IPV6_ROUTER is set (as router) but the RA is not locally
399	 * generated.  For convenience, we allow locally generated (rtadvd)
400	 * RAs to be processed on the advertising interface, as a router.
401	 *
402	 * Note that we don't test against ip6_forwarding as we could be
403	 * both a host and a router on different interfaces, hence the
404	 * check against the per-interface flags.
405	 */
406	if (!(ifp->if_eflags & (IFEF_ACCEPT_RTADV | IFEF_IPV6_ROUTER)) ||
407	    ((ifp->if_eflags & IFEF_IPV6_ROUTER) &&
408	    (ia6 = ifa_foraddr6(&saddr6)) == NULL))
409		goto freeit;
410
411	if (ia6 != NULL) {
412		IFA_REMREF(&ia6->ia_ifa);
413		ia6 = NULL;
414	}
415
416	if (ip6->ip6_hlim != 255) {
417		nd6log((LOG_ERR,
418		    "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
419		    ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
420		    ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
421		goto bad;
422	}
423
424	if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
425		nd6log((LOG_ERR,
426		    "nd6_ra_input: src %s is not link-local\n",
427		    ip6_sprintf(&saddr6)));
428		goto bad;
429	}
430
431#ifndef PULLDOWN_TEST
432	IP6_EXTHDR_CHECK(m, off, icmp6len, return);
433	nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
434#else
435	IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len);
436	if (nd_ra == NULL) {
437		icmp6stat.icp6s_tooshort++;
438		return;
439	}
440#endif
441
442	icmp6len -= sizeof(*nd_ra);
443	nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
444	if (nd6_options(&ndopts) < 0) {
445		nd6log((LOG_INFO,
446		    "nd6_ra_input: invalid ND option, ignored\n"));
447		/* nd6_options have incremented stats */
448		goto freeit;
449	}
450
451    {
452	struct nd_defrouter dr0;
453	u_int32_t advreachable = nd_ra->nd_ra_reachable;
454
455	/* remember if this is a multicasted advertisement */
456	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
457		mcast = 1;
458
459	lck_rw_lock_shared(nd_if_rwlock);
460	if (ifp->if_index >= nd_ifinfo_indexlim) {
461		lck_rw_done(nd_if_rwlock);
462		goto freeit;
463	}
464	ndi = &nd_ifinfo[ifp->if_index];
465	VERIFY(ndi->initialized);
466	lck_mtx_lock(&ndi->lock);
467	bzero(&dr0, sizeof (dr0));
468	dr0.rtaddr = saddr6;
469	dr0.flags  = nd_ra->nd_ra_flags_reserved;
470	dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
471	dr0.expire = timenow.tv_sec + dr0.rtlifetime;
472	dr0.ifp = ifp;
473	/* unspecified or not? (RFC 2461 6.3.4) */
474	if (advreachable) {
475		advreachable = ntohl(advreachable);
476		if (advreachable <= MAX_REACHABLE_TIME &&
477		    ndi->basereachable != advreachable) {
478			ndi->basereachable = advreachable;
479			ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
480			ndi->recalctm = nd6_recalc_reachtm_interval; /* reset */
481		}
482	}
483	if (nd_ra->nd_ra_retransmit)
484		ndi->retrans = ntohl(nd_ra->nd_ra_retransmit);
485	if (nd_ra->nd_ra_curhoplimit)
486		ndi->chlim = nd_ra->nd_ra_curhoplimit;
487	lck_mtx_unlock(&ndi->lock);
488	lck_rw_done(nd_if_rwlock);
489	ndi = NULL;
490	lck_mtx_lock(nd6_mutex);
491	dr = defrtrlist_update(&dr0);
492	lck_mtx_unlock(nd6_mutex);
493    }
494
495	/*
496	 * prefix
497	 */
498	if (ndopts.nd_opts_pi) {
499		struct nd_opt_hdr *pt;
500		struct nd_opt_prefix_info *pi = NULL;
501		struct nd_prefix pr;
502
503		for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi;
504		     pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end;
505		     pt = (struct nd_opt_hdr *)((caddr_t)pt +
506						(pt->nd_opt_len << 3))) {
507			if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION)
508				continue;
509			pi = (struct nd_opt_prefix_info *)pt;
510
511			if (pi->nd_opt_pi_len != 4) {
512				nd6log((LOG_INFO,
513				    "nd6_ra_input: invalid option "
514				    "len %d for prefix information option, "
515				    "ignored\n", pi->nd_opt_pi_len));
516				continue;
517			}
518
519			if (128 < pi->nd_opt_pi_prefix_len) {
520				nd6log((LOG_INFO,
521				    "nd6_ra_input: invalid prefix "
522				    "len %d for prefix information option, "
523				    "ignored\n", pi->nd_opt_pi_prefix_len));
524				continue;
525			}
526
527			if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix)
528			 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) {
529				nd6log((LOG_INFO,
530				    "nd6_ra_input: invalid prefix "
531				    "%s, ignored\n",
532				    ip6_sprintf(&pi->nd_opt_pi_prefix)));
533				continue;
534			}
535
536			bzero(&pr, sizeof(pr));
537			lck_mtx_init(&pr.ndpr_lock, ifa_mtx_grp, ifa_mtx_attr);
538			NDPR_LOCK(&pr);
539			pr.ndpr_prefix.sin6_family = AF_INET6;
540			pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix);
541			pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix;
542			pr.ndpr_ifp = m->m_pkthdr.rcvif;
543
544			pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved &
545					      ND_OPT_PI_FLAG_ONLINK) ? 1 : 0;
546			pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved &
547					    ND_OPT_PI_FLAG_AUTO) ? 1 : 0;
548			pr.ndpr_plen = pi->nd_opt_pi_prefix_len;
549			pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time);
550			pr.ndpr_pltime =
551				ntohl(pi->nd_opt_pi_preferred_time);
552
553			/*
554			 * Exceptions to stateless autoconfiguration processing:
555			 * + nd6_accept_6to4 == 0 && address has 6to4 prefix
556			 * + ip6_only_allow_rfc4193_prefix != 0 &&
557			 * address not RFC 4193
558			 */
559			if (ip6_only_allow_rfc4193_prefix &&
560			    !IN6_IS_ADDR_UNIQUE_LOCAL(&pi->nd_opt_pi_prefix)) {
561				nd6log((LOG_INFO,
562				    "nd6_ra_input: no SLAAC on prefix %s "
563				    "[not RFC 4193]\n",
564				    ip6_sprintf(&pi->nd_opt_pi_prefix)));
565				pr.ndpr_raf_auto = 0;
566			}
567			else if (!nd6_accept_6to4 &&
568				     IN6_IS_ADDR_6TO4(&pi->nd_opt_pi_prefix)) {
569				nd6log((LOG_INFO,
570				    "nd6_ra_input: no SLAAC on prefix %s "
571				    "[6to4]\n",
572				    ip6_sprintf(&pi->nd_opt_pi_prefix)));
573				pr.ndpr_raf_auto = 0;
574			}
575
576			if (in6_init_prefix_ltimes(&pr)) {
577				NDPR_UNLOCK(&pr);
578				lck_mtx_destroy(&pr.ndpr_lock, ifa_mtx_grp);
579				continue; /* prefix lifetime init failed */
580			} else {
581				NDPR_UNLOCK(&pr);
582			}
583			(void)prelist_update(&pr, dr, m, mcast);
584			lck_mtx_destroy(&pr.ndpr_lock, ifa_mtx_grp);
585
586			/*
587			 * We have to copy the values out after the
588			 * prelist_update call since some of these values won't
589			 * be properly set until after the router advertisement
590			 * updating can vet the values.
591			 */
592			struct nd_prefix_list *prfl = NULL;
593			MALLOC(prfl, struct nd_prefix_list *, sizeof (*prfl),
594			    M_TEMP, M_WAITOK | M_ZERO);
595
596			if (prfl == NULL) {
597				log(LOG_DEBUG, "%s: unable to MALLOC RA prefix "
598				    "structure\n", __func__);
599				continue;
600			}
601
602			bcopy(&pr.ndpr_prefix, &prfl->pr.ndpr_prefix,
603			    sizeof (prfl->pr.ndpr_prefix));
604			prfl->pr.ndpr_raf = pr.ndpr_raf;
605			prfl->pr.ndpr_plen = pr.ndpr_plen;
606			prfl->pr.ndpr_vltime = pr.ndpr_vltime;
607			prfl->pr.ndpr_pltime = pr.ndpr_pltime;
608			prfl->pr.ndpr_expire = pr.ndpr_expire;
609			prfl->pr.ndpr_stateflags = pr.ndpr_stateflags;
610			prfl->pr.ndpr_addrcnt = pr.ndpr_addrcnt;
611			prfl->pr.ndpr_ifp = pr.ndpr_ifp;
612
613			prfl->next = nd_prefix_list_head;
614			nd_prefix_list_head = prfl;
615			nd_prefix_list_length++;
616		}
617	}
618
619	/*
620	 * MTU
621	 */
622	if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) {
623		mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu);
624
625		/* lower bound */
626		if (mtu < IPV6_MMTU) {
627			nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option "
628			    "mtu=%d sent from %s, ignoring\n",
629			    mtu, ip6_sprintf(&ip6->ip6_src)));
630			goto skip;
631		}
632
633		lck_rw_lock_shared(nd_if_rwlock);
634		if (ifp->if_index >= nd_ifinfo_indexlim) {
635			lck_rw_done(nd_if_rwlock);
636			goto freeit;
637		}
638		ndi = &nd_ifinfo[ifp->if_index];
639		VERIFY(ndi->initialized);
640		lck_mtx_lock(&ndi->lock);
641		/* upper bound */
642		if (ndi->maxmtu) {
643			if (mtu <= ndi->maxmtu) {
644				int change = (ndi->linkmtu != mtu);
645
646				ndi->linkmtu = mtu;
647				lck_mtx_unlock(&ndi->lock);
648				lck_rw_done(nd_if_rwlock);
649				if (change) /* in6_maxmtu may change */
650					in6_setmaxmtu();
651			} else {
652				nd6log((LOG_INFO, "nd6_ra_input: bogus mtu "
653				    "mtu=%d sent from %s; "
654				    "exceeds maxmtu %d, ignoring\n",
655				    mtu, ip6_sprintf(&ip6->ip6_src),
656				    ndi->maxmtu));
657				lck_mtx_unlock(&ndi->lock);
658				lck_rw_done(nd_if_rwlock);
659			}
660		} else {
661			lck_mtx_unlock(&ndi->lock);
662			lck_rw_done(nd_if_rwlock);
663			nd6log((LOG_INFO, "nd6_ra_input: mtu option "
664			    "mtu=%d sent from %s; maxmtu unknown, "
665			    "ignoring\n",
666			    mtu, ip6_sprintf(&ip6->ip6_src)));
667		}
668		ndi = NULL;
669	}
670
671 skip:
672
673	/*
674	 * Source link layer address
675	 */
676	if (ndopts.nd_opts_src_lladdr) {
677		lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
678		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
679	}
680
681	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
682		nd6log((LOG_INFO,
683		    "nd6_ra_input: lladdrlen mismatch for %s "
684		    "(if %d, RA packet %d)\n",
685			ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
686		goto bad;
687	}
688
689	nd6_cache_lladdr(ifp, &saddr6, lladdr, (int)lladdrlen,
690	    ND_ROUTER_ADVERT, 0);
691
692	/* Post message */
693	nd6_post_msg(KEV_ND6_RA, nd_prefix_list_head, nd_prefix_list_length,
694	    mtu, lladdr, lladdrlen);
695
696	/*
697	 * Installing a link-layer address might change the state of the
698	 * router's neighbor cache, which might also affect our on-link
699	 * detection of adveritsed prefixes.
700	 */
701	lck_mtx_lock(nd6_mutex);
702	pfxlist_onlink_check();
703	lck_mtx_unlock(nd6_mutex);
704
705 freeit:
706	m_freem(m);
707	if (dr)
708		NDDR_REMREF(dr);
709
710    {
711	struct nd_prefix_list *prfl = NULL;
712	while ((prfl = nd_prefix_list_head) != NULL) {
713		nd_prefix_list_head = prfl->next;
714		FREE(prfl, M_TEMP);
715	}
716    }
717
718	return;
719
720 bad:
721	icmp6stat.icp6s_badra++;
722	goto freeit;
723}
724
725/*
726 * default router list proccessing sub routines
727 */
728
729/* tell the change to user processes watching the routing socket. */
730static void
731nd6_rtmsg(cmd, rt)
732	int cmd;
733	struct rtentry *rt;
734{
735	struct rt_addrinfo info;
736	struct ifnet *ifp = rt->rt_ifp;
737
738	RT_LOCK_ASSERT_HELD(rt);
739
740	bzero((caddr_t)&info, sizeof(info));
741	/* Lock ifp for if_lladdr */
742	ifnet_lock_shared(ifp);
743	info.rti_info[RTAX_DST] = rt_key(rt);
744	info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
745	info.rti_info[RTAX_NETMASK] = rt_mask(rt);
746	/*
747	 * ifa_addr pointers for both should always be valid
748	 * in this context; no need to hold locks.
749	 */
750	info.rti_info[RTAX_IFP] = ifp->if_lladdr->ifa_addr;
751	info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
752
753	rt_missmsg(cmd, &info, rt->rt_flags, 0);
754	ifnet_lock_done(ifp);
755}
756
757static void
758defrouter_addreq(struct nd_defrouter *new, boolean_t scoped)
759{
760	struct sockaddr_in6 def, mask, gate;
761	struct rtentry *newrt = NULL;
762	unsigned int ifscope;
763	int err;
764
765	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
766
767	if (new->stateflags & NDDRF_INSTALLED)
768		return;
769
770	if (new->ifp->if_eflags & IFEF_IPV6_ROUTER) {
771		nd6log2((LOG_INFO, "%s: ignoring router %s, scoped=%d, "
772		    "static=%d on advertising interface\n", if_name(new->ifp),
773		    ip6_sprintf(&new->rtaddr), scoped,
774		    (new->stateflags & NDDRF_STATIC) ? 1 : 0));
775		return;
776	}
777
778	nd6log2((LOG_INFO, "%s: adding default router %s, scoped=%d, "
779	    "static=%d\n", if_name(new->ifp), ip6_sprintf(&new->rtaddr),
780	    scoped, (new->stateflags & NDDRF_STATIC) ? 1 : 0));
781
782	Bzero(&def, sizeof(def));
783	Bzero(&mask, sizeof(mask));
784	Bzero(&gate, sizeof(gate));
785
786	def.sin6_len = mask.sin6_len = gate.sin6_len
787		= sizeof(struct sockaddr_in6);
788	def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
789	gate.sin6_addr = new->rtaddr;
790
791	ifscope = scoped ? new->ifp->if_index : IFSCOPE_NONE;
792
793	err = rtrequest_scoped(RTM_ADD, (struct sockaddr *)&def,
794	    (struct sockaddr *)&gate, (struct sockaddr *)&mask,
795	    RTF_GATEWAY, &newrt, ifscope);
796
797	if (newrt) {
798		RT_LOCK(newrt);
799		nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
800		RT_REMREF_LOCKED(newrt);
801		RT_UNLOCK(newrt);
802		new->stateflags |= NDDRF_INSTALLED;
803		if (ifscope != IFSCOPE_NONE)
804			new->stateflags |= NDDRF_IFSCOPE;
805		new->genid = nd6_defrouter_genid;
806	} else {
807		nd6log((LOG_ERR, "%s: failed to add default router "
808		    "%s on %s scoped %d (errno = %d)\n", __func__,
809		    ip6_sprintf(&gate.sin6_addr), if_name(new->ifp),
810		    (ifscope != IFSCOPE_NONE), err));
811	}
812	new->err = err;
813}
814
815struct nd_defrouter *
816defrouter_lookup(
817	struct in6_addr *addr,
818	struct ifnet *ifp)
819{
820	struct nd_defrouter *dr;
821
822	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
823
824	for (dr = TAILQ_FIRST(&nd_defrouter); dr;
825	     dr = TAILQ_NEXT(dr, dr_entry)) {
826		NDDR_LOCK(dr);
827		if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
828			NDDR_ADDREF_LOCKED(dr);
829			NDDR_UNLOCK(dr);
830			return(dr);
831		}
832		NDDR_UNLOCK(dr);
833	}
834
835	return (NULL);		/* search failed */
836}
837
838/*
839 * Remove the default route for a given router.
840 * This is just a subroutine function for defrouter_select(), and should
841 * not be called from anywhere else.
842 */
843static void
844defrouter_delreq(struct nd_defrouter *dr)
845{
846	struct sockaddr_in6 def, mask, gate;
847	struct rtentry *oldrt = NULL;
848	unsigned int ifscope;
849	int err;
850
851	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
852
853	/* ifp would be NULL for the "drany" case */
854	if (dr->ifp != NULL && !(dr->stateflags & NDDRF_INSTALLED))
855		return;
856
857	NDDR_LOCK_ASSERT_HELD(dr);
858
859	nd6log2((LOG_INFO, "%s: removing default router %s, scoped=%d, "
860	    "static=%d\n", dr->ifp != NULL ? if_name(dr->ifp) : "ANY",
861	    ip6_sprintf(&dr->rtaddr), (dr->stateflags & NDDRF_IFSCOPE) ? 1 : 0,
862	    (dr->stateflags & NDDRF_STATIC) ? 1 : 0));
863
864	Bzero(&def, sizeof(def));
865	Bzero(&mask, sizeof(mask));
866	Bzero(&gate, sizeof(gate));
867
868	def.sin6_len = mask.sin6_len = gate.sin6_len
869		= sizeof(struct sockaddr_in6);
870	def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
871	gate.sin6_addr = dr->rtaddr;
872
873	if (dr->ifp != NULL) {
874		ifscope = (dr->stateflags & NDDRF_IFSCOPE) ?
875		    dr->ifp->if_index : IFSCOPE_NONE;
876	} else {
877		ifscope = IFSCOPE_NONE;
878	}
879	err = rtrequest_scoped(RTM_DELETE,
880	    (struct sockaddr *)&def, (struct sockaddr *)&gate,
881	    (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, ifscope);
882
883	if (oldrt) {
884		RT_LOCK(oldrt);
885		nd6_rtmsg(RTM_DELETE, oldrt);
886		RT_UNLOCK(oldrt);
887		rtfree(oldrt);
888	} else if (err != ESRCH) {
889		nd6log((LOG_ERR, "%s: failed to delete default router "
890		    "%s on %s scoped %d (errno = %d)\n", __func__,
891		    ip6_sprintf(&gate.sin6_addr), dr->ifp != NULL ?
892		    if_name(dr->ifp) : "ANY", (ifscope != IFSCOPE_NONE), err));
893	}
894	/* ESRCH means it's no longer in the routing table; ignore it */
895	if (oldrt != NULL || err == ESRCH) {
896		dr->stateflags &= ~NDDRF_INSTALLED;
897		if (ifscope != IFSCOPE_NONE)
898			dr->stateflags &= ~NDDRF_IFSCOPE;
899	}
900	dr->err = 0;
901}
902
903
904/*
905 * remove all default routes from default router list
906 */
907void
908defrouter_reset(void)
909{
910	struct nd_defrouter *dr, drany;
911
912	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
913
914	dr = TAILQ_FIRST(&nd_defrouter);
915	while (dr) {
916		NDDR_LOCK(dr);
917		if (dr->stateflags & NDDRF_INSTALLED) {
918			NDDR_ADDREF_LOCKED(dr);
919			NDDR_UNLOCK(dr);
920			lck_mtx_unlock(nd6_mutex);
921			NDDR_LOCK(dr);
922			defrouter_delreq(dr);
923			NDDR_UNLOCK(dr);
924			lck_mtx_lock(nd6_mutex);
925			NDDR_REMREF(dr);
926			dr = TAILQ_FIRST(&nd_defrouter);
927		} else {
928			NDDR_UNLOCK(dr);
929			dr = TAILQ_NEXT(dr, dr_entry);
930		}
931	}
932
933	/* Nuke primary (non-scoped) default router */
934	if (ip6_doscopedroute) {
935		bzero(&drany, sizeof (drany));
936		lck_mtx_init(&drany.nddr_lock, ifa_mtx_grp, ifa_mtx_attr);
937		lck_mtx_unlock(nd6_mutex);
938		NDDR_LOCK(&drany);
939		defrouter_delreq(&drany);
940		NDDR_UNLOCK(&drany);
941		lck_mtx_destroy(&drany.nddr_lock, ifa_mtx_grp);
942		lck_mtx_lock(nd6_mutex);
943	}
944
945}
946
947int
948defrtrlist_ioctl(u_long cmd, caddr_t data)
949{
950	struct nd_defrouter dr0;
951	unsigned int ifindex;
952	struct ifnet *dr_ifp;
953	int error = 0, add = 0;
954
955	switch (cmd) {
956	case SIOCDRADD_IN6_32:		/* struct in6_defrouter_32 */
957	case SIOCDRADD_IN6_64:		/* struct in6_defrouter_64 */
958		++add;
959		/* FALLTHRU */
960	case SIOCDRDEL_IN6_32:		/* struct in6_defrouter_32 */
961	case SIOCDRDEL_IN6_64:		/* struct in6_defrouter_64 */
962		bzero(&dr0, sizeof (dr0));
963		if (cmd == SIOCDRADD_IN6_64 || cmd == SIOCDRDEL_IN6_64) {
964			struct in6_defrouter_64 *r_64 =
965			    (struct in6_defrouter_64 *)(void *)data;
966			u_int16_t i;
967
968			bcopy(&r_64->rtaddr.sin6_addr, &dr0.rtaddr,
969			    sizeof (dr0.rtaddr));
970			dr0.flags = r_64->flags;
971			bcopy(&r_64->if_index, &i, sizeof (i));
972			ifindex = i;
973		} else {
974			struct in6_defrouter_32 *r_32 =
975			    (struct in6_defrouter_32 *)(void *)data;
976			u_int16_t i;
977
978			bcopy(&r_32->rtaddr.sin6_addr, &dr0.rtaddr,
979			    sizeof (dr0.rtaddr));
980			dr0.flags = r_32->flags;
981			bcopy(&r_32->if_index, &i, sizeof (i));
982			ifindex = i;
983		}
984		ifnet_head_lock_shared();
985		/* Don't need to check is ifindex is < 0 since it's unsigned */
986		if (if_index < ifindex ||
987		    (dr_ifp = ifindex2ifnet[ifindex]) == NULL) {
988			ifnet_head_done();
989			error = EINVAL;
990			break;
991		}
992		dr0.ifp = dr_ifp;
993		ifnet_head_done();
994
995		if (IN6_IS_SCOPE_EMBED(&dr0.rtaddr)) {
996			uint16_t *scope = &dr0.rtaddr.s6_addr16[1];
997
998			if (*scope == 0) {
999				*scope = htons(dr_ifp->if_index);
1000			} else if (*scope != htons(dr_ifp->if_index)) {
1001				error = EINVAL;
1002				break;
1003			}
1004		}
1005
1006		if (add)
1007			error = defrtrlist_add_static(&dr0);
1008		if (!add || error != 0) {
1009			int err = defrtrlist_del_static(&dr0);
1010			if (!add)
1011				error = err;
1012		}
1013		break;
1014
1015	default:
1016		error = EOPNOTSUPP; /* check for safety */
1017		break;
1018	}
1019
1020	return (error);
1021}
1022
1023void
1024defrtrlist_del(struct nd_defrouter *dr)
1025{
1026	struct nd_defrouter *deldr = NULL;
1027	struct nd_prefix *pr;
1028	struct ifnet *ifp = dr->ifp;
1029
1030	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1031
1032	/*
1033	 * Flush all the routing table entries that use the router
1034	 * as a next hop.
1035	 */
1036	if (ip6_doscopedroute || !ip6_forwarding) {
1037		/* above is a good condition? */
1038		NDDR_ADDREF(dr);
1039		lck_mtx_unlock(nd6_mutex);
1040		rt6_flush(&dr->rtaddr, ifp);
1041		lck_mtx_lock(nd6_mutex);
1042		NDDR_REMREF(dr);
1043	}
1044
1045	if (!ip6_doscopedroute && dr == TAILQ_FIRST(&nd_defrouter))
1046		deldr = dr;	/* The router is primary. */
1047
1048	TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
1049	++nd6_defrouter_genid;
1050
1051	nd6log2((LOG_INFO, "%s: freeing defrouter %s\n", if_name(dr->ifp),
1052	    ip6_sprintf(&dr->rtaddr)));
1053
1054	/*
1055	 * Delete it from the routing table.
1056	 */
1057	NDDR_ADDREF(dr);
1058	lck_mtx_unlock(nd6_mutex);
1059	NDDR_LOCK(dr);
1060	defrouter_delreq(dr);
1061	NDDR_UNLOCK(dr);
1062	lck_mtx_lock(nd6_mutex);
1063	NDDR_REMREF(dr);
1064
1065	/*
1066	 * Also delete all the pointers to the router in each prefix lists.
1067	 */
1068	for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1069		struct nd_pfxrouter *pfxrtr;
1070
1071		NDPR_LOCK(pr);
1072		if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
1073			pfxrtr_del(pfxrtr);
1074		NDPR_UNLOCK(pr);
1075	}
1076
1077	pfxlist_onlink_check();
1078
1079	/*
1080	 * If the router is the primary one, choose a new one.  If Scoped
1081	 * Routing is enabled, always try to pick another eligible router
1082	 * on this interface.
1083	 */
1084	if (deldr || ip6_doscopedroute)
1085		defrouter_select(ifp);
1086
1087	lck_rw_lock_shared(nd_if_rwlock);
1088	if (ifp->if_index < nd_ifinfo_indexlim) {
1089		struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
1090		VERIFY(ndi->initialized);
1091		lck_mtx_lock(&ndi->lock);
1092		VERIFY(ndi->ndefrouters > 0);
1093		ndi->ndefrouters--;
1094		lck_mtx_unlock(&ndi->lock);
1095	}
1096	lck_rw_done(nd_if_rwlock);
1097
1098	NDDR_REMREF(dr);	/* remove list reference */
1099}
1100
1101int
1102defrtrlist_add_static(struct nd_defrouter *new)
1103{
1104	struct nd_defrouter *dr;
1105	int err = 0;
1106
1107	new->rtlifetime = -1;
1108	new->stateflags |= NDDRF_STATIC;
1109
1110	/* we only want the preference level */
1111	new->flags &= ND_RA_FLAG_RTPREF_MASK;
1112
1113	lck_mtx_lock(nd6_mutex);
1114	dr = defrouter_lookup(&new->rtaddr, new->ifp);
1115	if (dr != NULL && !(dr->stateflags & NDDRF_STATIC)) {
1116		err = EINVAL;
1117	} else {
1118		if (dr != NULL)
1119			NDDR_REMREF(dr);
1120		dr = defrtrlist_update(new);
1121		if (dr != NULL)
1122			err = dr->err;
1123		else
1124			err = ENOMEM;
1125	}
1126	if (dr != NULL)
1127		NDDR_REMREF(dr);
1128	lck_mtx_unlock(nd6_mutex);
1129
1130	return (err);
1131}
1132
1133int
1134defrtrlist_del_static(struct nd_defrouter *new)
1135{
1136	struct nd_defrouter *dr;
1137
1138	lck_mtx_lock(nd6_mutex);
1139	dr = defrouter_lookup(&new->rtaddr, new->ifp);
1140	if (dr == NULL || !(dr->stateflags & NDDRF_STATIC)) {
1141		if (dr != NULL)
1142			NDDR_REMREF(dr);
1143		dr = NULL;
1144	} else {
1145		defrtrlist_del(dr);
1146		NDDR_REMREF(dr);
1147	}
1148	lck_mtx_unlock(nd6_mutex);
1149
1150	return (dr != NULL ? 0 : EINVAL);
1151}
1152
1153/*
1154 * for default router selection
1155 * regards router-preference field as a 2-bit signed integer
1156 */
1157static int
1158rtpref(struct nd_defrouter *dr)
1159{
1160	switch (dr->flags & ND_RA_FLAG_RTPREF_MASK) {
1161	case ND_RA_FLAG_RTPREF_HIGH:
1162		return (RTPREF_HIGH);
1163	case ND_RA_FLAG_RTPREF_MEDIUM:
1164	case ND_RA_FLAG_RTPREF_RSV:
1165		return (RTPREF_MEDIUM);
1166	case ND_RA_FLAG_RTPREF_LOW:
1167		return (RTPREF_LOW);
1168	default:
1169		/*
1170		 * This case should never happen.  If it did, it would mean a
1171		 * serious bug of kernel internal.  We thus always bark here.
1172		 * Or, can we even panic?
1173		 */
1174		log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->flags);
1175		return (RTPREF_INVALID);
1176	}
1177	/* NOTREACHED */
1178}
1179
1180/*
1181 * Default Router Selection according to Section 6.3.6 of RFC 2461 and RFC 4191:
1182 *
1183 * 1) Routers that are reachable or probably reachable should be preferred.
1184 *    If we have more than one (probably) reachable router, prefer ones
1185 *    with the highest router preference.
1186 * 2) When no routers on the list are known to be reachable or
1187 *    probably reachable, routers SHOULD be selected in a round-robin
1188 *    fashion, regardless of router preference values.
1189 * 3) If the Default Router List is empty, assume that all
1190 *    destinations are on-link.
1191 *
1192 * When Scoped Routing is enabled, the selection logic is amended as follows:
1193 *
1194 * a) When a default interface is specified, the primary/non-scoped default
1195 *    router will be set to the reachable router on that link (if any) with
1196 *    the highest router preference.
1197 * b) When there are more than one routers on the same link, the one with
1198 *    the highest router preference will be installed, either as scoped or
1199 *    non-scoped route entry.  If they all share the same preference value,
1200 *    the one installed will be the static or the first encountered reachable
1201 *    router, i.e. static one wins over dynamic.
1202 * c) When no routers on the list are known to be reachable, or probably
1203 *    reachable, no round-robin selection will take place when the default
1204 *    interface is set.
1205 *
1206 * We assume nd_defrouter is sorted by router preference value.
1207 * Since the code below covers both with and without router preference cases,
1208 * we do not need to classify the cases by ifdef.
1209 */
1210void
1211defrouter_select(struct ifnet *ifp)
1212{
1213#pragma unused(ifp)
1214	struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL;
1215	struct nd_defrouter *installed_dr0 = NULL;
1216	struct rtentry *rt = NULL;
1217	struct llinfo_nd6 *ln = NULL;
1218	int  update = 0;
1219	boolean_t found_installedrt = FALSE;
1220
1221	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1222
1223	/*
1224	 * We no longer install (default) interface route; only prefix routes
1225	 * are installed as interface routes.  Therefore, there is no harm in
1226	 * going through this routine even if a default interface is specified,
1227	 * which happens when Scoped Routing is enabled.  But for efficiency,
1228	 * we fall back to the original KAME logic when Scoped Routing is
1229	 * not in effect.
1230	 */
1231	if (ip6_forwarding && !ip6_doscopedroute) {
1232		nd6log((LOG_WARNING,
1233		    "defrouter_select: called unexpectedly (forwarding=%d)\n",
1234		    ip6_forwarding));
1235		return;
1236	}
1237
1238	/*
1239	 * Let's handle easy case (3) first:
1240	 * If default router list is empty, there's nothing to be done.
1241	 */
1242	if (!TAILQ_FIRST(&nd_defrouter))
1243		return;
1244
1245	/*
1246	 * Due to the number of times we drop nd6_mutex, we need to
1247	 * serialize this function.
1248	 */
1249	while (nd_defrouter_busy) {
1250		nd_defrouter_waiters++;
1251		msleep(nd_defrouter_waitchan, nd6_mutex, (PZERO-1),
1252		    __func__, NULL);
1253		lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1254	}
1255	nd_defrouter_busy = TRUE;
1256
1257	/*
1258	 * Search for a (probably) reachable router from the list.
1259	 * We just pick up the first reachable one (if any), assuming that
1260	 * the ordering rule of the list described in defrtrlist_update().
1261	 *
1262	 * For all intents and purposes of Scoped Routing:
1263	 *	selected_dr	= candidate for primary router
1264	 *	installed_dr	= currently installed primary router
1265	 */
1266	for (dr = TAILQ_FIRST(&nd_defrouter); dr;
1267	     dr = TAILQ_NEXT(dr, dr_entry)) {
1268		boolean_t reachable, advrouter;
1269		struct in6_addr rtaddr;
1270		struct ifnet *drifp;
1271		struct nd_defrouter *drrele;
1272
1273		drrele = NULL;
1274		reachable = FALSE;
1275		NDDR_LOCK(dr);
1276		rtaddr = *(&dr->rtaddr);
1277		drifp = dr->ifp;
1278		advrouter = (drifp != NULL &&
1279		    (drifp->if_eflags & IFEF_IPV6_ROUTER));
1280		NDDR_ADDREF_LOCKED(dr);	/* for this for loop */
1281		NDDR_UNLOCK(dr);
1282
1283		lck_mtx_unlock(nd6_mutex);
1284		/* Callee returns a locked route upon success */
1285		if ((rt = nd6_lookup(&rtaddr, 0, drifp, 0)) != NULL) {
1286			RT_LOCK_ASSERT_HELD(rt);
1287			if ((ln = rt->rt_llinfo) != NULL &&
1288			    ND6_IS_LLINFO_PROBREACH(ln)) {
1289				reachable = TRUE;
1290				if (selected_dr == NULL &&
1291				    (!ip6_doscopedroute ||
1292				    (drifp == nd6_defifp && !advrouter))) {
1293					selected_dr = dr;
1294					NDDR_ADDREF(selected_dr);
1295				}
1296			}
1297			RT_REMREF_LOCKED(rt);
1298			RT_UNLOCK(rt);
1299			rt = NULL;
1300		}
1301		lck_mtx_lock(nd6_mutex);
1302
1303		/* Handle case (b) */
1304		NDDR_LOCK(dr);
1305		if (ip6_doscopedroute && drifp == nd6_defifp && !advrouter &&
1306		    (selected_dr == NULL || rtpref(dr) > rtpref(selected_dr) ||
1307		    (rtpref(dr) == rtpref(selected_dr) &&
1308		    (dr->stateflags & NDDRF_STATIC) &&
1309		    !(selected_dr->stateflags & NDDRF_STATIC)))) {
1310			if (selected_dr) {
1311				/* Release it later on */
1312				VERIFY(drrele == NULL);
1313				drrele = selected_dr;
1314			}
1315			selected_dr = dr;
1316			NDDR_ADDREF_LOCKED(selected_dr);
1317		}
1318
1319		if (!(dr->stateflags & NDDRF_INSTALLED)) {
1320			/*
1321			 * If the router hasn't been installed and it is
1322			 * reachable, try to install it later on below.
1323			 * If it's static, try to install it anyway.
1324			 */
1325			if (!advrouter && (reachable ||
1326			    (dr->stateflags & NDDRF_STATIC))) {
1327				dr->genid = -1;
1328				++update;
1329				nd6log2((LOG_INFO, "%s: possible router %s, "
1330				    "scoped=%d, static=%d\n", if_name(drifp),
1331				    ip6_sprintf(&rtaddr),
1332				    (dr->stateflags & NDDRF_IFSCOPE) ? 1 : 0,
1333				    (dr->stateflags & NDDRF_STATIC) ? 1 : 0));
1334			}
1335			NDDR_UNLOCK(dr);
1336			NDDR_REMREF(dr);	/* for this for loop */
1337			if (drrele != NULL)
1338				NDDR_REMREF(drrele);
1339			continue;
1340		}
1341
1342		/* Record the currently installed primary/non-scoped router */
1343		if (!ip6_doscopedroute || !(dr->stateflags & NDDRF_IFSCOPE)) {
1344			if (installed_dr == NULL) {
1345				installed_dr = dr;
1346				NDDR_ADDREF_LOCKED(installed_dr);
1347			} else {
1348				/* this should not happen; warn for diagnosis */
1349				log(LOG_ERR, "defrouter_select: more than one "
1350				    "%s default router is installed\n",
1351				    ip6_doscopedroute ? "non-scoped" : "");
1352			}
1353		}
1354		NDDR_UNLOCK(dr);
1355		NDDR_REMREF(dr);	/* for this for loop */
1356		if (drrele != NULL)
1357			NDDR_REMREF(drrele);
1358	}
1359
1360	/* If none was selected, use the currently installed one */
1361	if (ip6_doscopedroute && selected_dr == NULL && installed_dr != NULL) {
1362		selected_dr = installed_dr;
1363		NDDR_ADDREF(selected_dr);
1364	}
1365
1366	/*
1367	 * Install the unreachable one(s) if necesssary.
1368	 */
1369	for (dr = TAILQ_FIRST(&nd_defrouter); dr;
1370	     dr = TAILQ_NEXT(dr, dr_entry)) {
1371		struct nd_defrouter *_dr;
1372
1373		if (!ip6_doscopedroute)
1374			break;
1375
1376		NDDR_LOCK(dr);
1377
1378		/* If already (or will be) installed, skip */
1379		if ((dr->stateflags & NDDRF_INSTALLED) || dr->genid == -1) {
1380			NDDR_UNLOCK(dr);
1381			continue;
1382		}
1383
1384		/* See if there is already a default router for the link */
1385		for (_dr = TAILQ_FIRST(&nd_defrouter); _dr;
1386		     _dr = TAILQ_NEXT(_dr, dr_entry)) {
1387			if (_dr != dr)
1388				NDDR_LOCK(_dr);
1389			if (_dr == dr || _dr->ifp != dr->ifp) {
1390				if (_dr != dr)
1391					NDDR_UNLOCK(_dr);
1392				continue;
1393			}
1394
1395			if ((_dr->stateflags & NDDRF_INSTALLED) ||
1396			    _dr->genid == -1) {
1397				if (_dr != dr)
1398					NDDR_UNLOCK(_dr);
1399				break;
1400			}
1401			if (_dr != dr)
1402				NDDR_UNLOCK(_dr);
1403		}
1404
1405		/* If none so far, schedule it to be installed below */
1406		if (_dr == NULL && dr->ifp != NULL &&
1407		    !(dr->ifp->if_eflags & IFEF_IPV6_ROUTER)) {
1408			dr->genid = -1;
1409			++update;
1410			nd6log2((LOG_INFO, "%s: possible router %s, "
1411			    "static=%d (unreachable)\n", if_name(dr->ifp),
1412			    ip6_sprintf(&dr->rtaddr),
1413			    (dr->stateflags & NDDRF_STATIC) ? 1 : 0));
1414		}
1415		NDDR_UNLOCK(dr);
1416	}
1417
1418	dr = selected_dr;
1419	if (dr != NULL) {
1420		nd6log2((LOG_INFO, "%s: considering primary default router %s, "
1421		    "static=%d [round 1]\n", if_name(dr->ifp),
1422		    ip6_sprintf(&dr->rtaddr),
1423		    (dr->stateflags & NDDRF_STATIC) ? 1 : 0));
1424	}
1425
1426	/*
1427	 * If none of the default routers was found to be reachable,
1428	 * round-robin the list regardless of preference, except when
1429	 * Scoped Routing is enabled per case (c).
1430	 *
1431	 * Otherwise, if we have an installed router, check if the selected
1432	 * (reachable) router should really be preferred to the installed one.
1433	 * We only prefer the new router when the old one is not reachable
1434	 * or when the new one has a really higher preference value.
1435	 */
1436	if (!ip6_doscopedroute && selected_dr == NULL) {
1437		if (installed_dr == NULL ||
1438		    !TAILQ_NEXT(installed_dr, dr_entry)) {
1439			selected_dr = TAILQ_FIRST(&nd_defrouter);
1440			if (selected_dr)
1441				NDDR_ADDREF(selected_dr);
1442		} else {
1443			selected_dr = TAILQ_NEXT(installed_dr, dr_entry);
1444			if (selected_dr)
1445				NDDR_ADDREF(selected_dr);
1446		}
1447	} else if (selected_dr != NULL && installed_dr != NULL) {
1448		lck_mtx_unlock(nd6_mutex);
1449		rt = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp, 0);
1450		if (rt) {
1451			RT_LOCK_ASSERT_HELD(rt);
1452			if ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) &&
1453			    ND6_IS_LLINFO_PROBREACH(ln) &&
1454			    (!ip6_doscopedroute ||
1455				installed_dr->ifp == nd6_defifp) &&
1456			    rtpref(selected_dr) <= rtpref(installed_dr)) {
1457				NDDR_REMREF(selected_dr);
1458				selected_dr = installed_dr;
1459				NDDR_ADDREF(selected_dr);
1460			}
1461			RT_REMREF_LOCKED(rt);
1462			RT_UNLOCK(rt);
1463			rt = NULL;
1464			found_installedrt = TRUE;
1465		}
1466		lck_mtx_lock(nd6_mutex);
1467	}
1468
1469	if (ip6_doscopedroute) {
1470		/*
1471		 * If the installed primary router is not on the current
1472		 * IPv6 default interface, demote it to a scoped entry.
1473		 */
1474		if (installed_dr != NULL && installed_dr->ifp != nd6_defifp &&
1475		    !(installed_dr->stateflags & NDDRF_IFSCOPE)) {
1476			if (selected_dr != NULL &&
1477			    selected_dr->ifp != nd6_defifp) {
1478				NDDR_REMREF(selected_dr);
1479				selected_dr = NULL;
1480			}
1481			++update;
1482		}
1483
1484		/*
1485		 * If the selected router is currently scoped, make sure
1486		 * we update (it needs to be promoted to primary.)
1487		 */
1488		if (selected_dr != NULL &&
1489		    (selected_dr->stateflags & NDDRF_IFSCOPE))
1490			++update;
1491
1492		/*
1493		 * If the installed router is no longe reachable, remove
1494		 * it and install the selected router instead.
1495		 */
1496		if (installed_dr != NULL && selected_dr != NULL &&
1497		    installed_dr != selected_dr && found_installedrt == FALSE) {
1498			installed_dr0 = installed_dr;	/* skip it below */
1499			/* NB: we previousled referenced installed_dr */
1500			installed_dr = NULL;
1501			selected_dr->genid = -1;
1502			++update;
1503		}
1504	}
1505
1506	/*
1507	 * If Scoped Routing is enabled and there's nothing to update,
1508	 * just return.  Otherwise, if Scoped Routing is disabled and if
1509	 * the selected router is different than the installed one,
1510	 * remove the installed router and install the selected one.
1511	 */
1512	dr = selected_dr;
1513	VERIFY(dr != NULL || ip6_doscopedroute);
1514	if (!ip6_doscopedroute || !update) {
1515		if (dr == NULL)
1516			goto out;
1517
1518		if (dr != installed_dr) {
1519			nd6log2((LOG_INFO, "%s: no update, selected router %s, "
1520			    "installed router %s\n", if_name(dr->ifp),
1521			    ip6_sprintf(&dr->rtaddr), installed_dr != NULL ?
1522			    ip6_sprintf(&installed_dr->rtaddr) : "NONE"));
1523		} else {
1524			nd6log2((LOG_INFO, "%s: no update, router is %s\n",
1525			    if_name(dr->ifp), ip6_sprintf(&dr->rtaddr)));
1526		}
1527		if (!ip6_doscopedroute && installed_dr != dr) {
1528			/*
1529			 * No need to ADDREF dr because at this point
1530			 * dr points to selected_dr, which already holds
1531			 * a reference.
1532			 */
1533			lck_mtx_unlock(nd6_mutex);
1534			if (installed_dr) {
1535				NDDR_LOCK(installed_dr);
1536				defrouter_delreq(installed_dr);
1537				NDDR_UNLOCK(installed_dr);
1538			}
1539			NDDR_LOCK(dr);
1540			defrouter_addreq(dr, FALSE);
1541			NDDR_UNLOCK(dr);
1542			lck_mtx_lock(nd6_mutex);
1543		}
1544		goto out;
1545	}
1546
1547	/*
1548	 * Scoped Routing is enabled and we need to update.  The selected
1549	 * router needs to be installed as primary/non-scoped entry.  If
1550	 * there is any existing entry that is non-scoped, remove it from
1551	 * the routing table and reinstall it as scoped entry.
1552	 */
1553	if (dr != NULL) {
1554		nd6log2((LOG_INFO, "%s: considering primary default router %s, "
1555		    "static=%d [round 2]\n", if_name(dr->ifp),
1556		    ip6_sprintf(&dr->rtaddr),
1557		    (dr->stateflags & NDDRF_STATIC) ? 1 : 0));
1558	}
1559
1560	/*
1561	 * On the following while loops we use two flags:
1562	 *   dr->genid
1563	 *   NDDRF_PROCESSED
1564	 *
1565	 * genid is used to skip entries that are not to be added/removed on the
1566	 * second while loop.
1567	 * NDDRF_PROCESSED is used to skip entries that were already processed.
1568	 * This is necessary because we drop the nd6_mutex and start the while
1569	 * loop again.
1570	 */
1571	TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
1572		NDDR_LOCK(dr);
1573		VERIFY((dr->stateflags & NDDRF_PROCESSED) == 0);
1574		NDDR_UNLOCK(dr);
1575	}
1576	/* Remove conflicting entries */
1577	dr = TAILQ_FIRST(&nd_defrouter);
1578	while (dr) {
1579		NDDR_LOCK(dr);
1580		if (!(dr->stateflags & NDDRF_INSTALLED) ||
1581		    dr->stateflags & NDDRF_PROCESSED) {
1582			NDDR_UNLOCK(dr);
1583			dr = TAILQ_NEXT(dr, dr_entry);
1584			continue;
1585		}
1586		dr->stateflags |= NDDRF_PROCESSED;
1587
1588		/* A NULL selected_dr will remove primary default route */
1589		if ((dr == selected_dr && (dr->stateflags & NDDRF_IFSCOPE)) ||
1590		    (dr != selected_dr && !(dr->stateflags & NDDRF_IFSCOPE))) {
1591			NDDR_ADDREF_LOCKED(dr);
1592			NDDR_UNLOCK(dr);
1593			lck_mtx_unlock(nd6_mutex);
1594			NDDR_LOCK(dr);
1595			defrouter_delreq(dr);
1596			NDDR_UNLOCK(dr);
1597			lck_mtx_lock(nd6_mutex);
1598			NDDR_LOCK(dr);
1599			if (dr && dr != installed_dr0)
1600				dr->genid = -1;
1601			NDDR_UNLOCK(dr);
1602			NDDR_REMREF(dr);
1603			/*
1604			 * Since we lost nd6_mutex, we have to start over.
1605			 */
1606			dr = TAILQ_FIRST(&nd_defrouter);
1607			continue;
1608		}
1609		NDDR_UNLOCK(dr);
1610		dr = TAILQ_NEXT(dr, dr_entry);
1611	}
1612
1613	/* -1 is a special number, make sure we don't use it for genid */
1614	if (++nd6_defrouter_genid == -1)
1615		nd6_defrouter_genid = 1;
1616
1617	TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
1618		NDDR_LOCK(dr);
1619		dr->stateflags &= ~NDDRF_PROCESSED;
1620		NDDR_UNLOCK(dr);
1621	}
1622	/* Add the entries back */
1623	dr = TAILQ_FIRST(&nd_defrouter);
1624	while (dr) {
1625		struct nd_defrouter *_dr;
1626
1627		NDDR_LOCK(dr);
1628		if (dr->stateflags & NDDRF_PROCESSED ||
1629		    dr->genid != -1) {
1630			NDDR_UNLOCK(dr);
1631			dr = TAILQ_NEXT(dr, dr_entry);
1632			continue;
1633		}
1634		dr->stateflags |= NDDRF_PROCESSED;
1635
1636		/* Handle case (b) */
1637		for (_dr = TAILQ_FIRST(&nd_defrouter); _dr;
1638		     _dr = TAILQ_NEXT(_dr, dr_entry)) {
1639			if (_dr == dr)
1640				continue;
1641			/*
1642			 * This is safe because we previously checked if
1643			 * _dr == dr.
1644			 */
1645			NDDR_LOCK(_dr);
1646			if (_dr->ifp == dr->ifp && rtpref(_dr) >= rtpref(dr) &&
1647			    (_dr->stateflags & NDDRF_INSTALLED)) {
1648				NDDR_ADDREF_LOCKED(_dr);
1649				NDDR_UNLOCK(_dr);
1650				break;
1651			}
1652			NDDR_UNLOCK(_dr);
1653		}
1654
1655		/* If same preference and i/f, static entry takes precedence */
1656		if (_dr != NULL && rtpref(_dr) == rtpref(dr) &&
1657		    !(_dr->stateflags & NDDRF_STATIC) &&
1658		    (dr->stateflags & NDDRF_STATIC)) {
1659			lck_mtx_unlock(nd6_mutex);
1660			NDDR_LOCK(_dr);
1661			defrouter_delreq(_dr);
1662			NDDR_UNLOCK(_dr);
1663			lck_mtx_lock(nd6_mutex);
1664			NDDR_REMREF(_dr);
1665			_dr = NULL;
1666		}
1667
1668		if (_dr == NULL && !(dr->stateflags & NDDRF_INSTALLED)) {
1669			NDDR_ADDREF_LOCKED(dr);
1670			NDDR_UNLOCK(dr);
1671			lck_mtx_unlock(nd6_mutex);
1672			NDDR_LOCK(dr);
1673			defrouter_addreq(dr, (selected_dr == NULL ||
1674			    dr->ifp != selected_dr->ifp));
1675			dr->genid = nd6_defrouter_genid;
1676			NDDR_UNLOCK(dr);
1677			lck_mtx_lock(nd6_mutex);
1678			NDDR_REMREF(dr);
1679			/*
1680			 * Since we lost nd6_mutex, we have to start over.
1681			 */
1682			dr = TAILQ_FIRST(&nd_defrouter);
1683			continue;
1684		}
1685		NDDR_UNLOCK(dr);
1686		dr = TAILQ_NEXT(dr, dr_entry);
1687	}
1688out:
1689	TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
1690		NDDR_LOCK(dr);
1691		dr->stateflags &= ~NDDRF_PROCESSED;
1692		NDDR_UNLOCK(dr);
1693	}
1694	if (selected_dr)
1695		NDDR_REMREF(selected_dr);
1696	if (installed_dr)
1697		NDDR_REMREF(installed_dr);
1698	if (installed_dr0)
1699		NDDR_REMREF(installed_dr0);
1700	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1701	VERIFY(nd_defrouter_busy);
1702	nd_defrouter_busy = FALSE;
1703	if (nd_defrouter_waiters > 0) {
1704		nd_defrouter_waiters = 0;
1705		wakeup(nd_defrouter_waitchan);
1706	}
1707}
1708
1709static struct nd_defrouter *
1710defrtrlist_update_common(struct nd_defrouter *new, boolean_t scoped)
1711{
1712	struct nd_defrouter *dr, *n;
1713	struct ifnet *ifp = new->ifp;
1714	struct nd_ifinfo *ndi = NULL;
1715
1716	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1717
1718	if ((dr = defrouter_lookup(&new->rtaddr, ifp)) != NULL) {
1719		/* entry exists */
1720		if (new->rtlifetime == 0) {
1721			defrtrlist_del(dr);
1722			NDDR_REMREF(dr);
1723			dr = NULL;
1724		} else {
1725			int oldpref = rtpref(dr);
1726
1727			/* override */
1728			dr->flags = new->flags; /* xxx flag check */
1729			dr->rtlifetime = new->rtlifetime;
1730			dr->expire = new->expire;
1731
1732			/*
1733			 * If the preference does not change, there's no need
1734			 * to sort the entries.  If Scoped Routing is enabled,
1735			 * put the primary/non-scoped router at the top of the
1736			 * list of routers in the same preference band, unless
1737			 * it's already at that position.
1738			 */
1739			if (ip6_doscopedroute) {
1740				struct nd_defrouter *p = NULL;
1741
1742				/* same preference and scoped; just return */
1743				if (rtpref(new) == oldpref && scoped)
1744					return (dr);
1745
1746				n = TAILQ_FIRST(&nd_defrouter);
1747				while (n != NULL) {
1748					/* preference changed; sort it */
1749					if (rtpref(new) != oldpref)
1750						break;
1751
1752					/* not at the top of band; sort it */
1753					if (n != dr && rtpref(n) == oldpref &&
1754					    (!p || rtpref(p) > rtpref(n)))
1755						break;
1756
1757					p = n;
1758					n = TAILQ_NEXT(n, dr_entry);
1759				}
1760
1761				/* nothing has changed, just return */
1762				if (n == NULL && (scoped ||
1763				    !(dr->stateflags & NDDRF_IFSCOPE)))
1764					return (dr);
1765			} else if (rtpref(new) == oldpref) {
1766				return (dr);
1767			}
1768
1769			/*
1770			 * preferred router may be changed, so relocate
1771			 * this router.
1772			 * XXX: calling TAILQ_REMOVE directly is a bad manner.
1773			 * However, since defrtrlist_del() has many side
1774			 * effects, we intentionally do so here.
1775			 * defrouter_select() below will handle routing
1776			 * changes later.
1777			 */
1778			TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
1779			new->stateflags = dr->stateflags;
1780			new->stateflags &= ~NDDRF_PROCESSED;
1781
1782			n = dr;
1783			goto insert;
1784		}
1785		return (dr);
1786	}
1787
1788	VERIFY(dr == NULL);
1789
1790	/* entry does not exist */
1791	if (new->rtlifetime == 0) {
1792		return(NULL);
1793	}
1794
1795	n = nddr_alloc(M_WAITOK);
1796	if (n == NULL) {
1797		return(NULL);
1798	}
1799
1800	lck_rw_lock_shared(nd_if_rwlock);
1801	if (ifp->if_index >= nd_ifinfo_indexlim)
1802		goto freeit;
1803	ndi = &nd_ifinfo[ifp->if_index];
1804	VERIFY(ndi->initialized);
1805	lck_mtx_lock(&ndi->lock);
1806	if (ip6_maxifdefrouters >= 0 &&
1807	    ndi->ndefrouters >= ip6_maxifdefrouters) {
1808		lck_mtx_unlock(&ndi->lock);
1809freeit:
1810		lck_rw_done(nd_if_rwlock);
1811		nddr_free(n);
1812		return (NULL);
1813	}
1814
1815	NDDR_ADDREF(n);	/* for the nd_defrouter list */
1816	NDDR_ADDREF(n);	/* for the caller */
1817
1818	++nd6_defrouter_genid;
1819	ndi->ndefrouters++;
1820	VERIFY(ndi->ndefrouters != 0);
1821	lck_mtx_unlock(&ndi->lock);
1822	lck_rw_done(nd_if_rwlock);
1823
1824	nd6log2((LOG_INFO, "%s: allocating defrouter %s\n", if_name(ifp),
1825	    ip6_sprintf(&new->rtaddr)));
1826
1827	NDDR_LOCK(n);
1828	memcpy(&n->rtaddr, &new->rtaddr, sizeof(n->rtaddr));
1829	n->flags = new->flags;
1830	n->stateflags = new->stateflags;
1831	n->stateflags &= ~NDDRF_PROCESSED;
1832	n->rtlifetime = new->rtlifetime;
1833	n->expire = new->expire;
1834	n->ifp = new->ifp;
1835	n->genid = new->genid;
1836	n->err = new->err;
1837	NDDR_UNLOCK(n);
1838insert:
1839
1840	/*
1841	 * Insert the new router in the Default Router List;
1842	 * The Default Router List should be in the descending order
1843	 * of router-preferece.  When Scoped Routing is disabled, routers
1844	 * with the same preference are sorted in the arriving time order;
1845	 * otherwise, the first entry in the list of routers having the same
1846	 * preference is the primary default router, when the interface used
1847	 * by the entry is the default interface.
1848	 */
1849
1850	/* insert at the end of the group */
1851	for (dr = TAILQ_FIRST(&nd_defrouter); dr;
1852	     dr = TAILQ_NEXT(dr, dr_entry)) {
1853		if (rtpref(n) > rtpref(dr) ||
1854		    (ip6_doscopedroute && !scoped && rtpref(n) == rtpref(dr)))
1855			break;
1856	}
1857	if (dr)
1858		TAILQ_INSERT_BEFORE(dr, n, dr_entry);
1859	else
1860		TAILQ_INSERT_TAIL(&nd_defrouter, n, dr_entry);
1861
1862	defrouter_select(ifp);
1863
1864	return (n);
1865}
1866
1867static struct nd_defrouter *
1868defrtrlist_update(struct nd_defrouter *new)
1869{
1870	struct nd_defrouter *dr;
1871
1872	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1873	dr = defrtrlist_update_common(new,
1874	    (nd6_defifp != NULL && new->ifp != nd6_defifp));
1875
1876	return (dr);
1877}
1878
1879static void
1880defrtrlist_sync(struct ifnet *ifp)
1881{
1882	struct nd_defrouter *dr, new;
1883
1884	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1885
1886	if (!ip6_doscopedroute) {
1887		defrouter_select(ifp);
1888		return;
1889	}
1890
1891	for (dr = TAILQ_FIRST(&nd_defrouter); dr;
1892	     dr = TAILQ_NEXT(dr, dr_entry)) {
1893		NDDR_LOCK(dr);
1894		if (dr->ifp == ifp && (dr->stateflags & NDDRF_INSTALLED))
1895			break;
1896		NDDR_UNLOCK(dr);
1897	}
1898
1899	if (dr == NULL) {
1900		defrouter_select(ifp);
1901	} else {
1902		memcpy(&new.rtaddr, &dr->rtaddr, sizeof(new.rtaddr));
1903		new.flags = dr->flags;
1904		new.stateflags = dr->stateflags;
1905		new.stateflags &= ~NDDRF_PROCESSED;
1906		new.rtlifetime = dr->rtlifetime;
1907		new.expire = dr->expire;
1908		new.ifp = dr->ifp;
1909		new.genid = dr->genid;
1910		new.err = dr->err;
1911		NDDR_UNLOCK(dr);
1912		dr = defrtrlist_update_common(&new, FALSE);
1913		if (dr)
1914			NDDR_REMREF(dr);
1915	}
1916}
1917
1918static struct nd_pfxrouter *
1919pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
1920{
1921	struct nd_pfxrouter *search;
1922
1923	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1924	NDPR_LOCK_ASSERT_HELD(pr);
1925
1926	for (search = pr->ndpr_advrtrs.lh_first; search;
1927	    search = search->pfr_next) {
1928		if (search->router == dr)
1929			break;
1930	}
1931
1932	return(search);
1933}
1934
1935static void
1936pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
1937{
1938	struct nd_pfxrouter *new;
1939
1940	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1941	NDPR_LOCK_ASSERT_NOTHELD(pr);
1942
1943	new = zalloc(ndprtr_zone);
1944	if (new == NULL)
1945		return;
1946	bzero(new, sizeof(*new));
1947	new->router = dr;
1948
1949	NDPR_LOCK(pr);
1950	LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
1951	NDPR_UNLOCK(pr);
1952
1953	pfxlist_onlink_check();
1954}
1955
1956static void
1957pfxrtr_del(
1958	struct nd_pfxrouter *pfr)
1959{
1960	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1961	LIST_REMOVE(pfr, pfr_entry);
1962	zfree(ndprtr_zone, pfr);
1963}
1964
1965struct nd_prefix *
1966nd6_prefix_lookup(struct nd_prefix *pr)
1967{
1968	struct nd_prefix *search;
1969
1970	lck_mtx_lock(nd6_mutex);
1971	for (search = nd_prefix.lh_first; search; search = search->ndpr_next) {
1972		NDPR_LOCK(search);
1973		if (pr->ndpr_ifp == search->ndpr_ifp &&
1974		    pr->ndpr_plen == search->ndpr_plen &&
1975		    in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
1976		    &search->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
1977			NDPR_ADDREF_LOCKED(search);
1978			NDPR_UNLOCK(search);
1979			break;
1980		}
1981		NDPR_UNLOCK(search);
1982	}
1983	lck_mtx_unlock(nd6_mutex);
1984
1985	return(search);
1986}
1987
1988static void
1989purge_detached(struct ifnet *ifp)
1990{
1991	struct nd_prefix *pr, *pr_next;
1992	struct in6_ifaddr *ia;
1993	struct ifaddr *ifa, *ifa_next;
1994
1995	lck_mtx_lock(nd6_mutex);
1996
1997	pr = nd_prefix.lh_first;
1998repeat:
1999	while (pr) {
2000		pr_next = pr->ndpr_next;
2001		NDPR_LOCK(pr);
2002		if (pr->ndpr_ifp != ifp ||
2003		    IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
2004		    ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
2005		    !LIST_EMPTY(&pr->ndpr_advrtrs))) {
2006			NDPR_UNLOCK(pr);
2007			pr = pr_next;
2008			continue;
2009		}
2010		NDPR_UNLOCK(pr);
2011		ifnet_lock_shared(ifp);
2012		for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa_next) {
2013			ifa_next = ifa->ifa_list.tqe_next;
2014			IFA_LOCK(ifa);
2015			if (ifa->ifa_addr->sa_family != AF_INET6) {
2016				IFA_UNLOCK(ifa);
2017				continue;
2018			}
2019			ia = (struct in6_ifaddr *)ifa;
2020			if ((ia->ia6_flags & IN6_IFF_AUTOCONF) ==
2021			    IN6_IFF_AUTOCONF && ia->ia6_ndpr == pr) {
2022				IFA_ADDREF_LOCKED(ifa);	/* for us */
2023				IFA_UNLOCK(ifa);
2024				/*
2025				 * Purging the address requires writer access
2026				 * to the address list, so drop the ifnet lock
2027				 * now and repeat from beginning.
2028				 */
2029				ifnet_lock_done(ifp);
2030				lck_mtx_unlock(nd6_mutex);
2031				in6_purgeaddr(ifa);
2032				IFA_REMREF(ifa); /* drop ours */
2033				lck_mtx_lock(nd6_mutex);
2034				pr = nd_prefix.lh_first;
2035				goto repeat;
2036			}
2037			IFA_UNLOCK(ifa);
2038		}
2039		ifnet_lock_done(ifp);
2040		NDPR_LOCK(pr);
2041		if (pr->ndpr_addrcnt == 0) {
2042			NDPR_ADDREF_LOCKED(pr);
2043			prelist_remove(pr);
2044			NDPR_UNLOCK(pr);
2045			NDPR_REMREF(pr);
2046		} else {
2047			NDPR_UNLOCK(pr);
2048		}
2049		pr = pr_next;
2050	}
2051
2052	lck_mtx_unlock(nd6_mutex);
2053}
2054
2055int
2056nd6_prelist_add(struct nd_prefix *pr, struct nd_defrouter *dr,
2057    struct nd_prefix **newp, boolean_t force_scoped)
2058{
2059	struct nd_prefix *new = NULL;
2060	struct ifnet *ifp = pr->ndpr_ifp;
2061	struct nd_ifinfo *ndi = NULL;
2062	int i, error;
2063	struct timeval timenow;
2064
2065	getmicrotime(&timenow);
2066
2067	if (ip6_maxifprefixes >= 0) {
2068		lck_rw_lock_shared(nd_if_rwlock);
2069		if (ifp->if_index >= nd_ifinfo_indexlim) {
2070			lck_rw_done(nd_if_rwlock);
2071			return (EINVAL);
2072		}
2073		ndi = &nd_ifinfo[ifp->if_index];
2074		VERIFY(ndi->initialized);
2075		lck_mtx_lock(&ndi->lock);
2076		if (ndi->nprefixes >= ip6_maxifprefixes / 2) {
2077			lck_mtx_unlock(&ndi->lock);
2078			lck_rw_done(nd_if_rwlock);
2079			purge_detached(ifp);
2080			lck_rw_lock_shared(nd_if_rwlock);
2081			/*
2082			 * Refresh pointer since nd_ifinfo[] may have grown;
2083			 * repeating the bounds check against nd_ifinfo_indexlim
2084			 * isn't necessary since the array never shrinks.
2085			 */
2086			ndi = &nd_ifinfo[ifp->if_index];
2087			lck_mtx_lock(&ndi->lock);
2088		}
2089		if (ndi->nprefixes >= ip6_maxifprefixes) {
2090			lck_mtx_unlock(&ndi->lock);
2091			lck_rw_done(nd_if_rwlock);
2092			return(ENOMEM);
2093		}
2094		lck_mtx_unlock(&ndi->lock);
2095		lck_rw_done(nd_if_rwlock);
2096	}
2097
2098	new = ndpr_alloc(M_WAITOK);
2099	if (new == NULL)
2100		return ENOMEM;
2101
2102	NDPR_LOCK(new);
2103	NDPR_LOCK(pr);
2104	new->ndpr_ifp = pr->ndpr_ifp;
2105	new->ndpr_prefix = pr->ndpr_prefix;
2106	new->ndpr_plen = pr->ndpr_plen;
2107	new->ndpr_vltime = pr->ndpr_vltime;
2108	new->ndpr_pltime = pr->ndpr_pltime;
2109	new->ndpr_flags = pr->ndpr_flags;
2110	if (pr->ndpr_stateflags & NDPRF_STATIC)
2111		new->ndpr_stateflags |= NDPRF_STATIC;
2112	NDPR_UNLOCK(pr);
2113	if ((error = in6_init_prefix_ltimes(new)) != 0) {
2114		NDPR_UNLOCK(new);
2115		ndpr_free(new);
2116		return(error);
2117	}
2118	new->ndpr_lastupdate = timenow.tv_sec;
2119	if (newp != NULL) {
2120		*newp = new;
2121		NDPR_ADDREF_LOCKED(new);	/* for caller */
2122	}
2123	/* initialization */
2124	LIST_INIT(&new->ndpr_advrtrs);
2125	in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen);
2126	/* make prefix in the canonical form */
2127	for (i = 0; i < 4; i++)
2128		new->ndpr_prefix.sin6_addr.s6_addr32[i] &=
2129			new->ndpr_mask.s6_addr32[i];
2130
2131	NDPR_UNLOCK(new);
2132
2133	lck_mtx_lock(nd6_mutex);
2134	/* link ndpr_entry to nd_prefix list */
2135	LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry);
2136	new->ndpr_debug |= IFD_ATTACHED;
2137	NDPR_ADDREF(new);	/* for nd_prefix list */
2138
2139	/* ND_OPT_PI_FLAG_ONLINK processing */
2140	if (new->ndpr_raf_onlink) {
2141		int e;
2142
2143		if ((e = nd6_prefix_onlink_common(new, force_scoped,
2144		    new->ndpr_ifp->if_index)) != 0) {
2145			nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
2146			    "the prefix %s/%d on-link %s on %s (errno=%d)\n",
2147			    ip6_sprintf(&new->ndpr_prefix.sin6_addr),
2148			    new->ndpr_plen, force_scoped ? "scoped" :
2149			    "non-scoped", if_name(ifp), e));
2150			/* proceed anyway. XXX: is it correct? */
2151		}
2152	}
2153
2154	if (dr) {
2155		pfxrtr_add(new, dr);
2156	}
2157
2158	lck_rw_lock_shared(nd_if_rwlock);
2159	/*
2160	 * Refresh pointer since nd_ifinfo[] may have grown;
2161	 * repeating the bounds check against nd_ifinfo_indexlim
2162	 * isn't necessary since the array never shrinks.
2163	 */
2164	ndi = &nd_ifinfo[ifp->if_index];
2165	VERIFY(ndi->initialized);
2166	lck_mtx_lock(&ndi->lock);
2167	ndi->nprefixes++;
2168	VERIFY(ndi->nprefixes != 0);
2169	lck_mtx_unlock(&ndi->lock);
2170	lck_rw_done(nd_if_rwlock);
2171
2172	lck_mtx_unlock(nd6_mutex);
2173
2174	return 0;
2175}
2176
2177/*
2178 * Caller must have held an extra reference on nd_prefix.
2179 */
2180void
2181prelist_remove(struct nd_prefix *pr)
2182{
2183	struct nd_pfxrouter *pfr, *next;
2184	struct ifnet *ifp = pr->ndpr_ifp;
2185	int e;
2186
2187	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2188	NDPR_LOCK_ASSERT_HELD(pr);
2189
2190	/* make sure to invalidate the prefix until it is really freed. */
2191	pr->ndpr_vltime = 0;
2192	pr->ndpr_pltime = 0;
2193
2194	/*
2195	 * Though these flags are now meaningless, we'd rather keep the value
2196	 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users
2197	 * when executing "ndp -p".
2198	 */
2199
2200	if ((pr->ndpr_stateflags & NDPRF_ONLINK)) {
2201		NDPR_ADDREF_LOCKED(pr);
2202		NDPR_UNLOCK(pr);
2203		lck_mtx_unlock(nd6_mutex);
2204		if ((e = nd6_prefix_offlink(pr)) != 0) {
2205			nd6log((LOG_ERR, "prelist_remove: failed to make "
2206			    "%s/%d offlink on %s, errno=%d\n",
2207			    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
2208			    pr->ndpr_plen, if_name(ifp), e));
2209			/* what should we do? */
2210		}
2211		lck_mtx_lock(nd6_mutex);
2212		NDPR_LOCK(pr);
2213		if (NDPR_REMREF_LOCKED(pr) == NULL)
2214			return;
2215	}
2216
2217	if (pr->ndpr_addrcnt > 0)
2218		return;	/* notice here? */
2219
2220	/* unlink ndpr_entry from nd_prefix list */
2221	LIST_REMOVE(pr, ndpr_entry);
2222	pr->ndpr_debug &= ~IFD_ATTACHED;
2223
2224	/* free list of routers that adversed the prefix */
2225	for (pfr = pr->ndpr_advrtrs.lh_first; pfr; pfr = next) {
2226		next = pfr->pfr_next;
2227		pfxrtr_del(pfr);
2228	}
2229
2230	lck_rw_lock_shared(nd_if_rwlock);
2231	if (ifp->if_index < nd_ifinfo_indexlim) {
2232		struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
2233		VERIFY(ndi->initialized);
2234		lck_mtx_lock(&ndi->lock);
2235		VERIFY(ndi->nprefixes > 0);
2236		ndi->nprefixes--;
2237		lck_mtx_unlock(&ndi->lock);
2238	}
2239	lck_rw_done(nd_if_rwlock);
2240
2241	/* This must not be the last reference to the nd_prefix */
2242	if (NDPR_REMREF_LOCKED(pr) == NULL) {
2243		panic("%s: unexpected (missing) refcnt ndpr=%p", __func__, pr);
2244		/* NOTREACHED */
2245	}
2246
2247	pfxlist_onlink_check();
2248}
2249
2250int
2251prelist_update(
2252	struct nd_prefix *new,
2253	struct nd_defrouter *dr, /* may be NULL */
2254	struct mbuf *m,
2255	int mcast)
2256{
2257	struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
2258	struct ifaddr *ifa;
2259	struct ifnet *ifp = new->ndpr_ifp;
2260	struct nd_prefix *pr;
2261	int error = 0;
2262	int newprefix = 0;
2263	int auth;
2264	struct in6_addrlifetime lt6_tmp;
2265	struct timeval timenow;
2266
2267	/* no need to lock "new" here, as it is local to the caller */
2268	NDPR_LOCK_ASSERT_NOTHELD(new);
2269
2270	auth = 0;
2271	if (m) {
2272		/*
2273		 * Authenticity for NA consists authentication for
2274		 * both IP header and IP datagrams, doesn't it ?
2275		 */
2276#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM)
2277		auth = (m->m_flags & M_AUTHIPHDR
2278		     && m->m_flags & M_AUTHIPDGM) ? 1 : 0;
2279#endif
2280	}
2281
2282
2283	if ((pr = nd6_prefix_lookup(new)) != NULL) {
2284		/*
2285		 * nd6_prefix_lookup() ensures that pr and new have the same
2286		 * prefix on a same interface.
2287		 */
2288
2289		/*
2290		 * Update prefix information.  Note that the on-link (L) bit
2291		 * and the autonomous (A) bit should NOT be changed from 1
2292		 * to 0.
2293		 */
2294		lck_mtx_lock(nd6_mutex);
2295		NDPR_LOCK(pr);
2296		if (new->ndpr_raf_onlink == 1)
2297			pr->ndpr_raf_onlink = 1;
2298		if (new->ndpr_raf_auto == 1)
2299			pr->ndpr_raf_auto = 1;
2300		if (new->ndpr_raf_onlink) {
2301			pr->ndpr_vltime = new->ndpr_vltime;
2302			pr->ndpr_pltime = new->ndpr_pltime;
2303			pr->ndpr_preferred = new->ndpr_preferred;
2304			pr->ndpr_expire = new->ndpr_expire;
2305		}
2306
2307		if (new->ndpr_raf_onlink &&
2308		    (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
2309			int e;
2310
2311			NDPR_UNLOCK(pr);
2312			if ((e = nd6_prefix_onlink(pr)) != 0) {
2313				nd6log((LOG_ERR,
2314				    "prelist_update: failed to make "
2315				    "the prefix %s/%d on-link on %s "
2316				    "(errno=%d)\n",
2317				    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
2318				    pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
2319				/* proceed anyway. XXX: is it correct? */
2320			}
2321			NDPR_LOCK(pr);
2322		}
2323
2324		if (dr && pfxrtr_lookup(pr, dr) == NULL) {
2325			NDPR_UNLOCK(pr);
2326			pfxrtr_add(pr, dr);
2327		} else {
2328			NDPR_UNLOCK(pr);
2329		}
2330		lck_mtx_unlock(nd6_mutex);
2331	} else {
2332		struct nd_prefix *newpr = NULL;
2333
2334		newprefix = 1;
2335
2336		if (new->ndpr_vltime == 0)
2337			goto end;
2338		if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0)
2339			goto end;
2340
2341		bzero(&new->ndpr_addr, sizeof(struct in6_addr));
2342
2343		error = nd6_prelist_add(new, dr, &newpr, FALSE);
2344		if (error != 0 || newpr == NULL) {
2345			nd6log((LOG_NOTICE, "prelist_update: "
2346			    "nd6_prelist_add failed for %s/%d on %s "
2347			    "errno=%d, returnpr=%p\n",
2348			    ip6_sprintf(&new->ndpr_prefix.sin6_addr),
2349					new->ndpr_plen, if_name(new->ndpr_ifp),
2350					error, newpr));
2351			goto end; /* we should just give up in this case. */
2352		}
2353
2354		/*
2355		 * XXX: from the ND point of view, we can ignore a prefix
2356		 * with the on-link bit being zero.  However, we need a
2357		 * prefix structure for references from autoconfigured
2358		 * addresses.  Thus, we explicitly make sure that the prefix
2359		 * itself expires now.
2360		 */
2361		NDPR_LOCK(newpr);
2362		if (newpr->ndpr_raf_onlink == 0) {
2363			newpr->ndpr_vltime = 0;
2364			newpr->ndpr_pltime = 0;
2365			in6_init_prefix_ltimes(newpr);
2366		}
2367
2368		pr = newpr;
2369		NDPR_UNLOCK(newpr);
2370	}
2371
2372	/*
2373	 * Address autoconfiguration based on Section 5.5.3 of RFC 2462.
2374	 * Note that pr must be non NULL at this point.
2375	 */
2376
2377	/* 5.5.3 (a). Ignore the prefix without the A bit set. */
2378	if (!new->ndpr_raf_auto)
2379		goto afteraddrconf;
2380
2381	/*
2382	 * 5.5.3 (b). the link-local prefix should have been ignored in
2383	 * nd6_ra_input.
2384	 */
2385
2386	/* 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. */
2387	if (new->ndpr_pltime > new->ndpr_vltime) {
2388		error = EINVAL;	/* XXX: won't be used */
2389		goto end;
2390	}
2391
2392	/*
2393	 * 5.5.3 (d).  If the prefix advertised is not equal to the prefix of
2394	 * an address configured by stateless autoconfiguration already in the
2395	 * list of addresses associated with the interface, and the Valid
2396	 * Lifetime is not 0, form an address.  We first check if we have
2397	 * a matching prefix.
2398	 * Note: we apply a clarification in rfc2462bis-02 here.  We only
2399	 * consider autoconfigured addresses while RFC2462 simply said
2400	 * "address".
2401	 */
2402
2403 	getmicrotime(&timenow);
2404
2405	ifnet_lock_shared(ifp);
2406	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2407	{
2408		struct in6_ifaddr *ifa6;
2409		u_int32_t remaininglifetime;
2410
2411		IFA_LOCK(ifa);
2412		if (ifa->ifa_addr->sa_family != AF_INET6) {
2413			IFA_UNLOCK(ifa);
2414			continue;
2415		}
2416		ifa6 = (struct in6_ifaddr *)ifa;
2417
2418		/*
2419		 * We only consider autoconfigured addresses as per rfc2462bis.
2420		 */
2421		if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) {
2422			IFA_UNLOCK(ifa);
2423			continue;
2424		}
2425		/*
2426		 * Spec is not clear here, but I believe we should concentrate
2427		 * on unicast (i.e. not anycast) addresses.
2428		 * XXX: other ia6_flags? detached or duplicated?
2429		 */
2430		if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) {
2431			IFA_UNLOCK(ifa);
2432			continue;
2433		}
2434		/*
2435		 * Ignore the address if it is not associated with a prefix
2436		 * or is associated with a prefix that is different from this
2437		 * one.  (pr is never NULL here)
2438		 */
2439		if (ifa6->ia6_ndpr != pr) {
2440			IFA_UNLOCK(ifa);
2441			continue;
2442		}
2443
2444		if (ia6_match == NULL) { /* remember the first one */
2445			ia6_match = ifa6;
2446			IFA_ADDREF_LOCKED(ifa);	/* for ia6_match */
2447		}
2448
2449		/*
2450		 * An already autoconfigured address matched.  Now that we
2451		 * are sure there is at least one matched address, we can
2452		 * proceed to 5.5.3. (e): update the lifetimes according to the
2453		 * "two hours" rule and the privacy extension.
2454		 * We apply some clarifications in rfc2462bis:
2455		 * - use remaininglifetime instead of storedlifetime as a
2456		 *   variable name
2457		 * - remove the dead code in the "two-hour" rule
2458		 */
2459#define TWOHOUR		(120*60)
2460		lt6_tmp = ifa6->ia6_lifetime;
2461
2462		if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME)
2463			remaininglifetime = ND6_INFINITE_LIFETIME;
2464		else if (timenow.tv_sec - ifa6->ia6_updatetime >
2465			 lt6_tmp.ia6t_vltime) {
2466			/*
2467			 * The case of "invalid" address.  We should usually
2468			 * not see this case.
2469			 */
2470			remaininglifetime = 0;
2471		} else
2472			remaininglifetime = lt6_tmp.ia6t_vltime -
2473			    (timenow.tv_sec - ifa6->ia6_updatetime);
2474
2475		/* when not updating, keep the current stored lifetime. */
2476		lt6_tmp.ia6t_vltime = remaininglifetime;
2477
2478		if (TWOHOUR < new->ndpr_vltime ||
2479		    remaininglifetime < new->ndpr_vltime) {
2480			lt6_tmp.ia6t_vltime = new->ndpr_vltime;
2481		} else if (remaininglifetime <= TWOHOUR) {
2482			if (auth) {
2483				lt6_tmp.ia6t_vltime = new->ndpr_vltime;
2484			}
2485		} else {
2486			/*
2487			 * new->ndpr_vltime <= TWOHOUR &&
2488			 * TWOHOUR < remaininglifetime
2489			 */
2490			lt6_tmp.ia6t_vltime = TWOHOUR;
2491		}
2492
2493		/* The 2 hour rule is not imposed for preferred lifetime. */
2494		lt6_tmp.ia6t_pltime = new->ndpr_pltime;
2495
2496		/* Special handling for lifetimes of temporary addresses. */
2497		if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
2498			u_int32_t maxvltime, maxpltime;
2499
2500			/* Constrain lifetimes to system limits. */
2501			if (lt6_tmp.ia6t_vltime > ip6_temp_valid_lifetime)
2502				lt6_tmp.ia6t_vltime = ip6_temp_valid_lifetime;
2503			if (lt6_tmp.ia6t_pltime > ip6_temp_preferred_lifetime)
2504				lt6_tmp.ia6t_pltime =
2505				    ip6_temp_preferred_lifetime -
2506				    ip6_desync_factor;
2507
2508			/*
2509			 * According to RFC 4941, section 3.3 (1), we only
2510			 * update the lifetimes when they are in the maximum
2511			 * intervals.
2512			 */
2513			if (ip6_temp_valid_lifetime >
2514			    (u_int32_t)((timenow.tv_sec - ifa6->ia6_createtime) +
2515			    ip6_desync_factor)) {
2516				maxvltime = ip6_temp_valid_lifetime -
2517				    (timenow.tv_sec - ifa6->ia6_createtime) -
2518				    ip6_desync_factor;
2519			} else
2520				maxvltime = 0;
2521			if (ip6_temp_preferred_lifetime >
2522			    (u_int32_t)((timenow.tv_sec - ifa6->ia6_createtime) +
2523			    ip6_desync_factor)) {
2524				maxpltime = ip6_temp_preferred_lifetime -
2525				    (timenow.tv_sec - ifa6->ia6_createtime) -
2526				    ip6_desync_factor;
2527			} else
2528				maxpltime = 0;
2529
2530			if (lt6_tmp.ia6t_vltime > maxvltime)
2531				lt6_tmp.ia6t_vltime = maxvltime;
2532			if (lt6_tmp.ia6t_pltime > maxpltime)
2533				lt6_tmp.ia6t_pltime = maxpltime;
2534		}
2535
2536		in6_init_address_ltimes(pr, &lt6_tmp,
2537		    !!(ifa6->ia6_flags & IN6_IFF_TEMPORARY));
2538
2539		ifa6->ia6_lifetime = lt6_tmp;
2540		ifa6->ia6_updatetime = timenow.tv_sec;
2541		IFA_UNLOCK(ifa);
2542	}
2543	ifnet_lock_done(ifp);
2544	if (ia6_match == NULL && new->ndpr_vltime) {
2545		int ifidlen;
2546
2547		/*
2548		 * 5.5.3 (d) (continued)
2549		 * No address matched and the valid lifetime is non-zero.
2550		 * Create a new address.
2551		 */
2552
2553		/*
2554		 * Prefix Length check:
2555		 * If the sum of the prefix length and interface identifier
2556		 * length does not equal 128 bits, the Prefix Information
2557		 * option MUST be ignored.  The length of the interface
2558		 * identifier is defined in a separate link-type specific
2559		 * document.
2560		 */
2561		ifidlen = in6_if2idlen(ifp);
2562		if (ifidlen < 0) {
2563			/* this should not happen, so we always log it. */
2564			log(LOG_ERR, "prelist_update: IFID undefined (%s)\n",
2565			    if_name(ifp));
2566			goto end;
2567		}
2568		NDPR_LOCK(pr);
2569		if (ifidlen + pr->ndpr_plen != 128) {
2570			nd6log((LOG_INFO,
2571			    "prelist_update: invalid prefixlen "
2572			    "%d for %s, ignored\n",
2573			    pr->ndpr_plen, if_name(ifp)));
2574			NDPR_UNLOCK(pr);
2575			goto end;
2576		}
2577		NDPR_UNLOCK(pr);
2578
2579		if ((ia6 = in6_ifadd(new, mcast)) != NULL) {
2580			/*
2581			 * note that we should use pr (not new) for reference.
2582			 */
2583			IFA_LOCK(&ia6->ia_ifa);
2584			NDPR_LOCK(pr);
2585			ia6->ia6_ndpr = pr;
2586			NDPR_ADDREF_LOCKED(pr);	/* for addr reference */
2587			pr->ndpr_addrcnt++;
2588			VERIFY(pr->ndpr_addrcnt != 0);
2589			NDPR_UNLOCK(pr);
2590			IFA_UNLOCK(&ia6->ia_ifa);
2591
2592			/*
2593			 * RFC 4941 3.3 (2).
2594			 * When a new public address is created as described
2595			 * in RFC2462, also create a new temporary address.
2596			 *
2597			 * RFC 4941 3.5.
2598			 * When an interface connects to a new link, a new
2599			 * randomized interface identifier should be generated
2600			 * immediately together with a new set of temporary
2601			 * addresses.  Thus, we specifiy 1 as the 2nd arg of
2602			 * in6_tmpifadd().
2603			 */
2604			if (ip6_use_tempaddr) {
2605				int e;
2606				if ((e = in6_tmpifadd(ia6, 1, M_WAITOK)) != 0) {
2607					nd6log((LOG_NOTICE, "prelist_update: "
2608					    "failed to create a temporary "
2609					    "address, errno=%d\n",
2610					    e));
2611				}
2612			}
2613			IFA_REMREF(&ia6->ia_ifa);
2614			ia6 = NULL;
2615
2616			/*
2617			 * A newly added address might affect the status
2618			 * of other addresses, so we check and update it.
2619			 * XXX: what if address duplication happens?
2620			 */
2621			lck_mtx_lock(nd6_mutex);
2622			pfxlist_onlink_check();
2623			lck_mtx_unlock(nd6_mutex);
2624		} else {
2625			/* just set an error. do not bark here. */
2626			error = EADDRNOTAVAIL;
2627		}
2628	}
2629
2630afteraddrconf:
2631
2632end:
2633	if (pr != NULL)
2634		NDPR_REMREF(pr);
2635	if (ia6_match != NULL)
2636		IFA_REMREF(&ia6_match->ia_ifa);
2637	return error;
2638}
2639
2640/*
2641 * Neighbor Discover Default Router structure reference counting routines.
2642 */
2643static struct nd_defrouter *
2644nddr_alloc(int how)
2645{
2646	struct nd_defrouter *dr;
2647
2648	dr = (how == M_WAITOK) ? zalloc(nddr_zone) : zalloc_noblock(nddr_zone);
2649	if (dr != NULL) {
2650		bzero(dr, nddr_size);
2651		lck_mtx_init(&dr->nddr_lock, ifa_mtx_grp, ifa_mtx_attr);
2652		dr->nddr_debug |= IFD_ALLOC;
2653		if (nddr_debug != 0) {
2654			dr->nddr_debug |= IFD_DEBUG;
2655			dr->nddr_trace = nddr_trace;
2656		}
2657	}
2658	return (dr);
2659}
2660
2661static void
2662nddr_free(struct nd_defrouter *dr)
2663{
2664	NDDR_LOCK(dr);
2665	if (dr->nddr_debug & IFD_ATTACHED) {
2666		panic("%s: attached nddr %p is being freed", __func__, dr);
2667		/* NOTREACHED */
2668	} else if (!(dr->nddr_debug & IFD_ALLOC)) {
2669		panic("%s: nddr %p cannot be freed", __func__, dr);
2670		/* NOTREACHED */
2671	}
2672	dr->nddr_debug &= ~IFD_ALLOC;
2673	NDDR_UNLOCK(dr);
2674
2675	lck_mtx_destroy(&dr->nddr_lock, ifa_mtx_grp);
2676	zfree(nddr_zone, dr);
2677}
2678
2679static void
2680nddr_trace(struct nd_defrouter *dr, int refhold)
2681{
2682	struct nd_defrouter_dbg *dr_dbg = (struct nd_defrouter_dbg *)dr;
2683	ctrace_t *tr;
2684	uint32_t idx;
2685	uint16_t *cnt;
2686
2687	if (!(dr->nddr_debug & IFD_DEBUG)) {
2688		panic("%s: nddr %p has no debug structure", __func__, dr);
2689		/* NOTREACHED */
2690	}
2691	if (refhold) {
2692		cnt = &dr_dbg->nddr_refhold_cnt;
2693		tr = dr_dbg->nddr_refhold;
2694	} else {
2695		cnt = &dr_dbg->nddr_refrele_cnt;
2696		tr = dr_dbg->nddr_refrele;
2697	}
2698
2699	idx = atomic_add_16_ov(cnt, 1) % NDDR_TRACE_HIST_SIZE;
2700	ctrace_record(&tr[idx]);
2701}
2702
2703void
2704nddr_addref(struct nd_defrouter *nddr, int locked)
2705{
2706
2707	if (!locked)
2708		NDDR_LOCK_SPIN(nddr);
2709	else
2710		NDDR_LOCK_ASSERT_HELD(nddr);
2711
2712	if (++nddr->nddr_refcount == 0) {
2713		panic("%s: nddr %p wraparound refcnt\n", __func__, nddr);
2714		/* NOTREACHED */
2715	} else if (nddr->nddr_trace != NULL) {
2716		(*nddr->nddr_trace)(nddr, TRUE);
2717	}
2718
2719	if (!locked)
2720		NDDR_UNLOCK(nddr);
2721}
2722
2723struct nd_defrouter *
2724nddr_remref(struct nd_defrouter *nddr, int locked)
2725{
2726
2727	if (!locked)
2728		NDDR_LOCK_SPIN(nddr);
2729	else
2730		NDDR_LOCK_ASSERT_HELD(nddr);
2731
2732	if (nddr->nddr_refcount == 0) {
2733		panic("%s: nddr %p negative refcnt\n", __func__, nddr);
2734		/* NOTREACHED */
2735	} else if (nddr->nddr_trace != NULL) {
2736		(*nddr->nddr_trace)(nddr, FALSE);
2737	}
2738
2739	if (--nddr->nddr_refcount == 0) {
2740		NDDR_UNLOCK(nddr);
2741		nddr_free(nddr);
2742		nddr = NULL;
2743	}
2744
2745	if (!locked && nddr != NULL)
2746		NDDR_UNLOCK(nddr);
2747
2748	return (nddr);
2749}
2750
2751/*
2752 * Neighbor Discover Prefix structure reference counting routines.
2753 */
2754static struct nd_prefix *
2755ndpr_alloc(int how)
2756{
2757	struct nd_prefix *pr;
2758
2759	pr = (how == M_WAITOK) ? zalloc(ndpr_zone) : zalloc_noblock(ndpr_zone);
2760	if (pr != NULL) {
2761		bzero(pr, ndpr_size);
2762		lck_mtx_init(&pr->ndpr_lock, ifa_mtx_grp, ifa_mtx_attr);
2763		RB_INIT(&pr->ndpr_prproxy_sols);
2764		pr->ndpr_debug |= IFD_ALLOC;
2765		if (ndpr_debug != 0) {
2766			pr->ndpr_debug |= IFD_DEBUG;
2767			pr->ndpr_trace = ndpr_trace;
2768		}
2769	}
2770	return (pr);
2771}
2772
2773static void
2774ndpr_free(struct nd_prefix *pr)
2775{
2776	NDPR_LOCK(pr);
2777	if (pr->ndpr_debug & IFD_ATTACHED) {
2778		panic("%s: attached ndpr %p is being freed", __func__, pr);
2779		/* NOTREACHED */
2780	} else if (!(pr->ndpr_debug & IFD_ALLOC)) {
2781		panic("%s: ndpr %p cannot be freed", __func__, pr);
2782		/* NOTREACHED */
2783	} else if (pr->ndpr_rt != NULL) {
2784		panic("%s: ndpr %p route %p not freed", __func__, pr,
2785		    pr->ndpr_rt);
2786		/* NOTREACHED */
2787	} else if (pr->ndpr_prproxy_sols_cnt != 0) {
2788		panic("%s: ndpr %p non-zero solicitors count (%d)",
2789		    __func__, pr, pr->ndpr_prproxy_sols_cnt);
2790		/* NOTREACHED */
2791	} else if (!RB_EMPTY(&pr->ndpr_prproxy_sols)) {
2792		panic("%s: ndpr %p non-empty solicitors tree", __func__, pr);
2793		/* NOTREACHED */
2794	}
2795	pr->ndpr_debug &= ~IFD_ALLOC;
2796	NDPR_UNLOCK(pr);
2797
2798	lck_mtx_destroy(&pr->ndpr_lock, ifa_mtx_grp);
2799	zfree(ndpr_zone, pr);
2800}
2801
2802static void
2803ndpr_trace(struct nd_prefix *pr, int refhold)
2804{
2805	struct nd_prefix_dbg *pr_dbg = (struct nd_prefix_dbg *)pr;
2806	ctrace_t *tr;
2807	u_int32_t idx;
2808	u_int16_t *cnt;
2809
2810	if (!(pr->ndpr_debug & IFD_DEBUG)) {
2811		panic("%s: ndpr %p has no debug structure", __func__, pr);
2812		/* NOTREACHED */
2813	}
2814	if (refhold) {
2815		cnt = &pr_dbg->ndpr_refhold_cnt;
2816		tr = pr_dbg->ndpr_refhold;
2817	} else {
2818		cnt = &pr_dbg->ndpr_refrele_cnt;
2819		tr = pr_dbg->ndpr_refrele;
2820	}
2821
2822	idx = atomic_add_16_ov(cnt, 1) % NDPR_TRACE_HIST_SIZE;
2823	ctrace_record(&tr[idx]);
2824}
2825
2826void
2827ndpr_addref(struct nd_prefix *ndpr, int locked)
2828{
2829	if (!locked)
2830		NDPR_LOCK_SPIN(ndpr);
2831	else
2832		NDPR_LOCK_ASSERT_HELD(ndpr);
2833
2834	if (++ndpr->ndpr_refcount == 0) {
2835		panic("%s: ndpr %p wraparound refcnt\n", __func__, ndpr);
2836		/* NOTREACHED */
2837	} else if (ndpr->ndpr_trace != NULL) {
2838		(*ndpr->ndpr_trace)(ndpr, TRUE);
2839	}
2840
2841	if (!locked)
2842		NDPR_UNLOCK(ndpr);
2843}
2844
2845struct nd_prefix *
2846ndpr_remref(struct nd_prefix *ndpr, int locked)
2847{
2848	if (!locked)
2849		NDPR_LOCK_SPIN(ndpr);
2850	else
2851		NDPR_LOCK_ASSERT_HELD(ndpr);
2852
2853	if (ndpr->ndpr_refcount == 0) {
2854		panic("%s: ndpr %p negative refcnt\n", __func__, ndpr);
2855		/* NOTREACHED */
2856	} else if (ndpr->ndpr_trace != NULL) {
2857		(*ndpr->ndpr_trace)(ndpr, FALSE);
2858	}
2859
2860	if (--ndpr->ndpr_refcount == 0) {
2861		if (ndpr->ndpr_addrcnt != 0) {
2862			panic("%s: freeing ndpr %p with outstanding address "
2863			    "reference (%d)", __func__, ndpr,
2864			    ndpr->ndpr_addrcnt);
2865			/* NOTREACHED */
2866		}
2867		NDPR_UNLOCK(ndpr);
2868		ndpr_free(ndpr);
2869		ndpr = NULL;
2870	}
2871
2872	if (!locked && ndpr != NULL)
2873		NDPR_UNLOCK(ndpr);
2874
2875	return (ndpr);
2876}
2877
2878/*
2879 * A supplement function used in the on-link detection below;
2880 * detect if a given prefix has a (probably) reachable advertising router.
2881 * XXX: lengthy function name...
2882 */
2883static struct nd_pfxrouter *
2884find_pfxlist_reachable_router(struct nd_prefix *pr)
2885{
2886	struct nd_pfxrouter *pfxrtr;
2887	struct rtentry *rt;
2888	struct llinfo_nd6 *ln;
2889
2890	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2891	NDPR_LOCK_ASSERT_HELD(pr);
2892
2893	for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr;
2894	     pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) {
2895		NDPR_UNLOCK(pr);
2896		lck_mtx_unlock(nd6_mutex);
2897		/* Callee returns a locked route upon success */
2898		if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
2899		    pfxrtr->router->ifp, 0)) != NULL) {
2900			RT_LOCK_ASSERT_HELD(rt);
2901			if ((ln = rt->rt_llinfo) != NULL &&
2902			    ND6_IS_LLINFO_PROBREACH(ln)) {
2903				RT_REMREF_LOCKED(rt);
2904				RT_UNLOCK(rt);
2905				lck_mtx_lock(nd6_mutex);
2906				NDPR_LOCK(pr);
2907				break;	/* found */
2908			}
2909			RT_REMREF_LOCKED(rt);
2910			RT_UNLOCK(rt);
2911		}
2912		lck_mtx_lock(nd6_mutex);
2913		NDPR_LOCK(pr);
2914	}
2915	NDPR_LOCK_ASSERT_HELD(pr);
2916
2917	return (pfxrtr);
2918
2919}
2920
2921/*
2922 * Check if each prefix in the prefix list has at least one available router
2923 * that advertised the prefix (a router is "available" if its neighbor cache
2924 * entry is reachable or probably reachable).
2925 * If the check fails, the prefix may be off-link, because, for example,
2926 * we have moved from the network but the lifetime of the prefix has not
2927 * expired yet.  So we should not use the prefix if there is another prefix
2928 * that has an available router.
2929 * But, if there is no prefix that has an available router, we still regards
2930 * all the prefixes as on-link.  This is because we can't tell if all the
2931 * routers are simply dead or if we really moved from the network and there
2932 * is no router around us.
2933 */
2934void
2935pfxlist_onlink_check(void)
2936{
2937	struct nd_prefix *pr, *prclear;
2938	struct in6_ifaddr *ifa;
2939	struct nd_defrouter *dr;
2940	struct nd_pfxrouter *pfxrtr = NULL;
2941	int err, i, found = 0;
2942	struct ifaddr **ifap = NULL;
2943	struct nd_prefix *ndpr;
2944
2945	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2946
2947	while (nd_prefix_busy) {
2948		nd_prefix_waiters++;
2949		msleep(nd_prefix_waitchan, nd6_mutex, (PZERO-1),
2950		    __func__, NULL);
2951		lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2952	}
2953	nd_prefix_busy = TRUE;
2954
2955	/*
2956	 * Check if there is a prefix that has a reachable advertising
2957	 * router.
2958	 */
2959	pr = nd_prefix.lh_first;
2960	while (pr) {
2961		NDPR_LOCK(pr);
2962		if (pr->ndpr_stateflags & NDPRF_PROCESSED) {
2963			NDPR_UNLOCK(pr);
2964			pr = pr->ndpr_next;
2965			continue;
2966		}
2967		NDPR_ADDREF_LOCKED(pr);
2968		if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr) &&
2969		    (pr->ndpr_debug & IFD_ATTACHED)) {
2970			NDPR_UNLOCK(pr);
2971			NDPR_REMREF(pr);
2972			break;
2973		}
2974		pr->ndpr_stateflags |= NDPRF_PROCESSED;
2975		NDPR_UNLOCK(pr);
2976		NDPR_REMREF(pr);
2977		/*
2978		 * Since find_pfxlist_reachable_router() drops the nd6_mutex, we
2979		 * have to start over, but the NDPRF_PROCESSED flag will stop
2980		 * us from checking the same prefix twice.
2981		 */
2982		pr = nd_prefix.lh_first;
2983	}
2984	LIST_FOREACH(prclear, &nd_prefix, ndpr_entry) {
2985		NDPR_LOCK(prclear);
2986		prclear->ndpr_stateflags &= ~NDPRF_PROCESSED;
2987		NDPR_UNLOCK(prclear);
2988	}
2989
2990	/*
2991	 * If we have no such prefix, check whether we still have a router
2992	 * that does not advertise any prefixes.
2993	 */
2994	if (pr == NULL) {
2995		for (dr = TAILQ_FIRST(&nd_defrouter); dr;
2996		    dr = TAILQ_NEXT(dr, dr_entry)) {
2997			struct nd_prefix *pr0;
2998
2999			for (pr0 = nd_prefix.lh_first; pr0;
3000			    pr0 = pr0->ndpr_next) {
3001				NDPR_LOCK(pr0);
3002				if ((pfxrtr = pfxrtr_lookup(pr0, dr)) != NULL) {
3003					NDPR_UNLOCK(pr0);
3004					break;
3005				}
3006				NDPR_UNLOCK(pr0);
3007			}
3008			if (pfxrtr != NULL)
3009				break;
3010		}
3011	}
3012	if (pr != NULL || (TAILQ_FIRST(&nd_defrouter) && pfxrtr == NULL)) {
3013		/*
3014		 * There is at least one prefix that has a reachable router,
3015		 * or at least a router which probably does not advertise
3016		 * any prefixes.  The latter would be the case when we move
3017		 * to a new link where we have a router that does not provide
3018		 * prefixes and we configure an address by hand.
3019		 * Detach prefixes which have no reachable advertising
3020		 * router, and attach other prefixes.
3021		 */
3022		pr = nd_prefix.lh_first;
3023		while (pr) {
3024			NDPR_LOCK(pr);
3025			/*
3026			 * We aren't interested prefixes already processed,
3027			 * nor in prefixes without the L bit
3028			 * set nor in static prefixes
3029			 */
3030			if (pr->ndpr_raf_onlink == 0 ||
3031			    pr->ndpr_stateflags & NDPRF_PROCESSED ||
3032			    pr->ndpr_stateflags & NDPRF_STATIC) {
3033				NDPR_UNLOCK(pr);
3034				pr = pr->ndpr_next;
3035				continue;
3036			}
3037			NDPR_ADDREF_LOCKED(pr);
3038			if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
3039			    find_pfxlist_reachable_router(pr) == NULL &&
3040			    (pr->ndpr_debug & IFD_ATTACHED))
3041				pr->ndpr_stateflags |= NDPRF_DETACHED;
3042			if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
3043			    find_pfxlist_reachable_router(pr) != NULL &&
3044			    (pr->ndpr_debug & IFD_ATTACHED))
3045				pr->ndpr_stateflags &= ~NDPRF_DETACHED;
3046			pr->ndpr_stateflags |= NDPRF_PROCESSED;
3047			NDPR_UNLOCK(pr);
3048			NDPR_REMREF(pr);
3049			/*
3050			 * Since find_pfxlist_reachable_router() drops the
3051			 * nd6_mutex, we have to start over, but the
3052			 * NDPRF_PROCESSED flag will stop us from checking
3053			 * the same prefix twice.
3054			 */
3055			pr = nd_prefix.lh_first;
3056		}
3057	} else {
3058		/* there is no prefix that has a reachable router */
3059		for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3060			NDPR_LOCK(pr);
3061			if (pr->ndpr_raf_onlink == 0 ||
3062			    pr->ndpr_stateflags & NDPRF_STATIC) {
3063				NDPR_UNLOCK(pr);
3064				continue;
3065			}
3066			if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0)
3067				pr->ndpr_stateflags &= ~NDPRF_DETACHED;
3068			NDPR_UNLOCK(pr);
3069		}
3070	}
3071	LIST_FOREACH(prclear, &nd_prefix, ndpr_entry) {
3072		NDPR_LOCK(prclear);
3073		prclear->ndpr_stateflags &= ~NDPRF_PROCESSED;
3074		NDPR_UNLOCK(prclear);
3075	}
3076	VERIFY(nd_prefix_busy);
3077	nd_prefix_busy = FALSE;
3078	if (nd_prefix_waiters > 0) {
3079		nd_prefix_waiters = 0;
3080		wakeup(nd_prefix_waitchan);
3081	}
3082
3083	/*
3084	 * Remove each interface route associated with a (just) detached
3085	 * prefix, and reinstall the interface route for a (just) attached
3086	 * prefix.  Note that all attempt of reinstallation does not
3087	 * necessarily success, when a same prefix is shared among multiple
3088	 * interfaces.  Such cases will be handled in nd6_prefix_onlink,
3089	 * so we don't have to care about them.
3090	 */
3091	pr = nd_prefix.lh_first;
3092	while (pr) {
3093		int e;
3094
3095		NDPR_LOCK(pr);
3096		if (pr->ndpr_raf_onlink == 0 ||
3097		    pr->ndpr_stateflags & NDPRF_STATIC) {
3098			NDPR_UNLOCK(pr);
3099			pr = pr->ndpr_next;
3100			continue;
3101		}
3102		if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
3103		    (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
3104			NDPR_UNLOCK(pr);
3105			lck_mtx_unlock(nd6_mutex);
3106			if ((e = nd6_prefix_offlink(pr)) != 0) {
3107				nd6log((LOG_ERR,
3108				    "pfxlist_onlink_check: failed to "
3109				    "make %s/%d offlink, errno=%d\n",
3110				    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3111				    pr->ndpr_plen, e));
3112			}
3113			lck_mtx_lock(nd6_mutex);
3114			pr = nd_prefix.lh_first;
3115			continue;
3116		}
3117		if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
3118		    (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 &&
3119		    pr->ndpr_raf_onlink) {
3120			NDPR_UNLOCK(pr);
3121			if ((e = nd6_prefix_onlink(pr)) != 0) {
3122				nd6log((LOG_ERR,
3123				    "pfxlist_onlink_check: failed to "
3124				    "make %s/%d offlink, errno=%d\n",
3125				    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3126				    pr->ndpr_plen, e));
3127			}
3128		} else {
3129			NDPR_UNLOCK(pr);
3130		}
3131		pr = pr->ndpr_next;
3132	}
3133
3134	/*
3135	 * Changes on the prefix status might affect address status as well.
3136	 * Make sure that all addresses derived from an attached prefix are
3137	 * attached, and that all addresses derived from a detached prefix are
3138	 * detached.  Note, however, that a manually configured address should
3139	 * always be attached.
3140	 * The precise detection logic is same as the one for prefixes.
3141	 *
3142	 * ifnet_get_address_list_family_internal() may fail due to memory
3143	 * pressure, but we will eventually be called again when we receive
3144	 * another NA, RA, or when the link status changes.
3145	 */
3146	err = ifnet_get_address_list_family_internal(NULL, &ifap, AF_INET6, 0,
3147	    M_NOWAIT);
3148	if (err != 0 || ifap == NULL) {
3149		nd6log((LOG_ERR, "%s: ifnet_get_address_list_family_internal "
3150		    "failed", __func__));
3151		return;
3152	}
3153	for (i = 0; ifap[i]; i++) {
3154		ifa = ifatoia6(ifap[i]);
3155		IFA_LOCK(&ifa->ia_ifa);
3156		if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0 ||
3157		    (ifap[i]->ifa_debug & IFD_ATTACHED) == 0) {
3158			IFA_UNLOCK(&ifa->ia_ifa);
3159			continue;
3160		}
3161		if ((ndpr = ifa->ia6_ndpr) == NULL) {
3162			/*
3163			 * This can happen when we first configure the address
3164			 * (i.e. the address exists, but the prefix does not).
3165			 * XXX: complicated relationships...
3166			 */
3167			IFA_UNLOCK(&ifa->ia_ifa);
3168			continue;
3169		}
3170		NDPR_ADDREF(ndpr);
3171		IFA_UNLOCK(&ifa->ia_ifa);
3172
3173		NDPR_LOCK(ndpr);
3174		if (find_pfxlist_reachable_router(ndpr)) {
3175			NDPR_UNLOCK(ndpr);
3176			NDPR_REMREF(ndpr);
3177			found = 1;
3178			break;
3179		}
3180		NDPR_UNLOCK(ndpr);
3181		NDPR_REMREF(ndpr);
3182	}
3183	if (found) {
3184		for (i = 0; ifap[i]; i++) {
3185			ifa = ifatoia6(ifap[i]);
3186			IFA_LOCK(&ifa->ia_ifa);
3187			if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0 ||
3188			    (ifap[i]->ifa_debug & IFD_ATTACHED) == 0) {
3189				IFA_UNLOCK(&ifa->ia_ifa);
3190				continue;
3191			}
3192			if ((ndpr = ifa->ia6_ndpr) == NULL) {
3193				/* XXX: see above. */
3194				IFA_UNLOCK(&ifa->ia_ifa);
3195				continue;
3196			}
3197			NDPR_ADDREF(ndpr);
3198			IFA_UNLOCK(&ifa->ia_ifa);
3199			NDPR_LOCK(ndpr);
3200			if (find_pfxlist_reachable_router(ndpr)) {
3201				NDPR_UNLOCK(ndpr);
3202				IFA_LOCK(&ifa->ia_ifa);
3203				if (ifa->ia6_flags & IN6_IFF_DETACHED) {
3204					ifa->ia6_flags &= ~IN6_IFF_DETACHED;
3205					ifa->ia6_flags |= IN6_IFF_TENTATIVE;
3206					IFA_UNLOCK(&ifa->ia_ifa);
3207					nd6_dad_start((struct ifaddr *)ifa, 0);
3208				} else {
3209					IFA_UNLOCK(&ifa->ia_ifa);
3210				}
3211			} else {
3212				NDPR_UNLOCK(ndpr);
3213				IFA_LOCK(&ifa->ia_ifa);
3214				ifa->ia6_flags |= IN6_IFF_DETACHED;
3215				IFA_UNLOCK(&ifa->ia_ifa);
3216			}
3217			NDPR_REMREF(ndpr);
3218		}
3219	} else {
3220		for (i = 0; ifap[i]; i++) {
3221			ifa = ifatoia6(ifap[i]);
3222			IFA_LOCK(&ifa->ia_ifa);
3223			if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) {
3224				IFA_UNLOCK(&ifa->ia_ifa);
3225				continue;
3226			}
3227			if (ifa->ia6_flags & IN6_IFF_DETACHED) {
3228				ifa->ia6_flags &= ~IN6_IFF_DETACHED;
3229				ifa->ia6_flags |= IN6_IFF_TENTATIVE;
3230				IFA_UNLOCK(&ifa->ia_ifa);
3231				/* Do we need a delay in this case? */
3232				nd6_dad_start((struct ifaddr *)ifa, 0);
3233			} else {
3234				IFA_UNLOCK(&ifa->ia_ifa);
3235			}
3236		}
3237	}
3238	ifnet_free_address_list(ifap);
3239}
3240
3241static struct nd_prefix *
3242nd6_prefix_equal_lookup(struct nd_prefix *pr, boolean_t primary_only)
3243{
3244	struct nd_prefix *opr;
3245
3246	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3247
3248	for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) {
3249		if (opr == pr)
3250			continue;
3251
3252		NDPR_LOCK(opr);
3253		if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
3254			NDPR_UNLOCK(opr);
3255			continue;
3256		}
3257		if (opr->ndpr_plen == pr->ndpr_plen &&
3258		    in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
3259		    &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen) &&
3260		    (!primary_only ||
3261		    !(opr->ndpr_stateflags & NDPRF_IFSCOPE))) {
3262			NDPR_ADDREF_LOCKED(opr);
3263			NDPR_UNLOCK(opr);
3264			return (opr);
3265		}
3266		NDPR_UNLOCK(opr);
3267	}
3268	return (NULL);
3269}
3270
3271/*
3272 * Synchronize the interface routes of similar prefixes on different
3273 * interfaces; the one using the default interface would be (re)installed
3274 * as a primary/non-scoped entry, and the rest as scoped entri(es).
3275 */
3276static void
3277nd6_prefix_sync(struct ifnet *ifp)
3278{
3279	struct nd_prefix *pr, *opr;
3280	int err = 0;
3281
3282	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3283
3284	if (!ip6_doscopedroute || ifp == NULL)
3285		return;
3286
3287	for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3288		NDPR_LOCK(pr);
3289		if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
3290			NDPR_UNLOCK(pr);
3291			continue;
3292		}
3293		if (pr->ndpr_ifp == ifp &&
3294		    (pr->ndpr_stateflags & NDPRF_IFSCOPE) &&
3295		    !IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
3296			NDPR_UNLOCK(pr);
3297			break;
3298		}
3299		NDPR_UNLOCK(pr);
3300	}
3301
3302	if (pr == NULL)
3303		return;
3304
3305	/* Remove conflicting entries */
3306	opr = nd6_prefix_equal_lookup(pr, TRUE);
3307	if (opr != NULL) {
3308		lck_mtx_unlock(nd6_mutex);
3309		err = nd6_prefix_offlink(opr);
3310		lck_mtx_lock(nd6_mutex);
3311		if (err != 0) {
3312			nd6log((LOG_ERR,
3313			    "%s: failed to make %s/%d offlink on %s, "
3314			    "errno=%d\n", __func__,
3315			    ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
3316			    opr->ndpr_plen, if_name(opr->ndpr_ifp), err));
3317		}
3318	} else {
3319		nd6log((LOG_ERR,
3320		    "%s: scoped %s/%d on %s has no matching unscoped prefix\n",
3321		    __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3322		    pr->ndpr_plen, if_name(pr->ndpr_ifp)));
3323	}
3324
3325	lck_mtx_unlock(nd6_mutex);
3326	err = nd6_prefix_offlink(pr);
3327	lck_mtx_lock(nd6_mutex);
3328	if (err != 0) {
3329		nd6log((LOG_ERR,
3330		    "%s: failed to make %s/%d offlink on %s, errno=%d\n",
3331		    __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3332		    pr->ndpr_plen, if_name(pr->ndpr_ifp), err));
3333	}
3334
3335	/* Add the entries back */
3336	if (opr != NULL) {
3337		err = nd6_prefix_onlink_scoped(opr, opr->ndpr_ifp->if_index);
3338		if (err != 0) {
3339			nd6log((LOG_ERR,
3340			    "%s: failed to make %s/%d scoped onlink on %s, "
3341			    "errno=%d\n", __func__,
3342			    ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
3343			    opr->ndpr_plen, if_name(opr->ndpr_ifp), err));
3344		}
3345	}
3346
3347	err = nd6_prefix_onlink_scoped(pr, IFSCOPE_NONE);
3348	if (err != 0) {
3349		nd6log((LOG_ERR,
3350		    "%s: failed to make %s/%d onlink on %s, errno=%d\n",
3351		    __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3352		    pr->ndpr_plen, if_name(pr->ndpr_ifp), err));
3353	}
3354
3355	if (err != 0) {
3356		nd6log((LOG_ERR,
3357		    "%s: error promoting %s/%d to %s from %s\n",
3358		    __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3359		    pr->ndpr_plen, if_name(pr->ndpr_ifp),
3360		    (opr != NULL) ? if_name(opr->ndpr_ifp) : "NONE"));
3361	} else {
3362		nd6log2((LOG_INFO,
3363		    "%s: %s/%d promoted, previously on %s\n",
3364		    if_name(pr->ndpr_ifp),
3365		    ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen,
3366		    (opr != NULL) ? if_name(opr->ndpr_ifp) : "NONE"));
3367	}
3368
3369	if (opr != NULL)
3370		NDPR_REMREF(opr);
3371}
3372
3373static int
3374nd6_prefix_onlink_common(struct nd_prefix *pr, boolean_t force_scoped,
3375    unsigned int ifscope)
3376{
3377	struct ifaddr *ifa;
3378	struct ifnet *ifp = pr->ndpr_ifp;
3379	struct sockaddr_in6 mask6, prefix;
3380	struct nd_prefix *opr;
3381	u_int32_t rtflags;
3382	int error = 0, prproxy = 0;
3383	struct rtentry *rt = NULL;
3384
3385	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3386
3387	/* sanity check */
3388	NDPR_LOCK(pr);
3389	if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
3390		nd6log((LOG_ERR,
3391		    "nd6_prefix_onlink: %s/%d on %s scoped=%d is already "
3392		     "on-link\n", ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3393		     pr->ndpr_plen, if_name(pr->ndpr_ifp),
3394		     (pr->ndpr_stateflags & NDPRF_IFSCOPE) ? 1 : 0);
3395		NDPR_UNLOCK(pr);
3396		return (EEXIST));
3397	}
3398	NDPR_UNLOCK(pr);
3399
3400	/*
3401	 * Add the interface route associated with the prefix.  Before
3402	 * installing the route, check if there's the same prefix on another
3403	 * interface, and the prefix has already installed the interface route.
3404	 */
3405	opr = nd6_prefix_equal_lookup(pr, FALSE);
3406	if (opr != NULL)
3407		NDPR_REMREF(opr);
3408
3409	if (!ip6_doscopedroute) {
3410		/* if an interface route already exists, just return */
3411		if (opr != NULL)
3412			return (0);
3413		ifscope = IFSCOPE_NONE;
3414	} else if (!force_scoped) {
3415		/*
3416		 * If a primary/non-scoped interface route already exists,
3417		 * install the new one as a scoped entry.  If the existing
3418		 * interface route is scoped, install new as non-scoped.
3419		 */
3420		ifscope = (opr != NULL) ? ifp->if_index : IFSCOPE_NONE;
3421		opr = nd6_prefix_equal_lookup(pr, TRUE);
3422		if (opr != NULL)
3423			NDPR_REMREF(opr);
3424		else if (ifscope != IFSCOPE_NONE)
3425			ifscope = IFSCOPE_NONE;
3426	}
3427
3428	/*
3429	 * We prefer link-local addresses as the associated interface address.
3430	 */
3431	/* search for a link-local addr */
3432	ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
3433						      IN6_IFF_NOTREADY|
3434						      IN6_IFF_ANYCAST);
3435	if (ifa == NULL) {
3436		struct in6_ifaddr *ia6;
3437		ifnet_lock_shared(ifp);
3438		IFP_TO_IA6(ifp, ia6);
3439		ifnet_lock_done(ifp);
3440		if (ia6 != NULL)
3441			ifa = &ia6->ia_ifa;
3442		/* should we care about ia6_flags? */
3443	}
3444	NDPR_LOCK(pr);
3445	if (ifa == NULL) {
3446		/*
3447		 * This can still happen, when, for example, we receive an RA
3448		 * containing a prefix with the L bit set and the A bit clear,
3449		 * after removing all IPv6 addresses on the receiving
3450		 * interface.  This should, of course, be rare though.
3451		 */
3452		nd6log((LOG_NOTICE,
3453		    "nd6_prefix_onlink: failed to find any ifaddr"
3454		    " to add route for a prefix(%s/%d) on %s\n",
3455		    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3456		    pr->ndpr_plen, if_name(ifp)));
3457		NDPR_UNLOCK(pr);
3458		return (0);
3459	}
3460
3461	/*
3462	 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs.
3463	 * ifa->ifa_rtrequest = nd6_rtrequest;
3464	 */
3465	bzero(&mask6, sizeof(mask6));
3466	mask6.sin6_len = sizeof(mask6);
3467	mask6.sin6_addr = pr->ndpr_mask;
3468	prefix = pr->ndpr_prefix;
3469	if ((rt = pr->ndpr_rt) != NULL)
3470		pr->ndpr_rt = NULL;
3471	NDPR_ADDREF_LOCKED(pr);		/* keep reference for this routine */
3472	NDPR_UNLOCK(pr);
3473
3474	IFA_LOCK_SPIN(ifa);
3475	rtflags = ifa->ifa_flags | RTF_CLONING | RTF_UP;
3476	IFA_UNLOCK(ifa);
3477	if (nd6_need_cache(ifp)) {
3478		/* explicitly set in case ifa_flags does not set the flag. */
3479		rtflags |= RTF_CLONING;
3480	} else {
3481		/*
3482		 * explicitly clear the cloning bit in case ifa_flags sets it.
3483		 */
3484		rtflags &= ~RTF_CLONING;
3485	}
3486
3487	lck_mtx_unlock(nd6_mutex);
3488
3489	if (rt != NULL) {
3490		rtfree(rt);
3491		rt = NULL;
3492	}
3493
3494	error = rtrequest_scoped(RTM_ADD, (struct sockaddr *)&prefix,
3495	    ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt,
3496	    ifscope);
3497
3498	/*
3499	 * Serialize the setting of NDPRF_PRPROXY.
3500	 */
3501	lck_mtx_lock(&proxy6_lock);
3502
3503	if (rt != NULL) {
3504		RT_LOCK(rt);
3505		nd6_rtmsg(RTM_ADD, rt);
3506		RT_UNLOCK(rt);
3507		NDPR_LOCK(pr);
3508	} else {
3509		NDPR_LOCK(pr);
3510		nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a"
3511		    " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx,"
3512		    " scoped=%d, errno = %d\n",
3513		    ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3514		    pr->ndpr_plen, if_name(ifp),
3515		    ip6_sprintf(&((struct sockaddr_in6 *)
3516		    (void *)ifa->ifa_addr)->sin6_addr),
3517		    ip6_sprintf(&mask6.sin6_addr), rtflags,
3518		    (ifscope != IFSCOPE_NONE), error));
3519	}
3520	NDPR_LOCK_ASSERT_HELD(pr);
3521
3522	pr->ndpr_stateflags &= ~(NDPRF_IFSCOPE | NDPRF_PRPROXY);
3523
3524	/*
3525	 * TODO: If the prefix route exists, we should really find it and
3526	 * refer the prefix to it; otherwise ndpr_rt is NULL.
3527	 */
3528	if (rt != NULL || error == EEXIST) {
3529		struct nd_ifinfo *ndi;
3530
3531		VERIFY(pr->ndpr_prproxy_sols_cnt == 0);
3532		VERIFY(RB_EMPTY(&pr->ndpr_prproxy_sols));
3533
3534		lck_rw_lock_shared(nd_if_rwlock);
3535		ndi = ND_IFINFO(ifp);
3536		VERIFY(ndi != NULL && ndi->initialized);
3537		lck_mtx_lock(&ndi->lock);
3538
3539		pr->ndpr_rt = rt;	/* keep reference from rtrequest */
3540		pr->ndpr_stateflags |= NDPRF_ONLINK;
3541		if (ifscope != IFSCOPE_NONE) {
3542			pr->ndpr_stateflags |= NDPRF_IFSCOPE;
3543		} else if ((rtflags & RTF_CLONING) &&
3544		    (ndi->flags & ND6_IFF_PROXY_PREFIXES) &&
3545		    !IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
3546			/*
3547			 * At present, in order for the prefix to be eligible
3548			 * as a proxying/proxied prefix, we require that the
3549			 * prefix route entry be marked as a cloning route with
3550			 * RTF_PROXY; i.e. nd6_need_cache() needs to return
3551			 * true for the interface type, hence the test for
3552			 * RTF_CLONING above.
3553			 */
3554			pr->ndpr_stateflags |= NDPRF_PRPROXY;
3555		}
3556
3557		lck_mtx_unlock(&ndi->lock);
3558		lck_rw_done(nd_if_rwlock);
3559	}
3560
3561	prproxy = (pr->ndpr_stateflags & NDPRF_PRPROXY);
3562	VERIFY(!prproxy || !(pr->ndpr_stateflags & NDPRF_IFSCOPE));
3563	NDPR_UNLOCK(pr);
3564
3565	IFA_REMREF(ifa);
3566
3567	/*
3568	 * If this is an upstream prefix, find the downstream ones (if any)
3569	 * and re-configure their prefix routes accordingly.  Otherwise,
3570	 * this could be potentially be a downstream prefix, and so find the
3571	 * upstream prefix, if any.
3572	 */
3573	nd6_prproxy_prelist_update(pr, prproxy ? pr : NULL);
3574
3575	NDPR_REMREF(pr);	/* release reference for this routine */
3576	lck_mtx_unlock(&proxy6_lock);
3577
3578	lck_mtx_lock(nd6_mutex);
3579
3580	return (error);
3581}
3582
3583int
3584nd6_prefix_onlink(struct nd_prefix *pr)
3585{
3586	return (nd6_prefix_onlink_common(pr, FALSE, IFSCOPE_NONE));
3587}
3588
3589int
3590nd6_prefix_onlink_scoped(struct nd_prefix *pr, unsigned int ifscope)
3591{
3592	return (nd6_prefix_onlink_common(pr, TRUE, ifscope));
3593}
3594
3595int
3596nd6_prefix_offlink(struct nd_prefix *pr)
3597{
3598	int plen, error = 0, prproxy;
3599	struct ifnet *ifp = pr->ndpr_ifp;
3600	struct nd_prefix *opr;
3601	struct sockaddr_in6 sa6, mask6, prefix;
3602	struct rtentry *rt = NULL, *ndpr_rt = NULL;
3603	unsigned int ifscope;
3604
3605	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
3606
3607	/* sanity check */
3608	NDPR_LOCK(pr);
3609	if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
3610		nd6log((LOG_ERR,
3611		    "nd6_prefix_offlink: %s/%d on %s scoped=%d is already "
3612		    "off-link\n", ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3613		    pr->ndpr_plen, if_name(pr->ndpr_ifp),
3614		    (pr->ndpr_stateflags & NDPRF_IFSCOPE) ? 1 : 0));
3615		NDPR_UNLOCK(pr);
3616		return (EEXIST);
3617	}
3618
3619	bzero(&sa6, sizeof(sa6));
3620	sa6.sin6_family = AF_INET6;
3621	sa6.sin6_len = sizeof(sa6);
3622	bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr,
3623	      sizeof(struct in6_addr));
3624	bzero(&mask6, sizeof(mask6));
3625	mask6.sin6_family = AF_INET6;
3626	mask6.sin6_len = sizeof(sa6);
3627	bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr));
3628	prefix = pr->ndpr_prefix;
3629	plen = pr->ndpr_plen;
3630	if ((ndpr_rt = pr->ndpr_rt) != NULL)
3631		pr->ndpr_rt = NULL;
3632	NDPR_ADDREF_LOCKED(pr);		/* keep reference for this routine */
3633	NDPR_UNLOCK(pr);
3634
3635	ifscope = (pr->ndpr_stateflags & NDPRF_IFSCOPE) ?
3636	    ifp->if_index : IFSCOPE_NONE;
3637
3638	error = rtrequest_scoped(RTM_DELETE, (struct sockaddr *)&sa6,
3639	    NULL, (struct sockaddr *)&mask6, 0, &rt, ifscope);
3640
3641	if (rt != NULL) {
3642		/* report the route deletion to the routing socket. */
3643		RT_LOCK(rt);
3644		nd6_rtmsg(RTM_DELETE, rt);
3645		RT_UNLOCK(rt);
3646		rtfree(rt);
3647
3648		/*
3649		 * The following check takes place only when Scoped Routing
3650		 * is not enabled.  There might be the same prefix on another
3651		 * interface, the prefix which could not be on-link just
3652		 * because we have the interface route (see comments in
3653		 * nd6_prefix_onlink).  If there's one, try to make the prefix
3654		 * on-link on the interface.
3655		 */
3656		lck_mtx_lock(nd6_mutex);
3657		opr = nd_prefix.lh_first;
3658		while (opr) {
3659			/* does not apply in the Scoped Routing case */
3660			if (ip6_doscopedroute)
3661				break;
3662
3663			if (opr == pr) {
3664				opr = opr->ndpr_next;
3665				continue;
3666			}
3667
3668			NDPR_LOCK(opr);
3669			if ((opr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
3670				NDPR_UNLOCK(opr);
3671				opr = opr->ndpr_next;
3672				continue;
3673			}
3674			/*
3675			 * KAME specific: detached prefixes should not be
3676			 * on-link.
3677			 */
3678			if ((opr->ndpr_stateflags & NDPRF_DETACHED) != 0) {
3679				NDPR_UNLOCK(opr);
3680				opr = opr->ndpr_next;
3681				continue;
3682			}
3683			if (opr->ndpr_plen == plen &&
3684			    in6_are_prefix_equal(&prefix.sin6_addr,
3685		            &opr->ndpr_prefix.sin6_addr, plen)) {
3686				int e;
3687
3688				NDPR_UNLOCK(opr);
3689				lck_mtx_unlock(nd6_mutex);
3690				if ((e = nd6_prefix_onlink(opr)) != 0) {
3691					nd6log((LOG_ERR,
3692					    "nd6_prefix_offlink: failed to "
3693					    "recover a prefix %s/%d from %s "
3694					    "to %s (errno = %d)\n",
3695					    ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
3696					    opr->ndpr_plen, if_name(ifp),
3697					    if_name(opr->ndpr_ifp), e));
3698				}
3699				lck_mtx_lock(nd6_mutex);
3700				opr = nd_prefix.lh_first;
3701			} else {
3702				NDPR_UNLOCK(opr);
3703				opr = opr->ndpr_next;
3704			}
3705		}
3706		lck_mtx_unlock(nd6_mutex);
3707	} else {
3708		nd6log((LOG_ERR,
3709		    "nd6_prefix_offlink: failed to delete route: "
3710		    "%s/%d on %s, scoped %d, (errno = %d)\n",
3711		    ip6_sprintf(&sa6.sin6_addr), plen, if_name(ifp),
3712		    (ifscope != IFSCOPE_NONE), error));
3713	}
3714
3715	if (ndpr_rt != NULL)
3716		rtfree(ndpr_rt);
3717
3718	lck_mtx_lock(&proxy6_lock);
3719
3720	NDPR_LOCK(pr);
3721	prproxy = (pr->ndpr_stateflags & NDPRF_PRPROXY);
3722	VERIFY(!prproxy || !(pr->ndpr_stateflags & NDPRF_IFSCOPE));
3723	pr->ndpr_stateflags &= ~(NDPRF_ONLINK | NDPRF_IFSCOPE | NDPRF_PRPROXY);
3724	if (pr->ndpr_prproxy_sols_cnt > 0) {
3725		VERIFY(prproxy);
3726		nd6_prproxy_sols_reap(pr);
3727		VERIFY(pr->ndpr_prproxy_sols_cnt == 0);
3728		VERIFY(RB_EMPTY(&pr->ndpr_prproxy_sols));
3729	}
3730	NDPR_UNLOCK(pr);
3731
3732	/*
3733	 * If this was an upstream prefix, find the downstream ones and do
3734	 * some cleanups.  If this was a downstream prefix, the prefix route
3735	 * has been removed from the routing table above, but there may be
3736	 * other tasks to perform.
3737	 */
3738	nd6_prproxy_prelist_update(pr, prproxy ? pr : NULL);
3739
3740	NDPR_REMREF(pr);	/* release reference for this routine */
3741	lck_mtx_unlock(&proxy6_lock);
3742
3743	return (error);
3744}
3745
3746static struct in6_ifaddr *
3747in6_ifadd(
3748	struct nd_prefix *pr,
3749	int mcast)
3750{
3751	struct ifnet *ifp = pr->ndpr_ifp;
3752	struct in6_aliasreq ifra;
3753	struct in6_ifaddr *ia, *ib;
3754	int error, plen0;
3755	int updateflags;
3756	struct in6_addr mask;
3757	int prefixlen;
3758
3759	/*
3760	 * find a link-local address (will be interface ID).
3761	 * Is it really mandatory? Theoretically, a global or a site-local
3762	 * address can be configured without a link-local address, if we
3763	 * have a unique interface identifier...
3764	 *
3765	 * it is not mandatory to have a link-local address, we can generate
3766	 * interface identifier on the fly.  we do this because:
3767	 * (1) it should be the easiest way to find interface identifier.
3768	 * (2) RFC2462 5.4 suggesting the use of the same interface identifier
3769	 * for multiple addresses on a single interface, and possible shortcut
3770	 * of DAD.  we omitted DAD for this reason in the past.
3771	 * (3) a user can prevent autoconfiguration of global address
3772	 * by removing link-local address by hand (this is partly because we
3773	 * don't have other way to control the use of IPv6 on an interface.
3774	 * this has been our design choice - cf. NRL's "ifconfig auto").
3775	 * (4) it is easier to manage when an interface has addresses
3776	 * with the same interface identifier, than to have multiple addresses
3777	 * with different interface identifiers.
3778	 */
3779	ib = in6ifa_ifpforlinklocal(ifp, 0);/* 0 is OK? */
3780	if (ib == NULL)
3781		return (NULL);
3782
3783	IFA_LOCK(&ib->ia_ifa);
3784	NDPR_LOCK(pr);
3785	prefixlen = pr->ndpr_plen;
3786	in6_len2mask(&mask, prefixlen);
3787	plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
3788	/* prefixlen + ifidlen must be equal to 128 */
3789	if (prefixlen != plen0) {
3790		nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s "
3791		    "(prefix=%d ifid=%d)\n",
3792		    if_name(ifp), prefixlen, 128 - plen0));
3793		NDPR_UNLOCK(pr);
3794		IFA_UNLOCK(&ib->ia_ifa);
3795		IFA_REMREF(&ib->ia_ifa);
3796		return (NULL);
3797	}
3798
3799	/* make ifaddr */
3800
3801	bzero(&ifra, sizeof(ifra));
3802	/*
3803	 * in6_update_ifa() does not use ifra_name, but we accurately set it
3804	 * for safety.
3805	 */
3806	strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
3807	ifra.ifra_addr.sin6_family = AF_INET6;
3808	ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
3809	/* prefix */
3810	bcopy(&pr->ndpr_prefix.sin6_addr, &ifra.ifra_addr.sin6_addr,
3811	      sizeof(ifra.ifra_addr.sin6_addr));
3812	ifra.ifra_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
3813	ifra.ifra_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
3814	ifra.ifra_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
3815	ifra.ifra_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
3816
3817	/* interface ID */
3818	ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
3819	    (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
3820	ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
3821	    (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
3822	ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
3823	    (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
3824	ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
3825	    (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
3826
3827	/* new prefix mask. */
3828	ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
3829	ifra.ifra_prefixmask.sin6_family = AF_INET6;
3830	bcopy(&mask, &ifra.ifra_prefixmask.sin6_addr,
3831	      sizeof(ifra.ifra_prefixmask.sin6_addr));
3832
3833	/* lifetimes. */
3834	ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
3835	ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
3836
3837	/* XXX: scope zone ID? */
3838
3839	ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
3840
3841	NDPR_UNLOCK(pr);
3842	IFA_UNLOCK(&ib->ia_ifa);
3843	IFA_REMREF(&ib->ia_ifa);
3844
3845	/*
3846	 * Make sure that we do not have this address already.  This should
3847	 * usually not happen, but we can still see this case, e.g., if we
3848	 * have manually configured the exact address to be configured.
3849	 */
3850	if ((ib = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr)) != NULL) {
3851		IFA_REMREF(&ib->ia_ifa);
3852		/* this should be rare enough to make an explicit log */
3853		log(LOG_INFO, "in6_ifadd: %s is already configured\n",
3854		    ip6_sprintf(&ifra.ifra_addr.sin6_addr));
3855		return (NULL);
3856	}
3857
3858	/*
3859	 * Allocate ifaddr structure, link into chain, etc.
3860	 * If we are going to create a new address upon receiving a multicasted
3861	 * RA, we need to impose a random delay before starting DAD.
3862	 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
3863	 */
3864	updateflags = 0;
3865	if (mcast)
3866		updateflags |= IN6_IFAUPDATE_DADDELAY;
3867	error = in6_update_ifa(ifp, &ifra, NULL, updateflags, M_WAITOK);
3868	if (error != 0) {
3869		nd6log((LOG_ERR,
3870		    "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
3871		    ip6_sprintf(&ifra.ifra_addr.sin6_addr), if_name(ifp),
3872		    error));
3873		return(NULL);	/* ifaddr must not have been allocated. */
3874	}
3875
3876	ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
3877	if (ia == NULL) {
3878		/*
3879		 * XXX: both in6_ifadd and in6_iftmpadd follow this admittedly
3880		 * suboptimal pattern of calling in6_update_ifa to add the
3881		 * interface address, then calling in6ifa_ifpwithaddr to
3882		 * retrieve it from the interface address list after some
3883		 * concurrent kernel thread has first had the opportunity to
3884		 * call in6_purgeaddr and delete everything.
3885		 */
3886		nd6log((LOG_ERR,
3887		    "in6_ifadd: ifa update succeeded, but we got no ifaddr\n"));
3888		return(NULL);
3889	}
3890
3891	in6_post_msg(ifp, KEV_INET6_NEW_RTADV_ADDR, ia);
3892	return(ia);
3893}
3894
3895#define	IA6_NONCONST(i) ((struct in6_ifaddr *)(uintptr_t)(i))
3896
3897int
3898in6_tmpifadd(
3899	const struct in6_ifaddr *ia0, /* corresponding public address */
3900	int forcegen,
3901	int how)
3902{
3903	struct ifnet *ifp = ia0->ia_ifa.ifa_ifp;
3904	struct in6_ifaddr *ia, *newia;
3905	struct in6_aliasreq ifra;
3906	int i, error;
3907	int trylimit = 3;	/* XXX: adhoc value */
3908	int updateflags;
3909	u_int32_t randid[2];
3910	time_t vltime0, pltime0;
3911	struct timeval timenow;
3912	struct in6_addr addr;
3913	struct nd_prefix *ndpr;
3914
3915	getmicrotime(&timenow);
3916
3917	bzero(&ifra, sizeof(ifra));
3918	strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
3919	IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
3920	ifra.ifra_addr = ia0->ia_addr;
3921	/* copy prefix mask */
3922	ifra.ifra_prefixmask = ia0->ia_prefixmask;
3923	/* clear the old IFID */
3924	for (i = 0; i < 4; i++) {
3925		ifra.ifra_addr.sin6_addr.s6_addr32[i]
3926			&= ifra.ifra_prefixmask.sin6_addr.s6_addr32[i];
3927	}
3928	addr = ia0->ia_addr.sin6_addr;
3929	IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
3930
3931again:
3932	in6_get_tmpifid(ifp, (u_int8_t *)randid,
3933	    (const u_int8_t *)&addr.s6_addr[8], forcegen);
3934
3935	ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
3936	    (randid[0] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[2]));
3937	ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
3938	    (randid[1] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[3]));
3939
3940	/*
3941	 * in6_get_tmpifid() quite likely provided a unique interface ID.
3942	 * However, we may still have a chance to see collision, because
3943	 * there may be a time lag between generation of the ID and generation
3944	 * of the address.  So, we'll do one more sanity check.
3945	 */
3946	if ((ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr)) != NULL) {
3947		IFA_REMREF(&ia->ia_ifa);
3948		if (trylimit-- == 0) {
3949			nd6log((LOG_NOTICE, "in6_tmpifadd: failed to find "
3950			    "a unique random IFID\n"));
3951			return(EEXIST);
3952		}
3953		forcegen = 1;
3954		goto again;
3955	}
3956
3957	/*
3958	 * The Valid Lifetime is the lower of the Valid Lifetime of the
3959         * public address or TEMP_VALID_LIFETIME.
3960	 * The Preferred Lifetime is the lower of the Preferred Lifetime
3961         * of the public address or TEMP_PREFERRED_LIFETIME -
3962         * DESYNC_FACTOR.
3963	 */
3964	IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
3965	vltime0 = IFA6_IS_INVALID(ia0)
3966	    ? 0
3967	    : (ia0->ia6_lifetime.ia6t_vltime -
3968	      (timenow.tv_sec - ia0->ia6_updatetime));
3969	if (vltime0 > ip6_temp_valid_lifetime)
3970		vltime0 = ip6_temp_valid_lifetime;
3971	pltime0 = IFA6_IS_DEPRECATED(ia0)
3972	    ? 0
3973	    : (ia0->ia6_lifetime.ia6t_pltime -
3974	      (timenow.tv_sec - ia0->ia6_updatetime));
3975	if (pltime0 > ip6_temp_preferred_lifetime - ip6_desync_factor)
3976		pltime0 = ip6_temp_preferred_lifetime - ip6_desync_factor;
3977	ifra.ifra_lifetime.ia6t_vltime = vltime0;
3978	ifra.ifra_lifetime.ia6t_pltime = pltime0;
3979	IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
3980	/*
3981	 * A temporary address is created only if this calculated Preferred
3982	 * Lifetime is greater than REGEN_ADVANCE time units.
3983	 */
3984	if (ifra.ifra_lifetime.ia6t_pltime <= ip6_temp_regen_advance)
3985		return(0);
3986
3987	/* XXX: scope zone ID? */
3988
3989	ifra.ifra_flags |= (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY);
3990
3991	/* allocate ifaddr structure, link into chain, etc. */
3992	updateflags = 0;
3993
3994	if (how)
3995		updateflags |= IN6_IFAUPDATE_DADDELAY;
3996
3997	if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags, how)) != 0)
3998		return (error);
3999
4000	newia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
4001	if (newia == NULL) {
4002		/*
4003		 * XXX: both in6_ifadd and in6_iftmpadd follow this admittedly
4004		 * suboptimal pattern of calling in6_update_ifa to add the
4005		 * interface address, then calling in6ifa_ifpwithaddr to
4006		 * retrieve it from the interface address list after some
4007		 * concurrent kernel thread has first had the opportunity to
4008		 * call in6_purgeaddr and delete everything.
4009		 */
4010		nd6log((LOG_ERR,
4011		    "in6_tmpifadd: ifa update succeeded, but we got "
4012		    "no ifaddr\n"));
4013		return(EINVAL);
4014	}
4015	IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
4016	ndpr = ia0->ia6_ndpr;
4017	if (ndpr == NULL) {
4018		/*
4019		 * We lost the race with another thread that has purged
4020		 * ia0 address; in this case, purge the tmp addr as well.
4021		 */
4022		nd6log((LOG_ERR, "in6_tmpifadd: no public address\n"));
4023		VERIFY(!(ia0->ia6_flags & IN6_IFF_AUTOCONF));
4024		IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4025		in6_purgeaddr(&newia->ia_ifa);
4026		IFA_REMREF(&newia->ia_ifa);
4027		return (EADDRNOTAVAIL);
4028	}
4029	NDPR_ADDREF(ndpr);	/* for us */
4030	IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4031	IFA_LOCK(&newia->ia_ifa);
4032	if (newia->ia6_ndpr != NULL) {
4033		NDPR_LOCK(newia->ia6_ndpr);
4034		VERIFY(newia->ia6_ndpr->ndpr_addrcnt != 0);
4035		newia->ia6_ndpr->ndpr_addrcnt--;
4036		NDPR_UNLOCK(newia->ia6_ndpr);
4037		NDPR_REMREF(newia->ia6_ndpr);	/* release addr reference */
4038	}
4039	newia->ia6_ndpr = ndpr;
4040	NDPR_LOCK(newia->ia6_ndpr);
4041	newia->ia6_ndpr->ndpr_addrcnt++;
4042	VERIFY(newia->ia6_ndpr->ndpr_addrcnt != 0);
4043	NDPR_ADDREF_LOCKED(newia->ia6_ndpr);	/* for addr reference */
4044	NDPR_UNLOCK(newia->ia6_ndpr);
4045	IFA_UNLOCK(&newia->ia_ifa);
4046	/*
4047	 * A newly added address might affect the status of other addresses.
4048	 * XXX: when the temporary address is generated with a new public
4049	 * address, the onlink check is redundant.  However, it would be safe
4050	 * to do the check explicitly everywhere a new address is generated,
4051	 * and, in fact, we surely need the check when we create a new
4052	 * temporary address due to deprecation of an old temporary address.
4053	 */
4054	lck_mtx_lock(nd6_mutex);
4055	pfxlist_onlink_check();
4056	lck_mtx_unlock(nd6_mutex);
4057	IFA_REMREF(&newia->ia_ifa);
4058
4059	/* remove our reference */
4060	NDPR_REMREF(ndpr);
4061
4062	return(0);
4063}
4064#undef IA6_NONCONST
4065
4066int
4067in6_init_prefix_ltimes(struct nd_prefix *ndpr)
4068{
4069	struct timeval timenow;
4070
4071	NDPR_LOCK_ASSERT_HELD(ndpr);
4072
4073	getmicrotime(&timenow);
4074	/* check if preferred lifetime > valid lifetime.  RFC2462 5.5.3 (c) */
4075	if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) {
4076		nd6log((LOG_INFO, "in6_init_prefix_ltimes: preferred lifetime"
4077		    "(%d) is greater than valid lifetime(%d)\n",
4078		    (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime));
4079		return (EINVAL);
4080	}
4081	if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
4082		ndpr->ndpr_preferred = 0;
4083	else
4084		ndpr->ndpr_preferred = timenow.tv_sec + ndpr->ndpr_pltime;
4085	if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
4086		ndpr->ndpr_expire = 0;
4087	else
4088		ndpr->ndpr_expire = timenow.tv_sec + ndpr->ndpr_vltime;
4089
4090	return 0;
4091}
4092
4093static void
4094in6_init_address_ltimes(__unused struct nd_prefix *new,
4095    struct in6_addrlifetime *lt6, boolean_t is_temporary)
4096{
4097	struct timeval timenow;
4098
4099	getmicrotime(&timenow);
4100	/* Valid lifetime must not be updated unless explicitly specified. */
4101	/* init ia6t_expire */
4102	if (!is_temporary && lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
4103		lt6->ia6t_expire = 0;
4104	else {
4105		lt6->ia6t_expire = timenow.tv_sec;
4106		lt6->ia6t_expire += lt6->ia6t_vltime;
4107	}
4108
4109	/* init ia6t_preferred */
4110	if (!is_temporary && lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
4111		lt6->ia6t_preferred = 0;
4112	else {
4113		lt6->ia6t_preferred = timenow.tv_sec;
4114		lt6->ia6t_preferred += lt6->ia6t_pltime;
4115	}
4116}
4117
4118/*
4119 * Delete all the routing table entries that use the specified gateway.
4120 * XXX: this function causes search through all entries of routing table, so
4121 * it shouldn't be called when acting as a router.
4122 */
4123void
4124rt6_flush(
4125	struct in6_addr *gateway,
4126	struct ifnet *ifp)
4127{
4128	struct radix_node_head *rnh = rt_tables[AF_INET6];
4129
4130	/* We'll care only link-local addresses */
4131	if (!IN6_IS_ADDR_LINKLOCAL(gateway)) {
4132		return;
4133	}
4134	lck_mtx_lock(rnh_lock);
4135	/* XXX: hack for KAME's link-local address kludge */
4136	gateway->s6_addr16[1] = htons(ifp->if_index);
4137
4138	rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway);
4139	lck_mtx_unlock(rnh_lock);
4140}
4141
4142static int
4143rt6_deleteroute(
4144	struct radix_node *rn,
4145	void *arg)
4146{
4147	struct rtentry *rt = (struct rtentry *)rn;
4148	struct in6_addr *gate = (struct in6_addr *)arg;
4149
4150	lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
4151
4152	RT_LOCK(rt);
4153	if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) {
4154		RT_UNLOCK(rt);
4155		return(0);
4156	}
4157
4158	if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) {
4159		RT_UNLOCK(rt);
4160		return(0);
4161	}
4162	/*
4163	 * Do not delete a static route.
4164	 * XXX: this seems to be a bit ad-hoc. Should we consider the
4165	 * 'cloned' bit instead?
4166	 */
4167	if ((rt->rt_flags & RTF_STATIC) != 0) {
4168		RT_UNLOCK(rt);
4169		return(0);
4170	}
4171	/*
4172	 * We delete only host route. This means, in particular, we don't
4173	 * delete default route.
4174	 */
4175	if ((rt->rt_flags & RTF_HOST) == 0) {
4176		RT_UNLOCK(rt);
4177		return(0);
4178	}
4179
4180	/*
4181	 * Safe to drop rt_lock and use rt_key, rt_gateway, since holding
4182	 * rnh_lock here prevents another thread from calling rt_setgate()
4183	 * on this route.
4184	 */
4185	RT_UNLOCK(rt);
4186	return (rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
4187	    rt_mask(rt), rt->rt_flags, 0));
4188}
4189
4190int
4191nd6_setdefaultiface(
4192	int ifindex)
4193{
4194	int error = 0;
4195	ifnet_t def_ifp = NULL;
4196
4197	lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
4198
4199	ifnet_head_lock_shared();
4200	if (ifindex < 0 || if_index < ifindex) {
4201		ifnet_head_done();
4202		return(EINVAL);
4203	}
4204	def_ifp = ifindex2ifnet[ifindex];
4205	ifnet_head_done();
4206
4207	lck_mtx_lock(nd6_mutex);
4208	if (nd6_defifindex != ifindex) {
4209		struct ifnet *odef_ifp = nd6_defifp;
4210
4211		nd6_defifindex = ifindex;
4212		if (nd6_defifindex > 0)
4213			nd6_defifp = def_ifp;
4214		else
4215			nd6_defifp = NULL;
4216
4217		if (nd6_defifp != NULL)
4218			nd6log((LOG_INFO, "%s: is now the default "
4219			    "interface (was %s)\n", if_name(nd6_defifp),
4220			    odef_ifp != NULL ? if_name(odef_ifp) : "NONE"));
4221		else
4222			nd6log((LOG_INFO, "No default interface set\n"));
4223
4224		/*
4225		 * If the Default Router List is empty, install a route
4226		 * to the specified interface as default or remove the default
4227		 * route when the default interface becomes canceled.
4228		 * The check for the queue is actually redundant, but
4229		 * we do this here to avoid re-install the default route
4230		 * if the list is NOT empty.
4231		 */
4232		if (ip6_doscopedroute || TAILQ_FIRST(&nd_defrouter) == NULL) {
4233			defrtrlist_sync(nd6_defifp);
4234			nd6_prefix_sync(nd6_defifp);
4235		}
4236
4237		/*
4238		 * Our current implementation assumes one-to-one maping between
4239		 * interfaces and links, so it would be natural to use the
4240		 * default interface as the default link.
4241		 */
4242		scope6_setdefault(nd6_defifp);
4243	}
4244	lck_mtx_unlock(nd6_mutex);
4245
4246	return(error);
4247}
4248