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