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