Coverage Report

Created: 2024-10-03 06:24

/src/SockFuzzer/third_party/xnu/bsd/netinet6/nd6.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2000-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
 * XXX
60
 * KAME 970409 note:
61
 * BSD/OS version heavily modifies this code, related to llinfo.
62
 * Since we don't have BSD/OS version of net/route.c in our hand,
63
 * I left the code mostly as it was in 970310.  -- itojun
64
 */
65
66
#include <sys/param.h>
67
#include <sys/systm.h>
68
#include <sys/malloc.h>
69
#include <sys/mbuf.h>
70
#include <sys/socket.h>
71
#include <sys/sockio.h>
72
#include <sys/time.h>
73
#include <sys/kernel.h>
74
#include <sys/sysctl.h>
75
#include <sys/errno.h>
76
#include <sys/syslog.h>
77
#include <sys/protosw.h>
78
#include <sys/proc.h>
79
#include <sys/mcache.h>
80
81
#include <dev/random/randomdev.h>
82
83
#include <kern/queue.h>
84
#include <kern/zalloc.h>
85
86
#include <net/if.h>
87
#include <net/if_dl.h>
88
#include <net/if_types.h>
89
#include <net/if_llreach.h>
90
#include <net/route.h>
91
#include <net/dlil.h>
92
#include <net/ntstat.h>
93
#include <net/net_osdep.h>
94
#include <net/nwk_wq.h>
95
96
#include <netinet/in.h>
97
#include <netinet/in_arp.h>
98
#include <netinet/if_ether.h>
99
#include <netinet6/in6_var.h>
100
#include <netinet/ip6.h>
101
#include <netinet6/ip6_var.h>
102
#include <netinet6/nd6.h>
103
#include <netinet6/scope6_var.h>
104
#include <netinet/icmp6.h>
105
106
#include <os/log.h>
107
108
#include "loop.h"
109
110
408k
#define ND6_SLOWTIMER_INTERVAL          (60 * 60)       /* 1 hour */
111
#define ND6_RECALC_REACHTM_INTERVAL     (60 * 120)      /* 2 hours */
112
113
0
#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
114
115
/* timer values */
116
int     nd6_prune       = 1;    /* walk list every 1 seconds */
117
int     nd6_prune_lazy  = 5;    /* lazily walk list every 5 seconds */
118
int     nd6_delay       = 5;    /* delay first probe time 5 second */
119
int     nd6_umaxtries   = 3;    /* maximum unicast query */
120
int     nd6_mmaxtries   = 3;    /* maximum multicast query */
121
int     nd6_useloopback = 1;    /* use loopback interface for local traffic */
122
int     nd6_gctimer     = (60 * 60 * 24); /* 1 day: garbage collection timer */
123
124
/* preventing too many loops in ND option parsing */
125
int nd6_maxndopt = 10;  /* max # of ND options allowed */
126
127
int nd6_maxqueuelen = 1; /* max # of packets cached in unresolved ND entries */
128
129
#if ND6_DEBUG
130
int nd6_debug = 1;
131
#else
132
int nd6_debug = 0;
133
#endif
134
135
int nd6_optimistic_dad = ND6_OPTIMISTIC_DAD_DEFAULT;
136
137
/* for debugging? */
138
static int nd6_inuse, nd6_allocated;
139
140
/*
141
 * Synchronization notes:
142
 *
143
 * The global list of ND entries are stored in llinfo_nd6; an entry
144
 * gets inserted into the list when the route is created and gets
145
 * removed from the list when it is deleted; this is done as part
146
 * of RTM_ADD/RTM_RESOLVE/RTM_DELETE in nd6_rtrequest().
147
 *
148
 * Because rnh_lock and rt_lock for the entry are held during those
149
 * operations, the same locks (and thus lock ordering) must be used
150
 * elsewhere to access the relevant data structure fields:
151
 *
152
 * ln_next, ln_prev, ln_rt
153
 *
154
 *  - Routing lock (rnh_lock)
155
 *
156
 * ln_hold, ln_asked, ln_expire, ln_state, ln_router, ln_flags,
157
 * ln_llreach, ln_lastused
158
 *
159
 *  - Routing entry lock (rt_lock)
160
 *
161
 * Due to the dependency on rt_lock, llinfo_nd6 has the same lifetime
162
 * as the route entry itself.  When a route is deleted (RTM_DELETE),
163
 * it is simply removed from the global list but the memory is not
164
 * freed until the route itself is freed.
165
 */
166
struct llinfo_nd6 llinfo_nd6 = {
167
  .ln_next = &llinfo_nd6,
168
  .ln_prev = &llinfo_nd6,
169
};
170
171
static lck_grp_attr_t   *nd_if_lock_grp_attr = NULL;
172
static lck_grp_t        *nd_if_lock_grp = NULL;
173
static lck_attr_t       *nd_if_lock_attr = NULL;
174
175
/* Protected by nd6_mutex */
176
struct nd_drhead nd_defrouter_list;
177
struct nd_prhead nd_prefix = { .lh_first = 0 };
178
struct nd_rtihead nd_rti_list;
179
/*
180
 * nd6_timeout() is scheduled on a demand basis.  nd6_timeout_run is used
181
 * to indicate whether or not a timeout has been scheduled.  The rnh_lock
182
 * mutex is used to protect this scheduling; it is a natural choice given
183
 * the work done in the timer callback.  Unfortunately, there are cases
184
 * when nd6_timeout() needs to be scheduled while rnh_lock cannot be easily
185
 * held, due to lock ordering.  In those cases, we utilize a "demand" counter
186
 * nd6_sched_timeout_want which can be atomically incremented without
187
 * having to hold rnh_lock.  On places where we acquire rnh_lock, such as
188
 * nd6_rtrequest(), we check this counter and schedule the timer if it is
189
 * non-zero.  The increment happens on various places when we allocate
190
 * new ND entries, default routers, prefixes and addresses.
191
 */
192
static int nd6_timeout_run;   /* nd6_timeout is scheduled to run */
193
void nd6_timeout(void *);
194
int nd6_sched_timeout_want;   /* demand count for timer to be sched */
195
static boolean_t nd6_fast_timer_on = FALSE;
196
197
/* Serialization variables for nd6_service(), protected by rnh_lock */
198
static boolean_t nd6_service_busy;
199
static void *nd6_service_wc = &nd6_service_busy;
200
static int nd6_service_waiters = 0;
201
202
int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
203
static struct sockaddr_in6 all1_sa;
204
205
static int regen_tmpaddr(struct in6_ifaddr *);
206
extern lck_mtx_t *nd6_mutex;
207
208
static struct llinfo_nd6 *nd6_llinfo_alloc(zalloc_flags_t);
209
static void nd6_llinfo_free(void *);
210
static void nd6_llinfo_purge(struct rtentry *);
211
static void nd6_llinfo_get_ri(struct rtentry *, struct rt_reach_info *);
212
static void nd6_llinfo_get_iflri(struct rtentry *, struct ifnet_llreach_info *);
213
static void nd6_llinfo_refresh(struct rtentry *);
214
static uint64_t ln_getexpire(struct llinfo_nd6 *);
215
216
static void nd6_service(void *);
217
void nd6_slowtimo(void *);
218
static int nd6_is_new_addr_neighbor(struct sockaddr_in6 *, struct ifnet *);
219
static int nd6_siocgdrlst(void *, int);
220
static int nd6_siocgprlst(void *, int);
221
222
static void nd6_router_select_rti_entries(struct ifnet *);
223
static void nd6_purge_interface_default_routers(struct ifnet *);
224
static void nd6_purge_interface_rti_entries(struct ifnet *);
225
static void nd6_purge_interface_prefixes(struct ifnet *);
226
static void nd6_purge_interface_llinfo(struct ifnet *);
227
228
static int nd6_sysctl_drlist SYSCTL_HANDLER_ARGS;
229
static int nd6_sysctl_prlist SYSCTL_HANDLER_ARGS;
230
231
/*
232
 * Insertion and removal from llinfo_nd6 must be done with rnh_lock held.
233
 */
234
0
#define LN_DEQUEUE(_ln) do {                                            \
235
0
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);                 \
236
0
  RT_LOCK_ASSERT_HELD((_ln)->ln_rt);                              \
237
0
  (_ln)->ln_next->ln_prev = (_ln)->ln_prev;                       \
238
0
  (_ln)->ln_prev->ln_next = (_ln)->ln_next;                       \
239
0
  (_ln)->ln_prev = (_ln)->ln_next = NULL;                         \
240
0
  (_ln)->ln_flags &= ~ND6_LNF_IN_USE;                             \
241
0
} while (0)
242
243
22
#define LN_INSERTHEAD(_ln) do {                                         \
244
22
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);                 \
245
22
  RT_LOCK_ASSERT_HELD((_ln)->ln_rt);                              \
246
22
  (_ln)->ln_next = llinfo_nd6.ln_next;                            \
247
22
  llinfo_nd6.ln_next = (_ln);                                     \
248
22
  (_ln)->ln_prev = &llinfo_nd6;                                   \
249
22
  (_ln)->ln_next->ln_prev = (_ln);                                \
250
22
  (_ln)->ln_flags |= ND6_LNF_IN_USE;                              \
251
22
} while (0)
252
253
static ZONE_DECLARE(llinfo_nd6_zone, "llinfo_nd6",
254
    sizeof(struct llinfo_nd6), ZC_ZFREE_CLEARMEM);
255
256
extern int tvtohz(struct timeval *);
257
258
static int nd6_init_done;
259
260
SYSCTL_DECL(_net_inet6_icmp6);
261
262
SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
263
    CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
264
    nd6_sysctl_drlist, "S,in6_defrouter", "");
265
266
SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
267
    CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
268
    nd6_sysctl_prlist, "S,in6_defrouter", "");
269
270
SYSCTL_DECL(_net_inet6_ip6);
271
272
static int ip6_maxchainsent = 0;
273
SYSCTL_INT(_net_inet6_ip6, OID_AUTO, maxchainsent,
274
    CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_maxchainsent, 0,
275
    "use dlil_output_list");
276
277
SYSCTL_DECL(_net_inet6_icmp6);
278
int nd6_process_rti = ND6_PROCESS_RTI_DEFAULT;
279
280
SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_process_rti, CTLFLAG_RW | CTLFLAG_LOCKED,
281
    &nd6_process_rti, 0,
282
    "Enable/disable processing of Route Information Option in the "
283
    "IPv6 Router Advertisement.");
284
285
void
286
nd6_init(void)
287
1
{
288
1
  int i;
289
290
1
  VERIFY(!nd6_init_done);
291
292
1
  all1_sa.sin6_family = AF_INET6;
293
1
  all1_sa.sin6_len = sizeof(struct sockaddr_in6);
294
17
  for (i = 0; i < sizeof(all1_sa.sin6_addr); i++) {
295
16
    all1_sa.sin6_addr.s6_addr[i] = 0xff;
296
16
  }
297
298
  /* initialization of the default router list */
299
1
  TAILQ_INIT(&nd_defrouter_list);
300
1
  TAILQ_INIT(&nd_rti_list);
301
302
1
  nd_if_lock_grp_attr = lck_grp_attr_alloc_init();
303
1
  nd_if_lock_grp = lck_grp_alloc_init("nd_if_lock", nd_if_lock_grp_attr);
304
1
  nd_if_lock_attr = lck_attr_alloc_init();
305
306
1
  nd6_nbr_init();
307
1
  nd6_rtr_init();
308
309
1
  nd6_init_done = 1;
310
311
  /* start timer */
312
  // timeout(nd6_slowtimo, NULL, ND6_SLOWTIMER_INTERVAL * hz);
313
1
}
314
315
static struct llinfo_nd6 *
316
nd6_llinfo_alloc(zalloc_flags_t how)
317
22
{
318
22
  return zalloc_flags(llinfo_nd6_zone, how | Z_ZERO);
319
22
}
320
321
static void
322
nd6_llinfo_free(void *arg)
323
0
{
324
0
  struct llinfo_nd6 *ln = arg;
325
326
0
  if (ln->ln_next != NULL || ln->ln_prev != NULL) {
327
0
    panic("%s: trying to free %p when it is in use", __func__, ln);
328
    /* NOTREACHED */
329
0
  }
330
331
  /* Just in case there's anything there, free it */
332
0
  if (ln->ln_hold != NULL) {
333
0
    m_freem_list(ln->ln_hold);
334
0
    ln->ln_hold = NULL;
335
0
  }
336
337
  /* Purge any link-layer info caching */
338
0
  VERIFY(ln->ln_rt->rt_llinfo == ln);
339
0
  if (ln->ln_rt->rt_llinfo_purge != NULL) {
340
0
    ln->ln_rt->rt_llinfo_purge(ln->ln_rt);
341
0
  }
342
343
0
  zfree(llinfo_nd6_zone, ln);
344
0
}
345
346
static void
347
nd6_llinfo_purge(struct rtentry *rt)
348
0
{
349
0
  struct llinfo_nd6 *ln = rt->rt_llinfo;
350
351
0
  RT_LOCK_ASSERT_HELD(rt);
352
0
  VERIFY(rt->rt_llinfo_purge == nd6_llinfo_purge && ln != NULL);
353
354
0
  if (ln->ln_llreach != NULL) {
355
0
    RT_CONVERT_LOCK(rt);
356
0
    ifnet_llreach_free(ln->ln_llreach);
357
0
    ln->ln_llreach = NULL;
358
0
  }
359
0
  ln->ln_lastused = 0;
360
0
}
361
362
static void
363
nd6_llinfo_get_ri(struct rtentry *rt, struct rt_reach_info *ri)
364
0
{
365
0
  struct llinfo_nd6 *ln = rt->rt_llinfo;
366
0
  struct if_llreach *lr = ln->ln_llreach;
367
368
0
  if (lr == NULL) {
369
0
    bzero(ri, sizeof(*ri));
370
0
    ri->ri_rssi = IFNET_RSSI_UNKNOWN;
371
0
    ri->ri_lqm = IFNET_LQM_THRESH_OFF;
372
0
    ri->ri_npm = IFNET_NPM_THRESH_UNKNOWN;
373
0
  } else {
374
0
    IFLR_LOCK(lr);
375
    /* Export to rt_reach_info structure */
376
0
    ifnet_lr2ri(lr, ri);
377
    /* Export ND6 send expiration (calendar) time */
378
0
    ri->ri_snd_expire =
379
0
        ifnet_llreach_up2calexp(lr, ln->ln_lastused);
380
0
    IFLR_UNLOCK(lr);
381
0
  }
382
0
}
383
384
static void
385
nd6_llinfo_get_iflri(struct rtentry *rt, struct ifnet_llreach_info *iflri)
386
0
{
387
0
  struct llinfo_nd6 *ln = rt->rt_llinfo;
388
0
  struct if_llreach *lr = ln->ln_llreach;
389
390
0
  if (lr == NULL) {
391
0
    bzero(iflri, sizeof(*iflri));
392
0
    iflri->iflri_rssi = IFNET_RSSI_UNKNOWN;
393
0
    iflri->iflri_lqm = IFNET_LQM_THRESH_OFF;
394
0
    iflri->iflri_npm = IFNET_NPM_THRESH_UNKNOWN;
395
0
  } else {
396
0
    IFLR_LOCK(lr);
397
    /* Export to ifnet_llreach_info structure */
398
0
    ifnet_lr2iflri(lr, iflri);
399
    /* Export ND6 send expiration (uptime) time */
400
0
    iflri->iflri_snd_expire =
401
0
        ifnet_llreach_up2upexp(lr, ln->ln_lastused);
402
0
    IFLR_UNLOCK(lr);
403
0
  }
404
0
}
405
406
static void
407
nd6_llinfo_refresh(struct rtentry *rt)
408
0
{
409
0
  struct llinfo_nd6 *ln = rt->rt_llinfo;
410
0
  uint64_t timenow = net_uptime();
411
  /*
412
   * Can't refresh permanent, static or entries that are
413
   * not direct host entries
414
   */
415
0
  if (!ln || ln->ln_expire == 0 ||
416
0
      (rt->rt_flags & RTF_STATIC) ||
417
0
      !(rt->rt_flags & RTF_LLINFO)) {
418
0
    return;
419
0
  }
420
421
0
  if ((ln->ln_state > ND6_LLINFO_INCOMPLETE) &&
422
0
      (ln->ln_state < ND6_LLINFO_PROBE)) {
423
0
    if (ln->ln_expire > timenow) {
424
0
      ln_setexpire(ln, timenow);
425
0
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_PROBE);
426
0
    }
427
0
  }
428
0
  return;
429
0
}
430
431
const char *
432
ndcache_state2str(short ndp_state)
433
0
{
434
0
  const char *ndp_state_str = "UNKNOWN";
435
0
  switch (ndp_state) {
436
0
  case ND6_LLINFO_PURGE:
437
0
    ndp_state_str = "ND6_LLINFO_PURGE";
438
0
    break;
439
0
  case ND6_LLINFO_NOSTATE:
440
0
    ndp_state_str = "ND6_LLINFO_NOSTATE";
441
0
    break;
442
0
  case ND6_LLINFO_INCOMPLETE:
443
0
    ndp_state_str = "ND6_LLINFO_INCOMPLETE";
444
0
    break;
445
0
  case ND6_LLINFO_REACHABLE:
446
0
    ndp_state_str = "ND6_LLINFO_REACHABLE";
447
0
    break;
448
0
  case ND6_LLINFO_STALE:
449
0
    ndp_state_str = "ND6_LLINFO_STALE";
450
0
    break;
451
0
  case ND6_LLINFO_DELAY:
452
0
    ndp_state_str = "ND6_LLINFO_DELAY";
453
0
    break;
454
0
  case ND6_LLINFO_PROBE:
455
0
    ndp_state_str = "ND6_LLINFO_PROBE";
456
0
    break;
457
0
  default:
458
    /* Init'd to UNKNOWN */
459
0
    break;
460
0
  }
461
0
  return ndp_state_str;
462
0
}
463
464
void
465
ln_setexpire(struct llinfo_nd6 *ln, uint64_t expiry)
466
7.93k
{
467
7.93k
  ln->ln_expire = expiry;
468
7.93k
}
469
470
static uint64_t
471
ln_getexpire(struct llinfo_nd6 *ln)
472
0
{
473
0
  struct timeval caltime;
474
0
  uint64_t expiry;
475
476
0
  if (ln->ln_expire != 0) {
477
0
    struct rtentry *rt = ln->ln_rt;
478
479
0
    VERIFY(rt != NULL);
480
    /* account for system time change */
481
0
    getmicrotime(&caltime);
482
483
0
    rt->base_calendartime +=
484
0
        NET_CALCULATE_CLOCKSKEW(caltime,
485
0
        rt->base_calendartime, net_uptime(), rt->base_uptime);
486
487
0
    expiry = rt->base_calendartime +
488
0
        ln->ln_expire - rt->base_uptime;
489
0
  } else {
490
0
    expiry = 0;
491
0
  }
492
0
  return expiry;
493
0
}
494
495
void
496
nd6_ifreset(struct ifnet *ifp)
497
1
{
498
1
  struct nd_ifinfo *ndi = ND_IFINFO(ifp);
499
1
  VERIFY(NULL != ndi);
500
1
  VERIFY(ndi->initialized);
501
502
1
  LCK_MTX_ASSERT(&ndi->lock, LCK_MTX_ASSERT_OWNED);
503
1
  ndi->linkmtu = ifp->if_mtu;
504
1
  ndi->chlim = IPV6_DEFHLIM;
505
1
  ndi->basereachable = REACHABLE_TIME;
506
1
  ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
507
1
  ndi->retrans = RETRANS_TIMER;
508
1
}
509
510
void
511
nd6_ifattach(struct ifnet *ifp)
512
1
{
513
1
  struct nd_ifinfo *ndi = ND_IFINFO(ifp);
514
515
1
  VERIFY(NULL != ndi);
516
1
  if (!ndi->initialized) {
517
1
    lck_mtx_init(&ndi->lock, nd_if_lock_grp, nd_if_lock_attr);
518
1
    ndi->flags = ND6_IFF_PERFORMNUD;
519
1
    ndi->flags |= ND6_IFF_DAD;
520
1
    ndi->initialized = TRUE;
521
1
  }
522
523
1
  lck_mtx_lock(&ndi->lock);
524
525
1
  if (!(ifp->if_flags & IFF_MULTICAST)) {
526
0
    ndi->flags |= ND6_IFF_IFDISABLED;
527
0
  }
528
529
1
  nd6_ifreset(ifp);
530
1
  lck_mtx_unlock(&ndi->lock);
531
1
  nd6_setmtu(ifp);
532
533
1
  nd6log0(info,
534
1
      "Reinit'd ND information for interface %s\n",
535
1
      if_name(ifp));
536
1
  return;
537
1
}
538
539
#if 0
540
/*
541
 * XXX Look more into this. Especially since we recycle ifnets and do delayed
542
 * cleanup
543
 */
544
void
545
nd6_ifdetach(struct nd_ifinfo *nd)
546
{
547
  /* XXX destroy nd's lock? */
548
  FREE(nd, M_IP6NDP);
549
}
550
#endif
551
552
void
553
nd6_setmtu(struct ifnet *ifp)
554
1
{
555
1
  struct nd_ifinfo *ndi = ND_IFINFO(ifp);
556
1
  u_int32_t oldmaxmtu, maxmtu;
557
558
1
  if ((NULL == ndi) || (FALSE == ndi->initialized)) {
559
0
    return;
560
0
  }
561
562
1
  lck_mtx_lock(&ndi->lock);
563
1
  oldmaxmtu = ndi->maxmtu;
564
565
  /*
566
   * The ND level maxmtu is somewhat redundant to the interface MTU
567
   * and is an implementation artifact of KAME.  Instead of hard-
568
   * limiting the maxmtu based on the interface type here, we simply
569
   * take the if_mtu value since SIOCSIFMTU would have taken care of
570
   * the sanity checks related to the maximum MTU allowed for the
571
   * interface (a value that is known only by the interface layer),
572
   * by sending the request down via ifnet_ioctl().  The use of the
573
   * ND level maxmtu and linkmtu are done via IN6_LINKMTU() which
574
   * does further checking against if_mtu.
575
   */
576
1
  maxmtu = ndi->maxmtu = ifp->if_mtu;
577
578
  /*
579
   * Decreasing the interface MTU under IPV6 minimum MTU may cause
580
   * undesirable situation.  We thus notify the operator of the change
581
   * explicitly.  The check for oldmaxmtu is necessary to restrict the
582
   * log to the case of changing the MTU, not initializing it.
583
   */
584
1
  if (oldmaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) {
585
0
    log(LOG_NOTICE, "nd6_setmtu: "
586
0
        "new link MTU on %s (%u) is too small for IPv6\n",
587
0
        if_name(ifp), (uint32_t)ndi->maxmtu);
588
0
  }
589
1
  ndi->linkmtu = ifp->if_mtu;
590
1
  lck_mtx_unlock(&ndi->lock);
591
592
  /* also adjust in6_maxmtu if necessary. */
593
1
  if (maxmtu > in6_maxmtu) {
594
1
    in6_setmaxmtu();
595
1
  }
596
1
}
597
598
void
599
nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
600
30.9k
{
601
30.9k
  bzero(ndopts, sizeof(*ndopts));
602
30.9k
  ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
603
30.9k
  ndopts->nd_opts_last =
604
30.9k
      (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
605
606
30.9k
  if (icmp6len == 0) {
607
10.9k
    ndopts->nd_opts_done = 1;
608
10.9k
    ndopts->nd_opts_search = NULL;
609
10.9k
  }
610
30.9k
}
611
612
/*
613
 * Take one ND option.
614
 */
615
struct nd_opt_hdr *
616
nd6_option(union nd_opts *ndopts)
617
33.9k
{
618
33.9k
  struct nd_opt_hdr *nd_opt;
619
33.9k
  int olen;
620
621
33.9k
  if (!ndopts) {
622
0
    panic("ndopts == NULL in nd6_option\n");
623
0
  }
624
33.9k
  if (!ndopts->nd_opts_last) {
625
0
    panic("uninitialized ndopts in nd6_option\n");
626
0
  }
627
33.9k
  if (!ndopts->nd_opts_search) {
628
0
    return NULL;
629
0
  }
630
33.9k
  if (ndopts->nd_opts_done) {
631
0
    return NULL;
632
0
  }
633
634
33.9k
  nd_opt = ndopts->nd_opts_search;
635
636
  /* make sure nd_opt_len is inside the buffer */
637
33.9k
  if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) {
638
26
    bzero(ndopts, sizeof(*ndopts));
639
26
    return NULL;
640
26
  }
641
642
33.9k
  olen = nd_opt->nd_opt_len << 3;
643
33.9k
  if (olen == 0) {
644
    /*
645
     * Message validation requires that all included
646
     * options have a length that is greater than zero.
647
     */
648
154
    bzero(ndopts, sizeof(*ndopts));
649
154
    return NULL;
650
154
  }
651
652
33.7k
  ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
653
33.7k
  if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
654
    /* option overruns the end of buffer, invalid */
655
11.1k
    bzero(ndopts, sizeof(*ndopts));
656
11.1k
    return NULL;
657
22.6k
  } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
658
    /* reached the end of options chain */
659
8.66k
    ndopts->nd_opts_done = 1;
660
8.66k
    ndopts->nd_opts_search = NULL;
661
8.66k
  }
662
22.6k
  return nd_opt;
663
33.7k
}
664
665
/*
666
 * Parse multiple ND options.
667
 * This function is much easier to use, for ND routines that do not need
668
 * multiple options of the same type.
669
 */
670
int
671
nd6_options(union nd_opts *ndopts)
672
30.9k
{
673
30.9k
  struct nd_opt_hdr *nd_opt;
674
30.9k
  int i = 0;
675
676
30.9k
  if (ndopts == NULL) {
677
0
    panic("ndopts == NULL in nd6_options");
678
0
  }
679
30.9k
  if (ndopts->nd_opts_last == NULL) {
680
0
    panic("uninitialized ndopts in nd6_options");
681
0
  }
682
30.9k
  if (ndopts->nd_opts_search == NULL) {
683
10.9k
    return 0;
684
10.9k
  }
685
686
33.9k
  while (1) {
687
33.9k
    nd_opt = nd6_option(ndopts);
688
33.9k
    if (nd_opt == NULL && ndopts->nd_opts_last == NULL) {
689
      /*
690
       * Message validation requires that all included
691
       * options have a length that is greater than zero.
692
       */
693
11.3k
      icmp6stat.icp6s_nd_badopt++;
694
11.3k
      bzero(ndopts, sizeof(*ndopts));
695
11.3k
      return -1;
696
11.3k
    }
697
698
22.6k
    if (nd_opt == NULL) {
699
0
      goto skip1;
700
0
    }
701
702
22.6k
    switch (nd_opt->nd_opt_type) {
703
18.9k
    case ND_OPT_SOURCE_LINKADDR:
704
21.8k
    case ND_OPT_TARGET_LINKADDR:
705
22.0k
    case ND_OPT_MTU:
706
22.1k
    case ND_OPT_REDIRECTED_HEADER:
707
22.2k
    case ND_OPT_NONCE:
708
22.2k
      if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
709
13.3k
        nd6log(error,
710
13.3k
            "duplicated ND6 option found (type=%d)\n",
711
13.3k
            nd_opt->nd_opt_type);
712
        /* XXX bark? */
713
13.3k
      } else {
714
8.96k
        ndopts->nd_opt_array[nd_opt->nd_opt_type] =
715
8.96k
            nd_opt;
716
8.96k
      }
717
22.2k
      break;
718
54
    case ND_OPT_PREFIX_INFORMATION:
719
54
      if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
720
20
        ndopts->nd_opt_array[nd_opt->nd_opt_type] =
721
20
            nd_opt;
722
20
      }
723
54
      ndopts->nd_opts_pi_end =
724
54
          (struct nd_opt_prefix_info *)nd_opt;
725
54
      break;
726
21
    case ND_OPT_RDNSS:
727
72
    case ND_OPT_DNSSL:
728
135
    case ND_OPT_CAPTIVE_PORTAL:
729
      /* ignore */
730
135
      break;
731
40
    case ND_OPT_ROUTE_INFO:
732
40
      if (nd6_process_rti) {
733
40
        if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
734
28
          ndopts->nd_opt_array[nd_opt->nd_opt_type]
735
28
                  = nd_opt;
736
28
        }
737
40
        ndopts->nd_opts_rti_end =
738
40
            (struct nd_opt_route_info *)nd_opt;
739
40
        break;
740
40
      }
741
40
      OS_FALLTHROUGH;
742
142
    default:
743
      /*
744
       * Unknown options must be silently ignored,
745
       * to accomodate future extension to the protocol.
746
       */
747
142
      nd6log(debug,
748
22.6k
          "nd6_options: unsupported option %d - "
749
22.6k
          "option ignored\n", nd_opt->nd_opt_type);
750
22.6k
    }
751
752
22.6k
skip1:
753
22.6k
    i++;
754
22.6k
    if (i > nd6_maxndopt) {
755
40
      icmp6stat.icp6s_nd_toomanyopt++;
756
40
      nd6log(info, "too many loop in nd opt\n");
757
40
      break;
758
40
    }
759
760
22.6k
    if (ndopts->nd_opts_done) {
761
8.66k
      break;
762
8.66k
    }
763
22.6k
  }
764
765
8.70k
  return 0;
766
20.0k
}
767
768
struct nd6svc_arg {
769
  int draining;
770
  uint32_t killed;
771
  uint32_t aging_lazy;
772
  uint32_t aging;
773
  uint32_t sticky;
774
  uint32_t found;
775
};
776
777
778
static void
779
nd6_service_neighbor_cache(struct nd6svc_arg *ap, uint64_t timenow)
780
408k
{
781
408k
  struct llinfo_nd6 *ln;
782
408k
  struct ifnet *ifp = NULL;
783
408k
  boolean_t send_nc_failure_kev = FALSE;
784
408k
  struct radix_node_head  *rnh = rt_tables[AF_INET6];
785
786
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
787
408k
again:
788
  /*
789
   * send_nc_failure_kev gets set when default router's IPv6 address
790
   * can't be resolved.
791
   * That can happen either:
792
   * 1. When the entry has resolved once but can't be
793
   * resolved later and the neighbor cache entry for gateway is deleted
794
   * after max probe attempts.
795
   *
796
   * 2. When the entry is in ND6_LLINFO_INCOMPLETE but can not be resolved
797
   * after max neighbor address resolution attempts.
798
   *
799
   * Both set send_nc_failure_kev to true. ifp is also set to the previous
800
   * neighbor cache entry's route's ifp.
801
   * Once we are done sending the notification, set send_nc_failure_kev
802
   * to false to stop sending false notifications for non default router
803
   * neighbors.
804
   *
805
   * We may to send more information like Gateway's IP that could not be
806
   * resolved, however right now we do not install more than one default
807
   * route per interface in the routing table.
808
   */
809
408k
  if (send_nc_failure_kev && ifp != NULL &&
810
408k
      ifp->if_addrlen == IF_LLREACH_MAXLEN) {
811
0
    struct kev_msg ev_msg;
812
0
    struct kev_nd6_ndfailure nd6_ndfailure;
813
0
    bzero(&ev_msg, sizeof(ev_msg));
814
0
    bzero(&nd6_ndfailure, sizeof(nd6_ndfailure));
815
0
    ev_msg.vendor_code      = KEV_VENDOR_APPLE;
816
0
    ev_msg.kev_class        = KEV_NETWORK_CLASS;
817
0
    ev_msg.kev_subclass     = KEV_ND6_SUBCLASS;
818
0
    ev_msg.event_code       = KEV_ND6_NDFAILURE;
819
820
0
    nd6_ndfailure.link_data.if_family = ifp->if_family;
821
0
    nd6_ndfailure.link_data.if_unit = ifp->if_unit;
822
0
    strlcpy(nd6_ndfailure.link_data.if_name,
823
0
        ifp->if_name,
824
0
        sizeof(nd6_ndfailure.link_data.if_name));
825
0
    ev_msg.dv[0].data_ptr = &nd6_ndfailure;
826
0
    ev_msg.dv[0].data_length =
827
0
        sizeof(nd6_ndfailure);
828
0
    dlil_post_complete_msg(NULL, &ev_msg);
829
0
  }
830
831
408k
  send_nc_failure_kev = FALSE;
832
408k
  ifp = NULL;
833
  /*
834
   * The global list llinfo_nd6 is modified by nd6_request() and is
835
   * therefore protected by rnh_lock.  For obvious reasons, we cannot
836
   * hold rnh_lock across calls that might lead to code paths which
837
   * attempt to acquire rnh_lock, else we deadlock.  Hence for such
838
   * cases we drop rt_lock and rnh_lock, make the calls, and repeat the
839
   * loop.  To ensure that we don't process the same entry more than
840
   * once in a single timeout, we mark the "already-seen" entries with
841
   * ND6_LNF_TIMER_SKIP flag.  At the end of the loop, we do a second
842
   * pass thru the entries and clear the flag so they can be processed
843
   * during the next timeout.
844
   */
845
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
846
847
408k
  ln = llinfo_nd6.ln_next;
848
8.23M
  while (ln != NULL && ln != &llinfo_nd6) {
849
7.82M
    struct rtentry *rt;
850
7.82M
    struct sockaddr_in6 *dst;
851
7.82M
    struct llinfo_nd6 *next;
852
7.82M
    u_int32_t retrans, flags;
853
7.82M
    struct nd_ifinfo *ndi = NULL;
854
7.82M
    boolean_t is_router = FALSE;
855
856
    /* ln_next/prev/rt is protected by rnh_lock */
857
7.82M
    next = ln->ln_next;
858
7.82M
    rt = ln->ln_rt;
859
7.82M
    RT_LOCK(rt);
860
861
    /* We've seen this already; skip it */
862
7.82M
    if (ln->ln_flags & ND6_LNF_TIMER_SKIP) {
863
0
      RT_UNLOCK(rt);
864
0
      ln = next;
865
0
      continue;
866
0
    }
867
7.82M
    ap->found++;
868
869
    /* rt->rt_ifp should never be NULL */
870
7.82M
    if ((ifp = rt->rt_ifp) == NULL) {
871
0
      panic("%s: ln(%p) rt(%p) rt_ifp == NULL", __func__,
872
0
          ln, rt);
873
      /* NOTREACHED */
874
0
    }
875
876
    /* rt_llinfo must always be equal to ln */
877
7.82M
    if ((struct llinfo_nd6 *)rt->rt_llinfo != ln) {
878
0
      panic("%s: rt_llinfo(%p) is not equal to ln(%p)",
879
0
          __func__, rt->rt_llinfo, ln);
880
      /* NOTREACHED */
881
0
    }
882
883
    /* rt_key should never be NULL */
884
7.82M
    dst = SIN6(rt_key(rt));
885
7.82M
    if (dst == NULL) {
886
0
      panic("%s: rt(%p) key is NULL ln(%p)", __func__,
887
0
          rt, ln);
888
      /* NOTREACHED */
889
0
    }
890
891
    /* Set the flag in case we jump to "again" */
892
7.82M
    ln->ln_flags |= ND6_LNF_TIMER_SKIP;
893
894
7.82M
    if (ln->ln_expire == 0 || (rt->rt_flags & RTF_STATIC)) {
895
3.47M
      ap->sticky++;
896
4.34M
    } else if (ap->draining && (rt->rt_refcnt == 0)) {
897
      /*
898
       * If we are draining, immediately purge non-static
899
       * entries without oustanding route refcnt.
900
       */
901
0
      if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
902
0
        ND6_CACHE_STATE_TRANSITION(ln, (short)ND6_LLINFO_STALE);
903
0
      } else {
904
0
        ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_PURGE);
905
0
      }
906
0
      ln_setexpire(ln, timenow);
907
0
    }
908
909
    /*
910
     * If the entry has not expired, skip it.  Take note on the
911
     * state, as entries that are in the STALE state are simply
912
     * waiting to be garbage collected, in which case we can
913
     * relax the callout scheduling (use nd6_prune_lazy).
914
     */
915
7.82M
    if (ln->ln_expire > timenow) {
916
4.34M
      switch (ln->ln_state) {
917
4.06M
      case ND6_LLINFO_STALE:
918
4.06M
        ap->aging_lazy++;
919
4.06M
        break;
920
287k
      default:
921
287k
        ap->aging++;
922
287k
        break;
923
4.34M
      }
924
4.34M
      RT_UNLOCK(rt);
925
4.34M
      ln = next;
926
4.34M
      continue;
927
4.34M
    }
928
929
3.47M
    ndi = ND_IFINFO(ifp);
930
3.47M
    VERIFY(ndi->initialized);
931
0
    retrans = ndi->retrans;
932
3.47M
    flags = ndi->flags;
933
934
3.47M
    RT_LOCK_ASSERT_HELD(rt);
935
3.47M
    is_router = (rt->rt_flags & RTF_ROUTER) ? TRUE : FALSE;
936
937
3.47M
    switch (ln->ln_state) {
938
0
    case ND6_LLINFO_INCOMPLETE:
939
0
      if (ln->ln_asked < nd6_mmaxtries) {
940
0
        struct ifnet *exclifp = ln->ln_exclifp;
941
0
        ln->ln_asked++;
942
0
        ln_setexpire(ln, timenow + retrans / 1000);
943
0
        RT_ADDREF_LOCKED(rt);
944
0
        RT_UNLOCK(rt);
945
0
        lck_mtx_unlock(rnh_lock);
946
0
        if (ip6_forwarding) {
947
0
          nd6_prproxy_ns_output(ifp, exclifp,
948
0
              NULL, &dst->sin6_addr, ln);
949
0
        } else {
950
0
          nd6_ns_output(ifp, NULL,
951
0
              &dst->sin6_addr, ln, NULL);
952
0
        }
953
0
        RT_REMREF(rt);
954
0
        ap->aging++;
955
0
        lck_mtx_lock(rnh_lock);
956
0
      } else {
957
0
        struct mbuf *m = ln->ln_hold;
958
0
        ln->ln_hold = NULL;
959
0
        send_nc_failure_kev = is_router;
960
0
        if (m != NULL) {
961
0
          RT_ADDREF_LOCKED(rt);
962
0
          RT_UNLOCK(rt);
963
0
          lck_mtx_unlock(rnh_lock);
964
965
0
          struct mbuf *mnext;
966
0
          while (m) {
967
0
            mnext = m->m_nextpkt;
968
0
            m->m_nextpkt = NULL;
969
0
            m->m_pkthdr.rcvif = ifp;
970
0
            icmp6_error_flag(m, ICMP6_DST_UNREACH,
971
0
                ICMP6_DST_UNREACH_ADDR, 0, 0);
972
0
            m = mnext;
973
0
          }
974
0
        } else {
975
0
          RT_ADDREF_LOCKED(rt);
976
0
          RT_UNLOCK(rt);
977
0
          lck_mtx_unlock(rnh_lock);
978
0
        }
979
980
        /*
981
         * Enqueue work item to invoke callback for
982
         * this route entry
983
         */
984
0
        route_event_enqueue_nwk_wq_entry(rt, NULL,
985
0
            ROUTE_LLENTRY_UNREACH, NULL, FALSE);
986
0
        nd6_free(rt);
987
0
        ap->killed++;
988
0
        lck_mtx_lock(rnh_lock);
989
        /*
990
         * nd6_free above would flush out the routing table of
991
         * any cloned routes with same next-hop.
992
         * Walk the tree anyways as there could be static routes
993
         * left.
994
         *
995
         * We also already have a reference to rt that gets freed right
996
         * after the block below executes. Don't need an extra reference
997
         * on rt here.
998
         */
999
0
        if (is_router) {
1000
0
          struct route_event rt_ev;
1001
0
          route_event_init(&rt_ev, rt, NULL, ROUTE_LLENTRY_UNREACH);
1002
0
          (void) rnh->rnh_walktree(rnh, route_event_walktree, (void *)&rt_ev);
1003
0
        }
1004
0
        rtfree_locked(rt);
1005
0
      }
1006
0
      LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1007
0
      goto again;
1008
1009
408k
    case ND6_LLINFO_REACHABLE:
1010
408k
      if (ln->ln_expire != 0) {
1011
0
        ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_STALE);
1012
0
        ln_setexpire(ln, timenow + nd6_gctimer);
1013
0
        ap->aging_lazy++;
1014
        /*
1015
         * Enqueue work item to invoke callback for
1016
         * this route entry
1017
         */
1018
0
        route_event_enqueue_nwk_wq_entry(rt, NULL,
1019
0
            ROUTE_LLENTRY_STALE, NULL, TRUE);
1020
1021
0
        RT_ADDREF_LOCKED(rt);
1022
0
        RT_UNLOCK(rt);
1023
0
        if (is_router) {
1024
0
          struct route_event rt_ev;
1025
0
          route_event_init(&rt_ev, rt, NULL, ROUTE_LLENTRY_STALE);
1026
0
          (void) rnh->rnh_walktree(rnh, route_event_walktree, (void *)&rt_ev);
1027
0
        }
1028
0
        rtfree_locked(rt);
1029
408k
      } else {
1030
408k
        RT_UNLOCK(rt);
1031
408k
      }
1032
408k
      break;
1033
1034
0
    case ND6_LLINFO_STALE:
1035
0
    case ND6_LLINFO_PURGE:
1036
      /* Garbage Collection(RFC 4861 5.3) */
1037
0
      if (ln->ln_expire != 0) {
1038
0
        RT_ADDREF_LOCKED(rt);
1039
0
        RT_UNLOCK(rt);
1040
0
        lck_mtx_unlock(rnh_lock);
1041
0
        nd6_free(rt);
1042
0
        ap->killed++;
1043
0
        lck_mtx_lock(rnh_lock);
1044
0
        rtfree_locked(rt);
1045
0
        goto again;
1046
0
      } else {
1047
0
        RT_UNLOCK(rt);
1048
0
      }
1049
0
      break;
1050
1051
0
    case ND6_LLINFO_DELAY:
1052
0
      if ((flags & ND6_IFF_PERFORMNUD) != 0) {
1053
        /* We need NUD */
1054
0
        ln->ln_asked = 1;
1055
0
        ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_PROBE);
1056
0
        ln_setexpire(ln, timenow + retrans / 1000);
1057
0
        RT_ADDREF_LOCKED(rt);
1058
0
        RT_UNLOCK(rt);
1059
0
        lck_mtx_unlock(rnh_lock);
1060
0
        nd6_ns_output(ifp, &dst->sin6_addr,
1061
0
            &dst->sin6_addr, ln, NULL);
1062
0
        RT_REMREF(rt);
1063
0
        ap->aging++;
1064
0
        lck_mtx_lock(rnh_lock);
1065
0
        goto again;
1066
0
      }
1067
0
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_STALE);         /* XXX */
1068
0
      ln_setexpire(ln, timenow + nd6_gctimer);
1069
0
      RT_UNLOCK(rt);
1070
0
      ap->aging_lazy++;
1071
0
      break;
1072
1073
0
    case ND6_LLINFO_PROBE:
1074
0
      if (ln->ln_asked < nd6_umaxtries) {
1075
0
        ln->ln_asked++;
1076
0
        ln_setexpire(ln, timenow + retrans / 1000);
1077
0
        RT_ADDREF_LOCKED(rt);
1078
0
        RT_UNLOCK(rt);
1079
0
        lck_mtx_unlock(rnh_lock);
1080
0
        nd6_ns_output(ifp, &dst->sin6_addr,
1081
0
            &dst->sin6_addr, ln, NULL);
1082
0
        RT_REMREF(rt);
1083
0
        ap->aging++;
1084
0
        lck_mtx_lock(rnh_lock);
1085
0
      } else {
1086
0
        is_router = (rt->rt_flags & RTF_ROUTER) ? TRUE : FALSE;
1087
0
        send_nc_failure_kev = is_router;
1088
0
        RT_ADDREF_LOCKED(rt);
1089
0
        RT_UNLOCK(rt);
1090
0
        lck_mtx_unlock(rnh_lock);
1091
0
        nd6_free(rt);
1092
0
        ap->killed++;
1093
1094
        /*
1095
         * Enqueue work item to invoke callback for
1096
         * this route entry
1097
         */
1098
0
        route_event_enqueue_nwk_wq_entry(rt, NULL,
1099
0
            ROUTE_LLENTRY_UNREACH, NULL, FALSE);
1100
1101
0
        lck_mtx_lock(rnh_lock);
1102
        /*
1103
         * nd6_free above would flush out the routing table of
1104
         * any cloned routes with same next-hop.
1105
         * Walk the tree anyways as there could be static routes
1106
         * left.
1107
         *
1108
         * We also already have a reference to rt that gets freed right
1109
         * after the block below executes. Don't need an extra reference
1110
         * on rt here.
1111
         */
1112
0
        if (is_router) {
1113
0
          struct route_event rt_ev;
1114
0
          route_event_init(&rt_ev, rt, NULL, ROUTE_LLENTRY_UNREACH);
1115
0
          (void) rnh->rnh_walktree(rnh,
1116
0
              route_event_walktree, (void *)&rt_ev);
1117
0
        }
1118
0
        rtfree_locked(rt);
1119
0
      }
1120
0
      LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1121
0
      goto again;
1122
1123
3.06M
    default:
1124
3.06M
      RT_UNLOCK(rt);
1125
3.06M
      break;
1126
3.47M
    }
1127
3.47M
    ln = next;
1128
3.47M
  }
1129
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1130
1131
  /* Now clear the flag from all entries */
1132
408k
  ln = llinfo_nd6.ln_next;
1133
8.23M
  while (ln != NULL && ln != &llinfo_nd6) {
1134
7.82M
    struct rtentry *rt = ln->ln_rt;
1135
7.82M
    struct llinfo_nd6 *next = ln->ln_next;
1136
1137
7.82M
    RT_LOCK_SPIN(rt);
1138
7.82M
    if (ln->ln_flags & ND6_LNF_TIMER_SKIP) {
1139
7.82M
      ln->ln_flags &= ~ND6_LNF_TIMER_SKIP;
1140
7.82M
    }
1141
7.82M
    RT_UNLOCK(rt);
1142
7.82M
    ln = next;
1143
7.82M
  }
1144
408k
}
1145
1146
static void
1147
nd6_service_expired_default_router(struct nd6svc_arg *ap, uint64_t timenow)
1148
408k
{
1149
408k
  struct nd_defrouter *dr = NULL;
1150
408k
  struct nd_defrouter *ndr = NULL;
1151
408k
  struct nd_drhead nd_defrouter_tmp;
1152
  /* expire default router list */
1153
408k
  TAILQ_INIT(&nd_defrouter_tmp);
1154
1155
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1156
408k
  lck_mtx_lock(nd6_mutex);
1157
1158
408k
  TAILQ_FOREACH_SAFE(dr, &nd_defrouter_list, dr_entry, ndr) {
1159
0
    ap->found++;
1160
0
    if (dr->expire != 0 && dr->expire < timenow) {
1161
0
      VERIFY(dr->ifp != NULL);
1162
0
      in6_ifstat_inc(dr->ifp, ifs6_defrtr_expiry_cnt);
1163
0
      if ((dr->stateflags & NDDRF_INELIGIBLE) == 0) {
1164
0
        in6_event_enqueue_nwk_wq_entry(IN6_NDP_RTR_EXPIRY, dr->ifp,
1165
0
            &dr->rtaddr, dr->rtlifetime);
1166
0
      }
1167
0
      if (dr->ifp != NULL &&
1168
0
          dr->ifp->if_type == IFT_CELLULAR) {
1169
        /*
1170
         * Some buggy cellular gateways may not send
1171
         * periodic router advertisements.
1172
         * Or they may send it with router lifetime
1173
         * value that is less than the configured Max and Min
1174
         * Router Advertisement interval.
1175
         * To top that an idle device may not wake up
1176
         * when periodic RA is received on cellular
1177
         * interface.
1178
         * We could send RS on every wake but RFC
1179
         * 4861 precludes that.
1180
         * The addresses are of infinite lifetimes
1181
         * and are tied to the lifetime of the bearer,
1182
         * so keeping the addresses and just getting rid of
1183
         * the router does not help us anyways.
1184
         * If there's network renumbering, a lifetime with
1185
         * value 0 would remove the default router.
1186
         * Also it will get deleted as part of purge when
1187
         * the PDP context is torn down and configured again.
1188
         * For that reason, do not expire the default router
1189
         * learned on cellular interface. Ever.
1190
         */
1191
0
        dr->expire += dr->rtlifetime;
1192
0
        nd6log2(debug,
1193
0
            "%s: Refreshing expired default router entry "
1194
0
            "%s for interface %s\n", __func__,
1195
0
            ip6_sprintf(&dr->rtaddr), if_name(dr->ifp));
1196
0
      } else {
1197
0
        ap->killed++;
1198
        /*
1199
         * Remove the entry from default router list
1200
         * and add it to the temp list.
1201
         * nd_defrouter_tmp will be a local temporary
1202
         * list as no one else can get the same
1203
         * removed entry once it is removed from default
1204
         * router list.
1205
         * Remove the reference after calling defrtrlist_del
1206
         */
1207
0
        TAILQ_REMOVE(&nd_defrouter_list, dr, dr_entry);
1208
0
        TAILQ_INSERT_TAIL(&nd_defrouter_tmp, dr, dr_entry);
1209
0
      }
1210
0
    } else {
1211
0
      if (dr->expire == 0 || (dr->stateflags & NDDRF_STATIC)) {
1212
0
        ap->sticky++;
1213
0
      } else {
1214
0
        ap->aging_lazy++;
1215
0
      }
1216
0
    }
1217
0
  }
1218
1219
  /*
1220
   * Keep the following  separate from the above
1221
   * iteration of nd_defrouter because it's not safe
1222
   * to call defrtrlist_del while iterating global default
1223
   * router list. Global list has to be traversed
1224
   * while holding nd6_mutex throughout.
1225
   *
1226
   * The following call to defrtrlist_del should be
1227
   * safe as we are iterating a local list of
1228
   * default routers.
1229
   */
1230
408k
  TAILQ_FOREACH_SAFE(dr, &nd_defrouter_tmp, dr_entry, ndr) {
1231
0
    TAILQ_REMOVE(&nd_defrouter_tmp, dr, dr_entry);
1232
0
    defrtrlist_del(dr, NULL);
1233
0
    NDDR_REMREF(dr);        /* remove list reference */
1234
0
  }
1235
1236
  /* XXX TBD: Also iterate through RTI router lists */
1237
  /*
1238
   * Also check if default router selection needs to be triggered
1239
   * for default interface, to avoid an issue with co-existence of
1240
   * static un-scoped default route configuration and default router
1241
   * discovery/selection.
1242
   */
1243
408k
  if (trigger_v6_defrtr_select) {
1244
0
    defrouter_select(NULL, NULL);
1245
0
    trigger_v6_defrtr_select = FALSE;
1246
0
  }
1247
408k
  lck_mtx_unlock(nd6_mutex);
1248
408k
}
1249
1250
static void
1251
nd6_service_expired_route_info(struct nd6svc_arg *ap, uint64_t timenow)
1252
408k
{
1253
408k
  struct nd_route_info *rti = NULL;
1254
408k
  struct nd_route_info *rti_next = NULL;
1255
1256
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1257
408k
  lck_mtx_lock(nd6_mutex);
1258
408k
  nd6_rti_list_wait(__func__);
1259
1260
408k
  TAILQ_FOREACH_SAFE(rti, &nd_rti_list, nd_rti_entry, rti_next) {
1261
0
    struct nd_defrouter *dr = NULL;
1262
0
    struct nd_defrouter *ndr = NULL;
1263
0
    struct nd_route_info rti_tmp = {};
1264
1265
0
    rti_tmp.nd_rti_prefix = rti->nd_rti_prefix;
1266
0
    rti_tmp.nd_rti_prefixlen = rti->nd_rti_prefixlen;
1267
0
    TAILQ_INIT(&rti_tmp.nd_rti_router_list);
1268
1269
0
    TAILQ_FOREACH_SAFE(dr, &rti->nd_rti_router_list, dr_entry, ndr) {
1270
0
      ap->found++;
1271
0
      if (dr->expire != 0 && dr->expire < timenow) {
1272
0
        VERIFY(dr->ifp != NULL);
1273
0
        if (dr->ifp != NULL &&
1274
0
            dr->ifp->if_type == IFT_CELLULAR) {
1275
          /*
1276
           * Don't expire these routes over cellular.
1277
           * XXX Should we change this for non default routes?
1278
           */
1279
0
          dr->expire += dr->rtlifetime;
1280
0
          nd6log2(debug,
1281
0
              "%s: Refreshing expired default router entry "
1282
0
              "%s for interface %s\n", __func__,
1283
0
              ip6_sprintf(&dr->rtaddr), if_name(dr->ifp));
1284
0
        } else {
1285
0
          ap->killed++;
1286
          /*
1287
           * Remove the entry from rti entry's router list
1288
           * and add it to the temp list.
1289
           * Remove the reference after calling defrtrlist_del
1290
           */
1291
0
          TAILQ_REMOVE(&rti->nd_rti_router_list, dr, dr_entry);
1292
0
          TAILQ_INSERT_TAIL(&rti_tmp.nd_rti_router_list, dr, dr_entry);
1293
0
        }
1294
0
      } else {
1295
0
        if (dr->expire == 0 || (dr->stateflags & NDDRF_STATIC)) {
1296
0
          ap->sticky++;
1297
0
        } else {
1298
0
          ap->aging_lazy++;
1299
0
        }
1300
0
      }
1301
0
    }
1302
1303
    /*
1304
     * Keep the following  separate from the above
1305
     * iteration of nd_defrouter because it's not safe
1306
     * to call defrtrlist_del while iterating global default
1307
     * router list. Global list has to be traversed
1308
     * while holding nd6_mutex throughout.
1309
     *
1310
     * The following call to defrtrlist_del should be
1311
     * safe as we are iterating a local list of
1312
     * default routers.
1313
     */
1314
0
    TAILQ_FOREACH_SAFE(dr, &rti_tmp.nd_rti_router_list, dr_entry, ndr) {
1315
0
      TAILQ_REMOVE(&rti_tmp.nd_rti_router_list, dr, dr_entry);
1316
0
      defrtrlist_del(dr, &rti->nd_rti_router_list);
1317
0
      NDDR_REMREF(dr);        /* remove list reference */
1318
0
    }
1319
1320
    /*
1321
     * The above may have removed an entry from default router list.
1322
     * If it did and the list is now empty, remove the rti as well.
1323
     */
1324
0
    if (TAILQ_EMPTY(&rti->nd_rti_router_list)) {
1325
0
      TAILQ_REMOVE(&nd_rti_list, rti, nd_rti_entry);
1326
0
      ndrti_free(rti);
1327
0
    }
1328
0
  }
1329
1330
408k
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1331
408k
  nd6_rti_list_signal_done();
1332
408k
  lck_mtx_unlock(nd6_mutex);
1333
408k
}
1334
1335
1336
/*
1337
 * @function nd6_handle_duplicated_ip6_addr
1338
 *
1339
 * @brief
1340
 * Handle a duplicated IPv6 secured non-termporary address
1341
 *
1342
 * @discussion
1343
 * If the collision count hasn't been exceeded, removes the old
1344
 * conflicting IPv6 address, increments the collision count,
1345
 * and allocates a new address.
1346
 *
1347
 * Returns TRUE if the old address was removed, and the locks
1348
 * (in6_ifaddr_rwlock, ia6->ia_ifa) were unlocked.
1349
 */
1350
static boolean_t
1351
nd6_handle_duplicated_ip6_addr(struct in6_ifaddr *ia6)
1352
0
{
1353
0
  uint8_t collision_count;
1354
0
  int error = 0;
1355
0
  struct in6_ifaddr *new_ia6;
1356
0
  struct nd_prefix *pr;
1357
0
  struct ifnet *ifp;
1358
1359
0
  LCK_RW_ASSERT(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1360
0
  IFA_LOCK_ASSERT_HELD(&ia6->ia_ifa);
1361
1362
  /* don't retry too many times */
1363
0
  collision_count = ia6->ia6_cga_collision_count;
1364
0
  if (collision_count >= ip6_cga_conflict_retries) {
1365
0
    return FALSE;
1366
0
  }
1367
1368
  /* need the prefix to allocate a new address */
1369
0
  pr = ia6->ia6_ndpr;
1370
0
  if (pr == NULL) {
1371
0
    return FALSE;
1372
0
  }
1373
0
  NDPR_ADDREF(pr);
1374
0
  ifp = pr->ndpr_ifp;
1375
0
  log(LOG_DEBUG,
1376
0
      "%s: %s duplicated (collision count %d)\n",
1377
0
      ifp->if_xname, ip6_sprintf(&ia6->ia_addr.sin6_addr),
1378
0
      collision_count);
1379
1380
  /* remove the old address */
1381
0
  IFA_UNLOCK(&ia6->ia_ifa);
1382
0
  lck_rw_done(&in6_ifaddr_rwlock);
1383
0
  in6_purgeaddr(&ia6->ia_ifa);
1384
1385
  /* allocate a new address with new collision count */
1386
0
  collision_count++;
1387
0
  new_ia6 = in6_pfx_newpersistaddr(pr, 1, &error, FALSE, collision_count);
1388
0
  if (new_ia6 != NULL) {
1389
0
    log(LOG_DEBUG,
1390
0
        "%s: %s new (collision count %d)\n",
1391
0
        ifp->if_xname, ip6_sprintf(&new_ia6->ia_addr.sin6_addr),
1392
0
        collision_count);
1393
0
    IFA_LOCK(&new_ia6->ia_ifa);
1394
0
    NDPR_LOCK(pr);
1395
0
    new_ia6->ia6_ndpr = pr;
1396
0
    NDPR_ADDREF(pr); /* for addr reference */
1397
0
    pr->ndpr_addrcnt++;
1398
0
    VERIFY(pr->ndpr_addrcnt != 0);
1399
0
    NDPR_UNLOCK(pr);
1400
0
    IFA_UNLOCK(&new_ia6->ia_ifa);
1401
0
    IFA_REMREF(&new_ia6->ia_ifa);
1402
0
  } else {
1403
0
    log(LOG_ERR, "%s: in6_pfx_newpersistaddr failed %d\n",
1404
0
        __func__, error);
1405
0
  }
1406
1407
  /* release extra prefix reference */
1408
0
  NDPR_REMREF(pr);
1409
0
  return TRUE;
1410
0
}
1411
1412
static boolean_t
1413
secured_address_is_duplicated(int flags)
1414
408k
{
1415
408k
#define _IN6_IFF_DUPLICATED_AUTOCONF_SECURED                            \
1416
817k
  (IN6_IFF_DUPLICATED | IN6_IFF_AUTOCONF | IN6_IFF_SECURED)
1417
408k
  return (flags & _IN6_IFF_DUPLICATED_AUTOCONF_SECURED) ==
1418
408k
         _IN6_IFF_DUPLICATED_AUTOCONF_SECURED;
1419
408k
}
1420
1421
static void
1422
nd6_service_ip6_addr(struct nd6svc_arg *ap, uint64_t timenow)
1423
408k
{
1424
408k
  struct in6_ifaddr *ia6 = NULL;
1425
408k
  struct in6_ifaddr *nia6 = NULL;
1426
  /*
1427
   * expire interface addresses.
1428
   * in the past the loop was inside prefix expiry processing.
1429
   * However, from a stricter spec-conformance standpoint, we should
1430
   * rather separate address lifetimes and prefix lifetimes.
1431
   */
1432
1433
408k
addrloop:
1434
408k
  lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
1435
1436
408k
  TAILQ_FOREACH_SAFE(ia6, &in6_ifaddrhead, ia6_link, nia6) {
1437
408k
    int oldflags = ia6->ia6_flags;
1438
408k
    ap->found++;
1439
408k
    IFA_LOCK(&ia6->ia_ifa);
1440
    /*
1441
     * Extra reference for ourselves; it's no-op if
1442
     * we don't have to regenerate temporary address,
1443
     * otherwise it protects the address from going
1444
     * away since we drop in6_ifaddr_rwlock below.
1445
     */
1446
408k
    IFA_ADDREF_LOCKED(&ia6->ia_ifa);
1447
1448
    /* check for duplicated secured address */
1449
408k
    if (secured_address_is_duplicated(ia6->ia6_flags) &&
1450
408k
        nd6_handle_duplicated_ip6_addr(ia6)) {
1451
      /*
1452
       * nd6_handle_duplicated_ip6_addr() unlocked
1453
       * (in6_ifaddr_rwlock, ia6->ia_ifa) already.
1454
       * Still need to release extra reference on
1455
       * ia6->ia_ifa taken above.
1456
       */
1457
0
      IFA_REMREF(&ia6->ia_ifa);
1458
0
      goto addrloop;
1459
0
    }
1460
1461
    /* check address lifetime */
1462
408k
    if (IFA6_IS_INVALID(ia6, timenow)) {
1463
      /*
1464
       * If the expiring address is temporary, try
1465
       * regenerating a new one.  This would be useful when
1466
       * we suspended a laptop PC, then turned it on after a
1467
       * period that could invalidate all temporary
1468
       * addresses.  Although we may have to restart the
1469
       * loop (see below), it must be after purging the
1470
       * address.  Otherwise, we'd see an infinite loop of
1471
       * regeneration.
1472
       */
1473
0
      if (ip6_use_tempaddr &&
1474
0
          (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
1475
        /*
1476
         * NOTE: We have to drop the lock here
1477
         * because regen_tmpaddr() eventually calls
1478
         * in6_update_ifa(), which must take the lock
1479
         * and would otherwise cause a hang.  This is
1480
         * safe because the goto addrloop leads to a
1481
         * re-evaluation of the in6_ifaddrs list
1482
         */
1483
0
        IFA_UNLOCK(&ia6->ia_ifa);
1484
0
        lck_rw_done(&in6_ifaddr_rwlock);
1485
0
        (void) regen_tmpaddr(ia6);
1486
0
      } else {
1487
0
        IFA_UNLOCK(&ia6->ia_ifa);
1488
0
        lck_rw_done(&in6_ifaddr_rwlock);
1489
0
      }
1490
1491
      /*
1492
       * Purging the address would have caused
1493
       * in6_ifaddr_rwlock to be dropped and reacquired;
1494
       * therefore search again from the beginning
1495
       * of in6_ifaddrs list.
1496
       */
1497
0
      in6_purgeaddr(&ia6->ia_ifa);
1498
0
      ap->killed++;
1499
1500
0
      if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) == 0) {
1501
0
        in6_ifstat_inc(ia6->ia_ifa.ifa_ifp, ifs6_addr_expiry_cnt);
1502
0
        in6_event_enqueue_nwk_wq_entry(IN6_NDP_ADDR_EXPIRY,
1503
0
            ia6->ia_ifa.ifa_ifp, &ia6->ia_addr.sin6_addr,
1504
0
            0);
1505
0
      }
1506
      /* Release extra reference taken above */
1507
0
      IFA_REMREF(&ia6->ia_ifa);
1508
0
      goto addrloop;
1509
0
    }
1510
    /*
1511
     * The lazy timer runs every nd6_prune_lazy seconds with at
1512
     * most "2 * nd6_prune_lazy - 1" leeway. We consider the worst
1513
     * case here and make sure we schedule the regular timer if an
1514
     * interface address is about to expire.
1515
     */
1516
408k
    if (IFA6_IS_INVALID(ia6, timenow + 3 * nd6_prune_lazy)) {
1517
0
      ap->aging++;
1518
408k
    } else {
1519
408k
      ap->aging_lazy++;
1520
408k
    }
1521
408k
    IFA_LOCK_ASSERT_HELD(&ia6->ia_ifa);
1522
408k
    if (IFA6_IS_DEPRECATED(ia6, timenow)) {
1523
0
      ia6->ia6_flags |= IN6_IFF_DEPRECATED;
1524
1525
0
      if ((oldflags & IN6_IFF_DEPRECATED) == 0) {
1526
        /*
1527
         * Only enqueue the Deprecated event when the address just
1528
         * becomes deprecated.
1529
         * Keep it limited to the stable address as it is common for
1530
         * older temporary addresses to get deprecated while we generate
1531
         * new ones.
1532
         */
1533
0
        if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) == 0) {
1534
0
          in6_event_enqueue_nwk_wq_entry(IN6_ADDR_MARKED_DEPRECATED,
1535
0
              ia6->ia_ifa.ifa_ifp, &ia6->ia_addr.sin6_addr,
1536
0
              0);
1537
0
        }
1538
0
      }
1539
      /*
1540
       * If a temporary address has just become deprecated,
1541
       * regenerate a new one if possible.
1542
       */
1543
0
      if (ip6_use_tempaddr &&
1544
0
          (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
1545
0
          (oldflags & IN6_IFF_DEPRECATED) == 0) {
1546
        /* see NOTE above */
1547
0
        IFA_UNLOCK(&ia6->ia_ifa);
1548
0
        lck_rw_done(&in6_ifaddr_rwlock);
1549
0
        if (regen_tmpaddr(ia6) == 0) {
1550
          /*
1551
           * A new temporary address is
1552
           * generated.
1553
           * XXX: this means the address chain
1554
           * has changed while we are still in
1555
           * the loop.  Although the change
1556
           * would not cause disaster (because
1557
           * it's not a deletion, but an
1558
           * addition,) we'd rather restart the
1559
           * loop just for safety.  Or does this
1560
           * significantly reduce performance??
1561
           */
1562
          /* Release extra reference */
1563
0
          IFA_REMREF(&ia6->ia_ifa);
1564
0
          goto addrloop;
1565
0
        }
1566
0
        lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
1567
0
      } else {
1568
0
        IFA_UNLOCK(&ia6->ia_ifa);
1569
0
      }
1570
408k
    } else {
1571
      /*
1572
       * A new RA might have made a deprecated address
1573
       * preferred.
1574
       */
1575
408k
      ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
1576
408k
      IFA_UNLOCK(&ia6->ia_ifa);
1577
408k
    }
1578
408k
    LCK_RW_ASSERT(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1579
    /* Release extra reference taken above */
1580
408k
    IFA_REMREF(&ia6->ia_ifa);
1581
408k
  }
1582
408k
  lck_rw_done(&in6_ifaddr_rwlock);
1583
408k
}
1584
1585
static void
1586
nd6_service_expired_prefix(struct nd6svc_arg *ap, uint64_t timenow)
1587
408k
{
1588
408k
  struct nd_prefix *pr = NULL;
1589
1590
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1591
408k
  lck_mtx_lock(nd6_mutex);
1592
  /* expire prefix list */
1593
408k
  pr = nd_prefix.lh_first;
1594
408k
  while (pr != NULL) {
1595
0
    ap->found++;
1596
    /*
1597
     * check prefix lifetime.
1598
     * since pltime is just for autoconf, pltime processing for
1599
     * prefix is not necessary.
1600
     */
1601
0
    NDPR_LOCK(pr);
1602
0
    if (pr->ndpr_stateflags & NDPRF_PROCESSED_SERVICE ||
1603
0
        pr->ndpr_stateflags & NDPRF_DEFUNCT) {
1604
0
      pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
1605
0
      NDPR_UNLOCK(pr);
1606
0
      pr = pr->ndpr_next;
1607
0
      continue;
1608
0
    }
1609
0
    if (pr->ndpr_expire != 0 && pr->ndpr_expire < timenow) {
1610
      /*
1611
       * address expiration and prefix expiration are
1612
       * separate. NEVER perform in6_purgeaddr here.
1613
       */
1614
0
      pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
1615
0
      NDPR_ADDREF(pr);
1616
0
      prelist_remove(pr);
1617
0
      NDPR_UNLOCK(pr);
1618
1619
0
      in6_ifstat_inc(pr->ndpr_ifp, ifs6_pfx_expiry_cnt);
1620
0
      in6_event_enqueue_nwk_wq_entry(IN6_NDP_PFX_EXPIRY,
1621
0
          pr->ndpr_ifp, &pr->ndpr_prefix.sin6_addr,
1622
0
          0);
1623
0
      NDPR_REMREF(pr);
1624
0
      pfxlist_onlink_check();
1625
0
      pr = nd_prefix.lh_first;
1626
0
      ap->killed++;
1627
0
    } else {
1628
0
      if (pr->ndpr_expire == 0 ||
1629
0
          (pr->ndpr_stateflags & NDPRF_STATIC)) {
1630
0
        ap->sticky++;
1631
0
      } else {
1632
0
        ap->aging_lazy++;
1633
0
      }
1634
0
      pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
1635
0
      NDPR_UNLOCK(pr);
1636
0
      pr = pr->ndpr_next;
1637
0
    }
1638
0
  }
1639
408k
  LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
1640
0
    NDPR_LOCK(pr);
1641
0
    pr->ndpr_stateflags &= ~NDPRF_PROCESSED_SERVICE;
1642
0
    NDPR_UNLOCK(pr);
1643
0
  }
1644
408k
  lck_mtx_unlock(nd6_mutex);
1645
408k
}
1646
1647
1648
/*
1649
 * ND6 service routine to expire default route list and prefix list
1650
 */
1651
static void
1652
nd6_service(void *arg)
1653
408k
{
1654
408k
  struct nd6svc_arg *ap = arg;
1655
408k
  uint64_t timenow;
1656
1657
408k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1658
  /*
1659
   * Since we may drop rnh_lock and nd6_mutex below, we want
1660
   * to run this entire operation single threaded.
1661
   */
1662
408k
  while (nd6_service_busy) {
1663
0
    nd6log2(debug, "%s: %s is blocked by %d waiters\n",
1664
0
        __func__, ap->draining ? "drainer" : "timer",
1665
0
        nd6_service_waiters);
1666
0
    nd6_service_waiters++;
1667
0
    (void) msleep(nd6_service_wc, rnh_lock, (PZERO - 1),
1668
0
        __func__, NULL);
1669
0
    LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1670
0
  }
1671
1672
  /* We are busy now; tell everyone else to go away */
1673
408k
  nd6_service_busy = TRUE;
1674
408k
  net_update_uptime();
1675
408k
  timenow = net_uptime();
1676
1677
  /* Iterate and service neighbor cache entries */
1678
408k
  nd6_service_neighbor_cache(ap, timenow);
1679
1680
  /*
1681
   * There is lock ordering requirement and rnh_lock
1682
   * has to be released before acquiring nd6_mutex.
1683
   */
1684
408k
  lck_mtx_unlock(rnh_lock);
1685
1686
  /* Iterate and service expired default router */
1687
408k
  nd6_service_expired_default_router(ap, timenow);
1688
  /* Iterate and service expired route information entries */
1689
408k
  nd6_service_expired_route_info(ap, timenow);
1690
1691
  /* Iterate and service expired/duplicated IPv6 address */
1692
408k
  nd6_service_ip6_addr(ap, timenow);
1693
1694
  /* Iterate and service expired IPv6 prefixes */
1695
408k
  nd6_service_expired_prefix(ap, timenow);
1696
1697
408k
  lck_mtx_lock(rnh_lock);
1698
  /* We're done; let others enter */
1699
408k
  nd6_service_busy = FALSE;
1700
408k
  if (nd6_service_waiters > 0) {
1701
0
    nd6_service_waiters = 0;
1702
0
    wakeup(nd6_service_wc);
1703
0
  }
1704
408k
}
1705
1706
static int nd6_need_draining = 0;
1707
1708
void
1709
nd6_drain(void *arg)
1710
0
{
1711
0
#pragma unused(arg)
1712
0
  nd6log2(debug, "%s: draining ND6 entries\n", __func__);
1713
1714
0
  lck_mtx_lock(rnh_lock);
1715
0
  nd6_need_draining = 1;
1716
0
  nd6_sched_timeout(NULL, NULL);
1717
0
  lck_mtx_unlock(rnh_lock);
1718
0
}
1719
1720
/*
1721
 * We use the ``arg'' variable to decide whether or not the timer we're
1722
 * running is the fast timer. We do this to reset the nd6_fast_timer_on
1723
 * variable so that later we don't end up ignoring a ``fast timer''
1724
 * request if the 5 second timer is running (see nd6_sched_timeout).
1725
 */
1726
void
1727
nd6_timeout(void *arg)
1728
408k
{
1729
408k
  struct nd6svc_arg sarg;
1730
408k
  uint32_t buf;
1731
1732
408k
  lck_mtx_lock(rnh_lock);
1733
408k
  bzero(&sarg, sizeof(sarg));
1734
408k
  if (nd6_need_draining != 0) {
1735
0
    nd6_need_draining = 0;
1736
0
    sarg.draining = 1;
1737
0
  }
1738
408k
  nd6_service(&sarg);
1739
408k
  nd6log2(debug, "%s: found %u, aging_lazy %u, aging %u, "
1740
408k
      "sticky %u, killed %u\n", __func__, sarg.found, sarg.aging_lazy,
1741
408k
      sarg.aging, sarg.sticky, sarg.killed);
1742
  /* re-arm the timer if there's work to do */
1743
408k
  nd6_timeout_run--;
1744
  // VERIFY(nd6_timeout_run >= 0 && nd6_timeout_run < 2);
1745
408k
  if (arg == &nd6_fast_timer_on) {
1746
0
    nd6_fast_timer_on = FALSE;
1747
0
  }
1748
408k
  if (sarg.aging_lazy > 0 || sarg.aging > 0 || nd6_sched_timeout_want) {
1749
408k
    struct timeval atv, ltv, *leeway;
1750
408k
    int lazy = nd6_prune_lazy;
1751
1752
408k
    if (sarg.aging > 0 || lazy < 1) {
1753
287k
      atv.tv_usec = 0;
1754
287k
      atv.tv_sec = nd6_prune;
1755
287k
      leeway = NULL;
1756
287k
    } else {
1757
121k
      VERIFY(lazy >= 1);
1758
0
      atv.tv_usec = 0;
1759
121k
      atv.tv_sec = MAX(nd6_prune, lazy);
1760
121k
      ltv.tv_usec = 0;
1761
121k
      read_frandom(&buf, sizeof(buf));
1762
121k
      ltv.tv_sec = MAX(buf % lazy, 1) * 2;
1763
121k
      leeway = &ltv;
1764
121k
    }
1765
0
    nd6_sched_timeout(&atv, leeway);
1766
408k
  } else if (nd6_debug) {
1767
0
    nd6log2(debug, "%s: not rescheduling timer\n", __func__);
1768
0
  }
1769
0
  lck_mtx_unlock(rnh_lock);
1770
408k
}
1771
1772
void
1773
nd6_sched_timeout(struct timeval *atv, struct timeval *ltv)
1774
413k
{
1775
413k
  struct timeval tv;
1776
1777
413k
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1778
413k
  if (atv == NULL) {
1779
4.06k
    tv.tv_usec = 0;
1780
4.06k
    tv.tv_sec = MAX(nd6_prune, 1);
1781
4.06k
    atv = &tv;
1782
4.06k
    ltv = NULL;     /* ignore leeway */
1783
4.06k
  }
1784
  /* see comments on top of this file */
1785
413k
  if (nd6_timeout_run == 0) {
1786
408k
    if (ltv == NULL) {
1787
287k
      nd6log2(debug, "%s: timer scheduled in "
1788
287k
          "T+%llus.%lluu (demand %d)\n", __func__,
1789
287k
          (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1790
287k
          nd6_sched_timeout_want);
1791
287k
      nd6_fast_timer_on = TRUE;
1792
      // timeout(nd6_timeout, &nd6_fast_timer_on, tvtohz(atv));
1793
287k
    } else {
1794
121k
      nd6log2(debug, "%s: timer scheduled in "
1795
121k
          "T+%llus.%lluu with %llus.%lluu leeway "
1796
121k
          "(demand %d)\n", __func__, (uint64_t)atv->tv_sec,
1797
121k
          (uint64_t)atv->tv_usec, (uint64_t)ltv->tv_sec,
1798
121k
          (uint64_t)ltv->tv_usec, nd6_sched_timeout_want);
1799
121k
      nd6_fast_timer_on = FALSE;
1800
      // timeout_with_leeway(nd6_timeout, NULL,
1801
      //     tvtohz(atv), tvtohz(ltv));
1802
121k
    }
1803
408k
    nd6_timeout_run++;
1804
408k
    nd6_sched_timeout_want = 0;
1805
408k
  } else if (nd6_timeout_run == 1 && ltv == NULL &&
1806
4.40k
      nd6_fast_timer_on == FALSE) {
1807
342
    nd6log2(debug, "%s: fast timer scheduled in "
1808
342
        "T+%llus.%lluu (demand %d)\n", __func__,
1809
342
        (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1810
342
        nd6_sched_timeout_want);
1811
342
    nd6_fast_timer_on = TRUE;
1812
342
    nd6_sched_timeout_want = 0;
1813
342
    nd6_timeout_run++;
1814
    // timeout(nd6_timeout, &nd6_fast_timer_on, tvtohz(atv));
1815
4.06k
  } else {
1816
4.06k
    if (ltv == NULL) {
1817
4.05k
      nd6log2(debug, "%s: not scheduling timer: "
1818
4.05k
          "timers %d, fast_timer %d, T+%llus.%lluu\n",
1819
4.05k
          __func__, nd6_timeout_run, nd6_fast_timer_on,
1820
4.05k
          (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec);
1821
4.05k
    } else {
1822
11
      nd6log2(debug, "%s: not scheduling timer: "
1823
11
          "timers %d, fast_timer %d, T+%llus.%lluu "
1824
11
          "with %llus.%lluu leeway\n", __func__,
1825
11
          nd6_timeout_run, nd6_fast_timer_on,
1826
11
          (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1827
11
          (uint64_t)ltv->tv_sec, (uint64_t)ltv->tv_usec);
1828
11
    }
1829
4.06k
  }
1830
413k
}
1831
1832
/*
1833
 * ND6 router advertisement kernel notification
1834
 */
1835
void
1836
nd6_post_msg(u_int32_t code, struct nd_prefix_list *prefix_list,
1837
    u_int32_t list_length, u_int32_t mtu)
1838
0
{
1839
0
  struct kev_msg ev_msg;
1840
0
  struct kev_nd6_ra_data nd6_ra_msg_data;
1841
0
  struct nd_prefix_list *itr = prefix_list;
1842
1843
0
  bzero(&ev_msg, sizeof(struct kev_msg));
1844
0
  ev_msg.vendor_code      = KEV_VENDOR_APPLE;
1845
0
  ev_msg.kev_class        = KEV_NETWORK_CLASS;
1846
0
  ev_msg.kev_subclass     = KEV_ND6_SUBCLASS;
1847
0
  ev_msg.event_code       = code;
1848
1849
0
  bzero(&nd6_ra_msg_data, sizeof(nd6_ra_msg_data));
1850
1851
0
  if (mtu > 0 && mtu >= IPV6_MMTU) {
1852
0
    nd6_ra_msg_data.mtu = mtu;
1853
0
    nd6_ra_msg_data.flags |= KEV_ND6_DATA_VALID_MTU;
1854
0
  }
1855
1856
0
  if (list_length > 0 && prefix_list != NULL) {
1857
0
    nd6_ra_msg_data.list_length = list_length;
1858
0
    nd6_ra_msg_data.flags |= KEV_ND6_DATA_VALID_PREFIX;
1859
0
  }
1860
1861
0
  while (itr != NULL && nd6_ra_msg_data.list_index < list_length) {
1862
0
    bcopy(&itr->pr.ndpr_prefix, &nd6_ra_msg_data.prefix.prefix,
1863
0
        sizeof(nd6_ra_msg_data.prefix.prefix));
1864
0
    nd6_ra_msg_data.prefix.raflags = itr->pr.ndpr_raf;
1865
0
    nd6_ra_msg_data.prefix.prefixlen = itr->pr.ndpr_plen;
1866
0
    nd6_ra_msg_data.prefix.origin = PR_ORIG_RA;
1867
0
    nd6_ra_msg_data.prefix.vltime = itr->pr.ndpr_vltime;
1868
0
    nd6_ra_msg_data.prefix.pltime = itr->pr.ndpr_pltime;
1869
0
    nd6_ra_msg_data.prefix.expire = ndpr_getexpire(&itr->pr);
1870
0
    nd6_ra_msg_data.prefix.flags = itr->pr.ndpr_stateflags;
1871
0
    nd6_ra_msg_data.prefix.refcnt = itr->pr.ndpr_addrcnt;
1872
0
    nd6_ra_msg_data.prefix.if_index = itr->pr.ndpr_ifp->if_index;
1873
1874
    /* send the message up */
1875
0
    ev_msg.dv[0].data_ptr           = &nd6_ra_msg_data;
1876
0
    ev_msg.dv[0].data_length        = sizeof(nd6_ra_msg_data);
1877
0
    ev_msg.dv[1].data_length        = 0;
1878
0
    dlil_post_complete_msg(NULL, &ev_msg);
1879
1880
    /* clean up for the next prefix */
1881
0
    bzero(&nd6_ra_msg_data.prefix, sizeof(nd6_ra_msg_data.prefix));
1882
0
    itr = itr->next;
1883
0
    nd6_ra_msg_data.list_index++;
1884
0
  }
1885
0
}
1886
1887
/*
1888
 * Regenerate deprecated/invalidated temporary address
1889
 */
1890
static int
1891
regen_tmpaddr(struct in6_ifaddr *ia6)
1892
0
{
1893
0
  struct ifaddr *ifa;
1894
0
  struct ifnet *ifp;
1895
0
  struct in6_ifaddr *public_ifa6 = NULL;
1896
0
  uint64_t timenow = net_uptime();
1897
1898
0
  ifp = ia6->ia_ifa.ifa_ifp;
1899
0
  ifnet_lock_shared(ifp);
1900
0
  TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1901
0
    struct in6_ifaddr *it6;
1902
1903
0
    IFA_LOCK(ifa);
1904
0
    if (ifa->ifa_addr->sa_family != AF_INET6) {
1905
0
      IFA_UNLOCK(ifa);
1906
0
      continue;
1907
0
    }
1908
0
    it6 = (struct in6_ifaddr *)ifa;
1909
1910
    /* ignore no autoconf addresses. */
1911
0
    if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0) {
1912
0
      IFA_UNLOCK(ifa);
1913
0
      continue;
1914
0
    }
1915
    /* ignore autoconf addresses with different prefixes. */
1916
0
    if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr) {
1917
0
      IFA_UNLOCK(ifa);
1918
0
      continue;
1919
0
    }
1920
    /*
1921
     * Now we are looking at an autoconf address with the same
1922
     * prefix as ours.  If the address is temporary and is still
1923
     * preferred, do not create another one.  It would be rare, but
1924
     * could happen, for example, when we resume a laptop PC after
1925
     * a long period.
1926
     */
1927
0
    if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
1928
0
        !IFA6_IS_DEPRECATED(it6, timenow)) {
1929
0
      IFA_UNLOCK(ifa);
1930
0
      if (public_ifa6 != NULL) {
1931
0
        IFA_REMREF(&public_ifa6->ia_ifa);
1932
0
      }
1933
0
      public_ifa6 = NULL;
1934
0
      break;
1935
0
    }
1936
1937
    /*
1938
     * This is a public autoconf address that has the same prefix
1939
     * as ours.  If it is preferred, keep it.  We can't break the
1940
     * loop here, because there may be a still-preferred temporary
1941
     * address with the prefix.
1942
     */
1943
0
    if (!IFA6_IS_DEPRECATED(it6, timenow)) {
1944
0
      IFA_ADDREF_LOCKED(ifa); /* for public_ifa6 */
1945
0
      IFA_UNLOCK(ifa);
1946
0
      if (public_ifa6 != NULL) {
1947
0
        IFA_REMREF(&public_ifa6->ia_ifa);
1948
0
      }
1949
0
      public_ifa6 = it6;
1950
0
    } else {
1951
0
      IFA_UNLOCK(ifa);
1952
0
    }
1953
0
  }
1954
0
  ifnet_lock_done(ifp);
1955
1956
0
  if (public_ifa6 != NULL) {
1957
0
    int e;
1958
1959
0
    if ((e = in6_tmpifadd(public_ifa6, 0)) != 0) {
1960
0
      log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
1961
0
          " tmp addr,errno=%d\n", e);
1962
0
      IFA_REMREF(&public_ifa6->ia_ifa);
1963
0
      return -1;
1964
0
    }
1965
0
    IFA_REMREF(&public_ifa6->ia_ifa);
1966
0
    return 0;
1967
0
  }
1968
1969
0
  return -1;
1970
0
}
1971
1972
static void
1973
nd6_purge_interface_default_routers(struct ifnet *ifp)
1974
0
{
1975
0
  struct nd_defrouter *dr = NULL;
1976
0
  struct nd_defrouter *ndr = NULL;
1977
0
  struct nd_drhead nd_defrouter_tmp = {};
1978
1979
0
  TAILQ_INIT(&nd_defrouter_tmp);
1980
1981
0
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1982
1983
0
  TAILQ_FOREACH_SAFE(dr, &nd_defrouter_list, dr_entry, ndr) {
1984
0
    if (dr->ifp != ifp) {
1985
0
      continue;
1986
0
    }
1987
    /*
1988
     * Remove the entry from default router list
1989
     * and add it to the temp list.
1990
     * nd_defrouter_tmp will be a local temporary
1991
     * list as no one else can get the same
1992
     * removed entry once it is removed from default
1993
     * router list.
1994
     * Remove the reference after calling defrtrlist_del.
1995
     *
1996
     * The uninstalled entries have to be iterated first
1997
     * when we call defrtrlist_del.
1998
     * This is to ensure that we don't end up calling
1999
     * default router  selection when there are other
2000
     * uninstalled candidate default routers on
2001
     * the interface.
2002
     * If we don't respect that order, we may end
2003
     * up missing out on some entries.
2004
     *
2005
     * For that reason, installed ones must be inserted
2006
     * at the tail and uninstalled ones at the head
2007
     */
2008
0
    TAILQ_REMOVE(&nd_defrouter_list, dr, dr_entry);
2009
2010
0
    if (dr->stateflags & NDDRF_INSTALLED) {
2011
0
      TAILQ_INSERT_TAIL(&nd_defrouter_tmp, dr, dr_entry);
2012
0
    } else {
2013
0
      TAILQ_INSERT_HEAD(&nd_defrouter_tmp, dr, dr_entry);
2014
0
    }
2015
0
  }
2016
2017
  /*
2018
   * The following call to defrtrlist_del should be
2019
   * safe as we are iterating a local list of
2020
   * default routers.
2021
   *
2022
   * We don't really need nd6_mutex here but keeping
2023
   * it as it is to avoid changing assertios held in
2024
   * the functions in the call-path.
2025
   */
2026
0
  TAILQ_FOREACH_SAFE(dr, &nd_defrouter_tmp, dr_entry, ndr) {
2027
0
    TAILQ_REMOVE(&nd_defrouter_tmp, dr, dr_entry);
2028
0
    defrtrlist_del(dr, NULL);
2029
0
    NDDR_REMREF(dr);        /* remove list reference */
2030
0
  }
2031
0
}
2032
2033
static void
2034
nd6_purge_interface_prefixes(struct ifnet *ifp)
2035
0
{
2036
0
  boolean_t removed = FALSE;
2037
0
  struct nd_prefix *pr = NULL;
2038
0
  struct nd_prefix *npr = NULL;
2039
2040
0
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2041
2042
  /* Nuke prefix list entries toward ifp */
2043
0
  for (pr = nd_prefix.lh_first; pr; pr = npr) {
2044
0
    NDPR_LOCK(pr);
2045
0
    npr = pr->ndpr_next;
2046
0
    if (pr->ndpr_ifp == ifp &&
2047
0
        !(pr->ndpr_stateflags & NDPRF_DEFUNCT)) {
2048
      /*
2049
       * Because if_detach() does *not* release prefixes
2050
       * while purging addresses the reference count will
2051
       * still be above zero. We therefore reset it to
2052
       * make sure that the prefix really gets purged.
2053
       */
2054
0
      pr->ndpr_addrcnt = 0;
2055
2056
      /*
2057
       * Previously, pr->ndpr_addr is removed as well,
2058
       * but I strongly believe we don't have to do it.
2059
       * nd6_purge() is only called from in6_ifdetach(),
2060
       * which removes all the associated interface addresses
2061
       * by itself.
2062
       * (jinmei@kame.net 20010129)
2063
       */
2064
0
      NDPR_ADDREF(pr);
2065
0
      prelist_remove(pr);
2066
0
      NDPR_UNLOCK(pr);
2067
0
      NDPR_REMREF(pr);
2068
0
      removed = TRUE;
2069
0
      npr = nd_prefix.lh_first;
2070
0
    } else {
2071
0
      NDPR_UNLOCK(pr);
2072
0
    }
2073
0
  }
2074
0
  if (removed) {
2075
0
    pfxlist_onlink_check();
2076
0
  }
2077
0
}
2078
2079
static void
2080
nd6_router_select_rti_entries(struct ifnet *ifp)
2081
586
{
2082
586
  struct nd_route_info *rti = NULL;
2083
586
  struct nd_route_info *rti_next = NULL;
2084
2085
586
  nd6_rti_list_wait(__func__);
2086
2087
586
  TAILQ_FOREACH_SAFE(rti, &nd_rti_list, nd_rti_entry, rti_next) {
2088
0
    defrouter_select(ifp, &rti->nd_rti_router_list);
2089
0
  }
2090
2091
586
  nd6_rti_list_signal_done();
2092
586
}
2093
2094
static void
2095
nd6_purge_interface_rti_entries(struct ifnet *ifp)
2096
0
{
2097
0
  struct nd_route_info *rti = NULL;
2098
0
  struct nd_route_info *rti_next = NULL;
2099
2100
0
  nd6_rti_list_wait(__func__);
2101
2102
0
  TAILQ_FOREACH_SAFE(rti, &nd_rti_list, nd_rti_entry, rti_next) {
2103
0
    struct nd_route_info rti_tmp = {};
2104
0
    struct nd_defrouter *dr = NULL;
2105
0
    struct nd_defrouter *ndr = NULL;
2106
2107
0
    rti_tmp.nd_rti_prefix = rti->nd_rti_prefix;
2108
0
    rti_tmp.nd_rti_prefixlen = rti->nd_rti_prefixlen;
2109
0
    TAILQ_INIT(&rti_tmp.nd_rti_router_list);
2110
2111
0
    TAILQ_FOREACH_SAFE(dr, &rti->nd_rti_router_list, dr_entry, ndr) {
2112
      /*
2113
       * If ifp is provided, skip the entries that don't match.
2114
       * Else it is treated as a purge.
2115
       */
2116
0
      if (ifp != NULL && dr->ifp != ifp) {
2117
0
        continue;
2118
0
      }
2119
2120
      /*
2121
       * Remove the entry from rti's router list
2122
       * and add it to the temp list.
2123
       * Remove the reference after calling defrtrlist_del.
2124
       *
2125
       * The uninstalled entries have to be iterated first
2126
       * when we call defrtrlist_del.
2127
       * This is to ensure that we don't end up calling
2128
       * router  selection when there are other
2129
       * uninstalled candidate default routers on
2130
       * the interface.
2131
       * If we don't respect that order, we may end
2132
       * up missing out on some entries.
2133
       *
2134
       * For that reason, installed ones must be inserted
2135
       * at the tail and uninstalled ones at the head
2136
       */
2137
2138
0
      TAILQ_REMOVE(&rti->nd_rti_router_list, dr, dr_entry);
2139
0
      if (dr->stateflags & NDDRF_INSTALLED) {
2140
0
        TAILQ_INSERT_TAIL(&rti_tmp.nd_rti_router_list, dr, dr_entry);
2141
0
      } else {
2142
0
        TAILQ_INSERT_HEAD(&rti_tmp.nd_rti_router_list, dr, dr_entry);
2143
0
      }
2144
0
    }
2145
2146
    /*
2147
     * The following call to defrtrlist_del should be
2148
     * safe as we are iterating a local list of
2149
     * routers.
2150
     *
2151
     * We don't really need nd6_mutex here but keeping
2152
     * it as it is to avoid changing assertios held in
2153
     * the functions in the call-path.
2154
     */
2155
0
    TAILQ_FOREACH_SAFE(dr, &rti_tmp.nd_rti_router_list, dr_entry, ndr) {
2156
0
      TAILQ_REMOVE(&rti_tmp.nd_rti_router_list, dr, dr_entry);
2157
0
      defrtrlist_del(dr, &rti->nd_rti_router_list);
2158
0
      NDDR_REMREF(dr);        /* remove list reference */
2159
0
    }
2160
    /*
2161
     * The above may have removed an entry from default router list.
2162
     * If it did and the list is now empty, remove the rti as well.
2163
     */
2164
0
    if (TAILQ_EMPTY(&rti->nd_rti_router_list)) {
2165
0
      TAILQ_REMOVE(&nd_rti_list, rti, nd_rti_entry);
2166
0
      ndrti_free(rti);
2167
0
    }
2168
0
  }
2169
2170
0
  nd6_rti_list_signal_done();
2171
0
}
2172
2173
static void
2174
nd6_purge_interface_llinfo(struct ifnet *ifp)
2175
0
{
2176
0
  struct llinfo_nd6 *ln = NULL;
2177
  /* Note that rt->rt_ifp may not be the same as ifp,
2178
   * due to KAME goto ours hack.  See RTM_RESOLVE case in
2179
   * nd6_rtrequest(), and ip6_input().
2180
   */
2181
0
again:
2182
0
  lck_mtx_lock(rnh_lock);
2183
0
  ln = llinfo_nd6.ln_next;
2184
0
  while (ln != NULL && ln != &llinfo_nd6) {
2185
0
    struct rtentry *rt;
2186
0
    struct llinfo_nd6 *nln;
2187
2188
0
    nln = ln->ln_next;
2189
0
    rt = ln->ln_rt;
2190
0
    RT_LOCK(rt);
2191
0
    if (rt->rt_gateway != NULL &&
2192
0
        rt->rt_gateway->sa_family == AF_LINK &&
2193
0
        SDL(rt->rt_gateway)->sdl_index == ifp->if_index) {
2194
0
      RT_ADDREF_LOCKED(rt);
2195
0
      RT_UNLOCK(rt);
2196
0
      lck_mtx_unlock(rnh_lock);
2197
      /*
2198
       * See comments on nd6_service() for reasons why
2199
       * this loop is repeated; we bite the costs of
2200
       * going thru the same llinfo_nd6 more than once
2201
       * here, since this purge happens during detach,
2202
       * and that unlike the timer case, it's possible
2203
       * there's more than one purges happening at the
2204
       * same time (thus a flag wouldn't buy anything).
2205
       */
2206
0
      nd6_free(rt);
2207
0
      RT_REMREF(rt);
2208
0
      LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
2209
0
      goto again;
2210
0
    } else {
2211
0
      RT_UNLOCK(rt);
2212
0
    }
2213
0
    ln = nln;
2214
0
  }
2215
0
  lck_mtx_unlock(rnh_lock);
2216
0
}
2217
2218
/*
2219
 * Nuke neighbor cache/prefix/default router management table, right before
2220
 * ifp goes away.
2221
 */
2222
void
2223
nd6_purge(struct ifnet *ifp)
2224
0
{
2225
0
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
2226
0
  lck_mtx_lock(nd6_mutex);
2227
2228
  /* Nuke default router list entries toward ifp */
2229
0
  nd6_purge_interface_default_routers(ifp);
2230
2231
  /* Nuke prefix list entries toward ifp */
2232
0
  nd6_purge_interface_prefixes(ifp);
2233
2234
  /* Nuke route info option entries toward ifp */
2235
0
  nd6_purge_interface_rti_entries(ifp);
2236
2237
0
  lck_mtx_unlock(nd6_mutex);
2238
2239
  /* cancel default outgoing interface setting */
2240
0
  if (nd6_defifindex == ifp->if_index) {
2241
0
    nd6_setdefaultiface(0);
2242
0
  }
2243
2244
  /*
2245
   * Perform default router selection even when we are a router,
2246
   * if Scoped Routing is enabled.
2247
   * XXX ?Should really not be needed since when defrouter_select
2248
   * was changed to work on interface.
2249
   */
2250
0
  lck_mtx_lock(nd6_mutex);
2251
  /* refresh default router list */
2252
0
  defrouter_select(ifp, NULL);
2253
0
  lck_mtx_unlock(nd6_mutex);
2254
2255
  /* Nuke neighbor cache entries for the ifp. */
2256
0
  nd6_purge_interface_llinfo(ifp);
2257
0
}
2258
2259
/*
2260
 * Upon success, the returned route will be locked and the caller is
2261
 * responsible for releasing the reference and doing RT_UNLOCK(rt).
2262
 * This routine does not require rnh_lock to be held by the caller,
2263
 * although it needs to be indicated of such a case in order to call
2264
 * the correct variant of the relevant routing routines.
2265
 */
2266
struct rtentry *
2267
nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp, int rt_locked)
2268
20.9k
{
2269
20.9k
  struct rtentry *rt;
2270
20.9k
  struct sockaddr_in6 sin6;
2271
20.9k
  unsigned int ifscope;
2272
2273
20.9k
  bzero(&sin6, sizeof(sin6));
2274
20.9k
  sin6.sin6_len = sizeof(struct sockaddr_in6);
2275
20.9k
  sin6.sin6_family = AF_INET6;
2276
20.9k
  sin6.sin6_addr = *addr6;
2277
2278
20.9k
  ifscope = (ifp != NULL) ? ifp->if_index : IFSCOPE_NONE;
2279
20.9k
  if (rt_locked) {
2280
0
    LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
2281
0
    rt = rtalloc1_scoped_locked(SA(&sin6), create, 0, ifscope);
2282
20.9k
  } else {
2283
20.9k
    rt = rtalloc1_scoped(SA(&sin6), create, 0, ifscope);
2284
20.9k
  }
2285
2286
20.9k
  if (rt != NULL) {
2287
17.3k
    RT_LOCK(rt);
2288
17.3k
    if ((rt->rt_flags & RTF_LLINFO) == 0) {
2289
      /*
2290
       * This is the case for the default route.
2291
       * If we want to create a neighbor cache for the
2292
       * address, we should free the route for the
2293
       * destination and allocate an interface route.
2294
       */
2295
0
      if (create) {
2296
0
        RT_UNLOCK(rt);
2297
0
        if (rt_locked) {
2298
0
          rtfree_locked(rt);
2299
0
        } else {
2300
0
          rtfree(rt);
2301
0
        }
2302
0
        rt = NULL;
2303
0
      }
2304
0
    }
2305
17.3k
  }
2306
20.9k
  if (rt == NULL) {
2307
3.58k
    if (create && ifp) {
2308
21
      struct ifaddr *ifa;
2309
21
      u_int32_t ifa_flags;
2310
21
      int e;
2311
2312
      /*
2313
       * If no route is available and create is set,
2314
       * we allocate a host route for the destination
2315
       * and treat it like an interface route.
2316
       * This hack is necessary for a neighbor which can't
2317
       * be covered by our own prefix.
2318
       */
2319
21
      ifa = ifaof_ifpforaddr(SA(&sin6), ifp);
2320
21
      if (ifa == NULL) {
2321
0
        return NULL;
2322
0
      }
2323
2324
      /*
2325
       * Create a new route.  RTF_LLINFO is necessary
2326
       * to create a Neighbor Cache entry for the
2327
       * destination in nd6_rtrequest which will be
2328
       * called in rtrequest via ifa->ifa_rtrequest.
2329
       */
2330
21
      if (!rt_locked) {
2331
21
        lck_mtx_lock(rnh_lock);
2332
21
      }
2333
21
      IFA_LOCK_SPIN(ifa);
2334
21
      ifa_flags = ifa->ifa_flags;
2335
21
      IFA_UNLOCK(ifa);
2336
21
      if ((e = rtrequest_scoped_locked(RTM_ADD,
2337
21
          SA(&sin6), ifa->ifa_addr, SA(&all1_sa),
2338
21
          (ifa_flags | RTF_HOST | RTF_LLINFO) &
2339
21
          ~RTF_CLONING, &rt, ifscope)) != 0) {
2340
0
        if (e != EEXIST) {
2341
0
          log(LOG_ERR, "%s: failed to add route "
2342
0
              "for a neighbor(%s), errno=%d\n",
2343
0
              __func__, ip6_sprintf(addr6), e);
2344
0
        }
2345
0
      }
2346
21
      if (!rt_locked) {
2347
21
        lck_mtx_unlock(rnh_lock);
2348
21
      }
2349
21
      IFA_REMREF(ifa);
2350
21
      if (rt == NULL) {
2351
0
        return NULL;
2352
0
      }
2353
2354
21
      RT_LOCK(rt);
2355
21
      if (rt->rt_llinfo) {
2356
21
        struct llinfo_nd6 *ln = rt->rt_llinfo;
2357
21
        struct nd_ifinfo *ndi = ND_IFINFO(rt->rt_ifp);
2358
2359
21
        VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
2360
        /*
2361
         * For interface's that do not perform NUD
2362
         * neighbor cache entres must always be marked
2363
         * reachable with no expiry
2364
         */
2365
21
        if (ndi->flags & ND6_IFF_PERFORMNUD) {
2366
21
          ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_NOSTATE);
2367
21
        } else {
2368
0
          ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_REACHABLE);
2369
0
          ln_setexpire(ln, 0);
2370
0
        }
2371
21
      }
2372
3.56k
    } else {
2373
3.56k
      return NULL;
2374
3.56k
    }
2375
3.58k
  }
2376
17.3k
  RT_LOCK_ASSERT_HELD(rt);
2377
  /*
2378
   * Validation for the entry.
2379
   * Note that the check for rt_llinfo is necessary because a cloned
2380
   * route from a parent route that has the L flag (e.g. the default
2381
   * route to a p2p interface) may have the flag, too, while the
2382
   * destination is not actually a neighbor.
2383
   * XXX: we can't use rt->rt_ifp to check for the interface, since
2384
   *  it might be the loopback interface if the entry is for our
2385
   *  own address on a non-loopback interface. Instead, we should
2386
   *  use rt->rt_ifa->ifa_ifp, which would specify the REAL
2387
   *  interface.
2388
   * Note also that ifa_ifp and ifp may differ when we connect two
2389
   * interfaces to a same link, install a link prefix to an interface,
2390
   * and try to install a neighbor cache on an interface that does not
2391
   * have a route to the prefix.
2392
   *
2393
   * If the address is from a proxied prefix, the ifa_ifp and ifp might
2394
   * not match, because nd6_na_input() could have modified the ifp
2395
   * of the route to point to the interface where the NA arrived on,
2396
   * hence the test for RTF_PROXY.
2397
   */
2398
17.3k
  if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
2399
17.3k
      rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
2400
17.3k
      (ifp && rt->rt_ifa->ifa_ifp != ifp &&
2401
17.3k
      !(rt->rt_flags & RTF_PROXY))) {
2402
11
    RT_REMREF_LOCKED(rt);
2403
11
    RT_UNLOCK(rt);
2404
11
    if (create) {
2405
0
      log(LOG_DEBUG, "%s: failed to lookup %s "
2406
0
          "(if = %s)\n", __func__, ip6_sprintf(addr6),
2407
0
          ifp ? if_name(ifp) : "unspec");
2408
      /* xxx more logs... kazu */
2409
0
    }
2410
11
    return NULL;
2411
11
  }
2412
  /*
2413
   * Caller needs to release reference and call RT_UNLOCK(rt).
2414
   */
2415
17.3k
  return rt;
2416
17.3k
}
2417
2418
/*
2419
 * Test whether a given IPv6 address is a neighbor or not, ignoring
2420
 * the actual neighbor cache.  The neighbor cache is ignored in order
2421
 * to not reenter the routing code from within itself.
2422
 */
2423
static int
2424
nd6_is_new_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
2425
18.5k
{
2426
18.5k
  struct nd_prefix *pr;
2427
18.5k
  struct ifaddr *dstaddr;
2428
2429
18.5k
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2430
2431
  /*
2432
   * A link-local address is always a neighbor.
2433
   * XXX: a link does not necessarily specify a single interface.
2434
   */
2435
18.5k
  if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
2436
16.2k
    struct sockaddr_in6 sin6_copy;
2437
16.2k
    u_int32_t zone;
2438
2439
    /*
2440
     * We need sin6_copy since sa6_recoverscope() may modify the
2441
     * content (XXX).
2442
     */
2443
16.2k
    sin6_copy = *addr;
2444
16.2k
    if (sa6_recoverscope(&sin6_copy, FALSE)) {
2445
0
      return 0; /* XXX: should be impossible */
2446
0
    }
2447
16.2k
    if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone)) {
2448
0
      return 0;
2449
0
    }
2450
16.2k
    if (sin6_copy.sin6_scope_id == zone) {
2451
16.2k
      return 1;
2452
16.2k
    } else {
2453
0
      return 0;
2454
0
    }
2455
16.2k
  }
2456
2457
  /*
2458
   * If the address matches one of our addresses,
2459
   * it should be a neighbor.
2460
   * If the address matches one of our on-link prefixes, it should be a
2461
   * neighbor.
2462
   */
2463
2.32k
  for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
2464
0
    NDPR_LOCK(pr);
2465
0
    if (pr->ndpr_ifp != ifp) {
2466
0
      NDPR_UNLOCK(pr);
2467
0
      continue;
2468
0
    }
2469
0
    if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
2470
0
      NDPR_UNLOCK(pr);
2471
0
      continue;
2472
0
    }
2473
0
    if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
2474
0
        &addr->sin6_addr, &pr->ndpr_mask)) {
2475
0
      NDPR_UNLOCK(pr);
2476
0
      return 1;
2477
0
    }
2478
0
    NDPR_UNLOCK(pr);
2479
0
  }
2480
2481
  /*
2482
   * If the address is assigned on the node of the other side of
2483
   * a p2p interface, the address should be a neighbor.
2484
   */
2485
2.32k
  dstaddr = ifa_ifwithdstaddr(SA(addr));
2486
2.32k
  if (dstaddr != NULL) {
2487
0
    if (dstaddr->ifa_ifp == ifp) {
2488
0
      IFA_REMREF(dstaddr);
2489
0
      return 1;
2490
0
    }
2491
0
    IFA_REMREF(dstaddr);
2492
0
    dstaddr = NULL;
2493
0
  }
2494
2495
2.32k
  return 0;
2496
2.32k
}
2497
2498
2499
/*
2500
 * Detect if a given IPv6 address identifies a neighbor on a given link.
2501
 * XXX: should take care of the destination of a p2p link?
2502
 */
2503
int
2504
nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp,
2505
    int rt_locked)
2506
18.5k
{
2507
18.5k
  struct rtentry *rt;
2508
2509
18.5k
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
2510
18.5k
  lck_mtx_lock(nd6_mutex);
2511
18.5k
  if (nd6_is_new_addr_neighbor(addr, ifp)) {
2512
16.2k
    lck_mtx_unlock(nd6_mutex);
2513
16.2k
    return 1;
2514
16.2k
  }
2515
2.32k
  lck_mtx_unlock(nd6_mutex);
2516
2517
  /*
2518
   * Even if the address matches none of our addresses, it might be
2519
   * in the neighbor cache.
2520
   */
2521
2.32k
  if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp, rt_locked)) != NULL) {
2522
0
    RT_LOCK_ASSERT_HELD(rt);
2523
0
    RT_REMREF_LOCKED(rt);
2524
0
    RT_UNLOCK(rt);
2525
0
    return 1;
2526
0
  }
2527
2528
2.32k
  return 0;
2529
2.32k
}
2530
2531
/*
2532
 * Free an nd6 llinfo entry.
2533
 * Since the function would cause significant changes in the kernel, DO NOT
2534
 * make it global, unless you have a strong reason for the change, and are sure
2535
 * that the change is safe.
2536
 */
2537
void
2538
nd6_free(struct rtentry *rt)
2539
0
{
2540
0
  struct llinfo_nd6 *ln = NULL;
2541
0
  struct in6_addr in6 = {};
2542
0
  struct nd_defrouter *dr = NULL;
2543
2544
0
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
2545
0
  RT_LOCK_ASSERT_NOTHELD(rt);
2546
0
  lck_mtx_lock(nd6_mutex);
2547
2548
0
  RT_LOCK(rt);
2549
0
  RT_ADDREF_LOCKED(rt);   /* Extra ref */
2550
0
  ln = rt->rt_llinfo;
2551
0
  in6 = SIN6(rt_key(rt))->sin6_addr;
2552
2553
  /*
2554
   * Prevent another thread from modifying rt_key, rt_gateway
2555
   * via rt_setgate() after the rt_lock is dropped by marking
2556
   * the route as defunct.
2557
   */
2558
0
  rt->rt_flags |= RTF_CONDEMNED;
2559
2560
  /*
2561
   * We used to have pfctlinput(PRC_HOSTDEAD) here.  Even though it is
2562
   * not harmful, it was not really necessary.  Perform default router
2563
   * selection even when we are a router, if Scoped Routing is enabled.
2564
   */
2565
  /* XXX TDB Handle lists in route information option as well */
2566
0
  dr = defrouter_lookup(NULL, &SIN6(rt_key(rt))->sin6_addr, rt->rt_ifp);
2567
2568
0
  if ((ln && ln->ln_router) || dr) {
2569
    /*
2570
     * rt6_flush must be called whether or not the neighbor
2571
     * is in the Default Router List.
2572
     * See a corresponding comment in nd6_na_input().
2573
     */
2574
0
    RT_UNLOCK(rt);
2575
0
    lck_mtx_unlock(nd6_mutex);
2576
0
    rt6_flush(&in6, rt->rt_ifp);
2577
0
    lck_mtx_lock(nd6_mutex);
2578
0
  } else {
2579
0
    RT_UNLOCK(rt);
2580
0
  }
2581
2582
0
  if (dr) {
2583
0
    NDDR_REMREF(dr);
2584
    /*
2585
     * Unreachablity of a router might affect the default
2586
     * router selection and on-link detection of advertised
2587
     * prefixes.
2588
     */
2589
2590
    /*
2591
     * Temporarily fake the state to choose a new default
2592
     * router and to perform on-link determination of
2593
     * prefixes correctly.
2594
     * Below the state will be set correctly,
2595
     * or the entry itself will be deleted.
2596
     */
2597
0
    RT_LOCK_SPIN(rt);
2598
0
    ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_INCOMPLETE);
2599
2600
    /*
2601
     * Since defrouter_select() does not affect the
2602
     * on-link determination and MIP6 needs the check
2603
     * before the default router selection, we perform
2604
     * the check now.
2605
     */
2606
0
    RT_UNLOCK(rt);
2607
0
    pfxlist_onlink_check();
2608
2609
    /*
2610
     * refresh default router list
2611
     */
2612
0
    defrouter_select(rt->rt_ifp, NULL);
2613
2614
    /* Loop through all RTI's as well and trigger router selection. */
2615
0
    nd6_router_select_rti_entries(rt->rt_ifp);
2616
0
  }
2617
0
  RT_LOCK_ASSERT_NOTHELD(rt);
2618
0
  lck_mtx_unlock(nd6_mutex);
2619
  /*
2620
   * Detach the route from the routing tree and the list of neighbor
2621
   * caches, and disable the route entry not to be used in already
2622
   * cached routes.
2623
   */
2624
0
  (void) rtrequest(RTM_DELETE, rt_key(rt), NULL, rt_mask(rt), 0, NULL);
2625
2626
  /* Extra ref held above; now free it */
2627
0
  rtfree(rt);
2628
0
}
2629
2630
void
2631
nd6_rtrequest(int req, struct rtentry *rt, struct sockaddr *sa)
2632
25
{
2633
25
#pragma unused(sa)
2634
25
  struct sockaddr *gate = rt->rt_gateway;
2635
25
  struct llinfo_nd6 *ln = rt->rt_llinfo;
2636
25
  static struct sockaddr_dl null_sdl =
2637
25
  { .sdl_len = sizeof(null_sdl), .sdl_family = AF_LINK };
2638
25
  struct ifnet *ifp = rt->rt_ifp;
2639
25
  struct ifaddr *ifa;
2640
25
  uint64_t timenow;
2641
25
  char buf[MAX_IPv6_STR_LEN];
2642
25
  struct nd_ifinfo *ndi = ND_IFINFO(rt->rt_ifp);
2643
2644
25
  VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
2645
25
  VERIFY(nd6_init_done);
2646
25
  LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
2647
25
  RT_LOCK_ASSERT_HELD(rt);
2648
2649
  /*
2650
   * We have rnh_lock held, see if we need to schedule the timer;
2651
   * we might do this again below during RTM_RESOLVE, but doing it
2652
   * now handles all other cases.
2653
   */
2654
25
  if (nd6_sched_timeout_want) {
2655
0
    nd6_sched_timeout(NULL, NULL);
2656
0
  }
2657
2658
25
  if (rt->rt_flags & RTF_GATEWAY) {
2659
0
    return;
2660
0
  }
2661
2662
25
  if (!nd6_need_cache(ifp) && !(rt->rt_flags & RTF_HOST)) {
2663
    /*
2664
     * This is probably an interface direct route for a link
2665
     * which does not need neighbor caches (e.g. fe80::%lo0/64).
2666
     * We do not need special treatment below for such a route.
2667
     * Moreover, the RTF_LLINFO flag which would be set below
2668
     * would annoy the ndp(8) command.
2669
     */
2670
3
    return;
2671
3
  }
2672
2673
22
  if (req == RTM_RESOLVE) {
2674
0
    int no_nd_cache;
2675
2676
0
    if (!nd6_need_cache(ifp)) {     /* stf case */
2677
0
      no_nd_cache = 1;
2678
0
    } else {
2679
0
      struct sockaddr_in6 sin6;
2680
2681
0
      rtkey_to_sa6(rt, &sin6);
2682
      /*
2683
       * nd6_is_addr_neighbor() may call nd6_lookup(),
2684
       * therefore we drop rt_lock to avoid deadlock
2685
       * during the lookup.
2686
       */
2687
0
      RT_ADDREF_LOCKED(rt);
2688
0
      RT_UNLOCK(rt);
2689
0
      no_nd_cache = !nd6_is_addr_neighbor(&sin6, ifp, 1);
2690
0
      RT_LOCK(rt);
2691
0
      RT_REMREF_LOCKED(rt);
2692
0
    }
2693
2694
    /*
2695
     * FreeBSD and BSD/OS often make a cloned host route based
2696
     * on a less-specific route (e.g. the default route).
2697
     * If the less specific route does not have a "gateway"
2698
     * (this is the case when the route just goes to a p2p or an
2699
     * stf interface), we'll mistakenly make a neighbor cache for
2700
     * the host route, and will see strange neighbor solicitation
2701
     * for the corresponding destination.  In order to avoid the
2702
     * confusion, we check if the destination of the route is
2703
     * a neighbor in terms of neighbor discovery, and stop the
2704
     * process if not.  Additionally, we remove the LLINFO flag
2705
     * so that ndp(8) will not try to get the neighbor information
2706
     * of the destination.
2707
     */
2708
0
    if (no_nd_cache) {
2709
0
      rt->rt_flags &= ~RTF_LLINFO;
2710
0
      return;
2711
0
    }
2712
0
  }
2713
2714
22
  timenow = net_uptime();
2715
2716
22
  switch (req) {
2717
22
  case RTM_ADD:
2718
    /*
2719
     * There is no backward compatibility :)
2720
     *
2721
     * if ((rt->rt_flags & RTF_HOST) == 0 &&
2722
     *      SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
2723
     *              rt->rt_flags |= RTF_CLONING;
2724
     */
2725
22
    if ((rt->rt_flags & RTF_CLONING) ||
2726
22
        ((rt->rt_flags & RTF_LLINFO) && ln == NULL)) {
2727
      /*
2728
       * Case 1: This route should come from a route to
2729
       * interface (RTF_CLONING case) or the route should be
2730
       * treated as on-link but is currently not
2731
       * (RTF_LLINFO && ln == NULL case).
2732
       */
2733
21
      if (rt_setgate(rt, rt_key(rt), SA(&null_sdl)) == 0) {
2734
21
        gate = rt->rt_gateway;
2735
21
        SDL(gate)->sdl_type = ifp->if_type;
2736
21
        SDL(gate)->sdl_index = ifp->if_index;
2737
        /*
2738
         * In case we're called before 1.0 sec.
2739
         * has elapsed.
2740
         */
2741
21
        if (ln != NULL) {
2742
0
          ln_setexpire(ln,
2743
0
              (ifp->if_eflags & IFEF_IPV6_ND6ALT)
2744
0
              ? 0 : MAX(timenow, 1));
2745
0
        }
2746
21
      }
2747
21
      if (rt->rt_flags & RTF_CLONING) {
2748
0
        break;
2749
0
      }
2750
21
    }
2751
    /*
2752
     * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
2753
     * We don't do that here since llinfo is not ready yet.
2754
     *
2755
     * There are also couple of other things to be discussed:
2756
     * - unsolicited NA code needs improvement beforehand
2757
     * - RFC4861 says we MAY send multicast unsolicited NA
2758
     *   (7.2.6 paragraph 4), however, it also says that we
2759
     *   SHOULD provide a mechanism to prevent multicast NA storm.
2760
     *   we don't have anything like it right now.
2761
     *   note that the mechanism needs a mutual agreement
2762
     *   between proxies, which means that we need to implement
2763
     *   a new protocol, or a new kludge.
2764
     * - from RFC4861 6.2.4, host MUST NOT send an unsolicited RA.
2765
     *   we need to check ip6forwarding before sending it.
2766
     *   (or should we allow proxy ND configuration only for
2767
     *   routers?  there's no mention about proxy ND from hosts)
2768
     */
2769
22
    OS_FALLTHROUGH;
2770
22
  case RTM_RESOLVE:
2771
22
    if (!(ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))) {
2772
      /*
2773
       * Address resolution isn't necessary for a point to
2774
       * point link, so we can skip this test for a p2p link.
2775
       */
2776
0
      if (gate->sa_family != AF_LINK ||
2777
0
          gate->sa_len < sizeof(null_sdl)) {
2778
        /* Don't complain in case of RTM_ADD */
2779
0
        if (req == RTM_RESOLVE) {
2780
0
          log(LOG_ERR, "%s: route to %s has bad "
2781
0
              "gateway address (sa_family %u "
2782
0
              "sa_len %u) on %s\n", __func__,
2783
0
              inet_ntop(AF_INET6,
2784
0
              &SIN6(rt_key(rt))->sin6_addr, buf,
2785
0
              sizeof(buf)), gate->sa_family,
2786
0
              gate->sa_len, if_name(ifp));
2787
0
        }
2788
0
        break;
2789
0
      }
2790
0
      SDL(gate)->sdl_type = ifp->if_type;
2791
0
      SDL(gate)->sdl_index = ifp->if_index;
2792
0
    }
2793
22
    if (ln != NULL) {
2794
0
      break;  /* This happens on a route change */
2795
0
    }
2796
    /*
2797
     * Case 2: This route may come from cloning, or a manual route
2798
     * add with a LL address.
2799
     */
2800
22
    rt->rt_llinfo = ln = nd6_llinfo_alloc(Z_WAITOK);
2801
2802
22
    nd6_allocated++;
2803
22
    rt->rt_llinfo_get_ri    = nd6_llinfo_get_ri;
2804
22
    rt->rt_llinfo_get_iflri = nd6_llinfo_get_iflri;
2805
22
    rt->rt_llinfo_purge     = nd6_llinfo_purge;
2806
22
    rt->rt_llinfo_free      = nd6_llinfo_free;
2807
22
    rt->rt_llinfo_refresh   = nd6_llinfo_refresh;
2808
22
    rt->rt_flags |= RTF_LLINFO;
2809
22
    ln->ln_rt = rt;
2810
    /* this is required for "ndp" command. - shin */
2811
    /*
2812
     * For interface's that do not perform NUD
2813
     * neighbor cache entries must always be marked
2814
     * reachable with no expiry
2815
     */
2816
22
    if ((req == RTM_ADD) ||
2817
22
        !(ndi->flags & ND6_IFF_PERFORMNUD)) {
2818
      /*
2819
       * gate should have some valid AF_LINK entry,
2820
       * and ln->ln_expire should have some lifetime
2821
       * which is specified by ndp command.
2822
       */
2823
22
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_REACHABLE);
2824
22
      ln_setexpire(ln, 0);
2825
22
    } else {
2826
      /*
2827
       * When req == RTM_RESOLVE, rt is created and
2828
       * initialized in rtrequest(), so rt_expire is 0.
2829
       */
2830
0
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_NOSTATE);
2831
      /* In case we're called before 1.0 sec. has elapsed */
2832
0
      ln_setexpire(ln, (ifp->if_eflags & IFEF_IPV6_ND6ALT) ?
2833
0
          0 : MAX(timenow, 1));
2834
0
    }
2835
22
    LN_INSERTHEAD(ln);
2836
22
    nd6_inuse++;
2837
2838
    /* We have at least one entry; arm the timer if not already */
2839
22
    nd6_sched_timeout(NULL, NULL);
2840
2841
    /*
2842
     * If we have too many cache entries, initiate immediate
2843
     * purging for some "less recently used" entries.  Note that
2844
     * we cannot directly call nd6_free() here because it would
2845
     * cause re-entering rtable related routines triggering an LOR
2846
     * problem.
2847
     */
2848
22
    if (ip6_neighborgcthresh > 0 &&
2849
22
        nd6_inuse >= ip6_neighborgcthresh) {
2850
0
      int i;
2851
2852
0
      for (i = 0; i < 10 && llinfo_nd6.ln_prev != ln; i++) {
2853
0
        struct llinfo_nd6 *ln_end = llinfo_nd6.ln_prev;
2854
0
        struct rtentry *rt_end = ln_end->ln_rt;
2855
2856
        /* Move this entry to the head */
2857
0
        RT_LOCK(rt_end);
2858
0
        LN_DEQUEUE(ln_end);
2859
0
        LN_INSERTHEAD(ln_end);
2860
2861
0
        if (ln_end->ln_expire == 0) {
2862
0
          RT_UNLOCK(rt_end);
2863
0
          continue;
2864
0
        }
2865
0
        if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE) {
2866
0
          ND6_CACHE_STATE_TRANSITION(ln_end, ND6_LLINFO_STALE);
2867
0
        } else {
2868
0
          ND6_CACHE_STATE_TRANSITION(ln_end, ND6_LLINFO_PURGE);
2869
0
        }
2870
0
        ln_setexpire(ln_end, timenow);
2871
0
        RT_UNLOCK(rt_end);
2872
0
      }
2873
0
    }
2874
2875
    /*
2876
     * check if rt_key(rt) is one of my address assigned
2877
     * to the interface.
2878
     */
2879
22
    ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
2880
22
        &SIN6(rt_key(rt))->sin6_addr);
2881
22
    if (ifa != NULL) {
2882
1
      caddr_t macp = nd6_ifptomac(ifp);
2883
1
      ln_setexpire(ln, 0);
2884
1
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_REACHABLE);
2885
1
      if (macp != NULL) {
2886
0
        Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen);
2887
0
        SDL(gate)->sdl_alen = ifp->if_addrlen;
2888
0
      }
2889
1
      if (nd6_useloopback) {
2890
1
        if (rt->rt_ifp != lo_ifp) {
2891
          /*
2892
           * Purge any link-layer info caching.
2893
           */
2894
0
          if (rt->rt_llinfo_purge != NULL) {
2895
0
            rt->rt_llinfo_purge(rt);
2896
0
          }
2897
2898
          /*
2899
           * Adjust route ref count for the
2900
           * interfaces.
2901
           */
2902
0
          if (rt->rt_if_ref_fn != NULL) {
2903
0
            rt->rt_if_ref_fn(lo_ifp, 1);
2904
0
            rt->rt_if_ref_fn(rt->rt_ifp,
2905
0
                -1);
2906
0
          }
2907
0
        }
2908
1
        rt->rt_ifp = lo_ifp;
2909
        /*
2910
         * If rmx_mtu is not locked, update it
2911
         * to the MTU used by the new interface.
2912
         */
2913
1
        if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) {
2914
1
          rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
2915
1
        }
2916
        /*
2917
         * Make sure rt_ifa be equal to the ifaddr
2918
         * corresponding to the address.
2919
         * We need this because when we refer
2920
         * rt_ifa->ia6_flags in ip6_input, we assume
2921
         * that the rt_ifa points to the address instead
2922
         * of the loopback address.
2923
         */
2924
1
        if (ifa != rt->rt_ifa) {
2925
0
          rtsetifa(rt, ifa);
2926
0
        }
2927
1
      }
2928
1
      IFA_REMREF(ifa);
2929
21
    } else if (rt->rt_flags & RTF_ANNOUNCE) {
2930
0
      ln_setexpire(ln, 0);
2931
0
      ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_REACHABLE);
2932
2933
      /* join solicited node multicast for proxy ND */
2934
0
      if (ifp->if_flags & IFF_MULTICAST) {
2935
0
        struct in6_addr llsol;
2936
0
        struct in6_multi *in6m;
2937
0
        int error;
2938
2939
0
        llsol = SIN6(rt_key(rt))->sin6_addr;
2940
0
        llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
2941
0
        llsol.s6_addr32[1] = 0;
2942
0
        llsol.s6_addr32[2] = htonl(1);
2943
0
        llsol.s6_addr8[12] = 0xff;
2944
0
        if (in6_setscope(&llsol, ifp, NULL)) {
2945
0
          break;
2946
0
        }
2947
0
        error = in6_mc_join(ifp, &llsol,
2948
0
            NULL, &in6m, 0);
2949
0
        if (error) {
2950
0
          nd6log(error, "%s: failed to join "
2951
0
              "%s (errno=%d)\n", if_name(ifp),
2952
0
              ip6_sprintf(&llsol), error);
2953
0
        } else {
2954
0
          IN6M_REMREF(in6m);
2955
0
        }
2956
0
      }
2957
0
    }
2958
22
    break;
2959
2960
22
  case RTM_DELETE:
2961
0
    if (ln == NULL) {
2962
0
      break;
2963
0
    }
2964
    /* leave from solicited node multicast for proxy ND */
2965
0
    if ((rt->rt_flags & RTF_ANNOUNCE) &&
2966
0
        (ifp->if_flags & IFF_MULTICAST)) {
2967
0
      struct in6_addr llsol;
2968
0
      struct in6_multi *in6m;
2969
2970
0
      llsol = SIN6(rt_key(rt))->sin6_addr;
2971
0
      llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
2972
0
      llsol.s6_addr32[1] = 0;
2973
0
      llsol.s6_addr32[2] = htonl(1);
2974
0
      llsol.s6_addr8[12] = 0xff;
2975
0
      if (in6_setscope(&llsol, ifp, NULL) == 0) {
2976
0
        in6_multihead_lock_shared();
2977
0
        IN6_LOOKUP_MULTI(&llsol, ifp, in6m);
2978
0
        in6_multihead_lock_done();
2979
0
        if (in6m != NULL) {
2980
0
          in6_mc_leave(in6m, NULL);
2981
0
          IN6M_REMREF(in6m);
2982
0
        }
2983
0
      }
2984
0
    }
2985
0
    nd6_inuse--;
2986
    /*
2987
     * Unchain it but defer the actual freeing until the route
2988
     * itself is to be freed.  rt->rt_llinfo still points to
2989
     * llinfo_nd6, and likewise, ln->ln_rt stil points to this
2990
     * route entry, except that RTF_LLINFO is now cleared.
2991
     */
2992
0
    if (ln->ln_flags & ND6_LNF_IN_USE) {
2993
0
      LN_DEQUEUE(ln);
2994
0
    }
2995
2996
    /*
2997
     * Purge any link-layer info caching.
2998
     */
2999
0
    if (rt->rt_llinfo_purge != NULL) {
3000
0
      rt->rt_llinfo_purge(rt);
3001
0
    }
3002
3003
0
    rt->rt_flags &= ~RTF_LLINFO;
3004
0
    if (ln->ln_hold != NULL) {
3005
0
      m_freem_list(ln->ln_hold);
3006
0
      ln->ln_hold = NULL;
3007
0
    }
3008
22
  }
3009
22
}
3010
3011
static int
3012
nd6_siocgdrlst(void *data, int data_is_64)
3013
0
{
3014
0
  struct in6_drlist_32 *drl_32;
3015
0
  struct nd_defrouter *dr;
3016
0
  int i = 0;
3017
3018
0
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3019
3020
0
  dr = TAILQ_FIRST(&nd_defrouter_list);
3021
3022
  /* XXX Handle mapped defrouter entries */
3023
  /* For 64-bit process */
3024
0
  if (data_is_64) {
3025
0
    struct in6_drlist_64 *drl_64;
3026
3027
0
    drl_64 = _MALLOC(sizeof(*drl_64), M_TEMP, M_WAITOK | M_ZERO);
3028
0
    if (drl_64 == NULL) {
3029
0
      return ENOMEM;
3030
0
    }
3031
3032
    /* preserve the interface name */
3033
0
    bcopy(data, drl_64, sizeof(drl_64->ifname));
3034
3035
0
    while (dr && i < DRLSTSIZ) {
3036
0
      drl_64->defrouter[i].rtaddr = dr->rtaddr;
3037
0
      if (IN6_IS_ADDR_LINKLOCAL(
3038
0
            &drl_64->defrouter[i].rtaddr)) {
3039
        /* XXX: need to this hack for KAME stack */
3040
0
        drl_64->defrouter[i].rtaddr.s6_addr16[1] = 0;
3041
0
      } else {
3042
0
        log(LOG_ERR,
3043
0
            "default router list contains a "
3044
0
            "non-linklocal address(%s)\n",
3045
0
            ip6_sprintf(&drl_64->defrouter[i].rtaddr));
3046
0
      }
3047
0
      drl_64->defrouter[i].flags = dr->flags;
3048
0
      drl_64->defrouter[i].rtlifetime = (u_short)dr->rtlifetime;
3049
0
      drl_64->defrouter[i].expire = (u_long)nddr_getexpire(dr);
3050
0
      drl_64->defrouter[i].if_index = dr->ifp->if_index;
3051
0
      i++;
3052
0
      dr = TAILQ_NEXT(dr, dr_entry);
3053
0
    }
3054
0
    bcopy(drl_64, data, sizeof(*drl_64));
3055
0
    _FREE(drl_64, M_TEMP);
3056
0
    return 0;
3057
0
  }
3058
3059
  /* For 32-bit process */
3060
0
  drl_32 = _MALLOC(sizeof(*drl_32), M_TEMP, M_WAITOK | M_ZERO);
3061
0
  if (drl_32 == NULL) {
3062
0
    return ENOMEM;
3063
0
  }
3064
3065
  /* preserve the interface name */
3066
0
  bcopy(data, drl_32, sizeof(drl_32->ifname));
3067
3068
0
  while (dr != NULL && i < DRLSTSIZ) {
3069
0
    drl_32->defrouter[i].rtaddr = dr->rtaddr;
3070
0
    if (IN6_IS_ADDR_LINKLOCAL(&drl_32->defrouter[i].rtaddr)) {
3071
      /* XXX: need to this hack for KAME stack */
3072
0
      drl_32->defrouter[i].rtaddr.s6_addr16[1] = 0;
3073
0
    } else {
3074
0
      log(LOG_ERR,
3075
0
          "default router list contains a "
3076
0
          "non-linklocal address(%s)\n",
3077
0
          ip6_sprintf(&drl_32->defrouter[i].rtaddr));
3078
0
    }
3079
0
    drl_32->defrouter[i].flags = dr->flags;
3080
0
    drl_32->defrouter[i].rtlifetime = (u_short)dr->rtlifetime;
3081
0
    drl_32->defrouter[i].expire = (u_int32_t)nddr_getexpire(dr);
3082
0
    drl_32->defrouter[i].if_index = dr->ifp->if_index;
3083
0
    i++;
3084
0
    dr = TAILQ_NEXT(dr, dr_entry);
3085
0
  }
3086
0
  bcopy(drl_32, data, sizeof(*drl_32));
3087
0
  _FREE(drl_32, M_TEMP);
3088
0
  return 0;
3089
0
}
3090
3091
/*
3092
 * XXX meaning of fields, especialy "raflags", is very
3093
 * differnet between RA prefix list and RR/static prefix list.
3094
 * how about separating ioctls into two?
3095
 */
3096
static int
3097
nd6_siocgprlst(void *data, int data_is_64)
3098
0
{
3099
0
  struct in6_prlist_32 *prl_32;
3100
0
  struct nd_prefix *pr;
3101
0
  int i = 0;
3102
3103
0
  LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3104
3105
0
  pr = nd_prefix.lh_first;
3106
3107
  /* XXX Handle mapped defrouter entries */
3108
  /* For 64-bit process */
3109
0
  if (data_is_64) {
3110
0
    struct in6_prlist_64 *prl_64;
3111
3112
0
    prl_64 = _MALLOC(sizeof(*prl_64), M_TEMP, M_WAITOK | M_ZERO);
3113
0
    if (prl_64 == NULL) {
3114
0
      return ENOMEM;
3115
0
    }
3116
3117
    /* preserve the interface name */
3118
0
    bcopy(data, prl_64, sizeof(prl_64->ifname));
3119
3120
0
    while (pr && i < PRLSTSIZ) {
3121
0
      struct nd_pfxrouter *pfr;
3122
0
      int j;
3123
3124
0
      NDPR_LOCK(pr);
3125
0
      (void) in6_embedscope(&prl_64->prefix[i].prefix,
3126
0
          &pr->ndpr_prefix, NULL, NULL, NULL);
3127
0
      prl_64->prefix[i].raflags = pr->ndpr_raf;
3128
0
      prl_64->prefix[i].prefixlen = pr->ndpr_plen;
3129
0
      prl_64->prefix[i].vltime = pr->ndpr_vltime;
3130
0
      prl_64->prefix[i].pltime = pr->ndpr_pltime;
3131
0
      prl_64->prefix[i].if_index = pr->ndpr_ifp->if_index;
3132
0
      prl_64->prefix[i].expire = (u_long)ndpr_getexpire(pr);
3133
3134
0
      pfr = pr->ndpr_advrtrs.lh_first;
3135
0
      j = 0;
3136
0
      while (pfr) {
3137
0
        if (j < DRLSTSIZ) {
3138
0
#define RTRADDR prl_64->prefix[i].advrtr[j]
3139
0
          RTRADDR = pfr->router->rtaddr;
3140
0
          if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
3141
            /* XXX: hack for KAME */
3142
0
            RTRADDR.s6_addr16[1] = 0;
3143
0
          } else {
3144
0
            log(LOG_ERR,
3145
0
                "a router(%s) advertises "
3146
0
                "a prefix with "
3147
0
                "non-link local address\n",
3148
0
                ip6_sprintf(&RTRADDR));
3149
0
          }
3150
0
#undef RTRADDR
3151
0
        }
3152
0
        j++;
3153
0
        pfr = pfr->pfr_next;
3154
0
      }
3155
0
      ASSERT(j <= USHRT_MAX);
3156
0
      prl_64->prefix[i].advrtrs = (u_short)j;
3157
0
      prl_64->prefix[i].origin = PR_ORIG_RA;
3158
0
      NDPR_UNLOCK(pr);
3159
3160
0
      i++;
3161
0
      pr = pr->ndpr_next;
3162
0
    }
3163
0
    bcopy(prl_64, data, sizeof(*prl_64));
3164
0
    _FREE(prl_64, M_TEMP);
3165
0
    return 0;
3166
0
  }
3167
3168
  /* For 32-bit process */
3169
0
  prl_32 = _MALLOC(sizeof(*prl_32), M_TEMP, M_WAITOK | M_ZERO);
3170
0
  if (prl_32 == NULL) {
3171
0
    return ENOMEM;
3172
0
  }
3173
3174
  /* preserve the interface name */
3175
0
  bcopy(data, prl_32, sizeof(prl_32->ifname));
3176
3177
0
  while (pr && i < PRLSTSIZ) {
3178
0
    struct nd_pfxrouter *pfr;
3179
0
    int j;
3180
3181
0
    NDPR_LOCK(pr);
3182
0
    (void) in6_embedscope(&prl_32->prefix[i].prefix,
3183
0
        &pr->ndpr_prefix, NULL, NULL, NULL);
3184
0
    prl_32->prefix[i].raflags = pr->ndpr_raf;
3185
0
    prl_32->prefix[i].prefixlen = pr->ndpr_plen;
3186
0
    prl_32->prefix[i].vltime = pr->ndpr_vltime;
3187
0
    prl_32->prefix[i].pltime = pr->ndpr_pltime;
3188
0
    prl_32->prefix[i].if_index = pr->ndpr_ifp->if_index;
3189
0
    prl_32->prefix[i].expire = (u_int32_t)ndpr_getexpire(pr);
3190
3191
0
    pfr = pr->ndpr_advrtrs.lh_first;
3192
0
    j = 0;
3193
0
    while (pfr) {
3194
0
      if (j < DRLSTSIZ) {
3195
0
#define RTRADDR prl_32->prefix[i].advrtr[j]
3196
0
        RTRADDR = pfr->router->rtaddr;
3197
0
        if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
3198
          /* XXX: hack for KAME */
3199
0
          RTRADDR.s6_addr16[1] = 0;
3200
0
        } else {
3201
0
          log(LOG_ERR,
3202
0
              "a router(%s) advertises "
3203
0
              "a prefix with "
3204
0
              "non-link local address\n",
3205
0
              ip6_sprintf(&RTRADDR));
3206
0
        }
3207
0
#undef RTRADDR
3208
0
      }
3209
0
      j++;
3210
0
      pfr = pfr->pfr_next;
3211
0
    }
3212
0
    ASSERT(j <= USHRT_MAX);
3213
0
    prl_32->prefix[i].advrtrs = (u_short)j;
3214
0
    prl_32->prefix[i].origin = PR_ORIG_RA;
3215
0
    NDPR_UNLOCK(pr);
3216
3217
0
    i++;
3218
0
    pr = pr->ndpr_next;
3219
0
  }
3220
0
  bcopy(prl_32, data, sizeof(*prl_32));
3221
0
  _FREE(prl_32, M_TEMP);
3222
0
  return 0;
3223
0
}
3224
3225
int
3226
nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
3227
0
{
3228
0
  struct nd_defrouter *dr;
3229
0
  struct nd_prefix *pr;
3230
0
  struct rtentry *rt;
3231
0
  int error = 0;
3232
3233
0
  VERIFY(ifp != NULL);
3234
3235
0
  switch (cmd) {
3236
0
  case SIOCGDRLST_IN6_32:         /* struct in6_drlist_32 */
3237
0
  case SIOCGDRLST_IN6_64:         /* struct in6_drlist_64 */
3238
    /*
3239
     * obsolete API, use sysctl under net.inet6.icmp6
3240
     */
3241
0
    lck_mtx_lock(nd6_mutex);
3242
0
    error = nd6_siocgdrlst(data, cmd == SIOCGDRLST_IN6_64);
3243
0
    lck_mtx_unlock(nd6_mutex);
3244
0
    break;
3245
3246
0
  case SIOCGPRLST_IN6_32:         /* struct in6_prlist_32 */
3247
0
  case SIOCGPRLST_IN6_64:         /* struct in6_prlist_64 */
3248
    /*
3249
     * obsolete API, use sysctl under net.inet6.icmp6
3250
     */
3251
0
    lck_mtx_lock(nd6_mutex);
3252
0
    error = nd6_siocgprlst(data, cmd == SIOCGPRLST_IN6_64);
3253
0
    lck_mtx_unlock(nd6_mutex);
3254
0
    break;
3255
3256
0
  case OSIOCGIFINFO_IN6:          /* struct in6_ondireq */
3257
0
  case SIOCGIFINFO_IN6: {         /* struct in6_ondireq */
3258
0
    u_int32_t linkmtu;
3259
0
    struct in6_ondireq *ondi = (struct in6_ondireq *)(void *)data;
3260
0
    struct nd_ifinfo *ndi;
3261
    /*
3262
     * SIOCGIFINFO_IN6 ioctl is encoded with in6_ondireq
3263
     * instead of in6_ndireq, so we treat it as such.
3264
     */
3265
0
    ndi = ND_IFINFO(ifp);
3266
0
    if ((NULL == ndi) || (FALSE == ndi->initialized)) {
3267
0
      error = EINVAL;
3268
0
      break;
3269
0
    }
3270
0
    lck_mtx_lock(&ndi->lock);
3271
0
    linkmtu = IN6_LINKMTU(ifp);
3272
0
    bcopy(&linkmtu, &ondi->ndi.linkmtu, sizeof(linkmtu));
3273
0
    bcopy(&ndi->maxmtu, &ondi->ndi.maxmtu,
3274
0
        sizeof(u_int32_t));
3275
0
    bcopy(&ndi->basereachable, &ondi->ndi.basereachable,
3276
0
        sizeof(u_int32_t));
3277
0
    bcopy(&ndi->reachable, &ondi->ndi.reachable,
3278
0
        sizeof(u_int32_t));
3279
0
    bcopy(&ndi->retrans, &ondi->ndi.retrans,
3280
0
        sizeof(u_int32_t));
3281
0
    bcopy(&ndi->flags, &ondi->ndi.flags,
3282
0
        sizeof(u_int32_t));
3283
0
    bcopy(&ndi->recalctm, &ondi->ndi.recalctm,
3284
0
        sizeof(int));
3285
0
    ondi->ndi.chlim = ndi->chlim;
3286
    /*
3287
     * The below truncation is fine as we mostly use it for
3288
     * debugging purpose.
3289
     */
3290
0
    ondi->ndi.receivedra = (uint8_t)ndi->ndefrouters;
3291
0
    ondi->ndi.collision_count = (uint8_t)ndi->cga_collision_count;
3292
0
    lck_mtx_unlock(&ndi->lock);
3293
0
    break;
3294
0
  }
3295
3296
0
  case SIOCSIFINFO_FLAGS: {       /* struct in6_ndireq */
3297
    /*
3298
     * XXX BSD has a bunch of checks here to ensure
3299
     * that interface disabled flag is not reset if
3300
     * link local address has failed DAD.
3301
     * Investigate that part.
3302
     */
3303
0
    struct in6_ndireq *cndi = (struct in6_ndireq *)(void *)data;
3304
0
    u_int32_t oflags, flags;
3305
0
    struct nd_ifinfo *ndi = ND_IFINFO(ifp);
3306
3307
    /* XXX: almost all other fields of cndi->ndi is unused */
3308
0
    if ((NULL == ndi) || !ndi->initialized) {
3309
0
      error = EINVAL;
3310
0
      break;
3311
0
    }
3312
3313
0
    lck_mtx_lock(&ndi->lock);
3314
0
    oflags = ndi->flags;
3315
0
    bcopy(&cndi->ndi.flags, &(ndi->flags), sizeof(flags));
3316
0
    flags = ndi->flags;
3317
0
    lck_mtx_unlock(&ndi->lock);
3318
3319
0
    if (oflags == flags) {
3320
0
      break;
3321
0
    }
3322
3323
0
    error = nd6_setifinfo(ifp, oflags, flags);
3324
0
    break;
3325
0
  }
3326
3327
0
  case SIOCSNDFLUSH_IN6:          /* struct in6_ifreq */
3328
    /* flush default router list */
3329
    /*
3330
     * xxx sumikawa: should not delete route if default
3331
     * route equals to the top of default router list
3332
     *
3333
     * XXX TODO: Needs to be done for RTI as well
3334
     * Is very specific flush command with ndp for default routers.
3335
     */
3336
0
    lck_mtx_lock(nd6_mutex);
3337
0
    defrouter_reset();
3338
0
    defrouter_select(ifp, NULL);
3339
0
    lck_mtx_unlock(nd6_mutex);
3340
    /* xxx sumikawa: flush prefix list */
3341
0
    break;
3342
3343
0
  case SIOCSPFXFLUSH_IN6: {       /* struct in6_ifreq */
3344
    /* flush all the prefix advertised by routers */
3345
0
    struct nd_prefix *next = NULL;
3346
3347
0
    lck_mtx_lock(nd6_mutex);
3348
0
    for (pr = nd_prefix.lh_first; pr; pr = next) {
3349
0
      struct in6_ifaddr *ia = NULL;
3350
0
      bool iterate_pfxlist_again = false;
3351
3352
0
      next = pr->ndpr_next;
3353
3354
0
      NDPR_LOCK(pr);
3355
0
      if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
3356
0
        NDPR_UNLOCK(pr);
3357
0
        continue; /* XXX */
3358
0
      }
3359
0
      if (ifp != lo_ifp && pr->ndpr_ifp != ifp) {
3360
0
        NDPR_UNLOCK(pr);
3361
0
        continue;
3362
0
      }
3363
      /* do we really have to remove addresses as well? */
3364
0
      NDPR_ADDREF(pr);
3365
0
      NDPR_UNLOCK(pr);
3366
0
      lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
3367
0
      bool from_begining = true;
3368
0
      while (from_begining) {
3369
0
        from_begining = false;
3370
0
        TAILQ_FOREACH(ia, &in6_ifaddrhead, ia6_link) {
3371
0
          IFA_LOCK(&ia->ia_ifa);
3372
0
          if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0) {
3373
0
            IFA_UNLOCK(&ia->ia_ifa);
3374
0
            continue;
3375
0
          }
3376
3377
0
          if (ia->ia6_ndpr == pr) {
3378
0
            IFA_ADDREF_LOCKED(&ia->ia_ifa);
3379
0
            IFA_UNLOCK(&ia->ia_ifa);
3380
0
            lck_rw_done(&in6_ifaddr_rwlock);
3381
0
            lck_mtx_unlock(nd6_mutex);
3382
0
            in6_purgeaddr(&ia->ia_ifa);
3383
0
            IFA_REMREF(&ia->ia_ifa);
3384
0
            lck_mtx_lock(nd6_mutex);
3385
0
            lck_rw_lock_exclusive(
3386
0
              &in6_ifaddr_rwlock);
3387
            /*
3388
             * Purging the address caused
3389
             * in6_ifaddr_rwlock to be
3390
             * dropped and
3391
             * reacquired; therefore search again
3392
             * from the beginning of in6_ifaddrs.
3393
             * The same applies for the prefix list.
3394
             */
3395
0
            iterate_pfxlist_again = true;
3396
0
            from_begining = true;
3397
0
            break;
3398
0
          }
3399
0
          IFA_UNLOCK(&ia->ia_ifa);
3400
0
        }
3401
0
      }
3402
0
      lck_rw_done(&in6_ifaddr_rwlock);
3403
0
      NDPR_LOCK(pr);
3404
0
      prelist_remove(pr);
3405
0
      NDPR_UNLOCK(pr);
3406
0
      pfxlist_onlink_check();
3407
0
      NDPR_REMREF(pr);
3408
0
      if (iterate_pfxlist_again) {
3409
0
        next = nd_prefix.lh_first;
3410
0
      }
3411
0
    }
3412
0
    lck_mtx_unlock(nd6_mutex);
3413
0
    break;
3414
0
  }
3415
3416
0
  case SIOCSRTRFLUSH_IN6: {       /* struct in6_ifreq */
3417
    /* flush all the default routers */
3418
0
    struct nd_defrouter *next;
3419
0
    struct nd_drhead nd_defrouter_tmp;
3420
3421
0
    TAILQ_INIT(&nd_defrouter_tmp);
3422
0
    lck_mtx_lock(nd6_mutex);
3423
0
    if ((dr = TAILQ_FIRST(&nd_defrouter_list)) != NULL) {
3424
      /*
3425
       * The first entry of the list may be stored in
3426
       * the routing table, so we'll delete it later.
3427
       */
3428
0
      for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = next) {
3429
0
        next = TAILQ_NEXT(dr, dr_entry);
3430
0
        if (ifp == lo_ifp || dr->ifp == ifp) {
3431
          /*
3432
           * Remove the entry from default router list
3433
           * and add it to the temp list.
3434
           * nd_defrouter_tmp will be a local temporary
3435
           * list as no one else can get the same
3436
           * removed entry once it is removed from default
3437
           * router list.
3438
           * Remove the reference after calling defrtrlist_de
3439
           */
3440
0
          TAILQ_REMOVE(&nd_defrouter_list, dr, dr_entry);
3441
0
          TAILQ_INSERT_TAIL(&nd_defrouter_tmp, dr, dr_entry);
3442
0
        }
3443
0
      }
3444
3445
0
      dr = TAILQ_FIRST(&nd_defrouter_list);
3446
0
      if (ifp == lo_ifp ||
3447
0
          dr->ifp == ifp) {
3448
0
        TAILQ_REMOVE(&nd_defrouter_list, dr, dr_entry);
3449
0
        TAILQ_INSERT_TAIL(&nd_defrouter_tmp, dr, dr_entry);
3450
0
      }
3451
0
    }
3452
3453
    /*
3454
     * Keep the following separate from the above iteration of
3455
     * nd_defrouter because it's not safe to call
3456
     * defrtrlist_del while iterating global default
3457
     * router list. Global list has to be traversed
3458
     * while holding nd6_mutex throughout.
3459
     *
3460
     * The following call to defrtrlist_del should be
3461
     * safe as we are iterating a local list of
3462
     * default routers.
3463
     */
3464
0
    TAILQ_FOREACH_SAFE(dr, &nd_defrouter_tmp, dr_entry, next) {
3465
0
      TAILQ_REMOVE(&nd_defrouter_tmp, dr, dr_entry);
3466
0
      defrtrlist_del(dr, NULL);
3467
0
      NDDR_REMREF(dr);        /* remove list reference */
3468
0
    }
3469
3470
    /* For now flush RTI routes here as well to avoid any regressions */
3471
0
    nd6_purge_interface_rti_entries((ifp == lo_ifp) ? NULL : ifp);
3472
3473
0
    lck_mtx_unlock(nd6_mutex);
3474
0
    break;
3475
0
  }
3476
3477
0
  case SIOCGNBRINFO_IN6_32: {     /* struct in6_nbrinfo_32 */
3478
0
    struct llinfo_nd6 *ln;
3479
0
    struct in6_nbrinfo_32 nbi_32;
3480
0
    struct in6_addr nb_addr; /* make local for safety */
3481
3482
0
    bcopy(data, &nbi_32, sizeof(nbi_32));
3483
0
    nb_addr = nbi_32.addr;
3484
    /*
3485
     * XXX: KAME specific hack for scoped addresses
3486
     *      XXXX: for other scopes than link-local?
3487
     */
3488
0
    if (IN6_IS_ADDR_LINKLOCAL(&nbi_32.addr) ||
3489
0
        IN6_IS_ADDR_MC_LINKLOCAL(&nbi_32.addr)) {
3490
0
      u_int16_t *idp =
3491
0
          (u_int16_t *)(void *)&nb_addr.s6_addr[2];
3492
3493
0
      if (*idp == 0) {
3494
0
        *idp = htons(ifp->if_index);
3495
0
      }
3496
0
    }
3497
3498
    /* Callee returns a locked route upon success */
3499
0
    if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
3500
0
      error = EINVAL;
3501
0
      break;
3502
0
    }
3503
0
    RT_LOCK_ASSERT_HELD(rt);
3504
0
    ln = rt->rt_llinfo;
3505
0
    nbi_32.state = ln->ln_state;
3506
0
    nbi_32.asked = ln->ln_asked;
3507
0
    nbi_32.isrouter = ln->ln_router;
3508
0
    nbi_32.expire = (int)ln_getexpire(ln);
3509
0
    RT_REMREF_LOCKED(rt);
3510
0
    RT_UNLOCK(rt);
3511
0
    bcopy(&nbi_32, data, sizeof(nbi_32));
3512
0
    break;
3513
0
  }
3514
3515
0
  case SIOCGNBRINFO_IN6_64: {     /* struct in6_nbrinfo_64 */
3516
0
    struct llinfo_nd6 *ln;
3517
0
    struct in6_nbrinfo_64 nbi_64;
3518
0
    struct in6_addr nb_addr; /* make local for safety */
3519
3520
0
    bcopy(data, &nbi_64, sizeof(nbi_64));
3521
0
    nb_addr = nbi_64.addr;
3522
    /*
3523
     * XXX: KAME specific hack for scoped addresses
3524
     *      XXXX: for other scopes than link-local?
3525
     */
3526
0
    if (IN6_IS_ADDR_LINKLOCAL(&nbi_64.addr) ||
3527
0
        IN6_IS_ADDR_MC_LINKLOCAL(&nbi_64.addr)) {
3528
0
      u_int16_t *idp =
3529
0
          (u_int16_t *)(void *)&nb_addr.s6_addr[2];
3530
3531
0
      if (*idp == 0) {
3532
0
        *idp = htons(ifp->if_index);
3533
0
      }
3534
0
    }
3535
3536
    /* Callee returns a locked route upon success */
3537
0
    if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
3538
0
      error = EINVAL;
3539
0
      break;
3540
0
    }
3541
0
    RT_LOCK_ASSERT_HELD(rt);
3542
0
    ln = rt->rt_llinfo;
3543
0
    nbi_64.state = ln->ln_state;
3544
0
    nbi_64.asked = ln->ln_asked;
3545
0
    nbi_64.isrouter = ln->ln_router;
3546
0
    nbi_64.expire = (int)ln_getexpire(ln);
3547
0
    RT_REMREF_LOCKED(rt);
3548
0
    RT_UNLOCK(rt);
3549
0
    bcopy(&nbi_64, data, sizeof(nbi_64));
3550
0
    break;
3551
0
  }
3552
3553
0
  case SIOCGDEFIFACE_IN6_32:      /* struct in6_ndifreq_32 */
3554
0
  case SIOCGDEFIFACE_IN6_64: {    /* struct in6_ndifreq_64 */
3555
0
    struct in6_ndifreq_64 *ndif_64 =
3556
0
        (struct in6_ndifreq_64 *)(void *)data;
3557
0
    struct in6_ndifreq_32 *ndif_32 =
3558
0
        (struct in6_ndifreq_32 *)(void *)data;
3559
3560
0
    if (cmd == SIOCGDEFIFACE_IN6_64) {
3561
0
      u_int64_t j = nd6_defifindex;
3562
0
      __nochk_bcopy(&j, &ndif_64->ifindex, sizeof(j));
3563
0
    } else {
3564
0
      bcopy(&nd6_defifindex, &ndif_32->ifindex,
3565
0
          sizeof(u_int32_t));
3566
0
    }
3567
0
    break;
3568
0
  }
3569
3570
0
  case SIOCSDEFIFACE_IN6_32:      /* struct in6_ndifreq_32 */
3571
0
  case SIOCSDEFIFACE_IN6_64: {    /* struct in6_ndifreq_64 */
3572
0
    struct in6_ndifreq_64 *ndif_64 =
3573
0
        (struct in6_ndifreq_64 *)(void *)data;
3574
0
    struct in6_ndifreq_32 *ndif_32 =
3575
0
        (struct in6_ndifreq_32 *)(void *)data;
3576
0
    u_int32_t idx;
3577
3578
0
    if (cmd == SIOCSDEFIFACE_IN6_64) {
3579
0
      u_int64_t j;
3580
0
      __nochk_bcopy(&ndif_64->ifindex, &j, sizeof(j));
3581
0
      idx = (u_int32_t)j;
3582
0
    } else {
3583
0
      bcopy(&ndif_32->ifindex, &idx, sizeof(idx));
3584
0
    }
3585
3586
0
    error = nd6_setdefaultiface(idx);
3587
0
    return error;
3588
    /* NOTREACHED */
3589
0
  }
3590
0
  case SIOCGIFCGAPREP_IN6_32:
3591
0
  case SIOCGIFCGAPREP_IN6_64: {
3592
    /* get CGA parameters */
3593
0
    union {
3594
0
      struct in6_cgareq_32    *cga32;
3595
0
      struct in6_cgareq_64    *cga64;
3596
0
      void                    *data;
3597
0
    } cgareq_u;
3598
0
    struct nd_ifinfo        *ndi;
3599
0
    struct in6_cga_modifier *ndi_cga_mod;
3600
0
    struct in6_cga_modifier *req_cga_mod;
3601
3602
0
    ndi = ND_IFINFO(ifp);
3603
0
    if ((NULL == ndi) || !ndi->initialized) {
3604
0
      error = EINVAL;
3605
0
      break;
3606
0
    }
3607
0
    cgareq_u.data = data;
3608
0
    req_cga_mod = (cmd == SIOCGIFCGAPREP_IN6_64)
3609
0
        ? &(cgareq_u.cga64->cgar_cgaprep.cga_modifier)
3610
0
        : &(cgareq_u.cga32->cgar_cgaprep.cga_modifier);
3611
0
    lck_mtx_lock(&ndi->lock);
3612
0
    ndi_cga_mod = &(ndi->local_cga_modifier);
3613
0
    bcopy(ndi_cga_mod, req_cga_mod, sizeof(*req_cga_mod));
3614
0
    lck_mtx_unlock(&ndi->lock);
3615
0
    break;
3616
0
  }
3617
0
  case SIOCSIFCGAPREP_IN6_32:
3618
0
  case SIOCSIFCGAPREP_IN6_64:
3619
0
  {
3620
    /* set CGA parameters */
3621
0
    struct in6_cgareq       cgareq;
3622
0
    int                     is64;
3623
0
    struct nd_ifinfo        *ndi;
3624
0
    struct in6_cga_modifier *ndi_cga_mod;
3625
0
    struct in6_cga_modifier *req_cga_mod;
3626
3627
0
    ndi = ND_IFINFO(ifp);
3628
0
    if ((NULL == ndi) || !ndi->initialized) {
3629
0
      error = EINVAL;
3630
0
      break;
3631
0
    }
3632
0
    is64 = (cmd == SIOCSIFCGAPREP_IN6_64);
3633
0
    in6_cgareq_copy_from_user(data, is64, &cgareq);
3634
0
    req_cga_mod = &cgareq.cgar_cgaprep.cga_modifier;
3635
0
    lck_mtx_lock(&ndi->lock);
3636
0
    ndi_cga_mod = &(ndi->local_cga_modifier);
3637
0
    bcopy(req_cga_mod, ndi_cga_mod, sizeof(*ndi_cga_mod));
3638
0
    ndi->cga_initialized = TRUE;
3639
0
    ndi->cga_collision_count = 0;
3640
0
    lck_mtx_unlock(&ndi->lock);
3641
0
    break;
3642
0
  }
3643
0
  default:
3644
0
    break;
3645
0
  }
3646
0
  return error;
3647
0
}
3648
3649
/*
3650
 * Create neighbor cache entry and cache link-layer address,
3651
 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
3652
 */
3653
void
3654
nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
3655
    int lladdrlen, int type, int code)
3656
4.23k
{
3657
4.23k
#pragma unused(lladdrlen)
3658
4.23k
  struct rtentry *rt = NULL;
3659
4.23k
  struct llinfo_nd6 *ln = NULL;
3660
4.23k
  int is_newentry;
3661
4.23k
  struct sockaddr_dl *sdl = NULL;
3662
4.23k
  int do_update;
3663
4.23k
  int olladdr;
3664
4.23k
  int llchange;
3665
4.23k
  short newstate = 0;
3666
4.23k
  uint64_t timenow;
3667
4.23k
  boolean_t sched_timeout = FALSE;
3668
4.23k
  struct nd_ifinfo *ndi = NULL;
3669
3670
4.23k
  if (ifp == NULL) {
3671
0
    panic("ifp == NULL in nd6_cache_lladdr");
3672
0
  }
3673
4.23k
  if (from == NULL) {
3674
0
    panic("from == NULL in nd6_cache_lladdr");
3675
0
  }
3676
3677
  /* nothing must be updated for unspecified address */
3678
4.23k
  if (IN6_IS_ADDR_UNSPECIFIED(from)) {
3679
0
    return;
3680
0
  }
3681
3682
  /*
3683
   * Validation about ifp->if_addrlen and lladdrlen must be done in
3684
   * the caller.
3685
   */
3686
4.23k
  timenow = net_uptime();
3687
3688
4.23k
  rt = nd6_lookup(from, 0, ifp, 0);
3689
4.23k
  if (rt == NULL) {
3690
21
    if ((rt = nd6_lookup(from, 1, ifp, 0)) == NULL) {
3691
0
      return;
3692
0
    }
3693
21
    RT_LOCK_ASSERT_HELD(rt);
3694
21
    is_newentry = 1;
3695
4.21k
  } else {
3696
4.21k
    RT_LOCK_ASSERT_HELD(rt);
3697
    /* do nothing if static ndp is set */
3698
4.21k
    if (rt->rt_flags & RTF_STATIC) {
3699
0
      RT_REMREF_LOCKED(rt);
3700
0
      RT_UNLOCK(rt);
3701
0
      return;
3702
0
    }
3703
4.21k
    is_newentry = 0;
3704
4.21k
  }
3705
3706
4.23k
  if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
3707
0
fail:
3708
0
    RT_UNLOCK(rt);
3709
0
    nd6_free(rt);
3710
0
    rtfree(rt);
3711
0
    return;
3712
0
  }
3713
4.23k
  ln = (struct llinfo_nd6 *)rt->rt_llinfo;
3714
4.23k
  if (ln == NULL) {
3715
0
    goto fail;
3716
0
  }
3717
4.23k
  if (rt->rt_gateway == NULL) {
3718
0
    goto fail;
3719
0
  }
3720
4.23k
  if (rt->rt_gateway->sa_family != AF_LINK) {
3721
0
    goto fail;
3722
0
  }
3723
4.23k
  sdl = SDL(rt->rt_gateway);
3724
3725
4.23k
  olladdr = (sdl->sdl_alen) ? 1 : 0;
3726
4.23k
  if (olladdr && lladdr) {
3727
0
    if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen)) {
3728
0
      llchange = 1;
3729
0
    } else {
3730
0
      llchange = 0;
3731
0
    }
3732
4.23k
  } else {
3733
4.23k
    llchange = 0;
3734
4.23k
  }
3735
3736
  /*
3737
   * newentry olladdr  lladdr  llchange (*=record)
3738
   *  0 n n --  (1)
3739
   *  0 y n --  (2)
3740
   *  0 n y --  (3) * STALE
3741
   *  0 y y n (4) *
3742
   *  0 y y y (5) * STALE
3743
   *  1 --  n --  (6)   NOSTATE(= PASSIVE)
3744
   *  1 --  y --  (7) * STALE
3745
   */
3746
3747
4.23k
  if (lladdr != NULL) {           /* (3-5) and (7) */
3748
    /*
3749
     * Record source link-layer address
3750
     * XXX is it dependent to ifp->if_type?
3751
     */
3752
3.75k
    sdl->sdl_alen = ifp->if_addrlen;
3753
3.75k
    bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
3754
3755
    /* cache the gateway (sender HW) address */
3756
3.75k
    nd6_llreach_alloc(rt, ifp, LLADDR(sdl), sdl->sdl_alen, FALSE);
3757
3.75k
  }
3758
3759
4.23k
  if (is_newentry == 0) {
3760
4.21k
    if ((!olladdr && lladdr != NULL) ||     /* (3) */
3761
4.21k
        (olladdr && lladdr != NULL && llchange)) {  /* (5) */
3762
3.74k
      do_update = 1;
3763
3.74k
      newstate = ND6_LLINFO_STALE;
3764
3.74k
    } else {                                /* (1-2,4) */
3765
467
      do_update = 0;
3766
467
    }
3767
4.21k
  } else {
3768
21
    do_update = 1;
3769
21
    if (lladdr == NULL) {                   /* (6) */
3770
9
      newstate = ND6_LLINFO_NOSTATE;
3771
12
    } else {                                /* (7) */
3772
12
      newstate = ND6_LLINFO_STALE;
3773
12
    }
3774
21
  }
3775
3776
  /*
3777
   * For interface's that do not perform NUD
3778
   * neighbor cache entres must always be marked
3779
   * reachable with no expiry
3780
   */
3781
4.23k
  ndi = ND_IFINFO(ifp);
3782
4.23k
  VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
3783
3784
4.23k
  if (ndi && !(ndi->flags & ND6_IFF_PERFORMNUD)) {
3785
0
    newstate = ND6_LLINFO_REACHABLE;
3786
0
    ln_setexpire(ln, 0);
3787
0
  }
3788
3789
4.23k
  if (do_update) {
3790
    /*
3791
     * Update the state of the neighbor cache.
3792
     */
3793
3.76k
    ND6_CACHE_STATE_TRANSITION(ln, newstate);
3794
3795
3.76k
    if ((ln->ln_state == ND6_LLINFO_STALE) ||
3796
3.76k
        (ln->ln_state == ND6_LLINFO_REACHABLE)) {
3797
3.75k
      struct mbuf *m = ln->ln_hold;
3798
      /*
3799
       * XXX: since nd6_output() below will cause
3800
       * state tansition to DELAY and reset the timer,
3801
       * we must set the timer now, although it is actually
3802
       * meaningless.
3803
       */
3804
3.75k
      if (ln->ln_state == ND6_LLINFO_STALE) {
3805
3.75k
        ln_setexpire(ln, timenow + nd6_gctimer);
3806
3.75k
      }
3807
3808
3.75k
      ln->ln_hold = NULL;
3809
3.75k
      if (m != NULL) {
3810
0
        struct sockaddr_in6 sin6;
3811
3812
0
        rtkey_to_sa6(rt, &sin6);
3813
        /*
3814
         * we assume ifp is not a p2p here, so just
3815
         * set the 2nd argument as the 1st one.
3816
         */
3817
0
        RT_UNLOCK(rt);
3818
0
        nd6_output_list(ifp, ifp, m, &sin6, rt, NULL);
3819
0
        RT_LOCK(rt);
3820
0
      }
3821
3.75k
    } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
3822
      /* probe right away */
3823
0
      ln_setexpire(ln, timenow);
3824
0
      sched_timeout = TRUE;
3825
0
    }
3826
3.76k
  }
3827
3828
  /*
3829
   * ICMP6 type dependent behavior.
3830
   *
3831
   * NS: clear IsRouter if new entry
3832
   * RS: clear IsRouter
3833
   * RA: set IsRouter if there's lladdr
3834
   * redir: clear IsRouter if new entry
3835
   *
3836
   * RA case, (1):
3837
   * The spec says that we must set IsRouter in the following cases:
3838
   * - If lladdr exist, set IsRouter.  This means (1-5).
3839
   * - If it is old entry (!newentry), set IsRouter.  This means (7).
3840
   * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
3841
   * A quetion arises for (1) case.  (1) case has no lladdr in the
3842
   * neighbor cache, this is similar to (6).
3843
   * This case is rare but we figured that we MUST NOT set IsRouter.
3844
   *
3845
   * newentry olladdr  lladdr  llchange     NS  RS  RA  redir
3846
   *                D R
3847
   *  0 n n --  (1) c ? s
3848
   *  0 y n --  (2) c s s
3849
   *  0 n y --  (3) c s s
3850
   *  0 y y n (4) c s s
3851
   *  0 y y y (5) c s s
3852
   *  1 --  n --  (6) c c   c s
3853
   *  1 --  y --  (7) c c s c s
3854
   *
3855
   *          (c=clear s=set)
3856
   */
3857
4.23k
  switch (type & 0xff) {
3858
4.23k
  case ND_NEIGHBOR_SOLICIT:
3859
    /*
3860
     * New entry must have is_router flag cleared.
3861
     */
3862
4.23k
    if (is_newentry) {      /* (6-7) */
3863
21
      ln->ln_router = 0;
3864
21
    }
3865
4.23k
    break;
3866
0
  case ND_REDIRECT:
3867
    /*
3868
     * If the ICMP message is a Redirect to a better router, always
3869
     * set the is_router flag.  Otherwise, if the entry is newly
3870
     * created, then clear the flag.  [RFC 4861, sec 8.3]
3871
     */
3872
0
    if (code == ND_REDIRECT_ROUTER) {
3873
0
      ln->ln_router = 1;
3874
0
    } else if (is_newentry) { /* (6-7) */
3875
0
      ln->ln_router = 0;
3876
0
    }
3877
0
    break;
3878
0
  case ND_ROUTER_SOLICIT:
3879
    /*
3880
     * is_router flag must always be cleared.
3881
     */
3882
0
    ln->ln_router = 0;
3883
0
    break;
3884
0
  case ND_ROUTER_ADVERT:
3885
    /*
3886
     * Mark an entry with lladdr as a router.
3887
     */
3888
0
    if ((!is_newentry && (olladdr || lladdr)) ||    /* (2-5) */
3889
0
        (is_newentry && lladdr)) {                  /* (7) */
3890
0
      ln->ln_router = 1;
3891
0
    }
3892
0
    break;
3893
4.23k
  }
3894
3895
4.23k
  if (do_update) {
3896
3.76k
    int route_ev_code = 0;
3897
3898
3.76k
    if (llchange) {
3899
0
      route_ev_code = ROUTE_LLENTRY_CHANGED;
3900
3.76k
    } else {
3901
3.76k
      route_ev_code = ROUTE_LLENTRY_RESOLVED;
3902
3.76k
    }
3903
3904
    /* Enqueue work item to invoke callback for this route entry */
3905
3.76k
    route_event_enqueue_nwk_wq_entry(rt, NULL, route_ev_code, NULL, TRUE);
3906
3907
3.76k
    if (ln->ln_router || (rt->rt_flags & RTF_ROUTER)) {
3908
586
      struct radix_node_head  *rnh = NULL;
3909
586
      struct route_event rt_ev;
3910
586
      route_event_init(&rt_ev, rt, NULL, llchange ? ROUTE_LLENTRY_CHANGED :
3911
586
          ROUTE_LLENTRY_RESOLVED);
3912
      /*
3913
       * We already have a valid reference on rt.
3914
       * The function frees that before returning.
3915
       * We therefore don't need an extra reference here
3916
       */
3917
586
      RT_UNLOCK(rt);
3918
586
      lck_mtx_lock(rnh_lock);
3919
3920
586
      rnh = rt_tables[AF_INET6];
3921
586
      if (rnh != NULL) {
3922
586
        (void) rnh->rnh_walktree(rnh, route_event_walktree,
3923
586
            (void *)&rt_ev);
3924
586
      }
3925
586
      lck_mtx_unlock(rnh_lock);
3926
586
      RT_LOCK(rt);
3927
586
    }
3928
3.76k
  }
3929
3930
  /*
3931
   * When the link-layer address of a router changes, select the
3932
   * best router again.  In particular, when the neighbor entry is newly
3933
   * created, it might affect the selection policy.
3934
   * Question: can we restrict the first condition to the "is_newentry"
3935
   * case?
3936
   *
3937
   * Note: Perform default router selection even when we are a router,
3938
   * if Scoped Routing is enabled.
3939
   */
3940
4.23k
  if (do_update && ln->ln_router) {
3941
    /*
3942
     * XXX TODO: This should also be iterated over router list
3943
     * for route information option's router lists as well.
3944
     */
3945
586
    RT_REMREF_LOCKED(rt);
3946
586
    RT_UNLOCK(rt);
3947
586
    lck_mtx_lock(nd6_mutex);
3948
586
    defrouter_select(ifp, NULL);
3949
586
    nd6_router_select_rti_entries(ifp);
3950
586
    lck_mtx_unlock(nd6_mutex);
3951
3.64k
  } else {
3952
3.64k
    RT_REMREF_LOCKED(rt);
3953
3.64k
    RT_UNLOCK(rt);
3954
3.64k
  }
3955
4.23k
  if (sched_timeout) {
3956
0
    lck_mtx_lock(rnh_lock);
3957
0
    nd6_sched_timeout(NULL, NULL);
3958
0
    lck_mtx_unlock(rnh_lock);
3959
0
  }
3960
4.23k
}
3961
3962
void
3963
nd6_slowtimo(void *arg)
3964
408k
{
3965
408k
#pragma unused(arg)
3966
408k
  struct nd_ifinfo *nd6if = NULL;
3967
408k
  struct ifnet *ifp = NULL;
3968
3969
408k
  ifnet_head_lock_shared();
3970
1.22M
  for (ifp = ifnet_head.tqh_first; ifp;
3971
817k
      ifp = ifp->if_link.tqe_next) {
3972
817k
    nd6if = ND_IFINFO(ifp);
3973
817k
    if ((NULL == nd6if) || (FALSE == nd6if->initialized)) {
3974
408k
      continue;
3975
408k
    }
3976
3977
408k
    lck_mtx_lock(&nd6if->lock);
3978
408k
    if (nd6if->basereachable && /* already initialized */
3979
408k
        (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
3980
      /*
3981
       * Since reachable time rarely changes by router
3982
       * advertisements, we SHOULD insure that a new random
3983
       * value gets recomputed at least once every few hours.
3984
       * (RFC 4861, 6.3.4)
3985
       */
3986
204k
      nd6if->recalctm = nd6_recalc_reachtm_interval;
3987
204k
      nd6if->reachable =
3988
204k
          ND_COMPUTE_RTIME(nd6if->basereachable);
3989
204k
    }
3990
408k
    lck_mtx_unlock(&nd6if->lock);
3991
408k
  }
3992
408k
  ifnet_head_done();
3993
  // timeout(nd6_slowtimo, NULL, ND6_SLOWTIMER_INTERVAL * hz);
3994
408k
}
3995
3996
int
3997
nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
3998
    struct sockaddr_in6 *dst, struct rtentry *hint0, struct flowadv *adv)
3999
0
{
4000
0
  return nd6_output_list(ifp, origifp, m0, dst, hint0, adv);
4001
0
}
4002
4003
/*
4004
 * nd6_output_list()
4005
 *
4006
 * Assumption: route determination for first packet can be correctly applied to
4007
 * all packets in the chain.
4008
 */
4009
0
#define senderr(e) { error = (e); goto bad; }
4010
int
4011
nd6_output_list(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
4012
    struct sockaddr_in6 *dst, struct rtentry *hint0, struct flowadv *adv)
4013
11.7k
{
4014
11.7k
  struct rtentry *rt = hint0, *hint = hint0;
4015
11.7k
  struct llinfo_nd6 *ln = NULL;
4016
11.7k
  int error = 0;
4017
11.7k
  uint64_t timenow;
4018
11.7k
  struct rtentry *rtrele = NULL;
4019
11.7k
  struct nd_ifinfo *ndi = NULL;
4020
4021
11.7k
  if (rt != NULL) {
4022
11.7k
    RT_LOCK_SPIN(rt);
4023
11.7k
    RT_ADDREF_LOCKED(rt);
4024
11.7k
  }
4025
4026
11.7k
  if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr) || !nd6_need_cache(ifp)) {
4027
11.7k
    if (rt != NULL) {
4028
11.7k
      RT_UNLOCK(rt);
4029
11.7k
    }
4030
11.7k
    goto sendpkt;
4031
11.7k
  }
4032
4033
  /*
4034
   * Next hop determination.  Because we may involve the gateway route
4035
   * in addition to the original route, locking is rather complicated.
4036
   * The general concept is that regardless of whether the route points
4037
   * to the original route or to the gateway route, this routine takes
4038
   * an extra reference on such a route.  This extra reference will be
4039
   * released at the end.
4040
   *
4041
   * Care must be taken to ensure that the "hint0" route never gets freed
4042
   * via rtfree(), since the caller may have stored it inside a struct
4043
   * route with a reference held for that placeholder.
4044
   *
4045
   * This logic is similar to, though not exactly the same as the one
4046
   * used by route_to_gwroute().
4047
   */
4048
0
  if (rt != NULL) {
4049
    /*
4050
     * We have a reference to "rt" by now (or below via rtalloc1),
4051
     * which will either be released or freed at the end of this
4052
     * routine.
4053
     */
4054
0
    RT_LOCK_ASSERT_HELD(rt);
4055
0
    if (!(rt->rt_flags & RTF_UP)) {
4056
0
      RT_REMREF_LOCKED(rt);
4057
0
      RT_UNLOCK(rt);
4058
0
      if ((hint = rt = rtalloc1_scoped(SA(dst), 1, 0,
4059
0
          ifp->if_index)) != NULL) {
4060
0
        RT_LOCK_SPIN(rt);
4061
0
        if (rt->rt_ifp != ifp) {
4062
          /* XXX: loop care? */
4063
0
          RT_UNLOCK(rt);
4064
0
          error = nd6_output_list(ifp, origifp, m0,
4065
0
              dst, rt, adv);
4066
0
          rtfree(rt);
4067
0
          return error;
4068
0
        }
4069
0
      } else {
4070
0
        senderr(EHOSTUNREACH);
4071
0
      }
4072
0
    }
4073
4074
0
    if (rt->rt_flags & RTF_GATEWAY) {
4075
0
      struct rtentry *gwrt;
4076
0
      struct in6_ifaddr *ia6 = NULL;
4077
0
      struct sockaddr_in6 gw6;
4078
4079
0
      rtgw_to_sa6(rt, &gw6);
4080
      /*
4081
       * Must drop rt_lock since nd6_is_addr_neighbor()
4082
       * calls nd6_lookup() and acquires rnh_lock.
4083
       */
4084
0
      RT_UNLOCK(rt);
4085
4086
      /*
4087
       * We skip link-layer address resolution and NUD
4088
       * if the gateway is not a neighbor from ND point
4089
       * of view, regardless of the value of nd_ifinfo.flags.
4090
       * The second condition is a bit tricky; we skip
4091
       * if the gateway is our own address, which is
4092
       * sometimes used to install a route to a p2p link.
4093
       */
4094
0
      if (!nd6_is_addr_neighbor(&gw6, ifp, 0) ||
4095
0
          (ia6 = in6ifa_ifpwithaddr(ifp, &gw6.sin6_addr))) {
4096
        /*
4097
         * We allow this kind of tricky route only
4098
         * when the outgoing interface is p2p.
4099
         * XXX: we may need a more generic rule here.
4100
         */
4101
0
        if (ia6 != NULL) {
4102
0
          IFA_REMREF(&ia6->ia_ifa);
4103
0
        }
4104
0
        if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
4105
0
          senderr(EHOSTUNREACH);
4106
0
        }
4107
0
        goto sendpkt;
4108
0
      }
4109
4110
0
      RT_LOCK_SPIN(rt);
4111
0
      gw6 = *(SIN6(rt->rt_gateway));
4112
4113
      /* If hint is now down, give up */
4114
0
      if (!(rt->rt_flags & RTF_UP)) {
4115
0
        RT_UNLOCK(rt);
4116
0
        senderr(EHOSTUNREACH);
4117
0
      }
4118
4119
      /* If there's no gateway route, look it up */
4120
0
      if ((gwrt = rt->rt_gwroute) == NULL) {
4121
0
        RT_UNLOCK(rt);
4122
0
        goto lookup;
4123
0
      }
4124
      /* Become a regular mutex */
4125
0
      RT_CONVERT_LOCK(rt);
4126
4127
      /*
4128
       * Take gwrt's lock while holding route's lock;
4129
       * this is okay since gwrt never points back
4130
       * to rt, so no lock ordering issues.
4131
       */
4132
0
      RT_LOCK_SPIN(gwrt);
4133
0
      if (!(gwrt->rt_flags & RTF_UP)) {
4134
0
        rt->rt_gwroute = NULL;
4135
0
        RT_UNLOCK(gwrt);
4136
0
        RT_UNLOCK(rt);
4137
0
        rtfree(gwrt);
4138
0
lookup:
4139
0
        lck_mtx_lock(rnh_lock);
4140
0
        gwrt = rtalloc1_scoped_locked(SA(&gw6), 1, 0,
4141
0
            ifp->if_index);
4142
4143
0
        RT_LOCK(rt);
4144
        /*
4145
         * Bail out if the route is down, no route
4146
         * to gateway, circular route, or if the
4147
         * gateway portion of "rt" has changed.
4148
         */
4149
0
        if (!(rt->rt_flags & RTF_UP) ||
4150
0
            gwrt == NULL || gwrt == rt ||
4151
0
            !equal(SA(&gw6), rt->rt_gateway)) {
4152
0
          if (gwrt == rt) {
4153
0
            RT_REMREF_LOCKED(gwrt);
4154
0
            gwrt = NULL;
4155
0
          }
4156
0
          RT_UNLOCK(rt);
4157
0
          if (gwrt != NULL) {
4158
0
            rtfree_locked(gwrt);
4159
0
          }
4160
0
          lck_mtx_unlock(rnh_lock);
4161
0
          senderr(EHOSTUNREACH);
4162
0
        }
4163
0
        VERIFY(gwrt != NULL);
4164
        /*
4165
         * Set gateway route; callee adds ref to gwrt;
4166
         * gwrt has an extra ref from rtalloc1() for
4167
         * this routine.
4168
         */
4169
0
        rt_set_gwroute(rt, rt_key(rt), gwrt);
4170
0
        RT_UNLOCK(rt);
4171
0
        lck_mtx_unlock(rnh_lock);
4172
        /* Remember to release/free "rt" at the end */
4173
0
        rtrele = rt;
4174
0
        rt = gwrt;
4175
0
      } else {
4176
0
        RT_ADDREF_LOCKED(gwrt);
4177
0
        RT_UNLOCK(gwrt);
4178
0
        RT_UNLOCK(rt);
4179
        /* Remember to release/free "rt" at the end */
4180
0
        rtrele = rt;
4181
0
        rt = gwrt;
4182
0
      }
4183
0
      VERIFY(rt == gwrt);
4184
4185
      /*
4186
       * This is an opportunity to revalidate the parent
4187
       * route's gwroute, in case it now points to a dead
4188
       * route entry.  Parent route won't go away since the
4189
       * clone (hint) holds a reference to it.  rt == gwrt.
4190
       */
4191
0
      RT_LOCK_SPIN(hint);
4192
0
      if ((hint->rt_flags & (RTF_WASCLONED | RTF_UP)) ==
4193
0
          (RTF_WASCLONED | RTF_UP)) {
4194
0
        struct rtentry *prt = hint->rt_parent;
4195
0
        VERIFY(prt != NULL);
4196
4197
0
        RT_CONVERT_LOCK(hint);
4198
0
        RT_ADDREF(prt);
4199
0
        RT_UNLOCK(hint);
4200
0
        rt_revalidate_gwroute(prt, rt);
4201
0
        RT_REMREF(prt);
4202
0
      } else {
4203
0
        RT_UNLOCK(hint);
4204
0
      }
4205
4206
0
      RT_LOCK_SPIN(rt);
4207
      /* rt == gwrt; if it is now down, give up */
4208
0
      if (!(rt->rt_flags & RTF_UP)) {
4209
0
        RT_UNLOCK(rt);
4210
0
        rtfree(rt);
4211
0
        rt = NULL;
4212
        /* "rtrele" == original "rt" */
4213
0
        senderr(EHOSTUNREACH);
4214
0
      }
4215
0
    }
4216
4217
    /* Become a regular mutex */
4218
0
    RT_CONVERT_LOCK(rt);
4219
0
  }
4220
4221
  /*
4222
   * Address resolution or Neighbor Unreachability Detection
4223
   * for the next hop.
4224
   * At this point, the destination of the packet must be a unicast
4225
   * or an anycast address(i.e. not a multicast).
4226
   */
4227
4228
  /* Look up the neighbor cache for the nexthop */
4229
0
  if (rt && (rt->rt_flags & RTF_LLINFO) != 0) {
4230
0
    ln = rt->rt_llinfo;
4231
0
  } else {
4232
0
    struct sockaddr_in6 sin6;
4233
    /*
4234
     * Clear out Scope ID field in case it is set.
4235
     */
4236
0
    sin6 = *dst;
4237
0
    sin6.sin6_scope_id = 0;
4238
    /*
4239
     * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
4240
     * the condition below is not very efficient.  But we believe
4241
     * it is tolerable, because this should be a rare case.
4242
     * Must drop rt_lock since nd6_is_addr_neighbor() calls
4243
     * nd6_lookup() and acquires rnh_lock.
4244
     */
4245
0
    if (rt != NULL) {
4246
0
      RT_UNLOCK(rt);
4247
0
    }
4248
0
    if (nd6_is_addr_neighbor(&sin6, ifp, 0)) {
4249
      /* "rtrele" may have been used, so clean up "rt" now */
4250
0
      if (rt != NULL) {
4251
        /* Don't free "hint0" */
4252
0
        if (rt == hint0) {
4253
0
          RT_REMREF(rt);
4254
0
        } else {
4255
0
          rtfree(rt);
4256
0
        }
4257
0
      }
4258
      /* Callee returns a locked route upon success */
4259
0
      rt = nd6_lookup(&dst->sin6_addr, 1, ifp, 0);
4260
0
      if (rt != NULL) {
4261
0
        RT_LOCK_ASSERT_HELD(rt);
4262
0
        ln = rt->rt_llinfo;
4263
0
      }
4264
0
    } else if (rt != NULL) {
4265
0
      RT_LOCK(rt);
4266
0
    }
4267
0
  }
4268
4269
0
  if (!ln || !rt) {
4270
0
    if (rt != NULL) {
4271
0
      RT_UNLOCK(rt);
4272
0
    }
4273
0
    ndi = ND_IFINFO(ifp);
4274
0
    VERIFY(ndi != NULL && ndi->initialized);
4275
0
    lck_mtx_lock(&ndi->lock);
4276
0
    if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
4277
0
        !(ndi->flags & ND6_IFF_PERFORMNUD)) {
4278
0
      lck_mtx_unlock(&ndi->lock);
4279
0
      log(LOG_DEBUG,
4280
0
          "nd6_output: can't allocate llinfo for %s "
4281
0
          "(ln=0x%llx, rt=0x%llx)\n",
4282
0
          ip6_sprintf(&dst->sin6_addr),
4283
0
          (uint64_t)VM_KERNEL_ADDRPERM(ln),
4284
0
          (uint64_t)VM_KERNEL_ADDRPERM(rt));
4285
0
      senderr(EIO);   /* XXX: good error? */
4286
0
    }
4287
0
    lck_mtx_unlock(&ndi->lock);
4288
4289
0
    goto sendpkt;   /* send anyway */
4290
0
  }
4291
4292
0
  net_update_uptime();
4293
0
  timenow = net_uptime();
4294
4295
  /* We don't have to do link-layer address resolution on a p2p link. */
4296
0
  if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
4297
0
      ln->ln_state < ND6_LLINFO_REACHABLE) {
4298
0
    ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_STALE);
4299
0
    ln_setexpire(ln, timenow + nd6_gctimer);
4300
0
  }
4301
4302
  /*
4303
   * The first time we send a packet to a neighbor whose entry is
4304
   * STALE, we have to change the state to DELAY and a sets a timer to
4305
   * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
4306
   * neighbor unreachability detection on expiration.
4307
   * (RFC 4861 7.3.3)
4308
   */
4309
0
  if (ln->ln_state == ND6_LLINFO_STALE) {
4310
0
    ln->ln_asked = 0;
4311
0
    ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_DELAY);
4312
0
    ln_setexpire(ln, timenow + nd6_delay);
4313
    /* N.B.: we will re-arm the timer below. */
4314
0
    _CASSERT(ND6_LLINFO_DELAY > ND6_LLINFO_INCOMPLETE);
4315
0
  }
4316
4317
  /*
4318
   * If the neighbor cache entry has a state other than INCOMPLETE
4319
   * (i.e. its link-layer address is already resolved), just
4320
   * send the packet.
4321
   */
4322
0
  if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
4323
0
    RT_UNLOCK(rt);
4324
    /*
4325
     * Move this entry to the head of the queue so that it is
4326
     * less likely for this entry to be a target of forced
4327
     * garbage collection (see nd6_rtrequest()).  Do this only
4328
     * if the entry is non-permanent (as permanent ones will
4329
     * never be purged), and if the number of active entries
4330
     * is at least half of the threshold.
4331
     */
4332
0
    if (ln->ln_state == ND6_LLINFO_DELAY ||
4333
0
        (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
4334
0
        nd6_inuse >= (ip6_neighborgcthresh >> 1))) {
4335
0
      lck_mtx_lock(rnh_lock);
4336
0
      if (ln->ln_state == ND6_LLINFO_DELAY) {
4337
0
        nd6_sched_timeout(NULL, NULL);
4338
0
      }
4339
0
      if (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
4340
0
          nd6_inuse >= (ip6_neighborgcthresh >> 1)) {
4341
0
        RT_LOCK_SPIN(rt);
4342
0
        if (ln->ln_flags & ND6_LNF_IN_USE) {
4343
0
          LN_DEQUEUE(ln);
4344
0
          LN_INSERTHEAD(ln);
4345
0
        }
4346
0
        RT_UNLOCK(rt);
4347
0
      }
4348
0
      lck_mtx_unlock(rnh_lock);
4349
0
    }
4350
0
    goto sendpkt;
4351
0
  }
4352
4353
  /*
4354
   * If this is a prefix proxy route, record the inbound interface
4355
   * so that it can be excluded from the list of interfaces eligible
4356
   * for forwarding the proxied NS in nd6_prproxy_ns_output().
4357
   */
4358
0
  if (rt->rt_flags & RTF_PROXY) {
4359
0
    ln->ln_exclifp = ((origifp == ifp) ? NULL : origifp);
4360
0
  }
4361
4362
  /*
4363
   * There is a neighbor cache entry, but no ethernet address
4364
   * response yet.  Replace the held mbuf (if any) with this
4365
   * latest one.
4366
   *
4367
   * This code conforms to the rate-limiting rule described in Section
4368
   * 7.2.2 of RFC 4861, because the timer is set correctly after sending
4369
   * an NS below.
4370
   */
4371
0
  if (ln->ln_state == ND6_LLINFO_NOSTATE) {
4372
0
    ND6_CACHE_STATE_TRANSITION(ln, ND6_LLINFO_INCOMPLETE);
4373
0
  }
4374
0
  if (ln->ln_hold) {
4375
0
    m_freem_list(ln->ln_hold);
4376
0
  }
4377
0
  ln->ln_hold = m0;
4378
0
  if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) {
4379
0
    ln->ln_asked++;
4380
0
    ndi = ND_IFINFO(ifp);
4381
0
    VERIFY(ndi != NULL && ndi->initialized);
4382
0
    lck_mtx_lock(&ndi->lock);
4383
0
    ln_setexpire(ln, timenow + ndi->retrans / 1000);
4384
0
    lck_mtx_unlock(&ndi->lock);
4385
0
    RT_UNLOCK(rt);
4386
    /* We still have a reference on rt (for ln) */
4387
0
    if (ip6_forwarding) {
4388
0
      nd6_prproxy_ns_output(ifp, origifp, NULL,
4389
0
          &dst->sin6_addr, ln);
4390
0
    } else {
4391
0
      nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, NULL);
4392
0
    }
4393
0
    lck_mtx_lock(rnh_lock);
4394
0
    nd6_sched_timeout(NULL, NULL);
4395
0
    lck_mtx_unlock(rnh_lock);
4396
0
  } else {
4397
0
    RT_UNLOCK(rt);
4398
0
  }
4399
  /*
4400
   * Move this entry to the head of the queue so that it is
4401
   * less likely for this entry to be a target of forced
4402
   * garbage collection (see nd6_rtrequest()).  Do this only
4403
   * if the entry is non-permanent (as permanent ones will
4404
   * never be purged), and if the number of active entries
4405
   * is at least half of the threshold.
4406
   */
4407
0
  if (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
4408
0
      nd6_inuse >= (ip6_neighborgcthresh >> 1)) {
4409
0
    lck_mtx_lock(rnh_lock);
4410
0
    RT_LOCK_SPIN(rt);
4411
0
    if (ln->ln_flags & ND6_LNF_IN_USE) {
4412
0
      LN_DEQUEUE(ln);
4413
0
      LN_INSERTHEAD(ln);
4414
0
    }
4415
    /* Clean up "rt" now while we can */
4416
0
    if (rt == hint0) {
4417
0
      RT_REMREF_LOCKED(rt);
4418
0
      RT_UNLOCK(rt);
4419
0
    } else {
4420
0
      RT_UNLOCK(rt);
4421
0
      rtfree_locked(rt);
4422
0
    }
4423
0
    rt = NULL;      /* "rt" has been taken care of */
4424
0
    lck_mtx_unlock(rnh_lock);
4425
0
  }
4426
0
  error = 0;
4427
0
  goto release;
4428
4429
11.7k
sendpkt:
4430
11.7k
  if (rt != NULL) {
4431
11.7k
    RT_LOCK_ASSERT_NOTHELD(rt);
4432
11.7k
  }
4433
4434
  /* discard the packet if IPv6 operation is disabled on the interface */
4435
11.7k
  if (ifp->if_eflags & IFEF_IPV6_DISABLED) {
4436
0
    error = ENETDOWN; /* better error? */
4437
0
    goto bad;
4438
0
  }
4439
4440
11.7k
  if (ifp->if_flags & IFF_LOOPBACK) {
4441
    /* forwarding rules require the original scope_id */
4442
11.7k
    m0->m_pkthdr.rcvif = origifp;
4443
11.7k
    error = dlil_output(origifp, PF_INET6, m0, (caddr_t)rt,
4444
11.7k
        SA(dst), 0, adv);
4445
11.7k
    goto release;
4446
11.7k
  } else {
4447
    /* Do not allow loopback address to wind up on a wire */
4448
0
    struct ip6_hdr *ip6 = mtod(m0, struct ip6_hdr *);
4449
4450
0
    if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
4451
0
        IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst))) {
4452
0
      ip6stat.ip6s_badscope++;
4453
0
      error = EADDRNOTAVAIL;
4454
0
      goto bad;
4455
0
    }
4456
0
  }
4457
4458
0
  if (rt != NULL) {
4459
0
    RT_LOCK_SPIN(rt);
4460
    /* Mark use timestamp */
4461
0
    if (rt->rt_llinfo != NULL) {
4462
0
      nd6_llreach_use(rt->rt_llinfo);
4463
0
    }
4464
0
    RT_UNLOCK(rt);
4465
0
  }
4466
4467
0
  struct mbuf *mcur = m0;
4468
0
  uint32_t pktcnt = 0;
4469
4470
0
  while (mcur) {
4471
0
    if (hint != NULL && nstat_collect) {
4472
0
      int scnt;
4473
4474
0
      if ((mcur->m_pkthdr.csum_flags & CSUM_TSO_IPV6) &&
4475
0
          (mcur->m_pkthdr.tso_segsz > 0)) {
4476
0
        scnt = mcur->m_pkthdr.len / mcur->m_pkthdr.tso_segsz;
4477
0
      } else {
4478
0
        scnt = 1;
4479
0
      }
4480
4481
0
      nstat_route_tx(hint, scnt, mcur->m_pkthdr.len, 0);
4482
0
    }
4483
0
    pktcnt++;
4484
4485
0
    mcur->m_pkthdr.rcvif = NULL;
4486
0
    mcur = mcur->m_nextpkt;
4487
0
  }
4488
0
  if (pktcnt > ip6_maxchainsent) {
4489
0
    ip6_maxchainsent = pktcnt;
4490
0
  }
4491
0
  error = dlil_output(ifp, PF_INET6, m0, (caddr_t)rt, SA(dst), 0, adv);
4492
0
  goto release;
4493
4494
0
bad:
4495
0
  if (m0 != NULL) {
4496
0
    m_freem_list(m0);
4497
0
  }
4498
4499
11.7k
release:
4500
  /* Clean up "rt" unless it's already been done */
4501
11.7k
  if (rt != NULL) {
4502
11.7k
    RT_LOCK_SPIN(rt);
4503
11.7k
    if (rt == hint0) {
4504
11.7k
      RT_REMREF_LOCKED(rt);
4505
11.7k
      RT_UNLOCK(rt);
4506
11.7k
    } else {
4507
0
      RT_UNLOCK(rt);
4508
0
      rtfree(rt);
4509
0
    }
4510
11.7k
  }
4511
  /* And now clean up "rtrele" if there is any */
4512
11.7k
  if (rtrele != NULL) {
4513
0
    RT_LOCK_SPIN(rtrele);
4514
0
    if (rtrele == hint0) {
4515
0
      RT_REMREF_LOCKED(rtrele);
4516
0
      RT_UNLOCK(rtrele);
4517
0
    } else {
4518
0
      RT_UNLOCK(rtrele);
4519
0
      rtfree(rtrele);
4520
0
    }
4521
0
  }
4522
11.7k
  return error;
4523
0
}
4524
#undef senderr
4525
4526
int
4527
nd6_need_cache(struct ifnet *ifp)
4528
11.7k
{
4529
  /*
4530
   * XXX: we currently do not make neighbor cache on any interface
4531
   * other than ARCnet, Ethernet, FDDI and GIF.
4532
   *
4533
   * RFC2893 says:
4534
   * - unidirectional tunnels needs no ND
4535
   */
4536
11.7k
  switch (ifp->if_type) {
4537
0
  case IFT_ARCNET:
4538
0
  case IFT_ETHER:
4539
0
  case IFT_FDDI:
4540
0
  case IFT_IEEE1394:
4541
0
  case IFT_L2VLAN:
4542
0
  case IFT_IEEE8023ADLAG:
4543
#if IFT_IEEE80211
4544
  case IFT_IEEE80211:
4545
#endif
4546
0
  case IFT_GIF:           /* XXX need more cases? */
4547
0
  case IFT_PPP:
4548
#if IFT_TUNNEL
4549
  case IFT_TUNNEL:
4550
#endif
4551
0
  case IFT_BRIDGE:
4552
0
  case IFT_CELLULAR:
4553
0
  case IFT_6LOWPAN:
4554
0
    return 1;
4555
11.7k
  default:
4556
11.7k
    return 0;
4557
11.7k
  }
4558
11.7k
}
4559
4560
int
4561
nd6_storelladdr(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
4562
    struct sockaddr *dst, u_char *desten)
4563
0
{
4564
0
  int i;
4565
0
  struct sockaddr_dl *sdl;
4566
4567
0
  if (m->m_flags & M_MCAST) {
4568
0
    switch (ifp->if_type) {
4569
0
    case IFT_ETHER:
4570
0
    case IFT_FDDI:
4571
0
    case IFT_L2VLAN:
4572
0
    case IFT_IEEE8023ADLAG:
4573
#if IFT_IEEE80211
4574
    case IFT_IEEE80211:
4575
#endif
4576
0
    case IFT_BRIDGE:
4577
0
      ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr, desten);
4578
0
      return 1;
4579
0
    case IFT_IEEE1394:
4580
0
      for (i = 0; i < ifp->if_addrlen; i++) {
4581
0
        desten[i] = ~0;
4582
0
      }
4583
0
      return 1;
4584
0
    case IFT_ARCNET:
4585
0
      *desten = 0;
4586
0
      return 1;
4587
0
    default:
4588
0
      return 0; /* caller will free mbuf */
4589
0
    }
4590
0
  }
4591
4592
0
  if (rt == NULL) {
4593
    /* this could happen, if we could not allocate memory */
4594
0
    return 0; /* caller will free mbuf */
4595
0
  }
4596
0
  RT_LOCK(rt);
4597
0
  if (rt->rt_gateway->sa_family != AF_LINK) {
4598
0
    printf("nd6_storelladdr: something odd happens\n");
4599
0
    RT_UNLOCK(rt);
4600
0
    return 0; /* caller will free mbuf */
4601
0
  }
4602
0
  sdl = SDL(rt->rt_gateway);
4603
0
  if (sdl->sdl_alen == 0) {
4604
    /* this should be impossible, but we bark here for debugging */
4605
0
    printf("nd6_storelladdr: sdl_alen == 0\n");
4606
0
    RT_UNLOCK(rt);
4607
0
    return 0; /* caller will free mbuf */
4608
0
  }
4609
4610
0
  bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
4611
0
  RT_UNLOCK(rt);
4612
0
  return 1;
4613
0
}
4614
4615
/*
4616
 * This is the ND pre-output routine; care must be taken to ensure that
4617
 * the "hint" route never gets freed via rtfree(), since the caller may
4618
 * have stored it inside a struct route with a reference held for that
4619
 * placeholder.
4620
 */
4621
errno_t
4622
nd6_lookup_ipv6(ifnet_t  ifp, const struct sockaddr_in6 *ip6_dest,
4623
    struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint,
4624
    mbuf_t packet)
4625
0
{
4626
0
  route_t route = hint;
4627
0
  errno_t result = 0;
4628
0
  struct sockaddr_dl *sdl = NULL;
4629
0
  size_t  copy_len;
4630
4631
0
  if (ifp == NULL || ip6_dest == NULL) {
4632
0
    return EINVAL;
4633
0
  }
4634
4635
0
  if (ip6_dest->sin6_family != AF_INET6) {
4636
0
    return EAFNOSUPPORT;
4637
0
  }
4638
4639
0
  if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING)) {
4640
0
    return ENETDOWN;
4641
0
  }
4642
4643
0
  if (hint != NULL) {
4644
    /*
4645
     * Callee holds a reference on the route and returns
4646
     * with the route entry locked, upon success.
4647
     */
4648
0
    result = route_to_gwroute((const struct sockaddr *)ip6_dest,
4649
0
        hint, &route);
4650
0
    if (result != 0) {
4651
0
      return result;
4652
0
    }
4653
0
    if (route != NULL) {
4654
0
      RT_LOCK_ASSERT_HELD(route);
4655
0
    }
4656
0
  }
4657
4658
0
  if ((packet != NULL && (packet->m_flags & M_MCAST) != 0) ||
4659
0
      ((ifp->if_flags & IFF_MULTICAST) &&
4660
0
      IN6_IS_ADDR_MULTICAST(&ip6_dest->sin6_addr))) {
4661
0
    if (route != NULL) {
4662
0
      RT_UNLOCK(route);
4663
0
    }
4664
0
    result = dlil_resolve_multi(ifp,
4665
0
        (const struct sockaddr *)ip6_dest,
4666
0
        SA(ll_dest), ll_dest_len);
4667
0
    if (route != NULL) {
4668
0
      RT_LOCK(route);
4669
0
    }
4670
0
    goto release;
4671
0
  } else if (route == NULL) {
4672
    /*
4673
     * rdar://24596652
4674
     * For unicast, lookup existing ND6 entries but
4675
     * do not trigger a resolution
4676
     */
4677
0
    lck_mtx_lock(rnh_lock);
4678
0
    route = rt_lookup(TRUE,
4679
0
        __DECONST(struct sockaddr *, ip6_dest), NULL,
4680
0
        rt_tables[AF_INET6], ifp->if_index);
4681
0
    lck_mtx_unlock(rnh_lock);
4682
4683
0
    if (route != NULL) {
4684
0
      RT_LOCK(route);
4685
0
    }
4686
0
  }
4687
4688
0
  if (route == NULL) {
4689
    /*
4690
     * This could happen, if we could not allocate memory or
4691
     * if route_to_gwroute() didn't return a route.
4692
     */
4693
0
    result = ENOBUFS;
4694
0
    goto release;
4695
0
  }
4696
4697
0
  if (route->rt_gateway->sa_family != AF_LINK) {
4698
0
    nd6log0(error, "%s: route %s on %s%d gateway address not AF_LINK\n",
4699
0
        __func__, ip6_sprintf(&ip6_dest->sin6_addr),
4700
0
        route->rt_ifp->if_name, route->rt_ifp->if_unit);
4701
0
    result = EADDRNOTAVAIL;
4702
0
    goto release;
4703
0
  }
4704
4705
0
  sdl = SDL(route->rt_gateway);
4706
0
  if (sdl->sdl_alen == 0) {
4707
    /* this should be impossible, but we bark here for debugging */
4708
0
    nd6log(error, "%s: route %s on %s%d sdl_alen == 0\n", __func__,
4709
0
        ip6_sprintf(&ip6_dest->sin6_addr), route->rt_ifp->if_name,
4710
0
        route->rt_ifp->if_unit);
4711
0
    result = EHOSTUNREACH;
4712
0
    goto release;
4713
0
  }
4714
4715
0
  copy_len = sdl->sdl_len <= ll_dest_len ? sdl->sdl_len : ll_dest_len;
4716
0
  bcopy(sdl, ll_dest, copy_len);
4717
4718
0
release:
4719
0
  if (route != NULL) {
4720
0
    if (route == hint) {
4721
0
      RT_REMREF_LOCKED(route);
4722
0
      RT_UNLOCK(route);
4723
0
    } else {
4724
0
      RT_UNLOCK(route);
4725
0
      rtfree(route);
4726
0
    }
4727
0
  }
4728
0
  return result;
4729
0
}
4730
4731
#if (DEVELOPMENT || DEBUG)
4732
4733
static int sysctl_nd6_lookup_ipv6 SYSCTL_HANDLER_ARGS;
4734
SYSCTL_PROC(_net_inet6_icmp6, OID_AUTO, nd6_lookup_ipv6,
4735
    CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
4736
    sysctl_nd6_lookup_ipv6, "S", "");
4737
4738
int
4739
sysctl_nd6_lookup_ipv6 SYSCTL_HANDLER_ARGS
4740
0
{
4741
0
#pragma unused(oidp, arg1, arg2)
4742
0
  int error = 0;
4743
0
  struct nd6_lookup_ipv6_args nd6_lookup_ipv6_args;
4744
0
  ifnet_t ifp = NULL;
4745
4746
  /*
4747
   * Only root can lookup MAC addresses
4748
   */
4749
0
  error = proc_suser(current_proc());
4750
0
  if (error != 0) {
4751
0
    nd6log0(error, "%s: proc_suser() error %d\n",
4752
0
        __func__, error);
4753
0
    goto done;
4754
0
  }
4755
0
  if (req->oldptr == USER_ADDR_NULL) {
4756
0
    req->oldidx = sizeof(struct nd6_lookup_ipv6_args);
4757
0
  }
4758
0
  if (req->newptr == USER_ADDR_NULL) {
4759
0
    goto done;
4760
0
  }
4761
0
  if (req->oldlen != sizeof(struct nd6_lookup_ipv6_args) ||
4762
0
      req->newlen != sizeof(struct nd6_lookup_ipv6_args)) {
4763
0
    error = EINVAL;
4764
0
    nd6log0(error, "%s: bad req, error %d\n",
4765
0
        __func__, error);
4766
0
    goto done;
4767
0
  }
4768
0
  error = SYSCTL_IN(req, &nd6_lookup_ipv6_args,
4769
0
      sizeof(struct nd6_lookup_ipv6_args));
4770
0
  if (error != 0) {
4771
0
    nd6log0(error, "%s: SYSCTL_IN() error %d\n",
4772
0
        __func__, error);
4773
0
    goto done;
4774
0
  }
4775
4776
0
  if (nd6_lookup_ipv6_args.ll_dest_len > sizeof(nd6_lookup_ipv6_args.ll_dest_)) {
4777
0
    error = EINVAL;
4778
0
    nd6log0(error, "%s: bad ll_dest_len, error %d\n",
4779
0
        __func__, error);
4780
0
    goto done;
4781
0
  }
4782
4783
  /* Make sure to terminate the string */
4784
0
  nd6_lookup_ipv6_args.ifname[IFNAMSIZ - 1] = 0;
4785
4786
0
  error = ifnet_find_by_name(nd6_lookup_ipv6_args.ifname, &ifp);
4787
0
  if (error != 0) {
4788
0
    nd6log0(error, "%s: ifnet_find_by_name() error %d\n",
4789
0
        __func__, error);
4790
0
    goto done;
4791
0
  }
4792
4793
0
  error = nd6_lookup_ipv6(ifp, &nd6_lookup_ipv6_args.ip6_dest,
4794
0
      &nd6_lookup_ipv6_args.ll_dest_._sdl,
4795
0
      nd6_lookup_ipv6_args.ll_dest_len, NULL, NULL);
4796
0
  if (error != 0) {
4797
0
    nd6log0(error, "%s: nd6_lookup_ipv6() error %d\n",
4798
0
        __func__, error);
4799
0
    goto done;
4800
0
  }
4801
4802
0
  error = SYSCTL_OUT(req, &nd6_lookup_ipv6_args,
4803
0
      sizeof(struct nd6_lookup_ipv6_args));
4804
0
  if (error != 0) {
4805
0
    nd6log0(error, "%s: SYSCTL_OUT() error %d\n",
4806
0
        __func__, error);
4807
0
    goto done;
4808
0
  }
4809
0
done:
4810
0
  return error;
4811
0
}
4812
4813
#endif /* (DEVELOPEMENT || DEBUG) */
4814
4815
int
4816
nd6_setifinfo(struct ifnet *ifp, u_int32_t before, u_int32_t after)
4817
0
{
4818
0
  uint32_t b, a;
4819
0
  int err = 0;
4820
4821
  /*
4822
   * Handle ND6_IFF_IFDISABLED
4823
   */
4824
0
  if ((before & ND6_IFF_IFDISABLED) ||
4825
0
      (after & ND6_IFF_IFDISABLED)) {
4826
0
    b = (before & ND6_IFF_IFDISABLED);
4827
0
    a = (after & ND6_IFF_IFDISABLED);
4828
4829
0
    if (b != a && (err = nd6_if_disable(ifp,
4830
0
        ((int32_t)(a - b) > 0))) != 0) {
4831
0
      goto done;
4832
0
    }
4833
0
  }
4834
4835
  /*
4836
   * Handle ND6_IFF_PROXY_PREFIXES
4837
   */
4838
0
  if ((before & ND6_IFF_PROXY_PREFIXES) ||
4839
0
      (after & ND6_IFF_PROXY_PREFIXES)) {
4840
0
    b = (before & ND6_IFF_PROXY_PREFIXES);
4841
0
    a = (after & ND6_IFF_PROXY_PREFIXES);
4842
4843
0
    if (b != a && (err = nd6_if_prproxy(ifp,
4844
0
        ((int32_t)(a - b) > 0))) != 0) {
4845
0
      goto done;
4846
0
    }
4847
0
  }
4848
0
done:
4849
0
  return err;
4850
0
}
4851
4852
/*
4853
 * Enable/disable IPv6 on an interface, called as part of
4854
 * setting/clearing ND6_IFF_IFDISABLED, or during DAD failure.
4855
 */
4856
int
4857
nd6_if_disable(struct ifnet *ifp, boolean_t enable)
4858
0
{
4859
0
  if (enable) {
4860
0
    if_set_eflags(ifp, IFEF_IPV6_DISABLED);
4861
0
  } else {
4862
0
    if_clear_eflags(ifp, IFEF_IPV6_DISABLED);
4863
0
  }
4864
4865
0
  return 0;
4866
0
}
4867
4868
static int
4869
nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
4870
0
{
4871
0
#pragma unused(oidp, arg1, arg2)
4872
0
  char pbuf[MAX_IPv6_STR_LEN];
4873
0
  struct nd_defrouter *dr;
4874
0
  int error = 0;
4875
4876
0
  if (req->newptr != USER_ADDR_NULL) {
4877
0
    return EPERM;
4878
0
  }
4879
4880
  /* XXX Handle mapped defrouter entries */
4881
0
  lck_mtx_lock(nd6_mutex);
4882
0
  if (proc_is64bit(req->p)) {
4883
0
    struct in6_defrouter_64 d;
4884
4885
0
    bzero(&d, sizeof(d));
4886
0
    d.rtaddr.sin6_family = AF_INET6;
4887
0
    d.rtaddr.sin6_len = sizeof(d.rtaddr);
4888
4889
0
    TAILQ_FOREACH(dr, &nd_defrouter_list, dr_entry) {
4890
0
      d.rtaddr.sin6_addr = dr->rtaddr;
4891
0
      if (in6_recoverscope(&d.rtaddr,
4892
0
          &dr->rtaddr, dr->ifp) != 0) {
4893
0
        log(LOG_ERR, "scope error in default router "
4894
0
            "list (%s)\n", inet_ntop(AF_INET6,
4895
0
            &dr->rtaddr, pbuf, sizeof(pbuf)));
4896
0
      }
4897
0
      d.flags = dr->flags;
4898
0
      d.stateflags = dr->stateflags;
4899
0
      d.rtlifetime = (u_short)dr->rtlifetime;
4900
0
      d.expire = (int)nddr_getexpire(dr);
4901
0
      d.if_index = dr->ifp->if_index;
4902
0
      error = SYSCTL_OUT(req, &d, sizeof(d));
4903
0
      if (error != 0) {
4904
0
        break;
4905
0
      }
4906
0
    }
4907
0
  } else {
4908
0
    struct in6_defrouter_32 d;
4909
4910
0
    bzero(&d, sizeof(d));
4911
0
    d.rtaddr.sin6_family = AF_INET6;
4912
0
    d.rtaddr.sin6_len = sizeof(d.rtaddr);
4913
4914
0
    TAILQ_FOREACH(dr, &nd_defrouter_list, dr_entry) {
4915
0
      d.rtaddr.sin6_addr = dr->rtaddr;
4916
0
      if (in6_recoverscope(&d.rtaddr,
4917
0
          &dr->rtaddr, dr->ifp) != 0) {
4918
0
        log(LOG_ERR, "scope error in default router "
4919
0
            "list (%s)\n", inet_ntop(AF_INET6,
4920
0
            &dr->rtaddr, pbuf, sizeof(pbuf)));
4921
0
      }
4922
0
      d.flags = dr->flags;
4923
0
      d.stateflags = dr->stateflags;
4924
0
      d.rtlifetime = (u_short)dr->rtlifetime;
4925
0
      d.expire = (int)nddr_getexpire(dr);
4926
0
      d.if_index = dr->ifp->if_index;
4927
0
      error = SYSCTL_OUT(req, &d, sizeof(d));
4928
0
      if (error != 0) {
4929
0
        break;
4930
0
      }
4931
0
    }
4932
0
  }
4933
0
  lck_mtx_unlock(nd6_mutex);
4934
0
  return error;
4935
0
}
4936
4937
static int
4938
nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
4939
0
{
4940
0
#pragma unused(oidp, arg1, arg2)
4941
0
  char pbuf[MAX_IPv6_STR_LEN];
4942
0
  struct nd_pfxrouter *pfr;
4943
0
  struct sockaddr_in6 s6;
4944
0
  struct nd_prefix *pr;
4945
0
  int error = 0;
4946
4947
0
  if (req->newptr != USER_ADDR_NULL) {
4948
0
    return EPERM;
4949
0
  }
4950
4951
0
  bzero(&s6, sizeof(s6));
4952
0
  s6.sin6_family = AF_INET6;
4953
0
  s6.sin6_len = sizeof(s6);
4954
4955
  /* XXX Handle mapped defrouter entries */
4956
0
  lck_mtx_lock(nd6_mutex);
4957
0
  if (proc_is64bit(req->p)) {
4958
0
    struct in6_prefix_64 p;
4959
4960
0
    bzero(&p, sizeof(p));
4961
0
    p.origin = PR_ORIG_RA;
4962
4963
0
    LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
4964
0
      NDPR_LOCK(pr);
4965
0
      p.prefix = pr->ndpr_prefix;
4966
0
      if (in6_recoverscope(&p.prefix,
4967
0
          &pr->ndpr_prefix.sin6_addr, pr->ndpr_ifp) != 0) {
4968
0
        log(LOG_ERR, "scope error in "
4969
0
            "prefix list (%s)\n", inet_ntop(AF_INET6,
4970
0
            &p.prefix.sin6_addr, pbuf, sizeof(pbuf)));
4971
0
      }
4972
0
      p.raflags = pr->ndpr_raf;
4973
0
      p.prefixlen = pr->ndpr_plen;
4974
0
      p.vltime = pr->ndpr_vltime;
4975
0
      p.pltime = pr->ndpr_pltime;
4976
0
      p.if_index = pr->ndpr_ifp->if_index;
4977
0
      p.expire = (u_long)ndpr_getexpire(pr);
4978
0
      p.refcnt = pr->ndpr_addrcnt;
4979
0
      p.flags = pr->ndpr_stateflags;
4980
0
      p.advrtrs = 0;
4981
0
      LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
4982
0
      p.advrtrs++;
4983
0
      error = SYSCTL_OUT(req, &p, sizeof(p));
4984
0
      if (error != 0) {
4985
0
        NDPR_UNLOCK(pr);
4986
0
        break;
4987
0
      }
4988
0
      LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
4989
0
        s6.sin6_addr = pfr->router->rtaddr;
4990
0
        if (in6_recoverscope(&s6, &pfr->router->rtaddr,
4991
0
            pfr->router->ifp) != 0) {
4992
0
          log(LOG_ERR,
4993
0
              "scope error in prefix list (%s)\n",
4994
0
              inet_ntop(AF_INET6, &s6.sin6_addr,
4995
0
              pbuf, sizeof(pbuf)));
4996
0
        }
4997
0
        error = SYSCTL_OUT(req, &s6, sizeof(s6));
4998
0
        if (error != 0) {
4999
0
          break;
5000
0
        }
5001
0
      }
5002
0
      NDPR_UNLOCK(pr);
5003
0
      if (error != 0) {
5004
0
        break;
5005
0
      }
5006
0
    }
5007
0
  } else {
5008
0
    struct in6_prefix_32 p;
5009
5010
0
    bzero(&p, sizeof(p));
5011
0
    p.origin = PR_ORIG_RA;
5012
5013
0
    LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
5014
0
      NDPR_LOCK(pr);
5015
0
      p.prefix = pr->ndpr_prefix;
5016
0
      if (in6_recoverscope(&p.prefix,
5017
0
          &pr->ndpr_prefix.sin6_addr, pr->ndpr_ifp) != 0) {
5018
0
        log(LOG_ERR,
5019
0
            "scope error in prefix list (%s)\n",
5020
0
            inet_ntop(AF_INET6, &p.prefix.sin6_addr,
5021
0
            pbuf, sizeof(pbuf)));
5022
0
      }
5023
0
      p.raflags = pr->ndpr_raf;
5024
0
      p.prefixlen = pr->ndpr_plen;
5025
0
      p.vltime = pr->ndpr_vltime;
5026
0
      p.pltime = pr->ndpr_pltime;
5027
0
      p.if_index = pr->ndpr_ifp->if_index;
5028
0
      p.expire = (u_int32_t)ndpr_getexpire(pr);
5029
0
      p.refcnt = pr->ndpr_addrcnt;
5030
0
      p.flags = pr->ndpr_stateflags;
5031
0
      p.advrtrs = 0;
5032
0
      LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
5033
0
      p.advrtrs++;
5034
0
      error = SYSCTL_OUT(req, &p, sizeof(p));
5035
0
      if (error != 0) {
5036
0
        NDPR_UNLOCK(pr);
5037
0
        break;
5038
0
      }
5039
0
      LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
5040
0
        s6.sin6_addr = pfr->router->rtaddr;
5041
0
        if (in6_recoverscope(&s6, &pfr->router->rtaddr,
5042
0
            pfr->router->ifp) != 0) {
5043
0
          log(LOG_ERR,
5044
0
              "scope error in prefix list (%s)\n",
5045
0
              inet_ntop(AF_INET6, &s6.sin6_addr,
5046
0
              pbuf, sizeof(pbuf)));
5047
0
        }
5048
0
        error = SYSCTL_OUT(req, &s6, sizeof(s6));
5049
0
        if (error != 0) {
5050
0
          break;
5051
0
        }
5052
0
      }
5053
0
      NDPR_UNLOCK(pr);
5054
0
      if (error != 0) {
5055
0
        break;
5056
0
      }
5057
0
    }
5058
0
  }
5059
0
  lck_mtx_unlock(nd6_mutex);
5060
5061
0
  return error;
5062
0
}
5063
5064
void
5065
in6_ifaddr_set_dadprogress(struct in6_ifaddr *ia)
5066
0
{
5067
0
  struct ifnet* ifp = ia->ia_ifp;
5068
0
  uint32_t flags = IN6_IFF_TENTATIVE;
5069
0
  uint32_t optdad = nd6_optimistic_dad;
5070
0
  struct nd_ifinfo *ndi = NULL;
5071
5072
0
  ndi = ND_IFINFO(ifp);
5073
0
  VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
5074
0
  if (!(ndi->flags & ND6_IFF_DAD)) {
5075
0
    return;
5076
0
  }
5077
5078
0
  if (optdad) {
5079
0
    if (ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_EXCLUSIVE) {
5080
0
      optdad = 0;
5081
0
    } else {
5082
0
      lck_mtx_lock(&ndi->lock);
5083
0
      if ((ndi->flags & ND6_IFF_REPLICATED) != 0) {
5084
0
        optdad = 0;
5085
0
      }
5086
0
      lck_mtx_unlock(&ndi->lock);
5087
0
    }
5088
0
  }
5089
5090
0
  if (optdad) {
5091
0
    if ((optdad & ND6_OPTIMISTIC_DAD_LINKLOCAL) &&
5092
0
        IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
5093
0
      flags = IN6_IFF_OPTIMISTIC;
5094
0
    } else if ((optdad & ND6_OPTIMISTIC_DAD_AUTOCONF) &&
5095
0
        (ia->ia6_flags & IN6_IFF_AUTOCONF)) {
5096
0
      if (ia->ia6_flags & IN6_IFF_TEMPORARY) {
5097
0
        if (optdad & ND6_OPTIMISTIC_DAD_TEMPORARY) {
5098
0
          flags = IN6_IFF_OPTIMISTIC;
5099
0
        }
5100
0
      } else if (ia->ia6_flags & IN6_IFF_SECURED) {
5101
0
        if (optdad & ND6_OPTIMISTIC_DAD_SECURED) {
5102
0
          flags = IN6_IFF_OPTIMISTIC;
5103
0
        }
5104
0
      } else {
5105
        /*
5106
         * Keeping the behavior for temp and CGA
5107
         * SLAAC addresses to have a knob for optimistic
5108
         * DAD.
5109
         * Other than that if ND6_OPTIMISTIC_DAD_AUTOCONF
5110
         * is set, we should default to optimistic
5111
         * DAD.
5112
         * For now this means SLAAC addresses with interface
5113
         * identifier derived from modified EUI-64 bit
5114
         * identifiers.
5115
         */
5116
0
        flags = IN6_IFF_OPTIMISTIC;
5117
0
      }
5118
0
    } else if ((optdad & ND6_OPTIMISTIC_DAD_DYNAMIC) &&
5119
0
        (ia->ia6_flags & IN6_IFF_DYNAMIC)) {
5120
0
      if (ia->ia6_flags & IN6_IFF_TEMPORARY) {
5121
0
        if (optdad & ND6_OPTIMISTIC_DAD_TEMPORARY) {
5122
0
          flags = IN6_IFF_OPTIMISTIC;
5123
0
        }
5124
0
      } else {
5125
0
        flags = IN6_IFF_OPTIMISTIC;
5126
0
      }
5127
0
    } else if ((optdad & ND6_OPTIMISTIC_DAD_MANUAL) &&
5128
0
        (ia->ia6_flags & IN6_IFF_OPTIMISTIC)) {
5129
      /*
5130
       * rdar://17483438
5131
       * Bypass tentative for address assignments
5132
       * not covered above (e.g. manual) upon request
5133
       */
5134
0
      if (!IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr) &&
5135
0
          !(ia->ia6_flags & IN6_IFF_AUTOCONF) &&
5136
0
          !(ia->ia6_flags & IN6_IFF_DYNAMIC)) {
5137
0
        flags = IN6_IFF_OPTIMISTIC;
5138
0
      }
5139
0
    }
5140
0
  }
5141
5142
0
  ia->ia6_flags &= ~(IN6_IFF_DUPLICATED | IN6_IFF_DADPROGRESS);
5143
0
  ia->ia6_flags |= flags;
5144
5145
0
  nd6log2(debug, "%s - %s ifp %s ia6_flags 0x%x\n",
5146
0
      __func__,
5147
0
      ip6_sprintf(&ia->ia_addr.sin6_addr),
5148
0
      if_name(ia->ia_ifp),
5149
0
      ia->ia6_flags);
5150
0
}