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