1/* 2 * Copyright (c) 2000-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29/* 30 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 31 * All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. Neither the name of the project nor the names of its contributors 42 * may be used to endorse or promote products derived from this software 43 * without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58#include <sys/param.h> 59#include <sys/systm.h> 60#include <sys/malloc.h> 61#include <sys/mbuf.h> 62#include <sys/socket.h> 63#include <sys/sockio.h> 64#include <sys/time.h> 65#include <sys/kernel.h> 66#include <sys/errno.h> 67#include <sys/syslog.h> 68#include <sys/sysctl.h> 69#include <sys/mcache.h> 70#include <sys/protosw.h> 71#include <kern/queue.h> 72 73#include <kern/locks.h> 74#include <kern/zalloc.h> 75 76#include <net/if.h> 77#include <net/if_var.h> 78#include <net/if_types.h> 79#include <net/if_dl.h> 80#include <net/if_llreach.h> 81#include <net/route.h> 82 83#include <netinet/in.h> 84#include <netinet/in_var.h> 85#include <netinet6/in6_var.h> 86#include <netinet6/in6_ifattach.h> 87#include <netinet/ip6.h> 88#include <netinet6/ip6_var.h> 89#include <netinet6/nd6.h> 90#include <netinet6/scope6_var.h> 91#include <netinet/icmp6.h> 92 93#if IPSEC 94#include <netinet6/ipsec.h> 95#if INET6 96#include <netinet6/ipsec6.h> 97#endif 98#endif 99 100struct dadq; 101static struct dadq *nd6_dad_find(struct ifaddr *); 102void nd6_dad_stoptimer(struct ifaddr *); 103static void nd6_dad_timer(struct ifaddr *); 104static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); 105static void nd6_dad_ns_input(struct mbuf *, struct ifaddr *, char *, int); 106static struct mbuf *nd6_dad_na_input(struct mbuf *, struct ifnet *, 107 struct in6_addr *, caddr_t, int); 108static void dad_addref(struct dadq *, int); 109static void dad_remref(struct dadq *); 110static struct dadq *nd6_dad_attach(struct dadq *, struct ifaddr *); 111static void nd6_dad_detach(struct dadq *, struct ifaddr *); 112 113static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ 114 115static unsigned int dad_size; /* size of zone element */ 116static struct zone *dad_zone; /* zone for dadq */ 117 118#define DAD_ZONE_MAX 64 /* maximum elements in zone */ 119#define DAD_ZONE_NAME "nd6_dad" /* zone name */ 120 121#define DAD_LOCK_ASSERT_HELD(_dp) \ 122 lck_mtx_assert(&(_dp)->dad_lock, LCK_MTX_ASSERT_OWNED) 123 124#define DAD_LOCK_ASSERT_NOTHELD(_dp) \ 125 lck_mtx_assert(&(_dp)->dad_lock, LCK_MTX_ASSERT_NOTOWNED) 126 127#define DAD_LOCK(_dp) \ 128 lck_mtx_lock(&(_dp)->dad_lock) 129 130#define DAD_LOCK_SPIN(_dp) \ 131 lck_mtx_lock_spin(&(_dp)->dad_lock) 132 133#define DAD_CONVERT_LOCK(_dp) do { \ 134 DAD_LOCK_ASSERT_HELD(_dp); \ 135 lck_mtx_convert_spin(&(_dp)->dad_lock); \ 136} while (0) 137 138#define DAD_UNLOCK(_dp) \ 139 lck_mtx_unlock(&(_dp)->dad_lock) 140 141#define DAD_ADDREF(_dp) \ 142 dad_addref(_dp, 0) 143 144#define DAD_ADDREF_LOCKED(_dp) \ 145 dad_addref(_dp, 1) 146 147#define DAD_REMREF(_dp) \ 148 dad_remref(_dp) 149 150extern lck_mtx_t *dad6_mutex; 151extern lck_mtx_t *nd6_mutex; 152 153static int nd6_llreach_base = (LL_BASE_REACHABLE / 1000); /* seconds */ 154 155static struct sockaddr_in6 hostrtmask; 156 157SYSCTL_DECL(_net_inet6_icmp6); 158 159SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_llreach_base, 160 CTLFLAG_RW | CTLFLAG_LOCKED, &nd6_llreach_base, LL_BASE_REACHABLE, 161 "default ND6 link-layer reachability max lifetime (in seconds)"); 162 163/* 164 * Obtain a link-layer source cache entry for the sender. 165 * 166 * NOTE: This is currently only for ND6/Ethernet. 167 */ 168void 169nd6_llreach_alloc(struct rtentry *rt, struct ifnet *ifp, void *addr, 170 unsigned int alen, boolean_t solicited) 171{ 172 struct llinfo_nd6 *ln = rt->rt_llinfo; 173 174 if (nd6_llreach_base != 0 && 175 (ln->ln_expire != 0 || (ifp->if_eflags & IFEF_IPV6_ND6ALT) != 0) && 176 !(rt->rt_ifp->if_flags & IFF_LOOPBACK) && 177 ifp->if_addrlen == IF_LLREACH_MAXLEN && /* Ethernet */ 178 alen == ifp->if_addrlen) { 179 struct if_llreach *lr; 180 const char *why = NULL, *type = ""; 181 182 /* Become a regular mutex, just in case */ 183 RT_CONVERT_LOCK(rt); 184 185 if ((lr = ln->ln_llreach) != NULL) { 186 type = (solicited ? "ND6 advertisement" : 187 "ND6 unsolicited announcement"); 188 /* 189 * If target has changed, create a new record; 190 * otherwise keep existing record. 191 */ 192 IFLR_LOCK(lr); 193 if (bcmp(addr, lr->lr_key.addr, alen) != 0) { 194 IFLR_UNLOCK(lr); 195 /* Purge any link-layer info caching */ 196 VERIFY(rt->rt_llinfo_purge != NULL); 197 rt->rt_llinfo_purge(rt); 198 lr = NULL; 199 why = " for different target HW address; " 200 "using new llreach record"; 201 } else { 202 lr->lr_probes = 0; /* reset probe count */ 203 IFLR_UNLOCK(lr); 204 if (solicited) { 205 why = " for same target HW address; " 206 "keeping existing llreach record"; 207 } 208 } 209 } 210 211 if (lr == NULL) { 212 lr = ln->ln_llreach = ifnet_llreach_alloc(ifp, 213 ETHERTYPE_IPV6, addr, alen, nd6_llreach_base); 214 if (lr != NULL) { 215 lr->lr_probes = 0; /* reset probe count */ 216 if (why == NULL) 217 why = "creating new llreach record"; 218 } 219 } 220 221 if (nd6_debug && lr != NULL && why != NULL) { 222 char tmp[MAX_IPv6_STR_LEN]; 223 224 nd6log((LOG_DEBUG, "%s: %s%s for %s\n", if_name(ifp), 225 type, why, inet_ntop(AF_INET6, 226 &SIN6(rt_key(rt))->sin6_addr, tmp, sizeof (tmp)))); 227 } 228 } 229} 230 231void 232nd6_llreach_use(struct llinfo_nd6 *ln) 233{ 234 if (ln->ln_llreach != NULL) 235 ln->ln_lastused = net_uptime(); 236} 237 238/* 239 * Input a Neighbor Solicitation Message. 240 * 241 * Based on RFC 4861 242 * Based on RFC 4862 (duplicate address detection) 243 */ 244void 245nd6_ns_input( 246 struct mbuf *m, 247 int off, 248 int icmp6len) 249{ 250 struct ifnet *ifp = m->m_pkthdr.rcvif; 251 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 252 struct nd_neighbor_solicit *nd_ns; 253 struct in6_addr saddr6 = ip6->ip6_src; 254 struct in6_addr daddr6 = ip6->ip6_dst; 255 struct in6_addr taddr6; 256 struct in6_addr myaddr6; 257 char *lladdr = NULL; 258 struct ifaddr *ifa = NULL; 259 int lladdrlen = 0; 260 int anycast = 0, proxy = 0, dadprogress = 0; 261 int tlladdr; 262 union nd_opts ndopts; 263 struct sockaddr_dl proxydl; 264 boolean_t advrouter; 265 boolean_t is_dad_probe; 266 267 if ((ifp->if_eflags & IFEF_IPV6_ND6ALT) != 0) { 268 nd6log((LOG_INFO, "nd6_ns_input: on ND6ALT interface!\n")); 269 return; 270 } 271 272 /* Expect 32-bit aligned data pointer on strict-align platforms */ 273 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m); 274 275 IP6_EXTHDR_CHECK(m, off, icmp6len, return); 276 nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off); 277 m->m_pkthdr.pkt_flags |= PKTF_INET6_RESOLVE; 278 279 ip6 = mtod(m, struct ip6_hdr *); /* adjust pointer for safety */ 280 taddr6 = nd_ns->nd_ns_target; 281 if (in6_setscope(&taddr6, ifp, NULL) != 0) 282 goto bad; 283 284 if (ip6->ip6_hlim != IPV6_MAXHLIM) { 285 nd6log((LOG_ERR, 286 "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n", 287 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 288 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 289 goto bad; 290 } 291 292 is_dad_probe = IN6_IS_ADDR_UNSPECIFIED(&saddr6); 293 if (is_dad_probe) { 294 /* dst has to be a solicited node multicast address. */ 295 if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL && 296 /* don't check ifindex portion */ 297 daddr6.s6_addr32[1] == 0 && 298 daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE && 299 daddr6.s6_addr8[12] == 0xff) { 300 ; /* good */ 301 } else { 302 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 303 "(wrong ip6 dst)\n")); 304 goto bad; 305 } 306 } else if (!nd6_onlink_ns_rfc4861) { 307 struct sockaddr_in6 src_sa6; 308 309 /* 310 * According to recent IETF discussions, it is not a good idea 311 * to accept a NS from an address which would not be deemed 312 * to be a neighbor otherwise. This point is expected to be 313 * clarified in future revisions of the specification. 314 */ 315 bzero(&src_sa6, sizeof(src_sa6)); 316 src_sa6.sin6_family = AF_INET6; 317 src_sa6.sin6_len = sizeof(src_sa6); 318 src_sa6.sin6_addr = saddr6; 319 if (!nd6_is_addr_neighbor(&src_sa6, ifp, 0)) { 320 nd6log((LOG_INFO, "nd6_ns_input: " 321 "NS packet from non-neighbor\n")); 322 goto bad; 323 } 324 } 325 326 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 327 nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n")); 328 goto bad; 329 } 330 331 icmp6len -= sizeof(*nd_ns); 332 nd6_option_init(nd_ns + 1, icmp6len, &ndopts); 333 if (nd6_options(&ndopts) < 0) { 334 nd6log((LOG_INFO, 335 "nd6_ns_input: invalid ND option, ignored\n")); 336 /* nd6_options have incremented stats */ 337 goto freeit; 338 } 339 340 if (ndopts.nd_opts_src_lladdr) { 341 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 342 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 343 } 344 345 if (is_dad_probe && lladdr) { 346 nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet " 347 "(link-layer address option)\n")); 348 goto bad; 349 } 350 351 /* 352 * Attaching target link-layer address to the NA? 353 * (RFC 2461 7.2.4) 354 * 355 * NS IP dst is unicast/anycast MUST NOT add 356 * NS IP dst is solicited-node multicast MUST add 357 * 358 * In implementation, we add target link-layer address by default. 359 * We do not add one in MUST NOT cases. 360 */ 361 if (!IN6_IS_ADDR_MULTICAST(&daddr6)) 362 tlladdr = 0; 363 else 364 tlladdr = 1; 365 366 /* 367 * Target address (taddr6) must be either: 368 * (1) Valid unicast/anycast address for my receiving interface, 369 * (2) Unicast address for which I'm offering proxy service, or 370 * (3) "tentative" or "optimistic" address [DAD is in progress]. 371 */ 372 /* (1) and (3) check. */ 373 ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6); 374 375 /* (2) check. */ 376 if (ifa == NULL) { 377 struct rtentry *rt; 378 struct sockaddr_in6 tsin6; 379 380 bzero(&tsin6, sizeof tsin6); 381 tsin6.sin6_len = sizeof(struct sockaddr_in6); 382 tsin6.sin6_family = AF_INET6; 383 tsin6.sin6_addr = taddr6; 384 385 rt = rtalloc1_scoped((struct sockaddr *)&tsin6, 0, 0, 386 ifp->if_index); 387 388 if (rt != NULL) { 389 RT_LOCK(rt); 390 if ((rt->rt_flags & RTF_ANNOUNCE) != 0 && 391 rt->rt_gateway->sa_family == AF_LINK) { 392 /* 393 * proxy NDP for single entry 394 */ 395 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal( 396 ifp, IN6_IFF_NOTREADY|IN6_IFF_ANYCAST); 397 if (ifa) { 398 proxy = 1; 399 proxydl = *SDL(rt->rt_gateway); 400 } 401 } 402 RT_UNLOCK(rt); 403 rtfree(rt); 404 } 405 } 406 if (ifa == NULL && ip6_forwarding && nd6_prproxy) { 407 /* 408 * Is the target address part of the prefix that is being 409 * proxied and installed on another interface? 410 */ 411 ifa = (struct ifaddr *)in6ifa_prproxyaddr(&taddr6); 412 } 413 if (ifa == NULL) { 414 /* 415 * We've got an NS packet, and we don't have that address 416 * assigned for us. We MUST silently ignore it on this 417 * interface, c.f. RFC 4861 7.2.3. 418 * 419 * Forwarding associated with NDPRF_PRPROXY may apply. 420 */ 421 if (ip6_forwarding && nd6_prproxy) 422 nd6_prproxy_ns_input(ifp, &saddr6, lladdr, 423 lladdrlen, &daddr6, &taddr6); 424 goto freeit; 425 } 426 IFA_LOCK(ifa); 427 myaddr6 = *IFA_IN6(ifa); 428 anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST; 429 dadprogress = 430 ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DADPROGRESS; 431 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED) { 432 IFA_UNLOCK(ifa); 433 goto freeit; 434 } 435 IFA_UNLOCK(ifa); 436 437 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 438 nd6log((LOG_INFO, 439 "nd6_ns_input: lladdrlen mismatch for %s " 440 "(if %d, NS packet %d)\n", 441 ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2)); 442 goto bad; 443 } 444 445 if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) { 446 nd6log((LOG_INFO, 447 "nd6_ns_input: duplicate IP6 address %s\n", 448 ip6_sprintf(&saddr6))); 449 goto freeit; 450 } 451 452 /* 453 * We have neighbor solicitation packet, with target address equals to 454 * one of my DAD in-progress addresses. 455 * 456 * src addr how to process? 457 * --- --- 458 * multicast of course, invalid (rejected in ip6_input) 459 * unicast somebody is doing address resolution -> ignore 460 * unspec dup address detection 461 * 462 * The processing is defined in the "draft standard" RFC 4862 (and by 463 * RFC 4429, which is a "proposed standard" update to its obsolete 464 * predecessor, RFC 2462) The reason optimistic DAD is not included 465 * in RFC 4862 is entirely due to IETF procedural considerations. 466 */ 467 if (dadprogress) { 468 /* 469 * If source address is unspecified address, it is for 470 * duplicate address detection. 471 * 472 * If not, the packet is for addess resolution; 473 * silently ignore it. 474 */ 475 if (is_dad_probe) 476 nd6_dad_ns_input(m, ifa, lladdr, lladdrlen); 477 478 goto freeit; 479 } 480 481 /* Are we an advertising router on this interface? */ 482 advrouter = (ifp->if_eflags & IFEF_IPV6_ROUTER); 483 484 /* 485 * If the source address is unspecified address, entries must not 486 * be created or updated. 487 * It looks that sender is performing DAD. If I'm using the address, 488 * and it's a "preferred" address, i.e. not optimistic, then output NA 489 * toward all-node multicast address, to tell the sender that I'm using 490 * the address. 491 * S bit ("solicited") must be zero. 492 */ 493 if (is_dad_probe) { 494 saddr6 = in6addr_linklocal_allnodes; 495 if (in6_setscope(&saddr6, ifp, NULL) != 0) 496 goto bad; 497 if ((dadprogress & IN6_IFF_OPTIMISTIC) == 0) 498 nd6_na_output(ifp, &saddr6, &taddr6, 499 ((anycast || proxy || !tlladdr) ? 0 : 500 ND_NA_FLAG_OVERRIDE) | (advrouter ? 501 ND_NA_FLAG_ROUTER : 0), tlladdr, proxy ? 502 (struct sockaddr *)&proxydl : NULL); 503 goto freeit; 504 } 505 506 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, 507 ND_NEIGHBOR_SOLICIT, 0); 508 509 nd6_na_output(ifp, &saddr6, &taddr6, 510 ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) | 511 (advrouter ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED, 512 tlladdr, proxy ? (struct sockaddr *)&proxydl : NULL); 513 freeit: 514 m_freem(m); 515 if (ifa != NULL) 516 IFA_REMREF(ifa); 517 return; 518 519 bad: 520 nd6log((LOG_ERR, "nd6_ns_input: src=%s\n", ip6_sprintf(&saddr6))); 521 nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n", ip6_sprintf(&daddr6))); 522 nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", ip6_sprintf(&taddr6))); 523 icmp6stat.icp6s_badns++; 524 m_freem(m); 525 if (ifa != NULL) 526 IFA_REMREF(ifa); 527} 528 529/* 530 * Output a Neighbor Solicitation Message. Caller specifies: 531 * - ICMP6 header source IP6 address 532 * - ND6 header target IP6 address 533 * - ND6 header source datalink address 534 * 535 * Based on RFC 4861 536 * Based on RFC 4862 (duplicate address detection) 537 * Based on RFC 4429 (optimistic duplicate address detection) 538 * 539 * Caller must bump up ln->ln_rt refcnt to make sure 'ln' doesn't go 540 * away if there is a llinfo_nd6 passed in. 541 */ 542void 543nd6_ns_output( 544 struct ifnet *ifp, 545 const struct in6_addr *daddr6, 546 const struct in6_addr *taddr6, 547 struct llinfo_nd6 *ln, /* for source address determination */ 548 int dad) /* duplicated address detection */ 549{ 550 struct mbuf *m; 551 struct ip6_hdr *ip6; 552 struct nd_neighbor_solicit *nd_ns; 553 struct in6_ifaddr *ia = NULL; 554 struct in6_addr *src, src_in, src_storage; 555 struct ip6_moptions *im6o = NULL; 556 struct ifnet *outif = NULL; 557 int icmp6len; 558 int maxlen; 559 int flags; 560 caddr_t mac; 561 struct route_in6 ro; 562 struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 }, 563 IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0 }; 564 u_int32_t rtflags = 0; 565 566 if ((ifp->if_eflags & IFEF_IPV6_ND6ALT) || IN6_IS_ADDR_MULTICAST(taddr6)) 567 return; 568 569 bzero(&ro, sizeof(ro)); 570 571 ip6oa.ip6oa_boundif = ifp->if_index; 572 ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF; 573 574 /* estimate the size of message */ 575 maxlen = sizeof(*ip6) + sizeof(*nd_ns); 576 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 577 if (max_linkhdr + maxlen >= MCLBYTES) { 578#if DIAGNOSTIC 579 printf("nd6_ns_output: max_linkhdr + maxlen >= MCLBYTES " 580 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 581#endif 582 return; 583 } 584 585 MGETHDR(m, M_DONTWAIT, MT_DATA); /* XXXMAC: mac_create_mbuf_linklayer() probably */ 586 if (m && max_linkhdr + maxlen >= MHLEN) { 587 MCLGET(m, M_DONTWAIT); 588 if ((m->m_flags & M_EXT) == 0) { 589 m_free(m); 590 m = NULL; 591 } 592 } 593 if (m == NULL) 594 return; 595 m->m_pkthdr.rcvif = NULL; 596 597 if (daddr6 == NULL || IN6_IS_ADDR_MULTICAST(daddr6)) { 598 m->m_flags |= M_MCAST; 599 600 im6o = ip6_allocmoptions(M_DONTWAIT); 601 if (im6o == NULL) { 602 m_freem(m); 603 return; 604 } 605 606 im6o->im6o_multicast_ifp = ifp; 607 im6o->im6o_multicast_hlim = IPV6_MAXHLIM; 608 im6o->im6o_multicast_loop = 0; 609 } 610 611 icmp6len = sizeof(*nd_ns); 612 m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len; 613 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 614 615 /* fill neighbor solicitation packet */ 616 ip6 = mtod(m, struct ip6_hdr *); 617 ip6->ip6_flow = 0; 618 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 619 ip6->ip6_vfc |= IPV6_VERSION; 620 /* ip6->ip6_plen will be set later */ 621 ip6->ip6_nxt = IPPROTO_ICMPV6; 622 ip6->ip6_hlim = IPV6_MAXHLIM; 623 if (daddr6) 624 ip6->ip6_dst = *daddr6; 625 else { 626 ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 627 ip6->ip6_dst.s6_addr16[1] = 0; 628 ip6->ip6_dst.s6_addr32[1] = 0; 629 ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE; 630 ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3]; 631 ip6->ip6_dst.s6_addr8[12] = 0xff; 632 if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0) 633 goto bad; 634 } 635 if (!dad) { 636 /* 637 * RFC2461 7.2.2: 638 * "If the source address of the packet prompting the 639 * solicitation is the same as one of the addresses assigned 640 * to the outgoing interface, that address SHOULD be placed 641 * in the IP Source Address of the outgoing solicitation. 642 * Otherwise, any one of the addresses assigned to the 643 * interface should be used." 644 * 645 * We use the source address for the prompting packet 646 * (saddr6), if: 647 * - saddr6 is given from the caller (by giving "ln"), and 648 * - saddr6 belongs to the outgoing interface. 649 * Otherwise, we perform the source address selection as usual. 650 */ 651 struct ip6_hdr *hip6; /* hold ip6 */ 652 struct in6_addr *hsrc = NULL; 653 654 /* Caller holds ref on this route */ 655 if (ln != NULL) { 656 RT_LOCK(ln->ln_rt); 657 /* 658 * assuming every packet in ln_hold has the same IP 659 * header 660 */ 661 if (ln->ln_hold != NULL) { 662 hip6 = mtod(ln->ln_hold, struct ip6_hdr *); 663 /* XXX pullup? */ 664 if (sizeof (*hip6) < ln->ln_hold->m_len) 665 hsrc = &hip6->ip6_src; 666 else 667 hsrc = NULL; 668 } 669 /* Update probe count, if applicable */ 670 if (ln->ln_llreach != NULL) { 671 IFLR_LOCK_SPIN(ln->ln_llreach); 672 ln->ln_llreach->lr_probes++; 673 IFLR_UNLOCK(ln->ln_llreach); 674 } 675 rtflags = ln->ln_rt->rt_flags; 676 RT_UNLOCK(ln->ln_rt); 677 } 678 if (hsrc != NULL && (ia = in6ifa_ifpwithaddr(ifp, hsrc)) && 679 (ia->ia6_flags & IN6_IFF_OPTIMISTIC) == 0) { 680 src = hsrc; 681 } else { 682 int error; 683 struct sockaddr_in6 dst_sa; 684 685 bzero(&dst_sa, sizeof(dst_sa)); 686 dst_sa.sin6_family = AF_INET6; 687 dst_sa.sin6_len = sizeof(dst_sa); 688 dst_sa.sin6_addr = ip6->ip6_dst; 689 690 src = in6_selectsrc(&dst_sa, NULL, 691 NULL, &ro, NULL, &src_storage, ip6oa.ip6oa_boundif, 692 &error); 693 if (src == NULL) { 694 nd6log((LOG_DEBUG, 695 "nd6_ns_output: source can't be " 696 "determined: dst=%s, error=%d\n", 697 ip6_sprintf(&dst_sa.sin6_addr), 698 error)); 699 goto bad; 700 } 701 702 if (ia != NULL) { 703 IFA_REMREF(&ia->ia_ifa); 704 ia = NULL; 705 } 706 /* 707 * RFC 4429 section 3.2: 708 * When a node has a unicast packet to send 709 * from an Optimistic Address to a neighbor, 710 * but does not know the neighbor's link-layer 711 * address, it MUST NOT perform Address 712 * Resolution. 713 */ 714 ia = in6ifa_ifpwithaddr(ifp, src); 715 if (!ia || (ia->ia6_flags & IN6_IFF_OPTIMISTIC)) { 716 nd6log((LOG_DEBUG, 717 "nd6_ns_output: no preferred source " 718 "available: dst=%s\n", 719 ip6_sprintf(&dst_sa.sin6_addr))); 720 goto bad; 721 } 722 } 723 } else { 724 /* 725 * Source address for DAD packet must always be IPv6 726 * unspecified address. (0::0) 727 * We actually don't have to 0-clear the address (we did it 728 * above), but we do so here explicitly to make the intention 729 * clearer. 730 */ 731 bzero(&src_in, sizeof(src_in)); 732 src = &src_in; 733 ip6oa.ip6oa_flags &= ~IP6OAF_BOUND_SRCADDR; 734 } 735 ip6->ip6_src = *src; 736 nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1); 737 nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT; 738 nd_ns->nd_ns_code = 0; 739 nd_ns->nd_ns_reserved = 0; 740 nd_ns->nd_ns_target = *taddr6; 741 in6_clearscope(&nd_ns->nd_ns_target); /* XXX */ 742 743 /* 744 * Add source link-layer address option. 745 * 746 * spec implementation 747 * --- --- 748 * DAD packet MUST NOT do not add the option 749 * there's no link layer address: 750 * impossible do not add the option 751 * there's link layer address: 752 * Multicast NS MUST add one add the option 753 * Unicast NS SHOULD add one add the option 754 */ 755 if (!dad && (mac = nd6_ifptomac(ifp))) { 756 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 757 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1); 758 /* 8 byte alignments... */ 759 optlen = (optlen + 7) & ~7; 760 761 m->m_pkthdr.len += optlen; 762 m->m_len += optlen; 763 icmp6len += optlen; 764 bzero((caddr_t)nd_opt, optlen); 765 nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; 766 nd_opt->nd_opt_len = optlen >> 3; 767 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 768 } 769 770 ip6->ip6_plen = htons((u_short)icmp6len); 771 nd_ns->nd_ns_cksum = 0; 772 nd_ns->nd_ns_cksum 773 = in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len); 774 775 flags = dad ? IPV6_UNSPECSRC : 0; 776 flags |= IPV6_OUTARGS; 777 778 /* 779 * PKTF_{INET,INET6}_RESOLVE_RTR are mutually exclusive, so make 780 * sure only one of them is set (just in case.) 781 */ 782 m->m_pkthdr.pkt_flags &= ~(PKTF_INET_RESOLVE | PKTF_RESOLVE_RTR); 783 m->m_pkthdr.pkt_flags |= PKTF_INET6_RESOLVE; 784 /* 785 * If this is a NS for resolving the (default) router, mark 786 * the packet accordingly so that the driver can find out, 787 * in case it needs to perform driver-specific action(s). 788 */ 789 if (rtflags & RTF_ROUTER) 790 m->m_pkthdr.pkt_flags |= PKTF_RESOLVE_RTR; 791 792 if (ifp->if_eflags & IFEF_TXSTART) { 793 /* 794 * Use control service class if the interface 795 * supports transmit-start model 796 */ 797 (void) m_set_service_class(m, MBUF_SC_CTL); 798 } 799 800 ip6_output(m, NULL, NULL, flags, im6o, &outif, &ip6oa); 801 if (outif) { 802 icmp6_ifstat_inc(outif, ifs6_out_msg); 803 icmp6_ifstat_inc(outif, ifs6_out_neighborsolicit); 804 ifnet_release(outif); 805 } 806 icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++; 807 808exit: 809 if (im6o != NULL) 810 IM6O_REMREF(im6o); 811 812 ROUTE_RELEASE(&ro); /* we don't cache this route. */ 813 814 if (ia != NULL) 815 IFA_REMREF(&ia->ia_ifa); 816 return; 817 818bad: 819 m_freem(m); 820 goto exit; 821} 822 823/* 824 * Neighbor advertisement input handling. 825 * 826 * Based on RFC 4861 827 * Based on RFC 4862 (duplicate address detection) 828 * 829 * the following items are not implemented yet: 830 * - anycast advertisement delay rule (RFC 4861 7.2.7, SHOULD) 831 * - proxy advertisement delay rule (RFC 4861 7.2.8, last paragraph, "should") 832 */ 833void 834nd6_na_input(struct mbuf *m, int off, int icmp6len) 835{ 836 struct ifnet *ifp = m->m_pkthdr.rcvif; 837 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 838 struct nd_neighbor_advert *nd_na; 839 struct in6_addr saddr6 = ip6->ip6_src; 840 struct in6_addr daddr6 = ip6->ip6_dst; 841 struct in6_addr taddr6; 842 int flags; 843 int is_router; 844 int is_solicited; 845 int is_override; 846 char *lladdr = NULL; 847 int lladdrlen = 0; 848 struct llinfo_nd6 *ln; 849 struct rtentry *rt; 850 struct sockaddr_dl *sdl; 851 union nd_opts ndopts; 852 uint64_t timenow; 853 854 if ((ifp->if_eflags & IFEF_IPV6_ND6ALT) != 0) { 855 nd6log((LOG_INFO, "nd6_na_input: on ND6ALT interface!\n")); 856 return; 857 } 858 859 /* Expect 32-bit aligned data pointer on strict-align platforms */ 860 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m); 861 862 if (ip6->ip6_hlim != IPV6_MAXHLIM) { 863 nd6log((LOG_ERR, 864 "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", 865 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 866 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); 867 goto bad; 868 } 869 870 IP6_EXTHDR_CHECK(m, off, icmp6len, return); 871 nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off); 872 m->m_pkthdr.pkt_flags |= PKTF_INET6_RESOLVE; 873 874 flags = nd_na->nd_na_flags_reserved; 875 is_router = ((flags & ND_NA_FLAG_ROUTER) != 0); 876 is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0); 877 is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0); 878 879 taddr6 = nd_na->nd_na_target; 880 if (in6_setscope(&taddr6, ifp, NULL)) 881 goto bad; /* XXX: impossible */ 882 883 if (IN6_IS_ADDR_MULTICAST(&taddr6)) { 884 nd6log((LOG_ERR, 885 "nd6_na_input: invalid target address %s\n", 886 ip6_sprintf(&taddr6))); 887 goto bad; 888 } 889 if (IN6_IS_ADDR_MULTICAST(&daddr6)) 890 if (is_solicited) { 891 nd6log((LOG_ERR, 892 "nd6_na_input: a solicited adv is multicasted\n")); 893 goto bad; 894 } 895 896 icmp6len -= sizeof(*nd_na); 897 nd6_option_init(nd_na + 1, icmp6len, &ndopts); 898 if (nd6_options(&ndopts) < 0) { 899 nd6log((LOG_INFO, 900 "nd6_na_input: invalid ND option, ignored\n")); 901 /* nd6_options have incremented stats */ 902 goto freeit; 903 } 904 905 if (ndopts.nd_opts_tgt_lladdr) { 906 lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); 907 lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; 908 909 if (((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 910 nd6log((LOG_INFO, 911 "nd6_na_input: lladdrlen mismatch for %s " 912 "(if %d, NA packet %d)\n", 913 ip6_sprintf(&taddr6), ifp->if_addrlen, 914 lladdrlen - 2)); 915 goto bad; 916 } 917 } 918 919 m = nd6_dad_na_input(m, ifp, &taddr6, lladdr, lladdrlen); 920 if (m == NULL) 921 return; 922 923 /* Forwarding associated with NDPRF_PRPROXY may apply. */ 924 if (ip6_forwarding && nd6_prproxy) 925 nd6_prproxy_na_input(ifp, &saddr6, &daddr6, &taddr6, flags); 926 927 /* 928 * If no neighbor cache entry is found, NA SHOULD silently be 929 * discarded. If we are forwarding (and Scoped Routing is in 930 * effect), try to see if there is a neighbor cache entry on 931 * another interface (in case we are doing prefix proxying.) 932 */ 933 if ((rt = nd6_lookup(&taddr6, 0, ifp, 0)) == NULL) { 934 if (!ip6_forwarding || !ip6_doscopedroute || !nd6_prproxy) 935 goto freeit; 936 937 if ((rt = nd6_lookup(&taddr6, 0, NULL, 0)) == NULL) 938 goto freeit; 939 940 RT_LOCK_ASSERT_HELD(rt); 941 if (rt->rt_ifp != ifp) { 942 /* 943 * Purge any link-layer info caching. 944 */ 945 if (rt->rt_llinfo_purge != NULL) 946 rt->rt_llinfo_purge(rt); 947 948 /* Adjust route ref count for the interfaces */ 949 if (rt->rt_if_ref_fn != NULL) { 950 rt->rt_if_ref_fn(ifp, 1); 951 rt->rt_if_ref_fn(rt->rt_ifp, -1); 952 } 953 954 /* Change the interface when the existing route is on */ 955 rt->rt_ifp = ifp; 956 957 /* 958 * If rmx_mtu is not locked, update it 959 * to the MTU used by the new interface. 960 */ 961 if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) 962 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; 963 } 964 } 965 966 RT_LOCK_ASSERT_HELD(rt); 967 if ((ln = rt->rt_llinfo) == NULL || 968 (sdl = SDL(rt->rt_gateway)) == NULL) { 969 RT_REMREF_LOCKED(rt); 970 RT_UNLOCK(rt); 971 goto freeit; 972 } 973 974 timenow = net_uptime(); 975 976 if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { 977 /* 978 * If the link-layer has address, and no lladdr option came, 979 * discard the packet. 980 */ 981 if (ifp->if_addrlen && !lladdr) { 982 RT_REMREF_LOCKED(rt); 983 RT_UNLOCK(rt); 984 goto freeit; 985 } 986 987 /* 988 * Record link-layer address, and update the state. 989 */ 990 sdl->sdl_alen = ifp->if_addrlen; 991 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 992 if (is_solicited) { 993 ln->ln_state = ND6_LLINFO_REACHABLE; 994 if (ln->ln_expire != 0) { 995 struct nd_ifinfo *ndi; 996 997 lck_rw_lock_shared(nd_if_rwlock); 998 ndi = ND_IFINFO(rt->rt_ifp); 999 VERIFY(ndi != NULL && ndi->initialized); 1000 lck_mtx_lock(&ndi->lock); 1001 ln_setexpire(ln, timenow + ndi->reachable); 1002 lck_mtx_unlock(&ndi->lock); 1003 lck_rw_done(nd_if_rwlock); 1004 RT_UNLOCK(rt); 1005 lck_mtx_lock(rnh_lock); 1006 nd6_sched_timeout(NULL, NULL); 1007 lck_mtx_unlock(rnh_lock); 1008 RT_LOCK(rt); 1009 } 1010 } else { 1011 ln->ln_state = ND6_LLINFO_STALE; 1012 ln_setexpire(ln, timenow + nd6_gctimer); 1013 } 1014 if ((ln->ln_router = is_router) != 0) { 1015 /* 1016 * This means a router's state has changed from 1017 * non-reachable to probably reachable, and might 1018 * affect the status of associated prefixes.. 1019 */ 1020 RT_UNLOCK(rt); 1021 lck_mtx_lock(nd6_mutex); 1022 pfxlist_onlink_check(); 1023 lck_mtx_unlock(nd6_mutex); 1024 RT_LOCK(rt); 1025 } 1026 } else { 1027 int llchange; 1028 1029 /* 1030 * Check if the link-layer address has changed or not. 1031 */ 1032 if (!lladdr) 1033 llchange = 0; 1034 else { 1035 if (sdl->sdl_alen) { 1036 if (bcmp(lladdr, LLADDR(sdl), ifp->if_addrlen)) 1037 llchange = 1; 1038 else 1039 llchange = 0; 1040 } else 1041 llchange = 1; 1042 } 1043 1044 /* 1045 * This is VERY complex. Look at it with care. 1046 * 1047 * override solicit lladdr llchange action 1048 * (L: record lladdr) 1049 * 1050 * 0 0 n -- (2c) 1051 * 0 0 y n (2b) L 1052 * 0 0 y y (1) REACHABLE->STALE 1053 * 0 1 n -- (2c) *->REACHABLE 1054 * 0 1 y n (2b) L *->REACHABLE 1055 * 0 1 y y (1) REACHABLE->STALE 1056 * 1 0 n -- (2a) 1057 * 1 0 y n (2a) L 1058 * 1 0 y y (2a) L *->STALE 1059 * 1 1 n -- (2a) *->REACHABLE 1060 * 1 1 y n (2a) L *->REACHABLE 1061 * 1 1 y y (2a) L *->REACHABLE 1062 */ 1063 if (!is_override && (lladdr != NULL && llchange)) { /* (1) */ 1064 /* 1065 * If state is REACHABLE, make it STALE. 1066 * no other updates should be done. 1067 */ 1068 if (ln->ln_state == ND6_LLINFO_REACHABLE) { 1069 ln->ln_state = ND6_LLINFO_STALE; 1070 ln_setexpire(ln, timenow + nd6_gctimer); 1071 } 1072 RT_REMREF_LOCKED(rt); 1073 RT_UNLOCK(rt); 1074 goto freeit; 1075 } else if (is_override /* (2a) */ 1076 || (!is_override && (lladdr && !llchange)) /* (2b) */ 1077 || !lladdr) { /* (2c) */ 1078 /* 1079 * Update link-local address, if any. 1080 */ 1081 if (lladdr) { 1082 sdl->sdl_alen = ifp->if_addrlen; 1083 bcopy(lladdr, LLADDR(sdl), ifp->if_addrlen); 1084 } 1085 1086 /* 1087 * If solicited, make the state REACHABLE. 1088 * If not solicited and the link-layer address was 1089 * changed, make it STALE. 1090 */ 1091 if (is_solicited) { 1092 ln->ln_state = ND6_LLINFO_REACHABLE; 1093 if (ln->ln_expire != 0) { 1094 struct nd_ifinfo *ndi; 1095 1096 lck_rw_lock_shared(nd_if_rwlock); 1097 ndi = ND_IFINFO(ifp); 1098 VERIFY(ndi != NULL && ndi->initialized); 1099 lck_mtx_lock(&ndi->lock); 1100 ln_setexpire(ln, 1101 timenow + ndi->reachable); 1102 lck_mtx_unlock(&ndi->lock); 1103 lck_rw_done(nd_if_rwlock); 1104 RT_UNLOCK(rt); 1105 lck_mtx_lock(rnh_lock); 1106 nd6_sched_timeout(NULL, NULL); 1107 lck_mtx_unlock(rnh_lock); 1108 RT_LOCK(rt); 1109 } 1110 } else { 1111 if (lladdr && llchange) { 1112 ln->ln_state = ND6_LLINFO_STALE; 1113 ln_setexpire(ln, timenow + nd6_gctimer); 1114 } 1115 } 1116 } 1117 1118 if (ln->ln_router && !is_router) { 1119 /* 1120 * The peer dropped the router flag. 1121 * Remove the sender from the Default Router List and 1122 * update the Destination Cache entries. 1123 */ 1124 struct nd_defrouter *dr; 1125 struct in6_addr *in6; 1126 struct ifnet *rt_ifp = rt->rt_ifp; 1127 1128 in6 = &((struct sockaddr_in6 *) 1129 (void *)rt_key(rt))->sin6_addr; 1130 1131 RT_UNLOCK(rt); 1132 lck_mtx_lock(nd6_mutex); 1133 dr = defrouter_lookup(in6, rt_ifp); 1134 if (dr) { 1135 defrtrlist_del(dr); 1136 NDDR_REMREF(dr); 1137 lck_mtx_unlock(nd6_mutex); 1138 } else { 1139 lck_mtx_unlock(nd6_mutex); 1140 if (ip6_doscopedroute || !ip6_forwarding) { 1141 /* 1142 * Even if the neighbor is not in the 1143 * default router list, the neighbor 1144 * may be used as a next hop for some 1145 * destinations (e.g. redirect case). 1146 * So we must call rt6_flush explicitly. 1147 */ 1148 rt6_flush(&ip6->ip6_src, rt_ifp); 1149 } 1150 } 1151 RT_LOCK(rt); 1152 } 1153 ln->ln_router = is_router; 1154 } 1155 RT_LOCK_ASSERT_HELD(rt); 1156 rt->rt_flags &= ~RTF_REJECT; 1157 1158 /* cache the gateway (sender HW) address */ 1159 nd6_llreach_alloc(rt, ifp, LLADDR(sdl), sdl->sdl_alen, TRUE); 1160 1161 /* update the llinfo, send a queued packet if there is one */ 1162 ln->ln_asked = 0; 1163 if (ln->ln_hold != NULL) { 1164 struct mbuf *m_hold, *m_hold_next; 1165 struct sockaddr_in6 sin6; 1166 1167 rtkey_to_sa6(rt, &sin6); 1168 /* 1169 * reset the ln_hold in advance, to explicitly 1170 * prevent a ln_hold lookup in nd6_output() 1171 * (wouldn't happen, though...) 1172 */ 1173 for (m_hold = ln->ln_hold; 1174 m_hold; m_hold = m_hold_next) { 1175 m_hold_next = m_hold->m_nextpkt; 1176 m_hold->m_nextpkt = NULL; 1177 /* 1178 * we assume ifp is not a loopback here, so just set 1179 * the 2nd argument as the 1st one. 1180 */ 1181 RT_UNLOCK(rt); 1182 nd6_output(ifp, ifp, m_hold, &sin6, rt, NULL); 1183 RT_LOCK_SPIN(rt); 1184 } 1185 ln->ln_hold = NULL; 1186 1187 } 1188 RT_REMREF_LOCKED(rt); 1189 RT_UNLOCK(rt); 1190 1191bad: 1192 icmp6stat.icp6s_badna++; 1193 /* fall through */ 1194 1195freeit: 1196 m_freem(m); 1197} 1198 1199/* 1200 * Neighbor advertisement output handling. 1201 * 1202 * Based on RFC 2461 1203 * 1204 * the following items are not implemented yet: 1205 * - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD) 1206 * - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD) 1207 * 1208 * tlladdr - 1 if include target link-layer address 1209 * sdl0 - sockaddr_dl (= proxy NA) or NULL 1210 */ 1211void 1212nd6_na_output( 1213 struct ifnet *ifp, 1214 const struct in6_addr *daddr6_0, 1215 const struct in6_addr *taddr6, 1216 uint32_t flags, 1217 int tlladdr, /* 1 if include target link-layer address */ 1218 struct sockaddr *sdl0) /* sockaddr_dl (= proxy NA) or NULL */ 1219{ 1220 struct mbuf *m; 1221 struct ip6_hdr *ip6; 1222 struct nd_neighbor_advert *nd_na; 1223 struct ip6_moptions *im6o = NULL; 1224 caddr_t mac = NULL; 1225 struct route_in6 ro; 1226 struct in6_addr *src, src_storage, daddr6; 1227 struct in6_ifaddr *ia; 1228 struct sockaddr_in6 dst_sa; 1229 int icmp6len, maxlen, error; 1230 struct ifnet *outif = NULL; 1231 struct ip6_out_args ip6oa = { IFSCOPE_NONE, { 0 }, 1232 IP6OAF_SELECT_SRCIF | IP6OAF_BOUND_SRCADDR, 0 }; 1233 1234 bzero(&ro, sizeof(ro)); 1235 1236 daddr6 = *daddr6_0; /* make a local copy for modification */ 1237 1238 ip6oa.ip6oa_boundif = ifp->if_index; 1239 ip6oa.ip6oa_flags |= IP6OAF_BOUND_IF; 1240 1241 /* estimate the size of message */ 1242 maxlen = sizeof(*ip6) + sizeof(*nd_na); 1243 maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7; 1244 if (max_linkhdr + maxlen >= MCLBYTES) { 1245#if DIAGNOSTIC 1246 printf("nd6_na_output: max_linkhdr + maxlen >= MCLBYTES " 1247 "(%d + %d > %d)\n", max_linkhdr, maxlen, MCLBYTES); 1248#endif 1249 return; 1250 } 1251 1252 MGETHDR(m, M_DONTWAIT, MT_DATA); /* XXXMAC: mac_create_mbuf_linklayer() probably */ 1253 if (m && max_linkhdr + maxlen >= MHLEN) { 1254 MCLGET(m, M_DONTWAIT); 1255 if ((m->m_flags & M_EXT) == 0) { 1256 m_free(m); 1257 m = NULL; 1258 } 1259 } 1260 if (m == NULL) 1261 return; 1262 m->m_pkthdr.rcvif = NULL; 1263 1264 if (IN6_IS_ADDR_MULTICAST(&daddr6)) { 1265 m->m_flags |= M_MCAST; 1266 1267 im6o = ip6_allocmoptions(M_DONTWAIT); 1268 if (im6o == NULL) { 1269 m_freem(m); 1270 return; 1271 } 1272 1273 im6o->im6o_multicast_ifp = ifp; 1274 im6o->im6o_multicast_hlim = IPV6_MAXHLIM; 1275 im6o->im6o_multicast_loop = 0; 1276 } 1277 1278 icmp6len = sizeof(*nd_na); 1279 m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len; 1280 m->m_data += max_linkhdr; /* or MH_ALIGN() equivalent? */ 1281 1282 /* fill neighbor advertisement packet */ 1283 ip6 = mtod(m, struct ip6_hdr *); 1284 ip6->ip6_flow = 0; 1285 ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 1286 ip6->ip6_vfc |= IPV6_VERSION; 1287 ip6->ip6_nxt = IPPROTO_ICMPV6; 1288 ip6->ip6_hlim = IPV6_MAXHLIM; 1289 if (IN6_IS_ADDR_UNSPECIFIED(&daddr6)) { 1290 /* reply to DAD */ 1291 daddr6.s6_addr16[0] = IPV6_ADDR_INT16_MLL; 1292 daddr6.s6_addr16[1] = 0; 1293 daddr6.s6_addr32[1] = 0; 1294 daddr6.s6_addr32[2] = 0; 1295 daddr6.s6_addr32[3] = IPV6_ADDR_INT32_ONE; 1296 if (in6_setscope(&daddr6, ifp, NULL)) 1297 goto bad; 1298 1299 flags &= ~ND_NA_FLAG_SOLICITED; 1300 } else 1301 ip6->ip6_dst = daddr6; 1302 1303 bzero(&dst_sa, sizeof(struct sockaddr_in6)); 1304 dst_sa.sin6_family = AF_INET6; 1305 dst_sa.sin6_len = sizeof(struct sockaddr_in6); 1306 dst_sa.sin6_addr = daddr6; 1307 1308 /* 1309 * Select a source whose scope is the same as that of the dest. 1310 */ 1311 bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa)); 1312 src = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL, &src_storage, 1313 ip6oa.ip6oa_boundif, &error); 1314 if (src == NULL) { 1315 nd6log((LOG_DEBUG, "nd6_na_output: source can't be " 1316 "determined: dst=%s, error=%d\n", 1317 ip6_sprintf(&dst_sa.sin6_addr), error)); 1318 goto bad; 1319 } 1320 ip6->ip6_src = *src; 1321 1322 /* 1323 * RFC 4429 requires not setting "override" flag on NA packets sent 1324 * from optimistic addresses. 1325 */ 1326 ia = in6ifa_ifpwithaddr(ifp, src); 1327 if (ia != NULL) { 1328 if (ia->ia6_flags & IN6_IFF_OPTIMISTIC) 1329 flags &= ~ND_NA_FLAG_OVERRIDE; 1330 IFA_REMREF(&ia->ia_ifa); 1331 } 1332 1333 nd_na = (struct nd_neighbor_advert *)(ip6 + 1); 1334 nd_na->nd_na_type = ND_NEIGHBOR_ADVERT; 1335 nd_na->nd_na_code = 0; 1336 nd_na->nd_na_target = *taddr6; 1337 in6_clearscope(&nd_na->nd_na_target); /* XXX */ 1338 1339 /* 1340 * "tlladdr" indicates NS's condition for adding tlladdr or not. 1341 * see nd6_ns_input() for details. 1342 * Basically, if NS packet is sent to unicast/anycast addr, 1343 * target lladdr option SHOULD NOT be included. 1344 */ 1345 if (tlladdr) { 1346 /* 1347 * sdl0 != NULL indicates proxy NA. If we do proxy, use 1348 * lladdr in sdl0. If we are not proxying (sending NA for 1349 * my address) use lladdr configured for the interface. 1350 */ 1351 if (sdl0 == NULL) 1352 mac = nd6_ifptomac(ifp); 1353 else if (sdl0->sa_family == AF_LINK) { 1354 struct sockaddr_dl *sdl; 1355 sdl = (struct sockaddr_dl *)(void *)sdl0; 1356 if (sdl->sdl_alen == ifp->if_addrlen) 1357 mac = LLADDR(sdl); 1358 } 1359 } 1360 if (tlladdr && mac) { 1361 int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen; 1362 struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1); 1363 1364 /* roundup to 8 bytes alignment! */ 1365 optlen = (optlen + 7) & ~7; 1366 1367 m->m_pkthdr.len += optlen; 1368 m->m_len += optlen; 1369 icmp6len += optlen; 1370 bzero((caddr_t)nd_opt, optlen); 1371 nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; 1372 nd_opt->nd_opt_len = optlen >> 3; 1373 bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen); 1374 } else 1375 flags &= ~ND_NA_FLAG_OVERRIDE; 1376 1377 ip6->ip6_plen = htons((u_short)icmp6len); 1378 nd_na->nd_na_flags_reserved = flags; 1379 nd_na->nd_na_cksum = 0; 1380 nd_na->nd_na_cksum = 1381 in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len); 1382 1383 m->m_pkthdr.pkt_flags |= PKTF_INET6_RESOLVE; 1384 1385 if (ifp->if_eflags & IFEF_TXSTART) { 1386 /* Use control service class if the interface supports 1387 * transmit-start model. 1388 */ 1389 (void) m_set_service_class(m, MBUF_SC_CTL); 1390 } 1391 1392 ip6_output(m, NULL, NULL, IPV6_OUTARGS, im6o, &outif, &ip6oa); 1393 if (outif) { 1394 icmp6_ifstat_inc(outif, ifs6_out_msg); 1395 icmp6_ifstat_inc(outif, ifs6_out_neighboradvert); 1396 ifnet_release(outif); 1397 } 1398 icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++; 1399 1400exit: 1401 if (im6o != NULL) 1402 IM6O_REMREF(im6o); 1403 1404 ROUTE_RELEASE(&ro); 1405 return; 1406 1407bad: 1408 m_freem(m); 1409 goto exit; 1410} 1411 1412caddr_t 1413nd6_ifptomac( 1414 struct ifnet *ifp) 1415{ 1416 switch (ifp->if_type) { 1417 case IFT_ARCNET: 1418 case IFT_ETHER: 1419 case IFT_IEEE8023ADLAG: 1420 case IFT_FDDI: 1421 case IFT_IEEE1394: 1422#ifdef IFT_L2VLAN 1423 case IFT_L2VLAN: 1424#endif 1425#ifdef IFT_IEEE80211 1426 case IFT_IEEE80211: 1427#endif 1428#ifdef IFT_CARP 1429 case IFT_CARP: 1430#endif 1431 case IFT_BRIDGE: 1432 case IFT_ISO88025: 1433 return ((caddr_t)IF_LLADDR(ifp)); 1434 default: 1435 return NULL; 1436 } 1437} 1438 1439TAILQ_HEAD(dadq_head, dadq); 1440struct dadq { 1441 decl_lck_mtx_data(, dad_lock); 1442 u_int32_t dad_refcount; /* reference count */ 1443 int dad_attached; 1444 TAILQ_ENTRY(dadq) dad_list; 1445 struct ifaddr *dad_ifa; 1446 int dad_count; /* max NS to send */ 1447 int dad_ns_tcount; /* # of trials to send NS */ 1448 int dad_ns_ocount; /* NS sent so far */ 1449 int dad_ns_icount; 1450 int dad_na_icount; 1451 int dad_nd_ixcount; /* Count of IFDISABLED eligible ND rx'd */ 1452 uint8_t dad_ehsrc[ETHER_ADDR_LEN]; 1453}; 1454 1455static struct dadq_head dadq; 1456 1457void 1458nd6_nbr_init(void) 1459{ 1460 int i; 1461 1462 TAILQ_INIT(&dadq); 1463 1464 dad_size = sizeof (struct dadq); 1465 dad_zone = zinit(dad_size, DAD_ZONE_MAX * dad_size, 0, DAD_ZONE_NAME); 1466 if (dad_zone == NULL) { 1467 panic("%s: failed allocating %s", __func__, DAD_ZONE_NAME); 1468 /* NOTREACHED */ 1469 } 1470 zone_change(dad_zone, Z_EXPAND, TRUE); 1471 zone_change(dad_zone, Z_CALLERACCT, FALSE); 1472 1473 bzero(&hostrtmask, sizeof hostrtmask); 1474 hostrtmask.sin6_family = AF_INET6; 1475 hostrtmask.sin6_len = sizeof hostrtmask; 1476 for (i = 0; i < sizeof hostrtmask.sin6_addr; ++i) 1477 hostrtmask.sin6_addr.s6_addr[i] = 0xff; 1478} 1479 1480static struct dadq * 1481nd6_dad_find(struct ifaddr *ifa) 1482{ 1483 struct dadq *dp; 1484 1485 lck_mtx_lock(dad6_mutex); 1486 for (dp = dadq.tqh_first; dp; dp = dp->dad_list.tqe_next) { 1487 DAD_LOCK_SPIN(dp); 1488 if (dp->dad_ifa == ifa) { 1489 DAD_ADDREF_LOCKED(dp); 1490 DAD_UNLOCK(dp); 1491 lck_mtx_unlock(dad6_mutex); 1492 return (dp); 1493 } 1494 DAD_UNLOCK(dp); 1495 } 1496 lck_mtx_unlock(dad6_mutex); 1497 return (NULL); 1498} 1499 1500void 1501nd6_dad_stoptimer( 1502 struct ifaddr *ifa) 1503{ 1504 1505 untimeout((void (*)(void *))nd6_dad_timer, (void *)ifa); 1506} 1507 1508/* 1509 * Start Duplicate Address Detection (DAD) for specified interface address. 1510 */ 1511void 1512nd6_dad_start( 1513 struct ifaddr *ifa, 1514 int *tick_delay) /* minimum delay ticks for IFF_UP event */ 1515{ 1516 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1517 struct dadq *dp; 1518 1519 nd6log2((LOG_DEBUG, "%s - %s ifp %s ia6_flags 0x%x\n", 1520 __func__, 1521 ip6_sprintf(&ia->ia_addr.sin6_addr), 1522 if_name(ia->ia_ifp), 1523 ia->ia6_flags)); 1524 1525 /* 1526 * If we don't need DAD, don't do it. 1527 * There are several cases: 1528 * - DAD is disabled (ip6_dad_count == 0) 1529 * - the interface address is anycast 1530 */ 1531 IFA_LOCK(&ia->ia_ifa); 1532 if (!(ia->ia6_flags & IN6_IFF_DADPROGRESS)) { 1533 log(LOG_DEBUG, 1534 "nd6_dad_start: not a tentative or optimistic address " 1535 "%s(%s)\n", 1536 ip6_sprintf(&ia->ia_addr.sin6_addr), 1537 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1538 IFA_UNLOCK(&ia->ia_ifa); 1539 return; 1540 } 1541 if (!ip6_dad_count || (ia->ia6_flags & IN6_IFF_ANYCAST) != 0) { 1542 ia->ia6_flags &= ~IN6_IFF_DADPROGRESS; 1543 IFA_UNLOCK(&ia->ia_ifa); 1544 return; 1545 } 1546 IFA_UNLOCK(&ia->ia_ifa); 1547 if (ifa->ifa_ifp == NULL) 1548 panic("nd6_dad_start: ifa->ifa_ifp == NULL"); 1549 if (!(ifa->ifa_ifp->if_flags & IFF_UP) || 1550 (ifa->ifa_ifp->if_eflags & IFEF_IPV6_ND6ALT)) { 1551 return; 1552 } 1553 if ((dp = nd6_dad_find(ifa)) != NULL) { 1554 DAD_REMREF(dp); 1555 /* DAD already in progress */ 1556 return; 1557 } 1558 1559 dp = zalloc(dad_zone); 1560 if (dp == NULL) { 1561 log(LOG_ERR, "nd6_dad_start: memory allocation failed for " 1562 "%s(%s)\n", 1563 ip6_sprintf(&ia->ia_addr.sin6_addr), 1564 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1565 return; 1566 } 1567 bzero(dp, dad_size); 1568 lck_mtx_init(&dp->dad_lock, ifa_mtx_grp, ifa_mtx_attr); 1569 1570 /* Callee adds one reference for us */ 1571 dp = nd6_dad_attach(dp, ifa); 1572 1573 nd6log((LOG_DEBUG, "%s: starting %sDAD for %s\n", 1574 if_name(ifa->ifa_ifp), 1575 (ia->ia6_flags & IN6_IFF_OPTIMISTIC) ? "optimistic " : "", 1576 ip6_sprintf(&ia->ia_addr.sin6_addr))); 1577 1578 /* 1579 * Send NS packet for DAD, ip6_dad_count times. 1580 * Note that we must delay the first transmission, if this is the 1581 * first packet to be sent from the interface after interface 1582 * (re)initialization. 1583 */ 1584 if (tick_delay == NULL) { 1585 u_int32_t retrans; 1586 struct nd_ifinfo *ndi; 1587 1588 nd6_dad_ns_output(dp, ifa); 1589 lck_rw_lock_shared(nd_if_rwlock); 1590 ndi = ND_IFINFO(ifa->ifa_ifp); 1591 VERIFY(ndi != NULL && ndi->initialized); 1592 lck_mtx_lock(&ndi->lock); 1593 retrans = ndi->retrans * hz / 1000; 1594 lck_mtx_unlock(&ndi->lock); 1595 lck_rw_done(nd_if_rwlock); 1596 timeout((void (*)(void *))nd6_dad_timer, (void *)ifa, retrans); 1597 } else { 1598 int ntick; 1599 1600 if (*tick_delay == 0) 1601 ntick = random() % (MAX_RTR_SOLICITATION_DELAY * hz); 1602 else 1603 ntick = *tick_delay + random() % (hz / 2); 1604 *tick_delay = ntick; 1605 timeout((void (*)(void *))nd6_dad_timer, (void *)ifa, 1606 ntick); 1607 } 1608 1609 DAD_REMREF(dp); /* drop our reference */ 1610} 1611 1612static struct dadq * 1613nd6_dad_attach(struct dadq *dp, struct ifaddr *ifa) 1614{ 1615 lck_mtx_lock(dad6_mutex); 1616 DAD_LOCK(dp); 1617 dp->dad_ifa = ifa; 1618 IFA_ADDREF(ifa); /* for dad_ifa */ 1619 dp->dad_count = ip6_dad_count; 1620 dp->dad_ns_icount = dp->dad_na_icount = 0; 1621 dp->dad_ns_ocount = dp->dad_ns_tcount = 0; 1622 dp->dad_nd_ixcount = 0; 1623 VERIFY(!dp->dad_attached); 1624 dp->dad_attached = 1; 1625 DAD_ADDREF_LOCKED(dp); /* for caller */ 1626 DAD_ADDREF_LOCKED(dp); /* for dadq_head list */ 1627 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); 1628 DAD_UNLOCK(dp); 1629 lck_mtx_unlock(dad6_mutex); 1630 1631 return (dp); 1632} 1633 1634static void 1635nd6_dad_detach(struct dadq *dp, struct ifaddr *ifa) 1636{ 1637 int detached; 1638 1639 lck_mtx_lock(dad6_mutex); 1640 DAD_LOCK(dp); 1641 if ((detached = dp->dad_attached)) { 1642 VERIFY(dp->dad_ifa == ifa); 1643 TAILQ_REMOVE(&dadq, (struct dadq *)dp, dad_list); 1644 dp->dad_list.tqe_next = NULL; 1645 dp->dad_list.tqe_prev = NULL; 1646 dp->dad_attached = 0; 1647 } 1648 DAD_UNLOCK(dp); 1649 lck_mtx_unlock(dad6_mutex); 1650 if (detached) { 1651 DAD_REMREF(dp); /* drop dadq_head reference */ 1652 } 1653} 1654 1655/* 1656 * terminate DAD unconditionally. used for address removals. 1657 */ 1658void 1659nd6_dad_stop(struct ifaddr *ifa) 1660{ 1661 struct dadq *dp; 1662 1663 dp = nd6_dad_find(ifa); 1664 if (!dp) { 1665 /* DAD wasn't started yet */ 1666 return; 1667 } 1668 1669 untimeout((void (*)(void *))nd6_dad_timer, (void *)ifa); 1670 1671 nd6_dad_detach(dp, ifa); 1672 DAD_REMREF(dp); /* drop our reference */ 1673} 1674 1675static void 1676nd6_unsol_na_output(struct ifaddr *ifa) 1677{ 1678 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1679 struct ifnet *ifp = ifa->ifa_ifp; 1680 struct in6_addr saddr6, taddr6; 1681 1682 if ((ifp->if_flags & IFF_UP) == 0 || 1683 (ifp->if_flags & IFF_RUNNING) == 0 || 1684 (ifp->if_eflags & IFEF_IPV6_ND6ALT) != 0) 1685 return; 1686 1687 IFA_LOCK_SPIN(&ia->ia_ifa); 1688 taddr6 = ia->ia_addr.sin6_addr; 1689 IFA_UNLOCK(&ia->ia_ifa); 1690 if (in6_setscope(&taddr6, ifp, NULL) != 0) 1691 return; 1692 saddr6 = in6addr_linklocal_allnodes; 1693 if (in6_setscope(&saddr6, ifp, NULL) != 0) 1694 return; 1695 1696 nd6log((LOG_INFO, "%s: sending unsolicited NA\n", 1697 if_name(ifa->ifa_ifp))); 1698 1699 nd6_na_output(ifp, &saddr6, &taddr6, ND_NA_FLAG_OVERRIDE, 1, NULL); 1700} 1701 1702static void 1703nd6_dad_timer(struct ifaddr *ifa) 1704{ 1705 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1706 struct dadq *dp = NULL; 1707 struct nd_ifinfo *ndi; 1708 1709 /* Sanity check */ 1710 if (ia == NULL) { 1711 log(LOG_ERR, "nd6_dad_timer: called with null parameter\n"); 1712 goto done; 1713 } 1714 1715 nd6log2((LOG_DEBUG, "%s - %s ifp %s ia6_flags 0x%x\n", 1716 __func__, 1717 ip6_sprintf(&ia->ia_addr.sin6_addr), 1718 if_name(ia->ia_ifp), 1719 ia->ia6_flags)); 1720 1721 dp = nd6_dad_find(ifa); 1722 if (dp == NULL) { 1723 log(LOG_ERR, "nd6_dad_timer: DAD structure not found\n"); 1724 goto done; 1725 } 1726 IFA_LOCK(&ia->ia_ifa); 1727 if (ia->ia6_flags & IN6_IFF_DUPLICATED) { 1728 log(LOG_ERR, "nd6_dad_timer: called with duplicated address " 1729 "%s(%s)\n", 1730 ip6_sprintf(&ia->ia_addr.sin6_addr), 1731 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1732 IFA_UNLOCK(&ia->ia_ifa); 1733 goto done; 1734 } 1735 if ((ia->ia6_flags & IN6_IFF_DADPROGRESS) == 0) { 1736 log(LOG_ERR, "nd6_dad_timer: not a tentative or optimistic " 1737 "address %s(%s)\n", 1738 ip6_sprintf(&ia->ia_addr.sin6_addr), 1739 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1740 IFA_UNLOCK(&ia->ia_ifa); 1741 goto done; 1742 } 1743 IFA_UNLOCK(&ia->ia_ifa); 1744 1745 /* timeouted with IFF_{RUNNING,UP} check */ 1746 DAD_LOCK(dp); 1747 if (dp->dad_ns_tcount > dad_maxtry) { 1748 DAD_UNLOCK(dp); 1749 nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", 1750 if_name(ifa->ifa_ifp))); 1751 1752 nd6_dad_detach(dp, ifa); 1753 goto done; 1754 } 1755 1756 /* Need more checks? */ 1757 if (dp->dad_ns_ocount < dp->dad_count) { 1758 u_int32_t retrans; 1759 1760 DAD_UNLOCK(dp); 1761 /* 1762 * We have more NS to go. Send NS packet for DAD. 1763 */ 1764 nd6_dad_ns_output(dp, ifa); 1765 lck_rw_lock_shared(nd_if_rwlock); 1766 ndi = ND_IFINFO(ifa->ifa_ifp); 1767 VERIFY(ndi != NULL && ndi->initialized); 1768 lck_mtx_lock(&ndi->lock); 1769 retrans = ndi->retrans * hz / 1000; 1770 lck_mtx_unlock(&ndi->lock); 1771 lck_rw_done(nd_if_rwlock); 1772 timeout((void (*)(void *))nd6_dad_timer, (void *)ifa, retrans); 1773 } else { 1774 /* 1775 * We have transmitted sufficient number of DAD packets. 1776 * See what we've got. 1777 */ 1778 int duplicate; 1779 boolean_t candisable; 1780 1781 duplicate = 0; 1782 candisable = dp->dad_nd_ixcount > 0; 1783 1784 if (dp->dad_na_icount) { 1785 /* 1786 * the check is in nd6_dad_na_input(), 1787 * but just in case 1788 */ 1789 duplicate++; 1790 } 1791 1792 if (dp->dad_ns_icount) { 1793 /* We've seen NS, means DAD has failed. */ 1794 duplicate++; 1795 } 1796 DAD_UNLOCK(dp); 1797 1798 if (duplicate) { 1799 nd6log((LOG_INFO, 1800 "%s: duplicate IPv6 address %s [timer]\n", 1801 __func__, ip6_sprintf(&ia->ia_addr.sin6_addr), 1802 if_name(ia->ia_ifp))); 1803 nd6_dad_duplicated(ifa); 1804 /* (*dp) will be freed in nd6_dad_duplicated() */ 1805 } else { 1806 boolean_t txunsolna; 1807 1808 /* 1809 * We are done with DAD. No NA came, no NS came. 1810 * No duplicate address found. 1811 */ 1812 IFA_LOCK_SPIN(&ia->ia_ifa); 1813 ia->ia6_flags &= ~IN6_IFF_DADPROGRESS; 1814 IFA_UNLOCK(&ia->ia_ifa); 1815 1816 lck_rw_lock_shared(nd_if_rwlock); 1817 ndi = ND_IFINFO(ifa->ifa_ifp); 1818 VERIFY(ndi != NULL && ndi->initialized); 1819 lck_mtx_lock(&ndi->lock); 1820 txunsolna = (ndi->flags & ND6_IFF_REPLICATED) != 0; 1821 lck_mtx_unlock(&ndi->lock); 1822 lck_rw_done(nd_if_rwlock); 1823 1824 if (txunsolna) { 1825 nd6_unsol_na_output(ifa); 1826 } 1827 1828 nd6log((LOG_DEBUG, 1829 "%s: DAD complete for %s - no duplicates found%s\n", 1830 if_name(ifa->ifa_ifp), 1831 ip6_sprintf(&ia->ia_addr.sin6_addr), 1832 txunsolna ? ", tx unsolicited NA with O=1" : ".")); 1833 in6_post_msg(ia->ia_ifp, KEV_INET6_NEW_USER_ADDR, ia, 1834 dp->dad_ehsrc); 1835 nd6_dad_detach(dp, ifa); 1836 } 1837 } 1838 1839done: 1840 if (dp != NULL) 1841 DAD_REMREF(dp); /* drop our reference */ 1842} 1843 1844void 1845nd6_dad_duplicated(struct ifaddr *ifa) 1846{ 1847 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1848 struct dadq *dp; 1849 struct ifnet *ifp = ifa->ifa_ifp; 1850 boolean_t disable; 1851 1852 dp = nd6_dad_find(ifa); 1853 if (dp == NULL) { 1854 log(LOG_ERR, "%s: DAD structure not found.\n", __func__); 1855 return; 1856 } 1857 IFA_LOCK(&ia->ia_ifa); 1858 DAD_LOCK(dp); 1859 nd6log((LOG_ERR, "%s: NS in/out=%d/%d, NA in=%d, ND x=%d\n", 1860 __func__, dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_na_icount, 1861 dp->dad_nd_ixcount)); 1862 disable = dp->dad_nd_ixcount > 0; 1863 DAD_UNLOCK(dp); 1864 ia->ia6_flags &= ~IN6_IFF_DADPROGRESS; 1865 ia->ia6_flags |= IN6_IFF_DUPLICATED; 1866 IFA_UNLOCK(&ia->ia_ifa); 1867 1868 /* increment DAD collision counter */ 1869 ++ip6stat.ip6s_dad_collide; 1870 1871 /* We are done with DAD, with duplicated address found. (failure) */ 1872 untimeout((void (*)(void *))nd6_dad_timer, (void *)ifa); 1873 1874 IFA_LOCK(&ia->ia_ifa); 1875 log(LOG_ERR, "%s: DAD complete for %s - duplicate found.\n", 1876 if_name(ifp), ip6_sprintf(&ia->ia_addr.sin6_addr)); 1877 IFA_UNLOCK(&ia->ia_ifa); 1878 1879 if (disable) { 1880 log(LOG_ERR, "%s: possible hardware address duplication " 1881 "detected, disabling IPv6 for interface.\n", if_name(ifp)); 1882 1883 lck_rw_lock_shared(nd_if_rwlock); 1884 nd_ifinfo[ifp->if_index].flags |= ND6_IFF_IFDISABLED; 1885 lck_rw_done(nd_if_rwlock); 1886 /* Make sure to set IFEF_IPV6_DISABLED too */ 1887 nd6_if_disable(ifp, TRUE); 1888 } 1889 1890 log(LOG_ERR, "%s: manual intervention required!\n", if_name(ifp)); 1891 1892 /* Send an event to the configuration agent so that the 1893 * duplicate address will be notified to the user and will 1894 * be removed. 1895 */ 1896 in6_post_msg(ifp, KEV_INET6_NEW_USER_ADDR, ia, dp->dad_ehsrc); 1897 nd6_dad_detach(dp, ifa); 1898 DAD_REMREF(dp); /* drop our reference */ 1899} 1900 1901static void 1902nd6_dad_ns_output(struct dadq *dp, struct ifaddr *ifa) 1903{ 1904 struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; 1905 struct ifnet *ifp = ifa->ifa_ifp; 1906 struct in6_addr taddr6; 1907 1908 DAD_LOCK(dp); 1909 dp->dad_ns_tcount++; 1910 if ((ifp->if_flags & IFF_UP) == 0) { 1911 DAD_UNLOCK(dp); 1912 return; 1913 } 1914 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1915 DAD_UNLOCK(dp); 1916 return; 1917 } 1918 1919 dp->dad_ns_ocount++; 1920 DAD_UNLOCK(dp); 1921 IFA_LOCK_SPIN(&ia->ia_ifa); 1922 taddr6 = ia->ia_addr.sin6_addr; 1923 IFA_UNLOCK(&ia->ia_ifa); 1924 nd6_ns_output(ifp, NULL, &taddr6, NULL, 1); 1925} 1926 1927static void 1928nd6_dad_ns_input(struct mbuf *m, struct ifaddr *ifa, char *lladdr, 1929 int lladdrlen) 1930{ 1931 struct dadq *dp; 1932 struct in6_ifaddr *ia; 1933 boolean_t candisable, dadstarted; 1934 struct ip6aux *ip6a; 1935 1936 VERIFY(ifa != NULL); 1937 candisable = FALSE; 1938 IFA_LOCK(ifa); 1939 ia = (struct in6_ifaddr *) ifa; 1940 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) { 1941 ip6a = ip6_findaux(m); 1942 candisable = TRUE; 1943 if (ip6a && (ip6a->ip6a_flags & IP6A_HASEEN) != 0) { 1944 struct in6_addr in6 = ia->ia_addr.sin6_addr; 1945 1946 nd6log((LOG_INFO, 1947 "%s: eh_src=%02x:%02x:%02x:%02x:%02x:%02x -> %s\n", 1948 __func__, 1949 ip6a->ip6a_ehsrc[0], ip6a->ip6a_ehsrc[1], 1950 ip6a->ip6a_ehsrc[2], ip6a->ip6a_ehsrc[3], 1951 ip6a->ip6a_ehsrc[4], ip6a->ip6a_ehsrc[5], 1952 if_name(ifa->ifa_ifp))); 1953 1954 in6.s6_addr8[8] = ip6a->ip6a_ehsrc[0] ^ ND6_EUI64_UBIT; 1955 in6.s6_addr8[9] = ip6a->ip6a_ehsrc[1]; 1956 in6.s6_addr8[10] = ip6a->ip6a_ehsrc[2]; 1957 in6.s6_addr8[11] = 0xff; 1958 in6.s6_addr8[12] = 0xfe; 1959 in6.s6_addr8[13] = ip6a->ip6a_ehsrc[3]; 1960 in6.s6_addr8[14] = ip6a->ip6a_ehsrc[4]; 1961 in6.s6_addr8[15] = ip6a->ip6a_ehsrc[5]; 1962 1963 if (!IN6_ARE_ADDR_EQUAL(&in6, &ia->ia_addr.sin6_addr)) { 1964 nd6log((LOG_ERR, "%s: DAD NS for %s on %s " 1965 "is from another MAC address.\n", __func__, 1966 ip6_sprintf(&ia->ia_addr.sin6_addr), 1967 if_name(ifa->ifa_ifp))); 1968 candisable = FALSE; 1969 } 1970 } else { 1971 nd6log((LOG_INFO, 1972 "%s: no eh_src for DAD NS %s at %s.\n", __func__, 1973 ip6_sprintf(&ia->ia_addr.sin6_addr), 1974 if_name(ifa->ifa_ifp))); 1975 } 1976 } 1977 IFA_UNLOCK(ifa); 1978 1979 /* If DAD has not yet started, then this DAD NS probe is proof that 1980 * another node has started first. Otherwise, it could be a multicast 1981 * loopback, in which case it should be counted and handled later in 1982 * the DAD timer callback. 1983 */ 1984 dadstarted = FALSE; 1985 dp = nd6_dad_find(ifa); 1986 if (dp != NULL) { 1987 DAD_LOCK(dp); 1988 ++dp->dad_ns_icount; 1989 if (candisable) 1990 ++dp->dad_nd_ixcount; 1991 if (dp->dad_ns_ocount > 0) 1992 dadstarted = TRUE; 1993 if (lladdr && lladdrlen >= ETHER_ADDR_LEN) 1994 memcpy(dp->dad_ehsrc, lladdr, ETHER_ADDR_LEN); 1995 DAD_UNLOCK(dp); 1996 DAD_REMREF(dp); 1997 dp = NULL; 1998 } 1999 2000 nd6log((LOG_INFO, "%s: dadstarted=%d candisable=%d\n", 2001 __func__, dadstarted, candisable)); 2002 2003 if (!dadstarted) { 2004 nd6log((LOG_INFO, 2005 "%s: duplicate IPv6 address %s [processing NS on %s]\n", 2006 __func__, ip6_sprintf(&ia->ia_addr.sin6_addr), 2007 if_name(ifa->ifa_ifp))); 2008 nd6_dad_duplicated(ifa); 2009 } 2010} 2011 2012static struct mbuf * 2013nd6_dad_na_input(struct mbuf *m, struct ifnet *ifp, struct in6_addr *taddr, 2014 caddr_t lladdr, int lladdrlen) 2015{ 2016 struct ifaddr *ifa; 2017 struct in6_ifaddr *ia; 2018 struct dadq *dp; 2019 struct nd_ifinfo *ndi; 2020 boolean_t candisable, replicated; 2021 2022 ifa = (struct ifaddr *) in6ifa_ifpwithaddr(ifp, taddr); 2023 if (ifa == NULL) 2024 return m; 2025 2026 candisable = FALSE; 2027 replicated = FALSE; 2028 2029 /* Get the ND6_IFF_REPLICATED flag. */ 2030 lck_rw_lock_shared(nd_if_rwlock); 2031 ndi = ND_IFINFO(ifp); 2032 if (ndi != NULL && ndi->initialized) { 2033 lck_mtx_lock(&ndi->lock); 2034 replicated = !!(ndi->flags & ND6_IFF_REPLICATED); 2035 lck_mtx_unlock(&ndi->lock); 2036 } 2037 lck_rw_done(nd_if_rwlock); 2038 if (replicated) { 2039 nd6log((LOG_INFO, "%s: ignoring duplicate NA on " 2040 "replicated interface %s\n", __func__, if_name(ifp))); 2041 goto done; 2042 } 2043 2044 /* Lock the interface address until done (see label below). */ 2045 IFA_LOCK(ifa); 2046 ia = (struct in6_ifaddr *) ifa; 2047 2048 /* 2049 * If the address is a link-local address formed from an interface 2050 * identifier based on the hardware address which is supposed to be 2051 * uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP 2052 * operation on the interface SHOULD be disabled according to RFC 4862, 2053 * section 5.4.5, but here we decide not to disable if the target 2054 * hardware address is not also ours, which is a transitory possibility 2055 * in the presence of network-resident sleep proxies on the local link. 2056 */ 2057 if (!(ia->ia6_flags & IN6_IFF_DADPROGRESS)) { 2058 IFA_UNLOCK(ifa); 2059 nd6log((LOG_INFO, "%s: ignoring duplicate NA on " 2060 "%s [DAD not in progress]\n", __func__, 2061 if_name(ifp))); 2062 goto done; 2063 } 2064 2065 /* Some sleep proxies improperly send the client's Ethernet address in 2066 * the target link-layer address option, so detect this by comparing 2067 * the L2-header source address, if we have seen it, with the target 2068 * address, and ignoring the NA if they don't match. 2069 */ 2070 if (lladdr != NULL && lladdrlen >= ETHER_ADDR_LEN) { 2071 struct ip6aux *ip6a = ip6_findaux(m); 2072 if (ip6a && (ip6a->ip6a_flags & IP6A_HASEEN) != 0 && 2073 bcmp(ip6a->ip6a_ehsrc, lladdr, ETHER_ADDR_LEN) != 0) { 2074 IFA_UNLOCK(ifa); 2075 nd6log((LOG_ERR, "%s: ignoring duplicate NA on %s " 2076 "[eh_src != tgtlladdr]\n", __func__, if_name(ifp))); 2077 goto done; 2078 } 2079 } 2080 2081 IFA_UNLOCK(ifa); 2082 2083 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr) && 2084 !(ia->ia6_flags & IN6_IFF_SECURED)) { 2085 struct in6_addr in6; 2086 2087 /* 2088 * To avoid over-reaction, we only apply this logic when we are 2089 * very sure that hardware addresses are supposed to be unique. 2090 */ 2091 switch (ifp->if_type) { 2092 case IFT_BRIDGE: 2093 case IFT_ETHER: 2094 case IFT_FDDI: 2095 case IFT_ATM: 2096 case IFT_IEEE1394: 2097#ifdef IFT_IEEE80211 2098 case IFT_IEEE80211: 2099#endif 2100 /* Check if our hardware address matches the target */ 2101 if (lladdr != NULL && lladdrlen > 0) { 2102 struct ifaddr *llifa; 2103 struct sockaddr_dl *sdl; 2104 2105 llifa = ifp->if_lladdr; 2106 IFA_LOCK(llifa); 2107 sdl = (struct sockaddr_dl *)(void *) 2108 llifa->ifa_addr; 2109 if (lladdrlen == sdl->sdl_alen && 2110 bcmp(lladdr, LLADDR(sdl), lladdrlen) == 0) 2111 candisable = TRUE; 2112 IFA_UNLOCK(llifa); 2113 } 2114 in6 = ia->ia_addr.sin6_addr; 2115 if (in6_iid_from_hw(ifp, &in6) != 0) 2116 break; 2117 2118 /* Refine decision about whether IPv6 can be disabled */ 2119 IFA_LOCK(ifa); 2120 if (candisable && 2121 !IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) { 2122 /* 2123 * Apply this logic only to the embedded MAC 2124 * address form of link-local IPv6 address. 2125 */ 2126 candisable = FALSE; 2127 } else if (lladdr == NULL && 2128 IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) { 2129 /* 2130 * We received a NA with no target link-layer 2131 * address option. This means that someone else 2132 * has our address. Mark it as a hardware 2133 * duplicate so we disable IPv6 later on. 2134 */ 2135 candisable = TRUE; 2136 } 2137 IFA_UNLOCK(ifa); 2138 break; 2139 default: 2140 break; 2141 } 2142 } 2143 2144 dp = nd6_dad_find(ifa); 2145 if (dp == NULL) { 2146 nd6log((LOG_INFO, "%s: no DAD structure for %s on %s.\n", 2147 __func__, ip6_sprintf(taddr), if_name(ifp))); 2148 goto done; 2149 } 2150 2151 DAD_LOCK_SPIN(dp); 2152 if (lladdr != NULL && lladdrlen >= ETHER_ADDR_LEN) 2153 memcpy(dp->dad_ehsrc, lladdr, ETHER_ADDR_LEN); 2154 dp->dad_na_icount++; 2155 if (candisable) 2156 dp->dad_nd_ixcount++; 2157 DAD_UNLOCK(dp); 2158 DAD_REMREF(dp); 2159 2160 /* remove the address. */ 2161 nd6log((LOG_INFO, 2162 "%s: duplicate IPv6 address %s [processing NA on %s]\n", __func__, 2163 ip6_sprintf(taddr), if_name(ifp))); 2164 nd6_dad_duplicated(ifa); 2165 2166done: 2167 IFA_LOCK_ASSERT_NOTHELD(ifa); 2168 IFA_REMREF(ifa); 2169 m_freem(m); 2170 return NULL; 2171} 2172 2173static void 2174dad_addref(struct dadq *dp, int locked) 2175{ 2176 if (!locked) 2177 DAD_LOCK_SPIN(dp); 2178 else 2179 DAD_LOCK_ASSERT_HELD(dp); 2180 2181 if (++dp->dad_refcount == 0) { 2182 panic("%s: dad %p wraparound refcnt\n", __func__, dp); 2183 /* NOTREACHED */ 2184 } 2185 if (!locked) 2186 DAD_UNLOCK(dp); 2187} 2188 2189static void 2190dad_remref(struct dadq *dp) 2191{ 2192 struct ifaddr *ifa; 2193 2194 DAD_LOCK_SPIN(dp); 2195 if (dp->dad_refcount == 0) 2196 panic("%s: dad %p negative refcnt\n", __func__, dp); 2197 --dp->dad_refcount; 2198 if (dp->dad_refcount > 0) { 2199 DAD_UNLOCK(dp); 2200 return; 2201 } 2202 DAD_UNLOCK(dp); 2203 2204 if (dp->dad_attached || 2205 dp->dad_list.tqe_next != NULL || dp->dad_list.tqe_prev != NULL) { 2206 panic("%s: attached dad=%p is being freed", __func__, dp); 2207 /* NOTREACHED */ 2208 } 2209 2210 if ((ifa = dp->dad_ifa) != NULL) { 2211 IFA_REMREF(ifa); /* drop dad_ifa reference */ 2212 dp->dad_ifa = NULL; 2213 } 2214 2215 lck_mtx_destroy(&dp->dad_lock, ifa_mtx_grp); 2216 zfree(dad_zone, dp); 2217} 2218 2219void 2220nd6_llreach_set_reachable(struct ifnet *ifp, void *addr, unsigned int alen) 2221{ 2222 /* Nothing more to do if it's disabled */ 2223 if (nd6_llreach_base == 0) 2224 return; 2225 2226 ifnet_llreach_set_reachable(ifp, ETHERTYPE_IPV6, addr, alen); 2227} 2228 2229void 2230nd6_alt_node_addr_decompose(struct ifnet *ifp, struct sockaddr *sa, 2231 struct sockaddr_dl* sdl, struct sockaddr_in6 *sin6) 2232{ 2233 static const size_t EUI64_LENGTH = 8; 2234 2235 VERIFY(nd6_need_cache(ifp)); 2236 VERIFY(sa); 2237 VERIFY(sdl && (void *)sa != (void *)sdl); 2238 VERIFY(sin6 && (void *)sa != (void *)sin6); 2239 2240 bzero(sin6, sizeof *sin6); 2241 sin6->sin6_len = sizeof *sin6; 2242 sin6->sin6_family = AF_INET6; 2243 2244 bzero(sdl, sizeof *sdl); 2245 sdl->sdl_len = sizeof *sdl; 2246 sdl->sdl_family = AF_LINK; 2247 sdl->sdl_type = ifp->if_type; 2248 sdl->sdl_index = ifp->if_index; 2249 2250 switch (sa->sa_family) { 2251 case AF_INET6: { 2252 struct sockaddr_in6 *sin6a = (struct sockaddr_in6 *)(void *)sa; 2253 struct in6_addr *in6 = &sin6a->sin6_addr; 2254 2255 VERIFY(sa->sa_len == sizeof *sin6); 2256 2257 sdl->sdl_nlen = strlen(ifp->if_name); 2258 bcopy(ifp->if_name, sdl->sdl_data, sdl->sdl_nlen); 2259 if (in6->s6_addr[11] == 0xff && in6->s6_addr[12] == 0xfe) { 2260 sdl->sdl_alen = ETHER_ADDR_LEN; 2261 LLADDR(sdl)[0] = (in6->s6_addr[8] ^ ND6_EUI64_UBIT); 2262 LLADDR(sdl)[1] = in6->s6_addr[9]; 2263 LLADDR(sdl)[2] = in6->s6_addr[10]; 2264 LLADDR(sdl)[3] = in6->s6_addr[13]; 2265 LLADDR(sdl)[4] = in6->s6_addr[14]; 2266 LLADDR(sdl)[5] = in6->s6_addr[15]; 2267 } else { 2268 sdl->sdl_alen = EUI64_LENGTH; 2269 bcopy(&in6->s6_addr[8], LLADDR(sdl), EUI64_LENGTH); 2270 } 2271 2272 sdl->sdl_slen = 0; 2273 break; 2274 } 2275 case AF_LINK: { 2276 struct sockaddr_dl *sdla = (struct sockaddr_dl *)(void *)sa; 2277 struct in6_addr *in6 = &sin6->sin6_addr; 2278 caddr_t lla = LLADDR(sdla); 2279 2280 VERIFY(sa->sa_len <= sizeof *sdl); 2281 bcopy(sa, sdl, sa->sa_len); 2282 2283 sin6->sin6_scope_id = sdla->sdl_index; 2284 if (sin6->sin6_scope_id == 0) 2285 sin6->sin6_scope_id = ifp->if_index; 2286 in6->s6_addr[0] = 0xfe; 2287 in6->s6_addr[1] = 0x80; 2288 if (sdla->sdl_alen == EUI64_LENGTH) 2289 bcopy(lla, &in6->s6_addr[8], EUI64_LENGTH); 2290 else { 2291 VERIFY(sdla->sdl_alen == ETHER_ADDR_LEN); 2292 2293 in6->s6_addr[8] = ((uint8_t) lla[0] ^ ND6_EUI64_UBIT); 2294 in6->s6_addr[9] = (uint8_t) lla[1]; 2295 in6->s6_addr[10] = (uint8_t) lla[2]; 2296 in6->s6_addr[11] = 0xff; 2297 in6->s6_addr[12] = 0xfe; 2298 in6->s6_addr[13] = (uint8_t) lla[3]; 2299 in6->s6_addr[14] = (uint8_t) lla[4]; 2300 in6->s6_addr[15] = (uint8_t) lla[5]; 2301 } 2302 2303 break; 2304 } 2305 default: 2306 VERIFY(false); 2307 break; 2308 } 2309} 2310 2311void 2312nd6_alt_node_present(struct ifnet *ifp, struct sockaddr_in6 *sin6, 2313 struct sockaddr_dl *sdl, int32_t rssi, int lqm, int npm) 2314{ 2315 struct rtentry *rt; 2316 struct llinfo_nd6 *ln; 2317 struct if_llreach *lr; 2318 2319 nd6_cache_lladdr(ifp, &sin6->sin6_addr, LLADDR(sdl), sdl->sdl_alen, 2320 ND_NEIGHBOR_ADVERT, 0); 2321 2322 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED); 2323 lck_mtx_lock(rnh_lock); 2324 2325 rt = rtalloc1_scoped_locked((struct sockaddr *)sin6, 1, 0, 2326 ifp->if_index); 2327 if (rt != NULL) { 2328 RT_LOCK(rt); 2329 VERIFY(rt->rt_flags & RTF_LLINFO); 2330 VERIFY(rt->rt_llinfo); 2331 2332 ln = rt->rt_llinfo; 2333 ln->ln_state = ND6_LLINFO_REACHABLE; 2334 ln_setexpire(ln, 0); 2335 2336 lr = ln->ln_llreach; 2337 if (lr) { 2338 IFLR_LOCK(lr); 2339 lr->lr_rssi = rssi; 2340 lr->lr_lqm = (int32_t) lqm; 2341 lr->lr_npm = (int32_t) npm; 2342 IFLR_UNLOCK(lr); 2343 } 2344 2345 RT_UNLOCK(rt); 2346 RT_REMREF(rt); 2347 } 2348 2349 lck_mtx_unlock(rnh_lock); 2350 2351 if (rt == NULL) { 2352 log(LOG_ERR, "%s: failed to add/update host route to %s.\n", 2353 __func__, ip6_sprintf(&sin6->sin6_addr)); 2354 } else { 2355 nd6log((LOG_DEBUG, "%s: host route to %s [lr=0x%llx]\n", 2356 __func__, ip6_sprintf(&sin6->sin6_addr), 2357 (uint64_t)VM_KERNEL_ADDRPERM(lr))); 2358 } 2359} 2360 2361void 2362nd6_alt_node_absent(struct ifnet *ifp, struct sockaddr_in6 *sin6) 2363{ 2364 struct rtentry *rt; 2365 2366 nd6log((LOG_DEBUG, "%s: host route to %s\n", __func__, 2367 ip6_sprintf(&sin6->sin6_addr))); 2368 2369 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_NOTOWNED); 2370 lck_mtx_lock(rnh_lock); 2371 2372 rt = rtalloc1_scoped_locked((struct sockaddr *)sin6, 0, 0, 2373 ifp->if_index); 2374 if (rt != NULL) { 2375 RT_LOCK(rt); 2376 2377 if (!(rt->rt_flags & (RTF_CLONING|RTF_PRCLONING)) && 2378 (rt->rt_flags & (RTF_HOST|RTF_LLINFO|RTF_WASCLONED)) == 2379 (RTF_HOST|RTF_LLINFO|RTF_WASCLONED)) { 2380 rt->rt_flags |= RTF_CONDEMNED; 2381 RT_UNLOCK(rt); 2382 2383 (void) rtrequest_locked(RTM_DELETE, rt_key(rt), 2384 (struct sockaddr *)NULL, rt_mask(rt), 0, 2385 (struct rtentry **)NULL); 2386 2387 rtfree_locked(rt); 2388 } else { 2389 RT_REMREF_LOCKED(rt); 2390 RT_UNLOCK(rt); 2391 } 2392 } 2393 2394 lck_mtx_unlock(rnh_lock); 2395} 2396