]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet6/in6.c
xnu-1504.15.3.tar.gz
[apple/xnu.git] / bsd / netinet6 / in6.c
CommitLineData
2d21ac55 1/*
b7266188 2 * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
2d21ac55
A
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
9bccf70c
A
29/* $FreeBSD: src/sys/netinet6/in6.c,v 1.7.2.7 2001/08/06 20:26:22 ume Exp $ */
30/* $KAME: in6.c,v 1.187 2001/05/24 07:43:59 itojun Exp $ */
1c79356b
A
31
32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61/*
62 * Copyright (c) 1982, 1986, 1991, 1993
63 * The Regents of the University of California. All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 * 3. All advertising materials mentioning features or use of this software
74 * must display the following acknowledgement:
75 * This product includes software developed by the University of
76 * California, Berkeley and its contributors.
77 * 4. Neither the name of the University nor the names of its contributors
78 * may be used to endorse or promote products derived from this software
79 * without specific prior written permission.
80 *
81 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
82 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
84 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
87 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
89 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
90 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * SUCH DAMAGE.
92 *
93 * @(#)in.c 8.2 (Berkeley) 11/15/93
94 */
95
1c79356b
A
96
97#include <sys/param.h>
1c79356b 98#include <sys/ioctl.h>
1c79356b
A
99#include <sys/errno.h>
100#include <sys/malloc.h>
101#include <sys/socket.h>
102#include <sys/socketvar.h>
103#include <sys/sockio.h>
104#include <sys/systm.h>
105#include <sys/time.h>
106#include <sys/kernel.h>
107#include <sys/syslog.h>
9bccf70c 108#include <sys/kern_event.h>
b0d623f7 109
2d21ac55 110#include <kern/locks.h>
b0d623f7
A
111#include <kern/zalloc.h>
112#include <libkern/OSAtomic.h>
113#include <machine/machine_routines.h>
1c79356b
A
114
115#include <net/if.h>
116#include <net/if_types.h>
2d21ac55 117#include <net/if_var.h>
1c79356b 118#include <net/route.h>
1c79356b 119#include <net/if_dl.h>
2d21ac55 120#include <net/kpi_protocol.h>
1c79356b
A
121
122#include <netinet/in.h>
123#include <netinet/in_var.h>
1c79356b 124#include <netinet/if_ether.h>
9bccf70c
A
125#ifndef SCOPEDROUTING
126#include <netinet/in_systm.h>
127#include <netinet/ip.h>
128#include <netinet/in_pcb.h>
1c79356b
A
129#endif
130
131#include <netinet6/nd6.h>
132#include <netinet/ip6.h>
133#include <netinet6/ip6_var.h>
134#include <netinet6/mld6_var.h>
135#include <netinet6/ip6_mroute.h>
136#include <netinet6/in6_ifattach.h>
9bccf70c
A
137#include <netinet6/scope6_var.h>
138#ifndef SCOPEDROUTING
139#include <netinet6/in6_pcb.h>
140#endif
1c79356b
A
141
142#include <net/net_osdep.h>
143
b0d623f7
A
144#if PF
145#include <net/pfvar.h>
146#endif /* PF */
147
9bccf70c 148#ifndef __APPLE__
1c79356b
A
149MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address");
150#endif
9bccf70c 151 /*
1c79356b
A
152 * Definitions of some costant IP6 addresses.
153 */
154const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
155const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
156const struct in6_addr in6addr_nodelocal_allnodes =
157 IN6ADDR_NODELOCAL_ALLNODES_INIT;
158const struct in6_addr in6addr_linklocal_allnodes =
159 IN6ADDR_LINKLOCAL_ALLNODES_INIT;
160const struct in6_addr in6addr_linklocal_allrouters =
161 IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
162
163const struct in6_addr in6mask0 = IN6MASK0;
164const struct in6_addr in6mask32 = IN6MASK32;
165const struct in6_addr in6mask64 = IN6MASK64;
166const struct in6_addr in6mask96 = IN6MASK96;
167const struct in6_addr in6mask128 = IN6MASK128;
168
9bccf70c
A
169const struct sockaddr_in6 sa6_any = {sizeof(sa6_any), AF_INET6,
170 0, 0, IN6ADDR_ANY_INIT, 0};
171
91447636
A
172static int in6_lifaddr_ioctl(struct socket *, u_long, caddr_t,
173 struct ifnet *, struct proc *);
174static int in6_ifinit(struct ifnet *, struct in6_ifaddr *,
175 struct sockaddr_in6 *, int);
176static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *, int);
b0d623f7
A
177static struct in6_ifaddr *in6_ifaddr_alloc(int);
178static void in6_ifaddr_free(struct ifaddr *);
179static void in6_ifaddr_trace(struct ifaddr *, int);
180static struct in6_aliasreq *in6_aliasreq_to_native(void *, int,
181 struct in6_aliasreq *);
1c79356b 182
1c79356b 183struct in6_multihead in6_multihead; /* XXX BSS initialization */
2d21ac55 184extern lck_mtx_t *nd6_mutex;
b0d623f7 185extern lck_mtx_t *ip6_mutex;
2d21ac55 186extern int in6_init2done;
1c79356b 187
b0d623f7
A
188struct in6_ifaddr_dbg {
189 struct in6_ifaddr in6ifa; /* in6_ifaddr */
190 struct in6_ifaddr in6ifa_old; /* saved in6_ifaddr */
191 u_int16_t in6ifa_refhold_cnt; /* # of ifaref */
192 u_int16_t in6ifa_refrele_cnt; /* # of ifafree */
193 /*
194 * Alloc and free callers.
195 */
196 ctrace_t in6ifa_alloc;
197 ctrace_t in6ifa_free;
198 /*
199 * Circular lists of ifaref and ifafree callers.
200 */
201 ctrace_t in6ifa_refhold[CTRACE_HIST_SIZE];
202 ctrace_t in6ifa_refrele[CTRACE_HIST_SIZE];
203};
204
205static unsigned int in6ifa_debug; /* debug flags */
206static unsigned int in6ifa_size; /* size of zone element */
207static struct zone *in6ifa_zone; /* zone for in6_ifaddr */
208
209#define IN6IFA_ZONE_MAX 64 /* maximum elements in zone */
210#define IN6IFA_ZONE_NAME "in6_ifaddr" /* zone name */
211
1c79356b
A
212/*
213 * Subroutine for in6_ifaddloop() and in6_ifremloop().
214 * This routine does actual work.
215 */
216static void
217in6_ifloop_request(int cmd, struct ifaddr *ifa)
218{
1c79356b
A
219 struct sockaddr_in6 all1_sa;
220 struct rtentry *nrt = NULL;
9bccf70c 221 int e;
b0d623f7 222
1c79356b 223 bzero(&all1_sa, sizeof(all1_sa));
9bccf70c
A
224 all1_sa.sin6_family = AF_INET6;
225 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
1c79356b 226 all1_sa.sin6_addr = in6mask128;
9bccf70c
A
227
228 /*
229 * We specify the address itself as the gateway, and set the
230 * RTF_LLINFO flag, so that the corresponding host route would have
231 * the flag, and thus applications that assume traditional behavior
232 * would be happy. Note that we assume the caller of the function
233 * (probably implicitly) set nd6_rtrequest() to ifa->ifa_rtrequest,
234 * which changes the outgoing interface to the loopback interface.
235 */
b0d623f7 236 lck_mtx_lock(rnh_lock);
91447636 237 e = rtrequest_locked(cmd, ifa->ifa_addr, ifa->ifa_addr,
9bccf70c
A
238 (struct sockaddr *)&all1_sa,
239 RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
240 if (e != 0) {
241 log(LOG_ERR, "in6_ifloop_request: "
242 "%s operation failed for %s (errno=%d)\n",
243 cmd == RTM_ADD ? "ADD" : "DELETE",
244 ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
245 e);
246 }
1c79356b 247
b0d623f7
A
248 if (nrt != NULL)
249 RT_LOCK(nrt);
1c79356b
A
250 /*
251 * Make sure rt_ifa be equal to IFA, the second argument of the
252 * function.
9bccf70c
A
253 * We need this because when we refer to rt_ifa->ia6_flags in
254 * ip6_input, we assume that the rt_ifa points to the address instead
255 * of the loopback address.
1c79356b
A
256 */
257 if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
9bccf70c 258 rtsetifa(nrt, ifa);
1c79356b 259 }
9bccf70c
A
260
261 /*
262 * Report the addition/removal of the address to the routing socket.
263 * XXX: since we called rtinit for a p2p interface with a destination,
264 * we end up reporting twice in such a case. Should we rather
265 * omit the second report?
266 */
b0d623f7 267 if (nrt != NULL) {
9bccf70c
A
268 rt_newaddrmsg(cmd, ifa, e, nrt);
269 if (cmd == RTM_DELETE) {
b0d623f7 270 RT_UNLOCK(nrt);
2d21ac55 271 rtfree_locked(nrt);
9bccf70c
A
272 } else {
273 /* the cmd must be RTM_ADD here */
b0d623f7
A
274 RT_REMREF_LOCKED(nrt);
275 RT_UNLOCK(nrt);
9bccf70c
A
276 }
277 }
b0d623f7 278 lck_mtx_unlock(rnh_lock);
1c79356b
A
279}
280
281/*
9bccf70c
A
282 * Add ownaddr as loopback rtentry. We previously add the route only if
283 * necessary (ex. on a p2p link). However, since we now manage addresses
284 * separately from prefixes, we should always add the route. We can't
285 * rely on the cloning mechanism from the corresponding interface route
286 * any more.
1c79356b
A
287 */
288static void
289in6_ifaddloop(struct ifaddr *ifa)
290{
9bccf70c
A
291 struct rtentry *rt;
292
293 /* If there is no loopback entry, allocate one. */
b0d623f7
A
294 rt = rtalloc1(ifa->ifa_addr, 0, 0);
295 if (rt != NULL)
296 RT_LOCK(rt);
9bccf70c 297 if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
b0d623f7
A
298 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
299 if (rt != NULL) {
300 RT_REMREF_LOCKED(rt);
301 RT_UNLOCK(rt);
302 }
9bccf70c 303 in6_ifloop_request(RTM_ADD, ifa);
b0d623f7
A
304 } else if (rt != NULL) {
305 RT_REMREF_LOCKED(rt);
306 RT_UNLOCK(rt);
307 }
1c79356b
A
308}
309
310/*
311 * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
312 * if it exists.
313 */
314static void
91447636 315in6_ifremloop(struct ifaddr *ifa, int locked)
1c79356b 316{
9bccf70c
A
317 struct in6_ifaddr *ia;
318 struct rtentry *rt;
319 int ia_count = 0;
320
321 /*
322 * Some of BSD variants do not remove cloned routes
323 * from an interface direct route, when removing the direct route
324 * (see comments in net/net_osdep.h). Even for variants that do remove
325 * cloned routes, they could fail to remove the cloned routes when
326 * we handle multple addresses that share a common prefix.
327 * So, we should remove the route corresponding to the deleted address
328 * regardless of the result of in6_is_ifloop_auto().
329 */
330
331 /*
55e303ae 332 * Delete the entry only if exact one ifa exists. More than one ifa
9bccf70c
A
333 * can exist if we assign a same single address to multiple
334 * (probably p2p) interfaces.
335 * XXX: we should avoid such a configuration in IPv6...
336 */
91447636
A
337 if (!locked)
338 lck_mtx_lock(nd6_mutex);
339 for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
9bccf70c
A
340 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ia->ia_addr.sin6_addr)) {
341 ia_count++;
342 if (ia_count > 1)
343 break;
1c79356b 344 }
9bccf70c 345 }
91447636
A
346 if (!locked)
347 lck_mtx_unlock(nd6_mutex);
9bccf70c
A
348
349 if (ia_count == 1) {
350 /*
351 * Before deleting, check if a corresponding loopbacked host
55e303ae 352 * route surely exists. With this check, we can avoid to
9bccf70c 353 * delete an interface direct route whose destination is same
55e303ae 354 * as the address being removed. This can happen when remofing
9bccf70c
A
355 * a subnet-router anycast address on an interface attahced
356 * to a shared medium.
357 */
b0d623f7
A
358 rt = rtalloc1(ifa->ifa_addr, 0, 0);
359 if (rt != NULL) {
360 RT_LOCK(rt);
361 if ((rt->rt_flags & RTF_HOST) != 0 &&
362 (rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) {
363 RT_REMREF_LOCKED(rt);
364 RT_UNLOCK(rt);
365 in6_ifloop_request(RTM_DELETE, ifa);
366 } else {
367 RT_UNLOCK(rt);
368 }
9bccf70c 369 }
1c79356b
A
370 }
371}
372
b0d623f7
A
373#if 0
374/* Not used */
1c79356b
A
375int
376in6_ifindex2scopeid(idx)
377 int idx;
378{
379 struct ifnet *ifp;
380 struct ifaddr *ifa;
381 struct sockaddr_in6 *sin6;
382
b0d623f7
A
383 ifnet_head_lock_shared();
384 if (idx <= 0 || if_index < idx) {
385 ifnet_head_done();
1c79356b 386 return -1;
b0d623f7 387 }
91447636 388
1c79356b 389 ifp = ifindex2ifnet[idx];
91447636 390 ifnet_head_done();
1c79356b 391
91447636 392 ifnet_lock_shared(ifp);
9bccf70c 393 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
394 {
395 if (ifa->ifa_addr->sa_family != AF_INET6)
396 continue;
397 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
91447636 398 if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
b0d623f7 399 int scopeid = sin6->sin6_scope_id & 0xffff;
91447636 400 ifnet_lock_done(ifp);
b0d623f7 401 return scopeid;
91447636 402 }
1c79356b 403 }
91447636 404 ifnet_lock_done(ifp);
1c79356b
A
405
406 return -1;
407}
b0d623f7
A
408#endif
409
1c79356b
A
410
411int
9bccf70c 412in6_mask2len(mask, lim0)
1c79356b 413 struct in6_addr *mask;
9bccf70c 414 u_char *lim0;
1c79356b 415{
9bccf70c
A
416 int x = 0, y;
417 u_char *lim = lim0, *p;
418
419 if (lim0 == NULL ||
420 lim0 - (u_char *)mask > sizeof(*mask)) /* ignore the scope_id part */
421 lim = (u_char *)mask + sizeof(*mask);
422 for (p = (u_char *)mask; p < lim; x++, p++) {
423 if (*p != 0xff)
1c79356b
A
424 break;
425 }
426 y = 0;
9bccf70c 427 if (p < lim) {
1c79356b 428 for (y = 0; y < 8; y++) {
9bccf70c 429 if ((*p & (0x80 >> y)) == 0)
1c79356b
A
430 break;
431 }
432 }
9bccf70c
A
433
434 /*
435 * when the limit pointer is given, do a stricter check on the
436 * remaining bits.
437 */
438 if (p < lim) {
439 if (y != 0 && (*p & (0x00ff >> y)) != 0)
440 return(-1);
441 for (p = p + 1; p < lim; p++)
442 if (*p != 0)
443 return(-1);
444 }
445
1c79356b
A
446 return x * 8 + y;
447}
448
449void
450in6_len2mask(mask, len)
451 struct in6_addr *mask;
452 int len;
453{
454 int i;
455
456 bzero(mask, sizeof(*mask));
457 for (i = 0; i < len / 8; i++)
458 mask->s6_addr8[i] = 0xff;
459 if (len % 8)
460 mask->s6_addr8[i] = (0xff00 >> (len % 8)) & 0xff;
461}
462
b0d623f7
A
463void
464in6_aliasreq_64_to_32(struct in6_aliasreq_64 *src, struct in6_aliasreq_32 *dst)
465{
466 bzero(dst, sizeof (*dst));
467 bcopy(src->ifra_name, dst->ifra_name, sizeof (dst->ifra_name));
468 dst->ifra_addr = src->ifra_addr;
469 dst->ifra_dstaddr = src->ifra_dstaddr;
470 dst->ifra_prefixmask = src->ifra_prefixmask;
471 dst->ifra_flags = src->ifra_flags;
472 dst->ifra_lifetime.ia6t_expire = src->ifra_lifetime.ia6t_expire;
473 dst->ifra_lifetime.ia6t_preferred = src->ifra_lifetime.ia6t_preferred;
474 dst->ifra_lifetime.ia6t_vltime = src->ifra_lifetime.ia6t_vltime;
475 dst->ifra_lifetime.ia6t_pltime = src->ifra_lifetime.ia6t_pltime;
476}
477
478void
479in6_aliasreq_32_to_64(struct in6_aliasreq_32 *src, struct in6_aliasreq_64 *dst)
480{
481 bzero(dst, sizeof (*dst));
482 bcopy(src->ifra_name, dst->ifra_name, sizeof (dst->ifra_name));
483 dst->ifra_addr = src->ifra_addr;
484 dst->ifra_dstaddr = src->ifra_dstaddr;
485 dst->ifra_prefixmask = src->ifra_prefixmask;
486 dst->ifra_flags = src->ifra_flags;
487 dst->ifra_lifetime.ia6t_expire = src->ifra_lifetime.ia6t_expire;
488 dst->ifra_lifetime.ia6t_preferred = src->ifra_lifetime.ia6t_preferred;
489 dst->ifra_lifetime.ia6t_vltime = src->ifra_lifetime.ia6t_vltime;
490 dst->ifra_lifetime.ia6t_pltime = src->ifra_lifetime.ia6t_pltime;
491}
492
493static struct in6_aliasreq *
494in6_aliasreq_to_native(void *data, int data_is_64, struct in6_aliasreq *dst)
495{
496#if defined(__LP64__)
497 if (data_is_64)
498 dst = data;
499 else
500 in6_aliasreq_32_to_64((struct in6_aliasreq_32 *)data,
501 (struct in6_aliasreq_64 *)dst);
502#else
503 if (data_is_64)
504 in6_aliasreq_64_to_32((struct in6_aliasreq_64 *)data,
505 (struct in6_aliasreq_32 *)dst);
506 else
507 dst = data;
508#endif /* __LP64__ */
509 return (dst);
510}
511
1c79356b
A
512#define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
513#define ia62ifa(ia6) (&((ia6)->ia_ifa))
514
515int
b0d623f7
A
516in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
517 struct proc *p)
1c79356b
A
518{
519 struct in6_ifreq *ifr = (struct in6_ifreq *)data;
9bccf70c 520 struct in6_ifaddr *ia = NULL;
b0d623f7
A
521 struct in6_aliasreq sifra;
522 struct in6_aliasreq *ifra = NULL;
523 struct sockaddr_in6 *sa6;
524 int index, privileged, error = 0;
91447636 525 struct timeval timenow;
b0d623f7 526 int p64 = proc_is64bit(p);
91447636
A
527
528 getmicrotime(&timenow);
1c79356b 529
b0d623f7 530 privileged = (proc_suser(p) == 0);
b7266188 531#if MROUTING
1c79356b
A
532 switch (cmd) {
533 case SIOCGETSGCNT_IN6:
b0d623f7
A
534 case SIOCGETMIFCNT_IN6_32:
535 case SIOCGETMIFCNT_IN6_64:
1c79356b
A
536 return (mrt6_ioctl(cmd, data));
537 }
b7266188 538#endif
1c79356b 539 if (ifp == NULL)
b0d623f7 540 return (EOPNOTSUPP);
1c79356b
A
541
542 switch (cmd) {
91447636
A
543 case SIOCAUTOCONF_START:
544 case SIOCAUTOCONF_STOP:
b0d623f7
A
545 case SIOCLL_START_32:
546 case SIOCLL_START_64:
91447636 547 case SIOCLL_STOP:
b0d623f7
A
548 case SIOCPROTOATTACH_IN6_32:
549 case SIOCPROTOATTACH_IN6_64:
91447636
A
550 case SIOCPROTODETACH_IN6:
551 if (!privileged)
b0d623f7 552 return (EPERM);
91447636 553 break;
1c79356b
A
554 case SIOCSNDFLUSH_IN6:
555 case SIOCSPFXFLUSH_IN6:
556 case SIOCSRTRFLUSH_IN6:
b0d623f7
A
557 case SIOCSDEFIFACE_IN6_32:
558 case SIOCSDEFIFACE_IN6_64:
1c79356b
A
559 case SIOCSIFINFO_FLAGS:
560 if (!privileged)
b0d623f7 561 return (EPERM);
55e303ae 562 /* fall through */
9bccf70c 563 case OSIOCGIFINFO_IN6:
1c79356b 564 case SIOCGIFINFO_IN6:
b0d623f7
A
565 case SIOCGDRLST_IN6_32:
566 case SIOCGDRLST_IN6_64:
567 case SIOCGPRLST_IN6_32:
568 case SIOCGPRLST_IN6_64:
569 case SIOCGNBRINFO_IN6_32:
570 case SIOCGNBRINFO_IN6_64:
571 case SIOCGDEFIFACE_IN6_32:
572 case SIOCGDEFIFACE_IN6_64:
573 return (nd6_ioctl(cmd, data, ifp));
1c79356b
A
574 }
575
576 switch (cmd) {
577 case SIOCSIFPREFIX_IN6:
578 case SIOCDIFPREFIX_IN6:
579 case SIOCAIFPREFIX_IN6:
580 case SIOCCIFPREFIX_IN6:
581 case SIOCSGIFPREFIX_IN6:
1c79356b 582 case SIOCGIFPREFIX_IN6:
9bccf70c
A
583 log(LOG_NOTICE,
584 "prefix ioctls are now invalidated. "
585 "please use ifconfig.\n");
b0d623f7 586 return (EOPNOTSUPP);
9bccf70c
A
587 }
588
55e303ae 589 switch (cmd) {
9bccf70c
A
590 case SIOCSSCOPE6:
591 if (!privileged)
b0d623f7
A
592 return (EPERM);
593 return (scope6_set(ifp, ifr->ifr_ifru.ifru_scope_id));
594 /* NOTREACHED */
595
9bccf70c 596 case SIOCGSCOPE6:
b0d623f7
A
597 return (scope6_get(ifp, ifr->ifr_ifru.ifru_scope_id));
598 /* NOTREACHED */
599
9bccf70c 600 case SIOCGSCOPE6DEF:
b0d623f7 601 return (scope6_get_default(ifr->ifr_ifru.ifru_scope_id));
1c79356b
A
602 }
603
604 switch (cmd) {
605 case SIOCALIFADDR:
606 case SIOCDLIFADDR:
607 if (!privileged)
608 return(EPERM);
55e303ae 609 /* fall through */
1c79356b 610 case SIOCGLIFADDR:
b0d623f7
A
611 return (in6_lifaddr_ioctl(so, cmd, data, ifp, p));
612 }
613
614 /*
615 * Point ifra and sa6 to the right places depending on the command.
616 */
617 switch (cmd) {
618 case SIOCLL_START_32:
619 case SIOCAIFADDR_IN6_32:
620 /*
621 * Convert user ifra to the kernel form, when appropriate.
622 * This allows the conversion between different data models
623 * to be centralized, so that it can be passed around to other
624 * routines that are expecting the kernel form.
625 */
626 ifra = in6_aliasreq_to_native(data, 0, &sifra);
627 sa6 = (struct sockaddr_in6 *)&ifra->ifra_addr;
628 break;
629
630 case SIOCLL_START_64:
631 case SIOCAIFADDR_IN6_64:
632 ifra = in6_aliasreq_to_native(data, 1, &sifra);
633 sa6 = (struct sockaddr_in6 *)&ifra->ifra_addr;
634 break;
635
636 case SIOCSIFADDR_IN6: /* deprecated */
637 case SIOCGIFADDR_IN6:
638 case SIOCSIFDSTADDR_IN6: /* deprecated */
639 case SIOCSIFNETMASK_IN6: /* deprecated */
640 case SIOCGIFDSTADDR_IN6:
641 case SIOCGIFNETMASK_IN6:
642 case SIOCDIFADDR_IN6:
643 case SIOCGIFPSRCADDR_IN6:
644 case SIOCGIFPDSTADDR_IN6:
645 case SIOCGIFAFLAG_IN6:
646 case SIOCGIFALIFETIME_IN6:
647 case SIOCSIFALIFETIME_IN6:
648 case SIOCGIFSTAT_IN6:
649 case SIOCGIFSTAT_ICMP6:
650 sa6 = &ifr->ifr_addr;
651 break;
652
653 default:
654 sa6 = NULL;
655 break;
1c79356b 656 }
9bccf70c
A
657
658 switch (cmd) {
659
55e303ae 660 case SIOCAUTOCONF_START:
91447636 661 ifnet_lock_exclusive(ifp);
55e303ae 662 ifp->if_eflags |= IFEF_ACCEPT_RTADVD;
91447636 663 ifnet_lock_done(ifp);
55e303ae 664 return (0);
b0d623f7 665 /* NOTREACHED */
55e303ae 666
b0d623f7
A
667 case SIOCAUTOCONF_STOP: {
668 struct in6_ifaddr *nia = NULL;
55e303ae 669
b0d623f7
A
670 ifnet_lock_exclusive(ifp);
671 ifp->if_eflags &= ~IFEF_ACCEPT_RTADVD;
672 ifnet_lock_done(ifp);
55e303ae 673
b0d623f7
A
674 /* nuke prefix list. this may try to remove some ifaddrs as well */
675 in6_purgeprefix(ifp);
55e303ae 676
b0d623f7
A
677 /* removed autoconfigured address from interface */
678 lck_mtx_lock(nd6_mutex);
679 for (ia = in6_ifaddrs; ia != NULL; ia = nia) {
680 nia = ia->ia_next;
681 if (ia->ia_ifa.ifa_ifp != ifp)
682 continue;
683 if (ia->ia6_flags & IN6_IFF_AUTOCONF)
684 in6_purgeaddr(&ia->ia_ifa, 1);
685 }
686 lck_mtx_unlock(nd6_mutex);
687 return (0);
688 }
55e303ae 689
b0d623f7
A
690 case SIOCLL_START_32:
691 case SIOCLL_START_64:
692 /*
693 * NOTE: All the interface specific DLIL attachements should
694 * be done here. They are currently done in in6_ifattach()
695 * for the interfaces that need it.
55e303ae 696 */
b0d623f7
A
697 if (((ifp->if_type == IFT_PPP) || ((ifp->if_eflags & IFEF_NOAUTOIPV6LL) != 0)) &&
698 ifra->ifra_addr.sin6_family == AF_INET6 &&
699 ifra->ifra_dstaddr.sin6_family == AF_INET6) {
700 /* some interfaces may provide LinkLocal addresses */
701 error = in6_if_up(ifp, ifra);
702 } else {
703 error = in6_if_up(ifp, 0);
704 }
705 return (error);
706 /* NOTREACHED */
55e303ae 707
b0d623f7
A
708 case SIOCLL_STOP: {
709 struct in6_ifaddr *nia = NULL;
55e303ae 710
b0d623f7 711 /* removed link local addresses from interface */
55e303ae 712
b0d623f7
A
713 lck_mtx_lock(nd6_mutex);
714 for (ia = in6_ifaddrs; ia != NULL; ia = nia) {
715 nia = ia->ia_next;
716 if (ia->ia_ifa.ifa_ifp != ifp)
717 continue;
718 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr))
719 in6_purgeaddr(&ia->ia_ifa, 1);
55e303ae 720 }
b0d623f7
A
721 lck_mtx_unlock(nd6_mutex);
722 return (0);
723 }
55e303ae 724
b0d623f7
A
725 case SIOCPROTOATTACH_IN6_32:
726 case SIOCPROTOATTACH_IN6_64:
b7266188
A
727 if ((error = proto_plumb(PF_INET6, ifp)))
728 printf("SIOCPROTOATTACH_IN6: %s "
729 "error=%d\n", if_name(ifp), error);
55e303ae 730 return (error);
b0d623f7 731 /* NOTREACHED */
55e303ae 732
55e303ae 733 case SIOCPROTODETACH_IN6:
b0d623f7
A
734 /* Cleanup interface routes and addresses */
735 in6_purgeif(ifp);
55e303ae 736
2d21ac55 737 if ((error = proto_unplumb(PF_INET6, ifp)))
b0d623f7
A
738 printf("SIOCPROTODETACH_IN6: %s error=%d\n",
739 if_name(ifp), error);
740 return (error);
9bccf70c 741 }
b0d623f7 742
1c79356b 743 /*
b0d623f7
A
744 * Find address for this interface, if it exists; depending
745 * on the ioctl command, sa6 points to the address in ifra/ifr.
1c79356b 746 */
b0d623f7 747 if (sa6 != NULL && sa6->sin6_family == AF_INET6) {
1c79356b
A
748 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
749 if (sa6->sin6_addr.s6_addr16[1] == 0) {
9bccf70c 750 /* link ID is not embedded by the user */
1c79356b 751 sa6->sin6_addr.s6_addr16[1] =
b0d623f7 752 htons(ifp->if_index);
1c79356b 753 } else if (sa6->sin6_addr.s6_addr16[1] !=
b0d623f7
A
754 htons(ifp->if_index)) {
755 return (EINVAL); /* link ID contradicts */
1c79356b
A
756 }
757 if (sa6->sin6_scope_id) {
758 if (sa6->sin6_scope_id !=
759 (u_int32_t)ifp->if_index)
b0d623f7 760 return (EINVAL);
1c79356b
A
761 sa6->sin6_scope_id = 0; /* XXX: good way? */
762 }
763 }
b0d623f7
A
764 ia = in6ifa_ifpwithaddr(ifp, &sa6->sin6_addr);
765 } else {
766 ia = NULL;
1c79356b
A
767 }
768
769 switch (cmd) {
9bccf70c
A
770 case SIOCSIFADDR_IN6:
771 case SIOCSIFDSTADDR_IN6:
772 case SIOCSIFNETMASK_IN6:
773 /*
774 * Since IPv6 allows a node to assign multiple addresses
775 * on a single interface, SIOCSIFxxx ioctls are not suitable
776 * and should be unused.
777 */
778 /* we decided to obsolete this command (20000704) */
91447636
A
779 error = EINVAL;
780 goto ioctl_cleanup;
1c79356b
A
781
782 case SIOCDIFADDR_IN6:
783 /*
9bccf70c 784 * for IPv4, we look for existing in_ifaddr here to allow
1c79356b
A
785 * "ifconfig if0 delete" to remove first IPv4 address on the
786 * interface. For IPv6, as the spec allow multiple interface
787 * address from the day one, we consider "remove the first one"
9bccf70c 788 * semantics to be not preferable.
1c79356b 789 */
91447636
A
790 if (ia == NULL) {
791 error = EADDRNOTAVAIL;
792 goto ioctl_cleanup;
793 }
1c79356b 794 /* FALLTHROUGH */
b0d623f7
A
795 case SIOCAIFADDR_IN6_32:
796 case SIOCAIFADDR_IN6_64:
1c79356b 797 /*
9bccf70c 798 * We always require users to specify a valid IPv6 address for
b0d623f7
A
799 * the corresponding operation. Use "sa6" instead of "ifra"
800 * since SIOCDIFADDR_IN6 falls thru above.
1c79356b 801 */
b0d623f7
A
802 if (sa6->sin6_family != AF_INET6 ||
803 sa6->sin6_len != sizeof(struct sockaddr_in6)) {
91447636
A
804 error = EAFNOSUPPORT;
805 goto ioctl_cleanup;
806 }
807 if (!privileged) {
808 error = EPERM;
809 goto ioctl_cleanup;
810 }
1c79356b 811
1c79356b
A
812 break;
813
814 case SIOCGIFADDR_IN6:
815 /* This interface is basically deprecated. use SIOCGIFCONF. */
816 /* fall through */
817 case SIOCGIFAFLAG_IN6:
818 case SIOCGIFNETMASK_IN6:
819 case SIOCGIFDSTADDR_IN6:
820 case SIOCGIFALIFETIME_IN6:
821 /* must think again about its semantics */
91447636
A
822 if (ia == NULL) {
823 error = EADDRNOTAVAIL;
824 goto ioctl_cleanup;
825 }
1c79356b 826 break;
1c79356b 827
b0d623f7 828 case SIOCSIFALIFETIME_IN6:
91447636
A
829 if (!privileged) {
830 error = EPERM;
831 goto ioctl_cleanup;
832 }
833 if (ia == NULL) {
834 error = EADDRNOTAVAIL;
835 goto ioctl_cleanup;
836 }
1c79356b 837 /* sanity for overflow - beware unsigned */
b0d623f7
A
838 if (p64) {
839 struct in6_addrlifetime_64 *lt;
840
841 lt = (struct in6_addrlifetime_64 *)
842 &ifr->ifr_ifru.ifru_lifetime;
843 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
844 && lt->ia6t_vltime + timenow.tv_sec < timenow.tv_sec) {
845 error = EINVAL;
846 goto ioctl_cleanup;
847 }
848 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
849 && lt->ia6t_pltime + timenow.tv_sec < timenow.tv_sec) {
850 error = EINVAL;
851 goto ioctl_cleanup;
852 }
853 } else {
854 struct in6_addrlifetime_32 *lt;
855
856 lt = (struct in6_addrlifetime_32 *)
857 &ifr->ifr_ifru.ifru_lifetime;
858 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
859 && lt->ia6t_vltime + timenow.tv_sec < timenow.tv_sec) {
860 error = EINVAL;
861 goto ioctl_cleanup;
862 }
863 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
864 && lt->ia6t_pltime + timenow.tv_sec < timenow.tv_sec) {
865 error = EINVAL;
866 goto ioctl_cleanup;
867 }
1c79356b
A
868 }
869 break;
1c79356b
A
870 }
871
872 switch (cmd) {
1c79356b
A
873 case SIOCGIFADDR_IN6:
874 ifr->ifr_addr = ia->ia_addr;
875 break;
876
877 case SIOCGIFDSTADDR_IN6:
91447636
A
878 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
879 error = EINVAL;
880 goto ioctl_cleanup;
881 }
9bccf70c
A
882 /*
883 * XXX: should we check if ifa_dstaddr is NULL and return
884 * an error?
885 */
1c79356b
A
886 ifr->ifr_dstaddr = ia->ia_dstaddr;
887 break;
888
889 case SIOCGIFNETMASK_IN6:
890 ifr->ifr_addr = ia->ia_prefixmask;
891 break;
892
893 case SIOCGIFAFLAG_IN6:
894 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
895 break;
896
897 case SIOCGIFSTAT_IN6:
91447636
A
898 if (ifp == NULL) {
899 error = EINVAL;
900 goto ioctl_cleanup;
901 }
902 index = ifp->if_index;
b0d623f7 903 lck_mtx_lock(ip6_mutex);
91447636
A
904 if (in6_ifstat == NULL || index >= in6_ifstatmax
905 || in6_ifstat[index] == NULL) {
1c79356b
A
906 /* return EAFNOSUPPORT? */
907 bzero(&ifr->ifr_ifru.ifru_stat,
b0d623f7
A
908 sizeof (ifr->ifr_ifru.ifru_stat));
909 } else {
91447636 910 ifr->ifr_ifru.ifru_stat = *in6_ifstat[index];
b0d623f7
A
911 }
912 lck_mtx_unlock(ip6_mutex);
1c79356b
A
913 break;
914
915 case SIOCGIFSTAT_ICMP6:
91447636
A
916 if (ifp == NULL) {
917 error = EINVAL;
918 goto ioctl_cleanup;
919 }
920 index = ifp->if_index;
b0d623f7 921 lck_mtx_lock(ip6_mutex);
91447636
A
922 if (icmp6_ifstat == NULL || index >= icmp6_ifstatmax ||
923 icmp6_ifstat[index] == NULL) {
1c79356b
A
924 /* return EAFNOSUPPORT? */
925 bzero(&ifr->ifr_ifru.ifru_stat,
b0d623f7
A
926 sizeof (ifr->ifr_ifru.ifru_icmp6stat));
927 } else {
928 ifr->ifr_ifru.ifru_icmp6stat = *icmp6_ifstat[index];
929 }
930 lck_mtx_unlock(ip6_mutex);
1c79356b 931 break;
1c79356b 932
1c79356b 933 case SIOCGIFALIFETIME_IN6:
b0d623f7
A
934 if (p64) {
935 struct in6_addrlifetime_64 *lt;
936
937 lt = (struct in6_addrlifetime_64 *)
938 &ifr->ifr_ifru.ifru_lifetime;
939 lt->ia6t_expire = ia->ia6_lifetime.ia6t_expire;
940 lt->ia6t_preferred = ia->ia6_lifetime.ia6t_preferred;
941 lt->ia6t_vltime = ia->ia6_lifetime.ia6t_vltime;
942 lt->ia6t_pltime = ia->ia6_lifetime.ia6t_pltime;
943 } else {
944 struct in6_addrlifetime_32 *lt;
945
946 lt = (struct in6_addrlifetime_32 *)
947 &ifr->ifr_ifru.ifru_lifetime;
948 lt->ia6t_expire =
949 (uint32_t)ia->ia6_lifetime.ia6t_expire;
950 lt->ia6t_preferred =
951 (uint32_t)ia->ia6_lifetime.ia6t_preferred;
952 lt->ia6t_vltime =
953 (uint32_t)ia->ia6_lifetime.ia6t_vltime;
954 lt->ia6t_pltime =
955 (uint32_t)ia->ia6_lifetime.ia6t_pltime;
956 }
1c79356b
A
957 break;
958
959 case SIOCSIFALIFETIME_IN6:
b0d623f7
A
960 if (p64) {
961 struct in6_addrlifetime_64 *lt;
962
963 lt = (struct in6_addrlifetime_64 *)
964 &ifr->ifr_ifru.ifru_lifetime;
965 ia->ia6_lifetime.ia6t_expire = lt->ia6t_expire;
966 ia->ia6_lifetime.ia6t_preferred = lt->ia6t_preferred;
967 ia->ia6_lifetime.ia6t_vltime = lt->ia6t_vltime;
968 ia->ia6_lifetime.ia6t_pltime = lt->ia6t_pltime;
969 } else {
970 struct in6_addrlifetime_32 *lt;
971
972 lt = (struct in6_addrlifetime_32 *)
973 &ifr->ifr_ifru.ifru_lifetime;
974 ia->ia6_lifetime.ia6t_expire =
975 (uint32_t)lt->ia6t_expire;
976 ia->ia6_lifetime.ia6t_preferred =
977 (uint32_t)lt->ia6t_preferred;
978 ia->ia6_lifetime.ia6t_vltime = lt->ia6t_vltime;
979 ia->ia6_lifetime.ia6t_pltime = lt->ia6t_pltime;
980 }
1c79356b
A
981 /* for sanity */
982 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
983 ia->ia6_lifetime.ia6t_expire =
91447636 984 timenow.tv_sec + ia->ia6_lifetime.ia6t_vltime;
1c79356b
A
985 } else
986 ia->ia6_lifetime.ia6t_expire = 0;
987 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
988 ia->ia6_lifetime.ia6t_preferred =
91447636 989 timenow.tv_sec + ia->ia6_lifetime.ia6t_pltime;
1c79356b
A
990 } else
991 ia->ia6_lifetime.ia6t_preferred = 0;
992 break;
993
b0d623f7
A
994 case SIOCAIFADDR_IN6_32:
995 case SIOCAIFADDR_IN6_64: {
91447636 996 int i;
9bccf70c 997 struct nd_prefix pr0, *pr;
b0d623f7 998
91447636 999 /* Attempt to attache the protocol, in case it isn't attached */
2d21ac55 1000 error = proto_plumb(PF_INET6, ifp);
91447636
A
1001 if (error) {
1002 if (error != EEXIST) {
b0d623f7
A
1003 printf("SIOCAIFADDR_IN6: %s can't plumb "
1004 "protocol error=%d\n", if_name(ifp), error);
91447636 1005 goto ioctl_cleanup;
55e303ae 1006 }
b0d623f7 1007
91447636
A
1008 /* Ignore, EEXIST */
1009 error = 0;
b0d623f7 1010 } else {
91447636 1011 /* PF_INET6 wasn't previously attached */
b0d623f7
A
1012 if ((error = in6_if_up(ifp, NULL)) != 0)
1013 goto ioctl_cleanup;
9bccf70c 1014 }
1c79356b 1015
1c79356b 1016 /*
9bccf70c
A
1017 * first, make or update the interface address structure,
1018 * and link it to the list.
1c79356b 1019 */
b0d623f7 1020 if ((error = in6_update_ifa(ifp, ifra, ia, M_WAITOK)) != 0)
91447636 1021 goto ioctl_cleanup;
9bccf70c 1022
1c79356b 1023 /*
9bccf70c
A
1024 * then, make the prefix on-link on the interface.
1025 * XXX: we'd rather create the prefix before the address, but
1026 * we need at least one address to install the corresponding
1027 * interface route, so we configure the address first.
1c79356b 1028 */
1c79356b 1029
9bccf70c
A
1030 /*
1031 * convert mask to prefix length (prefixmask has already
1032 * been validated in in6_update_ifa().
1033 */
1034 bzero(&pr0, sizeof(pr0));
1035 pr0.ndpr_ifp = ifp;
1036 pr0.ndpr_plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
1037 NULL);
1038 if (pr0.ndpr_plen == 128)
1039 break; /* we don't need to install a host route. */
1040 pr0.ndpr_prefix = ifra->ifra_addr;
1041 pr0.ndpr_mask = ifra->ifra_prefixmask.sin6_addr;
1042 /* apply the mask for safety. */
1043 for (i = 0; i < 4; i++) {
1044 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
1045 ifra->ifra_prefixmask.sin6_addr.s6_addr32[i];
1c79356b 1046 }
9bccf70c 1047 /*
55e303ae
A
1048 * XXX: since we don't have an API to set prefix (not address)
1049 * lifetimes, we just use the same lifetimes as addresses.
1050 * The (temporarily) installed lifetimes can be overridden by
1051 * later advertised RAs (when accept_rtadv is non 0), which is
1052 * an intended behavior.
9bccf70c
A
1053 */
1054 pr0.ndpr_raf_onlink = 1; /* should be configurable? */
1055 pr0.ndpr_raf_auto =
1056 ((ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0);
1057 pr0.ndpr_vltime = ifra->ifra_lifetime.ia6t_vltime;
1058 pr0.ndpr_pltime = ifra->ifra_lifetime.ia6t_pltime;
1059
1060 /* add the prefix if there's one. */
1061 if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
1062 /*
1063 * nd6_prelist_add will install the corresponding
1064 * interface route.
1065 */
1066 if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
91447636 1067 goto ioctl_cleanup;
9bccf70c
A
1068 if (pr == NULL) {
1069 log(LOG_ERR, "nd6_prelist_add succedded but "
1070 "no prefix\n");
91447636
A
1071 error = EINVAL;
1072 goto ioctl_cleanup;
1c79356b 1073 }
1c79356b 1074 }
b0d623f7
A
1075 if (ia != NULL)
1076 ifafree(&ia->ia_ifa);
9bccf70c
A
1077 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr))
1078 == NULL) {
b0d623f7 1079 /* XXX: this should not happen! */
9bccf70c
A
1080 log(LOG_ERR, "in6_control: addition succeeded, but"
1081 " no ifaddr\n");
1082 } else {
1083 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
1084 ia->ia6_ndpr == NULL) { /* new autoconfed addr */
2d21ac55 1085 lck_mtx_lock(nd6_mutex);
9bccf70c 1086 pr->ndpr_refcnt++;
2d21ac55
A
1087 lck_mtx_unlock(nd6_mutex);
1088 ia->ia6_ndpr = pr;
9bccf70c
A
1089
1090 /*
1091 * If this is the first autoconf address from
1092 * the prefix, create a temporary address
1093 * as well (when specified).
1094 */
1095 if (ip6_use_tempaddr &&
1096 pr->ndpr_refcnt == 1) {
1097 int e;
b0d623f7
A
1098 if ((e = in6_tmpifadd(ia, 1,
1099 M_WAITOK)) != 0) {
9bccf70c
A
1100 log(LOG_NOTICE, "in6_control: "
1101 "failed to create a "
1102 "temporary address, "
1103 "errno=%d\n",
1104 e);
1105 }
1106 }
1107 }
1c79356b
A
1108
1109 /*
9bccf70c
A
1110 * this might affect the status of autoconfigured
1111 * addresses, that is, this address might make
1112 * other addresses detached.
1c79356b 1113 */
91447636 1114 pfxlist_onlink_check(0);
1c79356b
A
1115 }
1116
2d21ac55
A
1117 /* Drop use count held above during lookup/add */
1118 ndpr_rele(pr, FALSE);
b0d623f7
A
1119#if PF
1120 pf_ifaddr_hook(ifp, cmd);
1121#endif /* PF */
9bccf70c
A
1122 break;
1123 }
1124
b0d623f7 1125 case SIOCDIFADDR_IN6: {
9bccf70c
A
1126 int i = 0;
1127 struct nd_prefix pr0, *pr;
1c79356b
A
1128
1129 /*
9bccf70c
A
1130 * If the address being deleted is the only one that owns
1131 * the corresponding prefix, expire the prefix as well.
1132 * XXX: theoretically, we don't have to warry about such
1133 * relationship, since we separate the address management
1134 * and the prefix management. We do this, however, to provide
1135 * as much backward compatibility as possible in terms of
1136 * the ioctl operation.
1c79356b 1137 */
9bccf70c
A
1138 bzero(&pr0, sizeof(pr0));
1139 pr0.ndpr_ifp = ifp;
1140 pr0.ndpr_plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr,
1141 NULL);
1142 if (pr0.ndpr_plen == 128)
1143 goto purgeaddr;
1144 pr0.ndpr_prefix = ia->ia_addr;
1145 pr0.ndpr_mask = ia->ia_prefixmask.sin6_addr;
1146 for (i = 0; i < 4; i++) {
1147 pr0.ndpr_prefix.sin6_addr.s6_addr32[i] &=
1148 ia->ia_prefixmask.sin6_addr.s6_addr32[i];
1c79356b 1149 }
9bccf70c
A
1150 /*
1151 * The logic of the following condition is a bit complicated.
1152 * We expire the prefix when
1153 * 1. the address obeys autoconfiguration and it is the
1154 * only owner of the associated prefix, or
1155 * 2. the address does not obey autoconf and there is no
1156 * other owner of the prefix.
1157 */
1158 if ((pr = nd6_prefix_lookup(&pr0)) != NULL &&
1159 (((ia->ia6_flags & IN6_IFF_AUTOCONF) != 0 &&
1160 pr->ndpr_refcnt == 1) ||
1161 ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0 &&
1162 pr->ndpr_refcnt == 0))) {
1163 pr->ndpr_expire = 1; /* XXX: just for expiration */
1c79356b
A
1164 }
1165
2d21ac55
A
1166 /* Drop use count held above during lookup */
1167 if (pr != NULL)
1168 ndpr_rele(pr, FALSE);
1169
b0d623f7 1170purgeaddr:
91447636 1171 in6_purgeaddr(&ia->ia_ifa, 0);
b0d623f7
A
1172#if PF
1173 pf_ifaddr_hook(ifp, cmd);
1174#endif /* PF */
1c79356b 1175 break;
9bccf70c 1176 }
1c79356b
A
1177
1178 default:
2d21ac55 1179 error = ifnet_ioctl(ifp, PF_INET6, cmd, data);
91447636 1180 goto ioctl_cleanup;
1c79356b 1181 }
91447636 1182ioctl_cleanup:
b0d623f7
A
1183 if (ia != NULL)
1184 ifafree(&ia->ia_ifa);
1185 return (error);
1c79356b
A
1186}
1187
9bccf70c
A
1188/*
1189 * Update parameters of an IPv6 interface address.
1190 * If necessary, a new entry is created and linked into address chains.
1191 * This function is separated from in6_control().
1192 * XXX: should this be performed under splnet()?
1193 */
1194int
b0d623f7 1195in6_update_ifa(ifp, ifra, ia, how)
9bccf70c
A
1196 struct ifnet *ifp;
1197 struct in6_aliasreq *ifra;
1198 struct in6_ifaddr *ia;
b0d623f7 1199 int how;
1c79356b 1200{
9bccf70c
A
1201 int error = 0, hostIsNew = 0, plen = -1;
1202 struct in6_ifaddr *oia;
1203 struct sockaddr_in6 dst6;
1204 struct in6_addrlifetime *lt;
91447636 1205 struct timeval timenow;
1c79356b 1206
91447636
A
1207
1208 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
9bccf70c
A
1209 /* Validate parameters */
1210 if (ifp == NULL || ifra == NULL) /* this maybe redundant */
1211 return(EINVAL);
1212
1213 /*
1214 * The destination address for a p2p link must have a family
1215 * of AF_UNSPEC or AF_INET6.
1216 */
1217 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
1218 ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
1219 ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
1220 return(EAFNOSUPPORT);
1221 /*
1222 * validate ifra_prefixmask. don't check sin6_family, netmask
1223 * does not carry fields other than sin6_len.
1224 */
1225 if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
1226 return(EINVAL);
91447636
A
1227 /*
1228 * Set the address family value for the mask if it was not set.
1229 * Radar 3899482.
1230 */
1231 if (ifra->ifra_prefixmask.sin6_len == sizeof(struct sockaddr_in6) &&
1232 ifra->ifra_prefixmask.sin6_family == 0) {
1233 ifra->ifra_prefixmask.sin6_family = AF_INET6;
1234 }
9bccf70c
A
1235 /*
1236 * Because the IPv6 address architecture is classless, we require
1237 * users to specify a (non 0) prefix length (mask) for a new address.
1238 * We also require the prefix (when specified) mask is valid, and thus
1239 * reject a non-consecutive mask.
1240 */
1241 if (ia == NULL && ifra->ifra_prefixmask.sin6_len == 0)
1242 return(EINVAL);
1243 if (ifra->ifra_prefixmask.sin6_len != 0) {
1244 plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr,
1245 (u_char *)&ifra->ifra_prefixmask +
1246 ifra->ifra_prefixmask.sin6_len);
1247 if (plen <= 0)
1248 return(EINVAL);
1249 }
1250 else {
1251 /*
55e303ae 1252 * In this case, ia must not be NULL. We just use its prefix
9bccf70c
A
1253 * length.
1254 */
1255 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
1256 }
1257 /*
1258 * If the destination address on a p2p interface is specified,
1259 * and the address is a scoped one, validate/set the scope
1260 * zone identifier.
1261 */
1262 dst6 = ifra->ifra_dstaddr;
1263 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) &&
1264 (dst6.sin6_family == AF_INET6)) {
1265 int scopeid;
1266
1267#ifndef SCOPEDROUTING
1268 if ((error = in6_recoverscope(&dst6,
1269 &ifra->ifra_dstaddr.sin6_addr,
1270 ifp)) != 0)
1271 return(error);
1272#endif
1273 scopeid = in6_addr2scopeid(ifp, &dst6.sin6_addr);
1274 if (dst6.sin6_scope_id == 0) /* user omit to specify the ID. */
1275 dst6.sin6_scope_id = scopeid;
1276 else if (dst6.sin6_scope_id != scopeid)
1277 return(EINVAL); /* scope ID mismatch. */
1278#ifndef SCOPEDROUTING
1279 if ((error = in6_embedscope(&dst6.sin6_addr, &dst6, NULL, NULL))
1280 != 0)
1281 return(error);
1282 dst6.sin6_scope_id = 0; /* XXX */
1283#endif
1284 }
1285 /*
1286 * The destination address can be specified only for a p2p or a
1287 * loopback interface. If specified, the corresponding prefix length
1288 * must be 128.
1289 */
1290 if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
1291 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
1292 /* XXX: noisy message */
1293 log(LOG_INFO, "in6_update_ifa: a destination can be "
1294 "specified for a p2p or a loopback IF only\n");
1295 return(EINVAL);
1296 }
1297 if (plen != 128) {
1298 /*
1299 * The following message seems noisy, but we dare to
1300 * add it for diagnosis.
1301 */
1302 log(LOG_INFO, "in6_update_ifa: prefixlen must be 128 "
1303 "when dstaddr is specified\n");
1304 return(EINVAL);
1305 }
1306 }
1307 /* lifetime consistency check */
91447636
A
1308
1309 getmicrotime(&timenow);
9bccf70c
A
1310 lt = &ifra->ifra_lifetime;
1311 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
91447636 1312 && lt->ia6t_vltime + timenow.tv_sec < timenow.tv_sec) {
9bccf70c
A
1313 return EINVAL;
1314 }
1315 if (lt->ia6t_vltime == 0) {
1316 /*
1317 * the following log might be noisy, but this is a typical
1318 * configuration mistake or a tool's bug.
1319 */
1320 log(LOG_INFO,
1321 "in6_update_ifa: valid lifetime is 0 for %s\n",
1322 ip6_sprintf(&ifra->ifra_addr.sin6_addr));
1323 }
1324 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
91447636 1325 && lt->ia6t_pltime + timenow.tv_sec < timenow.tv_sec) {
9bccf70c
A
1326 return EINVAL;
1327 }
1328
1329 /*
1330 * If this is a new address, allocate a new ifaddr and link it
1331 * into chains.
1332 */
1333 if (ia == NULL) {
1334 hostIsNew = 1;
1335 /*
b0d623f7
A
1336 * in6_update_ifa() may be called in a process of a received
1337 * RA; in such a case, we should call malloc with M_NOWAIT.
1338 * The exception to this is during init time or as part of
1339 * handling an ioctl, when we know it's okay to do M_WAITOK.
9bccf70c 1340 */
b0d623f7 1341 ia = in6_ifaddr_alloc(how);
9bccf70c 1342 if (ia == NULL)
91447636 1343 return ENOBUFS;
9bccf70c
A
1344 /* Initialize the address and masks */
1345 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1346 ia->ia_addr.sin6_family = AF_INET6;
1347 ia->ia_addr.sin6_len = sizeof(ia->ia_addr);
1348 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
1349 /*
1350 * XXX: some functions expect that ifa_dstaddr is not
1351 * NULL for p2p interfaces.
1352 */
1353 ia->ia_ifa.ifa_dstaddr
1354 = (struct sockaddr *)&ia->ia_dstaddr;
1355 } else {
1356 ia->ia_ifa.ifa_dstaddr = NULL;
1357 }
1358 ia->ia_ifa.ifa_netmask
1359 = (struct sockaddr *)&ia->ia_prefixmask;
1360
1361 ia->ia_ifp = ifp;
b0d623f7 1362 ifaref(&ia->ia_ifa);
91447636
A
1363 lck_mtx_lock(nd6_mutex);
1364 if ((oia = in6_ifaddrs) != NULL) {
9bccf70c
A
1365 for ( ; oia->ia_next; oia = oia->ia_next)
1366 continue;
1367 oia->ia_next = ia;
1368 } else
91447636
A
1369 in6_ifaddrs = ia;
1370 lck_mtx_unlock(nd6_mutex);
9bccf70c 1371
91447636
A
1372 ifnet_lock_exclusive(ifp);
1373 if_attach_ifa(ifp, &ia->ia_ifa);
1374 ifnet_lock_done(ifp);
9bccf70c
A
1375 }
1376
1377 /* set prefix mask */
1378 if (ifra->ifra_prefixmask.sin6_len) {
1379 /*
1380 * We prohibit changing the prefix length of an existing
1381 * address, because
1382 * + such an operation should be rare in IPv6, and
1383 * + the operation would confuse prefix management.
1384 */
1385 if (ia->ia_prefixmask.sin6_len &&
1386 in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL) != plen) {
1387 log(LOG_INFO, "in6_update_ifa: the prefix length of an"
1388 " existing (%s) address should not be changed\n",
1389 ip6_sprintf(&ia->ia_addr.sin6_addr));
1390 error = EINVAL;
1391 goto unlink;
1392 }
1393 ia->ia_prefixmask = ifra->ifra_prefixmask;
1394 }
1395
1396 /*
1397 * If a new destination address is specified, scrub the old one and
1398 * install the new destination. Note that the interface must be
1399 * p2p or loopback (see the check above.)
1400 */
1401 if (dst6.sin6_family == AF_INET6 &&
1402 !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr,
1403 &ia->ia_dstaddr.sin6_addr)) {
1404 int e;
1405
1406 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
1407 (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1408 != 0) {
1409 log(LOG_ERR, "in6_update_ifa: failed to remove "
1410 "a route to the old destination: %s\n",
1411 ip6_sprintf(&ia->ia_addr.sin6_addr));
1412 /* proceed anyway... */
1413 }
1414 else
1415 ia->ia_flags &= ~IFA_ROUTE;
1416 ia->ia_dstaddr = dst6;
1417 }
1418
1419 /* reset the interface and routing table appropriately. */
1420 if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
1421 goto unlink;
1422
1423 /*
1424 * Beyond this point, we should call in6_purgeaddr upon an error,
1425 * not just go to unlink.
1426 */
1427
1428#if 0 /* disable this mechanism for now */
1429 /* update prefix list */
1430 if (hostIsNew &&
1431 (ifra->ifra_flags & IN6_IFF_NOPFX) == 0) { /* XXX */
1432 int iilen;
1433
1434 iilen = (sizeof(ia->ia_prefixmask.sin6_addr) << 3) - plen;
1435 if ((error = in6_prefix_add_ifid(iilen, ia)) != 0) {
91447636 1436 in6_purgeaddr((struct ifaddr *)ia, 0);
9bccf70c
A
1437 return(error);
1438 }
1439 }
1440#endif
1441
1442 if ((ifp->if_flags & IFF_MULTICAST) != 0) {
1443 struct sockaddr_in6 mltaddr, mltmask;
1444 struct in6_multi *in6m;
1445
1446 if (hostIsNew) {
1447 /*
1448 * join solicited multicast addr for new host id
1449 */
1450 struct in6_addr llsol;
1451 bzero(&llsol, sizeof(struct in6_addr));
1452 llsol.s6_addr16[0] = htons(0xff02);
1453 llsol.s6_addr16[1] = htons(ifp->if_index);
1454 llsol.s6_addr32[1] = 0;
1455 llsol.s6_addr32[2] = htonl(1);
1456 llsol.s6_addr32[3] =
1457 ifra->ifra_addr.sin6_addr.s6_addr32[3];
1458 llsol.s6_addr8[12] = 0xff;
91447636 1459 (void)in6_addmulti(&llsol, ifp, &error, 0);
9bccf70c
A
1460 if (error != 0) {
1461 log(LOG_WARNING,
1462 "in6_update_ifa: addmulti failed for "
1463 "%s on %s (errno=%d)\n",
1464 ip6_sprintf(&llsol), if_name(ifp),
1465 error);
91447636 1466 in6_purgeaddr((struct ifaddr *)ia, 0);
9bccf70c
A
1467 return(error);
1468 }
1469 }
1470
1471 bzero(&mltmask, sizeof(mltmask));
1472 mltmask.sin6_len = sizeof(struct sockaddr_in6);
1473 mltmask.sin6_family = AF_INET6;
1474 mltmask.sin6_addr = in6mask32;
1475
1476 /*
1477 * join link-local all-nodes address
1478 */
1479 bzero(&mltaddr, sizeof(mltaddr));
1480 mltaddr.sin6_len = sizeof(struct sockaddr_in6);
1481 mltaddr.sin6_family = AF_INET6;
1482 mltaddr.sin6_addr = in6addr_linklocal_allnodes;
1483 mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
1484
91447636 1485 ifnet_lock_shared(ifp);
9bccf70c 1486 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
91447636 1487 ifnet_lock_done(ifp);
9bccf70c
A
1488 if (in6m == NULL) {
1489 rtrequest(RTM_ADD,
1490 (struct sockaddr *)&mltaddr,
1491 (struct sockaddr *)&ia->ia_addr,
1492 (struct sockaddr *)&mltmask,
1493 RTF_UP|RTF_CLONING, /* xxx */
1494 (struct rtentry **)0);
91447636 1495 (void)in6_addmulti(&mltaddr.sin6_addr, ifp, &error, 0);
9bccf70c
A
1496 if (error != 0) {
1497 log(LOG_WARNING,
1498 "in6_update_ifa: addmulti failed for "
1499 "%s on %s (errno=%d)\n",
1500 ip6_sprintf(&mltaddr.sin6_addr),
1501 if_name(ifp), error);
1502 }
1503 }
1504
1505 /*
1506 * join node information group address
1507 */
1508#define hostnamelen strlen(hostname)
1509 if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr.sin6_addr)
1510 == 0) {
91447636 1511 ifnet_lock_shared(ifp);
9bccf70c 1512 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
91447636 1513 ifnet_lock_done(ifp);
9bccf70c
A
1514 if (in6m == NULL && ia != NULL) {
1515 (void)in6_addmulti(&mltaddr.sin6_addr,
91447636 1516 ifp, &error, 0);
9bccf70c
A
1517 if (error != 0) {
1518 log(LOG_WARNING, "in6_update_ifa: "
1519 "addmulti failed for "
1520 "%s on %s (errno=%d)\n",
1521 ip6_sprintf(&mltaddr.sin6_addr),
1522 if_name(ifp), error);
1523 }
1524 }
1525 }
1526#undef hostnamelen
1527
1528 /*
1529 * join node-local all-nodes address, on loopback.
1530 * XXX: since "node-local" is obsoleted by interface-local,
1531 * we have to join the group on every interface with
1532 * some interface-boundary restriction.
1533 */
1534 if (ifp->if_flags & IFF_LOOPBACK) {
1535 struct in6_ifaddr *ia_loop;
1536
1537 struct in6_addr loop6 = in6addr_loopback;
1538 ia_loop = in6ifa_ifpwithaddr(ifp, &loop6);
1539
1540 mltaddr.sin6_addr = in6addr_nodelocal_allnodes;
1541
91447636 1542 ifnet_lock_shared(ifp);
9bccf70c 1543 IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
91447636 1544 ifnet_lock_done(ifp);
9bccf70c
A
1545 if (in6m == NULL && ia_loop != NULL) {
1546 rtrequest(RTM_ADD,
1547 (struct sockaddr *)&mltaddr,
1548 (struct sockaddr *)&ia_loop->ia_addr,
1549 (struct sockaddr *)&mltmask,
1550 RTF_UP,
1551 (struct rtentry **)0);
1552 (void)in6_addmulti(&mltaddr.sin6_addr, ifp,
91447636 1553 &error, 0);
9bccf70c
A
1554 if (error != 0) {
1555 log(LOG_WARNING, "in6_update_ifa: "
1556 "addmulti failed for %s on %s "
1557 "(errno=%d)\n",
1558 ip6_sprintf(&mltaddr.sin6_addr),
1559 if_name(ifp), error);
1560 }
1561 }
b0d623f7
A
1562 if (ia_loop != NULL)
1563 ifafree(&ia_loop->ia_ifa);
9bccf70c
A
1564 }
1565 }
1566
1567 ia->ia6_flags = ifra->ifra_flags;
1568 ia->ia6_flags &= ~IN6_IFF_DUPLICATED; /*safety*/
1569 ia->ia6_flags &= ~IN6_IFF_NODAD; /* Mobile IPv6 */
1570
1571 ia->ia6_lifetime = ifra->ifra_lifetime;
1572 /* for sanity */
1573 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
1574 ia->ia6_lifetime.ia6t_expire =
91447636 1575 timenow.tv_sec + ia->ia6_lifetime.ia6t_vltime;
9bccf70c
A
1576 } else
1577 ia->ia6_lifetime.ia6t_expire = 0;
1578 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
1579 ia->ia6_lifetime.ia6t_preferred =
91447636 1580 timenow.tv_sec + ia->ia6_lifetime.ia6t_pltime;
9bccf70c
A
1581 } else
1582 ia->ia6_lifetime.ia6t_preferred = 0;
1583
1584 /*
1585 * make sure to initialize ND6 information. this is to workaround
1586 * issues with interfaces with IPv6 addresses, which have never brought
1587 * up. We are assuming that it is safe to nd6_ifattach multiple times.
1588 */
b0d623f7
A
1589 if ((error = nd6_ifattach(ifp)) != 0)
1590 return error;
9bccf70c
A
1591
1592 /*
1593 * Perform DAD, if needed.
1594 * XXX It may be of use, if we can administratively
1595 * disable DAD.
1596 */
1597 if (in6if_do_dad(ifp) && (ifra->ifra_flags & IN6_IFF_NODAD) == 0) {
1598 ia->ia6_flags |= IN6_IFF_TENTATIVE;
1599 nd6_dad_start((struct ifaddr *)ia, NULL);
1600 }
1601
1602 return(error);
1603
1604 unlink:
1605 /*
1606 * XXX: if a change of an existing address failed, keep the entry
1607 * anyway.
1608 */
1609 if (hostIsNew)
91447636 1610 in6_unlink_ifa(ia, ifp, 0);
9bccf70c
A
1611 return(error);
1612}
1613
1614void
91447636
A
1615in6_purgeaddr(
1616 struct ifaddr *ifa, int nd6_locked)
9bccf70c
A
1617{
1618 struct ifnet *ifp = ifa->ifa_ifp;
1619 struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
1620
1621 /* stop DAD processing */
55e303ae 1622 nd6_dad_stop(ifa);
9bccf70c
A
1623
1624 /*
1625 * delete route to the destination of the address being purged.
1626 * The interface must be p2p or loopback in this case.
1627 */
1628 if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
1629 int e;
1630
1631 if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
1632 != 0) {
1633 log(LOG_ERR, "in6_purgeaddr: failed to remove "
1634 "a route to the p2p destination: %s on %s, "
1635 "errno=%d\n",
1636 ip6_sprintf(&ia->ia_addr.sin6_addr), if_name(ifp),
1637 e);
1638 /* proceed anyway... */
1639 }
1640 else
1641 ia->ia_flags &= ~IFA_ROUTE;
1642 }
1643
1644 /* Remove ownaddr's loopback rtentry, if it exists. */
91447636 1645 in6_ifremloop(&(ia->ia_ifa), nd6_locked);
1c79356b
A
1646
1647 if (ifp->if_flags & IFF_MULTICAST) {
1648 /*
1649 * delete solicited multicast addr for deleting host id
1650 */
1651 struct in6_multi *in6m;
1652 struct in6_addr llsol;
1653 bzero(&llsol, sizeof(struct in6_addr));
1654 llsol.s6_addr16[0] = htons(0xff02);
1655 llsol.s6_addr16[1] = htons(ifp->if_index);
1656 llsol.s6_addr32[1] = 0;
1657 llsol.s6_addr32[2] = htonl(1);
1658 llsol.s6_addr32[3] =
1659 ia->ia_addr.sin6_addr.s6_addr32[3];
1660 llsol.s6_addr8[12] = 0xff;
1661
91447636 1662 ifnet_lock_shared(ifp);
1c79356b 1663 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
91447636 1664 ifnet_lock_done(ifp);
1c79356b 1665 if (in6m)
91447636 1666 in6_delmulti(in6m, nd6_locked);
1c79356b
A
1667 }
1668
91447636 1669 in6_unlink_ifa(ia, ifp, nd6_locked);
9bccf70c 1670 in6_post_msg(ifp, KEV_INET6_ADDR_DELETED, ia);
9bccf70c
A
1671}
1672
1673static void
91447636 1674in6_unlink_ifa(ia, ifp, nd6_locked)
9bccf70c
A
1675 struct in6_ifaddr *ia;
1676 struct ifnet *ifp;
91447636 1677 int nd6_locked;
9bccf70c
A
1678{
1679 int plen, iilen;
1680 struct in6_ifaddr *oia;
9bccf70c 1681
91447636
A
1682 ifnet_lock_exclusive(ifp);
1683 if_detach_ifa(ifp, &ia->ia_ifa);
1684 ifnet_lock_done(ifp);
1c79356b 1685
91447636
A
1686 if (!nd6_locked)
1687 lck_mtx_lock(nd6_mutex);
1c79356b 1688 oia = ia;
91447636
A
1689 if (oia == (ia = in6_ifaddrs))
1690 in6_ifaddrs = ia->ia_next;
1c79356b
A
1691 else {
1692 while (ia->ia_next && (ia->ia_next != oia))
1693 ia = ia->ia_next;
1694 if (ia->ia_next)
1695 ia->ia_next = oia->ia_next;
9bccf70c
A
1696 else {
1697 /* search failed */
1698 printf("Couldn't unlink in6_ifaddr from in6_ifaddr\n");
1699 }
1c79356b 1700 }
9bccf70c
A
1701 if (oia->ia6_ifpr) { /* check for safety */
1702 plen = in6_mask2len(&oia->ia_prefixmask.sin6_addr, NULL);
1703 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) - plen;
1c79356b
A
1704 in6_prefix_remove_ifid(iilen, oia);
1705 }
1c79356b 1706
9bccf70c
A
1707 /*
1708 * When an autoconfigured address is being removed, release the
1709 * reference to the base prefix. Also, since the release might
1710 * affect the status of other (detached) addresses, call
1711 * pfxlist_onlink_check().
1712 */
1713 if ((oia->ia6_flags & IN6_IFF_AUTOCONF) != 0) {
1714 if (oia->ia6_ndpr == NULL) {
1715 log(LOG_NOTICE, "in6_unlink_ifa: autoconf'ed address "
1716 "%p has no prefix\n", oia);
1717 } else {
1718 oia->ia6_ndpr->ndpr_refcnt--;
1719 oia->ia6_flags &= ~IN6_IFF_AUTOCONF;
1720 oia->ia6_ndpr = NULL;
1721 }
1722
91447636 1723 pfxlist_onlink_check(1);
9bccf70c 1724 }
91447636
A
1725 if (!nd6_locked)
1726 lck_mtx_unlock(nd6_mutex);
1727
9bccf70c
A
1728
1729 /*
91447636 1730 * release another refcnt for the link from in6_ifaddrs.
9bccf70c
A
1731 * Note that we should decrement the refcnt at least once for all *BSD.
1732 */
1733 ifafree(&oia->ia_ifa);
1734
9bccf70c
A
1735}
1736
1737void
1738in6_purgeif(ifp)
1739 struct ifnet *ifp;
1740{
91447636 1741 struct in6_ifaddr *ia, *nia = NULL;
9bccf70c
A
1742
1743 if (ifp == NULL || &ifp->if_addrlist == NULL)
1744 return;
1745
91447636
A
1746 lck_mtx_lock(nd6_mutex);
1747 for (ia = in6_ifaddrs; ia != NULL; ia = nia)
9bccf70c 1748 {
91447636
A
1749 nia = ia->ia_next;
1750 if (ia->ia_ifa.ifa_ifp != ifp)
9bccf70c 1751 continue;
91447636 1752 in6_purgeaddr(&ia->ia_ifa, 1);
9bccf70c 1753 }
91447636 1754 lck_mtx_unlock(nd6_mutex);
9bccf70c
A
1755
1756 in6_ifdetach(ifp);
1c79356b
A
1757}
1758
1759/*
1760 * SIOC[GAD]LIFADDR.
9bccf70c 1761 * SIOCGLIFADDR: get first address. (?)
1c79356b
A
1762 * SIOCGLIFADDR with IFLR_PREFIX:
1763 * get first address that matches the specified prefix.
1764 * SIOCALIFADDR: add the specified address.
1765 * SIOCALIFADDR with IFLR_PREFIX:
2d21ac55 1766 * add the specified prefix, filling hostaddr part from
1c79356b
A
1767 * the first link-local address. prefixlen must be <= 64.
1768 * SIOCDLIFADDR: delete the specified address.
1769 * SIOCDLIFADDR with IFLR_PREFIX:
1770 * delete the first address that matches the specified prefix.
1771 * return values:
1772 * EINVAL on invalid parameters
1773 * EADDRNOTAVAIL on prefix match failed/specified address not found
1774 * other values may be returned from in6_ioctl()
1775 *
1776 * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
1777 * this is to accomodate address naming scheme other than RFC2374,
1778 * in the future.
1779 * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
1780 * address encoding scheme. (see figure on page 8)
1781 */
1782static int
b0d623f7
A
1783in6_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data,
1784 struct ifnet *ifp, struct proc *p)
1c79356b
A
1785{
1786 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
b0d623f7 1787 struct ifaddr *ifa = NULL;
1c79356b 1788 struct sockaddr *sa;
b0d623f7 1789 int p64 = proc_is64bit(p);
1c79356b
A
1790
1791 /* sanity checks */
1792 if (!data || !ifp) {
1793 panic("invalid argument to in6_lifaddr_ioctl");
1794 /*NOTRECHED*/
1795 }
1796
1797 switch (cmd) {
1798 case SIOCGLIFADDR:
1799 /* address must be specified on GET with IFLR_PREFIX */
1800 if ((iflr->flags & IFLR_PREFIX) == 0)
1801 break;
55e303ae 1802 /* FALLTHROUGH */
1c79356b
A
1803 case SIOCALIFADDR:
1804 case SIOCDLIFADDR:
1805 /* address must be specified on ADD and DELETE */
1806 sa = (struct sockaddr *)&iflr->addr;
1807 if (sa->sa_family != AF_INET6)
1808 return EINVAL;
1809 if (sa->sa_len != sizeof(struct sockaddr_in6))
1810 return EINVAL;
1811 /* XXX need improvement */
1812 sa = (struct sockaddr *)&iflr->dstaddr;
1813 if (sa->sa_family && sa->sa_family != AF_INET6)
1814 return EINVAL;
1815 if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in6))
1816 return EINVAL;
1817 break;
55e303ae 1818 default: /* shouldn't happen */
1c79356b
A
1819#if 0
1820 panic("invalid cmd to in6_lifaddr_ioctl");
55e303ae 1821 /* NOTREACHED */
1c79356b
A
1822#else
1823 return EOPNOTSUPP;
1824#endif
1825 }
1826 if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
1827 return EINVAL;
1828
1829 switch (cmd) {
1830 case SIOCALIFADDR:
1831 {
1832 struct in6_aliasreq ifra;
2d21ac55 1833 struct in6_addr hostaddr;
1c79356b 1834 int prefixlen;
91447636 1835 int hostid_found = 0;
1c79356b
A
1836
1837 if ((iflr->flags & IFLR_PREFIX) != 0) {
1838 struct sockaddr_in6 *sin6;
1839
1840 /*
2d21ac55
A
1841 * hostaddr is to fill in the hostaddr part of the
1842 * address. hostaddr points to the first link-local
1c79356b
A
1843 * address attached to the interface.
1844 */
1845 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);
1846 if (!ifa)
1847 return EADDRNOTAVAIL;
2d21ac55 1848 hostaddr = *IFA_IN6(ifa);
91447636 1849 hostid_found = 1;
b0d623f7
A
1850 ifafree(ifa);
1851 ifa = NULL;
1c79356b
A
1852
1853 /* prefixlen must be <= 64. */
1854 if (64 < iflr->prefixlen)
1855 return EINVAL;
1856 prefixlen = iflr->prefixlen;
1857
2d21ac55 1858 /* hostaddr part must be zero. */
1c79356b
A
1859 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1860 if (sin6->sin6_addr.s6_addr32[2] != 0
1861 || sin6->sin6_addr.s6_addr32[3] != 0) {
1862 return EINVAL;
1863 }
1864 } else
1865 prefixlen = iflr->prefixlen;
1866
1867 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1868 bzero(&ifra, sizeof(ifra));
b0d623f7 1869 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof(ifra.ifra_name));
1c79356b
A
1870
1871 bcopy(&iflr->addr, &ifra.ifra_addr,
1872 ((struct sockaddr *)&iflr->addr)->sa_len);
91447636 1873 if (hostid_found) {
2d21ac55 1874 /* fill in hostaddr part */
1c79356b 1875 ifra.ifra_addr.sin6_addr.s6_addr32[2] =
2d21ac55 1876 hostaddr.s6_addr32[2];
1c79356b 1877 ifra.ifra_addr.sin6_addr.s6_addr32[3] =
2d21ac55 1878 hostaddr.s6_addr32[3];
1c79356b
A
1879 }
1880
1881 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
1882 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1883 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
91447636 1884 if (hostid_found) {
1c79356b 1885 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
2d21ac55 1886 hostaddr.s6_addr32[2];
1c79356b 1887 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
2d21ac55 1888 hostaddr.s6_addr32[3];
1c79356b
A
1889 }
1890 }
1891
1c79356b
A
1892 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1893 in6_len2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
1894
1895 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
b0d623f7
A
1896 if (!p64) {
1897#if defined(__LP64__)
1898 struct in6_aliasreq_32 ifra_32;
1899 /*
1900 * Use 32-bit ioctl and structure for 32-bit process.
1901 */
1902 in6_aliasreq_64_to_32((struct in6_aliasreq_64 *)&ifra,
1903 &ifra_32);
1904 return (in6_control(so, SIOCAIFADDR_IN6_32,
1905 (caddr_t)&ifra_32, ifp, p));
1906#else
1907 return (in6_control(so, SIOCAIFADDR_IN6,
1908 (caddr_t)&ifra, ifp, p));
1909#endif /* __LP64__ */
1910 } else {
1911#if defined(__LP64__)
1912 return (in6_control(so, SIOCAIFADDR_IN6,
1913 (caddr_t)&ifra, ifp, p));
1914#else
1915 struct in6_aliasreq_64 ifra_64;
1916 /*
1917 * Use 64-bit ioctl and structure for 64-bit process.
1918 */
1919 in6_aliasreq_32_to_64((struct in6_aliasreq_32 *)&ifra,
1920 &ifra_64);
1921 return (in6_control(so, SIOCAIFADDR_IN6_64,
1922 (caddr_t)&ifra_64, ifp, p));
1923#endif /* __LP64__ */
1924 }
1925 /* NOTREACHED */
1c79356b
A
1926 }
1927 case SIOCGLIFADDR:
1928 case SIOCDLIFADDR:
1929 {
1930 struct in6_ifaddr *ia;
1931 struct in6_addr mask, candidate, match;
1932 struct sockaddr_in6 *sin6;
1933 int cmp;
1934
1935 bzero(&mask, sizeof(mask));
1936 if (iflr->flags & IFLR_PREFIX) {
1937 /* lookup a prefix rather than address. */
1938 in6_len2mask(&mask, iflr->prefixlen);
1939
1940 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1941 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1942 match.s6_addr32[0] &= mask.s6_addr32[0];
1943 match.s6_addr32[1] &= mask.s6_addr32[1];
1944 match.s6_addr32[2] &= mask.s6_addr32[2];
1945 match.s6_addr32[3] &= mask.s6_addr32[3];
1946
1947 /* if you set extra bits, that's wrong */
1948 if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
1949 return EINVAL;
1950
1951 cmp = 1;
1952 } else {
1953 if (cmd == SIOCGLIFADDR) {
1954 /* on getting an address, take the 1st match */
55e303ae 1955 cmp = 0; /* XXX */
1c79356b
A
1956 } else {
1957 /* on deleting an address, do exact match */
1958 in6_len2mask(&mask, 128);
1959 sin6 = (struct sockaddr_in6 *)&iflr->addr;
1960 bcopy(&sin6->sin6_addr, &match, sizeof(match));
1961
1962 cmp = 1;
1963 }
1964 }
1965
91447636 1966 ifnet_lock_shared(ifp);
9bccf70c 1967 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
1968 {
1969 if (ifa->ifa_addr->sa_family != AF_INET6)
1970 continue;
1971 if (!cmp)
1972 break;
9bccf70c 1973
1c79356b 1974 bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
9bccf70c
A
1975#ifndef SCOPEDROUTING
1976 /*
1977 * XXX: this is adhoc, but is necessary to allow
1978 * a user to specify fe80::/64 (not /10) for a
1979 * link-local address.
1980 */
1981 if (IN6_IS_ADDR_LINKLOCAL(&candidate))
1982 candidate.s6_addr16[1] = 0;
1983#endif
1c79356b
A
1984 candidate.s6_addr32[0] &= mask.s6_addr32[0];
1985 candidate.s6_addr32[1] &= mask.s6_addr32[1];
1986 candidate.s6_addr32[2] &= mask.s6_addr32[2];
1987 candidate.s6_addr32[3] &= mask.s6_addr32[3];
1988 if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
1989 break;
1990 }
91447636 1991 ifnet_lock_done(ifp);
1c79356b
A
1992 if (!ifa)
1993 return EADDRNOTAVAIL;
1994 ia = ifa2ia6(ifa);
1995
1996 if (cmd == SIOCGLIFADDR) {
9bccf70c
A
1997#ifndef SCOPEDROUTING
1998 struct sockaddr_in6 *s6;
1999#endif
2000
1c79356b
A
2001 /* fill in the if_laddrreq structure */
2002 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
9bccf70c
A
2003#ifndef SCOPEDROUTING /* XXX see above */
2004 s6 = (struct sockaddr_in6 *)&iflr->addr;
2005 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
2006 s6->sin6_addr.s6_addr16[1] = 0;
2007 s6->sin6_scope_id =
2008 in6_addr2scopeid(ifp, &s6->sin6_addr);
2009 }
2010#endif
1c79356b
A
2011 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
2012 bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
2013 ia->ia_dstaddr.sin6_len);
9bccf70c
A
2014#ifndef SCOPEDROUTING /* XXX see above */
2015 s6 = (struct sockaddr_in6 *)&iflr->dstaddr;
2016 if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) {
2017 s6->sin6_addr.s6_addr16[1] = 0;
2018 s6->sin6_scope_id =
2019 in6_addr2scopeid(ifp,
2020 &s6->sin6_addr);
2021 }
2022#endif
1c79356b
A
2023 } else
2024 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
2025
2026 iflr->prefixlen =
9bccf70c
A
2027 in6_mask2len(&ia->ia_prefixmask.sin6_addr,
2028 NULL);
1c79356b 2029
55e303ae 2030 iflr->flags = ia->ia6_flags; /* XXX */
1c79356b
A
2031
2032 return 0;
2033 } else {
2034 struct in6_aliasreq ifra;
2035
2036 /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
2037 bzero(&ifra, sizeof(ifra));
2038 bcopy(iflr->iflr_name, ifra.ifra_name,
2039 sizeof(ifra.ifra_name));
2040
2041 bcopy(&ia->ia_addr, &ifra.ifra_addr,
2042 ia->ia_addr.sin6_len);
2043 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
2044 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
2045 ia->ia_dstaddr.sin6_len);
2046 } else {
2047 bzero(&ifra.ifra_dstaddr,
2048 sizeof(ifra.ifra_dstaddr));
2049 }
2050 bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
2051 ia->ia_prefixmask.sin6_len);
2052
2053 ifra.ifra_flags = ia->ia6_flags;
b0d623f7
A
2054 if (!p64) {
2055#if defined(__LP64__)
2056 struct in6_aliasreq_32 ifra_32;
2057 /*
2058 * Use 32-bit structure for 32-bit process.
2059 * SIOCDIFADDR_IN6 is encoded with in6_ifreq,
2060 * so it stays the same since the size does
2061 * not change. The data part of the ioctl,
2062 * however, is of a different structure, i.e.
2063 * in6_aliasreq.
2064 */
2065 in6_aliasreq_64_to_32(
2066 (struct in6_aliasreq_64 *)&ifra, &ifra_32);
2067 return (in6_control(so, SIOCDIFADDR_IN6,
2068 (caddr_t)&ifra_32, ifp, p));
2069#else
2070 return (in6_control(so, SIOCDIFADDR_IN6,
2071 (caddr_t)&ifra, ifp, p));
2072#endif /* __LP64__ */
2073 } else {
2074#if defined(__LP64__)
2075 return (in6_control(so, SIOCDIFADDR_IN6,
2076 (caddr_t)&ifra, ifp, p));
2077#else
2078 struct in6_aliasreq_64 ifra_64;
2079 /*
2080 * Use 64-bit structure for 64-bit process.
2081 * SIOCDIFADDR_IN6 is encoded with in6_ifreq,
2082 * so it stays the same since the size does
2083 * not change. The data part of the ioctl,
2084 * however, is of a different structure, i.e.
2085 * in6_aliasreq.
2086 */
2087 in6_aliasreq_32_to_64(
2088 (struct in6_aliasreq_32 *)&ifra, &ifra_64);
2089 return (in6_control(so, SIOCDIFADDR_IN6,
2090 (caddr_t)&ifra_64, ifp, p));
2091#endif /* __LP64__ */
2092 }
2093 /* NOTREACHED */
1c79356b 2094 }
9bccf70c 2095 }
1c79356b 2096 }
9bccf70c 2097
55e303ae 2098 return EOPNOTSUPP; /* just for safety */
1c79356b
A
2099}
2100
2101/*
9bccf70c
A
2102 * Initialize an interface's intetnet6 address
2103 * and routing table entry.
1c79356b 2104 */
9bccf70c
A
2105static int
2106in6_ifinit(ifp, ia, sin6, newhost)
1c79356b 2107 struct ifnet *ifp;
9bccf70c
A
2108 struct in6_ifaddr *ia;
2109 struct sockaddr_in6 *sin6;
2110 int newhost;
1c79356b 2111{
9bccf70c 2112 int error = 0, plen, ifacount = 0;
9bccf70c 2113 struct ifaddr *ifa;
1c79356b 2114
9bccf70c
A
2115 /*
2116 * Give the interface a chance to initialize
2117 * if this is its first address,
2118 * and to validate the address if necessary.
2119 */
91447636 2120 ifnet_lock_shared(ifp);
9bccf70c
A
2121 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
2122 {
2123 if (ifa->ifa_addr == NULL)
2124 continue; /* just for safety */
2125 if (ifa->ifa_addr->sa_family != AF_INET6)
1c79356b 2126 continue;
9bccf70c 2127 ifacount++;
1c79356b 2128 }
91447636 2129 ifnet_lock_done(ifp);
1c79356b 2130
9bccf70c 2131 ia->ia_addr = *sin6;
1c79356b 2132
1c79356b 2133
9bccf70c 2134 if (ifacount <= 1 &&
2d21ac55 2135 (error = ifnet_ioctl(ifp, PF_INET6, SIOCSIFADDR, ia))) {
9bccf70c 2136 if (error) {
9bccf70c 2137 return(error);
1c79356b 2138 }
1c79356b 2139 }
1c79356b 2140
9bccf70c 2141 ia->ia_ifa.ifa_metric = ifp->if_metric;
1c79356b 2142
9bccf70c 2143 /* we could do in(6)_socktrim here, but just omit it at this moment. */
1c79356b 2144
9bccf70c
A
2145 /*
2146 * Special case:
2147 * If the destination address is specified for a point-to-point
2148 * interface, install a route to the destination as an interface
2149 * direct route.
2150 */
2151 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
2152 if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
2153 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
2154 RTF_UP | RTF_HOST)) != 0)
2155 return(error);
2156 ia->ia_flags |= IFA_ROUTE;
2157 }
2158 if (plen < 128) {
1c79356b 2159 /*
9bccf70c 2160 * The RTF_CLONING flag is necessary for in6_is_ifloop_auto().
1c79356b 2161 */
9bccf70c 2162 ia->ia_ifa.ifa_flags |= RTF_CLONING;
1c79356b 2163 }
9bccf70c 2164
55e303ae 2165 /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
9bccf70c
A
2166 if (newhost) {
2167 /* set the rtrequest function to create llinfo */
2168 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
2169 in6_ifaddloop(&(ia->ia_ifa));
2170 }
2171
2172 return(error);
1c79356b 2173}
9bccf70c 2174
1c79356b
A
2175/*
2176 * Add an address to the list of IP6 multicast addresses for a
2177 * given interface.
2178 */
2179struct in6_multi *
91447636 2180in6_addmulti(maddr6, ifp, errorp, nd6_locked)
9bccf70c
A
2181 struct in6_addr *maddr6;
2182 struct ifnet *ifp;
1c79356b 2183 int *errorp;
91447636 2184 int nd6_locked;
1c79356b
A
2185{
2186 struct in6_multi *in6m;
2187 struct sockaddr_in6 sin6;
2188 struct ifmultiaddr *ifma;
1c79356b
A
2189
2190 *errorp = 0;
2191
2192 /*
2193 * Call generic routine to add membership or increment
2194 * refcount. It wants addresses in the form of a sockaddr,
2195 * so we build one here (being careful to zero the unused bytes).
2196 */
2197 bzero(&sin6, sizeof sin6);
2198 sin6.sin6_family = AF_INET6;
2199 sin6.sin6_len = sizeof sin6;
2200 sin6.sin6_addr = *maddr6;
2201 *errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma);
2202 if (*errorp) {
1c79356b
A
2203 return 0;
2204 }
2205
2206 /*
2207 * If ifma->ifma_protospec is null, then if_addmulti() created
2208 * a new record. Otherwise, we are done.
2209 */
2210 if (ifma->ifma_protospec != 0)
2211 return ifma->ifma_protospec;
2212
2213 /* XXX - if_addmulti uses M_WAITOK. Can this really be called
2214 at interrupt time? If so, need to fix if_addmulti. XXX */
2215 in6m = (struct in6_multi *)_MALLOC(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
2216 if (in6m == NULL) {
1c79356b
A
2217 return (NULL);
2218 }
2219
2220 bzero(in6m, sizeof *in6m);
2221 in6m->in6m_addr = *maddr6;
2222 in6m->in6m_ifp = ifp;
2223 in6m->in6m_ifma = ifma;
2224 ifma->ifma_protospec = in6m;
91447636
A
2225 if (nd6_locked == 0)
2226 lck_mtx_lock(nd6_mutex);
1c79356b 2227 LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry);
91447636
A
2228 if (nd6_locked == 0)
2229 lck_mtx_unlock(nd6_mutex);
1c79356b
A
2230
2231 /*
2232 * Let MLD6 know that we have joined a new IP6 multicast
2233 * group.
2234 */
2235 mld6_start_listening(in6m);
1c79356b
A
2236 return(in6m);
2237}
2238
2239/*
2240 * Delete a multicast address record.
2241 */
2242void
91447636
A
2243in6_delmulti(
2244 struct in6_multi *in6m, int nd6locked)
1c79356b
A
2245{
2246 struct ifmultiaddr *ifma = in6m->in6m_ifma;
1c79356b 2247
91447636 2248 if (ifma && ifma->ifma_usecount == 1) {
1c79356b
A
2249 /*
2250 * No remaining claims to this record; let MLD6 know
2251 * that we are leaving the multicast group.
2252 */
2253 mld6_stop_listening(in6m);
2254 ifma->ifma_protospec = 0;
91447636
A
2255 if (nd6locked == 0)
2256 lck_mtx_lock(nd6_mutex);
1c79356b 2257 LIST_REMOVE(in6m, in6m_entry);
91447636
A
2258 if (nd6locked == 0)
2259 lck_mtx_unlock(nd6_mutex);
9bccf70c 2260 FREE(in6m, M_IPMADDR);
1c79356b
A
2261 }
2262 /* XXX - should be separate API for when we have an ifma? */
91447636
A
2263 if (ifma) {
2264 if_delmultiaddr(ifma, 0);
2265 ifma_release(ifma);
2266 }
1c79356b 2267}
1c79356b
A
2268
2269/*
2270 * Find an IPv6 interface link-local address specific to an interface.
2271 */
2272struct in6_ifaddr *
2273in6ifa_ifpforlinklocal(ifp, ignoreflags)
2274 struct ifnet *ifp;
2275 int ignoreflags;
2276{
9bccf70c 2277 struct ifaddr *ifa;
1c79356b 2278
91447636 2279 ifnet_lock_shared(ifp);
9bccf70c 2280 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
2281 {
2282 if (ifa->ifa_addr == NULL)
2283 continue; /* just for safety */
2284 if (ifa->ifa_addr->sa_family != AF_INET6)
2285 continue;
2286 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
2287 if ((((struct in6_ifaddr *)ifa)->ia6_flags &
2288 ignoreflags) != 0)
2289 continue;
2290 break;
2291 }
2292 }
b0d623f7
A
2293 if (ifa != NULL)
2294 ifaref(ifa);
91447636 2295 ifnet_lock_done(ifp);
1c79356b
A
2296
2297 return((struct in6_ifaddr *)ifa);
2298}
2299
1c79356b
A
2300/*
2301 * find the internet address corresponding to a given interface and address.
2302 */
2303struct in6_ifaddr *
2304in6ifa_ifpwithaddr(ifp, addr)
2305 struct ifnet *ifp;
2306 struct in6_addr *addr;
2307{
9bccf70c 2308 struct ifaddr *ifa;
1c79356b 2309
91447636 2310 ifnet_lock_shared(ifp);
9bccf70c 2311 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
2312 {
2313 if (ifa->ifa_addr == NULL)
2314 continue; /* just for safety */
2315 if (ifa->ifa_addr->sa_family != AF_INET6)
2316 continue;
2317 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
2318 break;
2319 }
b0d623f7
A
2320 if (ifa != NULL)
2321 ifaref(ifa);
91447636 2322 ifnet_lock_done(ifp);
1c79356b
A
2323
2324 return((struct in6_ifaddr *)ifa);
2325}
2326
2327/*
2328 * Convert IP6 address to printable (loggable) representation.
2329 */
2330static char digits[] = "0123456789abcdef";
2331static int ip6round = 0;
2332char *
2333ip6_sprintf(addr)
9bccf70c 2334 const struct in6_addr *addr;
1c79356b
A
2335{
2336 static char ip6buf[8][48];
9bccf70c
A
2337 int i;
2338 char *cp;
55e303ae
A
2339 const u_short *a = (const u_short *)addr;
2340 const u_char *d;
1c79356b
A
2341 int dcolon = 0;
2342
2343 ip6round = (ip6round + 1) & 7;
2344 cp = ip6buf[ip6round];
2345
2346 for (i = 0; i < 8; i++) {
2347 if (dcolon == 1) {
2348 if (*a == 0) {
2349 if (i == 7)
2350 *cp++ = ':';
2351 a++;
2352 continue;
2353 } else
2354 dcolon = 2;
2355 }
2356 if (*a == 0) {
2357 if (dcolon == 0 && *(a + 1) == 0) {
2358 if (i == 0)
2359 *cp++ = ':';
2360 *cp++ = ':';
2361 dcolon = 1;
2362 } else {
2363 *cp++ = '0';
2364 *cp++ = ':';
2365 }
2366 a++;
2367 continue;
2368 }
55e303ae 2369 d = (const u_char *)a;
1c79356b
A
2370 *cp++ = digits[*d >> 4];
2371 *cp++ = digits[*d++ & 0xf];
2372 *cp++ = digits[*d >> 4];
2373 *cp++ = digits[*d & 0xf];
2374 *cp++ = ':';
2375 a++;
2376 }
2377 *--cp = 0;
2378 return(ip6buf[ip6round]);
2379}
2380
2d21ac55
A
2381int
2382in6addr_local(struct in6_addr *in6)
2383{
2384 struct rtentry *rt;
2385 struct sockaddr_in6 sin6;
2386 int local = 0;
2387
2388 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
2389 return (1);
2390
2391 sin6.sin6_family = AF_INET6;
2392 sin6.sin6_len = sizeof (sin6);
2393 bcopy(in6, &sin6.sin6_addr, sizeof (*in6));
b0d623f7 2394 rt = rtalloc1((struct sockaddr *)&sin6, 0, 0);
2d21ac55
A
2395
2396 if (rt != NULL) {
b0d623f7 2397 RT_LOCK_SPIN(rt);
2d21ac55
A
2398 if (rt->rt_gateway->sa_family == AF_LINK)
2399 local = 1;
b0d623f7 2400 RT_UNLOCK(rt);
2d21ac55
A
2401 rtfree(rt);
2402 } else {
2403 local = in6_localaddr(in6);
2404 }
2405 return (local);
2406}
2407
1c79356b
A
2408int
2409in6_localaddr(in6)
2410 struct in6_addr *in6;
2411{
2412 struct in6_ifaddr *ia;
2413
2414 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
2415 return 1;
2416
91447636
A
2417 lck_mtx_lock(nd6_mutex);
2418 for (ia = in6_ifaddrs; ia; ia = ia->ia_next)
1c79356b 2419 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
91447636
A
2420 &ia->ia_prefixmask.sin6_addr)) {
2421 lck_mtx_unlock(nd6_mutex);
1c79356b 2422 return 1;
91447636 2423 }
1c79356b 2424
91447636 2425 lck_mtx_unlock(nd6_mutex);
1c79356b
A
2426 return (0);
2427}
2428
1c79356b 2429int
9bccf70c
A
2430in6_is_addr_deprecated(sa6)
2431 struct sockaddr_in6 *sa6;
1c79356b 2432{
9bccf70c 2433 struct in6_ifaddr *ia;
1c79356b 2434
91447636
A
2435 lck_mtx_lock(nd6_mutex);
2436 for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
9bccf70c
A
2437 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr,
2438 &sa6->sin6_addr) &&
2439#if SCOPEDROUTING
2440 ia->ia_addr.sin6_scope_id == sa6->sin6_scope_id &&
2441#endif
91447636
A
2442 (ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) {
2443 lck_mtx_unlock(nd6_mutex);
9bccf70c 2444 return(1); /* true */
91447636 2445 }
1c79356b 2446
9bccf70c 2447 /* XXX: do we still have to go thru the rest of the list? */
1c79356b
A
2448 }
2449
91447636 2450 lck_mtx_unlock(nd6_mutex);
9bccf70c 2451 return(0); /* false */
1c79356b
A
2452}
2453
2454/*
2455 * return length of part which dst and src are equal
2456 * hard coding...
2457 */
1c79356b
A
2458int
2459in6_matchlen(src, dst)
2460struct in6_addr *src, *dst;
2461{
2462 int match = 0;
2463 u_char *s = (u_char *)src, *d = (u_char *)dst;
2464 u_char *lim = s + 16, r;
2465
2466 while (s < lim)
2467 if ((r = (*d++ ^ *s++)) != 0) {
2468 while (r < 128) {
2469 match++;
2470 r <<= 1;
2471 }
2472 break;
2473 } else
2474 match += 8;
2475 return match;
2476}
2477
9bccf70c 2478/* XXX: to be scope conscious */
1c79356b
A
2479int
2480in6_are_prefix_equal(p1, p2, len)
2481 struct in6_addr *p1, *p2;
2482 int len;
2483{
2484 int bytelen, bitlen;
2485
2486 /* sanity check */
2487 if (0 > len || len > 128) {
2488 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
2489 len);
2490 return(0);
2491 }
2492
2493 bytelen = len / 8;
2494 bitlen = len % 8;
2495
2496 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
2497 return(0);
91447636
A
2498 if (bitlen != 0 &&
2499 p1->s6_addr[bytelen] >> (8 - bitlen) !=
1c79356b
A
2500 p2->s6_addr[bytelen] >> (8 - bitlen))
2501 return(0);
2502
2503 return(1);
2504}
2505
2506void
2507in6_prefixlen2mask(maskp, len)
2508 struct in6_addr *maskp;
2509 int len;
2510{
2511 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
2512 int bytelen, bitlen, i;
2513
2514 /* sanity check */
2515 if (0 > len || len > 128) {
2516 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
2517 len);
2518 return;
2519 }
2520
2521 bzero(maskp, sizeof(*maskp));
2522 bytelen = len / 8;
2523 bitlen = len % 8;
2524 for (i = 0; i < bytelen; i++)
2525 maskp->s6_addr[i] = 0xff;
2526 if (bitlen)
2527 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
2528}
2529
2530/*
2531 * return the best address out of the same scope
2532 */
2533struct in6_ifaddr *
91447636
A
2534in6_ifawithscope(
2535 struct ifnet *oifp,
2536 struct in6_addr *dst)
1c79356b
A
2537{
2538 int dst_scope = in6_addrscope(dst), src_scope, best_scope = 0;
2539 int blen = -1;
2540 struct ifaddr *ifa;
2541 struct ifnet *ifp;
2542 struct in6_ifaddr *ifa_best = NULL;
2543
2544 if (oifp == NULL) {
9bccf70c 2545#if 0
1c79356b 2546 printf("in6_ifawithscope: output interface is not specified\n");
9bccf70c 2547#endif
1c79356b
A
2548 return(NULL);
2549 }
2550
2551 /*
2552 * We search for all addresses on all interfaces from the beginning.
2553 * Comparing an interface with the outgoing interface will be done
2554 * only at the final stage of tiebreaking.
2555 */
91447636
A
2556 ifnet_head_lock_shared();
2557 TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
1c79356b
A
2558 /*
2559 * We can never take an address that breaks the scope zone
2560 * of the destination.
2561 */
2562 if (in6_addr2scopeid(ifp, dst) != in6_addr2scopeid(oifp, dst))
2563 continue;
2564
91447636 2565 ifnet_lock_shared(ifp);
1c79356b 2566 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
2567 {
2568 int tlen = -1, dscopecmp, bscopecmp, matchcmp;
2569
2570 if (ifa->ifa_addr->sa_family != AF_INET6)
2571 continue;
2572
2573 src_scope = in6_addrscope(IFA_IN6(ifa));
2574
1c79356b
A
2575 /*
2576 * Don't use an address before completing DAD
2577 * nor a duplicated address.
2578 */
2579 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2580 IN6_IFF_NOTREADY)
2581 continue;
2582
2583 /* XXX: is there any case to allow anycasts? */
2584 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2585 IN6_IFF_ANYCAST)
2586 continue;
2587
2588 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2589 IN6_IFF_DETACHED)
2590 continue;
2591
2592 /*
2593 * If this is the first address we find,
2594 * keep it anyway.
2595 */
2596 if (ifa_best == NULL)
2597 goto replace;
2598
2599 /*
2600 * ifa_best is never NULL beyond this line except
2601 * within the block labeled "replace".
2602 */
2603
2604 /*
2605 * If ifa_best has a smaller scope than dst and
2606 * the current address has a larger one than
2607 * (or equal to) dst, always replace ifa_best.
2608 * Also, if the current address has a smaller scope
2609 * than dst, ignore it unless ifa_best also has a
2610 * smaller scope.
9bccf70c
A
2611 * Consequently, after the two if-clause below,
2612 * the followings must be satisfied:
2613 * (scope(src) < scope(dst) &&
2614 * scope(best) < scope(dst))
2615 * OR
2616 * (scope(best) >= scope(dst) &&
2617 * scope(src) >= scope(dst))
1c79356b
A
2618 */
2619 if (IN6_ARE_SCOPE_CMP(best_scope, dst_scope) < 0 &&
2620 IN6_ARE_SCOPE_CMP(src_scope, dst_scope) >= 0)
9bccf70c 2621 goto replace; /* (A) */
1c79356b
A
2622 if (IN6_ARE_SCOPE_CMP(src_scope, dst_scope) < 0 &&
2623 IN6_ARE_SCOPE_CMP(best_scope, dst_scope) >= 0)
9bccf70c 2624 continue; /* (B) */
1c79356b
A
2625
2626 /*
2627 * A deprecated address SHOULD NOT be used in new
2628 * communications if an alternate (non-deprecated)
2629 * address is available and has sufficient scope.
2630 * RFC 2462, Section 5.5.4.
2631 */
2632 if (((struct in6_ifaddr *)ifa)->ia6_flags &
2633 IN6_IFF_DEPRECATED) {
2634 /*
2635 * Ignore any deprecated addresses if
2636 * specified by configuration.
2637 */
2638 if (!ip6_use_deprecated)
2639 continue;
2640
2641 /*
2642 * If we have already found a non-deprecated
2643 * candidate, just ignore deprecated addresses.
2644 */
2645 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED)
2646 == 0)
2647 continue;
2648 }
2649
2650 /*
2651 * A non-deprecated address is always preferred
2652 * to a deprecated one regardless of scopes and
9bccf70c
A
2653 * address matching (Note invariants ensured by the
2654 * conditions (A) and (B) above.)
1c79356b
A
2655 */
2656 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) &&
2657 (((struct in6_ifaddr *)ifa)->ia6_flags &
2658 IN6_IFF_DEPRECATED) == 0)
2659 goto replace;
2660
9bccf70c
A
2661 /*
2662 * When we use temporary addresses described in
2663 * RFC 3041, we prefer temporary addresses to
2664 * public autoconf addresses. Again, note the
2665 * invariants from (A) and (B). Also note that we
2666 * don't have any preference between static addresses
2667 * and autoconf addresses (despite of whether or not
2668 * the latter is temporary or public.)
2669 */
2670 if (ip6_use_tempaddr) {
2671 struct in6_ifaddr *ifat;
2672
2673 ifat = (struct in6_ifaddr *)ifa;
2674 if ((ifa_best->ia6_flags &
2675 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2676 == IN6_IFF_AUTOCONF &&
2677 (ifat->ia6_flags &
2678 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2679 == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY)) {
2680 goto replace;
2681 }
2682 if ((ifa_best->ia6_flags &
2683 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2684 == (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY) &&
2685 (ifat->ia6_flags &
2686 (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY))
2687 == IN6_IFF_AUTOCONF) {
2688 continue;
2689 }
2690 }
2691
1c79356b
A
2692 /*
2693 * At this point, we have two cases:
2694 * 1. we are looking at a non-deprecated address,
2695 * and ifa_best is also non-deprecated.
2696 * 2. we are looking at a deprecated address,
2697 * and ifa_best is also deprecated.
2698 * Also, we do not have to consider a case where
2699 * the scope of if_best is larger(smaller) than dst and
2700 * the scope of the current address is smaller(larger)
2701 * than dst. Such a case has already been covered.
2702 * Tiebreaking is done according to the following
2703 * items:
2704 * - the scope comparison between the address and
2705 * dst (dscopecmp)
2706 * - the scope comparison between the address and
2707 * ifa_best (bscopecmp)
2708 * - if the address match dst longer than ifa_best
2709 * (matchcmp)
2710 * - if the address is on the outgoing I/F (outI/F)
2711 *
2712 * Roughly speaking, the selection policy is
2713 * - the most important item is scope. The same scope
2714 * is best. Then search for a larger scope.
2715 * Smaller scopes are the last resort.
2716 * - A deprecated address is chosen only when we have
2717 * no address that has an enough scope, but is
9bccf70c
A
2718 * prefered to any addresses of smaller scopes
2719 * (this must be already done above.)
2720 * - addresses on the outgoing I/F are preferred to
2721 * ones on other interfaces if none of above
2722 * tiebreaks. In the table below, the column "bI"
2723 * means if the best_ifa is on the outgoing
2724 * interface, and the column "sI" means if the ifa
2725 * is on the outgoing interface.
1c79356b 2726 * - If there is no other reasons to choose one,
9bccf70c 2727 * longest address match against dst is considered.
1c79356b
A
2728 *
2729 * The precise decision table is as follows:
9bccf70c
A
2730 * dscopecmp bscopecmp match bI oI | replace?
2731 * N/A equal N/A Y N | No (1)
2732 * N/A equal N/A N Y | Yes (2)
2733 * N/A equal larger N/A | Yes (3)
2734 * N/A equal !larger N/A | No (4)
2735 * larger larger N/A N/A | No (5)
2736 * larger smaller N/A N/A | Yes (6)
2737 * smaller larger N/A N/A | Yes (7)
2738 * smaller smaller N/A N/A | No (8)
2739 * equal smaller N/A N/A | Yes (9)
2740 * equal larger (already done at A above)
1c79356b
A
2741 */
2742 dscopecmp = IN6_ARE_SCOPE_CMP(src_scope, dst_scope);
2743 bscopecmp = IN6_ARE_SCOPE_CMP(src_scope, best_scope);
2744
9bccf70c
A
2745 if (bscopecmp == 0) {
2746 struct ifnet *bifp = ifa_best->ia_ifp;
2747
2748 if (bifp == oifp && ifp != oifp) /* (1) */
2749 continue;
2750 if (bifp != oifp && ifp == oifp) /* (2) */
2751 goto replace;
2752
2753 /*
2754 * Both bifp and ifp are on the outgoing
2755 * interface, or both two are on a different
2756 * interface from the outgoing I/F.
2757 * now we need address matching against dst
2758 * for tiebreaking.
2759 */
2760 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2761 matchcmp = tlen - blen;
2762 if (matchcmp > 0) /* (3) */
1c79356b 2763 goto replace;
9bccf70c 2764 continue; /* (4) */
1c79356b
A
2765 }
2766 if (dscopecmp > 0) {
9bccf70c 2767 if (bscopecmp > 0) /* (5) */
1c79356b 2768 continue;
9bccf70c 2769 goto replace; /* (6) */
1c79356b
A
2770 }
2771 if (dscopecmp < 0) {
9bccf70c 2772 if (bscopecmp > 0) /* (7) */
1c79356b 2773 goto replace;
9bccf70c 2774 continue; /* (8) */
1c79356b
A
2775 }
2776
2777 /* now dscopecmp must be 0 */
2778 if (bscopecmp < 0)
9bccf70c 2779 goto replace; /* (9) */
1c79356b
A
2780
2781 replace:
91447636
A
2782 ifaref(ifa);
2783 if (ifa_best)
2784 ifafree(&ifa_best->ia_ifa);
1c79356b
A
2785 ifa_best = (struct in6_ifaddr *)ifa;
2786 blen = tlen >= 0 ? tlen :
2787 in6_matchlen(IFA_IN6(ifa), dst);
2788 best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr);
2789 }
91447636 2790 ifnet_lock_done(ifp);
1c79356b 2791 }
91447636 2792 ifnet_head_done();
1c79356b
A
2793
2794 /* count statistics for future improvements */
2795 if (ifa_best == NULL)
2796 ip6stat.ip6s_sources_none++;
2797 else {
2798 if (oifp == ifa_best->ia_ifp)
2799 ip6stat.ip6s_sources_sameif[best_scope]++;
2800 else
2801 ip6stat.ip6s_sources_otherif[best_scope]++;
2802
2803 if (best_scope == dst_scope)
2804 ip6stat.ip6s_sources_samescope[best_scope]++;
2805 else
2806 ip6stat.ip6s_sources_otherscope[best_scope]++;
2807
2808 if ((ifa_best->ia6_flags & IN6_IFF_DEPRECATED) != 0)
2809 ip6stat.ip6s_sources_deprecated[best_scope]++;
2810 }
2811
2812 return(ifa_best);
2813}
2814
2815/*
2816 * return the best address out of the same scope. if no address was
2817 * found, return the first valid address from designated IF.
2818 */
1c79356b 2819struct in6_ifaddr *
91447636
A
2820in6_ifawithifp(
2821 struct ifnet *ifp,
2822 struct in6_addr *dst)
1c79356b
A
2823{
2824 int dst_scope = in6_addrscope(dst), blen = -1, tlen;
2825 struct ifaddr *ifa;
2826 struct in6_ifaddr *besta = 0;
55e303ae 2827 struct in6_ifaddr *dep[2]; /* last-resort: deprecated */
1c79356b
A
2828
2829 dep[0] = dep[1] = NULL;
2830
1c79356b
A
2831 /*
2832 * We first look for addresses in the same scope.
2833 * If there is one, return it.
2834 * If two or more, return one which matches the dst longest.
2835 * If none, return one of global addresses assigned other ifs.
2836 */
91447636 2837 ifnet_lock_shared(ifp);
9bccf70c 2838 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
2839 {
2840 if (ifa->ifa_addr->sa_family != AF_INET6)
2841 continue;
2842 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2843 continue; /* XXX: is there any case to allow anycast? */
2844 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2845 continue; /* don't use this interface */
2846 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2847 continue;
2848 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
b0d623f7
A
2849 if (ip6_use_deprecated) {
2850 if (dep[0] != NULL)
2851 ifafree(&dep[0]->ia_ifa);
1c79356b 2852 dep[0] = (struct in6_ifaddr *)ifa;
b0d623f7
A
2853 ifaref(ifa);
2854 }
1c79356b
A
2855 continue;
2856 }
2857
2858 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
2859 /*
2860 * call in6_matchlen() as few as possible
2861 */
2862 if (besta) {
2863 if (blen == -1)
2864 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
2865 tlen = in6_matchlen(IFA_IN6(ifa), dst);
2866 if (tlen > blen) {
2867 blen = tlen;
2868 besta = (struct in6_ifaddr *)ifa;
2869 }
2870 } else
2871 besta = (struct in6_ifaddr *)ifa;
2872 }
2873 }
91447636 2874 if (besta) {
b0d623f7 2875 ifaref(&besta->ia_ifa);
91447636 2876 ifnet_lock_done(ifp);
b0d623f7
A
2877 if (dep[0] != NULL)
2878 ifafree(&dep[0]->ia_ifa);
1c79356b 2879 return(besta);
91447636 2880 }
1c79356b 2881
9bccf70c 2882 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b
A
2883 {
2884 if (ifa->ifa_addr->sa_family != AF_INET6)
2885 continue;
2886 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
2887 continue; /* XXX: is there any case to allow anycast? */
2888 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
2889 continue; /* don't use this interface */
2890 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
2891 continue;
2892 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
b0d623f7
A
2893 if (ip6_use_deprecated) {
2894 if (dep[1] != NULL)
2895 ifafree(&dep[1]->ia_ifa);
1c79356b 2896 dep[1] = (struct in6_ifaddr *)ifa;
b0d623f7
A
2897 ifaref(ifa);
2898 }
1c79356b
A
2899 continue;
2900 }
b0d623f7
A
2901 if (ifa != NULL)
2902 ifaref(ifa);
91447636 2903 ifnet_lock_done(ifp);
b0d623f7
A
2904 if (dep[0] != NULL)
2905 ifafree(&dep[0]->ia_ifa);
2906 if (dep[1] != NULL)
2907 ifafree(&dep[1]->ia_ifa);
1c79356b
A
2908 return (struct in6_ifaddr *)ifa;
2909 }
91447636 2910 ifnet_lock_done(ifp);
1c79356b
A
2911
2912 /* use the last-resort values, that are, deprecated addresses */
b0d623f7
A
2913 if (dep[0]) {
2914 if (dep[1] != NULL)
2915 ifafree(&dep[1]->ia_ifa);
1c79356b 2916 return dep[0];
b0d623f7 2917 }
1c79356b
A
2918 if (dep[1])
2919 return dep[1];
2920
2921 return NULL;
2922}
2923
2924/*
2925 * perform DAD when interface becomes IFF_UP.
2926 */
b0d623f7 2927int
91447636
A
2928in6_if_up(
2929 struct ifnet *ifp,
2930 struct in6_aliasreq *ifra)
1c79356b
A
2931{
2932 struct ifaddr *ifa;
2933 struct in6_ifaddr *ia;
1c79356b 2934 int dad_delay; /* delay ticks before DAD output */
b0d623f7 2935 int error;
1c79356b 2936
9bccf70c 2937 if (!in6_init2done)
b0d623f7 2938 return ENXIO;
1c79356b 2939
9bccf70c
A
2940 /*
2941 * special cases, like 6to4, are handled in in6_ifattach
2942 */
b0d623f7
A
2943 error = in6_ifattach(ifp, NULL, ifra);
2944 if (error != 0)
2945 return error;
9bccf70c
A
2946
2947 dad_delay = 0;
91447636 2948 ifnet_lock_exclusive(ifp);
9bccf70c 2949 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1c79356b 2950 {
9bccf70c 2951 if (ifa->ifa_addr->sa_family != AF_INET6)
1c79356b 2952 continue;
9bccf70c
A
2953 ia = (struct in6_ifaddr *)ifa;
2954 if (ia->ia6_flags & IN6_IFF_TENTATIVE)
2955 nd6_dad_start(ifa, &dad_delay);
1c79356b 2956 }
91447636 2957 ifnet_lock_done(ifp);
b0d623f7
A
2958
2959 return 0;
9bccf70c
A
2960}
2961
2962int
91447636
A
2963in6if_do_dad(
2964 struct ifnet *ifp)
9bccf70c
A
2965{
2966 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
2967 return(0);
1c79356b
A
2968
2969 switch (ifp->if_type) {
9bccf70c 2970#if IFT_DUMMY
1c79356b 2971 case IFT_DUMMY:
9bccf70c 2972#endif
1c79356b 2973 case IFT_FAITH:
1c79356b 2974 /*
9bccf70c
A
2975 * These interfaces do not have the IFF_LOOPBACK flag,
2976 * but loop packets back. We do not have to do DAD on such
2977 * interfaces. We should even omit it, because loop-backed
2978 * NS would confuse the DAD procedure.
1c79356b 2979 */
9bccf70c 2980 return(0);
1c79356b 2981 default:
9bccf70c
A
2982 /*
2983 * Our DAD routine requires the interface up and running.
2984 * However, some interfaces can be up before the RUNNING
2985 * status. Additionaly, users may try to assign addresses
2986 * before the interface becomes up (or running).
2987 * We simply skip DAD in such a case as a work around.
2988 * XXX: we should rather mark "tentative" on such addresses,
2989 * and do DAD after the interface becomes ready.
2990 */
2991 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) !=
2992 (IFF_UP|IFF_RUNNING))
2993 return(0);
1c79356b 2994
9bccf70c 2995 return(1);
1c79356b
A
2996 }
2997}
2998
2999/*
3000 * Calculate max IPv6 MTU through all the interfaces and store it
3001 * to in6_maxmtu.
3002 */
3003void
3004in6_setmaxmtu()
3005{
b0d623f7 3006 u_int32_t maxmtu = 0;
1c79356b
A
3007 struct ifnet *ifp;
3008
91447636
A
3009 ifnet_head_lock_shared();
3010 TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
b0d623f7 3011 lck_rw_lock_shared(nd_if_rwlock);
1c79356b 3012 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2d21ac55
A
3013 IN6_LINKMTU(ifp) > maxmtu)
3014 maxmtu = IN6_LINKMTU(ifp);
b0d623f7 3015 lck_rw_done(nd_if_rwlock);
1c79356b 3016 }
91447636 3017 ifnet_head_done();
1c79356b
A
3018 if (maxmtu) /* update only when maxmtu is positive */
3019 in6_maxmtu = maxmtu;
3020}
3021
9bccf70c 3022/*
55e303ae 3023 * Convert sockaddr_in6 to sockaddr_in. Original sockaddr_in6 must be
1c79356b
A
3024 * v4 mapped addr or v4 compat addr
3025 */
3026void
3027in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
3028{
3029 bzero(sin, sizeof(*sin));
3030 sin->sin_len = sizeof(struct sockaddr_in);
3031 sin->sin_family = AF_INET;
3032 sin->sin_port = sin6->sin6_port;
3033 sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
3034}
3035
3036/* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
3037void
3038in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
3039{
3040 bzero(sin6, sizeof(*sin6));
3041 sin6->sin6_len = sizeof(struct sockaddr_in6);
3042 sin6->sin6_family = AF_INET6;
3043 sin6->sin6_port = sin->sin_port;
3044 sin6->sin6_addr.s6_addr32[0] = 0;
3045 sin6->sin6_addr.s6_addr32[1] = 0;
3046 sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
3047 sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
3048}
3049
3050/* Convert sockaddr_in6 into sockaddr_in. */
3051void
3052in6_sin6_2_sin_in_sock(struct sockaddr *nam)
3053{
3054 struct sockaddr_in *sin_p;
3055 struct sockaddr_in6 sin6;
3056
3057 /*
3058 * Save original sockaddr_in6 addr and convert it
3059 * to sockaddr_in.
3060 */
3061 sin6 = *(struct sockaddr_in6 *)nam;
3062 sin_p = (struct sockaddr_in *)nam;
3063 in6_sin6_2_sin(sin_p, &sin6);
3064}
3065
3066/* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
b0d623f7 3067int
1c79356b
A
3068in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
3069{
3070 struct sockaddr_in *sin_p;
3071 struct sockaddr_in6 *sin6_p;
3072
3073 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
3074 M_WAITOK);
b0d623f7
A
3075 if (sin6_p == NULL)
3076 return ENOBUFS;
1c79356b
A
3077 sin_p = (struct sockaddr_in *)*nam;
3078 in6_sin_2_v4mapsin6(sin_p, sin6_p);
3079 FREE(*nam, M_SONAME);
3080 *nam = (struct sockaddr *)sin6_p;
b0d623f7
A
3081
3082 return 0;
1c79356b 3083}
1c79356b 3084
b0d623f7
A
3085/*
3086 * Posts in6_event_data message kernel events.
3087 *
3088 * To get the same size of kev_in6_data between ILP32 and LP64 data models
3089 * we are using a special version of the in6_addrlifetime structure that
3090 * uses only 32 bits fields to be compatible with Leopard, and that
3091 * are large enough to span 68 years.
3092 */
9bccf70c 3093void
b0d623f7 3094in6_post_msg(struct ifnet *ifp, u_int32_t event_code, struct in6_ifaddr *ifa)
9bccf70c
A
3095{
3096 struct kev_msg ev_msg;
b0d623f7 3097 struct kev_in6_data in6_event_data;
9bccf70c
A
3098
3099 ev_msg.vendor_code = KEV_VENDOR_APPLE;
3100 ev_msg.kev_class = KEV_NETWORK_CLASS;
3101 ev_msg.kev_subclass = KEV_INET6_SUBCLASS;
3102 ev_msg.event_code = event_code;
3103
3104 in6_event_data.ia_addr = ifa->ia_addr;
3105 in6_event_data.ia_net = ifa->ia_net;
3106 in6_event_data.ia_dstaddr = ifa->ia_dstaddr;
3107 in6_event_data.ia_prefixmask = ifa->ia_prefixmask;
3108 in6_event_data.ia_plen = ifa->ia_plen;
3109 in6_event_data.ia6_flags = (u_int32_t)ifa->ia6_flags;
b0d623f7
A
3110
3111 in6_event_data.ia_lifetime.ia6t_expire =
3112 ifa->ia6_lifetime.ia6t_expire;
3113 in6_event_data.ia_lifetime.ia6t_preferred =
3114 ifa->ia6_lifetime.ia6t_preferred;
3115 in6_event_data.ia_lifetime.ia6t_vltime =
3116 ifa->ia6_lifetime.ia6t_vltime;
3117 in6_event_data.ia_lifetime.ia6t_pltime =
3118 ifa->ia6_lifetime.ia6t_pltime;
9bccf70c
A
3119
3120 if (ifp != NULL) {
b0d623f7
A
3121 strncpy(&in6_event_data.link_data.if_name[0],
3122 ifp->if_name, IFNAMSIZ);
9bccf70c 3123 in6_event_data.link_data.if_family = ifp->if_family;
b0d623f7 3124 in6_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit;
9bccf70c
A
3125 }
3126
3127 ev_msg.dv[0].data_ptr = &in6_event_data;
b0d623f7 3128 ev_msg.dv[0].data_length = sizeof (in6_event_data);
9bccf70c
A
3129 ev_msg.dv[1].data_length = 0;
3130
3131 kev_post_msg(&ev_msg);
3132}
b0d623f7
A
3133
3134/*
3135 * Called as part of ip6_init
3136 */
3137void
3138in6_ifaddr_init(void)
3139{
3140 PE_parse_boot_argn("ifa_debug", &in6ifa_debug, sizeof (in6ifa_debug));
3141
3142 in6ifa_size = (in6ifa_debug == 0) ? sizeof (struct in6_ifaddr) :
3143 sizeof (struct in6_ifaddr_dbg);
3144
3145 in6ifa_zone = zinit(in6ifa_size, IN6IFA_ZONE_MAX * in6ifa_size,
3146 0, IN6IFA_ZONE_NAME);
3147 if (in6ifa_zone == NULL)
3148 panic("%s: failed allocating %s", __func__, IN6IFA_ZONE_NAME);
3149
3150 zone_change(in6ifa_zone, Z_EXPAND, TRUE);
3151}
3152
3153static struct in6_ifaddr *
3154in6_ifaddr_alloc(int how)
3155{
3156 struct in6_ifaddr *in6ifa;
3157
3158 in6ifa = (how == M_WAITOK) ? zalloc(in6ifa_zone) :
3159 zalloc_noblock(in6ifa_zone);
3160 if (in6ifa != NULL) {
3161 bzero(in6ifa, in6ifa_size);
3162 in6ifa->ia_ifa.ifa_free = in6_ifaddr_free;
3163 in6ifa->ia_ifa.ifa_debug |= IFD_ALLOC;
3164 if (in6ifa_debug != 0) {
3165 struct in6_ifaddr_dbg *in6ifa_dbg =
3166 (struct in6_ifaddr_dbg *)in6ifa;
3167 in6ifa->ia_ifa.ifa_debug |= IFD_DEBUG;
3168 in6ifa->ia_ifa.ifa_trace = in6_ifaddr_trace;
3169 ctrace_record(&in6ifa_dbg->in6ifa_alloc);
3170 }
3171 }
3172 return (in6ifa);
3173}
3174
3175static void
3176in6_ifaddr_free(struct ifaddr *ifa)
3177{
3178 if (ifa->ifa_refcnt != 0)
3179 panic("%s: ifa %p bad ref cnt", __func__, ifa);
3180 if (!(ifa->ifa_debug & IFD_ALLOC))
3181 panic("%s: ifa %p cannot be freed", __func__, ifa);
3182
3183 if (ifa->ifa_debug & IFD_DEBUG) {
3184 struct in6_ifaddr_dbg *in6ifa_dbg =
3185 (struct in6_ifaddr_dbg *)ifa;
3186 ctrace_record(&in6ifa_dbg->in6ifa_free);
3187 bcopy(&in6ifa_dbg->in6ifa, &in6ifa_dbg->in6ifa_old,
3188 sizeof (struct in6_ifaddr));
3189 }
3190 bzero(ifa, sizeof (struct in6_ifaddr));
3191 zfree(in6ifa_zone, ifa);
3192}
3193
3194static void
3195in6_ifaddr_trace(struct ifaddr *ifa, int refhold)
3196{
3197 struct in6_ifaddr_dbg *in6ifa_dbg = (struct in6_ifaddr_dbg *)ifa;
3198 ctrace_t *tr;
3199 u_int32_t idx;
3200 u_int16_t *cnt;
3201
3202 if (!(ifa->ifa_debug & IFD_DEBUG))
3203 panic("%s: ifa %p has no debug structure", __func__, ifa);
3204
3205 if (refhold) {
3206 cnt = &in6ifa_dbg->in6ifa_refhold_cnt;
3207 tr = in6ifa_dbg->in6ifa_refhold;
3208 } else {
3209 cnt = &in6ifa_dbg->in6ifa_refrele_cnt;
3210 tr = in6ifa_dbg->in6ifa_refrele;
3211 }
3212
3213 idx = OSAddAtomic16(1, (volatile SInt16 *)cnt) % CTRACE_HIST_SIZE;
3214 ctrace_record(&tr[idx]);
3215}