2  * Copyright (c) 2000-2013 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@ 
  30  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 
  31  * All rights reserved. 
  33  * Redistribution and use in source and binary forms, with or without 
  34  * modification, are permitted provided that the following conditions 
  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. 
  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 
  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 
  66 #include <sys/param.h> 
  67 #include <sys/systm.h> 
  68 #include <sys/malloc.h> 
  70 #include <sys/socket.h> 
  71 #include <sys/sockio.h> 
  73 #include <sys/kernel.h> 
  74 #include <sys/sysctl.h> 
  75 #include <sys/errno.h> 
  76 #include <sys/syslog.h> 
  77 #include <sys/protosw.h> 
  79 #include <sys/mcache.h> 
  81 #include <dev/random/randomdev.h> 
  83 #include <kern/queue.h> 
  84 #include <kern/zalloc.h> 
  87 #include <net/if_dl.h> 
  88 #include <net/if_types.h> 
  89 #include <net/if_llreach.h> 
  90 #include <net/route.h> 
  92 #include <net/ntstat.h> 
  93 #include <net/net_osdep.h> 
  95 #include <netinet/in.h> 
  96 #include <netinet/in_arp.h> 
  97 #include <netinet/if_ether.h> 
  98 #include <netinet6/in6_var.h> 
  99 #include <netinet/ip6.h> 
 100 #include <netinet6/ip6_var.h> 
 101 #include <netinet6/nd6.h> 
 102 #include <netinet6/scope6_var.h> 
 103 #include <netinet/icmp6.h> 
 107 #define ND6_SLOWTIMER_INTERVAL          (60 * 60)       /* 1 hour */ 
 108 #define ND6_RECALC_REACHTM_INTERVAL     (60 * 120)      /* 2 hours */ 
 110 #define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0) 
 113 int     nd6_prune       
= 1;    /* walk list every 1 seconds */ 
 114 int     nd6_prune_lazy  
= 5;    /* lazily walk list every 5 seconds */ 
 115 int     nd6_delay       
= 5;    /* delay first probe time 5 second */ 
 116 int     nd6_umaxtries   
= 3;    /* maximum unicast query */ 
 117 int     nd6_mmaxtries   
= 3;    /* maximum multicast query */ 
 118 int     nd6_useloopback 
= 1;    /* use loopback interface for local traffic */ 
 119 int     nd6_gctimer     
= (60 * 60 * 24); /* 1 day: garbage collection timer */ 
 121 /* preventing too many loops in ND option parsing */ 
 122 int nd6_maxndopt 
= 10;  /* max # of ND options allowed */ 
 124 int nd6_maxqueuelen 
= 1; /* max # of packets cached in unresolved ND entries */ 
 132 int nd6_optimistic_dad 
= 
 133         (ND6_OPTIMISTIC_DAD_LINKLOCAL
|ND6_OPTIMISTIC_DAD_AUTOCONF
| 
 134         ND6_OPTIMISTIC_DAD_TEMPORARY
|ND6_OPTIMISTIC_DAD_DYNAMIC
| 
 135         ND6_OPTIMISTIC_DAD_SECURED
|ND6_OPTIMISTIC_DAD_MANUAL
); 
 138 static int nd6_inuse
, nd6_allocated
; 
 141  * Synchronization notes: 
 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(). 
 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: 
 152  * ln_next, ln_prev, ln_rt 
 154  *      - Routing lock (rnh_lock) 
 156  * ln_hold, ln_asked, ln_expire, ln_state, ln_router, ln_flags, 
 157  * ln_llreach, ln_lastused 
 159  *      - Routing entry lock (rt_lock) 
 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. 
 166 struct llinfo_nd6 llinfo_nd6 
= { 
 167         .ln_next 
= &llinfo_nd6
, 
 168         .ln_prev 
= &llinfo_nd6
, 
 171 /* Protected by nd_if_rwlock */ 
 172 size_t nd_ifinfo_indexlim 
= 32; /* increased for 5589193 */ 
 173 struct nd_ifinfo 
*nd_ifinfo 
= NULL
; 
 175 static lck_grp_attr_t   
*nd_if_lock_grp_attr
; 
 176 static lck_grp_t        
*nd_if_lock_grp
; 
 177 static lck_attr_t       
*nd_if_lock_attr
; 
 178 decl_lck_rw_data(, nd_if_rwlock_data
); 
 179 lck_rw_t                
*nd_if_rwlock 
= &nd_if_rwlock_data
; 
 181 /* Protected by nd6_mutex */ 
 182 struct nd_drhead nd_defrouter
; 
 183 struct nd_prhead nd_prefix 
= { 0 }; 
 186  * nd6_timeout() is scheduled on a demand basis.  nd6_timeout_run is used 
 187  * to indicate whether or not a timeout has been scheduled.  The rnh_lock 
 188  * mutex is used to protect this scheduling; it is a natural choice given 
 189  * the work done in the timer callback.  Unfortunately, there are cases 
 190  * when nd6_timeout() needs to be scheduled while rnh_lock cannot be easily 
 191  * held, due to lock ordering.  In those cases, we utilize a "demand" counter 
 192  * nd6_sched_timeout_want which can be atomically incremented without 
 193  * having to hold rnh_lock.  On places where we acquire rnh_lock, such as 
 194  * nd6_rtrequest(), we check this counter and schedule the timer if it is 
 195  * non-zero.  The increment happens on various places when we allocate 
 196  * new ND entries, default routers, prefixes and addresses. 
 198 static int nd6_timeout_run
;             /* nd6_timeout is scheduled to run */ 
 199 static void nd6_timeout(void *); 
 200 int nd6_sched_timeout_want
;             /* demand count for timer to be sched */ 
 201 static boolean_t nd6_fast_timer_on 
= FALSE
; 
 203 /* Serialization variables for nd6_service(), protected by rnh_lock */ 
 204 static boolean_t nd6_service_busy
; 
 205 static void *nd6_service_wc 
= &nd6_service_busy
; 
 206 static int nd6_service_waiters 
= 0; 
 208 int nd6_recalc_reachtm_interval 
= ND6_RECALC_REACHTM_INTERVAL
; 
 209 static struct sockaddr_in6 all1_sa
; 
 211 static int regen_tmpaddr(struct in6_ifaddr 
*); 
 212 extern lck_mtx_t 
*nd6_mutex
; 
 214 static struct llinfo_nd6 
*nd6_llinfo_alloc(int); 
 215 static void nd6_llinfo_free(void *); 
 216 static void nd6_llinfo_purge(struct rtentry 
*); 
 217 static void nd6_llinfo_get_ri(struct rtentry 
*, struct rt_reach_info 
*); 
 218 static void nd6_llinfo_get_iflri(struct rtentry 
*, struct ifnet_llreach_info 
*); 
 219 static uint64_t ln_getexpire(struct llinfo_nd6 
*); 
 221 static void nd6_service(void *); 
 222 static void nd6_slowtimo(void *); 
 223 static int nd6_is_new_addr_neighbor(struct sockaddr_in6 
*, struct ifnet 
*); 
 224 static int nd6_siocgdrlst(void *, int); 
 225 static int nd6_siocgprlst(void *, int); 
 227 static int nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
; 
 228 static int nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
; 
 231  * Insertion and removal from llinfo_nd6 must be done with rnh_lock held. 
 233 #define LN_DEQUEUE(_ln) do {                                            \ 
 234         lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);                 \ 
 235         RT_LOCK_ASSERT_HELD((_ln)->ln_rt);                              \ 
 236         (_ln)->ln_next->ln_prev = (_ln)->ln_prev;                       \ 
 237         (_ln)->ln_prev->ln_next = (_ln)->ln_next;                       \ 
 238         (_ln)->ln_prev = (_ln)->ln_next = NULL;                         \ 
 239         (_ln)->ln_flags &= ~ND6_LNF_IN_USE;                             \ 
 242 #define LN_INSERTHEAD(_ln) do {                                         \ 
 243         lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);                 \ 
 244         RT_LOCK_ASSERT_HELD((_ln)->ln_rt);                              \ 
 245         (_ln)->ln_next = llinfo_nd6.ln_next;                            \ 
 246         llinfo_nd6.ln_next = (_ln);                                     \ 
 247         (_ln)->ln_prev = &llinfo_nd6;                                   \ 
 248         (_ln)->ln_next->ln_prev = (_ln);                                \ 
 249         (_ln)->ln_flags |= ND6_LNF_IN_USE;                              \ 
 252 static struct zone 
*llinfo_nd6_zone
; 
 253 #define LLINFO_ND6_ZONE_MAX     256             /* maximum elements in zone */ 
 254 #define LLINFO_ND6_ZONE_NAME    "llinfo_nd6"    /* name for zone */ 
 256 extern int tvtohz(struct timeval 
*); 
 258 static int nd6_init_done
; 
 260 SYSCTL_DECL(_net_inet6_icmp6
); 
 262 SYSCTL_PROC(_net_inet6_icmp6
, ICMPV6CTL_ND6_DRLIST
, nd6_drlist
, 
 263         CTLTYPE_STRUCT 
| CTLFLAG_RD 
| CTLFLAG_LOCKED
, 0, 0, 
 264         nd6_sysctl_drlist
, "S,in6_defrouter", ""); 
 266 SYSCTL_PROC(_net_inet6_icmp6
, ICMPV6CTL_ND6_PRLIST
, nd6_prlist
, 
 267         CTLTYPE_STRUCT 
| CTLFLAG_RD 
| CTLFLAG_LOCKED
, 0, 0, 
 268         nd6_sysctl_prlist
, "S,in6_defrouter", ""); 
 275         VERIFY(!nd6_init_done
); 
 277         all1_sa
.sin6_family 
= AF_INET6
; 
 278         all1_sa
.sin6_len 
= sizeof (struct sockaddr_in6
); 
 279         for (i 
= 0; i 
< sizeof (all1_sa
.sin6_addr
); i
++) 
 280                 all1_sa
.sin6_addr
.s6_addr
[i
] = 0xff; 
 282         /* initialization of the default router list */ 
 283         TAILQ_INIT(&nd_defrouter
); 
 285         nd_if_lock_grp_attr 
= lck_grp_attr_alloc_init(); 
 286         nd_if_lock_grp 
= lck_grp_alloc_init("nd_if_lock", nd_if_lock_grp_attr
); 
 287         nd_if_lock_attr 
= lck_attr_alloc_init(); 
 288         lck_rw_init(nd_if_rwlock
, nd_if_lock_grp
, nd_if_lock_attr
); 
 290         llinfo_nd6_zone 
= zinit(sizeof (struct llinfo_nd6
), 
 291             LLINFO_ND6_ZONE_MAX 
* sizeof (struct llinfo_nd6
), 0, 
 292             LLINFO_ND6_ZONE_NAME
); 
 293         if (llinfo_nd6_zone 
== NULL
) 
 294                 panic("%s: failed allocating llinfo_nd6_zone", __func__
); 
 296         zone_change(llinfo_nd6_zone
, Z_EXPAND
, TRUE
); 
 297         zone_change(llinfo_nd6_zone
, Z_CALLERACCT
, FALSE
); 
 306         timeout(nd6_slowtimo
, NULL
, ND6_SLOWTIMER_INTERVAL 
* hz
); 
 309 static struct llinfo_nd6 
* 
 310 nd6_llinfo_alloc(int how
) 
 312         struct llinfo_nd6 
*ln
; 
 314         ln 
= (how 
== M_WAITOK
) ? zalloc(llinfo_nd6_zone
) : 
 315             zalloc_noblock(llinfo_nd6_zone
); 
 317                 bzero(ln
, sizeof (*ln
)); 
 323 nd6_llinfo_free(void *arg
) 
 325         struct llinfo_nd6 
*ln 
= arg
; 
 327         if (ln
->ln_next 
!= NULL 
|| ln
->ln_prev 
!= NULL
) { 
 328                 panic("%s: trying to free %p when it is in use", __func__
, ln
); 
 332         /* Just in case there's anything there, free it */ 
 333         if (ln
->ln_hold 
!= NULL
) { 
 334                 m_freem(ln
->ln_hold
); 
 338         /* Purge any link-layer info caching */ 
 339         VERIFY(ln
->ln_rt
->rt_llinfo 
== ln
); 
 340         if (ln
->ln_rt
->rt_llinfo_purge 
!= NULL
) 
 341                 ln
->ln_rt
->rt_llinfo_purge(ln
->ln_rt
); 
 343         zfree(llinfo_nd6_zone
, ln
); 
 347 nd6_llinfo_purge(struct rtentry 
*rt
) 
 349         struct llinfo_nd6 
*ln 
= rt
->rt_llinfo
; 
 351         RT_LOCK_ASSERT_HELD(rt
); 
 352         VERIFY(rt
->rt_llinfo_purge 
== nd6_llinfo_purge 
&& ln 
!= NULL
); 
 354         if (ln
->ln_llreach 
!= NULL
) { 
 356                 ifnet_llreach_free(ln
->ln_llreach
); 
 357                 ln
->ln_llreach 
= NULL
; 
 363 nd6_llinfo_get_ri(struct rtentry 
*rt
, struct rt_reach_info 
*ri
) 
 365         struct llinfo_nd6 
*ln 
= rt
->rt_llinfo
; 
 366         struct if_llreach 
*lr 
= ln
->ln_llreach
; 
 369                 bzero(ri
, sizeof (*ri
)); 
 370                 ri
->ri_rssi 
= IFNET_RSSI_UNKNOWN
; 
 371                 ri
->ri_lqm 
= IFNET_LQM_THRESH_OFF
; 
 372                 ri
->ri_npm 
= IFNET_NPM_THRESH_UNKNOWN
; 
 375                 /* Export to rt_reach_info structure */ 
 377                 /* Export ND6 send expiration (calendar) time */ 
 379                     ifnet_llreach_up2calexp(lr
, ln
->ln_lastused
); 
 385 nd6_llinfo_get_iflri(struct rtentry 
*rt
, struct ifnet_llreach_info 
*iflri
) 
 387         struct llinfo_nd6 
*ln 
= rt
->rt_llinfo
; 
 388         struct if_llreach 
*lr 
= ln
->ln_llreach
; 
 391                 bzero(iflri
, sizeof (*iflri
)); 
 392                 iflri
->iflri_rssi 
= IFNET_RSSI_UNKNOWN
; 
 393                 iflri
->iflri_lqm 
= IFNET_LQM_THRESH_OFF
; 
 394                 iflri
->iflri_npm 
= IFNET_NPM_THRESH_UNKNOWN
; 
 397                 /* Export to ifnet_llreach_info structure */ 
 398                 ifnet_lr2iflri(lr
, iflri
); 
 399                 /* Export ND6 send expiration (uptime) time */ 
 400                 iflri
->iflri_snd_expire 
= 
 401                     ifnet_llreach_up2upexp(lr
, ln
->ln_lastused
); 
 407 ln_setexpire(struct llinfo_nd6 
*ln
, uint64_t expiry
) 
 409         ln
->ln_expire 
= expiry
; 
 413 ln_getexpire(struct llinfo_nd6 
*ln
) 
 415         struct timeval caltime
; 
 418         if (ln
->ln_expire 
!= 0) { 
 419                 struct rtentry 
*rt 
= ln
->ln_rt
; 
 422                 /* account for system time change */ 
 423                 getmicrotime(&caltime
); 
 425                 rt
->base_calendartime 
+= 
 426                     NET_CALCULATE_CLOCKSKEW(caltime
, 
 427                     rt
->base_calendartime
, net_uptime(), rt
->base_uptime
); 
 429                 expiry 
= rt
->base_calendartime 
+ 
 430                     ln
->ln_expire 
- rt
->base_uptime
; 
 438 nd6_ifreset(struct ifnet 
*ifp
) 
 440         struct nd_ifinfo 
*ndi
; 
 442         lck_rw_assert(nd_if_rwlock
, LCK_RW_ASSERT_HELD
); 
 443         VERIFY(ifp 
!= NULL 
&& ifp
->if_index 
< nd_ifinfo_indexlim
); 
 444         ndi 
= &nd_ifinfo
[ifp
->if_index
]; 
 446         VERIFY(ndi
->initialized
); 
 447         lck_mtx_assert(&ndi
->lock
, LCK_MTX_ASSERT_OWNED
); 
 448         ndi
->linkmtu 
= ifp
->if_mtu
; 
 449         ndi
->chlim 
= IPV6_DEFHLIM
; 
 450         ndi
->basereachable 
= REACHABLE_TIME
; 
 451         ndi
->reachable 
= ND_COMPUTE_RTIME(ndi
->basereachable
); 
 452         ndi
->retrans 
= RETRANS_TIMER
; 
 456 nd6_ifattach(struct ifnet 
*ifp
) 
 459         struct nd_ifinfo 
*ndi
; 
 462          * We have some arrays that should be indexed by if_index. 
 463          * since if_index will grow dynamically, they should grow too. 
 465         lck_rw_lock_shared(nd_if_rwlock
); 
 466         newlim 
= nd_ifinfo_indexlim
; 
 467         if (nd_ifinfo 
== NULL 
|| if_index 
>= newlim
) { 
 468                 if (!lck_rw_lock_shared_to_exclusive(nd_if_rwlock
)) 
 469                         lck_rw_lock_exclusive(nd_if_rwlock
); 
 470                 lck_rw_assert(nd_if_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
 472                 newlim 
= nd_ifinfo_indexlim
; 
 473                 if (nd_ifinfo 
== NULL 
|| if_index 
>= newlim
) { 
 477                         while (if_index 
>= newlim
) 
 481                         n 
= newlim 
* sizeof (struct nd_ifinfo
); 
 482                         q 
= (caddr_t
)_MALLOC(n
, M_IP6NDP
, M_WAITOK
); 
 484                                 lck_rw_done(nd_if_rwlock
); 
 488                         if (nd_ifinfo 
!= NULL
) { 
 489                                 bcopy((caddr_t
)nd_ifinfo
, q
, n
/2); 
 491                                  * We might want to pattern fill the old 
 492                                  * array to catch use-after-free cases. 
 494                                 FREE((caddr_t
)nd_ifinfo
, M_IP6NDP
); 
 496                         nd_ifinfo 
= (struct nd_ifinfo 
*)(void *)q
; 
 497                         nd_ifinfo_indexlim 
= newlim
; 
 502         ndi 
= &nd_ifinfo
[ifp
->if_index
]; 
 503         if (!ndi
->initialized
) { 
 504                 lck_mtx_init(&ndi
->lock
, nd_if_lock_grp
, nd_if_lock_attr
); 
 505                 ndi
->flags 
= ND6_IFF_PERFORMNUD
; 
 506                 ndi
->initialized 
= TRUE
; 
 509         lck_mtx_lock(&ndi
->lock
); 
 511         if (!(ifp
->if_flags 
& IFF_MULTICAST
)) 
 512                 ndi
->flags 
|= ND6_IFF_IFDISABLED
; 
 515         lck_mtx_unlock(&ndi
->lock
); 
 517         lck_rw_done(nd_if_rwlock
); 
 525  * Reset ND level link MTU. This function is called when the physical MTU 
 526  * changes, which means we might have to adjust the ND level MTU. 
 529 nd6_setmtu(struct ifnet 
*ifp
) 
 531         struct nd_ifinfo 
*ndi
; 
 532         u_int32_t oldmaxmtu
, maxmtu
; 
 535          * Make sure IPv6 is enabled for the interface first, 
 536          * because this can be called directly from SIOCSIFMTU for IPv4 
 538         lck_rw_lock_shared(nd_if_rwlock
); 
 539         if (ifp
->if_index 
>= nd_ifinfo_indexlim 
|| 
 540             !nd_ifinfo
[ifp
->if_index
].initialized
) { 
 541                 lck_rw_done(nd_if_rwlock
); 
 542                 return; /* nd_ifinfo out of bound, or not yet initialized */ 
 545         ndi 
= &nd_ifinfo
[ifp
->if_index
]; 
 546         VERIFY(ndi
->initialized
); 
 547         lck_mtx_lock(&ndi
->lock
); 
 548         oldmaxmtu 
= ndi
->maxmtu
; 
 551          * The ND level maxmtu is somewhat redundant to the interface MTU 
 552          * and is an implementation artifact of KAME.  Instead of hard- 
 553          * limiting the maxmtu based on the interface type here, we simply 
 554          * take the if_mtu value since SIOCSIFMTU would have taken care of 
 555          * the sanity checks related to the maximum MTU allowed for the 
 556          * interface (a value that is known only by the interface layer), 
 557          * by sending the request down via ifnet_ioctl().  The use of the 
 558          * ND level maxmtu and linkmtu are done via IN6_LINKMTU() which 
 559          * does further checking against if_mtu. 
 561         maxmtu 
= ndi
->maxmtu 
= ifp
->if_mtu
; 
 564          * Decreasing the interface MTU under IPV6 minimum MTU may cause 
 565          * undesirable situation.  We thus notify the operator of the change 
 566          * explicitly.  The check for oldmaxmtu is necessary to restrict the 
 567          * log to the case of changing the MTU, not initializing it. 
 569         if (oldmaxmtu 
>= IPV6_MMTU 
&& ndi
->maxmtu 
< IPV6_MMTU
) { 
 570                 log(LOG_NOTICE
, "nd6_setmtu: " 
 571                     "new link MTU on %s (%u) is too small for IPv6\n", 
 572                     if_name(ifp
), (uint32_t)ndi
->maxmtu
); 
 574         ndi
->linkmtu 
= ifp
->if_mtu
; 
 575         lck_mtx_unlock(&ndi
->lock
); 
 576         lck_rw_done(nd_if_rwlock
); 
 578         /* also adjust in6_maxmtu if necessary. */ 
 579         if (maxmtu 
> in6_maxmtu
) 
 584 nd6_option_init(void *opt
, int icmp6len
, union nd_opts 
*ndopts
) 
 586         bzero(ndopts
, sizeof (*ndopts
)); 
 587         ndopts
->nd_opts_search 
= (struct nd_opt_hdr 
*)opt
; 
 588         ndopts
->nd_opts_last 
= 
 589             (struct nd_opt_hdr 
*)(((u_char 
*)opt
) + icmp6len
); 
 592                 ndopts
->nd_opts_done 
= 1; 
 593                 ndopts
->nd_opts_search 
= NULL
; 
 598  * Take one ND option. 
 601 nd6_option(union nd_opts 
*ndopts
) 
 603         struct nd_opt_hdr 
*nd_opt
; 
 607                 panic("ndopts == NULL in nd6_option\n"); 
 608         if (!ndopts
->nd_opts_last
) 
 609                 panic("uninitialized ndopts in nd6_option\n"); 
 610         if (!ndopts
->nd_opts_search
) 
 612         if (ndopts
->nd_opts_done
) 
 615         nd_opt 
= ndopts
->nd_opts_search
; 
 617         /* make sure nd_opt_len is inside the buffer */ 
 618         if ((caddr_t
)&nd_opt
->nd_opt_len 
>= (caddr_t
)ndopts
->nd_opts_last
) { 
 619                 bzero(ndopts
, sizeof (*ndopts
)); 
 623         olen 
= nd_opt
->nd_opt_len 
<< 3; 
 626                  * Message validation requires that all included 
 627                  * options have a length that is greater than zero. 
 629                 bzero(ndopts
, sizeof (*ndopts
)); 
 633         ndopts
->nd_opts_search 
= (struct nd_opt_hdr 
*)((caddr_t
)nd_opt 
+ olen
); 
 634         if (ndopts
->nd_opts_search 
> ndopts
->nd_opts_last
) { 
 635                 /* option overruns the end of buffer, invalid */ 
 636                 bzero(ndopts
, sizeof (*ndopts
)); 
 638         } else if (ndopts
->nd_opts_search 
== ndopts
->nd_opts_last
) { 
 639                 /* reached the end of options chain */ 
 640                 ndopts
->nd_opts_done 
= 1; 
 641                 ndopts
->nd_opts_search 
= NULL
; 
 647  * Parse multiple ND options. 
 648  * This function is much easier to use, for ND routines that do not need 
 649  * multiple options of the same type. 
 652 nd6_options(union nd_opts 
*ndopts
) 
 654         struct nd_opt_hdr 
*nd_opt
; 
 658                 panic("ndopts == NULL in nd6_options"); 
 659         if (ndopts
->nd_opts_last 
== NULL
) 
 660                 panic("uninitialized ndopts in nd6_options"); 
 661         if (ndopts
->nd_opts_search 
== NULL
) 
 665                 nd_opt 
= nd6_option(ndopts
); 
 666                 if (nd_opt 
== NULL 
&& ndopts
->nd_opts_last 
== NULL
) { 
 668                          * Message validation requires that all included 
 669                          * options have a length that is greater than zero. 
 671                         icmp6stat
.icp6s_nd_badopt
++; 
 672                         bzero(ndopts
, sizeof (*ndopts
)); 
 679                 switch (nd_opt
->nd_opt_type
) { 
 680                 case ND_OPT_SOURCE_LINKADDR
: 
 681                 case ND_OPT_TARGET_LINKADDR
: 
 683                 case ND_OPT_REDIRECTED_HEADER
: 
 684                         if (ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
]) { 
 686                                     "duplicated ND6 option found (type=%d)\n", 
 687                                     nd_opt
->nd_opt_type
)); 
 690                                 ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
] = 
 694                 case ND_OPT_PREFIX_INFORMATION
: 
 695                         if (ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
] == 0) { 
 696                                 ndopts
->nd_opt_array
[nd_opt
->nd_opt_type
] = 
 699                         ndopts
->nd_opts_pi_end 
= 
 700                             (struct nd_opt_prefix_info 
*)nd_opt
; 
 707                          * Unknown options must be silently ignored, 
 708                          * to accomodate future extension to the protocol. 
 711                             "nd6_options: unsupported option %d - " 
 712                             "option ignored\n", nd_opt
->nd_opt_type
)); 
 717                 if (i 
> nd6_maxndopt
) { 
 718                         icmp6stat
.icp6s_nd_toomanyopt
++; 
 719                         nd6log((LOG_INFO
, "too many loop in nd opt\n")); 
 723                 if (ndopts
->nd_opts_done
) 
 740  * ND6 service routine to expire default route list and prefix list 
 743 nd6_service(void *arg
) 
 745         struct nd6svc_arg 
*ap 
= arg
; 
 746         struct llinfo_nd6 
*ln
; 
 747         struct nd_defrouter 
*dr
; 
 748         struct nd_prefix 
*pr
; 
 749         struct ifnet 
*ifp 
= NULL
; 
 750         struct in6_ifaddr 
*ia6
, *nia6
; 
 753         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
 755          * Since we may drop rnh_lock and nd6_mutex below, we want 
 756          * to run this entire operation single threaded. 
 758         while (nd6_service_busy
) { 
 759                 nd6log2((LOG_DEBUG
, "%s: %s is blocked by %d waiters\n", 
 760                     __func__
, ap
->draining 
? "drainer" : "timer", 
 761                     nd6_service_waiters
)); 
 762                 nd6_service_waiters
++; 
 763                 (void) msleep(nd6_service_wc
, rnh_lock
, (PZERO
-1), 
 765                 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
 768         /* We are busy now; tell everyone else to go away */ 
 769         nd6_service_busy 
= TRUE
; 
 772         timenow 
= net_uptime(); 
 775          * The global list llinfo_nd6 is modified by nd6_request() and is 
 776          * therefore protected by rnh_lock.  For obvious reasons, we cannot 
 777          * hold rnh_lock across calls that might lead to code paths which 
 778          * attempt to acquire rnh_lock, else we deadlock.  Hence for such 
 779          * cases we drop rt_lock and rnh_lock, make the calls, and repeat the 
 780          * loop.  To ensure that we don't process the same entry more than 
 781          * once in a single timeout, we mark the "already-seen" entries with 
 782          * ND6_LNF_TIMER_SKIP flag.  At the end of the loop, we do a second 
 783          * pass thru the entries and clear the flag so they can be processed 
 784          * during the next timeout. 
 786         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
 788         ln 
= llinfo_nd6
.ln_next
; 
 789         while (ln 
!= NULL 
&& ln 
!= &llinfo_nd6
) { 
 791                 struct sockaddr_in6 
*dst
; 
 792                 struct llinfo_nd6 
*next
; 
 793                 u_int32_t retrans
, flags
; 
 795                 /* ln_next/prev/rt is protected by rnh_lock */ 
 800                 /* We've seen this already; skip it */ 
 801                 if (ln
->ln_flags 
& ND6_LNF_TIMER_SKIP
) { 
 808                 /* rt->rt_ifp should never be NULL */ 
 809                 if ((ifp 
= rt
->rt_ifp
) == NULL
) { 
 810                         panic("%s: ln(%p) rt(%p) rt_ifp == NULL", __func__
, 
 815                 /* rt_llinfo must always be equal to ln */ 
 816                 if ((struct llinfo_nd6 
*)rt
->rt_llinfo 
!= ln
) { 
 817                         panic("%s: rt_llinfo(%p) is not equal to ln(%p)", 
 818                             __func__
, rt
->rt_llinfo
, ln
); 
 822                 /* rt_key should never be NULL */ 
 823                 dst 
= SIN6(rt_key(rt
)); 
 825                         panic("%s: rt(%p) key is NULL ln(%p)", __func__
, 
 830                 /* Set the flag in case we jump to "again" */ 
 831                 ln
->ln_flags 
|= ND6_LNF_TIMER_SKIP
; 
 833                 if (ln
->ln_expire 
== 0 || (rt
->rt_flags 
& RTF_STATIC
)) { 
 835                 } else if (ap
->draining 
&& (rt
->rt_refcnt 
== 0)) { 
 837                          * If we are draining, immediately purge non-static 
 838                          * entries without oustanding route refcnt. 
 840                         if (ln
->ln_state 
> ND6_LLINFO_INCOMPLETE
) 
 841                                 ln
->ln_state 
= ND6_LLINFO_STALE
; 
 843                                 ln
->ln_state 
= ND6_LLINFO_PURGE
; 
 844                         ln_setexpire(ln
, timenow
); 
 848                  * If the entry has not expired, skip it.  Take note on the 
 849                  * state, as entries that are in the STALE state are simply 
 850                  * waiting to be garbage collected, in which case we can 
 851                  * relax the callout scheduling (use nd6_prune_lazy). 
 853                 if (ln
->ln_expire 
> timenow
) { 
 854                         switch (ln
->ln_state
) { 
 855                         case ND6_LLINFO_STALE
: 
 867                 lck_rw_lock_shared(nd_if_rwlock
); 
 868                 if (ifp
->if_index 
>= nd_ifinfo_indexlim
) { 
 870                          * In the event the nd_ifinfo[] array is not in synch 
 871                          * by now, we don't want to hold on to the llinfo entry 
 872                          * forever; just purge it rather than have it consume 
 873                          * resources.  That's better than transmitting out of 
 874                          * the interface as the rest of the layers may not be 
 877                          * We can retire this logic once we get rid of the 
 878                          * separate array and utilize a per-ifnet structure. 
 880                         retrans 
= RETRANS_TIMER
; 
 881                         flags 
= ND6_IFF_PERFORMNUD
; 
 882                         if (ln
->ln_expire 
!= 0) { 
 883                                 ln
->ln_state 
= ND6_LLINFO_PURGE
; 
 884                                 log (LOG_ERR
, "%s: purging rt(0x%llx) " 
 885                                     "ln(0x%llx) dst %s, if_index %d >= %d\n", 
 886                                     __func__
, (uint64_t)VM_KERNEL_ADDRPERM(rt
), 
 887                                     (uint64_t)VM_KERNEL_ADDRPERM(ln
), 
 888                                     ip6_sprintf(&dst
->sin6_addr
), ifp
->if_index
, 
 892                         struct nd_ifinfo 
*ndi 
= ND_IFINFO(ifp
); 
 893                         VERIFY(ndi
->initialized
); 
 894                         retrans 
= ndi
->retrans
; 
 897                 lck_rw_done(nd_if_rwlock
); 
 899                 RT_LOCK_ASSERT_HELD(rt
); 
 901                 switch (ln
->ln_state
) { 
 902                 case ND6_LLINFO_INCOMPLETE
: 
 903                         if (ln
->ln_asked 
< nd6_mmaxtries
) { 
 904                                 struct ifnet 
*exclifp 
= ln
->ln_exclifp
; 
 906                                 ln_setexpire(ln
, timenow 
+ retrans 
/ 1000); 
 907                                 RT_ADDREF_LOCKED(rt
); 
 909                                 lck_mtx_unlock(rnh_lock
); 
 910                                 if (ip6_forwarding
) { 
 911                                         nd6_prproxy_ns_output(ifp
, exclifp
, 
 912                                             NULL
, &dst
->sin6_addr
, ln
); 
 914                                         nd6_ns_output(ifp
, NULL
, 
 915                                             &dst
->sin6_addr
, ln
, 0); 
 919                                 lck_mtx_lock(rnh_lock
); 
 921                                 struct mbuf 
*m 
= ln
->ln_hold
; 
 925                                          * Fake rcvif to make ICMP error 
 926                                          * more helpful in diagnosing 
 928                                          * XXX: should we consider 
 931                                         m
->m_pkthdr
.rcvif 
= ifp
; 
 932                                         RT_ADDREF_LOCKED(rt
); 
 934                                         lck_mtx_unlock(rnh_lock
); 
 935                                         icmp6_error(m
, ICMP6_DST_UNREACH
, 
 936                                             ICMP6_DST_UNREACH_ADDR
, 0); 
 938                                         RT_ADDREF_LOCKED(rt
); 
 940                                         lck_mtx_unlock(rnh_lock
); 
 944                                 lck_mtx_lock(rnh_lock
); 
 947                         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
 950                 case ND6_LLINFO_REACHABLE
: 
 951                         if (ln
->ln_expire 
!= 0) { 
 952                                 ln
->ln_state 
= ND6_LLINFO_STALE
; 
 953                                 ln_setexpire(ln
, timenow 
+ nd6_gctimer
); 
 959                 case ND6_LLINFO_STALE
: 
 960                 case ND6_LLINFO_PURGE
: 
 961                         /* Garbage Collection(RFC 4861 5.3) */ 
 962                         if (ln
->ln_expire 
!= 0) { 
 963                                 RT_ADDREF_LOCKED(rt
); 
 965                                 lck_mtx_unlock(rnh_lock
); 
 968                                 lck_mtx_lock(rnh_lock
); 
 976                 case ND6_LLINFO_DELAY
: 
 977                         if ((flags 
& ND6_IFF_PERFORMNUD
) != 0) { 
 980                                 ln
->ln_state 
= ND6_LLINFO_PROBE
; 
 981                                 ln_setexpire(ln
, timenow 
+ retrans 
/ 1000); 
 982                                 RT_ADDREF_LOCKED(rt
); 
 984                                 lck_mtx_unlock(rnh_lock
); 
 985                                 nd6_ns_output(ifp
, &dst
->sin6_addr
, 
 986                                     &dst
->sin6_addr
, ln
, 0); 
 989                                 lck_mtx_lock(rnh_lock
); 
 992                         ln
->ln_state 
= ND6_LLINFO_STALE
; /* XXX */ 
 993                         ln_setexpire(ln
, timenow 
+ nd6_gctimer
); 
 998                 case ND6_LLINFO_PROBE
: 
 999                         if (ln
->ln_asked 
< nd6_umaxtries
) { 
1001                                 ln_setexpire(ln
, timenow 
+ retrans 
/ 1000); 
1002                                 RT_ADDREF_LOCKED(rt
); 
1004                                 lck_mtx_unlock(rnh_lock
); 
1005                                 nd6_ns_output(ifp
, &dst
->sin6_addr
, 
1006                                     &dst
->sin6_addr
, ln
, 0); 
1009                                 lck_mtx_lock(rnh_lock
); 
1011                                 RT_ADDREF_LOCKED(rt
); 
1013                                 lck_mtx_unlock(rnh_lock
); 
1016                                 lck_mtx_lock(rnh_lock
); 
1019                         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
1028         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
1030         /* Now clear the flag from all entries */ 
1031         ln 
= llinfo_nd6
.ln_next
; 
1032         while (ln 
!= NULL 
&& ln 
!= &llinfo_nd6
) { 
1033                 struct rtentry 
*rt 
= ln
->ln_rt
; 
1034                 struct llinfo_nd6 
*next 
= ln
->ln_next
; 
1037                 if (ln
->ln_flags 
& ND6_LNF_TIMER_SKIP
) 
1038                         ln
->ln_flags 
&= ~ND6_LNF_TIMER_SKIP
; 
1042         lck_mtx_unlock(rnh_lock
); 
1044         /* expire default router list */ 
1045         lck_mtx_lock(nd6_mutex
); 
1046         dr 
= TAILQ_FIRST(&nd_defrouter
); 
1049                 if (dr
->expire 
!= 0 && dr
->expire 
< timenow
) { 
1050                         struct nd_defrouter 
*t
; 
1051                         t 
= TAILQ_NEXT(dr
, dr_entry
); 
1056                         if (dr
->expire 
== 0 || (dr
->stateflags 
& NDDRF_STATIC
)) 
1060                         dr 
= TAILQ_NEXT(dr
, dr_entry
); 
1063         lck_mtx_unlock(nd6_mutex
); 
1066          * expire interface addresses. 
1067          * in the past the loop was inside prefix expiry processing. 
1068          * However, from a stricter speci-confrmance standpoint, we should 
1069          * rather separate address lifetimes and prefix lifetimes. 
1072         lck_rw_lock_exclusive(&in6_ifaddr_rwlock
); 
1073         for (ia6 
= in6_ifaddrs
; ia6
; ia6 
= nia6
) { 
1075                 nia6 
= ia6
->ia_next
; 
1076                 IFA_LOCK(&ia6
->ia_ifa
); 
1078                  * Extra reference for ourselves; it's no-op if 
1079                  * we don't have to regenerate temporary address, 
1080                  * otherwise it protects the address from going 
1081                  * away since we drop in6_ifaddr_rwlock below. 
1083                 IFA_ADDREF_LOCKED(&ia6
->ia_ifa
); 
1084                 /* check address lifetime */ 
1085                 if (IFA6_IS_INVALID(ia6
, timenow
)) { 
1087                          * If the expiring address is temporary, try 
1088                          * regenerating a new one.  This would be useful when 
1089                          * we suspended a laptop PC, then turned it on after a 
1090                          * period that could invalidate all temporary 
1091                          * addresses.  Although we may have to restart the 
1092                          * loop (see below), it must be after purging the 
1093                          * address.  Otherwise, we'd see an infinite loop of 
1096                         if (ip6_use_tempaddr 
&& 
1097                             (ia6
->ia6_flags 
& IN6_IFF_TEMPORARY
) != 0) { 
1099                                  * NOTE: We have to drop the lock here 
1100                                  * because regen_tmpaddr() eventually calls 
1101                                  * in6_update_ifa(), which must take the lock 
1102                                  * and would otherwise cause a hang.  This is 
1103                                  * safe because the goto addrloop leads to a 
1104                                  * re-evaluation of the in6_ifaddrs list 
1106                                 IFA_UNLOCK(&ia6
->ia_ifa
); 
1107                                 lck_rw_done(&in6_ifaddr_rwlock
); 
1108                                 (void) regen_tmpaddr(ia6
); 
1110                                 IFA_UNLOCK(&ia6
->ia_ifa
); 
1111                                 lck_rw_done(&in6_ifaddr_rwlock
); 
1115                          * Purging the address would have caused 
1116                          * in6_ifaddr_rwlock to be dropped and reacquired; 
1117                          * therefore search again from the beginning 
1118                          * of in6_ifaddrs list. 
1120                         in6_purgeaddr(&ia6
->ia_ifa
); 
1123                         /* Release extra reference taken above */ 
1124                         IFA_REMREF(&ia6
->ia_ifa
); 
1128                  * The lazy timer runs every nd6_prune_lazy seconds with at 
1129                  * most "2 * nd6_prune_lazy - 1" leeway. We consider the worst 
1130                  * case here and make sure we schedule the regular timer if an 
1131                  * interface address is about to expire. 
1133                 if (IFA6_IS_INVALID(ia6
, timenow 
+ 3 * nd6_prune_lazy
)) 
1137                 IFA_LOCK_ASSERT_HELD(&ia6
->ia_ifa
); 
1138                 if (IFA6_IS_DEPRECATED(ia6
, timenow
)) { 
1139                         int oldflags 
= ia6
->ia6_flags
; 
1141                         ia6
->ia6_flags 
|= IN6_IFF_DEPRECATED
; 
1144                          * If a temporary address has just become deprecated, 
1145                          * regenerate a new one if possible. 
1147                         if (ip6_use_tempaddr 
&& 
1148                             (ia6
->ia6_flags 
& IN6_IFF_TEMPORARY
) != 0 && 
1149                             (oldflags 
& IN6_IFF_DEPRECATED
) == 0) { 
1151                                 /* see NOTE above */ 
1152                                 IFA_UNLOCK(&ia6
->ia_ifa
); 
1153                                 lck_rw_done(&in6_ifaddr_rwlock
); 
1154                                 if (regen_tmpaddr(ia6
) == 0) { 
1156                                          * A new temporary address is 
1158                                          * XXX: this means the address chain 
1159                                          * has changed while we are still in 
1160                                          * the loop.  Although the change 
1161                                          * would not cause disaster (because 
1162                                          * it's not a deletion, but an 
1163                                          * addition,) we'd rather restart the 
1164                                          * loop just for safety.  Or does this 
1165                                          * significantly reduce performance?? 
1167                                         /* Release extra reference */ 
1168                                         IFA_REMREF(&ia6
->ia_ifa
); 
1171                                 lck_rw_lock_exclusive(&in6_ifaddr_rwlock
); 
1173                                 IFA_UNLOCK(&ia6
->ia_ifa
); 
1177                          * A new RA might have made a deprecated address 
1180                         ia6
->ia6_flags 
&= ~IN6_IFF_DEPRECATED
; 
1181                         IFA_UNLOCK(&ia6
->ia_ifa
); 
1183                 lck_rw_assert(&in6_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1184                 /* Release extra reference taken above */ 
1185                 IFA_REMREF(&ia6
->ia_ifa
); 
1187         lck_rw_done(&in6_ifaddr_rwlock
); 
1189         lck_mtx_lock(nd6_mutex
); 
1190         /* expire prefix list */ 
1191         pr 
= nd_prefix
.lh_first
; 
1192         while (pr 
!= NULL
) { 
1195                  * check prefix lifetime. 
1196                  * since pltime is just for autoconf, pltime processing for 
1197                  * prefix is not necessary. 
1200                 if (pr
->ndpr_stateflags 
& NDPRF_PROCESSED_SERVICE 
|| 
1201                     pr
->ndpr_stateflags 
& NDPRF_DEFUNCT
) { 
1202                         pr
->ndpr_stateflags 
|= NDPRF_PROCESSED_SERVICE
; 
1207                 if (pr
->ndpr_expire 
!= 0 && pr
->ndpr_expire 
< timenow
) { 
1209                          * address expiration and prefix expiration are 
1210                          * separate.  NEVER perform in6_purgeaddr here. 
1212                         pr
->ndpr_stateflags 
|= NDPRF_PROCESSED_SERVICE
; 
1213                         NDPR_ADDREF_LOCKED(pr
); 
1217                         pfxlist_onlink_check(); 
1218                         pr 
= nd_prefix
.lh_first
; 
1221                         if (pr
->ndpr_expire 
== 0 || 
1222                             (pr
->ndpr_stateflags 
& NDPRF_STATIC
)) 
1226                         pr
->ndpr_stateflags 
|= NDPRF_PROCESSED_SERVICE
; 
1231         LIST_FOREACH(pr
, &nd_prefix
, ndpr_entry
) { 
1233                 pr
->ndpr_stateflags 
&= ~NDPRF_PROCESSED_SERVICE
; 
1236         lck_mtx_unlock(nd6_mutex
); 
1238         lck_mtx_lock(rnh_lock
); 
1239         /* We're done; let others enter */ 
1240         nd6_service_busy 
= FALSE
; 
1241         if (nd6_service_waiters 
> 0) { 
1242                 nd6_service_waiters 
= 0; 
1243                 wakeup(nd6_service_wc
); 
1248 nd6_drain(void *arg
) 
1251         struct nd6svc_arg sarg
; 
1253         nd6log2((LOG_DEBUG
, "%s: draining ND6 entries\n", __func__
)); 
1255         lck_mtx_lock(rnh_lock
); 
1256         bzero(&sarg
, sizeof (sarg
)); 
1259         nd6log2((LOG_DEBUG
, "%s: found %u, aging_lazy %u, aging %u, " 
1260             "sticky %u, killed %u\n", __func__
, sarg
.found
, sarg
.aging_lazy
, 
1261             sarg
.aging
, sarg
.sticky
, sarg
.killed
)); 
1262         lck_mtx_unlock(rnh_lock
); 
1266  * We use the ``arg'' variable to decide whether or not the timer we're 
1267  * running is the fast timer. We do this to reset the nd6_fast_timer_on 
1268  * variable so that later we don't end up ignoring a ``fast timer''  
1269  * request if the 5 second timer is running (see nd6_sched_timeout). 
1272 nd6_timeout(void *arg
) 
1274         struct nd6svc_arg sarg
; 
1277         lck_mtx_lock(rnh_lock
); 
1278         bzero(&sarg
, sizeof (sarg
)); 
1280         nd6log2((LOG_DEBUG
, "%s: found %u, aging_lazy %u, aging %u, " 
1281             "sticky %u, killed %u\n", __func__
, sarg
.found
, sarg
.aging_lazy
, 
1282             sarg
.aging
, sarg
.sticky
, sarg
.killed
)); 
1283         /* re-arm the timer if there's work to do */ 
1285         VERIFY(nd6_timeout_run 
>= 0 && nd6_timeout_run 
< 2); 
1286         if (arg 
== &nd6_fast_timer_on
) 
1287                 nd6_fast_timer_on 
= FALSE
; 
1288         if (sarg
.aging_lazy 
> 0 || sarg
.aging 
> 0 || nd6_sched_timeout_want
) { 
1289                 struct timeval atv
, ltv
, *leeway
; 
1290                 int lazy 
= nd6_prune_lazy
; 
1292                 if (sarg
.aging 
> 0 || lazy 
< 1) { 
1294                         atv
.tv_sec 
= nd6_prune
; 
1299                         atv
.tv_sec 
= MAX(nd6_prune
, lazy
); 
1301                         read_frandom(&buf
, sizeof(buf
)); 
1302                         ltv
.tv_sec 
= MAX(buf 
% lazy
, 1) * 2; 
1305                 nd6_sched_timeout(&atv
, leeway
); 
1306         } else if (nd6_debug
) { 
1307                 nd6log2((LOG_DEBUG
, "%s: not rescheduling timer\n", __func__
)); 
1309         lck_mtx_unlock(rnh_lock
); 
1313 nd6_sched_timeout(struct timeval 
*atv
, struct timeval 
*ltv
) 
1317         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
1320                 tv
.tv_sec 
= MAX(nd6_prune
, 1); 
1322                 ltv 
= NULL
;     /* ignore leeway */ 
1324         /* see comments on top of this file */ 
1325         if (nd6_timeout_run 
== 0) { 
1327                         nd6log2((LOG_DEBUG
, "%s: timer scheduled in " 
1328                             "T+%llus.%lluu (demand %d)\n", __func__
, 
1329                             (uint64_t)atv
->tv_sec
, (uint64_t)atv
->tv_usec
, 
1330                             nd6_sched_timeout_want
)); 
1331                         nd6_fast_timer_on 
= TRUE
; 
1332                         timeout(nd6_timeout
, &nd6_fast_timer_on
, tvtohz(atv
)); 
1334                         nd6log2((LOG_DEBUG
, "%s: timer scheduled in " 
1335                             "T+%llus.%lluu with %llus.%lluu leeway " 
1336                             "(demand %d)\n", __func__
, (uint64_t)atv
->tv_sec
, 
1337                             (uint64_t)atv
->tv_usec
, (uint64_t)ltv
->tv_sec
, 
1338                             (uint64_t)ltv
->tv_usec
, nd6_sched_timeout_want
)); 
1339                         nd6_fast_timer_on 
= FALSE
; 
1340                         timeout_with_leeway(nd6_timeout
, NULL
, 
1341                             tvtohz(atv
), tvtohz(ltv
)); 
1344                 nd6_sched_timeout_want 
= 0; 
1345         } else if (nd6_timeout_run 
== 1 && ltv 
== NULL 
&&  
1346             nd6_fast_timer_on 
== FALSE
) { 
1347                 nd6log2((LOG_DEBUG
, "%s: fast timer scheduled in " 
1348                     "T+%llus.%lluu (demand %d)\n", __func__
, 
1349                     (uint64_t)atv
->tv_sec
, (uint64_t)atv
->tv_usec
, 
1350                     nd6_sched_timeout_want
)); 
1351                 nd6_fast_timer_on 
= TRUE
; 
1352                 nd6_sched_timeout_want 
= 0; 
1354                 timeout(nd6_timeout
, &nd6_fast_timer_on
, tvtohz(atv
)); 
1357                         nd6log2((LOG_DEBUG
, "%s: not scheduling timer: " 
1358                             "timers %d, fast_timer %d, T+%llus.%lluu\n", 
1359                             __func__
, nd6_timeout_run
, nd6_fast_timer_on
, 
1360                             (uint64_t)atv
->tv_sec
, (uint64_t)atv
->tv_usec
)); 
1362                         nd6log2((LOG_DEBUG
, "%s: not scheduling timer: " 
1363                             "timers %d, fast_timer %d, T+%llus.%lluu " 
1364                             "with %llus.%lluu leeway\n", __func__
, 
1365                             nd6_timeout_run
, nd6_fast_timer_on
, 
1366                             (uint64_t)atv
->tv_sec
, (uint64_t)atv
->tv_usec
, 
1367                             (uint64_t)ltv
->tv_sec
, (uint64_t)ltv
->tv_usec
)); 
1373  * ND6 router advertisement kernel notification 
1376 nd6_post_msg(u_int32_t code
, struct nd_prefix_list 
*prefix_list
, 
1377     u_int32_t list_length
, u_int32_t mtu
, char *dl_addr
, u_int32_t dl_addr_len
) 
1379         struct kev_msg ev_msg
; 
1380         struct kev_nd6_ra_data nd6_ra_msg_data
; 
1381         struct nd_prefix_list 
*itr 
= prefix_list
; 
1383         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
1384         ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
1385         ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
1386         ev_msg
.kev_subclass     
= KEV_ND6_SUBCLASS
; 
1387         ev_msg
.event_code       
= code
; 
1389         bzero(&nd6_ra_msg_data
, sizeof (nd6_ra_msg_data
)); 
1390         nd6_ra_msg_data
.lladdrlen 
= (dl_addr_len 
<= ND6_ROUTER_LL_SIZE
) ? 
1391             dl_addr_len 
: ND6_ROUTER_LL_SIZE
; 
1392         bcopy(dl_addr
, &nd6_ra_msg_data
.lladdr
, nd6_ra_msg_data
.lladdrlen
); 
1394         if (mtu 
> 0 && mtu 
>= IPV6_MMTU
) { 
1395                 nd6_ra_msg_data
.mtu 
= mtu
; 
1396                 nd6_ra_msg_data
.flags 
|= KEV_ND6_DATA_VALID_MTU
; 
1399         if (list_length 
> 0 && prefix_list 
!= NULL
) { 
1400                 nd6_ra_msg_data
.list_length 
= list_length
; 
1401                 nd6_ra_msg_data
.flags 
|= KEV_ND6_DATA_VALID_PREFIX
; 
1404         while (itr 
!= NULL 
&& nd6_ra_msg_data
.list_index 
< list_length
) { 
1405                 bcopy(&itr
->pr
.ndpr_prefix
, &nd6_ra_msg_data
.prefix
.prefix
, 
1406                     sizeof (nd6_ra_msg_data
.prefix
.prefix
)); 
1407                 nd6_ra_msg_data
.prefix
.raflags 
= itr
->pr
.ndpr_raf
; 
1408                 nd6_ra_msg_data
.prefix
.prefixlen 
= itr
->pr
.ndpr_plen
; 
1409                 nd6_ra_msg_data
.prefix
.origin 
= PR_ORIG_RA
; 
1410                 nd6_ra_msg_data
.prefix
.vltime 
= itr
->pr
.ndpr_vltime
; 
1411                 nd6_ra_msg_data
.prefix
.pltime 
= itr
->pr
.ndpr_pltime
; 
1412                 nd6_ra_msg_data
.prefix
.expire 
= ndpr_getexpire(&itr
->pr
); 
1413                 nd6_ra_msg_data
.prefix
.flags 
= itr
->pr
.ndpr_stateflags
; 
1414                 nd6_ra_msg_data
.prefix
.refcnt 
= itr
->pr
.ndpr_addrcnt
; 
1415                 nd6_ra_msg_data
.prefix
.if_index 
= itr
->pr
.ndpr_ifp
->if_index
; 
1417                 /* send the message up */ 
1418                 ev_msg
.dv
[0].data_ptr           
= &nd6_ra_msg_data
; 
1419                 ev_msg
.dv
[0].data_length        
= sizeof (nd6_ra_msg_data
); 
1420                 ev_msg
.dv
[1].data_length        
= 0; 
1421                 kev_post_msg(&ev_msg
); 
1423                 /* clean up for the next prefix */ 
1424                 bzero(&nd6_ra_msg_data
.prefix
, sizeof (nd6_ra_msg_data
.prefix
)); 
1426                 nd6_ra_msg_data
.list_index
++; 
1431  * Regenerate deprecated/invalidated temporary address 
1434 regen_tmpaddr(struct in6_ifaddr 
*ia6
) 
1438         struct in6_ifaddr 
*public_ifa6 
= NULL
; 
1439         uint64_t timenow 
= net_uptime(); 
1441         ifp 
= ia6
->ia_ifa
.ifa_ifp
; 
1442         ifnet_lock_shared(ifp
); 
1443         TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_list
) { 
1444                 struct in6_ifaddr 
*it6
; 
1447                 if (ifa
->ifa_addr
->sa_family 
!= AF_INET6
) { 
1451                 it6 
= (struct in6_ifaddr 
*)ifa
; 
1453                 /* ignore no autoconf addresses. */ 
1454                 if ((it6
->ia6_flags 
& IN6_IFF_AUTOCONF
) == 0) { 
1458                 /* ignore autoconf addresses with different prefixes. */ 
1459                 if (it6
->ia6_ndpr 
== NULL 
|| it6
->ia6_ndpr 
!= ia6
->ia6_ndpr
) { 
1464                  * Now we are looking at an autoconf address with the same 
1465                  * prefix as ours.  If the address is temporary and is still 
1466                  * preferred, do not create another one.  It would be rare, but 
1467                  * could happen, for example, when we resume a laptop PC after 
1470                 if ((it6
->ia6_flags 
& IN6_IFF_TEMPORARY
) != 0 && 
1471                     !IFA6_IS_DEPRECATED(it6
, timenow
)) { 
1473                         if (public_ifa6 
!= NULL
) 
1474                                 IFA_REMREF(&public_ifa6
->ia_ifa
); 
1480                  * This is a public autoconf address that has the same prefix 
1481                  * as ours.  If it is preferred, keep it.  We can't break the 
1482                  * loop here, because there may be a still-preferred temporary 
1483                  * address with the prefix. 
1485                 if (!IFA6_IS_DEPRECATED(it6
, timenow
)) { 
1486                         IFA_ADDREF_LOCKED(ifa
); /* for public_ifa6 */ 
1488                         if (public_ifa6 
!= NULL
) 
1489                                 IFA_REMREF(&public_ifa6
->ia_ifa
); 
1495         ifnet_lock_done(ifp
); 
1497         if (public_ifa6 
!= NULL
) { 
1500                 if ((e 
= in6_tmpifadd(public_ifa6
, 0)) != 0) { 
1501                         log(LOG_NOTICE
, "regen_tmpaddr: failed to create a new" 
1502                             " tmp addr,errno=%d\n", e
); 
1503                         IFA_REMREF(&public_ifa6
->ia_ifa
); 
1506                 IFA_REMREF(&public_ifa6
->ia_ifa
); 
1514  * Nuke neighbor cache/prefix/default router management table, right before 
1518 nd6_purge(struct ifnet 
*ifp
) 
1520         struct llinfo_nd6 
*ln
; 
1521         struct nd_defrouter 
*dr
, *ndr
; 
1522         struct nd_prefix 
*pr
, *npr
; 
1525         /* Nuke default router list entries toward ifp */ 
1526         lck_mtx_lock(nd6_mutex
); 
1527         if ((dr 
= TAILQ_FIRST(&nd_defrouter
)) != NULL
) { 
1529                  * The first entry of the list may be stored in 
1530                  * the routing table, so we'll delete it later. 
1532                 for (dr 
= TAILQ_NEXT(dr
, dr_entry
); dr
; dr 
= ndr
) { 
1533                         ndr 
= TAILQ_NEXT(dr
, dr_entry
); 
1534                         if (dr
->stateflags 
& NDDRF_INSTALLED
) 
1539                 dr 
= TAILQ_FIRST(&nd_defrouter
); 
1544         for (dr 
= TAILQ_FIRST(&nd_defrouter
); dr
; dr 
= ndr
) { 
1545                 ndr 
= TAILQ_NEXT(dr
, dr_entry
); 
1546                 if (!(dr
->stateflags 
& NDDRF_INSTALLED
)) 
1553         /* Nuke prefix list entries toward ifp */ 
1555         for (pr 
= nd_prefix
.lh_first
; pr
; pr 
= npr
) { 
1557                 npr 
= pr
->ndpr_next
; 
1558                 if (pr
->ndpr_ifp 
== ifp 
&&  
1559                     !(pr
->ndpr_stateflags 
& NDPRF_DEFUNCT
)) { 
1561                          * Because if_detach() does *not* release prefixes 
1562                          * while purging addresses the reference count will 
1563                          * still be above zero. We therefore reset it to 
1564                          * make sure that the prefix really gets purged. 
1566                         pr
->ndpr_addrcnt 
= 0; 
1569                          * Previously, pr->ndpr_addr is removed as well, 
1570                          * but I strongly believe we don't have to do it. 
1571                          * nd6_purge() is only called from in6_ifdetach(), 
1572                          * which removes all the associated interface addresses 
1574                          * (jinmei@kame.net 20010129) 
1576                         NDPR_ADDREF_LOCKED(pr
); 
1581                         npr 
= nd_prefix
.lh_first
; 
1587                 pfxlist_onlink_check(); 
1588         lck_mtx_unlock(nd6_mutex
); 
1590         /* cancel default outgoing interface setting */ 
1591         if (nd6_defifindex 
== ifp
->if_index
) { 
1592                 nd6_setdefaultiface(0); 
1596          * Perform default router selection even when we are a router, 
1597          * if Scoped Routing is enabled. 
1599         if (ip6_doscopedroute 
|| !ip6_forwarding
) { 
1600                 lck_mtx_lock(nd6_mutex
); 
1601                 /* refresh default router list */ 
1602                 defrouter_select(ifp
); 
1603                 lck_mtx_unlock(nd6_mutex
); 
1607          * Nuke neighbor cache entries for the ifp. 
1608          * Note that rt->rt_ifp may not be the same as ifp, 
1609          * due to KAME goto ours hack.  See RTM_RESOLVE case in 
1610          * nd6_rtrequest(), and ip6_input(). 
1613         lck_mtx_lock(rnh_lock
); 
1614         ln 
= llinfo_nd6
.ln_next
; 
1615         while (ln 
!= NULL 
&& ln 
!= &llinfo_nd6
) { 
1617                 struct llinfo_nd6 
*nln
; 
1622                 if (rt
->rt_gateway 
!= NULL 
&& 
1623                     rt
->rt_gateway
->sa_family 
== AF_LINK 
&& 
1624                     SDL(rt
->rt_gateway
)->sdl_index 
== ifp
->if_index
) { 
1625                         RT_ADDREF_LOCKED(rt
); 
1627                         lck_mtx_unlock(rnh_lock
); 
1629                          * See comments on nd6_service() for reasons why 
1630                          * this loop is repeated; we bite the costs of 
1631                          * going thru the same llinfo_nd6 more than once 
1632                          * here, since this purge happens during detach, 
1633                          * and that unlike the timer case, it's possible 
1634                          * there's more than one purges happening at the 
1635                          * same time (thus a flag wouldn't buy anything). 
1639                         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
); 
1646         lck_mtx_unlock(rnh_lock
); 
1650  * Upon success, the returned route will be locked and the caller is 
1651  * responsible for releasing the reference and doing RT_UNLOCK(rt). 
1652  * This routine does not require rnh_lock to be held by the caller, 
1653  * although it needs to be indicated of such a case in order to call 
1654  * the correct variant of the relevant routing routines. 
1657 nd6_lookup(struct in6_addr 
*addr6
, int create
, struct ifnet 
*ifp
, int rt_locked
) 
1660         struct sockaddr_in6 sin6
; 
1661         unsigned int ifscope
; 
1663         bzero(&sin6
, sizeof (sin6
)); 
1664         sin6
.sin6_len 
= sizeof (struct sockaddr_in6
); 
1665         sin6
.sin6_family 
= AF_INET6
; 
1666         sin6
.sin6_addr 
= *addr6
; 
1668         ifscope 
= (ifp 
!= NULL
) ? ifp
->if_index 
: IFSCOPE_NONE
; 
1670                 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
1671                 rt 
= rtalloc1_scoped_locked(SA(&sin6
), create
, 0, ifscope
); 
1673                 rt 
= rtalloc1_scoped(SA(&sin6
), create
, 0, ifscope
); 
1678                 if ((rt
->rt_flags 
& RTF_LLINFO
) == 0) { 
1680                          * This is the case for the default route. 
1681                          * If we want to create a neighbor cache for the 
1682                          * address, we should free the route for the 
1683                          * destination and allocate an interface route. 
1696                 if (create 
&& ifp
) { 
1698                         u_int32_t ifa_flags
; 
1702                          * If no route is available and create is set, 
1703                          * we allocate a host route for the destination 
1704                          * and treat it like an interface route. 
1705                          * This hack is necessary for a neighbor which can't 
1706                          * be covered by our own prefix. 
1708                         ifa 
= ifaof_ifpforaddr(SA(&sin6
), ifp
); 
1713                          * Create a new route.  RTF_LLINFO is necessary 
1714                          * to create a Neighbor Cache entry for the 
1715                          * destination in nd6_rtrequest which will be 
1716                          * called in rtrequest via ifa->ifa_rtrequest. 
1719                                 lck_mtx_lock(rnh_lock
); 
1721                         ifa_flags 
= ifa
->ifa_flags
; 
1723                         if ((e 
= rtrequest_scoped_locked(RTM_ADD
, 
1724                             SA(&sin6
), ifa
->ifa_addr
, SA(&all1_sa
), 
1725                             (ifa_flags 
| RTF_HOST 
| RTF_LLINFO
) & 
1726                             ~RTF_CLONING
, &rt
, ifscope
)) != 0) { 
1728                                         log(LOG_ERR
, "%s: failed to add route " 
1729                                             "for a neighbor(%s), errno=%d\n", 
1730                                             __func__
, ip6_sprintf(addr6
), e
); 
1733                                 lck_mtx_unlock(rnh_lock
); 
1739                         if (rt
->rt_llinfo
) { 
1740                                 struct llinfo_nd6 
*ln 
= rt
->rt_llinfo
; 
1741                                 ln
->ln_state 
= ND6_LLINFO_NOSTATE
; 
1747         RT_LOCK_ASSERT_HELD(rt
); 
1749          * Validation for the entry. 
1750          * Note that the check for rt_llinfo is necessary because a cloned 
1751          * route from a parent route that has the L flag (e.g. the default 
1752          * route to a p2p interface) may have the flag, too, while the 
1753          * destination is not actually a neighbor. 
1754          * XXX: we can't use rt->rt_ifp to check for the interface, since 
1755          *      it might be the loopback interface if the entry is for our 
1756          *      own address on a non-loopback interface. Instead, we should 
1757          *      use rt->rt_ifa->ifa_ifp, which would specify the REAL 
1759          * Note also that ifa_ifp and ifp may differ when we connect two 
1760          * interfaces to a same link, install a link prefix to an interface, 
1761          * and try to install a neighbor cache on an interface that does not 
1762          * have a route to the prefix. 
1764          * If the address is from a proxied prefix, the ifa_ifp and ifp might 
1765          * not match, because nd6_na_input() could have modified the ifp 
1766          * of the route to point to the interface where the NA arrived on, 
1767          * hence the test for RTF_PROXY. 
1769         if ((rt
->rt_flags 
& RTF_GATEWAY
) || (rt
->rt_flags 
& RTF_LLINFO
) == 0 || 
1770             rt
->rt_gateway
->sa_family 
!= AF_LINK 
|| rt
->rt_llinfo 
== NULL 
|| 
1771             (ifp 
&& rt
->rt_ifa
->ifa_ifp 
!= ifp 
&& 
1772             !(rt
->rt_flags 
& RTF_PROXY
))) { 
1773                 RT_REMREF_LOCKED(rt
); 
1776                         log(LOG_DEBUG
, "%s: failed to lookup %s " 
1777                             "(if = %s)\n", __func__
, ip6_sprintf(addr6
), 
1778                             ifp 
? if_name(ifp
) : "unspec"); 
1779                         /* xxx more logs... kazu */ 
1784          * Caller needs to release reference and call RT_UNLOCK(rt). 
1790  * Test whether a given IPv6 address is a neighbor or not, ignoring 
1791  * the actual neighbor cache.  The neighbor cache is ignored in order 
1792  * to not reenter the routing code from within itself. 
1795 nd6_is_new_addr_neighbor(struct sockaddr_in6 
*addr
, struct ifnet 
*ifp
) 
1797         struct nd_prefix 
*pr
; 
1798         struct ifaddr 
*dstaddr
; 
1800         lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
); 
1803          * A link-local address is always a neighbor. 
1804          * XXX: a link does not necessarily specify a single interface. 
1806         if (IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) { 
1807                 struct sockaddr_in6 sin6_copy
; 
1811                  * We need sin6_copy since sa6_recoverscope() may modify the 
1815                 if (sa6_recoverscope(&sin6_copy
, FALSE
)) 
1816                         return (0); /* XXX: should be impossible */ 
1817                 if (in6_setscope(&sin6_copy
.sin6_addr
, ifp
, &zone
)) 
1819                 if (sin6_copy
.sin6_scope_id 
== zone
) 
1826          * If the address matches one of our addresses, 
1827          * it should be a neighbor. 
1828          * If the address matches one of our on-link prefixes, it should be a 
1831         for (pr 
= nd_prefix
.lh_first
; pr
; pr 
= pr
->ndpr_next
) { 
1833                 if (pr
->ndpr_ifp 
!= ifp
) { 
1837                 if (!(pr
->ndpr_stateflags 
& NDPRF_ONLINK
)) { 
1841                 if (IN6_ARE_MASKED_ADDR_EQUAL(&pr
->ndpr_prefix
.sin6_addr
, 
1842                     &addr
->sin6_addr
, &pr
->ndpr_mask
)) { 
1850          * If the address is assigned on the node of the other side of 
1851          * a p2p interface, the address should be a neighbor. 
1853         dstaddr 
= ifa_ifwithdstaddr(SA(addr
)); 
1854         if (dstaddr 
!= NULL
) { 
1855                 if (dstaddr
->ifa_ifp 
== ifp
) { 
1856                         IFA_REMREF(dstaddr
); 
1859                 IFA_REMREF(dstaddr
); 
1864          * If the default router list is empty, all addresses are regarded 
1865          * as on-link, and thus, as a neighbor. 
1866          * XXX: we restrict the condition to hosts, because routers usually do 
1867          * not have the "default router list". 
1868          * XXX: this block should eventually be removed (it is disabled when 
1869          * Scoped Routing is in effect); treating all destinations as on-link 
1870          * in the absence of a router is rather harmful. 
1872         if (!ip6_doscopedroute 
&& !ip6_forwarding 
&& 
1873             TAILQ_FIRST(&nd_defrouter
) == NULL 
&& 
1874             nd6_defifindex 
== ifp
->if_index
) { 
1883  * Detect if a given IPv6 address identifies a neighbor on a given link. 
1884  * XXX: should take care of the destination of a p2p link? 
1887 nd6_is_addr_neighbor(struct sockaddr_in6 
*addr
, struct ifnet 
*ifp
, 
1892         lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_NOTOWNED
); 
1893         lck_mtx_lock(nd6_mutex
); 
1894         if (nd6_is_new_addr_neighbor(addr
, ifp
)) { 
1895                 lck_mtx_unlock(nd6_mutex
); 
1898         lck_mtx_unlock(nd6_mutex
); 
1901          * Even if the address matches none of our addresses, it might be 
1902          * in the neighbor cache. 
1904         if ((rt 
= nd6_lookup(&addr
->sin6_addr
, 0, ifp
, rt_locked
)) != NULL
) { 
1905                 RT_LOCK_ASSERT_HELD(rt
); 
1906                 RT_REMREF_LOCKED(rt
); 
1915  * Free an nd6 llinfo entry. 
1916  * Since the function would cause significant changes in the kernel, DO NOT 
1917  * make it global, unless you have a strong reason for the change, and are sure 
1918  * that the change is safe. 
1921 nd6_free(struct rtentry 
*rt
) 
1923         struct llinfo_nd6 
*ln
; 
1924         struct in6_addr in6
; 
1925         struct nd_defrouter 
*dr
; 
1927         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_NOTOWNED
); 
1928         RT_LOCK_ASSERT_NOTHELD(rt
); 
1929         lck_mtx_lock(nd6_mutex
); 
1932         RT_ADDREF_LOCKED(rt
);   /* Extra ref */ 
1934         in6 
= SIN6(rt_key(rt
))->sin6_addr
; 
1937          * Prevent another thread from modifying rt_key, rt_gateway 
1938          * via rt_setgate() after the rt_lock is dropped by marking 
1939          * the route as defunct. 
1941         rt
->rt_flags 
|= RTF_CONDEMNED
; 
1944          * We used to have pfctlinput(PRC_HOSTDEAD) here.  Even though it is 
1945          * not harmful, it was not really necessary.  Perform default router 
1946          * selection even when we are a router, if Scoped Routing is enabled. 
1948         if (ip6_doscopedroute 
|| !ip6_forwarding
) { 
1949                 dr 
= defrouter_lookup(&SIN6(rt_key(rt
))->sin6_addr
, rt
->rt_ifp
); 
1951                 if ((ln 
&& ln
->ln_router
) || dr
) { 
1953                          * rt6_flush must be called whether or not the neighbor 
1954                          * is in the Default Router List. 
1955                          * See a corresponding comment in nd6_na_input(). 
1958                         lck_mtx_unlock(nd6_mutex
); 
1959                         rt6_flush(&in6
, rt
->rt_ifp
); 
1960                         lck_mtx_lock(nd6_mutex
); 
1968                          * Unreachablity of a router might affect the default 
1969                          * router selection and on-link detection of advertised 
1974                          * Temporarily fake the state to choose a new default 
1975                          * router and to perform on-link determination of 
1976                          * prefixes correctly. 
1977                          * Below the state will be set correctly, 
1978                          * or the entry itself will be deleted. 
1981                         ln
->ln_state 
= ND6_LLINFO_INCOMPLETE
; 
1984                          * Since defrouter_select() does not affect the 
1985                          * on-link determination and MIP6 needs the check 
1986                          * before the default router selection, we perform 
1990                         pfxlist_onlink_check(); 
1993                          * refresh default router list 
1995                         defrouter_select(rt
->rt_ifp
); 
1997                 RT_LOCK_ASSERT_NOTHELD(rt
); 
2002         lck_mtx_unlock(nd6_mutex
); 
2004          * Detach the route from the routing tree and the list of neighbor 
2005          * caches, and disable the route entry not to be used in already 
2008         (void) rtrequest(RTM_DELETE
, rt_key(rt
), NULL
, rt_mask(rt
), 0, NULL
); 
2010         /* Extra ref held above; now free it */ 
2015 nd6_rtrequest(int req
, struct rtentry 
*rt
, struct sockaddr 
*sa
) 
2018         struct sockaddr 
*gate 
= rt
->rt_gateway
; 
2019         struct llinfo_nd6 
*ln 
= rt
->rt_llinfo
; 
2020         static struct sockaddr_dl null_sdl 
= 
2021             { .sdl_len 
= sizeof (null_sdl
), .sdl_family 
= AF_LINK 
}; 
2022         struct ifnet 
*ifp 
= rt
->rt_ifp
; 
2025         char buf
[MAX_IPv6_STR_LEN
]; 
2027         VERIFY(nd6_init_done
); 
2028         lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
2029         RT_LOCK_ASSERT_HELD(rt
); 
2032          * We have rnh_lock held, see if we need to schedule the timer; 
2033          * we might do this again below during RTM_RESOLVE, but doing it 
2034          * now handles all other cases. 
2036         if (nd6_sched_timeout_want
) 
2037                 nd6_sched_timeout(NULL
, NULL
); 
2039         if (rt
->rt_flags 
& RTF_GATEWAY
) 
2042         if (!nd6_need_cache(ifp
) && !(rt
->rt_flags 
& RTF_HOST
)) { 
2044                  * This is probably an interface direct route for a link 
2045                  * which does not need neighbor caches (e.g. fe80::%lo0/64). 
2046                  * We do not need special treatment below for such a route. 
2047                  * Moreover, the RTF_LLINFO flag which would be set below 
2048                  * would annoy the ndp(8) command. 
2053         if (req 
== RTM_RESOLVE
) { 
2056                 if (!nd6_need_cache(ifp
)) {     /* stf case */ 
2059                         struct sockaddr_in6 sin6
; 
2061                         rtkey_to_sa6(rt
, &sin6
); 
2063                          * nd6_is_addr_neighbor() may call nd6_lookup(), 
2064                          * therefore we drop rt_lock to avoid deadlock 
2065                          * during the lookup. 
2067                         RT_ADDREF_LOCKED(rt
); 
2069                         no_nd_cache 
= !nd6_is_addr_neighbor(&sin6
, ifp
, 1); 
2071                         RT_REMREF_LOCKED(rt
); 
2075                  * FreeBSD and BSD/OS often make a cloned host route based 
2076                  * on a less-specific route (e.g. the default route). 
2077                  * If the less specific route does not have a "gateway" 
2078                  * (this is the case when the route just goes to a p2p or an 
2079                  * stf interface), we'll mistakenly make a neighbor cache for 
2080                  * the host route, and will see strange neighbor solicitation 
2081                  * for the corresponding destination.  In order to avoid the 
2082                  * confusion, we check if the destination of the route is 
2083                  * a neighbor in terms of neighbor discovery, and stop the 
2084                  * process if not.  Additionally, we remove the LLINFO flag 
2085                  * so that ndp(8) will not try to get the neighbor information 
2086                  * of the destination. 
2089                         rt
->rt_flags 
&= ~RTF_LLINFO
; 
2094         timenow 
= net_uptime(); 
2099                  * There is no backward compatibility :) 
2101                  * if ((rt->rt_flags & RTF_HOST) == 0 && 
2102                  *      SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) 
2103                  *              rt->rt_flags |= RTF_CLONING; 
2105                 if ((rt
->rt_flags 
& RTF_CLONING
) || 
2106                     ((rt
->rt_flags 
& RTF_LLINFO
) && ln 
== NULL
)) { 
2108                          * Case 1: This route should come from a route to 
2109                          * interface (RTF_CLONING case) or the route should be 
2110                          * treated as on-link but is currently not 
2111                          * (RTF_LLINFO && ln == NULL case). 
2113                         if (rt_setgate(rt
, rt_key(rt
), SA(&null_sdl
)) == 0) { 
2114                                 gate 
= rt
->rt_gateway
; 
2115                                 SDL(gate
)->sdl_type 
= ifp
->if_type
; 
2116                                 SDL(gate
)->sdl_index 
= ifp
->if_index
; 
2118                                  * In case we're called before 1.0 sec. 
2123                                             (ifp
->if_eflags 
& IFEF_IPV6_ND6ALT
) 
2124                                             ? 0 : MAX(timenow
, 1)); 
2127                         if (rt
->rt_flags 
& RTF_CLONING
) 
2131                  * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here. 
2132                  * We don't do that here since llinfo is not ready yet. 
2134                  * There are also couple of other things to be discussed: 
2135                  * - unsolicited NA code needs improvement beforehand 
2136                  * - RFC4861 says we MAY send multicast unsolicited NA 
2137                  *   (7.2.6 paragraph 4), however, it also says that we 
2138                  *   SHOULD provide a mechanism to prevent multicast NA storm. 
2139                  *   we don't have anything like it right now. 
2140                  *   note that the mechanism needs a mutual agreement 
2141                  *   between proxies, which means that we need to implement 
2142                  *   a new protocol, or a new kludge. 
2143                  * - from RFC4861 6.2.4, host MUST NOT send an unsolicited RA. 
2144                  *   we need to check ip6forwarding before sending it. 
2145                  *   (or should we allow proxy ND configuration only for 
2146                  *   routers?  there's no mention about proxy ND from hosts) 
2150                 if (!(ifp
->if_flags 
& (IFF_POINTOPOINT 
| IFF_LOOPBACK
))) { 
2152                          * Address resolution isn't necessary for a point to 
2153                          * point link, so we can skip this test for a p2p link. 
2155                         if (gate
->sa_family 
!= AF_LINK 
|| 
2156                             gate
->sa_len 
< sizeof (null_sdl
)) { 
2157                                 /* Don't complain in case of RTM_ADD */ 
2158                                 if (req 
== RTM_RESOLVE
) { 
2159                                         log(LOG_ERR
, "%s: route to %s has bad " 
2160                                             "gateway address (sa_family %u " 
2161                                             "sa_len %u) on %s\n", __func__
, 
2163                                             &SIN6(rt_key(rt
))->sin6_addr
, buf
, 
2164                                             sizeof (buf
)), gate
->sa_family
, 
2165                                             gate
->sa_len
, if_name(ifp
)); 
2169                         SDL(gate
)->sdl_type 
= ifp
->if_type
; 
2170                         SDL(gate
)->sdl_index 
= ifp
->if_index
; 
2173                         break;  /* This happens on a route change */ 
2175                  * Case 2: This route may come from cloning, or a manual route 
2176                  * add with a LL address. 
2178                 rt
->rt_llinfo 
= ln 
= nd6_llinfo_alloc(M_WAITOK
); 
2183                 rt
->rt_llinfo_get_ri    
= nd6_llinfo_get_ri
; 
2184                 rt
->rt_llinfo_get_iflri 
= nd6_llinfo_get_iflri
; 
2185                 rt
->rt_llinfo_purge     
= nd6_llinfo_purge
; 
2186                 rt
->rt_llinfo_free      
= nd6_llinfo_free
; 
2187                 rt
->rt_flags 
|= RTF_LLINFO
; 
2189                 /* this is required for "ndp" command. - shin */ 
2190                 if (req 
== RTM_ADD
) { 
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. 
2196                         ln
->ln_state 
= ND6_LLINFO_REACHABLE
; 
2199                          * When req == RTM_RESOLVE, rt is created and 
2200                          * initialized in rtrequest(), so rt_expire is 0. 
2202                         ln
->ln_state 
= ND6_LLINFO_NOSTATE
; 
2204                         /* In case we're called before 1.0 sec. has elapsed */ 
2205                         ln_setexpire(ln
, (ifp
->if_eflags 
& IFEF_IPV6_ND6ALT
) ? 
2206                             0 : MAX(timenow
, 1)); 
2211                 /* We have at least one entry; arm the timer if not already */ 
2212                 nd6_sched_timeout(NULL
, NULL
); 
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 
2221                 if (ip6_neighborgcthresh 
> 0 && 
2222                     nd6_inuse 
>= ip6_neighborgcthresh
) { 
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
; 
2229                                 /* Move this entry to the head */ 
2232                                 LN_INSERTHEAD(ln_end
); 
2234                                 if (ln_end
->ln_expire 
== 0) { 
2238                                 if (ln_end
->ln_state 
> ND6_LLINFO_INCOMPLETE
) 
2239                                         ln_end
->ln_state 
= ND6_LLINFO_STALE
; 
2241                                         ln_end
->ln_state 
= ND6_LLINFO_PURGE
; 
2242                                 ln_setexpire(ln_end
, timenow
); 
2248                  * check if rt_key(rt) is one of my address assigned 
2251                 ifa 
= (struct ifaddr 
*)in6ifa_ifpwithaddr(rt
->rt_ifp
, 
2252                     &SIN6(rt_key(rt
))->sin6_addr
); 
2254                         caddr_t macp 
= nd6_ifptomac(ifp
); 
2255                         ln_setexpire(ln
, 0); 
2256                         ln
->ln_state 
= ND6_LLINFO_REACHABLE
; 
2258                                 Bcopy(macp
, LLADDR(SDL(gate
)), ifp
->if_addrlen
); 
2259                                 SDL(gate
)->sdl_alen 
= ifp
->if_addrlen
; 
2261                         if (nd6_useloopback
) { 
2262                                 if (rt
->rt_ifp 
!= lo_ifp
) { 
2264                                          * Purge any link-layer info caching. 
2266                                         if (rt
->rt_llinfo_purge 
!= NULL
) 
2267                                                 rt
->rt_llinfo_purge(rt
); 
2270                                          * Adjust route ref count for the 
2273                                         if (rt
->rt_if_ref_fn 
!= NULL
) { 
2274                                                 rt
->rt_if_ref_fn(lo_ifp
, 1); 
2275                                                 rt
->rt_if_ref_fn(rt
->rt_ifp
, 
2279                                 rt
->rt_ifp 
= lo_ifp
; 
2281                                  * If rmx_mtu is not locked, update it 
2282                                  * to the MTU used by the new interface. 
2284                                 if (!(rt
->rt_rmx
.rmx_locks 
& RTV_MTU
)) 
2285                                         rt
->rt_rmx
.rmx_mtu 
= rt
->rt_ifp
->if_mtu
; 
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. 
2294                                 if (ifa 
!= rt
->rt_ifa
) { 
2299                 } else if (rt
->rt_flags 
& RTF_ANNOUNCE
) { 
2300                         ln_setexpire(ln
, 0); 
2301                         ln
->ln_state 
= ND6_LLINFO_REACHABLE
; 
2303                         /* join solicited node multicast for proxy ND */ 
2304                         if (ifp
->if_flags 
& IFF_MULTICAST
) { 
2305                                 struct in6_addr llsol
; 
2306                                 struct in6_multi 
*in6m
; 
2309                                 llsol 
= SIN6(rt_key(rt
))->sin6_addr
; 
2310                                 llsol
.s6_addr32
[0] = IPV6_ADDR_INT32_MLL
; 
2311                                 llsol
.s6_addr32
[1] = 0; 
2312                                 llsol
.s6_addr32
[2] = htonl(1); 
2313                                 llsol
.s6_addr8
[12] = 0xff; 
2314                                 if (in6_setscope(&llsol
, ifp
, NULL
)) 
2316                                 error 
= in6_mc_join(ifp
, &llsol
, 
2319                                         nd6log((LOG_ERR
, "%s: failed to join " 
2320                                             "%s (errno=%d)\n", if_name(ifp
), 
2321                                             ip6_sprintf(&llsol
), error
)); 
2332                 /* leave from solicited node multicast for proxy ND */ 
2333                 if ((rt
->rt_flags 
& RTF_ANNOUNCE
) && 
2334                     (ifp
->if_flags 
& IFF_MULTICAST
)) { 
2335                         struct in6_addr llsol
; 
2336                         struct in6_multi 
*in6m
; 
2338                         llsol 
= SIN6(rt_key(rt
))->sin6_addr
; 
2339                         llsol
.s6_addr32
[0] = IPV6_ADDR_INT32_MLL
; 
2340                         llsol
.s6_addr32
[1] = 0; 
2341                         llsol
.s6_addr32
[2] = htonl(1); 
2342                         llsol
.s6_addr8
[12] = 0xff; 
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(); 
2348                                         in6_mc_leave(in6m
, NULL
); 
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. 
2360                 if (ln
->ln_flags 
& ND6_LNF_IN_USE
) 
2364                  * Purge any link-layer info caching. 
2366                 if (rt
->rt_llinfo_purge 
!= NULL
) 
2367                         rt
->rt_llinfo_purge(rt
); 
2369                 rt
->rt_flags 
&= ~RTF_LLINFO
; 
2370                 if (ln
->ln_hold 
!= NULL
) { 
2371                         m_freem(ln
->ln_hold
); 
2378 nd6_siocgdrlst(void *data
, int data_is_64
) 
2380         struct in6_drlist_32 
*drl_32
; 
2381         struct nd_defrouter 
*dr
; 
2384         lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
); 
2386         dr 
= TAILQ_FIRST(&nd_defrouter
); 
2388         /* For 64-bit process */ 
2390                 struct in6_drlist_64 
*drl_64
; 
2392                 drl_64 
= _MALLOC(sizeof (*drl_64
), M_TEMP
, M_WAITOK
|M_ZERO
); 
2396                 /* preserve the interface name */ 
2397                 bcopy(data
, drl_64
, sizeof (drl_64
->ifname
)); 
2399                 while (dr 
&& i 
< DRLSTSIZ
) { 
2400                         drl_64
->defrouter
[i
].rtaddr 
= dr
->rtaddr
; 
2401                         if (IN6_IS_ADDR_LINKLOCAL( 
2402                             &drl_64
->defrouter
[i
].rtaddr
)) { 
2403                                 /* XXX: need to this hack for KAME stack */ 
2404                                 drl_64
->defrouter
[i
].rtaddr
.s6_addr16
[1] = 0; 
2407                                     "default router list contains a " 
2408                                     "non-linklocal address(%s)\n", 
2409                                     ip6_sprintf(&drl_64
->defrouter
[i
].rtaddr
)); 
2411                         drl_64
->defrouter
[i
].flags 
= dr
->flags
; 
2412                         drl_64
->defrouter
[i
].rtlifetime 
= dr
->rtlifetime
; 
2413                         drl_64
->defrouter
[i
].expire 
= nddr_getexpire(dr
); 
2414                         drl_64
->defrouter
[i
].if_index 
= dr
->ifp
->if_index
; 
2416                         dr 
= TAILQ_NEXT(dr
, dr_entry
); 
2418                 bcopy(drl_64
, data
, sizeof (*drl_64
)); 
2419                 _FREE(drl_64
, M_TEMP
); 
2423         /* For 32-bit process */ 
2424         drl_32 
= _MALLOC(sizeof (*drl_32
), M_TEMP
, M_WAITOK
|M_ZERO
); 
2428         /* preserve the interface name */ 
2429         bcopy(data
, drl_32
, sizeof (drl_32
->ifname
)); 
2431         while (dr 
!= NULL 
&& i 
< DRLSTSIZ
) { 
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; 
2438                             "default router list contains a " 
2439                             "non-linklocal address(%s)\n", 
2440                             ip6_sprintf(&drl_32
->defrouter
[i
].rtaddr
)); 
2442                 drl_32
->defrouter
[i
].flags 
= dr
->flags
; 
2443                 drl_32
->defrouter
[i
].rtlifetime 
= dr
->rtlifetime
; 
2444                 drl_32
->defrouter
[i
].expire 
= nddr_getexpire(dr
); 
2445                 drl_32
->defrouter
[i
].if_index 
= dr
->ifp
->if_index
; 
2447                 dr 
= TAILQ_NEXT(dr
, dr_entry
); 
2449         bcopy(drl_32
, data
, sizeof (*drl_32
)); 
2450         _FREE(drl_32
, M_TEMP
); 
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? 
2460 nd6_siocgprlst(void *data
, int data_is_64
) 
2462         struct in6_prlist_32 
*prl_32
; 
2463         struct nd_prefix 
*pr
; 
2466         lck_mtx_assert(nd6_mutex
, LCK_MTX_ASSERT_OWNED
); 
2468         pr 
= nd_prefix
.lh_first
; 
2470         /* For 64-bit process */ 
2472                 struct in6_prlist_64 
*prl_64
; 
2474                 prl_64 
= _MALLOC(sizeof (*prl_64
), M_TEMP
, M_WAITOK
|M_ZERO
); 
2478                 /* preserve the interface name */ 
2479                 bcopy(data
, prl_64
, sizeof (prl_64
->ifname
)); 
2481                 while (pr 
&& i 
< PRLSTSIZ
) { 
2482                         struct nd_pfxrouter 
*pfr
; 
2486                         (void) in6_embedscope(&prl_64
->prefix
[i
].prefix
, 
2487                             &pr
->ndpr_prefix
, NULL
, NULL
, NULL
); 
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
; 
2493                         prl_64
->prefix
[i
].expire 
= ndpr_getexpire(pr
); 
2495                         pfr 
= pr
->ndpr_advrtrs
.lh_first
; 
2499 #define RTRADDR prl_64->prefix[i].advrtr[j] 
2500                                         RTRADDR 
= pfr
->router
->rtaddr
; 
2501                                         if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR
)) { 
2502                                                 /* XXX: hack for KAME */ 
2503                                                 RTRADDR
.s6_addr16
[1] = 0; 
2506                                                     "a router(%s) advertises " 
2508                                                     "non-link local address\n", 
2509                                                     ip6_sprintf(&RTRADDR
)); 
2514                                 pfr 
= pfr
->pfr_next
; 
2516                         prl_64
->prefix
[i
].advrtrs 
= j
; 
2517                         prl_64
->prefix
[i
].origin 
= PR_ORIG_RA
; 
2523                 bcopy(prl_64
, data
, sizeof (*prl_64
)); 
2524                 _FREE(prl_64
, M_TEMP
); 
2528         /* For 32-bit process */ 
2529         prl_32 
= _MALLOC(sizeof (*prl_32
), M_TEMP
, M_WAITOK
|M_ZERO
); 
2533         /* preserve the interface name */ 
2534         bcopy(data
, prl_32
, sizeof (prl_32
->ifname
)); 
2536         while (pr 
&& i 
< PRLSTSIZ
) { 
2537                 struct nd_pfxrouter 
*pfr
; 
2541                 (void) in6_embedscope(&prl_32
->prefix
[i
].prefix
, 
2542                     &pr
->ndpr_prefix
, NULL
, NULL
, NULL
); 
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
; 
2548                 prl_32
->prefix
[i
].expire 
= ndpr_getexpire(pr
); 
2550                 pfr 
= pr
->ndpr_advrtrs
.lh_first
; 
2554 #define RTRADDR prl_32->prefix[i].advrtr[j] 
2555                                 RTRADDR 
= pfr
->router
->rtaddr
; 
2556                                 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR
)) { 
2557                                         /* XXX: hack for KAME */ 
2558                                         RTRADDR
.s6_addr16
[1] = 0; 
2561                                             "a router(%s) advertises " 
2563                                             "non-link local address\n", 
2564                                             ip6_sprintf(&RTRADDR
)); 
2569                         pfr 
= pfr
->pfr_next
; 
2571                 prl_32
->prefix
[i
].advrtrs 
= j
; 
2572                 prl_32
->prefix
[i
].origin 
= PR_ORIG_RA
; 
2578         bcopy(prl_32
, data
, sizeof (*prl_32
)); 
2579         _FREE(prl_32
, M_TEMP
); 
2584 nd6_ioctl(u_long cmd
, caddr_t data
, struct ifnet 
*ifp
) 
2586         struct nd_defrouter 
*dr
; 
2587         struct nd_prefix 
*pr
; 
2591         VERIFY(ifp 
!= NULL
); 
2595         case SIOCGDRLST_IN6_32
:         /* struct in6_drlist_32 */ 
2596         case SIOCGDRLST_IN6_64
:         /* struct in6_drlist_64 */ 
2598                  * obsolete API, use sysctl under net.inet6.icmp6 
2600                 lck_mtx_lock(nd6_mutex
); 
2601                 error 
= nd6_siocgdrlst(data
, cmd 
== SIOCGDRLST_IN6_64
); 
2602                 lck_mtx_unlock(nd6_mutex
); 
2605         case SIOCGPRLST_IN6_32
:         /* struct in6_prlist_32 */ 
2606         case SIOCGPRLST_IN6_64
:         /* struct in6_prlist_64 */ 
2608                  * obsolete API, use sysctl under net.inet6.icmp6 
2610                 lck_mtx_lock(nd6_mutex
); 
2611                 error 
= nd6_siocgprlst(data
, cmd 
== SIOCGPRLST_IN6_64
); 
2612                 lck_mtx_unlock(nd6_mutex
); 
2615         case OSIOCGIFINFO_IN6
:          /* struct in6_ondireq */ 
2616         case SIOCGIFINFO_IN6
: {         /* struct in6_ondireq */ 
2618                 struct in6_ondireq 
*ondi 
= (struct in6_ondireq 
*)(void *)data
; 
2619                 struct nd_ifinfo 
*ndi
; 
2621                  * SIOCGIFINFO_IN6 ioctl is encoded with in6_ondireq 
2622                  * instead of in6_ndireq, so we treat it as such. 
2624                 lck_rw_lock_shared(nd_if_rwlock
); 
2625                 ndi 
= ND_IFINFO(ifp
); 
2626                 if (!nd_ifinfo 
|| i 
>= nd_ifinfo_indexlim 
|| 
2627                     !ndi
->initialized
) { 
2628                         lck_rw_done(nd_if_rwlock
); 
2632                 lck_mtx_lock(&ndi
->lock
); 
2633                 linkmtu 
= IN6_LINKMTU(ifp
); 
2634                 bcopy(&linkmtu
, &ondi
->ndi
.linkmtu
, sizeof (linkmtu
)); 
2635                 bcopy(&nd_ifinfo
[i
].maxmtu
, &ondi
->ndi
.maxmtu
, 
2636                     sizeof (u_int32_t
)); 
2637                 bcopy(&nd_ifinfo
[i
].basereachable
, &ondi
->ndi
.basereachable
, 
2638                     sizeof (u_int32_t
)); 
2639                 bcopy(&nd_ifinfo
[i
].reachable
, &ondi
->ndi
.reachable
, 
2640                     sizeof (u_int32_t
)); 
2641                 bcopy(&nd_ifinfo
[i
].retrans
, &ondi
->ndi
.retrans
, 
2642                     sizeof (u_int32_t
)); 
2643                 bcopy(&nd_ifinfo
[i
].flags
, &ondi
->ndi
.flags
, 
2644                     sizeof (u_int32_t
)); 
2645                 bcopy(&nd_ifinfo
[i
].recalctm
, &ondi
->ndi
.recalctm
, 
2647                 ondi
->ndi
.chlim 
= nd_ifinfo
[i
].chlim
; 
2648                 ondi
->ndi
.receivedra 
= 0; 
2649                 lck_mtx_unlock(&ndi
->lock
); 
2650                 lck_rw_done(nd_if_rwlock
); 
2654         case SIOCSIFINFO_FLAGS
: {       /* struct in6_ndireq */ 
2655                 struct in6_ndireq 
*cndi 
= (struct in6_ndireq 
*)(void *)data
; 
2656                 u_int32_t oflags
, flags
; 
2657                 struct nd_ifinfo 
*ndi
; 
2659                 /* XXX: almost all other fields of cndi->ndi is unused */ 
2660                 lck_rw_lock_shared(nd_if_rwlock
); 
2661                 ndi 
= ND_IFINFO(ifp
); 
2662                 if (!nd_ifinfo 
|| i 
>= nd_ifinfo_indexlim 
|| 
2663                     !ndi
->initialized
) { 
2664                         lck_rw_done(nd_if_rwlock
); 
2668                 lck_mtx_lock(&ndi
->lock
); 
2669                 oflags 
= nd_ifinfo
[i
].flags
; 
2670                 bcopy(&cndi
->ndi
.flags
, &nd_ifinfo
[i
].flags
, sizeof (flags
)); 
2671                 flags 
= nd_ifinfo
[i
].flags
; 
2672                 lck_mtx_unlock(&ndi
->lock
); 
2673                 lck_rw_done(nd_if_rwlock
); 
2675                 if (oflags 
== flags
) 
2678                 error 
= nd6_setifinfo(ifp
, oflags
, flags
); 
2682         case SIOCSNDFLUSH_IN6
:          /* struct in6_ifreq */ 
2683                 /* flush default router list */ 
2685                  * xxx sumikawa: should not delete route if default 
2686                  * route equals to the top of default router list 
2688                 lck_mtx_lock(nd6_mutex
); 
2690                 defrouter_select(ifp
); 
2691                 lck_mtx_unlock(nd6_mutex
); 
2692                 /* xxx sumikawa: flush prefix list */ 
2695         case SIOCSPFXFLUSH_IN6
: {       /* struct in6_ifreq */ 
2696                 /* flush all the prefix advertised by routers */ 
2697                 struct nd_prefix 
*next
; 
2699                 lck_mtx_lock(nd6_mutex
); 
2700                 for (pr 
= nd_prefix
.lh_first
; pr
; pr 
= next
) { 
2701                         struct in6_ifaddr 
*ia
; 
2703                         next 
= pr
->ndpr_next
; 
2706                         if (IN6_IS_ADDR_LINKLOCAL(&pr
->ndpr_prefix
.sin6_addr
)) { 
2710                         if (ifp 
!= lo_ifp 
&& pr
->ndpr_ifp 
!= ifp
) { 
2714                         /* do we really have to remove addresses as well? */ 
2715                         NDPR_ADDREF_LOCKED(pr
); 
2717                         lck_rw_lock_exclusive(&in6_ifaddr_rwlock
); 
2719                         while (ia 
!= NULL
) { 
2720                                 IFA_LOCK(&ia
->ia_ifa
); 
2721                                 if ((ia
->ia6_flags 
& IN6_IFF_AUTOCONF
) == 0) { 
2722                                         IFA_UNLOCK(&ia
->ia_ifa
); 
2727                                 if (ia
->ia6_ndpr 
== pr
) { 
2728                                         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
2729                                         IFA_UNLOCK(&ia
->ia_ifa
); 
2730                                         lck_rw_done(&in6_ifaddr_rwlock
); 
2731                                         lck_mtx_unlock(nd6_mutex
); 
2732                                         in6_purgeaddr(&ia
->ia_ifa
); 
2733                                         IFA_REMREF(&ia
->ia_ifa
); 
2734                                         lck_mtx_lock(nd6_mutex
); 
2735                                         lck_rw_lock_exclusive( 
2736                                             &in6_ifaddr_rwlock
); 
2738                                          * Purging the address caused 
2739                                          * in6_ifaddr_rwlock to be 
2741                                          * reacquired; therefore search again 
2742                                          * from the beginning of in6_ifaddrs. 
2743                                          * The same applies for the prefix list. 
2746                                         next 
= nd_prefix
.lh_first
; 
2750                                 IFA_UNLOCK(&ia
->ia_ifa
); 
2753                         lck_rw_done(&in6_ifaddr_rwlock
); 
2757                         pfxlist_onlink_check(); 
2759                          * If we were trying to restart this loop 
2760                          * above by changing the value of 'next', we might 
2761                          * end up freeing the only element on the list 
2762                          * when we call NDPR_REMREF(). 
2763                          * When this happens, we also have get out of this 
2764                          * loop because we have nothing else to do. 
2770                 lck_mtx_unlock(nd6_mutex
); 
2774         case SIOCSRTRFLUSH_IN6
: {       /* struct in6_ifreq */ 
2775                 /* flush all the default routers */ 
2776                 struct nd_defrouter 
*next
; 
2778                 lck_mtx_lock(nd6_mutex
); 
2779                 if ((dr 
= TAILQ_FIRST(&nd_defrouter
)) != NULL
) { 
2781                          * The first entry of the list may be stored in 
2782                          * the routing table, so we'll delete it later. 
2784                         for (dr 
= TAILQ_NEXT(dr
, dr_entry
); dr
; dr 
= next
) { 
2785                                 next 
= TAILQ_NEXT(dr
, dr_entry
); 
2786                                 if (ifp 
== lo_ifp 
|| dr
->ifp 
== ifp
) 
2789                         if (ifp 
== lo_ifp 
|| 
2790                             TAILQ_FIRST(&nd_defrouter
)->ifp 
== ifp
) 
2791                                 defrtrlist_del(TAILQ_FIRST(&nd_defrouter
)); 
2793                 lck_mtx_unlock(nd6_mutex
); 
2797         case SIOCGNBRINFO_IN6_32
: {     /* struct in6_nbrinfo_32 */ 
2798                 struct llinfo_nd6 
*ln
; 
2799                 struct in6_nbrinfo_32 nbi_32
; 
2800                 struct in6_addr nb_addr
; /* make local for safety */ 
2802                 bcopy(data
, &nbi_32
, sizeof (nbi_32
)); 
2803                 nb_addr 
= nbi_32
.addr
; 
2805                  * XXX: KAME specific hack for scoped addresses 
2806                  *      XXXX: for other scopes than link-local? 
2808                 if (IN6_IS_ADDR_LINKLOCAL(&nbi_32
.addr
) || 
2809                     IN6_IS_ADDR_MC_LINKLOCAL(&nbi_32
.addr
)) { 
2811                             (u_int16_t 
*)(void *)&nb_addr
.s6_addr
[2]; 
2814                                 *idp 
= htons(ifp
->if_index
); 
2817                 /* Callee returns a locked route upon success */ 
2818                 if ((rt 
= nd6_lookup(&nb_addr
, 0, ifp
, 0)) == NULL
) { 
2822                 RT_LOCK_ASSERT_HELD(rt
); 
2824                 nbi_32
.state 
= ln
->ln_state
; 
2825                 nbi_32
.asked 
= ln
->ln_asked
; 
2826                 nbi_32
.isrouter 
= ln
->ln_router
; 
2827                 nbi_32
.expire 
= ln_getexpire(ln
); 
2828                 RT_REMREF_LOCKED(rt
); 
2830                 bcopy(&nbi_32
, data
, sizeof (nbi_32
)); 
2834         case SIOCGNBRINFO_IN6_64
: {     /* struct in6_nbrinfo_64 */ 
2835                 struct llinfo_nd6 
*ln
; 
2836                 struct in6_nbrinfo_64 nbi_64
; 
2837                 struct in6_addr nb_addr
; /* make local for safety */ 
2839                 bcopy(data
, &nbi_64
, sizeof (nbi_64
)); 
2840                 nb_addr 
= nbi_64
.addr
; 
2842                  * XXX: KAME specific hack for scoped addresses 
2843                  *      XXXX: for other scopes than link-local? 
2845                 if (IN6_IS_ADDR_LINKLOCAL(&nbi_64
.addr
) || 
2846                     IN6_IS_ADDR_MC_LINKLOCAL(&nbi_64
.addr
)) { 
2848                             (u_int16_t 
*)(void *)&nb_addr
.s6_addr
[2]; 
2851                                 *idp 
= htons(ifp
->if_index
); 
2854                 /* Callee returns a locked route upon success */ 
2855                 if ((rt 
= nd6_lookup(&nb_addr
, 0, ifp
, 0)) == NULL
) { 
2859                 RT_LOCK_ASSERT_HELD(rt
); 
2861                 nbi_64
.state 
= ln
->ln_state
; 
2862                 nbi_64
.asked 
= ln
->ln_asked
; 
2863                 nbi_64
.isrouter 
= ln
->ln_router
; 
2864                 nbi_64
.expire 
= ln_getexpire(ln
); 
2865                 RT_REMREF_LOCKED(rt
); 
2867                 bcopy(&nbi_64
, data
, sizeof (nbi_64
)); 
2871         case SIOCGDEFIFACE_IN6_32
:      /* struct in6_ndifreq_32 */ 
2872         case SIOCGDEFIFACE_IN6_64
: {    /* struct in6_ndifreq_64 */ 
2873                 struct in6_ndifreq_64 
*ndif_64 
= 
2874                     (struct in6_ndifreq_64 
*)(void *)data
; 
2875                 struct in6_ndifreq_32 
*ndif_32 
= 
2876                     (struct in6_ndifreq_32 
*)(void *)data
; 
2878                 if (cmd 
== SIOCGDEFIFACE_IN6_64
) { 
2879                         u_int64_t j 
= nd6_defifindex
; 
2880                         bcopy(&j
, &ndif_64
->ifindex
, sizeof (j
)); 
2882                         bcopy(&nd6_defifindex
, &ndif_32
->ifindex
, 
2883                             sizeof (u_int32_t
)); 
2888         case SIOCSDEFIFACE_IN6_32
:      /* struct in6_ndifreq_32 */ 
2889         case SIOCSDEFIFACE_IN6_64
: {    /* struct in6_ndifreq_64 */ 
2890                 struct in6_ndifreq_64 
*ndif_64 
= 
2891                     (struct in6_ndifreq_64 
*)(void *)data
; 
2892                 struct in6_ndifreq_32 
*ndif_32 
= 
2893                     (struct in6_ndifreq_32 
*)(void *)data
; 
2896                 if (cmd 
== SIOCSDEFIFACE_IN6_64
) { 
2898                         bcopy(&ndif_64
->ifindex
, &j
, sizeof (j
)); 
2901                         bcopy(&ndif_32
->ifindex
, &idx
, sizeof (idx
)); 
2904                 error 
= nd6_setdefaultiface(idx
); 
2913  * Create neighbor cache entry and cache link-layer address, 
2914  * on reception of inbound ND6 packets. (RS/RA/NS/redirect) 
2917 nd6_cache_lladdr(struct ifnet 
*ifp
, struct in6_addr 
*from
, char *lladdr
, 
2918     int lladdrlen
, int type
, int code
) 
2920 #pragma unused(lladdrlen) 
2921         struct rtentry 
*rt 
= NULL
; 
2922         struct llinfo_nd6 
*ln 
= NULL
; 
2924         struct sockaddr_dl 
*sdl 
= NULL
; 
2930         boolean_t sched_timeout 
= FALSE
; 
2933                 panic("ifp == NULL in nd6_cache_lladdr"); 
2935                 panic("from == NULL in nd6_cache_lladdr"); 
2937         /* nothing must be updated for unspecified address */ 
2938         if (IN6_IS_ADDR_UNSPECIFIED(from
)) 
2942          * Validation about ifp->if_addrlen and lladdrlen must be done in 
2945         timenow 
= net_uptime(); 
2947         rt 
= nd6_lookup(from
, 0, ifp
, 0); 
2949                 if ((rt 
= nd6_lookup(from
, 1, ifp
, 0)) == NULL
) 
2951                 RT_LOCK_ASSERT_HELD(rt
); 
2954                 RT_LOCK_ASSERT_HELD(rt
); 
2955                 /* do nothing if static ndp is set */ 
2956                 if (rt
->rt_flags 
& RTF_STATIC
) { 
2957                         RT_REMREF_LOCKED(rt
); 
2966         if ((rt
->rt_flags 
& (RTF_GATEWAY 
| RTF_LLINFO
)) != RTF_LLINFO
) { 
2973         ln 
= (struct llinfo_nd6 
*)rt
->rt_llinfo
; 
2976         if (rt
->rt_gateway 
== NULL
) 
2978         if (rt
->rt_gateway
->sa_family 
!= AF_LINK
) 
2980         sdl 
= SDL(rt
->rt_gateway
); 
2982         olladdr 
= (sdl
->sdl_alen
) ? 1 : 0; 
2983         if (olladdr 
&& lladdr
) { 
2984                 if (bcmp(lladdr
, LLADDR(sdl
), ifp
->if_addrlen
)) 
2992          * newentry olladdr  lladdr  llchange   (*=record) 
2995          *      0       n       y       --      (3) * STALE 
2997          *      0       y       y       y       (5) * STALE 
2998          *      1       --      n       --      (6)   NOSTATE(= PASSIVE) 
2999          *      1       --      y       --      (7) * STALE 
3002         if (lladdr
) {           /* (3-5) and (7) */ 
3004                  * Record source link-layer address 
3005                  * XXX is it dependent to ifp->if_type? 
3007                 sdl
->sdl_alen 
= ifp
->if_addrlen
; 
3008                 bcopy(lladdr
, LLADDR(sdl
), ifp
->if_addrlen
); 
3010                 /* cache the gateway (sender HW) address */ 
3011                 nd6_llreach_alloc(rt
, ifp
, LLADDR(sdl
), sdl
->sdl_alen
, FALSE
); 
3015                 if ((!olladdr 
&& lladdr 
!= NULL
) ||     /* (3) */ 
3016                     (olladdr 
&& lladdr 
!= NULL 
&& llchange
)) {  /* (5) */ 
3018                         newstate 
= ND6_LLINFO_STALE
; 
3019                 } else                                  /* (1-2,4) */ 
3023                 if (lladdr 
== NULL
)                     /* (6) */ 
3024                         newstate 
= ND6_LLINFO_NOSTATE
; 
3026                         newstate 
= ND6_LLINFO_STALE
; 
3031                  * Update the state of the neighbor cache. 
3033                 ln
->ln_state 
= newstate
; 
3035                 if (ln
->ln_state 
== ND6_LLINFO_STALE
) { 
3036                         struct mbuf 
*m 
= ln
->ln_hold
; 
3038                          * XXX: since nd6_output() below will cause 
3039                          * state tansition to DELAY and reset the timer, 
3040                          * we must set the timer now, although it is actually 
3043                         ln_setexpire(ln
, timenow 
+ nd6_gctimer
); 
3047                                 struct sockaddr_in6 sin6
; 
3049                                 rtkey_to_sa6(rt
, &sin6
); 
3051                                  * we assume ifp is not a p2p here, so just 
3052                                  * set the 2nd argument as the 1st one. 
3055                                 nd6_output(ifp
, ifp
, m
, &sin6
, rt
, NULL
); 
3058                 } else if (ln
->ln_state 
== ND6_LLINFO_INCOMPLETE
) { 
3059                         /* probe right away */ 
3060                         ln_setexpire(ln
, timenow
); 
3061                         sched_timeout 
= TRUE
; 
3066          * ICMP6 type dependent behavior. 
3068          * NS: clear IsRouter if new entry 
3069          * RS: clear IsRouter 
3070          * RA: set IsRouter if there's lladdr 
3071          * redir: clear IsRouter if new entry 
3074          * The spec says that we must set IsRouter in the following cases: 
3075          * - If lladdr exist, set IsRouter.  This means (1-5). 
3076          * - If it is old entry (!newentry), set IsRouter.  This means (7). 
3077          * So, based on the spec, in (1-5) and (7) cases we must set IsRouter. 
3078          * A quetion arises for (1) case.  (1) case has no lladdr in the 
3079          * neighbor cache, this is similar to (6). 
3080          * This case is rare but we figured that we MUST NOT set IsRouter. 
3082          * newentry olladdr  lladdr  llchange       NS  RS      RA      redir 
3084          *      0       n       n       --      (1)     c       ?       s 
3085          *      0       y       n       --      (2)     c       s       s 
3086          *      0       n       y       --      (3)     c       s       s 
3089          *      1       --      n       --      (6) c   c               c s 
3090          *      1       --      y       --      (7) c   c       s       c s 
3094         switch (type 
& 0xff) { 
3095         case ND_NEIGHBOR_SOLICIT
: 
3097                  * New entry must have is_router flag cleared. 
3099                 if (is_newentry
)        /* (6-7) */ 
3104                  * If the ICMP message is a Redirect to a better router, always 
3105                  * set the is_router flag.  Otherwise, if the entry is newly 
3106                  * created, then clear the flag.  [RFC 4861, sec 8.3] 
3108                 if (code 
== ND_REDIRECT_ROUTER
) 
3110                 else if (is_newentry
) /* (6-7) */ 
3113         case ND_ROUTER_SOLICIT
: 
3115                  * is_router flag must always be cleared. 
3119         case ND_ROUTER_ADVERT
: 
3121                  * Mark an entry with lladdr as a router. 
3123                 if ((!is_newentry 
&& (olladdr 
|| lladdr
)) ||    /* (2-5) */ 
3124                     (is_newentry 
&& lladdr
)) {                  /* (7) */ 
3131          * When the link-layer address of a router changes, select the 
3132          * best router again.  In particular, when the neighbor entry is newly 
3133          * created, it might affect the selection policy. 
3134          * Question: can we restrict the first condition to the "is_newentry" 
3137          * Note: Perform default router selection even when we are a router, 
3138          * if Scoped Routing is enabled. 
3140         if (do_update 
&& ln
->ln_router 
&& 
3141             (ip6_doscopedroute 
|| !ip6_forwarding
)) { 
3142                 RT_REMREF_LOCKED(rt
); 
3144                 lck_mtx_lock(nd6_mutex
); 
3145                 defrouter_select(ifp
); 
3146                 lck_mtx_unlock(nd6_mutex
); 
3148                 RT_REMREF_LOCKED(rt
); 
3151         if (sched_timeout
) { 
3152                 lck_mtx_lock(rnh_lock
); 
3153                 nd6_sched_timeout(NULL
, NULL
); 
3154                 lck_mtx_unlock(rnh_lock
); 
3159 nd6_slowtimo(void *arg
) 
3163         struct nd_ifinfo 
*nd6if
; 
3165         lck_rw_lock_shared(nd_if_rwlock
); 
3166         for (i 
= 1; i 
< if_index 
+ 1; i
++) { 
3167                 if (!nd_ifinfo 
|| i 
>= nd_ifinfo_indexlim
) 
3169                 nd6if 
= &nd_ifinfo
[i
]; 
3170                 if (!nd6if
->initialized
) 
3172                 lck_mtx_lock(&nd6if
->lock
); 
3173                 if (nd6if
->basereachable 
&& /* already initialized */ 
3174                     (nd6if
->recalctm 
-= ND6_SLOWTIMER_INTERVAL
) <= 0) { 
3176                          * Since reachable time rarely changes by router 
3177                          * advertisements, we SHOULD insure that a new random 
3178                          * value gets recomputed at least once every few hours. 
3181                         nd6if
->recalctm 
= nd6_recalc_reachtm_interval
; 
3183                             ND_COMPUTE_RTIME(nd6if
->basereachable
); 
3185                 lck_mtx_unlock(&nd6if
->lock
); 
3187         lck_rw_done(nd_if_rwlock
); 
3188         timeout(nd6_slowtimo
, NULL
, ND6_SLOWTIMER_INTERVAL 
* hz
); 
3191 #define senderr(e) { error = (e); goto bad; } 
3193 nd6_output(struct ifnet 
*ifp
, struct ifnet 
*origifp
, struct mbuf 
*m0
, 
3194     struct sockaddr_in6 
*dst
, struct rtentry 
*hint0
, struct flowadv 
*adv
) 
3196         struct mbuf 
*m 
= m0
; 
3197         struct rtentry 
*rt 
= hint0
, *hint 
= hint0
; 
3198         struct llinfo_nd6 
*ln 
= NULL
; 
3201         struct rtentry 
*rtrele 
= NULL
; 
3202         struct nd_ifinfo 
*ndi
; 
3206                 RT_ADDREF_LOCKED(rt
); 
3209         if (IN6_IS_ADDR_MULTICAST(&dst
->sin6_addr
) || !nd6_need_cache(ifp
)) { 
3216          * Next hop determination.  Because we may involve the gateway route 
3217          * in addition to the original route, locking is rather complicated. 
3218          * The general concept is that regardless of whether the route points 
3219          * to the original route or to the gateway route, this routine takes 
3220          * an extra reference on such a route.  This extra reference will be 
3221          * released at the end. 
3223          * Care must be taken to ensure that the "hint0" route never gets freed 
3224          * via rtfree(), since the caller may have stored it inside a struct 
3225          * route with a reference held for that placeholder. 
3227          * This logic is similar to, though not exactly the same as the one 
3228          * used by route_to_gwroute(). 
3232                  * We have a reference to "rt" by now (or below via rtalloc1), 
3233                  * which will either be released or freed at the end of this 
3236                 RT_LOCK_ASSERT_HELD(rt
); 
3237                 if (!(rt
->rt_flags 
& RTF_UP
)) { 
3238                         RT_REMREF_LOCKED(rt
); 
3240                         if ((hint 
= rt 
= rtalloc1_scoped(SA(dst
), 1, 0, 
3241                             ifp
->if_index
)) != NULL
) { 
3243                                 if (rt
->rt_ifp 
!= ifp
) { 
3244                                         /* XXX: loop care? */ 
3246                                         error 
= nd6_output(ifp
, origifp
, m0
, 
3252                                 senderr(EHOSTUNREACH
); 
3256                 if (rt
->rt_flags 
& RTF_GATEWAY
) { 
3257                         struct rtentry 
*gwrt
; 
3258                         struct in6_ifaddr 
*ia6 
= NULL
; 
3259                         struct sockaddr_in6 gw6
; 
3261                         rtgw_to_sa6(rt
, &gw6
); 
3263                          * Must drop rt_lock since nd6_is_addr_neighbor() 
3264                          * calls nd6_lookup() and acquires rnh_lock. 
3269                          * We skip link-layer address resolution and NUD 
3270                          * if the gateway is not a neighbor from ND point 
3271                          * of view, regardless of the value of nd_ifinfo.flags. 
3272                          * The second condition is a bit tricky; we skip 
3273                          * if the gateway is our own address, which is 
3274                          * sometimes used to install a route to a p2p link. 
3276                         if (!nd6_is_addr_neighbor(&gw6
, ifp
, 0) || 
3277                             (ia6 
= in6ifa_ifpwithaddr(ifp
, &gw6
.sin6_addr
))) { 
3279                                  * We allow this kind of tricky route only 
3280                                  * when the outgoing interface is p2p. 
3281                                  * XXX: we may need a more generic rule here. 
3284                                         IFA_REMREF(&ia6
->ia_ifa
); 
3285                                 if ((ifp
->if_flags 
& IFF_POINTOPOINT
) == 0) 
3286                                         senderr(EHOSTUNREACH
); 
3291                         gw6 
= *(SIN6(rt
->rt_gateway
)); 
3293                         /* If hint is now down, give up */ 
3294                         if (!(rt
->rt_flags 
& RTF_UP
)) { 
3296                                 senderr(EHOSTUNREACH
); 
3299                         /* If there's no gateway route, look it up */ 
3300                         if ((gwrt 
= rt
->rt_gwroute
) == NULL
) { 
3304                         /* Become a regular mutex */ 
3305                         RT_CONVERT_LOCK(rt
); 
3308                          * Take gwrt's lock while holding route's lock; 
3309                          * this is okay since gwrt never points back 
3310                          * to rt, so no lock ordering issues. 
3313                         if (!(gwrt
->rt_flags 
& RTF_UP
)) { 
3314                                 rt
->rt_gwroute 
= NULL
; 
3319                                 lck_mtx_lock(rnh_lock
); 
3320                                 gwrt 
= rtalloc1_scoped_locked(SA(&gw6
), 1, 0, 
3325                                  * Bail out if the route is down, no route 
3326                                  * to gateway, circular route, or if the 
3327                                  * gateway portion of "rt" has changed. 
3329                                 if (!(rt
->rt_flags 
& RTF_UP
) || 
3330                                     gwrt 
== NULL 
|| gwrt 
== rt 
|| 
3331                                     !equal(SA(&gw6
), rt
->rt_gateway
)) { 
3333                                                 RT_REMREF_LOCKED(gwrt
); 
3338                                                 rtfree_locked(gwrt
); 
3339                                         lck_mtx_unlock(rnh_lock
); 
3340                                         senderr(EHOSTUNREACH
); 
3342                                 VERIFY(gwrt 
!= NULL
); 
3344                                  * Set gateway route; callee adds ref to gwrt; 
3345                                  * gwrt has an extra ref from rtalloc1() for 
3348                                 rt_set_gwroute(rt
, rt_key(rt
), gwrt
); 
3350                                 lck_mtx_unlock(rnh_lock
); 
3351                                 /* Remember to release/free "rt" at the end */ 
3355                                 RT_ADDREF_LOCKED(gwrt
); 
3358                                 /* Remember to release/free "rt" at the end */ 
3365                          * This is an opportunity to revalidate the parent 
3366                          * route's gwroute, in case it now points to a dead 
3367                          * route entry.  Parent route won't go away since the 
3368                          * clone (hint) holds a reference to it.  rt == gwrt. 
3371                         if ((hint
->rt_flags 
& (RTF_WASCLONED 
| RTF_UP
)) == 
3372                             (RTF_WASCLONED 
| RTF_UP
)) { 
3373                                 struct rtentry 
*prt 
= hint
->rt_parent
; 
3374                                 VERIFY(prt 
!= NULL
); 
3376                                 RT_CONVERT_LOCK(hint
); 
3379                                 rt_revalidate_gwroute(prt
, rt
); 
3386                         /* rt == gwrt; if it is now down, give up */ 
3387                         if (!(rt
->rt_flags 
& RTF_UP
)) { 
3391                                 /* "rtrele" == original "rt" */ 
3392                                 senderr(EHOSTUNREACH
); 
3396                 /* Become a regular mutex */ 
3397                 RT_CONVERT_LOCK(rt
); 
3401          * Address resolution or Neighbor Unreachability Detection 
3403          * At this point, the destination of the packet must be a unicast 
3404          * or an anycast address(i.e. not a multicast). 
3407         /* Look up the neighbor cache for the nexthop */ 
3408         if (rt 
&& (rt
->rt_flags 
& RTF_LLINFO
) != 0) { 
3411                 struct sockaddr_in6 sin6
; 
3413                  * Clear out Scope ID field in case it is set. 
3416                 sin6
.sin6_scope_id 
= 0; 
3418                  * Since nd6_is_addr_neighbor() internally calls nd6_lookup(), 
3419                  * the condition below is not very efficient.  But we believe 
3420                  * it is tolerable, because this should be a rare case. 
3421                  * Must drop rt_lock since nd6_is_addr_neighbor() calls 
3422                  * nd6_lookup() and acquires rnh_lock. 
3426                 if (nd6_is_addr_neighbor(&sin6
, ifp
, 0)) { 
3427                         /* "rtrele" may have been used, so clean up "rt" now */ 
3429                                 /* Don't free "hint0" */ 
3435                         /* Callee returns a locked route upon success */ 
3436                         rt 
= nd6_lookup(&dst
->sin6_addr
, 1, ifp
, 0); 
3438                                 RT_LOCK_ASSERT_HELD(rt
); 
3441                 } else if (rt 
!= NULL
) { 
3449                 lck_rw_lock_shared(nd_if_rwlock
); 
3450                 ndi 
= ND_IFINFO(ifp
); 
3451                 VERIFY(ndi 
!= NULL 
&& ndi
->initialized
); 
3452                 lck_mtx_lock(&ndi
->lock
); 
3453                 if ((ifp
->if_flags 
& IFF_POINTOPOINT
) == 0 && 
3454                     !(ndi
->flags 
& ND6_IFF_PERFORMNUD
)) { 
3455                         lck_mtx_unlock(&ndi
->lock
); 
3456                         lck_rw_done(nd_if_rwlock
); 
3458                             "nd6_output: can't allocate llinfo for %s " 
3459                             "(ln=0x%llx, rt=0x%llx)\n", 
3460                             ip6_sprintf(&dst
->sin6_addr
), 
3461                             (uint64_t)VM_KERNEL_ADDRPERM(ln
), 
3462                             (uint64_t)VM_KERNEL_ADDRPERM(rt
)); 
3463                         senderr(EIO
);   /* XXX: good error? */ 
3465                 lck_mtx_unlock(&ndi
->lock
); 
3466                 lck_rw_done(nd_if_rwlock
); 
3468                 goto sendpkt
;   /* send anyway */ 
3471         net_update_uptime(); 
3472         timenow 
= net_uptime(); 
3474         /* We don't have to do link-layer address resolution on a p2p link. */ 
3475         if ((ifp
->if_flags 
& IFF_POINTOPOINT
) != 0 && 
3476             ln
->ln_state 
< ND6_LLINFO_REACHABLE
) { 
3477                 ln
->ln_state 
= ND6_LLINFO_STALE
; 
3478                 ln_setexpire(ln
, timenow 
+ nd6_gctimer
); 
3482          * The first time we send a packet to a neighbor whose entry is 
3483          * STALE, we have to change the state to DELAY and a sets a timer to 
3484          * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do 
3485          * neighbor unreachability detection on expiration. 
3488         if (ln
->ln_state 
== ND6_LLINFO_STALE
) { 
3490                 ln
->ln_state 
= ND6_LLINFO_DELAY
; 
3491                 ln_setexpire(ln
, timenow 
+ nd6_delay
); 
3492                 /* N.B.: we will re-arm the timer below. */ 
3493                 _CASSERT(ND6_LLINFO_DELAY 
> ND6_LLINFO_INCOMPLETE
); 
3497          * If the neighbor cache entry has a state other than INCOMPLETE 
3498          * (i.e. its link-layer address is already resolved), just 
3501         if (ln
->ln_state 
> ND6_LLINFO_INCOMPLETE
) { 
3504                  * Move this entry to the head of the queue so that it is 
3505                  * less likely for this entry to be a target of forced 
3506                  * garbage collection (see nd6_rtrequest()).  Do this only 
3507                  * if the entry is non-permanent (as permanent ones will 
3508                  * never be purged), and if the number of active entries 
3509                  * is at least half of the threshold. 
3511                 if (ln
->ln_state 
== ND6_LLINFO_DELAY 
|| 
3512                     (ln
->ln_expire 
!= 0 && ip6_neighborgcthresh 
> 0 && 
3513                     nd6_inuse 
>= (ip6_neighborgcthresh 
>> 1))) { 
3514                         lck_mtx_lock(rnh_lock
); 
3515                         if (ln
->ln_state 
== ND6_LLINFO_DELAY
) 
3516                                 nd6_sched_timeout(NULL
, NULL
); 
3517                         if (ln
->ln_expire 
!= 0 && ip6_neighborgcthresh 
> 0 && 
3518                             nd6_inuse 
>= (ip6_neighborgcthresh 
>> 1)) { 
3520                                 if (ln
->ln_flags 
& ND6_LNF_IN_USE
) { 
3526                         lck_mtx_unlock(rnh_lock
); 
3532          * If this is a prefix proxy route, record the inbound interface 
3533          * so that it can be excluded from the list of interfaces eligible 
3534          * for forwarding the proxied NS in nd6_prproxy_ns_output(). 
3536         if (rt
->rt_flags 
& RTF_PROXY
) 
3537                 ln
->ln_exclifp 
= ((origifp 
== ifp
) ? NULL 
: origifp
); 
3540          * There is a neighbor cache entry, but no ethernet address 
3541          * response yet.  Replace the held mbuf (if any) with this 
3544          * This code conforms to the rate-limiting rule described in Section 
3545          * 7.2.2 of RFC 4861, because the timer is set correctly after sending 
3548         if (ln
->ln_state 
== ND6_LLINFO_NOSTATE
) 
3549                 ln
->ln_state 
= ND6_LLINFO_INCOMPLETE
; 
3551                 m_freem(ln
->ln_hold
); 
3553         if (ln
->ln_expire 
!= 0 && ln
->ln_asked 
< nd6_mmaxtries 
&& 
3554             ln
->ln_expire 
<= timenow
) { 
3556                 lck_rw_lock_shared(nd_if_rwlock
); 
3557                 ndi 
= ND_IFINFO(ifp
); 
3558                 VERIFY(ndi 
!= NULL 
&& ndi
->initialized
); 
3559                 lck_mtx_lock(&ndi
->lock
); 
3560                 ln_setexpire(ln
, timenow 
+ ndi
->retrans 
/ 1000); 
3561                 lck_mtx_unlock(&ndi
->lock
); 
3562                 lck_rw_done(nd_if_rwlock
); 
3564                 /* We still have a reference on rt (for ln) */ 
3566                         nd6_prproxy_ns_output(ifp
, origifp
, NULL
, 
3567                             &dst
->sin6_addr
, ln
); 
3569                         nd6_ns_output(ifp
, NULL
, &dst
->sin6_addr
, ln
, 0); 
3570                 lck_mtx_lock(rnh_lock
); 
3571                 nd6_sched_timeout(NULL
, NULL
); 
3572                 lck_mtx_unlock(rnh_lock
); 
3577          * Move this entry to the head of the queue so that it is 
3578          * less likely for this entry to be a target of forced 
3579          * garbage collection (see nd6_rtrequest()).  Do this only 
3580          * if the entry is non-permanent (as permanent ones will 
3581          * never be purged), and if the number of active entries 
3582          * is at least half of the threshold. 
3584         if (ln
->ln_expire 
!= 0 && ip6_neighborgcthresh 
> 0 && 
3585             nd6_inuse 
>= (ip6_neighborgcthresh 
>> 1)) { 
3586                 lck_mtx_lock(rnh_lock
); 
3588                 if (ln
->ln_flags 
& ND6_LNF_IN_USE
) { 
3592                 /* Clean up "rt" now while we can */ 
3594                         RT_REMREF_LOCKED(rt
); 
3600                 rt 
= NULL
;      /* "rt" has been taken care of */ 
3601                 lck_mtx_unlock(rnh_lock
); 
3608                 RT_LOCK_ASSERT_NOTHELD(rt
); 
3610         /* discard the packet if IPv6 operation is disabled on the interface */ 
3611         if (ifp
->if_eflags 
& IFEF_IPV6_DISABLED
) { 
3612                 error 
= ENETDOWN
; /* better error? */ 
3616         if (ifp
->if_flags 
& IFF_LOOPBACK
) { 
3617                 /* forwarding rules require the original scope_id */ 
3618                 m
->m_pkthdr
.rcvif 
= origifp
; 
3619                 error 
= dlil_output(origifp
, PF_INET6
, m
, (caddr_t
)rt
, 
3623                 /* Do not allow loopback address to wind up on a wire */ 
3624                 struct ip6_hdr 
*ip6 
= mtod(m
, struct ip6_hdr 
*); 
3626                 if ((IN6_IS_ADDR_LOOPBACK(&ip6
->ip6_src
) || 
3627                     IN6_IS_ADDR_LOOPBACK(&ip6
->ip6_dst
))) { 
3628                         ip6stat
.ip6s_badscope
++; 
3629                         error 
= EADDRNOTAVAIL
; 
3636                 /* Mark use timestamp */ 
3637                 if (rt
->rt_llinfo 
!= NULL
) 
3638                         nd6_llreach_use(rt
->rt_llinfo
); 
3642         if (hint 
!= NULL 
&& nstat_collect
) { 
3645                 if ((m
->m_pkthdr
.csum_flags 
& CSUM_TSO_IPV6
) && 
3646                     (m
->m_pkthdr
.tso_segsz 
> 0)) 
3647                         scnt 
= m
->m_pkthdr
.len 
/ m
->m_pkthdr
.tso_segsz
; 
3651                 nstat_route_tx(hint
, scnt
, m
->m_pkthdr
.len
, 0); 
3654         m
->m_pkthdr
.rcvif 
= NULL
; 
3655         error 
= dlil_output(ifp
, PF_INET6
, m
, (caddr_t
)rt
, SA(dst
), 0, adv
); 
3663         /* Clean up "rt" unless it's already been done */ 
3667                         RT_REMREF_LOCKED(rt
); 
3674         /* And now clean up "rtrele" if there is any */ 
3675         if (rtrele 
!= NULL
) { 
3676                 RT_LOCK_SPIN(rtrele
); 
3677                 if (rtrele 
== hint0
) { 
3678                         RT_REMREF_LOCKED(rtrele
); 
3690 nd6_need_cache(struct ifnet 
*ifp
) 
3693          * XXX: we currently do not make neighbor cache on any interface 
3694          * other than ARCnet, Ethernet, FDDI and GIF. 
3697          * - unidirectional tunnels needs no ND 
3699         switch (ifp
->if_type
) { 
3705         case IFT_IEEE8023ADLAG
: 
3709         case IFT_GIF
:           /* XXX need more cases? */ 
3723 nd6_storelladdr(struct ifnet 
*ifp
, struct rtentry 
*rt
, struct mbuf 
*m
, 
3724     struct sockaddr 
*dst
, u_char 
*desten
) 
3727         struct sockaddr_dl 
*sdl
; 
3729         if (m
->m_flags 
& M_MCAST
) { 
3730                 switch (ifp
->if_type
) { 
3734                 case IFT_IEEE8023ADLAG
: 
3739                         ETHER_MAP_IPV6_MULTICAST(&SIN6(dst
)->sin6_addr
, desten
); 
3742                         for (i 
= 0; i 
< ifp
->if_addrlen
; i
++) 
3749                         return (0); /* caller will free mbuf */ 
3754                 /* this could happen, if we could not allocate memory */ 
3755                 return (0); /* caller will free mbuf */ 
3758         if (rt
->rt_gateway
->sa_family 
!= AF_LINK
) { 
3759                 printf("nd6_storelladdr: something odd happens\n"); 
3761                 return (0); /* caller will free mbuf */ 
3763         sdl 
= SDL(rt
->rt_gateway
); 
3764         if (sdl
->sdl_alen 
== 0) { 
3765                 /* this should be impossible, but we bark here for debugging */ 
3766                 printf("nd6_storelladdr: sdl_alen == 0\n"); 
3768                 return (0); /* caller will free mbuf */ 
3771         bcopy(LLADDR(sdl
), desten
, sdl
->sdl_alen
); 
3777  * This is the ND pre-output routine; care must be taken to ensure that 
3778  * the "hint" route never gets freed via rtfree(), since the caller may 
3779  * have stored it inside a struct route with a reference held for that 
3783 nd6_lookup_ipv6(ifnet_t  ifp
, const struct sockaddr_in6 
*ip6_dest
, 
3784     struct sockaddr_dl 
*ll_dest
, size_t ll_dest_len
, route_t hint
, 
3787         route_t route 
= hint
; 
3789         struct sockaddr_dl 
*sdl 
= NULL
; 
3792         if (ip6_dest
->sin6_family 
!= AF_INET6
) 
3793                 return (EAFNOSUPPORT
); 
3795         if ((ifp
->if_flags 
& (IFF_UP
|IFF_RUNNING
)) != (IFF_UP
|IFF_RUNNING
)) 
3800                  * Callee holds a reference on the route and returns 
3801                  * with the route entry locked, upon success. 
3803                 result 
= route_to_gwroute((const struct sockaddr 
*)ip6_dest
, 
3808                         RT_LOCK_ASSERT_HELD(route
); 
3811         if ((packet
->m_flags 
& M_MCAST
) != 0) { 
3814                 result 
= dlil_resolve_multi(ifp
, 
3815                     (const struct sockaddr 
*)ip6_dest
, 
3816                     SA(ll_dest
), ll_dest_len
); 
3822         if (route 
== NULL
) { 
3824                  * This could happen, if we could not allocate memory or 
3825                  * if route_to_gwroute() didn't return a route. 
3831         if (route
->rt_gateway
->sa_family 
!= AF_LINK
) { 
3832                 printf("%s: route %s on %s%d gateway address not AF_LINK\n", 
3833                     __func__
, ip6_sprintf(&ip6_dest
->sin6_addr
), 
3834                     route
->rt_ifp
->if_name
, route
->rt_ifp
->if_unit
); 
3835                 result 
= EADDRNOTAVAIL
; 
3839         sdl 
= SDL(route
->rt_gateway
); 
3840         if (sdl
->sdl_alen 
== 0) { 
3841                 /* this should be impossible, but we bark here for debugging */ 
3842                 printf("%s: route %s on %s%d sdl_alen == 0\n", __func__
, 
3843                     ip6_sprintf(&ip6_dest
->sin6_addr
), route
->rt_ifp
->if_name
, 
3844                     route
->rt_ifp
->if_unit
); 
3845                 result 
= EHOSTUNREACH
; 
3849         copy_len 
= sdl
->sdl_len 
<= ll_dest_len 
? sdl
->sdl_len 
: ll_dest_len
; 
3850         bcopy(sdl
, ll_dest
, copy_len
); 
3853         if (route 
!= NULL
) { 
3854                 if (route 
== hint
) { 
3855                         RT_REMREF_LOCKED(route
); 
3866 nd6_setifinfo(struct ifnet 
*ifp
, u_int32_t before
, u_int32_t after
) 
3872          * Handle ND6_IFF_IFDISABLED 
3874         if ((before 
& ND6_IFF_IFDISABLED
) || 
3875             (after 
& ND6_IFF_IFDISABLED
)) { 
3876                 b 
= (before 
& ND6_IFF_IFDISABLED
); 
3877                 a 
= (after 
& ND6_IFF_IFDISABLED
); 
3879                 if (b 
!= a 
&& (err 
= nd6_if_disable(ifp
, 
3880                      ((int32_t)(a 
- b
) > 0))) != 0) 
3885          * Handle ND6_IFF_PROXY_PREFIXES 
3887         if ((before 
& ND6_IFF_PROXY_PREFIXES
) || 
3888             (after 
& ND6_IFF_PROXY_PREFIXES
)) { 
3889                 b 
= (before 
& ND6_IFF_PROXY_PREFIXES
); 
3890                 a 
= (after 
& ND6_IFF_PROXY_PREFIXES
); 
3892                 if (b 
!= a 
&& (err 
= nd6_if_prproxy(ifp
, 
3893                      ((int32_t)(a 
- b
) > 0))) != 0) 
3901  * Enable/disable IPv6 on an interface, called as part of 
3902  * setting/clearing ND6_IFF_IFDISABLED, or during DAD failure. 
3905 nd6_if_disable(struct ifnet 
*ifp
, boolean_t enable
) 
3907         ifnet_lock_shared(ifp
); 
3909                 ifp
->if_eflags 
|= IFEF_IPV6_DISABLED
; 
3911                 ifp
->if_eflags 
&= ~IFEF_IPV6_DISABLED
; 
3912         ifnet_lock_done(ifp
); 
3918 nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
 
3920 #pragma unused(oidp, arg1, arg2) 
3921         char pbuf
[MAX_IPv6_STR_LEN
]; 
3922         struct nd_defrouter 
*dr
; 
3925         if (req
->newptr 
!= USER_ADDR_NULL
) 
3928         lck_mtx_lock(nd6_mutex
); 
3929         if (proc_is64bit(req
->p
)) { 
3930                 struct in6_defrouter_64 d
; 
3932                 bzero(&d
, sizeof (d
)); 
3933                 d
.rtaddr
.sin6_family 
= AF_INET6
; 
3934                 d
.rtaddr
.sin6_len 
= sizeof (d
.rtaddr
); 
3936                 TAILQ_FOREACH(dr
, &nd_defrouter
, dr_entry
) { 
3937                         d
.rtaddr
.sin6_addr 
= dr
->rtaddr
; 
3938                         if (in6_recoverscope(&d
.rtaddr
, 
3939                             &dr
->rtaddr
, dr
->ifp
) != 0) 
3940                                 log(LOG_ERR
, "scope error in default router " 
3941                                     "list (%s)\n", inet_ntop(AF_INET6
, 
3942                                     &dr
->rtaddr
, pbuf
, sizeof (pbuf
))); 
3943                         d
.flags 
= dr
->flags
; 
3944                         d
.stateflags 
= dr
->stateflags
; 
3945                         d
.stateflags 
&= ~NDDRF_PROCESSED
; 
3946                         d
.rtlifetime 
= dr
->rtlifetime
; 
3947                         d
.expire 
= nddr_getexpire(dr
); 
3948                         d
.if_index 
= dr
->ifp
->if_index
; 
3949                         error 
= SYSCTL_OUT(req
, &d
, sizeof (d
)); 
3954                 struct in6_defrouter_32 d
; 
3956                 bzero(&d
, sizeof (d
)); 
3957                 d
.rtaddr
.sin6_family 
= AF_INET6
; 
3958                 d
.rtaddr
.sin6_len 
= sizeof (d
.rtaddr
); 
3960                 TAILQ_FOREACH(dr
, &nd_defrouter
, dr_entry
) { 
3961                         d
.rtaddr
.sin6_addr 
= dr
->rtaddr
; 
3962                         if (in6_recoverscope(&d
.rtaddr
, 
3963                             &dr
->rtaddr
, dr
->ifp
) != 0) 
3964                                 log(LOG_ERR
, "scope error in default router " 
3965                                     "list (%s)\n", inet_ntop(AF_INET6
, 
3966                                     &dr
->rtaddr
, pbuf
, sizeof (pbuf
))); 
3967                         d
.flags 
= dr
->flags
; 
3968                         d
.stateflags 
= dr
->stateflags
; 
3969                         d
.stateflags 
&= ~NDDRF_PROCESSED
; 
3970                         d
.rtlifetime 
= dr
->rtlifetime
; 
3971                         d
.expire 
= nddr_getexpire(dr
); 
3972                         d
.if_index 
= dr
->ifp
->if_index
; 
3973                         error 
= SYSCTL_OUT(req
, &d
, sizeof (d
)); 
3978         lck_mtx_unlock(nd6_mutex
); 
3983 nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
 
3985 #pragma unused(oidp, arg1, arg2) 
3986         char pbuf
[MAX_IPv6_STR_LEN
]; 
3987         struct nd_pfxrouter 
*pfr
; 
3988         struct sockaddr_in6 s6
; 
3989         struct nd_prefix 
*pr
; 
3992         if (req
->newptr 
!= USER_ADDR_NULL
) 
3995         bzero(&s6
, sizeof (s6
)); 
3996         s6
.sin6_family 
= AF_INET6
; 
3997         s6
.sin6_len 
= sizeof (s6
); 
3999         lck_mtx_lock(nd6_mutex
); 
4000         if (proc_is64bit(req
->p
)) { 
4001                 struct in6_prefix_64 p
; 
4003                 bzero(&p
, sizeof (p
)); 
4004                 p
.origin 
= PR_ORIG_RA
; 
4006                 LIST_FOREACH(pr
, &nd_prefix
, ndpr_entry
) { 
4008                         p
.prefix 
= pr
->ndpr_prefix
; 
4009                         if (in6_recoverscope(&p
.prefix
, 
4010                             &pr
->ndpr_prefix
.sin6_addr
, pr
->ndpr_ifp
) != 0) 
4011                                 log(LOG_ERR
, "scope error in " 
4012                                     "prefix list (%s)\n", inet_ntop(AF_INET6
, 
4013                                     &p
.prefix
.sin6_addr
, pbuf
, sizeof (pbuf
))); 
4014                         p
.raflags 
= pr
->ndpr_raf
; 
4015                         p
.prefixlen 
= pr
->ndpr_plen
; 
4016                         p
.vltime 
= pr
->ndpr_vltime
; 
4017                         p
.pltime 
= pr
->ndpr_pltime
; 
4018                         p
.if_index 
= pr
->ndpr_ifp
->if_index
; 
4019                         p
.expire 
= ndpr_getexpire(pr
); 
4020                         p
.refcnt 
= pr
->ndpr_addrcnt
; 
4021                         p
.flags 
= pr
->ndpr_stateflags
; 
4023                         LIST_FOREACH(pfr
, &pr
->ndpr_advrtrs
, pfr_entry
) 
4025                         error 
= SYSCTL_OUT(req
, &p
, sizeof (p
)); 
4030                         LIST_FOREACH(pfr
, &pr
->ndpr_advrtrs
, pfr_entry
) { 
4031                                 s6
.sin6_addr 
= pfr
->router
->rtaddr
; 
4032                                 if (in6_recoverscope(&s6
, &pfr
->router
->rtaddr
, 
4033                                     pfr
->router
->ifp
) != 0) 
4035                                             "scope error in prefix list (%s)\n", 
4036                                             inet_ntop(AF_INET6
, &s6
.sin6_addr
, 
4037                                             pbuf
, sizeof (pbuf
))); 
4038                                 error 
= SYSCTL_OUT(req
, &s6
, sizeof (s6
)); 
4047                 struct in6_prefix_32 p
; 
4049                 bzero(&p
, sizeof (p
)); 
4050                 p
.origin 
= PR_ORIG_RA
; 
4052                 LIST_FOREACH(pr
, &nd_prefix
, ndpr_entry
) { 
4054                         p
.prefix 
= pr
->ndpr_prefix
; 
4055                         if (in6_recoverscope(&p
.prefix
, 
4056                             &pr
->ndpr_prefix
.sin6_addr
, pr
->ndpr_ifp
) != 0) 
4058                                     "scope error in prefix list (%s)\n", 
4059                                     inet_ntop(AF_INET6
, &p
.prefix
.sin6_addr
, 
4060                                     pbuf
, sizeof (pbuf
))); 
4061                         p
.raflags 
= pr
->ndpr_raf
; 
4062                         p
.prefixlen 
= pr
->ndpr_plen
; 
4063                         p
.vltime 
= pr
->ndpr_vltime
; 
4064                         p
.pltime 
= pr
->ndpr_pltime
; 
4065                         p
.if_index 
= pr
->ndpr_ifp
->if_index
; 
4066                         p
.expire 
= ndpr_getexpire(pr
); 
4067                         p
.refcnt 
= pr
->ndpr_addrcnt
; 
4068                         p
.flags 
= pr
->ndpr_stateflags
; 
4070                         LIST_FOREACH(pfr
, &pr
->ndpr_advrtrs
, pfr_entry
) 
4072                         error 
= SYSCTL_OUT(req
, &p
, sizeof (p
)); 
4077                         LIST_FOREACH(pfr
, &pr
->ndpr_advrtrs
, pfr_entry
) { 
4078                                 s6
.sin6_addr 
= pfr
->router
->rtaddr
; 
4079                                 if (in6_recoverscope(&s6
, &pfr
->router
->rtaddr
, 
4080                                     pfr
->router
->ifp
) != 0) 
4082                                             "scope error in prefix list (%s)\n", 
4083                                             inet_ntop(AF_INET6
, &s6
.sin6_addr
, 
4084                                             pbuf
, sizeof (pbuf
))); 
4085                                 error 
= SYSCTL_OUT(req
, &s6
, sizeof (s6
)); 
4094         lck_mtx_unlock(nd6_mutex
);