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