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