]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet6/nd6.c
xnu-3248.60.10.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6.c
CommitLineData
b0d623f7 1/*
3e170ce0 2 * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
b0d623f7
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
39236c6e 5 *
b0d623f7
A
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.
39236c6e 14 *
b0d623f7
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
39236c6e 17 *
b0d623f7
A
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.
39236c6e 25 *
b0d623f7
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
1c79356b
A
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>
2d21ac55 74#include <sys/sysctl.h>
1c79356b 75#include <sys/errno.h>
1c79356b
A
76#include <sys/syslog.h>
77#include <sys/protosw.h>
b0d623f7 78#include <sys/proc.h>
6d2010ae
A
79#include <sys/mcache.h>
80
39236c6e
A
81#include <dev/random/randomdev.h>
82
1c79356b 83#include <kern/queue.h>
b0d623f7 84#include <kern/zalloc.h>
1c79356b
A
85
86#include <net/if.h>
87#include <net/if_dl.h>
88#include <net/if_types.h>
6d2010ae 89#include <net/if_llreach.h>
1c79356b
A
90#include <net/route.h>
91#include <net/dlil.h>
6d2010ae 92#include <net/ntstat.h>
39236c6e 93#include <net/net_osdep.h>
1c79356b
A
94
95#include <netinet/in.h>
b0d623f7 96#include <netinet/in_arp.h>
1c79356b 97#include <netinet/if_ether.h>
1c79356b
A
98#include <netinet6/in6_var.h>
99#include <netinet/ip6.h>
100#include <netinet6/ip6_var.h>
101#include <netinet6/nd6.h>
6d2010ae 102#include <netinet6/scope6_var.h>
1c79356b
A
103#include <netinet/icmp6.h>
104
1c79356b 105#include "loop.h"
1c79356b 106
39236c6e
A
107#define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
108#define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
1c79356b 109
b0d623f7 110#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
1c79356b
A
111
112/* timer values */
113int nd6_prune = 1; /* walk list every 1 seconds */
39236c6e 114int nd6_prune_lazy = 5; /* lazily walk list every 5 seconds */
1c79356b
A
115int nd6_delay = 5; /* delay first probe time 5 second */
116int nd6_umaxtries = 3; /* maximum unicast query */
117int nd6_mmaxtries = 3; /* maximum multicast query */
118int nd6_useloopback = 1; /* use loopback interface for local traffic */
9bccf70c 119int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */
1c79356b
A
120
121/* preventing too many loops in ND option parsing */
122int nd6_maxndopt = 10; /* max # of ND options allowed */
123
6d2010ae 124int nd6_maxqueuelen = 1; /* max # of packets cached in unresolved ND entries */
9bccf70c
A
125
126#if ND6_DEBUG
127int nd6_debug = 1;
128#else
129int nd6_debug = 0;
130#endif
131
316670eb 132int nd6_optimistic_dad =
39236c6e
A
133 (ND6_OPTIMISTIC_DAD_LINKLOCAL|ND6_OPTIMISTIC_DAD_AUTOCONF|
134 ND6_OPTIMISTIC_DAD_TEMPORARY|ND6_OPTIMISTIC_DAD_DYNAMIC|
fe8ab488 135 ND6_OPTIMISTIC_DAD_SECURED|ND6_OPTIMISTIC_DAD_MANUAL);
6d2010ae 136
1c79356b
A
137/* for debugging? */
138static int nd6_inuse, nd6_allocated;
139
b0d623f7
A
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 *
39236c6e 156 * ln_hold, ln_asked, ln_expire, ln_state, ln_router, ln_flags,
6d2010ae 157 * ln_llreach, ln_lastused
b0d623f7
A
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 */
166struct llinfo_nd6 llinfo_nd6 = {
39236c6e
A
167 .ln_next = &llinfo_nd6,
168 .ln_prev = &llinfo_nd6,
b0d623f7
A
169};
170
3e170ce0
A
171static lck_grp_attr_t *nd_if_lock_grp_attr = NULL;
172static lck_grp_t *nd_if_lock_grp = NULL;
173static lck_attr_t *nd_if_lock_attr = NULL;
b0d623f7
A
174
175/* Protected by nd6_mutex */
1c79356b
A
176struct nd_drhead nd_defrouter;
177struct nd_prhead nd_prefix = { 0 };
178
39236c6e
A
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 */
192static int nd6_timeout_run; /* nd6_timeout is scheduled to run */
193static void nd6_timeout(void *);
194int nd6_sched_timeout_want; /* demand count for timer to be sched */
195static boolean_t nd6_fast_timer_on = FALSE;
196
197/* Serialization variables for nd6_service(), protected by rnh_lock */
198static boolean_t nd6_service_busy;
199static void *nd6_service_wc = &nd6_service_busy;
200static int nd6_service_waiters = 0;
6d2010ae 201
1c79356b
A
202int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
203static struct sockaddr_in6 all1_sa;
204
91447636 205static int regen_tmpaddr(struct in6_ifaddr *);
91447636 206extern lck_mtx_t *nd6_mutex;
1c79356b 207
39236c6e 208static struct llinfo_nd6 *nd6_llinfo_alloc(int);
b0d623f7 209static void nd6_llinfo_free(void *);
6d2010ae
A
210static void nd6_llinfo_purge(struct rtentry *);
211static void nd6_llinfo_get_ri(struct rtentry *, struct rt_reach_info *);
316670eb 212static void nd6_llinfo_get_iflri(struct rtentry *, struct ifnet_llreach_info *);
3e170ce0 213static void nd6_llinfo_refresh(struct rtentry *);
39236c6e 214static uint64_t ln_getexpire(struct llinfo_nd6 *);
1c79356b 215
39236c6e
A
216static void nd6_service(void *);
217static void nd6_slowtimo(void *);
218static int nd6_is_new_addr_neighbor(struct sockaddr_in6 *, struct ifnet *);
316670eb
A
219static int nd6_siocgdrlst(void *, int);
220static int nd6_siocgprlst(void *, int);
b0d623f7 221
39236c6e
A
222static int nd6_sysctl_drlist SYSCTL_HANDLER_ARGS;
223static int nd6_sysctl_prlist SYSCTL_HANDLER_ARGS;
224
b0d623f7
A
225/*
226 * Insertion and removal from llinfo_nd6 must be done with rnh_lock held.
227 */
39236c6e 228#define LN_DEQUEUE(_ln) do { \
b0d623f7
A
229 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
230 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
231 (_ln)->ln_next->ln_prev = (_ln)->ln_prev; \
232 (_ln)->ln_prev->ln_next = (_ln)->ln_next; \
233 (_ln)->ln_prev = (_ln)->ln_next = NULL; \
234 (_ln)->ln_flags &= ~ND6_LNF_IN_USE; \
235} while (0)
236
39236c6e 237#define LN_INSERTHEAD(_ln) do { \
b0d623f7
A
238 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
239 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
240 (_ln)->ln_next = llinfo_nd6.ln_next; \
241 llinfo_nd6.ln_next = (_ln); \
242 (_ln)->ln_prev = &llinfo_nd6; \
243 (_ln)->ln_next->ln_prev = (_ln); \
244 (_ln)->ln_flags |= ND6_LNF_IN_USE; \
245} while (0)
246
247static struct zone *llinfo_nd6_zone;
248#define LLINFO_ND6_ZONE_MAX 256 /* maximum elements in zone */
249#define LLINFO_ND6_ZONE_NAME "llinfo_nd6" /* name for zone */
e2fac8b1 250
39236c6e
A
251extern int tvtohz(struct timeval *);
252
253static int nd6_init_done;
254
255SYSCTL_DECL(_net_inet6_icmp6);
256
257SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
fe8ab488 258 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
39236c6e
A
259 nd6_sysctl_drlist, "S,in6_defrouter", "");
260
261SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
fe8ab488 262 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
39236c6e
A
263 nd6_sysctl_prlist, "S,in6_defrouter", "");
264
3e170ce0
A
265SYSCTL_DECL(_net_inet6_ip6);
266
267static int ip6_maxchainsent = 0;
268SYSCTL_INT(_net_inet6_ip6, OID_AUTO, maxchainsent,
269 CTLFLAG_RW | CTLFLAG_LOCKED, &ip6_maxchainsent, 0,
270 "use dlil_output_list");
271
1c79356b 272void
39236c6e 273nd6_init(void)
1c79356b 274{
1c79356b
A
275 int i;
276
39236c6e 277 VERIFY(!nd6_init_done);
1c79356b
A
278
279 all1_sa.sin6_family = AF_INET6;
39236c6e
A
280 all1_sa.sin6_len = sizeof (struct sockaddr_in6);
281 for (i = 0; i < sizeof (all1_sa.sin6_addr); i++)
1c79356b
A
282 all1_sa.sin6_addr.s6_addr[i] = 0xff;
283
284 /* initialization of the default router list */
285 TAILQ_INIT(&nd_defrouter);
286
316670eb
A
287 nd_if_lock_grp_attr = lck_grp_attr_alloc_init();
288 nd_if_lock_grp = lck_grp_alloc_init("nd_if_lock", nd_if_lock_grp_attr);
289 nd_if_lock_attr = lck_attr_alloc_init();
b0d623f7
A
290
291 llinfo_nd6_zone = zinit(sizeof (struct llinfo_nd6),
292 LLINFO_ND6_ZONE_MAX * sizeof (struct llinfo_nd6), 0,
293 LLINFO_ND6_ZONE_NAME);
294 if (llinfo_nd6_zone == NULL)
295 panic("%s: failed allocating llinfo_nd6_zone", __func__);
296
297 zone_change(llinfo_nd6_zone, Z_EXPAND, TRUE);
6d2010ae
A
298 zone_change(llinfo_nd6_zone, Z_CALLERACCT, FALSE);
299
300 nd6_nbr_init();
301 nd6_rtr_init();
316670eb 302 nd6_prproxy_init();
b0d623f7 303
1c79356b
A
304 nd6_init_done = 1;
305
306 /* start timer */
39236c6e 307 timeout(nd6_slowtimo, NULL, ND6_SLOWTIMER_INTERVAL * hz);
1c79356b
A
308}
309
b0d623f7 310static struct llinfo_nd6 *
39236c6e 311nd6_llinfo_alloc(int how)
b0d623f7 312{
39236c6e
A
313 struct llinfo_nd6 *ln;
314
315 ln = (how == M_WAITOK) ? zalloc(llinfo_nd6_zone) :
316 zalloc_noblock(llinfo_nd6_zone);
317 if (ln != NULL)
318 bzero(ln, sizeof (*ln));
319
320 return (ln);
b0d623f7
A
321}
322
323static void
324nd6_llinfo_free(void *arg)
325{
326 struct llinfo_nd6 *ln = arg;
327
328 if (ln->ln_next != NULL || ln->ln_prev != NULL) {
329 panic("%s: trying to free %p when it is in use", __func__, ln);
330 /* NOTREACHED */
331 }
332
333 /* Just in case there's anything there, free it */
334 if (ln->ln_hold != NULL) {
3e170ce0 335 m_freem_list(ln->ln_hold);
b0d623f7
A
336 ln->ln_hold = NULL;
337 }
338
6d2010ae
A
339 /* Purge any link-layer info caching */
340 VERIFY(ln->ln_rt->rt_llinfo == ln);
341 if (ln->ln_rt->rt_llinfo_purge != NULL)
342 ln->ln_rt->rt_llinfo_purge(ln->ln_rt);
343
b0d623f7
A
344 zfree(llinfo_nd6_zone, ln);
345}
346
6d2010ae
A
347static void
348nd6_llinfo_purge(struct rtentry *rt)
349{
350 struct llinfo_nd6 *ln = rt->rt_llinfo;
351
352 RT_LOCK_ASSERT_HELD(rt);
353 VERIFY(rt->rt_llinfo_purge == nd6_llinfo_purge && ln != NULL);
354
355 if (ln->ln_llreach != NULL) {
356 RT_CONVERT_LOCK(rt);
357 ifnet_llreach_free(ln->ln_llreach);
358 ln->ln_llreach = NULL;
359 }
360 ln->ln_lastused = 0;
361}
362
363static void
364nd6_llinfo_get_ri(struct rtentry *rt, struct rt_reach_info *ri)
365{
366 struct llinfo_nd6 *ln = rt->rt_llinfo;
367 struct if_llreach *lr = ln->ln_llreach;
368
369 if (lr == NULL) {
370 bzero(ri, sizeof (*ri));
316670eb
A
371 ri->ri_rssi = IFNET_RSSI_UNKNOWN;
372 ri->ri_lqm = IFNET_LQM_THRESH_OFF;
373 ri->ri_npm = IFNET_NPM_THRESH_UNKNOWN;
6d2010ae
A
374 } else {
375 IFLR_LOCK(lr);
376 /* Export to rt_reach_info structure */
377 ifnet_lr2ri(lr, ri);
316670eb
A
378 /* Export ND6 send expiration (calendar) time */
379 ri->ri_snd_expire =
380 ifnet_llreach_up2calexp(lr, ln->ln_lastused);
381 IFLR_UNLOCK(lr);
382 }
383}
384
385static void
386nd6_llinfo_get_iflri(struct rtentry *rt, struct ifnet_llreach_info *iflri)
387{
388 struct llinfo_nd6 *ln = rt->rt_llinfo;
389 struct if_llreach *lr = ln->ln_llreach;
390
391 if (lr == NULL) {
392 bzero(iflri, sizeof (*iflri));
393 iflri->iflri_rssi = IFNET_RSSI_UNKNOWN;
394 iflri->iflri_lqm = IFNET_LQM_THRESH_OFF;
395 iflri->iflri_npm = IFNET_NPM_THRESH_UNKNOWN;
396 } else {
397 IFLR_LOCK(lr);
398 /* Export to ifnet_llreach_info structure */
399 ifnet_lr2iflri(lr, iflri);
400 /* Export ND6 send expiration (uptime) time */
401 iflri->iflri_snd_expire =
402 ifnet_llreach_up2upexp(lr, ln->ln_lastused);
6d2010ae
A
403 IFLR_UNLOCK(lr);
404 }
405}
406
3e170ce0
A
407static void
408nd6_llinfo_refresh(struct rtentry *rt)
409{
410 struct llinfo_nd6 *ln = rt->rt_llinfo;
411 uint64_t timenow = net_uptime();
412 /*
413 * Can't refresh permanent, static or entries that are
414 * not direct host entries
415 */
416 if (!ln || ln->ln_expire == 0 ||
417 (rt->rt_flags & RTF_STATIC) ||
418 !(rt->rt_flags & RTF_LLINFO)) {
419 return;
420 }
421
422 if ((ln->ln_state > ND6_LLINFO_INCOMPLETE) &&
423 (ln->ln_state < ND6_LLINFO_PROBE)) {
424 if (ln->ln_expire > timenow) {
425 ln->ln_expire = timenow;
426 ln->ln_state = ND6_LLINFO_PROBE;
427 }
428 }
429 return;
430}
431
39236c6e
A
432void
433ln_setexpire(struct llinfo_nd6 *ln, uint64_t expiry)
434{
435 ln->ln_expire = expiry;
436}
437
438static uint64_t
439ln_getexpire(struct llinfo_nd6 *ln)
440{
441 struct timeval caltime;
442 uint64_t expiry;
443
444 if (ln->ln_expire != 0) {
445 struct rtentry *rt = ln->ln_rt;
446
447 VERIFY(rt != NULL);
448 /* account for system time change */
449 getmicrotime(&caltime);
450
451 rt->base_calendartime +=
452 NET_CALCULATE_CLOCKSKEW(caltime,
453 rt->base_calendartime, net_uptime(), rt->base_uptime);
454
455 expiry = rt->base_calendartime +
456 ln->ln_expire - rt->base_uptime;
457 } else {
458 expiry = 0;
459 }
460 return (expiry);
461}
462
463void
464nd6_ifreset(struct ifnet *ifp)
465{
3e170ce0
A
466 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
467 VERIFY(NULL != ndi);
39236c6e 468 VERIFY(ndi->initialized);
3e170ce0 469
39236c6e
A
470 lck_mtx_assert(&ndi->lock, LCK_MTX_ASSERT_OWNED);
471 ndi->linkmtu = ifp->if_mtu;
472 ndi->chlim = IPV6_DEFHLIM;
473 ndi->basereachable = REACHABLE_TIME;
474 ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
475 ndi->retrans = RETRANS_TIMER;
476}
477
3e170ce0 478void
b0d623f7 479nd6_ifattach(struct ifnet *ifp)
1c79356b 480{
3e170ce0 481 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
1c79356b 482
3e170ce0 483 VERIFY(NULL != ndi);
39236c6e
A
484 if (!ndi->initialized) {
485 lck_mtx_init(&ndi->lock, nd_if_lock_grp, nd_if_lock_attr);
fe8ab488 486 ndi->flags = ND6_IFF_PERFORMNUD;
39236c6e 487 ndi->initialized = TRUE;
b0d623f7 488 }
39236c6e
A
489
490 lck_mtx_lock(&ndi->lock);
491
3e170ce0 492 if (!(ifp->if_flags & IFF_MULTICAST)) {
39236c6e 493 ndi->flags |= ND6_IFF_IFDISABLED;
3e170ce0 494 }
39236c6e
A
495
496 nd6_ifreset(ifp);
497 lck_mtx_unlock(&ndi->lock);
316670eb 498 nd6_setmtu(ifp);
3e170ce0 499 return;
1c79356b
A
500}
501
3e170ce0 502#if 0
1c79356b 503/*
3e170ce0
A
504 * XXX Look more into this. Especially since we recycle ifnets and do delayed
505 * cleanup
1c79356b 506 */
3e170ce0
A
507void
508nd6_ifdetach(struct nd_ifinfo *nd)
509{
510 /* XXX destroy nd's lock? */
511 FREE(nd, M_IP6NDP);
512}
513#endif
514
1c79356b 515void
2d21ac55 516nd6_setmtu(struct ifnet *ifp)
1c79356b 517{
3e170ce0 518 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
b0d623f7 519 u_int32_t oldmaxmtu, maxmtu;
55e303ae 520
3e170ce0
A
521 if ((NULL == ndi) || (FALSE == ndi->initialized)) {
522 return;
55e303ae
A
523 }
524
316670eb 525 lck_mtx_lock(&ndi->lock);
55e303ae 526 oldmaxmtu = ndi->maxmtu;
1c79356b 527
2d21ac55
A
528 /*
529 * The ND level maxmtu is somewhat redundant to the interface MTU
530 * and is an implementation artifact of KAME. Instead of hard-
531 * limiting the maxmtu based on the interface type here, we simply
532 * take the if_mtu value since SIOCSIFMTU would have taken care of
533 * the sanity checks related to the maximum MTU allowed for the
534 * interface (a value that is known only by the interface layer),
535 * by sending the request down via ifnet_ioctl(). The use of the
6d2010ae
A
536 * ND level maxmtu and linkmtu are done via IN6_LINKMTU() which
537 * does further checking against if_mtu.
2d21ac55 538 */
b0d623f7 539 maxmtu = ndi->maxmtu = ifp->if_mtu;
1c79356b 540
2d21ac55 541 /*
39236c6e
A
542 * Decreasing the interface MTU under IPV6 minimum MTU may cause
543 * undesirable situation. We thus notify the operator of the change
544 * explicitly. The check for oldmaxmtu is necessary to restrict the
545 * log to the case of changing the MTU, not initializing it.
546 */
2d21ac55
A
547 if (oldmaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) {
548 log(LOG_NOTICE, "nd6_setmtu: "
39236c6e
A
549 "new link MTU on %s (%u) is too small for IPv6\n",
550 if_name(ifp), (uint32_t)ndi->maxmtu);
1c79356b 551 }
6d2010ae 552 ndi->linkmtu = ifp->if_mtu;
316670eb 553 lck_mtx_unlock(&ndi->lock);
2d21ac55
A
554
555 /* also adjust in6_maxmtu if necessary. */
3e170ce0 556 if (maxmtu > in6_maxmtu) {
2d21ac55 557 in6_setmaxmtu();
3e170ce0 558 }
1c79356b
A
559}
560
561void
39236c6e 562nd6_option_init(void *opt, int icmp6len, union nd_opts *ndopts)
1c79356b 563{
39236c6e 564 bzero(ndopts, sizeof (*ndopts));
1c79356b 565 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
39236c6e
A
566 ndopts->nd_opts_last =
567 (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
1c79356b
A
568
569 if (icmp6len == 0) {
570 ndopts->nd_opts_done = 1;
571 ndopts->nd_opts_search = NULL;
572 }
573}
574
575/*
576 * Take one ND option.
577 */
578struct nd_opt_hdr *
39236c6e 579nd6_option(union nd_opts *ndopts)
1c79356b
A
580{
581 struct nd_opt_hdr *nd_opt;
582 int olen;
583
584 if (!ndopts)
585 panic("ndopts == NULL in nd6_option\n");
586 if (!ndopts->nd_opts_last)
587 panic("uninitialized ndopts in nd6_option\n");
588 if (!ndopts->nd_opts_search)
39236c6e 589 return (NULL);
1c79356b 590 if (ndopts->nd_opts_done)
39236c6e 591 return (NULL);
1c79356b
A
592
593 nd_opt = ndopts->nd_opts_search;
594
9bccf70c
A
595 /* make sure nd_opt_len is inside the buffer */
596 if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) {
39236c6e
A
597 bzero(ndopts, sizeof (*ndopts));
598 return (NULL);
9bccf70c
A
599 }
600
1c79356b
A
601 olen = nd_opt->nd_opt_len << 3;
602 if (olen == 0) {
603 /*
604 * Message validation requires that all included
605 * options have a length that is greater than zero.
606 */
39236c6e
A
607 bzero(ndopts, sizeof (*ndopts));
608 return (NULL);
1c79356b
A
609 }
610
611 ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
9bccf70c
A
612 if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
613 /* option overruns the end of buffer, invalid */
39236c6e
A
614 bzero(ndopts, sizeof (*ndopts));
615 return (NULL);
9bccf70c
A
616 } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
617 /* reached the end of options chain */
1c79356b
A
618 ndopts->nd_opts_done = 1;
619 ndopts->nd_opts_search = NULL;
620 }
39236c6e 621 return (nd_opt);
1c79356b
A
622}
623
624/*
625 * Parse multiple ND options.
626 * This function is much easier to use, for ND routines that do not need
627 * multiple options of the same type.
628 */
629int
39236c6e 630nd6_options(union nd_opts *ndopts)
1c79356b
A
631{
632 struct nd_opt_hdr *nd_opt;
633 int i = 0;
634
6d2010ae
A
635 if (ndopts == NULL)
636 panic("ndopts == NULL in nd6_options");
637 if (ndopts->nd_opts_last == NULL)
638 panic("uninitialized ndopts in nd6_options");
639 if (ndopts->nd_opts_search == NULL)
39236c6e 640 return (0);
1c79356b
A
641
642 while (1) {
643 nd_opt = nd6_option(ndopts);
6d2010ae 644 if (nd_opt == NULL && ndopts->nd_opts_last == NULL) {
1c79356b
A
645 /*
646 * Message validation requires that all included
647 * options have a length that is greater than zero.
648 */
9bccf70c 649 icmp6stat.icp6s_nd_badopt++;
39236c6e
A
650 bzero(ndopts, sizeof (*ndopts));
651 return (-1);
1c79356b
A
652 }
653
6d2010ae 654 if (nd_opt == NULL)
1c79356b
A
655 goto skip1;
656
657 switch (nd_opt->nd_opt_type) {
658 case ND_OPT_SOURCE_LINKADDR:
659 case ND_OPT_TARGET_LINKADDR:
660 case ND_OPT_MTU:
661 case ND_OPT_REDIRECTED_HEADER:
1c79356b 662 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
9bccf70c
A
663 nd6log((LOG_INFO,
664 "duplicated ND6 option found (type=%d)\n",
665 nd_opt->nd_opt_type));
1c79356b
A
666 /* XXX bark? */
667 } else {
39236c6e
A
668 ndopts->nd_opt_array[nd_opt->nd_opt_type] =
669 nd_opt;
1c79356b
A
670 }
671 break;
672 case ND_OPT_PREFIX_INFORMATION:
673 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
39236c6e
A
674 ndopts->nd_opt_array[nd_opt->nd_opt_type] =
675 nd_opt;
1c79356b
A
676 }
677 ndopts->nd_opts_pi_end =
39236c6e 678 (struct nd_opt_prefix_info *)nd_opt;
1c79356b 679 break;
6d2010ae 680 case ND_OPT_RDNSS:
39236c6e
A
681 /* ignore */
682 break;
1c79356b
A
683 default:
684 /*
685 * Unknown options must be silently ignored,
686 * to accomodate future extension to the protocol.
687 */
9bccf70c 688 nd6log((LOG_DEBUG,
1c79356b 689 "nd6_options: unsupported option %d - "
9bccf70c 690 "option ignored\n", nd_opt->nd_opt_type));
1c79356b
A
691 }
692
693skip1:
694 i++;
695 if (i > nd6_maxndopt) {
696 icmp6stat.icp6s_nd_toomanyopt++;
9bccf70c 697 nd6log((LOG_INFO, "too many loop in nd opt\n"));
1c79356b
A
698 break;
699 }
700
701 if (ndopts->nd_opts_done)
702 break;
703 }
704
39236c6e 705 return (0);
1c79356b
A
706}
707
39236c6e
A
708struct nd6svc_arg {
709 int draining;
710 uint32_t killed;
711 uint32_t aging_lazy;
712 uint32_t aging;
713 uint32_t sticky;
714 uint32_t found;
715};
716
717/*
718 * ND6 service routine to expire default route list and prefix list
719 */
720static void
721nd6_service(void *arg)
0b4e3aa0 722{
39236c6e 723 struct nd6svc_arg *ap = arg;
9bccf70c
A
724 struct llinfo_nd6 *ln;
725 struct nd_defrouter *dr;
726 struct nd_prefix *pr;
91447636 727 struct ifnet *ifp = NULL;
9bccf70c 728 struct in6_ifaddr *ia6, *nia6;
39236c6e 729 uint64_t timenow;
3e170ce0 730 bool send_nc_failure_kev = false;
91447636 731
39236c6e
A
732 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
733 /*
734 * Since we may drop rnh_lock and nd6_mutex below, we want
735 * to run this entire operation single threaded.
736 */
737 while (nd6_service_busy) {
738 nd6log2((LOG_DEBUG, "%s: %s is blocked by %d waiters\n",
739 __func__, ap->draining ? "drainer" : "timer",
740 nd6_service_waiters));
741 nd6_service_waiters++;
742 (void) msleep(nd6_service_wc, rnh_lock, (PZERO-1),
743 __func__, NULL);
744 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
745 }
746
747 /* We are busy now; tell everyone else to go away */
748 nd6_service_busy = TRUE;
749
750 net_update_uptime();
751 timenow = net_uptime();
b0d623f7 752again:
3e170ce0
A
753 /*
754 * send_nc_failure_kev gets set when default router's IPv6 address
755 * can't be resolved.
756 * That can happen either:
757 * 1. When the entry has resolved once but can't be
758 * resolved later and the neighbor cache entry for gateway is deleted
759 * after max probe attempts.
760 *
761 * 2. When the entry is in ND6_LLINFO_INCOMPLETE but can not be resolved
762 * after max neighbor address resolution attempts.
763 *
764 * Both set send_nc_failure_kev to true. ifp is also set to the previous
765 * neighbor cache entry's route's ifp.
766 * Once we are done sending the notification, set send_nc_failure_kev
767 * to false to stop sending false notifications for non default router
768 * neighbors.
769 *
770 * We may to send more information like Gateway's IP that could not be
771 * resolved, however right now we do not install more than one default
772 * route per interface in the routing table.
773 */
774 if (send_nc_failure_kev && ifp->if_addrlen == IF_LLREACH_MAXLEN) {
775 struct kev_msg ev_msg;
776 struct kev_nd6_ndfailure nd6_ndfailure;
777 bzero(&ev_msg, sizeof(ev_msg));
778 bzero(&nd6_ndfailure, sizeof(nd6_ndfailure));
779 ev_msg.vendor_code = KEV_VENDOR_APPLE;
780 ev_msg.kev_class = KEV_NETWORK_CLASS;
781 ev_msg.kev_subclass = KEV_ND6_SUBCLASS;
782 ev_msg.event_code = KEV_ND6_NDFAILURE;
783
784 nd6_ndfailure.link_data.if_family = ifp->if_family;
785 nd6_ndfailure.link_data.if_unit = ifp->if_unit;
786 strlcpy(nd6_ndfailure.link_data.if_name,
787 ifp->if_name,
788 sizeof(nd6_ndfailure.link_data.if_name));
789 ev_msg.dv[0].data_ptr = &nd6_ndfailure;
790 ev_msg.dv[0].data_length =
791 sizeof(nd6_ndfailure);
792 kev_post_msg(&ev_msg);
793 }
794
795 send_nc_failure_kev = false;
796 ifp = NULL;
b0d623f7
A
797 /*
798 * The global list llinfo_nd6 is modified by nd6_request() and is
799 * therefore protected by rnh_lock. For obvious reasons, we cannot
800 * hold rnh_lock across calls that might lead to code paths which
801 * attempt to acquire rnh_lock, else we deadlock. Hence for such
802 * cases we drop rt_lock and rnh_lock, make the calls, and repeat the
803 * loop. To ensure that we don't process the same entry more than
804 * once in a single timeout, we mark the "already-seen" entries with
805 * ND6_LNF_TIMER_SKIP flag. At the end of the loop, we do a second
806 * pass thru the entries and clear the flag so they can be processed
807 * during the next timeout.
808 */
39236c6e
A
809 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
810
1c79356b 811 ln = llinfo_nd6.ln_next;
b0d623f7 812 while (ln != NULL && ln != &llinfo_nd6) {
1c79356b 813 struct rtentry *rt;
1c79356b 814 struct sockaddr_in6 *dst;
b0d623f7 815 struct llinfo_nd6 *next;
316670eb 816 u_int32_t retrans, flags;
3e170ce0 817 struct nd_ifinfo *ndi = NULL;
b0d623f7
A
818
819 /* ln_next/prev/rt is protected by rnh_lock */
820 next = ln->ln_next;
821 rt = ln->ln_rt;
822 RT_LOCK(rt);
1c79356b 823
b0d623f7
A
824 /* We've seen this already; skip it */
825 if (ln->ln_flags & ND6_LNF_TIMER_SKIP) {
826 RT_UNLOCK(rt);
1c79356b
A
827 ln = next;
828 continue;
829 }
39236c6e 830 ap->found++;
b0d623f7
A
831
832 /* rt->rt_ifp should never be NULL */
1c79356b 833 if ((ifp = rt->rt_ifp) == NULL) {
b0d623f7
A
834 panic("%s: ln(%p) rt(%p) rt_ifp == NULL", __func__,
835 ln, rt);
836 /* NOTREACHED */
1c79356b 837 }
e2fac8b1 838
b0d623f7
A
839 /* rt_llinfo must always be equal to ln */
840 if ((struct llinfo_nd6 *)rt->rt_llinfo != ln) {
841 panic("%s: rt_llinfo(%p) is not equal to ln(%p)",
39236c6e 842 __func__, rt->rt_llinfo, ln);
b0d623f7
A
843 /* NOTREACHED */
844 }
e2fac8b1 845
b0d623f7 846 /* rt_key should never be NULL */
39236c6e 847 dst = SIN6(rt_key(rt));
b0d623f7
A
848 if (dst == NULL) {
849 panic("%s: rt(%p) key is NULL ln(%p)", __func__,
850 rt, ln);
851 /* NOTREACHED */
1c79356b 852 }
55e303ae 853
b0d623f7
A
854 /* Set the flag in case we jump to "again" */
855 ln->ln_flags |= ND6_LNF_TIMER_SKIP;
856
39236c6e
A
857 if (ln->ln_expire == 0 || (rt->rt_flags & RTF_STATIC)) {
858 ap->sticky++;
859 } else if (ap->draining && (rt->rt_refcnt == 0)) {
860 /*
861 * If we are draining, immediately purge non-static
862 * entries without oustanding route refcnt.
863 */
864 if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
865 ln->ln_state = ND6_LLINFO_STALE;
866 else
867 ln->ln_state = ND6_LLINFO_PURGE;
868 ln_setexpire(ln, timenow);
869 }
870
871 /*
872 * If the entry has not expired, skip it. Take note on the
873 * state, as entries that are in the STALE state are simply
874 * waiting to be garbage collected, in which case we can
875 * relax the callout scheduling (use nd6_prune_lazy).
876 */
877 if (ln->ln_expire > timenow) {
878 switch (ln->ln_state) {
879 case ND6_LLINFO_STALE:
880 ap->aging_lazy++;
881 break;
882 default:
883 ap->aging++;
884 break;
885 }
b0d623f7 886 RT_UNLOCK(rt);
55e303ae
A
887 ln = next;
888 continue;
889 }
b0d623f7 890
3e170ce0
A
891 ndi = ND_IFINFO(ifp);
892 VERIFY(ndi->initialized);
893 retrans = ndi->retrans;
894 flags = ndi->flags;
b0d623f7
A
895
896 RT_LOCK_ASSERT_HELD(rt);
1c79356b
A
897
898 switch (ln->ln_state) {
899 case ND6_LLINFO_INCOMPLETE:
900 if (ln->ln_asked < nd6_mmaxtries) {
39236c6e 901 struct ifnet *exclifp = ln->ln_exclifp;
1c79356b 902 ln->ln_asked++;
39236c6e 903 ln_setexpire(ln, timenow + retrans / 1000);
b0d623f7
A
904 RT_ADDREF_LOCKED(rt);
905 RT_UNLOCK(rt);
906 lck_mtx_unlock(rnh_lock);
316670eb 907 if (ip6_forwarding) {
39236c6e
A
908 nd6_prproxy_ns_output(ifp, exclifp,
909 NULL, &dst->sin6_addr, ln);
316670eb
A
910 } else {
911 nd6_ns_output(ifp, NULL,
912 &dst->sin6_addr, ln, 0);
913 }
b0d623f7 914 RT_REMREF(rt);
39236c6e
A
915 ap->aging++;
916 lck_mtx_lock(rnh_lock);
1c79356b
A
917 } else {
918 struct mbuf *m = ln->ln_hold;
55e303ae 919 ln->ln_hold = NULL;
3e170ce0 920 send_nc_failure_kev = (rt->rt_flags & RTF_ROUTER) ? true : false;
b0d623f7 921 if (m != NULL) {
39236c6e 922 RT_ADDREF_LOCKED(rt);
b0d623f7
A
923 RT_UNLOCK(rt);
924 lck_mtx_unlock(rnh_lock);
3e170ce0
A
925
926 struct mbuf *mnext;
927 while (m) {
928 mnext = m->m_nextpkt;
929 m->m_nextpkt = NULL;
930 m->m_pkthdr.rcvif = ifp;
931 icmp6_error_flag(m, ICMP6_DST_UNREACH,
932 ICMP6_DST_UNREACH_ADDR, 0, 0);
933 m = mnext;
934 }
b0d623f7 935 } else {
39236c6e 936 RT_ADDREF_LOCKED(rt);
b0d623f7
A
937 RT_UNLOCK(rt);
938 lck_mtx_unlock(rnh_lock);
1c79356b 939 }
b0d623f7 940 nd6_free(rt);
39236c6e
A
941 ap->killed++;
942 lck_mtx_lock(rnh_lock);
943 rtfree_locked(rt);
1c79356b 944 }
39236c6e 945 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
b0d623f7
A
946 goto again;
947
1c79356b 948 case ND6_LLINFO_REACHABLE:
39236c6e 949 if (ln->ln_expire != 0) {
1c79356b 950 ln->ln_state = ND6_LLINFO_STALE;
39236c6e
A
951 ln_setexpire(ln, timenow + nd6_gctimer);
952 ap->aging_lazy++;
9bccf70c 953 }
b0d623f7 954 RT_UNLOCK(rt);
1c79356b 955 break;
9bccf70c
A
956
957 case ND6_LLINFO_STALE:
e2fac8b1 958 case ND6_LLINFO_PURGE:
39236c6e
A
959 /* Garbage Collection(RFC 4861 5.3) */
960 if (ln->ln_expire != 0) {
961 RT_ADDREF_LOCKED(rt);
b0d623f7
A
962 RT_UNLOCK(rt);
963 lck_mtx_unlock(rnh_lock);
964 nd6_free(rt);
39236c6e
A
965 ap->killed++;
966 lck_mtx_lock(rnh_lock);
967 rtfree_locked(rt);
b0d623f7
A
968 goto again;
969 } else {
970 RT_UNLOCK(rt);
971 }
9bccf70c
A
972 break;
973
1c79356b 974 case ND6_LLINFO_DELAY:
316670eb 975 if ((flags & ND6_IFF_PERFORMNUD) != 0) {
1c79356b
A
976 /* We need NUD */
977 ln->ln_asked = 1;
978 ln->ln_state = ND6_LLINFO_PROBE;
39236c6e 979 ln_setexpire(ln, timenow + retrans / 1000);
b0d623f7
A
980 RT_ADDREF_LOCKED(rt);
981 RT_UNLOCK(rt);
982 lck_mtx_unlock(rnh_lock);
1c79356b 983 nd6_ns_output(ifp, &dst->sin6_addr,
6d2010ae 984 &dst->sin6_addr, ln, 0);
b0d623f7 985 RT_REMREF(rt);
39236c6e
A
986 ap->aging++;
987 lck_mtx_lock(rnh_lock);
b0d623f7 988 goto again;
9bccf70c 989 }
b0d623f7 990 ln->ln_state = ND6_LLINFO_STALE; /* XXX */
39236c6e 991 ln_setexpire(ln, timenow + nd6_gctimer);
b0d623f7 992 RT_UNLOCK(rt);
39236c6e 993 ap->aging_lazy++;
1c79356b 994 break;
b0d623f7 995
1c79356b
A
996 case ND6_LLINFO_PROBE:
997 if (ln->ln_asked < nd6_umaxtries) {
998 ln->ln_asked++;
39236c6e 999 ln_setexpire(ln, timenow + retrans / 1000);
b0d623f7
A
1000 RT_ADDREF_LOCKED(rt);
1001 RT_UNLOCK(rt);
1002 lck_mtx_unlock(rnh_lock);
1c79356b 1003 nd6_ns_output(ifp, &dst->sin6_addr,
6d2010ae 1004 &dst->sin6_addr, ln, 0);
b0d623f7 1005 RT_REMREF(rt);
39236c6e
A
1006 ap->aging++;
1007 lck_mtx_lock(rnh_lock);
1c79356b 1008 } else {
3e170ce0 1009 send_nc_failure_kev = (rt->rt_flags & RTF_ROUTER) ? true : false;
39236c6e 1010 RT_ADDREF_LOCKED(rt);
b0d623f7
A
1011 RT_UNLOCK(rt);
1012 lck_mtx_unlock(rnh_lock);
1013 nd6_free(rt);
39236c6e
A
1014 ap->killed++;
1015 lck_mtx_lock(rnh_lock);
1016 rtfree_locked(rt);
1c79356b 1017 }
39236c6e 1018 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
b0d623f7
A
1019 goto again;
1020
1021 default:
1022 RT_UNLOCK(rt);
1c79356b 1023 break;
1c79356b
A
1024 }
1025 ln = next;
1026 }
b0d623f7
A
1027 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
1028
1029 /* Now clear the flag from all entries */
1030 ln = llinfo_nd6.ln_next;
1031 while (ln != NULL && ln != &llinfo_nd6) {
1032 struct rtentry *rt = ln->ln_rt;
1033 struct llinfo_nd6 *next = ln->ln_next;
1034
1035 RT_LOCK_SPIN(rt);
1036 if (ln->ln_flags & ND6_LNF_TIMER_SKIP)
1037 ln->ln_flags &= ~ND6_LNF_TIMER_SKIP;
1038 RT_UNLOCK(rt);
1039 ln = next;
1040 }
1041 lck_mtx_unlock(rnh_lock);
1042
9bccf70c 1043 /* expire default router list */
91447636 1044 lck_mtx_lock(nd6_mutex);
1c79356b
A
1045 dr = TAILQ_FIRST(&nd_defrouter);
1046 while (dr) {
39236c6e
A
1047 ap->found++;
1048 if (dr->expire != 0 && dr->expire < timenow) {
1c79356b
A
1049 struct nd_defrouter *t;
1050 t = TAILQ_NEXT(dr, dr_entry);
6d2010ae 1051 defrtrlist_del(dr);
1c79356b 1052 dr = t;
39236c6e 1053 ap->killed++;
1c79356b 1054 } else {
39236c6e
A
1055 if (dr->expire == 0 || (dr->stateflags & NDDRF_STATIC))
1056 ap->sticky++;
1057 else
1058 ap->aging_lazy++;
1c79356b
A
1059 dr = TAILQ_NEXT(dr, dr_entry);
1060 }
1061 }
6d2010ae 1062 lck_mtx_unlock(nd6_mutex);
1c79356b 1063
9bccf70c
A
1064 /*
1065 * expire interface addresses.
1066 * in the past the loop was inside prefix expiry processing.
1067 * However, from a stricter speci-confrmance standpoint, we should
1068 * rather separate address lifetimes and prefix lifetimes.
1069 */
6d2010ae
A
1070addrloop:
1071 lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
91447636 1072 for (ia6 = in6_ifaddrs; ia6; ia6 = nia6) {
39236c6e 1073 ap->found++;
9bccf70c 1074 nia6 = ia6->ia_next;
6d2010ae
A
1075 IFA_LOCK(&ia6->ia_ifa);
1076 /*
1077 * Extra reference for ourselves; it's no-op if
1078 * we don't have to regenerate temporary address,
1079 * otherwise it protects the address from going
1080 * away since we drop in6_ifaddr_rwlock below.
1081 */
1082 IFA_ADDREF_LOCKED(&ia6->ia_ifa);
9bccf70c 1083 /* check address lifetime */
39236c6e 1084 if (IFA6_IS_INVALID(ia6, timenow)) {
9bccf70c
A
1085 /*
1086 * If the expiring address is temporary, try
1087 * regenerating a new one. This would be useful when
55e303ae 1088 * we suspended a laptop PC, then turned it on after a
9bccf70c
A
1089 * period that could invalidate all temporary
1090 * addresses. Although we may have to restart the
1091 * loop (see below), it must be after purging the
1092 * address. Otherwise, we'd see an infinite loop of
316670eb 1093 * regeneration.
9bccf70c
A
1094 */
1095 if (ip6_use_tempaddr &&
1096 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
316670eb
A
1097 /*
1098 * NOTE: We have to drop the lock here
1099 * because regen_tmpaddr() eventually calls
1100 * in6_update_ifa(), which must take the lock
1101 * and would otherwise cause a hang. This is
1102 * safe because the goto addrloop leads to a
1103 * re-evaluation of the in6_ifaddrs list
2d21ac55 1104 */
6d2010ae
A
1105 IFA_UNLOCK(&ia6->ia_ifa);
1106 lck_rw_done(&in6_ifaddr_rwlock);
1107 (void) regen_tmpaddr(ia6);
1108 } else {
1109 IFA_UNLOCK(&ia6->ia_ifa);
1110 lck_rw_done(&in6_ifaddr_rwlock);
9bccf70c
A
1111 }
1112
6d2010ae
A
1113 /*
1114 * Purging the address would have caused
1115 * in6_ifaddr_rwlock to be dropped and reacquired;
1116 * therefore search again from the beginning
1117 * of in6_ifaddrs list.
1118 */
1119 in6_purgeaddr(&ia6->ia_ifa);
39236c6e 1120 ap->killed++;
9bccf70c 1121
b0d623f7 1122 /* Release extra reference taken above */
6d2010ae
A
1123 IFA_REMREF(&ia6->ia_ifa);
1124 goto addrloop;
55e303ae 1125 }
39236c6e
A
1126 /*
1127 * The lazy timer runs every nd6_prune_lazy seconds with at
1128 * most "2 * nd6_prune_lazy - 1" leeway. We consider the worst
1129 * case here and make sure we schedule the regular timer if an
1130 * interface address is about to expire.
1131 */
1132 if (IFA6_IS_INVALID(ia6, timenow + 3 * nd6_prune_lazy))
1133 ap->aging++;
1134 else
1135 ap->aging_lazy++;
6d2010ae 1136 IFA_LOCK_ASSERT_HELD(&ia6->ia_ifa);
39236c6e 1137 if (IFA6_IS_DEPRECATED(ia6, timenow)) {
9bccf70c
A
1138 int oldflags = ia6->ia6_flags;
1139
1140 ia6->ia6_flags |= IN6_IFF_DEPRECATED;
1141
1142 /*
1143 * If a temporary address has just become deprecated,
1144 * regenerate a new one if possible.
1145 */
1146 if (ip6_use_tempaddr &&
1147 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
1148 (oldflags & IN6_IFF_DEPRECATED) == 0) {
1149
2d21ac55 1150 /* see NOTE above */
6d2010ae
A
1151 IFA_UNLOCK(&ia6->ia_ifa);
1152 lck_rw_done(&in6_ifaddr_rwlock);
9bccf70c
A
1153 if (regen_tmpaddr(ia6) == 0) {
1154 /*
1155 * A new temporary address is
1156 * generated.
1157 * XXX: this means the address chain
1158 * has changed while we are still in
1159 * the loop. Although the change
1160 * would not cause disaster (because
55e303ae
A
1161 * it's not a deletion, but an
1162 * addition,) we'd rather restart the
316670eb 1163 * loop just for safety. Or does this
9bccf70c
A
1164 * significantly reduce performance??
1165 */
6d2010ae
A
1166 /* Release extra reference */
1167 IFA_REMREF(&ia6->ia_ifa);
9bccf70c
A
1168 goto addrloop;
1169 }
6d2010ae
A
1170 lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
1171 } else {
1172 IFA_UNLOCK(&ia6->ia_ifa);
1c79356b 1173 }
55e303ae 1174 } else {
9bccf70c
A
1175 /*
1176 * A new RA might have made a deprecated address
1177 * preferred.
1178 */
1179 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
6d2010ae 1180 IFA_UNLOCK(&ia6->ia_ifa);
1c79356b 1181 }
6d2010ae
A
1182 lck_rw_assert(&in6_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1183 /* Release extra reference taken above */
1184 IFA_REMREF(&ia6->ia_ifa);
9bccf70c 1185 }
6d2010ae
A
1186 lck_rw_done(&in6_ifaddr_rwlock);
1187
1188 lck_mtx_lock(nd6_mutex);
9bccf70c
A
1189 /* expire prefix list */
1190 pr = nd_prefix.lh_first;
39236c6e
A
1191 while (pr != NULL) {
1192 ap->found++;
1c79356b
A
1193 /*
1194 * check prefix lifetime.
1195 * since pltime is just for autoconf, pltime processing for
1196 * prefix is not necessary.
1c79356b 1197 */
6d2010ae 1198 NDPR_LOCK(pr);
fe8ab488
A
1199 if (pr->ndpr_stateflags & NDPRF_PROCESSED_SERVICE ||
1200 pr->ndpr_stateflags & NDPRF_DEFUNCT) {
1201 pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
6d2010ae
A
1202 NDPR_UNLOCK(pr);
1203 pr = pr->ndpr_next;
1204 continue;
1205 }
39236c6e 1206 if (pr->ndpr_expire != 0 && pr->ndpr_expire < timenow) {
1c79356b
A
1207 /*
1208 * address expiration and prefix expiration are
9bccf70c 1209 * separate. NEVER perform in6_purgeaddr here.
1c79356b 1210 */
39236c6e 1211 pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
6d2010ae
A
1212 NDPR_ADDREF_LOCKED(pr);
1213 prelist_remove(pr);
1214 NDPR_UNLOCK(pr);
1215 NDPR_REMREF(pr);
fe8ab488 1216 pfxlist_onlink_check();
6d2010ae 1217 pr = nd_prefix.lh_first;
39236c6e 1218 ap->killed++;
6d2010ae 1219 } else {
39236c6e
A
1220 if (pr->ndpr_expire == 0 ||
1221 (pr->ndpr_stateflags & NDPRF_STATIC))
1222 ap->sticky++;
1223 else
1224 ap->aging_lazy++;
1225 pr->ndpr_stateflags |= NDPRF_PROCESSED_SERVICE;
6d2010ae 1226 NDPR_UNLOCK(pr);
1c79356b 1227 pr = pr->ndpr_next;
6d2010ae
A
1228 }
1229 }
1230 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
1231 NDPR_LOCK(pr);
39236c6e 1232 pr->ndpr_stateflags &= ~NDPRF_PROCESSED_SERVICE;
6d2010ae
A
1233 NDPR_UNLOCK(pr);
1234 }
91447636 1235 lck_mtx_unlock(nd6_mutex);
39236c6e
A
1236
1237 lck_mtx_lock(rnh_lock);
1238 /* We're done; let others enter */
1239 nd6_service_busy = FALSE;
1240 if (nd6_service_waiters > 0) {
1241 nd6_service_waiters = 0;
1242 wakeup(nd6_service_wc);
1243 }
1244}
1245
1246void
1247nd6_drain(void *arg)
1248{
1249#pragma unused(arg)
1250 struct nd6svc_arg sarg;
1251
1252 nd6log2((LOG_DEBUG, "%s: draining ND6 entries\n", __func__));
1253
1254 lck_mtx_lock(rnh_lock);
1255 bzero(&sarg, sizeof (sarg));
1256 sarg.draining = 1;
1257 nd6_service(&sarg);
1258 nd6log2((LOG_DEBUG, "%s: found %u, aging_lazy %u, aging %u, "
1259 "sticky %u, killed %u\n", __func__, sarg.found, sarg.aging_lazy,
1260 sarg.aging, sarg.sticky, sarg.killed));
1261 lck_mtx_unlock(rnh_lock);
1262}
1263
1264/*
1265 * We use the ``arg'' variable to decide whether or not the timer we're
1266 * running is the fast timer. We do this to reset the nd6_fast_timer_on
1267 * variable so that later we don't end up ignoring a ``fast timer''
1268 * request if the 5 second timer is running (see nd6_sched_timeout).
1269 */
1270static void
1271nd6_timeout(void *arg)
1272{
1273 struct nd6svc_arg sarg;
fe8ab488 1274 uint32_t buf;
39236c6e
A
1275
1276 lck_mtx_lock(rnh_lock);
1277 bzero(&sarg, sizeof (sarg));
1278 nd6_service(&sarg);
1279 nd6log2((LOG_DEBUG, "%s: found %u, aging_lazy %u, aging %u, "
1280 "sticky %u, killed %u\n", __func__, sarg.found, sarg.aging_lazy,
1281 sarg.aging, sarg.sticky, sarg.killed));
1282 /* re-arm the timer if there's work to do */
1283 nd6_timeout_run--;
1284 VERIFY(nd6_timeout_run >= 0 && nd6_timeout_run < 2);
1285 if (arg == &nd6_fast_timer_on)
1286 nd6_fast_timer_on = FALSE;
1287 if (sarg.aging_lazy > 0 || sarg.aging > 0 || nd6_sched_timeout_want) {
1288 struct timeval atv, ltv, *leeway;
1289 int lazy = nd6_prune_lazy;
1290
1291 if (sarg.aging > 0 || lazy < 1) {
1292 atv.tv_usec = 0;
1293 atv.tv_sec = nd6_prune;
1294 leeway = NULL;
1295 } else {
1296 VERIFY(lazy >= 1);
1297 atv.tv_usec = 0;
1298 atv.tv_sec = MAX(nd6_prune, lazy);
1299 ltv.tv_usec = 0;
fe8ab488
A
1300 read_frandom(&buf, sizeof(buf));
1301 ltv.tv_sec = MAX(buf % lazy, 1) * 2;
39236c6e
A
1302 leeway = &ltv;
1303 }
1304 nd6_sched_timeout(&atv, leeway);
1305 } else if (nd6_debug) {
1306 nd6log2((LOG_DEBUG, "%s: not rescheduling timer\n", __func__));
1307 }
1308 lck_mtx_unlock(rnh_lock);
1309}
1310
1311void
1312nd6_sched_timeout(struct timeval *atv, struct timeval *ltv)
1313{
1314 struct timeval tv;
1315
1316 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
1317 if (atv == NULL) {
1318 tv.tv_usec = 0;
1319 tv.tv_sec = MAX(nd6_prune, 1);
1320 atv = &tv;
1321 ltv = NULL; /* ignore leeway */
1322 }
1323 /* see comments on top of this file */
1324 if (nd6_timeout_run == 0) {
1325 if (ltv == NULL) {
1326 nd6log2((LOG_DEBUG, "%s: timer scheduled in "
1327 "T+%llus.%lluu (demand %d)\n", __func__,
1328 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1329 nd6_sched_timeout_want));
1330 nd6_fast_timer_on = TRUE;
1331 timeout(nd6_timeout, &nd6_fast_timer_on, tvtohz(atv));
1332 } else {
1333 nd6log2((LOG_DEBUG, "%s: timer scheduled in "
1334 "T+%llus.%lluu with %llus.%lluu leeway "
1335 "(demand %d)\n", __func__, (uint64_t)atv->tv_sec,
1336 (uint64_t)atv->tv_usec, (uint64_t)ltv->tv_sec,
1337 (uint64_t)ltv->tv_usec, nd6_sched_timeout_want));
1338 nd6_fast_timer_on = FALSE;
1339 timeout_with_leeway(nd6_timeout, NULL,
1340 tvtohz(atv), tvtohz(ltv));
1341 }
1342 nd6_timeout_run++;
1343 nd6_sched_timeout_want = 0;
1344 } else if (nd6_timeout_run == 1 && ltv == NULL &&
1345 nd6_fast_timer_on == FALSE) {
1346 nd6log2((LOG_DEBUG, "%s: fast timer scheduled in "
1347 "T+%llus.%lluu (demand %d)\n", __func__,
1348 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1349 nd6_sched_timeout_want));
1350 nd6_fast_timer_on = TRUE;
1351 nd6_sched_timeout_want = 0;
1352 nd6_timeout_run++;
1353 timeout(nd6_timeout, &nd6_fast_timer_on, tvtohz(atv));
1354 } else {
1355 if (ltv == NULL) {
1356 nd6log2((LOG_DEBUG, "%s: not scheduling timer: "
1357 "timers %d, fast_timer %d, T+%llus.%lluu\n",
1358 __func__, nd6_timeout_run, nd6_fast_timer_on,
1359 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec));
1360 } else {
1361 nd6log2((LOG_DEBUG, "%s: not scheduling timer: "
1362 "timers %d, fast_timer %d, T+%llus.%lluu "
1363 "with %llus.%lluu leeway\n", __func__,
1364 nd6_timeout_run, nd6_fast_timer_on,
1365 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec,
1366 (uint64_t)ltv->tv_sec, (uint64_t)ltv->tv_usec));
1367 }
1368 }
d1ecb069
A
1369}
1370
316670eb
A
1371/*
1372 * ND6 router advertisement kernel notification
1373 */
1374void
1375nd6_post_msg(u_int32_t code, struct nd_prefix_list *prefix_list,
1376 u_int32_t list_length, u_int32_t mtu, char *dl_addr, u_int32_t dl_addr_len)
1377{
1378 struct kev_msg ev_msg;
1379 struct kev_nd6_ra_data nd6_ra_msg_data;
1380 struct nd_prefix_list *itr = prefix_list;
1381
39236c6e
A
1382 bzero(&ev_msg, sizeof (struct kev_msg));
1383 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1384 ev_msg.kev_class = KEV_NETWORK_CLASS;
1385 ev_msg.kev_subclass = KEV_ND6_SUBCLASS;
1386 ev_msg.event_code = code;
316670eb 1387
39236c6e 1388 bzero(&nd6_ra_msg_data, sizeof (nd6_ra_msg_data));
316670eb
A
1389 nd6_ra_msg_data.lladdrlen = (dl_addr_len <= ND6_ROUTER_LL_SIZE) ?
1390 dl_addr_len : ND6_ROUTER_LL_SIZE;
1391 bcopy(dl_addr, &nd6_ra_msg_data.lladdr, nd6_ra_msg_data.lladdrlen);
1392
1393 if (mtu > 0 && mtu >= IPV6_MMTU) {
1394 nd6_ra_msg_data.mtu = mtu;
1395 nd6_ra_msg_data.flags |= KEV_ND6_DATA_VALID_MTU;
1396 }
1397
1398 if (list_length > 0 && prefix_list != NULL) {
1399 nd6_ra_msg_data.list_length = list_length;
1400 nd6_ra_msg_data.flags |= KEV_ND6_DATA_VALID_PREFIX;
1401 }
1402
1403 while (itr != NULL && nd6_ra_msg_data.list_index < list_length) {
1404 bcopy(&itr->pr.ndpr_prefix, &nd6_ra_msg_data.prefix.prefix,
1405 sizeof (nd6_ra_msg_data.prefix.prefix));
1406 nd6_ra_msg_data.prefix.raflags = itr->pr.ndpr_raf;
1407 nd6_ra_msg_data.prefix.prefixlen = itr->pr.ndpr_plen;
1408 nd6_ra_msg_data.prefix.origin = PR_ORIG_RA;
1409 nd6_ra_msg_data.prefix.vltime = itr->pr.ndpr_vltime;
1410 nd6_ra_msg_data.prefix.pltime = itr->pr.ndpr_pltime;
39236c6e 1411 nd6_ra_msg_data.prefix.expire = ndpr_getexpire(&itr->pr);
316670eb
A
1412 nd6_ra_msg_data.prefix.flags = itr->pr.ndpr_stateflags;
1413 nd6_ra_msg_data.prefix.refcnt = itr->pr.ndpr_addrcnt;
1414 nd6_ra_msg_data.prefix.if_index = itr->pr.ndpr_ifp->if_index;
1415
1416 /* send the message up */
39236c6e
A
1417 ev_msg.dv[0].data_ptr = &nd6_ra_msg_data;
1418 ev_msg.dv[0].data_length = sizeof (nd6_ra_msg_data);
1419 ev_msg.dv[1].data_length = 0;
316670eb
A
1420 kev_post_msg(&ev_msg);
1421
1422 /* clean up for the next prefix */
39236c6e 1423 bzero(&nd6_ra_msg_data.prefix, sizeof (nd6_ra_msg_data.prefix));
316670eb
A
1424 itr = itr->next;
1425 nd6_ra_msg_data.list_index++;
1426 }
1427}
1428
d1ecb069 1429/*
39236c6e 1430 * Regenerate deprecated/invalidated temporary address
d1ecb069 1431 */
9bccf70c 1432static int
39236c6e 1433regen_tmpaddr(struct in6_ifaddr *ia6)
9bccf70c
A
1434{
1435 struct ifaddr *ifa;
1436 struct ifnet *ifp;
1437 struct in6_ifaddr *public_ifa6 = NULL;
39236c6e 1438 uint64_t timenow = net_uptime();
9bccf70c
A
1439
1440 ifp = ia6->ia_ifa.ifa_ifp;
6d2010ae 1441 ifnet_lock_shared(ifp);
39236c6e 1442 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
9bccf70c
A
1443 struct in6_ifaddr *it6;
1444
6d2010ae
A
1445 IFA_LOCK(ifa);
1446 if (ifa->ifa_addr->sa_family != AF_INET6) {
1447 IFA_UNLOCK(ifa);
9bccf70c 1448 continue;
6d2010ae 1449 }
9bccf70c
A
1450 it6 = (struct in6_ifaddr *)ifa;
1451
1452 /* ignore no autoconf addresses. */
6d2010ae
A
1453 if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0) {
1454 IFA_UNLOCK(ifa);
9bccf70c 1455 continue;
6d2010ae 1456 }
9bccf70c 1457 /* ignore autoconf addresses with different prefixes. */
6d2010ae
A
1458 if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr) {
1459 IFA_UNLOCK(ifa);
9bccf70c 1460 continue;
6d2010ae 1461 }
9bccf70c
A
1462 /*
1463 * Now we are looking at an autoconf address with the same
1464 * prefix as ours. If the address is temporary and is still
1465 * preferred, do not create another one. It would be rare, but
1466 * could happen, for example, when we resume a laptop PC after
1467 * a long period.
1468 */
1469 if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
39236c6e 1470 !IFA6_IS_DEPRECATED(it6, timenow)) {
6d2010ae
A
1471 IFA_UNLOCK(ifa);
1472 if (public_ifa6 != NULL)
1473 IFA_REMREF(&public_ifa6->ia_ifa);
9bccf70c
A
1474 public_ifa6 = NULL;
1475 break;
1476 }
1477
1478 /*
1479 * This is a public autoconf address that has the same prefix
1480 * as ours. If it is preferred, keep it. We can't break the
1481 * loop here, because there may be a still-preferred temporary
1482 * address with the prefix.
1483 */
39236c6e 1484 if (!IFA6_IS_DEPRECATED(it6, timenow)) {
6d2010ae
A
1485 IFA_ADDREF_LOCKED(ifa); /* for public_ifa6 */
1486 IFA_UNLOCK(ifa);
1487 if (public_ifa6 != NULL)
1488 IFA_REMREF(&public_ifa6->ia_ifa);
1489 public_ifa6 = it6;
1490 } else {
1491 IFA_UNLOCK(ifa);
1492 }
9bccf70c 1493 }
91447636 1494 ifnet_lock_done(ifp);
9bccf70c
A
1495
1496 if (public_ifa6 != NULL) {
1497 int e;
1498
39236c6e 1499 if ((e = in6_tmpifadd(public_ifa6, 0)) != 0) {
9bccf70c
A
1500 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
1501 " tmp addr,errno=%d\n", e);
6d2010ae 1502 IFA_REMREF(&public_ifa6->ia_ifa);
39236c6e 1503 return (-1);
9bccf70c 1504 }
6d2010ae 1505 IFA_REMREF(&public_ifa6->ia_ifa);
39236c6e 1506 return (0);
9bccf70c
A
1507 }
1508
39236c6e 1509 return (-1);
9bccf70c
A
1510}
1511
1c79356b
A
1512/*
1513 * Nuke neighbor cache/prefix/default router management table, right before
1514 * ifp goes away.
1515 */
1516void
39236c6e 1517nd6_purge(struct ifnet *ifp)
1c79356b 1518{
b0d623f7 1519 struct llinfo_nd6 *ln;
6d2010ae 1520 struct nd_defrouter *dr, *ndr;
1c79356b 1521 struct nd_prefix *pr, *npr;
fe8ab488 1522 boolean_t removed;
1c79356b
A
1523
1524 /* Nuke default router list entries toward ifp */
91447636 1525 lck_mtx_lock(nd6_mutex);
1c79356b
A
1526 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
1527 /*
1528 * The first entry of the list may be stored in
1529 * the routing table, so we'll delete it later.
1530 */
1531 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = ndr) {
1532 ndr = TAILQ_NEXT(dr, dr_entry);
6d2010ae
A
1533 if (dr->stateflags & NDDRF_INSTALLED)
1534 continue;
1c79356b 1535 if (dr->ifp == ifp)
6d2010ae 1536 defrtrlist_del(dr);
1c79356b
A
1537 }
1538 dr = TAILQ_FIRST(&nd_defrouter);
1539 if (dr->ifp == ifp)
6d2010ae
A
1540 defrtrlist_del(dr);
1541 }
1542
1543 for (dr = TAILQ_FIRST(&nd_defrouter); dr; dr = ndr) {
1544 ndr = TAILQ_NEXT(dr, dr_entry);
1545 if (!(dr->stateflags & NDDRF_INSTALLED))
1546 continue;
1547
1548 if (dr->ifp == ifp)
1549 defrtrlist_del(dr);
1c79356b
A
1550 }
1551
1552 /* Nuke prefix list entries toward ifp */
fe8ab488 1553 removed = FALSE;
1c79356b 1554 for (pr = nd_prefix.lh_first; pr; pr = npr) {
6d2010ae 1555 NDPR_LOCK(pr);
fe8ab488
A
1556 npr = pr->ndpr_next;
1557 if (pr->ndpr_ifp == ifp &&
1558 !(pr->ndpr_stateflags & NDPRF_DEFUNCT)) {
6d2010ae
A
1559 /*
1560 * Because if_detach() does *not* release prefixes
1561 * while purging addresses the reference count will
1562 * still be above zero. We therefore reset it to
1563 * make sure that the prefix really gets purged.
1564 */
1565 pr->ndpr_addrcnt = 0;
1566
9bccf70c
A
1567 /*
1568 * Previously, pr->ndpr_addr is removed as well,
1569 * but I strongly believe we don't have to do it.
1570 * nd6_purge() is only called from in6_ifdetach(),
1571 * which removes all the associated interface addresses
1572 * by itself.
1573 * (jinmei@kame.net 20010129)
1574 */
6d2010ae
A
1575 NDPR_ADDREF_LOCKED(pr);
1576 prelist_remove(pr);
1577 NDPR_UNLOCK(pr);
1578 NDPR_REMREF(pr);
fe8ab488
A
1579 removed = TRUE;
1580 npr = nd_prefix.lh_first;
6d2010ae
A
1581 } else {
1582 NDPR_UNLOCK(pr);
1c79356b
A
1583 }
1584 }
fe8ab488
A
1585 if (removed)
1586 pfxlist_onlink_check();
6d2010ae 1587 lck_mtx_unlock(nd6_mutex);
1c79356b
A
1588
1589 /* cancel default outgoing interface setting */
b0d623f7 1590 if (nd6_defifindex == ifp->if_index) {
1c79356b 1591 nd6_setdefaultiface(0);
b0d623f7 1592 }
1c79356b 1593
316670eb
A
1594 /*
1595 * Perform default router selection even when we are a router,
1596 * if Scoped Routing is enabled.
1597 */
1598 if (ip6_doscopedroute || !ip6_forwarding) {
6d2010ae 1599 lck_mtx_lock(nd6_mutex);
9bccf70c 1600 /* refresh default router list */
6d2010ae
A
1601 defrouter_select(ifp);
1602 lck_mtx_unlock(nd6_mutex);
9bccf70c 1603 }
1c79356b
A
1604
1605 /*
1606 * Nuke neighbor cache entries for the ifp.
1607 * Note that rt->rt_ifp may not be the same as ifp,
1608 * due to KAME goto ours hack. See RTM_RESOLVE case in
1609 * nd6_rtrequest(), and ip6_input().
1610 */
b0d623f7
A
1611again:
1612 lck_mtx_lock(rnh_lock);
1c79356b 1613 ln = llinfo_nd6.ln_next;
b0d623f7 1614 while (ln != NULL && ln != &llinfo_nd6) {
1c79356b 1615 struct rtentry *rt;
b0d623f7 1616 struct llinfo_nd6 *nln;
1c79356b
A
1617
1618 nln = ln->ln_next;
1619 rt = ln->ln_rt;
b0d623f7
A
1620 RT_LOCK(rt);
1621 if (rt->rt_gateway != NULL &&
1622 rt->rt_gateway->sa_family == AF_LINK &&
1623 SDL(rt->rt_gateway)->sdl_index == ifp->if_index) {
39236c6e 1624 RT_ADDREF_LOCKED(rt);
b0d623f7
A
1625 RT_UNLOCK(rt);
1626 lck_mtx_unlock(rnh_lock);
1627 /*
39236c6e 1628 * See comments on nd6_service() for reasons why
b0d623f7
A
1629 * this loop is repeated; we bite the costs of
1630 * going thru the same llinfo_nd6 more than once
1631 * here, since this purge happens during detach,
1632 * and that unlike the timer case, it's possible
1633 * there's more than one purges happening at the
1634 * same time (thus a flag wouldn't buy anything).
1635 */
1636 nd6_free(rt);
39236c6e 1637 RT_REMREF(rt);
b0d623f7
A
1638 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1639 goto again;
1640 } else {
1641 RT_UNLOCK(rt);
1c79356b
A
1642 }
1643 ln = nln;
1644 }
b0d623f7 1645 lck_mtx_unlock(rnh_lock);
1c79356b
A
1646}
1647
b0d623f7
A
1648/*
1649 * Upon success, the returned route will be locked and the caller is
1650 * responsible for releasing the reference and doing RT_UNLOCK(rt).
1651 * This routine does not require rnh_lock to be held by the caller,
1652 * although it needs to be indicated of such a case in order to call
1653 * the correct variant of the relevant routing routines.
1654 */
1c79356b 1655struct rtentry *
39236c6e 1656nd6_lookup(struct in6_addr *addr6, int create, struct ifnet *ifp, int rt_locked)
1c79356b
A
1657{
1658 struct rtentry *rt;
1659 struct sockaddr_in6 sin6;
6d2010ae 1660 unsigned int ifscope;
1c79356b 1661
39236c6e
A
1662 bzero(&sin6, sizeof (sin6));
1663 sin6.sin6_len = sizeof (struct sockaddr_in6);
1c79356b
A
1664 sin6.sin6_family = AF_INET6;
1665 sin6.sin6_addr = *addr6;
b0d623f7 1666
6d2010ae
A
1667 ifscope = (ifp != NULL) ? ifp->if_index : IFSCOPE_NONE;
1668 if (rt_locked) {
1669 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
39236c6e 1670 rt = rtalloc1_scoped_locked(SA(&sin6), create, 0, ifscope);
6d2010ae 1671 } else {
39236c6e 1672 rt = rtalloc1_scoped(SA(&sin6), create, 0, ifscope);
6d2010ae 1673 }
b0d623f7
A
1674
1675 if (rt != NULL) {
1676 RT_LOCK(rt);
1677 if ((rt->rt_flags & RTF_LLINFO) == 0) {
1678 /*
6d2010ae
A
1679 * This is the case for the default route.
1680 * If we want to create a neighbor cache for the
1681 * address, we should free the route for the
1682 * destination and allocate an interface route.
b0d623f7
A
1683 */
1684 if (create) {
1685 RT_UNLOCK(rt);
1686 if (rt_locked)
1687 rtfree_locked(rt);
1688 else
1689 rtfree(rt);
1690 rt = NULL;
1691 }
1c79356b
A
1692 }
1693 }
b0d623f7 1694 if (rt == NULL) {
1c79356b 1695 if (create && ifp) {
b0d623f7 1696 struct ifaddr *ifa;
6d2010ae 1697 u_int32_t ifa_flags;
1c79356b
A
1698 int e;
1699
1700 /*
1701 * If no route is available and create is set,
1702 * we allocate a host route for the destination
1703 * and treat it like an interface route.
1704 * This hack is necessary for a neighbor which can't
1705 * be covered by our own prefix.
1706 */
39236c6e 1707 ifa = ifaof_ifpforaddr(SA(&sin6), ifp);
b0d623f7 1708 if (ifa == NULL)
39236c6e 1709 return (NULL);
1c79356b
A
1710
1711 /*
55e303ae 1712 * Create a new route. RTF_LLINFO is necessary
1c79356b
A
1713 * to create a Neighbor Cache entry for the
1714 * destination in nd6_rtrequest which will be
55e303ae 1715 * called in rtrequest via ifa->ifa_rtrequest.
1c79356b 1716 */
b0d623f7
A
1717 if (!rt_locked)
1718 lck_mtx_lock(rnh_lock);
6d2010ae
A
1719 IFA_LOCK_SPIN(ifa);
1720 ifa_flags = ifa->ifa_flags;
1721 IFA_UNLOCK(ifa);
1722 if ((e = rtrequest_scoped_locked(RTM_ADD,
39236c6e 1723 SA(&sin6), ifa->ifa_addr, SA(&all1_sa),
6d2010ae
A
1724 (ifa_flags | RTF_HOST | RTF_LLINFO) &
1725 ~RTF_CLONING, &rt, ifscope)) != 0) {
91447636 1726 if (e != EEXIST)
b0d623f7
A
1727 log(LOG_ERR, "%s: failed to add route "
1728 "for a neighbor(%s), errno=%d\n",
1729 __func__, ip6_sprintf(addr6), e);
91447636 1730 }
b0d623f7
A
1731 if (!rt_locked)
1732 lck_mtx_unlock(rnh_lock);
6d2010ae 1733 IFA_REMREF(ifa);
b0d623f7 1734 if (rt == NULL)
39236c6e 1735 return (NULL);
b0d623f7
A
1736
1737 RT_LOCK(rt);
1c79356b 1738 if (rt->rt_llinfo) {
b0d623f7 1739 struct llinfo_nd6 *ln = rt->rt_llinfo;
1c79356b
A
1740 ln->ln_state = ND6_LLINFO_NOSTATE;
1741 }
91447636 1742 } else {
39236c6e 1743 return (NULL);
91447636 1744 }
1c79356b 1745 }
b0d623f7 1746 RT_LOCK_ASSERT_HELD(rt);
1c79356b
A
1747 /*
1748 * Validation for the entry.
55e303ae
A
1749 * Note that the check for rt_llinfo is necessary because a cloned
1750 * route from a parent route that has the L flag (e.g. the default
1751 * route to a p2p interface) may have the flag, too, while the
1752 * destination is not actually a neighbor.
1c79356b 1753 * XXX: we can't use rt->rt_ifp to check for the interface, since
39236c6e
A
1754 * it might be the loopback interface if the entry is for our
1755 * own address on a non-loopback interface. Instead, we should
1756 * use rt->rt_ifa->ifa_ifp, which would specify the REAL
6d2010ae
A
1757 * interface.
1758 * Note also that ifa_ifp and ifp may differ when we connect two
1759 * interfaces to a same link, install a link prefix to an interface,
1760 * and try to install a neighbor cache on an interface that does not
1761 * have a route to the prefix.
316670eb
A
1762 *
1763 * If the address is from a proxied prefix, the ifa_ifp and ifp might
1764 * not match, because nd6_na_input() could have modified the ifp
1765 * of the route to point to the interface where the NA arrived on,
1766 * hence the test for RTF_PROXY.
1c79356b 1767 */
316670eb 1768 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
39236c6e 1769 rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
316670eb
A
1770 (ifp && rt->rt_ifa->ifa_ifp != ifp &&
1771 !(rt->rt_flags & RTF_PROXY))) {
b0d623f7
A
1772 RT_REMREF_LOCKED(rt);
1773 RT_UNLOCK(rt);
1c79356b 1774 if (create) {
b0d623f7
A
1775 log(LOG_DEBUG, "%s: failed to lookup %s "
1776 "(if = %s)\n", __func__, ip6_sprintf(addr6),
1777 ifp ? if_name(ifp) : "unspec");
1c79356b
A
1778 /* xxx more logs... kazu */
1779 }
39236c6e 1780 return (NULL);
b0d623f7
A
1781 }
1782 /*
1783 * Caller needs to release reference and call RT_UNLOCK(rt).
1784 */
39236c6e 1785 return (rt);
1c79356b
A
1786}
1787
1788/*
6d2010ae
A
1789 * Test whether a given IPv6 address is a neighbor or not, ignoring
1790 * the actual neighbor cache. The neighbor cache is ignored in order
1791 * to not reenter the routing code from within itself.
1c79356b 1792 */
6d2010ae 1793static int
39236c6e 1794nd6_is_new_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp)
1c79356b 1795{
6d2010ae
A
1796 struct nd_prefix *pr;
1797 struct ifaddr *dstaddr;
1c79356b 1798
6d2010ae 1799 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1c79356b 1800
9bccf70c
A
1801 /*
1802 * A link-local address is always a neighbor.
6d2010ae 1803 * XXX: a link does not necessarily specify a single interface.
9bccf70c 1804 */
6d2010ae
A
1805 if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
1806 struct sockaddr_in6 sin6_copy;
1807 u_int32_t zone;
1808
1809 /*
1810 * We need sin6_copy since sa6_recoverscope() may modify the
1811 * content (XXX).
1812 */
1813 sin6_copy = *addr;
316670eb 1814 if (sa6_recoverscope(&sin6_copy, FALSE))
6d2010ae
A
1815 return (0); /* XXX: should be impossible */
1816 if (in6_setscope(&sin6_copy.sin6_addr, ifp, &zone))
1817 return (0);
1818 if (sin6_copy.sin6_scope_id == zone)
1819 return (1);
1820 else
1821 return (0);
1822 }
1c79356b
A
1823
1824 /*
1825 * If the address matches one of our addresses,
1826 * it should be a neighbor.
6d2010ae
A
1827 * If the address matches one of our on-link prefixes, it should be a
1828 * neighbor.
1c79356b 1829 */
6d2010ae
A
1830 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1831 NDPR_LOCK(pr);
1832 if (pr->ndpr_ifp != ifp) {
1833 NDPR_UNLOCK(pr);
1834 continue;
1835 }
1836 if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
1837 NDPR_UNLOCK(pr);
91447636 1838 continue;
6d2010ae
A
1839 }
1840 if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
1841 &addr->sin6_addr, &pr->ndpr_mask)) {
1842 NDPR_UNLOCK(pr);
1843 return (1);
1844 }
1845 NDPR_UNLOCK(pr);
1846 }
1c79356b 1847
6d2010ae
A
1848 /*
1849 * If the address is assigned on the node of the other side of
1850 * a p2p interface, the address should be a neighbor.
1851 */
39236c6e 1852 dstaddr = ifa_ifwithdstaddr(SA(addr));
6d2010ae
A
1853 if (dstaddr != NULL) {
1854 if (dstaddr->ifa_ifp == ifp) {
1855 IFA_REMREF(dstaddr);
1856 return (1);
1c79356b 1857 }
6d2010ae
A
1858 IFA_REMREF(dstaddr);
1859 dstaddr = NULL;
1c79356b 1860 }
6d2010ae
A
1861
1862 /*
1863 * If the default router list is empty, all addresses are regarded
1864 * as on-link, and thus, as a neighbor.
1865 * XXX: we restrict the condition to hosts, because routers usually do
1866 * not have the "default router list".
316670eb
A
1867 * XXX: this block should eventually be removed (it is disabled when
1868 * Scoped Routing is in effect); treating all destinations as on-link
1869 * in the absence of a router is rather harmful.
6d2010ae 1870 */
316670eb
A
1871 if (!ip6_doscopedroute && !ip6_forwarding &&
1872 TAILQ_FIRST(&nd_defrouter) == NULL &&
6d2010ae
A
1873 nd6_defifindex == ifp->if_index) {
1874 return (1);
1875 }
1876
1877 return (0);
1878}
1879
1880
1881/*
1882 * Detect if a given IPv6 address identifies a neighbor on a given link.
1883 * XXX: should take care of the destination of a p2p link?
1884 */
1885int
39236c6e
A
1886nd6_is_addr_neighbor(struct sockaddr_in6 *addr, struct ifnet *ifp,
1887 int rt_locked)
6d2010ae
A
1888{
1889 struct rtentry *rt;
1890
1891 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
1892 lck_mtx_lock(nd6_mutex);
1893 if (nd6_is_new_addr_neighbor(addr, ifp)) {
1894 lck_mtx_unlock(nd6_mutex);
1895 return (1);
1896 }
1897 lck_mtx_unlock(nd6_mutex);
1c79356b
A
1898
1899 /*
1900 * Even if the address matches none of our addresses, it might be
6d2010ae 1901 * in the neighbor cache.
1c79356b 1902 */
b0d623f7
A
1903 if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp, rt_locked)) != NULL) {
1904 RT_LOCK_ASSERT_HELD(rt);
1905 RT_REMREF_LOCKED(rt);
1906 RT_UNLOCK(rt);
6d2010ae 1907 return (1);
b0d623f7 1908 }
1c79356b 1909
6d2010ae 1910 return (0);
1c79356b
A
1911}
1912
1913/*
1914 * Free an nd6 llinfo entry.
6d2010ae
A
1915 * Since the function would cause significant changes in the kernel, DO NOT
1916 * make it global, unless you have a strong reason for the change, and are sure
1917 * that the change is safe.
1c79356b 1918 */
b0d623f7 1919void
39236c6e 1920nd6_free(struct rtentry *rt)
1c79356b 1921{
b0d623f7
A
1922 struct llinfo_nd6 *ln;
1923 struct in6_addr in6;
1c79356b
A
1924 struct nd_defrouter *dr;
1925
b0d623f7
A
1926 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1927 RT_LOCK_ASSERT_NOTHELD(rt);
1928 lck_mtx_lock(nd6_mutex);
1929
1930 RT_LOCK(rt);
1931 RT_ADDREF_LOCKED(rt); /* Extra ref */
1932 ln = rt->rt_llinfo;
39236c6e 1933 in6 = SIN6(rt_key(rt))->sin6_addr;
b0d623f7
A
1934
1935 /*
1936 * Prevent another thread from modifying rt_key, rt_gateway
1937 * via rt_setgate() after the rt_lock is dropped by marking
1938 * the route as defunct.
1939 */
1940 rt->rt_flags |= RTF_CONDEMNED;
1941
1c79356b 1942 /*
316670eb
A
1943 * We used to have pfctlinput(PRC_HOSTDEAD) here. Even though it is
1944 * not harmful, it was not really necessary. Perform default router
1945 * selection even when we are a router, if Scoped Routing is enabled.
1c79356b 1946 */
316670eb 1947 if (ip6_doscopedroute || !ip6_forwarding) {
39236c6e 1948 dr = defrouter_lookup(&SIN6(rt_key(rt))->sin6_addr, rt->rt_ifp);
9bccf70c 1949
b7266188 1950 if ((ln && ln->ln_router) || dr) {
1c79356b
A
1951 /*
1952 * rt6_flush must be called whether or not the neighbor
1953 * is in the Default Router List.
1954 * See a corresponding comment in nd6_na_input().
1955 */
b0d623f7 1956 RT_UNLOCK(rt);
6d2010ae 1957 lck_mtx_unlock(nd6_mutex);
1c79356b 1958 rt6_flush(&in6, rt->rt_ifp);
6d2010ae 1959 lck_mtx_lock(nd6_mutex);
b0d623f7
A
1960 } else {
1961 RT_UNLOCK(rt);
1c79356b
A
1962 }
1963
1964 if (dr) {
6d2010ae 1965 NDDR_REMREF(dr);
1c79356b
A
1966 /*
1967 * Unreachablity of a router might affect the default
1968 * router selection and on-link detection of advertised
1969 * prefixes.
1970 */
1971
1972 /*
1973 * Temporarily fake the state to choose a new default
1974 * router and to perform on-link determination of
55e303ae 1975 * prefixes correctly.
1c79356b
A
1976 * Below the state will be set correctly,
1977 * or the entry itself will be deleted.
1978 */
b0d623f7 1979 RT_LOCK_SPIN(rt);
1c79356b
A
1980 ln->ln_state = ND6_LLINFO_INCOMPLETE;
1981
9bccf70c
A
1982 /*
1983 * Since defrouter_select() does not affect the
1984 * on-link determination and MIP6 needs the check
1985 * before the default router selection, we perform
1986 * the check now.
1987 */
b0d623f7 1988 RT_UNLOCK(rt);
6d2010ae 1989 pfxlist_onlink_check();
9bccf70c 1990
6d2010ae
A
1991 /*
1992 * refresh default router list
1993 */
1994 defrouter_select(rt->rt_ifp);
1c79356b 1995 }
b0d623f7
A
1996 RT_LOCK_ASSERT_NOTHELD(rt);
1997 } else {
1998 RT_UNLOCK(rt);
1c79356b
A
1999 }
2000
b0d623f7 2001 lck_mtx_unlock(nd6_mutex);
9bccf70c
A
2002 /*
2003 * Detach the route from the routing tree and the list of neighbor
2004 * caches, and disable the route entry not to be used in already
2005 * cached routes.
2006 */
39236c6e 2007 (void) rtrequest(RTM_DELETE, rt_key(rt), NULL, rt_mask(rt), 0, NULL);
9bccf70c 2008
b0d623f7
A
2009 /* Extra ref held above; now free it */
2010 rtfree(rt);
1c79356b
A
2011}
2012
1c79356b 2013void
39236c6e 2014nd6_rtrequest(int req, struct rtentry *rt, struct sockaddr *sa)
1c79356b 2015{
39236c6e 2016#pragma unused(sa)
1c79356b 2017 struct sockaddr *gate = rt->rt_gateway;
b0d623f7 2018 struct llinfo_nd6 *ln = rt->rt_llinfo;
39236c6e
A
2019 static struct sockaddr_dl null_sdl =
2020 { .sdl_len = sizeof (null_sdl), .sdl_family = AF_LINK };
1c79356b
A
2021 struct ifnet *ifp = rt->rt_ifp;
2022 struct ifaddr *ifa;
39236c6e
A
2023 uint64_t timenow;
2024 char buf[MAX_IPv6_STR_LEN];
91447636 2025
39236c6e 2026 VERIFY(nd6_init_done);
b0d623f7
A
2027 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
2028 RT_LOCK_ASSERT_HELD(rt);
1c79356b 2029
39236c6e
A
2030 /*
2031 * We have rnh_lock held, see if we need to schedule the timer;
2032 * we might do this again below during RTM_RESOLVE, but doing it
2033 * now handles all other cases.
2034 */
2035 if (nd6_sched_timeout_want)
2036 nd6_sched_timeout(NULL, NULL);
2037
2038 if (rt->rt_flags & RTF_GATEWAY)
1c79356b
A
2039 return;
2040
39236c6e 2041 if (!nd6_need_cache(ifp) && !(rt->rt_flags & RTF_HOST)) {
9bccf70c
A
2042 /*
2043 * This is probably an interface direct route for a link
2044 * which does not need neighbor caches (e.g. fe80::%lo0/64).
2045 * We do not need special treatment below for such a route.
2046 * Moreover, the RTF_LLINFO flag which would be set below
2047 * would annoy the ndp(8) command.
2048 */
2049 return;
2050 }
2051
b0d623f7
A
2052 if (req == RTM_RESOLVE) {
2053 int no_nd_cache;
2054
2055 if (!nd6_need_cache(ifp)) { /* stf case */
2056 no_nd_cache = 1;
2057 } else {
6d2010ae
A
2058 struct sockaddr_in6 sin6;
2059
2060 rtkey_to_sa6(rt, &sin6);
b0d623f7
A
2061 /*
2062 * nd6_is_addr_neighbor() may call nd6_lookup(),
2063 * therefore we drop rt_lock to avoid deadlock
6d2010ae 2064 * during the lookup.
b0d623f7
A
2065 */
2066 RT_ADDREF_LOCKED(rt);
2067 RT_UNLOCK(rt);
6d2010ae 2068 no_nd_cache = !nd6_is_addr_neighbor(&sin6, ifp, 1);
b0d623f7
A
2069 RT_LOCK(rt);
2070 RT_REMREF_LOCKED(rt);
2071 }
2072
55e303ae
A
2073 /*
2074 * FreeBSD and BSD/OS often make a cloned host route based
2075 * on a less-specific route (e.g. the default route).
2076 * If the less specific route does not have a "gateway"
2077 * (this is the case when the route just goes to a p2p or an
2078 * stf interface), we'll mistakenly make a neighbor cache for
2079 * the host route, and will see strange neighbor solicitation
2080 * for the corresponding destination. In order to avoid the
2081 * confusion, we check if the destination of the route is
2082 * a neighbor in terms of neighbor discovery, and stop the
2083 * process if not. Additionally, we remove the LLINFO flag
2084 * so that ndp(8) will not try to get the neighbor information
2085 * of the destination.
2086 */
b0d623f7
A
2087 if (no_nd_cache) {
2088 rt->rt_flags &= ~RTF_LLINFO;
2089 return;
2090 }
55e303ae
A
2091 }
2092
39236c6e
A
2093 timenow = net_uptime();
2094
1c79356b
A
2095 switch (req) {
2096 case RTM_ADD:
2097 /*
2098 * There is no backward compatibility :)
2099 *
2100 * if ((rt->rt_flags & RTF_HOST) == 0 &&
39236c6e
A
2101 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
2102 * rt->rt_flags |= RTF_CLONING;
1c79356b 2103 */
6d2010ae
A
2104 if ((rt->rt_flags & RTF_CLONING) ||
2105 ((rt->rt_flags & RTF_LLINFO) && ln == NULL)) {
1c79356b 2106 /*
6d2010ae
A
2107 * Case 1: This route should come from a route to
2108 * interface (RTF_CLONING case) or the route should be
2109 * treated as on-link but is currently not
2110 * (RTF_LLINFO && ln == NULL case).
1c79356b 2111 */
39236c6e 2112 if (rt_setgate(rt, rt_key(rt), SA(&null_sdl)) == 0) {
b0d623f7
A
2113 gate = rt->rt_gateway;
2114 SDL(gate)->sdl_type = ifp->if_type;
2115 SDL(gate)->sdl_index = ifp->if_index;
2116 /*
2117 * In case we're called before 1.0 sec.
2118 * has elapsed.
2119 */
39236c6e
A
2120 if (ln != NULL) {
2121 ln_setexpire(ln,
db609669 2122 (ifp->if_eflags & IFEF_IPV6_ND6ALT)
39236c6e
A
2123 ? 0 : MAX(timenow, 1));
2124 }
1c79356b 2125 }
39236c6e 2126 if (rt->rt_flags & RTF_CLONING)
1c79356b
A
2127 break;
2128 }
2129 /*
2130 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
2131 * We don't do that here since llinfo is not ready yet.
2132 *
2133 * There are also couple of other things to be discussed:
2134 * - unsolicited NA code needs improvement beforehand
39236c6e 2135 * - RFC4861 says we MAY send multicast unsolicited NA
1c79356b
A
2136 * (7.2.6 paragraph 4), however, it also says that we
2137 * SHOULD provide a mechanism to prevent multicast NA storm.
2138 * we don't have anything like it right now.
9bccf70c 2139 * note that the mechanism needs a mutual agreement
1c79356b 2140 * between proxies, which means that we need to implement
9bccf70c 2141 * a new protocol, or a new kludge.
39236c6e 2142 * - from RFC4861 6.2.4, host MUST NOT send an unsolicited RA.
1c79356b
A
2143 * we need to check ip6forwarding before sending it.
2144 * (or should we allow proxy ND configuration only for
2145 * routers? there's no mention about proxy ND from hosts)
2146 */
1c79356b
A
2147 /* FALLTHROUGH */
2148 case RTM_RESOLVE:
39236c6e 2149 if (!(ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))) {
1c79356b
A
2150 /*
2151 * Address resolution isn't necessary for a point to
2152 * point link, so we can skip this test for a p2p link.
2153 */
2154 if (gate->sa_family != AF_LINK ||
39236c6e 2155 gate->sa_len < sizeof (null_sdl)) {
6d2010ae
A
2156 /* Don't complain in case of RTM_ADD */
2157 if (req == RTM_RESOLVE) {
39236c6e
A
2158 log(LOG_ERR, "%s: route to %s has bad "
2159 "gateway address (sa_family %u "
2160 "sa_len %u) on %s\n", __func__,
2161 inet_ntop(AF_INET6,
2162 &SIN6(rt_key(rt))->sin6_addr, buf,
2163 sizeof (buf)), gate->sa_family,
2164 gate->sa_len, if_name(ifp));
6d2010ae 2165 }
1c79356b
A
2166 break;
2167 }
2168 SDL(gate)->sdl_type = ifp->if_type;
2169 SDL(gate)->sdl_index = ifp->if_index;
2170 }
2171 if (ln != NULL)
2172 break; /* This happens on a route change */
2173 /*
2174 * Case 2: This route may come from cloning, or a manual route
2175 * add with a LL address.
2176 */
39236c6e
A
2177 rt->rt_llinfo = ln = nd6_llinfo_alloc(M_WAITOK);
2178 if (ln == NULL)
1c79356b 2179 break;
b0d623f7 2180
1c79356b 2181 nd6_allocated++;
39236c6e
A
2182 rt->rt_llinfo_get_ri = nd6_llinfo_get_ri;
2183 rt->rt_llinfo_get_iflri = nd6_llinfo_get_iflri;
2184 rt->rt_llinfo_purge = nd6_llinfo_purge;
2185 rt->rt_llinfo_free = nd6_llinfo_free;
3e170ce0 2186 rt->rt_llinfo_refresh = nd6_llinfo_refresh;
39236c6e 2187 rt->rt_flags |= RTF_LLINFO;
1c79356b
A
2188 ln->ln_rt = rt;
2189 /* this is required for "ndp" command. - shin */
2190 if (req == RTM_ADD) {
39236c6e 2191 /*
1c79356b
A
2192 * gate should have some valid AF_LINK entry,
2193 * and ln->ln_expire should have some lifetime
2194 * which is specified by ndp command.
2195 */
2196 ln->ln_state = ND6_LLINFO_REACHABLE;
2197 } else {
39236c6e 2198 /*
1c79356b
A
2199 * When req == RTM_RESOLVE, rt is created and
2200 * initialized in rtrequest(), so rt_expire is 0.
2201 */
2202 ln->ln_state = ND6_LLINFO_NOSTATE;
39236c6e 2203
b0d623f7 2204 /* In case we're called before 1.0 sec. has elapsed */
39236c6e
A
2205 ln_setexpire(ln, (ifp->if_eflags & IFEF_IPV6_ND6ALT) ?
2206 0 : MAX(timenow, 1));
1c79356b 2207 }
b0d623f7 2208 LN_INSERTHEAD(ln);
39236c6e
A
2209 nd6_inuse++;
2210
2211 /* We have at least one entry; arm the timer if not already */
2212 nd6_sched_timeout(NULL, NULL);
b0d623f7
A
2213
2214 /*
2215 * If we have too many cache entries, initiate immediate
2216 * purging for some "less recently used" entries. Note that
2217 * we cannot directly call nd6_free() here because it would
2218 * cause re-entering rtable related routines triggering an LOR
2219 * problem.
2220 */
39236c6e 2221 if (ip6_neighborgcthresh > 0 &&
b0d623f7
A
2222 nd6_inuse >= ip6_neighborgcthresh) {
2223 int i;
2224
2225 for (i = 0; i < 10 && llinfo_nd6.ln_prev != ln; i++) {
2226 struct llinfo_nd6 *ln_end = llinfo_nd6.ln_prev;
2227 struct rtentry *rt_end = ln_end->ln_rt;
2228
2229 /* Move this entry to the head */
2230 RT_LOCK(rt_end);
2231 LN_DEQUEUE(ln_end);
2232 LN_INSERTHEAD(ln_end);
2233
2234 if (ln_end->ln_expire == 0) {
2235 RT_UNLOCK(rt_end);
2236 continue;
2237 }
2238 if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE)
2239 ln_end->ln_state = ND6_LLINFO_STALE;
2240 else
2241 ln_end->ln_state = ND6_LLINFO_PURGE;
39236c6e 2242 ln_setexpire(ln_end, timenow);
b0d623f7
A
2243 RT_UNLOCK(rt_end);
2244 }
2245 }
1c79356b
A
2246
2247 /*
2248 * check if rt_key(rt) is one of my address assigned
2249 * to the interface.
2250 */
2251 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
39236c6e
A
2252 &SIN6(rt_key(rt))->sin6_addr);
2253 if (ifa != NULL) {
1c79356b 2254 caddr_t macp = nd6_ifptomac(ifp);
39236c6e 2255 ln_setexpire(ln, 0);
1c79356b 2256 ln->ln_state = ND6_LLINFO_REACHABLE;
39236c6e 2257 if (macp != NULL) {
1c79356b
A
2258 Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen);
2259 SDL(gate)->sdl_alen = ifp->if_addrlen;
2260 }
2261 if (nd6_useloopback) {
6d2010ae
A
2262 if (rt->rt_ifp != lo_ifp) {
2263 /*
2264 * Purge any link-layer info caching.
2265 */
2266 if (rt->rt_llinfo_purge != NULL)
2267 rt->rt_llinfo_purge(rt);
2268
2269 /*
2270 * Adjust route ref count for the
2271 * interfaces.
2272 */
2273 if (rt->rt_if_ref_fn != NULL) {
2274 rt->rt_if_ref_fn(lo_ifp, 1);
39236c6e
A
2275 rt->rt_if_ref_fn(rt->rt_ifp,
2276 -1);
6d2010ae 2277 }
d1ecb069 2278 }
39236c6e
A
2279 rt->rt_ifp = lo_ifp;
2280 /*
2281 * If rmx_mtu is not locked, update it
2282 * to the MTU used by the new interface.
2283 */
2284 if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
2285 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
1c79356b
A
2286 /*
2287 * Make sure rt_ifa be equal to the ifaddr
2288 * corresponding to the address.
2289 * We need this because when we refer
2290 * rt_ifa->ia6_flags in ip6_input, we assume
2291 * that the rt_ifa points to the address instead
2292 * of the loopback address.
2293 */
2294 if (ifa != rt->rt_ifa) {
9bccf70c 2295 rtsetifa(rt, ifa);
1c79356b
A
2296 }
2297 }
6d2010ae 2298 IFA_REMREF(ifa);
1c79356b 2299 } else if (rt->rt_flags & RTF_ANNOUNCE) {
39236c6e 2300 ln_setexpire(ln, 0);
1c79356b
A
2301 ln->ln_state = ND6_LLINFO_REACHABLE;
2302
2303 /* join solicited node multicast for proxy ND */
2304 if (ifp->if_flags & IFF_MULTICAST) {
2305 struct in6_addr llsol;
6d2010ae 2306 struct in6_multi *in6m;
1c79356b
A
2307 int error;
2308
2309 llsol = SIN6(rt_key(rt))->sin6_addr;
6d2010ae 2310 llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
1c79356b
A
2311 llsol.s6_addr32[1] = 0;
2312 llsol.s6_addr32[2] = htonl(1);
2313 llsol.s6_addr8[12] = 0xff;
6d2010ae
A
2314 if (in6_setscope(&llsol, ifp, NULL))
2315 break;
39236c6e
A
2316 error = in6_mc_join(ifp, &llsol,
2317 NULL, &in6m, 0);
6d2010ae 2318 if (error) {
9bccf70c
A
2319 nd6log((LOG_ERR, "%s: failed to join "
2320 "%s (errno=%d)\n", if_name(ifp),
2321 ip6_sprintf(&llsol), error));
6d2010ae
A
2322 } else {
2323 IN6M_REMREF(in6m);
9bccf70c 2324 }
1c79356b
A
2325 }
2326 }
2327 break;
2328
2329 case RTM_DELETE:
6d2010ae 2330 if (ln == NULL)
1c79356b
A
2331 break;
2332 /* leave from solicited node multicast for proxy ND */
39236c6e
A
2333 if ((rt->rt_flags & RTF_ANNOUNCE) &&
2334 (ifp->if_flags & IFF_MULTICAST)) {
1c79356b
A
2335 struct in6_addr llsol;
2336 struct in6_multi *in6m;
2337
2338 llsol = SIN6(rt_key(rt))->sin6_addr;
6d2010ae 2339 llsol.s6_addr32[0] = IPV6_ADDR_INT32_MLL;
1c79356b
A
2340 llsol.s6_addr32[1] = 0;
2341 llsol.s6_addr32[2] = htonl(1);
2342 llsol.s6_addr8[12] = 0xff;
6d2010ae
A
2343 if (in6_setscope(&llsol, ifp, NULL) == 0) {
2344 in6_multihead_lock_shared();
2345 IN6_LOOKUP_MULTI(&llsol, ifp, in6m);
2346 in6_multihead_lock_done();
2347 if (in6m != NULL) {
2348 in6_mc_leave(in6m, NULL);
2349 IN6M_REMREF(in6m);
2350 }
2351 }
1c79356b
A
2352 }
2353 nd6_inuse--;
b0d623f7
A
2354 /*
2355 * Unchain it but defer the actual freeing until the route
2356 * itself is to be freed. rt->rt_llinfo still points to
2357 * llinfo_nd6, and likewise, ln->ln_rt stil points to this
2358 * route entry, except that RTF_LLINFO is now cleared.
2359 */
2360 if (ln->ln_flags & ND6_LNF_IN_USE)
2361 LN_DEQUEUE(ln);
6d2010ae
A
2362
2363 /*
2364 * Purge any link-layer info caching.
2365 */
2366 if (rt->rt_llinfo_purge != NULL)
2367 rt->rt_llinfo_purge(rt);
2368
1c79356b 2369 rt->rt_flags &= ~RTF_LLINFO;
6d2010ae 2370 if (ln->ln_hold != NULL) {
3e170ce0 2371 m_freem_list(ln->ln_hold);
6d2010ae
A
2372 ln->ln_hold = NULL;
2373 }
1c79356b
A
2374 }
2375}
2376
316670eb 2377static int
b0d623f7 2378nd6_siocgdrlst(void *data, int data_is_64)
1c79356b 2379{
316670eb 2380 struct in6_drlist_32 *drl_32;
b0d623f7
A
2381 struct nd_defrouter *dr;
2382 int i = 0;
1c79356b 2383
b0d623f7
A
2384 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2385
b0d623f7 2386 dr = TAILQ_FIRST(&nd_defrouter);
316670eb
A
2387
2388 /* For 64-bit process */
b0d623f7 2389 if (data_is_64) {
316670eb
A
2390 struct in6_drlist_64 *drl_64;
2391
2392 drl_64 = _MALLOC(sizeof (*drl_64), M_TEMP, M_WAITOK|M_ZERO);
2393 if (drl_64 == NULL)
2394 return (ENOMEM);
2395
2396 /* preserve the interface name */
2397 bcopy(data, drl_64, sizeof (drl_64->ifname));
2398
1c79356b 2399 while (dr && i < DRLSTSIZ) {
b0d623f7 2400 drl_64->defrouter[i].rtaddr = dr->rtaddr;
39236c6e
A
2401 if (IN6_IS_ADDR_LINKLOCAL(
2402 &drl_64->defrouter[i].rtaddr)) {
1c79356b 2403 /* XXX: need to this hack for KAME stack */
b0d623f7
A
2404 drl_64->defrouter[i].rtaddr.s6_addr16[1] = 0;
2405 } else {
1c79356b
A
2406 log(LOG_ERR,
2407 "default router list contains a "
2408 "non-linklocal address(%s)\n",
b0d623f7
A
2409 ip6_sprintf(&drl_64->defrouter[i].rtaddr));
2410 }
2411 drl_64->defrouter[i].flags = dr->flags;
2412 drl_64->defrouter[i].rtlifetime = dr->rtlifetime;
39236c6e 2413 drl_64->defrouter[i].expire = nddr_getexpire(dr);
b0d623f7 2414 drl_64->defrouter[i].if_index = dr->ifp->if_index;
1c79356b
A
2415 i++;
2416 dr = TAILQ_NEXT(dr, dr_entry);
2417 }
316670eb
A
2418 bcopy(drl_64, data, sizeof (*drl_64));
2419 _FREE(drl_64, M_TEMP);
2420 return (0);
b0d623f7 2421 }
316670eb 2422
b0d623f7 2423 /* For 32-bit process */
316670eb
A
2424 drl_32 = _MALLOC(sizeof (*drl_32), M_TEMP, M_WAITOK|M_ZERO);
2425 if (drl_32 == NULL)
2426 return (ENOMEM);
2427
2428 /* preserve the interface name */
2429 bcopy(data, drl_32, sizeof (drl_32->ifname));
2430
39236c6e 2431 while (dr != NULL && i < DRLSTSIZ) {
b0d623f7
A
2432 drl_32->defrouter[i].rtaddr = dr->rtaddr;
2433 if (IN6_IS_ADDR_LINKLOCAL(&drl_32->defrouter[i].rtaddr)) {
2434 /* XXX: need to this hack for KAME stack */
2435 drl_32->defrouter[i].rtaddr.s6_addr16[1] = 0;
2436 } else {
2437 log(LOG_ERR,
2438 "default router list contains a "
2439 "non-linklocal address(%s)\n",
2440 ip6_sprintf(&drl_32->defrouter[i].rtaddr));
2441 }
2442 drl_32->defrouter[i].flags = dr->flags;
2443 drl_32->defrouter[i].rtlifetime = dr->rtlifetime;
39236c6e 2444 drl_32->defrouter[i].expire = nddr_getexpire(dr);
b0d623f7
A
2445 drl_32->defrouter[i].if_index = dr->ifp->if_index;
2446 i++;
2447 dr = TAILQ_NEXT(dr, dr_entry);
2448 }
316670eb
A
2449 bcopy(drl_32, data, sizeof (*drl_32));
2450 _FREE(drl_32, M_TEMP);
2451 return (0);
b0d623f7
A
2452}
2453
316670eb
A
2454/*
2455 * XXX meaning of fields, especialy "raflags", is very
2456 * differnet between RA prefix list and RR/static prefix list.
2457 * how about separating ioctls into two?
2458 */
2459static int
b0d623f7
A
2460nd6_siocgprlst(void *data, int data_is_64)
2461{
316670eb 2462 struct in6_prlist_32 *prl_32;
b0d623f7 2463 struct nd_prefix *pr;
b0d623f7
A
2464 int i = 0;
2465
2466 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
316670eb 2467
b0d623f7 2468 pr = nd_prefix.lh_first;
316670eb
A
2469
2470 /* For 64-bit process */
b0d623f7 2471 if (data_is_64) {
316670eb
A
2472 struct in6_prlist_64 *prl_64;
2473
2474 prl_64 = _MALLOC(sizeof (*prl_64), M_TEMP, M_WAITOK|M_ZERO);
2475 if (prl_64 == NULL)
2476 return (ENOMEM);
2477
2478 /* preserve the interface name */
2479 bcopy(data, prl_64, sizeof (prl_64->ifname));
2480
1c79356b
A
2481 while (pr && i < PRLSTSIZ) {
2482 struct nd_pfxrouter *pfr;
2483 int j;
2484
6d2010ae 2485 NDPR_LOCK(pr);
b0d623f7 2486 (void) in6_embedscope(&prl_64->prefix[i].prefix,
6d2010ae 2487 &pr->ndpr_prefix, NULL, NULL, NULL);
b0d623f7
A
2488 prl_64->prefix[i].raflags = pr->ndpr_raf;
2489 prl_64->prefix[i].prefixlen = pr->ndpr_plen;
2490 prl_64->prefix[i].vltime = pr->ndpr_vltime;
2491 prl_64->prefix[i].pltime = pr->ndpr_pltime;
2492 prl_64->prefix[i].if_index = pr->ndpr_ifp->if_index;
39236c6e 2493 prl_64->prefix[i].expire = ndpr_getexpire(pr);
1c79356b
A
2494
2495 pfr = pr->ndpr_advrtrs.lh_first;
2496 j = 0;
9bccf70c 2497 while (pfr) {
1c79356b 2498 if (j < DRLSTSIZ) {
39236c6e 2499#define RTRADDR prl_64->prefix[i].advrtr[j]
1c79356b
A
2500 RTRADDR = pfr->router->rtaddr;
2501 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
2502 /* XXX: hack for KAME */
2503 RTRADDR.s6_addr16[1] = 0;
b0d623f7 2504 } else {
1c79356b
A
2505 log(LOG_ERR,
2506 "a router(%s) advertises "
2507 "a prefix with "
2508 "non-link local address\n",
2509 ip6_sprintf(&RTRADDR));
b0d623f7 2510 }
1c79356b
A
2511#undef RTRADDR
2512 }
2513 j++;
2514 pfr = pfr->pfr_next;
2515 }
b0d623f7
A
2516 prl_64->prefix[i].advrtrs = j;
2517 prl_64->prefix[i].origin = PR_ORIG_RA;
6d2010ae 2518 NDPR_UNLOCK(pr);
1c79356b
A
2519
2520 i++;
2521 pr = pr->ndpr_next;
2522 }
316670eb
A
2523 bcopy(prl_64, data, sizeof (*prl_64));
2524 _FREE(prl_64, M_TEMP);
2525 return (0);
b0d623f7 2526 }
316670eb 2527
b0d623f7 2528 /* For 32-bit process */
316670eb
A
2529 prl_32 = _MALLOC(sizeof (*prl_32), M_TEMP, M_WAITOK|M_ZERO);
2530 if (prl_32 == NULL)
2531 return (ENOMEM);
2532
2533 /* preserve the interface name */
2534 bcopy(data, prl_32, sizeof (prl_32->ifname));
2535
b0d623f7
A
2536 while (pr && i < PRLSTSIZ) {
2537 struct nd_pfxrouter *pfr;
2538 int j;
2539
6d2010ae 2540 NDPR_LOCK(pr);
b0d623f7 2541 (void) in6_embedscope(&prl_32->prefix[i].prefix,
6d2010ae 2542 &pr->ndpr_prefix, NULL, NULL, NULL);
b0d623f7
A
2543 prl_32->prefix[i].raflags = pr->ndpr_raf;
2544 prl_32->prefix[i].prefixlen = pr->ndpr_plen;
2545 prl_32->prefix[i].vltime = pr->ndpr_vltime;
2546 prl_32->prefix[i].pltime = pr->ndpr_pltime;
2547 prl_32->prefix[i].if_index = pr->ndpr_ifp->if_index;
39236c6e 2548 prl_32->prefix[i].expire = ndpr_getexpire(pr);
b0d623f7
A
2549
2550 pfr = pr->ndpr_advrtrs.lh_first;
2551 j = 0;
2552 while (pfr) {
2553 if (j < DRLSTSIZ) {
39236c6e 2554#define RTRADDR prl_32->prefix[i].advrtr[j]
b0d623f7
A
2555 RTRADDR = pfr->router->rtaddr;
2556 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
2557 /* XXX: hack for KAME */
2558 RTRADDR.s6_addr16[1] = 0;
2559 } else {
2560 log(LOG_ERR,
2561 "a router(%s) advertises "
2562 "a prefix with "
2563 "non-link local address\n",
2564 ip6_sprintf(&RTRADDR));
2565 }
2566#undef RTRADDR
2567 }
2568 j++;
2569 pfr = pfr->pfr_next;
2570 }
2571 prl_32->prefix[i].advrtrs = j;
2572 prl_32->prefix[i].origin = PR_ORIG_RA;
6d2010ae 2573 NDPR_UNLOCK(pr);
b0d623f7
A
2574
2575 i++;
2576 pr = pr->ndpr_next;
2577 }
316670eb
A
2578 bcopy(prl_32, data, sizeof (*prl_32));
2579 _FREE(prl_32, M_TEMP);
2580 return (0);
b0d623f7
A
2581}
2582
2583int
2584nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
2585{
6d2010ae 2586 struct nd_defrouter *dr;
b0d623f7
A
2587 struct nd_prefix *pr;
2588 struct rtentry *rt;
3e170ce0 2589 int error = 0;
39236c6e
A
2590
2591 VERIFY(ifp != NULL);
b0d623f7
A
2592
2593 switch (cmd) {
316670eb
A
2594 case SIOCGDRLST_IN6_32: /* struct in6_drlist_32 */
2595 case SIOCGDRLST_IN6_64: /* struct in6_drlist_64 */
b0d623f7
A
2596 /*
2597 * obsolete API, use sysctl under net.inet6.icmp6
2598 */
2599 lck_mtx_lock(nd6_mutex);
316670eb 2600 error = nd6_siocgdrlst(data, cmd == SIOCGDRLST_IN6_64);
91447636 2601 lck_mtx_unlock(nd6_mutex);
9bccf70c 2602 break;
b0d623f7 2603
316670eb
A
2604 case SIOCGPRLST_IN6_32: /* struct in6_prlist_32 */
2605 case SIOCGPRLST_IN6_64: /* struct in6_prlist_64 */
b0d623f7
A
2606 /*
2607 * obsolete API, use sysctl under net.inet6.icmp6
2608 */
2609 lck_mtx_lock(nd6_mutex);
316670eb 2610 error = nd6_siocgprlst(data, cmd == SIOCGPRLST_IN6_64);
b0d623f7 2611 lck_mtx_unlock(nd6_mutex);
1c79356b 2612 break;
b0d623f7 2613
316670eb
A
2614 case OSIOCGIFINFO_IN6: /* struct in6_ondireq */
2615 case SIOCGIFINFO_IN6: { /* struct in6_ondireq */
2616 u_int32_t linkmtu;
2617 struct in6_ondireq *ondi = (struct in6_ondireq *)(void *)data;
2618 struct nd_ifinfo *ndi;
b0d623f7
A
2619 /*
2620 * SIOCGIFINFO_IN6 ioctl is encoded with in6_ondireq
2621 * instead of in6_ndireq, so we treat it as such.
2622 */
316670eb 2623 ndi = ND_IFINFO(ifp);
3e170ce0 2624 if ((NULL == ndi) || (FALSE == ndi->initialized)){
9bccf70c
A
2625 error = EINVAL;
2626 break;
2627 }
316670eb
A
2628 lck_mtx_lock(&ndi->lock);
2629 linkmtu = IN6_LINKMTU(ifp);
2630 bcopy(&linkmtu, &ondi->ndi.linkmtu, sizeof (linkmtu));
3e170ce0 2631 bcopy(&ndi->maxmtu, &ondi->ndi.maxmtu,
316670eb 2632 sizeof (u_int32_t));
3e170ce0 2633 bcopy(&ndi->basereachable, &ondi->ndi.basereachable,
316670eb 2634 sizeof (u_int32_t));
3e170ce0 2635 bcopy(&ndi->reachable, &ondi->ndi.reachable,
316670eb 2636 sizeof (u_int32_t));
3e170ce0 2637 bcopy(&ndi->retrans, &ondi->ndi.retrans,
316670eb 2638 sizeof (u_int32_t));
3e170ce0 2639 bcopy(&ndi->flags, &ondi->ndi.flags,
316670eb 2640 sizeof (u_int32_t));
3e170ce0 2641 bcopy(&ndi->recalctm, &ondi->ndi.recalctm,
316670eb 2642 sizeof (int));
3e170ce0 2643 ondi->ndi.chlim = ndi->chlim;
316670eb
A
2644 ondi->ndi.receivedra = 0;
2645 lck_mtx_unlock(&ndi->lock);
1c79356b 2646 break;
316670eb 2647 }
b0d623f7 2648
316670eb 2649 case SIOCSIFINFO_FLAGS: { /* struct in6_ndireq */
3e170ce0
A
2650 /*
2651 * XXX BSD has a bunch of checks here to ensure
2652 * that interface disabled flag is not reset if
2653 * link local address has failed DAD.
2654 * Investigate that part.
2655 */
316670eb
A
2656 struct in6_ndireq *cndi = (struct in6_ndireq *)(void *)data;
2657 u_int32_t oflags, flags;
3e170ce0 2658 struct nd_ifinfo *ndi = ND_IFINFO(ifp);
316670eb
A
2659
2660 /* XXX: almost all other fields of cndi->ndi is unused */
3e170ce0 2661 if ((NULL == ndi) || !ndi->initialized) {
9bccf70c
A
2662 error = EINVAL;
2663 break;
2664 }
3e170ce0 2665
316670eb 2666 lck_mtx_lock(&ndi->lock);
3e170ce0
A
2667 oflags = ndi->flags;
2668 bcopy(&cndi->ndi.flags, &(ndi->flags), sizeof (flags));
2669 flags = ndi->flags;
316670eb 2670 lck_mtx_unlock(&ndi->lock);
316670eb 2671
3e170ce0 2672 if (oflags == flags) {
316670eb 2673 break;
3e170ce0 2674 }
316670eb
A
2675
2676 error = nd6_setifinfo(ifp, oflags, flags);
1c79356b 2677 break;
316670eb 2678 }
b0d623f7 2679
316670eb 2680 case SIOCSNDFLUSH_IN6: /* struct in6_ifreq */
1c79356b
A
2681 /* flush default router list */
2682 /*
2683 * xxx sumikawa: should not delete route if default
2684 * route equals to the top of default router list
2685 */
91447636 2686 lck_mtx_lock(nd6_mutex);
6d2010ae
A
2687 defrouter_reset();
2688 defrouter_select(ifp);
91447636 2689 lck_mtx_unlock(nd6_mutex);
1c79356b
A
2690 /* xxx sumikawa: flush prefix list */
2691 break;
b0d623f7 2692
316670eb 2693 case SIOCSPFXFLUSH_IN6: { /* struct in6_ifreq */
1c79356b 2694 /* flush all the prefix advertised by routers */
4bd07ac2 2695 struct nd_prefix *next = NULL;
1c79356b 2696
6d2010ae 2697 lck_mtx_lock(nd6_mutex);
1c79356b 2698 for (pr = nd_prefix.lh_first; pr; pr = next) {
4bd07ac2
A
2699 struct in6_ifaddr *ia = NULL;
2700 bool iterate_pfxlist_again = false;
9bccf70c 2701
1c79356b 2702 next = pr->ndpr_next;
9bccf70c 2703
6d2010ae
A
2704 NDPR_LOCK(pr);
2705 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
2706 NDPR_UNLOCK(pr);
9bccf70c 2707 continue; /* XXX */
6d2010ae
A
2708 }
2709 if (ifp != lo_ifp && pr->ndpr_ifp != ifp) {
2710 NDPR_UNLOCK(pr);
2711 continue;
2712 }
9bccf70c 2713 /* do we really have to remove addresses as well? */
6d2010ae
A
2714 NDPR_ADDREF_LOCKED(pr);
2715 NDPR_UNLOCK(pr);
2716 lck_rw_lock_exclusive(&in6_ifaddr_rwlock);
2717 ia = in6_ifaddrs;
2718 while (ia != NULL) {
2719 IFA_LOCK(&ia->ia_ifa);
2720 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0) {
2721 IFA_UNLOCK(&ia->ia_ifa);
2722 ia = ia->ia_next;
2723 continue;
2724 }
9bccf70c 2725
6d2010ae
A
2726 if (ia->ia6_ndpr == pr) {
2727 IFA_ADDREF_LOCKED(&ia->ia_ifa);
2728 IFA_UNLOCK(&ia->ia_ifa);
2729 lck_rw_done(&in6_ifaddr_rwlock);
2730 lck_mtx_unlock(nd6_mutex);
2731 in6_purgeaddr(&ia->ia_ifa);
316670eb 2732 IFA_REMREF(&ia->ia_ifa);
6d2010ae 2733 lck_mtx_lock(nd6_mutex);
39236c6e
A
2734 lck_rw_lock_exclusive(
2735 &in6_ifaddr_rwlock);
6d2010ae
A
2736 /*
2737 * Purging the address caused
2738 * in6_ifaddr_rwlock to be
2739 * dropped and
2740 * reacquired; therefore search again
2741 * from the beginning of in6_ifaddrs.
2742 * The same applies for the prefix list.
2743 */
2744 ia = in6_ifaddrs;
4bd07ac2 2745 iterate_pfxlist_again = true;
9bccf70c 2746 continue;
6d2010ae
A
2747 }
2748 IFA_UNLOCK(&ia->ia_ifa);
2749 ia = ia->ia_next;
9bccf70c 2750 }
6d2010ae
A
2751 lck_rw_done(&in6_ifaddr_rwlock);
2752 NDPR_LOCK(pr);
2753 prelist_remove(pr);
2754 NDPR_UNLOCK(pr);
39236c6e 2755 pfxlist_onlink_check();
6d2010ae 2756 NDPR_REMREF(pr);
4bd07ac2
A
2757 if (iterate_pfxlist_again) {
2758 next = nd_prefix.lh_first;
2759 }
1c79356b 2760 }
91447636 2761 lck_mtx_unlock(nd6_mutex);
1c79356b 2762 break;
b0d623f7
A
2763 }
2764
316670eb 2765 case SIOCSRTRFLUSH_IN6: { /* struct in6_ifreq */
1c79356b 2766 /* flush all the default routers */
2d21ac55 2767 struct nd_defrouter *next;
1c79356b 2768
91447636 2769 lck_mtx_lock(nd6_mutex);
1c79356b
A
2770 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
2771 /*
2772 * The first entry of the list may be stored in
2773 * the routing table, so we'll delete it later.
2774 */
2775 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = next) {
2776 next = TAILQ_NEXT(dr, dr_entry);
6d2010ae
A
2777 if (ifp == lo_ifp || dr->ifp == ifp)
2778 defrtrlist_del(dr);
1c79356b 2779 }
6d2010ae
A
2780 if (ifp == lo_ifp ||
2781 TAILQ_FIRST(&nd_defrouter)->ifp == ifp)
2782 defrtrlist_del(TAILQ_FIRST(&nd_defrouter));
1c79356b 2783 }
91447636 2784 lck_mtx_unlock(nd6_mutex);
1c79356b 2785 break;
b0d623f7
A
2786 }
2787
316670eb 2788 case SIOCGNBRINFO_IN6_32: { /* struct in6_nbrinfo_32 */
1c79356b 2789 struct llinfo_nd6 *ln;
316670eb
A
2790 struct in6_nbrinfo_32 nbi_32;
2791 struct in6_addr nb_addr; /* make local for safety */
1c79356b 2792
316670eb
A
2793 bcopy(data, &nbi_32, sizeof (nbi_32));
2794 nb_addr = nbi_32.addr;
1c79356b
A
2795 /*
2796 * XXX: KAME specific hack for scoped addresses
39236c6e 2797 * XXXX: for other scopes than link-local?
1c79356b 2798 */
316670eb
A
2799 if (IN6_IS_ADDR_LINKLOCAL(&nbi_32.addr) ||
2800 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_32.addr)) {
2801 u_int16_t *idp =
2802 (u_int16_t *)(void *)&nb_addr.s6_addr[2];
1c79356b
A
2803
2804 if (*idp == 0)
2805 *idp = htons(ifp->if_index);
2806 }
2807
b0d623f7 2808 /* Callee returns a locked route upon success */
91447636 2809 if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
1c79356b 2810 error = EINVAL;
1c79356b
A
2811 break;
2812 }
b0d623f7
A
2813 RT_LOCK_ASSERT_HELD(rt);
2814 ln = rt->rt_llinfo;
316670eb
A
2815 nbi_32.state = ln->ln_state;
2816 nbi_32.asked = ln->ln_asked;
2817 nbi_32.isrouter = ln->ln_router;
39236c6e 2818 nbi_32.expire = ln_getexpire(ln);
b0d623f7
A
2819 RT_REMREF_LOCKED(rt);
2820 RT_UNLOCK(rt);
316670eb 2821 bcopy(&nbi_32, data, sizeof (nbi_32));
1c79356b 2822 break;
b0d623f7
A
2823 }
2824
316670eb 2825 case SIOCGNBRINFO_IN6_64: { /* struct in6_nbrinfo_64 */
b0d623f7 2826 struct llinfo_nd6 *ln;
316670eb
A
2827 struct in6_nbrinfo_64 nbi_64;
2828 struct in6_addr nb_addr; /* make local for safety */
b0d623f7 2829
316670eb
A
2830 bcopy(data, &nbi_64, sizeof (nbi_64));
2831 nb_addr = nbi_64.addr;
b0d623f7
A
2832 /*
2833 * XXX: KAME specific hack for scoped addresses
39236c6e 2834 * XXXX: for other scopes than link-local?
b0d623f7 2835 */
316670eb
A
2836 if (IN6_IS_ADDR_LINKLOCAL(&nbi_64.addr) ||
2837 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_64.addr)) {
2838 u_int16_t *idp =
2839 (u_int16_t *)(void *)&nb_addr.s6_addr[2];
b0d623f7
A
2840
2841 if (*idp == 0)
2842 *idp = htons(ifp->if_index);
2843 }
2844
2845 /* Callee returns a locked route upon success */
2846 if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
2847 error = EINVAL;
2848 break;
2849 }
2850 RT_LOCK_ASSERT_HELD(rt);
2851 ln = rt->rt_llinfo;
316670eb
A
2852 nbi_64.state = ln->ln_state;
2853 nbi_64.asked = ln->ln_asked;
2854 nbi_64.isrouter = ln->ln_router;
39236c6e 2855 nbi_64.expire = ln_getexpire(ln);
b0d623f7
A
2856 RT_REMREF_LOCKED(rt);
2857 RT_UNLOCK(rt);
316670eb 2858 bcopy(&nbi_64, data, sizeof (nbi_64));
1c79356b 2859 break;
b0d623f7
A
2860 }
2861
316670eb
A
2862 case SIOCGDEFIFACE_IN6_32: /* struct in6_ndifreq_32 */
2863 case SIOCGDEFIFACE_IN6_64: { /* struct in6_ndifreq_64 */
2864 struct in6_ndifreq_64 *ndif_64 =
2865 (struct in6_ndifreq_64 *)(void *)data;
2866 struct in6_ndifreq_32 *ndif_32 =
2867 (struct in6_ndifreq_32 *)(void *)data;
b0d623f7 2868
316670eb
A
2869 if (cmd == SIOCGDEFIFACE_IN6_64) {
2870 u_int64_t j = nd6_defifindex;
2871 bcopy(&j, &ndif_64->ifindex, sizeof (j));
2872 } else {
2873 bcopy(&nd6_defifindex, &ndif_32->ifindex,
2874 sizeof (u_int32_t));
2875 }
1c79356b
A
2876 break;
2877 }
b0d623f7 2878
316670eb
A
2879 case SIOCSDEFIFACE_IN6_32: /* struct in6_ndifreq_32 */
2880 case SIOCSDEFIFACE_IN6_64: { /* struct in6_ndifreq_64 */
2881 struct in6_ndifreq_64 *ndif_64 =
2882 (struct in6_ndifreq_64 *)(void *)data;
2883 struct in6_ndifreq_32 *ndif_32 =
2884 (struct in6_ndifreq_32 *)(void *)data;
2885 u_int32_t idx;
b0d623f7 2886
316670eb
A
2887 if (cmd == SIOCSDEFIFACE_IN6_64) {
2888 u_int64_t j;
2889 bcopy(&ndif_64->ifindex, &j, sizeof (j));
2890 idx = (u_int32_t)j;
2891 } else {
2892 bcopy(&ndif_32->ifindex, &idx, sizeof (idx));
2893 }
2894
2895 error = nd6_setdefaultiface(idx);
6d2010ae 2896 return (error);
b0d623f7
A
2897 /* NOTREACHED */
2898 }
2899 }
2900 return (error);
1c79356b
A
2901}
2902
2903/*
2904 * Create neighbor cache entry and cache link-layer address,
2905 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
2906 */
b0d623f7 2907void
39236c6e
A
2908nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
2909 int lladdrlen, int type, int code)
1c79356b 2910{
39236c6e 2911#pragma unused(lladdrlen)
1c79356b
A
2912 struct rtentry *rt = NULL;
2913 struct llinfo_nd6 *ln = NULL;
2914 int is_newentry;
2915 struct sockaddr_dl *sdl = NULL;
2916 int do_update;
2917 int olladdr;
2918 int llchange;
2919 int newstate = 0;
39236c6e
A
2920 uint64_t timenow;
2921 boolean_t sched_timeout = FALSE;
1c79356b 2922
6d2010ae 2923 if (ifp == NULL)
1c79356b 2924 panic("ifp == NULL in nd6_cache_lladdr");
6d2010ae 2925 if (from == NULL)
1c79356b
A
2926 panic("from == NULL in nd6_cache_lladdr");
2927
2928 /* nothing must be updated for unspecified address */
2929 if (IN6_IS_ADDR_UNSPECIFIED(from))
b0d623f7 2930 return;
1c79356b
A
2931
2932 /*
2933 * Validation about ifp->if_addrlen and lladdrlen must be done in
2934 * the caller.
1c79356b 2935 */
39236c6e 2936 timenow = net_uptime();
1c79356b 2937
b0d623f7
A
2938 rt = nd6_lookup(from, 0, ifp, 0);
2939 if (rt == NULL) {
b0d623f7
A
2940 if ((rt = nd6_lookup(from, 1, ifp, 0)) == NULL)
2941 return;
2942 RT_LOCK_ASSERT_HELD(rt);
1c79356b 2943 is_newentry = 1;
9bccf70c 2944 } else {
b0d623f7 2945 RT_LOCK_ASSERT_HELD(rt);
9bccf70c 2946 /* do nothing if static ndp is set */
91447636 2947 if (rt->rt_flags & RTF_STATIC) {
b0d623f7
A
2948 RT_REMREF_LOCKED(rt);
2949 RT_UNLOCK(rt);
2950 return;
91447636 2951 }
1c79356b 2952 is_newentry = 0;
9bccf70c 2953 }
1c79356b 2954
6d2010ae
A
2955 if (rt == NULL)
2956 return;
1c79356b
A
2957 if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
2958fail:
b0d623f7
A
2959 RT_UNLOCK(rt);
2960 nd6_free(rt);
2961 rtfree(rt);
2962 return;
1c79356b 2963 }
6d2010ae
A
2964 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
2965 if (ln == NULL)
1c79356b 2966 goto fail;
6d2010ae 2967 if (rt->rt_gateway == NULL)
1c79356b
A
2968 goto fail;
2969 if (rt->rt_gateway->sa_family != AF_LINK)
2970 goto fail;
2971 sdl = SDL(rt->rt_gateway);
2972
2973 olladdr = (sdl->sdl_alen) ? 1 : 0;
2974 if (olladdr && lladdr) {
2975 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
2976 llchange = 1;
2977 else
2978 llchange = 0;
2979 } else
2980 llchange = 0;
2981
2982 /*
2983 * newentry olladdr lladdr llchange (*=record)
2984 * 0 n n -- (1)
2985 * 0 y n -- (2)
2986 * 0 n y -- (3) * STALE
2987 * 0 y y n (4) *
2988 * 0 y y y (5) * STALE
2989 * 1 -- n -- (6) NOSTATE(= PASSIVE)
2990 * 1 -- y -- (7) * STALE
2991 */
2992
55e303ae 2993 if (lladdr) { /* (3-5) and (7) */
1c79356b
A
2994 /*
2995 * Record source link-layer address
2996 * XXX is it dependent to ifp->if_type?
2997 */
2998 sdl->sdl_alen = ifp->if_addrlen;
2999 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
6d2010ae
A
3000
3001 /* cache the gateway (sender HW) address */
3002 nd6_llreach_alloc(rt, ifp, LLADDR(sdl), sdl->sdl_alen, FALSE);
1c79356b
A
3003 }
3004
3005 if (!is_newentry) {
6d2010ae
A
3006 if ((!olladdr && lladdr != NULL) || /* (3) */
3007 (olladdr && lladdr != NULL && llchange)) { /* (5) */
1c79356b
A
3008 do_update = 1;
3009 newstate = ND6_LLINFO_STALE;
55e303ae 3010 } else /* (1-2,4) */
1c79356b
A
3011 do_update = 0;
3012 } else {
3013 do_update = 1;
6d2010ae 3014 if (lladdr == NULL) /* (6) */
1c79356b 3015 newstate = ND6_LLINFO_NOSTATE;
55e303ae 3016 else /* (7) */
1c79356b
A
3017 newstate = ND6_LLINFO_STALE;
3018 }
3019
3020 if (do_update) {
3021 /*
3022 * Update the state of the neighbor cache.
3023 */
3024 ln->ln_state = newstate;
3025
3026 if (ln->ln_state == ND6_LLINFO_STALE) {
b0d623f7 3027 struct mbuf *m = ln->ln_hold;
9bccf70c
A
3028 /*
3029 * XXX: since nd6_output() below will cause
3030 * state tansition to DELAY and reset the timer,
3031 * we must set the timer now, although it is actually
3032 * meaningless.
3033 */
39236c6e 3034 ln_setexpire(ln, timenow + nd6_gctimer);
b0d623f7 3035 ln->ln_hold = NULL;
9bccf70c 3036
b0d623f7 3037 if (m != NULL) {
6d2010ae
A
3038 struct sockaddr_in6 sin6;
3039
3040 rtkey_to_sa6(rt, &sin6);
9bccf70c
A
3041 /*
3042 * we assume ifp is not a p2p here, so just
3043 * set the 2nd argument as the 1st one.
3044 */
b0d623f7 3045 RT_UNLOCK(rt);
3e170ce0 3046 nd6_output_list(ifp, ifp, m, &sin6, rt, NULL);
b0d623f7 3047 RT_LOCK(rt);
1c79356b
A
3048 }
3049 } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
3050 /* probe right away */
39236c6e
A
3051 ln_setexpire(ln, timenow);
3052 sched_timeout = TRUE;
1c79356b
A
3053 }
3054 }
3055
3056 /*
3057 * ICMP6 type dependent behavior.
3058 *
3059 * NS: clear IsRouter if new entry
3060 * RS: clear IsRouter
3061 * RA: set IsRouter if there's lladdr
3062 * redir: clear IsRouter if new entry
3063 *
3064 * RA case, (1):
3065 * The spec says that we must set IsRouter in the following cases:
3066 * - If lladdr exist, set IsRouter. This means (1-5).
3067 * - If it is old entry (!newentry), set IsRouter. This means (7).
3068 * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
3069 * A quetion arises for (1) case. (1) case has no lladdr in the
3070 * neighbor cache, this is similar to (6).
3071 * This case is rare but we figured that we MUST NOT set IsRouter.
3072 *
39236c6e
A
3073 * newentry olladdr lladdr llchange NS RS RA redir
3074 * D R
3075 * 0 n n -- (1) c ? s
3076 * 0 y n -- (2) c s s
3077 * 0 n y -- (3) c s s
3078 * 0 y y n (4) c s s
3079 * 0 y y y (5) c s s
3080 * 1 -- n -- (6) c c c s
3081 * 1 -- y -- (7) c c s c s
1c79356b
A
3082 *
3083 * (c=clear s=set)
3084 */
3085 switch (type & 0xff) {
3086 case ND_NEIGHBOR_SOLICIT:
3087 /*
3088 * New entry must have is_router flag cleared.
3089 */
55e303ae 3090 if (is_newentry) /* (6-7) */
1c79356b
A
3091 ln->ln_router = 0;
3092 break;
3093 case ND_REDIRECT:
3094 /*
39236c6e
A
3095 * If the ICMP message is a Redirect to a better router, always
3096 * set the is_router flag. Otherwise, if the entry is newly
3097 * created, then clear the flag. [RFC 4861, sec 8.3]
1c79356b
A
3098 */
3099 if (code == ND_REDIRECT_ROUTER)
3100 ln->ln_router = 1;
55e303ae 3101 else if (is_newentry) /* (6-7) */
1c79356b
A
3102 ln->ln_router = 0;
3103 break;
3104 case ND_ROUTER_SOLICIT:
3105 /*
3106 * is_router flag must always be cleared.
3107 */
3108 ln->ln_router = 0;
3109 break;
3110 case ND_ROUTER_ADVERT:
3111 /*
3112 * Mark an entry with lladdr as a router.
3113 */
6d2010ae
A
3114 if ((!is_newentry && (olladdr || lladdr)) || /* (2-5) */
3115 (is_newentry && lladdr)) { /* (7) */
1c79356b
A
3116 ln->ln_router = 1;
3117 }
3118 break;
3119 }
3120
9bccf70c
A
3121 /*
3122 * When the link-layer address of a router changes, select the
3123 * best router again. In particular, when the neighbor entry is newly
3124 * created, it might affect the selection policy.
3125 * Question: can we restrict the first condition to the "is_newentry"
3126 * case?
316670eb
A
3127 *
3128 * Note: Perform default router selection even when we are a router,
3129 * if Scoped Routing is enabled.
9bccf70c 3130 */
316670eb
A
3131 if (do_update && ln->ln_router &&
3132 (ip6_doscopedroute || !ip6_forwarding)) {
b0d623f7
A
3133 RT_REMREF_LOCKED(rt);
3134 RT_UNLOCK(rt);
91447636 3135 lck_mtx_lock(nd6_mutex);
6d2010ae 3136 defrouter_select(ifp);
91447636 3137 lck_mtx_unlock(nd6_mutex);
b0d623f7
A
3138 } else {
3139 RT_REMREF_LOCKED(rt);
3140 RT_UNLOCK(rt);
91447636 3141 }
39236c6e
A
3142 if (sched_timeout) {
3143 lck_mtx_lock(rnh_lock);
3144 nd6_sched_timeout(NULL, NULL);
3145 lck_mtx_unlock(rnh_lock);
3146 }
1c79356b
A
3147}
3148
3149static void
39236c6e 3150nd6_slowtimo(void *arg)
1c79356b 3151{
39236c6e 3152#pragma unused(arg)
3e170ce0
A
3153 struct nd_ifinfo *nd6if = NULL;
3154 struct ifnet *ifp = NULL;
3155
3156 ifnet_head_lock_shared();
3157 for (ifp = ifnet_head.tqh_first; ifp;
3158 ifp = ifp->if_link.tqe_next) {
3159 nd6if = ND_IFINFO(ifp);
3160 if ((NULL == nd6if) || (FALSE == nd6if->initialized)) {
3161 continue;
3162 }
1c79356b 3163
316670eb 3164 lck_mtx_lock(&nd6if->lock);
1c79356b
A
3165 if (nd6if->basereachable && /* already initialized */
3166 (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
3167 /*
3168 * Since reachable time rarely changes by router
3169 * advertisements, we SHOULD insure that a new random
3170 * value gets recomputed at least once every few hours.
39236c6e 3171 * (RFC 4861, 6.3.4)
1c79356b
A
3172 */
3173 nd6if->recalctm = nd6_recalc_reachtm_interval;
39236c6e
A
3174 nd6if->reachable =
3175 ND_COMPUTE_RTIME(nd6if->basereachable);
1c79356b 3176 }
316670eb 3177 lck_mtx_unlock(&nd6if->lock);
1c79356b 3178 }
3e170ce0 3179 ifnet_head_done();
39236c6e 3180 timeout(nd6_slowtimo, NULL, ND6_SLOWTIMER_INTERVAL * hz);
9bccf70c 3181}
1c79356b 3182
1c79356b 3183int
b0d623f7 3184nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
316670eb 3185 struct sockaddr_in6 *dst, struct rtentry *hint0, struct flowadv *adv)
1c79356b 3186{
3e170ce0
A
3187 return nd6_output_list(ifp, origifp, m0, dst, hint0, adv);
3188}
3189
3190/*
3191 * nd6_output_list()
3192 *
3193 * Assumption: route determination for first packet can be correctly applied to
3194 * all packets in the chain.
3195 */
3196#define senderr(e) { error = (e); goto bad; }
3197int
3198nd6_output_list(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
3199 struct sockaddr_in6 *dst, struct rtentry *hint0, struct flowadv *adv)
3200{
b0d623f7 3201 struct rtentry *rt = hint0, *hint = hint0;
1c79356b
A
3202 struct llinfo_nd6 *ln = NULL;
3203 int error = 0;
39236c6e 3204 uint64_t timenow;
b0d623f7 3205 struct rtentry *rtrele = NULL;
3e170ce0 3206 struct nd_ifinfo *ndi = NULL;
1c79356b 3207
b0d623f7
A
3208 if (rt != NULL) {
3209 RT_LOCK_SPIN(rt);
3210 RT_ADDREF_LOCKED(rt);
3211 }
1c79356b 3212
b0d623f7
A
3213 if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr) || !nd6_need_cache(ifp)) {
3214 if (rt != NULL)
3215 RT_UNLOCK(rt);
1c79356b 3216 goto sendpkt;
b0d623f7 3217 }
1c79356b
A
3218
3219 /*
b0d623f7
A
3220 * Next hop determination. Because we may involve the gateway route
3221 * in addition to the original route, locking is rather complicated.
3222 * The general concept is that regardless of whether the route points
3223 * to the original route or to the gateway route, this routine takes
3224 * an extra reference on such a route. This extra reference will be
3225 * released at the end.
3226 *
3227 * Care must be taken to ensure that the "hint0" route never gets freed
3228 * via rtfree(), since the caller may have stored it inside a struct
3229 * route with a reference held for that placeholder.
3230 *
3231 * This logic is similar to, though not exactly the same as the one
316670eb 3232 * used by route_to_gwroute().
1c79356b 3233 */
b0d623f7
A
3234 if (rt != NULL) {
3235 /*
3236 * We have a reference to "rt" by now (or below via rtalloc1),
3237 * which will either be released or freed at the end of this
3238 * routine.
3239 */
3240 RT_LOCK_ASSERT_HELD(rt);
3241 if (!(rt->rt_flags & RTF_UP)) {
3242 RT_REMREF_LOCKED(rt);
3243 RT_UNLOCK(rt);
39236c6e
A
3244 if ((hint = rt = rtalloc1_scoped(SA(dst), 1, 0,
3245 ifp->if_index)) != NULL) {
b0d623f7 3246 RT_LOCK_SPIN(rt);
9bccf70c
A
3247 if (rt->rt_ifp != ifp) {
3248 /* XXX: loop care? */
b0d623f7 3249 RT_UNLOCK(rt);
3e170ce0 3250 error = nd6_output_list(ifp, origifp, m0,
316670eb 3251 dst, rt, adv);
b0d623f7
A
3252 rtfree(rt);
3253 return (error);
9bccf70c 3254 }
91447636 3255 } else {
1c79356b 3256 senderr(EHOSTUNREACH);
91447636 3257 }
1c79356b 3258 }
9bccf70c 3259
1c79356b 3260 if (rt->rt_flags & RTF_GATEWAY) {
b0d623f7
A
3261 struct rtentry *gwrt;
3262 struct in6_ifaddr *ia6 = NULL;
3263 struct sockaddr_in6 gw6;
3264
6d2010ae 3265 rtgw_to_sa6(rt, &gw6);
b0d623f7
A
3266 /*
3267 * Must drop rt_lock since nd6_is_addr_neighbor()
3268 * calls nd6_lookup() and acquires rnh_lock.
3269 */
3270 RT_UNLOCK(rt);
9bccf70c
A
3271
3272 /*
3273 * We skip link-layer address resolution and NUD
3274 * if the gateway is not a neighbor from ND point
55e303ae
A
3275 * of view, regardless of the value of nd_ifinfo.flags.
3276 * The second condition is a bit tricky; we skip
9bccf70c
A
3277 * if the gateway is our own address, which is
3278 * sometimes used to install a route to a p2p link.
3279 */
b0d623f7
A
3280 if (!nd6_is_addr_neighbor(&gw6, ifp, 0) ||
3281 (ia6 = in6ifa_ifpwithaddr(ifp, &gw6.sin6_addr))) {
9bccf70c
A
3282 /*
3283 * We allow this kind of tricky route only
3284 * when the outgoing interface is p2p.
3285 * XXX: we may need a more generic rule here.
3286 */
b0d623f7 3287 if (ia6 != NULL)
6d2010ae 3288 IFA_REMREF(&ia6->ia_ifa);
9bccf70c
A
3289 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
3290 senderr(EHOSTUNREACH);
9bccf70c
A
3291 goto sendpkt;
3292 }
3293
b0d623f7 3294 RT_LOCK_SPIN(rt);
39236c6e 3295 gw6 = *(SIN6(rt->rt_gateway));
b0d623f7
A
3296
3297 /* If hint is now down, give up */
3298 if (!(rt->rt_flags & RTF_UP)) {
3299 RT_UNLOCK(rt);
3300 senderr(EHOSTUNREACH);
3301 }
3302
3303 /* If there's no gateway route, look it up */
3304 if ((gwrt = rt->rt_gwroute) == NULL) {
3305 RT_UNLOCK(rt);
1c79356b 3306 goto lookup;
b0d623f7
A
3307 }
3308 /* Become a regular mutex */
3309 RT_CONVERT_LOCK(rt);
3310
3311 /*
3312 * Take gwrt's lock while holding route's lock;
3313 * this is okay since gwrt never points back
3314 * to rt, so no lock ordering issues.
3315 */
3316 RT_LOCK_SPIN(gwrt);
3317 if (!(gwrt->rt_flags & RTF_UP)) {
b0d623f7
A
3318 rt->rt_gwroute = NULL;
3319 RT_UNLOCK(gwrt);
3320 RT_UNLOCK(rt);
3321 rtfree(gwrt);
3322lookup:
316670eb 3323 lck_mtx_lock(rnh_lock);
39236c6e 3324 gwrt = rtalloc1_scoped_locked(SA(&gw6), 1, 0,
316670eb 3325 ifp->if_index);
b0d623f7
A
3326
3327 RT_LOCK(rt);
3328 /*
3329 * Bail out if the route is down, no route
3330 * to gateway, circular route, or if the
3331 * gateway portion of "rt" has changed.
3332 */
3333 if (!(rt->rt_flags & RTF_UP) ||
3334 gwrt == NULL || gwrt == rt ||
3335 !equal(SA(&gw6), rt->rt_gateway)) {
3336 if (gwrt == rt) {
3337 RT_REMREF_LOCKED(gwrt);
3338 gwrt = NULL;
3339 }
3340 RT_UNLOCK(rt);
3341 if (gwrt != NULL)
316670eb
A
3342 rtfree_locked(gwrt);
3343 lck_mtx_unlock(rnh_lock);
b0d623f7
A
3344 senderr(EHOSTUNREACH);
3345 }
316670eb
A
3346 VERIFY(gwrt != NULL);
3347 /*
3348 * Set gateway route; callee adds ref to gwrt;
3349 * gwrt has an extra ref from rtalloc1() for
3350 * this routine.
3351 */
3352 rt_set_gwroute(rt, rt_key(rt), gwrt);
b0d623f7 3353 RT_UNLOCK(rt);
316670eb 3354 lck_mtx_unlock(rnh_lock);
b0d623f7
A
3355 /* Remember to release/free "rt" at the end */
3356 rtrele = rt;
3357 rt = gwrt;
b0d623f7
A
3358 } else {
3359 RT_ADDREF_LOCKED(gwrt);
3360 RT_UNLOCK(gwrt);
3361 RT_UNLOCK(rt);
b0d623f7
A
3362 /* Remember to release/free "rt" at the end */
3363 rtrele = rt;
3364 rt = gwrt;
1c79356b 3365 }
316670eb
A
3366 VERIFY(rt == gwrt);
3367
3368 /*
3369 * This is an opportunity to revalidate the parent
3370 * route's gwroute, in case it now points to a dead
3371 * route entry. Parent route won't go away since the
3372 * clone (hint) holds a reference to it. rt == gwrt.
3373 */
3374 RT_LOCK_SPIN(hint);
3375 if ((hint->rt_flags & (RTF_WASCLONED | RTF_UP)) ==
3376 (RTF_WASCLONED | RTF_UP)) {
3377 struct rtentry *prt = hint->rt_parent;
3378 VERIFY(prt != NULL);
3379
3380 RT_CONVERT_LOCK(hint);
3381 RT_ADDREF(prt);
3382 RT_UNLOCK(hint);
3383 rt_revalidate_gwroute(prt, rt);
3384 RT_REMREF(prt);
3385 } else {
3386 RT_UNLOCK(hint);
3387 }
3388
3389 RT_LOCK_SPIN(rt);
3390 /* rt == gwrt; if it is now down, give up */
3391 if (!(rt->rt_flags & RTF_UP)) {
3392 RT_UNLOCK(rt);
3393 rtfree(rt);
3394 rt = NULL;
3395 /* "rtrele" == original "rt" */
3396 senderr(EHOSTUNREACH);
3397 }
1c79356b 3398 }
316670eb 3399
b0d623f7
A
3400 /* Become a regular mutex */
3401 RT_CONVERT_LOCK(rt);
1c79356b
A
3402 }
3403
3404 /*
3405 * Address resolution or Neighbor Unreachability Detection
3406 * for the next hop.
3407 * At this point, the destination of the packet must be a unicast
3408 * or an anycast address(i.e. not a multicast).
3409 */
3410
3411 /* Look up the neighbor cache for the nexthop */
b0d623f7
A
3412 if (rt && (rt->rt_flags & RTF_LLINFO) != 0) {
3413 ln = rt->rt_llinfo;
3414 } else {
6d2010ae
A
3415 struct sockaddr_in6 sin6;
3416 /*
3417 * Clear out Scope ID field in case it is set.
3418 */
3419 sin6 = *dst;
3420 sin6.sin6_scope_id = 0;
9bccf70c
A
3421 /*
3422 * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
55e303ae 3423 * the condition below is not very efficient. But we believe
9bccf70c 3424 * it is tolerable, because this should be a rare case.
b0d623f7
A
3425 * Must drop rt_lock since nd6_is_addr_neighbor() calls
3426 * nd6_lookup() and acquires rnh_lock.
9bccf70c 3427 */
b0d623f7
A
3428 if (rt != NULL)
3429 RT_UNLOCK(rt);
6d2010ae 3430 if (nd6_is_addr_neighbor(&sin6, ifp, 0)) {
b0d623f7
A
3431 /* "rtrele" may have been used, so clean up "rt" now */
3432 if (rt != NULL) {
3433 /* Don't free "hint0" */
3434 if (rt == hint0)
3435 RT_REMREF(rt);
3436 else
3437 rtfree(rt);
3438 }
3439 /* Callee returns a locked route upon success */
3440 rt = nd6_lookup(&dst->sin6_addr, 1, ifp, 0);
3441 if (rt != NULL) {
3442 RT_LOCK_ASSERT_HELD(rt);
3443 ln = rt->rt_llinfo;
3444 }
3445 } else if (rt != NULL) {
3446 RT_LOCK(rt);
3447 }
1c79356b 3448 }
b0d623f7 3449
1c79356b 3450 if (!ln || !rt) {
3e170ce0 3451 if (rt != NULL) {
b0d623f7 3452 RT_UNLOCK(rt);
3e170ce0 3453 }
316670eb
A
3454 ndi = ND_IFINFO(ifp);
3455 VERIFY(ndi != NULL && ndi->initialized);
3456 lck_mtx_lock(&ndi->lock);
9bccf70c 3457 if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
316670eb
A
3458 !(ndi->flags & ND6_IFF_PERFORMNUD)) {
3459 lck_mtx_unlock(&ndi->lock);
9bccf70c
A
3460 log(LOG_DEBUG,
3461 "nd6_output: can't allocate llinfo for %s "
39236c6e
A
3462 "(ln=0x%llx, rt=0x%llx)\n",
3463 ip6_sprintf(&dst->sin6_addr),
3464 (uint64_t)VM_KERNEL_ADDRPERM(ln),
3465 (uint64_t)VM_KERNEL_ADDRPERM(rt));
9bccf70c
A
3466 senderr(EIO); /* XXX: good error? */
3467 }
316670eb 3468 lck_mtx_unlock(&ndi->lock);
9bccf70c
A
3469
3470 goto sendpkt; /* send anyway */
1c79356b
A
3471 }
3472
39236c6e
A
3473 net_update_uptime();
3474 timenow = net_uptime();
91447636 3475
1c79356b
A
3476 /* We don't have to do link-layer address resolution on a p2p link. */
3477 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
9bccf70c 3478 ln->ln_state < ND6_LLINFO_REACHABLE) {
1c79356b 3479 ln->ln_state = ND6_LLINFO_STALE;
39236c6e 3480 ln_setexpire(ln, timenow + nd6_gctimer);
9bccf70c 3481 }
1c79356b
A
3482
3483 /*
3484 * The first time we send a packet to a neighbor whose entry is
3485 * STALE, we have to change the state to DELAY and a sets a timer to
3486 * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
3487 * neighbor unreachability detection on expiration.
39236c6e 3488 * (RFC 4861 7.3.3)
1c79356b
A
3489 */
3490 if (ln->ln_state == ND6_LLINFO_STALE) {
3491 ln->ln_asked = 0;
3492 ln->ln_state = ND6_LLINFO_DELAY;
39236c6e
A
3493 ln_setexpire(ln, timenow + nd6_delay);
3494 /* N.B.: we will re-arm the timer below. */
3495 _CASSERT(ND6_LLINFO_DELAY > ND6_LLINFO_INCOMPLETE);
1c79356b
A
3496 }
3497
3498 /*
3499 * If the neighbor cache entry has a state other than INCOMPLETE
55e303ae 3500 * (i.e. its link-layer address is already resolved), just
1c79356b
A
3501 * send the packet.
3502 */
b0d623f7
A
3503 if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
3504 RT_UNLOCK(rt);
3505 /*
3506 * Move this entry to the head of the queue so that it is
3507 * less likely for this entry to be a target of forced
39236c6e
A
3508 * garbage collection (see nd6_rtrequest()). Do this only
3509 * if the entry is non-permanent (as permanent ones will
3510 * never be purged), and if the number of active entries
3511 * is at least half of the threshold.
b0d623f7 3512 */
39236c6e
A
3513 if (ln->ln_state == ND6_LLINFO_DELAY ||
3514 (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
3515 nd6_inuse >= (ip6_neighborgcthresh >> 1))) {
3516 lck_mtx_lock(rnh_lock);
3517 if (ln->ln_state == ND6_LLINFO_DELAY)
3518 nd6_sched_timeout(NULL, NULL);
3519 if (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
3520 nd6_inuse >= (ip6_neighborgcthresh >> 1)) {
3521 RT_LOCK_SPIN(rt);
3522 if (ln->ln_flags & ND6_LNF_IN_USE) {
3523 LN_DEQUEUE(ln);
3524 LN_INSERTHEAD(ln);
3525 }
3526 RT_UNLOCK(rt);
3527 }
3528 lck_mtx_unlock(rnh_lock);
b0d623f7 3529 }
1c79356b 3530 goto sendpkt;
b0d623f7 3531 }
1c79356b 3532
39236c6e
A
3533 /*
3534 * If this is a prefix proxy route, record the inbound interface
3535 * so that it can be excluded from the list of interfaces eligible
3536 * for forwarding the proxied NS in nd6_prproxy_ns_output().
3537 */
3538 if (rt->rt_flags & RTF_PROXY)
3539 ln->ln_exclifp = ((origifp == ifp) ? NULL : origifp);
3540
1c79356b
A
3541 /*
3542 * There is a neighbor cache entry, but no ethernet address
55e303ae 3543 * response yet. Replace the held mbuf (if any) with this
1c79356b
A
3544 * latest one.
3545 *
55e303ae 3546 * This code conforms to the rate-limiting rule described in Section
39236c6e 3547 * 7.2.2 of RFC 4861, because the timer is set correctly after sending
55e303ae 3548 * an NS below.
1c79356b 3549 */
9bccf70c 3550 if (ln->ln_state == ND6_LLINFO_NOSTATE)
1c79356b
A
3551 ln->ln_state = ND6_LLINFO_INCOMPLETE;
3552 if (ln->ln_hold)
3e170ce0
A
3553 m_freem_list(ln->ln_hold);
3554 ln->ln_hold = m0;
39236c6e
A
3555 if (ln->ln_expire != 0 && ln->ln_asked < nd6_mmaxtries &&
3556 ln->ln_expire <= timenow) {
b0d623f7 3557 ln->ln_asked++;
316670eb
A
3558 ndi = ND_IFINFO(ifp);
3559 VERIFY(ndi != NULL && ndi->initialized);
3560 lck_mtx_lock(&ndi->lock);
39236c6e 3561 ln_setexpire(ln, timenow + ndi->retrans / 1000);
316670eb 3562 lck_mtx_unlock(&ndi->lock);
b0d623f7
A
3563 RT_UNLOCK(rt);
3564 /* We still have a reference on rt (for ln) */
316670eb 3565 if (ip6_forwarding)
39236c6e
A
3566 nd6_prproxy_ns_output(ifp, origifp, NULL,
3567 &dst->sin6_addr, ln);
316670eb
A
3568 else
3569 nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
39236c6e
A
3570 lck_mtx_lock(rnh_lock);
3571 nd6_sched_timeout(NULL, NULL);
3572 lck_mtx_unlock(rnh_lock);
b0d623f7 3573 } else {
3e170ce0
A
3574 if(ln->ln_state == ND6_LLINFO_INCOMPLETE) {
3575 ln->ln_expire = timenow;
3576 }
b0d623f7 3577 RT_UNLOCK(rt);
1c79356b 3578 }
b0d623f7
A
3579 /*
3580 * Move this entry to the head of the queue so that it is
3581 * less likely for this entry to be a target of forced
39236c6e
A
3582 * garbage collection (see nd6_rtrequest()). Do this only
3583 * if the entry is non-permanent (as permanent ones will
3584 * never be purged), and if the number of active entries
3585 * is at least half of the threshold.
b0d623f7 3586 */
39236c6e
A
3587 if (ln->ln_expire != 0 && ip6_neighborgcthresh > 0 &&
3588 nd6_inuse >= (ip6_neighborgcthresh >> 1)) {
3589 lck_mtx_lock(rnh_lock);
3590 RT_LOCK_SPIN(rt);
3591 if (ln->ln_flags & ND6_LNF_IN_USE) {
3592 LN_DEQUEUE(ln);
3593 LN_INSERTHEAD(ln);
3594 }
3595 /* Clean up "rt" now while we can */
3596 if (rt == hint0) {
3597 RT_REMREF_LOCKED(rt);
3598 RT_UNLOCK(rt);
3599 } else {
3600 RT_UNLOCK(rt);
3601 rtfree_locked(rt);
3602 }
3603 rt = NULL; /* "rt" has been taken care of */
3604 lck_mtx_unlock(rnh_lock);
b0d623f7 3605 }
b0d623f7
A
3606 error = 0;
3607 goto release;
3608
3609sendpkt:
3610 if (rt != NULL)
3611 RT_LOCK_ASSERT_NOTHELD(rt);
9bccf70c 3612
6d2010ae 3613 /* discard the packet if IPv6 operation is disabled on the interface */
39236c6e 3614 if (ifp->if_eflags & IFEF_IPV6_DISABLED) {
6d2010ae
A
3615 error = ENETDOWN; /* better error? */
3616 goto bad;
3617 }
9bccf70c 3618
39236c6e 3619 if (ifp->if_flags & IFF_LOOPBACK) {
b0d623f7 3620 /* forwarding rules require the original scope_id */
3e170ce0
A
3621 m0->m_pkthdr.rcvif = origifp;
3622 error = dlil_output(origifp, PF_INET6, m0, (caddr_t)rt,
39236c6e 3623 SA(dst), 0, adv);
b0d623f7 3624 goto release;
e5568f75
A
3625 } else {
3626 /* Do not allow loopback address to wind up on a wire */
3e170ce0 3627 struct ip6_hdr *ip6 = mtod(m0, struct ip6_hdr *);
b0d623f7 3628
e5568f75 3629 if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
39236c6e 3630 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst))) {
e5568f75 3631 ip6stat.ip6s_badscope++;
39236c6e 3632 error = EADDRNOTAVAIL;
e5568f75
A
3633 goto bad;
3634 }
9bccf70c
A
3635 }
3636
6d2010ae
A
3637 if (rt != NULL) {
3638 RT_LOCK_SPIN(rt);
3639 /* Mark use timestamp */
3640 if (rt->rt_llinfo != NULL)
3641 nd6_llreach_use(rt->rt_llinfo);
3642 RT_UNLOCK(rt);
3643 }
3644
3e170ce0
A
3645 struct mbuf *mcur = m0;
3646 uint32_t pktcnt = 0;
39236c6e 3647
3e170ce0
A
3648 while (mcur) {
3649 if (hint != NULL && nstat_collect) {
3650 int scnt;
39236c6e 3651
3e170ce0
A
3652 if ((mcur->m_pkthdr.csum_flags & CSUM_TSO_IPV6) &&
3653 (mcur->m_pkthdr.tso_segsz > 0))
3654 scnt = mcur->m_pkthdr.len / mcur->m_pkthdr.tso_segsz;
3655 else
3656 scnt = 1;
6d2010ae 3657
3e170ce0
A
3658 nstat_route_tx(hint, scnt, mcur->m_pkthdr.len, 0);
3659 }
3660 pktcnt++;
3661
3662 mcur->m_pkthdr.rcvif = NULL;
3663 mcur = mcur->m_nextpkt;
3664 }
3665 if (pktcnt > ip6_maxchainsent)
3666 ip6_maxchainsent = pktcnt;
3667 error = dlil_output(ifp, PF_INET6, m0, (caddr_t)rt, SA(dst), 0, adv);
b0d623f7
A
3668 goto release;
3669
3670bad:
3e170ce0
A
3671 if (m0 != NULL)
3672 m_freem_list(m0);
b0d623f7
A
3673
3674release:
3675 /* Clean up "rt" unless it's already been done */
3676 if (rt != NULL) {
3677 RT_LOCK_SPIN(rt);
3678 if (rt == hint0) {
3679 RT_REMREF_LOCKED(rt);
3680 RT_UNLOCK(rt);
3681 } else {
3682 RT_UNLOCK(rt);
3683 rtfree(rt);
3684 }
3685 }
3686 /* And now clean up "rtrele" if there is any */
3687 if (rtrele != NULL) {
3688 RT_LOCK_SPIN(rtrele);
3689 if (rtrele == hint0) {
3690 RT_REMREF_LOCKED(rtrele);
3691 RT_UNLOCK(rtrele);
3692 } else {
3693 RT_UNLOCK(rtrele);
3694 rtfree(rtrele);
3695 }
3696 }
1c79356b 3697 return (error);
b0d623f7 3698}
1c79356b
A
3699#undef senderr
3700
9bccf70c 3701int
39236c6e 3702nd6_need_cache(struct ifnet *ifp)
9bccf70c
A
3703{
3704 /*
3705 * XXX: we currently do not make neighbor cache on any interface
3706 * other than ARCnet, Ethernet, FDDI and GIF.
3707 *
3708 * RFC2893 says:
3709 * - unidirectional tunnels needs no ND
3710 */
3711 switch (ifp->if_type) {
3712 case IFT_ARCNET:
3713 case IFT_ETHER:
3714 case IFT_FDDI:
3715 case IFT_IEEE1394:
9bccf70c 3716 case IFT_L2VLAN:
91447636 3717 case IFT_IEEE8023ADLAG:
9bccf70c
A
3718#if IFT_IEEE80211
3719 case IFT_IEEE80211:
3720#endif
3721 case IFT_GIF: /* XXX need more cases? */
6d2010ae
A
3722 case IFT_PPP:
3723#if IFT_TUNNEL
3724 case IFT_TUNNEL:
3725#endif
3726 case IFT_BRIDGE:
3727 case IFT_CELLULAR:
39236c6e 3728 return (1);
9bccf70c 3729 default:
39236c6e 3730 return (0);
9bccf70c
A
3731 }
3732}
3733
1c79356b 3734int
39236c6e
A
3735nd6_storelladdr(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
3736 struct sockaddr *dst, u_char *desten)
1c79356b 3737{
9bccf70c 3738 int i;
1c79356b
A
3739 struct sockaddr_dl *sdl;
3740
3741 if (m->m_flags & M_MCAST) {
3742 switch (ifp->if_type) {
3743 case IFT_ETHER:
9bccf70c 3744 case IFT_FDDI:
91447636
A
3745 case IFT_L2VLAN:
3746 case IFT_IEEE8023ADLAG:
9bccf70c
A
3747#if IFT_IEEE80211
3748 case IFT_IEEE80211:
3749#endif
b7266188 3750 case IFT_BRIDGE:
39236c6e
A
3751 ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr, desten);
3752 return (1);
9bccf70c
A
3753 case IFT_IEEE1394:
3754 for (i = 0; i < ifp->if_addrlen; i++)
3755 desten[i] = ~0;
39236c6e 3756 return (1);
1c79356b
A
3757 case IFT_ARCNET:
3758 *desten = 0;
39236c6e 3759 return (1);
1c79356b 3760 default:
39236c6e 3761 return (0); /* caller will free mbuf */
1c79356b
A
3762 }
3763 }
3764
9bccf70c
A
3765 if (rt == NULL) {
3766 /* this could happen, if we could not allocate memory */
39236c6e 3767 return (0); /* caller will free mbuf */
9bccf70c 3768 }
b0d623f7 3769 RT_LOCK(rt);
9bccf70c 3770 if (rt->rt_gateway->sa_family != AF_LINK) {
1c79356b 3771 printf("nd6_storelladdr: something odd happens\n");
b0d623f7 3772 RT_UNLOCK(rt);
39236c6e 3773 return (0); /* caller will free mbuf */
1c79356b
A
3774 }
3775 sdl = SDL(rt->rt_gateway);
3776 if (sdl->sdl_alen == 0) {
3777 /* this should be impossible, but we bark here for debugging */
3778 printf("nd6_storelladdr: sdl_alen == 0\n");
b0d623f7 3779 RT_UNLOCK(rt);
39236c6e 3780 return (0); /* caller will free mbuf */
1c79356b
A
3781 }
3782
3783 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
b0d623f7 3784 RT_UNLOCK(rt);
39236c6e 3785 return (1);
1c79356b 3786}
91447636 3787
b0d623f7
A
3788/*
3789 * This is the ND pre-output routine; care must be taken to ensure that
3790 * the "hint" route never gets freed via rtfree(), since the caller may
3791 * have stored it inside a struct route with a reference held for that
3792 * placeholder.
3793 */
91447636 3794errno_t
b0d623f7
A
3795nd6_lookup_ipv6(ifnet_t ifp, const struct sockaddr_in6 *ip6_dest,
3796 struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint,
3797 mbuf_t packet)
91447636
A
3798{
3799 route_t route = hint;
3800 errno_t result = 0;
3801 struct sockaddr_dl *sdl = NULL;
3802 size_t copy_len;
b0d623f7 3803
91447636 3804 if (ip6_dest->sin6_family != AF_INET6)
b0d623f7
A
3805 return (EAFNOSUPPORT);
3806
91447636 3807 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
b0d623f7
A
3808 return (ENETDOWN);
3809
3810 if (hint != NULL) {
3811 /*
3812 * Callee holds a reference on the route and returns
3813 * with the route entry locked, upon success.
3814 */
316670eb
A
3815 result = route_to_gwroute((const struct sockaddr *)ip6_dest,
3816 hint, &route);
91447636 3817 if (result != 0)
b0d623f7
A
3818 return (result);
3819 if (route != NULL)
3820 RT_LOCK_ASSERT_HELD(route);
91447636 3821 }
b0d623f7 3822
91447636 3823 if ((packet->m_flags & M_MCAST) != 0) {
b0d623f7
A
3824 if (route != NULL)
3825 RT_UNLOCK(route);
3826 result = dlil_resolve_multi(ifp,
39236c6e
A
3827 (const struct sockaddr *)ip6_dest,
3828 SA(ll_dest), ll_dest_len);
b0d623f7
A
3829 if (route != NULL)
3830 RT_LOCK(route);
3831 goto release;
91447636 3832 }
b0d623f7 3833
91447636 3834 if (route == NULL) {
b0d623f7
A
3835 /*
3836 * This could happen, if we could not allocate memory or
316670eb 3837 * if route_to_gwroute() didn't return a route.
b0d623f7
A
3838 */
3839 result = ENOBUFS;
3840 goto release;
91447636 3841 }
b0d623f7 3842
91447636 3843 if (route->rt_gateway->sa_family != AF_LINK) {
39236c6e
A
3844 printf("%s: route %s on %s%d gateway address not AF_LINK\n",
3845 __func__, ip6_sprintf(&ip6_dest->sin6_addr),
3846 route->rt_ifp->if_name, route->rt_ifp->if_unit);
91447636 3847 result = EADDRNOTAVAIL;
b0d623f7 3848 goto release;
91447636 3849 }
b0d623f7 3850
91447636
A
3851 sdl = SDL(route->rt_gateway);
3852 if (sdl->sdl_alen == 0) {
3853 /* this should be impossible, but we bark here for debugging */
39236c6e
A
3854 printf("%s: route %s on %s%d sdl_alen == 0\n", __func__,
3855 ip6_sprintf(&ip6_dest->sin6_addr), route->rt_ifp->if_name,
3856 route->rt_ifp->if_unit);
91447636 3857 result = EHOSTUNREACH;
b0d623f7 3858 goto release;
91447636 3859 }
b0d623f7 3860
91447636
A
3861 copy_len = sdl->sdl_len <= ll_dest_len ? sdl->sdl_len : ll_dest_len;
3862 bcopy(sdl, ll_dest, copy_len);
3863
b0d623f7
A
3864release:
3865 if (route != NULL) {
3866 if (route == hint) {
3867 RT_REMREF_LOCKED(route);
3868 RT_UNLOCK(route);
3869 } else {
3870 RT_UNLOCK(route);
3871 rtfree(route);
3872 }
3873 }
3874 return (result);
91447636
A
3875}
3876
316670eb
A
3877int
3878nd6_setifinfo(struct ifnet *ifp, u_int32_t before, u_int32_t after)
3879{
39236c6e
A
3880 uint32_t b, a;
3881 int err = 0;
3882
316670eb 3883 /*
39236c6e 3884 * Handle ND6_IFF_IFDISABLED
316670eb 3885 */
39236c6e
A
3886 if ((before & ND6_IFF_IFDISABLED) ||
3887 (after & ND6_IFF_IFDISABLED)) {
3888 b = (before & ND6_IFF_IFDISABLED);
3889 a = (after & ND6_IFF_IFDISABLED);
316670eb 3890
39236c6e
A
3891 if (b != a && (err = nd6_if_disable(ifp,
3892 ((int32_t)(a - b) > 0))) != 0)
3893 goto done;
3894 }
3895
3896 /*
3897 * Handle ND6_IFF_PROXY_PREFIXES
3898 */
3899 if ((before & ND6_IFF_PROXY_PREFIXES) ||
3900 (after & ND6_IFF_PROXY_PREFIXES)) {
3901 b = (before & ND6_IFF_PROXY_PREFIXES);
3902 a = (after & ND6_IFF_PROXY_PREFIXES);
316670eb 3903
39236c6e
A
3904 if (b != a && (err = nd6_if_prproxy(ifp,
3905 ((int32_t)(a - b) > 0))) != 0)
3906 goto done;
3907 }
3908done:
3909 return (err);
316670eb
A
3910}
3911
39236c6e
A
3912/*
3913 * Enable/disable IPv6 on an interface, called as part of
3914 * setting/clearing ND6_IFF_IFDISABLED, or during DAD failure.
3915 */
3916int
3917nd6_if_disable(struct ifnet *ifp, boolean_t enable)
3918{
3919 ifnet_lock_shared(ifp);
3920 if (enable)
3921 ifp->if_eflags |= IFEF_IPV6_DISABLED;
3922 else
3923 ifp->if_eflags &= ~IFEF_IPV6_DISABLED;
3924 ifnet_lock_done(ifp);
3925
3926 return (0);
3927}
9bccf70c
A
3928
3929static int
b0d623f7 3930nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
9bccf70c 3931{
2d21ac55 3932#pragma unused(oidp, arg1, arg2)
39236c6e 3933 char pbuf[MAX_IPv6_STR_LEN];
9bccf70c 3934 struct nd_defrouter *dr;
39236c6e 3935 int error = 0;
9bccf70c 3936
39236c6e 3937 if (req->newptr != USER_ADDR_NULL)
b0d623f7 3938 return (EPERM);
9bccf70c 3939
91447636 3940 lck_mtx_lock(nd6_mutex);
39236c6e
A
3941 if (proc_is64bit(req->p)) {
3942 struct in6_defrouter_64 d;
3943
3944 bzero(&d, sizeof (d));
3945 d.rtaddr.sin6_family = AF_INET6;
3946 d.rtaddr.sin6_len = sizeof (d.rtaddr);
3947
3948 TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
3949 d.rtaddr.sin6_addr = dr->rtaddr;
3950 if (in6_recoverscope(&d.rtaddr,
3951 &dr->rtaddr, dr->ifp) != 0)
3952 log(LOG_ERR, "scope error in default router "
3953 "list (%s)\n", inet_ntop(AF_INET6,
3954 &dr->rtaddr, pbuf, sizeof (pbuf)));
3955 d.flags = dr->flags;
3956 d.stateflags = dr->stateflags;
3957 d.stateflags &= ~NDDRF_PROCESSED;
3958 d.rtlifetime = dr->rtlifetime;
3959 d.expire = nddr_getexpire(dr);
3960 d.if_index = dr->ifp->if_index;
3961 error = SYSCTL_OUT(req, &d, sizeof (d));
3962 if (error != 0)
b0d623f7
A
3963 break;
3964 }
3965 } else {
39236c6e
A
3966 struct in6_defrouter_32 d;
3967
3968 bzero(&d, sizeof (d));
3969 d.rtaddr.sin6_family = AF_INET6;
3970 d.rtaddr.sin6_len = sizeof (d.rtaddr);
3971
3972 TAILQ_FOREACH(dr, &nd_defrouter, dr_entry) {
3973 d.rtaddr.sin6_addr = dr->rtaddr;
3974 if (in6_recoverscope(&d.rtaddr,
3975 &dr->rtaddr, dr->ifp) != 0)
3976 log(LOG_ERR, "scope error in default router "
3977 "list (%s)\n", inet_ntop(AF_INET6,
3978 &dr->rtaddr, pbuf, sizeof (pbuf)));
3979 d.flags = dr->flags;
3980 d.stateflags = dr->stateflags;
3981 d.stateflags &= ~NDDRF_PROCESSED;
3982 d.rtlifetime = dr->rtlifetime;
3983 d.expire = nddr_getexpire(dr);
3984 d.if_index = dr->ifp->if_index;
3985 error = SYSCTL_OUT(req, &d, sizeof (d));
3986 if (error != 0)
b0d623f7
A
3987 break;
3988 }
9bccf70c 3989 }
91447636 3990 lck_mtx_unlock(nd6_mutex);
b0d623f7 3991 return (error);
9bccf70c
A
3992}
3993
3994static int
b0d623f7 3995nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
9bccf70c 3996{
2d21ac55 3997#pragma unused(oidp, arg1, arg2)
39236c6e
A
3998 char pbuf[MAX_IPv6_STR_LEN];
3999 struct nd_pfxrouter *pfr;
4000 struct sockaddr_in6 s6;
9bccf70c 4001 struct nd_prefix *pr;
39236c6e 4002 int error = 0;
9bccf70c 4003
39236c6e 4004 if (req->newptr != USER_ADDR_NULL)
b0d623f7 4005 return (EPERM);
9bccf70c 4006
39236c6e
A
4007 bzero(&s6, sizeof (s6));
4008 s6.sin6_family = AF_INET6;
4009 s6.sin6_len = sizeof (s6);
9bccf70c 4010
39236c6e
A
4011 lck_mtx_lock(nd6_mutex);
4012 if (proc_is64bit(req->p)) {
4013 struct in6_prefix_64 p;
9bccf70c 4014
39236c6e
A
4015 bzero(&p, sizeof (p));
4016 p.origin = PR_ORIG_RA;
9bccf70c 4017
39236c6e
A
4018 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
4019 NDPR_LOCK(pr);
4020 p.prefix = pr->ndpr_prefix;
4021 if (in6_recoverscope(&p.prefix,
4022 &pr->ndpr_prefix.sin6_addr, pr->ndpr_ifp) != 0)
4023 log(LOG_ERR, "scope error in "
4024 "prefix list (%s)\n", inet_ntop(AF_INET6,
4025 &p.prefix.sin6_addr, pbuf, sizeof (pbuf)));
4026 p.raflags = pr->ndpr_raf;
4027 p.prefixlen = pr->ndpr_plen;
4028 p.vltime = pr->ndpr_vltime;
4029 p.pltime = pr->ndpr_pltime;
4030 p.if_index = pr->ndpr_ifp->if_index;
4031 p.expire = ndpr_getexpire(pr);
4032 p.refcnt = pr->ndpr_addrcnt;
4033 p.flags = pr->ndpr_stateflags;
4034 p.advrtrs = 0;
4035 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
4036 p.advrtrs++;
4037 error = SYSCTL_OUT(req, &p, sizeof (p));
4038 if (error != 0) {
4039 NDPR_UNLOCK(pr);
4040 break;
4041 }
4042 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
4043 s6.sin6_addr = pfr->router->rtaddr;
4044 if (in6_recoverscope(&s6, &pfr->router->rtaddr,
4045 pfr->router->ifp) != 0)
b0d623f7
A
4046 log(LOG_ERR,
4047 "scope error in prefix list (%s)\n",
39236c6e
A
4048 inet_ntop(AF_INET6, &s6.sin6_addr,
4049 pbuf, sizeof (pbuf)));
4050 error = SYSCTL_OUT(req, &s6, sizeof (s6));
4051 if (error != 0)
4052 break;
9bccf70c 4053 }
39236c6e
A
4054 NDPR_UNLOCK(pr);
4055 if (error != 0)
b0d623f7
A
4056 break;
4057 }
4058 } else {
39236c6e 4059 struct in6_prefix_32 p;
9bccf70c 4060
39236c6e
A
4061 bzero(&p, sizeof (p));
4062 p.origin = PR_ORIG_RA;
b0d623f7 4063
39236c6e
A
4064 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
4065 NDPR_LOCK(pr);
4066 p.prefix = pr->ndpr_prefix;
4067 if (in6_recoverscope(&p.prefix,
4068 &pr->ndpr_prefix.sin6_addr, pr->ndpr_ifp) != 0)
4069 log(LOG_ERR,
4070 "scope error in prefix list (%s)\n",
4071 inet_ntop(AF_INET6, &p.prefix.sin6_addr,
4072 pbuf, sizeof (pbuf)));
4073 p.raflags = pr->ndpr_raf;
4074 p.prefixlen = pr->ndpr_plen;
4075 p.vltime = pr->ndpr_vltime;
4076 p.pltime = pr->ndpr_pltime;
4077 p.if_index = pr->ndpr_ifp->if_index;
4078 p.expire = ndpr_getexpire(pr);
4079 p.refcnt = pr->ndpr_addrcnt;
4080 p.flags = pr->ndpr_stateflags;
4081 p.advrtrs = 0;
4082 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
4083 p.advrtrs++;
4084 error = SYSCTL_OUT(req, &p, sizeof (p));
4085 if (error != 0) {
6d2010ae 4086 NDPR_UNLOCK(pr);
39236c6e
A
4087 break;
4088 }
4089 LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
4090 s6.sin6_addr = pfr->router->rtaddr;
4091 if (in6_recoverscope(&s6, &pfr->router->rtaddr,
4092 pfr->router->ifp) != 0)
4093 log(LOG_ERR,
4094 "scope error in prefix list (%s)\n",
4095 inet_ntop(AF_INET6, &s6.sin6_addr,
4096 pbuf, sizeof (pbuf)));
4097 error = SYSCTL_OUT(req, &s6, sizeof (s6));
4098 if (error != 0)
4099 break;
b0d623f7 4100 }
39236c6e
A
4101 NDPR_UNLOCK(pr);
4102 if (error != 0)
b0d623f7
A
4103 break;
4104 }
9bccf70c 4105 }
91447636 4106 lck_mtx_unlock(nd6_mutex);
39236c6e 4107
b0d623f7 4108 return (error);
9bccf70c 4109}