2 * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* $FreeBSD: src/sys/netinet6/nd6.c,v 1.20 2002/08/02 20:49:14 rwatson Exp $ */
30 /* $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $ */
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * BSD/OS version heavily modifies this code, related to llinfo.
65 * Since we don't have BSD/OS version of net/route.c in our hand,
66 * I left the code mostly as it was in 970310. -- itojun
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/malloc.h>
73 #include <sys/socket.h>
74 #include <sys/sockio.h>
76 #include <sys/kernel.h>
77 #include <sys/sysctl.h>
78 #include <sys/errno.h>
79 #include <sys/syslog.h>
80 #include <sys/protosw.h>
82 #include <sys/mcache.h>
84 #include <kern/queue.h>
85 #include <kern/zalloc.h>
87 #define DONT_WARN_OBSOLETE
89 #include <net/if_dl.h>
90 #include <net/if_types.h>
91 #include <net/if_llreach.h>
92 #include <net/route.h>
94 #include <net/ntstat.h>
96 #include <netinet/in.h>
97 #include <netinet/in_arp.h>
98 #include <netinet/if_ether.h>
99 #include <netinet6/in6_var.h>
100 #include <netinet/ip6.h>
101 #include <netinet6/ip6_var.h>
102 #include <netinet6/nd6.h>
103 #include <netinet6/scope6_var.h>
104 #include <netinet/icmp6.h>
108 #include <net/net_osdep.h>
110 #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
111 #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
113 #define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
116 int nd6_prune
= 1; /* walk list every 1 seconds */
117 int nd6_delay
= 5; /* delay first probe time 5 second */
118 int nd6_umaxtries
= 3; /* maximum unicast query */
119 int nd6_mmaxtries
= 3; /* maximum multicast query */
120 int nd6_useloopback
= 1; /* use loopback interface for local traffic */
121 int nd6_gctimer
= (60 * 60 * 24); /* 1 day: garbage collection timer */
123 /* preventing too many loops in ND option parsing */
124 int nd6_maxndopt
= 10; /* max # of ND options allowed */
126 int nd6_maxnudhint
= 0; /* max # of subsequent upper layer hints */
127 int nd6_maxqueuelen
= 1; /* max # of packets cached in unresolved ND entries */
135 int nd6_optimistic_dad
=
136 (ND6_OPTIMISTIC_DAD_LINKLOCAL
|ND6_OPTIMISTIC_DAD_AUTOCONF
|
137 ND6_OPTIMISTIC_DAD_TEMPORARY
|ND6_OPTIMISTIC_DAD_DYNAMIC
);
139 static int nd6_is_new_addr_neighbor (struct sockaddr_in6
*, struct ifnet
*);
142 static int nd6_inuse
, nd6_allocated
;
145 * Synchronization notes:
147 * The global list of ND entries are stored in llinfo_nd6; an entry
148 * gets inserted into the list when the route is created and gets
149 * removed from the list when it is deleted; this is done as part
150 * of RTM_ADD/RTM_RESOLVE/RTM_DELETE in nd6_rtrequest().
152 * Because rnh_lock and rt_lock for the entry are held during those
153 * operations, the same locks (and thus lock ordering) must be used
154 * elsewhere to access the relevant data structure fields:
156 * ln_next, ln_prev, ln_rt
158 * - Routing lock (rnh_lock)
160 * ln_hold, ln_asked, ln_expire, ln_state, ln_router, ln_byhint, ln_flags,
161 * ln_llreach, ln_lastused
163 * - Routing entry lock (rt_lock)
165 * Due to the dependency on rt_lock, llinfo_nd6 has the same lifetime
166 * as the route entry itself. When a route is deleted (RTM_DELETE),
167 * it is simply removed from the global list but the memory is not
168 * freed until the route itself is freed.
170 struct llinfo_nd6 llinfo_nd6
= {
171 &llinfo_nd6
, &llinfo_nd6
, NULL
, NULL
, 0, 0, 0, 0, 0, 0, NULL
, 0
174 /* Protected by nd_if_rwlock */
175 size_t nd_ifinfo_indexlim
= 32; /* increased for 5589193 */
176 struct nd_ifinfo
*nd_ifinfo
= NULL
;
178 static lck_grp_attr_t
*nd_if_lock_grp_attr
;
179 static lck_grp_t
*nd_if_lock_grp
;
180 static lck_attr_t
*nd_if_lock_attr
;
181 decl_lck_rw_data(, nd_if_rwlock_data
);
182 lck_rw_t
*nd_if_rwlock
= &nd_if_rwlock_data
;
184 /* Protected by nd6_mutex */
185 struct nd_drhead nd_defrouter
;
186 struct nd_prhead nd_prefix
= { 0 };
188 /* Serialization variables for nd6_drain() */
189 static boolean_t nd6_drain_busy
;
190 static void *nd6_drain_waitchan
= &nd6_drain_busy
;
191 static int nd6_drain_waiters
= 0;
193 int nd6_recalc_reachtm_interval
= ND6_RECALC_REACHTM_INTERVAL
;
194 static struct sockaddr_in6 all1_sa
;
196 static int regen_tmpaddr(struct in6_ifaddr
*);
197 extern lck_mtx_t
*nd6_mutex
;
199 static void nd6_slowtimo(void *ignored_arg
);
200 static struct llinfo_nd6
*nd6_llinfo_alloc(void);
201 static void nd6_llinfo_free(void *);
202 static void nd6_llinfo_purge(struct rtentry
*);
203 static void nd6_llinfo_get_ri(struct rtentry
*, struct rt_reach_info
*);
204 static void nd6_llinfo_get_iflri(struct rtentry
*, struct ifnet_llreach_info
*);
206 static int nd6_siocgdrlst(void *, int);
207 static int nd6_siocgprlst(void *, int);
210 * Insertion and removal from llinfo_nd6 must be done with rnh_lock held.
212 #define LN_DEQUEUE(_ln) do { \
213 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
214 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
215 (_ln)->ln_next->ln_prev = (_ln)->ln_prev; \
216 (_ln)->ln_prev->ln_next = (_ln)->ln_next; \
217 (_ln)->ln_prev = (_ln)->ln_next = NULL; \
218 (_ln)->ln_flags &= ~ND6_LNF_IN_USE; \
221 #define LN_INSERTHEAD(_ln) do { \
222 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
223 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
224 (_ln)->ln_next = llinfo_nd6.ln_next; \
225 llinfo_nd6.ln_next = (_ln); \
226 (_ln)->ln_prev = &llinfo_nd6; \
227 (_ln)->ln_next->ln_prev = (_ln); \
228 (_ln)->ln_flags |= ND6_LNF_IN_USE; \
231 static struct zone
*llinfo_nd6_zone
;
232 #define LLINFO_ND6_ZONE_MAX 256 /* maximum elements in zone */
233 #define LLINFO_ND6_ZONE_NAME "llinfo_nd6" /* name for zone */
238 static int nd6_init_done
= 0;
242 log(LOG_NOTICE
, "nd6_init called more than once (ignored)\n");
246 all1_sa
.sin6_family
= AF_INET6
;
247 all1_sa
.sin6_len
= sizeof(struct sockaddr_in6
);
248 for (i
= 0; i
< sizeof(all1_sa
.sin6_addr
); i
++)
249 all1_sa
.sin6_addr
.s6_addr
[i
] = 0xff;
251 /* initialization of the default router list */
252 TAILQ_INIT(&nd_defrouter
);
254 nd_if_lock_grp_attr
= lck_grp_attr_alloc_init();
255 nd_if_lock_grp
= lck_grp_alloc_init("nd_if_lock", nd_if_lock_grp_attr
);
256 nd_if_lock_attr
= lck_attr_alloc_init();
257 lck_rw_init(nd_if_rwlock
, nd_if_lock_grp
, nd_if_lock_attr
);
259 llinfo_nd6_zone
= zinit(sizeof (struct llinfo_nd6
),
260 LLINFO_ND6_ZONE_MAX
* sizeof (struct llinfo_nd6
), 0,
261 LLINFO_ND6_ZONE_NAME
);
262 if (llinfo_nd6_zone
== NULL
)
263 panic("%s: failed allocating llinfo_nd6_zone", __func__
);
265 zone_change(llinfo_nd6_zone
, Z_EXPAND
, TRUE
);
266 zone_change(llinfo_nd6_zone
, Z_CALLERACCT
, FALSE
);
275 timeout(nd6_slowtimo
, (caddr_t
)0, ND6_SLOWTIMER_INTERVAL
* hz
);
278 static struct llinfo_nd6
*
279 nd6_llinfo_alloc(void)
281 return (zalloc(llinfo_nd6_zone
));
285 nd6_llinfo_free(void *arg
)
287 struct llinfo_nd6
*ln
= arg
;
289 if (ln
->ln_next
!= NULL
|| ln
->ln_prev
!= NULL
) {
290 panic("%s: trying to free %p when it is in use", __func__
, ln
);
294 /* Just in case there's anything there, free it */
295 if (ln
->ln_hold
!= NULL
) {
296 m_freem(ln
->ln_hold
);
300 /* Purge any link-layer info caching */
301 VERIFY(ln
->ln_rt
->rt_llinfo
== ln
);
302 if (ln
->ln_rt
->rt_llinfo_purge
!= NULL
)
303 ln
->ln_rt
->rt_llinfo_purge(ln
->ln_rt
);
305 zfree(llinfo_nd6_zone
, ln
);
309 nd6_llinfo_purge(struct rtentry
*rt
)
311 struct llinfo_nd6
*ln
= rt
->rt_llinfo
;
313 RT_LOCK_ASSERT_HELD(rt
);
314 VERIFY(rt
->rt_llinfo_purge
== nd6_llinfo_purge
&& ln
!= NULL
);
316 if (ln
->ln_llreach
!= NULL
) {
318 ifnet_llreach_free(ln
->ln_llreach
);
319 ln
->ln_llreach
= NULL
;
325 nd6_llinfo_get_ri(struct rtentry
*rt
, struct rt_reach_info
*ri
)
327 struct llinfo_nd6
*ln
= rt
->rt_llinfo
;
328 struct if_llreach
*lr
= ln
->ln_llreach
;
331 bzero(ri
, sizeof (*ri
));
332 ri
->ri_rssi
= IFNET_RSSI_UNKNOWN
;
333 ri
->ri_lqm
= IFNET_LQM_THRESH_OFF
;
334 ri
->ri_npm
= IFNET_NPM_THRESH_UNKNOWN
;
337 /* Export to rt_reach_info structure */
339 /* Export ND6 send expiration (calendar) time */
341 ifnet_llreach_up2calexp(lr
, ln
->ln_lastused
);
347 nd6_llinfo_get_iflri(struct rtentry
*rt
, struct ifnet_llreach_info
*iflri
)
349 struct llinfo_nd6
*ln
= rt
->rt_llinfo
;
350 struct if_llreach
*lr
= ln
->ln_llreach
;
353 bzero(iflri
, sizeof (*iflri
));
354 iflri
->iflri_rssi
= IFNET_RSSI_UNKNOWN
;
355 iflri
->iflri_lqm
= IFNET_LQM_THRESH_OFF
;
356 iflri
->iflri_npm
= IFNET_NPM_THRESH_UNKNOWN
;
359 /* Export to ifnet_llreach_info structure */
360 ifnet_lr2iflri(lr
, iflri
);
361 /* Export ND6 send expiration (uptime) time */
362 iflri
->iflri_snd_expire
=
363 ifnet_llreach_up2upexp(lr
, ln
->ln_lastused
);
369 nd6_ifattach(struct ifnet
*ifp
)
372 * We have some arrays that should be indexed by if_index.
373 * since if_index will grow dynamically, they should grow too.
375 lck_rw_lock_exclusive(nd_if_rwlock
);
376 if (nd_ifinfo
== NULL
|| if_index
>= nd_ifinfo_indexlim
) {
379 size_t newlim
= nd_ifinfo_indexlim
;
381 while (if_index
>= newlim
)
385 n
= newlim
* sizeof(struct nd_ifinfo
);
386 q
= (caddr_t
)_MALLOC(n
, M_IP6NDP
, M_WAITOK
);
388 lck_rw_done(nd_if_rwlock
);
392 nd_ifinfo_indexlim
= newlim
;
394 bcopy((caddr_t
)nd_ifinfo
, q
, n
/2);
396 * We might want to pattern fill the old
397 * array to catch use-after-free cases.
399 FREE((caddr_t
)nd_ifinfo
, M_IP6NDP
);
401 nd_ifinfo
= (struct nd_ifinfo
*)(void *)q
;
404 #define ND nd_ifinfo[ifp->if_index]
406 * Don't initialize if called twice.
408 if (ND
.initialized
) {
409 lck_rw_done(nd_if_rwlock
);
412 lck_mtx_init(&ND
.lock
, nd_if_lock_grp
, nd_if_lock_attr
);
413 ND
.initialized
= TRUE
;
414 ND
.linkmtu
= ifp
->if_mtu
;
415 ND
.chlim
= IPV6_DEFHLIM
;
416 ND
.basereachable
= REACHABLE_TIME
;
417 ND
.reachable
= ND_COMPUTE_RTIME(ND
.basereachable
);
418 ND
.retrans
= RETRANS_TIMER
;
419 ND
.flags
= ND6_IFF_PERFORMNUD
;
420 lck_rw_done(nd_if_rwlock
);
429 * Reset ND level link MTU. This function is called when the physical MTU
430 * changes, which means we might have to adjust the ND level MTU.
433 nd6_setmtu(struct ifnet
*ifp
)
435 struct nd_ifinfo
*ndi
;
436 u_int32_t oldmaxmtu
, maxmtu
;
439 * Make sure IPv6 is enabled for the interface first,
440 * because this can be called directly from SIOCSIFMTU for IPv4
442 lck_rw_lock_shared(nd_if_rwlock
);
443 if (ifp
->if_index
>= nd_ifinfo_indexlim
||
444 !nd_ifinfo
[ifp
->if_index
].initialized
) {
445 lck_rw_done(nd_if_rwlock
);
446 return; /* nd_ifinfo out of bound, or not yet initialized */
449 ndi
= &nd_ifinfo
[ifp
->if_index
];
450 VERIFY(ndi
->initialized
);
451 lck_mtx_lock(&ndi
->lock
);
452 oldmaxmtu
= ndi
->maxmtu
;
455 * The ND level maxmtu is somewhat redundant to the interface MTU
456 * and is an implementation artifact of KAME. Instead of hard-
457 * limiting the maxmtu based on the interface type here, we simply
458 * take the if_mtu value since SIOCSIFMTU would have taken care of
459 * the sanity checks related to the maximum MTU allowed for the
460 * interface (a value that is known only by the interface layer),
461 * by sending the request down via ifnet_ioctl(). The use of the
462 * ND level maxmtu and linkmtu are done via IN6_LINKMTU() which
463 * does further checking against if_mtu.
465 maxmtu
= ndi
->maxmtu
= ifp
->if_mtu
;
468 * Decreasing the interface MTU under IPV6 minimum MTU may cause
469 * undesirable situation. We thus notify the operator of the change
470 * explicitly. The check for oldmaxmtu is necessary to restrict the
471 * log to the case of changing the MTU, not initializing it.
473 if (oldmaxmtu
>= IPV6_MMTU
&& ndi
->maxmtu
< IPV6_MMTU
) {
474 log(LOG_NOTICE
, "nd6_setmtu: "
475 "new link MTU on %s%d (%u) is too small for IPv6\n",
476 ifp
->if_name
, ifp
->if_unit
, (uint32_t)ndi
->maxmtu
);
478 ndi
->linkmtu
= ifp
->if_mtu
;
479 lck_mtx_unlock(&ndi
->lock
);
480 lck_rw_done(nd_if_rwlock
);
482 /* also adjust in6_maxmtu if necessary. */
483 if (maxmtu
> in6_maxmtu
)
491 union nd_opts
*ndopts
)
493 bzero(ndopts
, sizeof(*ndopts
));
494 ndopts
->nd_opts_search
= (struct nd_opt_hdr
*)opt
;
496 = (struct nd_opt_hdr
*)(((u_char
*)opt
) + icmp6len
);
499 ndopts
->nd_opts_done
= 1;
500 ndopts
->nd_opts_search
= NULL
;
505 * Take one ND option.
509 union nd_opts
*ndopts
)
511 struct nd_opt_hdr
*nd_opt
;
515 panic("ndopts == NULL in nd6_option\n");
516 if (!ndopts
->nd_opts_last
)
517 panic("uninitialized ndopts in nd6_option\n");
518 if (!ndopts
->nd_opts_search
)
520 if (ndopts
->nd_opts_done
)
523 nd_opt
= ndopts
->nd_opts_search
;
525 /* make sure nd_opt_len is inside the buffer */
526 if ((caddr_t
)&nd_opt
->nd_opt_len
>= (caddr_t
)ndopts
->nd_opts_last
) {
527 bzero(ndopts
, sizeof(*ndopts
));
531 olen
= nd_opt
->nd_opt_len
<< 3;
534 * Message validation requires that all included
535 * options have a length that is greater than zero.
537 bzero(ndopts
, sizeof(*ndopts
));
541 ndopts
->nd_opts_search
= (struct nd_opt_hdr
*)((caddr_t
)nd_opt
+ olen
);
542 if (ndopts
->nd_opts_search
> ndopts
->nd_opts_last
) {
543 /* option overruns the end of buffer, invalid */
544 bzero(ndopts
, sizeof(*ndopts
));
546 } else if (ndopts
->nd_opts_search
== ndopts
->nd_opts_last
) {
547 /* reached the end of options chain */
548 ndopts
->nd_opts_done
= 1;
549 ndopts
->nd_opts_search
= NULL
;
555 * Parse multiple ND options.
556 * This function is much easier to use, for ND routines that do not need
557 * multiple options of the same type.
561 union nd_opts
*ndopts
)
563 struct nd_opt_hdr
*nd_opt
;
567 panic("ndopts == NULL in nd6_options");
568 if (ndopts
->nd_opts_last
== NULL
)
569 panic("uninitialized ndopts in nd6_options");
570 if (ndopts
->nd_opts_search
== NULL
)
574 nd_opt
= nd6_option(ndopts
);
575 if (nd_opt
== NULL
&& ndopts
->nd_opts_last
== NULL
) {
577 * Message validation requires that all included
578 * options have a length that is greater than zero.
580 icmp6stat
.icp6s_nd_badopt
++;
581 bzero(ndopts
, sizeof(*ndopts
));
588 switch (nd_opt
->nd_opt_type
) {
589 case ND_OPT_SOURCE_LINKADDR
:
590 case ND_OPT_TARGET_LINKADDR
:
592 case ND_OPT_REDIRECTED_HEADER
:
593 if (ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
]) {
595 "duplicated ND6 option found (type=%d)\n",
596 nd_opt
->nd_opt_type
));
599 ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
]
603 case ND_OPT_PREFIX_INFORMATION
:
604 if (ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
] == 0) {
605 ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
]
608 ndopts
->nd_opts_pi_end
=
609 (struct nd_opt_prefix_info
*)nd_opt
;
616 * Unknown options must be silently ignored,
617 * to accomodate future extension to the protocol.
620 "nd6_options: unsupported option %d - "
621 "option ignored\n", nd_opt
->nd_opt_type
));
626 if (i
> nd6_maxndopt
) {
627 icmp6stat
.icp6s_nd_toomanyopt
++;
628 nd6log((LOG_INFO
, "too many loop in nd opt\n"));
632 if (ndopts
->nd_opts_done
)
640 nd6_drain(__unused
void *ignored_arg
)
642 struct llinfo_nd6
*ln
;
643 struct nd_defrouter
*dr
;
644 struct nd_prefix
*pr
;
645 struct ifnet
*ifp
= NULL
;
646 struct in6_ifaddr
*ia6
, *nia6
;
647 struct in6_addrlifetime
*lt6
;
648 struct timeval timenow
;
650 getmicrotime(&timenow
);
653 * The global list llinfo_nd6 is modified by nd6_request() and is
654 * therefore protected by rnh_lock. For obvious reasons, we cannot
655 * hold rnh_lock across calls that might lead to code paths which
656 * attempt to acquire rnh_lock, else we deadlock. Hence for such
657 * cases we drop rt_lock and rnh_lock, make the calls, and repeat the
658 * loop. To ensure that we don't process the same entry more than
659 * once in a single timeout, we mark the "already-seen" entries with
660 * ND6_LNF_TIMER_SKIP flag. At the end of the loop, we do a second
661 * pass thru the entries and clear the flag so they can be processed
662 * during the next timeout.
664 lck_mtx_lock(rnh_lock
);
665 ln
= llinfo_nd6
.ln_next
;
666 while (ln
!= NULL
&& ln
!= &llinfo_nd6
) {
668 struct sockaddr_in6
*dst
;
669 struct llinfo_nd6
*next
;
670 struct nd_ifinfo
*ndi
;
671 u_int32_t retrans
, flags
;
673 /* ln_next/prev/rt is protected by rnh_lock */
678 /* We've seen this already; skip it */
679 if (ln
->ln_flags
& ND6_LNF_TIMER_SKIP
) {
685 /* rt->rt_ifp should never be NULL */
686 if ((ifp
= rt
->rt_ifp
) == NULL
) {
687 panic("%s: ln(%p) rt(%p) rt_ifp == NULL", __func__
,
692 /* rt_llinfo must always be equal to ln */
693 if ((struct llinfo_nd6
*)rt
->rt_llinfo
!= ln
) {
694 panic("%s: rt_llinfo(%p) is not equal to ln(%p)",
695 __func__
, rt
->rt_llinfo
, ln
);
699 /* rt_key should never be NULL */
700 dst
= (struct sockaddr_in6
*)(void *)rt_key(rt
);
702 panic("%s: rt(%p) key is NULL ln(%p)", __func__
,
707 /* Set the flag in case we jump to "again" */
708 ln
->ln_flags
|= ND6_LNF_TIMER_SKIP
;
710 if (ln
->ln_expire
> timenow
.tv_sec
) {
716 lck_rw_lock_shared(nd_if_rwlock
);
717 if (ifp
->if_index
>= nd_ifinfo_indexlim
) {
718 lck_rw_done(nd_if_rwlock
);
723 ndi
= ND_IFINFO(ifp
);
724 VERIFY(ndi
->initialized
);
725 lck_mtx_lock(&ndi
->lock
);
726 retrans
= ndi
->retrans
;
728 lck_mtx_unlock(&ndi
->lock
);
729 lck_rw_done(nd_if_rwlock
);
731 RT_LOCK_ASSERT_HELD(rt
);
733 switch (ln
->ln_state
) {
734 case ND6_LLINFO_INCOMPLETE
:
735 if (ln
->ln_asked
< nd6_mmaxtries
) {
737 ln
->ln_expire
= timenow
.tv_sec
+ retrans
/ 1000;
738 RT_ADDREF_LOCKED(rt
);
740 lck_mtx_unlock(rnh_lock
);
741 if (ip6_forwarding
) {
742 nd6_prproxy_ns_output(ifp
, NULL
,
743 &dst
->sin6_addr
, ln
);
745 nd6_ns_output(ifp
, NULL
,
746 &dst
->sin6_addr
, ln
, 0);
750 struct mbuf
*m
= ln
->ln_hold
;
754 * Fake rcvif to make ICMP error
755 * more helpful in diagnosing
757 * XXX: should we consider
760 m
->m_pkthdr
.rcvif
= ifp
;
762 lck_mtx_unlock(rnh_lock
);
763 icmp6_error(m
, ICMP6_DST_UNREACH
,
764 ICMP6_DST_UNREACH_ADDR
, 0);
767 lck_mtx_unlock(rnh_lock
);
771 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
);
774 case ND6_LLINFO_REACHABLE
:
776 ln
->ln_state
= ND6_LLINFO_STALE
;
777 ln
->ln_expire
= rt_expiry(rt
, timenow
.tv_sec
,
783 case ND6_LLINFO_STALE
:
784 case ND6_LLINFO_PURGE
:
785 /* Garbage Collection(RFC 2461 5.3) */
788 lck_mtx_unlock(rnh_lock
);
790 lck_mtx_assert(rnh_lock
,
791 LCK_MTX_ASSERT_NOTOWNED
);
798 case ND6_LLINFO_DELAY
:
799 if ((flags
& ND6_IFF_PERFORMNUD
) != 0) {
802 ln
->ln_state
= ND6_LLINFO_PROBE
;
803 ln
->ln_expire
= timenow
.tv_sec
+ retrans
/ 1000;
804 RT_ADDREF_LOCKED(rt
);
806 lck_mtx_unlock(rnh_lock
);
807 nd6_ns_output(ifp
, &dst
->sin6_addr
,
808 &dst
->sin6_addr
, ln
, 0);
809 lck_mtx_assert(rnh_lock
,
810 LCK_MTX_ASSERT_NOTOWNED
);
814 ln
->ln_state
= ND6_LLINFO_STALE
; /* XXX */
815 ln
->ln_expire
= rt_expiry(rt
, timenow
.tv_sec
,
820 case ND6_LLINFO_PROBE
:
821 if (ln
->ln_asked
< nd6_umaxtries
) {
823 ln
->ln_expire
= timenow
.tv_sec
+ retrans
/ 1000;
824 RT_ADDREF_LOCKED(rt
);
826 lck_mtx_unlock(rnh_lock
);
827 nd6_ns_output(ifp
, &dst
->sin6_addr
,
828 &dst
->sin6_addr
, ln
, 0);
832 lck_mtx_unlock(rnh_lock
);
835 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
);
844 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
846 /* Now clear the flag from all entries */
847 ln
= llinfo_nd6
.ln_next
;
848 while (ln
!= NULL
&& ln
!= &llinfo_nd6
) {
849 struct rtentry
*rt
= ln
->ln_rt
;
850 struct llinfo_nd6
*next
= ln
->ln_next
;
853 if (ln
->ln_flags
& ND6_LNF_TIMER_SKIP
)
854 ln
->ln_flags
&= ~ND6_LNF_TIMER_SKIP
;
858 lck_mtx_unlock(rnh_lock
);
860 /* expire default router list */
861 lck_mtx_lock(nd6_mutex
);
862 dr
= TAILQ_FIRST(&nd_defrouter
);
864 if (dr
->expire
&& dr
->expire
< timenow
.tv_sec
) {
865 struct nd_defrouter
*t
;
866 t
= TAILQ_NEXT(dr
, dr_entry
);
870 dr
= TAILQ_NEXT(dr
, dr_entry
);
873 lck_mtx_unlock(nd6_mutex
);
876 * expire interface addresses.
877 * in the past the loop was inside prefix expiry processing.
878 * However, from a stricter speci-confrmance standpoint, we should
879 * rather separate address lifetimes and prefix lifetimes.
882 lck_rw_lock_exclusive(&in6_ifaddr_rwlock
);
883 for (ia6
= in6_ifaddrs
; ia6
; ia6
= nia6
) {
885 IFA_LOCK(&ia6
->ia_ifa
);
887 * Extra reference for ourselves; it's no-op if
888 * we don't have to regenerate temporary address,
889 * otherwise it protects the address from going
890 * away since we drop in6_ifaddr_rwlock below.
892 IFA_ADDREF_LOCKED(&ia6
->ia_ifa
);
893 /* check address lifetime */
894 lt6
= &ia6
->ia6_lifetime
;
895 if (IFA6_IS_INVALID(ia6
)) {
897 * If the expiring address is temporary, try
898 * regenerating a new one. This would be useful when
899 * we suspended a laptop PC, then turned it on after a
900 * period that could invalidate all temporary
901 * addresses. Although we may have to restart the
902 * loop (see below), it must be after purging the
903 * address. Otherwise, we'd see an infinite loop of
906 if (ip6_use_tempaddr
&&
907 (ia6
->ia6_flags
& IN6_IFF_TEMPORARY
) != 0) {
909 * NOTE: We have to drop the lock here
910 * because regen_tmpaddr() eventually calls
911 * in6_update_ifa(), which must take the lock
912 * and would otherwise cause a hang. This is
913 * safe because the goto addrloop leads to a
914 * re-evaluation of the in6_ifaddrs list
916 IFA_UNLOCK(&ia6
->ia_ifa
);
917 lck_rw_done(&in6_ifaddr_rwlock
);
918 (void) regen_tmpaddr(ia6
);
920 IFA_UNLOCK(&ia6
->ia_ifa
);
921 lck_rw_done(&in6_ifaddr_rwlock
);
925 * Purging the address would have caused
926 * in6_ifaddr_rwlock to be dropped and reacquired;
927 * therefore search again from the beginning
928 * of in6_ifaddrs list.
930 in6_purgeaddr(&ia6
->ia_ifa
);
932 /* Release extra reference taken above */
933 IFA_REMREF(&ia6
->ia_ifa
);
936 IFA_LOCK_ASSERT_HELD(&ia6
->ia_ifa
);
937 if (IFA6_IS_DEPRECATED(ia6
)) {
938 int oldflags
= ia6
->ia6_flags
;
940 ia6
->ia6_flags
|= IN6_IFF_DEPRECATED
;
943 * If a temporary address has just become deprecated,
944 * regenerate a new one if possible.
946 if (ip6_use_tempaddr
&&
947 (ia6
->ia6_flags
& IN6_IFF_TEMPORARY
) != 0 &&
948 (oldflags
& IN6_IFF_DEPRECATED
) == 0) {
951 IFA_UNLOCK(&ia6
->ia_ifa
);
952 lck_rw_done(&in6_ifaddr_rwlock
);
953 if (regen_tmpaddr(ia6
) == 0) {
955 * A new temporary address is
957 * XXX: this means the address chain
958 * has changed while we are still in
959 * the loop. Although the change
960 * would not cause disaster (because
961 * it's not a deletion, but an
962 * addition,) we'd rather restart the
963 * loop just for safety. Or does this
964 * significantly reduce performance??
966 /* Release extra reference */
967 IFA_REMREF(&ia6
->ia_ifa
);
970 lck_rw_lock_exclusive(&in6_ifaddr_rwlock
);
972 IFA_UNLOCK(&ia6
->ia_ifa
);
976 * A new RA might have made a deprecated address
979 ia6
->ia6_flags
&= ~IN6_IFF_DEPRECATED
;
980 IFA_UNLOCK(&ia6
->ia_ifa
);
982 lck_rw_assert(&in6_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
983 /* Release extra reference taken above */
984 IFA_REMREF(&ia6
->ia_ifa
);
986 lck_rw_done(&in6_ifaddr_rwlock
);
988 lck_mtx_lock(nd6_mutex
);
990 * Since we drop the nd6_mutex in prelist_remove, we want to run this
991 * section single threaded.
993 while (nd6_drain_busy
) {
995 msleep(nd6_drain_waitchan
, nd6_mutex
, (PZERO
-1),
997 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
999 nd6_drain_busy
= TRUE
;
1001 /* expire prefix list */
1002 pr
= nd_prefix
.lh_first
;
1005 * check prefix lifetime.
1006 * since pltime is just for autoconf, pltime processing for
1007 * prefix is not necessary.
1010 if (pr
->ndpr_stateflags
& NDPRF_PROCESSED
) {
1015 if (pr
->ndpr_expire
&& pr
->ndpr_expire
< timenow
.tv_sec
) {
1017 * address expiration and prefix expiration are
1018 * separate. NEVER perform in6_purgeaddr here.
1020 pr
->ndpr_stateflags
|= NDPRF_PROCESSED
;
1021 NDPR_ADDREF_LOCKED(pr
);
1025 pr
= nd_prefix
.lh_first
;
1027 pr
->ndpr_stateflags
|= NDPRF_PROCESSED
;
1032 LIST_FOREACH(pr
, &nd_prefix
, ndpr_entry
) {
1034 pr
->ndpr_stateflags
&= ~NDPRF_PROCESSED
;
1037 nd6_drain_busy
= FALSE
;
1038 if (nd6_drain_waiters
> 0) {
1039 nd6_drain_waiters
= 0;
1040 wakeup(nd6_drain_waitchan
);
1042 lck_mtx_unlock(nd6_mutex
);
1046 * ND6 router advertisement kernel notification
1049 nd6_post_msg(u_int32_t code
, struct nd_prefix_list
*prefix_list
,
1050 u_int32_t list_length
, u_int32_t mtu
, char *dl_addr
, u_int32_t dl_addr_len
)
1052 struct kev_msg ev_msg
;
1053 struct kev_nd6_ra_data nd6_ra_msg_data
;
1054 struct nd_prefix_list
*itr
= prefix_list
;
1056 bzero(&ev_msg
, sizeof(struct kev_msg
));
1057 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1058 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1059 ev_msg
.kev_subclass
= KEV_ND6_SUBCLASS
;
1060 ev_msg
.event_code
= code
;
1062 bzero(&nd6_ra_msg_data
, sizeof(nd6_ra_msg_data
));
1063 nd6_ra_msg_data
.lladdrlen
= (dl_addr_len
<= ND6_ROUTER_LL_SIZE
) ?
1064 dl_addr_len
: ND6_ROUTER_LL_SIZE
;
1065 bcopy(dl_addr
, &nd6_ra_msg_data
.lladdr
, nd6_ra_msg_data
.lladdrlen
);
1067 if (mtu
> 0 && mtu
>= IPV6_MMTU
) {
1068 nd6_ra_msg_data
.mtu
= mtu
;
1069 nd6_ra_msg_data
.flags
|= KEV_ND6_DATA_VALID_MTU
;
1072 if (list_length
> 0 && prefix_list
!= NULL
) {
1073 nd6_ra_msg_data
.list_length
= list_length
;
1074 nd6_ra_msg_data
.flags
|= KEV_ND6_DATA_VALID_PREFIX
;
1077 while (itr
!= NULL
&& nd6_ra_msg_data
.list_index
< list_length
) {
1078 bcopy(&itr
->pr
.ndpr_prefix
, &nd6_ra_msg_data
.prefix
.prefix
,
1079 sizeof (nd6_ra_msg_data
.prefix
.prefix
));
1080 nd6_ra_msg_data
.prefix
.raflags
= itr
->pr
.ndpr_raf
;
1081 nd6_ra_msg_data
.prefix
.prefixlen
= itr
->pr
.ndpr_plen
;
1082 nd6_ra_msg_data
.prefix
.origin
= PR_ORIG_RA
;
1083 nd6_ra_msg_data
.prefix
.vltime
= itr
->pr
.ndpr_vltime
;
1084 nd6_ra_msg_data
.prefix
.pltime
= itr
->pr
.ndpr_pltime
;
1085 nd6_ra_msg_data
.prefix
.expire
= itr
->pr
.ndpr_expire
;
1086 nd6_ra_msg_data
.prefix
.flags
= itr
->pr
.ndpr_stateflags
;
1087 nd6_ra_msg_data
.prefix
.refcnt
= itr
->pr
.ndpr_addrcnt
;
1088 nd6_ra_msg_data
.prefix
.if_index
= itr
->pr
.ndpr_ifp
->if_index
;
1090 /* send the message up */
1091 ev_msg
.dv
[0].data_ptr
= &nd6_ra_msg_data
;
1092 ev_msg
.dv
[0].data_length
= sizeof(nd6_ra_msg_data
);
1093 ev_msg
.dv
[1].data_length
= 0;
1094 kev_post_msg(&ev_msg
);
1096 /* clean up for the next prefix */
1097 bzero(&nd6_ra_msg_data
.prefix
, sizeof(nd6_ra_msg_data
.prefix
));
1099 nd6_ra_msg_data
.list_index
++;
1104 * ND6 timer routine to expire default route list and prefix list
1107 nd6_timer(__unused
void *ignored_arg
)
1110 timeout(nd6_timer
, (caddr_t
)0, nd6_prune
* hz
);
1115 struct in6_ifaddr
*ia6
) /* deprecated/invalidated temporary address */
1119 struct in6_ifaddr
*public_ifa6
= NULL
;
1120 struct timeval timenow
;
1122 getmicrotime(&timenow
);
1124 ifp
= ia6
->ia_ifa
.ifa_ifp
;
1125 ifnet_lock_shared(ifp
);
1126 for (ifa
= ifp
->if_addrlist
.tqh_first
; ifa
;
1127 ifa
= ifa
->ifa_list
.tqe_next
)
1129 struct in6_ifaddr
*it6
;
1132 if (ifa
->ifa_addr
->sa_family
!= AF_INET6
) {
1136 it6
= (struct in6_ifaddr
*)ifa
;
1138 /* ignore no autoconf addresses. */
1139 if ((it6
->ia6_flags
& IN6_IFF_AUTOCONF
) == 0) {
1143 /* ignore autoconf addresses with different prefixes. */
1144 if (it6
->ia6_ndpr
== NULL
|| it6
->ia6_ndpr
!= ia6
->ia6_ndpr
) {
1149 * Now we are looking at an autoconf address with the same
1150 * prefix as ours. If the address is temporary and is still
1151 * preferred, do not create another one. It would be rare, but
1152 * could happen, for example, when we resume a laptop PC after
1155 if ((it6
->ia6_flags
& IN6_IFF_TEMPORARY
) != 0 &&
1156 !IFA6_IS_DEPRECATED(it6
)) {
1158 if (public_ifa6
!= NULL
)
1159 IFA_REMREF(&public_ifa6
->ia_ifa
);
1165 * This is a public autoconf address that has the same prefix
1166 * as ours. If it is preferred, keep it. We can't break the
1167 * loop here, because there may be a still-preferred temporary
1168 * address with the prefix.
1170 if (!IFA6_IS_DEPRECATED(it6
)) {
1171 IFA_ADDREF_LOCKED(ifa
); /* for public_ifa6 */
1173 if (public_ifa6
!= NULL
)
1174 IFA_REMREF(&public_ifa6
->ia_ifa
);
1180 ifnet_lock_done(ifp
);
1182 if (public_ifa6
!= NULL
) {
1185 if ((e
= in6_tmpifadd(public_ifa6
, 0, M_WAITOK
)) != 0) {
1186 log(LOG_NOTICE
, "regen_tmpaddr: failed to create a new"
1187 " tmp addr,errno=%d\n", e
);
1188 IFA_REMREF(&public_ifa6
->ia_ifa
);
1191 IFA_REMREF(&public_ifa6
->ia_ifa
);
1199 * Nuke neighbor cache/prefix/default router management table, right before
1206 struct llinfo_nd6
*ln
;
1207 struct nd_defrouter
*dr
, *ndr
;
1208 struct nd_prefix
*pr
, *npr
;
1210 /* Nuke default router list entries toward ifp */
1211 lck_mtx_lock(nd6_mutex
);
1212 if ((dr
= TAILQ_FIRST(&nd_defrouter
)) != NULL
) {
1214 * The first entry of the list may be stored in
1215 * the routing table, so we'll delete it later.
1217 for (dr
= TAILQ_NEXT(dr
, dr_entry
); dr
; dr
= ndr
) {
1218 ndr
= TAILQ_NEXT(dr
, dr_entry
);
1219 if (dr
->stateflags
& NDDRF_INSTALLED
)
1224 dr
= TAILQ_FIRST(&nd_defrouter
);
1229 for (dr
= TAILQ_FIRST(&nd_defrouter
); dr
; dr
= ndr
) {
1230 ndr
= TAILQ_NEXT(dr
, dr_entry
);
1231 if (!(dr
->stateflags
& NDDRF_INSTALLED
))
1238 /* Nuke prefix list entries toward ifp */
1239 for (pr
= nd_prefix
.lh_first
; pr
; pr
= npr
) {
1240 npr
= pr
->ndpr_next
;
1242 if (pr
->ndpr_ifp
== ifp
) {
1244 * Because if_detach() does *not* release prefixes
1245 * while purging addresses the reference count will
1246 * still be above zero. We therefore reset it to
1247 * make sure that the prefix really gets purged.
1249 pr
->ndpr_addrcnt
= 0;
1252 * Previously, pr->ndpr_addr is removed as well,
1253 * but I strongly believe we don't have to do it.
1254 * nd6_purge() is only called from in6_ifdetach(),
1255 * which removes all the associated interface addresses
1257 * (jinmei@kame.net 20010129)
1259 NDPR_ADDREF_LOCKED(pr
);
1267 lck_mtx_unlock(nd6_mutex
);
1269 /* cancel default outgoing interface setting */
1270 if (nd6_defifindex
== ifp
->if_index
) {
1271 nd6_setdefaultiface(0);
1275 * Perform default router selection even when we are a router,
1276 * if Scoped Routing is enabled.
1278 if (ip6_doscopedroute
|| !ip6_forwarding
) {
1279 lck_mtx_lock(nd6_mutex
);
1280 /* refresh default router list */
1281 defrouter_select(ifp
);
1282 lck_mtx_unlock(nd6_mutex
);
1286 * Nuke neighbor cache entries for the ifp.
1287 * Note that rt->rt_ifp may not be the same as ifp,
1288 * due to KAME goto ours hack. See RTM_RESOLVE case in
1289 * nd6_rtrequest(), and ip6_input().
1292 lck_mtx_lock(rnh_lock
);
1293 ln
= llinfo_nd6
.ln_next
;
1294 while (ln
!= NULL
&& ln
!= &llinfo_nd6
) {
1296 struct llinfo_nd6
*nln
;
1301 if (rt
->rt_gateway
!= NULL
&&
1302 rt
->rt_gateway
->sa_family
== AF_LINK
&&
1303 SDL(rt
->rt_gateway
)->sdl_index
== ifp
->if_index
) {
1305 lck_mtx_unlock(rnh_lock
);
1307 * See comments on nd6_timer() for reasons why
1308 * this loop is repeated; we bite the costs of
1309 * going thru the same llinfo_nd6 more than once
1310 * here, since this purge happens during detach,
1311 * and that unlike the timer case, it's possible
1312 * there's more than one purges happening at the
1313 * same time (thus a flag wouldn't buy anything).
1316 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
);
1323 lck_mtx_unlock(rnh_lock
);
1327 * Upon success, the returned route will be locked and the caller is
1328 * responsible for releasing the reference and doing RT_UNLOCK(rt).
1329 * This routine does not require rnh_lock to be held by the caller,
1330 * although it needs to be indicated of such a case in order to call
1331 * the correct variant of the relevant routing routines.
1335 struct in6_addr
*addr6
,
1341 struct sockaddr_in6 sin6
;
1342 unsigned int ifscope
;
1344 bzero(&sin6
, sizeof(sin6
));
1345 sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1346 sin6
.sin6_family
= AF_INET6
;
1347 sin6
.sin6_addr
= *addr6
;
1349 ifscope
= (ifp
!= NULL
) ? ifp
->if_index
: IFSCOPE_NONE
;
1351 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
1352 rt
= rtalloc1_scoped_locked((struct sockaddr
*)&sin6
,
1353 create
, 0, ifscope
);
1355 rt
= rtalloc1_scoped((struct sockaddr
*)&sin6
,
1356 create
, 0, ifscope
);
1361 if ((rt
->rt_flags
& RTF_LLINFO
) == 0) {
1363 * This is the case for the default route.
1364 * If we want to create a neighbor cache for the
1365 * address, we should free the route for the
1366 * destination and allocate an interface route.
1379 if (create
&& ifp
) {
1381 u_int32_t ifa_flags
;
1385 * If no route is available and create is set,
1386 * we allocate a host route for the destination
1387 * and treat it like an interface route.
1388 * This hack is necessary for a neighbor which can't
1389 * be covered by our own prefix.
1391 ifa
= ifaof_ifpforaddr((struct sockaddr
*)&sin6
, ifp
);
1396 * Create a new route. RTF_LLINFO is necessary
1397 * to create a Neighbor Cache entry for the
1398 * destination in nd6_rtrequest which will be
1399 * called in rtrequest via ifa->ifa_rtrequest.
1402 lck_mtx_lock(rnh_lock
);
1404 ifa_flags
= ifa
->ifa_flags
;
1406 if ((e
= rtrequest_scoped_locked(RTM_ADD
,
1407 (struct sockaddr
*)&sin6
, ifa
->ifa_addr
,
1408 (struct sockaddr
*)&all1_sa
,
1409 (ifa_flags
| RTF_HOST
| RTF_LLINFO
) &
1410 ~RTF_CLONING
, &rt
, ifscope
)) != 0) {
1412 log(LOG_ERR
, "%s: failed to add route "
1413 "for a neighbor(%s), errno=%d\n",
1414 __func__
, ip6_sprintf(addr6
), e
);
1417 lck_mtx_unlock(rnh_lock
);
1423 if (rt
->rt_llinfo
) {
1424 struct llinfo_nd6
*ln
= rt
->rt_llinfo
;
1425 ln
->ln_state
= ND6_LLINFO_NOSTATE
;
1431 RT_LOCK_ASSERT_HELD(rt
);
1433 * Validation for the entry.
1434 * Note that the check for rt_llinfo is necessary because a cloned
1435 * route from a parent route that has the L flag (e.g. the default
1436 * route to a p2p interface) may have the flag, too, while the
1437 * destination is not actually a neighbor.
1438 * XXX: we can't use rt->rt_ifp to check for the interface, since
1439 * it might be the loopback interface if the entry is for our
1440 * own address on a non-loopback interface. Instead, we should
1441 * use rt->rt_ifa->ifa_ifp, which would specify the REAL
1443 * Note also that ifa_ifp and ifp may differ when we connect two
1444 * interfaces to a same link, install a link prefix to an interface,
1445 * and try to install a neighbor cache on an interface that does not
1446 * have a route to the prefix.
1448 * If the address is from a proxied prefix, the ifa_ifp and ifp might
1449 * not match, because nd6_na_input() could have modified the ifp
1450 * of the route to point to the interface where the NA arrived on,
1451 * hence the test for RTF_PROXY.
1453 if ((rt
->rt_flags
& RTF_GATEWAY
) || (rt
->rt_flags
& RTF_LLINFO
) == 0 ||
1454 rt
->rt_gateway
->sa_family
!= AF_LINK
|| rt
->rt_llinfo
== NULL
||
1455 (ifp
&& rt
->rt_ifa
->ifa_ifp
!= ifp
&&
1456 !(rt
->rt_flags
& RTF_PROXY
))) {
1457 RT_REMREF_LOCKED(rt
);
1460 log(LOG_DEBUG
, "%s: failed to lookup %s "
1461 "(if = %s)\n", __func__
, ip6_sprintf(addr6
),
1462 ifp
? if_name(ifp
) : "unspec");
1463 /* xxx more logs... kazu */
1468 * Caller needs to release reference and call RT_UNLOCK(rt).
1474 * Test whether a given IPv6 address is a neighbor or not, ignoring
1475 * the actual neighbor cache. The neighbor cache is ignored in order
1476 * to not reenter the routing code from within itself.
1479 nd6_is_new_addr_neighbor(
1480 struct sockaddr_in6
*addr
,
1483 struct nd_prefix
*pr
;
1484 struct ifaddr
*dstaddr
;
1486 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
1489 * A link-local address is always a neighbor.
1490 * XXX: a link does not necessarily specify a single interface.
1492 if (IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
1493 struct sockaddr_in6 sin6_copy
;
1497 * We need sin6_copy since sa6_recoverscope() may modify the
1501 if (sa6_recoverscope(&sin6_copy
, FALSE
))
1502 return (0); /* XXX: should be impossible */
1503 if (in6_setscope(&sin6_copy
.sin6_addr
, ifp
, &zone
))
1505 if (sin6_copy
.sin6_scope_id
== zone
)
1512 * If the address matches one of our addresses,
1513 * it should be a neighbor.
1514 * If the address matches one of our on-link prefixes, it should be a
1517 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
1519 if (pr
->ndpr_ifp
!= ifp
) {
1523 if (!(pr
->ndpr_stateflags
& NDPRF_ONLINK
)) {
1527 if (IN6_ARE_MASKED_ADDR_EQUAL(&pr
->ndpr_prefix
.sin6_addr
,
1528 &addr
->sin6_addr
, &pr
->ndpr_mask
)) {
1536 * If the address is assigned on the node of the other side of
1537 * a p2p interface, the address should be a neighbor.
1539 dstaddr
= ifa_ifwithdstaddr((struct sockaddr
*)addr
);
1540 if (dstaddr
!= NULL
) {
1541 if (dstaddr
->ifa_ifp
== ifp
) {
1542 IFA_REMREF(dstaddr
);
1545 IFA_REMREF(dstaddr
);
1550 * If the default router list is empty, all addresses are regarded
1551 * as on-link, and thus, as a neighbor.
1552 * XXX: we restrict the condition to hosts, because routers usually do
1553 * not have the "default router list".
1554 * XXX: this block should eventually be removed (it is disabled when
1555 * Scoped Routing is in effect); treating all destinations as on-link
1556 * in the absence of a router is rather harmful.
1558 if (!ip6_doscopedroute
&& !ip6_forwarding
&&
1559 TAILQ_FIRST(&nd_defrouter
) == NULL
&&
1560 nd6_defifindex
== ifp
->if_index
) {
1569 * Detect if a given IPv6 address identifies a neighbor on a given link.
1570 * XXX: should take care of the destination of a p2p link?
1573 nd6_is_addr_neighbor(struct sockaddr_in6
*addr
, struct ifnet
*ifp
, int rt_locked
)
1577 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
);
1578 lck_mtx_lock(nd6_mutex
);
1579 if (nd6_is_new_addr_neighbor(addr
, ifp
)) {
1580 lck_mtx_unlock(nd6_mutex
);
1583 lck_mtx_unlock(nd6_mutex
);
1586 * Even if the address matches none of our addresses, it might be
1587 * in the neighbor cache.
1589 if ((rt
= nd6_lookup(&addr
->sin6_addr
, 0, ifp
, rt_locked
)) != NULL
) {
1590 RT_LOCK_ASSERT_HELD(rt
);
1591 RT_REMREF_LOCKED(rt
);
1600 * Free an nd6 llinfo entry.
1601 * Since the function would cause significant changes in the kernel, DO NOT
1602 * make it global, unless you have a strong reason for the change, and are sure
1603 * that the change is safe.
1609 struct llinfo_nd6
*ln
;
1610 struct in6_addr in6
;
1611 struct nd_defrouter
*dr
;
1613 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
);
1614 RT_LOCK_ASSERT_NOTHELD(rt
);
1615 lck_mtx_lock(nd6_mutex
);
1618 RT_ADDREF_LOCKED(rt
); /* Extra ref */
1620 in6
= ((struct sockaddr_in6
*)(void *)rt_key(rt
))->sin6_addr
;
1623 * Prevent another thread from modifying rt_key, rt_gateway
1624 * via rt_setgate() after the rt_lock is dropped by marking
1625 * the route as defunct.
1627 rt
->rt_flags
|= RTF_CONDEMNED
;
1630 * We used to have pfctlinput(PRC_HOSTDEAD) here. Even though it is
1631 * not harmful, it was not really necessary. Perform default router
1632 * selection even when we are a router, if Scoped Routing is enabled.
1634 if (ip6_doscopedroute
|| !ip6_forwarding
) {
1635 dr
= defrouter_lookup(&((struct sockaddr_in6
*)(void *)
1636 rt_key(rt
))->sin6_addr
, rt
->rt_ifp
);
1638 if ((ln
&& ln
->ln_router
) || dr
) {
1640 * rt6_flush must be called whether or not the neighbor
1641 * is in the Default Router List.
1642 * See a corresponding comment in nd6_na_input().
1645 lck_mtx_unlock(nd6_mutex
);
1646 rt6_flush(&in6
, rt
->rt_ifp
);
1647 lck_mtx_lock(nd6_mutex
);
1655 * Unreachablity of a router might affect the default
1656 * router selection and on-link detection of advertised
1661 * Temporarily fake the state to choose a new default
1662 * router and to perform on-link determination of
1663 * prefixes correctly.
1664 * Below the state will be set correctly,
1665 * or the entry itself will be deleted.
1668 ln
->ln_state
= ND6_LLINFO_INCOMPLETE
;
1671 * Since defrouter_select() does not affect the
1672 * on-link determination and MIP6 needs the check
1673 * before the default router selection, we perform
1677 pfxlist_onlink_check();
1680 * refresh default router list
1682 defrouter_select(rt
->rt_ifp
);
1684 RT_LOCK_ASSERT_NOTHELD(rt
);
1689 lck_mtx_unlock(nd6_mutex
);
1691 * Detach the route from the routing tree and the list of neighbor
1692 * caches, and disable the route entry not to be used in already
1695 (void) rtrequest(RTM_DELETE
, rt_key(rt
), (struct sockaddr
*)0,
1696 rt_mask(rt
), 0, (struct rtentry
**)0);
1698 /* Extra ref held above; now free it */
1703 * Upper-layer reachability hint for Neighbor Unreachability Detection.
1705 * XXX cost-effective methods?
1710 struct in6_addr
*dst6
,
1713 struct llinfo_nd6
*ln
;
1714 struct timeval timenow
;
1716 getmicrotime(&timenow
);
1719 * If the caller specified "rt", use that. Otherwise, resolve the
1720 * routing table by supplied "dst6".
1725 /* Callee returns a locked route upon success */
1726 if ((rt
= nd6_lookup(dst6
, 0, NULL
, 0)) == NULL
)
1728 RT_LOCK_ASSERT_HELD(rt
);
1731 RT_ADDREF_LOCKED(rt
);
1734 if ((rt
->rt_flags
& RTF_GATEWAY
) != 0 ||
1735 (rt
->rt_flags
& RTF_LLINFO
) == 0 ||
1736 !rt
->rt_llinfo
|| !rt
->rt_gateway
||
1737 rt
->rt_gateway
->sa_family
!= AF_LINK
) {
1738 /* This is not a host route. */
1743 if (ln
->ln_state
< ND6_LLINFO_REACHABLE
)
1747 * if we get upper-layer reachability confirmation many times,
1748 * it is possible we have false information.
1752 if (ln
->ln_byhint
> nd6_maxnudhint
)
1756 ln
->ln_state
= ND6_LLINFO_REACHABLE
;
1757 if (ln
->ln_expire
) {
1758 struct nd_ifinfo
*ndi
;
1760 lck_rw_lock_shared(nd_if_rwlock
);
1761 ndi
= ND_IFINFO(rt
->rt_ifp
);
1762 VERIFY(ndi
!= NULL
&& ndi
->initialized
);
1763 lck_mtx_lock(&ndi
->lock
);
1764 ln
->ln_expire
= timenow
.tv_sec
+ ndi
->reachable
;
1765 lck_mtx_unlock(&ndi
->lock
);
1766 lck_rw_done(nd_if_rwlock
);
1769 RT_REMREF_LOCKED(rt
);
1777 __unused
struct sockaddr
*sa
)
1779 struct sockaddr
*gate
= rt
->rt_gateway
;
1780 struct llinfo_nd6
*ln
= rt
->rt_llinfo
;
1781 static struct sockaddr_dl null_sdl
= {sizeof(null_sdl
), AF_LINK
, 0, 0, 0, 0, 0,
1782 {0,0,0,0,0,0,0,0,0,0,0,0,} };
1783 struct ifnet
*ifp
= rt
->rt_ifp
;
1785 struct timeval timenow
;
1787 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
1788 RT_LOCK_ASSERT_HELD(rt
);
1790 if ((rt
->rt_flags
& RTF_GATEWAY
))
1793 if (nd6_need_cache(ifp
) == 0 && (rt
->rt_flags
& RTF_HOST
) == 0) {
1795 * This is probably an interface direct route for a link
1796 * which does not need neighbor caches (e.g. fe80::%lo0/64).
1797 * We do not need special treatment below for such a route.
1798 * Moreover, the RTF_LLINFO flag which would be set below
1799 * would annoy the ndp(8) command.
1804 if (req
== RTM_RESOLVE
) {
1807 if (!nd6_need_cache(ifp
)) { /* stf case */
1810 struct sockaddr_in6 sin6
;
1812 rtkey_to_sa6(rt
, &sin6
);
1814 * nd6_is_addr_neighbor() may call nd6_lookup(),
1815 * therefore we drop rt_lock to avoid deadlock
1816 * during the lookup.
1818 RT_ADDREF_LOCKED(rt
);
1820 no_nd_cache
= !nd6_is_addr_neighbor(&sin6
, ifp
, 1);
1822 RT_REMREF_LOCKED(rt
);
1826 * FreeBSD and BSD/OS often make a cloned host route based
1827 * on a less-specific route (e.g. the default route).
1828 * If the less specific route does not have a "gateway"
1829 * (this is the case when the route just goes to a p2p or an
1830 * stf interface), we'll mistakenly make a neighbor cache for
1831 * the host route, and will see strange neighbor solicitation
1832 * for the corresponding destination. In order to avoid the
1833 * confusion, we check if the destination of the route is
1834 * a neighbor in terms of neighbor discovery, and stop the
1835 * process if not. Additionally, we remove the LLINFO flag
1836 * so that ndp(8) will not try to get the neighbor information
1837 * of the destination.
1840 rt
->rt_flags
&= ~RTF_LLINFO
;
1845 getmicrotime(&timenow
);
1849 * There is no backward compatibility :)
1851 * if ((rt->rt_flags & RTF_HOST) == 0 &&
1852 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1853 * rt->rt_flags |= RTF_CLONING;
1855 if ((rt
->rt_flags
& RTF_CLONING
) ||
1856 ((rt
->rt_flags
& RTF_LLINFO
) && ln
== NULL
)) {
1858 * Case 1: This route should come from a route to
1859 * interface (RTF_CLONING case) or the route should be
1860 * treated as on-link but is currently not
1861 * (RTF_LLINFO && ln == NULL case).
1863 if (rt_setgate(rt
, rt_key(rt
),
1864 (struct sockaddr
*)&null_sdl
) == 0) {
1865 gate
= rt
->rt_gateway
;
1866 SDL(gate
)->sdl_type
= ifp
->if_type
;
1867 SDL(gate
)->sdl_index
= ifp
->if_index
;
1869 * In case we're called before 1.0 sec.
1874 (ifp
->if_eflags
& IFEF_IPV6_ND6ALT
)
1875 ? 0 : MAX(timenow
.tv_sec
, 1);
1877 if ((rt
->rt_flags
& RTF_CLONING
))
1881 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
1882 * We don't do that here since llinfo is not ready yet.
1884 * There are also couple of other things to be discussed:
1885 * - unsolicited NA code needs improvement beforehand
1886 * - RFC2461 says we MAY send multicast unsolicited NA
1887 * (7.2.6 paragraph 4), however, it also says that we
1888 * SHOULD provide a mechanism to prevent multicast NA storm.
1889 * we don't have anything like it right now.
1890 * note that the mechanism needs a mutual agreement
1891 * between proxies, which means that we need to implement
1892 * a new protocol, or a new kludge.
1893 * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
1894 * we need to check ip6forwarding before sending it.
1895 * (or should we allow proxy ND configuration only for
1896 * routers? there's no mention about proxy ND from hosts)
1900 if ((ifp
->if_flags
& (IFF_POINTOPOINT
| IFF_LOOPBACK
)) == 0) {
1902 * Address resolution isn't necessary for a point to
1903 * point link, so we can skip this test for a p2p link.
1905 if (gate
->sa_family
!= AF_LINK
||
1906 gate
->sa_len
< sizeof(null_sdl
)) {
1907 /* Don't complain in case of RTM_ADD */
1908 if (req
== RTM_RESOLVE
) {
1910 "nd6_rtrequest: bad gateway "
1911 "value: %s\n", if_name(ifp
));
1915 SDL(gate
)->sdl_type
= ifp
->if_type
;
1916 SDL(gate
)->sdl_index
= ifp
->if_index
;
1919 break; /* This happens on a route change */
1921 * Case 2: This route may come from cloning, or a manual route
1922 * add with a LL address.
1924 rt
->rt_llinfo
= ln
= nd6_llinfo_alloc();
1926 log(LOG_DEBUG
, "nd6_rtrequest: malloc failed\n");
1929 rt
->rt_llinfo_get_ri
= nd6_llinfo_get_ri
;
1930 rt
->rt_llinfo_get_iflri
= nd6_llinfo_get_iflri
;
1931 rt
->rt_llinfo_purge
= nd6_llinfo_purge
;
1932 rt
->rt_llinfo_free
= nd6_llinfo_free
;
1936 Bzero(ln
, sizeof(*ln
));
1938 /* this is required for "ndp" command. - shin */
1939 if (req
== RTM_ADD
) {
1941 * gate should have some valid AF_LINK entry,
1942 * and ln->ln_expire should have some lifetime
1943 * which is specified by ndp command.
1945 ln
->ln_state
= ND6_LLINFO_REACHABLE
;
1949 * When req == RTM_RESOLVE, rt is created and
1950 * initialized in rtrequest(), so rt_expire is 0.
1952 ln
->ln_state
= ND6_LLINFO_NOSTATE
;
1954 /* In case we're called before 1.0 sec. has elapsed */
1955 ln
->ln_expire
= (ifp
->if_eflags
& IFEF_IPV6_ND6ALT
)
1956 ? 0 : MAX(timenow
.tv_sec
, 1);
1958 rt
->rt_flags
|= RTF_LLINFO
;
1962 * If we have too many cache entries, initiate immediate
1963 * purging for some "less recently used" entries. Note that
1964 * we cannot directly call nd6_free() here because it would
1965 * cause re-entering rtable related routines triggering an LOR
1968 if (ip6_neighborgcthresh
>= 0 &&
1969 nd6_inuse
>= ip6_neighborgcthresh
) {
1972 for (i
= 0; i
< 10 && llinfo_nd6
.ln_prev
!= ln
; i
++) {
1973 struct llinfo_nd6
*ln_end
= llinfo_nd6
.ln_prev
;
1974 struct rtentry
*rt_end
= ln_end
->ln_rt
;
1976 /* Move this entry to the head */
1979 LN_INSERTHEAD(ln_end
);
1981 if (ln_end
->ln_expire
== 0) {
1985 if (ln_end
->ln_state
> ND6_LLINFO_INCOMPLETE
)
1986 ln_end
->ln_state
= ND6_LLINFO_STALE
;
1988 ln_end
->ln_state
= ND6_LLINFO_PURGE
;
1989 ln_end
->ln_expire
= timenow
.tv_sec
;
1995 * check if rt_key(rt) is one of my address assigned
1998 ifa
= (struct ifaddr
*)in6ifa_ifpwithaddr(rt
->rt_ifp
,
1999 &SIN6(rt_key(rt
))->sin6_addr
);
2001 caddr_t macp
= nd6_ifptomac(ifp
);
2003 ln
->ln_state
= ND6_LLINFO_REACHABLE
;
2006 Bcopy(macp
, LLADDR(SDL(gate
)), ifp
->if_addrlen
);
2007 SDL(gate
)->sdl_alen
= ifp
->if_addrlen
;
2009 if (nd6_useloopback
) {
2010 if (rt
->rt_ifp
!= lo_ifp
) {
2012 * Purge any link-layer info caching.
2014 if (rt
->rt_llinfo_purge
!= NULL
)
2015 rt
->rt_llinfo_purge(rt
);
2018 * Adjust route ref count for the
2021 if (rt
->rt_if_ref_fn
!= NULL
) {
2022 rt
->rt_if_ref_fn(lo_ifp
, 1);
2023 rt
->rt_if_ref_fn(rt
->rt_ifp
, -1);
2026 rt
->rt_ifp
= lo_ifp
; /* XXX */
2028 * Make sure rt_ifa be equal to the ifaddr
2029 * corresponding to the address.
2030 * We need this because when we refer
2031 * rt_ifa->ia6_flags in ip6_input, we assume
2032 * that the rt_ifa points to the address instead
2033 * of the loopback address.
2035 if (ifa
!= rt
->rt_ifa
) {
2040 } else if (rt
->rt_flags
& RTF_ANNOUNCE
) {
2042 ln
->ln_state
= ND6_LLINFO_REACHABLE
;
2045 /* join solicited node multicast for proxy ND */
2046 if (ifp
->if_flags
& IFF_MULTICAST
) {
2047 struct in6_addr llsol
;
2048 struct in6_multi
*in6m
;
2051 llsol
= SIN6(rt_key(rt
))->sin6_addr
;
2052 llsol
.s6_addr32
[0] = IPV6_ADDR_INT32_MLL
;
2053 llsol
.s6_addr32
[1] = 0;
2054 llsol
.s6_addr32
[2] = htonl(1);
2055 llsol
.s6_addr8
[12] = 0xff;
2056 if (in6_setscope(&llsol
, ifp
, NULL
))
2058 error
= in6_mc_join(ifp
, &llsol
, NULL
, &in6m
, 0);
2060 nd6log((LOG_ERR
, "%s: failed to join "
2061 "%s (errno=%d)\n", if_name(ifp
),
2062 ip6_sprintf(&llsol
), error
));
2073 /* leave from solicited node multicast for proxy ND */
2074 if ((rt
->rt_flags
& RTF_ANNOUNCE
) != 0 &&
2075 (ifp
->if_flags
& IFF_MULTICAST
) != 0) {
2076 struct in6_addr llsol
;
2077 struct in6_multi
*in6m
;
2079 llsol
= SIN6(rt_key(rt
))->sin6_addr
;
2080 llsol
.s6_addr32
[0] = IPV6_ADDR_INT32_MLL
;
2081 llsol
.s6_addr32
[1] = 0;
2082 llsol
.s6_addr32
[2] = htonl(1);
2083 llsol
.s6_addr8
[12] = 0xff;
2084 if (in6_setscope(&llsol
, ifp
, NULL
) == 0) {
2085 in6_multihead_lock_shared();
2086 IN6_LOOKUP_MULTI(&llsol
, ifp
, in6m
);
2087 in6_multihead_lock_done();
2089 in6_mc_leave(in6m
, NULL
);
2096 * Unchain it but defer the actual freeing until the route
2097 * itself is to be freed. rt->rt_llinfo still points to
2098 * llinfo_nd6, and likewise, ln->ln_rt stil points to this
2099 * route entry, except that RTF_LLINFO is now cleared.
2101 if (ln
->ln_flags
& ND6_LNF_IN_USE
)
2105 * Purge any link-layer info caching.
2107 if (rt
->rt_llinfo_purge
!= NULL
)
2108 rt
->rt_llinfo_purge(rt
);
2110 rt
->rt_flags
&= ~RTF_LLINFO
;
2111 if (ln
->ln_hold
!= NULL
) {
2112 m_freem(ln
->ln_hold
);
2119 nd6_siocgdrlst(void *data
, int data_is_64
)
2121 struct in6_drlist_32
*drl_32
;
2122 struct nd_defrouter
*dr
;
2125 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2127 dr
= TAILQ_FIRST(&nd_defrouter
);
2129 /* For 64-bit process */
2131 struct in6_drlist_64
*drl_64
;
2133 drl_64
= _MALLOC(sizeof (*drl_64
), M_TEMP
, M_WAITOK
|M_ZERO
);
2137 /* preserve the interface name */
2138 bcopy(data
, drl_64
, sizeof (drl_64
->ifname
));
2140 while (dr
&& i
< DRLSTSIZ
) {
2141 drl_64
->defrouter
[i
].rtaddr
= dr
->rtaddr
;
2142 if (IN6_IS_ADDR_LINKLOCAL(&drl_64
->defrouter
[i
].rtaddr
)) {
2143 /* XXX: need to this hack for KAME stack */
2144 drl_64
->defrouter
[i
].rtaddr
.s6_addr16
[1] = 0;
2147 "default router list contains a "
2148 "non-linklocal address(%s)\n",
2149 ip6_sprintf(&drl_64
->defrouter
[i
].rtaddr
));
2151 drl_64
->defrouter
[i
].flags
= dr
->flags
;
2152 drl_64
->defrouter
[i
].rtlifetime
= dr
->rtlifetime
;
2153 drl_64
->defrouter
[i
].expire
= dr
->expire
;
2154 drl_64
->defrouter
[i
].if_index
= dr
->ifp
->if_index
;
2156 dr
= TAILQ_NEXT(dr
, dr_entry
);
2158 bcopy(drl_64
, data
, sizeof (*drl_64
));
2159 _FREE(drl_64
, M_TEMP
);
2163 /* For 32-bit process */
2164 drl_32
= _MALLOC(sizeof (*drl_32
), M_TEMP
, M_WAITOK
|M_ZERO
);
2168 /* preserve the interface name */
2169 bcopy(data
, drl_32
, sizeof (drl_32
->ifname
));
2171 while (dr
&& i
< DRLSTSIZ
) {
2172 drl_32
->defrouter
[i
].rtaddr
= dr
->rtaddr
;
2173 if (IN6_IS_ADDR_LINKLOCAL(&drl_32
->defrouter
[i
].rtaddr
)) {
2174 /* XXX: need to this hack for KAME stack */
2175 drl_32
->defrouter
[i
].rtaddr
.s6_addr16
[1] = 0;
2178 "default router list contains a "
2179 "non-linklocal address(%s)\n",
2180 ip6_sprintf(&drl_32
->defrouter
[i
].rtaddr
));
2182 drl_32
->defrouter
[i
].flags
= dr
->flags
;
2183 drl_32
->defrouter
[i
].rtlifetime
= dr
->rtlifetime
;
2184 drl_32
->defrouter
[i
].expire
= dr
->expire
;
2185 drl_32
->defrouter
[i
].if_index
= dr
->ifp
->if_index
;
2187 dr
= TAILQ_NEXT(dr
, dr_entry
);
2189 bcopy(drl_32
, data
, sizeof (*drl_32
));
2190 _FREE(drl_32
, M_TEMP
);
2195 * XXX meaning of fields, especialy "raflags", is very
2196 * differnet between RA prefix list and RR/static prefix list.
2197 * how about separating ioctls into two?
2200 nd6_siocgprlst(void *data
, int data_is_64
)
2202 struct in6_prlist_32
*prl_32
;
2203 struct nd_prefix
*pr
;
2206 lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
);
2208 pr
= nd_prefix
.lh_first
;
2210 /* For 64-bit process */
2212 struct in6_prlist_64
*prl_64
;
2214 prl_64
= _MALLOC(sizeof (*prl_64
), M_TEMP
, M_WAITOK
|M_ZERO
);
2218 /* preserve the interface name */
2219 bcopy(data
, prl_64
, sizeof (prl_64
->ifname
));
2221 while (pr
&& i
< PRLSTSIZ
) {
2222 struct nd_pfxrouter
*pfr
;
2226 (void) in6_embedscope(&prl_64
->prefix
[i
].prefix
,
2227 &pr
->ndpr_prefix
, NULL
, NULL
, NULL
);
2228 prl_64
->prefix
[i
].raflags
= pr
->ndpr_raf
;
2229 prl_64
->prefix
[i
].prefixlen
= pr
->ndpr_plen
;
2230 prl_64
->prefix
[i
].vltime
= pr
->ndpr_vltime
;
2231 prl_64
->prefix
[i
].pltime
= pr
->ndpr_pltime
;
2232 prl_64
->prefix
[i
].if_index
= pr
->ndpr_ifp
->if_index
;
2233 prl_64
->prefix
[i
].expire
= pr
->ndpr_expire
;
2235 pfr
= pr
->ndpr_advrtrs
.lh_first
;
2239 #define RTRADDR prl_64->prefix[i].advrtr[j]
2240 RTRADDR
= pfr
->router
->rtaddr
;
2241 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR
)) {
2242 /* XXX: hack for KAME */
2243 RTRADDR
.s6_addr16
[1] = 0;
2246 "a router(%s) advertises "
2248 "non-link local address\n",
2249 ip6_sprintf(&RTRADDR
));
2254 pfr
= pfr
->pfr_next
;
2256 prl_64
->prefix
[i
].advrtrs
= j
;
2257 prl_64
->prefix
[i
].origin
= PR_ORIG_RA
;
2263 bcopy(prl_64
, data
, sizeof (*prl_64
));
2264 _FREE(prl_64
, M_TEMP
);
2268 /* For 32-bit process */
2269 prl_32
= _MALLOC(sizeof (*prl_32
), M_TEMP
, M_WAITOK
|M_ZERO
);
2273 /* preserve the interface name */
2274 bcopy(data
, prl_32
, sizeof (prl_32
->ifname
));
2276 while (pr
&& i
< PRLSTSIZ
) {
2277 struct nd_pfxrouter
*pfr
;
2281 (void) in6_embedscope(&prl_32
->prefix
[i
].prefix
,
2282 &pr
->ndpr_prefix
, NULL
, NULL
, NULL
);
2283 prl_32
->prefix
[i
].raflags
= pr
->ndpr_raf
;
2284 prl_32
->prefix
[i
].prefixlen
= pr
->ndpr_plen
;
2285 prl_32
->prefix
[i
].vltime
= pr
->ndpr_vltime
;
2286 prl_32
->prefix
[i
].pltime
= pr
->ndpr_pltime
;
2287 prl_32
->prefix
[i
].if_index
= pr
->ndpr_ifp
->if_index
;
2288 prl_32
->prefix
[i
].expire
= pr
->ndpr_expire
;
2290 pfr
= pr
->ndpr_advrtrs
.lh_first
;
2294 #define RTRADDR prl_32->prefix[i].advrtr[j]
2295 RTRADDR
= pfr
->router
->rtaddr
;
2296 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR
)) {
2297 /* XXX: hack for KAME */
2298 RTRADDR
.s6_addr16
[1] = 0;
2301 "a router(%s) advertises "
2303 "non-link local address\n",
2304 ip6_sprintf(&RTRADDR
));
2309 pfr
= pfr
->pfr_next
;
2311 prl_32
->prefix
[i
].advrtrs
= j
;
2312 prl_32
->prefix
[i
].origin
= PR_ORIG_RA
;
2318 bcopy(prl_32
, data
, sizeof (*prl_32
));
2319 _FREE(prl_32
, M_TEMP
);
2324 nd6_ioctl(u_long cmd
, caddr_t data
, struct ifnet
*ifp
)
2326 struct nd_defrouter
*dr
;
2327 struct nd_prefix
*pr
;
2329 int i
= ifp
->if_index
, error
= 0;
2332 case SIOCGDRLST_IN6_32
: /* struct in6_drlist_32 */
2333 case SIOCGDRLST_IN6_64
: /* struct in6_drlist_64 */
2335 * obsolete API, use sysctl under net.inet6.icmp6
2337 lck_mtx_lock(nd6_mutex
);
2338 error
= nd6_siocgdrlst(data
, cmd
== SIOCGDRLST_IN6_64
);
2339 lck_mtx_unlock(nd6_mutex
);
2342 case SIOCGPRLST_IN6_32
: /* struct in6_prlist_32 */
2343 case SIOCGPRLST_IN6_64
: /* struct in6_prlist_64 */
2345 * obsolete API, use sysctl under net.inet6.icmp6
2347 lck_mtx_lock(nd6_mutex
);
2348 error
= nd6_siocgprlst(data
, cmd
== SIOCGPRLST_IN6_64
);
2349 lck_mtx_unlock(nd6_mutex
);
2352 case OSIOCGIFINFO_IN6
: /* struct in6_ondireq */
2353 case SIOCGIFINFO_IN6
: { /* struct in6_ondireq */
2355 struct in6_ondireq
*ondi
= (struct in6_ondireq
*)(void *)data
;
2356 struct nd_ifinfo
*ndi
;
2358 * SIOCGIFINFO_IN6 ioctl is encoded with in6_ondireq
2359 * instead of in6_ndireq, so we treat it as such.
2361 lck_rw_lock_shared(nd_if_rwlock
);
2362 ndi
= ND_IFINFO(ifp
);
2363 if (!nd_ifinfo
|| i
>= nd_ifinfo_indexlim
||
2364 !ndi
->initialized
) {
2365 lck_rw_done(nd_if_rwlock
);
2369 lck_mtx_lock(&ndi
->lock
);
2370 linkmtu
= IN6_LINKMTU(ifp
);
2371 bcopy(&linkmtu
, &ondi
->ndi
.linkmtu
, sizeof (linkmtu
));
2372 bcopy(&nd_ifinfo
[i
].maxmtu
, &ondi
->ndi
.maxmtu
,
2373 sizeof (u_int32_t
));
2374 bcopy(&nd_ifinfo
[i
].basereachable
, &ondi
->ndi
.basereachable
,
2375 sizeof (u_int32_t
));
2376 bcopy(&nd_ifinfo
[i
].reachable
, &ondi
->ndi
.reachable
,
2377 sizeof (u_int32_t
));
2378 bcopy(&nd_ifinfo
[i
].retrans
, &ondi
->ndi
.retrans
,
2379 sizeof (u_int32_t
));
2380 bcopy(&nd_ifinfo
[i
].flags
, &ondi
->ndi
.flags
,
2381 sizeof (u_int32_t
));
2382 bcopy(&nd_ifinfo
[i
].recalctm
, &ondi
->ndi
.recalctm
,
2384 ondi
->ndi
.chlim
= nd_ifinfo
[i
].chlim
;
2385 ondi
->ndi
.receivedra
= 0;
2386 lck_mtx_unlock(&ndi
->lock
);
2387 lck_rw_done(nd_if_rwlock
);
2391 case SIOCSIFINFO_FLAGS
: { /* struct in6_ndireq */
2392 struct in6_ndireq
*cndi
= (struct in6_ndireq
*)(void *)data
;
2393 u_int32_t oflags
, flags
;
2394 struct nd_ifinfo
*ndi
;
2396 /* XXX: almost all other fields of cndi->ndi is unused */
2397 lck_rw_lock_shared(nd_if_rwlock
);
2398 ndi
= ND_IFINFO(ifp
);
2399 if (!nd_ifinfo
|| i
>= nd_ifinfo_indexlim
||
2400 !ndi
->initialized
) {
2401 lck_rw_done(nd_if_rwlock
);
2405 lck_mtx_lock(&ndi
->lock
);
2406 oflags
= nd_ifinfo
[i
].flags
;
2407 bcopy(&cndi
->ndi
.flags
, &nd_ifinfo
[i
].flags
, sizeof (flags
));
2408 flags
= nd_ifinfo
[i
].flags
;
2409 lck_mtx_unlock(&ndi
->lock
);
2410 lck_rw_done(nd_if_rwlock
);
2412 if (oflags
== flags
)
2415 error
= nd6_setifinfo(ifp
, oflags
, flags
);
2419 case SIOCSNDFLUSH_IN6
: /* struct in6_ifreq */
2420 /* flush default router list */
2422 * xxx sumikawa: should not delete route if default
2423 * route equals to the top of default router list
2425 lck_mtx_lock(nd6_mutex
);
2427 defrouter_select(ifp
);
2428 lck_mtx_unlock(nd6_mutex
);
2429 /* xxx sumikawa: flush prefix list */
2432 case SIOCSPFXFLUSH_IN6
: { /* struct in6_ifreq */
2433 /* flush all the prefix advertised by routers */
2434 struct nd_prefix
*next
;
2436 lck_mtx_lock(nd6_mutex
);
2437 for (pr
= nd_prefix
.lh_first
; pr
; pr
= next
) {
2438 struct in6_ifaddr
*ia
;
2440 next
= pr
->ndpr_next
;
2443 if (IN6_IS_ADDR_LINKLOCAL(&pr
->ndpr_prefix
.sin6_addr
)) {
2447 if (ifp
!= lo_ifp
&& pr
->ndpr_ifp
!= ifp
) {
2451 /* do we really have to remove addresses as well? */
2452 NDPR_ADDREF_LOCKED(pr
);
2454 lck_rw_lock_exclusive(&in6_ifaddr_rwlock
);
2456 while (ia
!= NULL
) {
2457 IFA_LOCK(&ia
->ia_ifa
);
2458 if ((ia
->ia6_flags
& IN6_IFF_AUTOCONF
) == 0) {
2459 IFA_UNLOCK(&ia
->ia_ifa
);
2464 if (ia
->ia6_ndpr
== pr
) {
2465 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
2466 IFA_UNLOCK(&ia
->ia_ifa
);
2467 lck_rw_done(&in6_ifaddr_rwlock
);
2468 lck_mtx_unlock(nd6_mutex
);
2469 in6_purgeaddr(&ia
->ia_ifa
);
2470 IFA_REMREF(&ia
->ia_ifa
);
2471 lck_mtx_lock(nd6_mutex
);
2472 lck_rw_lock_exclusive(&in6_ifaddr_rwlock
);
2474 * Purging the address caused
2475 * in6_ifaddr_rwlock to be
2477 * reacquired; therefore search again
2478 * from the beginning of in6_ifaddrs.
2479 * The same applies for the prefix list.
2482 next
= nd_prefix
.lh_first
;
2486 IFA_UNLOCK(&ia
->ia_ifa
);
2489 lck_rw_done(&in6_ifaddr_rwlock
);
2494 * If we were trying to restart this loop
2495 * above by changing the value of 'next', we might
2496 * end up freeing the only element on the list
2497 * when we call NDPR_REMREF().
2498 * When this happens, we also have get out of this
2499 * loop because we have nothing else to do.
2505 lck_mtx_unlock(nd6_mutex
);
2509 case SIOCSRTRFLUSH_IN6
: { /* struct in6_ifreq */
2510 /* flush all the default routers */
2511 struct nd_defrouter
*next
;
2513 lck_mtx_lock(nd6_mutex
);
2514 if ((dr
= TAILQ_FIRST(&nd_defrouter
)) != NULL
) {
2516 * The first entry of the list may be stored in
2517 * the routing table, so we'll delete it later.
2519 for (dr
= TAILQ_NEXT(dr
, dr_entry
); dr
; dr
= next
) {
2520 next
= TAILQ_NEXT(dr
, dr_entry
);
2521 if (ifp
== lo_ifp
|| dr
->ifp
== ifp
)
2524 if (ifp
== lo_ifp
||
2525 TAILQ_FIRST(&nd_defrouter
)->ifp
== ifp
)
2526 defrtrlist_del(TAILQ_FIRST(&nd_defrouter
));
2528 lck_mtx_unlock(nd6_mutex
);
2532 case SIOCGNBRINFO_IN6_32
: { /* struct in6_nbrinfo_32 */
2533 struct llinfo_nd6
*ln
;
2534 struct in6_nbrinfo_32 nbi_32
;
2535 struct in6_addr nb_addr
; /* make local for safety */
2537 bcopy(data
, &nbi_32
, sizeof (nbi_32
));
2538 nb_addr
= nbi_32
.addr
;
2540 * XXX: KAME specific hack for scoped addresses
2541 * XXXX: for other scopes than link-local?
2543 if (IN6_IS_ADDR_LINKLOCAL(&nbi_32
.addr
) ||
2544 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_32
.addr
)) {
2546 (u_int16_t
*)(void *)&nb_addr
.s6_addr
[2];
2549 *idp
= htons(ifp
->if_index
);
2552 /* Callee returns a locked route upon success */
2553 if ((rt
= nd6_lookup(&nb_addr
, 0, ifp
, 0)) == NULL
) {
2557 RT_LOCK_ASSERT_HELD(rt
);
2559 nbi_32
.state
= ln
->ln_state
;
2560 nbi_32
.asked
= ln
->ln_asked
;
2561 nbi_32
.isrouter
= ln
->ln_router
;
2562 nbi_32
.expire
= ln
->ln_expire
;
2563 RT_REMREF_LOCKED(rt
);
2565 bcopy(&nbi_32
, data
, sizeof (nbi_32
));
2569 case SIOCGNBRINFO_IN6_64
: { /* struct in6_nbrinfo_64 */
2570 struct llinfo_nd6
*ln
;
2571 struct in6_nbrinfo_64 nbi_64
;
2572 struct in6_addr nb_addr
; /* make local for safety */
2574 bcopy(data
, &nbi_64
, sizeof (nbi_64
));
2575 nb_addr
= nbi_64
.addr
;
2577 * XXX: KAME specific hack for scoped addresses
2578 * XXXX: for other scopes than link-local?
2580 if (IN6_IS_ADDR_LINKLOCAL(&nbi_64
.addr
) ||
2581 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_64
.addr
)) {
2583 (u_int16_t
*)(void *)&nb_addr
.s6_addr
[2];
2586 *idp
= htons(ifp
->if_index
);
2589 /* Callee returns a locked route upon success */
2590 if ((rt
= nd6_lookup(&nb_addr
, 0, ifp
, 0)) == NULL
) {
2594 RT_LOCK_ASSERT_HELD(rt
);
2596 nbi_64
.state
= ln
->ln_state
;
2597 nbi_64
.asked
= ln
->ln_asked
;
2598 nbi_64
.isrouter
= ln
->ln_router
;
2599 nbi_64
.expire
= ln
->ln_expire
;
2600 RT_REMREF_LOCKED(rt
);
2602 bcopy(&nbi_64
, data
, sizeof (nbi_64
));
2606 case SIOCGDEFIFACE_IN6_32
: /* struct in6_ndifreq_32 */
2607 case SIOCGDEFIFACE_IN6_64
: { /* struct in6_ndifreq_64 */
2608 struct in6_ndifreq_64
*ndif_64
=
2609 (struct in6_ndifreq_64
*)(void *)data
;
2610 struct in6_ndifreq_32
*ndif_32
=
2611 (struct in6_ndifreq_32
*)(void *)data
;
2613 if (cmd
== SIOCGDEFIFACE_IN6_64
) {
2614 u_int64_t j
= nd6_defifindex
;
2615 bcopy(&j
, &ndif_64
->ifindex
, sizeof (j
));
2617 bcopy(&nd6_defifindex
, &ndif_32
->ifindex
,
2618 sizeof (u_int32_t
));
2623 case SIOCSDEFIFACE_IN6_32
: /* struct in6_ndifreq_32 */
2624 case SIOCSDEFIFACE_IN6_64
: { /* struct in6_ndifreq_64 */
2625 struct in6_ndifreq_64
*ndif_64
=
2626 (struct in6_ndifreq_64
*)(void *)data
;
2627 struct in6_ndifreq_32
*ndif_32
=
2628 (struct in6_ndifreq_32
*)(void *)data
;
2631 if (cmd
== SIOCSDEFIFACE_IN6_64
) {
2633 bcopy(&ndif_64
->ifindex
, &j
, sizeof (j
));
2636 bcopy(&ndif_32
->ifindex
, &idx
, sizeof (idx
));
2639 error
= nd6_setdefaultiface(idx
);
2648 * Create neighbor cache entry and cache link-layer address,
2649 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
2654 struct in6_addr
*from
,
2656 __unused
int lladdrlen
,
2657 int type
, /* ICMP6 type */
2658 int code
) /* type dependent information */
2660 struct rtentry
*rt
= NULL
;
2661 struct llinfo_nd6
*ln
= NULL
;
2663 struct sockaddr_dl
*sdl
= NULL
;
2668 struct timeval timenow
;
2671 panic("ifp == NULL in nd6_cache_lladdr");
2673 panic("from == NULL in nd6_cache_lladdr");
2675 /* nothing must be updated for unspecified address */
2676 if (IN6_IS_ADDR_UNSPECIFIED(from
))
2680 * Validation about ifp->if_addrlen and lladdrlen must be done in
2683 * XXX If the link does not have link-layer adderss, what should
2684 * we do? (ifp->if_addrlen == 0)
2685 * Spec says nothing in sections for RA, RS and NA. There's small
2686 * description on it in NS section (RFC 2461 7.2.3).
2688 getmicrotime(&timenow
);
2690 rt
= nd6_lookup(from
, 0, ifp
, 0);
2692 if ((rt
= nd6_lookup(from
, 1, ifp
, 0)) == NULL
)
2694 RT_LOCK_ASSERT_HELD(rt
);
2697 RT_LOCK_ASSERT_HELD(rt
);
2698 /* do nothing if static ndp is set */
2699 if (rt
->rt_flags
& RTF_STATIC
) {
2700 RT_REMREF_LOCKED(rt
);
2709 if ((rt
->rt_flags
& (RTF_GATEWAY
| RTF_LLINFO
)) != RTF_LLINFO
) {
2716 ln
= (struct llinfo_nd6
*)rt
->rt_llinfo
;
2719 if (rt
->rt_gateway
== NULL
)
2721 if (rt
->rt_gateway
->sa_family
!= AF_LINK
)
2723 sdl
= SDL(rt
->rt_gateway
);
2725 olladdr
= (sdl
->sdl_alen
) ? 1 : 0;
2726 if (olladdr
&& lladdr
) {
2727 if (bcmp(lladdr
, LLADDR(sdl
), ifp
->if_addrlen
))
2735 * newentry olladdr lladdr llchange (*=record)
2738 * 0 n y -- (3) * STALE
2740 * 0 y y y (5) * STALE
2741 * 1 -- n -- (6) NOSTATE(= PASSIVE)
2742 * 1 -- y -- (7) * STALE
2745 if (lladdr
) { /* (3-5) and (7) */
2747 * Record source link-layer address
2748 * XXX is it dependent to ifp->if_type?
2750 sdl
->sdl_alen
= ifp
->if_addrlen
;
2751 bcopy(lladdr
, LLADDR(sdl
), ifp
->if_addrlen
);
2753 /* cache the gateway (sender HW) address */
2754 nd6_llreach_alloc(rt
, ifp
, LLADDR(sdl
), sdl
->sdl_alen
, FALSE
);
2758 if ((!olladdr
&& lladdr
!= NULL
) || /* (3) */
2759 (olladdr
&& lladdr
!= NULL
&& llchange
)) { /* (5) */
2761 newstate
= ND6_LLINFO_STALE
;
2762 } else /* (1-2,4) */
2766 if (lladdr
== NULL
) /* (6) */
2767 newstate
= ND6_LLINFO_NOSTATE
;
2769 newstate
= ND6_LLINFO_STALE
;
2774 * Update the state of the neighbor cache.
2776 ln
->ln_state
= newstate
;
2778 if (ln
->ln_state
== ND6_LLINFO_STALE
) {
2779 struct mbuf
*m
= ln
->ln_hold
;
2781 * XXX: since nd6_output() below will cause
2782 * state tansition to DELAY and reset the timer,
2783 * we must set the timer now, although it is actually
2786 ln
->ln_expire
= timenow
.tv_sec
+ nd6_gctimer
;
2790 struct sockaddr_in6 sin6
;
2792 rtkey_to_sa6(rt
, &sin6
);
2794 * we assume ifp is not a p2p here, so just
2795 * set the 2nd argument as the 1st one.
2798 nd6_output(ifp
, ifp
, m
, &sin6
, rt
, NULL
);
2801 } else if (ln
->ln_state
== ND6_LLINFO_INCOMPLETE
) {
2802 /* probe right away */
2803 ln
->ln_expire
= timenow
.tv_sec
;
2808 * ICMP6 type dependent behavior.
2810 * NS: clear IsRouter if new entry
2811 * RS: clear IsRouter
2812 * RA: set IsRouter if there's lladdr
2813 * redir: clear IsRouter if new entry
2816 * The spec says that we must set IsRouter in the following cases:
2817 * - If lladdr exist, set IsRouter. This means (1-5).
2818 * - If it is old entry (!newentry), set IsRouter. This means (7).
2819 * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
2820 * A quetion arises for (1) case. (1) case has no lladdr in the
2821 * neighbor cache, this is similar to (6).
2822 * This case is rare but we figured that we MUST NOT set IsRouter.
2824 * newentry olladdr lladdr llchange NS RS RA redir
2826 * 0 n n -- (1) c ? s
2827 * 0 y n -- (2) c s s
2828 * 0 n y -- (3) c s s
2831 * 1 -- n -- (6) c c c s
2832 * 1 -- y -- (7) c c s c s
2836 switch (type
& 0xff) {
2837 case ND_NEIGHBOR_SOLICIT
:
2839 * New entry must have is_router flag cleared.
2841 if (is_newentry
) /* (6-7) */
2846 * If the icmp is a redirect to a better router, always set the
2847 * is_router flag. Otherwise, if the entry is newly created,
2848 * clear the flag. [RFC 2461, sec 8.3]
2850 if (code
== ND_REDIRECT_ROUTER
)
2852 else if (is_newentry
) /* (6-7) */
2855 case ND_ROUTER_SOLICIT
:
2857 * is_router flag must always be cleared.
2861 case ND_ROUTER_ADVERT
:
2863 * Mark an entry with lladdr as a router.
2865 if ((!is_newentry
&& (olladdr
|| lladdr
)) || /* (2-5) */
2866 (is_newentry
&& lladdr
)) { /* (7) */
2873 * When the link-layer address of a router changes, select the
2874 * best router again. In particular, when the neighbor entry is newly
2875 * created, it might affect the selection policy.
2876 * Question: can we restrict the first condition to the "is_newentry"
2879 * Note: Perform default router selection even when we are a router,
2880 * if Scoped Routing is enabled.
2882 if (do_update
&& ln
->ln_router
&&
2883 (ip6_doscopedroute
|| !ip6_forwarding
)) {
2884 RT_REMREF_LOCKED(rt
);
2886 lck_mtx_lock(nd6_mutex
);
2887 defrouter_select(ifp
);
2888 lck_mtx_unlock(nd6_mutex
);
2890 RT_REMREF_LOCKED(rt
);
2897 __unused
void *ignored_arg
)
2900 struct nd_ifinfo
*nd6if
;
2902 lck_rw_lock_shared(nd_if_rwlock
);
2903 for (i
= 1; i
< if_index
+ 1; i
++) {
2904 if (!nd_ifinfo
|| i
>= nd_ifinfo_indexlim
)
2906 nd6if
= &nd_ifinfo
[i
];
2907 if (!nd6if
->initialized
)
2909 lck_mtx_lock(&nd6if
->lock
);
2910 if (nd6if
->basereachable
&& /* already initialized */
2911 (nd6if
->recalctm
-= ND6_SLOWTIMER_INTERVAL
) <= 0) {
2913 * Since reachable time rarely changes by router
2914 * advertisements, we SHOULD insure that a new random
2915 * value gets recomputed at least once every few hours.
2918 nd6if
->recalctm
= nd6_recalc_reachtm_interval
;
2919 nd6if
->reachable
= ND_COMPUTE_RTIME(nd6if
->basereachable
);
2921 lck_mtx_unlock(&nd6if
->lock
);
2923 lck_rw_done(nd_if_rwlock
);
2924 timeout(nd6_slowtimo
, (caddr_t
)0, ND6_SLOWTIMER_INTERVAL
* hz
);
2927 #define senderr(e) { error = (e); goto bad;}
2929 nd6_output(struct ifnet
*ifp
, struct ifnet
*origifp
, struct mbuf
*m0
,
2930 struct sockaddr_in6
*dst
, struct rtentry
*hint0
, struct flowadv
*adv
)
2932 struct mbuf
*m
= m0
;
2933 struct rtentry
*rt
= hint0
, *hint
= hint0
;
2934 struct llinfo_nd6
*ln
= NULL
;
2936 struct timeval timenow
;
2937 struct rtentry
*rtrele
= NULL
;
2938 struct nd_ifinfo
*ndi
;
2942 RT_ADDREF_LOCKED(rt
);
2945 if (IN6_IS_ADDR_MULTICAST(&dst
->sin6_addr
) || !nd6_need_cache(ifp
)) {
2952 * Next hop determination. Because we may involve the gateway route
2953 * in addition to the original route, locking is rather complicated.
2954 * The general concept is that regardless of whether the route points
2955 * to the original route or to the gateway route, this routine takes
2956 * an extra reference on such a route. This extra reference will be
2957 * released at the end.
2959 * Care must be taken to ensure that the "hint0" route never gets freed
2960 * via rtfree(), since the caller may have stored it inside a struct
2961 * route with a reference held for that placeholder.
2963 * This logic is similar to, though not exactly the same as the one
2964 * used by route_to_gwroute().
2968 * We have a reference to "rt" by now (or below via rtalloc1),
2969 * which will either be released or freed at the end of this
2972 RT_LOCK_ASSERT_HELD(rt
);
2973 if (!(rt
->rt_flags
& RTF_UP
)) {
2974 RT_REMREF_LOCKED(rt
);
2976 if ((hint
= rt
= rtalloc1_scoped((struct sockaddr
*)dst
,
2977 1, 0, ifp
->if_index
)) != NULL
) {
2979 if (rt
->rt_ifp
!= ifp
) {
2980 /* XXX: loop care? */
2982 error
= nd6_output(ifp
, origifp
, m0
,
2988 senderr(EHOSTUNREACH
);
2992 if (rt
->rt_flags
& RTF_GATEWAY
) {
2993 struct rtentry
*gwrt
;
2994 struct in6_ifaddr
*ia6
= NULL
;
2995 struct sockaddr_in6 gw6
;
2997 rtgw_to_sa6(rt
, &gw6
);
2999 * Must drop rt_lock since nd6_is_addr_neighbor()
3000 * calls nd6_lookup() and acquires rnh_lock.
3005 * We skip link-layer address resolution and NUD
3006 * if the gateway is not a neighbor from ND point
3007 * of view, regardless of the value of nd_ifinfo.flags.
3008 * The second condition is a bit tricky; we skip
3009 * if the gateway is our own address, which is
3010 * sometimes used to install a route to a p2p link.
3012 if (!nd6_is_addr_neighbor(&gw6
, ifp
, 0) ||
3013 (ia6
= in6ifa_ifpwithaddr(ifp
, &gw6
.sin6_addr
))) {
3015 * We allow this kind of tricky route only
3016 * when the outgoing interface is p2p.
3017 * XXX: we may need a more generic rule here.
3020 IFA_REMREF(&ia6
->ia_ifa
);
3021 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0)
3022 senderr(EHOSTUNREACH
);
3027 gw6
= *((struct sockaddr_in6
*)(void *)rt
->rt_gateway
);
3029 /* If hint is now down, give up */
3030 if (!(rt
->rt_flags
& RTF_UP
)) {
3032 senderr(EHOSTUNREACH
);
3035 /* If there's no gateway route, look it up */
3036 if ((gwrt
= rt
->rt_gwroute
) == NULL
) {
3040 /* Become a regular mutex */
3041 RT_CONVERT_LOCK(rt
);
3044 * Take gwrt's lock while holding route's lock;
3045 * this is okay since gwrt never points back
3046 * to rt, so no lock ordering issues.
3049 if (!(gwrt
->rt_flags
& RTF_UP
)) {
3050 rt
->rt_gwroute
= NULL
;
3055 lck_mtx_lock(rnh_lock
);
3056 gwrt
= rtalloc1_scoped_locked(
3057 (struct sockaddr
*)&gw6
, 1, 0,
3062 * Bail out if the route is down, no route
3063 * to gateway, circular route, or if the
3064 * gateway portion of "rt" has changed.
3066 if (!(rt
->rt_flags
& RTF_UP
) ||
3067 gwrt
== NULL
|| gwrt
== rt
||
3068 !equal(SA(&gw6
), rt
->rt_gateway
)) {
3070 RT_REMREF_LOCKED(gwrt
);
3075 rtfree_locked(gwrt
);
3076 lck_mtx_unlock(rnh_lock
);
3077 senderr(EHOSTUNREACH
);
3079 VERIFY(gwrt
!= NULL
);
3081 * Set gateway route; callee adds ref to gwrt;
3082 * gwrt has an extra ref from rtalloc1() for
3085 rt_set_gwroute(rt
, rt_key(rt
), gwrt
);
3087 lck_mtx_unlock(rnh_lock
);
3088 /* Remember to release/free "rt" at the end */
3092 RT_ADDREF_LOCKED(gwrt
);
3095 /* Remember to release/free "rt" at the end */
3102 * This is an opportunity to revalidate the parent
3103 * route's gwroute, in case it now points to a dead
3104 * route entry. Parent route won't go away since the
3105 * clone (hint) holds a reference to it. rt == gwrt.
3108 if ((hint
->rt_flags
& (RTF_WASCLONED
| RTF_UP
)) ==
3109 (RTF_WASCLONED
| RTF_UP
)) {
3110 struct rtentry
*prt
= hint
->rt_parent
;
3111 VERIFY(prt
!= NULL
);
3113 RT_CONVERT_LOCK(hint
);
3116 rt_revalidate_gwroute(prt
, rt
);
3123 /* rt == gwrt; if it is now down, give up */
3124 if (!(rt
->rt_flags
& RTF_UP
)) {
3128 /* "rtrele" == original "rt" */
3129 senderr(EHOSTUNREACH
);
3133 /* Become a regular mutex */
3134 RT_CONVERT_LOCK(rt
);
3138 * Address resolution or Neighbor Unreachability Detection
3140 * At this point, the destination of the packet must be a unicast
3141 * or an anycast address(i.e. not a multicast).
3144 /* Look up the neighbor cache for the nexthop */
3145 if (rt
&& (rt
->rt_flags
& RTF_LLINFO
) != 0) {
3148 struct sockaddr_in6 sin6
;
3150 * Clear out Scope ID field in case it is set.
3153 sin6
.sin6_scope_id
= 0;
3155 * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
3156 * the condition below is not very efficient. But we believe
3157 * it is tolerable, because this should be a rare case.
3158 * Must drop rt_lock since nd6_is_addr_neighbor() calls
3159 * nd6_lookup() and acquires rnh_lock.
3163 if (nd6_is_addr_neighbor(&sin6
, ifp
, 0)) {
3164 /* "rtrele" may have been used, so clean up "rt" now */
3166 /* Don't free "hint0" */
3172 /* Callee returns a locked route upon success */
3173 rt
= nd6_lookup(&dst
->sin6_addr
, 1, ifp
, 0);
3175 RT_LOCK_ASSERT_HELD(rt
);
3178 } else if (rt
!= NULL
) {
3186 lck_rw_lock_shared(nd_if_rwlock
);
3187 ndi
= ND_IFINFO(ifp
);
3188 VERIFY(ndi
!= NULL
&& ndi
->initialized
);
3189 lck_mtx_lock(&ndi
->lock
);
3190 if ((ifp
->if_flags
& IFF_POINTOPOINT
) == 0 &&
3191 !(ndi
->flags
& ND6_IFF_PERFORMNUD
)) {
3192 lck_mtx_unlock(&ndi
->lock
);
3193 lck_rw_done(nd_if_rwlock
);
3195 "nd6_output: can't allocate llinfo for %s "
3197 ip6_sprintf(&dst
->sin6_addr
), ln
, rt
);
3198 senderr(EIO
); /* XXX: good error? */
3200 lck_mtx_unlock(&ndi
->lock
);
3201 lck_rw_done(nd_if_rwlock
);
3203 goto sendpkt
; /* send anyway */
3206 getmicrotime(&timenow
);
3208 /* We don't have to do link-layer address resolution on a p2p link. */
3209 if ((ifp
->if_flags
& IFF_POINTOPOINT
) != 0 &&
3210 ln
->ln_state
< ND6_LLINFO_REACHABLE
) {
3211 ln
->ln_state
= ND6_LLINFO_STALE
;
3212 ln
->ln_expire
= rt_expiry(rt
, timenow
.tv_sec
, nd6_gctimer
);
3216 * The first time we send a packet to a neighbor whose entry is
3217 * STALE, we have to change the state to DELAY and a sets a timer to
3218 * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
3219 * neighbor unreachability detection on expiration.
3222 if (ln
->ln_state
== ND6_LLINFO_STALE
) {
3224 ln
->ln_state
= ND6_LLINFO_DELAY
;
3225 ln
->ln_expire
= rt_expiry(rt
, timenow
.tv_sec
, nd6_delay
);
3229 * If the neighbor cache entry has a state other than INCOMPLETE
3230 * (i.e. its link-layer address is already resolved), just
3233 if (ln
->ln_state
> ND6_LLINFO_INCOMPLETE
) {
3236 * Move this entry to the head of the queue so that it is
3237 * less likely for this entry to be a target of forced
3238 * garbage collection (see nd6_rtrequest()).
3240 lck_mtx_lock(rnh_lock
);
3242 if (ln
->ln_flags
& ND6_LNF_IN_USE
) {
3247 lck_mtx_unlock(rnh_lock
);
3252 * There is a neighbor cache entry, but no ethernet address
3253 * response yet. Replace the held mbuf (if any) with this
3256 * This code conforms to the rate-limiting rule described in Section
3257 * 7.2.2 of RFC 2461, because the timer is set correctly after sending
3260 if (ln
->ln_state
== ND6_LLINFO_NOSTATE
)
3261 ln
->ln_state
= ND6_LLINFO_INCOMPLETE
;
3263 m_freem(ln
->ln_hold
);
3265 if (ln
->ln_expire
&& ln
->ln_asked
< nd6_mmaxtries
&&
3266 ln
->ln_expire
< timenow
.tv_sec
) {
3268 lck_rw_lock_shared(nd_if_rwlock
);
3269 ndi
= ND_IFINFO(ifp
);
3270 VERIFY(ndi
!= NULL
&& ndi
->initialized
);
3271 lck_mtx_lock(&ndi
->lock
);
3272 ln
->ln_expire
= timenow
.tv_sec
+ ndi
->retrans
/ 1000;
3273 lck_mtx_unlock(&ndi
->lock
);
3274 lck_rw_done(nd_if_rwlock
);
3276 /* We still have a reference on rt (for ln) */
3278 nd6_prproxy_ns_output(ifp
, NULL
, &dst
->sin6_addr
, ln
);
3280 nd6_ns_output(ifp
, NULL
, &dst
->sin6_addr
, ln
, 0);
3285 * Move this entry to the head of the queue so that it is
3286 * less likely for this entry to be a target of forced
3287 * garbage collection (see nd6_rtrequest()).
3289 lck_mtx_lock(rnh_lock
);
3291 if (ln
->ln_flags
& ND6_LNF_IN_USE
) {
3295 /* Clean up "rt" now while we can */
3297 RT_REMREF_LOCKED(rt
);
3303 rt
= NULL
; /* "rt" has been taken care of */
3304 lck_mtx_unlock(rnh_lock
);
3311 RT_LOCK_ASSERT_NOTHELD(rt
);
3313 /* discard the packet if IPv6 operation is disabled on the interface */
3314 lck_rw_lock_shared(nd_if_rwlock
);
3315 ndi
= ND_IFINFO(ifp
);
3316 VERIFY(ndi
!= NULL
&& ndi
->initialized
);
3317 /* test is done here without holding ndi lock, for performance */
3318 if (ndi
->flags
& ND6_IFF_IFDISABLED
) {
3319 lck_rw_done(nd_if_rwlock
);
3320 error
= ENETDOWN
; /* better error? */
3323 lck_rw_done(nd_if_rwlock
);
3325 if ((ifp
->if_flags
& IFF_LOOPBACK
) != 0) {
3326 /* forwarding rules require the original scope_id */
3327 m
->m_pkthdr
.rcvif
= origifp
;
3328 error
= dlil_output(origifp
, PF_INET6
, m
, (caddr_t
)rt
,
3329 (struct sockaddr
*)dst
, 0, adv
);
3332 /* Do not allow loopback address to wind up on a wire */
3333 struct ip6_hdr
*ip6
= mtod(m
, struct ip6_hdr
*);
3335 if ((IN6_IS_ADDR_LOOPBACK(&ip6
->ip6_src
) ||
3336 IN6_IS_ADDR_LOOPBACK(&ip6
->ip6_dst
))) {
3337 ip6stat
.ip6s_badscope
++;
3339 * Do not simply drop the packet just like a
3340 * firewall -- we want the the application to feel
3341 * the pain. Return ENETUNREACH like ip6_output
3342 * does in some similar cases. This can startle
3343 * the otherwise clueless process that specifies
3344 * loopback as the source address.
3346 error
= ENETUNREACH
;
3353 /* Mark use timestamp */
3354 if (rt
->rt_llinfo
!= NULL
)
3355 nd6_llreach_use(rt
->rt_llinfo
);
3359 if (hint
&& nstat_collect
)
3360 nstat_route_tx(hint
, 1, m
->m_pkthdr
.len
, 0);
3362 m
->m_pkthdr
.rcvif
= NULL
;
3363 error
= dlil_output(ifp
, PF_INET6
, m
, (caddr_t
)rt
,
3364 (struct sockaddr
*)dst
, 0, adv
);
3372 /* Clean up "rt" unless it's already been done */
3376 RT_REMREF_LOCKED(rt
);
3383 /* And now clean up "rtrele" if there is any */
3384 if (rtrele
!= NULL
) {
3385 RT_LOCK_SPIN(rtrele
);
3386 if (rtrele
== hint0
) {
3387 RT_REMREF_LOCKED(rtrele
);
3403 * XXX: we currently do not make neighbor cache on any interface
3404 * other than ARCnet, Ethernet, FDDI and GIF.
3407 * - unidirectional tunnels needs no ND
3409 switch (ifp
->if_type
) {
3415 case IFT_IEEE8023ADLAG
:
3419 case IFT_GIF
: /* XXX need more cases? */
3437 struct sockaddr
*dst
,
3441 struct sockaddr_dl
*sdl
;
3443 if (m
->m_flags
& M_MCAST
) {
3444 switch (ifp
->if_type
) {
3448 case IFT_IEEE8023ADLAG
:
3453 ETHER_MAP_IPV6_MULTICAST(&SIN6(dst
)->sin6_addr
,
3457 for (i
= 0; i
< ifp
->if_addrlen
; i
++)
3464 return(0); /* caller will free mbuf */
3469 /* this could happen, if we could not allocate memory */
3470 return(0); /* caller will free mbuf */
3473 if (rt
->rt_gateway
->sa_family
!= AF_LINK
) {
3474 printf("nd6_storelladdr: something odd happens\n");
3476 return(0); /* caller will free mbuf */
3478 sdl
= SDL(rt
->rt_gateway
);
3479 if (sdl
->sdl_alen
== 0) {
3480 /* this should be impossible, but we bark here for debugging */
3481 printf("nd6_storelladdr: sdl_alen == 0\n");
3483 return(0); /* caller will free mbuf */
3486 bcopy(LLADDR(sdl
), desten
, sdl
->sdl_alen
);
3492 * This is the ND pre-output routine; care must be taken to ensure that
3493 * the "hint" route never gets freed via rtfree(), since the caller may
3494 * have stored it inside a struct route with a reference held for that
3498 nd6_lookup_ipv6(ifnet_t ifp
, const struct sockaddr_in6
*ip6_dest
,
3499 struct sockaddr_dl
*ll_dest
, size_t ll_dest_len
, route_t hint
,
3502 route_t route
= hint
;
3504 struct sockaddr_dl
*sdl
= NULL
;
3507 if (ip6_dest
->sin6_family
!= AF_INET6
)
3508 return (EAFNOSUPPORT
);
3510 if ((ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) != (IFF_UP
|IFF_RUNNING
))
3515 * Callee holds a reference on the route and returns
3516 * with the route entry locked, upon success.
3518 result
= route_to_gwroute((const struct sockaddr
*)ip6_dest
,
3523 RT_LOCK_ASSERT_HELD(route
);
3526 if ((packet
->m_flags
& M_MCAST
) != 0) {
3529 result
= dlil_resolve_multi(ifp
,
3530 (const struct sockaddr
*)ip6_dest
,
3531 (struct sockaddr
*)ll_dest
, ll_dest_len
);
3537 if (route
== NULL
) {
3539 * This could happen, if we could not allocate memory or
3540 * if route_to_gwroute() didn't return a route.
3546 if (route
->rt_gateway
->sa_family
!= AF_LINK
) {
3547 printf("nd6_lookup_ipv6: gateway address not AF_LINK\n");
3548 result
= EADDRNOTAVAIL
;
3552 sdl
= SDL(route
->rt_gateway
);
3553 if (sdl
->sdl_alen
== 0) {
3554 /* this should be impossible, but we bark here for debugging */
3555 printf("nd6_lookup_ipv6: sdl_alen == 0\n");
3556 result
= EHOSTUNREACH
;
3560 copy_len
= sdl
->sdl_len
<= ll_dest_len
? sdl
->sdl_len
: ll_dest_len
;
3561 bcopy(sdl
, ll_dest
, copy_len
);
3564 if (route
!= NULL
) {
3565 if (route
== hint
) {
3566 RT_REMREF_LOCKED(route
);
3577 nd6_setifinfo(struct ifnet
*ifp
, u_int32_t before
, u_int32_t after
)
3580 * We only care about ND6_IFF_PROXY_PREFIXES for now.
3582 before
&= ND6_IFF_PROXY_PREFIXES
;
3583 after
&= ND6_IFF_PROXY_PREFIXES
;
3585 if (before
== after
)
3588 return (nd6_if_prproxy(ifp
, ((int32_t)(after
- before
) > 0)));
3591 SYSCTL_DECL(_net_inet6_icmp6
);
3594 nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
3596 #pragma unused(oidp, arg1, arg2)
3599 struct nd_defrouter
*dr
;
3600 int p64
= proc_is64bit(req
->p
);
3605 lck_mtx_lock(nd6_mutex
);
3607 struct in6_defrouter_64
*d
, *de
;
3609 for (dr
= TAILQ_FIRST(&nd_defrouter
);
3611 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
3612 d
= (struct in6_defrouter_64
*)(void *)buf
;
3613 de
= (struct in6_defrouter_64
*)
3614 (void *)(buf
+ sizeof (buf
));
3617 bzero(d
, sizeof (*d
));
3618 d
->rtaddr
.sin6_family
= AF_INET6
;
3619 d
->rtaddr
.sin6_len
= sizeof (d
->rtaddr
);
3620 if (in6_recoverscope(&d
->rtaddr
, &dr
->rtaddr
,
3624 "default router list (%s)\n",
3625 ip6_sprintf(&dr
->rtaddr
));
3626 d
->flags
= dr
->flags
;
3627 d
->stateflags
= dr
->stateflags
;
3628 d
->stateflags
&= ~NDDRF_PROCESSED
;
3629 d
->rtlifetime
= dr
->rtlifetime
;
3630 d
->expire
= dr
->expire
;
3631 d
->if_index
= dr
->ifp
->if_index
;
3633 panic("buffer too short");
3635 error
= SYSCTL_OUT(req
, buf
, sizeof (*d
));
3640 struct in6_defrouter_32
*d_32
, *de_32
;
3642 for (dr
= TAILQ_FIRST(&nd_defrouter
);
3644 dr
= TAILQ_NEXT(dr
, dr_entry
)) {
3645 d_32
= (struct in6_defrouter_32
*)(void *)buf
;
3646 de_32
= (struct in6_defrouter_32
*)
3647 (void *)(buf
+ sizeof (buf
));
3649 if (d_32
+ 1 <= de_32
) {
3650 bzero(d_32
, sizeof (*d_32
));
3651 d_32
->rtaddr
.sin6_family
= AF_INET6
;
3652 d_32
->rtaddr
.sin6_len
= sizeof (d_32
->rtaddr
);
3653 if (in6_recoverscope(&d_32
->rtaddr
, &dr
->rtaddr
,
3657 "default router list (%s)\n",
3658 ip6_sprintf(&dr
->rtaddr
));
3659 d_32
->flags
= dr
->flags
;
3660 d_32
->stateflags
= dr
->stateflags
;
3661 d_32
->stateflags
&= ~NDDRF_PROCESSED
;
3662 d_32
->rtlifetime
= dr
->rtlifetime
;
3663 d_32
->expire
= dr
->expire
;
3664 d_32
->if_index
= dr
->ifp
->if_index
;
3666 panic("buffer too short");
3668 error
= SYSCTL_OUT(req
, buf
, sizeof (*d_32
));
3673 lck_mtx_unlock(nd6_mutex
);
3678 nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
3680 #pragma unused(oidp, arg1, arg2)
3683 struct nd_prefix
*pr
;
3684 int p64
= proc_is64bit(req
->p
);
3689 lck_mtx_lock(nd6_mutex
);
3691 struct in6_prefix_64
*p
, *pe
;
3693 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
3694 u_short advrtrs
= 0;
3696 struct sockaddr_in6
*sin6
, *s6
;
3697 struct nd_pfxrouter
*pfr
;
3699 p
= (struct in6_prefix_64
*)(void *)buf
;
3700 pe
= (struct in6_prefix_64
*)
3701 (void *)(buf
+ sizeof (buf
));
3704 bzero(p
, sizeof (*p
));
3705 sin6
= (struct sockaddr_in6
*)(p
+ 1);
3708 p
->prefix
= pr
->ndpr_prefix
;
3709 if (in6_recoverscope(&p
->prefix
,
3710 &p
->prefix
.sin6_addr
, pr
->ndpr_ifp
) != 0)
3712 "scope error in prefix list (%s)\n",
3713 ip6_sprintf(&p
->prefix
.sin6_addr
));
3714 p
->raflags
= pr
->ndpr_raf
;
3715 p
->prefixlen
= pr
->ndpr_plen
;
3716 p
->vltime
= pr
->ndpr_vltime
;
3717 p
->pltime
= pr
->ndpr_pltime
;
3718 p
->if_index
= pr
->ndpr_ifp
->if_index
;
3719 p
->expire
= pr
->ndpr_expire
;
3720 p
->refcnt
= pr
->ndpr_addrcnt
;
3721 p
->flags
= pr
->ndpr_stateflags
;
3722 p
->origin
= PR_ORIG_RA
;
3724 for (pfr
= pr
->ndpr_advrtrs
.lh_first
;
3726 pfr
= pfr
->pfr_next
) {
3727 if ((void *)&sin6
[advrtrs
+ 1] >
3732 s6
= &sin6
[advrtrs
];
3733 bzero(s6
, sizeof (*s6
));
3734 s6
->sin6_family
= AF_INET6
;
3735 s6
->sin6_len
= sizeof (*sin6
);
3736 if (in6_recoverscope(s6
,
3737 &pfr
->router
->rtaddr
,
3738 pfr
->router
->ifp
) != 0)
3739 log(LOG_ERR
, "scope error in "
3740 "prefix list (%s)\n",
3741 ip6_sprintf(&pfr
->router
->
3745 p
->advrtrs
= advrtrs
;
3748 panic("buffer too short");
3750 advance
= sizeof (*p
) + sizeof (*sin6
) * advrtrs
;
3751 error
= SYSCTL_OUT(req
, buf
, advance
);
3756 struct in6_prefix_32
*p_32
, *pe_32
;
3758 for (pr
= nd_prefix
.lh_first
; pr
; pr
= pr
->ndpr_next
) {
3759 u_short advrtrs
= 0;
3761 struct sockaddr_in6
*sin6
, *s6
;
3762 struct nd_pfxrouter
*pfr
;
3764 p_32
= (struct in6_prefix_32
*)(void *)buf
;
3765 pe_32
= (struct in6_prefix_32
*)
3766 (void *)(buf
+ sizeof (buf
));
3768 if (p_32
+ 1 <= pe_32
) {
3769 bzero(p_32
, sizeof (*p_32
));
3770 sin6
= (struct sockaddr_in6
*)(p_32
+ 1);
3773 p_32
->prefix
= pr
->ndpr_prefix
;
3774 if (in6_recoverscope(&p_32
->prefix
,
3775 &p_32
->prefix
.sin6_addr
, pr
->ndpr_ifp
) != 0)
3776 log(LOG_ERR
, "scope error in prefix "
3777 "list (%s)\n", ip6_sprintf(&p_32
->
3779 p_32
->raflags
= pr
->ndpr_raf
;
3780 p_32
->prefixlen
= pr
->ndpr_plen
;
3781 p_32
->vltime
= pr
->ndpr_vltime
;
3782 p_32
->pltime
= pr
->ndpr_pltime
;
3783 p_32
->if_index
= pr
->ndpr_ifp
->if_index
;
3784 p_32
->expire
= pr
->ndpr_expire
;
3785 p_32
->refcnt
= pr
->ndpr_addrcnt
;
3786 p_32
->flags
= pr
->ndpr_stateflags
;
3787 p_32
->origin
= PR_ORIG_RA
;
3789 for (pfr
= pr
->ndpr_advrtrs
.lh_first
;
3791 pfr
= pfr
->pfr_next
) {
3792 if ((void *)&sin6
[advrtrs
+ 1] >
3797 s6
= &sin6
[advrtrs
];
3798 bzero(s6
, sizeof (*s6
));
3799 s6
->sin6_family
= AF_INET6
;
3800 s6
->sin6_len
= sizeof (*sin6
);
3801 if (in6_recoverscope(s6
,
3802 &pfr
->router
->rtaddr
,
3803 pfr
->router
->ifp
) != 0)
3804 log(LOG_ERR
, "scope error in "
3805 "prefix list (%s)\n",
3806 ip6_sprintf(&pfr
->router
->
3810 p_32
->advrtrs
= advrtrs
;
3813 panic("buffer too short");
3815 advance
= sizeof (*p_32
) + sizeof (*sin6
) * advrtrs
;
3816 error
= SYSCTL_OUT(req
, buf
, advance
);
3821 lck_mtx_unlock(nd6_mutex
);
3824 SYSCTL_PROC(_net_inet6_icmp6
, ICMPV6CTL_ND6_DRLIST
, nd6_drlist
,
3825 CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, nd6_sysctl_drlist
, "S,in6_defrouter","");
3826 SYSCTL_PROC(_net_inet6_icmp6
, ICMPV6CTL_ND6_PRLIST
, nd6_prlist
,
3827 CTLFLAG_RD
| CTLFLAG_LOCKED
, 0, 0, nd6_sysctl_prlist
, "S,in6_defrouter","");