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