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