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