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