Annotation of sys/netinet6/nd6.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: nd6.c,v 1.74 2007/06/08 09:31:38 henning Exp $ */
2: /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */
3:
4: /*
5: * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6: * All rights reserved.
7: *
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.
19: *
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: #include <sys/param.h>
34: #include <sys/systm.h>
35: #include <sys/timeout.h>
36: #include <sys/malloc.h>
37: #include <sys/mbuf.h>
38: #include <sys/socket.h>
39: #include <sys/sockio.h>
40: #include <sys/time.h>
41: #include <sys/kernel.h>
42: #include <sys/protosw.h>
43: #include <sys/errno.h>
44: #include <sys/ioctl.h>
45: #include <sys/syslog.h>
46: #include <sys/queue.h>
47: #include <dev/rndvar.h>
48:
49: #include <net/if.h>
50: #include <net/if_dl.h>
51: #include <net/if_types.h>
52: #include <net/if_fddi.h>
53: #include <net/route.h>
54:
55: #include <netinet/in.h>
56: #include <netinet/if_ether.h>
57: #include <netinet/ip_ipsp.h>
58:
59: #include <netinet6/in6_var.h>
60: #include <netinet/ip6.h>
61: #include <netinet6/ip6_var.h>
62: #include <netinet6/nd6.h>
63: #include <netinet/icmp6.h>
64:
65: #define ND6_SLOWTIMER_INTERVAL (60 * 60) /* 1 hour */
66: #define ND6_RECALC_REACHTM_INTERVAL (60 * 120) /* 2 hours */
67:
68: #define SIN6(s) ((struct sockaddr_in6 *)s)
69: #define SDL(s) ((struct sockaddr_dl *)s)
70:
71: /* timer values */
72: int nd6_prune = 1; /* walk list every 1 seconds */
73: int nd6_delay = 5; /* delay first probe time 5 second */
74: int nd6_umaxtries = 3; /* maximum unicast query */
75: int nd6_mmaxtries = 3; /* maximum multicast query */
76: int nd6_useloopback = 1; /* use loopback interface for local traffic */
77: int nd6_gctimer = (60 * 60 * 24); /* 1 day: garbage collection timer */
78:
79: /* preventing too many loops in ND option parsing */
80: int nd6_maxndopt = 10; /* max # of ND options allowed */
81:
82: int nd6_maxnudhint = 0; /* max # of subsequent upper layer hints */
83:
84: #ifdef ND6_DEBUG
85: int nd6_debug = 1;
86: #else
87: int nd6_debug = 0;
88: #endif
89:
90: /* for debugging? */
91: static int nd6_inuse, nd6_allocated;
92:
93: struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6};
94: struct nd_drhead nd_defrouter;
95: struct nd_prhead nd_prefix = { 0 };
96:
97: int nd6_recalc_reachtm_interval = ND6_RECALC_REACHTM_INTERVAL;
98: static struct sockaddr_in6 all1_sa;
99:
100: static void nd6_setmtu0(struct ifnet *, struct nd_ifinfo *);
101: static void nd6_slowtimo(void *);
102: static struct llinfo_nd6 *nd6_free(struct rtentry *, int);
103: static void nd6_llinfo_timer(void *);
104:
105: struct timeout nd6_slowtimo_ch;
106: struct timeout nd6_timer_ch;
107: extern struct timeout in6_tmpaddrtimer_ch;
108:
109: static int fill_drlist(void *, size_t *, size_t);
110: static int fill_prlist(void *, size_t *, size_t);
111:
112: void
113: nd6_init()
114: {
115: static int nd6_init_done = 0;
116: int i;
117:
118: if (nd6_init_done) {
119: log(LOG_NOTICE, "nd6_init called more than once(ignored)\n");
120: return;
121: }
122:
123: all1_sa.sin6_family = AF_INET6;
124: all1_sa.sin6_len = sizeof(struct sockaddr_in6);
125: for (i = 0; i < sizeof(all1_sa.sin6_addr); i++)
126: all1_sa.sin6_addr.s6_addr[i] = 0xff;
127:
128: /* initialization of the default router list */
129: TAILQ_INIT(&nd_defrouter);
130:
131: nd6_init_done = 1;
132:
133: /* start timer */
134: timeout_set(&nd6_slowtimo_ch, nd6_slowtimo, NULL);
135: timeout_add(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz);
136: }
137:
138: struct nd_ifinfo *
139: nd6_ifattach(ifp)
140: struct ifnet *ifp;
141: {
142: struct nd_ifinfo *nd;
143:
144: nd = (struct nd_ifinfo *)malloc(sizeof(*nd), M_IP6NDP, M_WAITOK);
145: bzero(nd, sizeof(*nd));
146:
147: nd->initialized = 1;
148:
149: nd->chlim = IPV6_DEFHLIM;
150: nd->basereachable = REACHABLE_TIME;
151: nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
152: nd->retrans = RETRANS_TIMER;
153: /*
154: * Note that the default value of ip6_accept_rtadv is 0, which means
155: * we won't accept RAs by default even if we set ND6_IFF_ACCEPT_RTADV
156: * here.
157: */
158: nd->flags = (ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV);
159:
160: /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
161: nd6_setmtu0(ifp, nd);
162:
163: return nd;
164: }
165:
166: void
167: nd6_ifdetach(nd)
168: struct nd_ifinfo *nd;
169: {
170:
171: free(nd, M_IP6NDP);
172: }
173:
174: void
175: nd6_setmtu(ifp)
176: struct ifnet *ifp;
177: {
178: nd6_setmtu0(ifp, ND_IFINFO(ifp));
179: }
180:
181: void
182: nd6_setmtu0(ifp, ndi)
183: struct ifnet *ifp;
184: struct nd_ifinfo *ndi;
185: {
186: u_int32_t omaxmtu;
187:
188: omaxmtu = ndi->maxmtu;
189:
190: if (ifp->if_type == IFT_FDDI)
191: ndi->maxmtu = MIN(FDDIMTU, ifp->if_mtu);
192: else
193: ndi->maxmtu = ifp->if_mtu;
194:
195: /*
196: * Decreasing the interface MTU under IPV6 minimum MTU may cause
197: * undesirable situation. We thus notify the operator of the change
198: * explicitly. The check for omaxmtu is necessary to restrict the
199: * log to the case of changing the MTU, not initializing it.
200: */
201: if (omaxmtu >= IPV6_MMTU && ndi->maxmtu < IPV6_MMTU) {
202: log(LOG_NOTICE, "nd6_setmtu0: "
203: "new link MTU on %s (%lu) is too small for IPv6\n",
204: ifp->if_xname, (unsigned long)ndi->maxmtu);
205: }
206:
207: if (ndi->maxmtu > in6_maxmtu)
208: in6_setmaxmtu(); /* check all interfaces just in case */
209: }
210:
211: void
212: nd6_option_init(opt, icmp6len, ndopts)
213: void *opt;
214: int icmp6len;
215: union nd_opts *ndopts;
216: {
217:
218: bzero(ndopts, sizeof(*ndopts));
219: ndopts->nd_opts_search = (struct nd_opt_hdr *)opt;
220: ndopts->nd_opts_last
221: = (struct nd_opt_hdr *)(((u_char *)opt) + icmp6len);
222:
223: if (icmp6len == 0) {
224: ndopts->nd_opts_done = 1;
225: ndopts->nd_opts_search = NULL;
226: }
227: }
228:
229: /*
230: * Take one ND option.
231: */
232: struct nd_opt_hdr *
233: nd6_option(ndopts)
234: union nd_opts *ndopts;
235: {
236: struct nd_opt_hdr *nd_opt;
237: int olen;
238:
239: if (!ndopts)
240: panic("ndopts == NULL in nd6_option");
241: if (!ndopts->nd_opts_last)
242: panic("uninitialized ndopts in nd6_option");
243: if (!ndopts->nd_opts_search)
244: return NULL;
245: if (ndopts->nd_opts_done)
246: return NULL;
247:
248: nd_opt = ndopts->nd_opts_search;
249:
250: /* make sure nd_opt_len is inside the buffer */
251: if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) {
252: bzero(ndopts, sizeof(*ndopts));
253: return NULL;
254: }
255:
256: olen = nd_opt->nd_opt_len << 3;
257: if (olen == 0) {
258: /*
259: * Message validation requires that all included
260: * options have a length that is greater than zero.
261: */
262: bzero(ndopts, sizeof(*ndopts));
263: return NULL;
264: }
265:
266: ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen);
267: if (ndopts->nd_opts_search > ndopts->nd_opts_last) {
268: /* option overruns the end of buffer, invalid */
269: bzero(ndopts, sizeof(*ndopts));
270: return NULL;
271: } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) {
272: /* reached the end of options chain */
273: ndopts->nd_opts_done = 1;
274: ndopts->nd_opts_search = NULL;
275: }
276: return nd_opt;
277: }
278:
279: /*
280: * Parse multiple ND options.
281: * This function is much easier to use, for ND routines that do not need
282: * multiple options of the same type.
283: */
284: int
285: nd6_options(ndopts)
286: union nd_opts *ndopts;
287: {
288: struct nd_opt_hdr *nd_opt;
289: int i = 0;
290:
291: if (!ndopts)
292: panic("ndopts == NULL in nd6_options");
293: if (!ndopts->nd_opts_last)
294: panic("uninitialized ndopts in nd6_options");
295: if (!ndopts->nd_opts_search)
296: return 0;
297:
298: while (1) {
299: nd_opt = nd6_option(ndopts);
300: if (!nd_opt && !ndopts->nd_opts_last) {
301: /*
302: * Message validation requires that all included
303: * options have a length that is greater than zero.
304: */
305: icmp6stat.icp6s_nd_badopt++;
306: bzero(ndopts, sizeof(*ndopts));
307: return -1;
308: }
309:
310: if (!nd_opt)
311: goto skip1;
312:
313: switch (nd_opt->nd_opt_type) {
314: case ND_OPT_SOURCE_LINKADDR:
315: case ND_OPT_TARGET_LINKADDR:
316: case ND_OPT_MTU:
317: case ND_OPT_REDIRECTED_HEADER:
318: if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
319: nd6log((LOG_INFO,
320: "duplicated ND6 option found (type=%d)\n",
321: nd_opt->nd_opt_type));
322: /* XXX bark? */
323: } else {
324: ndopts->nd_opt_array[nd_opt->nd_opt_type]
325: = nd_opt;
326: }
327: break;
328: case ND_OPT_PREFIX_INFORMATION:
329: if (ndopts->nd_opt_array[nd_opt->nd_opt_type] == 0) {
330: ndopts->nd_opt_array[nd_opt->nd_opt_type]
331: = nd_opt;
332: }
333: ndopts->nd_opts_pi_end =
334: (struct nd_opt_prefix_info *)nd_opt;
335: break;
336: default:
337: /*
338: * Unknown options must be silently ignored,
339: * to accommodate future extension to the protocol.
340: */
341: nd6log((LOG_DEBUG,
342: "nd6_options: unsupported option %d - "
343: "option ignored\n", nd_opt->nd_opt_type));
344: }
345:
346: skip1:
347: i++;
348: if (i > nd6_maxndopt) {
349: icmp6stat.icp6s_nd_toomanyopt++;
350: nd6log((LOG_INFO, "too many loop in nd opt\n"));
351: break;
352: }
353:
354: if (ndopts->nd_opts_done)
355: break;
356: }
357:
358: return 0;
359: }
360:
361: /*
362: * ND6 timer routine to handle ND6 entries
363: */
364: void
365: nd6_llinfo_settimer(struct llinfo_nd6 *ln, long tick)
366: {
367: int s;
368:
369: s = splsoftnet();
370:
371: if (tick < 0) {
372: ln->ln_expire = 0;
373: ln->ln_ntick = 0;
374: timeout_del(&ln->ln_timer_ch);
375: } else {
376: ln->ln_expire = time_second + tick / hz;
377: if (tick > INT_MAX) {
378: ln->ln_ntick = tick - INT_MAX;
379: timeout_add(&ln->ln_timer_ch, INT_MAX);
380: } else {
381: ln->ln_ntick = 0;
382: timeout_add(&ln->ln_timer_ch, tick);
383: }
384: }
385:
386: splx(s);
387: }
388:
389: static void
390: nd6_llinfo_timer(void *arg)
391: {
392: int s;
393: struct llinfo_nd6 *ln;
394: struct rtentry *rt;
395: struct sockaddr_in6 *dst;
396: struct ifnet *ifp;
397: struct nd_ifinfo *ndi = NULL;
398:
399: s = splsoftnet();
400:
401: ln = (struct llinfo_nd6 *)arg;
402:
403: if (ln->ln_ntick > 0) {
404: if (ln->ln_ntick > INT_MAX) {
405: ln->ln_ntick -= INT_MAX;
406: nd6_llinfo_settimer(ln, INT_MAX);
407: } else {
408: ln->ln_ntick = 0;
409: nd6_llinfo_settimer(ln, ln->ln_ntick);
410: }
411: splx(s);
412: return;
413: }
414:
415: if ((rt = ln->ln_rt) == NULL)
416: panic("ln->ln_rt == NULL");
417: if ((ifp = rt->rt_ifp) == NULL)
418: panic("ln->ln_rt->rt_ifp == NULL");
419: ndi = ND_IFINFO(ifp);
420: dst = (struct sockaddr_in6 *)rt_key(rt);
421:
422: /* sanity check */
423: if (rt->rt_llinfo && (struct llinfo_nd6 *)rt->rt_llinfo != ln)
424: panic("rt_llinfo(%p) is not equal to ln(%p)",
425: rt->rt_llinfo, ln);
426: if (!dst)
427: panic("dst=0 in nd6_timer(ln=%p)", ln);
428:
429: switch (ln->ln_state) {
430: case ND6_LLINFO_INCOMPLETE:
431: if (ln->ln_asked < nd6_mmaxtries) {
432: ln->ln_asked++;
433: nd6_llinfo_settimer(ln, (long)ndi->retrans * hz / 1000);
434: nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
435: } else {
436: struct mbuf *m = ln->ln_hold;
437: if (m) {
438: ln->ln_hold = NULL;
439: /*
440: * Fake rcvif to make the ICMP error
441: * more helpful in diagnosing for the
442: * receiver.
443: * XXX: should we consider
444: * older rcvif?
445: */
446: m->m_pkthdr.rcvif = rt->rt_ifp;
447:
448: icmp6_error(m, ICMP6_DST_UNREACH,
449: ICMP6_DST_UNREACH_ADDR, 0);
450: }
451: (void)nd6_free(rt, 0);
452: ln = NULL;
453: }
454: break;
455: case ND6_LLINFO_REACHABLE:
456: if (!ND6_LLINFO_PERMANENT(ln)) {
457: ln->ln_state = ND6_LLINFO_STALE;
458: nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
459: }
460: break;
461:
462: case ND6_LLINFO_STALE:
463: /* Garbage Collection(RFC 2461 5.3) */
464: if (!ND6_LLINFO_PERMANENT(ln)) {
465: (void)nd6_free(rt, 1);
466: ln = NULL;
467: }
468: break;
469:
470: case ND6_LLINFO_DELAY:
471: if (ndi && (ndi->flags & ND6_IFF_PERFORMNUD) != 0) {
472: /* We need NUD */
473: ln->ln_asked = 1;
474: ln->ln_state = ND6_LLINFO_PROBE;
475: nd6_llinfo_settimer(ln, (long)ndi->retrans * hz / 1000);
476: nd6_ns_output(ifp, &dst->sin6_addr,
477: &dst->sin6_addr, ln, 0);
478: } else {
479: ln->ln_state = ND6_LLINFO_STALE; /* XXX */
480: nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
481: }
482: break;
483: case ND6_LLINFO_PROBE:
484: if (ln->ln_asked < nd6_umaxtries) {
485: ln->ln_asked++;
486: nd6_llinfo_settimer(ln, (long)ndi->retrans * hz / 1000);
487: nd6_ns_output(ifp, &dst->sin6_addr,
488: &dst->sin6_addr, ln, 0);
489: } else {
490: (void)nd6_free(rt, 0);
491: ln = NULL;
492: }
493: break;
494: }
495:
496: splx(s);
497: }
498:
499: /*
500: * ND6 timer routine to expire default route list and prefix list
501: */
502: void
503: nd6_timer(ignored_arg)
504: void *ignored_arg;
505: {
506: int s;
507: struct nd_defrouter *dr;
508: struct nd_prefix *pr;
509: struct in6_ifaddr *ia6, *nia6;
510: struct in6_addrlifetime *lt6;
511:
512: s = splsoftnet();
513: timeout_set(&nd6_timer_ch, nd6_timer, NULL);
514: timeout_add(&nd6_timer_ch, nd6_prune * hz);
515:
516: /* expire default router list */
517: dr = TAILQ_FIRST(&nd_defrouter);
518: while (dr) {
519: if (dr->expire && dr->expire < time_second) {
520: struct nd_defrouter *t;
521: t = TAILQ_NEXT(dr, dr_entry);
522: defrtrlist_del(dr);
523: dr = t;
524: } else {
525: dr = TAILQ_NEXT(dr, dr_entry);
526: }
527: }
528:
529: /*
530: * expire interface addresses.
531: * in the past the loop was inside prefix expiry processing.
532: * However, from a stricter spec-conformance standpoint, we should
533: * rather separate address lifetimes and prefix lifetimes.
534: */
535: for (ia6 = in6_ifaddr; ia6; ia6 = nia6) {
536: nia6 = ia6->ia_next;
537: /* check address lifetime */
538: lt6 = &ia6->ia6_lifetime;
539: if (IFA6_IS_INVALID(ia6)) {
540: in6_purgeaddr(&ia6->ia_ifa);
541: } else if (IFA6_IS_DEPRECATED(ia6)) {
542: ia6->ia6_flags |= IN6_IFF_DEPRECATED;
543: } else {
544: /*
545: * A new RA might have made a deprecated address
546: * preferred.
547: */
548: ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
549: }
550: }
551:
552: /* expire prefix list */
553: pr = LIST_FIRST(&nd_prefix);
554: while (pr != NULL) {
555: /*
556: * check prefix lifetime.
557: * since pltime is just for autoconf, pltime processing for
558: * prefix is not necessary.
559: */
560: if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME &&
561: time_second - pr->ndpr_lastupdate > pr->ndpr_vltime) {
562: struct nd_prefix *t;
563: t = LIST_NEXT(pr, ndpr_entry);
564:
565: /*
566: * address expiration and prefix expiration are
567: * separate. NEVER perform in6_purgeaddr here.
568: */
569:
570: prelist_remove(pr);
571: pr = t;
572: } else
573: pr = LIST_NEXT(pr, ndpr_entry);
574: }
575: splx(s);
576: }
577:
578: /*
579: * Nuke neighbor cache/prefix/default router management table, right before
580: * ifp goes away.
581: */
582: void
583: nd6_purge(ifp)
584: struct ifnet *ifp;
585: {
586: struct llinfo_nd6 *ln, *nln;
587: struct nd_defrouter *dr, *ndr;
588: struct nd_prefix *pr, *npr;
589:
590: /*
591: * Nuke default router list entries toward ifp.
592: * We defer removal of default router list entries that is installed
593: * in the routing table, in order to keep additional side effects as
594: * small as possible.
595: */
596: for (dr = TAILQ_FIRST(&nd_defrouter); dr; dr = ndr) {
597: ndr = TAILQ_NEXT(dr, dr_entry);
598: if (dr->installed)
599: continue;
600:
601: if (dr->ifp == ifp)
602: defrtrlist_del(dr);
603: }
604: for (dr = TAILQ_FIRST(&nd_defrouter); dr; dr = ndr) {
605: ndr = TAILQ_NEXT(dr, dr_entry);
606: if (!dr->installed)
607: continue;
608:
609: if (dr->ifp == ifp)
610: defrtrlist_del(dr);
611: }
612:
613: /* Nuke prefix list entries toward ifp */
614: for (pr = LIST_FIRST(&nd_prefix); pr != NULL; pr = npr) {
615: npr = LIST_NEXT(pr, ndpr_entry);
616: if (pr->ndpr_ifp == ifp) {
617: /*
618: * Because if_detach() does *not* release prefixes
619: * while purging addresses the reference count will
620: * still be above zero. We therefore reset it to
621: * make sure that the prefix really gets purged.
622: */
623: pr->ndpr_refcnt = 0;
624: /*
625: * Previously, pr->ndpr_addr is removed as well,
626: * but I strongly believe we don't have to do it.
627: * nd6_purge() is only called from in6_ifdetach(),
628: * which removes all the associated interface addresses
629: * by itself.
630: * (jinmei@kame.net 20010129)
631: */
632: prelist_remove(pr);
633: }
634: }
635:
636: /* cancel default outgoing interface setting */
637: if (nd6_defifindex == ifp->if_index)
638: nd6_setdefaultiface(0);
639:
640: if (!ip6_forwarding && ip6_accept_rtadv) { /* XXX: too restrictive? */
641: /* refresh default router list */
642: defrouter_select();
643: }
644:
645: /*
646: * Nuke neighbor cache entries for the ifp.
647: * Note that rt->rt_ifp may not be the same as ifp,
648: * due to KAME goto ours hack. See RTM_RESOLVE case in
649: * nd6_rtrequest(), and ip6_input().
650: */
651: ln = llinfo_nd6.ln_next;
652: while (ln && ln != &llinfo_nd6) {
653: struct rtentry *rt;
654: struct sockaddr_dl *sdl;
655:
656: nln = ln->ln_next;
657: rt = ln->ln_rt;
658: if (rt && rt->rt_gateway &&
659: rt->rt_gateway->sa_family == AF_LINK) {
660: sdl = (struct sockaddr_dl *)rt->rt_gateway;
661: if (sdl->sdl_index == ifp->if_index)
662: nln = nd6_free(rt, 0);
663: }
664: ln = nln;
665: }
666: }
667:
668: struct rtentry *
669: nd6_lookup(addr6, create, ifp)
670: struct in6_addr *addr6;
671: int create;
672: struct ifnet *ifp;
673: {
674: struct rtentry *rt;
675: struct sockaddr_in6 sin6;
676:
677: bzero(&sin6, sizeof(sin6));
678: sin6.sin6_len = sizeof(struct sockaddr_in6);
679: sin6.sin6_family = AF_INET6;
680: sin6.sin6_addr = *addr6;
681:
682: rt = rtalloc1((struct sockaddr *)&sin6, create, 0);
683: if (rt && (rt->rt_flags & RTF_LLINFO) == 0) {
684: /*
685: * This is the case for the default route.
686: * If we want to create a neighbor cache for the address, we
687: * should free the route for the destination and allocate an
688: * interface route.
689: */
690: if (create) {
691: RTFREE(rt);
692: rt = 0;
693: }
694: }
695: if (!rt) {
696: if (create && ifp) {
697: int e;
698:
699: /*
700: * If no route is available and create is set,
701: * we allocate a host route for the destination
702: * and treat it like an interface route.
703: * This hack is necessary for a neighbor which can't
704: * be covered by our own prefix.
705: */
706: struct ifaddr *ifa =
707: ifaof_ifpforaddr((struct sockaddr *)&sin6, ifp);
708: if (ifa == NULL)
709: return (NULL);
710:
711: /*
712: * Create a new route. RTF_LLINFO is necessary
713: * to create a Neighbor Cache entry for the
714: * destination in nd6_rtrequest which will be
715: * called in rtrequest via ifa->ifa_rtrequest.
716: */
717: if ((e = rtrequest(RTM_ADD, (struct sockaddr *)&sin6,
718: ifa->ifa_addr, (struct sockaddr *)&all1_sa,
719: (ifa->ifa_flags | RTF_HOST | RTF_LLINFO) &
720: ~RTF_CLONING, &rt, 0)) != 0) {
721: #if 0
722: log(LOG_ERR,
723: "nd6_lookup: failed to add route for a "
724: "neighbor(%s), errno=%d\n",
725: ip6_sprintf(addr6), e);
726: #endif
727: return (NULL);
728: }
729: if (rt == NULL)
730: return (NULL);
731: if (rt->rt_llinfo) {
732: struct llinfo_nd6 *ln =
733: (struct llinfo_nd6 *)rt->rt_llinfo;
734: ln->ln_state = ND6_LLINFO_NOSTATE;
735: }
736: } else
737: return (NULL);
738: }
739: rt->rt_refcnt--;
740: /*
741: * Validation for the entry.
742: * Note that the check for rt_llinfo is necessary because a cloned
743: * route from a parent route that has the L flag (e.g. the default
744: * route to a p2p interface) may have the flag, too, while the
745: * destination is not actually a neighbor.
746: * XXX: we can't use rt->rt_ifp to check for the interface, since
747: * it might be the loopback interface if the entry is for our
748: * own address on a non-loopback interface. Instead, we should
749: * use rt->rt_ifa->ifa_ifp, which would specify the REAL
750: * interface.
751: */
752: if ((rt->rt_flags & RTF_GATEWAY) || (rt->rt_flags & RTF_LLINFO) == 0 ||
753: rt->rt_gateway->sa_family != AF_LINK || rt->rt_llinfo == NULL ||
754: (ifp && rt->rt_ifa->ifa_ifp != ifp)) {
755: if (create) {
756: nd6log((LOG_DEBUG,
757: "nd6_lookup: failed to lookup %s (if = %s)\n",
758: ip6_sprintf(addr6),
759: ifp ? ifp->if_xname : "unspec"));
760: }
761: return (NULL);
762: }
763: return (rt);
764: }
765:
766: /*
767: * Detect if a given IPv6 address identifies a neighbor on a given link.
768: * XXX: should take care of the destination of a p2p link?
769: */
770: int
771: nd6_is_addr_neighbor(addr, ifp)
772: struct sockaddr_in6 *addr;
773: struct ifnet *ifp;
774: {
775: struct nd_prefix *pr;
776: struct rtentry *rt;
777:
778: /*
779: * A link-local address is always a neighbor.
780: * XXX: we should use the sin6_scope_id field rather than the embedded
781: * interface index.
782: * XXX: a link does not necessarily specify a single interface.
783: */
784: if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) &&
785: ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]) == ifp->if_index)
786: return (1);
787:
788: /*
789: * If the address matches one of our on-link prefixes, it should be a
790: * neighbor.
791: */
792: LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
793: if (pr->ndpr_ifp != ifp)
794: continue;
795:
796: if (!(pr->ndpr_stateflags & NDPRF_ONLINK))
797: continue;
798:
799: if (IN6_ARE_MASKED_ADDR_EQUAL(&pr->ndpr_prefix.sin6_addr,
800: &addr->sin6_addr, &pr->ndpr_mask))
801: return (1);
802: }
803:
804: /*
805: * If the default router list is empty, all addresses are regarded
806: * as on-link, and thus, as a neighbor.
807: * XXX: we restrict the condition to hosts, because routers usually do
808: * not have the "default router list".
809: */
810: if (!ip6_forwarding && TAILQ_FIRST(&nd_defrouter) == NULL &&
811: nd6_defifindex == ifp->if_index) {
812: return (1);
813: }
814:
815: /*
816: * Even if the address matches none of our addresses, it might be
817: * in the neighbor cache.
818: */
819: if ((rt = nd6_lookup(&addr->sin6_addr, 0, ifp)) != NULL)
820: return (1);
821:
822: return (0);
823: }
824:
825: /*
826: * Free an nd6 llinfo entry.
827: * Since the function would cause significant changes in the kernel, DO NOT
828: * make it global, unless you have a strong reason for the change, and are sure
829: * that the change is safe.
830: */
831: static struct llinfo_nd6 *
832: nd6_free(rt, gc)
833: struct rtentry *rt;
834: int gc;
835: {
836: struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo, *next;
837: struct in6_addr in6 = ((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
838: struct nd_defrouter *dr;
839:
840: /*
841: * we used to have pfctlinput(PRC_HOSTDEAD) here.
842: * even though it is not harmful, it was not really necessary.
843: */
844:
845: if (!ip6_forwarding) {
846: int s;
847: s = splsoftnet();
848: dr = defrouter_lookup(&((struct sockaddr_in6 *)rt_key(rt))->sin6_addr,
849: rt->rt_ifp);
850:
851: if (dr != NULL && dr->expire &&
852: ln->ln_state == ND6_LLINFO_STALE && gc) {
853: /*
854: * If the reason for the deletion is just garbage
855: * collection, and the neighbor is an active default
856: * router, do not delete it. Instead, reset the GC
857: * timer using the router's lifetime.
858: * Simply deleting the entry would affect default
859: * router selection, which is not necessarily a good
860: * thing, especially when we're using router preference
861: * values.
862: * XXX: the check for ln_state would be redundant,
863: * but we intentionally keep it just in case.
864: */
865: if (dr->expire > time_second * hz) {
866: nd6_llinfo_settimer(ln,
867: dr->expire - time_second * hz);
868: } else
869: nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
870: splx(s);
871: return (ln->ln_next);
872: }
873:
874: if (ln->ln_router || dr) {
875: /*
876: * rt6_flush must be called whether or not the neighbor
877: * is in the Default Router List.
878: * See a corresponding comment in nd6_na_input().
879: */
880: rt6_flush(&in6, rt->rt_ifp);
881: }
882:
883: if (dr) {
884: /*
885: * Unreachability of a router might affect the default
886: * router selection and on-link detection of advertised
887: * prefixes.
888: */
889:
890: /*
891: * Temporarily fake the state to choose a new default
892: * router and to perform on-link determination of
893: * prefixes correctly.
894: * Below the state will be set correctly,
895: * or the entry itself will be deleted.
896: */
897: ln->ln_state = ND6_LLINFO_INCOMPLETE;
898:
899: /*
900: * Since defrouter_select() does not affect the
901: * on-link determination and MIP6 needs the check
902: * before the default router selection, we perform
903: * the check now.
904: */
905: pfxlist_onlink_check();
906:
907: /*
908: * refresh default router list
909: */
910: defrouter_select();
911: }
912: splx(s);
913: }
914:
915: /*
916: * Before deleting the entry, remember the next entry as the
917: * return value. We need this because pfxlist_onlink_check() above
918: * might have freed other entries (particularly the old next entry) as
919: * a side effect (XXX).
920: */
921: next = ln->ln_next;
922:
923: /*
924: * Detach the route from the routing tree and the list of neighbor
925: * caches, and disable the route entry not to be used in already
926: * cached routes.
927: */
928: rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
929: rt_mask(rt), 0, (struct rtentry **)0, 0);
930:
931: return (next);
932: }
933:
934: /*
935: * Upper-layer reachability hint for Neighbor Unreachability Detection.
936: *
937: * XXX cost-effective methods?
938: */
939: void
940: nd6_nud_hint(rt, dst6, force)
941: struct rtentry *rt;
942: struct in6_addr *dst6;
943: int force;
944: {
945: struct llinfo_nd6 *ln;
946:
947: /*
948: * If the caller specified "rt", use that. Otherwise, resolve the
949: * routing table by supplied "dst6".
950: */
951: if (!rt) {
952: if (!dst6)
953: return;
954: if (!(rt = nd6_lookup(dst6, 0, NULL)))
955: return;
956: }
957:
958: if ((rt->rt_flags & RTF_GATEWAY) != 0 ||
959: (rt->rt_flags & RTF_LLINFO) == 0 ||
960: !rt->rt_llinfo || !rt->rt_gateway ||
961: rt->rt_gateway->sa_family != AF_LINK) {
962: /* This is not a host route. */
963: return;
964: }
965:
966: ln = (struct llinfo_nd6 *)rt->rt_llinfo;
967: if (ln->ln_state < ND6_LLINFO_REACHABLE)
968: return;
969:
970: /*
971: * if we get upper-layer reachability confirmation many times,
972: * it is possible we have false information.
973: */
974: if (!force) {
975: ln->ln_byhint++;
976: if (ln->ln_byhint > nd6_maxnudhint)
977: return;
978: }
979:
980: ln->ln_state = ND6_LLINFO_REACHABLE;
981: if (!ND6_LLINFO_PERMANENT(ln)) {
982: nd6_llinfo_settimer(ln,
983: (long)ND_IFINFO(rt->rt_ifp)->reachable * hz);
984: }
985: }
986:
987: void
988: nd6_rtrequest(req, rt, info)
989: int req;
990: struct rtentry *rt;
991: struct rt_addrinfo *info; /* xxx unused */
992: {
993: struct sockaddr *gate = rt->rt_gateway;
994: struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
995: static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
996: struct ifnet *ifp = rt->rt_ifp;
997: struct ifaddr *ifa;
998: int mine = 0;
999:
1000: if ((rt->rt_flags & RTF_GATEWAY) != 0)
1001: return;
1002:
1003: if (nd6_need_cache(ifp) == 0 && (rt->rt_flags & RTF_HOST) == 0) {
1004: /*
1005: * This is probably an interface direct route for a link
1006: * which does not need neighbor caches (e.g. fe80::%lo0/64).
1007: * We do not need special treatment below for such a route.
1008: * Moreover, the RTF_LLINFO flag which would be set below
1009: * would annoy the ndp(8) command.
1010: */
1011: return;
1012: }
1013:
1014: if (req == RTM_RESOLVE &&
1015: (nd6_need_cache(ifp) == 0 || /* stf case */
1016: !nd6_is_addr_neighbor((struct sockaddr_in6 *)rt_key(rt), ifp))) {
1017: /*
1018: * FreeBSD and BSD/OS often make a cloned host route based
1019: * on a less-specific route (e.g. the default route).
1020: * If the less specific route does not have a "gateway"
1021: * (this is the case when the route just goes to a p2p or an
1022: * stf interface), we'll mistakenly make a neighbor cache for
1023: * the host route, and will see strange neighbor solicitation
1024: * for the corresponding destination. In order to avoid the
1025: * confusion, we check if the destination of the route is
1026: * a neighbor in terms of neighbor discovery, and stop the
1027: * process if not. Additionally, we remove the LLINFO flag
1028: * so that ndp(8) will not try to get the neighbor information
1029: * of the destination.
1030: */
1031: rt->rt_flags &= ~RTF_LLINFO;
1032: return;
1033: }
1034:
1035: switch (req) {
1036: case RTM_ADD:
1037: /*
1038: * There is no backward compatibility :)
1039: *
1040: * if ((rt->rt_flags & RTF_HOST) == 0 &&
1041: * SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff)
1042: * rt->rt_flags |= RTF_CLONING;
1043: */
1044: if ((rt->rt_flags & RTF_CLONING) ||
1045: ((rt->rt_flags & RTF_LLINFO) && !ln)) {
1046: /*
1047: * Case 1: This route should come from a route to
1048: * interface (RTF_CLONING case) or the route should be
1049: * treated as on-link but is currently not
1050: * (RTF_LLINFO && !ln case).
1051: */
1052: rt_setgate(rt, rt_key(rt),
1053: (struct sockaddr *)&null_sdl, 0);
1054: gate = rt->rt_gateway;
1055: SDL(gate)->sdl_type = ifp->if_type;
1056: SDL(gate)->sdl_index = ifp->if_index;
1057: if (ln)
1058: nd6_llinfo_settimer(ln, 0);
1059: if ((rt->rt_flags & RTF_CLONING) != 0)
1060: break;
1061: }
1062: /*
1063: * In IPv4 code, we try to announce new RTF_ANNOUNCE entry here.
1064: * We don't do that here since llinfo is not ready yet.
1065: *
1066: * There are also couple of other things to be discussed:
1067: * - unsolicited NA code needs improvement beforehand
1068: * - RFC2461 says we MAY send multicast unsolicited NA
1069: * (7.2.6 paragraph 4), however, it also says that we
1070: * SHOULD provide a mechanism to prevent multicast NA storm.
1071: * we don't have anything like it right now.
1072: * note that the mechanism needs a mutual agreement
1073: * between proxies, which means that we need to implement
1074: * a new protocol, or a new kludge.
1075: * - from RFC2461 6.2.4, host MUST NOT send an unsolicited NA.
1076: * we need to check ip6forwarding before sending it.
1077: * (or should we allow proxy ND configuration only for
1078: * routers? there's no mention about proxy ND from hosts)
1079: */
1080: #if 0
1081: /* XXX it does not work */
1082: if (rt->rt_flags & RTF_ANNOUNCE)
1083: nd6_na_output(ifp,
1084: &SIN6(rt_key(rt))->sin6_addr,
1085: &SIN6(rt_key(rt))->sin6_addr,
1086: ip6_forwarding ? ND_NA_FLAG_ROUTER : 0,
1087: 1, NULL);
1088: #endif
1089: /* FALLTHROUGH */
1090: case RTM_RESOLVE:
1091: if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) == 0) {
1092: /*
1093: * Address resolution isn't necessary for a point to
1094: * point link, so we can skip this test for a p2p link.
1095: */
1096: if (gate->sa_family != AF_LINK ||
1097: gate->sa_len < sizeof(null_sdl)) {
1098: log(LOG_DEBUG,
1099: "nd6_rtrequest: bad gateway value: %s\n",
1100: ifp->if_xname);
1101: break;
1102: }
1103: SDL(gate)->sdl_type = ifp->if_type;
1104: SDL(gate)->sdl_index = ifp->if_index;
1105: }
1106: if (ln != NULL)
1107: break; /* This happens on a route change */
1108: /*
1109: * Case 2: This route may come from cloning, or a manual route
1110: * add with a LL address.
1111: */
1112: R_Malloc(ln, struct llinfo_nd6 *, sizeof(*ln));
1113: rt->rt_llinfo = (caddr_t)ln;
1114: if (!ln) {
1115: log(LOG_DEBUG, "nd6_rtrequest: malloc failed\n");
1116: break;
1117: }
1118: nd6_inuse++;
1119: nd6_allocated++;
1120: Bzero(ln, sizeof(*ln));
1121: ln->ln_rt = rt;
1122: timeout_set(&ln->ln_timer_ch, nd6_llinfo_timer, ln);
1123: /* this is required for "ndp" command. - shin */
1124: if (req == RTM_ADD) {
1125: /*
1126: * gate should have some valid AF_LINK entry,
1127: * and ln->ln_expire should have some lifetime
1128: * which is specified by ndp command.
1129: */
1130: ln->ln_state = ND6_LLINFO_REACHABLE;
1131: ln->ln_byhint = 0;
1132: } else {
1133: /*
1134: * When req == RTM_RESOLVE, rt is created and
1135: * initialized in rtrequest(), so rt_expire is 0.
1136: */
1137: ln->ln_state = ND6_LLINFO_NOSTATE;
1138: nd6_llinfo_settimer(ln, 0);
1139: }
1140: rt->rt_flags |= RTF_LLINFO;
1141: ln->ln_next = llinfo_nd6.ln_next;
1142: llinfo_nd6.ln_next = ln;
1143: ln->ln_prev = &llinfo_nd6;
1144: ln->ln_next->ln_prev = ln;
1145:
1146: /*
1147: * check if rt_key(rt) is one of my address assigned
1148: * to the interface.
1149: */
1150: ifa = (struct ifaddr *)in6ifa_ifpwithaddr(rt->rt_ifp,
1151: &SIN6(rt_key(rt))->sin6_addr);
1152: if (ifa) {
1153: caddr_t macp = nd6_ifptomac(ifp);
1154: nd6_llinfo_settimer(ln, -1);
1155: ln->ln_state = ND6_LLINFO_REACHABLE;
1156: ln->ln_byhint = 0;
1157: mine = 1;
1158: if (macp) {
1159: Bcopy(macp, LLADDR(SDL(gate)), ifp->if_addrlen);
1160: SDL(gate)->sdl_alen = ifp->if_addrlen;
1161: }
1162: if (nd6_useloopback) {
1163: rt->rt_ifp = lo0ifp; /*XXX*/
1164: /*
1165: * Make sure rt_ifa be equal to the ifaddr
1166: * corresponding to the address.
1167: * We need this because when we refer
1168: * rt_ifa->ia6_flags in ip6_input, we assume
1169: * that the rt_ifa points to the address instead
1170: * of the loopback address.
1171: */
1172: if (ifa != rt->rt_ifa) {
1173: IFAFREE(rt->rt_ifa);
1174: ifa->ifa_refcnt++;
1175: rt->rt_ifa = ifa;
1176: }
1177: }
1178: } else if (rt->rt_flags & RTF_ANNOUNCE) {
1179: nd6_llinfo_settimer(ln, -1);
1180: ln->ln_state = ND6_LLINFO_REACHABLE;
1181: ln->ln_byhint = 0;
1182:
1183: /* join solicited node multicast for proxy ND */
1184: if (ifp->if_flags & IFF_MULTICAST) {
1185: struct in6_addr llsol;
1186: int error;
1187:
1188: llsol = SIN6(rt_key(rt))->sin6_addr;
1189: llsol.s6_addr16[0] = htons(0xff02);
1190: llsol.s6_addr16[1] = htons(ifp->if_index);
1191: llsol.s6_addr32[1] = 0;
1192: llsol.s6_addr32[2] = htonl(1);
1193: llsol.s6_addr8[12] = 0xff;
1194:
1195: if (in6_addmulti(&llsol, ifp, &error)) {
1196: nd6log((LOG_ERR, "%s: failed to join "
1197: "%s (errno=%d)\n", ifp->if_xname,
1198: ip6_sprintf(&llsol), error));
1199: }
1200: }
1201: }
1202: break;
1203:
1204: case RTM_DELETE:
1205: if (!ln)
1206: break;
1207: /* leave from solicited node multicast for proxy ND */
1208: if ((rt->rt_flags & RTF_ANNOUNCE) != 0 &&
1209: (ifp->if_flags & IFF_MULTICAST) != 0) {
1210: struct in6_addr llsol;
1211: struct in6_multi *in6m;
1212:
1213: llsol = SIN6(rt_key(rt))->sin6_addr;
1214: llsol.s6_addr16[0] = htons(0xff02);
1215: llsol.s6_addr16[1] = htons(ifp->if_index);
1216: llsol.s6_addr32[1] = 0;
1217: llsol.s6_addr32[2] = htonl(1);
1218: llsol.s6_addr8[12] = 0xff;
1219:
1220: IN6_LOOKUP_MULTI(llsol, ifp, in6m);
1221: if (in6m)
1222: in6_delmulti(in6m);
1223: }
1224: nd6_inuse--;
1225: ln->ln_next->ln_prev = ln->ln_prev;
1226: ln->ln_prev->ln_next = ln->ln_next;
1227: ln->ln_prev = NULL;
1228: nd6_llinfo_settimer(ln, -1);
1229: rt->rt_llinfo = 0;
1230: rt->rt_flags &= ~RTF_LLINFO;
1231: if (ln->ln_hold)
1232: m_freem(ln->ln_hold);
1233: Free((caddr_t)ln);
1234: }
1235: }
1236:
1237: int
1238: nd6_ioctl(cmd, data, ifp)
1239: u_long cmd;
1240: caddr_t data;
1241: struct ifnet *ifp;
1242: {
1243: struct in6_drlist *drl = (struct in6_drlist *)data;
1244: struct in6_oprlist *oprl = (struct in6_oprlist *)data;
1245: struct in6_ndireq *ndi = (struct in6_ndireq *)data;
1246: struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
1247: struct in6_ndifreq *ndif = (struct in6_ndifreq *)data;
1248: struct nd_defrouter *dr;
1249: struct nd_prefix *pr;
1250: struct rtentry *rt;
1251: int i = 0, error = 0;
1252: int s;
1253:
1254: switch (cmd) {
1255: case SIOCGDRLST_IN6:
1256: /*
1257: * obsolete API, use sysctl under net.inet6.icmp6
1258: */
1259: bzero(drl, sizeof(*drl));
1260: s = splsoftnet();
1261: dr = TAILQ_FIRST(&nd_defrouter);
1262: while (dr && i < DRLSTSIZ) {
1263: drl->defrouter[i].rtaddr = dr->rtaddr;
1264: if (IN6_IS_ADDR_LINKLOCAL(&drl->defrouter[i].rtaddr)) {
1265: /* XXX: need to this hack for KAME stack */
1266: drl->defrouter[i].rtaddr.s6_addr16[1] = 0;
1267: } else
1268: log(LOG_ERR,
1269: "default router list contains a "
1270: "non-linklocal address(%s)\n",
1271: ip6_sprintf(&drl->defrouter[i].rtaddr));
1272:
1273: drl->defrouter[i].flags = dr->flags;
1274: drl->defrouter[i].rtlifetime = dr->rtlifetime;
1275: drl->defrouter[i].expire = dr->expire;
1276: drl->defrouter[i].if_index = dr->ifp->if_index;
1277: i++;
1278: dr = TAILQ_NEXT(dr, dr_entry);
1279: }
1280: splx(s);
1281: break;
1282: case SIOCGPRLST_IN6:
1283: /*
1284: * obsolete API, use sysctl under net.inet6.icmp6
1285: *
1286: * XXX the structure in6_prlist was changed in backward-
1287: * incompatible manner. in6_oprlist is used for SIOCGPRLST_IN6,
1288: * in6_prlist is used for nd6_sysctl() - fill_prlist().
1289: */
1290: /*
1291: * XXX meaning of fields, especially "raflags", is very
1292: * different between RA prefix list and RR/static prefix list.
1293: * how about separating ioctls into two?
1294: */
1295: bzero(oprl, sizeof(*oprl));
1296: s = splsoftnet();
1297: pr = LIST_FIRST(&nd_prefix);
1298: while (pr && i < PRLSTSIZ) {
1299: struct nd_pfxrouter *pfr;
1300: int j;
1301:
1302: oprl->prefix[i].prefix = pr->ndpr_prefix.sin6_addr;
1303: oprl->prefix[i].raflags = pr->ndpr_raf;
1304: oprl->prefix[i].prefixlen = pr->ndpr_plen;
1305: oprl->prefix[i].vltime = pr->ndpr_vltime;
1306: oprl->prefix[i].pltime = pr->ndpr_pltime;
1307: oprl->prefix[i].if_index = pr->ndpr_ifp->if_index;
1308: oprl->prefix[i].expire = pr->ndpr_expire;
1309:
1310: pfr = LIST_FIRST(&pr->ndpr_advrtrs);
1311: j = 0;
1312: while(pfr) {
1313: if (j < DRLSTSIZ) {
1314: #define RTRADDR oprl->prefix[i].advrtr[j]
1315: RTRADDR = pfr->router->rtaddr;
1316: if (IN6_IS_ADDR_LINKLOCAL(&RTRADDR)) {
1317: /* XXX: hack for KAME */
1318: RTRADDR.s6_addr16[1] = 0;
1319: } else
1320: log(LOG_ERR,
1321: "a router(%s) advertises "
1322: "a prefix with "
1323: "non-link local address\n",
1324: ip6_sprintf(&RTRADDR));
1325: #undef RTRADDR
1326: }
1327: j++;
1328: pfr = LIST_NEXT(pfr, pfr_entry);
1329: }
1330: oprl->prefix[i].advrtrs = j;
1331: oprl->prefix[i].origin = PR_ORIG_RA;
1332:
1333: i++;
1334: pr = LIST_NEXT(pr, ndpr_entry);
1335: }
1336: splx(s);
1337:
1338: break;
1339: case OSIOCGIFINFO_IN6:
1340: /* XXX: old ndp(8) assumes a positive value for linkmtu. */
1341: bzero(&ndi->ndi, sizeof(ndi->ndi));
1342: ndi->ndi.linkmtu = IN6_LINKMTU(ifp);
1343: ndi->ndi.maxmtu = ND_IFINFO(ifp)->maxmtu;
1344: ndi->ndi.basereachable = ND_IFINFO(ifp)->basereachable;
1345: ndi->ndi.reachable = ND_IFINFO(ifp)->reachable;
1346: ndi->ndi.retrans = ND_IFINFO(ifp)->retrans;
1347: ndi->ndi.flags = ND_IFINFO(ifp)->flags;
1348: ndi->ndi.recalctm = ND_IFINFO(ifp)->recalctm;
1349: ndi->ndi.chlim = ND_IFINFO(ifp)->chlim;
1350: break;
1351: case SIOCGIFINFO_IN6:
1352: ndi->ndi = *ND_IFINFO(ifp);
1353: break;
1354: case SIOCSIFINFO_FLAGS:
1355: ND_IFINFO(ifp)->flags = ndi->ndi.flags;
1356: break;
1357: case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */
1358: /* sync kernel routing table with the default router list */
1359: defrouter_reset();
1360: defrouter_select();
1361: break;
1362: case SIOCSPFXFLUSH_IN6:
1363: {
1364: /* flush all the prefix advertised by routers */
1365: struct nd_prefix *pr, *next;
1366:
1367: s = splsoftnet();
1368: for (pr = LIST_FIRST(&nd_prefix); pr; pr = next) {
1369: struct in6_ifaddr *ia, *ia_next;
1370:
1371: next = LIST_NEXT(pr, ndpr_entry);
1372:
1373: if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1374: continue; /* XXX */
1375:
1376: /* do we really have to remove addresses as well? */
1377: for (ia = in6_ifaddr; ia; ia = ia_next) {
1378: /* ia might be removed. keep the next ptr. */
1379: ia_next = ia->ia_next;
1380:
1381: if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 0)
1382: continue;
1383:
1384: if (ia->ia6_ndpr == pr)
1385: in6_purgeaddr(&ia->ia_ifa);
1386: }
1387: prelist_remove(pr);
1388: }
1389: splx(s);
1390: break;
1391: }
1392: case SIOCSRTRFLUSH_IN6:
1393: {
1394: /* flush all the default routers */
1395: struct nd_defrouter *dr, *next;
1396:
1397: s = splsoftnet();
1398: defrouter_reset();
1399: for (dr = TAILQ_FIRST(&nd_defrouter); dr; dr = next) {
1400: next = TAILQ_NEXT(dr, dr_entry);
1401: defrtrlist_del(dr);
1402: }
1403: defrouter_select();
1404: splx(s);
1405: break;
1406: }
1407: case SIOCGNBRINFO_IN6:
1408: {
1409: struct llinfo_nd6 *ln;
1410: struct in6_addr nb_addr = nbi->addr; /* make local for safety */
1411:
1412: /*
1413: * XXX: KAME specific hack for scoped addresses
1414: * XXXX: for other scopes than link-local?
1415: */
1416: if (IN6_IS_ADDR_LINKLOCAL(&nbi->addr) ||
1417: IN6_IS_ADDR_MC_LINKLOCAL(&nbi->addr)) {
1418: u_int16_t *idp = (u_int16_t *)&nb_addr.s6_addr[2];
1419:
1420: if (*idp == 0)
1421: *idp = htons(ifp->if_index);
1422: }
1423:
1424: s = splsoftnet();
1425: if ((rt = nd6_lookup(&nb_addr, 0, ifp)) == NULL ||
1426: (ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) {
1427: error = EINVAL;
1428: splx(s);
1429: break;
1430: }
1431: nbi->state = ln->ln_state;
1432: nbi->asked = ln->ln_asked;
1433: nbi->isrouter = ln->ln_router;
1434: nbi->expire = ln->ln_expire;
1435: splx(s);
1436:
1437: break;
1438: }
1439: case SIOCGDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */
1440: ndif->ifindex = nd6_defifindex;
1441: break;
1442: case SIOCSDEFIFACE_IN6: /* XXX: should be implemented as a sysctl? */
1443: return (nd6_setdefaultiface(ndif->ifindex));
1444: break;
1445: }
1446: return (error);
1447: }
1448:
1449: /*
1450: * Create neighbor cache entry and cache link-layer address,
1451: * on reception of inbound ND6 packets. (RS/RA/NS/redirect)
1452: */
1453: struct rtentry *
1454: nd6_cache_lladdr(ifp, from, lladdr, lladdrlen, type, code)
1455: struct ifnet *ifp;
1456: struct in6_addr *from;
1457: char *lladdr;
1458: int lladdrlen;
1459: int type; /* ICMP6 type */
1460: int code; /* type dependent information */
1461: {
1462: struct rtentry *rt = NULL;
1463: struct llinfo_nd6 *ln = NULL;
1464: int is_newentry;
1465: struct sockaddr_dl *sdl = NULL;
1466: int do_update;
1467: int olladdr;
1468: int llchange;
1469: int newstate = 0;
1470:
1471: if (!ifp)
1472: panic("ifp == NULL in nd6_cache_lladdr");
1473: if (!from)
1474: panic("from == NULL in nd6_cache_lladdr");
1475:
1476: /* nothing must be updated for unspecified address */
1477: if (IN6_IS_ADDR_UNSPECIFIED(from))
1478: return NULL;
1479:
1480: /*
1481: * Validation about ifp->if_addrlen and lladdrlen must be done in
1482: * the caller.
1483: *
1484: * XXX If the link does not have link-layer address, what should
1485: * we do? (ifp->if_addrlen == 0)
1486: * Spec says nothing in sections for RA, RS and NA. There's small
1487: * description on it in NS section (RFC 2461 7.2.3).
1488: */
1489:
1490: rt = nd6_lookup(from, 0, ifp);
1491: if (!rt) {
1492: #if 0
1493: /* nothing must be done if there's no lladdr */
1494: if (!lladdr || !lladdrlen)
1495: return NULL;
1496: #endif
1497:
1498: rt = nd6_lookup(from, 1, ifp);
1499: is_newentry = 1;
1500: } else {
1501: /* do nothing if static ndp is set */
1502: if (rt->rt_flags & RTF_STATIC)
1503: return NULL;
1504: is_newentry = 0;
1505: }
1506:
1507: if (!rt)
1508: return NULL;
1509: if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
1510: fail:
1511: (void)nd6_free(rt, 0);
1512: return NULL;
1513: }
1514: ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1515: if (!ln)
1516: goto fail;
1517: if (!rt->rt_gateway)
1518: goto fail;
1519: if (rt->rt_gateway->sa_family != AF_LINK)
1520: goto fail;
1521: sdl = SDL(rt->rt_gateway);
1522:
1523: olladdr = (sdl->sdl_alen) ? 1 : 0;
1524: if (olladdr && lladdr) {
1525: if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
1526: llchange = 1;
1527: else
1528: llchange = 0;
1529: } else
1530: llchange = 0;
1531:
1532: /*
1533: * newentry olladdr lladdr llchange (*=record)
1534: * 0 n n -- (1)
1535: * 0 y n -- (2)
1536: * 0 n y -- (3) * STALE
1537: * 0 y y n (4) *
1538: * 0 y y y (5) * STALE
1539: * 1 -- n -- (6) NOSTATE(= PASSIVE)
1540: * 1 -- y -- (7) * STALE
1541: */
1542:
1543: if (lladdr) { /* (3-5) and (7) */
1544: /*
1545: * Record source link-layer address
1546: * XXX is it dependent to ifp->if_type?
1547: */
1548: sdl->sdl_alen = ifp->if_addrlen;
1549: bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
1550: }
1551:
1552: if (!is_newentry) {
1553: if ((!olladdr && lladdr) || /* (3) */
1554: (olladdr && lladdr && llchange)) { /* (5) */
1555: do_update = 1;
1556: newstate = ND6_LLINFO_STALE;
1557: } else /* (1-2,4) */
1558: do_update = 0;
1559: } else {
1560: do_update = 1;
1561: if (!lladdr) /* (6) */
1562: newstate = ND6_LLINFO_NOSTATE;
1563: else /* (7) */
1564: newstate = ND6_LLINFO_STALE;
1565: }
1566:
1567: if (do_update) {
1568: /*
1569: * Update the state of the neighbor cache.
1570: */
1571: ln->ln_state = newstate;
1572:
1573: if (ln->ln_state == ND6_LLINFO_STALE) {
1574: /*
1575: * XXX: since nd6_output() below will cause
1576: * state transition to DELAY and reset the timer,
1577: * we must set the timer now, although it is actually
1578: * meaningless.
1579: */
1580: nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
1581:
1582: if (ln->ln_hold) {
1583: /*
1584: * we assume ifp is not a p2p here, so just
1585: * set the 2nd argument as the 1st one.
1586: */
1587: nd6_output(ifp, ifp, ln->ln_hold,
1588: (struct sockaddr_in6 *)rt_key(rt), rt);
1589: ln->ln_hold = NULL;
1590: }
1591: } else if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
1592: /* probe right away */
1593: nd6_llinfo_settimer((void *)ln, 0);
1594: }
1595: }
1596:
1597: /*
1598: * ICMP6 type dependent behavior.
1599: *
1600: * NS: clear IsRouter if new entry
1601: * RS: clear IsRouter
1602: * RA: set IsRouter if there's lladdr
1603: * redir: clear IsRouter if new entry
1604: *
1605: * RA case, (1):
1606: * The spec says that we must set IsRouter in the following cases:
1607: * - If lladdr exist, set IsRouter. This means (1-5).
1608: * - If it is old entry (!newentry), set IsRouter. This means (7).
1609: * So, based on the spec, in (1-5) and (7) cases we must set IsRouter.
1610: * A question arises for (1) case. (1) case has no lladdr in the
1611: * neighbor cache, this is similar to (6).
1612: * This case is rare but we figured that we MUST NOT set IsRouter.
1613: *
1614: * newentry olladdr lladdr llchange NS RS RA redir
1615: * D R
1616: * 0 n n -- (1) c ? s
1617: * 0 y n -- (2) c s s
1618: * 0 n y -- (3) c s s
1619: * 0 y y n (4) c s s
1620: * 0 y y y (5) c s s
1621: * 1 -- n -- (6) c c c s
1622: * 1 -- y -- (7) c c s c s
1623: *
1624: * (c=clear s=set)
1625: */
1626: switch (type & 0xff) {
1627: case ND_NEIGHBOR_SOLICIT:
1628: /*
1629: * New entry must have is_router flag cleared.
1630: */
1631: if (is_newentry) /* (6-7) */
1632: ln->ln_router = 0;
1633: break;
1634: case ND_REDIRECT:
1635: /*
1636: * If the icmp is a redirect to a better router, always set the
1637: * is_router flag. Otherwise, if the entry is newly created,
1638: * clear the flag. [RFC 2461, sec 8.3]
1639: */
1640: if (code == ND_REDIRECT_ROUTER)
1641: ln->ln_router = 1;
1642: else if (is_newentry) /* (6-7) */
1643: ln->ln_router = 0;
1644: break;
1645: case ND_ROUTER_SOLICIT:
1646: /*
1647: * is_router flag must always be cleared.
1648: */
1649: ln->ln_router = 0;
1650: break;
1651: case ND_ROUTER_ADVERT:
1652: /*
1653: * Mark an entry with lladdr as a router.
1654: */
1655: if ((!is_newentry && (olladdr || lladdr)) || /* (2-5) */
1656: (is_newentry && lladdr)) { /* (7) */
1657: ln->ln_router = 1;
1658: }
1659: break;
1660: }
1661:
1662: /*
1663: * When the link-layer address of a router changes, select the
1664: * best router again. In particular, when the neighbor entry is newly
1665: * created, it might affect the selection policy.
1666: * Question: can we restrict the first condition to the "is_newentry"
1667: * case?
1668: * XXX: when we hear an RA from a new router with the link-layer
1669: * address option, defrouter_select() is called twice, since
1670: * defrtrlist_update called the function as well. However, I believe
1671: * we can compromise the overhead, since it only happens the first
1672: * time.
1673: * XXX: although defrouter_select() should not have a bad effect
1674: * for those are not autoconfigured hosts, we explicitly avoid such
1675: * cases for safety.
1676: */
1677: if (do_update && ln->ln_router && !ip6_forwarding && ip6_accept_rtadv)
1678: defrouter_select();
1679:
1680: return rt;
1681: }
1682:
1683: static void
1684: nd6_slowtimo(ignored_arg)
1685: void *ignored_arg;
1686: {
1687: int s = splsoftnet();
1688: struct nd_ifinfo *nd6if;
1689: struct ifnet *ifp;
1690:
1691: timeout_set(&nd6_slowtimo_ch, nd6_slowtimo, NULL);
1692: timeout_add(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz);
1693: for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1694: {
1695: nd6if = ND_IFINFO(ifp);
1696: if (nd6if->basereachable && /* already initialized */
1697: (nd6if->recalctm -= ND6_SLOWTIMER_INTERVAL) <= 0) {
1698: /*
1699: * Since reachable time rarely changes by router
1700: * advertisements, we SHOULD insure that a new random
1701: * value gets recomputed at least once every few hours.
1702: * (RFC 2461, 6.3.4)
1703: */
1704: nd6if->recalctm = nd6_recalc_reachtm_interval;
1705: nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
1706: }
1707: }
1708: splx(s);
1709: }
1710:
1711: #define senderr(e) { error = (e); goto bad;}
1712: int
1713: nd6_output(ifp, origifp, m0, dst, rt0)
1714: struct ifnet *ifp;
1715: struct ifnet *origifp;
1716: struct mbuf *m0;
1717: struct sockaddr_in6 *dst;
1718: struct rtentry *rt0;
1719: {
1720: struct mbuf *m = m0;
1721: struct rtentry *rt = rt0;
1722: struct sockaddr_in6 *gw6 = NULL;
1723: struct llinfo_nd6 *ln = NULL;
1724: int error = 0;
1725: #ifdef IPSEC
1726: struct m_tag *mtag;
1727: #endif /* IPSEC */
1728:
1729: if (IN6_IS_ADDR_MULTICAST(&dst->sin6_addr))
1730: goto sendpkt;
1731:
1732: if (nd6_need_cache(ifp) == 0)
1733: goto sendpkt;
1734:
1735: /*
1736: * next hop determination. This routine is derived from ether_output.
1737: */
1738: if (rt) {
1739: if ((rt->rt_flags & RTF_UP) == 0) {
1740: if ((rt0 = rt = rtalloc1((struct sockaddr *)dst,
1741: 1, 0)) != NULL)
1742: {
1743: rt->rt_refcnt--;
1744: if (rt->rt_ifp != ifp)
1745: senderr(EHOSTUNREACH);
1746: } else
1747: senderr(EHOSTUNREACH);
1748: }
1749:
1750: if (rt->rt_flags & RTF_GATEWAY) {
1751: gw6 = (struct sockaddr_in6 *)rt->rt_gateway;
1752:
1753: /*
1754: * We skip link-layer address resolution and NUD
1755: * if the gateway is not a neighbor from ND point
1756: * of view, regardless of the value of nd_ifinfo.flags.
1757: * The second condition is a bit tricky; we skip
1758: * if the gateway is our own address, which is
1759: * sometimes used to install a route to a p2p link.
1760: */
1761: if (!nd6_is_addr_neighbor(gw6, ifp) ||
1762: in6ifa_ifpwithaddr(ifp, &gw6->sin6_addr)) {
1763: /*
1764: * We allow this kind of tricky route only
1765: * when the outgoing interface is p2p.
1766: * XXX: we may need a more generic rule here.
1767: */
1768: if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
1769: senderr(EHOSTUNREACH);
1770:
1771: goto sendpkt;
1772: }
1773:
1774: if (rt->rt_gwroute == 0)
1775: goto lookup;
1776: if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
1777: rtfree(rt); rt = rt0;
1778: lookup:
1779: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1, 0);
1780: if ((rt = rt->rt_gwroute) == 0)
1781: senderr(EHOSTUNREACH);
1782: }
1783: }
1784: }
1785:
1786: /*
1787: * Address resolution or Neighbor Unreachability Detection
1788: * for the next hop.
1789: * At this point, the destination of the packet must be a unicast
1790: * or an anycast address(i.e. not a multicast).
1791: */
1792:
1793: /* Look up the neighbor cache for the nexthop */
1794: if (rt && (rt->rt_flags & RTF_LLINFO) != 0)
1795: ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1796: else {
1797: /*
1798: * Since nd6_is_addr_neighbor() internally calls nd6_lookup(),
1799: * the condition below is not very efficient. But we believe
1800: * it is tolerable, because this should be a rare case.
1801: */
1802: if (nd6_is_addr_neighbor(dst, ifp) &&
1803: (rt = nd6_lookup(&dst->sin6_addr, 1, ifp)) != NULL)
1804: ln = (struct llinfo_nd6 *)rt->rt_llinfo;
1805: }
1806: if (!ln || !rt) {
1807: if ((ifp->if_flags & IFF_POINTOPOINT) == 0 &&
1808: !(ND_IFINFO(ifp)->flags & ND6_IFF_PERFORMNUD)) {
1809: log(LOG_DEBUG,
1810: "nd6_output: can't allocate llinfo for %s "
1811: "(ln=%p, rt=%p)\n",
1812: ip6_sprintf(&dst->sin6_addr), ln, rt);
1813: senderr(EIO); /* XXX: good error? */
1814: }
1815:
1816: goto sendpkt; /* send anyway */
1817: }
1818:
1819: /* We don't have to do link-layer address resolution on a p2p link. */
1820: if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
1821: ln->ln_state < ND6_LLINFO_REACHABLE) {
1822: ln->ln_state = ND6_LLINFO_STALE;
1823: nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
1824: }
1825:
1826: /*
1827: * The first time we send a packet to a neighbor whose entry is
1828: * STALE, we have to change the state to DELAY and a sets a timer to
1829: * expire in DELAY_FIRST_PROBE_TIME seconds to ensure do
1830: * neighbor unreachability detection on expiration.
1831: * (RFC 2461 7.3.3)
1832: */
1833: if (ln->ln_state == ND6_LLINFO_STALE) {
1834: ln->ln_asked = 0;
1835: ln->ln_state = ND6_LLINFO_DELAY;
1836: nd6_llinfo_settimer(ln, nd6_delay * hz);
1837: }
1838:
1839: /*
1840: * If the neighbor cache entry has a state other than INCOMPLETE
1841: * (i.e. its link-layer address is already resolved), just
1842: * send the packet.
1843: */
1844: if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
1845: goto sendpkt;
1846:
1847: /*
1848: * There is a neighbor cache entry, but no ethernet address
1849: * response yet. Replace the held mbuf (if any) with this
1850: * latest one.
1851: */
1852: if (ln->ln_state == ND6_LLINFO_NOSTATE)
1853: ln->ln_state = ND6_LLINFO_INCOMPLETE;
1854: if (ln->ln_hold)
1855: m_freem(ln->ln_hold);
1856: ln->ln_hold = m;
1857: /*
1858: * If there has been no NS for the neighbor after entering the
1859: * INCOMPLETE state, send the first solicitation.
1860: */
1861: if (!ND6_LLINFO_PERMANENT(ln) && ln->ln_asked == 0) {
1862: ln->ln_asked++;
1863: nd6_llinfo_settimer(ln,
1864: (long)ND_IFINFO(ifp)->retrans * hz / 1000);
1865: nd6_ns_output(ifp, NULL, &dst->sin6_addr, ln, 0);
1866: }
1867: return (0);
1868:
1869: sendpkt:
1870: #ifdef IPSEC
1871: /*
1872: * If the packet needs outgoing IPsec crypto processing and the
1873: * interface doesn't support it, drop it.
1874: */
1875: mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL);
1876: #endif /* IPSEC */
1877:
1878: if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
1879: #ifdef IPSEC
1880: if (mtag != NULL &&
1881: (origifp->if_capabilities & IFCAP_IPSEC) == 0) {
1882: /* Tell IPsec to do its own crypto. */
1883: ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
1884: error = EACCES;
1885: goto bad;
1886: }
1887: #endif /* IPSEC */
1888: return ((*ifp->if_output)(origifp, m, (struct sockaddr *)dst,
1889: rt));
1890: }
1891: #ifdef IPSEC
1892: if (mtag != NULL &&
1893: (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
1894: /* Tell IPsec to do its own crypto. */
1895: ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
1896: error = EACCES;
1897: goto bad;
1898: }
1899: #endif /* IPSEC */
1900: return ((*ifp->if_output)(ifp, m, (struct sockaddr *)dst, rt));
1901:
1902: bad:
1903: if (m)
1904: m_freem(m);
1905: return (error);
1906: }
1907: #undef senderr
1908:
1909: int
1910: nd6_need_cache(ifp)
1911: struct ifnet *ifp;
1912: {
1913: /*
1914: * XXX: we currently do not make neighbor cache on any interface
1915: * other than Ethernet, FDDI and GIF.
1916: *
1917: * RFC2893 says:
1918: * - unidirectional tunnels needs no ND
1919: */
1920: switch (ifp->if_type) {
1921: case IFT_ETHER:
1922: case IFT_FDDI:
1923: case IFT_IEEE1394:
1924: case IFT_PROPVIRTUAL:
1925: case IFT_L2VLAN:
1926: case IFT_IEEE80211:
1927: case IFT_CARP:
1928: case IFT_GIF: /* XXX need more cases? */
1929: return (1);
1930: default:
1931: return (0);
1932: }
1933: }
1934:
1935: int
1936: nd6_storelladdr(ifp, rt, m, dst, desten)
1937: struct ifnet *ifp;
1938: struct rtentry *rt;
1939: struct mbuf *m;
1940: struct sockaddr *dst;
1941: u_char *desten;
1942: {
1943: struct sockaddr_dl *sdl;
1944:
1945: if (m->m_flags & M_MCAST) {
1946: switch (ifp->if_type) {
1947: case IFT_ETHER:
1948: case IFT_FDDI:
1949: ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr,
1950: desten);
1951: return (1);
1952: break;
1953: default:
1954: m_freem(m);
1955: return (0);
1956: }
1957: }
1958:
1959: if (rt == NULL) {
1960: /* this could happen, if we could not allocate memory */
1961: m_freem(m);
1962: return (0);
1963: }
1964: if (rt->rt_gateway->sa_family != AF_LINK) {
1965: printf("nd6_storelladdr: something odd happens\n");
1966: m_freem(m);
1967: return (0);
1968: }
1969: sdl = SDL(rt->rt_gateway);
1970: if (sdl->sdl_alen == 0) {
1971: /* this should be impossible, but we bark here for debugging */
1972: printf("nd6_storelladdr: sdl_alen == 0, dst=%s, if=%s\n",
1973: ip6_sprintf(&SIN6(dst)->sin6_addr), ifp->if_xname);
1974: m_freem(m);
1975: return (0);
1976: }
1977:
1978: bcopy(LLADDR(sdl), desten, sdl->sdl_alen);
1979: return (1);
1980: }
1981:
1982: int
1983: nd6_sysctl(name, oldp, oldlenp, newp, newlen)
1984: int name;
1985: void *oldp; /* syscall arg, need copyout */
1986: size_t *oldlenp;
1987: void *newp; /* syscall arg, need copyin */
1988: size_t newlen;
1989: {
1990: void *p;
1991: size_t ol, l;
1992: int error;
1993:
1994: error = 0;
1995: l = 0;
1996:
1997: if (newp)
1998: return EPERM;
1999: if (oldp && !oldlenp)
2000: return EINVAL;
2001: ol = oldlenp ? *oldlenp : 0;
2002:
2003: if (oldp) {
2004: p = malloc(*oldlenp, M_TEMP, M_WAITOK);
2005: if (!p)
2006: return ENOMEM;
2007: } else
2008: p = NULL;
2009: switch (name) {
2010: case ICMPV6CTL_ND6_DRLIST:
2011: error = fill_drlist(p, oldlenp, ol);
2012: if (!error && p && oldp)
2013: error = copyout(p, oldp, *oldlenp);
2014: break;
2015:
2016: case ICMPV6CTL_ND6_PRLIST:
2017: error = fill_prlist(p, oldlenp, ol);
2018: if (!error && p && oldp)
2019: error = copyout(p, oldp, *oldlenp);
2020: break;
2021:
2022: default:
2023: error = ENOPROTOOPT;
2024: break;
2025: }
2026: if (p)
2027: free(p, M_TEMP);
2028:
2029: return (error);
2030: }
2031:
2032: static int
2033: fill_drlist(oldp, oldlenp, ol)
2034: void *oldp;
2035: size_t *oldlenp, ol;
2036: {
2037: int error = 0, s;
2038: struct in6_defrouter *d = NULL, *de = NULL;
2039: struct nd_defrouter *dr;
2040: size_t l;
2041:
2042: s = splsoftnet();
2043:
2044: if (oldp) {
2045: d = (struct in6_defrouter *)oldp;
2046: de = (struct in6_defrouter *)((caddr_t)oldp + *oldlenp);
2047: }
2048: l = 0;
2049:
2050: for (dr = TAILQ_FIRST(&nd_defrouter); dr;
2051: dr = TAILQ_NEXT(dr, dr_entry)) {
2052:
2053: if (oldp && d + 1 <= de) {
2054: bzero(d, sizeof(*d));
2055: d->rtaddr.sin6_family = AF_INET6;
2056: d->rtaddr.sin6_len = sizeof(struct sockaddr_in6);
2057: d->rtaddr.sin6_addr = dr->rtaddr;
2058: in6_recoverscope(&d->rtaddr, &d->rtaddr.sin6_addr,
2059: dr->ifp);
2060: d->flags = dr->flags;
2061: d->rtlifetime = dr->rtlifetime;
2062: d->expire = dr->expire;
2063: d->if_index = dr->ifp->if_index;
2064: }
2065:
2066: l += sizeof(*d);
2067: if (d)
2068: d++;
2069: }
2070:
2071: if (oldp) {
2072: *oldlenp = l; /* (caddr_t)d - (caddr_t)oldp */
2073: if (l > ol)
2074: error = ENOMEM;
2075: } else
2076: *oldlenp = l;
2077:
2078: splx(s);
2079:
2080: return (error);
2081: }
2082:
2083: static int
2084: fill_prlist(oldp, oldlenp, ol)
2085: void *oldp;
2086: size_t *oldlenp, ol;
2087: {
2088: int error = 0, s;
2089: struct nd_prefix *pr;
2090: struct in6_prefix *p = NULL;
2091: struct in6_prefix *pe = NULL;
2092: size_t l;
2093:
2094: s = splsoftnet();
2095:
2096: if (oldp) {
2097: p = (struct in6_prefix *)oldp;
2098: pe = (struct in6_prefix *)((caddr_t)oldp + *oldlenp);
2099: }
2100: l = 0;
2101:
2102: LIST_FOREACH(pr, &nd_prefix, ndpr_entry) {
2103: u_short advrtrs;
2104: size_t advance;
2105: struct sockaddr_in6 *sin6;
2106: struct sockaddr_in6 *s6;
2107: struct nd_pfxrouter *pfr;
2108:
2109: if (oldp && p + 1 <= pe)
2110: {
2111: bzero(p, sizeof(*p));
2112: sin6 = (struct sockaddr_in6 *)(p + 1);
2113:
2114: p->prefix = pr->ndpr_prefix;
2115: if (in6_recoverscope(&p->prefix,
2116: &p->prefix.sin6_addr, pr->ndpr_ifp) != 0)
2117: log(LOG_ERR,
2118: "scope error in prefix list (%s)\n",
2119: ip6_sprintf(&p->prefix.sin6_addr));
2120: p->raflags = pr->ndpr_raf;
2121: p->prefixlen = pr->ndpr_plen;
2122: p->vltime = pr->ndpr_vltime;
2123: p->pltime = pr->ndpr_pltime;
2124: p->if_index = pr->ndpr_ifp->if_index;
2125: if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME)
2126: p->expire = 0;
2127: else {
2128: time_t maxexpire;
2129:
2130: /* XXX: we assume time_t is signed. */
2131: maxexpire = (-1) &
2132: ~(1 << ((sizeof(maxexpire) * 8) - 1));
2133: if (pr->ndpr_vltime <
2134: maxexpire - pr->ndpr_lastupdate) {
2135: p->expire = pr->ndpr_lastupdate +
2136: pr->ndpr_vltime;
2137: } else
2138: p->expire = maxexpire;
2139: }
2140: p->refcnt = pr->ndpr_refcnt;
2141: p->flags = pr->ndpr_stateflags;
2142: p->origin = PR_ORIG_RA;
2143: advrtrs = 0;
2144: LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry) {
2145: if ((void *)&sin6[advrtrs + 1] > (void *)pe) {
2146: advrtrs++;
2147: continue;
2148: }
2149: s6 = &sin6[advrtrs];
2150: s6->sin6_family = AF_INET6;
2151: s6->sin6_len = sizeof(struct sockaddr_in6);
2152: s6->sin6_addr = pfr->router->rtaddr;
2153: in6_recoverscope(s6, &pfr->router->rtaddr,
2154: pfr->router->ifp);
2155: advrtrs++;
2156: }
2157: p->advrtrs = advrtrs;
2158: }
2159: else {
2160: advrtrs = 0;
2161: LIST_FOREACH(pfr, &pr->ndpr_advrtrs, pfr_entry)
2162: advrtrs++;
2163: }
2164:
2165: advance = sizeof(*p) + sizeof(*sin6) * advrtrs;
2166: l += advance;
2167: if (p)
2168: p = (struct in6_prefix *)((caddr_t)p + advance);
2169: }
2170:
2171: if (oldp) {
2172: *oldlenp = l; /* (caddr_t)d - (caddr_t)oldp */
2173: if (l > ol)
2174: error = ENOMEM;
2175: } else
2176: *oldlenp = l;
2177:
2178: splx(s);
2179:
2180: return (error);
2181: }
CVSweb