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