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