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