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