Coverage Report

Created: 2026-11-12 06:44

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