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