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

Annotation of src/sys/netinet6/nd6_nbr.c, Revision 1.166

1.166   ! roy         1: /*     $NetBSD: nd6_nbr.c,v 1.165 2019/04/29 11:57:22 roy Exp $        */
1.28      itojun      2: /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
1.3       thorpej     3:
1.2       itojun      4: /*
                      5:  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
                      6:  * All rights reserved.
1.22      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.22      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:  */
1.33      lukem      32:
                     33: #include <sys/cdefs.h>
1.166   ! roy        34: __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.165 2019/04/29 11:57:22 roy Exp $");
1.2       itojun     35:
1.110     pooka      36: #ifdef _KERNEL_OPT
1.2       itojun     37: #include "opt_inet.h"
1.128     ozaki-r    38: #include "opt_net_mpsafe.h"
1.110     pooka      39: #endif
1.2       itojun     40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
1.137     ozaki-r    43: #include <sys/kmem.h>
1.2       itojun     44: #include <sys/mbuf.h>
                     45: #include <sys/socket.h>
1.86      ad         46: #include <sys/socketvar.h>
1.2       itojun     47: #include <sys/sockio.h>
                     48: #include <sys/time.h>
                     49: #include <sys/kernel.h>
                     50: #include <sys/errno.h>
                     51: #include <sys/ioctl.h>
                     52: #include <sys/syslog.h>
                     53: #include <sys/queue.h>
1.21      itojun     54: #include <sys/callout.h>
1.149     roy        55: #include <sys/cprng.h>
1.2       itojun     56:
                     57: #include <net/if.h>
                     58: #include <net/if_types.h>
                     59: #include <net/if_dl.h>
                     60: #include <net/route.h>
                     61:
                     62: #include <netinet/in.h>
                     63: #include <netinet/in_var.h>
                     64: #include <netinet6/in6_var.h>
1.62      rpaulo     65: #include <netinet6/in6_ifattach.h>
1.14      itojun     66: #include <netinet/ip6.h>
1.2       itojun     67: #include <netinet6/ip6_var.h>
1.59      rpaulo     68: #include <netinet6/scope6_var.h>
1.2       itojun     69: #include <netinet6/nd6.h>
1.14      itojun     70: #include <netinet/icmp6.h>
1.85      thorpej    71: #include <netinet6/icmp6_private.h>
1.2       itojun     72:
1.64      liamjfoy   73: #include "carp.h"
                     74: #if NCARP > 0
                     75: #include <netinet/ip_carp.h>
                     76: #endif
                     77:
1.2       itojun     78: struct dadq;
1.158     roy        79: static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *, bool *);
1.162     roy        80: static bool nd6_dad_ownnonce(struct ifaddr *, struct nd_opt_nonce *nonce);
1.72      dyoung     81: static void nd6_dad_starttimer(struct dadq *, int);
1.144     ozaki-r    82: static void nd6_dad_destroytimer(struct dadq *);
                     83: static void nd6_dad_timer(struct dadq *);
1.72      dyoung     84: static void nd6_dad_ns_output(struct dadq *, struct ifaddr *);
1.166   ! roy        85: static void nd6_dad_input(struct ifaddr *, struct nd_opt_nonce *,
        !            86:     const struct sockaddr_dl *);
        !            87: static void nd6_dad_duplicated(struct ifaddr *, struct dadq *,
        !            88:     const struct sockaddr_dl *);
1.2       itojun     89:
1.9       itojun     90: static int dad_maxtry = 15;    /* max # of *tries* to transmit DAD packet */
1.2       itojun     91:
                     92: /*
1.61      rpaulo     93:  * Input a Neighbor Solicitation Message.
1.2       itojun     94:  *
                     95:  * Based on RFC 2461
1.61      rpaulo     96:  * Based on RFC 2462 (duplicate address detection)
1.2       itojun     97:  */
                     98: void
1.72      dyoung     99: nd6_ns_input(struct mbuf *m, int off, int icmp6len)
1.2       itojun    100: {
1.119     ozaki-r   101:        struct ifnet *ifp;
1.2       itojun    102:        struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1.16      itojun    103:        struct nd_neighbor_solicit *nd_ns;
1.2       itojun    104:        struct in6_addr saddr6 = ip6->ip6_src;
                    105:        struct in6_addr daddr6 = ip6->ip6_dst;
1.16      itojun    106:        struct in6_addr taddr6;
1.2       itojun    107:        struct in6_addr myaddr6;
                    108:        char *lladdr = NULL;
1.127     ozaki-r   109:        struct ifaddr *ifa = NULL;
1.2       itojun    110:        int lladdrlen = 0;
                    111:        int anycast = 0, proxy = 0, tentative = 0;
1.39      itojun    112:        int router = ip6_forwarding;
1.2       itojun    113:        int tlladdr;
                    114:        union nd_opts ndopts;
1.78      dyoung    115:        const struct sockaddr_dl *proxydl = NULL;
1.119     ozaki-r   116:        struct psref psref;
1.127     ozaki-r   117:        struct psref psref_ia;
1.135     ryo       118:        char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
1.119     ozaki-r   119:
                    120:        ifp = m_get_rcvif_psref(m, &psref);
                    121:        if (ifp == NULL)
                    122:                goto freeit;
1.2       itojun    123:
1.26      itojun    124:        IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
                    125:        if (nd_ns == NULL) {
1.85      thorpej   126:                ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
1.119     ozaki-r   127:                m_put_rcvif_psref(ifp, &psref);
1.26      itojun    128:                return;
                    129:        }
                    130:        ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
                    131:        taddr6 = nd_ns->nd_ns_target;
1.59      rpaulo    132:        if (in6_setscope(&taddr6, ifp, NULL) != 0)
                    133:                goto bad;
1.26      itojun    134:
1.2       itojun    135:        if (ip6->ip6_hlim != 255) {
1.114     ozaki-r   136:                nd6log(LOG_ERR, "invalid hlim (%d) from %s to %s on %s\n",
1.136     christos  137:                    ip6->ip6_hlim, IN6_PRINT(ip6buf, &ip6->ip6_src),
                    138:                    IN6_PRINT(ip6buf2, &ip6->ip6_dst), if_name(ifp));
1.26      itojun    139:                goto bad;
1.2       itojun    140:        }
                    141:
                    142:        if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
1.61      rpaulo    143:                /* dst has to be a solicited node multicast address. */
1.39      itojun    144:                /* don't check ifindex portion */
                    145:                if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
                    146:                    daddr6.s6_addr32[1] == 0 &&
                    147:                    daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
                    148:                    daddr6.s6_addr8[12] == 0xff) {
1.31      itojun    149:                        ; /* good */
1.2       itojun    150:                } else {
1.114     ozaki-r   151:                        nd6log(LOG_INFO, "bad DAD packet (wrong ip6 dst)\n");
1.2       itojun    152:                        goto bad;
                    153:                }
1.89      matt      154:        } else {
1.99      roy       155:                struct sockaddr_in6 ssin6;
                    156:
1.89      matt      157:                /*
                    158:                 * Make sure the source address is from a neighbor's address.
                    159:                 */
1.99      roy       160:                sockaddr_in6_init(&ssin6, &saddr6, 0, 0, 0);
                    161:                if (nd6_is_addr_neighbor(&ssin6, ifp) == 0) {
1.117     is        162:                        nd6log(LOG_INFO,
                    163:                            "NS packet from non-neighbor %s on %s\n",
1.136     christos  164:                            IN6_PRINT(ip6buf, &saddr6), if_name(ifp));
1.89      matt      165:                        goto bad;
                    166:                }
1.2       itojun    167:        }
                    168:
                    169:        if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
1.114     ozaki-r   170:                nd6log(LOG_INFO, "bad NS target (multicast)\n");
1.2       itojun    171:                goto bad;
                    172:        }
                    173:
                    174:        icmp6len -= sizeof(*nd_ns);
                    175:        nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
                    176:        if (nd6_options(&ndopts) < 0) {
1.114     ozaki-r   177:                nd6log(LOG_INFO, "invalid ND option, ignored\n");
1.26      itojun    178:                /* nd6_options have incremented stats */
                    179:                goto freeit;
1.2       itojun    180:        }
                    181:
                    182:        if (ndopts.nd_opts_src_lladdr) {
1.31      itojun    183:                lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
1.2       itojun    184:                lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
                    185:        }
1.42      itojun    186:
1.2       itojun    187:        if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
1.114     ozaki-r   188:                nd6log(LOG_INFO,
                    189:                    "bad DAD packet (link-layer address option)\n");
1.2       itojun    190:                goto bad;
                    191:        }
                    192:
                    193:        /*
                    194:         * Attaching target link-layer address to the NA?
                    195:         * (RFC 2461 7.2.4)
                    196:         *
1.62      rpaulo    197:         * NS IP dst is multicast                       MUST add
                    198:         * Otherwise                                    MAY be omitted
1.2       itojun    199:         *
1.62      rpaulo    200:         * In this implementation, we omit the target link-layer address
1.156     maxv      201:         * in the "MAY" case.
1.2       itojun    202:         */
                    203: #if 0 /* too much! */
                    204:        ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6);
                    205:        if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST))
                    206:                tlladdr = 0;
                    207:        else
                    208: #endif
                    209:        if (!IN6_IS_ADDR_MULTICAST(&daddr6))
                    210:                tlladdr = 0;
                    211:        else
                    212:                tlladdr = 1;
                    213:
                    214:        /*
                    215:         * Target address (taddr6) must be either:
                    216:         * (1) Valid unicast/anycast address for my receiving interface,
                    217:         * (2) Unicast address for which I'm offering proxy service, or
                    218:         * (3) "tentative" address on which DAD is being performed.
                    219:         */
                    220:        /* (1) and (3) check. */
1.64      liamjfoy  221: #if NCARP > 0
1.127     ozaki-r   222:        if (ifp->if_carp && ifp->if_type != IFT_CARP) {
                    223:                int s = pserialize_read_enter();
1.64      liamjfoy  224:                ifa = carp_iamatch6(ifp->if_carp, &taddr6);
1.127     ozaki-r   225:                if (ifa != NULL)
                    226:                        ifa_acquire(ifa, &psref_ia);
                    227:                pserialize_read_exit(s);
                    228:        } else
1.64      liamjfoy  229:                ifa = NULL;
                    230:        if (!ifa)
1.127     ozaki-r   231:                ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6,
                    232:                    &psref_ia);
1.64      liamjfoy  233: #else
1.127     ozaki-r   234:        ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6,
                    235:            &psref_ia);
1.64      liamjfoy  236: #endif
1.2       itojun    237:
                    238:        /* (2) check. */
1.62      rpaulo    239:        if (ifa == NULL) {
1.2       itojun    240:                struct rtentry *rt;
                    241:                struct sockaddr_in6 tsin6;
                    242:
1.81      dyoung    243:                sockaddr_in6_init(&tsin6, &taddr6, 0, 0, 0);
1.2       itojun    244:
1.123     ozaki-r   245:                rt = rtalloc1(sin6tosa(&tsin6), 0);
1.16      itojun    246:                if (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 &&
                    247:                    rt->rt_gateway->sa_family == AF_LINK) {
1.2       itojun    248:                        /*
1.16      itojun    249:                         * proxy NDP for single entry
1.2       itojun    250:                         */
1.127     ozaki-r   251:                        ifa = (struct ifaddr *)in6ifa_ifpforlinklocal_psref(ifp,
                    252:                                IN6_IFF_NOTREADY|IN6_IFF_ANYCAST, &psref_ia);
1.16      itojun    253:                        if (ifa) {
1.2       itojun    254:                                proxy = 1;
1.78      dyoung    255:                                proxydl = satocsdl(rt->rt_gateway);
1.39      itojun    256:                                router = 0;     /* XXX */
1.16      itojun    257:                        }
1.2       itojun    258:                }
1.16      itojun    259:                if (rt)
1.132     ozaki-r   260:                        rt_unref(rt);
1.2       itojun    261:        }
1.62      rpaulo    262:        if (ifa == NULL) {
1.2       itojun    263:                /*
1.60      wiz       264:                 * We've got an NS packet, and we don't have that address
1.2       itojun    265:                 * assigned for us.  We MUST silently ignore it.
                    266:                 * See RFC2461 7.2.3.
                    267:                 */
1.16      itojun    268:                goto freeit;
1.2       itojun    269:        }
1.9       itojun    270:        myaddr6 = *IFA_IN6(ifa);
1.2       itojun    271:        anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
                    272:        tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
                    273:        if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
1.16      itojun    274:                goto freeit;
1.2       itojun    275:
                    276:        if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
1.114     ozaki-r   277:                nd6log(LOG_INFO, "lladdrlen mismatch for %s "
1.2       itojun    278:                    "(if %d, NS packet %d)\n",
1.136     christos  279:                    IN6_PRINT(ip6buf, &taddr6),
1.135     ryo       280:                    ifp->if_addrlen, lladdrlen - 2);
1.26      itojun    281:                goto bad;
1.2       itojun    282:        }
                    283:
                    284:        if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
1.114     ozaki-r   285:                nd6log(LOG_INFO, "duplicate IP6 address %s\n",
1.136     christos  286:                    IN6_PRINT(ip6buf, &saddr6));
1.16      itojun    287:                goto freeit;
1.2       itojun    288:        }
                    289:
                    290:        /*
                    291:         * We have neighbor solicitation packet, with target address equals to
                    292:         * one of my tentative address.
                    293:         *
                    294:         * src addr     how to process?
                    295:         * ---          ---
                    296:         * multicast    of course, invalid (rejected in ip6_input)
                    297:         * unicast      somebody is doing address resolution -> ignore
                    298:         * unspec       dup address detection
                    299:         *
                    300:         * The processing is defined in RFC 2462.
                    301:         */
                    302:        if (tentative) {
                    303:                /*
                    304:                 * If source address is unspecified address, it is for
1.61      rpaulo    305:                 * duplicate address detection.
1.2       itojun    306:                 *
                    307:                 * If not, the packet is for addess resolution;
                    308:                 * silently ignore it.
                    309:                 */
1.166   ! roy       310:                if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
        !           311:                        struct sockaddr_dl sdl, *sdlp;
        !           312:
        !           313:                        if (lladdr != NULL)
        !           314:                                sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
        !           315:                                    ifp->if_index, ifp->if_type,
        !           316:                                    NULL, 0, lladdr, lladdrlen);
        !           317:                        else
        !           318:                                sdlp = NULL;
        !           319:                        nd6_dad_input(ifa, ndopts.nd_opts_nonce, sdlp);
        !           320:                }
1.16      itojun    321:                goto freeit;
1.2       itojun    322:        }
1.161     roy       323:
1.162     roy       324:        /*
                    325:         * It looks that sender is performing DAD.
                    326:         * Check that the nonce is not being used by the same address
                    327:         * on another interface.
                    328:         */
                    329:        if (IN6_IS_ADDR_UNSPECIFIED(&saddr6) && ndopts.nd_opts_nonce != NULL) {
                    330:                if (nd6_dad_ownnonce(ifa, ndopts.nd_opts_nonce))
                    331:                        goto freeit;
                    332:        }
                    333:
1.127     ozaki-r   334:        ifa_release(ifa, &psref_ia);
                    335:        ifa = NULL;
1.2       itojun    336:
                    337:        /*
                    338:         * If the source address is unspecified address, entries must not
                    339:         * be created or updated.
                    340:         * It looks that sender is performing DAD.  Output NA toward
                    341:         * all-node multicast address, to tell the sender that I'm using
                    342:         * the address.
                    343:         * S bit ("solicited") must be zero.
                    344:         */
                    345:        if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
1.59      rpaulo    346:                struct in6_addr in6_all;
                    347:
                    348:                in6_all = in6addr_linklocal_allnodes;
                    349:                if (in6_setscope(&in6_all, ifp, NULL) != 0)
                    350:                        goto bad;
                    351:                nd6_na_output(ifp, &in6_all, &taddr6,
1.39      itojun    352:                    ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
1.59      rpaulo    353:                    (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0),
1.78      dyoung    354:                    tlladdr, (const struct sockaddr *)proxydl);
1.16      itojun    355:                goto freeit;
1.2       itojun    356:        }
                    357:
1.7       itojun    358:        nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0);
1.2       itojun    359:
                    360:        nd6_na_output(ifp, &saddr6, &taddr6,
1.39      itojun    361:            ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
                    362:            (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED,
1.78      dyoung    363:            tlladdr, (const struct sockaddr *)proxydl);
1.16      itojun    364:  freeit:
1.127     ozaki-r   365:        ifa_release(ifa, &psref_ia);
1.119     ozaki-r   366:        m_put_rcvif_psref(ifp, &psref);
1.16      itojun    367:        m_freem(m);
1.2       itojun    368:        return;
                    369:
                    370:  bad:
1.136     christos  371:        nd6log(LOG_ERR, "src=%s\n", IN6_PRINT(ip6buf, &saddr6));
                    372:        nd6log(LOG_ERR, "dst=%s\n", IN6_PRINT(ip6buf, &daddr6));
                    373:        nd6log(LOG_ERR, "tgt=%s\n", IN6_PRINT(ip6buf, &taddr6));
1.85      thorpej   374:        ICMP6_STATINC(ICMP6_STAT_BADNS);
1.127     ozaki-r   375:        ifa_release(ifa, &psref_ia);
1.119     ozaki-r   376:        m_put_rcvif_psref(ifp, &psref);
1.16      itojun    377:        m_freem(m);
1.2       itojun    378: }
                    379:
                    380: /*
1.61      rpaulo    381:  * Output a Neighbor Solicitation Message. Caller specifies:
1.2       itojun    382:  *     - ICMP6 header source IP6 address
                    383:  *     - ND6 header target IP6 address
                    384:  *     - ND6 header source datalink address
                    385:  *
                    386:  * Based on RFC 2461
1.61      rpaulo    387:  * Based on RFC 2462 (duplicate address detection)
1.2       itojun    388:  */
                    389: void
1.72      dyoung    390: nd6_ns_output(struct ifnet *ifp, const struct in6_addr *daddr6,
                    391:     const struct in6_addr *taddr6,
1.111     ozaki-r   392:     struct in6_addr *hsrc,
1.149     roy       393:     uint8_t *nonce             /* duplicate address detection */)
1.2       itojun    394: {
                    395:        struct mbuf *m;
                    396:        struct ip6_hdr *ip6;
                    397:        struct nd_neighbor_solicit *nd_ns;
1.59      rpaulo    398:        struct in6_addr *src, src_in;
1.2       itojun    399:        struct ip6_moptions im6o;
                    400:        int icmp6len;
1.15      itojun    401:        int maxlen;
1.80      dyoung    402:        const void *mac;
1.73      dyoung    403:        struct route ro;
1.39      itojun    404:
1.2       itojun    405:        if (IN6_IS_ADDR_MULTICAST(taddr6))
                    406:                return;
                    407:
1.82      dyoung    408:        memset(&ro, 0, sizeof(ro));
                    409:
1.15      itojun    410:        /* estimate the size of message */
                    411:        maxlen = sizeof(*ip6) + sizeof(*nd_ns);
                    412:        maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
1.155     maxv      413:        KASSERTMSG(max_linkhdr + maxlen <= MCLBYTES,
                    414:            "max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
1.138     ozaki-r   415:            max_linkhdr, maxlen, MCLBYTES);
1.15      itojun    416:
                    417:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    418:        if (m && max_linkhdr + maxlen >= MHLEN) {
                    419:                MCLGET(m, M_DONTWAIT);
                    420:                if ((m->m_flags & M_EXT) == 0) {
                    421:                        m_free(m);
                    422:                        m = NULL;
                    423:                }
                    424:        }
                    425:        if (m == NULL)
1.2       itojun    426:                return;
1.118     ozaki-r   427:        m_reset_rcvif(m);
1.2       itojun    428:
                    429:        if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
                    430:                m->m_flags |= M_MCAST;
1.120     ozaki-r   431:                im6o.im6o_multicast_if_index = if_get_index(ifp);
1.2       itojun    432:                im6o.im6o_multicast_hlim = 255;
                    433:                im6o.im6o_multicast_loop = 0;
                    434:        }
                    435:
                    436:        icmp6len = sizeof(*nd_ns);
                    437:        m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
1.164     maxv      438:        m->m_data += max_linkhdr;       /* or m_align() equivalent? */
1.2       itojun    439:
                    440:        /* fill neighbor solicitation packet */
                    441:        ip6 = mtod(m, struct ip6_hdr *);
                    442:        ip6->ip6_flow = 0;
1.10      itojun    443:        ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
                    444:        ip6->ip6_vfc |= IPV6_VERSION;
1.2       itojun    445:        /* ip6->ip6_plen will be set later */
                    446:        ip6->ip6_nxt = IPPROTO_ICMPV6;
                    447:        ip6->ip6_hlim = 255;
                    448:        if (daddr6)
1.59      rpaulo    449:                ip6->ip6_dst = *daddr6;
1.2       itojun    450:        else {
1.59      rpaulo    451:                ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
                    452:                ip6->ip6_dst.s6_addr16[1] = 0;
                    453:                ip6->ip6_dst.s6_addr32[1] = 0;
                    454:                ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
                    455:                ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
                    456:                ip6->ip6_dst.s6_addr8[12] = 0xff;
                    457:                if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
                    458:                        goto bad;
1.2       itojun    459:        }
1.149     roy       460:        if (nonce == NULL) {
1.127     ozaki-r   461:                int s;
1.2       itojun    462:                /*
                    463:                 * RFC2461 7.2.2:
                    464:                 * "If the source address of the packet prompting the
                    465:                 * solicitation is the same as one of the addresses assigned
                    466:                 * to the outgoing interface, that address SHOULD be placed
                    467:                 * in the IP Source Address of the outgoing solicitation.
                    468:                 * Otherwise, any one of the addresses assigned to the
                    469:                 * interface should be used."
                    470:                 *
                    471:                 * We use the source address for the prompting packet
1.59      rpaulo    472:                 * (hsrc), if:
                    473:                 * - hsrc is given from the caller (by giving "ln"), and
                    474:                 * - hsrc belongs to the outgoing interface.
1.39      itojun    475:                 * Otherwise, we perform the source address selection as usual.
1.2       itojun    476:                 */
1.127     ozaki-r   477:                s = pserialize_read_enter();
1.153     ozaki-r   478:                if (hsrc && in6ifa_ifpwithaddr(ifp, hsrc)) {
                    479:                        pserialize_read_exit(s);
1.59      rpaulo    480:                        src = hsrc;
1.153     ozaki-r   481:                } else {
1.39      itojun    482:                        int error;
1.59      rpaulo    483:                        struct sockaddr_in6 dst_sa;
1.39      itojun    484:
1.153     ozaki-r   485:                        pserialize_read_exit(s);
                    486:
1.81      dyoung    487:                        sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
1.59      rpaulo    488:
1.129     ozaki-r   489:                        error = in6_selectsrc(&dst_sa, NULL,
                    490:                            NULL, &ro, NULL, NULL, NULL, &src_in);
                    491:                        if (error != 0) {
1.135     ryo       492:                                char ip6buf[INET6_ADDRSTRLEN];
1.114     ozaki-r   493:                                nd6log(LOG_DEBUG, "source can't be "
1.39      itojun    494:                                    "determined: dst=%s, error=%d\n",
1.136     christos  495:                                    IN6_PRINT(ip6buf, &dst_sa.sin6_addr),
1.135     ryo       496:                                    error);
1.127     ozaki-r   497:                                pserialize_read_exit(s);
1.39      itojun    498:                                goto bad;
1.2       itojun    499:                        }
1.129     ozaki-r   500:                        src = &src_in;
1.2       itojun    501:                }
                    502:        } else {
                    503:                /*
                    504:                 * Source address for DAD packet must always be IPv6
                    505:                 * unspecified address. (0::0)
1.39      itojun    506:                 * We actually don't have to 0-clear the address (we did it
                    507:                 * above), but we do so here explicitly to make the intention
                    508:                 * clearer.
1.2       itojun    509:                 */
1.92      cegger    510:                memset(&src_in, 0, sizeof(src_in));
1.59      rpaulo    511:                src = &src_in;
1.2       itojun    512:        }
1.59      rpaulo    513:        ip6->ip6_src = *src;
1.2       itojun    514:        nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
                    515:        nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
                    516:        nd_ns->nd_ns_code = 0;
                    517:        nd_ns->nd_ns_reserved = 0;
                    518:        nd_ns->nd_ns_target = *taddr6;
1.59      rpaulo    519:        in6_clearscope(&nd_ns->nd_ns_target); /* XXX */
1.2       itojun    520:
                    521:        /*
                    522:         * Add source link-layer address option.
                    523:         *
                    524:         *                              spec            implementation
                    525:         *                              ---             ---
                    526:         * DAD packet                   MUST NOT        do not add the option
                    527:         * there's no link layer address:
                    528:         *                              impossible      do not add the option
                    529:         * there's link layer address:
                    530:         *      Multicast NS            MUST add one    add the option
                    531:         *      Unicast NS              SHOULD add one  add the option
                    532:         */
1.149     roy       533:        if (nonce == NULL && (mac = nd6_ifptomac(ifp))) {
1.2       itojun    534:                int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
                    535:                struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
1.8       is        536:                /* 8 byte alignments... */
                    537:                optlen = (optlen + 7) & ~7;
1.42      itojun    538:
1.2       itojun    539:                m->m_pkthdr.len += optlen;
                    540:                m->m_len += optlen;
                    541:                icmp6len += optlen;
1.92      cegger    542:                memset((void *)nd_opt, 0, optlen);
1.2       itojun    543:                nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
                    544:                nd_opt->nd_opt_len = optlen >> 3;
1.94      tsutsui   545:                memcpy((void *)(nd_opt + 1), mac, ifp->if_addrlen);
1.2       itojun    546:        }
                    547:
1.149     roy       548:        /* Add a nonce option (RFC 3971) to detect looped back NS messages.
                    549:         * This behavior is documented in RFC 7527. */
                    550:        if (nonce != NULL) {
                    551:                int optlen = sizeof(struct nd_opt_hdr) + ND_OPT_NONCE_LEN;
                    552:                struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
                    553:
                    554:                /* 8-byte alignment is required. */
                    555:                optlen = (optlen + 7) & ~7;
                    556:                m->m_pkthdr.len += optlen;
                    557:                m->m_len += optlen;
                    558:                icmp6len += optlen;
                    559:                memset(nd_opt, 0, optlen);
                    560:                nd_opt->nd_opt_type = ND_OPT_NONCE;
                    561:                nd_opt->nd_opt_len = optlen >> 3;
                    562:                memcpy(nd_opt + 1, nonce, ND_OPT_NONCE_LEN);
                    563:        }
                    564:
1.51      itojun    565:        ip6->ip6_plen = htons((u_int16_t)icmp6len);
1.2       itojun    566:        nd_ns->nd_ns_cksum = 0;
1.39      itojun    567:        nd_ns->nd_ns_cksum =
                    568:            in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
1.2       itojun    569:
1.149     roy       570:        ip6_output(m, NULL, &ro, nonce != NULL ? IPV6_UNSPECSRC : 0,
                    571:            &im6o, NULL, NULL);
1.32      itojun    572:        icmp6_ifstat_inc(ifp, ifs6_out_msg);
                    573:        icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
1.85      thorpej   574:        ICMP6_STATINC(ICMP6_STAT_OUTHIST + ND_NEIGHBOR_SOLICIT);
1.32      itojun    575:
1.73      dyoung    576:        rtcache_free(&ro);
1.32      itojun    577:        return;
                    578:
                    579:   bad:
1.73      dyoung    580:        rtcache_free(&ro);
1.32      itojun    581:        m_freem(m);
                    582:        return;
1.2       itojun    583: }
                    584:
                    585: /*
                    586:  * Neighbor advertisement input handling.
                    587:  *
                    588:  * Based on RFC 2461
1.61      rpaulo    589:  * Based on RFC 2462 (duplicate address detection)
1.16      itojun    590:  *
                    591:  * the following items are not implemented yet:
                    592:  * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
                    593:  * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
1.2       itojun    594:  */
                    595: void
1.72      dyoung    596: nd6_na_input(struct mbuf *m, int off, int icmp6len)
1.2       itojun    597: {
1.119     ozaki-r   598:        struct ifnet *ifp;
1.2       itojun    599:        struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
1.16      itojun    600:        struct nd_neighbor_advert *nd_na;
1.2       itojun    601:        struct in6_addr saddr6 = ip6->ip6_src;
                    602:        struct in6_addr daddr6 = ip6->ip6_dst;
1.16      itojun    603:        struct in6_addr taddr6;
                    604:        int flags;
                    605:        int is_router;
                    606:        int is_solicited;
                    607:        int is_override;
1.2       itojun    608:        char *lladdr = NULL;
                    609:        int lladdrlen = 0;
                    610:        struct ifaddr *ifa;
1.115     ozaki-r   611:        struct llentry *ln = NULL;
1.2       itojun    612:        union nd_opts ndopts;
1.99      roy       613:        struct sockaddr_in6 ssin6;
1.103     roy       614:        int rt_announce;
1.116     ozaki-r   615:        bool checklink = false;
1.119     ozaki-r   616:        struct psref psref;
1.127     ozaki-r   617:        struct psref psref_ia;
1.135     ryo       618:        char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
1.119     ozaki-r   619:
                    620:        ifp = m_get_rcvif_psref(m, &psref);
                    621:        if (ifp == NULL)
                    622:                goto freeit;
1.2       itojun    623:
                    624:        if (ip6->ip6_hlim != 255) {
1.114     ozaki-r   625:                nd6log(LOG_ERR,
                    626:                    "invalid hlim (%d) from %s to %s on %s\n",
1.136     christos  627:                    ip6->ip6_hlim, IN6_PRINT(ip6buf, &ip6->ip6_src),
                    628:                    IN6_PRINT(ip6buf2, &ip6->ip6_dst), if_name(ifp));
1.26      itojun    629:                goto bad;
1.16      itojun    630:        }
                    631:
                    632:        IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
                    633:        if (nd_na == NULL) {
1.119     ozaki-r   634:                m_put_rcvif_psref(ifp, &psref);
1.85      thorpej   635:                ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
1.2       itojun    636:                return;
                    637:        }
1.59      rpaulo    638:
1.16      itojun    639:        flags = nd_na->nd_na_flags_reserved;
                    640:        is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
                    641:        is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
                    642:        is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
1.2       itojun    643:
1.59      rpaulo    644:        taddr6 = nd_na->nd_na_target;
1.119     ozaki-r   645:        if (in6_setscope(&taddr6, ifp, NULL)) {
1.145     maxv      646:                goto bad;
1.119     ozaki-r   647:        }
1.2       itojun    648:
                    649:        if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
1.114     ozaki-r   650:                nd6log(LOG_ERR, "invalid target address %s\n",
1.136     christos  651:                    IN6_PRINT(ip6buf, &taddr6));
1.26      itojun    652:                goto bad;
1.2       itojun    653:        }
1.39      itojun    654:        if (is_solicited && IN6_IS_ADDR_MULTICAST(&daddr6)) {
1.114     ozaki-r   655:                nd6log(LOG_ERR, "a solicited adv is multicasted\n");
1.39      itojun    656:                goto bad;
                    657:        }
1.2       itojun    658:
                    659:        icmp6len -= sizeof(*nd_na);
                    660:        nd6_option_init(nd_na + 1, icmp6len, &ndopts);
                    661:        if (nd6_options(&ndopts) < 0) {
1.114     ozaki-r   662:                nd6log(LOG_INFO, "invalid ND option, ignored\n");
1.26      itojun    663:                /* nd6_options have incremented stats */
1.16      itojun    664:                goto freeit;
1.2       itojun    665:        }
                    666:
1.163     roy       667:        if (ndopts.nd_opts_tgt_lladdr != NULL) {
                    668:                struct ifnet *ifp_ll;
                    669:                struct psref psref_ll;
                    670:
1.2       itojun    671:                lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
                    672:                lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
1.163     roy       673:
                    674:                if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
                    675:                        nd6log(LOG_INFO, "lladdrlen mismatch for %s "
                    676:                            "(if %d, NA packet %d)\n", IN6_PRINT(ip6buf, &taddr6),
                    677:                            ifp->if_addrlen, lladdrlen - 2);
                    678:                        goto bad;
                    679:                }
                    680:
                    681:                ifp_ll = if_get_bylla(lladdr, ifp->if_addrlen, &psref_ll);
                    682:                if (ifp_ll != NULL) {
                    683:                        /* it's from me, ignore it. */
                    684:                        if_put(ifp_ll, &psref_ll);
                    685:                        goto freeit;
                    686:                }
1.2       itojun    687:        }
                    688:
1.127     ozaki-r   689:        ifa = (struct ifaddr *)in6ifa_ifpwithaddr_psref(ifp, &taddr6, &psref_ia);
1.2       itojun    690:
                    691:        /*
                    692:         * Target address matches one of my interface address.
                    693:         *
                    694:         * If my address is tentative, this means that there's somebody
                    695:         * already using the same address as mine.  This indicates DAD failure.
                    696:         * This is defined in RFC 2462.
                    697:         *
                    698:         * Otherwise, process as defined in RFC 2461.
                    699:         */
                    700:        if (ifa) {
1.166   ! roy       701:                if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE) {
        !           702:                        struct sockaddr_dl sdl, *sdlp;
        !           703:
        !           704:                        if (lladdr != NULL)
        !           705:                                sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
        !           706:                                    ifp->if_index, ifp->if_type,
        !           707:                                    NULL, 0, lladdr, lladdrlen);
        !           708:                        else
        !           709:                                sdlp = NULL;
        !           710:                        nd6_dad_input(ifa, NULL, sdlp);
        !           711:                } else
1.159     roy       712:                        log(LOG_ERR,
                    713:                            "nd6_na_input: duplicate IP6 address %s\n",
                    714:                            IN6_PRINT(ip6buf, &taddr6));
1.127     ozaki-r   715:                ifa_release(ifa, &psref_ia);
                    716:                ifa = NULL;
1.16      itojun    717:                goto freeit;
1.2       itojun    718:        }
1.99      roy       719:
1.90      matt      720:        /*
                    721:         * Make sure the source address is from a neighbor's address.
                    722:         */
1.99      roy       723:        sockaddr_in6_init(&ssin6, &saddr6, 0, 0, 0);
                    724:        if (nd6_is_addr_neighbor(&ssin6, ifp) == 0) {
1.117     is        725:                nd6log(LOG_INFO, "ND packet from non-neighbor %s on %s\n",
1.136     christos  726:                    IN6_PRINT(ip6buf, &saddr6), if_name(ifp));
1.90      matt      727:                goto bad;
                    728:        }
1.2       itojun    729:
                    730:        /*
1.39      itojun    731:         * If no neighbor cache entry is found, NA SHOULD silently be
                    732:         * discarded.
1.2       itojun    733:         */
1.115     ozaki-r   734:        ln = nd6_lookup(&taddr6, ifp, true);
                    735:        if (ln == NULL)
1.16      itojun    736:                goto freeit;
1.2       itojun    737:
1.103     roy       738:        rt_announce = 0;
1.2       itojun    739:        if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
                    740:                /*
                    741:                 * If the link-layer has address, and no lladdr option came,
                    742:                 * discard the packet.
                    743:                 */
                    744:                if (ifp->if_addrlen && !lladdr)
1.16      itojun    745:                        goto freeit;
1.2       itojun    746:
                    747:                /*
                    748:                 * Record link-layer address, and update the state.
                    749:                 */
1.115     ozaki-r   750:                memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
                    751:                ln->la_flags |= LLE_VALID;
1.103     roy       752:                rt_announce = 1;
1.2       itojun    753:                if (is_solicited) {
                    754:                        ln->ln_state = ND6_LLINFO_REACHABLE;
1.27      itojun    755:                        ln->ln_byhint = 0;
1.47      itojun    756:                        if (!ND6_LLINFO_PERMANENT(ln)) {
                    757:                                nd6_llinfo_settimer(ln,
1.113     ozaki-r   758:                                    ND_IFINFO(ln->lle_tbl->llt_ifp)->reachable * hz);
1.47      itojun    759:                        }
1.28      itojun    760:                } else {
1.2       itojun    761:                        ln->ln_state = ND6_LLINFO_STALE;
1.113     ozaki-r   762:                        nd6_llinfo_settimer(ln, nd6_gctimer * hz);
1.31      itojun    763:                }
                    764:                if ((ln->ln_router = is_router) != 0) {
                    765:                        /*
                    766:                         * This means a router's state has changed from
                    767:                         * non-reachable to probably reachable, and might
                    768:                         * affect the status of associated prefixes..
                    769:                         */
1.116     ozaki-r   770:                        checklink = true;
1.28      itojun    771:                }
1.2       itojun    772:        } else {
                    773:                int llchange;
                    774:
                    775:                /*
                    776:                 * Check if the link-layer address has changed or not.
                    777:                 */
1.62      rpaulo    778:                if (lladdr == NULL)
1.2       itojun    779:                        llchange = 0;
                    780:                else {
1.115     ozaki-r   781:                        if (ln->la_flags & LLE_VALID) {
                    782:                                if (memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen))
1.103     roy       783:                                        llchange = rt_announce = 1;
1.2       itojun    784:                                else
                    785:                                        llchange = 0;
                    786:                        } else
1.103     roy       787:                                llchange = rt_announce = 1;
1.2       itojun    788:                }
                    789:
                    790:                /*
                    791:                 * This is VERY complex.  Look at it with care.
                    792:                 *
                    793:                 * override solicit lladdr llchange     action
                    794:                 *                                      (L: record lladdr)
                    795:                 *
                    796:                 *      0       0       n       --      (2c)
                    797:                 *      0       0       y       n       (2b) L
                    798:                 *      0       0       y       y       (1)    REACHABLE->STALE
                    799:                 *      0       1       n       --      (2c)   *->REACHABLE
                    800:                 *      0       1       y       n       (2b) L *->REACHABLE
                    801:                 *      0       1       y       y       (1)    REACHABLE->STALE
                    802:                 *      1       0       n       --      (2a)
                    803:                 *      1       0       y       n       (2a) L
                    804:                 *      1       0       y       y       (2a) L *->STALE
                    805:                 *      1       1       n       --      (2a)   *->REACHABLE
                    806:                 *      1       1       y       n       (2a) L *->REACHABLE
                    807:                 *      1       1       y       y       (2a) L *->REACHABLE
                    808:                 */
1.62      rpaulo    809:                if (!is_override && lladdr != NULL && llchange) { /* (1) */
1.2       itojun    810:                        /*
                    811:                         * If state is REACHABLE, make it STALE.
                    812:                         * no other updates should be done.
                    813:                         */
1.28      itojun    814:                        if (ln->ln_state == ND6_LLINFO_REACHABLE) {
1.2       itojun    815:                                ln->ln_state = ND6_LLINFO_STALE;
1.113     ozaki-r   816:                                nd6_llinfo_settimer(ln, nd6_gctimer * hz);
1.28      itojun    817:                        }
1.16      itojun    818:                        goto freeit;
1.2       itojun    819:                } else if (is_override                             /* (2a) */
1.62      rpaulo    820:                    || (!is_override && lladdr != NULL && !llchange) /* (2b) */
                    821:                    || lladdr == NULL) {                           /* (2c) */
1.2       itojun    822:                        /*
                    823:                         * Update link-local address, if any.
                    824:                         */
1.62      rpaulo    825:                        if (lladdr != NULL) {
1.115     ozaki-r   826:                                memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
                    827:                                ln->la_flags |= LLE_VALID;
1.2       itojun    828:                        }
                    829:
                    830:                        /*
                    831:                         * If solicited, make the state REACHABLE.
                    832:                         * If not solicited and the link-layer address was
                    833:                         * changed, make it STALE.
                    834:                         */
                    835:                        if (is_solicited) {
                    836:                                ln->ln_state = ND6_LLINFO_REACHABLE;
1.27      itojun    837:                                ln->ln_byhint = 0;
1.47      itojun    838:                                if (!ND6_LLINFO_PERMANENT(ln)) {
                    839:                                        nd6_llinfo_settimer(ln,
1.113     ozaki-r   840:                                            ND_IFINFO(ifp)->reachable * hz);
1.2       itojun    841:                                }
                    842:                        } else {
1.28      itojun    843:                                if (lladdr && llchange) {
1.2       itojun    844:                                        ln->ln_state = ND6_LLINFO_STALE;
1.47      itojun    845:                                        nd6_llinfo_settimer(ln,
1.113     ozaki-r   846:                                            nd6_gctimer * hz);
1.28      itojun    847:                                }
1.2       itojun    848:                        }
                    849:                }
                    850:
                    851:                if (ln->ln_router && !is_router) {
                    852:                        /*
                    853:                         * The peer dropped the router flag.
                    854:                         * Remove the sender from the Default Router List and
                    855:                         * update the Destination Cache entries.
                    856:                         */
                    857:                        struct nd_defrouter *dr;
1.77      dyoung    858:                        const struct in6_addr *in6;
1.2       itojun    859:
1.115     ozaki-r   860:                        in6 = &ln->r_l3addr.addr6;
1.29      itojun    861:
1.134     ozaki-r   862:                        ND6_WLOCK();
1.131     ozaki-r   863:                        dr = nd6_defrouter_lookup(in6, ln->lle_tbl->llt_ifp);
1.2       itojun    864:                        if (dr)
1.131     ozaki-r   865:                                nd6_defrtrlist_del(dr, NULL);
1.46      itojun    866:                        else if (!ip6_forwarding) {
1.2       itojun    867:                                /*
                    868:                                 * Even if the neighbor is not in the default
                    869:                                 * router list, the neighbor may be used
                    870:                                 * as a next hop for some destinations
                    871:                                 * (e.g. redirect case). So we must
1.131     ozaki-r   872:                                 * call nd6_rt_flush explicitly.
1.2       itojun    873:                                 */
1.131     ozaki-r   874:                                nd6_rt_flush(&ip6->ip6_src, ln->lle_tbl->llt_ifp);
1.2       itojun    875:                        }
1.134     ozaki-r   876:                        ND6_UNLOCK();
1.2       itojun    877:                }
                    878:                ln->ln_router = is_router;
                    879:        }
1.115     ozaki-r   880:         /*
                    881:         * XXX: does this matter?
                    882:         * rt->rt_flags &= ~RTF_REJECT;
                    883:         */
1.2       itojun    884:        ln->ln_asked = 0;
1.115     ozaki-r   885:        nd6_llinfo_release_pkts(ln, ifp);
                    886:        /* FIXME */
                    887: #if 0
1.103     roy       888:        if (rt_announce) /* tell user process about any new lladdr */
1.106     roy       889:                rt_newmsg(RTM_CHANGE, rt);
1.115     ozaki-r   890: #endif
1.16      itojun    891:
                    892:  freeit:
1.115     ozaki-r   893:        if (ln != NULL)
                    894:                LLE_WUNLOCK(ln);
                    895:
1.134     ozaki-r   896:        if (checklink) {
                    897:                ND6_WLOCK();
1.131     ozaki-r   898:                nd6_pfxlist_onlink_check();
1.134     ozaki-r   899:                ND6_UNLOCK();
                    900:        }
1.116     ozaki-r   901:
1.119     ozaki-r   902:        m_put_rcvif_psref(ifp, &psref);
1.16      itojun    903:        m_freem(m);
1.26      itojun    904:        return;
                    905:
                    906:  bad:
1.115     ozaki-r   907:        if (ln != NULL)
                    908:                LLE_WUNLOCK(ln);
                    909:
1.85      thorpej   910:        ICMP6_STATINC(ICMP6_STAT_BADNA);
1.119     ozaki-r   911:        m_put_rcvif_psref(ifp, &psref);
1.26      itojun    912:        m_freem(m);
1.2       itojun    913: }
                    914:
                    915: /*
                    916:  * Neighbor advertisement output handling.
                    917:  *
                    918:  * Based on RFC 2461
                    919:  *
1.16      itojun    920:  * the following items are not implemented yet:
                    921:  * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
                    922:  * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
1.2       itojun    923:  */
                    924: void
1.83      matt      925: nd6_na_output(
                    926:        struct ifnet *ifp,
                    927:        const struct in6_addr *daddr6_0,
                    928:        const struct in6_addr *taddr6,
                    929:        u_long flags,
                    930:        int tlladdr,            /* 1 if include target link-layer address */
                    931:        const struct sockaddr *sdl0)    /* sockaddr_dl (= proxy NA) or NULL */
1.2       itojun    932: {
                    933:        struct mbuf *m;
                    934:        struct ip6_hdr *ip6;
                    935:        struct nd_neighbor_advert *nd_na;
                    936:        struct ip6_moptions im6o;
1.73      dyoung    937:        struct sockaddr *dst;
                    938:        union {
                    939:                struct sockaddr         dst;
                    940:                struct sockaddr_in6     dst6;
                    941:        } u;
1.129     ozaki-r   942:        struct in6_addr daddr6;
1.39      itojun    943:        int icmp6len, maxlen, error;
1.78      dyoung    944:        const void *mac;
1.73      dyoung    945:        struct route ro;
1.39      itojun    946:
                    947:        mac = NULL;
1.69      dyoung    948:        memset(&ro, 0, sizeof(ro));
1.15      itojun    949:
1.59      rpaulo    950:        daddr6 = *daddr6_0;     /* make a local copy for modification */
                    951:
1.15      itojun    952:        /* estimate the size of message */
                    953:        maxlen = sizeof(*ip6) + sizeof(*nd_na);
                    954:        maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
1.155     maxv      955:        KASSERTMSG(max_linkhdr + maxlen <= MCLBYTES,
                    956:            "max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
1.138     ozaki-r   957:            max_linkhdr, maxlen, MCLBYTES);
1.15      itojun    958:
                    959:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    960:        if (m && max_linkhdr + maxlen >= MHLEN) {
                    961:                MCLGET(m, M_DONTWAIT);
                    962:                if ((m->m_flags & M_EXT) == 0) {
                    963:                        m_free(m);
                    964:                        m = NULL;
                    965:                }
                    966:        }
                    967:        if (m == NULL)
1.2       itojun    968:                return;
1.118     ozaki-r   969:        m_reset_rcvif(m);
1.2       itojun    970:
1.59      rpaulo    971:        if (IN6_IS_ADDR_MULTICAST(&daddr6)) {
1.2       itojun    972:                m->m_flags |= M_MCAST;
1.120     ozaki-r   973:                im6o.im6o_multicast_if_index = if_get_index(ifp);
1.2       itojun    974:                im6o.im6o_multicast_hlim = 255;
                    975:                im6o.im6o_multicast_loop = 0;
                    976:        }
                    977:
                    978:        icmp6len = sizeof(*nd_na);
                    979:        m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
1.164     maxv      980:        m->m_data += max_linkhdr;       /* or m_align() equivalent? */
1.2       itojun    981:
                    982:        /* fill neighbor advertisement packet */
                    983:        ip6 = mtod(m, struct ip6_hdr *);
                    984:        ip6->ip6_flow = 0;
1.10      itojun    985:        ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
                    986:        ip6->ip6_vfc |= IPV6_VERSION;
1.2       itojun    987:        ip6->ip6_nxt = IPPROTO_ICMPV6;
                    988:        ip6->ip6_hlim = 255;
1.59      rpaulo    989:        if (IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
1.2       itojun    990:                /* reply to DAD */
1.59      rpaulo    991:                daddr6.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
                    992:                daddr6.s6_addr16[1] = 0;
                    993:                daddr6.s6_addr32[1] = 0;
                    994:                daddr6.s6_addr32[2] = 0;
                    995:                daddr6.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
                    996:                if (in6_setscope(&daddr6, ifp, NULL))
                    997:                        goto bad;
1.39      itojun    998:
1.2       itojun    999:                flags &= ~ND_NA_FLAG_SOLICITED;
1.39      itojun   1000:        }
1.59      rpaulo   1001:        ip6->ip6_dst = daddr6;
1.73      dyoung   1002:        sockaddr_in6_init(&u.dst6, &daddr6, 0, 0, 0);
                   1003:        dst = &u.dst;
1.108     ozaki-r  1004:        if (rtcache_setdst(&ro, dst) != 0)
                   1005:                goto bad;
1.2       itojun   1006:
                   1007:        /*
                   1008:         * Select a source whose scope is the same as that of the dest.
                   1009:         */
1.129     ozaki-r  1010:        error = in6_selectsrc(satosin6(dst), NULL, NULL, &ro, NULL, NULL, NULL,
                   1011:            &ip6->ip6_src);
                   1012:        if (error != 0) {
1.135     ryo      1013:                char ip6buf[INET6_ADDRSTRLEN];
1.114     ozaki-r  1014:                nd6log(LOG_DEBUG, "source can't be "
1.39      itojun   1015:                    "determined: dst=%s, error=%d\n",
1.136     christos 1016:                    IN6_PRINT(ip6buf, &satocsin6(dst)->sin6_addr), error);
1.39      itojun   1017:                goto bad;
1.2       itojun   1018:        }
                   1019:        nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
                   1020:        nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
                   1021:        nd_na->nd_na_code = 0;
                   1022:        nd_na->nd_na_target = *taddr6;
1.59      rpaulo   1023:        in6_clearscope(&nd_na->nd_na_target); /* XXX */
1.2       itojun   1024:
                   1025:        /*
                   1026:         * "tlladdr" indicates NS's condition for adding tlladdr or not.
                   1027:         * see nd6_ns_input() for details.
                   1028:         * Basically, if NS packet is sent to unicast/anycast addr,
                   1029:         * target lladdr option SHOULD NOT be included.
                   1030:         */
1.16      itojun   1031:        if (tlladdr) {
                   1032:                /*
                   1033:                 * sdl0 != NULL indicates proxy NA.  If we do proxy, use
                   1034:                 * lladdr in sdl0.  If we are not proxying (sending NA for
                   1035:                 * my address) use lladdr configured for the interface.
                   1036:                 */
                   1037:                if (sdl0 == NULL)
                   1038:                        mac = nd6_ifptomac(ifp);
                   1039:                else if (sdl0->sa_family == AF_LINK) {
1.78      dyoung   1040:                        const struct sockaddr_dl *sdl;
                   1041:                        sdl = satocsdl(sdl0);
1.16      itojun   1042:                        if (sdl->sdl_alen == ifp->if_addrlen)
1.78      dyoung   1043:                                mac = CLLADDR(sdl);
1.16      itojun   1044:                }
                   1045:        }
                   1046:        if (tlladdr && mac) {
1.2       itojun   1047:                int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
                   1048:                struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
1.42      itojun   1049:
1.8       is       1050:                /* roundup to 8 bytes alignment! */
                   1051:                optlen = (optlen + 7) & ~7;
                   1052:
1.2       itojun   1053:                m->m_pkthdr.len += optlen;
                   1054:                m->m_len += optlen;
                   1055:                icmp6len += optlen;
1.92      cegger   1056:                memset((void *)nd_opt, 0, optlen);
1.2       itojun   1057:                nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
                   1058:                nd_opt->nd_opt_len = optlen >> 3;
1.94      tsutsui  1059:                memcpy((void *)(nd_opt + 1), mac, ifp->if_addrlen);
1.2       itojun   1060:        } else
                   1061:                flags &= ~ND_NA_FLAG_OVERRIDE;
                   1062:
1.51      itojun   1063:        ip6->ip6_plen = htons((u_int16_t)icmp6len);
1.2       itojun   1064:        nd_na->nd_na_flags_reserved = flags;
                   1065:        nd_na->nd_na_cksum = 0;
                   1066:        nd_na->nd_na_cksum =
1.39      itojun   1067:            in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
1.2       itojun   1068:
1.87      dyoung   1069:        ip6_output(m, NULL, NULL, 0, &im6o, NULL, NULL);
1.32      itojun   1070:
                   1071:        icmp6_ifstat_inc(ifp, ifs6_out_msg);
                   1072:        icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
1.85      thorpej  1073:        ICMP6_STATINC(ICMP6_STAT_OUTHIST + ND_NEIGHBOR_ADVERT);
1.39      itojun   1074:
1.73      dyoung   1075:        rtcache_free(&ro);
1.39      itojun   1076:        return;
                   1077:
                   1078:   bad:
1.73      dyoung   1079:        rtcache_free(&ro);
1.39      itojun   1080:        m_freem(m);
                   1081:        return;
1.2       itojun   1082: }
                   1083:
1.80      dyoung   1084: const void *
                   1085: nd6_ifptomac(const struct ifnet *ifp)
1.2       itojun   1086: {
                   1087:        switch (ifp->if_type) {
1.8       is       1088:        case IFT_ARCNET:
1.2       itojun   1089:        case IFT_ETHER:
                   1090:        case IFT_FDDI:
1.23      onoe     1091:        case IFT_IEEE1394:
1.39      itojun   1092:        case IFT_PROPVIRTUAL:
1.64      liamjfoy 1093:        case IFT_CARP:
1.39      itojun   1094:        case IFT_L2VLAN:
                   1095:        case IFT_IEEE80211:
1.80      dyoung   1096:                return CLLADDR(ifp->if_sadl);
1.2       itojun   1097:        default:
                   1098:                return NULL;
                   1099:        }
                   1100: }
                   1101:
                   1102: TAILQ_HEAD(dadq_head, dadq);
                   1103: struct dadq {
                   1104:        TAILQ_ENTRY(dadq) dad_list;
                   1105:        struct ifaddr *dad_ifa;
1.149     roy      1106:        int dad_count;                  /* max NS to send */
                   1107:        int dad_ns_tcount;              /* # of trials to send NS */
                   1108:        int dad_ns_ocount;              /* NS sent so far */
                   1109:        int dad_ns_lcount;              /* looped back NS */
1.21      itojun   1110:        struct callout dad_timer_ch;
1.149     roy      1111: #define        ND_OPT_NONCE_STORE      3       /* dad_count should not exceed this */
                   1112:        /*
                   1113:         * The default ip6_dad_count is 1 as specified by RFC 4862 and
                   1114:         * practically must users won't exceed this.
                   1115:         * A storage of 3 is defaulted to here, in-case the administrator wants
                   1116:         * to match the equivalent behaviour in our ARP implementation.
                   1117:         * This constraint could be removed by sending the on wire nonce as
                   1118:         * hmac(key, dad_ns_ocount), but that would increase the nonce size
                   1119:         * sent on the wire.
                   1120:         */
                   1121:        uint8_t dad_nonce[ND_OPT_NONCE_STORE][ND_OPT_NONCE_LEN];
1.2       itojun   1122: };
                   1123:
                   1124: static struct dadq_head dadq;
1.26      itojun   1125: static int dad_init = 0;
1.125     ozaki-r  1126: static kmutex_t nd6_dad_lock;
1.2       itojun   1127:
                   1128: static struct dadq *
1.158     roy      1129: nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *nonce, bool *found_nonce)
1.2       itojun   1130: {
1.162     roy      1131:        struct in6_addr *myaddr6, *dadaddr6;
                   1132:        bool match_ifa;
1.2       itojun   1133:        struct dadq *dp;
1.149     roy      1134:        int i, nonce_max;
1.2       itojun   1135:
1.125     ozaki-r  1136:        KASSERT(mutex_owned(&nd6_dad_lock));
1.162     roy      1137:        KASSERT(ifa != NULL);
                   1138:
                   1139:        myaddr6 = IFA_IN6(ifa);
                   1140:        if (nonce != NULL &&
                   1141:            nonce->nd_opt_nonce_len != (ND_OPT_NONCE_LEN + 2) / 8)
                   1142:                nonce = NULL;
                   1143:        match_ifa = nonce == NULL || found_nonce == NULL || *found_nonce == false;
                   1144:        if (found_nonce != NULL)
                   1145:                *found_nonce = false;
1.125     ozaki-r  1146:
1.72      dyoung   1147:        TAILQ_FOREACH(dp, &dadq, dad_list) {
1.162     roy      1148:                if (match_ifa) {
                   1149:                        if (dp->dad_ifa != ifa)
                   1150:                                continue;
                   1151:                } else {
                   1152:                        dadaddr6 = IFA_IN6(dp->dad_ifa);
                   1153:                        if (!IN6_ARE_ADDR_EQUAL(myaddr6, dadaddr6))
                   1154:                                continue;
                   1155:                }
1.149     roy      1156:
1.162     roy      1157:                if (nonce == NULL)
1.149     roy      1158:                        break;
                   1159:
                   1160:                nonce_max = MIN(dp->dad_ns_ocount, ND_OPT_NONCE_STORE);
                   1161:                for (i = 0; i < nonce_max; i++) {
                   1162:                        if (memcmp(nonce->nd_opt_nonce,
                   1163:                            dp->dad_nonce[i],
                   1164:                            ND_OPT_NONCE_LEN) == 0)
                   1165:                                break;
                   1166:                }
                   1167:                if (i < nonce_max) {
                   1168:                        char ip6buf[INET6_ADDRSTRLEN];
                   1169:
1.158     roy      1170:                        *found_nonce = true;
1.149     roy      1171:                        log(LOG_DEBUG,
                   1172:                            "%s: detected a looped back NS message for %s\n",
                   1173:                            ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???",
1.162     roy      1174:                            IN6_PRINT(ip6buf, myaddr6));
1.149     roy      1175:                        dp->dad_ns_lcount++;
                   1176:                        continue;
                   1177:                }
                   1178:
                   1179:                break;
1.2       itojun   1180:        }
1.149     roy      1181:        return dp;
1.2       itojun   1182: }
                   1183:
1.162     roy      1184: static bool
                   1185: nd6_dad_ownnonce(struct ifaddr *ifa, struct nd_opt_nonce *nonce)
                   1186: {
                   1187:        bool found_nonce = true;
                   1188:
                   1189:        mutex_enter(&nd6_dad_lock);
                   1190:        nd6_dad_find(ifa, nonce, &found_nonce);
                   1191:        mutex_exit(&nd6_dad_lock);
                   1192:
                   1193:        return found_nonce;
                   1194: }
                   1195:
1.26      itojun   1196: static void
1.72      dyoung   1197: nd6_dad_starttimer(struct dadq *dp, int ticks)
1.26      itojun   1198: {
                   1199:
                   1200:        callout_reset(&dp->dad_timer_ch, ticks,
1.144     ozaki-r  1201:            (void (*)(void *))nd6_dad_timer, dp);
1.26      itojun   1202: }
                   1203:
                   1204: static void
1.152     ozaki-r  1205: nd6_dad_stoptimer(struct dadq *dp)
1.26      itojun   1206: {
1.152     ozaki-r  1207:
                   1208:        KASSERT(mutex_owned(&nd6_dad_lock));
1.26      itojun   1209:
1.144     ozaki-r  1210:        TAILQ_REMOVE(&dadq, dp, dad_list);
1.152     ozaki-r  1211:        /* Tell the timer that dp is being destroyed. */
1.144     ozaki-r  1212:        dp->dad_ifa = NULL;
1.152     ozaki-r  1213:        callout_halt(&dp->dad_timer_ch, &nd6_dad_lock);
                   1214: }
                   1215:
                   1216: static void
                   1217: nd6_dad_destroytimer(struct dadq *dp)
                   1218: {
                   1219:
                   1220:        KASSERT(dp->dad_ifa == NULL);
                   1221:        callout_destroy(&dp->dad_timer_ch);
                   1222:        kmem_intr_free(dp, sizeof(*dp));
1.26      itojun   1223: }
                   1224:
1.2       itojun   1225: /*
1.61      rpaulo   1226:  * Start Duplicate Address Detection (DAD) for specified interface address.
1.72      dyoung   1227:  *
1.100     ozaki-r  1228:  * Note that callout is used when xtick > 0 and not when xtick == 0.
                   1229:  *
1.72      dyoung   1230:  * xtick: minimum delay ticks for IFF_UP event
1.2       itojun   1231:  */
                   1232: void
1.72      dyoung   1233: nd6_dad_start(struct ifaddr *ifa, int xtick)
1.2       itojun   1234: {
                   1235:        struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
                   1236:        struct dadq *dp;
1.135     ryo      1237:        char ip6buf[INET6_ADDRSTRLEN];
1.2       itojun   1238:
                   1239:        if (!dad_init) {
                   1240:                TAILQ_INIT(&dadq);
1.125     ozaki-r  1241:                mutex_init(&nd6_dad_lock, MUTEX_DEFAULT, IPL_NONE);
1.2       itojun   1242:                dad_init++;
                   1243:        }
                   1244:
                   1245:        /*
                   1246:         * If we don't need DAD, don't do it.
                   1247:         * There are several cases:
1.157     ozaki-r  1248:         * - DAD is disabled
1.2       itojun   1249:         * - the interface address is anycast
                   1250:         */
                   1251:        if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
1.15      itojun   1252:                log(LOG_DEBUG,
                   1253:                        "nd6_dad_start: called with non-tentative address "
1.2       itojun   1254:                        "%s(%s)\n",
1.136     christos 1255:                        IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
1.9       itojun   1256:                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1.2       itojun   1257:                return;
                   1258:        }
1.157     ozaki-r  1259:        if (ia->ia6_flags & IN6_IFF_ANYCAST || !ip6_dad_enabled()) {
1.2       itojun   1260:                ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1.165     roy      1261:                rt_addrmsg(RTM_NEWADDR, ifa);
1.2       itojun   1262:                return;
                   1263:        }
1.124     ozaki-r  1264:        KASSERT(ifa->ifa_ifp != NULL);
1.2       itojun   1265:        if (!(ifa->ifa_ifp->if_flags & IFF_UP))
                   1266:                return;
1.125     ozaki-r  1267:
1.137     ozaki-r  1268:        dp = kmem_intr_alloc(sizeof(*dp), KM_NOSLEEP);
                   1269:
1.125     ozaki-r  1270:        mutex_enter(&nd6_dad_lock);
1.158     roy      1271:        if (nd6_dad_find(ifa, NULL, NULL) != NULL) {
1.125     ozaki-r  1272:                mutex_exit(&nd6_dad_lock);
1.2       itojun   1273:                /* DAD already in progress */
1.137     ozaki-r  1274:                if (dp != NULL)
                   1275:                        kmem_intr_free(dp, sizeof(*dp));
1.2       itojun   1276:                return;
                   1277:        }
                   1278:
                   1279:        if (dp == NULL) {
1.125     ozaki-r  1280:                mutex_exit(&nd6_dad_lock);
1.15      itojun   1281:                log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
1.2       itojun   1282:                        "%s(%s)\n",
1.136     christos 1283:                        IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
1.9       itojun   1284:                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1.2       itojun   1285:                return;
                   1286:        }
                   1287:
                   1288:        /*
                   1289:         * Send NS packet for DAD, ip6_dad_count times.
                   1290:         * Note that we must delay the first transmission, if this is the
                   1291:         * first packet to be sent from the interface after interface
                   1292:         * (re)initialization.
                   1293:         */
1.137     ozaki-r  1294:        callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE);
1.2       itojun   1295:        dp->dad_ifa = ifa;
1.101     rmind    1296:        ifaref(ifa);    /* just for safety */
1.2       itojun   1297:        dp->dad_count = ip6_dad_count;
1.9       itojun   1298:        dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
1.149     roy      1299:        dp->dad_ns_lcount = 0;
1.125     ozaki-r  1300:        TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
                   1301:
                   1302:        nd6log(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
1.136     christos 1303:            IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr));
1.125     ozaki-r  1304:
1.63      rpaulo   1305:        if (xtick == 0) {
1.9       itojun   1306:                nd6_dad_ns_output(dp, ifa);
1.38      itojun   1307:                nd6_dad_starttimer(dp,
1.47      itojun   1308:                    (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1.62      rpaulo   1309:        } else
1.63      rpaulo   1310:                nd6_dad_starttimer(dp, xtick);
1.125     ozaki-r  1311:        mutex_exit(&nd6_dad_lock);
1.2       itojun   1312: }
                   1313:
1.26      itojun   1314: /*
                   1315:  * terminate DAD unconditionally.  used for address removals.
                   1316:  */
                   1317: void
1.72      dyoung   1318: nd6_dad_stop(struct ifaddr *ifa)
1.26      itojun   1319: {
                   1320:        struct dadq *dp;
                   1321:
                   1322:        if (!dad_init)
                   1323:                return;
1.125     ozaki-r  1324:
                   1325:        mutex_enter(&nd6_dad_lock);
1.158     roy      1326:        dp = nd6_dad_find(ifa, NULL, NULL);
1.62      rpaulo   1327:        if (dp == NULL) {
1.125     ozaki-r  1328:                mutex_exit(&nd6_dad_lock);
1.26      itojun   1329:                /* DAD wasn't started yet */
                   1330:                return;
                   1331:        }
                   1332:
1.125     ozaki-r  1333:        /* Prevent the timer from running anymore. */
1.152     ozaki-r  1334:        nd6_dad_stoptimer(dp);
1.144     ozaki-r  1335:
1.125     ozaki-r  1336:        mutex_exit(&nd6_dad_lock);
1.152     ozaki-r  1337:
                   1338:        nd6_dad_destroytimer(dp);
                   1339:        ifafree(ifa);
1.26      itojun   1340: }
                   1341:
1.2       itojun   1342: static void
1.144     ozaki-r  1343: nd6_dad_timer(struct dadq *dp)
1.2       itojun   1344: {
1.144     ozaki-r  1345:        struct ifaddr *ifa;
                   1346:        struct in6_ifaddr *ia;
1.135     ryo      1347:        char ip6buf[INET6_ADDRSTRLEN];
1.137     ozaki-r  1348:        bool need_free = false;
1.2       itojun   1349:
1.152     ozaki-r  1350:        KERNEL_LOCK_UNLESS_NET_MPSAFE();
1.125     ozaki-r  1351:        mutex_enter(&nd6_dad_lock);
1.2       itojun   1352:
1.144     ozaki-r  1353:        ifa = dp->dad_ifa;
                   1354:        if (ifa == NULL) {
1.152     ozaki-r  1355:                /* dp is being destroyed by someone.  Do nothing. */
1.2       itojun   1356:                goto done;
                   1357:        }
1.144     ozaki-r  1358:
                   1359:        ia = (struct in6_ifaddr *)ifa;
1.2       itojun   1360:        if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
1.61      rpaulo   1361:                log(LOG_ERR, "nd6_dad_timer: called with duplicate address "
1.2       itojun   1362:                        "%s(%s)\n",
1.136     christos 1363:                        IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
1.9       itojun   1364:                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1.2       itojun   1365:                goto done;
                   1366:        }
                   1367:        if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
1.15      itojun   1368:                log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
1.2       itojun   1369:                        "%s(%s)\n",
1.136     christos 1370:                        IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr),
1.9       itojun   1371:                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
                   1372:                goto done;
                   1373:        }
                   1374:
                   1375:        /* timeouted with IFF_{RUNNING,UP} check */
                   1376:        if (dp->dad_ns_tcount > dad_maxtry) {
1.114     ozaki-r  1377:                nd6log(LOG_INFO, "%s: could not run DAD, driver problem?\n",
                   1378:                        if_name(ifa->ifa_ifp));
1.9       itojun   1379:
1.152     ozaki-r  1380:                nd6_dad_stoptimer(dp);
1.137     ozaki-r  1381:                need_free = true;
1.2       itojun   1382:                goto done;
                   1383:        }
                   1384:
                   1385:        /* Need more checks? */
1.55      itojun   1386:        if (dp->dad_ns_ocount < dp->dad_count) {
1.2       itojun   1387:                /*
                   1388:                 * We have more NS to go.  Send NS packet for DAD.
                   1389:                 */
1.9       itojun   1390:                nd6_dad_ns_output(dp, ifa);
1.38      itojun   1391:                nd6_dad_starttimer(dp,
1.47      itojun   1392:                    (long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1.2       itojun   1393:        } else {
                   1394:                /*
1.158     roy      1395:                 * We are done with DAD.  No NA came, no NS came.
                   1396:                 * No duplicate address found.
1.2       itojun   1397:                 */
1.158     roy      1398:                ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1.165     roy      1399:                rt_addrmsg(RTM_NEWADDR, ifa);
1.2       itojun   1400:
1.158     roy      1401:                nd6log(LOG_DEBUG,
                   1402:                    "%s: DAD complete for %s - no duplicates found\n",
                   1403:                    if_name(ifa->ifa_ifp),
                   1404:                    IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr));
1.2       itojun   1405:
1.158     roy      1406:                nd6_dad_stoptimer(dp);
                   1407:                need_free = true;
1.2       itojun   1408:        }
                   1409: done:
1.125     ozaki-r  1410:        mutex_exit(&nd6_dad_lock);
1.130     mlelstv  1411:
1.137     ozaki-r  1412:        if (need_free) {
1.152     ozaki-r  1413:                nd6_dad_destroytimer(dp);
                   1414:                KASSERT(ifa != NULL);
                   1415:                ifafree(ifa);
1.137     ozaki-r  1416:        }
                   1417:
1.152     ozaki-r  1418:        KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
1.2       itojun   1419: }
                   1420:
1.133     ozaki-r  1421: static void
1.166   ! roy      1422: nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp,
        !          1423:     const struct sockaddr_dl *from)
1.2       itojun   1424: {
1.147     ozaki-r  1425:        struct in6_ifaddr *ia;
1.62      rpaulo   1426:        struct ifnet *ifp;
1.166   ! roy      1427:        char ip6buf[INET6_ADDRSTRLEN], llabuf[LLA_ADDRSTRLEN], *llastr;
1.2       itojun   1428:
1.147     ozaki-r  1429:        KASSERT(mutex_owned(&nd6_dad_lock));
                   1430:        KASSERT(ifa != NULL);
1.2       itojun   1431:
1.62      rpaulo   1432:        ifp = ifa->ifa_ifp;
1.147     ozaki-r  1433:        ia = (struct in6_ifaddr *)ifa;
1.2       itojun   1434:
                   1435:        ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
                   1436:        ia->ia6_flags |= IN6_IFF_DUPLICATED;
                   1437:
1.166   ! roy      1438:        if (__predict_false(from == NULL))
        !          1439:                llastr = NULL;
        !          1440:        else
        !          1441:                llastr = lla_snprintf(llabuf, sizeof(llabuf),
        !          1442:                    CLLADDR(from), from->sdl_alen);
        !          1443:
        !          1444:        log(LOG_ERR, "%s: DAD duplicate address %s from %s\n",
        !          1445:            if_name(ifp), IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), llastr);
1.62      rpaulo   1446:
1.97      roy      1447:        /* Inform the routing socket that DAD has completed */
1.166   ! roy      1448:        rt_addrmsg_src(RTM_NEWADDR, ifa, (const struct sockaddr *)from);
1.97      roy      1449:
1.62      rpaulo   1450:        /*
                   1451:         * If the address is a link-local address formed from an interface
                   1452:         * identifier based on the hardware address which is supposed to be
                   1453:         * uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP
                   1454:         * operation on the interface SHOULD be disabled.
                   1455:         * [rfc2462bis-03 Section 5.4.5]
                   1456:         */
                   1457:        if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
                   1458:                struct in6_addr in6;
                   1459:
                   1460:                /*
                   1461:                 * To avoid over-reaction, we only apply this logic when we are
                   1462:                 * very sure that hardware addresses are supposed to be unique.
                   1463:                 */
                   1464:                switch (ifp->if_type) {
                   1465:                case IFT_ETHER:
                   1466:                case IFT_FDDI:
                   1467:                case IFT_ATM:
                   1468:                case IFT_IEEE1394:
                   1469:                case IFT_IEEE80211:
                   1470:                        in6 = ia->ia_addr.sin6_addr;
                   1471:                        if (in6_get_hw_ifid(ifp, &in6) == 0 &&
                   1472:                            IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) {
                   1473:                                ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
                   1474:                                log(LOG_ERR, "%s: possible hardware address "
                   1475:                                    "duplication detected, disable IPv6\n",
                   1476:                                    if_name(ifp));
                   1477:                        }
                   1478:                        break;
                   1479:                }
                   1480:        }
1.2       itojun   1481: }
                   1482:
1.9       itojun   1483: static void
1.72      dyoung   1484: nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa)
1.9       itojun   1485: {
                   1486:        struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
                   1487:        struct ifnet *ifp = ifa->ifa_ifp;
1.149     roy      1488:        uint8_t *nonce;
1.9       itojun   1489:
                   1490:        dp->dad_ns_tcount++;
                   1491:        if ((ifp->if_flags & IFF_UP) == 0) {
                   1492: #if 0
                   1493:                printf("%s: interface down?\n", if_name(ifp));
                   1494: #endif
                   1495:                return;
                   1496:        }
                   1497:        if ((ifp->if_flags & IFF_RUNNING) == 0) {
                   1498: #if 0
                   1499:                printf("%s: interface not running?\n", if_name(ifp));
                   1500: #endif
                   1501:                return;
                   1502:        }
                   1503:
1.65      drochner 1504:        dp->dad_ns_tcount = 0;
1.149     roy      1505:        nonce = dp->dad_nonce[dp->dad_ns_ocount % ND_OPT_NONCE_STORE];
                   1506:        cprng_fast(nonce, ND_OPT_NONCE_LEN);
1.9       itojun   1507:        dp->dad_ns_ocount++;
1.149     roy      1508:
                   1509:        nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, nonce);
1.9       itojun   1510: }
                   1511:
                   1512: static void
1.166   ! roy      1513: nd6_dad_input(struct ifaddr *ifa, struct nd_opt_nonce *nonce,
        !          1514:     const struct sockaddr_dl *from)
1.2       itojun   1515: {
                   1516:        struct dadq *dp;
1.158     roy      1517:        bool found_nonce = false;
1.2       itojun   1518:
1.158     roy      1519:        KASSERT(ifa != NULL);
1.125     ozaki-r  1520:
                   1521:        mutex_enter(&nd6_dad_lock);
1.158     roy      1522:        dp = nd6_dad_find(ifa, nonce, &found_nonce);
                   1523:        if (!found_nonce) {
1.166   ! roy      1524:                nd6_dad_duplicated(ifa, dp, from);
1.158     roy      1525:                if (dp != NULL)
1.152     ozaki-r  1526:                        nd6_dad_stoptimer(dp);
1.2       itojun   1527:        }
1.147     ozaki-r  1528:        mutex_exit(&nd6_dad_lock);
1.158     roy      1529:        if (dp != NULL) {
1.152     ozaki-r  1530:                nd6_dad_destroytimer(dp);
                   1531:                ifafree(ifa);
                   1532:        }
1.2       itojun   1533: }

CVSweb <webmaster@jp.NetBSD.org>