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