]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet6/nd6.c
xnu-123.5.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6.c
CommitLineData
1c79356b
A
1/* $KAME: nd6.c,v 1.51.2.1 2000/04/13 11:59:29 jinmei Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * XXX
34 * KAME 970409 note:
35 * BSD/OS version heavily modifies this code, related to llinfo.
36 * Since we don't have BSD/OS version of net/route.c in our hand,
37 * I left the code mostly as it was in 970310. -- itojun
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/malloc.h>
43#include <sys/mbuf.h>
44#include <sys/socket.h>
45#include <sys/sockio.h>
46#include <sys/time.h>
47#include <sys/kernel.h>
48#include <sys/errno.h>
49#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
50#include <sys/ioctl.h>
51#endif
52#include <sys/syslog.h>
53#include <sys/protosw.h>
54#include <kern/queue.h>
55
56#include <net/if.h>
57#include <net/if_dl.h>
58#include <net/if_types.h>
59#if !(defined(__bsdi__) && _BSDI_VERSION >= 199802) && !defined(__APPLE__)
60#include <net/if_atm.h>
61#endif
62#include <net/route.h>
63#include <net/dlil.h>
64
65#include <netinet/in.h>
66#ifndef __NetBSD__
67#include <netinet/if_ether.h>
68#if __FreeBSD__
69#include <netinet/if_fddi.h>
70#endif
71#ifdef __bsdi__
72#include <net/if_fddi.h>
73#endif
74#else /* __NetBSD__ */
75#include <net/if_ether.h>
76#include <netinet/if_inarp.h>
77#include <net/if_fddi.h>
78#endif /* __NetBSD__ */
79#include <netinet6/in6_var.h>
80#include <netinet/ip6.h>
81#include <netinet6/ip6_var.h>
82#include <netinet6/nd6.h>
83#include <netinet6/in6_prefix.h>
84#include <netinet/icmp6.h>
85
86#ifndef __bsdi__
87#include "loop.h"
88#endif
89#if defined(__NetBSD__) || defined(__OpenBSD__)
90extern struct ifnet loif[NLOOP];
91#endif
92
93#include <net/net_osdep.h>
94
95#define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
96#define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
97
98#define SIN6(s) ((struct sockaddr_in6 *)s)
99#define SDL(s) ((struct sockaddr_dl *)s)
100
101/* timer values */
102int nd6_prune = 1; /* walk list every 1 seconds */
103int nd6_delay = 5; /* delay first probe time 5 second */
104int nd6_umaxtries = 3; /* maximum unicast query */
105int nd6_mmaxtries = 3; /* maximum multicast query */
106int nd6_useloopback = 1; /* use loopback interface for local traffic */
107
108/* preventing too many loops in ND option parsing */
109int nd6_maxndopt = 10; /* max # of ND options allowed */
110
111/* for debugging? */
112static int nd6_inuse, nd6_allocated;
113
114struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6};
115struct nd_ifinfo *nd_ifinfo = NULL;
116struct nd_drhead nd_defrouter;
117struct nd_prhead nd_prefix = { 0 };
118
119int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
120static struct sockaddr_in6 all1_sa;
121
122static void nd6_slowtimo __P((void *));
123
124#if MIP6
125void (*mip6_expired_defrouter_hook)(struct nd_defrouter *dr) = 0;
126#endif
127
128void
129nd6_init()
130{
131 static int nd6_init_done = 0;
132 int i;
133
134 if (nd6_init_done) {
135 log(LOG_NOTICE, "nd6_init called more than once(ignored)\n");
136 return;
137 }
138
139 all1_sa.sin6_family = AF_INET6;
140 all1_sa.sin6_len = sizeof(struct sockaddr_in6);
141 for (i = 0; i < sizeof(all1_sa.sin6_addr); i++)
142 all1_sa.sin6_addr.s6_addr[i] = 0xff;
143
144 /* initialization of the default router list */
145 TAILQ_INIT(&nd_defrouter);
146
147 nd6_init_done = 1;
148
149 /* start timer */
150 timeout(nd6_slowtimo, (caddr_t)0, ND6_SLOWTIMER_INTERVAL * hz);
151}
152
153void
154nd6_ifattach(ifp)
155 struct ifnet *ifp;
156{
157 static size_t if_indexlim = 8;
158
159 /*
160 * We have some arrays that should be indexed by if_index.
161 * since if_index will grow dynamically, they should grow too.
162 */
163 if (nd_ifinfo == NULL || if_index >= if_indexlim) {
164 size_t n;
165 caddr_t q;
166
167 while (if_index >= if_indexlim)
168 if_indexlim <<= 1;
169
170 /* grow nd_ifinfo */
171 n = if_indexlim * sizeof(struct nd_ifinfo);
172 q = (caddr_t)_MALLOC(n, M_IP6NDP, M_WAITOK);
173 bzero(q, n);
174 if (nd_ifinfo) {
175 bcopy((caddr_t)nd_ifinfo, q, n/2);
176 _FREE((caddr_t)nd_ifinfo, M_IP6NDP);
177 }
178 nd_ifinfo = (struct nd_ifinfo *)q;
179 }
180
181#define ND nd_ifinfo[ifp->if_index]
182 ND.linkmtu = ifindex2ifnet[ifp->if_index]->if_mtu;
183 ND.chlim = IPV6_DEFHLIM;
184 ND.basereachable = REACHABLE_TIME;
185 ND.reachable = ND_COMPUTE_RTIME(ND.basereachable);
186 ND.retrans = RETRANS_TIMER;
187 ND.receivedra = 0;
188 ND.flags = ND6_IFF_PERFORMNUD;
189 nd6_setmtu(ifp);
190#undef ND
191}
192
193/*
194 * Reset ND level link MTU. This function is called when the physical MTU
195 * changes, which means we might have to adjust the ND level MTU.
196 */
197void
198nd6_setmtu(ifp)
199 struct ifnet *ifp;
200{
201 struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
202 u_long oldmaxmtu = ndi->maxmtu;
203 u_long oldlinkmtu = ndi->linkmtu;
204
205 switch(ifp->if_type) {
206 case IFT_ARCNET: /* XXX MTU handling needs more work */
207 ndi->maxmtu = MIN(60480, ifp->if_mtu);
208 break;
209 case IFT_ETHER:
210 ndi->maxmtu = MIN(ETHERMTU, ifp->if_mtu);
211 break;
212#if defined(__FreeBSD__) || defined(__bsdi__)
213 case IFT_FDDI:
214 ndi->maxmtu = MIN(FDDIIPMTU, ifp->if_mtu);
215 break;
216#endif
217#if !(defined(__bsdi__) && _BSDI_VERSION >= 199802) && !defined (__APPLE__)
218 case IFT_ATM:
219 ndi->maxmtu = MIN(ATMMTU, ifp->if_mtu);
220 break;
221#endif
222 default:
223 ndi->maxmtu = ifp->if_mtu;
224 break;
225 }
226
227 if (oldmaxmtu != ndi->maxmtu) {
228 /*
229 * If the ND level MTU is not set yet, or if the maxmtu
230 * is reset to a smaller value than the ND level MTU,
231 * also reset the ND level MTU.
232 */
233 if (ndi->linkmtu == 0 ||
234 ndi->maxmtu < ndi->linkmtu) {
235 ndi->linkmtu = ndi->maxmtu;
236 /* also adjust in6_maxmtu if necessary. */
237 if (oldlinkmtu == 0) {
238 /*
239 * XXX: the case analysis is grotty, but
240 * it is not efficient to call in6_setmaxmtu()
241 * here when we are during the initialization
242 * procedure.
243 */
244 if (in6_maxmtu < ndi->linkmtu)
245 in6_maxmtu = ndi->linkmtu;
246 }
247 else
248 in6_setmaxmtu();
249 }
250 }
251#undef MIN
252}
253
254void
255nd6_option_init(opt, icmp6len, ndopts)
256 void *opt;
257 int icmp6len;
258 union nd_opts *ndopts;
259{
260 bzero(ndopts, sizeof(*ndopts));
261 ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
262 ndopts->nd_opts_last
263 = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
264
265 if (icmp6len == 0) {
266 ndopts->nd_opts_done = 1;
267 ndopts->nd_opts_search = NULL;
268 }
269}
270
271/*
272 * Take one ND option.
273 */
274struct nd_opt_hdr *
275nd6_option(ndopts)
276 union nd_opts *ndopts;
277{
278 struct nd_opt_hdr *nd_opt;
279 int olen;
280
281 if (!ndopts)
282 panic("ndopts == NULL in nd6_option\n");
283 if (!ndopts->nd_opts_last)
284 panic("uninitialized ndopts in nd6_option\n");
285 if (!ndopts->nd_opts_search)
286 return NULL;
287 if (ndopts->nd_opts_done)
288 return NULL;
289
290 nd_opt = ndopts->nd_opts_search;
291
292 olen = nd_opt->nd_opt_len << 3;
293 if (olen == 0) {
294 /*
295 * Message validation requires that all included
296 * options have a length that is greater than zero.
297 */
298 bzero(ndopts, sizeof(*ndopts));
299 return NULL;
300 }
301
302 ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
303 if (!(ndopts->nd_opts_search < ndopts->nd_opts_last)) {
304 ndopts->nd_opts_done = 1;
305 ndopts->nd_opts_search = NULL;
306 }
307 return nd_opt;
308}
309
310/*
311 * Parse multiple ND options.
312 * This function is much easier to use, for ND routines that do not need
313 * multiple options of the same type.
314 */
315int
316nd6_options(ndopts)
317 union nd_opts *ndopts;
318{
319 struct nd_opt_hdr *nd_opt;
320 int i = 0;
321
322 if (!ndopts)
323 panic("ndopts == NULL in nd6_options\n");
324 if (!ndopts->nd_opts_last)
325 panic("uninitialized ndopts in nd6_options\n");
326 if (!ndopts->nd_opts_search)
327 return 0;
328
329 while (1) {
330 nd_opt = nd6_option(ndopts);
331 if (!nd_opt && !ndopts->nd_opts_last) {
332 /*
333 * Message validation requires that all included
334 * options have a length that is greater than zero.
335 */
336 bzero(ndopts, sizeof(*ndopts));
337 return -1;
338 }
339
340 if (!nd_opt)
341 goto skip1;
342
343 switch (nd_opt->nd_opt_type) {
344 case ND_OPT_SOURCE_LINKADDR:
345 case ND_OPT_TARGET_LINKADDR:
346 case ND_OPT_MTU:
347 case ND_OPT_REDIRECTED_HEADER:
348 case ND_OPT_ADV_INTERVAL:
349 if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
350 printf("duplicated ND6 option found "
351 "(type=%d)\n", nd_opt->nd_opt_type);
352 /* XXX bark? */
353 } else {
354 ndopts->nd_opt_array[nd_opt->nd_opt_type]
355 = nd_opt;
356 }
357 break;
358 case ND_OPT_PREFIX_INFORMATION:
359 if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
360 ndopts->nd_opt_array[nd_opt->nd_opt_type]
361 = nd_opt;
362 }
363 ndopts->nd_opts_pi_end =
364 (struct nd_opt_prefix_info *)nd_opt;
365 break;
366 case ND_OPT_HA_INFORMATION:
367 break;
368 default:
369 /*
370 * Unknown options must be silently ignored,
371 * to accomodate future extension to the protocol.
372 */
373 log(LOG_DEBUG,
374 "nd6_options: unsupported option %d - "
375 "option ignored\n", nd_opt->nd_opt_type);
376 }
377
378skip1:
379 i++;
380 if (i > nd6_maxndopt) {
381 icmp6stat.icp6s_nd_toomanyopt++;
382 printf("too many loop in nd opt\n");
383 break;
384 }
385
386 if (ndopts->nd_opts_done)
387 break;
388 }
389
390 return 0;
391}
392
393/*
394 * ND6 timer routine to expire default route list and prefix list
395 */
396void
397nd6_timer(ignored_arg)
398 void *ignored_arg;
399{
400 int s;
401 register struct llinfo_nd6 *ln;
402 register struct nd_defrouter *dr;
403 register struct nd_prefix *pr;
404#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
405 long time_second = time.tv_sec;
406#endif
407#ifdef __APPLE__
408 boolean_t funnel_state;
409 funnel_state = thread_set_funneled(TRUE);
410#endif
411
412#if __NetBSD__
413 s = splsoftnet();
414#else
415 s = splnet();
416#endif
417 timeout(nd6_timer, (caddr_t)0, nd6_prune * hz);
418
419 ln = llinfo_nd6.ln_next;
420 /* XXX BSD/OS separates this code -- itojun */
421 while (ln && ln != &llinfo_nd6) {
422 struct rtentry *rt;
423 struct ifnet *ifp;
424 struct sockaddr_in6 *dst;
425 struct llinfo_nd6 *next = ln->ln_next;
426 /* XXX: used for the DELAY case only: */
427 struct nd_ifinfo *ndi = NULL;
428
429 if ((rt = ln->ln_rt) == NULL) {
430 ln = next;
431 continue;
432 }
433 if ((ifp = rt->rt_ifp) == NULL) {
434 ln = next;
435 continue;
436 }
437 ndi = &nd_ifinfo[ifp->if_index];
438 dst = (struct sockaddr_in6 *)rt_key(rt);
439
440 if (ln->ln_expire > time_second) {
441 ln = next;
442 continue;
443 }
444
445 /* sanity check */
446 if (!rt)
447 panic("rt=0 in nd6_timer(ln=%p)\n", ln);
448 if (rt->rt_llinfo && (struct llinfo_nd6 *)rt->rt_llinfo != ln)
449 panic("rt_llinfo(%p) is not equal to ln(%p)\n",
450 rt->rt_llinfo, ln);
451 if (!dst)
452 panic("dst=0 in nd6_timer(ln=%p)\n", ln);
453
454 switch (ln->ln_state) {
455 case ND6_LLINFO_INCOMPLETE:
456 if (ln->ln_asked < nd6_mmaxtries) {
457 ln->ln_asked++;
458 ln->ln_expire = time_second +
459 nd_ifinfo[ifp->if_index].retrans / 1000;
460 nd6_ns_output(ifp, NULL, &dst->sin6_addr,
461 ln, 0);
462 } else {
463 struct mbuf *m = ln->ln_hold;
464 if (m) {
465 if (rt->rt_ifp) {
466 /*
467 * Fake rcvif to make ICMP error
468 * more helpful in diagnosing
469 * for the receiver.
470 * XXX: should we consider
471 * older rcvif?
472 */
473 m->m_pkthdr.rcvif = rt->rt_ifp;
474 }
475 icmp6_error(m, ICMP6_DST_UNREACH,
476 ICMP6_DST_UNREACH_ADDR, 0);
477 ln->ln_hold = NULL;
478 }
479 nd6_free(rt);
480 }
481 break;
482 case ND6_LLINFO_REACHABLE:
483 if (ln->ln_expire)
484 ln->ln_state = ND6_LLINFO_STALE;
485 break;
486 /*
487 * ND6_LLINFO_STALE state requires nothing for timer
488 * routine.
489 */
490 case ND6_LLINFO_DELAY:
491 if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) {
492 /* We need NUD */
493 ln->ln_asked = 1;
494 ln->ln_state = ND6_LLINFO_PROBE;
495 ln->ln_expire = time_second +
496 ndi->retrans / 1000;
497 nd6_ns_output(ifp, &dst->sin6_addr,
498 &dst->sin6_addr,
499 ln, 0);
500 }
501 else
502 ln->ln_state = ND6_LLINFO_STALE; /* XXX */
503 break;
504 case ND6_LLINFO_PROBE:
505 if (ln->ln_asked < nd6_umaxtries) {
506 ln->ln_asked++;
507 ln->ln_expire = time_second +
508 nd_ifinfo[ifp->if_index].retrans / 1000;
509 nd6_ns_output(ifp, &dst->sin6_addr,
510 &dst->sin6_addr, ln, 0);
511 } else {
512 nd6_free(rt);
513 }
514 break;
515 case ND6_LLINFO_WAITDELETE:
516 nd6_free(rt);
517 break;
518 }
519 ln = next;
520 }
521
522 /* expire */
523 dr = TAILQ_FIRST(&nd_defrouter);
524 while (dr) {
525 if (dr->expire && dr->expire < time_second) {
526 struct nd_defrouter *t;
527 t = TAILQ_NEXT(dr, dr_entry);
528 defrtrlist_del(dr);
529 dr = t;
530 } else {
531#if MIP6
532 if (mip6_expired_defrouter_hook)
533 (*mip6_expired_defrouter_hook)(dr);
534#endif /* MIP6 */
535 dr = TAILQ_NEXT(dr, dr_entry);
536 }
537 }
538 pr = nd_prefix.lh_first;
539 while (pr) {
540 struct in6_ifaddr *ia6;
541 struct in6_addrlifetime *lt6;
542
543 if (IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
544 ia6 = NULL;
545 else
546 ia6 = in6ifa_ifpwithaddr(pr->ndpr_ifp, &pr->ndpr_addr);
547
548 if (ia6) {
549 /* check address lifetime */
550 lt6 = &ia6->ia6_lifetime;
551 if (lt6->ia6t_preferred && lt6->ia6t_preferred < time_second)
552 ia6->ia6_flags |= IN6_IFF_DEPRECATED;
553 if (lt6->ia6t_expire && lt6->ia6t_expire < time_second) {
554 if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
555 in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
556 /* xxx ND_OPT_PI_FLAG_ONLINK processing */
557 }
558 }
559
560 /*
561 * check prefix lifetime.
562 * since pltime is just for autoconf, pltime processing for
563 * prefix is not necessary.
564 *
565 * we offset expire time by NDPR_KEEP_EXPIRE, so that we
566 * can use the old prefix information to validate the
567 * next prefix information to come. See prelist_update()
568 * for actual validation.
569 */
570 if (pr->ndpr_expire
571 && pr->ndpr_expire + NDPR_KEEP_EXPIRED < time_second) {
572 struct nd_prefix *t;
573 t = pr->ndpr_next;
574
575 /*
576 * address expiration and prefix expiration are
577 * separate. NEVER perform in6_ifdel here.
578 */
579
580 prelist_remove(pr);
581 pr = t;
582 } else
583 pr = pr->ndpr_next;
584 }
585 splx(s);
586#ifdef __APPLE__
587 (void) thread_set_funneled(funnel_state);
588#endif
589}
590
591/*
592 * Nuke neighbor cache/prefix/default router management table, right before
593 * ifp goes away.
594 */
595void
596nd6_purge(ifp)
597 struct ifnet *ifp;
598{
599 struct llinfo_nd6 *ln, *nln;
600 struct nd_defrouter *dr, *ndr, drany;
601 struct nd_prefix *pr, *npr;
602
603 /* Nuke default router list entries toward ifp */
604 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
605 /*
606 * The first entry of the list may be stored in
607 * the routing table, so we'll delete it later.
608 */
609 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = ndr) {
610 ndr = TAILQ_NEXT(dr, dr_entry);
611 if (dr->ifp == ifp)
612 defrtrlist_del(dr);
613 }
614 dr = TAILQ_FIRST(&nd_defrouter);
615 if (dr->ifp == ifp)
616 defrtrlist_del(dr);
617 }
618
619 /* Nuke prefix list entries toward ifp */
620 for (pr = nd_prefix.lh_first; pr; pr = npr) {
621 npr = pr->ndpr_next;
622 if (pr->ndpr_ifp == ifp) {
623 if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
624 in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
625 prelist_remove(pr);
626 }
627 }
628
629 /* cancel default outgoing interface setting */
630 if (nd6_defifindex == ifp->if_index)
631 nd6_setdefaultiface(0);
632
633 /* refresh default router list */
634 bzero(&drany, sizeof(drany));
635 defrouter_delreq(&drany, 0);
636 defrouter_select();
637
638 /*
639 * Nuke neighbor cache entries for the ifp.
640 * Note that rt->rt_ifp may not be the same as ifp,
641 * due to KAME goto ours hack. See RTM_RESOLVE case in
642 * nd6_rtrequest(), and ip6_input().
643 */
644 ln = llinfo_nd6.ln_next;
645 while (ln && ln != &llinfo_nd6) {
646 struct rtentry *rt;
647 struct sockaddr_dl *sdl;
648
649 nln = ln->ln_next;
650 rt = ln->ln_rt;
651 if (rt && rt->rt_gateway &&
652 rt->rt_gateway->sa_family == AF_LINK) {
653 sdl = (struct sockaddr_dl *)rt->rt_gateway;
654 if (sdl->sdl_index == ifp->if_index)
655 nd6_free(rt);
656 }
657 ln = nln;
658 }
659
660 /*
661 * Neighbor cache entry for interface route will be retained
662 * with ND6_LLINFO_WAITDELETE state, by nd6_free(). Nuke it.
663 */
664 ln = llinfo_nd6.ln_next;
665 while (ln && ln != &llinfo_nd6) {
666 struct rtentry *rt;
667 struct sockaddr_dl *sdl;
668
669 nln = ln->ln_next;
670 rt = ln->ln_rt;
671 if (rt && rt->rt_gateway &&
672 rt->rt_gateway->sa_family == AF_LINK) {
673 sdl = (struct sockaddr_dl *)rt->rt_gateway;
674 if (sdl->sdl_index == ifp->if_index) {
675 rtrequest(RTM_DELETE, rt_key(rt),
676 (struct sockaddr *)0, rt_mask(rt), 0,
677 (struct rtentry **)0);
678 }
679 }
680 ln = nln;
681 }
682}
683
684struct rtentry *
685nd6_lookup(addr6, create, ifp)
686 struct in6_addr *addr6;
687 int create;
688 struct ifnet *ifp;
689{
690 struct rtentry *rt;
691 struct sockaddr_in6 sin6;
692
693 bzero(&sin6, sizeof(sin6));
694 sin6.sin6_len = sizeof(struct sockaddr_in6);
695 sin6.sin6_family = AF_INET6;
696 sin6.sin6_addr = *addr6;
697 rt = rtalloc1((struct sockaddr *)&sin6, create
698#if __FreeBSD__ || defined (__APPLE__)
699 , 0UL
700#endif /*__FreeBSD__*/
701 );
702 if (rt && (rt->rt_flags & RTF_LLINFO) == 0) {
703 /*
704 * This is the case for the default route.
705 * If we want to create a neighbor cache for the address, we
706 * should free the route for the destination and allocate an
707 * interface route.
708 */
709 if (create) {
710 RTFREE(rt);
711 rt = 0;
712 }
713 }
714 if (!rt) {
715 if (create && ifp) {
716 int e;
717
718 /*
719 * If no route is available and create is set,
720 * we allocate a host route for the destination
721 * and treat it like an interface route.
722 * This hack is necessary for a neighbor which can't
723 * be covered by our own prefix.
724 */
725 struct ifaddr *ifa =
726 ifaof_ifpforaddr((struct sockaddr *)&sin6, ifp);
727 if (ifa == NULL)
728 return(NULL);
729
730 /*
731 * Create a new route. RTF_LLINFO is necessary
732 * to create a Neighbor Cache entry for the
733 * destination in nd6_rtrequest which will be
734 * called in rtequest via ifa->ifa_rtrequest.
735 */
736 if ((e = rtrequest(RTM_ADD, (struct sockaddr *)&sin6,
737 ifa->ifa_addr,
738 (struct sockaddr *)&all1_sa,
739 (ifa->ifa_flags |
740 RTF_HOST | RTF_LLINFO) &
741 ~RTF_CLONING,
742 &rt)) != 0)
743 log(LOG_ERR,
744 "nd6_lookup: failed to add route for a "
745 "neighbor(%s), errno=%d\n",
746 ip6_sprintf(addr6), e);
747 if (rt == NULL)
748 return(NULL);
749 if (rt->rt_llinfo) {
750 struct llinfo_nd6 *ln =
751 (struct llinfo_nd6 *)rt->rt_llinfo;
752 ln->ln_state = ND6_LLINFO_NOSTATE;
753 }
754 }
755 else
756 return(NULL);
757 }
758 rt->rt_refcnt--;
759 /*
760 * Validation for the entry.
761 * XXX: we can't use rt->rt_ifp to check for the interface, since
762 * it might be the loopback interface if the entry is for our
763 * own address on a non-loopback interface. Instead, we should
764 * use rt->rt_ifa->ifa_ifp, which would specify the REAL interface.
765 */
766 if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
767 rt->rt_gateway->sa_family != AF_LINK ||
768 (ifp && rt->rt_ifa->ifa_ifp != ifp)) {
769 if (create) {
770 log(LOG_DEBUG, "nd6_lookup: failed to lookup %s (if = %s)\n",
771 ip6_sprintf(addr6), ifp ? if_name(ifp) : "unspec");
772 /* xxx more logs... kazu */
773 }
774 return(0);
775 }
776 return(rt);
777}
778
779/*
780 * Detect if a given IPv6 address identifies a neighbor on a given link.
781 * XXX: should take care of the destination of a p2p link?
782 */
783int
784nd6_is_addr_neighbor(addr, ifp)
785 struct in6_addr *addr;
786 struct ifnet *ifp;
787{
788 register struct ifaddr *ifa;
789 int i;
790
791#define IFADDR6(a) ((((struct in6_ifaddr *)(a))->ia_addr).sin6_addr)
792#define IFMASK6(a) ((((struct in6_ifaddr *)(a))->ia_prefixmask).sin6_addr)
793
794 /* A link-local address is always a neighbor. */
795 if (IN6_IS_ADDR_LINKLOCAL(addr))
796 return(1);
797
798 /*
799 * If the address matches one of our addresses,
800 * it should be a neighbor.
801 */
802#if defined(__bsdi__) || (defined(__FreeBSD__) && __FreeBSD__ < 3)
803 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
804#else
805 for (ifa = ifp->if_addrlist.tqh_first;
806 ifa;
807 ifa = ifa->ifa_list.tqe_next)
808#endif
809 {
810 if (ifa->ifa_addr->sa_family != AF_INET6)
811 next: continue;
812
813 for (i = 0; i < 4; i++) {
814 if ((IFADDR6(ifa).s6_addr32[i] ^ addr->s6_addr32[i]) &
815 IFMASK6(ifa).s6_addr32[i])
816 goto next;
817 }
818 return(1);
819 }
820
821 /*
822 * Even if the address matches none of our addresses, it might be
823 * in the neighbor cache.
824 */
825 if (nd6_lookup(addr, 0, ifp))
826 return(1);
827
828 return(0);
829#undef IFADDR6
830#undef IFMASK6
831}
832
833/*
834 * Free an nd6 llinfo entry.
835 */
836void
837nd6_free(rt)
838 struct rtentry *rt;
839{
840 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
841 struct sockaddr_dl *sdl;
842 struct in6_addr in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
843 struct nd_defrouter *dr;
844
845 /*
846 * Clear all destination cache entries for the neighbor.
847 * XXX: is it better to restrict this to hosts?
848 */
849 pfctlinput(PRC_HOSTDEAD, rt_key(rt));
850
851 if (!ip6_forwarding && ip6_accept_rtadv) { /* XXX: too restrictive? */
852 int s;
853#ifdef __NetBSD__
854 s = splsoftnet();
855#else
856 s = splnet();
857#endif
858 dr = defrouter_lookup(&((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
859 rt->rt_ifp);
860 if (ln->ln_router || dr) {
861 /*
862 * rt6_flush must be called whether or not the neighbor
863 * is in the Default Router List.
864 * See a corresponding comment in nd6_na_input().
865 */
866 rt6_flush(&in6, rt->rt_ifp);
867 }
868
869 if (dr) {
870 /*
871 * Unreachablity of a router might affect the default
872 * router selection and on-link detection of advertised
873 * prefixes.
874 */
875
876 /*
877 * Temporarily fake the state to choose a new default
878 * router and to perform on-link determination of
879 * prefixes coreectly.
880 * Below the state will be set correctly,
881 * or the entry itself will be deleted.
882 */
883 ln->ln_state = ND6_LLINFO_INCOMPLETE;
884
885 if (dr == TAILQ_FIRST(&nd_defrouter)) {
886 /*
887 * It is used as the current default router,
888 * so we have to move it to the end of the
889 * list and choose a new one.
890 * XXX: it is not very efficient if this is
891 * the only router.
892 */
893 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
894 TAILQ_INSERT_TAIL(&nd_defrouter, dr, dr_entry);
895
896 defrouter_select();
897 }
898 pfxlist_onlink_check();
899 }
900 splx(s);
901 }
902
903 if (rt->rt_refcnt > 0 && (sdl = SDL(rt->rt_gateway)) &&
904 sdl->sdl_family == AF_LINK) {
905 sdl->sdl_alen = 0;
906 ln->ln_state = ND6_LLINFO_WAITDELETE;
907 ln->ln_asked = 0;
908 rt->rt_flags &= ~RTF_REJECT;
909 return;
910 }
911
912 rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
913 rt_mask(rt), 0, (struct rtentry **)0);
914}
915
916/*
917 * Upper-layer reachability hint for Neighbor Unreachability Detection.
918 *
919 * XXX cost-effective metods?
920 */
921void
922nd6_nud_hint(rt, dst6)
923 struct rtentry *rt;
924 struct in6_addr *dst6;
925{
926 struct llinfo_nd6 *ln;
927#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
928 long time_second = time.tv_sec;
929#endif
930
931 /*
932 * If the caller specified "rt", use that. Otherwise, resolve the
933 * routing table by supplied "dst6".
934 */
935 if (!rt) {
936 if (!dst6)
937 return;
938 if (!(rt = nd6_lookup(dst6, 0, NULL)))
939 return;
940 }
941
942 if ((rt->rt_flags & RTF_GATEWAY)
943 || (rt->rt_flags & RTF_LLINFO) == 0
944 || !rt->rt_llinfo
945 || !rt->rt_gateway
946 || rt->rt_gateway->sa_family != AF_LINK) {
947 /* This is not a host route. */
948 return;
949 }
950
951 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
952 if (ln->ln_state < ND6_LLINFO_REACHABLE)
953 return;
954
955 ln->ln_state = ND6_LLINFO_REACHABLE;
956 if (ln->ln_expire && nd_ifinfo)
957 ln->ln_expire = time_second +
958 (rt->rt_ifp ? nd_ifinfo[rt->rt_ifp->if_index].reachable : 0) ;
959}
960
961#if OLDIP6OUTPUT
962/*
963 * Resolve an IP6 address into an ethernet address. If success,
964 * desten is filled in. If there is no entry in ndptab,
965 * set one up and multicast a solicitation for the IP6 address.
966 * Hold onto this mbuf and resend it once the address
967 * is finally resolved. A return value of 1 indicates
968 * that desten has been filled in and the packet should be sent
969 * normally; a 0 return indicates that the packet has been
970 * taken over here, either now or for later transmission.
971 */
972int
973nd6_resolve(ifp, rt, m, dst, desten)
974 struct ifnet *ifp;
975 struct rtentry *rt;
976 struct mbuf *m;
977 struct sockaddr *dst;
978 u_char *desten;
979{
980 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)NULL;
981 struct sockaddr_dl *sdl;
982#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
983 long time_second = time.tv_sec;
984#endif
985
986 if (m->m_flags & M_MCAST) {
987 switch (ifp->if_type) {
988 case IFT_ETHER:
989 case IFT_FDDI:
990 ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
991 desten);
992 return(1);
993 break;
994 case IFT_ARCNET:
995 *desten = 0;
996 return(1);
997 break;
998 default:
999 return(0);
1000 }
1001 }
1002 if (rt && (rt->rt_flags & RTF_LLINFO) != 0)
1003 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1004 else {
1005 if ((rt = nd6_lookup(&(SIN6(dst)->sin6_addr), 1, ifp)) != NULL)
1006 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1007 }
1008 if (!ln || !rt) {
1009 log(LOG_DEBUG, "nd6_resolve: can't allocate llinfo for %s\n",
1010 ip6_sprintf(&(SIN6(dst)->sin6_addr)));
1011 m_freem(m);
1012 return(0);
1013 }
1014 sdl = SDL(rt->rt_gateway);
1015 /*
1016 * Ckeck the address family and length is valid, the address
1017 * is resolved; otherwise, try to resolve.
1018 */
1019 if (ln->ln_state >= ND6_LLINFO_REACHABLE
1020 && sdl->sdl_family == AF_LINK
1021 && sdl->sdl_alen != 0) {
1022 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
1023 if (ln->ln_state == ND6_LLINFO_STALE) {
1024 ln->ln_asked = 0;
1025 ln->ln_state = ND6_LLINFO_DELAY;
1026 ln->ln_expire = time_second + nd6_delay;
1027 }
1028 return(1);
1029 }
1030 /*
1031 * There is an ndp entry, but no ethernet address
1032 * response yet. Replace the held mbuf with this
1033 * latest one.
1034 *
1035 * XXX Does the code conform to rate-limiting rule?
1036 * (RFC 2461 7.2.2)
1037 */
1038 if (ln->ln_state == ND6_LLINFO_WAITDELETE ||
1039 ln->ln_state == ND6_LLINFO_NOSTATE)
1040 ln->ln_state = ND6_LLINFO_INCOMPLETE;
1041 if (ln->ln_hold)
1042 m_freem(ln->ln_hold);
1043 ln->ln_hold = m;
1044 if (ln->ln_expire) {
1045 rt->rt_flags &= ~RTF_REJECT;
1046 if (ln->ln_asked < nd6_mmaxtries &&
1047 ln->ln_expire < time_second) {
1048 ln->ln_asked++;
1049 ln->ln_expire = time_second +
1050 nd_ifinfo[ifp->if_index].retrans / 1000;
1051 nd6_ns_output(ifp, NULL, &(SIN6(dst)->sin6_addr),
1052 ln, 0);
1053 }
1054 }
1055 return(0);
1056}
1057#endif /* OLDIP6OUTPUT */
1058
1059void
1060#if defined(__bsdi__) && _BSDI_VERSION >= 199802
1061nd6_rtrequest(req, rt, info)
1062 int req;
1063 struct rtentry *rt;
1064 struct rt_addrinfo *info; /* xxx unused */
1065#else
1066nd6_rtrequest(req, rt, sa)
1067 int req;
1068 struct rtentry *rt;
1069 struct sockaddr *sa; /* xxx unused */
1070#endif
1071{
1072 struct sockaddr *gate = rt->rt_gateway;
1073 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1074 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1075 struct ifnet *ifp = rt->rt_ifp;
1076 struct ifaddr *ifa;
1077#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
1078 long time_second = time.tv_sec;
1079#endif
1080
1081 if (rt->rt_flags & RTF_GATEWAY)
1082 return;
1083
1084 switch (req) {
1085 case RTM_ADD:
1086 /*
1087 * There is no backward compatibility :)
1088 *
1089 * if ((rt->rt_flags & RTF_HOST) == 0 &&
1090 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1091 * rt->rt_flags |= RTF_CLONING;
1092 */
1093 if (rt->rt_flags & (RTF_CLONING | RTF_LLINFO)) {
1094 /*
1095 * Case 1: This route should come from
1096 * a route to interface. RTF_LLINFO flag is set
1097 * for a host route whose destination should be
1098 * treated as on-link.
1099 */
1100 rt_setgate(rt, rt_key(rt),
1101 (struct sockaddr *)&null_sdl);
1102 gate = rt->rt_gateway;
1103 SDL(gate)->sdl_type = ifp->if_type;
1104 SDL(gate)->sdl_index = ifp->if_index;
1105 if (ln)
1106 ln->ln_expire = time_second;
1107#if 1
1108 if (ln && ln->ln_expire == 0) {
1109 /* cludge for desktops */
1110#if 0
1111 printf("nd6_request: time.tv_sec is zero; "
1112 "treat it as 1\n");
1113#endif
1114 ln->ln_expire = 1;
1115 }
1116#endif
1117 if (rt->rt_flags & RTF_CLONING)
1118 break;
1119 }
1120 /*
1121 * In IPv4 code, we try to annonuce new RTF_ANNOUNCE entry here.
1122 * We don't do that here since llinfo is not ready yet.
1123 *
1124 * There are also couple of other things to be discussed:
1125 * - unsolicited NA code needs improvement beforehand
1126 * - RFC2461 says we MAY send multicast unsolicited NA
1127 * (7.2.6 paragraph 4), however, it also says that we
1128 * SHOULD provide a mechanism to prevent multicast NA storm.
1129 * we don't have anything like it right now.
1130 * note that the mechanism need a mutual agreement
1131 * between proxies, which means that we need to implement
1132 * a new protocol, or new kludge.
1133 * - from RFC2461 6.2.4, host MUST NOT send unsolicited NA.
1134 * we need to check ip6forwarding before sending it.
1135 * (or should we allow proxy ND configuration only for
1136 * routers? there's no mention about proxy ND from hosts)
1137 */
1138#if 0
1139 /* XXX it does not work */
1140 if (rt->rt_flags & RTF_ANNOUNCE)
1141 nd6_na_output(ifp,
1142 &SIN6(rt_key(rt))->sin6_addr,
1143 &SIN6(rt_key(rt))->sin6_addr,
1144 ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
1145 1, NULL);
1146#endif
1147 /* FALLTHROUGH */
1148 case RTM_RESOLVE:
1149 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
1150 /*
1151 * Address resolution isn't necessary for a point to
1152 * point link, so we can skip this test for a p2p link.
1153 */
1154 if (gate->sa_family != AF_LINK ||
1155 gate->sa_len < sizeof(null_sdl)) {
1156 log(LOG_DEBUG,
1157 "nd6_rtrequest: bad gateway value\n");
1158 break;
1159 }
1160 SDL(gate)->sdl_type = ifp->if_type;
1161 SDL(gate)->sdl_index = ifp->if_index;
1162 }
1163 if (ln != NULL)
1164 break; /* This happens on a route change */
1165 /*
1166 * Case 2: This route may come from cloning, or a manual route
1167 * add with a LL address.
1168 */
1169 R_Malloc(ln, struct llinfo_nd6 *, sizeof(*ln));
1170 rt->rt_llinfo = (caddr_t)ln;
1171 if (!ln) {
1172 log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n");
1173 break;
1174 }
1175 nd6_inuse++;
1176 nd6_allocated++;
1177 Bzero(ln, sizeof(*ln));
1178 ln->ln_rt = rt;
1179 /* this is required for "ndp" command. - shin */
1180 if (req == RTM_ADD) {
1181 /*
1182 * gate should have some valid AF_LINK entry,
1183 * and ln->ln_expire should have some lifetime
1184 * which is specified by ndp command.
1185 */
1186 ln->ln_state = ND6_LLINFO_REACHABLE;
1187 } else {
1188 /*
1189 * When req == RTM_RESOLVE, rt is created and
1190 * initialized in rtrequest(), so rt_expire is 0.
1191 */
1192 ln->ln_state = ND6_LLINFO_NOSTATE;
1193 ln->ln_expire = time_second;
1194 }
1195 rt->rt_flags |= RTF_LLINFO;
1196 ln->ln_next = llinfo_nd6.ln_next;
1197 llinfo_nd6.ln_next = ln;
1198 ln->ln_prev = &llinfo_nd6;
1199 ln->ln_next->ln_prev = ln;
1200
1201 /*
1202 * check if rt_key(rt) is one of my address assigned
1203 * to the interface.
1204 */
1205 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
1206 &SIN6(rt_key(rt))->sin6_addr);
1207 if (ifa) {
1208 caddr_t macp = nd6_ifptomac(ifp);
1209 ln->ln_expire = 0;
1210 ln->ln_state = ND6_LLINFO_REACHABLE;
1211 if (macp) {
1212 Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen);
1213 SDL(gate)->sdl_alen = ifp->if_addrlen;
1214 }
1215 if (nd6_useloopback) {
1216#ifdef __bsdi__
1217#if _BSDI_VERSION >= 199802
1218 extern struct ifnet *loifp;
1219 rt->rt_ifp = loifp; /*XXX*/
1220#else
1221 extern struct ifnet loif;
1222 rt->rt_ifp = &loif; /*XXX*/
1223#endif
1224#else /* non-bsdi */
1225 rt->rt_ifp = &loif[0]; /*XXX*/
1226#endif
1227 /*
1228 * Make sure rt_ifa be equal to the ifaddr
1229 * corresponding to the address.
1230 * We need this because when we refer
1231 * rt_ifa->ia6_flags in ip6_input, we assume
1232 * that the rt_ifa points to the address instead
1233 * of the loopback address.
1234 */
1235 if (ifa != rt->rt_ifa) {
1236 rt->rt_ifa->ifa_refcnt--;
1237 ifa->ifa_refcnt++;
1238 rt->rt_ifa = ifa;
1239 }
1240 }
1241 } else if (rt->rt_flags & RTF_ANNOUNCE) {
1242 ln->ln_expire = 0;
1243 ln->ln_state = ND6_LLINFO_REACHABLE;
1244
1245 /* join solicited node multicast for proxy ND */
1246 if (ifp->if_flags & IFF_MULTICAST) {
1247 struct in6_addr llsol;
1248 int error;
1249
1250 llsol = SIN6(rt_key(rt))->sin6_addr;
1251 llsol.s6_addr16[0] = htons(0xff02);
1252 llsol.s6_addr16[1] = htons(ifp->if_index);
1253 llsol.s6_addr32[1] = 0;
1254 llsol.s6_addr32[2] = htonl(1);
1255 llsol.s6_addr8[12] = 0xff;
1256
1257 (void)in6_addmulti(&llsol, ifp, &error);
1258 if (error)
1259 printf(
1260"nd6_rtrequest: could not join solicited node multicast (errno=%d)\n", error);
1261 }
1262 }
1263 break;
1264
1265 case RTM_DELETE:
1266 if (!ln)
1267 break;
1268 /* leave from solicited node multicast for proxy ND */
1269 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
1270 (ifp->if_flags & IFF_MULTICAST) != 0) {
1271 struct in6_addr llsol;
1272 struct in6_multi *in6m;
1273
1274 llsol = SIN6(rt_key(rt))->sin6_addr;
1275 llsol.s6_addr16[0] = htons(0xff02);
1276 llsol.s6_addr16[1] = htons(ifp->if_index);
1277 llsol.s6_addr32[1] = 0;
1278 llsol.s6_addr32[2] = htonl(1);
1279 llsol.s6_addr8[12] = 0xff;
1280
1281 IN6_LOOKUP_MULTI(llsol, ifp, in6m);
1282 if (in6m)
1283 in6_delmulti(in6m);
1284 }
1285 nd6_inuse--;
1286 ln->ln_next->ln_prev = ln->ln_prev;
1287 ln->ln_prev->ln_next = ln->ln_next;
1288 ln->ln_prev = NULL;
1289 rt->rt_llinfo = 0;
1290 rt->rt_flags &= ~RTF_LLINFO;
1291 if (ln->ln_hold)
1292 m_freem(ln->ln_hold);
1293 Free((caddr_t)ln);
1294 }
1295}
1296
1297void
1298#if defined(__bsdi__) && _BSDI_VERSION >= 199802
1299nd6_p2p_rtrequest(req, rt, info)
1300 int req;
1301 struct rtentry *rt;
1302 struct rt_addrinfo *info; /* xxx unused */
1303#else
1304nd6_p2p_rtrequest(req, rt, sa)
1305 int req;
1306 struct rtentry *rt;
1307 struct sockaddr *sa; /* xxx unused */
1308#endif
1309{
1310 struct sockaddr *gate = rt->rt_gateway;
1311 static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1312 struct ifnet *ifp = rt->rt_ifp;
1313 struct ifaddr *ifa;
1314
1315 if (rt->rt_flags & RTF_GATEWAY)
1316 return;
1317
1318 switch (req) {
1319 case RTM_ADD:
1320 /*
1321 * There is no backward compatibility :)
1322 *
1323 * if ((rt->rt_flags & RTF_HOST) == 0 &&
1324 * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1325 * rt->rt_flags |= RTF_CLONING;
1326 */
1327 if (rt->rt_flags & RTF_CLONING) {
1328 /*
1329 * Case 1: This route should come from
1330 * a route to interface.
1331 */
1332 rt_setgate(rt, rt_key(rt),
1333 (struct sockaddr *)&null_sdl);
1334 gate = rt->rt_gateway;
1335 SDL(gate)->sdl_type = ifp->if_type;
1336 SDL(gate)->sdl_index = ifp->if_index;
1337 break;
1338 }
1339 /* Announce a new entry if requested. */
1340 if (rt->rt_flags & RTF_ANNOUNCE)
1341 nd6_na_output(ifp,
1342 &SIN6(rt_key(rt))->sin6_addr,
1343 &SIN6(rt_key(rt))->sin6_addr,
1344 ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
1345 1, NULL);
1346 /* FALLTHROUGH */
1347 case RTM_RESOLVE:
1348 /*
1349 * check if rt_key(rt) is one of my address assigned
1350 * to the interface.
1351 */
1352 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
1353 &SIN6(rt_key(rt))->sin6_addr);
1354 if (ifa) {
1355 if (nd6_useloopback) {
1356#ifdef __bsdi__
1357#if _BSDI_VERSION >= 199802
1358 extern struct ifnet *loifp;
1359 rt->rt_ifp = loifp; /*XXX*/
1360#else
1361 extern struct ifnet loif;
1362 rt->rt_ifp = &loif; /*XXX*/
1363#endif
1364#else
1365 rt->rt_ifp = &loif[0]; /*XXX*/
1366#endif /*__bsdi__*/
1367 }
1368 }
1369 break;
1370 }
1371}
1372
1373int
1374nd6_ioctl(cmd, data, ifp)
1375 u_long cmd;
1376 caddr_t data;
1377 struct ifnet *ifp;
1378{
1379 struct in6_drlist *drl = (struct in6_drlist *)data;
1380 struct in6_prlist *prl = (struct in6_prlist *)data;
1381 struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1382 struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
1383 struct in6_ndifreq *ndif = (struct in6_ndifreq *)data;
1384 struct nd_defrouter *dr, any;
1385 struct nd_prefix *pr;
1386 struct rtentry *rt;
1387 int i = 0, error = 0;
1388 int s;
1389
1390 switch (cmd) {
1391 case SIOCGDRLST_IN6:
1392 bzero(drl, sizeof(*drl));
1393#ifdef __NetBSD__
1394 s = splsoftnet();
1395#else
1396 s = splnet();
1397#endif
1398 dr = TAILQ_FIRST(&nd_defrouter);
1399 while (dr && i < DRLSTSIZ) {
1400 drl->defrouter[i].rtaddr = dr->rtaddr;
1401 if (IN6_IS_ADDR_LINKLOCAL(&drl->defrouter[i].rtaddr)) {
1402 /* XXX: need to this hack for KAME stack */
1403 drl->defrouter[i].rtaddr.s6_addr16[1] = 0;
1404 }
1405 else
1406 log(LOG_ERR,
1407 "default router list contains a "
1408 "non-linklocal address(%s)\n",
1409 ip6_sprintf(&drl->defrouter[i].rtaddr));
1410
1411 drl->defrouter[i].flags = dr->flags;
1412 drl->defrouter[i].rtlifetime = dr->rtlifetime;
1413 drl->defrouter[i].expire = dr->expire;
1414 drl->defrouter[i].if_index = dr->ifp->if_index;
1415 i++;
1416 dr = TAILQ_NEXT(dr, dr_entry);
1417 }
1418 splx(s);
1419 break;
1420 case SIOCGPRLST_IN6:
1421 /*
1422 * XXX meaning of fields, especialy "raflags", is very
1423 * differnet between RA prefix list and RR/static prefix list.
1424 * how about separating ioctls into two?
1425 */
1426 bzero(prl, sizeof(*prl));
1427#ifdef __NetBSD__
1428 s = splsoftnet();
1429#else
1430 s = splnet();
1431#endif
1432 pr = nd_prefix.lh_first;
1433 while (pr && i < PRLSTSIZ) {
1434 struct nd_pfxrouter *pfr;
1435 int j;
1436
1437 prl->prefix[i].prefix = pr->ndpr_prefix.sin6_addr;
1438 prl->prefix[i].raflags = pr->ndpr_raf;
1439 prl->prefix[i].prefixlen = pr->ndpr_plen;
1440 prl->prefix[i].vltime = pr->ndpr_vltime;
1441 prl->prefix[i].pltime = pr->ndpr_pltime;
1442 prl->prefix[i].if_index = pr->ndpr_ifp->if_index;
1443 prl->prefix[i].expire = pr->ndpr_expire;
1444
1445 pfr = pr->ndpr_advrtrs.lh_first;
1446 j = 0;
1447 while(pfr) {
1448 if (j < DRLSTSIZ) {
1449#define RTRADDR prl->prefix[i].advrtr[j]
1450 RTRADDR = pfr->router->rtaddr;
1451 if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
1452 /* XXX: hack for KAME */
1453 RTRADDR.s6_addr16[1] = 0;
1454 }
1455 else
1456 log(LOG_ERR,
1457 "a router(%s) advertises "
1458 "a prefix with "
1459 "non-link local address\n",
1460 ip6_sprintf(&RTRADDR));
1461#undef RTRADDR
1462 }
1463 j++;
1464 pfr = pfr->pfr_next;
1465 }
1466 prl->prefix[i].advrtrs = j;
1467 prl->prefix[i].origin = PR_ORIG_RA;
1468
1469 i++;
1470 pr = pr->ndpr_next;
1471 }
1472 {
1473 struct rr_prefix *rpp;
1474
1475 for (rpp = LIST_FIRST(&rr_prefix); rpp;
1476 rpp = LIST_NEXT(rpp, rp_entry)) {
1477 if (i >= PRLSTSIZ)
1478 break;
1479 prl->prefix[i].prefix = rpp->rp_prefix.sin6_addr;
1480 prl->prefix[i].raflags = rpp->rp_raf;
1481 prl->prefix[i].prefixlen = rpp->rp_plen;
1482 prl->prefix[i].vltime = rpp->rp_vltime;
1483 prl->prefix[i].pltime = rpp->rp_pltime;
1484 prl->prefix[i].if_index = rpp->rp_ifp->if_index;
1485 prl->prefix[i].expire = rpp->rp_expire;
1486 prl->prefix[i].advrtrs = 0;
1487 prl->prefix[i].origin = rpp->rp_origin;
1488 i++;
1489 }
1490 }
1491 splx(s);
1492
1493 break;
1494 case SIOCGIFINFO_IN6:
1495 ndi->ndi = nd_ifinfo[ifp->if_index];
1496 break;
1497 case SIOCSIFINFO_FLAGS:
1498 /* XXX: almost all other fields of ndi->ndi is unused */
1499 nd_ifinfo[ifp->if_index].flags = ndi->ndi.flags;
1500 break;
1501 case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */
1502 /* flush default router list */
1503 /*
1504 * xxx sumikawa: should not delete route if default
1505 * route equals to the top of default router list
1506 */
1507 bzero(&any, sizeof(any));
1508 defrouter_delreq(&any, 0);
1509 defrouter_select();
1510 /* xxx sumikawa: flush prefix list */
1511 break;
1512 case SIOCSPFXFLUSH_IN6:
1513 {
1514 /* flush all the prefix advertised by routers */
1515 struct nd_prefix *pr, *next;
1516
1517#ifdef __NetBSD__
1518 s = splsoftnet();
1519#else
1520 s = splnet();
1521#endif
1522 for (pr = nd_prefix.lh_first; pr; pr = next) {
1523 next = pr->ndpr_next;
1524 if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr))
1525 in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr);
1526 prelist_remove(pr);
1527 }
1528 splx(s);
1529 break;
1530 }
1531 case SIOCSRTRFLUSH_IN6:
1532 {
1533 /* flush all the default routers */
1534 struct nd_defrouter *dr, *next;
1535
1536#ifdef __NetBSD__
1537 s = splsoftnet();
1538#else
1539 s = splnet();
1540#endif
1541 if ((dr = TAILQ_FIRST(&nd_defrouter)) != NULL) {
1542 /*
1543 * The first entry of the list may be stored in
1544 * the routing table, so we'll delete it later.
1545 */
1546 for (dr = TAILQ_NEXT(dr, dr_entry); dr; dr = next) {
1547 next = TAILQ_NEXT(dr, dr_entry);
1548 defrtrlist_del(dr);
1549 }
1550 defrtrlist_del(TAILQ_FIRST(&nd_defrouter));
1551 }
1552 splx(s);
1553 break;
1554 }
1555 case SIOCGNBRINFO_IN6:
1556 {
1557 struct llinfo_nd6 *ln;
1558 struct in6_addr nb_addr = nbi->addr; /* make local for safety */
1559
1560 /*
1561 * XXX: KAME specific hack for scoped addresses
1562 * XXXX: for other scopes than link-local?
1563 */
1564 if (IN6_IS_ADDR_LINKLOCAL(&nbi->addr) ||
1565 IN6_IS_ADDR_MC_LINKLOCAL(&nbi->addr)) {
1566 u_int16_t *idp = (u_int16_t *)&nb_addr.s6_addr[2];
1567
1568 if (*idp == 0)
1569 *idp = htons(ifp->if_index);
1570 }
1571
1572#ifdef __NetBSD__
1573 s = splsoftnet();
1574#else
1575 s = splnet();
1576#endif
1577 if ((rt = nd6_lookup(&nb_addr, 0, ifp)) == NULL) {
1578 error = EINVAL;
1579 splx(s);
1580 break;
1581 }
1582 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1583 nbi->state = ln->ln_state;
1584 nbi->asked = ln->ln_asked;
1585 nbi->isrouter = ln->ln_router;
1586 nbi->expire = ln->ln_expire;
1587 splx(s);
1588
1589 break;
1590 }
1591 case SIOCGDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */
1592 ndif->ifindex = nd6_defifindex;
1593 break;
1594 case SIOCSDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */
1595 return(nd6_setdefaultiface(ndif->ifindex));
1596 break;
1597 }
1598 return(error);
1599}
1600
1601/*
1602 * Create neighbor cache entry and cache link-layer address,
1603 * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
1604 */
1605struct rtentry *
1606nd6_cache_lladdr(ifp, from, lladdr, lladdrlen, type, code)
1607 struct ifnet *ifp;
1608 struct in6_addr *from;
1609 char *lladdr;
1610 int lladdrlen;
1611 int type; /* ICMP6 type */
1612 int code; /* type dependent information */
1613{
1614 struct rtentry *rt = NULL;
1615 struct llinfo_nd6 *ln = NULL;
1616 int is_newentry;
1617 struct sockaddr_dl *sdl = NULL;
1618 int do_update;
1619 int olladdr;
1620 int llchange;
1621 int newstate = 0;
1622#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
1623 long time_second = time.tv_sec;
1624#endif
1625
1626 if (!ifp)
1627 panic("ifp == NULL in nd6_cache_lladdr");
1628 if (!from)
1629 panic("from == NULL in nd6_cache_lladdr");
1630
1631 /* nothing must be updated for unspecified address */
1632 if (IN6_IS_ADDR_UNSPECIFIED(from))
1633 return NULL;
1634
1635 /*
1636 * Validation about ifp->if_addrlen and lladdrlen must be done in
1637 * the caller.
1638 *
1639 * XXX If the link does not have link-layer adderss, what should
1640 * we do? (ifp->if_addrlen == 0)
1641 * Spec says nothing in sections for RA, RS and NA. There's small
1642 * description on it in NS section (RFC 2461 7.2.3).
1643 */
1644
1645 rt = nd6_lookup(from, 0, ifp);
1646 if (!rt) {
1647#if 0
1648 /* nothing must be done if there's no lladdr */
1649 if (!lladdr || !lladdrlen)
1650 return NULL;
1651#endif
1652
1653 rt = nd6_lookup(from, 1, ifp);
1654 is_newentry = 1;
1655 } else
1656 is_newentry = 0;
1657
1658 if (!rt)
1659 return NULL;
1660 if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
1661fail:
1662 nd6_free(rt);
1663 return NULL;
1664 }
1665 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1666 if (!ln)
1667 goto fail;
1668 if (!rt->rt_gateway)
1669 goto fail;
1670 if (rt->rt_gateway->sa_family != AF_LINK)
1671 goto fail;
1672 sdl = SDL(rt->rt_gateway);
1673
1674 olladdr = (sdl->sdl_alen) ? 1 : 0;
1675 if (olladdr && lladdr) {
1676 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
1677 llchange = 1;
1678 else
1679 llchange = 0;
1680 } else
1681 llchange = 0;
1682
1683 /*
1684 * newentry olladdr lladdr llchange (*=record)
1685 * 0 n n -- (1)
1686 * 0 y n -- (2)
1687 * 0 n y -- (3) * STALE
1688 * 0 y y n (4) *
1689 * 0 y y y (5) * STALE
1690 * 1 -- n -- (6) NOSTATE(= PASSIVE)
1691 * 1 -- y -- (7) * STALE
1692 */
1693
1694 if (lladdr) { /*(3-5) and (7)*/
1695 /*
1696 * Record source link-layer address
1697 * XXX is it dependent to ifp->if_type?
1698 */
1699 sdl->sdl_alen = ifp->if_addrlen;
1700 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
1701 }
1702
1703 if (!is_newentry) {
1704 if ((!olladdr && lladdr) /*(3)*/
1705 || (olladdr && lladdr && llchange)) { /*(5)*/
1706 do_update = 1;
1707 newstate = ND6_LLINFO_STALE;
1708 } else /*(1-2,4)*/
1709 do_update = 0;
1710 } else {
1711 do_update = 1;
1712 if (!lladdr) /*(6)*/
1713 newstate = ND6_LLINFO_NOSTATE;
1714 else /*(7)*/
1715 newstate = ND6_LLINFO_STALE;
1716 }
1717
1718 if (do_update) {
1719 /*
1720 * Update the state of the neighbor cache.
1721 */
1722 ln->ln_state = newstate;
1723
1724 if (ln->ln_state == ND6_LLINFO_STALE) {
1725 rt->rt_flags &= ~RTF_REJECT;
1726 if (ln->ln_hold) {
1727#if OLDIP6OUTPUT
1728 (*ifp->if_output)(ifp, ln->ln_hold,
1729 rt_key(rt), rt);
1730#else
1731 nd6_output(ifp, ln->ln_hold,
1732 (struct sockaddr_in6 *)rt_key(rt),
1733 rt);
1734#endif
1735 ln->ln_hold = 0;
1736 }
1737 } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
1738 /* probe right away */
1739 ln->ln_expire = time_second;
1740 }
1741 }
1742
1743 /*
1744 * ICMP6 type dependent behavior.
1745 *
1746 * NS: clear IsRouter if new entry
1747 * RS: clear IsRouter
1748 * RA: set IsRouter if there's lladdr
1749 * redir: clear IsRouter if new entry
1750 *
1751 * RA case, (1):
1752 * The spec says that we must set IsRouter in the following cases:
1753 * - If lladdr exist, set IsRouter. This means (1-5).
1754 * - If it is old entry (!newentry), set IsRouter. This means (7).
1755 * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
1756 * A quetion arises for (1) case. (1) case has no lladdr in the
1757 * neighbor cache, this is similar to (6).
1758 * This case is rare but we figured that we MUST NOT set IsRouter.
1759 *
1760 * newentry olladdr lladdr llchange NS RS RA redir
1761 * D R
1762 * 0 n n -- (1) c ? s
1763 * 0 y n -- (2) c s s
1764 * 0 n y -- (3) c s s
1765 * 0 y y n (4) c s s
1766 * 0 y y y (5) c s s
1767 * 1 -- n -- (6) c c c s
1768 * 1 -- y -- (7) c c s c s
1769 *
1770 * (c=clear s=set)
1771 */
1772 switch (type & 0xff) {
1773 case ND_NEIGHBOR_SOLICIT:
1774 /*
1775 * New entry must have is_router flag cleared.
1776 */
1777 if (is_newentry) /*(6-7)*/
1778 ln->ln_router = 0;
1779 break;
1780 case ND_REDIRECT:
1781 /*
1782 * If the icmp is a redirect to a better router, always set the
1783 * is_router flag. Otherwise, if the entry is newly created,
1784 * clear the flag. [RFC 2461, sec 8.3]
1785 *
1786 */
1787 if (code == ND_REDIRECT_ROUTER)
1788 ln->ln_router = 1;
1789 else if (is_newentry) /*(6-7)*/
1790 ln->ln_router = 0;
1791 break;
1792 case ND_ROUTER_SOLICIT:
1793 /*
1794 * is_router flag must always be cleared.
1795 */
1796 ln->ln_router = 0;
1797 break;
1798 case ND_ROUTER_ADVERT:
1799 /*
1800 * Mark an entry with lladdr as a router.
1801 */
1802 if ((!is_newentry && (olladdr || lladdr)) /*(2-5)*/
1803 || (is_newentry && lladdr)) { /*(7)*/
1804 ln->ln_router = 1;
1805 }
1806 break;
1807 }
1808
1809 return rt;
1810}
1811
1812static void
1813nd6_slowtimo(ignored_arg)
1814 void *ignored_arg;
1815{
1816 int s;
1817 register int i;
1818 register struct nd_ifinfo *nd6if;
1819#ifdef __APPLE__
1820 boolean_t funnel_state;
1821 funnel_state = thread_set_funneled(TRUE);
1822#endif
1823
1824#ifdef __NetBSD__
1825 s = splsoftnet();
1826#else
1827 s = splnet();
1828#endif
1829
1830 timeout(nd6_slowtimo, (caddr_t)0, ND6_SLOWTIMER_INTERVAL * hz);
1831 for (i = 1; i < if_index + 1; i++) {
1832 nd6if = &nd_ifinfo[i];
1833 if (nd6if->basereachable && /* already initialized */
1834 (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
1835 /*
1836 * Since reachable time rarely changes by router
1837 * advertisements, we SHOULD insure that a new random
1838 * value gets recomputed at least once every few hours.
1839 * (RFC 2461, 6.3.4)
1840 */
1841 nd6if->recalctm = nd6_recalc_reachtm_interval;
1842 nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
1843 }
1844 }
1845 splx(s);
1846#ifdef __APPLE__
1847 (void) thread_set_funneled(funnel_state);
1848#endif
1849
1850}
1851
1852#define senderr(e) { error = (e); goto bad;}
1853int
1854nd6_output(ifp, m0, dst, rt0)
1855 register struct ifnet *ifp;
1856 struct mbuf *m0;
1857 struct sockaddr_in6 *dst;
1858 struct rtentry *rt0;
1859{
1860 register struct mbuf *m = m0;
1861 register struct rtentry *rt = rt0;
1862 struct llinfo_nd6 *ln = NULL;
1863 int error = 0;
1864#if !(defined(__FreeBSD__) && __FreeBSD__ >= 3) && !defined (__APPLE__)
1865 long time_second = time.tv_sec;
1866#endif
1867
1868 if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
1869 goto sendpkt;
1870
1871 /*
1872 * XXX: we currently do not make neighbor cache on any interface
1873 * other than ARCnet, Ethernet, FDDI and GIF.
1874 *
1875 * draft-ietf-ngtrans-mech-04.txt says:
1876 * - unidirectional tunnels needs no ND
1877 */
1878 switch (ifp->if_type) {
1879 case IFT_ARCNET:
1880 case IFT_ETHER:
1881 case IFT_FDDI:
1882 case IFT_GIF: /* XXX need more cases? */
1883 break;
1884 default:
1885 goto sendpkt;
1886 }
1887
1888 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
1889 (nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD) == 0)
1890 goto sendpkt;
1891
1892 /*
1893 * next hop determination. This routine is derived from ether_outpout.
1894 */
1895 if (rt) {
1896 if ((rt->rt_flags & RTF_UP) == 0) {
1897#if __FreeBSD__ || defined (__APPLE__)
1898 if ((rt0 = rt = rtalloc1((struct sockaddr *)dst, 1, 0UL)) !=
1899 NULL)
1900#else
1901 if ((rt0 = rt = rtalloc1((struct sockaddr *)dst, 1)) !=
1902 NULL)
1903#endif
1904 {
1905 rt->rt_refcnt--;
1906 if (rt->rt_ifp != ifp)
1907 return nd6_output(ifp, m0, dst, rt); /* XXX: loop care? */
1908 } else
1909 senderr(EHOSTUNREACH);
1910 }
1911 if (rt->rt_flags & RTF_GATEWAY) {
1912 if (rt->rt_gwroute == 0)
1913 goto lookup;
1914 if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
1915 rtfree(rt); rt = rt0;
1916#if __FreeBSD__ || defined (__APPLE__)
1917 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0UL);
1918#else
1919 lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
1920#endif
1921 if ((rt = rt->rt_gwroute) == 0)
1922 senderr(EHOSTUNREACH);
1923#ifdef __bsdi__
1924 /* the "G" test below also prevents rt == rt0 */
1925 if ((rt->rt_flags & RTF_GATEWAY) ||
1926 (rt->rt_ifp != ifp)) {
1927 rt->rt_refcnt--;
1928 rt0->rt_gwroute = 0;
1929 senderr(EHOSTUNREACH);
1930 }
1931#endif
1932 }
1933 }
1934 if (rt->rt_flags & RTF_REJECT)
1935 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
1936 }
1937
1938 /*
1939 * Address resolution or Neighbor Unreachability Detection
1940 * for the next hop.
1941 * At this point, the destination of the packet must be a unicast
1942 * or an anycast address(i.e. not a multicast).
1943 */
1944
1945 /* Look up the neighbor cache for the nexthop */
1946 if (rt && (rt->rt_flags & RTF_LLINFO) != 0)
1947 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1948 else {
1949 if ((rt = nd6_lookup(&dst->sin6_addr, 1, ifp)) != NULL)
1950 ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1951 }
1952 if (!ln || !rt) {
1953 log(LOG_DEBUG, "nd6_output: can't allocate llinfo for %s "
1954 "(ln=%p, rt=%p)\n",
1955 ip6_sprintf(&dst->sin6_addr), ln, rt);
1956 senderr(EIO); /* XXX: good error? */
1957 }
1958
1959 /* We don't have to do link-layer address resolution on a p2p link. */
1960 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
1961 ln->ln_state < ND6_LLINFO_REACHABLE)
1962 ln->ln_state = ND6_LLINFO_STALE;
1963
1964 /*
1965 * The first time we send a packet to a neighbor whose entry is
1966 * STALE, we have to change the state to DELAY and a sets a timer to
1967 * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
1968 * neighbor unreachability detection on expiration.
1969 * (RFC 2461 7.3.3)
1970 */
1971 if (ln->ln_state == ND6_LLINFO_STALE) {
1972 ln->ln_asked = 0;
1973 ln->ln_state = ND6_LLINFO_DELAY;
1974 ln->ln_expire = time_second + nd6_delay;
1975 }
1976
1977 /*
1978 * If the neighbor cache entry has a state other than INCOMPLETE
1979 * (i.e. its link-layer address is already reloved), just
1980 * send the packet.
1981 */
1982 if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
1983 goto sendpkt;
1984
1985 /*
1986 * There is a neighbor cache entry, but no ethernet address
1987 * response yet. Replace the held mbuf (if any) with this
1988 * latest one.
1989 *
1990 * XXX Does the code conform to rate-limiting rule?
1991 * (RFC 2461 7.2.2)
1992 */
1993 if (ln->ln_state == ND6_LLINFO_WAITDELETE ||
1994 ln->ln_state == ND6_LLINFO_NOSTATE)
1995 ln->ln_state = ND6_LLINFO_INCOMPLETE;
1996 if (ln->ln_hold)
1997 m_freem(ln->ln_hold);
1998 ln->ln_hold = m;
1999 if (ln->ln_expire) {
2000 rt->rt_flags &= ~RTF_REJECT;
2001 if (ln->ln_asked < nd6_mmaxtries &&
2002 ln->ln_expire < time_second) {
2003 ln->ln_asked++;
2004 ln->ln_expire = time_second +
2005 nd_ifinfo[ifp->if_index].retrans / 1000;
2006 nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
2007 }
2008 }
2009 return(0);
2010
2011 sendpkt:
2012#ifdef __APPLE__
2013 return (dlil_output(ifptodlt(ifp, PF_INET6), m, rt, (struct sockaddr *)dst, 0));
2014#else
2015 return((*ifp->if_output)(ifp, m, (struct sockaddr *)dst, rt));
2016#endif
2017
2018 bad:
2019 if (m)
2020 m_freem(m);
2021 return (error);
2022}
2023#undef senderr
2024
2025int
2026nd6_storelladdr(ifp, rt, m, dst, desten)
2027 struct ifnet *ifp;
2028 struct rtentry *rt;
2029 struct mbuf *m;
2030 struct sockaddr *dst;
2031 u_char *desten;
2032{
2033 struct sockaddr_dl *sdl;
2034
2035 if (m->m_flags & M_MCAST) {
2036 switch (ifp->if_type) {
2037 case IFT_ETHER:
2038 case IFT_FDDI:
2039 ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
2040 desten);
2041 return(1);
2042 break;
2043 case IFT_ARCNET:
2044 *desten = 0;
2045 return(1);
2046 default:
2047 return(0);
2048 }
2049 }
2050
2051 if (rt == NULL ||
2052 rt->rt_gateway->sa_family != AF_LINK) {
2053 printf("nd6_storelladdr: something odd happens\n");
2054 return(0);
2055 }
2056 sdl = SDL(rt->rt_gateway);
2057 if (sdl->sdl_alen == 0) {
2058 /* this should be impossible, but we bark here for debugging */
2059 printf("nd6_storelladdr: sdl_alen == 0\n");
2060 return(0);
2061 }
2062
2063 bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
2064 return(1);
2065}