[BACK]Return to nd6.c CVS log [TXT][DIR] Up to [local] / sys / netinet6

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