]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/nd6.c
xnu-1486.2.11.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6.c
1 /*
2 * Copyright (c) 2008 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 /* $FreeBSD: src/sys/netinet6/nd6.c,v 1.20 2002/08/02 20:49:14 rwatson Exp $ */
30 /* $KAME: nd6.c,v 1.144 2001/05/24 07:44:00 itojun Exp $ */
31
32 /*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61 /*
62 * XXX
63 * KAME 970409 note:
64 * BSD/OS version heavily modifies this code, related to llinfo.
65 * Since we don't have BSD/OS version of net/route.c in our hand,
66 * I left the code mostly as it was in 970310. -- itojun
67 */
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/malloc.h>
72 #include <sys/mbuf.h>
73 #include <sys/socket.h>
74 #include <sys/sockio.h>
75 #include <sys/time.h>
76 #include <sys/kernel.h>
77 #include <sys/sysctl.h>
78 #include <sys/errno.h>
79 #include <sys/syslog.h>
80 #include <sys/protosw.h>
81 #include <sys/proc.h>
82 #include <kern/queue.h>
83 #include <kern/zalloc.h>
84
85 #define DONT_WARN_OBSOLETE
86 #include <net/if.h>
87 #include <net/if_dl.h>
88 #include <net/if_types.h>
89 #include <net/if_atm.h>
90 #include <net/route.h>
91 #include <net/dlil.h>
92
93 #include <netinet/in.h>
94 #include <netinet/in_arp.h>
95 #include <netinet/if_ether.h>
96 #include <netinet/if_fddi.h>
97 #include <netinet6/in6_var.h>
98 #include <netinet/ip6.h>
99 #include <netinet6/ip6_var.h>
100 #include <netinet6/nd6.h>
101 #include <netinet6/in6_prefix.h>
102 #include <netinet/icmp6.h>
103
104 #include "loop.h"
105
106 #include <net/net_osdep.h>
107
108 #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
109 #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
110
111 #define SA(p) ((struct sockaddr *)(p))
112 #define SIN6(s) ((struct sockaddr_in6 *)s)
113 #define SDL(s) ((struct sockaddr_dl *)s)
114 #define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
115
116 /* timer values */
117 int nd6_prune = 1; /* walk list every 1 seconds */
118 int nd6_delay = 5; /* delay first probe time 5 second */
119 int nd6_umaxtries = 3; /* maximum unicast query */
120 int nd6_mmaxtries = 3; /* maximum multicast query */
121 int nd6_useloopback = 1; /* use loopback interface for local traffic */
122 int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */
123
124 /* preventing too many loops in ND option parsing */
125 int nd6_maxndopt = 10; /* max # of ND options allowed */
126
127 int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */
128
129 #if ND6_DEBUG
130 int nd6_debug = 1;
131 #else
132 int nd6_debug = 0;
133 #endif
134
135 /* for debugging? */
136 static int nd6_inuse, nd6_allocated;
137
138 /*
139 * Synchronization notes:
140 *
141 * The global list of ND entries are stored in llinfo_nd6; an entry
142 * gets inserted into the list when the route is created and gets
143 * removed from the list when it is deleted; this is done as part
144 * of RTM_ADD/RTM_RESOLVE/RTM_DELETE in nd6_rtrequest().
145 *
146 * Because rnh_lock and rt_lock for the entry are held during those
147 * operations, the same locks (and thus lock ordering) must be used
148 * elsewhere to access the relevant data structure fields:
149 *
150 * ln_next, ln_prev, ln_rt
151 *
152 * - Routing lock (rnh_lock)
153 *
154 * ln_hold, ln_asked, ln_expire, ln_state, ln_router, ln_byhint, ln_flags
155 *
156 * - Routing entry lock (rt_lock)
157 *
158 * Due to the dependency on rt_lock, llinfo_nd6 has the same lifetime
159 * as the route entry itself. When a route is deleted (RTM_DELETE),
160 * it is simply removed from the global list but the memory is not
161 * freed until the route itself is freed.
162 */
163 struct llinfo_nd6 llinfo_nd6 = {
164 &llinfo_nd6, &llinfo_nd6, NULL, NULL, 0, 0, 0, 0, 0, 0
165 };
166
167 /* Protected by nd_if_rwlock */
168 size_t nd_ifinfo_indexlim = 32; /* increased for 5589193 */
169 struct nd_ifinfo *nd_ifinfo = NULL;
170
171 static lck_grp_attr_t *nd_if_rwlock_grp_attr;
172 static lck_grp_t *nd_if_rwlock_grp;
173 static lck_attr_t *nd_if_rwlock_attr;
174 lck_rw_t *nd_if_rwlock;
175
176 /* Protected by nd6_mutex */
177 struct nd_drhead nd_defrouter;
178 struct nd_prhead nd_prefix = { 0 };
179
180 int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
181 static struct sockaddr_in6 all1_sa;
182
183 static int regen_tmpaddr(struct in6_ifaddr *);
184 extern lck_mtx_t *ip6_mutex;
185 extern lck_mtx_t *nd6_mutex;
186
187 static void nd6_slowtimo(void *ignored_arg);
188 static struct llinfo_nd6 *nd6_llinfo_alloc(void);
189 static void nd6_llinfo_free(void *);
190
191 static void nd6_siocgdrlst(void *, int);
192 static void nd6_siocgprlst(void *, int);
193
194 /*
195 * Insertion and removal from llinfo_nd6 must be done with rnh_lock held.
196 */
197 #define LN_DEQUEUE(_ln) do { \
198 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
199 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
200 (_ln)->ln_next->ln_prev = (_ln)->ln_prev; \
201 (_ln)->ln_prev->ln_next = (_ln)->ln_next; \
202 (_ln)->ln_prev = (_ln)->ln_next = NULL; \
203 (_ln)->ln_flags &= ~ND6_LNF_IN_USE; \
204 } while (0)
205
206 #define LN_INSERTHEAD(_ln) do { \
207 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); \
208 RT_LOCK_ASSERT_HELD((_ln)->ln_rt); \
209 (_ln)->ln_next = llinfo_nd6.ln_next; \
210 llinfo_nd6.ln_next = (_ln); \
211 (_ln)->ln_prev = &llinfo_nd6; \
212 (_ln)->ln_next->ln_prev = (_ln); \
213 (_ln)->ln_flags |= ND6_LNF_IN_USE; \
214 } while (0)
215
216 static struct zone *llinfo_nd6_zone;
217 #define LLINFO_ND6_ZONE_MAX 256 /* maximum elements in zone */
218 #define LLINFO_ND6_ZONE_NAME "llinfo_nd6" /* name for zone */
219
220 void
221 nd6_init()
222 {
223 static int nd6_init_done = 0;
224 int i;
225
226 if (nd6_init_done) {
227 log(LOG_NOTICE, "nd6_init called more than once (ignored)\n");
228 return;
229 }
230
231 all1_sa.sin6_family = AF_INET6;
232 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
233 for (i = 0; i < sizeof(all1_sa.sin6_addr); i++)
234 all1_sa.sin6_addr.s6_addr[i] = 0xff;
235
236 /* initialization of the default router list */
237 TAILQ_INIT(&nd_defrouter);
238
239 nd_if_rwlock_grp_attr = lck_grp_attr_alloc_init();
240 nd_if_rwlock_grp = lck_grp_alloc_init("nd_if_rwlock",
241 nd_if_rwlock_grp_attr);
242 nd_if_rwlock_attr = lck_attr_alloc_init();
243 nd_if_rwlock = lck_rw_alloc_init(nd_if_rwlock_grp, nd_if_rwlock_attr);
244
245 llinfo_nd6_zone = zinit(sizeof (struct llinfo_nd6),
246 LLINFO_ND6_ZONE_MAX * sizeof (struct llinfo_nd6), 0,
247 LLINFO_ND6_ZONE_NAME);
248 if (llinfo_nd6_zone == NULL)
249 panic("%s: failed allocating llinfo_nd6_zone", __func__);
250
251 zone_change(llinfo_nd6_zone, Z_EXPAND, TRUE);
252
253 nd6_init_done = 1;
254
255 /* start timer */
256 timeout(nd6_slowtimo, (caddr_t)0, ND6_SLOWTIMER_INTERVAL * hz);
257 }
258
259 static struct llinfo_nd6 *
260 nd6_llinfo_alloc(void)
261 {
262 return (zalloc(llinfo_nd6_zone));
263 }
264
265 static void
266 nd6_llinfo_free(void *arg)
267 {
268 struct llinfo_nd6 *ln = arg;
269
270 if (ln->ln_next != NULL || ln->ln_prev != NULL) {
271 panic("%s: trying to free %p when it is in use", __func__, ln);
272 /* NOTREACHED */
273 }
274
275 /* Just in case there's anything there, free it */
276 if (ln->ln_hold != NULL) {
277 m_freem(ln->ln_hold);
278 ln->ln_hold = NULL;
279 }
280
281 zfree(llinfo_nd6_zone, ln);
282 }
283
284 int
285 nd6_ifattach(struct ifnet *ifp)
286 {
287
288 /*
289 * We have some arrays that should be indexed by if_index.
290 * since if_index will grow dynamically, they should grow too.
291 */
292 lck_rw_lock_exclusive(nd_if_rwlock);
293 if (nd_ifinfo == NULL || if_index >= nd_ifinfo_indexlim) {
294 size_t n;
295 caddr_t q;
296 size_t newlim = nd_ifinfo_indexlim;
297
298 while (if_index >= newlim)
299 newlim <<= 1;
300
301 /* grow nd_ifinfo */
302 n = newlim * sizeof(struct nd_ifinfo);
303 q = (caddr_t)_MALLOC(n, M_IP6NDP, M_WAITOK);
304 if (q == NULL) {
305 lck_rw_done(nd_if_rwlock);
306 return ENOBUFS;
307 }
308 bzero(q, n);
309 nd_ifinfo_indexlim = newlim;
310 if (nd_ifinfo) {
311 bcopy((caddr_t)nd_ifinfo, q, n/2);
312 /*
313 * We might want to pattern fill the old
314 * array to catch use-after-free cases.
315 */
316 FREE((caddr_t)nd_ifinfo, M_IP6NDP);
317 }
318 nd_ifinfo = (struct nd_ifinfo *)q;
319 }
320 lck_rw_done(nd_if_rwlock);
321
322 #define ND nd_ifinfo[ifp->if_index]
323
324 /*
325 * Don't initialize if called twice.
326 * XXX: to detect this, we should choose a member that is never set
327 * before initialization of the ND structure itself. We formaly used
328 * the linkmtu member, which was not suitable because it could be
329 * initialized via "ifconfig mtu".
330 */
331 lck_rw_lock_shared(nd_if_rwlock);
332 if (ND.basereachable) {
333 lck_rw_done(nd_if_rwlock);
334 return 0;
335 }
336 ND.linkmtu = ifp->if_mtu;
337 ND.chlim = IPV6_DEFHLIM;
338 ND.basereachable = REACHABLE_TIME;
339 ND.reachable = ND_COMPUTE_RTIME(ND.basereachable);
340 ND.retrans = RETRANS_TIMER;
341 ND.receivedra = 0;
342 ND.flags = ND6_IFF_PERFORMNUD;
343 lck_rw_done(nd_if_rwlock);
344 nd6_setmtu(ifp);
345 #undef ND
346
347 return 0;
348 }
349
350 /*
351 * Reset ND level link MTU. This function is called when the physical MTU
352 * changes, which means we might have to adjust the ND level MTU.
353 */
354 void
355 nd6_setmtu(struct ifnet *ifp)
356 {
357 struct nd_ifinfo *ndi;
358 u_int32_t oldmaxmtu, maxmtu;
359
360 /*
361 * Make sure IPv6 is enabled for the interface first,
362 * because this can be called directly from SIOCSIFMTU for IPv4
363 */
364 lck_rw_lock_shared(nd_if_rwlock);
365 if (ifp->if_index >= nd_ifinfo_indexlim) {
366 lck_rw_done(nd_if_rwlock);
367 return; /* we're out of bound for nd_ifinfo */
368 }
369
370 ndi = &nd_ifinfo[ifp->if_index];
371 oldmaxmtu = ndi->maxmtu;
372
373 /*
374 * The ND level maxmtu is somewhat redundant to the interface MTU
375 * and is an implementation artifact of KAME. Instead of hard-
376 * limiting the maxmtu based on the interface type here, we simply
377 * take the if_mtu value since SIOCSIFMTU would have taken care of
378 * the sanity checks related to the maximum MTU allowed for the
379 * interface (a value that is known only by the interface layer),
380 * by sending the request down via ifnet_ioctl(). The use of the
381 * ND level maxmtu and linkmtu (the latter obtained via RA) are done
382 * via IN6_LINKMTU() which does further checking against if_mtu.
383 */
384 maxmtu = ndi->maxmtu = ifp->if_mtu;
385
386 /*
387 * Decreasing the interface MTU under IPV6 minimum MTU may cause
388 * undesirable situation. We thus notify the operator of the change
389 * explicitly. The check for oldmaxmtu is necessary to restrict the
390 * log to the case of changing the MTU, not initializing it.
391 */
392 if (oldmaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) {
393 log(LOG_NOTICE, "nd6_setmtu: "
394 "new link MTU on %s%d (%u) is too small for IPv6\n",
395 ifp->if_name, ifp->if_unit, (uint32_t)ndi->maxmtu);
396 }
397 lck_rw_done(nd_if_rwlock);
398
399 /* also adjust in6_maxmtu if necessary. */
400 if (maxmtu > in6_maxmtu)
401 in6_setmaxmtu();
402 }
403
404 void
405 nd6_option_init(
406 void *opt,
407 int icmp6len,
408 union nd_opts *ndopts)
409 {
410 bzero(ndopts, sizeof(*ndopts));
411 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
412 ndopts->nd_opts_last
413 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
414
415 if (icmp6len == 0) {
416 ndopts->nd_opts_done = 1;
417 ndopts->nd_opts_search = NULL;
418 }
419 }
420
421 /*
422 * Take one ND option.
423 */
424 struct nd_opt_hdr *
425 nd6_option(
426 union nd_opts *ndopts)
427 {
428 struct nd_opt_hdr *nd_opt;
429 int olen;
430
431 if (!ndopts)
432 panic("ndopts == NULL in nd6_option\n");
433 if (!ndopts->nd_opts_last)
434 panic("uninitialized ndopts in nd6_option\n");
435 if (!ndopts->nd_opts_search)
436 return NULL;
437 if (ndopts->nd_opts_done)
438 return NULL;
439
440 nd_opt = ndopts->nd_opts_search;
441
442 /* make sure nd_opt_len is inside the buffer */
443 if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) {
444 bzero(ndopts, sizeof(*ndopts));
445 return NULL;
446 }
447
448 olen = nd_opt->nd_opt_len << 3;
449 if (olen == 0) {
450 /*
451 * Message validation requires that all included
452 * options have a length that is greater than zero.
453 */
454 bzero(ndopts, sizeof(*ndopts));
455 return NULL;
456 }
457
458 ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
459 if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
460 /* option overruns the end of buffer, invalid */
461 bzero(ndopts, sizeof(*ndopts));
462 return NULL;
463 } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
464 /* reached the end of options chain */
465 ndopts->nd_opts_done = 1;
466 ndopts->nd_opts_search = NULL;
467 }
468 return nd_opt;
469 }
470
471 /*
472 * Parse multiple ND options.
473 * This function is much easier to use, for ND routines that do not need
474 * multiple options of the same type.
475 */
476 int
477 nd6_options(
478 union nd_opts *ndopts)
479 {
480 struct nd_opt_hdr *nd_opt;
481 int i = 0;
482
483 if (!ndopts)
484 panic("ndopts == NULL in nd6_options\n");
485 if (!ndopts->nd_opts_last)
486 panic("uninitialized ndopts in nd6_options\n");
487 if (!ndopts->nd_opts_search)
488 return 0;
489
490 while (1) {
491 nd_opt = nd6_option(ndopts);
492 if (!nd_opt && !ndopts->nd_opts_last) {
493 /*
494 * Message validation requires that all included
495 * options have a length that is greater than zero.
496 */
497 icmp6stat.icp6s_nd_badopt++;
498 bzero(ndopts, sizeof(*ndopts));
499 return -1;
500 }
501
502 if (!nd_opt)
503 goto skip1;
504
505 switch (nd_opt->nd_opt_type) {
506 case ND_OPT_SOURCE_LINKADDR:
507 case ND_OPT_TARGET_LINKADDR:
508 case ND_OPT_MTU:
509 case ND_OPT_REDIRECTED_HEADER:
510 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
511 nd6log((LOG_INFO,
512 "duplicated ND6 option found (type=%d)\n",
513 nd_opt->nd_opt_type));
514 /* XXX bark? */
515 } else {
516 ndopts->nd_opt_array[nd_opt->nd_opt_type]
517 = nd_opt;
518 }
519 break;
520 case ND_OPT_PREFIX_INFORMATION:
521 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
522 ndopts->nd_opt_array[nd_opt->nd_opt_type]
523 = nd_opt;
524 }
525 ndopts->nd_opts_pi_end =
526 (struct nd_opt_prefix_info *)nd_opt;
527 break;
528 default:
529 /*
530 * Unknown options must be silently ignored,
531 * to accomodate future extension to the protocol.
532 */
533 nd6log((LOG_DEBUG,
534 "nd6_options: unsupported option %d - "
535 "option ignored\n", nd_opt->nd_opt_type));
536 }
537
538 skip1:
539 i++;
540 if (i > nd6_maxndopt) {
541 icmp6stat.icp6s_nd_toomanyopt++;
542 nd6log((LOG_INFO, "too many loop in nd opt\n"));
543 break;
544 }
545
546 if (ndopts->nd_opts_done)
547 break;
548 }
549
550 return 0;
551 }
552
553 /*
554 * ND6 timer routine to expire default route list and prefix list
555 */
556 void
557 nd6_timer(
558 __unused void *ignored_arg)
559 {
560 struct llinfo_nd6 *ln;
561 struct nd_defrouter *dr;
562 struct nd_prefix *pr;
563 struct ifnet *ifp = NULL;
564 struct in6_ifaddr *ia6, *nia6;
565 struct in6_addrlifetime *lt6;
566 struct timeval timenow;
567
568 getmicrotime(&timenow);
569 again:
570 /*
571 * The global list llinfo_nd6 is modified by nd6_request() and is
572 * therefore protected by rnh_lock. For obvious reasons, we cannot
573 * hold rnh_lock across calls that might lead to code paths which
574 * attempt to acquire rnh_lock, else we deadlock. Hence for such
575 * cases we drop rt_lock and rnh_lock, make the calls, and repeat the
576 * loop. To ensure that we don't process the same entry more than
577 * once in a single timeout, we mark the "already-seen" entries with
578 * ND6_LNF_TIMER_SKIP flag. At the end of the loop, we do a second
579 * pass thru the entries and clear the flag so they can be processed
580 * during the next timeout.
581 */
582 lck_mtx_lock(rnh_lock);
583 ln = llinfo_nd6.ln_next;
584 while (ln != NULL && ln != &llinfo_nd6) {
585 struct rtentry *rt;
586 struct sockaddr_in6 *dst;
587 struct llinfo_nd6 *next;
588 struct nd_ifinfo ndi;
589
590 /* ln_next/prev/rt is protected by rnh_lock */
591 next = ln->ln_next;
592 rt = ln->ln_rt;
593 RT_LOCK(rt);
594
595 /* We've seen this already; skip it */
596 if (ln->ln_flags & ND6_LNF_TIMER_SKIP) {
597 RT_UNLOCK(rt);
598 ln = next;
599 continue;
600 }
601
602 /* rt->rt_ifp should never be NULL */
603 if ((ifp = rt->rt_ifp) == NULL) {
604 panic("%s: ln(%p) rt(%p) rt_ifp == NULL", __func__,
605 ln, rt);
606 /* NOTREACHED */
607 }
608
609 /* rt_llinfo must always be equal to ln */
610 if ((struct llinfo_nd6 *)rt->rt_llinfo != ln) {
611 panic("%s: rt_llinfo(%p) is not equal to ln(%p)",
612 __func__, rt->rt_llinfo, ln);
613 /* NOTREACHED */
614 }
615
616 /* rt_key should never be NULL */
617 dst = (struct sockaddr_in6 *)rt_key(rt);
618 if (dst == NULL) {
619 panic("%s: rt(%p) key is NULL ln(%p)", __func__,
620 rt, ln);
621 /* NOTREACHED */
622 }
623
624 /* Set the flag in case we jump to "again" */
625 ln->ln_flags |= ND6_LNF_TIMER_SKIP;
626
627 if (ln->ln_expire > timenow.tv_sec) {
628 RT_UNLOCK(rt);
629 ln = next;
630 continue;
631 }
632
633 /* Make a copy (we're using it read-only anyway) */
634 lck_rw_lock_shared(nd_if_rwlock);
635 if (ifp->if_index >= nd_ifinfo_indexlim) {
636 lck_rw_done(nd_if_rwlock);
637 RT_UNLOCK(rt);
638 ln = next;
639 continue;
640 }
641 ndi = nd_ifinfo[ifp->if_index];
642 lck_rw_done(nd_if_rwlock);
643
644 RT_LOCK_ASSERT_HELD(rt);
645
646 switch (ln->ln_state) {
647 case ND6_LLINFO_INCOMPLETE:
648 if (ln->ln_asked < nd6_mmaxtries) {
649 ln->ln_asked++;
650 ln->ln_expire = timenow.tv_sec +
651 ndi.retrans / 1000;
652 RT_ADDREF_LOCKED(rt);
653 RT_UNLOCK(rt);
654 lck_mtx_unlock(rnh_lock);
655 nd6_ns_output(ifp, NULL, &dst->sin6_addr,
656 ln, 0, 0);
657 RT_REMREF(rt);
658 } else {
659 struct mbuf *m = ln->ln_hold;
660 ln->ln_hold = NULL;
661 if (m != NULL) {
662 /*
663 * Fake rcvif to make ICMP error
664 * more helpful in diagnosing
665 * for the receiver.
666 * XXX: should we consider
667 * older rcvif?
668 */
669 m->m_pkthdr.rcvif = ifp;
670 RT_UNLOCK(rt);
671 lck_mtx_unlock(rnh_lock);
672 icmp6_error(m, ICMP6_DST_UNREACH,
673 ICMP6_DST_UNREACH_ADDR, 0);
674 } else {
675 RT_UNLOCK(rt);
676 lck_mtx_unlock(rnh_lock);
677 }
678 nd6_free(rt);
679 }
680 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
681 goto again;
682
683 case ND6_LLINFO_REACHABLE:
684 if (ln->ln_expire) {
685 ln->ln_state = ND6_LLINFO_STALE;
686 ln->ln_expire = timenow.tv_sec + nd6_gctimer;
687 }
688 RT_UNLOCK(rt);
689 break;
690
691 case ND6_LLINFO_STALE:
692 case ND6_LLINFO_PURGE:
693 /* Garbage Collection(RFC 2461 5.3) */
694 if (ln->ln_expire) {
695 RT_UNLOCK(rt);
696 lck_mtx_unlock(rnh_lock);
697 nd6_free(rt);
698 lck_mtx_assert(rnh_lock,
699 LCK_MTX_ASSERT_NOTOWNED);
700 goto again;
701 } else {
702 RT_UNLOCK(rt);
703 }
704 break;
705
706 case ND6_LLINFO_DELAY:
707 if ((ndi.flags & ND6_IFF_PERFORMNUD) != 0) {
708 /* We need NUD */
709 ln->ln_asked = 1;
710 ln->ln_state = ND6_LLINFO_PROBE;
711 ln->ln_expire = timenow.tv_sec +
712 ndi.retrans / 1000;
713 RT_ADDREF_LOCKED(rt);
714 RT_UNLOCK(rt);
715 lck_mtx_unlock(rnh_lock);
716 nd6_ns_output(ifp, &dst->sin6_addr,
717 &dst->sin6_addr, ln, 0, 0);
718 lck_mtx_assert(rnh_lock,
719 LCK_MTX_ASSERT_NOTOWNED);
720 RT_REMREF(rt);
721 goto again;
722 }
723 ln->ln_state = ND6_LLINFO_STALE; /* XXX */
724 ln->ln_expire = timenow.tv_sec + nd6_gctimer;
725 RT_UNLOCK(rt);
726 break;
727
728 case ND6_LLINFO_PROBE:
729 if (ln->ln_asked < nd6_umaxtries) {
730 ln->ln_asked++;
731 ln->ln_expire = timenow.tv_sec +
732 ndi.retrans / 1000;
733 RT_ADDREF_LOCKED(rt);
734 RT_UNLOCK(rt);
735 lck_mtx_unlock(rnh_lock);
736 nd6_ns_output(ifp, &dst->sin6_addr,
737 &dst->sin6_addr, ln, 0, 0);
738 RT_REMREF(rt);
739 } else {
740 RT_UNLOCK(rt);
741 lck_mtx_unlock(rnh_lock);
742 nd6_free(rt);
743 }
744 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
745 goto again;
746
747 default:
748 RT_UNLOCK(rt);
749 break;
750 }
751 ln = next;
752 }
753 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
754
755 /* Now clear the flag from all entries */
756 ln = llinfo_nd6.ln_next;
757 while (ln != NULL && ln != &llinfo_nd6) {
758 struct rtentry *rt = ln->ln_rt;
759 struct llinfo_nd6 *next = ln->ln_next;
760
761 RT_LOCK_SPIN(rt);
762 if (ln->ln_flags & ND6_LNF_TIMER_SKIP)
763 ln->ln_flags &= ~ND6_LNF_TIMER_SKIP;
764 RT_UNLOCK(rt);
765 ln = next;
766 }
767 lck_mtx_unlock(rnh_lock);
768
769 /* expire default router list */
770 lck_mtx_lock(nd6_mutex);
771 dr = TAILQ_FIRST(&nd_defrouter);
772 while (dr) {
773 if (dr->expire && dr->expire < timenow.tv_sec) {
774 struct nd_defrouter *t;
775 t = TAILQ_NEXT(dr, dr_entry);
776 defrtrlist_del(dr, 1);
777 dr = t;
778 } else {
779 dr = TAILQ_NEXT(dr, dr_entry);
780 }
781 }
782
783 /*
784 * expire interface addresses.
785 * in the past the loop was inside prefix expiry processing.
786 * However, from a stricter speci-confrmance standpoint, we should
787 * rather separate address lifetimes and prefix lifetimes.
788 */
789 addrloop:
790 for (ia6 = in6_ifaddrs; ia6; ia6 = nia6) {
791 nia6 = ia6->ia_next;
792 /* check address lifetime */
793 lt6 = &ia6->ia6_lifetime;
794 if (IFA6_IS_INVALID(ia6)) {
795 int regen = 0;
796
797 /*
798 * Extra reference for ourselves; it's no-op if
799 * we don't have to regenerate temporary address,
800 * otherwise it protects the address from going
801 * away since we drop nd6_mutex below.
802 */
803 ifaref(&ia6->ia_ifa);
804
805 /*
806 * If the expiring address is temporary, try
807 * regenerating a new one. This would be useful when
808 * we suspended a laptop PC, then turned it on after a
809 * period that could invalidate all temporary
810 * addresses. Although we may have to restart the
811 * loop (see below), it must be after purging the
812 * address. Otherwise, we'd see an infinite loop of
813 * regeneration.
814 */
815 if (ip6_use_tempaddr &&
816 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
817 /* NOTE: We have to drop the lock here because
818 * regen_tmpaddr() eventually calls in6_update_ifa(),
819 * which must take the lock and would otherwise cause a
820 * hang. This is safe because the goto addrloop
821 * leads to a reevaluation of the in6_ifaddrs list
822 */
823 lck_mtx_unlock(nd6_mutex);
824 if (regen_tmpaddr(ia6) == 0)
825 regen = 1;
826 lck_mtx_lock(nd6_mutex);
827 }
828
829 in6_purgeaddr(&ia6->ia_ifa, 1);
830
831 /* Release extra reference taken above */
832 ifafree(&ia6->ia_ifa);
833
834 if (regen)
835 goto addrloop; /* XXX: see below */
836 }
837 if (IFA6_IS_DEPRECATED(ia6)) {
838 int oldflags = ia6->ia6_flags;
839
840 ia6->ia6_flags |= IN6_IFF_DEPRECATED;
841
842 /*
843 * If a temporary address has just become deprecated,
844 * regenerate a new one if possible.
845 */
846 if (ip6_use_tempaddr &&
847 (ia6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
848 (oldflags & IN6_IFF_DEPRECATED) == 0) {
849
850 /* see NOTE above */
851 lck_mtx_unlock(nd6_mutex);
852 if (regen_tmpaddr(ia6) == 0) {
853 /*
854 * A new temporary address is
855 * generated.
856 * XXX: this means the address chain
857 * has changed while we are still in
858 * the loop. Although the change
859 * would not cause disaster (because
860 * it's not a deletion, but an
861 * addition,) we'd rather restart the
862 * loop just for safety. Or does this
863 * significantly reduce performance??
864 */
865 lck_mtx_lock(nd6_mutex);
866 goto addrloop;
867 }
868 lck_mtx_lock(nd6_mutex);
869 }
870 } else {
871 /*
872 * A new RA might have made a deprecated address
873 * preferred.
874 */
875 ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
876 }
877 }
878
879 /* expire prefix list */
880 pr = nd_prefix.lh_first;
881 while (pr) {
882 /*
883 * check prefix lifetime.
884 * since pltime is just for autoconf, pltime processing for
885 * prefix is not necessary.
886 */
887 if (pr->ndpr_expire && pr->ndpr_expire < timenow.tv_sec) {
888 struct nd_prefix *t;
889 t = pr->ndpr_next;
890
891 /*
892 * address expiration and prefix expiration are
893 * separate. NEVER perform in6_purgeaddr here.
894 */
895
896 prelist_remove(pr, 1);
897 pr = t;
898 } else
899 pr = pr->ndpr_next;
900 }
901 lck_mtx_unlock(nd6_mutex);
902 timeout(nd6_timer, (caddr_t)0, nd6_prune * hz);
903 }
904
905 static int
906 regen_tmpaddr(
907 struct in6_ifaddr *ia6) /* deprecated/invalidated temporary address */
908 {
909 struct ifaddr *ifa;
910 struct ifnet *ifp;
911 struct in6_ifaddr *public_ifa6 = NULL;
912 struct timeval timenow;
913
914 getmicrotime(&timenow);
915
916 ifp = ia6->ia_ifa.ifa_ifp;
917 ifnet_lock_exclusive(ifp);
918 for (ifa = ifp->if_addrlist.tqh_first; ifa;
919 ifa = ifa->ifa_list.tqe_next)
920 {
921 struct in6_ifaddr *it6;
922
923 if (ifa->ifa_addr->sa_family != AF_INET6)
924 continue;
925
926 it6 = (struct in6_ifaddr *)ifa;
927
928 /* ignore no autoconf addresses. */
929 if ((it6->ia6_flags & IN6_IFF_AUTOCONF) == 0)
930 continue;
931
932 /* ignore autoconf addresses with different prefixes. */
933 if (it6->ia6_ndpr == NULL || it6->ia6_ndpr != ia6->ia6_ndpr)
934 continue;
935
936 /*
937 * Now we are looking at an autoconf address with the same
938 * prefix as ours. If the address is temporary and is still
939 * preferred, do not create another one. It would be rare, but
940 * could happen, for example, when we resume a laptop PC after
941 * a long period.
942 */
943 if ((it6->ia6_flags & IN6_IFF_TEMPORARY) != 0 &&
944 !IFA6_IS_DEPRECATED(it6)) {
945 public_ifa6 = NULL;
946 break;
947 }
948
949 /*
950 * This is a public autoconf address that has the same prefix
951 * as ours. If it is preferred, keep it. We can't break the
952 * loop here, because there may be a still-preferred temporary
953 * address with the prefix.
954 */
955 if (!IFA6_IS_DEPRECATED(it6))
956 public_ifa6 = it6;
957 }
958 ifnet_lock_done(ifp);
959
960 if (public_ifa6 != NULL) {
961 int e;
962
963 if ((e = in6_tmpifadd(public_ifa6, 0, M_WAITOK)) != 0) {
964 log(LOG_NOTICE, "regen_tmpaddr: failed to create a new"
965 " tmp addr,errno=%d\n", e);
966 return(-1);
967 }
968 return(0);
969 }
970
971 return(-1);
972 }
973
974 /*
975 * Nuke neighbor cache/prefix/default router management table, right before
976 * ifp goes away.
977 */
978 void
979 nd6_purge(
980 struct ifnet *ifp)
981 {
982 struct llinfo_nd6 *ln;
983 struct nd_defrouter *dr, *ndr, drany;
984 struct nd_prefix *pr, *npr;
985
986 /* Nuke default router list entries toward ifp */
987 lck_mtx_lock(nd6_mutex);
988 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
989 /*
990 * The first entry of the list may be stored in
991 * the routing table, so we'll delete it later.
992 */
993 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = ndr) {
994 ndr = TAILQ_NEXT(dr, dr_entry);
995 if (dr->ifp == ifp)
996 defrtrlist_del(dr, 1);
997 }
998 dr = TAILQ_FIRST(&nd_defrouter);
999 if (dr->ifp == ifp)
1000 defrtrlist_del(dr, 1);
1001 }
1002
1003 /* Nuke prefix list entries toward ifp */
1004 for (pr = nd_prefix.lh_first; pr; pr = npr) {
1005 npr = pr->ndpr_next;
1006 if (pr->ndpr_ifp == ifp) {
1007 /*
1008 * Previously, pr->ndpr_addr is removed as well,
1009 * but I strongly believe we don't have to do it.
1010 * nd6_purge() is only called from in6_ifdetach(),
1011 * which removes all the associated interface addresses
1012 * by itself.
1013 * (jinmei@kame.net 20010129)
1014 */
1015 prelist_remove(pr, 1);
1016 }
1017 }
1018
1019 /* cancel default outgoing interface setting */
1020 if (nd6_defifindex == ifp->if_index) {
1021 /* Release nd6_mutex as it will be acquired
1022 * during nd6_setdefaultiface again
1023 */
1024 lck_mtx_unlock(nd6_mutex);
1025 nd6_setdefaultiface(0);
1026 lck_mtx_lock(nd6_mutex);
1027 }
1028
1029 if (!ip6_forwarding && (ip6_accept_rtadv || (ifp->if_eflags & IFEF_ACCEPT_RTADVD))) {
1030 /* refresh default router list */
1031 bzero(&drany, sizeof(drany));
1032 defrouter_delreq(&drany, 0);
1033 defrouter_select();
1034 }
1035 lck_mtx_unlock(nd6_mutex);
1036
1037 /*
1038 * Nuke neighbor cache entries for the ifp.
1039 * Note that rt->rt_ifp may not be the same as ifp,
1040 * due to KAME goto ours hack. See RTM_RESOLVE case in
1041 * nd6_rtrequest(), and ip6_input().
1042 */
1043 again:
1044 lck_mtx_lock(rnh_lock);
1045 ln = llinfo_nd6.ln_next;
1046 while (ln != NULL && ln != &llinfo_nd6) {
1047 struct rtentry *rt;
1048 struct llinfo_nd6 *nln;
1049
1050 nln = ln->ln_next;
1051 rt = ln->ln_rt;
1052 RT_LOCK(rt);
1053 if (rt->rt_gateway != NULL &&
1054 rt->rt_gateway->sa_family == AF_LINK &&
1055 SDL(rt->rt_gateway)->sdl_index == ifp->if_index) {
1056 RT_UNLOCK(rt);
1057 lck_mtx_unlock(rnh_lock);
1058 /*
1059 * See comments on nd6_timer() for reasons why
1060 * this loop is repeated; we bite the costs of
1061 * going thru the same llinfo_nd6 more than once
1062 * here, since this purge happens during detach,
1063 * and that unlike the timer case, it's possible
1064 * there's more than one purges happening at the
1065 * same time (thus a flag wouldn't buy anything).
1066 */
1067 nd6_free(rt);
1068 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1069 goto again;
1070 } else {
1071 RT_UNLOCK(rt);
1072 }
1073 ln = nln;
1074 }
1075 lck_mtx_unlock(rnh_lock);
1076 }
1077
1078 /*
1079 * Upon success, the returned route will be locked and the caller is
1080 * responsible for releasing the reference and doing RT_UNLOCK(rt).
1081 * This routine does not require rnh_lock to be held by the caller,
1082 * although it needs to be indicated of such a case in order to call
1083 * the correct variant of the relevant routing routines.
1084 */
1085 struct rtentry *
1086 nd6_lookup(
1087 struct in6_addr *addr6,
1088 int create,
1089 struct ifnet *ifp,
1090 int rt_locked)
1091 {
1092 struct rtentry *rt;
1093 struct sockaddr_in6 sin6;
1094
1095 bzero(&sin6, sizeof(sin6));
1096 sin6.sin6_len = sizeof(struct sockaddr_in6);
1097 sin6.sin6_family = AF_INET6;
1098 sin6.sin6_addr = *addr6;
1099 #if SCOPEDROUTING
1100 sin6.sin6_scope_id = in6_addr2scopeid(ifp, addr6);
1101 #endif
1102 if (rt_locked)
1103 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
1104
1105 rt = rt_locked ? rtalloc1_locked((struct sockaddr *)&sin6, create, 0) :
1106 rtalloc1((struct sockaddr *)&sin6, create, 0);
1107
1108 if (rt != NULL) {
1109 RT_LOCK(rt);
1110 if ((rt->rt_flags & RTF_LLINFO) == 0) {
1111 /*
1112 * This is the case for the default route. If we
1113 * want to create a neighbor cache for the address,
1114 * we should free the route for the destination and
1115 * allocate an interface route.
1116 */
1117 if (create) {
1118 RT_UNLOCK(rt);
1119 if (rt_locked)
1120 rtfree_locked(rt);
1121 else
1122 rtfree(rt);
1123 rt = NULL;
1124 }
1125 }
1126 }
1127 if (rt == NULL) {
1128 if (create && ifp) {
1129 struct ifaddr *ifa;
1130 int e;
1131
1132 /*
1133 * If no route is available and create is set,
1134 * we allocate a host route for the destination
1135 * and treat it like an interface route.
1136 * This hack is necessary for a neighbor which can't
1137 * be covered by our own prefix.
1138 */
1139 ifa = ifaof_ifpforaddr((struct sockaddr *)&sin6, ifp);
1140 if (ifa == NULL)
1141 return(NULL);
1142
1143 /*
1144 * Create a new route. RTF_LLINFO is necessary
1145 * to create a Neighbor Cache entry for the
1146 * destination in nd6_rtrequest which will be
1147 * called in rtrequest via ifa->ifa_rtrequest.
1148 */
1149 if (!rt_locked)
1150 lck_mtx_lock(rnh_lock);
1151 if ((e = rtrequest_locked(RTM_ADD,
1152 (struct sockaddr *)&sin6, ifa->ifa_addr,
1153 (struct sockaddr *)&all1_sa,
1154 (ifa->ifa_flags | RTF_HOST | RTF_LLINFO) &
1155 ~RTF_CLONING, &rt)) != 0) {
1156 if (e != EEXIST)
1157 log(LOG_ERR, "%s: failed to add route "
1158 "for a neighbor(%s), errno=%d\n",
1159 __func__, ip6_sprintf(addr6), e);
1160 }
1161 if (!rt_locked)
1162 lck_mtx_unlock(rnh_lock);
1163 ifafree(ifa);
1164 if (rt == NULL)
1165 return(NULL);
1166
1167 RT_LOCK(rt);
1168 if (rt->rt_llinfo) {
1169 struct llinfo_nd6 *ln = rt->rt_llinfo;
1170 ln->ln_state = ND6_LLINFO_NOSTATE;
1171 }
1172 } else {
1173 return(NULL);
1174 }
1175 }
1176 RT_LOCK_ASSERT_HELD(rt);
1177 /*
1178 * Validation for the entry.
1179 * Note that the check for rt_llinfo is necessary because a cloned
1180 * route from a parent route that has the L flag (e.g. the default
1181 * route to a p2p interface) may have the flag, too, while the
1182 * destination is not actually a neighbor.
1183 * XXX: we can't use rt->rt_ifp to check for the interface, since
1184 * it might be the loopback interface if the entry is for our
1185 * own address on a non-loopback interface. Instead, we should
1186 * use rt->rt_ifa->ifa_ifp, which would specify the REAL
1187 * interface.
1188 */
1189 if (((ifp && (ifp->if_type != IFT_PPP)) && ((ifp->if_eflags & IFEF_NOAUTOIPV6LL) == 0)) &&
1190 ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
1191 rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
1192 (ifp && rt->rt_ifa->ifa_ifp != ifp))) {
1193 RT_REMREF_LOCKED(rt);
1194 RT_UNLOCK(rt);
1195 if (create) {
1196 log(LOG_DEBUG, "%s: failed to lookup %s "
1197 "(if = %s)\n", __func__, ip6_sprintf(addr6),
1198 ifp ? if_name(ifp) : "unspec");
1199 /* xxx more logs... kazu */
1200 }
1201 return(NULL);
1202 }
1203 /*
1204 * Caller needs to release reference and call RT_UNLOCK(rt).
1205 */
1206 return(rt);
1207 }
1208
1209 /*
1210 * Detect if a given IPv6 address identifies a neighbor on a given link.
1211 * XXX: should take care of the destination of a p2p link?
1212 */
1213 int
1214 nd6_is_addr_neighbor(
1215 struct sockaddr_in6 *addr,
1216 struct ifnet *ifp,
1217 int rt_locked)
1218 {
1219 struct ifaddr *ifa;
1220 struct rtentry *rt;
1221 int i;
1222
1223 #define IFADDR6(a) ((((struct in6_ifaddr *)(a))->ia_addr).sin6_addr)
1224 #define IFMASK6(a) ((((struct in6_ifaddr *)(a))->ia_prefixmask).sin6_addr)
1225
1226 /*
1227 * A link-local address is always a neighbor.
1228 * XXX: we should use the sin6_scope_id field rather than the embedded
1229 * interface index.
1230 */
1231 if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) &&
1232 ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]) == ifp->if_index)
1233 return(1);
1234
1235 /*
1236 * If the address matches one of our addresses,
1237 * it should be a neighbor.
1238 */
1239 ifnet_lock_shared(ifp);
1240 for (ifa = ifp->if_addrlist.tqh_first;
1241 ifa;
1242 ifa = ifa->ifa_list.tqe_next)
1243 {
1244 if (ifa->ifa_addr->sa_family != AF_INET6)
1245 continue;
1246
1247 for (i = 0; i < 4; i++) {
1248 if ((IFADDR6(ifa).s6_addr32[i] ^
1249 addr->sin6_addr.s6_addr32[i]) &
1250 IFMASK6(ifa).s6_addr32[i])
1251 continue;
1252 }
1253 ifnet_lock_done(ifp);
1254 return(1);
1255 }
1256 ifnet_lock_done(ifp);
1257
1258 /*
1259 * Even if the address matches none of our addresses, it might be
1260 * in the neighbor cache. Callee returns a locked route upon
1261 * success.
1262 */
1263 if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp, rt_locked)) != NULL) {
1264 RT_LOCK_ASSERT_HELD(rt);
1265 RT_REMREF_LOCKED(rt);
1266 RT_UNLOCK(rt);
1267 return(1);
1268 }
1269
1270 return(0);
1271 #undef IFADDR6
1272 #undef IFMASK6
1273 }
1274
1275 /*
1276 * Free an nd6 llinfo entry.
1277 */
1278 void
1279 nd6_free(
1280 struct rtentry *rt)
1281 {
1282 struct llinfo_nd6 *ln;
1283 struct in6_addr in6;
1284 struct nd_defrouter *dr;
1285
1286 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
1287 RT_LOCK_ASSERT_NOTHELD(rt);
1288 lck_mtx_lock(nd6_mutex);
1289
1290 RT_LOCK(rt);
1291 RT_ADDREF_LOCKED(rt); /* Extra ref */
1292 ln = rt->rt_llinfo;
1293 in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
1294
1295 /*
1296 * Prevent another thread from modifying rt_key, rt_gateway
1297 * via rt_setgate() after the rt_lock is dropped by marking
1298 * the route as defunct.
1299 */
1300 rt->rt_flags |= RTF_CONDEMNED;
1301
1302 /*
1303 * we used to have pfctlinput(PRC_HOSTDEAD) here.
1304 * even though it is not harmful, it was not really necessary.
1305 */
1306
1307 if (!ip6_forwarding && (ip6_accept_rtadv ||
1308 (rt->rt_ifp->if_eflags & IFEF_ACCEPT_RTADVD))) {
1309 dr = defrouter_lookup(&((struct sockaddr_in6 *)rt_key(rt))->
1310 sin6_addr, rt->rt_ifp);
1311
1312 if (ln->ln_router || dr) {
1313 /*
1314 * rt6_flush must be called whether or not the neighbor
1315 * is in the Default Router List.
1316 * See a corresponding comment in nd6_na_input().
1317 */
1318 RT_UNLOCK(rt);
1319 rt6_flush(&in6, rt->rt_ifp);
1320 } else {
1321 RT_UNLOCK(rt);
1322 }
1323
1324 if (dr) {
1325 /*
1326 * Unreachablity of a router might affect the default
1327 * router selection and on-link detection of advertised
1328 * prefixes.
1329 */
1330
1331 /*
1332 * Temporarily fake the state to choose a new default
1333 * router and to perform on-link determination of
1334 * prefixes correctly.
1335 * Below the state will be set correctly,
1336 * or the entry itself will be deleted.
1337 */
1338 RT_LOCK_SPIN(rt);
1339 ln->ln_state = ND6_LLINFO_INCOMPLETE;
1340
1341 /*
1342 * Since defrouter_select() does not affect the
1343 * on-link determination and MIP6 needs the check
1344 * before the default router selection, we perform
1345 * the check now.
1346 */
1347 RT_UNLOCK(rt);
1348 pfxlist_onlink_check(1);
1349
1350 if (dr == TAILQ_FIRST(&nd_defrouter)) {
1351 /*
1352 * It is used as the current default router,
1353 * so we have to move it to the end of the
1354 * list and choose a new one.
1355 * XXX: it is not very efficient if this is
1356 * the only router.
1357 */
1358 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
1359 TAILQ_INSERT_TAIL(&nd_defrouter, dr, dr_entry);
1360
1361 defrouter_select();
1362 }
1363 }
1364 RT_LOCK_ASSERT_NOTHELD(rt);
1365 } else {
1366 RT_UNLOCK(rt);
1367 }
1368
1369 lck_mtx_unlock(nd6_mutex);
1370 /*
1371 * Detach the route from the routing tree and the list of neighbor
1372 * caches, and disable the route entry not to be used in already
1373 * cached routes.
1374 */
1375 (void) rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
1376 rt_mask(rt), 0, (struct rtentry **)0);
1377
1378 /* Extra ref held above; now free it */
1379 rtfree(rt);
1380 }
1381
1382 /*
1383 * Upper-layer reachability hint for Neighbor Unreachability Detection.
1384 *
1385 * XXX cost-effective metods?
1386 */
1387 void
1388 nd6_nud_hint(
1389 struct rtentry *rt,
1390 struct in6_addr *dst6,
1391 int force)
1392 {
1393 struct llinfo_nd6 *ln;
1394 struct timeval timenow;
1395
1396 getmicrotime(&timenow);
1397
1398 /*
1399 * If the caller specified "rt", use that. Otherwise, resolve the
1400 * routing table by supplied "dst6".
1401 */
1402 if (!rt) {
1403 if (!dst6)
1404 return;
1405 /* Callee returns a locked route upon success */
1406 if ((rt = nd6_lookup(dst6, 0, NULL, 0)) == NULL)
1407 return;
1408 RT_LOCK_ASSERT_HELD(rt);
1409 } else {
1410 RT_LOCK(rt);
1411 RT_ADDREF_LOCKED(rt);
1412 }
1413
1414 if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
1415 (rt->rt_flags & RTF_LLINFO) == 0 ||
1416 !rt->rt_llinfo || !rt->rt_gateway ||
1417 rt->rt_gateway->sa_family != AF_LINK) {
1418 /* This is not a host route. */
1419 goto done;
1420 }
1421
1422 ln = rt->rt_llinfo;
1423 if (ln->ln_state < ND6_LLINFO_REACHABLE)
1424 goto done;
1425
1426 /*
1427 * if we get upper-layer reachability confirmation many times,
1428 * it is possible we have false information.
1429 */
1430 if (!force) {
1431 ln->ln_byhint++;
1432 if (ln->ln_byhint > nd6_maxnudhint)
1433 goto done;
1434 }
1435
1436 ln->ln_state = ND6_LLINFO_REACHABLE;
1437 if (ln->ln_expire) {
1438 lck_rw_lock_shared(nd_if_rwlock);
1439 ln->ln_expire = timenow.tv_sec +
1440 nd_ifinfo[rt->rt_ifp->if_index].reachable;
1441 lck_rw_done(nd_if_rwlock);
1442 }
1443 done:
1444 RT_REMREF_LOCKED(rt);
1445 RT_UNLOCK(rt);
1446 }
1447
1448 void
1449 nd6_rtrequest(
1450 int req,
1451 struct rtentry *rt,
1452 __unused struct sockaddr *sa)
1453 {
1454 struct sockaddr *gate = rt->rt_gateway;
1455 struct llinfo_nd6 *ln = rt->rt_llinfo;
1456 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK, 0, 0, 0, 0, 0,
1457 {0,0,0,0,0,0,0,0,0,0,0,0,} };
1458 struct ifnet *ifp = rt->rt_ifp;
1459 struct ifaddr *ifa;
1460 struct timeval timenow;
1461
1462 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
1463 RT_LOCK_ASSERT_HELD(rt);
1464
1465 if ((rt->rt_flags & RTF_GATEWAY))
1466 return;
1467
1468 if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
1469 /*
1470 * This is probably an interface direct route for a link
1471 * which does not need neighbor caches (e.g. fe80::%lo0/64).
1472 * We do not need special treatment below for such a route.
1473 * Moreover, the RTF_LLINFO flag which would be set below
1474 * would annoy the ndp(8) command.
1475 */
1476 return;
1477 }
1478
1479 if (req == RTM_RESOLVE) {
1480 int no_nd_cache;
1481
1482 if (!nd6_need_cache(ifp)) { /* stf case */
1483 no_nd_cache = 1;
1484 } else {
1485 /*
1486 * nd6_is_addr_neighbor() may call nd6_lookup(),
1487 * therefore we drop rt_lock to avoid deadlock
1488 * during the lookup. Using rt_key(rt) is still
1489 * safe because it won't change while rnh_lock
1490 * is held.
1491 */
1492 RT_ADDREF_LOCKED(rt);
1493 RT_UNLOCK(rt);
1494 no_nd_cache = !nd6_is_addr_neighbor(
1495 (struct sockaddr_in6 *)rt_key(rt), ifp, 1);
1496 RT_LOCK(rt);
1497 RT_REMREF_LOCKED(rt);
1498 }
1499
1500 /*
1501 * FreeBSD and BSD/OS often make a cloned host route based
1502 * on a less-specific route (e.g. the default route).
1503 * If the less specific route does not have a "gateway"
1504 * (this is the case when the route just goes to a p2p or an
1505 * stf interface), we'll mistakenly make a neighbor cache for
1506 * the host route, and will see strange neighbor solicitation
1507 * for the corresponding destination. In order to avoid the
1508 * confusion, we check if the destination of the route is
1509 * a neighbor in terms of neighbor discovery, and stop the
1510 * process if not. Additionally, we remove the LLINFO flag
1511 * so that ndp(8) will not try to get the neighbor information
1512 * of the destination.
1513 */
1514 if (no_nd_cache) {
1515 rt->rt_flags &= ~RTF_LLINFO;
1516 return;
1517 }
1518 }
1519
1520 getmicrotime(&timenow);
1521 switch (req) {
1522 case RTM_ADD:
1523 /*
1524 * There is no backward compatibility :)
1525 *
1526 * if ((rt->rt_flags & RTF_HOST) == 0 &&
1527 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1528 * rt->rt_flags |= RTF_CLONING;
1529 */
1530 if (rt->rt_flags & (RTF_CLONING | RTF_LLINFO)) {
1531 /*
1532 * Case 1: This route should come from
1533 * a route to interface. RTF_LLINFO flag is set
1534 * for a host route whose destination should be
1535 * treated as on-link.
1536 */
1537 if (rt_setgate(rt, rt_key(rt),
1538 (struct sockaddr *)&null_sdl) == 0) {
1539 gate = rt->rt_gateway;
1540 SDL(gate)->sdl_type = ifp->if_type;
1541 SDL(gate)->sdl_index = ifp->if_index;
1542 /*
1543 * In case we're called before 1.0 sec.
1544 * has elapsed.
1545 */
1546 if (ln != NULL)
1547 ln->ln_expire = MAX(timenow.tv_sec, 1);
1548 }
1549 if ((rt->rt_flags & RTF_CLONING))
1550 break;
1551 }
1552 /*
1553 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
1554 * We don't do that here since llinfo is not ready yet.
1555 *
1556 * There are also couple of other things to be discussed:
1557 * - unsolicited NA code needs improvement beforehand
1558 * - RFC2461 says we MAY send multicast unsolicited NA
1559 * (7.2.6 paragraph 4), however, it also says that we
1560 * SHOULD provide a mechanism to prevent multicast NA storm.
1561 * we don't have anything like it right now.
1562 * note that the mechanism needs a mutual agreement
1563 * between proxies, which means that we need to implement
1564 * a new protocol, or a new kludge.
1565 * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
1566 * we need to check ip6forwarding before sending it.
1567 * (or should we allow proxy ND configuration only for
1568 * routers? there's no mention about proxy ND from hosts)
1569 */
1570 #if 0
1571 /* XXX it does not work */
1572 if (rt->rt_flags & RTF_ANNOUNCE)
1573 nd6_na_output(ifp,
1574 &SIN6(rt_key(rt))->sin6_addr,
1575 &SIN6(rt_key(rt))->sin6_addr,
1576 ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
1577 1, NULL);
1578 #endif
1579 /* FALLTHROUGH */
1580 case RTM_RESOLVE:
1581 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
1582 /*
1583 * Address resolution isn't necessary for a point to
1584 * point link, so we can skip this test for a p2p link.
1585 */
1586 if (gate->sa_family != AF_LINK ||
1587 gate->sa_len < sizeof(null_sdl)) {
1588 log(LOG_DEBUG,
1589 "nd6_rtrequest: bad gateway value: %s\n",
1590 if_name(ifp));
1591 break;
1592 }
1593 SDL(gate)->sdl_type = ifp->if_type;
1594 SDL(gate)->sdl_index = ifp->if_index;
1595 }
1596 if (ln != NULL)
1597 break; /* This happens on a route change */
1598 /*
1599 * Case 2: This route may come from cloning, or a manual route
1600 * add with a LL address.
1601 */
1602 rt->rt_llinfo = ln = nd6_llinfo_alloc();
1603 if (ln == NULL) {
1604 log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n");
1605 break;
1606 }
1607 rt->rt_llinfo_free = nd6_llinfo_free;
1608
1609 nd6_inuse++;
1610 nd6_allocated++;
1611 Bzero(ln, sizeof(*ln));
1612 ln->ln_rt = rt;
1613 /* this is required for "ndp" command. - shin */
1614 if (req == RTM_ADD) {
1615 /*
1616 * gate should have some valid AF_LINK entry,
1617 * and ln->ln_expire should have some lifetime
1618 * which is specified by ndp command.
1619 */
1620 ln->ln_state = ND6_LLINFO_REACHABLE;
1621 ln->ln_byhint = 0;
1622 } else {
1623 /*
1624 * When req == RTM_RESOLVE, rt is created and
1625 * initialized in rtrequest(), so rt_expire is 0.
1626 */
1627 ln->ln_state = ND6_LLINFO_NOSTATE;
1628 /* In case we're called before 1.0 sec. has elapsed */
1629 ln->ln_expire = MAX(timenow.tv_sec, 1);
1630 }
1631 rt->rt_flags |= RTF_LLINFO;
1632 LN_INSERTHEAD(ln);
1633
1634 /*
1635 * If we have too many cache entries, initiate immediate
1636 * purging for some "less recently used" entries. Note that
1637 * we cannot directly call nd6_free() here because it would
1638 * cause re-entering rtable related routines triggering an LOR
1639 * problem.
1640 */
1641 if (ip6_neighborgcthresh >= 0 &&
1642 nd6_inuse >= ip6_neighborgcthresh) {
1643 int i;
1644
1645 for (i = 0; i < 10 && llinfo_nd6.ln_prev != ln; i++) {
1646 struct llinfo_nd6 *ln_end = llinfo_nd6.ln_prev;
1647 struct rtentry *rt_end = ln_end->ln_rt;
1648
1649 /* Move this entry to the head */
1650 RT_LOCK(rt_end);
1651 LN_DEQUEUE(ln_end);
1652 LN_INSERTHEAD(ln_end);
1653
1654 if (ln_end->ln_expire == 0) {
1655 RT_UNLOCK(rt_end);
1656 continue;
1657 }
1658 if (ln_end->ln_state > ND6_LLINFO_INCOMPLETE)
1659 ln_end->ln_state = ND6_LLINFO_STALE;
1660 else
1661 ln_end->ln_state = ND6_LLINFO_PURGE;
1662 ln_end->ln_expire = timenow.tv_sec;
1663 RT_UNLOCK(rt_end);
1664 }
1665 }
1666
1667 /*
1668 * check if rt_key(rt) is one of my address assigned
1669 * to the interface.
1670 */
1671 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
1672 &SIN6(rt_key(rt))->sin6_addr);
1673 if (ifa) {
1674 caddr_t macp = nd6_ifptomac(ifp);
1675 ln->ln_expire = 0;
1676 ln->ln_state = ND6_LLINFO_REACHABLE;
1677 ln->ln_byhint = 0;
1678 if (macp) {
1679 Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen);
1680 SDL(gate)->sdl_alen = ifp->if_addrlen;
1681 }
1682 if (nd6_useloopback) {
1683 rt->rt_ifp = lo_ifp; /* XXX */
1684 /*
1685 * Make sure rt_ifa be equal to the ifaddr
1686 * corresponding to the address.
1687 * We need this because when we refer
1688 * rt_ifa->ia6_flags in ip6_input, we assume
1689 * that the rt_ifa points to the address instead
1690 * of the loopback address.
1691 */
1692 if (ifa != rt->rt_ifa) {
1693 rtsetifa(rt, ifa);
1694 }
1695 }
1696 ifafree(ifa);
1697 } else if (rt->rt_flags & RTF_ANNOUNCE) {
1698 ln->ln_expire = 0;
1699 ln->ln_state = ND6_LLINFO_REACHABLE;
1700 ln->ln_byhint = 0;
1701
1702 /* join solicited node multicast for proxy ND */
1703 if (ifp->if_flags & IFF_MULTICAST) {
1704 struct in6_addr llsol;
1705 int error;
1706
1707 llsol = SIN6(rt_key(rt))->sin6_addr;
1708 llsol.s6_addr16[0] = htons(0xff02);
1709 llsol.s6_addr16[1] = htons(ifp->if_index);
1710 llsol.s6_addr32[1] = 0;
1711 llsol.s6_addr32[2] = htonl(1);
1712 llsol.s6_addr8[12] = 0xff;
1713
1714 if (!in6_addmulti(&llsol, ifp, &error, 0)) {
1715 nd6log((LOG_ERR, "%s: failed to join "
1716 "%s (errno=%d)\n", if_name(ifp),
1717 ip6_sprintf(&llsol), error));
1718 }
1719 }
1720 }
1721 break;
1722
1723 case RTM_DELETE:
1724 if (!ln)
1725 break;
1726 /* leave from solicited node multicast for proxy ND */
1727 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
1728 (ifp->if_flags & IFF_MULTICAST) != 0) {
1729 struct in6_addr llsol;
1730 struct in6_multi *in6m;
1731
1732 llsol = SIN6(rt_key(rt))->sin6_addr;
1733 llsol.s6_addr16[0] = htons(0xff02);
1734 llsol.s6_addr16[1] = htons(ifp->if_index);
1735 llsol.s6_addr32[1] = 0;
1736 llsol.s6_addr32[2] = htonl(1);
1737 llsol.s6_addr8[12] = 0xff;
1738
1739 ifnet_lock_shared(ifp);
1740 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
1741 ifnet_lock_done(ifp);
1742 if (in6m)
1743 in6_delmulti(in6m, 0);
1744 }
1745 nd6_inuse--;
1746 /*
1747 * Unchain it but defer the actual freeing until the route
1748 * itself is to be freed. rt->rt_llinfo still points to
1749 * llinfo_nd6, and likewise, ln->ln_rt stil points to this
1750 * route entry, except that RTF_LLINFO is now cleared.
1751 */
1752 if (ln->ln_flags & ND6_LNF_IN_USE)
1753 LN_DEQUEUE(ln);
1754 rt->rt_flags &= ~RTF_LLINFO;
1755 if (ln->ln_hold != NULL)
1756 m_freem(ln->ln_hold);
1757 ln->ln_hold = NULL;
1758 }
1759 }
1760
1761 static void
1762 nd6_siocgdrlst(void *data, int data_is_64)
1763 {
1764 struct in6_drlist_64 *drl_64 = (struct in6_drlist_64 *)data;
1765 struct in6_drlist_32 *drl_32 = (struct in6_drlist_32 *)data;
1766 struct nd_defrouter *dr;
1767 int i = 0;
1768
1769 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1770
1771 bzero(data, data_is_64 ? sizeof (*drl_64) : sizeof (*drl_32));
1772 dr = TAILQ_FIRST(&nd_defrouter);
1773 if (data_is_64) {
1774 /* For 64-bit process */
1775 while (dr && i < DRLSTSIZ) {
1776 drl_64->defrouter[i].rtaddr = dr->rtaddr;
1777 if (IN6_IS_ADDR_LINKLOCAL(&drl_64->defrouter[i].rtaddr)) {
1778 /* XXX: need to this hack for KAME stack */
1779 drl_64->defrouter[i].rtaddr.s6_addr16[1] = 0;
1780 } else {
1781 log(LOG_ERR,
1782 "default router list contains a "
1783 "non-linklocal address(%s)\n",
1784 ip6_sprintf(&drl_64->defrouter[i].rtaddr));
1785 }
1786 drl_64->defrouter[i].flags = dr->flags;
1787 drl_64->defrouter[i].rtlifetime = dr->rtlifetime;
1788 drl_64->defrouter[i].expire = dr->expire;
1789 drl_64->defrouter[i].if_index = dr->ifp->if_index;
1790 i++;
1791 dr = TAILQ_NEXT(dr, dr_entry);
1792 }
1793 return;
1794 }
1795 /* For 32-bit process */
1796 while (dr && i < DRLSTSIZ) {
1797 drl_32->defrouter[i].rtaddr = dr->rtaddr;
1798 if (IN6_IS_ADDR_LINKLOCAL(&drl_32->defrouter[i].rtaddr)) {
1799 /* XXX: need to this hack for KAME stack */
1800 drl_32->defrouter[i].rtaddr.s6_addr16[1] = 0;
1801 } else {
1802 log(LOG_ERR,
1803 "default router list contains a "
1804 "non-linklocal address(%s)\n",
1805 ip6_sprintf(&drl_32->defrouter[i].rtaddr));
1806 }
1807 drl_32->defrouter[i].flags = dr->flags;
1808 drl_32->defrouter[i].rtlifetime = dr->rtlifetime;
1809 drl_32->defrouter[i].expire = dr->expire;
1810 drl_32->defrouter[i].if_index = dr->ifp->if_index;
1811 i++;
1812 dr = TAILQ_NEXT(dr, dr_entry);
1813 }
1814 }
1815
1816 static void
1817 nd6_siocgprlst(void *data, int data_is_64)
1818 {
1819 struct in6_prlist_64 *prl_64 = (struct in6_prlist_64 *)data;
1820 struct in6_prlist_32 *prl_32 = (struct in6_prlist_32 *)data;
1821 struct nd_prefix *pr;
1822 struct rr_prefix *rpp;
1823 int i = 0;
1824
1825 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1826 /*
1827 * XXX meaning of fields, especialy "raflags", is very
1828 * differnet between RA prefix list and RR/static prefix list.
1829 * how about separating ioctls into two?
1830 */
1831 bzero(data, data_is_64 ? sizeof (*prl_64) : sizeof (*prl_32));
1832 pr = nd_prefix.lh_first;
1833 if (data_is_64) {
1834 /* For 64-bit process */
1835 while (pr && i < PRLSTSIZ) {
1836 struct nd_pfxrouter *pfr;
1837 int j;
1838
1839 (void) in6_embedscope(&prl_64->prefix[i].prefix,
1840 &pr->ndpr_prefix, NULL, NULL);
1841 prl_64->prefix[i].raflags = pr->ndpr_raf;
1842 prl_64->prefix[i].prefixlen = pr->ndpr_plen;
1843 prl_64->prefix[i].vltime = pr->ndpr_vltime;
1844 prl_64->prefix[i].pltime = pr->ndpr_pltime;
1845 prl_64->prefix[i].if_index = pr->ndpr_ifp->if_index;
1846 prl_64->prefix[i].expire = pr->ndpr_expire;
1847
1848 pfr = pr->ndpr_advrtrs.lh_first;
1849 j = 0;
1850 while (pfr) {
1851 if (j < DRLSTSIZ) {
1852 #define RTRADDR prl_64->prefix[i].advrtr[j]
1853 RTRADDR = pfr->router->rtaddr;
1854 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
1855 /* XXX: hack for KAME */
1856 RTRADDR.s6_addr16[1] = 0;
1857 } else {
1858 log(LOG_ERR,
1859 "a router(%s) advertises "
1860 "a prefix with "
1861 "non-link local address\n",
1862 ip6_sprintf(&RTRADDR));
1863 }
1864 #undef RTRADDR
1865 }
1866 j++;
1867 pfr = pfr->pfr_next;
1868 }
1869 prl_64->prefix[i].advrtrs = j;
1870 prl_64->prefix[i].origin = PR_ORIG_RA;
1871
1872 i++;
1873 pr = pr->ndpr_next;
1874 }
1875
1876 for (rpp = LIST_FIRST(&rr_prefix); rpp;
1877 rpp = LIST_NEXT(rpp, rp_entry)) {
1878 if (i >= PRLSTSIZ)
1879 break;
1880 (void) in6_embedscope(&prl_64->prefix[i].prefix,
1881 &pr->ndpr_prefix, NULL, NULL);
1882 prl_64->prefix[i].raflags = rpp->rp_raf;
1883 prl_64->prefix[i].prefixlen = rpp->rp_plen;
1884 prl_64->prefix[i].vltime = rpp->rp_vltime;
1885 prl_64->prefix[i].pltime = rpp->rp_pltime;
1886 prl_64->prefix[i].if_index = rpp->rp_ifp->if_index;
1887 prl_64->prefix[i].expire = rpp->rp_expire;
1888 prl_64->prefix[i].advrtrs = 0;
1889 prl_64->prefix[i].origin = rpp->rp_origin;
1890 i++;
1891 }
1892 return;
1893 }
1894 /* For 32-bit process */
1895 while (pr && i < PRLSTSIZ) {
1896 struct nd_pfxrouter *pfr;
1897 int j;
1898
1899 (void) in6_embedscope(&prl_32->prefix[i].prefix,
1900 &pr->ndpr_prefix, NULL, NULL);
1901 prl_32->prefix[i].raflags = pr->ndpr_raf;
1902 prl_32->prefix[i].prefixlen = pr->ndpr_plen;
1903 prl_32->prefix[i].vltime = pr->ndpr_vltime;
1904 prl_32->prefix[i].pltime = pr->ndpr_pltime;
1905 prl_32->prefix[i].if_index = pr->ndpr_ifp->if_index;
1906 prl_32->prefix[i].expire = pr->ndpr_expire;
1907
1908 pfr = pr->ndpr_advrtrs.lh_first;
1909 j = 0;
1910 while (pfr) {
1911 if (j < DRLSTSIZ) {
1912 #define RTRADDR prl_32->prefix[i].advrtr[j]
1913 RTRADDR = pfr->router->rtaddr;
1914 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
1915 /* XXX: hack for KAME */
1916 RTRADDR.s6_addr16[1] = 0;
1917 } else {
1918 log(LOG_ERR,
1919 "a router(%s) advertises "
1920 "a prefix with "
1921 "non-link local address\n",
1922 ip6_sprintf(&RTRADDR));
1923 }
1924 #undef RTRADDR
1925 }
1926 j++;
1927 pfr = pfr->pfr_next;
1928 }
1929 prl_32->prefix[i].advrtrs = j;
1930 prl_32->prefix[i].origin = PR_ORIG_RA;
1931
1932 i++;
1933 pr = pr->ndpr_next;
1934 }
1935
1936 for (rpp = LIST_FIRST(&rr_prefix); rpp;
1937 rpp = LIST_NEXT(rpp, rp_entry)) {
1938 if (i >= PRLSTSIZ)
1939 break;
1940 (void) in6_embedscope(&prl_32->prefix[i].prefix,
1941 &pr->ndpr_prefix, NULL, NULL);
1942 prl_32->prefix[i].raflags = rpp->rp_raf;
1943 prl_32->prefix[i].prefixlen = rpp->rp_plen;
1944 prl_32->prefix[i].vltime = rpp->rp_vltime;
1945 prl_32->prefix[i].pltime = rpp->rp_pltime;
1946 prl_32->prefix[i].if_index = rpp->rp_ifp->if_index;
1947 prl_32->prefix[i].expire = rpp->rp_expire;
1948 prl_32->prefix[i].advrtrs = 0;
1949 prl_32->prefix[i].origin = rpp->rp_origin;
1950 i++;
1951 }
1952 }
1953
1954 int
1955 nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
1956 {
1957 struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1958 struct in6_ondireq *ondi = (struct in6_ondireq *)data;
1959 struct nd_defrouter *dr, any;
1960 struct nd_prefix *pr;
1961 struct rtentry *rt;
1962 int i = ifp->if_index, error = 0;
1963
1964 switch (cmd) {
1965 case SIOCGDRLST_IN6_32:
1966 case SIOCGDRLST_IN6_64:
1967 /*
1968 * obsolete API, use sysctl under net.inet6.icmp6
1969 */
1970 lck_mtx_lock(nd6_mutex);
1971 nd6_siocgdrlst(data, cmd == SIOCGDRLST_IN6_64);
1972 lck_mtx_unlock(nd6_mutex);
1973 break;
1974
1975 case SIOCGPRLST_IN6_32:
1976 case SIOCGPRLST_IN6_64:
1977 /*
1978 * obsolete API, use sysctl under net.inet6.icmp6
1979 */
1980 lck_mtx_lock(nd6_mutex);
1981 nd6_siocgprlst(data, cmd == SIOCGPRLST_IN6_64);
1982 lck_mtx_unlock(nd6_mutex);
1983 break;
1984
1985 case OSIOCGIFINFO_IN6:
1986 case SIOCGIFINFO_IN6:
1987 /*
1988 * SIOCGIFINFO_IN6 ioctl is encoded with in6_ondireq
1989 * instead of in6_ndireq, so we treat it as such.
1990 */
1991 lck_rw_lock_shared(nd_if_rwlock);
1992 if (!nd_ifinfo || i >= nd_ifinfo_indexlim) {
1993 lck_rw_done(nd_if_rwlock);
1994 error = EINVAL;
1995 break;
1996 }
1997 ondi->ndi.linkmtu = IN6_LINKMTU(ifp);
1998 ondi->ndi.maxmtu = nd_ifinfo[i].maxmtu;
1999 ondi->ndi.basereachable = nd_ifinfo[i].basereachable;
2000 ondi->ndi.reachable = nd_ifinfo[i].reachable;
2001 ondi->ndi.retrans = nd_ifinfo[i].retrans;
2002 ondi->ndi.flags = nd_ifinfo[i].flags;
2003 ondi->ndi.recalctm = nd_ifinfo[i].recalctm;
2004 ondi->ndi.chlim = nd_ifinfo[i].chlim;
2005 ondi->ndi.receivedra = nd_ifinfo[i].receivedra;
2006 lck_rw_done(nd_if_rwlock);
2007 break;
2008
2009 case SIOCSIFINFO_FLAGS:
2010 /* XXX: almost all other fields of ndi->ndi is unused */
2011 lck_rw_lock_shared(nd_if_rwlock);
2012 if (!nd_ifinfo || i >= nd_ifinfo_indexlim) {
2013 lck_rw_done(nd_if_rwlock);
2014 error = EINVAL;
2015 break;
2016 }
2017 nd_ifinfo[i].flags = ndi->ndi.flags;
2018 lck_rw_done(nd_if_rwlock);
2019 break;
2020
2021 case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */
2022 /* flush default router list */
2023 /*
2024 * xxx sumikawa: should not delete route if default
2025 * route equals to the top of default router list
2026 */
2027 bzero(&any, sizeof(any));
2028 lck_mtx_lock(nd6_mutex);
2029 defrouter_delreq(&any, 1);
2030 defrouter_select();
2031 lck_mtx_unlock(nd6_mutex);
2032 /* xxx sumikawa: flush prefix list */
2033 break;
2034
2035 case SIOCSPFXFLUSH_IN6: {
2036 /* flush all the prefix advertised by routers */
2037 struct nd_prefix *next;
2038 lck_mtx_lock(nd6_mutex);
2039
2040 for (pr = nd_prefix.lh_first; pr; pr = next) {
2041 struct in6_ifaddr *ia, *ia_next;
2042
2043 next = pr->ndpr_next;
2044
2045 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
2046 continue; /* XXX */
2047
2048 /* do we really have to remove addresses as well? */
2049 for (ia = in6_ifaddrs; ia; ia = ia_next) {
2050 /* ia might be removed. keep the next ptr. */
2051 ia_next = ia->ia_next;
2052
2053 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0)
2054 continue;
2055
2056 if (ia->ia6_ndpr == pr)
2057 in6_purgeaddr(&ia->ia_ifa, 1);
2058 }
2059 prelist_remove(pr, 1);
2060 }
2061 lck_mtx_unlock(nd6_mutex);
2062 break;
2063 }
2064
2065 case SIOCSRTRFLUSH_IN6: {
2066 /* flush all the default routers */
2067 struct nd_defrouter *next;
2068
2069 lck_mtx_lock(nd6_mutex);
2070 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
2071 /*
2072 * The first entry of the list may be stored in
2073 * the routing table, so we'll delete it later.
2074 */
2075 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = next) {
2076 next = TAILQ_NEXT(dr, dr_entry);
2077 defrtrlist_del(dr, 1);
2078 }
2079 defrtrlist_del(TAILQ_FIRST(&nd_defrouter), 1);
2080 }
2081 lck_mtx_unlock(nd6_mutex);
2082 break;
2083 }
2084
2085 case SIOCGNBRINFO_IN6_32: {
2086 struct llinfo_nd6 *ln;
2087 struct in6_nbrinfo_32 *nbi_32 = (struct in6_nbrinfo_32 *)data;
2088 /* make local for safety */
2089 struct in6_addr nb_addr = nbi_32->addr;
2090
2091 /*
2092 * XXX: KAME specific hack for scoped addresses
2093 * XXXX: for other scopes than link-local?
2094 */
2095 if (IN6_IS_ADDR_LINKLOCAL(&nbi_32->addr) ||
2096 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_32->addr)) {
2097 u_int16_t *idp = (u_int16_t *)&nb_addr.s6_addr[2];
2098
2099 if (*idp == 0)
2100 *idp = htons(ifp->if_index);
2101 }
2102
2103 /* Callee returns a locked route upon success */
2104 if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
2105 error = EINVAL;
2106 break;
2107 }
2108 RT_LOCK_ASSERT_HELD(rt);
2109 ln = rt->rt_llinfo;
2110 nbi_32->state = ln->ln_state;
2111 nbi_32->asked = ln->ln_asked;
2112 nbi_32->isrouter = ln->ln_router;
2113 nbi_32->expire = ln->ln_expire;
2114 RT_REMREF_LOCKED(rt);
2115 RT_UNLOCK(rt);
2116 break;
2117 }
2118
2119 case SIOCGNBRINFO_IN6_64: {
2120 struct llinfo_nd6 *ln;
2121 struct in6_nbrinfo_64 *nbi_64 = (struct in6_nbrinfo_64 *)data;
2122 /* make local for safety */
2123 struct in6_addr nb_addr = nbi_64->addr;
2124
2125 /*
2126 * XXX: KAME specific hack for scoped addresses
2127 * XXXX: for other scopes than link-local?
2128 */
2129 if (IN6_IS_ADDR_LINKLOCAL(&nbi_64->addr) ||
2130 IN6_IS_ADDR_MC_LINKLOCAL(&nbi_64->addr)) {
2131 u_int16_t *idp = (u_int16_t *)&nb_addr.s6_addr[2];
2132
2133 if (*idp == 0)
2134 *idp = htons(ifp->if_index);
2135 }
2136
2137 /* Callee returns a locked route upon success */
2138 if ((rt = nd6_lookup(&nb_addr, 0, ifp, 0)) == NULL) {
2139 error = EINVAL;
2140 break;
2141 }
2142 RT_LOCK_ASSERT_HELD(rt);
2143 ln = rt->rt_llinfo;
2144 nbi_64->state = ln->ln_state;
2145 nbi_64->asked = ln->ln_asked;
2146 nbi_64->isrouter = ln->ln_router;
2147 nbi_64->expire = ln->ln_expire;
2148 RT_REMREF_LOCKED(rt);
2149 RT_UNLOCK(rt);
2150 break;
2151 }
2152
2153 case SIOCGDEFIFACE_IN6_32: /* XXX: should be implemented as a sysctl? */
2154 case SIOCGDEFIFACE_IN6_64: {
2155 struct in6_ndifreq_64 *ndif_64 = (struct in6_ndifreq_64 *)data;
2156 struct in6_ndifreq_32 *ndif_32 = (struct in6_ndifreq_32 *)data;
2157
2158 if (cmd == SIOCGDEFIFACE_IN6_64)
2159 ndif_64->ifindex = nd6_defifindex;
2160 else
2161 ndif_32->ifindex = nd6_defifindex;
2162 break;
2163 }
2164
2165 case SIOCSDEFIFACE_IN6_32: /* XXX: should be implemented as a sysctl? */
2166 case SIOCSDEFIFACE_IN6_64: {
2167 struct in6_ndifreq_64 *ndif_64 = (struct in6_ndifreq_64 *)data;
2168 struct in6_ndifreq_32 *ndif_32 = (struct in6_ndifreq_32 *)data;
2169
2170 return (nd6_setdefaultiface(cmd == SIOCSDEFIFACE_IN6_64 ?
2171 ndif_64->ifindex : ndif_32->ifindex));
2172 /* NOTREACHED */
2173 }
2174 }
2175 return (error);
2176 }
2177
2178 /*
2179 * Create neighbor cache entry and cache link-layer address,
2180 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
2181 */
2182 void
2183 nd6_cache_lladdr(
2184 struct ifnet *ifp,
2185 struct in6_addr *from,
2186 char *lladdr,
2187 __unused int lladdrlen,
2188 int type, /* ICMP6 type */
2189 int code) /* type dependent information */
2190 {
2191 struct rtentry *rt = NULL;
2192 struct llinfo_nd6 *ln = NULL;
2193 int is_newentry;
2194 struct sockaddr_dl *sdl = NULL;
2195 int do_update;
2196 int olladdr;
2197 int llchange;
2198 int newstate = 0;
2199 struct timeval timenow;
2200
2201 if (!ifp)
2202 panic("ifp == NULL in nd6_cache_lladdr");
2203 if (!from)
2204 panic("from == NULL in nd6_cache_lladdr");
2205
2206 /* nothing must be updated for unspecified address */
2207 if (IN6_IS_ADDR_UNSPECIFIED(from))
2208 return;
2209
2210 /*
2211 * Validation about ifp->if_addrlen and lladdrlen must be done in
2212 * the caller.
2213 *
2214 * XXX If the link does not have link-layer adderss, what should
2215 * we do? (ifp->if_addrlen == 0)
2216 * Spec says nothing in sections for RA, RS and NA. There's small
2217 * description on it in NS section (RFC 2461 7.2.3).
2218 */
2219 getmicrotime(&timenow);
2220
2221 rt = nd6_lookup(from, 0, ifp, 0);
2222 if (rt == NULL) {
2223 #if 0
2224 /* nothing must be done if there's no lladdr */
2225 if (!lladdr || !lladdrlen)
2226 return;
2227 #endif
2228
2229 if ((rt = nd6_lookup(from, 1, ifp, 0)) == NULL)
2230 return;
2231 RT_LOCK_ASSERT_HELD(rt);
2232 is_newentry = 1;
2233 } else {
2234 RT_LOCK_ASSERT_HELD(rt);
2235 /* do nothing if static ndp is set */
2236 if (rt->rt_flags & RTF_STATIC) {
2237 RT_REMREF_LOCKED(rt);
2238 RT_UNLOCK(rt);
2239 return;
2240 }
2241 is_newentry = 0;
2242 }
2243
2244 if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
2245 fail:
2246 RT_UNLOCK(rt);
2247 nd6_free(rt);
2248 rtfree(rt);
2249 return;
2250 }
2251 ln = rt->rt_llinfo;
2252 if (!ln)
2253 goto fail;
2254 if (!rt->rt_gateway)
2255 goto fail;
2256 if (rt->rt_gateway->sa_family != AF_LINK)
2257 goto fail;
2258 sdl = SDL(rt->rt_gateway);
2259
2260 olladdr = (sdl->sdl_alen) ? 1 : 0;
2261 if (olladdr && lladdr) {
2262 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
2263 llchange = 1;
2264 else
2265 llchange = 0;
2266 } else
2267 llchange = 0;
2268
2269 /*
2270 * newentry olladdr lladdr llchange (*=record)
2271 * 0 n n -- (1)
2272 * 0 y n -- (2)
2273 * 0 n y -- (3) * STALE
2274 * 0 y y n (4) *
2275 * 0 y y y (5) * STALE
2276 * 1 -- n -- (6) NOSTATE(= PASSIVE)
2277 * 1 -- y -- (7) * STALE
2278 */
2279
2280 if (lladdr) { /* (3-5) and (7) */
2281 /*
2282 * Record source link-layer address
2283 * XXX is it dependent to ifp->if_type?
2284 */
2285 sdl->sdl_alen = ifp->if_addrlen;
2286 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
2287 }
2288
2289 if (!is_newentry) {
2290 if ((!olladdr && lladdr) /* (3) */
2291 || (olladdr && lladdr && llchange)) { /* (5) */
2292 do_update = 1;
2293 newstate = ND6_LLINFO_STALE;
2294 } else /* (1-2,4) */
2295 do_update = 0;
2296 } else {
2297 do_update = 1;
2298 if (!lladdr) /* (6) */
2299 newstate = ND6_LLINFO_NOSTATE;
2300 else /* (7) */
2301 newstate = ND6_LLINFO_STALE;
2302 }
2303
2304 if (do_update) {
2305 /*
2306 * Update the state of the neighbor cache.
2307 */
2308 ln->ln_state = newstate;
2309
2310 if (ln->ln_state == ND6_LLINFO_STALE) {
2311 struct mbuf *m = ln->ln_hold;
2312 /*
2313 * XXX: since nd6_output() below will cause
2314 * state tansition to DELAY and reset the timer,
2315 * we must set the timer now, although it is actually
2316 * meaningless.
2317 */
2318 ln->ln_expire = timenow.tv_sec + nd6_gctimer;
2319 ln->ln_hold = NULL;
2320
2321 if (m != NULL) {
2322 /*
2323 * we assume ifp is not a p2p here, so just
2324 * set the 2nd argument as the 1st one.
2325 */
2326 RT_UNLOCK(rt);
2327 nd6_output(ifp, ifp, m,
2328 (struct sockaddr_in6 *)rt_key(rt), rt, 0);
2329 RT_LOCK(rt);
2330 }
2331 } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
2332 /* probe right away */
2333 ln->ln_expire = timenow.tv_sec;
2334 }
2335 }
2336
2337 /*
2338 * ICMP6 type dependent behavior.
2339 *
2340 * NS: clear IsRouter if new entry
2341 * RS: clear IsRouter
2342 * RA: set IsRouter if there's lladdr
2343 * redir: clear IsRouter if new entry
2344 *
2345 * RA case, (1):
2346 * The spec says that we must set IsRouter in the following cases:
2347 * - If lladdr exist, set IsRouter. This means (1-5).
2348 * - If it is old entry (!newentry), set IsRouter. This means (7).
2349 * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
2350 * A quetion arises for (1) case. (1) case has no lladdr in the
2351 * neighbor cache, this is similar to (6).
2352 * This case is rare but we figured that we MUST NOT set IsRouter.
2353 *
2354 * newentry olladdr lladdr llchange NS RS RA redir
2355 * D R
2356 * 0 n n -- (1) c ? s
2357 * 0 y n -- (2) c s s
2358 * 0 n y -- (3) c s s
2359 * 0 y y n (4) c s s
2360 * 0 y y y (5) c s s
2361 * 1 -- n -- (6) c c c s
2362 * 1 -- y -- (7) c c s c s
2363 *
2364 * (c=clear s=set)
2365 */
2366 switch (type & 0xff) {
2367 case ND_NEIGHBOR_SOLICIT:
2368 /*
2369 * New entry must have is_router flag cleared.
2370 */
2371 if (is_newentry) /* (6-7) */
2372 ln->ln_router = 0;
2373 break;
2374 case ND_REDIRECT:
2375 /*
2376 * If the icmp is a redirect to a better router, always set the
2377 * is_router flag. Otherwise, if the entry is newly created,
2378 * clear the flag. [RFC 2461, sec 8.3]
2379 */
2380 if (code == ND_REDIRECT_ROUTER)
2381 ln->ln_router = 1;
2382 else if (is_newentry) /* (6-7) */
2383 ln->ln_router = 0;
2384 break;
2385 case ND_ROUTER_SOLICIT:
2386 /*
2387 * is_router flag must always be cleared.
2388 */
2389 ln->ln_router = 0;
2390 break;
2391 case ND_ROUTER_ADVERT:
2392 /*
2393 * Mark an entry with lladdr as a router.
2394 */
2395 if ((!is_newentry && (olladdr || lladdr)) /* (2-5) */
2396 || (is_newentry && lladdr)) { /* (7) */
2397 ln->ln_router = 1;
2398 }
2399 break;
2400 }
2401
2402 /*
2403 * When the link-layer address of a router changes, select the
2404 * best router again. In particular, when the neighbor entry is newly
2405 * created, it might affect the selection policy.
2406 * Question: can we restrict the first condition to the "is_newentry"
2407 * case?
2408 * XXX: when we hear an RA from a new router with the link-layer
2409 * address option, defrouter_select() is called twice, since
2410 * defrtrlist_update called the function as well. However, I believe
2411 * we can compromise the overhead, since it only happens the first
2412 * time.
2413 * XXX: although defrouter_select() should not have a bad effect
2414 * for those are not autoconfigured hosts, we explicitly avoid such
2415 * cases for safety.
2416 */
2417 if (do_update && ln->ln_router && !ip6_forwarding &&
2418 (ip6_accept_rtadv || (ifp->if_eflags & IFEF_ACCEPT_RTADVD))) {
2419 RT_REMREF_LOCKED(rt);
2420 RT_UNLOCK(rt);
2421 lck_mtx_lock(nd6_mutex);
2422 defrouter_select();
2423 lck_mtx_unlock(nd6_mutex);
2424 } else {
2425 RT_REMREF_LOCKED(rt);
2426 RT_UNLOCK(rt);
2427 }
2428 }
2429
2430 static void
2431 nd6_slowtimo(
2432 __unused void *ignored_arg)
2433 {
2434 int i;
2435 struct nd_ifinfo *nd6if;
2436
2437 lck_rw_lock_shared(nd_if_rwlock);
2438 for (i = 1; i < if_index + 1; i++) {
2439 if (!nd_ifinfo || i >= nd_ifinfo_indexlim)
2440 break;
2441 nd6if = &nd_ifinfo[i];
2442 if (nd6if->basereachable && /* already initialized */
2443 (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
2444 /*
2445 * Since reachable time rarely changes by router
2446 * advertisements, we SHOULD insure that a new random
2447 * value gets recomputed at least once every few hours.
2448 * (RFC 2461, 6.3.4)
2449 */
2450 nd6if->recalctm = nd6_recalc_reachtm_interval;
2451 nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
2452 }
2453 }
2454 lck_rw_done(nd_if_rwlock);
2455 timeout(nd6_slowtimo, (caddr_t)0, ND6_SLOWTIMER_INTERVAL * hz);
2456 }
2457
2458 #define senderr(e) { error = (e); goto bad;}
2459 int
2460 nd6_output(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0,
2461 struct sockaddr_in6 *dst, struct rtentry *hint0, int locked)
2462 {
2463 struct mbuf *m = m0;
2464 struct rtentry *rt = hint0, *hint = hint0;
2465 struct llinfo_nd6 *ln = NULL;
2466 int error = 0;
2467 struct timeval timenow;
2468 struct rtentry *rtrele = NULL;
2469
2470 if (rt != NULL) {
2471 RT_LOCK_SPIN(rt);
2472 RT_ADDREF_LOCKED(rt);
2473 }
2474
2475 if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr) || !nd6_need_cache(ifp)) {
2476 if (rt != NULL)
2477 RT_UNLOCK(rt);
2478 goto sendpkt;
2479 }
2480
2481 /*
2482 * Next hop determination. Because we may involve the gateway route
2483 * in addition to the original route, locking is rather complicated.
2484 * The general concept is that regardless of whether the route points
2485 * to the original route or to the gateway route, this routine takes
2486 * an extra reference on such a route. This extra reference will be
2487 * released at the end.
2488 *
2489 * Care must be taken to ensure that the "hint0" route never gets freed
2490 * via rtfree(), since the caller may have stored it inside a struct
2491 * route with a reference held for that placeholder.
2492 *
2493 * This logic is similar to, though not exactly the same as the one
2494 * used by arp_route_to_gateway_route().
2495 */
2496 if (rt != NULL) {
2497 /*
2498 * We have a reference to "rt" by now (or below via rtalloc1),
2499 * which will either be released or freed at the end of this
2500 * routine.
2501 */
2502 RT_LOCK_ASSERT_HELD(rt);
2503 if (!(rt->rt_flags & RTF_UP)) {
2504 RT_REMREF_LOCKED(rt);
2505 RT_UNLOCK(rt);
2506 if ((hint = rt = rtalloc1((struct sockaddr *)dst,
2507 1, 0)) != NULL) {
2508 RT_LOCK_SPIN(rt);
2509 if (rt->rt_ifp != ifp) {
2510 /* XXX: loop care? */
2511 RT_UNLOCK(rt);
2512 error = nd6_output(ifp, origifp, m0,
2513 dst, rt, locked);
2514 rtfree(rt);
2515 return (error);
2516 }
2517 } else {
2518 senderr(EHOSTUNREACH);
2519 }
2520 }
2521
2522 if (rt->rt_flags & RTF_GATEWAY) {
2523 struct rtentry *gwrt;
2524 struct in6_ifaddr *ia6 = NULL;
2525 struct sockaddr_in6 gw6;
2526
2527 gw6 = *((struct sockaddr_in6 *)rt->rt_gateway);
2528 /*
2529 * Must drop rt_lock since nd6_is_addr_neighbor()
2530 * calls nd6_lookup() and acquires rnh_lock.
2531 */
2532 RT_UNLOCK(rt);
2533
2534 /*
2535 * We skip link-layer address resolution and NUD
2536 * if the gateway is not a neighbor from ND point
2537 * of view, regardless of the value of nd_ifinfo.flags.
2538 * The second condition is a bit tricky; we skip
2539 * if the gateway is our own address, which is
2540 * sometimes used to install a route to a p2p link.
2541 */
2542 if (!nd6_is_addr_neighbor(&gw6, ifp, 0) ||
2543 (ia6 = in6ifa_ifpwithaddr(ifp, &gw6.sin6_addr))) {
2544 /*
2545 * We allow this kind of tricky route only
2546 * when the outgoing interface is p2p.
2547 * XXX: we may need a more generic rule here.
2548 */
2549 if (ia6 != NULL)
2550 ifafree(&ia6->ia_ifa);
2551 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
2552 senderr(EHOSTUNREACH);
2553 goto sendpkt;
2554 }
2555
2556 RT_LOCK_SPIN(rt);
2557 gw6 = *((struct sockaddr_in6 *)rt->rt_gateway);
2558
2559 /* If hint is now down, give up */
2560 if (!(rt->rt_flags & RTF_UP)) {
2561 RT_UNLOCK(rt);
2562 senderr(EHOSTUNREACH);
2563 }
2564
2565 /* If there's no gateway route, look it up */
2566 if ((gwrt = rt->rt_gwroute) == NULL) {
2567 RT_UNLOCK(rt);
2568 goto lookup;
2569 }
2570 /* Become a regular mutex */
2571 RT_CONVERT_LOCK(rt);
2572
2573 /*
2574 * Take gwrt's lock while holding route's lock;
2575 * this is okay since gwrt never points back
2576 * to rt, so no lock ordering issues.
2577 */
2578 RT_LOCK_SPIN(gwrt);
2579 if (!(gwrt->rt_flags & RTF_UP)) {
2580 struct rtentry *ogwrt;
2581
2582 rt->rt_gwroute = NULL;
2583 RT_UNLOCK(gwrt);
2584 RT_UNLOCK(rt);
2585 rtfree(gwrt);
2586 lookup:
2587 gwrt = rtalloc1((struct sockaddr *)&gw6, 1, 0);
2588
2589 RT_LOCK(rt);
2590 /*
2591 * Bail out if the route is down, no route
2592 * to gateway, circular route, or if the
2593 * gateway portion of "rt" has changed.
2594 */
2595 if (!(rt->rt_flags & RTF_UP) ||
2596 gwrt == NULL || gwrt == rt ||
2597 !equal(SA(&gw6), rt->rt_gateway)) {
2598 if (gwrt == rt) {
2599 RT_REMREF_LOCKED(gwrt);
2600 gwrt = NULL;
2601 }
2602 RT_UNLOCK(rt);
2603 if (gwrt != NULL)
2604 rtfree(gwrt);
2605 senderr(EHOSTUNREACH);
2606 }
2607
2608 /* Remove any existing gwrt */
2609 ogwrt = rt->rt_gwroute;
2610 if ((rt->rt_gwroute = gwrt) != NULL)
2611 RT_ADDREF(gwrt);
2612
2613 RT_UNLOCK(rt);
2614 /* Now free the replaced gwrt */
2615 if (ogwrt != NULL)
2616 rtfree(ogwrt);
2617 /* If still no route to gateway, bail out */
2618 if (gwrt == NULL)
2619 senderr(EHOSTUNREACH);
2620 /* Remember to release/free "rt" at the end */
2621 rtrele = rt;
2622 rt = gwrt;
2623 RT_LOCK_SPIN(rt);
2624 /* If gwrt is now down, give up */
2625 if (!(rt->rt_flags & RTF_UP)) {
2626 RT_UNLOCK(rt);
2627 rtfree(rt);
2628 rt = NULL;
2629 /* "rtrele" == original "rt" */
2630 senderr(EHOSTUNREACH);
2631 }
2632 } else {
2633 RT_ADDREF_LOCKED(gwrt);
2634 RT_UNLOCK(gwrt);
2635 RT_UNLOCK(rt);
2636 RT_LOCK_SPIN(gwrt);
2637 /* If gwrt is now down, give up */
2638 if (!(gwrt->rt_flags & RTF_UP)) {
2639 RT_UNLOCK(gwrt);
2640 rtfree(gwrt);
2641 senderr(EHOSTUNREACH);
2642 }
2643 /* Remember to release/free "rt" at the end */
2644 rtrele = rt;
2645 rt = gwrt;
2646 }
2647 }
2648 /* Become a regular mutex */
2649 RT_CONVERT_LOCK(rt);
2650 }
2651
2652 if (rt != NULL)
2653 RT_LOCK_ASSERT_HELD(rt);
2654
2655 /*
2656 * Address resolution or Neighbor Unreachability Detection
2657 * for the next hop.
2658 * At this point, the destination of the packet must be a unicast
2659 * or an anycast address(i.e. not a multicast).
2660 */
2661
2662 /* Look up the neighbor cache for the nexthop */
2663 if (rt && (rt->rt_flags & RTF_LLINFO) != 0) {
2664 ln = rt->rt_llinfo;
2665 } else {
2666 /*
2667 * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
2668 * the condition below is not very efficient. But we believe
2669 * it is tolerable, because this should be a rare case.
2670 * Must drop rt_lock since nd6_is_addr_neighbor() calls
2671 * nd6_lookup() and acquires rnh_lock.
2672 */
2673 if (rt != NULL)
2674 RT_UNLOCK(rt);
2675 if (nd6_is_addr_neighbor(dst, ifp, 0)) {
2676 /* "rtrele" may have been used, so clean up "rt" now */
2677 if (rt != NULL) {
2678 /* Don't free "hint0" */
2679 if (rt == hint0)
2680 RT_REMREF(rt);
2681 else
2682 rtfree(rt);
2683 }
2684 /* Callee returns a locked route upon success */
2685 rt = nd6_lookup(&dst->sin6_addr, 1, ifp, 0);
2686 if (rt != NULL) {
2687 RT_LOCK_ASSERT_HELD(rt);
2688 ln = rt->rt_llinfo;
2689 }
2690 } else if (rt != NULL) {
2691 RT_LOCK(rt);
2692 }
2693 }
2694
2695 if (!ln || !rt) {
2696 if (rt != NULL)
2697 RT_UNLOCK(rt);
2698 lck_rw_lock_shared(nd_if_rwlock);
2699 if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
2700 !(nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD)) {
2701 lck_rw_done(nd_if_rwlock);
2702 log(LOG_DEBUG,
2703 "nd6_output: can't allocate llinfo for %s "
2704 "(ln=%p, rt=%p)\n",
2705 ip6_sprintf(&dst->sin6_addr), ln, rt);
2706 senderr(EIO); /* XXX: good error? */
2707 }
2708 lck_rw_done(nd_if_rwlock);
2709
2710 goto sendpkt; /* send anyway */
2711 }
2712
2713 getmicrotime(&timenow);
2714
2715 /* We don't have to do link-layer address resolution on a p2p link. */
2716 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
2717 ln->ln_state < ND6_LLINFO_REACHABLE) {
2718 ln->ln_state = ND6_LLINFO_STALE;
2719 ln->ln_expire = timenow.tv_sec + nd6_gctimer;
2720 }
2721
2722 /*
2723 * The first time we send a packet to a neighbor whose entry is
2724 * STALE, we have to change the state to DELAY and a sets a timer to
2725 * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
2726 * neighbor unreachability detection on expiration.
2727 * (RFC 2461 7.3.3)
2728 */
2729 if (ln->ln_state == ND6_LLINFO_STALE) {
2730 ln->ln_asked = 0;
2731 ln->ln_state = ND6_LLINFO_DELAY;
2732 ln->ln_expire = timenow.tv_sec + nd6_delay;
2733 }
2734
2735 /*
2736 * If the neighbor cache entry has a state other than INCOMPLETE
2737 * (i.e. its link-layer address is already resolved), just
2738 * send the packet.
2739 */
2740 if (ln->ln_state > ND6_LLINFO_INCOMPLETE) {
2741 RT_UNLOCK(rt);
2742 /*
2743 * Move this entry to the head of the queue so that it is
2744 * less likely for this entry to be a target of forced
2745 * garbage collection (see nd6_rtrequest()).
2746 */
2747 lck_mtx_lock(rnh_lock);
2748 RT_LOCK_SPIN(rt);
2749 if (ln->ln_flags & ND6_LNF_IN_USE) {
2750 LN_DEQUEUE(ln);
2751 LN_INSERTHEAD(ln);
2752 }
2753 RT_UNLOCK(rt);
2754 lck_mtx_unlock(rnh_lock);
2755 goto sendpkt;
2756 }
2757
2758 /*
2759 * There is a neighbor cache entry, but no ethernet address
2760 * response yet. Replace the held mbuf (if any) with this
2761 * latest one.
2762 *
2763 * This code conforms to the rate-limiting rule described in Section
2764 * 7.2.2 of RFC 2461, because the timer is set correctly after sending
2765 * an NS below.
2766 */
2767 if (ln->ln_state == ND6_LLINFO_NOSTATE)
2768 ln->ln_state = ND6_LLINFO_INCOMPLETE;
2769 if (ln->ln_hold)
2770 m_freem(ln->ln_hold);
2771 ln->ln_hold = m;
2772 if (ln->ln_expire && ln->ln_asked < nd6_mmaxtries &&
2773 ln->ln_expire < timenow.tv_sec) {
2774 ln->ln_asked++;
2775 lck_rw_lock_shared(nd_if_rwlock);
2776 ln->ln_expire = timenow.tv_sec +
2777 nd_ifinfo[ifp->if_index].retrans / 1000;
2778 lck_rw_done(nd_if_rwlock);
2779 RT_UNLOCK(rt);
2780 /* We still have a reference on rt (for ln) */
2781 nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0, locked);
2782 } else {
2783 RT_UNLOCK(rt);
2784 }
2785 /*
2786 * Move this entry to the head of the queue so that it is
2787 * less likely for this entry to be a target of forced
2788 * garbage collection (see nd6_rtrequest()).
2789 */
2790 lck_mtx_lock(rnh_lock);
2791 RT_LOCK_SPIN(rt);
2792 if (ln->ln_flags & ND6_LNF_IN_USE) {
2793 LN_DEQUEUE(ln);
2794 LN_INSERTHEAD(ln);
2795 }
2796 /* Clean up "rt" now while we can */
2797 if (rt == hint0) {
2798 RT_REMREF_LOCKED(rt);
2799 RT_UNLOCK(rt);
2800 } else {
2801 RT_UNLOCK(rt);
2802 rtfree_locked(rt);
2803 }
2804 rt = NULL; /* "rt" has been taken care of */
2805 lck_mtx_unlock(rnh_lock);
2806
2807 error = 0;
2808 goto release;
2809
2810 sendpkt:
2811 if (rt != NULL)
2812 RT_LOCK_ASSERT_NOTHELD(rt);
2813
2814 /* Clean up HW checksum flags before sending the packet */
2815 m->m_pkthdr.csum_data = 0;
2816 m->m_pkthdr.csum_flags = 0;
2817
2818 if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
2819 /* forwarding rules require the original scope_id */
2820 m->m_pkthdr.rcvif = origifp;
2821 if (locked)
2822 lck_mtx_unlock(ip6_mutex);
2823 error = dlil_output(origifp, PF_INET6, m, (caddr_t)rt,
2824 (struct sockaddr *)dst, 0);
2825 if (locked)
2826 lck_mtx_lock(ip6_mutex);
2827 goto release;
2828 } else {
2829 /* Do not allow loopback address to wind up on a wire */
2830 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
2831
2832 if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) ||
2833 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst))) {
2834 ip6stat.ip6s_badscope++;
2835 /*
2836 * Do not simply drop the packet just like a
2837 * firewall -- we want the the application to feel
2838 * the pain. Return ENETUNREACH like ip6_output
2839 * does in some similar cases. This can startle
2840 * the otherwise clueless process that specifies
2841 * loopback as the source address.
2842 */
2843 error = ENETUNREACH;
2844 goto bad;
2845 }
2846 }
2847
2848 m->m_pkthdr.rcvif = NULL;
2849 if (locked)
2850 lck_mtx_unlock(ip6_mutex);
2851 error = dlil_output(ifp, PF_INET6, m, (caddr_t)rt,
2852 (struct sockaddr *)dst, 0);
2853 if (locked)
2854 lck_mtx_lock(ip6_mutex);
2855 goto release;
2856
2857 bad:
2858 if (m != NULL)
2859 m_freem(m);
2860
2861 release:
2862 /* Clean up "rt" unless it's already been done */
2863 if (rt != NULL) {
2864 RT_LOCK_SPIN(rt);
2865 if (rt == hint0) {
2866 RT_REMREF_LOCKED(rt);
2867 RT_UNLOCK(rt);
2868 } else {
2869 RT_UNLOCK(rt);
2870 rtfree(rt);
2871 }
2872 }
2873 /* And now clean up "rtrele" if there is any */
2874 if (rtrele != NULL) {
2875 RT_LOCK_SPIN(rtrele);
2876 if (rtrele == hint0) {
2877 RT_REMREF_LOCKED(rtrele);
2878 RT_UNLOCK(rtrele);
2879 } else {
2880 RT_UNLOCK(rtrele);
2881 rtfree(rtrele);
2882 }
2883 }
2884 return (error);
2885 }
2886 #undef senderr
2887
2888 int
2889 nd6_need_cache(
2890 struct ifnet *ifp)
2891 {
2892 /*
2893 * XXX: we currently do not make neighbor cache on any interface
2894 * other than ARCnet, Ethernet, FDDI and GIF.
2895 *
2896 * RFC2893 says:
2897 * - unidirectional tunnels needs no ND
2898 */
2899 switch (ifp->if_type) {
2900 case IFT_ARCNET:
2901 case IFT_ETHER:
2902 case IFT_FDDI:
2903 case IFT_IEEE1394:
2904 case IFT_L2VLAN:
2905 case IFT_IEEE8023ADLAG:
2906 #if IFT_IEEE80211
2907 case IFT_IEEE80211:
2908 #endif
2909 case IFT_GIF: /* XXX need more cases? */
2910 return(1);
2911 default:
2912 return(0);
2913 }
2914 }
2915
2916 int
2917 nd6_storelladdr(
2918 struct ifnet *ifp,
2919 struct rtentry *rt,
2920 struct mbuf *m,
2921 struct sockaddr *dst,
2922 u_char *desten)
2923 {
2924 int i;
2925 struct sockaddr_dl *sdl;
2926
2927 if (m->m_flags & M_MCAST) {
2928 switch (ifp->if_type) {
2929 case IFT_ETHER:
2930 case IFT_FDDI:
2931 case IFT_L2VLAN:
2932 case IFT_IEEE8023ADLAG:
2933 #if IFT_IEEE80211
2934 case IFT_IEEE80211:
2935 #endif
2936 ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
2937 desten);
2938 return(1);
2939 case IFT_IEEE1394:
2940 for (i = 0; i < ifp->if_addrlen; i++)
2941 desten[i] = ~0;
2942 return(1);
2943 case IFT_ARCNET:
2944 *desten = 0;
2945 return(1);
2946 default:
2947 return(0); /* caller will free mbuf */
2948 }
2949 }
2950
2951 if (rt == NULL) {
2952 /* this could happen, if we could not allocate memory */
2953 return(0); /* caller will free mbuf */
2954 }
2955 RT_LOCK(rt);
2956 if (rt->rt_gateway->sa_family != AF_LINK) {
2957 printf("nd6_storelladdr: something odd happens\n");
2958 RT_UNLOCK(rt);
2959 return(0); /* caller will free mbuf */
2960 }
2961 sdl = SDL(rt->rt_gateway);
2962 if (sdl->sdl_alen == 0) {
2963 /* this should be impossible, but we bark here for debugging */
2964 printf("nd6_storelladdr: sdl_alen == 0\n");
2965 RT_UNLOCK(rt);
2966 return(0); /* caller will free mbuf */
2967 }
2968
2969 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
2970 RT_UNLOCK(rt);
2971 return(1);
2972 }
2973
2974 /*
2975 * This is the ND pre-output routine; care must be taken to ensure that
2976 * the "hint" route never gets freed via rtfree(), since the caller may
2977 * have stored it inside a struct route with a reference held for that
2978 * placeholder.
2979 */
2980 errno_t
2981 nd6_lookup_ipv6(ifnet_t ifp, const struct sockaddr_in6 *ip6_dest,
2982 struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint,
2983 mbuf_t packet)
2984 {
2985 route_t route = hint;
2986 errno_t result = 0;
2987 struct sockaddr_dl *sdl = NULL;
2988 size_t copy_len;
2989
2990 if (ip6_dest->sin6_family != AF_INET6)
2991 return (EAFNOSUPPORT);
2992
2993 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
2994 return (ENETDOWN);
2995
2996 if (hint != NULL) {
2997 /*
2998 * Callee holds a reference on the route and returns
2999 * with the route entry locked, upon success.
3000 */
3001 result = arp_route_to_gateway_route(
3002 (const struct sockaddr*)ip6_dest, hint, &route);
3003 if (result != 0)
3004 return (result);
3005 if (route != NULL)
3006 RT_LOCK_ASSERT_HELD(route);
3007 }
3008
3009 if ((packet->m_flags & M_MCAST) != 0) {
3010 if (route != NULL)
3011 RT_UNLOCK(route);
3012 result = dlil_resolve_multi(ifp,
3013 (const struct sockaddr*)ip6_dest,
3014 (struct sockaddr *)ll_dest, ll_dest_len);
3015 if (route != NULL)
3016 RT_LOCK(route);
3017 goto release;
3018 }
3019
3020 if (route == NULL) {
3021 /*
3022 * This could happen, if we could not allocate memory or
3023 * if arp_route_to_gateway_route() didn't return a route.
3024 */
3025 result = ENOBUFS;
3026 goto release;
3027 }
3028
3029 if (route->rt_gateway->sa_family != AF_LINK) {
3030 printf("nd6_lookup_ipv6: gateway address not AF_LINK\n");
3031 result = EADDRNOTAVAIL;
3032 goto release;
3033 }
3034
3035 sdl = SDL(route->rt_gateway);
3036 if (sdl->sdl_alen == 0) {
3037 /* this should be impossible, but we bark here for debugging */
3038 printf("nd6_lookup_ipv6: sdl_alen == 0\n");
3039 result = EHOSTUNREACH;
3040 goto release;
3041 }
3042
3043 copy_len = sdl->sdl_len <= ll_dest_len ? sdl->sdl_len : ll_dest_len;
3044 bcopy(sdl, ll_dest, copy_len);
3045
3046 release:
3047 if (route != NULL) {
3048 if (route == hint) {
3049 RT_REMREF_LOCKED(route);
3050 RT_UNLOCK(route);
3051 } else {
3052 RT_UNLOCK(route);
3053 rtfree(route);
3054 }
3055 }
3056 return (result);
3057 }
3058
3059 SYSCTL_DECL(_net_inet6_icmp6);
3060
3061 static int
3062 nd6_sysctl_drlist SYSCTL_HANDLER_ARGS
3063 {
3064 #pragma unused(oidp, arg1, arg2)
3065 int error = 0;
3066 char buf[1024];
3067 struct nd_defrouter *dr;
3068 int p64 = proc_is64bit(req->p);
3069
3070 if (req->newptr)
3071 return (EPERM);
3072
3073 lck_mtx_lock(nd6_mutex);
3074 if (p64) {
3075 struct in6_defrouter_64 *d, *de;
3076
3077 for (dr = TAILQ_FIRST(&nd_defrouter);
3078 dr;
3079 dr = TAILQ_NEXT(dr, dr_entry)) {
3080 d = (struct in6_defrouter_64 *)buf;
3081 de = (struct in6_defrouter_64 *)(buf + sizeof (buf));
3082
3083 if (d + 1 <= de) {
3084 bzero(d, sizeof (*d));
3085 d->rtaddr.sin6_family = AF_INET6;
3086 d->rtaddr.sin6_len = sizeof (d->rtaddr);
3087 if (in6_recoverscope(&d->rtaddr, &dr->rtaddr,
3088 dr->ifp) != 0)
3089 log(LOG_ERR,
3090 "scope error in "
3091 "default router list (%s)\n",
3092 ip6_sprintf(&dr->rtaddr));
3093 d->flags = dr->flags;
3094 d->rtlifetime = dr->rtlifetime;
3095 d->expire = dr->expire;
3096 d->if_index = dr->ifp->if_index;
3097 } else {
3098 panic("buffer too short");
3099 }
3100 error = SYSCTL_OUT(req, buf, sizeof (*d));
3101 if (error)
3102 break;
3103 }
3104 } else {
3105 struct in6_defrouter_32 *d_32, *de_32;
3106
3107 for (dr = TAILQ_FIRST(&nd_defrouter);
3108 dr;
3109 dr = TAILQ_NEXT(dr, dr_entry)) {
3110 d_32 = (struct in6_defrouter_32 *)buf;
3111 de_32 = (struct in6_defrouter_32 *)(buf + sizeof (buf));
3112
3113 if (d_32 + 1 <= de_32) {
3114 bzero(d_32, sizeof (*d_32));
3115 d_32->rtaddr.sin6_family = AF_INET6;
3116 d_32->rtaddr.sin6_len = sizeof (d_32->rtaddr);
3117 if (in6_recoverscope(&d_32->rtaddr, &dr->rtaddr,
3118 dr->ifp) != 0)
3119 log(LOG_ERR,
3120 "scope error in "
3121 "default router list (%s)\n",
3122 ip6_sprintf(&dr->rtaddr));
3123 d_32->flags = dr->flags;
3124 d_32->rtlifetime = dr->rtlifetime;
3125 d_32->expire = dr->expire;
3126 d_32->if_index = dr->ifp->if_index;
3127 } else {
3128 panic("buffer too short");
3129 }
3130 error = SYSCTL_OUT(req, buf, sizeof (*d_32));
3131 if (error)
3132 break;
3133 }
3134 }
3135 lck_mtx_unlock(nd6_mutex);
3136 return (error);
3137 }
3138
3139 static int
3140 nd6_sysctl_prlist SYSCTL_HANDLER_ARGS
3141 {
3142 #pragma unused(oidp, arg1, arg2)
3143 int error = 0;
3144 char buf[1024];
3145 struct nd_prefix *pr;
3146 int p64 = proc_is64bit(req->p);
3147
3148 if (req->newptr)
3149 return (EPERM);
3150
3151 lck_mtx_lock(nd6_mutex);
3152 if (p64) {
3153 struct in6_prefix_64 *p, *pe;
3154
3155 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3156 u_short advrtrs = 0;
3157 size_t advance;
3158 struct sockaddr_in6 *sin6, *s6;
3159 struct nd_pfxrouter *pfr;
3160
3161 p = (struct in6_prefix_64 *)buf;
3162 pe = (struct in6_prefix_64 *)(buf + sizeof (buf));
3163
3164 if (p + 1 <= pe) {
3165 bzero(p, sizeof (*p));
3166 sin6 = (struct sockaddr_in6 *)(p + 1);
3167
3168 p->prefix = pr->ndpr_prefix;
3169 if (in6_recoverscope(&p->prefix,
3170 &p->prefix.sin6_addr, pr->ndpr_ifp) != 0)
3171 log(LOG_ERR,
3172 "scope error in prefix list (%s)\n",
3173 ip6_sprintf(&p->prefix.sin6_addr));
3174 p->raflags = pr->ndpr_raf;
3175 p->prefixlen = pr->ndpr_plen;
3176 p->vltime = pr->ndpr_vltime;
3177 p->pltime = pr->ndpr_pltime;
3178 p->if_index = pr->ndpr_ifp->if_index;
3179 p->expire = pr->ndpr_expire;
3180 p->refcnt = pr->ndpr_refcnt;
3181 p->flags = pr->ndpr_stateflags;
3182 p->origin = PR_ORIG_RA;
3183 advrtrs = 0;
3184 for (pfr = pr->ndpr_advrtrs.lh_first;
3185 pfr;
3186 pfr = pfr->pfr_next) {
3187 if ((void *)&sin6[advrtrs + 1] >
3188 (void *)pe) {
3189 advrtrs++;
3190 continue;
3191 }
3192 s6 = &sin6[advrtrs];
3193 bzero(s6, sizeof (*s6));
3194 s6->sin6_family = AF_INET6;
3195 s6->sin6_len = sizeof (*sin6);
3196 if (in6_recoverscope(s6,
3197 &pfr->router->rtaddr,
3198 pfr->router->ifp) != 0)
3199 log(LOG_ERR, "scope error in "
3200 "prefix list (%s)\n",
3201 ip6_sprintf(&pfr->router->
3202 rtaddr));
3203 advrtrs++;
3204 }
3205 p->advrtrs = advrtrs;
3206 } else {
3207 panic("buffer too short");
3208 }
3209 advance = sizeof (*p) + sizeof (*sin6) * advrtrs;
3210 error = SYSCTL_OUT(req, buf, advance);
3211 if (error)
3212 break;
3213 }
3214 } else {
3215 struct in6_prefix_32 *p_32, *pe_32;
3216
3217 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3218 u_short advrtrs = 0;
3219 size_t advance;
3220 struct sockaddr_in6 *sin6, *s6;
3221 struct nd_pfxrouter *pfr;
3222
3223 p_32 = (struct in6_prefix_32 *)buf;
3224 pe_32 = (struct in6_prefix_32 *)(buf + sizeof (buf));
3225
3226 if (p_32 + 1 <= pe_32) {
3227 bzero(p_32, sizeof (*p_32));
3228 sin6 = (struct sockaddr_in6 *)(p_32 + 1);
3229
3230 p_32->prefix = pr->ndpr_prefix;
3231 if (in6_recoverscope(&p_32->prefix,
3232 &p_32->prefix.sin6_addr, pr->ndpr_ifp) != 0)
3233 log(LOG_ERR, "scope error in prefix "
3234 "list (%s)\n", ip6_sprintf(&p_32->
3235 prefix.sin6_addr));
3236 p_32->raflags = pr->ndpr_raf;
3237 p_32->prefixlen = pr->ndpr_plen;
3238 p_32->vltime = pr->ndpr_vltime;
3239 p_32->pltime = pr->ndpr_pltime;
3240 p_32->if_index = pr->ndpr_ifp->if_index;
3241 p_32->expire = pr->ndpr_expire;
3242 p_32->refcnt = pr->ndpr_refcnt;
3243 p_32->flags = pr->ndpr_stateflags;
3244 p_32->origin = PR_ORIG_RA;
3245 advrtrs = 0;
3246 for (pfr = pr->ndpr_advrtrs.lh_first;
3247 pfr;
3248 pfr = pfr->pfr_next) {
3249 if ((void *)&sin6[advrtrs + 1] >
3250 (void *)pe_32) {
3251 advrtrs++;
3252 continue;
3253 }
3254 s6 = &sin6[advrtrs];
3255 bzero(s6, sizeof (*s6));
3256 s6->sin6_family = AF_INET6;
3257 s6->sin6_len = sizeof (*sin6);
3258 if (in6_recoverscope(s6,
3259 &pfr->router->rtaddr,
3260 pfr->router->ifp) != 0)
3261 log(LOG_ERR, "scope error in "
3262 "prefix list (%s)\n",
3263 ip6_sprintf(&pfr->router->
3264 rtaddr));
3265 advrtrs++;
3266 }
3267 p_32->advrtrs = advrtrs;
3268 } else {
3269 panic("buffer too short");
3270 }
3271 advance = sizeof (*p_32) + sizeof (*sin6) * advrtrs;
3272 error = SYSCTL_OUT(req, buf, advance);
3273 if (error)
3274 break;
3275 }
3276 }
3277 lck_mtx_unlock(nd6_mutex);
3278 return (error);
3279 }
3280 SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
3281 CTLFLAG_RD, 0, 0, nd6_sysctl_drlist, "S,in6_defrouter","");
3282 SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_PRLIST, nd6_prlist,
3283 CTLFLAG_RD, 0, 0, nd6_sysctl_prlist, "S,in6_defrouter","");
3284