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