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