xref: /xnu-10002.81.5/bsd/netinet6/in6.c (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
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 
58 /*
59  * Copyright (c) 1982, 1986, 1991, 1993
60  *	The Regents of the University of California.  All rights reserved.
61  *
62  * Redistribution and use in source and binary forms, with or without
63  * modification, are permitted provided that the following conditions
64  * are met:
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer.
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in the
69  *    documentation and/or other materials provided with the distribution.
70  * 3. All advertising materials mentioning features or use of this software
71  *    must display the following acknowledgement:
72  *	This product includes software developed by the University of
73  *	California, Berkeley and its contributors.
74  * 4. Neither the name of the University nor the names of its contributors
75  *    may be used to endorse or promote products derived from this software
76  *    without specific prior written permission.
77  *
78  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88  * SUCH DAMAGE.
89  *
90  *	@(#)in.c	8.2 (Berkeley) 11/15/93
91  */
92 
93 
94 #include <sys/param.h>
95 #include <sys/ioctl.h>
96 #include <sys/errno.h>
97 #include <sys/malloc.h>
98 #include <sys/socket.h>
99 #include <sys/socketvar.h>
100 #include <sys/sockio.h>
101 #include <sys/systm.h>
102 #include <sys/time.h>
103 #include <sys/kernel.h>
104 #include <sys/syslog.h>
105 #include <sys/kern_event.h>
106 #include <sys/mcache.h>
107 #include <sys/protosw.h>
108 
109 #include <kern/locks.h>
110 #include <kern/zalloc.h>
111 #include <libkern/OSAtomic.h>
112 #include <machine/machine_routines.h>
113 #include <mach/boolean.h>
114 
115 #include <net/if.h>
116 #include <net/if_types.h>
117 #include <net/if_var.h>
118 #include <net/route.h>
119 #include <net/if_dl.h>
120 #include <net/kpi_protocol.h>
121 #include <net/nwk_wq.h>
122 
123 #include <netinet/in.h>
124 #include <netinet/in_var.h>
125 #include <netinet/if_ether.h>
126 #include <netinet/in_systm.h>
127 #include <netinet/ip.h>
128 #include <netinet/in_pcb.h>
129 #include <netinet/icmp6.h>
130 #include <netinet/tcp.h>
131 #include <netinet/tcp_seq.h>
132 #include <netinet/tcp_var.h>
133 
134 #include <netinet6/nd6.h>
135 #include <netinet/ip6.h>
136 #include <netinet6/ip6_var.h>
137 #include <netinet6/mld6_var.h>
138 #include <netinet6/in6_ifattach.h>
139 #include <netinet6/scope6_var.h>
140 #include <netinet6/in6_var.h>
141 #include <netinet6/in6_pcb.h>
142 
143 #include <net/net_osdep.h>
144 
145 #include <net/dlil.h>
146 
147 #if PF
148 #include <net/pfvar.h>
149 #endif /* PF */
150 
151 /*
152  * Definitions of some costant IP6 addresses.
153  */
154 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
155 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
156 const struct in6_addr in6addr_nodelocal_allnodes =
157     IN6ADDR_NODELOCAL_ALLNODES_INIT;
158 const struct in6_addr in6addr_linklocal_allnodes =
159     IN6ADDR_LINKLOCAL_ALLNODES_INIT;
160 const struct in6_addr in6addr_linklocal_allrouters =
161     IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
162 const struct in6_addr in6addr_linklocal_allv2routers =
163     IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT;
164 const struct in6_addr in6addr_multicast_prefix =
165     IN6ADDR_MULTICAST_PREFIX;
166 
167 const struct in6_addr in6mask0 = IN6MASK0;
168 const struct in6_addr in6mask7 = IN6MASK7;
169 const struct in6_addr in6mask8 = IN6MASK8;
170 const struct in6_addr in6mask16 = IN6MASK16;
171 const struct in6_addr in6mask32 = IN6MASK32;
172 const struct in6_addr in6mask64 = IN6MASK64;
173 const struct in6_addr in6mask96 = IN6MASK96;
174 const struct in6_addr in6mask128 = IN6MASK128;
175 
176 const struct sockaddr_in6 sa6_any = {
177 	.sin6_len = sizeof(sa6_any),
178 	.sin6_family = AF_INET6,
179 	.sin6_port = 0,
180 	.sin6_flowinfo = 0,
181 	.sin6_addr = IN6ADDR_ANY_INIT,
182 	.sin6_scope_id = 0
183 };
184 
185 static int in6ctl_associd(struct socket *, u_long, caddr_t);
186 static int in6ctl_connid(struct socket *, u_long, caddr_t);
187 static int in6ctl_conninfo(struct socket *, u_long, caddr_t);
188 static int in6ctl_llstart(struct ifnet *, u_long, caddr_t);
189 static int in6ctl_llstop(struct ifnet *);
190 static int in6ctl_cgastart(struct ifnet *, u_long, caddr_t);
191 static int in6ctl_gifaddr(struct ifnet *, struct in6_ifaddr *, u_long,
192     struct in6_ifreq *);
193 static int in6ctl_gifstat(struct ifnet *, u_long, struct in6_ifreq *);
194 static int in6ctl_alifetime(struct in6_ifaddr *, u_long, struct in6_ifreq *,
195     boolean_t);
196 static int in6ctl_aifaddr(struct ifnet *, struct in6_aliasreq *);
197 static void in6ctl_difaddr(struct ifnet *, struct in6_ifaddr *);
198 static int in6_autoconf(struct ifnet *, int);
199 static int in6_setrouter(struct ifnet *, ipv6_router_mode_t);
200 static int in6_ifinit(struct ifnet *, struct in6_ifaddr *, int);
201 static int in6_ifaupdate_aux(struct in6_ifaddr *, struct ifnet *, int);
202 static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
203 static struct in6_ifaddr *in6_ifaddr_alloc(zalloc_flags_t);
204 static void in6_ifaddr_attached(struct ifaddr *);
205 static void in6_ifaddr_detached(struct ifaddr *);
206 static void in6_ifaddr_free(struct ifaddr *);
207 static void in6_ifaddr_trace(struct ifaddr *, int);
208 #if defined(__LP64__)
209 static void in6_cgareq_32_to_64(const struct in6_cgareq_32 *,
210     struct in6_cgareq_64 *);
211 #else
212 static void in6_cgareq_64_to_32(const struct in6_cgareq_64 *,
213     struct in6_cgareq_32 *);
214 #endif
215 static struct in6_aliasreq *in6_aliasreq_to_native(void *, int,
216     struct in6_aliasreq *);
217 static int in6_to_kamescope(struct sockaddr_in6 *, struct ifnet *);
218 static int in6_getassocids(struct socket *, uint32_t *, user_addr_t);
219 static int in6_getconnids(struct socket *, sae_associd_t, uint32_t *,
220     user_addr_t);
221 
222 static void in6_if_up_dad_start(struct ifnet *);
223 
224 #define IA6_HASH_INIT(ia) {                                      \
225 	(ia)->ia6_hash.tqe_next = (void *)(uintptr_t)-1;         \
226 	(ia)->ia6_hash.tqe_prev = (void *)(uintptr_t)-1;         \
227 }
228 
229 #define IA6_IS_HASHED(ia)                                        \
230 	(!((ia)->ia6_hash.tqe_next == (void *)(uintptr_t)-1 ||   \
231 	(ia)->ia6_hash.tqe_prev == (void *)(uintptr_t)-1))
232 
233 static void in6_iahash_remove(struct in6_ifaddr *);
234 static void in6_iahash_insert(struct in6_ifaddr *);
235 static void in6_iahash_insert_ptp(struct in6_ifaddr *);
236 
237 #define IN6IFA_TRACE_HIST_SIZE  32      /* size of trace history */
238 
239 /* For gdb */
240 __private_extern__ unsigned int in6ifa_trace_hist_size = IN6IFA_TRACE_HIST_SIZE;
241 
242 struct in6_ifaddr_dbg {
243 	struct in6_ifaddr       in6ifa;                 /* in6_ifaddr */
244 	struct in6_ifaddr       in6ifa_old;             /* saved in6_ifaddr */
245 	u_int16_t               in6ifa_refhold_cnt;     /* # of IFA_ADDREF */
246 	u_int16_t               in6ifa_refrele_cnt;     /* # of IFA_REMREF */
247 	/*
248 	 * Alloc and free callers.
249 	 */
250 	ctrace_t                in6ifa_alloc;
251 	ctrace_t                in6ifa_free;
252 	/*
253 	 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
254 	 */
255 	ctrace_t                in6ifa_refhold[IN6IFA_TRACE_HIST_SIZE];
256 	ctrace_t                in6ifa_refrele[IN6IFA_TRACE_HIST_SIZE];
257 	/*
258 	 * Trash list linkage
259 	 */
260 	TAILQ_ENTRY(in6_ifaddr_dbg) in6ifa_trash_link;
261 };
262 
263 /* List of trash in6_ifaddr entries protected by in6ifa_trash_lock */
264 static TAILQ_HEAD(, in6_ifaddr_dbg) in6ifa_trash_head;
265 static LCK_MTX_DECLARE_ATTR(in6ifa_trash_lock, &ifa_mtx_grp, &ifa_mtx_attr);
266 
267 #if DEBUG
268 static unsigned int in6ifa_debug = 1;           /* debugging (enabled) */
269 #else
270 static unsigned int in6ifa_debug;               /* debugging (disabled) */
271 #endif /* !DEBUG */
272 static struct zone *in6ifa_zone;                /* zone for in6_ifaddr */
273 #define IN6IFA_ZONE_NAME        "in6_ifaddr"    /* zone name */
274 
275 struct eventhandler_lists_ctxt in6_evhdlr_ctxt;
276 struct eventhandler_lists_ctxt in6_clat46_evhdlr_ctxt;
277 /*
278  * Subroutine for in6_ifaddloop() and in6_ifremloop().
279  * This routine does actual work.
280  */
281 static void
in6_ifloop_request(int cmd,struct ifaddr * ifa)282 in6_ifloop_request(int cmd, struct ifaddr *ifa)
283 {
284 	struct sockaddr_in6 all1_sa;
285 	struct rtentry *nrt = NULL;
286 	int e;
287 
288 	bzero(&all1_sa, sizeof(all1_sa));
289 	all1_sa.sin6_family = AF_INET6;
290 	all1_sa.sin6_len = sizeof(struct sockaddr_in6);
291 	all1_sa.sin6_addr = in6mask128;
292 
293 	/*
294 	 * We specify the address itself as the gateway, and set the
295 	 * RTF_LLINFO flag, so that the corresponding host route would have
296 	 * the flag, and thus applications that assume traditional behavior
297 	 * would be happy.  Note that we assume the caller of the function
298 	 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
299 	 * which changes the outgoing interface to the loopback interface.
300 	 * ifa_addr for INET6 is set once during init; no need to hold lock.
301 	 */
302 	lck_mtx_lock(rnh_lock);
303 	e = rtrequest_locked(cmd, ifa->ifa_addr, ifa->ifa_addr,
304 	    (struct sockaddr *)&all1_sa, RTF_UP | RTF_HOST | RTF_LLINFO, &nrt);
305 	if (e != 0) {
306 		log(LOG_ERR, "in6_ifloop_request: "
307 		    "%s operation failed for %s (errno=%d)\n",
308 		    cmd == RTM_ADD ? "ADD" : "DELETE",
309 		    ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
310 		    e);
311 	}
312 
313 	if (nrt != NULL) {
314 		RT_LOCK(nrt);
315 	}
316 	/*
317 	 * Make sure rt_ifa be equal to IFA, the second argument of the
318 	 * function.
319 	 * We need this because when we refer to rt_ifa->ia6_flags in
320 	 * ip6_input, we assume that the rt_ifa points to the address instead
321 	 * of the loopback address.
322 	 */
323 	if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
324 		rtsetifa(nrt, ifa);
325 	}
326 
327 	/*
328 	 * Report the addition/removal of the address to the routing socket.
329 	 * XXX: since we called rtinit for a p2p interface with a destination,
330 	 *   we end up reporting twice in such a case.  Should we rather
331 	 *   omit the second report?
332 	 */
333 	if (nrt != NULL) {
334 		rt_newaddrmsg((u_char)cmd, ifa, e, nrt);
335 		if (cmd == RTM_DELETE) {
336 			RT_UNLOCK(nrt);
337 			rtfree_locked(nrt);
338 		} else {
339 			/* the cmd must be RTM_ADD here */
340 			RT_REMREF_LOCKED(nrt);
341 			RT_UNLOCK(nrt);
342 		}
343 	}
344 	lck_mtx_unlock(rnh_lock);
345 }
346 
347 /*
348  * Add ownaddr as loopback rtentry.  We previously add the route only if
349  * necessary (ex. on a p2p link).  However, since we now manage addresses
350  * separately from prefixes, we should always add the route.  We can't
351  * rely on the cloning mechanism from the corresponding interface route
352  * any more.
353  */
354 static void
in6_ifaddloop(struct ifaddr * ifa)355 in6_ifaddloop(struct ifaddr *ifa)
356 {
357 	struct rtentry *rt;
358 
359 	/*
360 	 * If there is no loopback entry, allocate one.  ifa_addr for
361 	 * INET6 is set once during init; no need to hold lock.
362 	 */
363 	rt = rtalloc1(ifa->ifa_addr, 0, 0);
364 	if (rt != NULL) {
365 		RT_LOCK(rt);
366 	}
367 	if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
368 	    (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
369 		if (rt != NULL) {
370 			RT_REMREF_LOCKED(rt);
371 			RT_UNLOCK(rt);
372 		}
373 		in6_ifloop_request(RTM_ADD, ifa);
374 	} else if (rt != NULL) {
375 		RT_REMREF_LOCKED(rt);
376 		RT_UNLOCK(rt);
377 	}
378 }
379 
380 /*
381  * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
382  * if it exists.
383  */
384 static void
in6_ifremloop(struct ifaddr * ifa)385 in6_ifremloop(struct ifaddr *ifa)
386 {
387 	struct in6_ifaddr *ia;
388 	struct rtentry *rt;
389 	int ia_count = 0;
390 
391 	/*
392 	 * Some of BSD variants do not remove cloned routes
393 	 * from an interface direct route, when removing the direct route
394 	 * (see comments in net/net_osdep.h).  Even for variants that do remove
395 	 * cloned routes, they could fail to remove the cloned routes when
396 	 * we handle multple addresses that share a common prefix.
397 	 * So, we should remove the route corresponding to the deleted address
398 	 * regardless of the result of in6_is_ifloop_auto().
399 	 */
400 
401 	/*
402 	 * Delete the entry only if exact one ifa exists.  More than one ifa
403 	 * can exist if we assign a same single address to multiple
404 	 * (probably p2p) interfaces.
405 	 * XXX: we should avoid such a configuration in IPv6...
406 	 */
407 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
408 	TAILQ_FOREACH(ia, IN6ADDR_HASH(IFA_IN6(ifa)), ia6_hash) {
409 		IFA_LOCK(&ia->ia_ifa);
410 		if (in6_are_addr_equal_scoped(IFA_IN6(ifa), &ia->ia_addr.sin6_addr, IFA_SIN6(ifa)->sin6_scope_id, ia->ia_addr.sin6_scope_id)) {
411 			ia_count++;
412 			if (ia_count > 1) {
413 				IFA_UNLOCK(&ia->ia_ifa);
414 				break;
415 			}
416 		}
417 		IFA_UNLOCK(&ia->ia_ifa);
418 	}
419 	lck_rw_done(&in6_ifaddr_rwlock);
420 
421 	if (ia_count == 1) {
422 		/*
423 		 * Before deleting, check if a corresponding loopbacked host
424 		 * route surely exists.  With this check, we can avoid to
425 		 * delete an interface direct route whose destination is same
426 		 * as the address being removed.  This can happen when removing
427 		 * a subnet-router anycast address on an interface attahced
428 		 * to a shared medium.  ifa_addr for INET6 is set once during
429 		 * init; no need to hold lock.
430 		 */
431 		rt = rtalloc1(ifa->ifa_addr, 0, 0);
432 		if (rt != NULL) {
433 			RT_LOCK(rt);
434 			if ((rt->rt_flags & RTF_HOST) != 0 &&
435 			    (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
436 				RT_REMREF_LOCKED(rt);
437 				RT_UNLOCK(rt);
438 				in6_ifloop_request(RTM_DELETE, ifa);
439 			} else {
440 				RT_UNLOCK(rt);
441 			}
442 		}
443 	}
444 }
445 
446 
447 int
in6_mask2len(struct in6_addr * mask,u_char * lim0)448 in6_mask2len(struct in6_addr *mask, u_char *lim0)
449 {
450 	int x = 0, y;
451 	u_char *lim = lim0, *p;
452 
453 	/* ignore the scope_id part */
454 	if (lim0 == NULL || lim0 - (u_char *)mask > sizeof(*mask)) {
455 		lim = (u_char *)mask + sizeof(*mask);
456 	}
457 	for (p = (u_char *)mask; p < lim; x++, p++) {
458 		if (*p != 0xff) {
459 			break;
460 		}
461 	}
462 	y = 0;
463 	if (p < lim) {
464 		for (y = 0; y < 8; y++) {
465 			if ((*p & (0x80 >> y)) == 0) {
466 				break;
467 			}
468 		}
469 	}
470 
471 	/*
472 	 * when the limit pointer is given, do a stricter check on the
473 	 * remaining bits.
474 	 */
475 	if (p < lim) {
476 		if (y != 0 && (*p & (0x00ff >> y)) != 0) {
477 			return -1;
478 		}
479 		for (p = p + 1; p < lim; p++) {
480 			if (*p != 0) {
481 				return -1;
482 			}
483 		}
484 	}
485 
486 	return x * 8 + y;
487 }
488 
489 void
in6_len2mask(struct in6_addr * mask,int len)490 in6_len2mask(struct in6_addr *mask, int len)
491 {
492 	int i;
493 
494 	bzero(mask, sizeof(*mask));
495 	for (i = 0; i < len / 8; i++) {
496 		mask->s6_addr8[i] = 0xff;
497 	}
498 	if (len % 8) {
499 		mask->s6_addr8[i] = (0xff00 >> (len % 8)) & 0xff;
500 	}
501 }
502 
503 void
in6_aliasreq_64_to_32(struct in6_aliasreq_64 * src,struct in6_aliasreq_32 * dst)504 in6_aliasreq_64_to_32(struct in6_aliasreq_64 *src, struct in6_aliasreq_32 *dst)
505 {
506 	bzero(dst, sizeof(*dst));
507 	bcopy(src->ifra_name, dst->ifra_name, sizeof(dst->ifra_name));
508 	dst->ifra_addr = src->ifra_addr;
509 	dst->ifra_dstaddr = src->ifra_dstaddr;
510 	dst->ifra_prefixmask = src->ifra_prefixmask;
511 	dst->ifra_flags = src->ifra_flags;
512 	dst->ifra_lifetime.ia6t_expire = (u_int32_t)src->ifra_lifetime.ia6t_expire;
513 	dst->ifra_lifetime.ia6t_preferred = (u_int32_t)src->ifra_lifetime.ia6t_preferred;
514 	dst->ifra_lifetime.ia6t_vltime = src->ifra_lifetime.ia6t_vltime;
515 	dst->ifra_lifetime.ia6t_pltime = src->ifra_lifetime.ia6t_pltime;
516 }
517 
518 void
in6_aliasreq_32_to_64(struct in6_aliasreq_32 * src,struct in6_aliasreq_64 * dst)519 in6_aliasreq_32_to_64(struct in6_aliasreq_32 *src, struct in6_aliasreq_64 *dst)
520 {
521 	bzero(dst, sizeof(*dst));
522 	bcopy(src->ifra_name, dst->ifra_name, sizeof(dst->ifra_name));
523 	dst->ifra_addr = src->ifra_addr;
524 	dst->ifra_dstaddr = src->ifra_dstaddr;
525 	dst->ifra_prefixmask = src->ifra_prefixmask;
526 	dst->ifra_flags = src->ifra_flags;
527 	dst->ifra_lifetime.ia6t_expire = src->ifra_lifetime.ia6t_expire;
528 	dst->ifra_lifetime.ia6t_preferred = src->ifra_lifetime.ia6t_preferred;
529 	dst->ifra_lifetime.ia6t_vltime = src->ifra_lifetime.ia6t_vltime;
530 	dst->ifra_lifetime.ia6t_pltime = src->ifra_lifetime.ia6t_pltime;
531 }
532 
533 #if defined(__LP64__)
534 static void
in6_cgareq_32_to_64(const struct in6_cgareq_32 * src,struct in6_cgareq_64 * dst)535 in6_cgareq_32_to_64(const struct in6_cgareq_32 *src,
536     struct in6_cgareq_64 *dst)
537 {
538 	bzero(dst, sizeof(*dst));
539 	bcopy(src->cgar_name, dst->cgar_name, sizeof(dst->cgar_name));
540 	dst->cgar_flags = src->cgar_flags;
541 	bcopy(src->cgar_cgaprep.cga_modifier.octets,
542 	    dst->cgar_cgaprep.cga_modifier.octets,
543 	    sizeof(dst->cgar_cgaprep.cga_modifier.octets));
544 	dst->cgar_cgaprep.cga_security_level =
545 	    src->cgar_cgaprep.cga_security_level;
546 	dst->cgar_lifetime.ia6t_expire = src->cgar_lifetime.ia6t_expire;
547 	dst->cgar_lifetime.ia6t_preferred = src->cgar_lifetime.ia6t_preferred;
548 	dst->cgar_lifetime.ia6t_vltime = src->cgar_lifetime.ia6t_vltime;
549 	dst->cgar_lifetime.ia6t_pltime = src->cgar_lifetime.ia6t_pltime;
550 	dst->cgar_collision_count = src->cgar_collision_count;
551 }
552 #endif
553 
554 #if !defined(__LP64__)
555 static void
in6_cgareq_64_to_32(const struct in6_cgareq_64 * src,struct in6_cgareq_32 * dst)556 in6_cgareq_64_to_32(const struct in6_cgareq_64 *src,
557     struct in6_cgareq_32 *dst)
558 {
559 	bzero(dst, sizeof(*dst));
560 	bcopy(src->cgar_name, dst->cgar_name, sizeof(dst->cgar_name));
561 	dst->cgar_flags = src->cgar_flags;
562 	bcopy(src->cgar_cgaprep.cga_modifier.octets,
563 	    dst->cgar_cgaprep.cga_modifier.octets,
564 	    sizeof(dst->cgar_cgaprep.cga_modifier.octets));
565 	dst->cgar_cgaprep.cga_security_level =
566 	    src->cgar_cgaprep.cga_security_level;
567 	dst->cgar_lifetime.ia6t_expire = (u_int32_t)src->cgar_lifetime.ia6t_expire;
568 	dst->cgar_lifetime.ia6t_preferred = (u_int32_t)src->cgar_lifetime.ia6t_preferred;
569 	dst->cgar_lifetime.ia6t_vltime = src->cgar_lifetime.ia6t_vltime;
570 	dst->cgar_lifetime.ia6t_pltime = src->cgar_lifetime.ia6t_pltime;
571 	dst->cgar_collision_count = src->cgar_collision_count;
572 }
573 #endif
574 
575 static struct in6_aliasreq *
in6_aliasreq_to_native(void * data,int data_is_64,struct in6_aliasreq * dst)576 in6_aliasreq_to_native(void *data, int data_is_64, struct in6_aliasreq *dst)
577 {
578 #if defined(__LP64__)
579 	if (data_is_64) {
580 		bcopy(data, dst, sizeof(*dst));
581 	} else {
582 		in6_aliasreq_32_to_64((struct in6_aliasreq_32 *)data,
583 		    (struct in6_aliasreq_64 *)dst);
584 	}
585 #else
586 	if (data_is_64) {
587 		in6_aliasreq_64_to_32((struct in6_aliasreq_64 *)data,
588 		    (struct in6_aliasreq_32 *)dst);
589 	} else {
590 		bcopy(data, dst, sizeof(*dst));
591 	}
592 #endif /* __LP64__ */
593 	return dst;
594 }
595 
596 void
in6_cgareq_copy_from_user(const void * user_data,int user_is_64,struct in6_cgareq * cgareq)597 in6_cgareq_copy_from_user(const void *user_data, int user_is_64,
598     struct in6_cgareq *cgareq)
599 {
600 #if defined(__LP64__)
601 	if (user_is_64) {
602 		bcopy(user_data, cgareq, sizeof(*cgareq));
603 	} else {
604 		in6_cgareq_32_to_64((const struct in6_cgareq_32 *)user_data,
605 		    (struct in6_cgareq_64 *)cgareq);
606 	}
607 #else
608 	if (user_is_64) {
609 		in6_cgareq_64_to_32((const struct in6_cgareq_64 *)user_data,
610 		    (struct in6_cgareq_32 *)cgareq);
611 	} else {
612 		bcopy(user_data, cgareq, sizeof(*cgareq));
613 	}
614 #endif /* __LP64__ */
615 }
616 
617 static __attribute__((noinline)) int
in6ctl_associd(struct socket * so,u_long cmd,caddr_t data)618 in6ctl_associd(struct socket *so, u_long cmd, caddr_t data)
619 {
620 	int error = 0;
621 	union {
622 		struct so_aidreq32 a32;
623 		struct so_aidreq64 a64;
624 	} u;
625 
626 	VERIFY(so != NULL);
627 
628 	switch (cmd) {
629 	case SIOCGASSOCIDS32: {         /* struct so_aidreq32 */
630 		bcopy(data, &u.a32, sizeof(u.a32));
631 		error = in6_getassocids(so, &u.a32.sar_cnt, u.a32.sar_aidp);
632 		if (error == 0) {
633 			bcopy(&u.a32, data, sizeof(u.a32));
634 		}
635 		break;
636 	}
637 
638 	case SIOCGASSOCIDS64: {         /* struct so_aidreq64 */
639 		bcopy(data, &u.a64, sizeof(u.a64));
640 		error = in6_getassocids(so, &u.a64.sar_cnt, (user_addr_t)u.a64.sar_aidp);
641 		if (error == 0) {
642 			bcopy(&u.a64, data, sizeof(u.a64));
643 		}
644 		break;
645 	}
646 
647 	default:
648 		VERIFY(0);
649 		/* NOTREACHED */
650 	}
651 
652 	return error;
653 }
654 
655 static __attribute__((noinline)) int
in6ctl_connid(struct socket * so,u_long cmd,caddr_t data)656 in6ctl_connid(struct socket *so, u_long cmd, caddr_t data)
657 {
658 	int error = 0;
659 	union {
660 		struct so_cidreq32 c32;
661 		struct so_cidreq64 c64;
662 	} u;
663 
664 	VERIFY(so != NULL);
665 
666 	switch (cmd) {
667 	case SIOCGCONNIDS32: {          /* struct so_cidreq32 */
668 		bcopy(data, &u.c32, sizeof(u.c32));
669 		error = in6_getconnids(so, u.c32.scr_aid, &u.c32.scr_cnt,
670 		    u.c32.scr_cidp);
671 		if (error == 0) {
672 			bcopy(&u.c32, data, sizeof(u.c32));
673 		}
674 		break;
675 	}
676 
677 	case SIOCGCONNIDS64: {          /* struct so_cidreq64 */
678 		bcopy(data, &u.c64, sizeof(u.c64));
679 		error = in6_getconnids(so, u.c64.scr_aid, &u.c64.scr_cnt,
680 		    (user_addr_t)u.c64.scr_cidp);
681 		if (error == 0) {
682 			bcopy(&u.c64, data, sizeof(u.c64));
683 		}
684 		break;
685 	}
686 
687 	default:
688 		VERIFY(0);
689 		/* NOTREACHED */
690 	}
691 
692 	return error;
693 }
694 
695 static __attribute__((noinline)) int
in6ctl_conninfo(struct socket * so,u_long cmd,caddr_t data)696 in6ctl_conninfo(struct socket *so, u_long cmd, caddr_t data)
697 {
698 	int error = 0;
699 	union {
700 		struct so_cinforeq32 ci32;
701 		struct so_cinforeq64 ci64;
702 	} u;
703 
704 	VERIFY(so != NULL);
705 
706 	switch (cmd) {
707 	case SIOCGCONNINFO32: {         /* struct so_cinforeq32 */
708 		bcopy(data, &u.ci32, sizeof(u.ci32));
709 		error = in6_getconninfo(so, u.ci32.scir_cid, &u.ci32.scir_flags,
710 		    &u.ci32.scir_ifindex, &u.ci32.scir_error, u.ci32.scir_src,
711 		    &u.ci32.scir_src_len, u.ci32.scir_dst, &u.ci32.scir_dst_len,
712 		    &u.ci32.scir_aux_type, u.ci32.scir_aux_data,
713 		    &u.ci32.scir_aux_len);
714 		if (error == 0) {
715 			bcopy(&u.ci32, data, sizeof(u.ci32));
716 		}
717 		break;
718 	}
719 
720 	case SIOCGCONNINFO64: {         /* struct so_cinforeq64 */
721 		bcopy(data, &u.ci64, sizeof(u.ci64));
722 		error = in6_getconninfo(so, u.ci64.scir_cid, &u.ci64.scir_flags,
723 		    &u.ci64.scir_ifindex, &u.ci64.scir_error, (user_addr_t)u.ci64.scir_src,
724 		    &u.ci64.scir_src_len, (user_addr_t)u.ci64.scir_dst, &u.ci64.scir_dst_len,
725 		    &u.ci64.scir_aux_type, (user_addr_t)u.ci64.scir_aux_data,
726 		    &u.ci64.scir_aux_len);
727 		if (error == 0) {
728 			bcopy(&u.ci64, data, sizeof(u.ci64));
729 		}
730 		break;
731 	}
732 
733 	default:
734 		VERIFY(0);
735 		/* NOTREACHED */
736 	}
737 
738 	return error;
739 }
740 
741 static __attribute__((noinline)) int
in6ctl_llstart(struct ifnet * ifp,u_long cmd,caddr_t data)742 in6ctl_llstart(struct ifnet *ifp, u_long cmd, caddr_t data)
743 {
744 	struct in6_aliasreq sifra, *ifra = NULL;
745 	boolean_t is64;
746 	int error = 0;
747 
748 	VERIFY(ifp != NULL);
749 
750 	switch (cmd) {
751 	case SIOCLL_START_32:           /* struct in6_aliasreq_32 */
752 	case SIOCLL_START_64:           /* struct in6_aliasreq_64 */
753 		is64 = (cmd == SIOCLL_START_64);
754 		/*
755 		 * Convert user ifra to the kernel form, when appropriate.
756 		 * This allows the conversion between different data models
757 		 * to be centralized, so that it can be passed around to other
758 		 * routines that are expecting the kernel form.
759 		 */
760 		ifra = in6_aliasreq_to_native(data, is64, &sifra);
761 
762 		/*
763 		 * NOTE: All the interface specific DLIL attachements should
764 		 * be done here.  They are currently done in in6_ifattach_aux()
765 		 * for the interfaces that need it.
766 		 */
767 		if (ifra->ifra_addr.sin6_family == AF_INET6 &&
768 		    /* Only check ifra_dstaddr if valid */
769 		    (ifra->ifra_dstaddr.sin6_len == 0 ||
770 		    ifra->ifra_dstaddr.sin6_family == AF_INET6)) {
771 			/* some interfaces may provide LinkLocal addresses */
772 			error = in6_ifattach_aliasreq(ifp, NULL, ifra);
773 		} else {
774 			error = in6_ifattach_aliasreq(ifp, NULL, NULL);
775 		}
776 		if (error == 0) {
777 			in6_if_up_dad_start(ifp);
778 		}
779 		break;
780 
781 	default:
782 		VERIFY(0);
783 		/* NOTREACHED */
784 	}
785 
786 	return error;
787 }
788 
789 static __attribute__((noinline)) int
in6ctl_llstop(struct ifnet * ifp)790 in6ctl_llstop(struct ifnet *ifp)
791 {
792 	struct in6_ifaddr *ia;
793 	struct nd_prefix pr0, *pr;
794 
795 	VERIFY(ifp != NULL);
796 
797 	/* Remove link local addresses from interface */
798 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
799 	boolean_t from_begining = TRUE;
800 	while (from_begining) {
801 		from_begining = FALSE;
802 		TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
803 			if (ia->ia_ifa.ifa_ifp != ifp) {
804 				continue;
805 			}
806 			IFA_LOCK(&ia->ia_ifa);
807 			if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
808 				IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for us */
809 				IFA_UNLOCK(&ia->ia_ifa);
810 				lck_rw_done(&in6_ifaddr_rwlock);
811 				in6_purgeaddr(&ia->ia_ifa);
812 				IFA_REMREF(&ia->ia_ifa);        /* for us */
813 				lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
814 				/*
815 				 * Purging the address caused in6_ifaddr_rwlock
816 				 * to be dropped and reacquired;
817 				 * therefore search again from the beginning
818 				 * of in6_ifaddrs list.
819 				 */
820 				from_begining = TRUE;
821 				break;
822 			}
823 			IFA_UNLOCK(&ia->ia_ifa);
824 		}
825 	}
826 	lck_rw_done(&in6_ifaddr_rwlock);
827 
828 	/* Delete the link local prefix */
829 	bzero(&pr0, sizeof(pr0));
830 	pr0.ndpr_plen = 64;
831 	pr0.ndpr_ifp = ifp;
832 	pr0.ndpr_prefix.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_ULL;
833 	(void)in6_setscope(&pr0.ndpr_prefix.sin6_addr, ifp, IN6_NULL_IF_EMBEDDED_SCOPE(&pr0.ndpr_prefix.sin6_scope_id));
834 	pr = nd6_prefix_lookup(&pr0, ND6_PREFIX_EXPIRY_UNSPEC);
835 	if (pr) {
836 		lck_mtx_lock(nd6_mutex);
837 		NDPR_LOCK(pr);
838 		prelist_remove(pr);
839 		NDPR_UNLOCK(pr);
840 		NDPR_REMREF(pr); /* Drop the reference from lookup */
841 		lck_mtx_unlock(nd6_mutex);
842 	}
843 
844 	return 0;
845 }
846 
847 /*
848  * This routine configures secure link local address
849  */
850 static __attribute__((noinline)) int
in6ctl_cgastart(struct ifnet * ifp,u_long cmd,caddr_t data)851 in6ctl_cgastart(struct ifnet *ifp, u_long cmd, caddr_t data)
852 {
853 	struct in6_cgareq llcgasr;
854 	int is64, error = 0;
855 
856 	VERIFY(ifp != NULL);
857 
858 	switch (cmd) {
859 	case SIOCLL_CGASTART_32:        /* struct in6_cgareq_32 */
860 	case SIOCLL_CGASTART_64:        /* struct in6_cgareq_64 */
861 		is64 = (cmd == SIOCLL_CGASTART_64);
862 		/*
863 		 * Convert user cgareq to the kernel form, when appropriate.
864 		 * This allows the conversion between different data models
865 		 * to be centralized, so that it can be passed around to other
866 		 * routines that are expecting the kernel form.
867 		 */
868 		in6_cgareq_copy_from_user(data, is64, &llcgasr);
869 
870 		/*
871 		 * NOTE: All the interface specific DLIL attachements
872 		 * should be done here.  They are currently done in
873 		 * in6_ifattach_cgareq() for the interfaces that
874 		 * need it.
875 		 */
876 		error = in6_ifattach_llcgareq(ifp, &llcgasr);
877 		if (error == 0) {
878 			in6_if_up_dad_start(ifp);
879 		}
880 		break;
881 
882 	default:
883 		VERIFY(0);
884 		/* NOTREACHED */
885 	}
886 
887 	return error;
888 }
889 
890 /*
891  * Caller passes in the ioctl data pointer directly via "ifr", with the
892  * expectation that this routine always uses bcopy() or other byte-aligned
893  * memory accesses.
894  */
895 static __attribute__((noinline)) int
in6ctl_gifaddr(struct ifnet * ifp,struct in6_ifaddr * ia,u_long cmd,struct in6_ifreq * ifr)896 in6ctl_gifaddr(struct ifnet *ifp, struct in6_ifaddr *ia, u_long cmd,
897     struct in6_ifreq *ifr)
898 {
899 	struct sockaddr_in6 addr;
900 	int error = 0;
901 
902 	VERIFY(ifp != NULL);
903 
904 	if (ia == NULL) {
905 		return EADDRNOTAVAIL;
906 	}
907 
908 	switch (cmd) {
909 	case SIOCGIFADDR_IN6:           /* struct in6_ifreq */
910 		IFA_LOCK(&ia->ia_ifa);
911 		bcopy(&ia->ia_addr, &addr, sizeof(addr));
912 		IFA_UNLOCK(&ia->ia_ifa);
913 		if ((error = sa6_recoverscope(&addr, TRUE)) != 0) {
914 			break;
915 		}
916 		bcopy(&addr, &ifr->ifr_addr, sizeof(addr));
917 		break;
918 
919 	case SIOCGIFDSTADDR_IN6:        /* struct in6_ifreq */
920 		if (!(ifp->if_flags & IFF_POINTOPOINT)) {
921 			error = EINVAL;
922 			break;
923 		}
924 		/*
925 		 * XXX: should we check if ifa_dstaddr is NULL and return
926 		 * an error?
927 		 */
928 		IFA_LOCK(&ia->ia_ifa);
929 		bcopy(&ia->ia_dstaddr, &addr, sizeof(addr));
930 		IFA_UNLOCK(&ia->ia_ifa);
931 		if ((error = sa6_recoverscope(&addr, TRUE)) != 0) {
932 			break;
933 		}
934 		bcopy(&addr, &ifr->ifr_dstaddr, sizeof(addr));
935 		break;
936 
937 	default:
938 		VERIFY(0);
939 		/* NOTREACHED */
940 	}
941 
942 	return error;
943 }
944 
945 /*
946  * Caller passes in the ioctl data pointer directly via "ifr", with the
947  * expectation that this routine always uses bcopy() or other byte-aligned
948  * memory accesses.
949  */
950 static __attribute__((noinline)) int
in6ctl_gifstat(struct ifnet * ifp,u_long cmd,struct in6_ifreq * ifr)951 in6ctl_gifstat(struct ifnet *ifp, u_long cmd, struct in6_ifreq *ifr)
952 {
953 	int error = 0, index;
954 
955 	VERIFY(ifp != NULL);
956 	index = ifp->if_index;
957 
958 	switch (cmd) {
959 	case SIOCGIFSTAT_IN6:           /* struct in6_ifreq */
960 		/* N.B.: if_inet6data is never freed once set. */
961 		if (IN6_IFEXTRA(ifp) == NULL) {
962 			/* return (EAFNOSUPPORT)? */
963 			bzero(&ifr->ifr_ifru.ifru_stat,
964 			    sizeof(ifr->ifr_ifru.ifru_stat));
965 		} else {
966 			bcopy(&IN6_IFEXTRA(ifp)->in6_ifstat,
967 			    &ifr->ifr_ifru.ifru_stat,
968 			    sizeof(ifr->ifr_ifru.ifru_stat));
969 		}
970 		break;
971 
972 	case SIOCGIFSTAT_ICMP6:         /* struct in6_ifreq */
973 		/* N.B.: if_inet6data is never freed once set. */
974 		if (IN6_IFEXTRA(ifp) == NULL) {
975 			/* return (EAFNOSUPPORT)? */
976 			bzero(&ifr->ifr_ifru.ifru_icmp6stat,
977 			    sizeof(ifr->ifr_ifru.ifru_icmp6stat));
978 		} else {
979 			bcopy(&IN6_IFEXTRA(ifp)->icmp6_ifstat,
980 			    &ifr->ifr_ifru.ifru_icmp6stat,
981 			    sizeof(ifr->ifr_ifru.ifru_icmp6stat));
982 		}
983 		break;
984 
985 	default:
986 		VERIFY(0);
987 		/* NOTREACHED */
988 	}
989 
990 	return error;
991 }
992 
993 /*
994  * Caller passes in the ioctl data pointer directly via "ifr", with the
995  * expectation that this routine always uses bcopy() or other byte-aligned
996  * memory accesses.
997  */
998 static __attribute__((noinline)) int
in6ctl_alifetime(struct in6_ifaddr * ia,u_long cmd,struct in6_ifreq * ifr,boolean_t p64)999 in6ctl_alifetime(struct in6_ifaddr *ia, u_long cmd, struct in6_ifreq *ifr,
1000     boolean_t p64)
1001 {
1002 	uint64_t timenow = net_uptime();
1003 	struct in6_addrlifetime ia6_lt;
1004 	struct timeval caltime;
1005 	int error = 0;
1006 
1007 	if (ia == NULL) {
1008 		return EADDRNOTAVAIL;
1009 	}
1010 
1011 	switch (cmd) {
1012 	case SIOCGIFALIFETIME_IN6:      /* struct in6_ifreq */
1013 		IFA_LOCK(&ia->ia_ifa);
1014 		/* retrieve time as calendar time (last arg is 1) */
1015 		in6ifa_getlifetime(ia, &ia6_lt, 1);
1016 		if (p64) {
1017 			struct in6_addrlifetime_64 lt;
1018 
1019 			bzero(&lt, sizeof(lt));
1020 			lt.ia6t_expire = ia6_lt.ia6t_expire;
1021 			lt.ia6t_preferred = ia6_lt.ia6t_preferred;
1022 			lt.ia6t_vltime = ia6_lt.ia6t_vltime;
1023 			lt.ia6t_pltime = ia6_lt.ia6t_pltime;
1024 			bcopy(&lt, &ifr->ifr_ifru.ifru_lifetime, sizeof(ifr->ifr_ifru.ifru_lifetime));
1025 		} else {
1026 			struct in6_addrlifetime_32 lt;
1027 
1028 			bzero(&lt, sizeof(lt));
1029 			lt.ia6t_expire = (uint32_t)ia6_lt.ia6t_expire;
1030 			lt.ia6t_preferred = (uint32_t)ia6_lt.ia6t_preferred;
1031 			lt.ia6t_vltime = (uint32_t)ia6_lt.ia6t_vltime;
1032 			lt.ia6t_pltime = (uint32_t)ia6_lt.ia6t_pltime;
1033 			/*
1034 			 * 32-bit userland expects a 32-bit in6_addrlifetime to
1035 			 * come back:
1036 			 */
1037 			bcopy(&lt, &ifr->ifr_ifru.ifru_lifetime, sizeof(lt));
1038 		}
1039 		IFA_UNLOCK(&ia->ia_ifa);
1040 		break;
1041 
1042 	case SIOCSIFALIFETIME_IN6:      /* struct in6_ifreq */
1043 		getmicrotime(&caltime);
1044 
1045 		/* sanity for overflow - beware unsigned */
1046 		if (p64) {
1047 			struct in6_addrlifetime_64 lt;
1048 
1049 			bcopy(&ifr->ifr_ifru.ifru_lifetime, &lt, sizeof(lt));
1050 			if (lt.ia6t_vltime != ND6_INFINITE_LIFETIME &&
1051 			    lt.ia6t_vltime + caltime.tv_sec < caltime.tv_sec) {
1052 				error = EINVAL;
1053 				break;
1054 			}
1055 			if (lt.ia6t_pltime != ND6_INFINITE_LIFETIME &&
1056 			    lt.ia6t_pltime + caltime.tv_sec < caltime.tv_sec) {
1057 				error = EINVAL;
1058 				break;
1059 			}
1060 		} else {
1061 			struct in6_addrlifetime_32 lt;
1062 
1063 			bcopy(&ifr->ifr_ifru.ifru_lifetime, &lt, sizeof(lt));
1064 			if (lt.ia6t_vltime != ND6_INFINITE_LIFETIME &&
1065 			    lt.ia6t_vltime + caltime.tv_sec < caltime.tv_sec) {
1066 				error = EINVAL;
1067 				break;
1068 			}
1069 			if (lt.ia6t_pltime != ND6_INFINITE_LIFETIME &&
1070 			    lt.ia6t_pltime + caltime.tv_sec < caltime.tv_sec) {
1071 				error = EINVAL;
1072 				break;
1073 			}
1074 		}
1075 
1076 		IFA_LOCK(&ia->ia_ifa);
1077 		if (p64) {
1078 			struct in6_addrlifetime_64 lt;
1079 
1080 			bcopy(&ifr->ifr_ifru.ifru_lifetime, &lt, sizeof(lt));
1081 			ia6_lt.ia6t_expire = (time_t)lt.ia6t_expire;
1082 			ia6_lt.ia6t_preferred = (time_t)lt.ia6t_preferred;
1083 			ia6_lt.ia6t_vltime = lt.ia6t_vltime;
1084 			ia6_lt.ia6t_pltime = lt.ia6t_pltime;
1085 		} else {
1086 			struct in6_addrlifetime_32 lt;
1087 
1088 			bcopy(&ifr->ifr_ifru.ifru_lifetime, &lt, sizeof(lt));
1089 			ia6_lt.ia6t_expire = (uint32_t)lt.ia6t_expire;
1090 			ia6_lt.ia6t_preferred = (uint32_t)lt.ia6t_preferred;
1091 			ia6_lt.ia6t_vltime = lt.ia6t_vltime;
1092 			ia6_lt.ia6t_pltime = lt.ia6t_pltime;
1093 		}
1094 		/* for sanity */
1095 		if (ia6_lt.ia6t_vltime != ND6_INFINITE_LIFETIME) {
1096 			ia6_lt.ia6t_expire = (time_t)(timenow + ia6_lt.ia6t_vltime);
1097 		} else {
1098 			ia6_lt.ia6t_expire = 0;
1099 		}
1100 
1101 		if (ia6_lt.ia6t_pltime != ND6_INFINITE_LIFETIME) {
1102 			ia6_lt.ia6t_preferred = (time_t)(timenow + ia6_lt.ia6t_pltime);
1103 		} else {
1104 			ia6_lt.ia6t_preferred = 0;
1105 		}
1106 
1107 		in6ifa_setlifetime(ia, &ia6_lt);
1108 		IFA_UNLOCK(&ia->ia_ifa);
1109 		break;
1110 
1111 	default:
1112 		VERIFY(0);
1113 		/* NOTREACHED */
1114 	}
1115 
1116 	return error;
1117 }
1118 
1119 static int
in6ctl_clat46start(struct ifnet * ifp)1120 in6ctl_clat46start(struct ifnet *ifp)
1121 {
1122 	struct nd_prefix *pr = NULL;
1123 	struct nd_prefix *next = NULL;
1124 	struct in6_ifaddr *ia6 = NULL;
1125 	int error = 0;
1126 
1127 	if (ifp == lo_ifp) {
1128 		return EINVAL;
1129 	}
1130 	/*
1131 	 * Traverse the list of prefixes and find the first non-linklocal
1132 	 * prefix on the interface.
1133 	 * For that found eligible prefix, configure a CLAT46 reserved address.
1134 	 */
1135 	lck_mtx_lock(nd6_mutex);
1136 	for (pr = nd_prefix.lh_first; pr; pr = next) {
1137 		next = pr->ndpr_next;
1138 
1139 		NDPR_LOCK(pr);
1140 		if (pr->ndpr_ifp != ifp) {
1141 			NDPR_UNLOCK(pr);
1142 			continue;
1143 		}
1144 
1145 		if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
1146 			NDPR_UNLOCK(pr);
1147 			continue; /* XXX */
1148 		}
1149 
1150 		if (pr->ndpr_raf_auto == 0) {
1151 			NDPR_UNLOCK(pr);
1152 			continue;
1153 		}
1154 
1155 		if (pr->ndpr_stateflags & NDPRF_DEFUNCT) {
1156 			NDPR_UNLOCK(pr);
1157 			continue;
1158 		}
1159 
1160 		if ((pr->ndpr_stateflags & NDPRF_CLAT46) == 0
1161 		    && pr->ndpr_vltime != 0) {
1162 			NDPR_ADDREF(pr); /* Take reference for rest of the processing */
1163 			NDPR_UNLOCK(pr);
1164 			break;
1165 		} else {
1166 			NDPR_UNLOCK(pr);
1167 			continue;
1168 		}
1169 	}
1170 	lck_mtx_unlock(nd6_mutex);
1171 
1172 	if (pr != NULL) {
1173 		if ((ia6 = in6_pfx_newpersistaddr(pr, FALSE, &error,
1174 		    TRUE, CLAT46_COLLISION_COUNT_OFFSET)) == NULL) {
1175 			nd6log0(error,
1176 			    "Could not configure CLAT46 address on"
1177 			    " interface %s.\n", ifp->if_xname);
1178 		} else {
1179 			IFA_LOCK(&ia6->ia_ifa);
1180 			NDPR_LOCK(pr);
1181 			ia6->ia6_ndpr = pr;
1182 			NDPR_ADDREF(pr); /* for addr reference */
1183 			pr->ndpr_stateflags |= NDPRF_CLAT46;
1184 			pr->ndpr_addrcnt++;
1185 			VERIFY(pr->ndpr_addrcnt != 0);
1186 			NDPR_UNLOCK(pr);
1187 			IFA_UNLOCK(&ia6->ia_ifa);
1188 			IFA_REMREF(&ia6->ia_ifa);
1189 			ia6 = NULL;
1190 			/*
1191 			 * A newly added address might affect the status
1192 			 * of other addresses, so we check and update it.
1193 			 * XXX: what if address duplication happens?
1194 			 */
1195 			lck_mtx_lock(nd6_mutex);
1196 			pfxlist_onlink_check();
1197 			lck_mtx_unlock(nd6_mutex);
1198 		}
1199 		NDPR_REMREF(pr);
1200 	}
1201 	return error;
1202 }
1203 
1204 static int
in6ctl_clat46stop(struct ifnet * ifp)1205 in6ctl_clat46stop(struct ifnet *ifp)
1206 {
1207 	int error = 0;
1208 	struct in6_ifaddr *ia = NULL;
1209 
1210 	if (ifp == lo_ifp) {
1211 		return EINVAL;
1212 	}
1213 	if ((ifp->if_eflags & IFEF_CLAT46) == 0) {
1214 		/* CLAT46 isn't enabled */
1215 		goto done;
1216 	}
1217 	if_clear_eflags(ifp, IFEF_CLAT46);
1218 
1219 	/* find CLAT46 address and remove it */
1220 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
1221 	TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
1222 		if (ia->ia_ifa.ifa_ifp != ifp) {
1223 			continue;
1224 		}
1225 		IFA_LOCK(&ia->ia_ifa);
1226 		if ((ia->ia6_flags & IN6_IFF_CLAT46) != 0) {
1227 			IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for us */
1228 			IFA_UNLOCK(&ia->ia_ifa);
1229 			lck_rw_done(&in6_ifaddr_rwlock);
1230 			in6_purgeaddr(&ia->ia_ifa);
1231 			IFA_REMREF(&ia->ia_ifa);        /* for us */
1232 			goto done;
1233 		}
1234 		IFA_UNLOCK(&ia->ia_ifa);
1235 	}
1236 	lck_rw_done(&in6_ifaddr_rwlock);
1237 
1238 done:
1239 	return error;
1240 }
1241 
1242 #define ifa2ia6(ifa)    ((struct in6_ifaddr *)(void *)(ifa))
1243 
1244 /*
1245  * Generic INET6 control operations (ioctl's).
1246  *
1247  * ifp is NULL if not an interface-specific ioctl.
1248  *
1249  * Most of the routines called to handle the ioctls would end up being
1250  * tail-call optimized, which unfortunately causes this routine to
1251  * consume too much stack space; this is the reason for the "noinline"
1252  * attribute used on those routines.
1253  *
1254  * If called directly from within the networking stack (as opposed to via
1255  * pru_control), the socket parameter may be NULL.
1256  */
1257 int
in6_control(struct socket * so,u_long cmd,caddr_t data,struct ifnet * ifp,struct proc * p)1258 in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
1259     struct proc *p)
1260 {
1261 	struct in6_ifreq *ifr = (struct in6_ifreq *)(void *)data;
1262 	struct in6_aliasreq sifra, *ifra = NULL;
1263 	struct in6_ifaddr *ia = NULL;
1264 	struct sockaddr_in6 sin6, *sa6 = NULL;
1265 	boolean_t privileged = (proc_suser(p) == 0);
1266 	boolean_t p64 = proc_is64bit(p);
1267 	boolean_t so_unlocked = FALSE;
1268 	int intval, error = 0;
1269 
1270 	/* In case it's NULL, make sure it came from the kernel */
1271 	VERIFY(so != NULL || p == kernproc);
1272 
1273 	/*
1274 	 * ioctls which don't require ifp, may require socket.
1275 	 */
1276 	switch (cmd) {
1277 	case SIOCAADDRCTL_POLICY:       /* struct in6_addrpolicy */
1278 	case SIOCDADDRCTL_POLICY:       /* struct in6_addrpolicy */
1279 		if (!privileged) {
1280 			return EPERM;
1281 		}
1282 		return in6_src_ioctl(cmd, data);
1283 	/* NOTREACHED */
1284 
1285 	case SIOCDRADD_IN6_32:          /* struct in6_defrouter_32 */
1286 	case SIOCDRADD_IN6_64:          /* struct in6_defrouter_64 */
1287 	case SIOCDRDEL_IN6_32:          /* struct in6_defrouter_32 */
1288 	case SIOCDRDEL_IN6_64:          /* struct in6_defrouter_64 */
1289 		if (!privileged) {
1290 			return EPERM;
1291 		}
1292 		return defrtrlist_ioctl(cmd, data);
1293 	/* NOTREACHED */
1294 
1295 	case SIOCGASSOCIDS32:           /* struct so_aidreq32 */
1296 	case SIOCGASSOCIDS64:           /* struct so_aidreq64 */
1297 		return in6ctl_associd(so, cmd, data);
1298 	/* NOTREACHED */
1299 
1300 	case SIOCGCONNIDS32:            /* struct so_cidreq32 */
1301 	case SIOCGCONNIDS64:            /* struct so_cidreq64 */
1302 		return in6ctl_connid(so, cmd, data);
1303 	/* NOTREACHED */
1304 
1305 	case SIOCGCONNINFO32:           /* struct so_cinforeq32 */
1306 	case SIOCGCONNINFO64:           /* struct so_cinforeq64 */
1307 		return in6ctl_conninfo(so, cmd, data);
1308 		/* NOTREACHED */
1309 	}
1310 
1311 	/*
1312 	 * The rest of ioctls require ifp; reject if we don't have one;
1313 	 * return ENXIO to be consistent with ifioctl().
1314 	 */
1315 	if (ifp == NULL) {
1316 		return ENXIO;
1317 	}
1318 
1319 	/*
1320 	 * Unlock the socket since ifnet_ioctl() may be invoked by
1321 	 * one of the ioctl handlers below.  Socket will be re-locked
1322 	 * prior to returning.
1323 	 */
1324 	if (so != NULL) {
1325 		socket_unlock(so, 0);
1326 		so_unlocked = TRUE;
1327 	}
1328 
1329 	lck_mtx_lock(&ifp->if_inet6_ioctl_lock);
1330 	while (ifp->if_inet6_ioctl_busy) {
1331 		(void) msleep(&ifp->if_inet6_ioctl_busy, &ifp->if_inet6_ioctl_lock, (PZERO - 1),
1332 		    __func__, NULL);
1333 		LCK_MTX_ASSERT(&ifp->if_inet6_ioctl_lock, LCK_MTX_ASSERT_OWNED);
1334 	}
1335 	ifp->if_inet6_ioctl_busy = TRUE;
1336 	lck_mtx_unlock(&ifp->if_inet6_ioctl_lock);
1337 
1338 	/*
1339 	 * ioctls which require ifp but not interface address.
1340 	 */
1341 	switch (cmd) {
1342 	case SIOCAUTOCONF_START:        /* struct in6_ifreq */
1343 		if (!privileged) {
1344 			error = EPERM;
1345 			goto done;
1346 		}
1347 		error = in6_autoconf(ifp, TRUE);
1348 		goto done;
1349 
1350 	case SIOCAUTOCONF_STOP:         /* struct in6_ifreq */
1351 		if (!privileged) {
1352 			error = EPERM;
1353 			goto done;
1354 		}
1355 		error = in6_autoconf(ifp, FALSE);
1356 		goto done;
1357 
1358 	case SIOCLL_START_32:           /* struct in6_aliasreq_32 */
1359 	case SIOCLL_START_64:           /* struct in6_aliasreq_64 */
1360 		if (!privileged) {
1361 			error = EPERM;
1362 			goto done;
1363 		}
1364 		error = in6ctl_llstart(ifp, cmd, data);
1365 		goto done;
1366 
1367 	case SIOCLL_STOP:               /* struct in6_ifreq */
1368 		if (!privileged) {
1369 			error = EPERM;
1370 			goto done;
1371 		}
1372 		error = in6ctl_llstop(ifp);
1373 		goto done;
1374 
1375 	case SIOCCLAT46_START:          /* struct in6_ifreq */
1376 		if (!privileged) {
1377 			error = EPERM;
1378 			goto done;
1379 		}
1380 		error = in6ctl_clat46start(ifp);
1381 		if (error == 0) {
1382 			if_set_eflags(ifp, IFEF_CLAT46);
1383 		}
1384 		goto done;
1385 
1386 	case SIOCCLAT46_STOP:           /* struct in6_ifreq */
1387 		if (!privileged) {
1388 			error = EPERM;
1389 			goto done;
1390 		}
1391 		error = in6ctl_clat46stop(ifp);
1392 		goto done;
1393 	case SIOCGETROUTERMODE_IN6:     /* struct in6_ifreq */
1394 		intval = ifp->if_ipv6_router_mode;
1395 		bcopy(&intval, &((struct in6_ifreq *)(void *)data)->ifr_intval,
1396 		    sizeof(intval));
1397 		goto done;
1398 	case SIOCSETROUTERMODE_IN6:     /* struct in6_ifreq */
1399 		if (!privileged) {
1400 			error = EPERM;
1401 			goto done;
1402 		}
1403 		bcopy(&((struct in6_ifreq *)(void *)data)->ifr_intval,
1404 		    &intval, sizeof(intval));
1405 		switch (intval) {
1406 		case IPV6_ROUTER_MODE_DISABLED:
1407 		case IPV6_ROUTER_MODE_EXCLUSIVE:
1408 		case IPV6_ROUTER_MODE_HYBRID:
1409 			break;
1410 		default:
1411 			error = EINVAL;
1412 			goto done;
1413 		}
1414 		error = in6_setrouter(ifp, (ipv6_router_mode_t)intval);
1415 		goto done;
1416 
1417 	case SIOCPROTOATTACH_IN6_32:    /* struct in6_aliasreq_32 */
1418 	case SIOCPROTOATTACH_IN6_64:    /* struct in6_aliasreq_64 */
1419 		if (!privileged) {
1420 			error = EPERM;
1421 			goto done;
1422 		}
1423 		error = in6_domifattach(ifp);
1424 		goto done;
1425 
1426 	case SIOCPROTODETACH_IN6:       /* struct in6_ifreq */
1427 		if (!privileged) {
1428 			error = EPERM;
1429 			goto done;
1430 		}
1431 		/* Cleanup interface routes and addresses */
1432 		in6_purgeif(ifp);
1433 
1434 		if ((error = proto_unplumb(PF_INET6, ifp))) {
1435 			log(LOG_ERR, "SIOCPROTODETACH_IN6: %s error=%d\n",
1436 			    if_name(ifp), error);
1437 		}
1438 		goto done;
1439 
1440 	case SIOCSNDFLUSH_IN6:          /* struct in6_ifreq */
1441 	case SIOCSPFXFLUSH_IN6:         /* struct in6_ifreq */
1442 	case SIOCSRTRFLUSH_IN6:         /* struct in6_ifreq */
1443 	case SIOCSDEFIFACE_IN6_32:      /* struct in6_ndifreq_32 */
1444 	case SIOCSDEFIFACE_IN6_64:      /* struct in6_ndifreq_64 */
1445 	case SIOCSIFINFO_FLAGS:         /* struct in6_ndireq */
1446 	case SIOCGIFCGAPREP_IN6_32:     /* struct in6_cgareq_32 */
1447 	case SIOCGIFCGAPREP_IN6_64:     /* struct in6_cgareq_64 */
1448 	case SIOCSIFCGAPREP_IN6_32:     /* struct in6_cgareq_32 */
1449 	case SIOCSIFCGAPREP_IN6_64:     /* struct in6_cgareq_32 */
1450 		if (!privileged) {
1451 			error = EPERM;
1452 			goto done;
1453 		}
1454 		OS_FALLTHROUGH;
1455 	case OSIOCGIFINFO_IN6:          /* struct in6_ondireq */
1456 	case SIOCGIFINFO_IN6:           /* struct in6_ondireq */
1457 	case SIOCGDRLST_IN6_32:         /* struct in6_drlist_32 */
1458 	case SIOCGDRLST_IN6_64:         /* struct in6_drlist_64 */
1459 	case SIOCGPRLST_IN6_32:         /* struct in6_prlist_32 */
1460 	case SIOCGPRLST_IN6_64:         /* struct in6_prlist_64 */
1461 	case SIOCGNBRINFO_IN6_32:       /* struct in6_nbrinfo_32 */
1462 	case SIOCGNBRINFO_IN6_64:       /* struct in6_nbrinfo_64 */
1463 	case SIOCGDEFIFACE_IN6_32:      /* struct in6_ndifreq_32 */
1464 	case SIOCGDEFIFACE_IN6_64:      /* struct in6_ndifreq_64 */
1465 		error = nd6_ioctl(cmd, data, ifp);
1466 		goto done;
1467 
1468 	case SIOCSIFPREFIX_IN6:         /* struct in6_prefixreq (deprecated) */
1469 	case SIOCDIFPREFIX_IN6:         /* struct in6_prefixreq (deprecated) */
1470 	case SIOCAIFPREFIX_IN6:         /* struct in6_rrenumreq (deprecated) */
1471 	case SIOCCIFPREFIX_IN6:         /* struct in6_rrenumreq (deprecated) */
1472 	case SIOCSGIFPREFIX_IN6:        /* struct in6_rrenumreq (deprecated) */
1473 	case SIOCGIFPREFIX_IN6:         /* struct in6_prefixreq (deprecated) */
1474 		log(LOG_NOTICE,
1475 		    "prefix ioctls are now invalidated. "
1476 		    "please use ifconfig.\n");
1477 		error = EOPNOTSUPP;
1478 		goto done;
1479 
1480 	case SIOCSSCOPE6:               /* struct in6_ifreq (deprecated) */
1481 	case SIOCGSCOPE6:               /* struct in6_ifreq (deprecated) */
1482 	case SIOCGSCOPE6DEF:            /* struct in6_ifreq (deprecated) */
1483 		error = EOPNOTSUPP;
1484 		goto done;
1485 
1486 	case SIOCLL_CGASTART_32:        /* struct in6_cgareq_32 */
1487 	case SIOCLL_CGASTART_64:        /* struct in6_cgareq_64 */
1488 		if (!privileged) {
1489 			error = EPERM;
1490 		} else {
1491 			error = in6ctl_cgastart(ifp, cmd, data);
1492 		}
1493 		goto done;
1494 
1495 	case SIOCGIFSTAT_IN6:           /* struct in6_ifreq */
1496 	case SIOCGIFSTAT_ICMP6:         /* struct in6_ifreq */
1497 		error = in6ctl_gifstat(ifp, cmd, ifr);
1498 		goto done;
1499 	}
1500 
1501 	/*
1502 	 * ioctls which require interface address; obtain sockaddr_in6.
1503 	 */
1504 	switch (cmd) {
1505 	case SIOCSIFADDR_IN6:           /* struct in6_ifreq (deprecated) */
1506 	case SIOCSIFDSTADDR_IN6:        /* struct in6_ifreq (deprecated) */
1507 	case SIOCSIFNETMASK_IN6:        /* struct in6_ifreq (deprecated) */
1508 		/*
1509 		 * Since IPv6 allows a node to assign multiple addresses
1510 		 * on a single interface, SIOCSIFxxx ioctls are deprecated.
1511 		 */
1512 		/* we decided to obsolete this command (20000704) */
1513 		error = EOPNOTSUPP;
1514 		goto done;
1515 
1516 	case SIOCAIFADDR_IN6_32:        /* struct in6_aliasreq_32 */
1517 	case SIOCAIFADDR_IN6_64:        /* struct in6_aliasreq_64 */
1518 		if (!privileged) {
1519 			error = EPERM;
1520 			goto done;
1521 		}
1522 		/*
1523 		 * Convert user ifra to the kernel form, when appropriate.
1524 		 * This allows the conversion between different data models
1525 		 * to be centralized, so that it can be passed around to other
1526 		 * routines that are expecting the kernel form.
1527 		 */
1528 		ifra = in6_aliasreq_to_native(data,
1529 		    (cmd == SIOCAIFADDR_IN6_64), &sifra);
1530 		bcopy(&ifra->ifra_addr, &sin6, sizeof(sin6));
1531 		sa6 = &sin6;
1532 		break;
1533 
1534 	case SIOCDIFADDR_IN6:           /* struct in6_ifreq */
1535 	case SIOCSIFALIFETIME_IN6:      /* struct in6_ifreq */
1536 		if (!privileged) {
1537 			error = EPERM;
1538 			goto done;
1539 		}
1540 		OS_FALLTHROUGH;
1541 	case SIOCGIFADDR_IN6:           /* struct in6_ifreq */
1542 	case SIOCGIFDSTADDR_IN6:        /* struct in6_ifreq */
1543 	case SIOCGIFNETMASK_IN6:        /* struct in6_ifreq */
1544 	case SIOCGIFAFLAG_IN6:          /* struct in6_ifreq */
1545 	case SIOCGIFALIFETIME_IN6:      /* struct in6_ifreq */
1546 		bcopy(&ifr->ifr_addr, &sin6, sizeof(sin6));
1547 		sa6 = &sin6;
1548 		break;
1549 	case SIOCGIFDSTADDR:
1550 	case SIOCSIFDSTADDR:
1551 	case SIOCGIFBRDADDR:
1552 	case SIOCSIFBRDADDR:
1553 	case SIOCGIFNETMASK:
1554 	case SIOCSIFNETMASK:
1555 	case SIOCGIFADDR:
1556 	case SIOCSIFADDR:
1557 	case SIOCAIFADDR:
1558 	case SIOCDIFADDR:
1559 		/* Do not handle these AF_INET commands in AF_INET6 path */
1560 		error = EINVAL;
1561 		goto done;
1562 	}
1563 
1564 	/*
1565 	 * Find address for this interface, if it exists.
1566 	 *
1567 	 * In netinet code, we have checked ifra_addr in SIOCSIF*ADDR operation
1568 	 * only, and used the first interface address as the target of other
1569 	 * operations (without checking ifra_addr).  This was because netinet
1570 	 * code/API assumed at most 1 interface address per interface.
1571 	 * Since IPv6 allows a node to assign multiple addresses
1572 	 * on a single interface, we almost always look and check the
1573 	 * presence of ifra_addr, and reject invalid ones here.
1574 	 * It also decreases duplicated code among SIOC*_IN6 operations.
1575 	 */
1576 	VERIFY(ia == NULL);
1577 	if (sa6 != NULL && sa6->sin6_family == AF_INET6) {
1578 		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
1579 			if (in6_embedded_scope) {
1580 				if (sa6->sin6_addr.s6_addr16[1] == 0) {
1581 					/* link ID is not embedded by the user */
1582 					sa6->sin6_addr.s6_addr16[1] =
1583 					    htons(ifp->if_index);
1584 				} else if (sa6->sin6_addr.s6_addr16[1] !=
1585 				    htons(ifp->if_index)) {
1586 					error = EINVAL; /* link ID contradicts */
1587 					goto done;
1588 				}
1589 				if (sa6->sin6_scope_id) {
1590 					if (sa6->sin6_scope_id !=
1591 					    (u_int32_t)ifp->if_index) {
1592 						error = EINVAL;
1593 						goto done;
1594 					}
1595 					sa6->sin6_scope_id = 0; /* XXX: good way? */
1596 				}
1597 			} else {
1598 				if (sa6->sin6_scope_id == IFSCOPE_NONE) {
1599 					sa6->sin6_scope_id = ifp->if_index;
1600 				} else if (sa6->sin6_scope_id != ifp->if_index) {
1601 					error = EINVAL; /* link ID contradicts */
1602 					goto done;
1603 				}
1604 			}
1605 		}
1606 		/*
1607 		 * Any failures from this point on must take into account
1608 		 * a non-NULL "ia" with an outstanding reference count, and
1609 		 * therefore requires IFA_REMREF.  Jump to "done" label
1610 		 * instead of calling return if "ia" is valid.
1611 		 */
1612 		ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
1613 	}
1614 
1615 	/*
1616 	 * SIOCDIFADDR_IN6/SIOCAIFADDR_IN6 specific tests.
1617 	 */
1618 	switch (cmd) {
1619 	case SIOCDIFADDR_IN6:           /* struct in6_ifreq */
1620 		if (ia == NULL) {
1621 			error = EADDRNOTAVAIL;
1622 			goto done;
1623 		}
1624 		OS_FALLTHROUGH;
1625 	case SIOCAIFADDR_IN6_32:        /* struct in6_aliasreq_32 */
1626 	case SIOCAIFADDR_IN6_64:        /* struct in6_aliasreq_64 */
1627 		VERIFY(sa6 != NULL);
1628 		/*
1629 		 * We always require users to specify a valid IPv6 address for
1630 		 * the corresponding operation.  Use "sa6" instead of "ifra"
1631 		 * since SIOCDIFADDR_IN6 falls thru above.
1632 		 */
1633 		if (sa6->sin6_family != AF_INET6 ||
1634 		    sa6->sin6_len != sizeof(struct sockaddr_in6)) {
1635 			error = EAFNOSUPPORT;
1636 			goto done;
1637 		}
1638 
1639 		if ((cmd == SIOCAIFADDR_IN6_32 || cmd == SIOCAIFADDR_IN6_64) &&
1640 		    (IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr) ||
1641 		    IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr) ||
1642 		    IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr) ||
1643 		    IN6_IS_ADDR_V4COMPAT(&sa6->sin6_addr))) {
1644 			error = EINVAL;
1645 			goto done;
1646 		}
1647 		break;
1648 	}
1649 
1650 	/*
1651 	 * And finally process address-related ioctls.
1652 	 */
1653 	switch (cmd) {
1654 	case SIOCGIFADDR_IN6:           /* struct in6_ifreq */
1655 	/* This interface is basically deprecated. use SIOCGIFCONF. */
1656 	/* FALLTHRU */
1657 	case SIOCGIFDSTADDR_IN6:        /* struct in6_ifreq */
1658 		error = in6ctl_gifaddr(ifp, ia, cmd, ifr);
1659 		break;
1660 
1661 	case SIOCGIFNETMASK_IN6:        /* struct in6_ifreq */
1662 		if (ia != NULL) {
1663 			IFA_LOCK(&ia->ia_ifa);
1664 			bcopy(&ia->ia_prefixmask, &ifr->ifr_addr,
1665 			    sizeof(struct sockaddr_in6));
1666 			IFA_UNLOCK(&ia->ia_ifa);
1667 		} else {
1668 			error = EADDRNOTAVAIL;
1669 		}
1670 		break;
1671 
1672 	case SIOCGIFAFLAG_IN6:          /* struct in6_ifreq */
1673 		if (ia != NULL) {
1674 			IFA_LOCK(&ia->ia_ifa);
1675 			bcopy(&ia->ia6_flags, &ifr->ifr_ifru.ifru_flags6,
1676 			    sizeof(ifr->ifr_ifru.ifru_flags6));
1677 			IFA_UNLOCK(&ia->ia_ifa);
1678 		} else {
1679 			error = EADDRNOTAVAIL;
1680 		}
1681 		break;
1682 
1683 	case SIOCGIFALIFETIME_IN6:      /* struct in6_ifreq */
1684 	case SIOCSIFALIFETIME_IN6:      /* struct in6_ifreq */
1685 		error = in6ctl_alifetime(ia, cmd, ifr, p64);
1686 		break;
1687 
1688 	case SIOCAIFADDR_IN6_32:        /* struct in6_aliasreq_32 */
1689 	case SIOCAIFADDR_IN6_64:        /* struct in6_aliasreq_64 */
1690 		error = in6ctl_aifaddr(ifp, ifra);
1691 		break;
1692 
1693 	case SIOCDIFADDR_IN6:
1694 		in6ctl_difaddr(ifp, ia);
1695 		break;
1696 
1697 	default:
1698 		error = ifnet_ioctl(ifp, PF_INET6, cmd, data);
1699 		break;
1700 	}
1701 
1702 done:
1703 	if (ifp != NULL) {
1704 		lck_mtx_lock(&ifp->if_inet6_ioctl_lock);
1705 		ifp->if_inet6_ioctl_busy = FALSE;
1706 		lck_mtx_unlock(&ifp->if_inet6_ioctl_lock);
1707 		wakeup(&ifp->if_inet6_ioctl_busy);
1708 	}
1709 
1710 	if (ia != NULL) {
1711 		IFA_REMREF(&ia->ia_ifa);
1712 	}
1713 	if (so_unlocked) {
1714 		socket_lock(so, 0);
1715 	}
1716 
1717 	return error;
1718 }
1719 
1720 static __attribute__((noinline)) int
in6ctl_aifaddr(struct ifnet * ifp,struct in6_aliasreq * ifra)1721 in6ctl_aifaddr(struct ifnet *ifp, struct in6_aliasreq *ifra)
1722 {
1723 	int i, error, addtmp;
1724 	uint8_t plen;
1725 	struct nd_prefix pr0, *pr;
1726 	struct in6_ifaddr *ia;
1727 
1728 	VERIFY(ifp != NULL && ifra != NULL);
1729 	ia = NULL;
1730 
1731 	/*
1732 	 * XXX This interface is not meant to be used for static LLA
1733 	 * configuration.
1734 	 * Instead one can use SIOCLL_START can be used to configure LLA
1735 	 * statically.
1736 	 * For bin-compat reasons though, allow it for now and only make
1737 	 * sure that scope gets communicated correctly.
1738 	 */
1739 	if (IN6_IS_ADDR_LINKLOCAL(&ifra->ifra_addr.sin6_addr)) {
1740 		if (in6_embedded_scope) {
1741 			ifra->ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
1742 		} else {
1743 			/*
1744 			 * XXX May be we should rather also check if sin6_scope_id
1745 			 * is already set or enforce if set that it is same
1746 			 * as interface index?
1747 			 * For now to avoid any unintended consequence, just use
1748 			 * interface index and set sin6_scope_id.
1749 			 * Also should we just prohibit this interface to configure
1750 			 * additional link local and limti LLA configuration through
1751 			 * other *_start ioctls?
1752 			 */
1753 			ifra->ifra_addr.sin6_addr.s6_addr16[1] = 0;
1754 			ifra->ifra_addr.sin6_scope_id = ifp->if_index;
1755 		}
1756 	}
1757 
1758 	/* Attempt to attach the protocol, in case it isn't attached */
1759 	error = in6_domifattach(ifp);
1760 	if (error == 0) {
1761 		/* PF_INET6 wasn't previously attached */
1762 		error = in6_ifattach_aliasreq(ifp, NULL, NULL);
1763 		if (error != 0) {
1764 			goto done;
1765 		}
1766 
1767 		in6_if_up_dad_start(ifp);
1768 	} else if (error != EEXIST) {
1769 		goto done;
1770 	}
1771 
1772 	/*
1773 	 * First, make or update the interface address structure, and link it
1774 	 * to the list.
1775 	 */
1776 	error = in6_update_ifa(ifp, ifra, 0, &ia);
1777 	if (error != 0) {
1778 		goto done;
1779 	}
1780 	VERIFY(ia != NULL);
1781 
1782 	/* Now, make the prefix on-link on the interface. */
1783 	plen = (uint8_t)in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL);
1784 	if (plen == 128) {
1785 		goto done;
1786 	}
1787 
1788 	/*
1789 	 * NOTE: We'd rather create the prefix before the address, but we need
1790 	 * at least one address to install the corresponding interface route,
1791 	 * so we configure the address first.
1792 	 */
1793 
1794 	/*
1795 	 * Convert mask to prefix length (prefixmask has already been validated
1796 	 * in in6_update_ifa().
1797 	 */
1798 	bzero(&pr0, sizeof(pr0));
1799 	pr0.ndpr_plen = plen;
1800 	pr0.ndpr_ifp = ifp;
1801 	pr0.ndpr_prefix = ifra->ifra_addr;
1802 	pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
1803 
1804 	/* apply the mask for safety. */
1805 	for (i = 0; i < 4; i++) {
1806 		pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
1807 		    ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
1808 	}
1809 
1810 	/*
1811 	 * Since we don't have an API to set prefix (not address) lifetimes, we
1812 	 * just use the same lifetimes as addresses. The (temporarily)
1813 	 * installed lifetimes can be overridden by later advertised RAs (when
1814 	 * accept_rtadv is non 0), which is an intended behavior.
1815 	 */
1816 	pr0.ndpr_raf_onlink = 1; /* should be configurable? */
1817 	pr0.ndpr_raf_auto = !!(ifra->ifra_flags & IN6_IFF_AUTOCONF);
1818 	if (ifra->ifra_flags & (IN6_IFF_AUTOCONF | IN6_IFF_DYNAMIC)) {
1819 		pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
1820 		pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
1821 	} else {
1822 		pr0.ndpr_vltime = ND6_INFINITE_LIFETIME;
1823 		pr0.ndpr_pltime = ND6_INFINITE_LIFETIME;
1824 	}
1825 	pr0.ndpr_stateflags |= NDPRF_STATIC;
1826 	lck_mtx_init(&pr0.ndpr_lock, &ifa_mtx_grp, &ifa_mtx_attr);
1827 
1828 	/* add the prefix if there's none. */
1829 	if ((pr = nd6_prefix_lookup(&pr0, ND6_PREFIX_EXPIRY_NEVER)) == NULL) {
1830 		/*
1831 		 * nd6_prelist_add will install the corresponding interface
1832 		 * route.
1833 		 */
1834 		error = nd6_prelist_add(&pr0, NULL, &pr, FALSE);
1835 		if (error != 0) {
1836 			goto done;
1837 		}
1838 
1839 		if (pr == NULL) {
1840 			log(LOG_ERR, "%s: nd6_prelist_add okay, but"
1841 			    " no prefix.\n", __func__);
1842 			error = EINVAL;
1843 			goto done;
1844 		}
1845 	}
1846 
1847 	IFA_LOCK(&ia->ia_ifa);
1848 
1849 	/* if this is a new autoconfed addr */
1850 	addtmp = FALSE;
1851 	if (ia->ia6_ndpr == NULL) {
1852 		NDPR_LOCK(pr);
1853 		++pr->ndpr_addrcnt;
1854 		if (!(ia->ia6_flags & IN6_IFF_NOTMANUAL)) {
1855 			++pr->ndpr_manual_addrcnt;
1856 			VERIFY(pr->ndpr_manual_addrcnt != 0);
1857 		}
1858 		VERIFY(pr->ndpr_addrcnt != 0);
1859 		ia->ia6_ndpr = pr;
1860 		NDPR_ADDREF(pr); /* for addr reference */
1861 
1862 		/*
1863 		 * If this is the first autoconf address from the prefix,
1864 		 * create a temporary address as well (when specified).
1865 		 */
1866 		if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
1867 		    ip6_use_tempaddr &&
1868 		    pr->ndpr_addrcnt == 1 &&
1869 		    (!IN6_IS_ADDR_UNIQUE_LOCAL(&ia->ia_addr.sin6_addr)
1870 		    || ip6_ula_use_tempaddr)) {
1871 			addtmp = true;
1872 		}
1873 		NDPR_UNLOCK(pr);
1874 	}
1875 
1876 	IFA_UNLOCK(&ia->ia_ifa);
1877 
1878 	if (addtmp) {
1879 		int e;
1880 		e = in6_tmpifadd(ia, 1);
1881 		if (e != 0) {
1882 			log(LOG_NOTICE, "%s: failed to create a"
1883 			    " temporary address, error=%d\n",
1884 			    __func__, e);
1885 		}
1886 	}
1887 
1888 	/*
1889 	 * This might affect the status of autoconfigured addresses, that is,
1890 	 * this address might make other addresses detached.
1891 	 */
1892 	lck_mtx_lock(nd6_mutex);
1893 	pfxlist_onlink_check();
1894 	lck_mtx_unlock(nd6_mutex);
1895 
1896 	/* Drop use count held above during lookup/add */
1897 	NDPR_REMREF(pr);
1898 
1899 done:
1900 	if (ia != NULL) {
1901 		IFA_REMREF(&ia->ia_ifa);
1902 	}
1903 	return error;
1904 }
1905 
1906 static __attribute__((noinline)) void
in6ctl_difaddr(struct ifnet * ifp,struct in6_ifaddr * ia)1907 in6ctl_difaddr(struct ifnet *ifp, struct in6_ifaddr *ia)
1908 {
1909 	int i = 0;
1910 	struct nd_prefix pr0, *pr;
1911 
1912 	VERIFY(ifp != NULL && ia != NULL);
1913 
1914 	/*
1915 	 * If the address being deleted is the only one that owns
1916 	 * the corresponding prefix, expire the prefix as well.
1917 	 * XXX: theoretically, we don't have to worry about such
1918 	 * relationship, since we separate the address management
1919 	 * and the prefix management.  We do this, however, to provide
1920 	 * as much backward compatibility as possible in terms of
1921 	 * the ioctl operation.
1922 	 * Note that in6_purgeaddr() will decrement ndpr_addrcnt.
1923 	 */
1924 	IFA_LOCK(&ia->ia_ifa);
1925 	bzero(&pr0, sizeof(pr0));
1926 	pr0.ndpr_ifp = ifp;
1927 	pr0.ndpr_plen = (uint8_t)in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
1928 	if (pr0.ndpr_plen == 128) {
1929 		IFA_UNLOCK(&ia->ia_ifa);
1930 		goto purgeaddr;
1931 	}
1932 	pr0.ndpr_prefix = ia->ia_addr;
1933 	pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
1934 	for (i = 0; i < 4; i++) {
1935 		pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
1936 		    ia->ia_prefixmask.sin6_addr.s6_addr32[i];
1937 	}
1938 	IFA_UNLOCK(&ia->ia_ifa);
1939 
1940 	if ((pr = nd6_prefix_lookup(&pr0, ND6_PREFIX_EXPIRY_UNSPEC)) != NULL) {
1941 		IFA_LOCK(&ia->ia_ifa);
1942 		NDPR_LOCK(pr);
1943 		if (pr->ndpr_addrcnt == 1) {
1944 			/* XXX: just for expiration */
1945 			pr->ndpr_expire = 1;
1946 		}
1947 		NDPR_UNLOCK(pr);
1948 		IFA_UNLOCK(&ia->ia_ifa);
1949 
1950 		/* Drop use count held above during lookup */
1951 		NDPR_REMREF(pr);
1952 	}
1953 
1954 purgeaddr:
1955 	in6_purgeaddr(&ia->ia_ifa);
1956 }
1957 
1958 static __attribute__((noinline)) int
in6_autoconf(struct ifnet * ifp,int enable)1959 in6_autoconf(struct ifnet *ifp, int enable)
1960 {
1961 	int error = 0;
1962 
1963 	VERIFY(ifp != NULL);
1964 
1965 	if (ifp->if_flags & IFF_LOOPBACK) {
1966 		return EINVAL;
1967 	}
1968 
1969 	if (enable) {
1970 		/*
1971 		 * An interface in IPv6 router mode implies that it
1972 		 * is either configured with a static IP address or
1973 		 * autoconfigured via a locally-generated RA.  Prevent
1974 		 * SIOCAUTOCONF_START from being set in that mode.
1975 		 */
1976 		ifnet_lock_exclusive(ifp);
1977 		if (ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_EXCLUSIVE) {
1978 			if_clear_eflags(ifp, IFEF_ACCEPT_RTADV);
1979 			error = EBUSY;
1980 		} else {
1981 			if_set_eflags(ifp, IFEF_ACCEPT_RTADV);
1982 		}
1983 		ifnet_lock_done(ifp);
1984 	} else {
1985 		struct in6_ifaddr *ia = NULL;
1986 
1987 		if_clear_eflags(ifp, IFEF_ACCEPT_RTADV);
1988 
1989 		/* Remove autoconfigured address from interface */
1990 		lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
1991 		boolean_t from_begining = TRUE;
1992 		while (from_begining) {
1993 			from_begining = FALSE;
1994 			TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
1995 				if (ia->ia_ifa.ifa_ifp != ifp) {
1996 					continue;
1997 				}
1998 				IFA_LOCK(&ia->ia_ifa);
1999 				if (ia->ia6_flags & IN6_IFF_AUTOCONF) {
2000 					IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for us */
2001 					IFA_UNLOCK(&ia->ia_ifa);
2002 					lck_rw_done(&in6_ifaddr_rwlock);
2003 					in6_purgeaddr(&ia->ia_ifa);
2004 					IFA_REMREF(&ia->ia_ifa);        /* for us */
2005 					lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2006 					/*
2007 					 * Purging the address caused in6_ifaddr_rwlock
2008 					 * to be dropped and reacquired;
2009 					 * therefore search again from the beginning
2010 					 * of in6_ifaddrs list.
2011 					 */
2012 					from_begining = TRUE;
2013 					break;
2014 				}
2015 				IFA_UNLOCK(&ia->ia_ifa);
2016 			}
2017 		}
2018 		lck_rw_done(&in6_ifaddr_rwlock);
2019 	}
2020 	return error;
2021 }
2022 
2023 /*
2024  * Handle SIOCSETROUTERMODE_IN6 to set the IPv6 router mode on the interface
2025  * Entering or exiting IPV6_ROUTER_MODE_EXCLUSIVE will result in the removal of
2026  * autoconfigured IPv6 addresses on the interface.
2027  */
2028 static __attribute__((noinline)) int
in6_setrouter(struct ifnet * ifp,ipv6_router_mode_t mode)2029 in6_setrouter(struct ifnet *ifp, ipv6_router_mode_t mode)
2030 {
2031 	int                     error = 0;
2032 	ipv6_router_mode_t      prev_mode;
2033 
2034 	VERIFY(ifp != NULL);
2035 
2036 	if (ifp->if_flags & IFF_LOOPBACK) {
2037 		return ENODEV;
2038 	}
2039 
2040 	prev_mode = ifp->if_ipv6_router_mode;
2041 	if (prev_mode == mode) {
2042 		/* no mode change, there's nothing to do */
2043 		return 0;
2044 	}
2045 	if (mode == IPV6_ROUTER_MODE_EXCLUSIVE) {
2046 		struct nd_ifinfo *ndi = NULL;
2047 
2048 		ndi = ND_IFINFO(ifp);
2049 		if (ndi != NULL && ndi->initialized) {
2050 			lck_mtx_lock(&ndi->lock);
2051 			if (ndi->flags & ND6_IFF_PROXY_PREFIXES) {
2052 				/* No proxy if we are an advertising router */
2053 				ndi->flags &= ~ND6_IFF_PROXY_PREFIXES;
2054 				lck_mtx_unlock(&ndi->lock);
2055 				(void) nd6_if_prproxy(ifp, FALSE);
2056 			} else {
2057 				lck_mtx_unlock(&ndi->lock);
2058 			}
2059 		}
2060 	}
2061 
2062 	ifp->if_ipv6_router_mode = mode;
2063 	lck_mtx_lock(nd6_mutex);
2064 	defrouter_select(ifp, NULL);
2065 	lck_mtx_unlock(nd6_mutex);
2066 	if_allmulti(ifp, (mode == IPV6_ROUTER_MODE_EXCLUSIVE));
2067 	if (mode == IPV6_ROUTER_MODE_EXCLUSIVE ||
2068 	    (prev_mode == IPV6_ROUTER_MODE_EXCLUSIVE
2069 	    && mode == IPV6_ROUTER_MODE_DISABLED)) {
2070 		error = in6_autoconf(ifp, FALSE);
2071 	}
2072 	return error;
2073 }
2074 
2075 static int
in6_to_kamescope(struct sockaddr_in6 * sin6,struct ifnet * ifp)2076 in6_to_kamescope(struct sockaddr_in6 *sin6, struct ifnet *ifp)
2077 {
2078 	struct sockaddr_in6 tmp;
2079 	int error, id;
2080 
2081 	VERIFY(sin6 != NULL);
2082 	tmp = *sin6;
2083 
2084 	error = in6_recoverscope(&tmp, &sin6->sin6_addr, ifp);
2085 	if (error != 0) {
2086 		return error;
2087 	}
2088 
2089 	id = in6_addr2scopeid(ifp, &tmp.sin6_addr);
2090 	if (tmp.sin6_scope_id == 0) {
2091 		tmp.sin6_scope_id = id;
2092 	} else if (tmp.sin6_scope_id != id) {
2093 		return EINVAL; /* scope ID mismatch. */
2094 	}
2095 	error = in6_embedscope(&tmp.sin6_addr, &tmp, NULL, NULL, NULL, IN6_NULL_IF_EMBEDDED_SCOPE(&tmp.sin6_scope_id));
2096 	if (error != 0) {
2097 		return error;
2098 	}
2099 
2100 	if (in6_embedded_scope || !IN6_IS_SCOPE_EMBED(&tmp.sin6_addr)) {
2101 		tmp.sin6_scope_id = 0;
2102 	}
2103 	*sin6 = tmp;
2104 	return 0;
2105 }
2106 
2107 /*
2108  * When the address is being configured we should clear out certain flags
2109  * coming in from the caller.
2110  */
2111 #define IN6_IFF_CLR_ADDR_FLAG_MASK      (~(IN6_IFF_DEPRECATED | IN6_IFF_DETACHED | IN6_IFF_DUPLICATED))
2112 
2113 static int
in6_ifaupdate_aux(struct in6_ifaddr * ia,struct ifnet * ifp,int ifaupflags)2114 in6_ifaupdate_aux(struct in6_ifaddr *ia, struct ifnet *ifp, int ifaupflags)
2115 {
2116 	struct sockaddr_in6 mltaddr, mltmask;
2117 	struct in6_addr llsol;
2118 	struct ifaddr *ifa;
2119 	struct in6_multi *in6m_sol;
2120 	struct in6_multi_mship *imm;
2121 	struct rtentry *rt;
2122 	int delay, error = 0;
2123 
2124 	VERIFY(ifp != NULL && ia != NULL);
2125 	ifa = &ia->ia_ifa;
2126 	in6m_sol = NULL;
2127 
2128 	nd6log2(debug, "%s - %s ifp %s ia6_flags 0x%x ifaupflags 0x%x\n",
2129 	    __func__,
2130 	    ip6_sprintf(&ia->ia_addr.sin6_addr),
2131 	    if_name(ia->ia_ifp),
2132 	    ia->ia6_flags,
2133 	    ifaupflags);
2134 
2135 	/*
2136 	 * Just to be safe, always clear certain flags when address
2137 	 * is being configured
2138 	 */
2139 	ia->ia6_flags &= IN6_IFF_CLR_ADDR_FLAG_MASK;
2140 
2141 	/*
2142 	 * Mark the address as tentative before joining multicast addresses,
2143 	 * so that corresponding MLD responses would not have a tentative
2144 	 * source address.
2145 	 */
2146 	if (in6if_do_dad(ifp)) {
2147 		in6_ifaddr_set_dadprogress(ia);
2148 		/*
2149 		 * Do not delay sending neighbor solicitations when using optimistic
2150 		 * duplicate address detection, c.f. RFC 4429.
2151 		 */
2152 		if (ia->ia6_flags & IN6_IFF_OPTIMISTIC) {
2153 			ifaupflags &= ~IN6_IFAUPDATE_DADDELAY;
2154 		} else {
2155 			ifaupflags |= IN6_IFAUPDATE_DADDELAY;
2156 		}
2157 	} else {
2158 		/*
2159 		 * If the interface has been marked to not perform
2160 		 * DAD, make sure to reset DAD in progress flags
2161 		 * that may come in from the caller.
2162 		 */
2163 		ia->ia6_flags &= ~IN6_IFF_DADPROGRESS;
2164 	}
2165 
2166 	/* Join necessary multicast groups */
2167 	if ((ifp->if_flags & IFF_MULTICAST) != 0) {
2168 		/* join solicited multicast addr for new host id */
2169 		bzero(&llsol, sizeof(struct in6_addr));
2170 		llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
2171 		llsol.s6_addr32[1] = 0;
2172 		llsol.s6_addr32[2] = htonl(1);
2173 		llsol.s6_addr32[3] = ia->ia_addr.sin6_addr.s6_addr32[3];
2174 		llsol.s6_addr8[12] = 0xff;
2175 		if ((error = in6_setscope(&llsol, ifp, NULL)) != 0) {
2176 			/* XXX: should not happen */
2177 			log(LOG_ERR, "%s: in6_setscope failed\n", __func__);
2178 			goto unwind;
2179 		}
2180 		delay = 0;
2181 		if ((ifaupflags & IN6_IFAUPDATE_DADDELAY)) {
2182 			/*
2183 			 * We need a random delay for DAD on the address
2184 			 * being configured.  It also means delaying
2185 			 * transmission of the corresponding MLD report to
2186 			 * avoid report collision. [RFC 4862]
2187 			 */
2188 			delay = random() % MAX_RTR_SOLICITATION_DELAY;
2189 		}
2190 		imm = in6_joingroup(ifp, &llsol, &error, delay);
2191 		if (imm == NULL) {
2192 			nd6log(info,
2193 			    "%s: addmulti failed for %s on %s (errno=%d)\n",
2194 			    __func__, ip6_sprintf(&llsol), if_name(ifp),
2195 			    error);
2196 			VERIFY(error != 0);
2197 			goto unwind;
2198 		}
2199 		in6m_sol = imm->i6mm_maddr;
2200 		/* take a refcount for this routine */
2201 		IN6M_ADDREF(in6m_sol);
2202 
2203 		IFA_LOCK_SPIN(ifa);
2204 		LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
2205 		IFA_UNLOCK(ifa);
2206 
2207 		bzero(&mltmask, sizeof(mltmask));
2208 		mltmask.sin6_len = sizeof(struct sockaddr_in6);
2209 		mltmask.sin6_family = AF_INET6;
2210 		mltmask.sin6_addr = in6mask32;
2211 #define MLTMASK_LEN  4  /* mltmask's masklen (=32bit=4octet) */
2212 
2213 		/*
2214 		 * join link-local all-nodes address
2215 		 */
2216 		bzero(&mltaddr, sizeof(mltaddr));
2217 		mltaddr.sin6_len = sizeof(struct sockaddr_in6);
2218 		mltaddr.sin6_family = AF_INET6;
2219 		mltaddr.sin6_addr = in6addr_linklocal_allnodes;
2220 		if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, IN6_NULL_IF_EMBEDDED_SCOPE(&mltaddr.sin6_scope_id))) != 0) {
2221 			goto unwind; /* XXX: should not fail */
2222 		}
2223 		/*
2224 		 * XXX: do we really need this automatic routes?
2225 		 * We should probably reconsider this stuff.  Most applications
2226 		 * actually do not need the routes, since they usually specify
2227 		 * the outgoing interface.
2228 		 */
2229 		rt = rtalloc1_scoped((struct sockaddr *)&mltaddr, 0, 0UL,
2230 		    ia->ia_ifp->if_index);
2231 		if (rt) {
2232 			if (memcmp(&mltaddr.sin6_addr, &((struct sockaddr_in6 *)
2233 			    (void *)rt_key(rt))->sin6_addr, MLTMASK_LEN)) {
2234 				rtfree(rt);
2235 				rt = NULL;
2236 			}
2237 		}
2238 		if (!rt) {
2239 			error = rtrequest_scoped(RTM_ADD,
2240 			    (struct sockaddr *)&mltaddr,
2241 			    (struct sockaddr *)&ia->ia_addr,
2242 			    (struct sockaddr *)&mltmask, RTF_UP | RTF_CLONING,
2243 			    NULL, ia->ia_ifp->if_index);
2244 			if (error) {
2245 				goto unwind;
2246 			}
2247 		} else {
2248 			rtfree(rt);
2249 		}
2250 
2251 		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
2252 		if (!imm) {
2253 			nd6log(info,
2254 			    "%s: addmulti failed for %s on %s (errno=%d)\n",
2255 			    __func__, ip6_sprintf(&mltaddr.sin6_addr),
2256 			    if_name(ifp), error);
2257 			VERIFY(error != 0);
2258 			goto unwind;
2259 		}
2260 		IFA_LOCK_SPIN(ifa);
2261 		LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
2262 		IFA_UNLOCK(ifa);
2263 
2264 		/*
2265 		 * join node information group address
2266 		 */
2267 #define hostnamelen     strlen(hostname)
2268 		delay = 0;
2269 		if ((ifaupflags & IN6_IFAUPDATE_DADDELAY)) {
2270 			/*
2271 			 * The spec doesn't say anything about delay for this
2272 			 * group, but the same logic should apply.
2273 			 */
2274 			delay = random() % MAX_RTR_SOLICITATION_DELAY;
2275 		}
2276 		lck_mtx_lock(&hostname_lock);
2277 		int n = in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr, IN6_NULL_IF_EMBEDDED_SCOPE(&mltaddr.sin6_scope_id));
2278 		lck_mtx_unlock(&hostname_lock);
2279 		if (n == 0) {
2280 			imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error,
2281 			    delay); /* XXX jinmei */
2282 			if (!imm) {
2283 				nd6log(info,
2284 				    "%s: addmulti failed for %s on %s "
2285 				    "(errno=%d)\n",
2286 				    __func__, ip6_sprintf(&mltaddr.sin6_addr),
2287 				    if_name(ifp), error);
2288 				/* XXX not very fatal, go on... */
2289 				error = 0;
2290 			} else {
2291 				IFA_LOCK_SPIN(ifa);
2292 				LIST_INSERT_HEAD(&ia->ia6_memberships,
2293 				    imm, i6mm_chain);
2294 				IFA_UNLOCK(ifa);
2295 			}
2296 		}
2297 #undef hostnamelen
2298 
2299 		/*
2300 		 * join interface-local all-nodes address.
2301 		 * (ff01::1%ifN, and ff01::%ifN/32)
2302 		 */
2303 		mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
2304 		if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, IN6_NULL_IF_EMBEDDED_SCOPE(&mltaddr.sin6_scope_id))) != 0) {
2305 			goto unwind; /* XXX: should not fail */
2306 		}
2307 		/* XXX: again, do we really need the route? */
2308 		rt = rtalloc1_scoped((struct sockaddr *)&mltaddr, 0, 0UL,
2309 		    ia->ia_ifp->if_index);
2310 		if (rt) {
2311 			if (memcmp(&mltaddr.sin6_addr, &((struct sockaddr_in6 *)
2312 			    (void *)rt_key(rt))->sin6_addr, MLTMASK_LEN)) {
2313 				rtfree(rt);
2314 				rt = NULL;
2315 			}
2316 		}
2317 		if (!rt) {
2318 			error = rtrequest_scoped(RTM_ADD,
2319 			    (struct sockaddr *)&mltaddr,
2320 			    (struct sockaddr *)&ia->ia_addr,
2321 			    (struct sockaddr *)&mltmask, RTF_UP | RTF_CLONING,
2322 			    NULL, ia->ia_ifp->if_index);
2323 			if (error) {
2324 				goto unwind;
2325 			}
2326 		} else {
2327 			rtfree(rt);
2328 		}
2329 
2330 		imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error, 0);
2331 		if (!imm) {
2332 			nd6log(info,
2333 			    "%s: addmulti failed for %s on %s (errno=%d)\n",
2334 			    __func__, ip6_sprintf(&mltaddr.sin6_addr),
2335 			    if_name(ifp), error);
2336 			VERIFY(error != 0);
2337 			goto unwind;
2338 		}
2339 		IFA_LOCK(ifa);
2340 		LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
2341 		IFA_UNLOCK(ifa);
2342 #undef  MLTMASK_LEN
2343 
2344 		/*
2345 		 * create a ff00::/8 route
2346 		 */
2347 		bzero(&mltmask, sizeof(mltmask));
2348 		mltmask.sin6_len = sizeof(struct sockaddr_in6);
2349 		mltmask.sin6_family = AF_INET6;
2350 		mltmask.sin6_addr = in6mask8;
2351 #define MLTMASK_LEN_8_BITS  1  /* ff00::/8 mltmask's masklen (=8bit=1octet) */
2352 
2353 		bzero(&mltaddr, sizeof(mltaddr));
2354 		mltaddr.sin6_len = sizeof(struct sockaddr_in6);
2355 		mltaddr.sin6_family = AF_INET6;
2356 		mltaddr.sin6_addr = in6addr_multicast_prefix;
2357 
2358 		rt = rtalloc1_scoped((struct sockaddr *)&mltaddr, 0, 0UL,
2359 		    ia->ia_ifp->if_index);
2360 		if (rt) {
2361 			if (memcmp(&mltaddr.sin6_addr, &((struct sockaddr_in6 *)
2362 			    (void *)rt_key(rt))->sin6_addr, MLTMASK_LEN_8_BITS)) {
2363 				rtfree(rt);
2364 				rt = NULL;
2365 			}
2366 		}
2367 		if (!rt) {
2368 			error = rtrequest_scoped(RTM_ADD,
2369 			    (struct sockaddr *)&mltaddr,
2370 			    (struct sockaddr *)&ia->ia_addr,
2371 			    (struct sockaddr *)&mltmask, RTF_UP | RTF_CLONING,
2372 			    NULL, ia->ia_ifp->if_index);
2373 			if (error) {
2374 				goto unwind;
2375 			}
2376 		} else {
2377 			rtfree(rt);
2378 		}
2379 	}
2380 #undef  MLTMASK_LEN_8_BITS
2381 
2382 	/* Ensure nd6_service() is scheduled as soon as it's convenient */
2383 	++nd6_sched_timeout_want;
2384 
2385 	/*
2386 	 * Perform DAD, if:
2387 	 * * Interface is marked to perform DAD, AND
2388 	 * * Address is not marked to skip DAD, AND
2389 	 * * Address is in a pre-DAD state (Tentative or Optimistic)
2390 	 */
2391 	IFA_LOCK_SPIN(ifa);
2392 	if (in6if_do_dad(ifp) && (ia->ia6_flags & IN6_IFF_NODAD) == 0 &&
2393 	    (ia->ia6_flags & IN6_IFF_DADPROGRESS) != 0) {
2394 		int mindelay, maxdelay;
2395 		int *delayptr, delayval;
2396 
2397 		IFA_UNLOCK(ifa);
2398 		delayptr = NULL;
2399 		/*
2400 		 * Avoid the DAD delay if the caller wants us to skip it.
2401 		 * This is not compliant with RFC 2461, but it's only being
2402 		 * used for signalling and not for actual DAD.
2403 		 */
2404 		if ((ifaupflags & IN6_IFAUPDATE_DADDELAY) &&
2405 		    !(ia->ia6_flags & IN6_IFF_SWIFTDAD)) {
2406 			/*
2407 			 * We need to impose a delay before sending an NS
2408 			 * for DAD.  Check if we also needed a delay for the
2409 			 * corresponding MLD message.  If we did, the delay
2410 			 * should be larger than the MLD delay (this could be
2411 			 * relaxed a bit, but this simple logic is at least
2412 			 * safe).
2413 			 */
2414 			mindelay = 0;
2415 			if (in6m_sol != NULL) {
2416 				IN6M_LOCK(in6m_sol);
2417 				if (in6m_sol->in6m_state ==
2418 				    MLD_REPORTING_MEMBER) {
2419 					mindelay = in6m_sol->in6m_timer;
2420 				}
2421 				IN6M_UNLOCK(in6m_sol);
2422 			}
2423 			maxdelay = MAX_RTR_SOLICITATION_DELAY * hz;
2424 			if (maxdelay - mindelay == 0) {
2425 				delayval = 0;
2426 			} else {
2427 				delayval =
2428 				    (random() % (maxdelay - mindelay)) +
2429 				    mindelay;
2430 			}
2431 			delayptr = &delayval;
2432 		}
2433 
2434 		nd6_dad_start((struct ifaddr *)ia, delayptr);
2435 	} else {
2436 		IFA_UNLOCK(ifa);
2437 	}
2438 
2439 	goto done;
2440 
2441 unwind:
2442 	VERIFY(error != 0);
2443 	in6_purgeaddr(&ia->ia_ifa);
2444 
2445 done:
2446 	/* release reference held for this routine */
2447 	if (in6m_sol != NULL) {
2448 		IN6M_REMREF(in6m_sol);
2449 	}
2450 	return error;
2451 }
2452 
2453 /*
2454  * Request an IPv6 interface address.  If the address is new, then it will be
2455  * constructed and appended to the interface address chains.  The interface
2456  * address structure is optionally returned with a reference for the caller.
2457  */
2458 int
in6_update_ifa(struct ifnet * ifp,struct in6_aliasreq * ifra,int ifaupflags,struct in6_ifaddr ** iar)2459 in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, int ifaupflags,
2460     struct in6_ifaddr **iar)
2461 {
2462 	struct in6_addrlifetime ia6_lt;
2463 	struct in6_ifaddr *ia;
2464 	struct ifaddr *ifa;
2465 	struct ifaddr *xifa;
2466 	struct in6_addrlifetime *lt;
2467 	uint64_t timenow;
2468 	int plen, error;
2469 
2470 	/* Sanity check parameters and initialize locals */
2471 	VERIFY(ifp != NULL && ifra != NULL && iar != NULL);
2472 	ia = NULL;
2473 	ifa = NULL;
2474 	error = 0;
2475 
2476 	/*
2477 	 * We always require users to specify a valid IPv6 address for
2478 	 * the corresponding operation.
2479 	 */
2480 	if (ifra->ifra_addr.sin6_family != AF_INET6 ||
2481 	    ifra->ifra_addr.sin6_len != sizeof(struct sockaddr_in6)) {
2482 		error = EAFNOSUPPORT;
2483 		goto unwind;
2484 	}
2485 
2486 	/* Validate ifra_prefixmask.sin6_len is properly bounded. */
2487 	if (ifra->ifra_prefixmask.sin6_len == 0 ||
2488 	    ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6)) {
2489 		error = EINVAL;
2490 		goto unwind;
2491 	}
2492 
2493 	/* Validate prefix length extracted from ifra_prefixmask structure. */
2494 	plen = (uint8_t)in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
2495 	    (u_char *)&ifra->ifra_prefixmask + ifra->ifra_prefixmask.sin6_len);
2496 	if (plen <= 0) {
2497 		error = EINVAL;
2498 		goto unwind;
2499 	}
2500 
2501 	/* Validate lifetimes */
2502 	lt = &ifra->ifra_lifetime;
2503 	if (lt->ia6t_pltime > lt->ia6t_vltime) {
2504 		log(LOG_INFO,
2505 		    "%s: pltime 0x%x > vltime 0x%x for %s\n", __func__,
2506 		    lt->ia6t_pltime, lt->ia6t_vltime,
2507 		    ip6_sprintf(&ifra->ifra_addr.sin6_addr));
2508 		error = EINVAL;
2509 		goto unwind;
2510 	}
2511 	if (lt->ia6t_vltime == 0) {
2512 		/*
2513 		 * the following log might be noisy, but this is a typical
2514 		 * configuration mistake or a tool's bug.
2515 		 */
2516 		log(LOG_INFO, "%s: valid lifetime is 0 for %s\n", __func__,
2517 		    ip6_sprintf(&ifra->ifra_addr.sin6_addr));
2518 	}
2519 
2520 	/*
2521 	 * Before we lock the ifnet structure, we first check to see if the
2522 	 * address already exists. If so, then we don't allocate and link a
2523 	 * new one here.
2524 	 */
2525 	struct sockaddr_in6 lookup_address = ifra->ifra_addr;
2526 	if (IN6_IS_ADDR_LINKLOCAL(&lookup_address.sin6_addr)) {
2527 		if (in6_embedded_scope) {
2528 			if (lookup_address.sin6_addr.s6_addr16[1] == 0) {
2529 				/* link ID is not embedded by the user */
2530 				lookup_address.sin6_addr.s6_addr16[1] =
2531 				    htons(ifp->if_index);
2532 			} else if (lookup_address.sin6_addr.s6_addr16[1] !=
2533 			    htons(ifp->if_index)) {
2534 				error = EINVAL; /* link ID contradicts */
2535 				goto done;
2536 			}
2537 		} else {
2538 			if (lookup_address.sin6_scope_id == IFSCOPE_NONE) {
2539 				lookup_address.sin6_scope_id = ifp->if_index;
2540 			}
2541 		}
2542 		if (lookup_address.sin6_scope_id != 0 &&
2543 		    lookup_address.sin6_scope_id !=
2544 		    (u_int32_t)ifp->if_index) {
2545 			error = EINVAL;
2546 			goto done;
2547 		}
2548 	}
2549 
2550 	ia = in6ifa_ifpwithaddr(ifp, &lookup_address.sin6_addr);
2551 	if (ia != NULL) {
2552 		ifa = &ia->ia_ifa;
2553 	}
2554 
2555 	/*
2556 	 * Validate destination address on interface types that require it.
2557 	 */
2558 	if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) {
2559 		switch (ifra->ifra_dstaddr.sin6_family) {
2560 		case AF_INET6:
2561 			if (plen != 128) {
2562 				/* noisy message for diagnostic purposes */
2563 				log(LOG_INFO,
2564 				    "%s: prefix length < 128 with"
2565 				    " explicit dstaddr.\n", __func__);
2566 				error = EINVAL;
2567 				goto unwind;
2568 			}
2569 			break;
2570 
2571 		case AF_UNSPEC:
2572 			break;
2573 
2574 		default:
2575 			error = EAFNOSUPPORT;
2576 			goto unwind;
2577 		}
2578 	} else if (ifra->ifra_dstaddr.sin6_family != AF_UNSPEC) {
2579 		log(LOG_INFO,
2580 		    "%s: dstaddr valid only on p2p and loopback interfaces.\n",
2581 		    __func__);
2582 		error = EINVAL;
2583 		goto unwind;
2584 	}
2585 
2586 	timenow = net_uptime();
2587 
2588 	if (ia == NULL) {
2589 		zalloc_flags_t how;
2590 
2591 		/* Is this the first new IPv6 address for the interface? */
2592 		ifaupflags |= IN6_IFAUPDATE_NEWADDR;
2593 
2594 		/* Allocate memory for IPv6 interface address structure. */
2595 		how = (ifaupflags & IN6_IFAUPDATE_NOWAIT) ? Z_NOWAIT : Z_WAITOK;
2596 		ia = in6_ifaddr_alloc(how);
2597 		if (ia == NULL) {
2598 			error = ENOBUFS;
2599 			goto unwind;
2600 		}
2601 
2602 		ifa = &ia->ia_ifa;
2603 
2604 		/*
2605 		 * Initialize interface address structure.
2606 		 *
2607 		 * Note well: none of these sockaddr_in6 structures contain a
2608 		 * valid sin6_port, sin6_flowinfo or even a sin6_scope_id field.
2609 		 * We still embed link-local scope identifiers at the end of an
2610 		 * arbitrary fe80::/32 prefix, for historical reasons. Also, the
2611 		 * ifa_dstaddr field is always non-NULL on point-to-point and
2612 		 * loopback interfaces, and conventionally points to a socket
2613 		 * address of AF_UNSPEC family when there is no destination.
2614 		 *
2615 		 * Please enjoy the dancing sea turtle.
2616 		 */
2617 		IFA_ADDREF(ifa); /* for this and optionally for caller */
2618 		IA6_HASH_INIT(ia);
2619 		ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
2620 		if (ifra->ifra_dstaddr.sin6_family == AF_INET6 ||
2621 		    (ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
2622 			ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
2623 		}
2624 		ifa->ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask;
2625 		ifa->ifa_ifp = ifp;
2626 		ifa->ifa_metric = ifp->if_metric;
2627 		ifa->ifa_rtrequest = nd6_rtrequest;
2628 
2629 		LIST_INIT(&ia->ia6_memberships);
2630 		ia->ia_addr.sin6_family = AF_INET6;
2631 		ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
2632 		ia->ia_addr.sin6_addr = ifra->ifra_addr.sin6_addr;
2633 		ia->ia_prefixmask.sin6_family = AF_INET6;
2634 		ia->ia_prefixmask.sin6_len = sizeof(ia->ia_prefixmask);
2635 		ia->ia_prefixmask.sin6_addr = ifra->ifra_prefixmask.sin6_addr;
2636 		error = in6_to_kamescope(&ia->ia_addr, ifp);
2637 		if (error != 0) {
2638 			goto unwind;
2639 		}
2640 		if (ifa->ifa_dstaddr != NULL) {
2641 			ia->ia_dstaddr = ifra->ifra_dstaddr;
2642 			error = in6_to_kamescope(&ia->ia_dstaddr, ifp);
2643 			if (error != 0) {
2644 				goto unwind;
2645 			}
2646 		}
2647 
2648 		/* Append to address chains */
2649 		ifnet_lock_exclusive(ifp);
2650 		ifaupflags |= IN6_IFAUPDATE_1STADDR;
2651 		TAILQ_FOREACH(xifa, &ifp->if_addrlist, ifa_list) {
2652 			IFA_LOCK_SPIN(xifa);
2653 			if (xifa->ifa_addr->sa_family != AF_INET6) {
2654 				IFA_UNLOCK(xifa);
2655 				ifaupflags &= ~IN6_IFAUPDATE_1STADDR;
2656 				break;
2657 			}
2658 			IFA_UNLOCK(xifa);
2659 		}
2660 
2661 		IFA_LOCK_SPIN(ifa);
2662 		if_attach_ifa(ifp, ifa); /* holds reference for ifnet link */
2663 		IFA_UNLOCK(ifa);
2664 		ifnet_lock_done(ifp);
2665 
2666 		lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2667 		TAILQ_INSERT_TAIL(&in6_ifaddrhead, ia, ia6_link);
2668 		IFA_ADDREF(ifa); /* hold for in6_ifaddrs link */
2669 		os_atomic_inc(&in6_ifaddrlist_genid, relaxed);
2670 		lck_rw_done(&in6_ifaddr_rwlock);
2671 	} else {
2672 		ifa = &ia->ia_ifa;
2673 		ifaupflags &= ~(IN6_IFAUPDATE_NEWADDR | IN6_IFAUPDATE_1STADDR);
2674 	}
2675 
2676 	VERIFY(ia != NULL && ifa == &ia->ia_ifa);
2677 	IFA_LOCK(ifa);
2678 
2679 	/*
2680 	 * Set lifetimes.  We do not refer to ia6t_expire and ia6t_preferred
2681 	 * to see if the address is deprecated or invalidated, but initialize
2682 	 * these members for applications.
2683 	 */
2684 	ia->ia6_updatetime = ia->ia6_createtime = timenow;
2685 	ia6_lt = *lt;
2686 	if (ia6_lt.ia6t_vltime != ND6_INFINITE_LIFETIME) {
2687 		ia6_lt.ia6t_expire = (time_t)(timenow + ia6_lt.ia6t_vltime);
2688 	} else {
2689 		ia6_lt.ia6t_expire = 0;
2690 	}
2691 	if (ia6_lt.ia6t_pltime != ND6_INFINITE_LIFETIME) {
2692 		ia6_lt.ia6t_preferred = (time_t)(timenow + ia6_lt.ia6t_pltime);
2693 	} else {
2694 		ia6_lt.ia6t_preferred = 0;
2695 	}
2696 	in6ifa_setlifetime(ia, &ia6_lt);
2697 
2698 	/*
2699 	 * Backward compatibility - if IN6_IFF_DEPRECATED is set from the
2700 	 * userland, make it deprecated.
2701 	 */
2702 	if ((ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) {
2703 		ia->ia6_lifetime.ia6ti_pltime = 0;
2704 		ia->ia6_lifetime.ia6ti_preferred = timenow;
2705 	}
2706 
2707 	/*
2708 	 * Update flag or prefix length
2709 	 */
2710 	ia->ia_plen = plen;
2711 	ia->ia6_flags = ifra->ifra_flags;
2712 
2713 	/* Release locks (new address available to concurrent tasks) */
2714 	IFA_UNLOCK(ifa);
2715 
2716 	/* Further initialization of the interface address */
2717 	error = in6_ifinit(ifp, ia, ifaupflags);
2718 	if (error != 0) {
2719 		goto unwind;
2720 	}
2721 
2722 	/* Finish updating the address while other tasks are working with it */
2723 	error = in6_ifaupdate_aux(ia, ifp, ifaupflags);
2724 	if (error != 0) {
2725 		goto unwind;
2726 	}
2727 
2728 	/* Return success (optionally w/ address for caller). */
2729 	VERIFY(error == 0);
2730 	(void) ifnet_notify_address(ifp, AF_INET6);
2731 
2732 	goto done;
2733 
2734 unwind:
2735 	VERIFY(error != 0);
2736 	if (ia != NULL) {
2737 		VERIFY(ifa == &ia->ia_ifa);
2738 		IFA_REMREF(ifa);
2739 		ia = NULL;
2740 	}
2741 
2742 done:
2743 	*iar = ia;
2744 	return error;
2745 }
2746 
2747 void
in6_purgeaddr(struct ifaddr * ifa)2748 in6_purgeaddr(struct ifaddr *ifa)
2749 {
2750 	struct ifnet *ifp = ifa->ifa_ifp;
2751 	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
2752 	struct in6_multi_mship *imm;
2753 
2754 	LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
2755 
2756 	/* stop DAD processing */
2757 	nd6_dad_stop(ifa);
2758 
2759 	/*
2760 	 * delete route to the destination of the address being purged.
2761 	 * The interface must be p2p or loopback in this case.
2762 	 */
2763 	IFA_LOCK(ifa);
2764 	if ((ia->ia_flags & IFA_ROUTE) && ia->ia_plen == 128) {
2765 		int error, rtf;
2766 
2767 		IFA_UNLOCK(ifa);
2768 		rtf = (ia->ia_dstaddr.sin6_family == AF_INET6) ? RTF_HOST : 0;
2769 		error = rtinit(&(ia->ia_ifa), RTM_DELETE, rtf);
2770 		if (error != 0) {
2771 			log(LOG_ERR, "in6_purgeaddr: failed to remove "
2772 			    "a route to the p2p destination: %s on %s, "
2773 			    "errno=%d\n",
2774 			    ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
2775 			    error);
2776 			/* proceed anyway... */
2777 		}
2778 		IFA_LOCK_SPIN(ifa);
2779 		ia->ia_flags &= ~IFA_ROUTE;
2780 	}
2781 	IFA_UNLOCK(ifa);
2782 
2783 	/* Remove ownaddr's loopback rtentry, if it exists. */
2784 	in6_ifremloop(&(ia->ia_ifa));
2785 
2786 	/*
2787 	 * leave from multicast groups we have joined for the interface
2788 	 */
2789 	IFA_LOCK(ifa);
2790 	while ((imm = ia->ia6_memberships.lh_first) != NULL) {
2791 		LIST_REMOVE(imm, i6mm_chain);
2792 		IFA_UNLOCK(ifa);
2793 		in6_leavegroup(imm);
2794 		IFA_LOCK(ifa);
2795 	}
2796 	IFA_UNLOCK(ifa);
2797 
2798 	/* in6_unlink_ifa() will need exclusive access */
2799 	in6_unlink_ifa(ia, ifp);
2800 	in6_post_msg(ifp, KEV_INET6_ADDR_DELETED, ia, NULL);
2801 
2802 	(void) ifnet_notify_address(ifp, AF_INET6);
2803 }
2804 
2805 static void
in6_unlink_ifa(struct in6_ifaddr * ia,struct ifnet * ifp)2806 in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
2807 {
2808 	struct in6_ifaddr *nia;
2809 	struct ifaddr *ifa;
2810 	int unlinked;
2811 
2812 	LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
2813 
2814 	ifa = &ia->ia_ifa;
2815 	IFA_ADDREF(ifa);
2816 
2817 	ifnet_lock_exclusive(ifp);
2818 	IFA_LOCK(ifa);
2819 	if (ifa->ifa_debug & IFD_ATTACHED) {
2820 		if_detach_ifa(ifp, ifa);
2821 	}
2822 	IFA_UNLOCK(ifa);
2823 	ifnet_lock_done(ifp);
2824 
2825 	unlinked = 0;
2826 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2827 	TAILQ_FOREACH(nia, &in6_ifaddrhead, ia6_link) {
2828 		if (ia == nia) {
2829 			TAILQ_REMOVE(&in6_ifaddrhead, ia, ia6_link);
2830 			os_atomic_inc(&in6_ifaddrlist_genid, relaxed);
2831 			IFA_LOCK(ifa);
2832 			if (IA6_IS_HASHED(ia)) {
2833 				in6_iahash_remove(ia);
2834 			}
2835 			IFA_UNLOCK(ifa);
2836 			unlinked = 1;
2837 			break;
2838 		}
2839 	}
2840 
2841 	/*
2842 	 * When IPv6 address is being removed, release the
2843 	 * reference to the base prefix.
2844 	 * Also, since the release might, affect the status
2845 	 * of other (detached) addresses, call
2846 	 * pfxlist_onlink_check().
2847 	 */
2848 	IFA_LOCK(ifa);
2849 	/*
2850 	 * Only log the below message for addresses other than
2851 	 * link local.
2852 	 * Only one LLA (auto-configured or statically) is allowed
2853 	 * on an interface.
2854 	 * LLA prefix, while added to the prefix list, is not
2855 	 * reference countedi (as it is the only one).
2856 	 * The prefix also never expires on its own as LLAs
2857 	 * have infinite lifetime.
2858 	 *
2859 	 * For now quiece down the log message for LLAs.
2860 	 */
2861 	if (!IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
2862 		if (ia->ia6_ndpr == NULL) {
2863 			log(LOG_NOTICE, "in6_unlink_ifa: IPv6 address "
2864 			    "0x%llx has no prefix\n",
2865 			    (uint64_t)VM_KERNEL_ADDRPERM(ia));
2866 		} else {
2867 			struct nd_prefix *pr = ia->ia6_ndpr;
2868 
2869 			NDPR_LOCK(pr);
2870 			if (!(ia->ia6_flags & IN6_IFF_NOTMANUAL)) {
2871 				VERIFY(pr->ndpr_manual_addrcnt != 0);
2872 				pr->ndpr_manual_addrcnt--;
2873 			}
2874 			ia->ia6_flags &= ~IN6_IFF_AUTOCONF;
2875 			ia->ia6_ndpr = NULL;
2876 			VERIFY(pr->ndpr_addrcnt != 0);
2877 			pr->ndpr_addrcnt--;
2878 			if (ia->ia6_flags & IN6_IFF_CLAT46) {
2879 				pr->ndpr_stateflags &= ~NDPRF_CLAT46;
2880 			}
2881 			NDPR_UNLOCK(pr);
2882 			NDPR_REMREF(pr);        /* release addr reference */
2883 		}
2884 	}
2885 	IFA_UNLOCK(ifa);
2886 	lck_rw_done(&in6_ifaddr_rwlock);
2887 
2888 	if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
2889 		lck_mtx_lock(nd6_mutex);
2890 		pfxlist_onlink_check();
2891 		lck_mtx_unlock(nd6_mutex);
2892 	}
2893 	/*
2894 	 * release another refcnt for the link from in6_ifaddrs.
2895 	 * Do this only if it's not already unlinked in the event that we lost
2896 	 * the race, since in6_ifaddr_rwlock was momentarily dropped above.
2897 	 */
2898 	if (unlinked) {
2899 		IFA_REMREF(ifa);
2900 	}
2901 
2902 	/* release reference held for this routine */
2903 	IFA_REMREF(ifa);
2904 
2905 	/* invalidate route caches */
2906 	routegenid_inet6_update();
2907 }
2908 
2909 void
in6_purgeif(struct ifnet * ifp)2910 in6_purgeif(struct ifnet *ifp)
2911 {
2912 	struct in6_ifaddr *ia;
2913 
2914 	if (ifp == NULL) {
2915 		return;
2916 	}
2917 
2918 	LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
2919 
2920 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2921 	boolean_t from_begining = TRUE;
2922 	while (from_begining) {
2923 		from_begining = FALSE;
2924 		TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
2925 			if (ia->ia_ifa.ifa_ifp != ifp) {
2926 				continue;
2927 			}
2928 			IFA_ADDREF(&ia->ia_ifa);        /* for us */
2929 			lck_rw_done(&in6_ifaddr_rwlock);
2930 			in6_purgeaddr(&ia->ia_ifa);
2931 			IFA_REMREF(&ia->ia_ifa);        /* for us */
2932 			lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2933 			/*
2934 			 * Purging the address would have caused
2935 			 * in6_ifaddr_rwlock to be dropped and reacquired;
2936 			 * therefore search again from the beginning
2937 			 * of in6_ifaddrs list.
2938 			 */
2939 			from_begining = TRUE;
2940 			break;
2941 		}
2942 	}
2943 	lck_rw_done(&in6_ifaddr_rwlock);
2944 
2945 	in6_ifdetach(ifp);
2946 }
2947 
2948 /*
2949  * Initialize an interface's internet6 address and routing table entry.
2950  */
2951 static int
in6_ifinit(struct ifnet * ifp,struct in6_ifaddr * ia,int ifaupflags)2952 in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, int ifaupflags)
2953 {
2954 	int error;
2955 	struct ifaddr *ifa;
2956 
2957 	error = 0;
2958 	ifa = &ia->ia_ifa;
2959 
2960 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2961 	IFA_LOCK(&ia->ia_ifa);
2962 	if (IA6_IS_HASHED(ia)) {
2963 		in6_iahash_remove(ia);
2964 	}
2965 	if ((ifp->if_flags & IFF_POINTOPOINT)) {
2966 		in6_iahash_insert_ptp(ia);
2967 	} else {
2968 		in6_iahash_insert(ia);
2969 	}
2970 	IFA_UNLOCK(&ia->ia_ifa);
2971 	lck_rw_done(&in6_ifaddr_rwlock);
2972 
2973 	/*
2974 	 * NOTE: SIOCSIFADDR is defined with struct ifreq as parameter,
2975 	 * but here we are sending it down to the interface with a pointer
2976 	 * to struct ifaddr, for legacy reasons.
2977 	 */
2978 	if ((ifaupflags & IN6_IFAUPDATE_1STADDR) != 0) {
2979 		error = ifnet_ioctl(ifp, PF_INET6, SIOCSIFADDR, ia);
2980 		if (error != 0) {
2981 			if (error != EOPNOTSUPP) {
2982 				goto failed;
2983 			}
2984 			error = 0;
2985 		}
2986 	}
2987 
2988 	IFA_LOCK(ifa);
2989 
2990 	/*
2991 	 * Special case:
2992 	 * If the destination address is specified for a point-to-point
2993 	 * interface, install a route to the destination as an interface
2994 	 * direct route.
2995 	 */
2996 	if (!(ia->ia_flags & IFA_ROUTE) && ia->ia_plen == 128 &&
2997 	    ia->ia_dstaddr.sin6_family == AF_INET6) {
2998 		IFA_UNLOCK(ifa);
2999 		error = rtinit(ifa, RTM_ADD, RTF_UP | RTF_HOST);
3000 		if (error != 0) {
3001 			goto failed;
3002 		}
3003 		IFA_LOCK(ifa);
3004 		ia->ia_flags |= IFA_ROUTE;
3005 	}
3006 	IFA_LOCK_ASSERT_HELD(ifa);
3007 	if (ia->ia_plen < 128) {
3008 		/*
3009 		 * The RTF_CLONING flag is necessary for in6_is_ifloop_auto().
3010 		 */
3011 		ia->ia_flags |= RTF_CLONING;
3012 	}
3013 
3014 	IFA_UNLOCK(ifa);
3015 
3016 	/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
3017 	if ((ifaupflags & IN6_IFAUPDATE_NEWADDR) != 0) {
3018 		in6_ifaddloop(ifa);
3019 	}
3020 
3021 	/* invalidate route caches */
3022 	routegenid_inet6_update();
3023 
3024 	VERIFY(error == 0);
3025 	return 0;
3026 failed:
3027 	VERIFY(error != 0);
3028 	lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
3029 	IFA_LOCK(&ia->ia_ifa);
3030 	if (IA6_IS_HASHED(ia)) {
3031 		in6_iahash_remove(ia);
3032 	}
3033 	IFA_UNLOCK(&ia->ia_ifa);
3034 	lck_rw_done(&in6_ifaddr_rwlock);
3035 
3036 	return error;
3037 }
3038 
3039 void
in6_purgeaddrs(struct ifnet * ifp)3040 in6_purgeaddrs(struct ifnet *ifp)
3041 {
3042 	in6_purgeif(ifp);
3043 }
3044 
3045 /*
3046  * Find an IPv6 interface link-local address specific to an interface.
3047  */
3048 struct in6_ifaddr *
in6ifa_ifpforlinklocal(struct ifnet * ifp,int ignoreflags)3049 in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
3050 {
3051 	struct ifaddr *ifa;
3052 
3053 	ifnet_lock_shared(ifp);
3054 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
3055 	{
3056 		IFA_LOCK_SPIN(ifa);
3057 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3058 			IFA_UNLOCK(ifa);
3059 			continue;
3060 		}
3061 		if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
3062 			if ((((struct in6_ifaddr *)ifa)->ia6_flags &
3063 			    ignoreflags) != 0) {
3064 				IFA_UNLOCK(ifa);
3065 				continue;
3066 			}
3067 			IFA_ADDREF_LOCKED(ifa); /* for caller */
3068 			IFA_UNLOCK(ifa);
3069 			break;
3070 		}
3071 		IFA_UNLOCK(ifa);
3072 	}
3073 	ifnet_lock_done(ifp);
3074 
3075 	return (struct in6_ifaddr *)ifa;
3076 }
3077 
3078 struct in6_ifaddr *
in6ifa_ifpwithflag(struct ifnet * ifp,int flag)3079 in6ifa_ifpwithflag(struct ifnet * ifp, int flag)
3080 {
3081 	struct ifaddr *ifa;
3082 
3083 	ifnet_lock_shared(ifp);
3084 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
3085 	{
3086 		IFA_LOCK_SPIN(ifa);
3087 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3088 			IFA_UNLOCK(ifa);
3089 			continue;
3090 		}
3091 		if ((((struct in6_ifaddr *)ifa)->ia6_flags & flag) == flag) {
3092 			IFA_ADDREF_LOCKED(ifa);
3093 			IFA_UNLOCK(ifa);
3094 			break;
3095 		}
3096 		IFA_UNLOCK(ifa);
3097 	}
3098 	ifnet_lock_done(ifp);
3099 
3100 	return (struct in6_ifaddr *)ifa;
3101 }
3102 
3103 /*
3104  * find the internet address corresponding to a given interface and address.
3105  */
3106 struct in6_ifaddr *
in6ifa_ifpwithaddr(struct ifnet * ifp,struct in6_addr * addr)3107 in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr)
3108 {
3109 	struct ifaddr *ifa;
3110 
3111 	ifnet_lock_shared(ifp);
3112 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
3113 	{
3114 		IFA_LOCK_SPIN(ifa);
3115 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3116 			IFA_UNLOCK(ifa);
3117 			continue;
3118 		}
3119 		if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) {
3120 			IFA_ADDREF_LOCKED(ifa); /* for caller */
3121 			IFA_UNLOCK(ifa);
3122 			break;
3123 		}
3124 		IFA_UNLOCK(ifa);
3125 	}
3126 	ifnet_lock_done(ifp);
3127 
3128 	return (struct in6_ifaddr *)ifa;
3129 }
3130 
3131 struct in6_ifaddr *
in6ifa_prproxyaddr(struct in6_addr * addr,uint32_t ifscope)3132 in6ifa_prproxyaddr(struct in6_addr *addr, uint32_t ifscope)
3133 {
3134 	struct in6_ifaddr *ia;
3135 
3136 	lck_rw_lock_shared(&in6_ifaddr_rwlock);
3137 	TAILQ_FOREACH(ia, IN6ADDR_HASH(addr), ia6_hash) {
3138 		IFA_LOCK(&ia->ia_ifa);
3139 		if (in6_are_addr_equal_scoped(addr, IFA_IN6(&ia->ia_ifa), ifscope, ia->ia_ifp->if_index)) {
3140 			IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for caller */
3141 			IFA_UNLOCK(&ia->ia_ifa);
3142 			break;
3143 		}
3144 		IFA_UNLOCK(&ia->ia_ifa);
3145 	}
3146 	lck_rw_done(&in6_ifaddr_rwlock);
3147 
3148 	if (ia != NULL && !nd6_prproxy_ifaddr(ia)) {
3149 		IFA_REMREF(&ia->ia_ifa);
3150 		ia = NULL;
3151 	}
3152 
3153 	return ia;
3154 }
3155 
3156 void
in6ifa_getlifetime(struct in6_ifaddr * ia6,struct in6_addrlifetime * t_dst,int iscalendar)3157 in6ifa_getlifetime(struct in6_ifaddr *ia6, struct in6_addrlifetime *t_dst,
3158     int iscalendar)
3159 {
3160 	struct in6_addrlifetime_i *t_src = &ia6->ia6_lifetime;
3161 	struct timeval caltime;
3162 
3163 	t_dst->ia6t_vltime = t_src->ia6ti_vltime;
3164 	t_dst->ia6t_pltime = t_src->ia6ti_pltime;
3165 	t_dst->ia6t_expire = 0;
3166 	t_dst->ia6t_preferred = 0;
3167 
3168 	/* account for system time change */
3169 	getmicrotime(&caltime);
3170 	t_src->ia6ti_base_calendartime +=
3171 	    NET_CALCULATE_CLOCKSKEW(caltime,
3172 	    t_src->ia6ti_base_calendartime, net_uptime(),
3173 	    t_src->ia6ti_base_uptime);
3174 
3175 	if (iscalendar) {
3176 		if (t_src->ia6ti_expire != 0 &&
3177 		    t_src->ia6ti_vltime != ND6_INFINITE_LIFETIME) {
3178 			t_dst->ia6t_expire = (time_t)(t_src->ia6ti_base_calendartime +
3179 			    t_src->ia6ti_expire - t_src->ia6ti_base_uptime);
3180 		}
3181 
3182 		if (t_src->ia6ti_preferred != 0 &&
3183 		    t_src->ia6ti_pltime != ND6_INFINITE_LIFETIME) {
3184 			t_dst->ia6t_preferred = (time_t)(t_src->ia6ti_base_calendartime +
3185 			    t_src->ia6ti_preferred - t_src->ia6ti_base_uptime);
3186 		}
3187 	} else {
3188 		if (t_src->ia6ti_expire != 0 &&
3189 		    t_src->ia6ti_vltime != ND6_INFINITE_LIFETIME) {
3190 			t_dst->ia6t_expire = (time_t)t_src->ia6ti_expire;
3191 		}
3192 
3193 		if (t_src->ia6ti_preferred != 0 &&
3194 		    t_src->ia6ti_pltime != ND6_INFINITE_LIFETIME) {
3195 			t_dst->ia6t_preferred = (time_t)t_src->ia6ti_preferred;
3196 		}
3197 	}
3198 }
3199 
3200 void
in6ifa_setlifetime(struct in6_ifaddr * ia6,struct in6_addrlifetime * t_src)3201 in6ifa_setlifetime(struct in6_ifaddr *ia6, struct in6_addrlifetime *t_src)
3202 {
3203 	struct in6_addrlifetime_i *t_dst = &ia6->ia6_lifetime;
3204 	struct timeval caltime;
3205 
3206 	/* account for system time change */
3207 	getmicrotime(&caltime);
3208 	t_dst->ia6ti_base_calendartime +=
3209 	    NET_CALCULATE_CLOCKSKEW(caltime,
3210 	    t_dst->ia6ti_base_calendartime, net_uptime(),
3211 	    t_dst->ia6ti_base_uptime);
3212 
3213 	/* trust the caller for the values */
3214 	t_dst->ia6ti_expire = t_src->ia6t_expire;
3215 	t_dst->ia6ti_preferred = t_src->ia6t_preferred;
3216 	t_dst->ia6ti_vltime = t_src->ia6t_vltime;
3217 	t_dst->ia6ti_pltime = t_src->ia6t_pltime;
3218 }
3219 
3220 /*
3221  * Convert IP6 address to printable (loggable) representation.
3222  */
3223 char *
ip6_sprintf(const struct in6_addr * addr)3224 ip6_sprintf(const struct in6_addr *addr)
3225 {
3226 	static const char digits[] = "0123456789abcdef";
3227 	static int ip6round = 0;
3228 	static char ip6buf[8][48];
3229 
3230 	int i;
3231 	char *cp;
3232 	const u_short *a = (const u_short *)addr;
3233 	const u_char *d;
3234 	u_char n;
3235 	int dcolon = 0;
3236 	int zpad = 0;
3237 
3238 	ip6round = (ip6round + 1) & 7;
3239 	cp = ip6buf[ip6round];
3240 
3241 	for (i = 0; i < 8; i++) {
3242 		if (dcolon == 1) {
3243 			if (*a == 0) {
3244 				if (i == 7) {
3245 					*cp++ = ':';
3246 				}
3247 				a++;
3248 				continue;
3249 			} else {
3250 				dcolon = 2;
3251 			}
3252 		}
3253 		if (*a == 0) {
3254 			if (dcolon == 0 && *(a + 1) == 0) {
3255 				if (i == 0) {
3256 					*cp++ = ':';
3257 				}
3258 				*cp++ = ':';
3259 				dcolon = 1;
3260 			} else {
3261 				*cp++ = '0';
3262 				*cp++ = ':';
3263 			}
3264 			a++;
3265 			continue;
3266 		}
3267 		d = (const u_char *)a;
3268 		zpad = 0;
3269 		if ((n = *d >> 4) != 0) {
3270 			*cp++ = digits[n];
3271 			zpad = 1;
3272 		}
3273 		if ((n = *d++ & 0xf) != 0 || zpad) {
3274 			*cp++ = digits[n];
3275 			zpad = 1;
3276 		}
3277 		if ((n = *d >> 4) != 0 || zpad) {
3278 			*cp++ = digits[n];
3279 			zpad = 1;
3280 		}
3281 		if ((n = *d & 0xf) != 0 || zpad) {
3282 			*cp++ = digits[n];
3283 		}
3284 		*cp++ = ':';
3285 		a++;
3286 	}
3287 	*--cp = 0;
3288 	return ip6buf[ip6round];
3289 }
3290 
3291 int
in6addr_local(struct in6_addr * in6)3292 in6addr_local(struct in6_addr *in6)
3293 {
3294 	struct rtentry *rt;
3295 	struct sockaddr_in6 sin6;
3296 	int local = 0;
3297 
3298 	if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_SCOPE_LINKLOCAL(in6)) {
3299 		return 1;
3300 	}
3301 
3302 	sin6.sin6_family = AF_INET6;
3303 	sin6.sin6_len = sizeof(sin6);
3304 	bcopy(in6, &sin6.sin6_addr, sizeof(*in6));
3305 	rt = rtalloc1((struct sockaddr *)&sin6, 0, 0);
3306 
3307 	if (rt != NULL) {
3308 		RT_LOCK_SPIN(rt);
3309 		if (rt->rt_gateway->sa_family == AF_LINK) {
3310 			local = 1;
3311 		}
3312 		RT_UNLOCK(rt);
3313 		rtfree(rt);
3314 	} else {
3315 		local = in6_localaddr(in6);
3316 	}
3317 	return local;
3318 }
3319 
3320 int
in6_localaddr(struct in6_addr * in6)3321 in6_localaddr(struct in6_addr *in6)
3322 {
3323 	struct in6_ifaddr *ia;
3324 
3325 	if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6) || IN6_IS_ADDR_MC_UNICAST_BASED_LINKLOCAL(in6)) {
3326 		return 1;
3327 	}
3328 
3329 	lck_rw_lock_shared(&in6_ifaddr_rwlock);
3330 	TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
3331 		IFA_LOCK_SPIN(&ia->ia_ifa);
3332 		if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
3333 		    &ia->ia_prefixmask.sin6_addr)) {
3334 			IFA_UNLOCK(&ia->ia_ifa);
3335 			lck_rw_done(&in6_ifaddr_rwlock);
3336 			return 1;
3337 		}
3338 		IFA_UNLOCK(&ia->ia_ifa);
3339 	}
3340 	lck_rw_done(&in6_ifaddr_rwlock);
3341 	return 0;
3342 }
3343 
3344 /*
3345  * return length of part which dst and src are equal
3346  * hard coding...
3347  */
3348 int
in6_matchlen(struct in6_addr * src,struct in6_addr * dst)3349 in6_matchlen(struct in6_addr *src, struct in6_addr *dst)
3350 {
3351 	int match = 0;
3352 	u_char *s = (u_char *)src, *d = (u_char *)dst;
3353 	u_char *lim = s + 16, r;
3354 
3355 	while (s < lim) {
3356 		if ((r = (*d++ ^ *s++)) != 0) {
3357 			while (r < 128) {
3358 				match++;
3359 				r <<= 1;
3360 			}
3361 			break;
3362 		} else {
3363 			match += 8;
3364 		}
3365 	}
3366 	return match;
3367 }
3368 
3369 /* XXX: to be scope conscious */
3370 int
in6_are_prefix_equal(struct in6_addr * p1,uint32_t ifscope1,struct in6_addr * p2,uint32_t ifscope2,int len)3371 in6_are_prefix_equal(struct in6_addr *p1, uint32_t ifscope1, struct in6_addr *p2, uint32_t ifscope2, int len)
3372 {
3373 	int bytelen, bitlen;
3374 
3375 	/* sanity check */
3376 	if (0 > len || len > 128) {
3377 		log(LOG_ERR, "%s: invalid prefix length(%d)\n", __func__, len);
3378 		return 0;
3379 	}
3380 
3381 	bytelen = len / 8;
3382 	bitlen = len % 8;
3383 
3384 	if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen)) {
3385 		return 0;
3386 	}
3387 	if (bitlen != 0 &&
3388 	    p1->s6_addr[bytelen] >> (8 - bitlen) !=
3389 	    p2->s6_addr[bytelen] >> (8 - bitlen)) {
3390 		return 0;
3391 	}
3392 
3393 	if (IN6_IS_SCOPE_EMBED(p1) && !in6_embedded_scope) {
3394 		return ifscope1 == ifscope2;
3395 	}
3396 
3397 	return 1;
3398 }
3399 
3400 void
in6_prefixlen2mask(struct in6_addr * maskp,int len)3401 in6_prefixlen2mask(struct in6_addr *maskp, int len)
3402 {
3403 	u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
3404 	int bytelen, bitlen, i;
3405 
3406 	/* sanity check */
3407 	if (0 > len || len > 128) {
3408 		log(LOG_ERR, "%s: invalid prefix length(%d)\n", __func__, len);
3409 		return;
3410 	}
3411 
3412 	bzero(maskp, sizeof(*maskp));
3413 	bytelen = len / 8;
3414 	bitlen = len % 8;
3415 	for (i = 0; i < bytelen; i++) {
3416 		maskp->s6_addr[i] = 0xff;
3417 	}
3418 	if (bitlen) {
3419 		maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
3420 	}
3421 }
3422 
3423 /*
3424  * return the best address out of the same scope
3425  */
3426 struct in6_ifaddr *
in6_ifawithscope(struct ifnet * oifp,struct in6_addr * dst)3427 in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst)
3428 {
3429 	int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
3430 	int blen = -1;
3431 	struct ifaddr *ifa;
3432 	struct ifnet *ifp;
3433 	struct in6_ifaddr *ifa_best = NULL;
3434 
3435 	if (oifp == NULL) {
3436 		return NULL;
3437 	}
3438 
3439 	/*
3440 	 * We search for all addresses on all interfaces from the beginning.
3441 	 * Comparing an interface with the outgoing interface will be done
3442 	 * only at the final stage of tiebreaking.
3443 	 */
3444 	ifnet_head_lock_shared();
3445 	TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
3446 		/*
3447 		 * We can never take an address that breaks the scope zone
3448 		 * of the destination.
3449 		 */
3450 		if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst)) {
3451 			continue;
3452 		}
3453 
3454 		ifnet_lock_shared(ifp);
3455 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
3456 			int tlen = -1, dscopecmp, bscopecmp, matchcmp;
3457 
3458 			IFA_LOCK(ifa);
3459 			if (ifa->ifa_addr->sa_family != AF_INET6) {
3460 				IFA_UNLOCK(ifa);
3461 				continue;
3462 			}
3463 			src_scope = in6_addrscope(IFA_IN6(ifa));
3464 
3465 			/*
3466 			 * Don't use an address before completing DAD
3467 			 * nor a duplicated address.
3468 			 */
3469 			if (((struct in6_ifaddr *)ifa)->ia6_flags &
3470 			    (IN6_IFF_NOTREADY | IN6_IFF_CLAT46)) {
3471 				IFA_UNLOCK(ifa);
3472 				continue;
3473 			}
3474 			/* XXX: is there any case to allow anycasts? */
3475 			if (((struct in6_ifaddr *)ifa)->ia6_flags &
3476 			    IN6_IFF_ANYCAST) {
3477 				IFA_UNLOCK(ifa);
3478 				continue;
3479 			}
3480 			if (((struct in6_ifaddr *)ifa)->ia6_flags &
3481 			    IN6_IFF_DETACHED) {
3482 				IFA_UNLOCK(ifa);
3483 				continue;
3484 			}
3485 			/*
3486 			 * If this is the first address we find,
3487 			 * keep it anyway.
3488 			 */
3489 			if (ifa_best == NULL) {
3490 				goto replace;
3491 			}
3492 
3493 			/*
3494 			 * ifa_best is never NULL beyond this line except
3495 			 * within the block labeled "replace".
3496 			 */
3497 
3498 			/*
3499 			 * If ifa_best has a smaller scope than dst and
3500 			 * the current address has a larger one than
3501 			 * (or equal to) dst, always replace ifa_best.
3502 			 * Also, if the current address has a smaller scope
3503 			 * than dst, ignore it unless ifa_best also has a
3504 			 * smaller scope.
3505 			 * Consequently, after the two if-clause below,
3506 			 * the followings must be satisfied:
3507 			 * (scope(src) < scope(dst) &&
3508 			 *  scope(best) < scope(dst))
3509 			 *  OR
3510 			 * (scope(best) >= scope(dst) &&
3511 			 *  scope(src) >= scope(dst))
3512 			 */
3513 			if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
3514 			    IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0) {
3515 				goto replace; /* (A) */
3516 			}
3517 			if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
3518 			    IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0) {
3519 				IFA_UNLOCK(ifa);
3520 				continue; /* (B) */
3521 			}
3522 			/*
3523 			 * A deprecated address SHOULD NOT be used in new
3524 			 * communications if an alternate (non-deprecated)
3525 			 * address is available and has sufficient scope.
3526 			 * RFC 4862, Section 5.5.4.
3527 			 */
3528 			if (((struct in6_ifaddr *)ifa)->ia6_flags &
3529 			    IN6_IFF_DEPRECATED) {
3530 				/*
3531 				 * Ignore any deprecated addresses if
3532 				 * specified by configuration.
3533 				 */
3534 				if (!ip6_use_deprecated) {
3535 					IFA_UNLOCK(ifa);
3536 					continue;
3537 				}
3538 				/*
3539 				 * If we have already found a non-deprecated
3540 				 * candidate, just ignore deprecated addresses.
3541 				 */
3542 				if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED)
3543 				    == 0) {
3544 					IFA_UNLOCK(ifa);
3545 					continue;
3546 				}
3547 			}
3548 
3549 			/*
3550 			 * A non-deprecated address is always preferred
3551 			 * to a deprecated one regardless of scopes and
3552 			 * address matching (Note invariants ensured by the
3553 			 * conditions (A) and (B) above.)
3554 			 */
3555 			if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) &&
3556 			    (((struct in6_ifaddr *)ifa)->ia6_flags &
3557 			    IN6_IFF_DEPRECATED) == 0) {
3558 				goto replace;
3559 			}
3560 
3561 			/*
3562 			 * When we use temporary addresses described in
3563 			 * RFC 4941, we prefer temporary addresses to
3564 			 * public autoconf addresses.  Again, note the
3565 			 * invariants from (A) and (B).  Also note that we
3566 			 * don't have any preference between static addresses
3567 			 * and autoconf addresses (despite of whether or not
3568 			 * the latter is temporary or public.)
3569 			 */
3570 			if (ip6_use_tempaddr) {
3571 				struct in6_ifaddr *ifat;
3572 
3573 				ifat = (struct in6_ifaddr *)ifa;
3574 				if ((ifa_best->ia6_flags &
3575 				    (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))
3576 				    == IN6_IFF_AUTOCONF &&
3577 				    (ifat->ia6_flags &
3578 				    (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))
3579 				    == (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)) {
3580 					goto replace;
3581 				}
3582 				if ((ifa_best->ia6_flags &
3583 				    (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))
3584 				    == (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY) &&
3585 				    (ifat->ia6_flags &
3586 				    (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY))
3587 				    == IN6_IFF_AUTOCONF) {
3588 					IFA_UNLOCK(ifa);
3589 					continue;
3590 				}
3591 			}
3592 
3593 			/*
3594 			 * At this point, we have two cases:
3595 			 * 1. we are looking at a non-deprecated address,
3596 			 *    and ifa_best is also non-deprecated.
3597 			 * 2. we are looking at a deprecated address,
3598 			 *    and ifa_best is also deprecated.
3599 			 * Also, we do not have to consider a case where
3600 			 * the scope of if_best is larger(smaller) than dst and
3601 			 * the scope of the current address is smaller(larger)
3602 			 * than dst. Such a case has already been covered.
3603 			 * Tiebreaking is done according to the following
3604 			 * items:
3605 			 * - the scope comparison between the address and
3606 			 *   dst (dscopecmp)
3607 			 * - the scope comparison between the address and
3608 			 *   ifa_best (bscopecmp)
3609 			 * - if the address match dst longer than ifa_best
3610 			 *   (matchcmp)
3611 			 * - if the address is on the outgoing I/F (outI/F)
3612 			 *
3613 			 * Roughly speaking, the selection policy is
3614 			 * - the most important item is scope. The same scope
3615 			 *   is best. Then search for a larger scope.
3616 			 *   Smaller scopes are the last resort.
3617 			 * - A deprecated address is chosen only when we have
3618 			 *   no address that has an enough scope, but is
3619 			 *   prefered to any addresses of smaller scopes
3620 			 *   (this must be already done above.)
3621 			 * - addresses on the outgoing I/F are preferred to
3622 			 *   ones on other interfaces if none of above
3623 			 *   tiebreaks.  In the table below, the column "bI"
3624 			 *   means if the best_ifa is on the outgoing
3625 			 *   interface, and the column "sI" means if the ifa
3626 			 *   is on the outgoing interface.
3627 			 * - If there is no other reasons to choose one,
3628 			 *   longest address match against dst is considered.
3629 			 *
3630 			 * The precise decision table is as follows:
3631 			 * dscopecmp bscopecmp  match   bI oI | replace?
3632 			 *   N/A       equal    N/A     Y   N |   No (1)
3633 			 *   N/A       equal    N/A     N   Y |  Yes (2)
3634 			 *   N/A       equal    larger   N/A  |  Yes (3)
3635 			 *   N/A       equal    !larger  N/A  |   No (4)
3636 			 *   larger    larger   N/A      N/A  |   No (5)
3637 			 *   larger    smaller  N/A      N/A  |  Yes (6)
3638 			 *   smaller   larger   N/A      N/A  |  Yes (7)
3639 			 *   smaller   smaller  N/A      N/A  |   No (8)
3640 			 *   equal     smaller  N/A      N/A  |  Yes (9)
3641 			 *   equal     larger   (already done at A above)
3642 			 */
3643 			dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
3644 			bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
3645 
3646 			if (bscopecmp == 0) {
3647 				struct ifnet *bifp = ifa_best->ia_ifp;
3648 
3649 				if (bifp == oifp && ifp != oifp) { /* (1) */
3650 					IFA_UNLOCK(ifa);
3651 					continue;
3652 				}
3653 				if (bifp != oifp && ifp == oifp) { /* (2) */
3654 					goto replace;
3655 				}
3656 
3657 				/*
3658 				 * Both bifp and ifp are on the outgoing
3659 				 * interface, or both two are on a different
3660 				 * interface from the outgoing I/F.
3661 				 * now we need address matching against dst
3662 				 * for tiebreaking.
3663 				 */
3664 				tlen = in6_matchlen(IFA_IN6(ifa), dst);
3665 				matchcmp = tlen - blen;
3666 				if (matchcmp > 0) { /* (3) */
3667 					goto replace;
3668 				}
3669 				IFA_UNLOCK(ifa);
3670 				continue; /* (4) */
3671 			}
3672 			if (dscopecmp > 0) {
3673 				if (bscopecmp > 0) { /* (5) */
3674 					IFA_UNLOCK(ifa);
3675 					continue;
3676 				}
3677 				goto replace; /* (6) */
3678 			}
3679 			if (dscopecmp < 0) {
3680 				if (bscopecmp > 0) { /* (7) */
3681 					goto replace;
3682 				}
3683 				IFA_UNLOCK(ifa);
3684 				continue; /* (8) */
3685 			}
3686 
3687 			/* now dscopecmp must be 0 */
3688 			if (bscopecmp < 0) {
3689 				goto replace; /* (9) */
3690 			}
3691 replace:
3692 			IFA_ADDREF_LOCKED(ifa); /* for ifa_best */
3693 			blen = tlen >= 0 ? tlen :
3694 			    in6_matchlen(IFA_IN6(ifa), dst);
3695 			best_scope =
3696 			    in6_addrscope(&ifa2ia6(ifa)->ia_addr.sin6_addr);
3697 			IFA_UNLOCK(ifa);
3698 			if (ifa_best) {
3699 				IFA_REMREF(&ifa_best->ia_ifa);
3700 			}
3701 			ifa_best = (struct in6_ifaddr *)ifa;
3702 		}
3703 		ifnet_lock_done(ifp);
3704 	}
3705 	ifnet_head_done();
3706 
3707 	/* count statistics for future improvements */
3708 	if (ifa_best == NULL) {
3709 		ip6stat.ip6s_sources_none++;
3710 	} else {
3711 		IFA_LOCK_SPIN(&ifa_best->ia_ifa);
3712 		if (oifp == ifa_best->ia_ifp) {
3713 			ip6stat.ip6s_sources_sameif[best_scope]++;
3714 		} else {
3715 			ip6stat.ip6s_sources_otherif[best_scope]++;
3716 		}
3717 
3718 		if (best_scope == dst_scope) {
3719 			ip6stat.ip6s_sources_samescope[best_scope]++;
3720 		} else {
3721 			ip6stat.ip6s_sources_otherscope[best_scope]++;
3722 		}
3723 
3724 		if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0) {
3725 			ip6stat.ip6s_sources_deprecated[best_scope]++;
3726 		}
3727 		IFA_UNLOCK(&ifa_best->ia_ifa);
3728 	}
3729 
3730 	return ifa_best;
3731 }
3732 
3733 /*
3734  * return the best address out of the same scope. if no address was
3735  * found, return the first valid address from designated IF.
3736  */
3737 struct in6_ifaddr *
in6_ifawithifp(struct ifnet * ifp,struct in6_addr * dst)3738 in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
3739 {
3740 	int dst_scope = in6_addrscope(dst), blen = -1, tlen;
3741 	struct ifaddr *ifa;
3742 	struct in6_ifaddr *besta = NULL;
3743 	struct in6_ifaddr *dep[2];      /* last-resort: deprecated */
3744 
3745 	dep[0] = dep[1] = NULL;
3746 
3747 	/*
3748 	 * We first look for addresses in the same scope.
3749 	 * If there is one, return it.
3750 	 * If two or more, return one which matches the dst longest.
3751 	 * If none, return one of global addresses assigned other ifs.
3752 	 */
3753 	ifnet_lock_shared(ifp);
3754 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
3755 		IFA_LOCK(ifa);
3756 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3757 			IFA_UNLOCK(ifa);
3758 			continue;
3759 		}
3760 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_ANYCAST) {
3761 			IFA_UNLOCK(ifa);
3762 			continue; /* XXX: is there any case to allow anycast? */
3763 		}
3764 		if (ifa2ia6(ifa)->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_CLAT46)) {
3765 			IFA_UNLOCK(ifa);
3766 			continue; /* don't use this interface */
3767 		}
3768 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_DETACHED) {
3769 			IFA_UNLOCK(ifa);
3770 			continue;
3771 		}
3772 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
3773 			if (ip6_use_deprecated) {
3774 				IFA_ADDREF_LOCKED(ifa); /* for dep[0] */
3775 				IFA_UNLOCK(ifa);
3776 				if (dep[0] != NULL) {
3777 					IFA_REMREF(&dep[0]->ia_ifa);
3778 				}
3779 				dep[0] = (struct in6_ifaddr *)ifa;
3780 			} else {
3781 				IFA_UNLOCK(ifa);
3782 			}
3783 			continue;
3784 		}
3785 
3786 		if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
3787 			/*
3788 			 * call in6_matchlen() as few as possible
3789 			 */
3790 			if (besta) {
3791 				if (blen == -1) {
3792 					IFA_UNLOCK(ifa);
3793 					IFA_LOCK(&besta->ia_ifa);
3794 					blen = in6_matchlen(
3795 						&besta->ia_addr.sin6_addr, dst);
3796 					IFA_UNLOCK(&besta->ia_ifa);
3797 					IFA_LOCK(ifa);
3798 				}
3799 				tlen = in6_matchlen(IFA_IN6(ifa), dst);
3800 				if (tlen > blen) {
3801 					blen = tlen;
3802 					IFA_ADDREF_LOCKED(ifa); /* for besta */
3803 					IFA_UNLOCK(ifa);
3804 					IFA_REMREF(&besta->ia_ifa);
3805 					besta = (struct in6_ifaddr *)ifa;
3806 				} else {
3807 					IFA_UNLOCK(ifa);
3808 				}
3809 			} else {
3810 				besta = (struct in6_ifaddr *)ifa;
3811 				IFA_ADDREF_LOCKED(ifa); /* for besta */
3812 				IFA_UNLOCK(ifa);
3813 			}
3814 		} else {
3815 			IFA_UNLOCK(ifa);
3816 		}
3817 	}
3818 	if (besta) {
3819 		ifnet_lock_done(ifp);
3820 		if (dep[0] != NULL) {
3821 			IFA_REMREF(&dep[0]->ia_ifa);
3822 		}
3823 		return besta;
3824 	}
3825 
3826 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
3827 		IFA_LOCK(ifa);
3828 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3829 			IFA_UNLOCK(ifa);
3830 			continue;
3831 		}
3832 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_ANYCAST) {
3833 			IFA_UNLOCK(ifa);
3834 			continue; /* XXX: is there any case to allow anycast? */
3835 		}
3836 		if (ifa2ia6(ifa)->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_CLAT46)) {
3837 			IFA_UNLOCK(ifa);
3838 			continue; /* don't use this interface */
3839 		}
3840 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_DETACHED) {
3841 			IFA_UNLOCK(ifa);
3842 			continue;
3843 		}
3844 		if (ifa2ia6(ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
3845 			if (ip6_use_deprecated) {
3846 				IFA_ADDREF_LOCKED(ifa); /* for dep[1] */
3847 				IFA_UNLOCK(ifa);
3848 				if (dep[1] != NULL) {
3849 					IFA_REMREF(&dep[1]->ia_ifa);
3850 				}
3851 				dep[1] = (struct in6_ifaddr *)ifa;
3852 			} else {
3853 				IFA_UNLOCK(ifa);
3854 			}
3855 			continue;
3856 		}
3857 		IFA_ADDREF_LOCKED(ifa); /* for caller */
3858 		IFA_UNLOCK(ifa);
3859 		ifnet_lock_done(ifp);
3860 		if (dep[0] != NULL) {
3861 			IFA_REMREF(&dep[0]->ia_ifa);
3862 		}
3863 		if (dep[1] != NULL) {
3864 			IFA_REMREF(&dep[1]->ia_ifa);
3865 		}
3866 		return (struct in6_ifaddr *)ifa;
3867 	}
3868 	ifnet_lock_done(ifp);
3869 
3870 	/* use the last-resort values, that are, deprecated addresses */
3871 	if (dep[0]) {
3872 		if (dep[1] != NULL) {
3873 			IFA_REMREF(&dep[1]->ia_ifa);
3874 		}
3875 		return dep[0];
3876 	}
3877 	if (dep[1]) {
3878 		return dep[1];
3879 	}
3880 
3881 	return NULL;
3882 }
3883 
3884 /*
3885  * perform DAD when interface becomes IFF_UP.
3886  */
3887 static void
in6_if_up_dad_start(struct ifnet * ifp)3888 in6_if_up_dad_start(struct ifnet *ifp)
3889 {
3890 	struct ifaddr *ifa;
3891 	struct nd_ifinfo *ndi = NULL;
3892 
3893 	ndi = ND_IFINFO(ifp);
3894 	VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
3895 	if (!(ndi->flags & ND6_IFF_DAD)) {
3896 		return;
3897 	}
3898 
3899 	/* start DAD on all the interface addresses */
3900 	ifnet_lock_exclusive(ifp);
3901 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
3902 		struct in6_ifaddr *ia6;
3903 
3904 		IFA_LOCK_SPIN(ifa);
3905 		if (ifa->ifa_addr->sa_family != AF_INET6) {
3906 			IFA_UNLOCK(ifa);
3907 			continue;
3908 		}
3909 		ia6 = (struct in6_ifaddr *)ifa;
3910 		if (ia6->ia6_flags & IN6_IFF_DADPROGRESS) {
3911 			int delay = 0;  /* delay ticks before DAD output */
3912 			IFA_UNLOCK(ifa);
3913 			nd6_dad_start(ifa, &delay);
3914 		} else {
3915 			IFA_UNLOCK(ifa);
3916 		}
3917 	}
3918 	ifnet_lock_done(ifp);
3919 }
3920 
3921 int
in6if_do_dad(struct ifnet * ifp)3922 in6if_do_dad(
3923 	struct ifnet *ifp)
3924 {
3925 	struct nd_ifinfo *ndi = NULL;
3926 
3927 	if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
3928 		return 0;
3929 	}
3930 
3931 	ndi = ND_IFINFO(ifp);
3932 	VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
3933 	if (!(ndi->flags & ND6_IFF_DAD)) {
3934 		return 0;
3935 	}
3936 
3937 	/*
3938 	 * If we are using the alternative neighbor discovery
3939 	 * interface on this interface, then skip DAD.
3940 	 *
3941 	 * Also, skip it for interfaces marked "local private"
3942 	 * for now, even when not marked as using the alternative
3943 	 * interface.  This is for historical reasons.
3944 	 */
3945 	if (ifp->if_eflags &
3946 	    (IFEF_IPV6_ND6ALT | IFEF_LOCALNET_PRIVATE | IFEF_DIRECTLINK)) {
3947 		return 0;
3948 	}
3949 
3950 	if (ifp->if_family == IFNET_FAMILY_IPSEC ||
3951 	    ifp->if_family == IFNET_FAMILY_UTUN) {
3952 		/*
3953 		 * Ignore DAD for tunneling virtual interfaces, which get
3954 		 * their IPv6 address explicitly assigned.
3955 		 */
3956 		return 0;
3957 	}
3958 
3959 	switch (ifp->if_type) {
3960 #if IFT_DUMMY
3961 	case IFT_DUMMY:
3962 #endif
3963 	case IFT_FAITH:
3964 		/*
3965 		 * These interfaces do not have the IFF_LOOPBACK flag,
3966 		 * but loop packets back.  We do not have to do DAD on such
3967 		 * interfaces.  We should even omit it, because loop-backed
3968 		 * NS would confuse the DAD procedure.
3969 		 */
3970 		return 0;
3971 	default:
3972 		/*
3973 		 * Our DAD routine requires the interface up and running.
3974 		 * However, some interfaces can be up before the RUNNING
3975 		 * status.  Additionaly, users may try to assign addresses
3976 		 * before the interface becomes up (or running).
3977 		 * We simply skip DAD in such a case as a work around.
3978 		 * XXX: we should rather mark "tentative" on such addresses,
3979 		 * and do DAD after the interface becomes ready.
3980 		 */
3981 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
3982 		    (IFF_UP | IFF_RUNNING)) {
3983 			return 0;
3984 		}
3985 
3986 		return 1;
3987 	}
3988 }
3989 
3990 /*
3991  * Calculate max IPv6 MTU through all the interfaces and store it
3992  * to in6_maxmtu.
3993  */
3994 void
in6_setmaxmtu(void)3995 in6_setmaxmtu(void)
3996 {
3997 	u_int32_t maxmtu = 0;
3998 	struct ifnet *ifp;
3999 
4000 	ifnet_head_lock_shared();
4001 	TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
4002 		struct nd_ifinfo *ndi = NULL;
4003 
4004 		if ((ndi = ND_IFINFO(ifp)) != NULL && !ndi->initialized) {
4005 			ndi = NULL;
4006 		}
4007 		if (ndi != NULL) {
4008 			lck_mtx_lock(&ndi->lock);
4009 		}
4010 		if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
4011 		    IN6_LINKMTU(ifp) > maxmtu) {
4012 			maxmtu = IN6_LINKMTU(ifp);
4013 		}
4014 		if (ndi != NULL) {
4015 			lck_mtx_unlock(&ndi->lock);
4016 		}
4017 	}
4018 	ifnet_head_done();
4019 	if (maxmtu) {   /* update only when maxmtu is positive */
4020 		in6_maxmtu = maxmtu;
4021 	}
4022 }
4023 /*
4024  * Provide the length of interface identifiers to be used for the link attached
4025  * to the given interface.  The length should be defined in "IPv6 over
4026  * xxx-link" document.  Note that address architecture might also define
4027  * the length for a particular set of address prefixes, regardless of the
4028  * link type.  Also see RFC 4862 for additional background.
4029  */
4030 int
in6_if2idlen(struct ifnet * ifp)4031 in6_if2idlen(struct ifnet *ifp)
4032 {
4033 	switch (ifp->if_type) {
4034 	case IFT_ETHER:         /* RFC2464 */
4035 	case IFT_IEEE8023ADLAG: /* IEEE802.3ad Link Aggregate */
4036 #ifdef IFT_PROPVIRTUAL
4037 	case IFT_PROPVIRTUAL:   /* XXX: no RFC. treat it as ether */
4038 #endif
4039 #ifdef IFT_L2VLAN
4040 	case IFT_L2VLAN:        /* ditto */
4041 #endif
4042 #ifdef IFT_IEEE80211
4043 	case IFT_IEEE80211:     /* ditto */
4044 #endif
4045 #ifdef IFT_MIP
4046 	case IFT_MIP:   /* ditto */
4047 #endif
4048 		return 64;
4049 	case IFT_FDDI:          /* RFC2467 */
4050 		return 64;
4051 	case IFT_ISO88025:      /* RFC2470 (IPv6 over Token Ring) */
4052 		return 64;
4053 	case IFT_PPP:           /* RFC2472 */
4054 		return 64;
4055 	case IFT_ARCNET:        /* RFC2497 */
4056 		return 64;
4057 	case IFT_FRELAY:        /* RFC2590 */
4058 		return 64;
4059 	case IFT_IEEE1394:      /* RFC3146 */
4060 		return 64;
4061 	case IFT_GIF:
4062 		return 64;    /* draft-ietf-v6ops-mech-v2-07 */
4063 	case IFT_LOOP:
4064 		return 64;    /* XXX: is this really correct? */
4065 	case IFT_OTHER:
4066 		return 64;    /* for utun interfaces */
4067 	case IFT_CELLULAR:
4068 		return 64;    /* Packet Data over Cellular */
4069 	case IFT_BRIDGE:
4070 		return 64;    /* Transparent bridge interface */
4071 	default:
4072 		/*
4073 		 * Unknown link type:
4074 		 * It might be controversial to use the today's common constant
4075 		 * of 64 for these cases unconditionally.  For full compliance,
4076 		 * we should return an error in this case.  On the other hand,
4077 		 * if we simply miss the standard for the link type or a new
4078 		 * standard is defined for a new link type, the IFID length
4079 		 * is very likely to be the common constant.  As a compromise,
4080 		 * we always use the constant, but make an explicit notice
4081 		 * indicating the "unknown" case.
4082 		 */
4083 		log(LOG_NOTICE, "%s: unknown link type (%d)\n", __func__,
4084 		    ifp->if_type);
4085 		return 64;
4086 	}
4087 }
4088 /*
4089  * Convert sockaddr_in6 to sockaddr_in.  Original sockaddr_in6 must be
4090  * v4 mapped addr or v4 compat addr
4091  */
4092 void
in6_sin6_2_sin(struct sockaddr_in * sin,struct sockaddr_in6 * sin6)4093 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
4094 {
4095 	bzero(sin, sizeof(*sin));
4096 	sin->sin_len = sizeof(struct sockaddr_in);
4097 	sin->sin_family = AF_INET;
4098 	sin->sin_port = sin6->sin6_port;
4099 	sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
4100 }
4101 
4102 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
4103 void
in6_sin_2_v4mapsin6(struct sockaddr_in * sin,struct sockaddr_in6 * sin6)4104 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
4105 {
4106 	bzero(sin6, sizeof(*sin6));
4107 	sin6->sin6_len = sizeof(struct sockaddr_in6);
4108 	sin6->sin6_family = AF_INET6;
4109 	sin6->sin6_port = sin->sin_port;
4110 	sin6->sin6_addr.s6_addr32[0] = 0;
4111 	sin6->sin6_addr.s6_addr32[1] = 0;
4112 	if (sin->sin_addr.s_addr) {
4113 		sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
4114 		sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
4115 	} else {
4116 		sin6->sin6_addr.s6_addr32[2] = 0;
4117 		sin6->sin6_addr.s6_addr32[3] = 0;
4118 	}
4119 }
4120 
4121 /* Convert sockaddr_in6 into sockaddr_in. */
4122 void
in6_sin6_2_sin_in_sock(struct sockaddr * nam)4123 in6_sin6_2_sin_in_sock(struct sockaddr *nam)
4124 {
4125 	struct sockaddr_in *sin_p;
4126 	struct sockaddr_in6 sin6;
4127 
4128 	/*
4129 	 * Save original sockaddr_in6 addr and convert it
4130 	 * to sockaddr_in.
4131 	 */
4132 	sin6 = *(struct sockaddr_in6 *)(void *)nam;
4133 	sin_p = (struct sockaddr_in *)(void *)nam;
4134 	in6_sin6_2_sin(sin_p, &sin6);
4135 }
4136 
4137 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
4138 int
in6_sin_2_v4mapsin6_in_sock(struct sockaddr ** nam)4139 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
4140 {
4141 	struct sockaddr_in *sin_p;
4142 	struct sockaddr_in6 *sin6_p;
4143 
4144 	sin6_p = (struct sockaddr_in6 *)alloc_sockaddr(sizeof(*sin6_p),
4145 	    Z_WAITOK | Z_NOFAIL);
4146 
4147 	sin_p = (struct sockaddr_in *)(void *)*nam;
4148 	in6_sin_2_v4mapsin6(sin_p, sin6_p);
4149 	free_sockaddr(*nam);
4150 	*nam = (struct sockaddr *)sin6_p;
4151 
4152 	return 0;
4153 }
4154 
4155 /*
4156  * Posts in6_event_data message kernel events.
4157  *
4158  * To get the same size of kev_in6_data between ILP32 and LP64 data models
4159  * we are using a special version of the in6_addrlifetime structure that
4160  * uses only 32 bits fields to be compatible with Leopard, and that
4161  * are large enough to span 68 years.
4162  */
4163 void
in6_post_msg(struct ifnet * ifp,u_int32_t event_code,struct in6_ifaddr * ifa,uint8_t * mac)4164 in6_post_msg(struct ifnet *ifp, u_int32_t event_code, struct in6_ifaddr *ifa,
4165     uint8_t *mac)
4166 {
4167 	struct kev_msg ev_msg;
4168 	struct kev_in6_data in6_event_data;
4169 	struct in6_addrlifetime ia6_lt;
4170 
4171 	bzero(&in6_event_data, sizeof(struct kev_in6_data));
4172 	bzero(&ev_msg, sizeof(struct kev_msg));
4173 	ev_msg.vendor_code      = KEV_VENDOR_APPLE;
4174 	ev_msg.kev_class        = KEV_NETWORK_CLASS;
4175 	ev_msg.kev_subclass     = KEV_INET6_SUBCLASS;
4176 	ev_msg.event_code       = event_code;
4177 
4178 	if (ifa) {
4179 		IFA_LOCK(&ifa->ia_ifa);
4180 		in6_event_data.ia_addr          = ifa->ia_addr;
4181 		in6_event_data.ia_net           = ifa->ia_net;
4182 		in6_event_data.ia_dstaddr       = ifa->ia_dstaddr;
4183 		in6_event_data.ia_prefixmask    = ifa->ia_prefixmask;
4184 		in6_event_data.ia_plen          = ifa->ia_plen;
4185 		in6_event_data.ia6_flags        = (u_int32_t)ifa->ia6_flags;
4186 
4187 		/* retrieve time as calendar time (last arg is 1) */
4188 		in6ifa_getlifetime(ifa, &ia6_lt, 1);
4189 		in6_event_data.ia_lifetime.ia6t_expire = (u_int32_t)ia6_lt.ia6t_expire;
4190 		in6_event_data.ia_lifetime.ia6t_preferred = (u_int32_t)ia6_lt.ia6t_preferred;
4191 		in6_event_data.ia_lifetime.ia6t_vltime = ia6_lt.ia6t_vltime;
4192 		in6_event_data.ia_lifetime.ia6t_pltime = ia6_lt.ia6t_pltime;
4193 		IFA_UNLOCK(&ifa->ia_ifa);
4194 	}
4195 
4196 	if (ifp != NULL) {
4197 		(void) strlcpy(&in6_event_data.link_data.if_name[0],
4198 		    ifp->if_name, IFNAMSIZ);
4199 		in6_event_data.link_data.if_family = ifp->if_family;
4200 		in6_event_data.link_data.if_unit  = (u_int32_t)ifp->if_unit;
4201 	}
4202 
4203 	if (mac != NULL) {
4204 		memcpy(&in6_event_data.ia_mac, mac,
4205 		    sizeof(in6_event_data.ia_mac));
4206 	}
4207 
4208 	ev_msg.dv[0].data_ptr    = &in6_event_data;
4209 	ev_msg.dv[0].data_length = sizeof(in6_event_data);
4210 	ev_msg.dv[1].data_length = 0;
4211 
4212 	dlil_post_complete_msg(NULL, &ev_msg);
4213 }
4214 
4215 /*
4216  * Called as part of ip6_init
4217  */
4218 void
in6_ifaddr_init(void)4219 in6_ifaddr_init(void)
4220 {
4221 	in6_cga_init();
4222 	in6_multi_init();
4223 
4224 	PE_parse_boot_argn("ifa_debug", &in6ifa_debug, sizeof(in6ifa_debug));
4225 
4226 	vm_size_t in6ifa_size = (in6ifa_debug == 0) ? sizeof(struct in6_ifaddr) :
4227 	    sizeof(struct in6_ifaddr_dbg);
4228 
4229 	in6ifa_zone = zone_create(IN6IFA_ZONE_NAME, in6ifa_size, ZC_ZFREE_CLEARMEM);
4230 
4231 	TAILQ_INIT(&in6ifa_trash_head);
4232 }
4233 
4234 static struct in6_ifaddr *
in6_ifaddr_alloc(zalloc_flags_t how)4235 in6_ifaddr_alloc(zalloc_flags_t how)
4236 {
4237 	struct in6_ifaddr *in6ifa;
4238 
4239 	in6ifa = zalloc_flags(in6ifa_zone, how | Z_ZERO);
4240 	if (in6ifa != NULL) {
4241 		in6ifa->ia_ifa.ifa_free = in6_ifaddr_free;
4242 		in6ifa->ia_ifa.ifa_debug |= IFD_ALLOC;
4243 		in6ifa->ia_ifa.ifa_del_wc = &in6ifa->ia_ifa.ifa_debug;
4244 		in6ifa->ia_ifa.ifa_del_waiters = 0;
4245 		ifa_lock_init(&in6ifa->ia_ifa);
4246 		if (in6ifa_debug != 0) {
4247 			struct in6_ifaddr_dbg *in6ifa_dbg =
4248 			    (struct in6_ifaddr_dbg *)in6ifa;
4249 			in6ifa->ia_ifa.ifa_debug |= IFD_DEBUG;
4250 			in6ifa->ia_ifa.ifa_trace = in6_ifaddr_trace;
4251 			in6ifa->ia_ifa.ifa_attached = in6_ifaddr_attached;
4252 			in6ifa->ia_ifa.ifa_detached = in6_ifaddr_detached;
4253 			ctrace_record(&in6ifa_dbg->in6ifa_alloc);
4254 		}
4255 	}
4256 
4257 	return in6ifa;
4258 }
4259 
4260 static void
in6_ifaddr_free(struct ifaddr * ifa)4261 in6_ifaddr_free(struct ifaddr *ifa)
4262 {
4263 	IFA_LOCK_ASSERT_HELD(ifa);
4264 
4265 	if (ifa->ifa_refcnt != 0) {
4266 		panic("%s: ifa %p bad ref cnt", __func__, ifa);
4267 		/* NOTREACHED */
4268 	} else if (!(ifa->ifa_debug & IFD_ALLOC)) {
4269 		panic("%s: ifa %p cannot be freed", __func__, ifa);
4270 		/* NOTREACHED */
4271 	}
4272 	if (ifa->ifa_debug & IFD_DEBUG) {
4273 		struct in6_ifaddr_dbg *in6ifa_dbg =
4274 		    (struct in6_ifaddr_dbg *)ifa;
4275 		ctrace_record(&in6ifa_dbg->in6ifa_free);
4276 		bcopy(&in6ifa_dbg->in6ifa, &in6ifa_dbg->in6ifa_old,
4277 		    sizeof(struct in6_ifaddr));
4278 		if (ifa->ifa_debug & IFD_TRASHED) {
4279 			/* Become a regular mutex, just in case */
4280 			IFA_CONVERT_LOCK(ifa);
4281 			lck_mtx_lock(&in6ifa_trash_lock);
4282 			TAILQ_REMOVE(&in6ifa_trash_head, in6ifa_dbg,
4283 			    in6ifa_trash_link);
4284 			lck_mtx_unlock(&in6ifa_trash_lock);
4285 			ifa->ifa_debug &= ~IFD_TRASHED;
4286 		}
4287 	}
4288 	IFA_UNLOCK(ifa);
4289 	ifa_lock_destroy(ifa);
4290 	bzero(ifa, sizeof(struct in6_ifaddr));
4291 	zfree(in6ifa_zone, ifa);
4292 }
4293 
4294 static void
in6_ifaddr_attached(struct ifaddr * ifa)4295 in6_ifaddr_attached(struct ifaddr *ifa)
4296 {
4297 	struct in6_ifaddr_dbg *in6ifa_dbg = (struct in6_ifaddr_dbg *)ifa;
4298 
4299 	IFA_LOCK_ASSERT_HELD(ifa);
4300 
4301 	if (!(ifa->ifa_debug & IFD_DEBUG)) {
4302 		panic("%s: ifa %p has no debug structure", __func__, ifa);
4303 		/* NOTREACHED */
4304 	}
4305 	if (ifa->ifa_debug & IFD_TRASHED) {
4306 		/* Become a regular mutex, just in case */
4307 		IFA_CONVERT_LOCK(ifa);
4308 		lck_mtx_lock(&in6ifa_trash_lock);
4309 		TAILQ_REMOVE(&in6ifa_trash_head, in6ifa_dbg, in6ifa_trash_link);
4310 		lck_mtx_unlock(&in6ifa_trash_lock);
4311 		ifa->ifa_debug &= ~IFD_TRASHED;
4312 	}
4313 }
4314 
4315 static void
in6_ifaddr_detached(struct ifaddr * ifa)4316 in6_ifaddr_detached(struct ifaddr *ifa)
4317 {
4318 	struct in6_ifaddr_dbg *in6ifa_dbg = (struct in6_ifaddr_dbg *)ifa;
4319 
4320 	IFA_LOCK_ASSERT_HELD(ifa);
4321 
4322 	if (!(ifa->ifa_debug & IFD_DEBUG)) {
4323 		panic("%s: ifa %p has no debug structure", __func__, ifa);
4324 		/* NOTREACHED */
4325 	} else if (ifa->ifa_debug & IFD_TRASHED) {
4326 		panic("%s: ifa %p is already in trash list", __func__, ifa);
4327 		/* NOTREACHED */
4328 	}
4329 	ifa->ifa_debug |= IFD_TRASHED;
4330 	/* Become a regular mutex, just in case */
4331 	IFA_CONVERT_LOCK(ifa);
4332 	lck_mtx_lock(&in6ifa_trash_lock);
4333 	TAILQ_INSERT_TAIL(&in6ifa_trash_head, in6ifa_dbg, in6ifa_trash_link);
4334 	lck_mtx_unlock(&in6ifa_trash_lock);
4335 }
4336 
4337 static void
in6_ifaddr_trace(struct ifaddr * ifa,int refhold)4338 in6_ifaddr_trace(struct ifaddr *ifa, int refhold)
4339 {
4340 	struct in6_ifaddr_dbg *in6ifa_dbg = (struct in6_ifaddr_dbg *)ifa;
4341 	ctrace_t *tr;
4342 	u_int32_t idx;
4343 	u_int16_t *cnt;
4344 
4345 	if (!(ifa->ifa_debug & IFD_DEBUG)) {
4346 		panic("%s: ifa %p has no debug structure", __func__, ifa);
4347 		/* NOTREACHED */
4348 	}
4349 	if (refhold) {
4350 		cnt = &in6ifa_dbg->in6ifa_refhold_cnt;
4351 		tr = in6ifa_dbg->in6ifa_refhold;
4352 	} else {
4353 		cnt = &in6ifa_dbg->in6ifa_refrele_cnt;
4354 		tr = in6ifa_dbg->in6ifa_refrele;
4355 	}
4356 
4357 	idx = os_atomic_inc_orig(cnt, relaxed) % IN6IFA_TRACE_HIST_SIZE;
4358 	ctrace_record(&tr[idx]);
4359 }
4360 
4361 /*
4362  * Handle SIOCGASSOCIDS ioctl for PF_INET6 domain.
4363  */
4364 static int
in6_getassocids(struct socket * so,uint32_t * cnt,user_addr_t aidp)4365 in6_getassocids(struct socket *so, uint32_t *cnt, user_addr_t aidp)
4366 {
4367 	struct in6pcb *in6p = sotoin6pcb(so);
4368 	sae_associd_t aid;
4369 
4370 	if (in6p == NULL || in6p->inp_state == INPCB_STATE_DEAD) {
4371 		return EINVAL;
4372 	}
4373 
4374 	/* IN6PCB has no concept of association */
4375 	aid = SAE_ASSOCID_ANY;
4376 	*cnt = 0;
4377 
4378 	/* just asking how many there are? */
4379 	if (aidp == USER_ADDR_NULL) {
4380 		return 0;
4381 	}
4382 
4383 	return copyout(&aid, aidp, sizeof(aid));
4384 }
4385 
4386 /*
4387  * Handle SIOCGCONNIDS ioctl for PF_INET6 domain.
4388  */
4389 static int
in6_getconnids(struct socket * so,sae_associd_t aid,uint32_t * cnt,user_addr_t cidp)4390 in6_getconnids(struct socket *so, sae_associd_t aid, uint32_t *cnt,
4391     user_addr_t cidp)
4392 {
4393 	struct in6pcb *in6p = sotoin6pcb(so);
4394 	sae_connid_t cid;
4395 
4396 	if (in6p == NULL || in6p->inp_state == INPCB_STATE_DEAD) {
4397 		return EINVAL;
4398 	}
4399 
4400 	if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
4401 		return EINVAL;
4402 	}
4403 
4404 	/* if connected, return 1 connection count */
4405 	*cnt = ((so->so_state & SS_ISCONNECTED) ? 1 : 0);
4406 
4407 	/* just asking how many there are? */
4408 	if (cidp == USER_ADDR_NULL) {
4409 		return 0;
4410 	}
4411 
4412 	/* if IN6PCB is connected, assign it connid 1 */
4413 	cid = ((*cnt != 0) ? 1 : SAE_CONNID_ANY);
4414 
4415 	return copyout(&cid, cidp, sizeof(cid));
4416 }
4417 
4418 /*
4419  * Handle SIOCGCONNINFO ioctl for PF_INET6 domain.
4420  */
4421 int
in6_getconninfo(struct socket * so,sae_connid_t cid,uint32_t * flags,uint32_t * ifindex,int32_t * soerror,user_addr_t src,socklen_t * src_len,user_addr_t dst,socklen_t * dst_len,uint32_t * aux_type,user_addr_t aux_data,uint32_t * aux_len)4422 in6_getconninfo(struct socket *so, sae_connid_t cid, uint32_t *flags,
4423     uint32_t *ifindex, int32_t *soerror, user_addr_t src, socklen_t *src_len,
4424     user_addr_t dst, socklen_t *dst_len, uint32_t *aux_type,
4425     user_addr_t aux_data, uint32_t *aux_len)
4426 {
4427 	struct in6pcb *in6p = sotoin6pcb(so);
4428 	struct sockaddr_in6 sin6;
4429 	struct ifnet *ifp = NULL;
4430 	int error = 0;
4431 	u_int32_t copy_len = 0;
4432 
4433 	/*
4434 	 * Don't test for INPCB_STATE_DEAD since this may be called
4435 	 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
4436 	 */
4437 	if (in6p == NULL) {
4438 		error = EINVAL;
4439 		goto out;
4440 	}
4441 
4442 	if (cid != SAE_CONNID_ANY && cid != SAE_CONNID_ALL && cid != 1) {
4443 		error = EINVAL;
4444 		goto out;
4445 	}
4446 
4447 	ifp = in6p->in6p_last_outifp;
4448 	*ifindex = ((ifp != NULL) ? ifp->if_index : 0);
4449 	*soerror = so->so_error;
4450 	*flags = 0;
4451 	if (so->so_state & SS_ISCONNECTED) {
4452 		*flags |= (CIF_CONNECTED | CIF_PREFERRED);
4453 	}
4454 	if (in6p->in6p_flags & INP_BOUND_IF) {
4455 		*flags |= CIF_BOUND_IF;
4456 	}
4457 	if (!(in6p->in6p_flags & INP_IN6ADDR_ANY)) {
4458 		*flags |= CIF_BOUND_IP;
4459 	}
4460 	if (!(in6p->in6p_flags & INP_ANONPORT)) {
4461 		*flags |= CIF_BOUND_PORT;
4462 	}
4463 
4464 	bzero(&sin6, sizeof(sin6));
4465 	sin6.sin6_len = sizeof(sin6);
4466 	sin6.sin6_family = AF_INET6;
4467 
4468 	/* source address and port */
4469 	sin6.sin6_port = in6p->in6p_lport;
4470 	if (!in6_embedded_scope) {
4471 		sin6.sin6_scope_id = in6p->inp_lifscope;
4472 	}
4473 	in6_recoverscope(&sin6, &in6p->in6p_laddr, NULL);
4474 	if (*src_len == 0) {
4475 		*src_len = sin6.sin6_len;
4476 	} else {
4477 		if (src != USER_ADDR_NULL) {
4478 			copy_len = min(*src_len, sizeof(sin6));
4479 			error = copyout(&sin6, src, copy_len);
4480 			if (error != 0) {
4481 				goto out;
4482 			}
4483 			*src_len = copy_len;
4484 		}
4485 	}
4486 
4487 	/* destination address and port */
4488 	sin6.sin6_port = in6p->in6p_fport;
4489 	if (!in6_embedded_scope) {
4490 		sin6.sin6_scope_id = in6p->inp_fifscope;
4491 	}
4492 	in6_recoverscope(&sin6, &in6p->in6p_faddr, NULL);
4493 	if (*dst_len == 0) {
4494 		*dst_len = sin6.sin6_len;
4495 	} else {
4496 		if (dst != USER_ADDR_NULL) {
4497 			copy_len = min(*dst_len, sizeof(sin6));
4498 			error = copyout(&sin6, dst, copy_len);
4499 			if (error != 0) {
4500 				goto out;
4501 			}
4502 			*dst_len = copy_len;
4503 		}
4504 	}
4505 
4506 	if (SOCK_PROTO(so) == IPPROTO_TCP) {
4507 		struct conninfo_tcp tcp_ci;
4508 
4509 		*aux_type = CIAUX_TCP;
4510 		if (*aux_len == 0) {
4511 			*aux_len = sizeof(tcp_ci);
4512 		} else {
4513 			if (aux_data != USER_ADDR_NULL) {
4514 				copy_len = min(*aux_len, sizeof(tcp_ci));
4515 				bzero(&tcp_ci, sizeof(tcp_ci));
4516 				tcp_getconninfo(so, &tcp_ci);
4517 				error = copyout(&tcp_ci, aux_data, copy_len);
4518 				if (error != 0) {
4519 					goto out;
4520 				}
4521 				*aux_len = copy_len;
4522 			}
4523 		}
4524 	} else {
4525 		*aux_type = 0;
4526 		*aux_len = 0;
4527 	}
4528 
4529 out:
4530 	return error;
4531 }
4532 
4533 /*
4534  * 'u' group ioctls.
4535  *
4536  * The switch statement below does nothing at runtime, as it serves as a
4537  * compile time check to ensure that all of the socket 'u' ioctls (those
4538  * in the 'u' group going thru soo_ioctl) that are made available by the
4539  * networking stack is unique.  This works as long as this routine gets
4540  * updated each time a new interface ioctl gets added.
4541  *
4542  * Any failures at compile time indicates duplicated ioctl values.
4543  */
4544 static __attribute__((unused)) void
in6ioctl_cassert(void)4545 in6ioctl_cassert(void)
4546 {
4547 	/*
4548 	 * This is equivalent to _CASSERT() and the compiler wouldn't
4549 	 * generate any instructions, thus for compile time only.
4550 	 */
4551 	switch ((u_long)0) {
4552 	case 0:
4553 
4554 	/* bsd/netinet6/in6_var.h */
4555 	case SIOCAADDRCTL_POLICY:
4556 	case SIOCDADDRCTL_POLICY:
4557 	case SIOCDRADD_IN6_32:
4558 	case SIOCDRADD_IN6_64:
4559 	case SIOCDRDEL_IN6_32:
4560 	case SIOCDRDEL_IN6_64:
4561 		;
4562 	}
4563 }
4564 
4565 void
in6_ip6_to_sockaddr(const struct in6_addr * ip6,u_int16_t port,uint32_t ifscope,struct sockaddr_in6 * sin6,u_int32_t maxlen)4566 in6_ip6_to_sockaddr(const struct in6_addr *ip6, u_int16_t port, uint32_t ifscope,
4567     struct sockaddr_in6 *sin6, u_int32_t maxlen)
4568 {
4569 	if (maxlen < sizeof(struct sockaddr_in6)) {
4570 		return;
4571 	}
4572 
4573 	*sin6 = (struct sockaddr_in6) {
4574 		.sin6_family = AF_INET6,
4575 		.sin6_len = sizeof(*sin6),
4576 		.sin6_port = port,
4577 		.sin6_addr = *ip6,
4578 		.sin6_scope_id = IN6_IS_SCOPE_EMBED(ip6) ? ifscope : IFSCOPE_NONE,
4579 	};
4580 
4581 	if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) {
4582 		in6_verify_ifscope(&sin6->sin6_addr, ifscope);
4583 		if (in6_embedded_scope) {
4584 			sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
4585 			sin6->sin6_addr.s6_addr16[1] = 0;
4586 		}
4587 	}
4588 }
4589 
4590 /* IPv6 events */
4591 struct in6_event {
4592 	in6_evhdlr_code_t in6_event_code;
4593 	struct ifnet *in6_ifp;
4594 	struct in6_addr in6_address;
4595 	uint32_t val;
4596 };
4597 
4598 struct in6_event2kev in6_event2kev_array[IN6_EVENT_MAX] = {
4599 	{
4600 		.in6_event_code = IN6_ADDR_MARKED_DUPLICATED,
4601 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4602 		.in6_event_kev_code = KEV_ND6_DAD_FAILURE,
4603 		.in6_event_str = "IN6_ADDR_MARKED_DUPLICATED",
4604 	},
4605 	{
4606 		.in6_event_code = IN6_ADDR_MARKED_DETACHED,
4607 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4608 		.in6_event_kev_code = KEV_ND6_ADDR_DETACHED,
4609 		.in6_event_str = "IN6_ADDR_MARKED_DETACHED",
4610 	},
4611 	{
4612 		.in6_event_code = IN6_ADDR_MARKED_DEPRECATED,
4613 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4614 		.in6_event_kev_code = KEV_ND6_ADDR_DEPRECATED,
4615 		.in6_event_str = "IN6_ADDR_MARKED_DEPRECATED",
4616 	},
4617 	{
4618 		.in6_event_code = IN6_NDP_RTR_EXPIRY,
4619 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4620 		.in6_event_kev_code = KEV_ND6_RTR_EXPIRED,
4621 		.in6_event_str = "IN6_NDP_RTR_EXPIRY",
4622 	},
4623 	{
4624 		.in6_event_code = IN6_NDP_PFX_EXPIRY,
4625 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4626 		.in6_event_kev_code = KEV_ND6_PFX_EXPIRED,
4627 		.in6_event_str = "IN6_NDP_PFX_EXPIRY",
4628 	},
4629 	{
4630 		.in6_event_code = IN6_NDP_ADDR_EXPIRY,
4631 		.in6_event_kev_subclass = KEV_ND6_SUBCLASS,
4632 		.in6_event_kev_code = KEV_ND6_ADDR_EXPIRED,
4633 		.in6_event_str = "IN6_NDP_ADDR_EXPIRY",
4634 	},
4635 };
4636 
4637 void
in6_eventhdlr_callback(struct eventhandler_entry_arg arg0 __unused,in6_evhdlr_code_t in6_ev_code,struct ifnet * ifp,struct in6_addr * p_addr6,uint32_t val)4638 in6_eventhdlr_callback(struct eventhandler_entry_arg arg0 __unused,
4639     in6_evhdlr_code_t in6_ev_code, struct ifnet *ifp,
4640     struct in6_addr *p_addr6, uint32_t val)
4641 {
4642 	struct kev_msg ev_msg;
4643 	struct kev_nd6_event nd6_event;
4644 
4645 	bzero(&ev_msg, sizeof(ev_msg));
4646 	bzero(&nd6_event, sizeof(nd6_event));
4647 
4648 	nd6log0(info, "%s Event %s received for %s\n",
4649 	    __func__, in6_event2kev_array[in6_ev_code].in6_event_str,
4650 	    ip6_sprintf(p_addr6));
4651 
4652 	ev_msg.vendor_code      = KEV_VENDOR_APPLE;
4653 	ev_msg.kev_class        = KEV_NETWORK_CLASS;
4654 	ev_msg.kev_subclass     =
4655 	    in6_event2kev_array[in6_ev_code].in6_event_kev_subclass;
4656 	ev_msg.event_code       =
4657 	    in6_event2kev_array[in6_ev_code].in6_event_kev_code;
4658 
4659 	nd6_event.link_data.if_family = ifp->if_family;
4660 	nd6_event.link_data.if_unit = ifp->if_unit;
4661 	strlcpy(nd6_event.link_data.if_name, ifp->if_name,
4662 	    sizeof(nd6_event.link_data.if_name));
4663 
4664 	VERIFY(p_addr6 != NULL);
4665 	bcopy(p_addr6, &nd6_event.in6_address,
4666 	    sizeof(nd6_event.in6_address));
4667 	nd6_event.val = val;
4668 
4669 	ev_msg.dv[0].data_ptr = &nd6_event;
4670 	ev_msg.dv[0].data_length = sizeof(nd6_event);
4671 
4672 	kev_post_msg(&ev_msg);
4673 }
4674 
4675 struct in6_event_nwk_wq_entry {
4676 	struct nwk_wq_entry nwk_wqe;
4677 	struct in6_event in6_ev_arg;
4678 };
4679 
4680 static void
in6_event_callback(struct nwk_wq_entry * nwk_item)4681 in6_event_callback(struct nwk_wq_entry *nwk_item)
4682 {
4683 	struct in6_event_nwk_wq_entry *p_ev;
4684 
4685 	p_ev = __container_of(nwk_item, struct in6_event_nwk_wq_entry, nwk_wqe);
4686 
4687 	EVENTHANDLER_INVOKE(&in6_evhdlr_ctxt, in6_event,
4688 	    p_ev->in6_ev_arg.in6_event_code, p_ev->in6_ev_arg.in6_ifp,
4689 	    &p_ev->in6_ev_arg.in6_address, p_ev->in6_ev_arg.val);
4690 
4691 	kfree_type(struct in6_event_nwk_wq_entry, p_ev);
4692 }
4693 
4694 void
in6_event_enqueue_nwk_wq_entry(in6_evhdlr_code_t in6_event_code,struct ifnet * ifp,struct in6_addr * p_addr6,uint32_t val)4695 in6_event_enqueue_nwk_wq_entry(in6_evhdlr_code_t in6_event_code,
4696     struct ifnet *ifp, struct in6_addr *p_addr6,
4697     uint32_t val)
4698 {
4699 	struct in6_event_nwk_wq_entry *p_in6_ev = NULL;
4700 
4701 	p_in6_ev = kalloc_type(struct in6_event_nwk_wq_entry,
4702 	    Z_WAITOK | Z_ZERO | Z_NOFAIL);
4703 
4704 	p_in6_ev->nwk_wqe.func = in6_event_callback;
4705 	p_in6_ev->in6_ev_arg.in6_event_code = in6_event_code;
4706 	p_in6_ev->in6_ev_arg.in6_ifp = ifp;
4707 	if (p_addr6 != NULL) {
4708 		bcopy(p_addr6, &p_in6_ev->in6_ev_arg.in6_address,
4709 		    sizeof(p_in6_ev->in6_ev_arg.in6_address));
4710 	}
4711 	p_in6_ev->in6_ev_arg.val = val;
4712 
4713 	nwk_wq_enqueue(&p_in6_ev->nwk_wqe);
4714 }
4715 
4716 /*
4717  * Caller must hold in6_ifaddr_rwlock as writer.
4718  */
4719 static void
in6_iahash_remove(struct in6_ifaddr * ia)4720 in6_iahash_remove(struct in6_ifaddr *ia)
4721 {
4722 	LCK_RW_ASSERT(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
4723 	IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
4724 
4725 	if (!IA6_IS_HASHED(ia)) {
4726 		panic("%s: attempt to remove wrong ia %p from ipv6 hash table", __func__, ia);
4727 		/* NOTREACHED */
4728 	}
4729 	TAILQ_REMOVE(IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia, ia6_hash);
4730 	IA6_HASH_INIT(ia);
4731 	if (IFA_REMREF_LOCKED(&ia->ia_ifa) == NULL) {
4732 		panic("%s: unexpected (missing) refcnt ifa=%p", __func__,
4733 		    &ia->ia_ifa);
4734 		/* NOTREACHED */
4735 	}
4736 }
4737 
4738 /*
4739  * Caller must hold in6_ifaddr_rwlock as writer.
4740  */
4741 static void
in6_iahash_insert(struct in6_ifaddr * ia)4742 in6_iahash_insert(struct in6_ifaddr *ia)
4743 {
4744 	LCK_RW_ASSERT(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
4745 	IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
4746 
4747 	if (ia->ia_addr.sin6_family != AF_INET6) {
4748 		panic("%s: attempt to insert wrong ia %p into hash table", __func__, ia);
4749 		/* NOTREACHED */
4750 	} else if (IA6_IS_HASHED(ia)) {
4751 		panic("%s: attempt to double-insert ia %p into hash table", __func__, ia);
4752 		/* NOTREACHED */
4753 	}
4754 	TAILQ_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr),
4755 	    ia, ia6_hash);
4756 	IFA_ADDREF_LOCKED(&ia->ia_ifa);
4757 }
4758 
4759 /*
4760  * Some point to point interfaces that are tunnels borrow the address from
4761  * an underlying interface (e.g. VPN server). In order for source address
4762  * selection logic to find the underlying interface first, we add the address
4763  * of borrowing point to point interfaces at the end of the list.
4764  * (see rdar://6733789)
4765  *
4766  * Caller must hold in6_ifaddr_rwlock as writer.
4767  */
4768 static void
in6_iahash_insert_ptp(struct in6_ifaddr * ia)4769 in6_iahash_insert_ptp(struct in6_ifaddr *ia)
4770 {
4771 	struct in6_ifaddr *tmp_ifa;
4772 	struct ifnet *tmp_ifp;
4773 
4774 	LCK_RW_ASSERT(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
4775 	IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
4776 
4777 	if (ia->ia_addr.sin6_family != AF_INET6) {
4778 		panic("%s: attempt to insert wrong ia %p into hash table", __func__, ia);
4779 		/* NOTREACHED */
4780 	} else if (IA6_IS_HASHED(ia)) {
4781 		panic("%s: attempt to double-insert ia %p into hash table", __func__, ia);
4782 		/* NOTREACHED */
4783 	}
4784 	IFA_UNLOCK(&ia->ia_ifa);
4785 	TAILQ_FOREACH(tmp_ifa, IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia6_hash) {
4786 		IFA_LOCK(&tmp_ifa->ia_ifa);
4787 		/* ia->ia_addr won't change, so check without lock */
4788 		if (in6_are_addr_equal_scoped(&tmp_ifa->ia_addr.sin6_addr, &ia->ia_addr.sin6_addr, tmp_ifa->ia_addr.sin6_scope_id, ia->ia_addr.sin6_scope_id)) {
4789 			IFA_UNLOCK(&tmp_ifa->ia_ifa);
4790 			break;
4791 		}
4792 		IFA_UNLOCK(&tmp_ifa->ia_ifa);
4793 	}
4794 	tmp_ifp = (tmp_ifa == NULL) ? NULL : tmp_ifa->ia_ifp;
4795 
4796 	IFA_LOCK(&ia->ia_ifa);
4797 	if (tmp_ifp == NULL) {
4798 		TAILQ_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr),
4799 		    ia, ia6_hash);
4800 	} else {
4801 		TAILQ_INSERT_TAIL(IN6ADDR_HASH(&ia->ia_addr.sin6_addr),
4802 		    ia, ia6_hash);
4803 	}
4804 	IFA_ADDREF_LOCKED(&ia->ia_ifa);
4805 }
4806 
4807 /*
4808  * ipv6 socket options.
4809  *
4810  * The switch statement below does nothing at runtime, as it serves as a
4811  * compile time check to ensure that all of the ipv6 socket options are
4812  * unique.  This works as long as this routine gets updated each time a
4813  * new ipv6 socket option gets added.
4814  *
4815  * Any failures at compile time indicates duplicated ipv6 socket option
4816  * values.
4817  */
4818 static __attribute__((unused)) void
tcpsockopt_cassert(void)4819 tcpsockopt_cassert(void)
4820 {
4821 	/*
4822 	 * This is equivalent to _CASSERT() and the compiler wouldn't
4823 	 * generate any instructions, thus for compile time only.
4824 	 */
4825 	switch ((int)0) {
4826 	case 0:
4827 
4828 	/* bsd/netinet6/in6.h */
4829 	case IPV6_SOCKOPT_RESERVED1:
4830 	case IPV6_UNICAST_HOPS:
4831 	case IPV6_MULTICAST_IF:
4832 	case IPV6_MULTICAST_HOPS:
4833 	case IPV6_MULTICAST_LOOP:
4834 	case IPV6_JOIN_GROUP:
4835 	case IPV6_LEAVE_GROUP:
4836 	case IPV6_PORTRANGE:
4837 	case ICMP6_FILTER:
4838 	case IPV6_2292PKTINFO:
4839 	case IPV6_2292HOPLIMIT:
4840 	case IPV6_2292NEXTHOP:
4841 	case IPV6_2292HOPOPTS:
4842 	case IPV6_2292DSTOPTS:
4843 	case IPV6_2292RTHDR:
4844 	case IPV6_2292PKTOPTIONS:
4845 #ifdef __APPLE_USE_RFC_2292
4846 // #define IPV6_PKTINFO    IPV6_3542PKTINFO
4847 // #define IPV6_HOPLIMIT   IPV6_3542HOPLIMIT
4848 // #define IPV6_NEXTHOP    IPV6_3542NEXTHOP
4849 // #define IPV6_HOPOPTS    IPV6_3542HOPOPTS
4850 // #define IPV6_DSTOPTS    IPV6_3542DSTOPTS
4851 // #define IPV6_RTHDR      IPV6_3542RTHDR
4852 	case IPV6_PKTOPTIONS:
4853 #endif /* __APPLE_USE_RFC_2292 */
4854 	case IPV6_CHECKSUM:
4855 	case IPV6_V6ONLY:
4856 #ifndef KERNEL
4857 // #define IPV6_BINDV6ONLY         IPV6_V6ONLY
4858 #endif /* KERNEL */
4859 	case IPV6_IPSEC_POLICY:
4860 	case IPV6_FAITH:
4861 	case IPV6_FW_ADD:
4862 	case IPV6_FW_DEL:
4863 	case IPV6_FW_FLUSH:
4864 	case IPV6_FW_ZERO:
4865 	case IPV6_FW_GET:
4866 	case IPV6_RECVTCLASS:
4867 	case IPV6_TCLASS:
4868 #ifdef __APPLE_USE_RFC_3542
4869 	case IPV6_RTHDRDSTOPTS:
4870 	case IPV6_RECVPKTINFO:
4871 	case IPV6_RECVHOPLIMIT:
4872 	case IPV6_RECVRTHDR:
4873 	case IPV6_RECVHOPOPTS:
4874 	case IPV6_RECVDSTOPTS:
4875 #ifdef KERNEL
4876 	case IPV6_RECVRTHDRDSTOPTS:
4877 #endif
4878 	case IPV6_USE_MIN_MTU:
4879 	case IPV6_RECVPATHMTU:
4880 	case IPV6_PATHMTU:
4881 	case IPV6_3542PKTINFO:
4882 	case IPV6_3542HOPLIMIT:
4883 	case IPV6_3542NEXTHOP:
4884 	case IPV6_3542HOPOPTS:
4885 	case IPV6_3542DSTOPTS:
4886 	case IPV6_3542RTHDR:
4887 // #define IPV6_PKTINFO    IPV6_3542PKTINFO
4888 // #define IPV6_HOPLIMIT   IPV6_3542HOPLIMIT
4889 // #define IPV6_NEXTHOP    IPV6_3542NEXTHOP
4890 // #define IPV6_HOPOPTS    IPV6_3542HOPOPTS
4891 // #define IPV6_DSTOPTS    IPV6_3542DSTOPTS
4892 // #define IPV6_RTHDR      IPV6_3542RTHDR
4893 	case IPV6_AUTOFLOWLABEL:
4894 	case IPV6_DONTFRAG:
4895 	case IPV6_PREFER_TEMPADDR:
4896 	case IPV6_MSFILTER:
4897 #endif /* __APPLE_USE_RFC_3542 */
4898 	case IPV6_BOUND_IF:
4899 
4900 	/* bsd/netinet6/in6_private.h */
4901 	case IPV6_NO_IFT_CELLULAR:
4902 	case IPV6_OUT_IF:
4903 		;
4904 	}
4905 }
4906