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