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