[BACK]Return to nd6.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Annotation of src/sys/netinet6/nd6.c, Revision 1.30.4.1

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

CVSweb <webmaster@jp.NetBSD.org>