nd6_nbr.c revision 148385
1195534Sscottl/*	$FreeBSD: head/sys/netinet6/nd6_nbr.c 148385 2005-07-25 12:31:43Z ume $	*/
2195534Sscottl/*	$KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $	*/
3195534Sscottl
4195534Sscottl/*-
5195534Sscottl * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6195534Sscottl * All rights reserved.
7195534Sscottl *
8195534Sscottl * Redistribution and use in source and binary forms, with or without
9195534Sscottl * modification, are permitted provided that the following conditions
10195534Sscottl * are met:
11195534Sscottl * 1. Redistributions of source code must retain the above copyright
12195534Sscottl *    notice, this list of conditions and the following disclaimer.
13195534Sscottl * 2. Redistributions in binary form must reproduce the above copyright
14195534Sscottl *    notice, this list of conditions and the following disclaimer in the
15195534Sscottl *    documentation and/or other materials provided with the distribution.
16195534Sscottl * 3. Neither the name of the project nor the names of its contributors
17195534Sscottl *    may be used to endorse or promote products derived from this software
18195534Sscottl *    without specific prior written permission.
19195534Sscottl *
20195534Sscottl * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21195534Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22195534Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23195534Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24195534Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25195534Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26195534Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27195534Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28195534Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29195534Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30195534Sscottl * SUCH DAMAGE.
31195534Sscottl */
32260387Sscottl
33260387Sscottl#include "opt_inet.h"
34195534Sscottl#include "opt_inet6.h"
35195534Sscottl#include "opt_ipsec.h"
36195534Sscottl#include "opt_carp.h"
37195534Sscottl
38195534Sscottl#include <sys/param.h>
39195534Sscottl#include <sys/systm.h>
40195534Sscottl#include <sys/malloc.h>
41195534Sscottl#include <sys/mbuf.h>
42198748Smav#include <sys/socket.h>
43195534Sscottl#include <sys/sockio.h>
44195534Sscottl#include <sys/time.h>
45195534Sscottl#include <sys/kernel.h>
46195534Sscottl#include <sys/errno.h>
47195534Sscottl#include <sys/syslog.h>
48195534Sscottl#include <sys/queue.h>
49204220Smav#include <sys/callout.h>
50195534Sscottl
51195534Sscottl#include <net/if.h>
52195534Sscottl#include <net/if_types.h>
53195534Sscottl#include <net/if_dl.h>
54195534Sscottl#include <net/if_var.h>
55195534Sscottl#include <net/route.h>
56195534Sscottl
57195534Sscottl#include <netinet/in.h>
58195534Sscottl#include <netinet/in_var.h>
59195534Sscottl#include <netinet6/in6_var.h>
60195534Sscottl#include <netinet/ip6.h>
61195534Sscottl#include <netinet6/ip6_var.h>
62195534Sscottl#include <netinet6/scope6_var.h>
63195534Sscottl#include <netinet6/nd6.h>
64195534Sscottl#include <netinet/icmp6.h>
65260387Sscottl
66195534Sscottl#ifdef DEV_CARP
67195534Sscottl#include <netinet/ip_carp.h>
68195534Sscottl#endif
69195534Sscottl
70195534Sscottl#include <net/net_osdep.h>
71195534Sscottl
72195534Sscottl#define SDL(s) ((struct sockaddr_dl *)s)
73195534Sscottl
74195534Sscottlstruct dadq;
75195534Sscottlstatic struct dadq *nd6_dad_find __P((struct ifaddr *));
76195534Sscottlstatic void nd6_dad_starttimer __P((struct dadq *, int));
77195534Sscottlstatic void nd6_dad_stoptimer __P((struct dadq *));
78195534Sscottlstatic void nd6_dad_timer __P((struct ifaddr *));
79195534Sscottlstatic void nd6_dad_ns_output __P((struct dadq *, struct ifaddr *));
80195534Sscottlstatic void nd6_dad_ns_input __P((struct ifaddr *));
81195534Sscottlstatic void nd6_dad_na_input __P((struct ifaddr *));
82216088Sken
83216088Skenstatic int dad_ignore_ns = 0;	/* ignore NS in DAD - specwise incorrect*/
84216088Skenstatic int dad_maxtry = 15;	/* max # of *tries* to transmit DAD packet */
85216088Sken
86223081Sgibbs/*
87223081Sgibbs * Input a Neighbor Solicitation Message.
88230590Sken *
89230590Sken * Based on RFC 2461
90195534Sscottl * Based on RFC 2462 (duplicated address detection)
91195534Sscottl */
92195534Sscottlvoid
93195534Sscottlnd6_ns_input(m, off, icmp6len)
94195534Sscottl	struct mbuf *m;
95195534Sscottl	int off, icmp6len;
96195534Sscottl{
97195534Sscottl	struct ifnet *ifp = m->m_pkthdr.rcvif;
98195534Sscottl	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
99195534Sscottl	struct nd_neighbor_solicit *nd_ns;
100195534Sscottl	struct in6_addr saddr6 = ip6->ip6_src;
101195534Sscottl	struct in6_addr daddr6 = ip6->ip6_dst;
102195534Sscottl	struct in6_addr taddr6;
103195534Sscottl	struct in6_addr myaddr6;
104195534Sscottl	char *lladdr = NULL;
105195534Sscottl	struct ifaddr *ifa = NULL;
106195534Sscottl	int lladdrlen = 0;
107195534Sscottl	int anycast = 0, proxy = 0, tentative = 0;
108195534Sscottl	int tlladdr;
109198331Smav	union nd_opts ndopts;
110195534Sscottl	struct sockaddr_dl *proxydl = NULL;
111195534Sscottl
112195534Sscottl#ifndef PULLDOWN_TEST
113195534Sscottl	IP6_EXTHDR_CHECK(m, off, icmp6len,);
114195534Sscottl	nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
115253958Smav#else
116260387Sscottl	IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len);
117260387Sscottl	if (nd_ns == NULL) {
118195534Sscottl		icmp6stat.icp6s_tooshort++;
119195534Sscottl		return;
120195534Sscottl	}
121195534Sscottl#endif
122195534Sscottl	ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */
123195534Sscottl	taddr6 = nd_ns->nd_ns_target;
124195534Sscottl	if (in6_setscope(&taddr6, ifp, NULL) != 0)
125195534Sscottl		goto bad;
126195534Sscottl
127195534Sscottl	if (ip6->ip6_hlim != 255) {
128195534Sscottl		nd6log((LOG_ERR,
129195534Sscottl		    "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
130195534Sscottl		    ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
131195534Sscottl		    ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
132195534Sscottl		goto bad;
133195534Sscottl	}
134208911Smjacob
135208911Smjacob	if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
136260387Sscottl		/* dst has to be solicited node multicast address. */
137195534Sscottl		if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
138195534Sscottl		    /* don't check ifindex portion */
139195534Sscottl		    daddr6.s6_addr32[1] == 0 &&
140195534Sscottl		    daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
141195534Sscottl		    daddr6.s6_addr8[12] == 0xff) {
142195534Sscottl			; /* good */
143195534Sscottl		} else {
144195534Sscottl			nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
145195534Sscottl			    "(wrong ip6 dst)\n"));
146195534Sscottl			goto bad;
147195534Sscottl		}
148195534Sscottl	}
149195534Sscottl
150195534Sscottl	if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
151195534Sscottl		nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
152195534Sscottl		goto bad;
153195534Sscottl	}
154195534Sscottl
155195534Sscottl	icmp6len -= sizeof(*nd_ns);
156260387Sscottl	nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
157195534Sscottl	if (nd6_options(&ndopts) < 0) {
158195534Sscottl		nd6log((LOG_INFO,
159195534Sscottl		    "nd6_ns_input: invalid ND option, ignored\n"));
160195534Sscottl		/* nd6_options have incremented stats */
161195534Sscottl		goto freeit;
162195534Sscottl	}
163195534Sscottl
164195534Sscottl	if (ndopts.nd_opts_src_lladdr) {
165195534Sscottl		lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
166195534Sscottl		lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
167195534Sscottl	}
168195534Sscottl
169195534Sscottl	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
170195534Sscottl		nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
171195534Sscottl		    "(link-layer address option)\n"));
172198748Smav		goto bad;
173198748Smav	}
174195534Sscottl
175199178Smav	/*
176199178Smav	 * Attaching target link-layer address to the NA?
177195534Sscottl	 * (RFC 2461 7.2.4)
178195534Sscottl	 *
179195534Sscottl	 * NS IP dst is unicast/anycast			MUST NOT add
180195534Sscottl	 * NS IP dst is solicited-node multicast	MUST add
181	 *
182	 * In implementation, we add target link-layer address by default.
183	 * We do not add one in MUST NOT cases.
184	 */
185#if 0 /* too much! */
186	ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &daddr6);
187	if (ifa && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST))
188		tlladdr = 0;
189	else
190#endif
191	if (!IN6_IS_ADDR_MULTICAST(&daddr6))
192		tlladdr = 0;
193	else
194		tlladdr = 1;
195
196	/*
197	 * Target address (taddr6) must be either:
198	 * (1) Valid unicast/anycast address for my receiving interface,
199	 * (2) Unicast address for which I'm offering proxy service, or
200	 * (3) "tentative" address on which DAD is being performed.
201	 */
202	/* (1) and (3) check. */
203#ifdef DEV_CARP
204	if (ifp->if_carp)
205		ifa = carp_iamatch6(ifp->if_carp, &taddr6);
206	if (!ifa)
207		ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
208#else
209	ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
210#endif
211
212	/* (2) check. */
213	if (!ifa) {
214		struct rtentry *rt;
215		struct sockaddr_in6 tsin6;
216		int need_proxy;
217
218		bzero(&tsin6, sizeof tsin6);
219		tsin6.sin6_len = sizeof(struct sockaddr_in6);
220		tsin6.sin6_family = AF_INET6;
221		tsin6.sin6_addr = taddr6;
222
223		rt = rtalloc1((struct sockaddr *)&tsin6, 0, 0);
224		need_proxy = (rt && (rt->rt_flags & RTF_ANNOUNCE) != 0 &&
225		    rt->rt_gateway->sa_family == AF_LINK);
226		if (rt)
227			rtfree(rt);
228		if (need_proxy) {
229			/*
230			 * proxy NDP for single entry
231			 */
232			ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
233				IN6_IFF_NOTREADY|IN6_IFF_ANYCAST);
234			if (ifa) {
235				proxy = 1;
236				proxydl = SDL(rt->rt_gateway);
237			}
238		}
239	}
240	if (!ifa) {
241		/*
242		 * We've got an NS packet, and we don't have that adddress
243		 * assigned for us.  We MUST silently ignore it.
244		 * See RFC2461 7.2.3.
245		 */
246		goto freeit;
247	}
248	myaddr6 = *IFA_IN6(ifa);
249	anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
250	tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
251	if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
252		goto freeit;
253
254	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
255		nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s "
256		    "(if %d, NS packet %d)\n",
257		    ip6_sprintf(&taddr6),
258		    ifp->if_addrlen, lladdrlen - 2));
259		goto bad;
260	}
261
262	if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
263		nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n",
264		    ip6_sprintf(&saddr6)));
265		goto freeit;
266	}
267
268	/*
269	 * We have neighbor solicitation packet, with target address equals to
270	 * one of my tentative address.
271	 *
272	 * src addr	how to process?
273	 * ---		---
274	 * multicast	of course, invalid (rejected in ip6_input)
275	 * unicast	somebody is doing address resolution -> ignore
276	 * unspec	dup address detection
277	 *
278	 * The processing is defined in RFC 2462.
279	 */
280	if (tentative) {
281		/*
282		 * If source address is unspecified address, it is for
283		 * duplicated address detection.
284		 *
285		 * If not, the packet is for addess resolution;
286		 * silently ignore it.
287		 */
288		if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
289			nd6_dad_ns_input(ifa);
290
291		goto freeit;
292	}
293
294	/*
295	 * If the source address is unspecified address, entries must not
296	 * be created or updated.
297	 * It looks that sender is performing DAD.  Output NA toward
298	 * all-node multicast address, to tell the sender that I'm using
299	 * the address.
300	 * S bit ("solicited") must be zero.
301	 */
302	if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
303		struct in6_addr in6_all;
304
305		in6_all = in6addr_linklocal_allnodes;
306		if (in6_setscope(&in6_all, ifp, NULL) != 0)
307			goto bad;
308		nd6_na_output(ifp, &in6_all, &taddr6,
309		    ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
310		    (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0),
311		    tlladdr, (struct sockaddr *)proxydl);
312		goto freeit;
313	}
314
315	nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen,
316	    ND_NEIGHBOR_SOLICIT, 0);
317
318	nd6_na_output(ifp, &saddr6, &taddr6,
319	    ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
320	    (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED,
321	    tlladdr, (struct sockaddr *)proxydl);
322 freeit:
323	m_freem(m);
324	return;
325
326 bad:
327	nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6)));
328	nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6)));
329	nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6)));
330	icmp6stat.icp6s_badns++;
331	m_freem(m);
332}
333
334/*
335 * Output a Neighbor Solicitation Message. Caller specifies:
336 *	- ICMP6 header source IP6 address
337 *	- ND6 header target IP6 address
338 *	- ND6 header source datalink address
339 *
340 * Based on RFC 2461
341 * Based on RFC 2462 (duplicated address detection)
342 */
343void
344nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
345	struct ifnet *ifp;
346	const struct in6_addr *daddr6, *taddr6;
347	struct llinfo_nd6 *ln;	/* for source address determination */
348	int dad;	/* duplicated address detection */
349{
350	struct mbuf *m;
351	struct ip6_hdr *ip6;
352	struct nd_neighbor_solicit *nd_ns;
353	struct in6_addr *src, src_in;
354	struct ip6_moptions im6o;
355	int icmp6len;
356	int maxlen;
357	caddr_t mac;
358	struct route_in6 ro;
359
360	bzero(&ro, sizeof(ro));
361
362	if (IN6_IS_ADDR_MULTICAST(taddr6))
363		return;
364
365	/* estimate the size of message */
366	maxlen = sizeof(*ip6) + sizeof(*nd_ns);
367	maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
368	if (max_linkhdr + maxlen >= MCLBYTES) {
369#ifdef DIAGNOSTIC
370		printf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES "
371		    "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
372#endif
373		return;
374	}
375
376	MGETHDR(m, M_DONTWAIT, MT_DATA);
377	if (m && max_linkhdr + maxlen >= MHLEN) {
378		MCLGET(m, M_DONTWAIT);
379		if ((m->m_flags & M_EXT) == 0) {
380			m_free(m);
381			m = NULL;
382		}
383	}
384	if (m == NULL)
385		return;
386	m->m_pkthdr.rcvif = NULL;
387
388	if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) {
389		m->m_flags |= M_MCAST;
390		im6o.im6o_multicast_ifp = ifp;
391		im6o.im6o_multicast_hlim = 255;
392		im6o.im6o_multicast_loop = 0;
393	}
394
395	icmp6len = sizeof(*nd_ns);
396	m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
397	m->m_data += max_linkhdr;	/* or MH_ALIGN() equivalent? */
398
399	/* fill neighbor solicitation packet */
400	ip6 = mtod(m, struct ip6_hdr *);
401	ip6->ip6_flow = 0;
402	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
403	ip6->ip6_vfc |= IPV6_VERSION;
404	/* ip6->ip6_plen will be set later */
405	ip6->ip6_nxt = IPPROTO_ICMPV6;
406	ip6->ip6_hlim = 255;
407	if (daddr6)
408		ip6->ip6_dst = *daddr6;
409	else {
410		ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
411		ip6->ip6_dst.s6_addr16[1] = 0;
412		ip6->ip6_dst.s6_addr32[1] = 0;
413		ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
414		ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
415		ip6->ip6_dst.s6_addr8[12] = 0xff;
416		if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
417			goto bad;
418	}
419	if (!dad) {
420		/*
421		 * RFC2461 7.2.2:
422		 * "If the source address of the packet prompting the
423		 * solicitation is the same as one of the addresses assigned
424		 * to the outgoing interface, that address SHOULD be placed
425		 * in the IP Source Address of the outgoing solicitation.
426		 * Otherwise, any one of the addresses assigned to the
427		 * interface should be used."
428		 *
429		 * We use the source address for the prompting packet
430		 * (saddr6), if:
431		 * - saddr6 is given from the caller (by giving "ln"), and
432		 * - saddr6 belongs to the outgoing interface.
433		 * Otherwise, we perform the source address selection as usual.
434		 */
435		struct ip6_hdr *hip6;		/* hold ip6 */
436		struct in6_addr *hsrc = NULL;
437
438		if (ln && ln->ln_hold) {
439			hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
440			/* XXX pullup? */
441			if (sizeof(*hip6) < ln->ln_hold->m_len)
442				hsrc = &hip6->ip6_src;
443			else
444				hsrc = NULL;
445		}
446		if (hsrc && in6ifa_ifpwithaddr(ifp, hsrc))
447			src = hsrc;
448		else {
449			int error;
450			struct sockaddr_in6 dst_sa;
451
452			bzero(&dst_sa, sizeof(dst_sa));
453			dst_sa.sin6_family = AF_INET6;
454			dst_sa.sin6_len = sizeof(dst_sa);
455			dst_sa.sin6_addr = ip6->ip6_dst;
456
457			src = in6_selectsrc(&dst_sa, NULL,
458			    NULL, &ro, NULL, NULL, &error);
459			if (src == NULL) {
460				nd6log((LOG_DEBUG,
461				    "nd6_ns_output: source can't be "
462				    "determined: dst=%s, error=%d\n",
463				    ip6_sprintf(&dst_sa.sin6_addr), error));
464				goto bad;
465			}
466		}
467	} else {
468		/*
469		 * Source address for DAD packet must always be IPv6
470		 * unspecified address. (0::0)
471		 * We actually don't have to 0-clear the address (we did it
472		 * above), but we do so here explicitly to make the intention
473		 * clearer.
474		 */
475		bzero(&src_in, sizeof(src_in));
476		src = &src_in;
477	}
478	ip6->ip6_src = *src;
479	nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
480	nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
481	nd_ns->nd_ns_code = 0;
482	nd_ns->nd_ns_reserved = 0;
483	nd_ns->nd_ns_target = *taddr6;
484	in6_clearscope(&nd_ns->nd_ns_target); /* XXX */
485
486	/*
487	 * Add source link-layer address option.
488	 *
489	 *				spec		implementation
490	 *				---		---
491	 * DAD packet			MUST NOT	do not add the option
492	 * there's no link layer address:
493	 *				impossible	do not add the option
494	 * there's link layer address:
495	 *	Multicast NS		MUST add one	add the option
496	 *	Unicast NS		SHOULD add one	add the option
497	 */
498	if (!dad && (mac = nd6_ifptomac(ifp))) {
499		int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
500		struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
501		/* 8 byte alignments... */
502		optlen = (optlen + 7) & ~7;
503
504		m->m_pkthdr.len += optlen;
505		m->m_len += optlen;
506		icmp6len += optlen;
507		bzero((caddr_t)nd_opt, optlen);
508		nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
509		nd_opt->nd_opt_len = optlen >> 3;
510		bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
511	}
512
513	ip6->ip6_plen = htons((u_short)icmp6len);
514	nd_ns->nd_ns_cksum = 0;
515	nd_ns->nd_ns_cksum =
516	    in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
517
518	ip6_output(m, NULL, &ro, dad ? IPV6_DADOUTPUT : 0, &im6o, NULL, NULL);
519	icmp6_ifstat_inc(ifp, ifs6_out_msg);
520	icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
521	icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
522
523	if (ro.ro_rt) {		/* we don't cache this route. */
524		RTFREE(ro.ro_rt);
525	}
526	return;
527
528  bad:
529	if (ro.ro_rt) {
530		RTFREE(ro.ro_rt);
531	}
532	m_freem(m);
533	return;
534}
535
536/*
537 * Neighbor advertisement input handling.
538 *
539 * Based on RFC 2461
540 * Based on RFC 2462 (duplicated address detection)
541 *
542 * the following items are not implemented yet:
543 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
544 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
545 */
546void
547nd6_na_input(m, off, icmp6len)
548	struct mbuf *m;
549	int off, icmp6len;
550{
551	struct ifnet *ifp = m->m_pkthdr.rcvif;
552	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
553	struct nd_neighbor_advert *nd_na;
554	struct in6_addr daddr6 = ip6->ip6_dst;
555	struct in6_addr taddr6;
556	int flags;
557	int is_router;
558	int is_solicited;
559	int is_override;
560	char *lladdr = NULL;
561	int lladdrlen = 0;
562	struct ifaddr *ifa;
563	struct llinfo_nd6 *ln;
564	struct rtentry *rt;
565	struct sockaddr_dl *sdl;
566	union nd_opts ndopts;
567
568	if (ip6->ip6_hlim != 255) {
569		nd6log((LOG_ERR,
570		    "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
571		    ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
572		    ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
573		goto bad;
574	}
575
576#ifndef PULLDOWN_TEST
577	IP6_EXTHDR_CHECK(m, off, icmp6len,);
578	nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
579#else
580	IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len);
581	if (nd_na == NULL) {
582		icmp6stat.icp6s_tooshort++;
583		return;
584	}
585#endif
586
587	flags = nd_na->nd_na_flags_reserved;
588	is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
589	is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
590	is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
591
592	taddr6 = nd_na->nd_na_target;
593	if (in6_setscope(&taddr6, ifp, NULL))
594		return;		/* XXX: impossible */
595
596	if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
597		nd6log((LOG_ERR,
598		    "nd6_na_input: invalid target address %s\n",
599		    ip6_sprintf(&taddr6)));
600		goto bad;
601	}
602	if (IN6_IS_ADDR_MULTICAST(&daddr6))
603		if (is_solicited) {
604			nd6log((LOG_ERR,
605			    "nd6_na_input: a solicited adv is multicasted\n"));
606			goto bad;
607		}
608
609	icmp6len -= sizeof(*nd_na);
610	nd6_option_init(nd_na + 1, icmp6len, &ndopts);
611	if (nd6_options(&ndopts) < 0) {
612		nd6log((LOG_INFO,
613		    "nd6_na_input: invalid ND option, ignored\n"));
614		/* nd6_options have incremented stats */
615		goto freeit;
616	}
617
618	if (ndopts.nd_opts_tgt_lladdr) {
619		lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
620		lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
621	}
622
623	ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
624
625	/*
626	 * Target address matches one of my interface address.
627	 *
628	 * If my address is tentative, this means that there's somebody
629	 * already using the same address as mine.  This indicates DAD failure.
630	 * This is defined in RFC 2462.
631	 *
632	 * Otherwise, process as defined in RFC 2461.
633	 */
634	if (ifa
635	 && (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
636		nd6_dad_na_input(ifa);
637		goto freeit;
638	}
639
640	/* Just for safety, maybe unnecessary. */
641	if (ifa) {
642		log(LOG_ERR,
643		    "nd6_na_input: duplicate IP6 address %s\n",
644		    ip6_sprintf(&taddr6));
645		goto freeit;
646	}
647
648	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
649		nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
650		    "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
651		    ifp->if_addrlen, lladdrlen - 2));
652		goto bad;
653	}
654
655	/*
656	 * If no neighbor cache entry is found, NA SHOULD silently be
657	 * discarded.
658	 */
659	rt = nd6_lookup(&taddr6, 0, ifp);
660	if ((rt == NULL) ||
661	   ((ln = (struct llinfo_nd6 *)rt->rt_llinfo) == NULL) ||
662	   ((sdl = SDL(rt->rt_gateway)) == NULL))
663		goto freeit;
664
665	if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
666		/*
667		 * If the link-layer has address, and no lladdr option came,
668		 * discard the packet.
669		 */
670		if (ifp->if_addrlen && !lladdr)
671			goto freeit;
672
673		/*
674		 * Record link-layer address, and update the state.
675		 */
676		sdl->sdl_alen = ifp->if_addrlen;
677		bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
678		if (is_solicited) {
679			ln->ln_state = ND6_LLINFO_REACHABLE;
680			ln->ln_byhint = 0;
681			if (ln->ln_expire) {
682				ln->ln_expire = time_second +
683				    ND_IFINFO(rt->rt_ifp)->reachable;
684			}
685		} else {
686			ln->ln_state = ND6_LLINFO_STALE;
687			ln->ln_expire = time_second + nd6_gctimer;
688		}
689		if ((ln->ln_router = is_router) != 0) {
690			/*
691			 * This means a router's state has changed from
692			 * non-reachable to probably reachable, and might
693			 * affect the status of associated prefixes..
694			 */
695			pfxlist_onlink_check();
696		}
697	} else {
698		int llchange;
699
700		/*
701		 * Check if the link-layer address has changed or not.
702		 */
703		if (!lladdr)
704			llchange = 0;
705		else {
706			if (sdl->sdl_alen) {
707				if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen))
708					llchange = 1;
709				else
710					llchange = 0;
711			} else
712				llchange = 1;
713		}
714
715		/*
716		 * This is VERY complex.  Look at it with care.
717		 *
718		 * override solicit lladdr llchange	action
719		 *					(L: record lladdr)
720		 *
721		 *	0	0	n	--	(2c)
722		 *	0	0	y	n	(2b) L
723		 *	0	0	y	y	(1)    REACHABLE->STALE
724		 *	0	1	n	--	(2c)   *->REACHABLE
725		 *	0	1	y	n	(2b) L *->REACHABLE
726		 *	0	1	y	y	(1)    REACHABLE->STALE
727		 *	1	0	n	--	(2a)
728		 *	1	0	y	n	(2a) L
729		 *	1	0	y	y	(2a) L *->STALE
730		 *	1	1	n	--	(2a)   *->REACHABLE
731		 *	1	1	y	n	(2a) L *->REACHABLE
732		 *	1	1	y	y	(2a) L *->REACHABLE
733		 */
734		if (!is_override && (lladdr && llchange)) {	   /* (1) */
735			/*
736			 * If state is REACHABLE, make it STALE.
737			 * no other updates should be done.
738			 */
739			if (ln->ln_state == ND6_LLINFO_REACHABLE) {
740				ln->ln_state = ND6_LLINFO_STALE;
741				ln->ln_expire = time_second + nd6_gctimer;
742			}
743			goto freeit;
744		} else if (is_override				   /* (2a) */
745			|| (!is_override && (lladdr && !llchange)) /* (2b) */
746			|| !lladdr) {				   /* (2c) */
747			/*
748			 * Update link-local address, if any.
749			 */
750			if (lladdr) {
751				sdl->sdl_alen = ifp->if_addrlen;
752				bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen);
753			}
754
755			/*
756			 * If solicited, make the state REACHABLE.
757			 * If not solicited and the link-layer address was
758			 * changed, make it STALE.
759			 */
760			if (is_solicited) {
761				ln->ln_state = ND6_LLINFO_REACHABLE;
762				ln->ln_byhint = 0;
763				if (ln->ln_expire) {
764					ln->ln_expire = time_second +
765					    ND_IFINFO(ifp)->reachable;
766				}
767			} else {
768				if (lladdr && llchange) {
769					ln->ln_state = ND6_LLINFO_STALE;
770					ln->ln_expire = time_second + nd6_gctimer;
771				}
772			}
773		}
774
775		if (ln->ln_router && !is_router) {
776			/*
777			 * The peer dropped the router flag.
778			 * Remove the sender from the Default Router List and
779			 * update the Destination Cache entries.
780			 */
781			struct nd_defrouter *dr;
782			struct in6_addr *in6;
783			int s;
784
785			in6 = &((struct sockaddr_in6 *)rt_key(rt))->sin6_addr;
786
787			/*
788			 * Lock to protect the default router list.
789			 * XXX: this might be unnecessary, since this function
790			 * is only called under the network software interrupt
791			 * context.  However, we keep it just for safety.
792			 */
793			s = splnet();
794			dr = defrouter_lookup(in6, ifp);
795			if (dr)
796				defrtrlist_del(dr);
797			else if (!ip6_forwarding && ip6_accept_rtadv) {
798				/*
799				 * Even if the neighbor is not in the default
800				 * router list, the neighbor may be used
801				 * as a next hop for some destinations
802				 * (e.g. redirect case). So we must
803				 * call rt6_flush explicitly.
804				 */
805				rt6_flush(&ip6->ip6_src, ifp);
806			}
807			splx(s);
808		}
809		ln->ln_router = is_router;
810	}
811	rt->rt_flags &= ~RTF_REJECT;
812	ln->ln_asked = 0;
813	if (ln->ln_hold) {
814		/*
815		 * we assume ifp is not a loopback here, so just set the 2nd
816		 * argument as the 1st one.
817		 */
818		nd6_output(ifp, ifp, ln->ln_hold,
819			   (struct sockaddr_in6 *)rt_key(rt), rt);
820		ln->ln_hold = NULL;
821	}
822
823 freeit:
824	m_freem(m);
825	return;
826
827 bad:
828	icmp6stat.icp6s_badna++;
829	m_freem(m);
830}
831
832/*
833 * Neighbor advertisement output handling.
834 *
835 * Based on RFC 2461
836 *
837 * the following items are not implemented yet:
838 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
839 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
840 */
841void
842nd6_na_output(ifp, daddr6_0, taddr6, flags, tlladdr, sdl0)
843	struct ifnet *ifp;
844	const struct in6_addr *daddr6_0, *taddr6;
845	u_long flags;
846	int tlladdr;		/* 1 if include target link-layer address */
847	struct sockaddr *sdl0;	/* sockaddr_dl (= proxy NA) or NULL */
848{
849	struct mbuf *m;
850	struct ip6_hdr *ip6;
851	struct nd_neighbor_advert *nd_na;
852	struct ip6_moptions im6o;
853	struct in6_addr *src, daddr6;
854	struct sockaddr_in6 dst_sa;
855	int icmp6len, maxlen, error;
856	caddr_t mac = NULL;
857	struct route_in6 ro;
858
859	bzero(&ro, sizeof(ro));
860
861	daddr6 = *daddr6_0;	/* make a local copy for modification */
862
863	/* estimate the size of message */
864	maxlen = sizeof(*ip6) + sizeof(*nd_na);
865	maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
866	if (max_linkhdr + maxlen >= MCLBYTES) {
867#ifdef DIAGNOSTIC
868		printf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES "
869		    "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES);
870#endif
871		return;
872	}
873
874	MGETHDR(m, M_DONTWAIT, MT_DATA);
875	if (m && max_linkhdr + maxlen >= MHLEN) {
876		MCLGET(m, M_DONTWAIT);
877		if ((m->m_flags & M_EXT) == 0) {
878			m_free(m);
879			m = NULL;
880		}
881	}
882	if (m == NULL)
883		return;
884	m->m_pkthdr.rcvif = NULL;
885
886	if (IN6_IS_ADDR_MULTICAST(&daddr6)) {
887		m->m_flags |= M_MCAST;
888		im6o.im6o_multicast_ifp = ifp;
889		im6o.im6o_multicast_hlim = 255;
890		im6o.im6o_multicast_loop = 0;
891	}
892
893	icmp6len = sizeof(*nd_na);
894	m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
895	m->m_data += max_linkhdr;	/* or MH_ALIGN() equivalent? */
896
897	/* fill neighbor advertisement packet */
898	ip6 = mtod(m, struct ip6_hdr *);
899	ip6->ip6_flow = 0;
900	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
901	ip6->ip6_vfc |= IPV6_VERSION;
902	ip6->ip6_nxt = IPPROTO_ICMPV6;
903	ip6->ip6_hlim = 255;
904	if (IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
905		/* reply to DAD */
906		ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
907		ip6->ip6_dst.s6_addr16[1] = 0;
908		ip6->ip6_dst.s6_addr32[1] = 0;
909		ip6->ip6_dst.s6_addr32[2] = 0;
910		ip6->ip6_dst.s6_addr32[3] = IPV6_ADDR_INT32_ONE;
911		if (in6_setscope(&daddr6, ifp, NULL))
912			goto bad;
913
914		flags &= ~ND_NA_FLAG_SOLICITED;
915	}
916	ip6->ip6_dst = daddr6;
917	bzero(&dst_sa, sizeof(struct sockaddr_in6));
918	dst_sa.sin6_family = AF_INET6;
919	dst_sa.sin6_len = sizeof(struct sockaddr_in6);
920	dst_sa.sin6_addr = daddr6;
921
922	/*
923	 * Select a source whose scope is the same as that of the dest.
924	 */
925	bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
926	src = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, NULL, &error);
927	if (src == NULL) {
928		nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
929		    "determined: dst=%s, error=%d\n",
930		    ip6_sprintf(&dst_sa.sin6_addr), error));
931		goto bad;
932	}
933	ip6->ip6_src = *src;
934	nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
935	nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
936	nd_na->nd_na_code = 0;
937	nd_na->nd_na_target = *taddr6;
938	in6_clearscope(&nd_na->nd_na_target); /* XXX */
939
940	/*
941	 * "tlladdr" indicates NS's condition for adding tlladdr or not.
942	 * see nd6_ns_input() for details.
943	 * Basically, if NS packet is sent to unicast/anycast addr,
944	 * target lladdr option SHOULD NOT be included.
945	 */
946	if (tlladdr) {
947		/*
948		 * sdl0 != NULL indicates proxy NA.  If we do proxy, use
949		 * lladdr in sdl0.  If we are not proxying (sending NA for
950		 * my address) use lladdr configured for the interface.
951		 */
952		if (sdl0 == NULL) {
953#ifdef DEV_CARP
954			if (ifp->if_carp)
955				mac = carp_macmatch6(ifp->if_carp, m, taddr6);
956			if (mac == NULL)
957				mac = nd6_ifptomac(ifp);
958#else
959			mac = nd6_ifptomac(ifp);
960#endif
961		} else if (sdl0->sa_family == AF_LINK) {
962			struct sockaddr_dl *sdl;
963			sdl = (struct sockaddr_dl *)sdl0;
964			if (sdl->sdl_alen == ifp->if_addrlen)
965				mac = LLADDR(sdl);
966		}
967	}
968	if (tlladdr && mac) {
969		int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
970		struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
971
972		/* roundup to 8 bytes alignment! */
973		optlen = (optlen + 7) & ~7;
974
975		m->m_pkthdr.len += optlen;
976		m->m_len += optlen;
977		icmp6len += optlen;
978		bzero((caddr_t)nd_opt, optlen);
979		nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
980		nd_opt->nd_opt_len = optlen >> 3;
981		bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
982	} else
983		flags &= ~ND_NA_FLAG_OVERRIDE;
984
985	ip6->ip6_plen = htons((u_short)icmp6len);
986	nd_na->nd_na_flags_reserved = flags;
987	nd_na->nd_na_cksum = 0;
988	nd_na->nd_na_cksum =
989	    in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
990
991	ip6_output(m, NULL, &ro, 0, &im6o, NULL, NULL);
992	icmp6_ifstat_inc(ifp, ifs6_out_msg);
993	icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
994	icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++;
995
996	if (ro.ro_rt) {		/* we don't cache this route. */
997		RTFREE(ro.ro_rt);
998	}
999	return;
1000
1001  bad:
1002	if (ro.ro_rt) {
1003		RTFREE(ro.ro_rt);
1004	}
1005	m_freem(m);
1006	return;
1007}
1008
1009caddr_t
1010nd6_ifptomac(ifp)
1011	struct ifnet *ifp;
1012{
1013	switch (ifp->if_type) {
1014	case IFT_ARCNET:
1015	case IFT_ETHER:
1016	case IFT_FDDI:
1017	case IFT_IEEE1394:
1018#ifdef IFT_L2VLAN
1019	case IFT_L2VLAN:
1020#endif
1021#ifdef IFT_IEEE80211
1022	case IFT_IEEE80211:
1023#endif
1024#ifdef IFT_CARP
1025	case IFT_CARP:
1026#endif
1027	case IFT_ISO88025:
1028		return IF_LLADDR(ifp);
1029	default:
1030		return NULL;
1031	}
1032}
1033
1034TAILQ_HEAD(dadq_head, dadq);
1035struct dadq {
1036	TAILQ_ENTRY(dadq) dad_list;
1037	struct ifaddr *dad_ifa;
1038	int dad_count;		/* max NS to send */
1039	int dad_ns_tcount;	/* # of trials to send NS */
1040	int dad_ns_ocount;	/* NS sent so far */
1041	int dad_ns_icount;
1042	int dad_na_icount;
1043	struct callout dad_timer_ch;
1044};
1045
1046static struct dadq_head dadq;
1047static int dad_init = 0;
1048
1049static struct dadq *
1050nd6_dad_find(ifa)
1051	struct ifaddr *ifa;
1052{
1053	struct dadq *dp;
1054
1055	for (dp = dadq.tqh_first; dp; dp = dp->dad_list.tqe_next) {
1056		if (dp->dad_ifa == ifa)
1057			return dp;
1058	}
1059	return NULL;
1060}
1061
1062static void
1063nd6_dad_starttimer(dp, ticks)
1064	struct dadq *dp;
1065	int ticks;
1066{
1067
1068	callout_reset(&dp->dad_timer_ch, ticks,
1069	    (void (*) __P((void *)))nd6_dad_timer, (void *)dp->dad_ifa);
1070}
1071
1072static void
1073nd6_dad_stoptimer(dp)
1074	struct dadq *dp;
1075{
1076
1077	callout_stop(&dp->dad_timer_ch);
1078}
1079
1080/*
1081 * Start Duplicated Address Detection (DAD) for specified interface address.
1082 */
1083void
1084nd6_dad_start(ifa, tick)
1085	struct ifaddr *ifa;
1086	int *tick;	/* minimum delay ticks for IFF_UP event */
1087{
1088	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1089	struct dadq *dp;
1090
1091	if (!dad_init) {
1092		TAILQ_INIT(&dadq);
1093		dad_init++;
1094	}
1095
1096	/*
1097	 * If we don't need DAD, don't do it.
1098	 * There are several cases:
1099	 * - DAD is disabled (ip6_dad_count == 0)
1100	 * - the interface address is anycast
1101	 */
1102	if (!(ia->ia6_flags & IN6_IFF_TENTATIVE)) {
1103		log(LOG_DEBUG,
1104			"nd6_dad_start: called with non-tentative address "
1105			"%s(%s)\n",
1106			ip6_sprintf(&ia->ia_addr.sin6_addr),
1107			ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1108		return;
1109	}
1110	if (ia->ia6_flags & IN6_IFF_ANYCAST) {
1111		ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1112		return;
1113	}
1114	if (!ip6_dad_count) {
1115		ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1116		return;
1117	}
1118	if (!ifa->ifa_ifp)
1119		panic("nd6_dad_start: ifa->ifa_ifp == NULL");
1120	if (!(ifa->ifa_ifp->if_flags & IFF_UP)) {
1121		return;
1122	}
1123	if (nd6_dad_find(ifa) != NULL) {
1124		/* DAD already in progress */
1125		return;
1126	}
1127
1128	dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT);
1129	if (dp == NULL) {
1130		log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
1131			"%s(%s)\n",
1132			ip6_sprintf(&ia->ia_addr.sin6_addr),
1133			ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1134		return;
1135	}
1136	bzero(dp, sizeof(*dp));
1137	callout_init(&dp->dad_timer_ch, 0);
1138	TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
1139
1140	nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
1141	    ip6_sprintf(&ia->ia_addr.sin6_addr)));
1142
1143	/*
1144	 * Send NS packet for DAD, ip6_dad_count times.
1145	 * Note that we must delay the first transmission, if this is the
1146	 * first packet to be sent from the interface after interface
1147	 * (re)initialization.
1148	 */
1149	dp->dad_ifa = ifa;
1150	IFAREF(ifa);	/* just for safety */
1151	dp->dad_count = ip6_dad_count;
1152	dp->dad_ns_icount = dp->dad_na_icount = 0;
1153	dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
1154	if (tick == NULL) {
1155		nd6_dad_ns_output(dp, ifa);
1156		nd6_dad_starttimer(dp,
1157		    ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1158	} else {
1159		int ntick;
1160
1161		if (*tick == 0)
1162			ntick = arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz);
1163		else
1164			ntick = *tick + arc4random() % (hz / 2);
1165		*tick = ntick;
1166		nd6_dad_starttimer(dp, ntick);
1167	}
1168}
1169
1170/*
1171 * terminate DAD unconditionally.  used for address removals.
1172 */
1173void
1174nd6_dad_stop(ifa)
1175	struct ifaddr *ifa;
1176{
1177	struct dadq *dp;
1178
1179	if (!dad_init)
1180		return;
1181	dp = nd6_dad_find(ifa);
1182	if (!dp) {
1183		/* DAD wasn't started yet */
1184		return;
1185	}
1186
1187	nd6_dad_stoptimer(dp);
1188
1189	TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1190	free(dp, M_IP6NDP);
1191	dp = NULL;
1192	IFAFREE(ifa);
1193}
1194
1195static void
1196nd6_dad_timer(ifa)
1197	struct ifaddr *ifa;
1198{
1199	int s;
1200	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1201	struct dadq *dp;
1202
1203	s = splnet();		/* XXX */
1204
1205	/* Sanity check */
1206	if (ia == NULL) {
1207		log(LOG_ERR, "nd6_dad_timer: called with null parameter\n");
1208		goto done;
1209	}
1210	dp = nd6_dad_find(ifa);
1211	if (dp == NULL) {
1212		log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n");
1213		goto done;
1214	}
1215	if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
1216		log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
1217			"%s(%s)\n",
1218			ip6_sprintf(&ia->ia_addr.sin6_addr),
1219			ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1220		goto done;
1221	}
1222	if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
1223		log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
1224			"%s(%s)\n",
1225			ip6_sprintf(&ia->ia_addr.sin6_addr),
1226			ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1227		goto done;
1228	}
1229
1230	/* timeouted with IFF_{RUNNING,UP} check */
1231	if (dp->dad_ns_tcount > dad_maxtry) {
1232		nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n",
1233		    if_name(ifa->ifa_ifp)));
1234
1235		TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1236		free(dp, M_IP6NDP);
1237		dp = NULL;
1238		IFAFREE(ifa);
1239		goto done;
1240	}
1241
1242	/* Need more checks? */
1243	if (dp->dad_ns_ocount < dp->dad_count) {
1244		/*
1245		 * We have more NS to go.  Send NS packet for DAD.
1246		 */
1247		nd6_dad_ns_output(dp, ifa);
1248		nd6_dad_starttimer(dp,
1249		    ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1250	} else {
1251		/*
1252		 * We have transmitted sufficient number of DAD packets.
1253		 * See what we've got.
1254		 */
1255		int duplicate;
1256
1257		duplicate = 0;
1258
1259		if (dp->dad_na_icount) {
1260			/*
1261			 * the check is in nd6_dad_na_input(),
1262			 * but just in case
1263			 */
1264			duplicate++;
1265		}
1266
1267		if (dp->dad_ns_icount) {
1268#if 0 /* heuristics */
1269			/*
1270			 * if
1271			 * - we have sent many(?) DAD NS, and
1272			 * - the number of NS we sent equals to the
1273			 *   number of NS we've got, and
1274			 * - we've got no NA
1275			 * we may have a faulty network card/driver which
1276			 * loops back multicasts to myself.
1277			 */
1278			if (3 < dp->dad_count
1279			 && dp->dad_ns_icount == dp->dad_count
1280			 && dp->dad_na_icount == 0) {
1281				log(LOG_INFO, "DAD questionable for %s(%s): "
1282				    "network card loops back multicast?\n",
1283				    ip6_sprintf(&ia->ia_addr.sin6_addr),
1284				    if_name(ifa->ifa_ifp));
1285				/* XXX consider it a duplicate or not? */
1286				/* duplicate++; */
1287			} else {
1288				/* We've seen NS, means DAD has failed. */
1289				duplicate++;
1290			}
1291#else
1292			/* We've seen NS, means DAD has failed. */
1293			duplicate++;
1294#endif
1295		}
1296
1297		if (duplicate) {
1298			/* (*dp) will be freed in nd6_dad_duplicated() */
1299			dp = NULL;
1300			nd6_dad_duplicated(ifa);
1301		} else {
1302			/*
1303			 * We are done with DAD.  No NA came, no NS came.
1304			 * duplicated address found.
1305			 */
1306			ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1307
1308			nd6log((LOG_DEBUG,
1309			    "%s: DAD complete for %s - no duplicates found\n",
1310			    if_name(ifa->ifa_ifp),
1311			    ip6_sprintf(&ia->ia_addr.sin6_addr)));
1312
1313			TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1314			free(dp, M_IP6NDP);
1315			dp = NULL;
1316			IFAFREE(ifa);
1317		}
1318	}
1319
1320done:
1321	splx(s);
1322}
1323
1324void
1325nd6_dad_duplicated(ifa)
1326	struct ifaddr *ifa;
1327{
1328	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1329	struct dadq *dp;
1330
1331	dp = nd6_dad_find(ifa);
1332	if (dp == NULL) {
1333		log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n");
1334		return;
1335	}
1336
1337	log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: "
1338	    "NS in/out=%d/%d, NA in=%d\n",
1339	    if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr),
1340	    dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount);
1341
1342	ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1343	ia->ia6_flags |= IN6_IFF_DUPLICATED;
1344
1345	/* We are done with DAD, with duplicated address found. (failure) */
1346	nd6_dad_stoptimer(dp);
1347
1348	log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
1349	    if_name(ifa->ifa_ifp), ip6_sprintf(&ia->ia_addr.sin6_addr));
1350	log(LOG_ERR, "%s: manual intervention required\n",
1351	    if_name(ifa->ifa_ifp));
1352
1353	TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list);
1354	free(dp, M_IP6NDP);
1355	dp = NULL;
1356	IFAFREE(ifa);
1357}
1358
1359static void
1360nd6_dad_ns_output(dp, ifa)
1361	struct dadq *dp;
1362	struct ifaddr *ifa;
1363{
1364	struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1365	struct ifnet *ifp = ifa->ifa_ifp;
1366
1367	dp->dad_ns_tcount++;
1368	if ((ifp->if_flags & IFF_UP) == 0) {
1369#if 0
1370		printf("%s: interface down?\n", if_name(ifp));
1371#endif
1372		return;
1373	}
1374	if ((ifp->if_flags & IFF_RUNNING) == 0) {
1375#if 0
1376		printf("%s: interface not running?\n", if_name(ifp));
1377#endif
1378		return;
1379	}
1380
1381	dp->dad_ns_ocount++;
1382	nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, 1);
1383}
1384
1385static void
1386nd6_dad_ns_input(ifa)
1387	struct ifaddr *ifa;
1388{
1389	struct in6_ifaddr *ia;
1390	struct ifnet *ifp;
1391	const struct in6_addr *taddr6;
1392	struct dadq *dp;
1393	int duplicate;
1394
1395	if (!ifa)
1396		panic("ifa == NULL in nd6_dad_ns_input");
1397
1398	ia = (struct in6_ifaddr *)ifa;
1399	ifp = ifa->ifa_ifp;
1400	taddr6 = &ia->ia_addr.sin6_addr;
1401	duplicate = 0;
1402	dp = nd6_dad_find(ifa);
1403
1404	/* Quickhack - completely ignore DAD NS packets */
1405	if (dad_ignore_ns) {
1406		nd6log((LOG_INFO,
1407		    "nd6_dad_ns_input: ignoring DAD NS packet for "
1408		    "address %s(%s)\n", ip6_sprintf(taddr6),
1409		    if_name(ifa->ifa_ifp)));
1410		return;
1411	}
1412
1413	/*
1414	 * if I'm yet to start DAD, someone else started using this address
1415	 * first.  I have a duplicate and you win.
1416	 */
1417	if (!dp || dp->dad_ns_ocount == 0)
1418		duplicate++;
1419
1420	/* XXX more checks for loopback situation - see nd6_dad_timer too */
1421
1422	if (duplicate) {
1423		dp = NULL;	/* will be freed in nd6_dad_duplicated() */
1424		nd6_dad_duplicated(ifa);
1425	} else {
1426		/*
1427		 * not sure if I got a duplicate.
1428		 * increment ns count and see what happens.
1429		 */
1430		if (dp)
1431			dp->dad_ns_icount++;
1432	}
1433}
1434
1435static void
1436nd6_dad_na_input(ifa)
1437	struct ifaddr *ifa;
1438{
1439	struct dadq *dp;
1440
1441	if (!ifa)
1442		panic("ifa == NULL in nd6_dad_na_input");
1443
1444	dp = nd6_dad_find(ifa);
1445	if (dp)
1446		dp->dad_na_icount++;
1447
1448	/* remove the address. */
1449	nd6_dad_duplicated(ifa);
1450}
1451