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