]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/nd6_nbr.c
xnu-2782.30.5.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6_nbr.c
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
100 struct dadq;
101 static struct dadq *nd6_dad_find(struct ifaddr *);
102 void nd6_dad_stoptimer(struct ifaddr *);
103 static void nd6_dad_timer(struct ifaddr *);
104 static void nd6_dad_ns_output(struct dadq *, struct ifaddr *);
105 static void nd6_dad_ns_input(struct mbuf *, struct ifaddr *, char *, int);
106 static struct mbuf *nd6_dad_na_input(struct mbuf *, struct ifnet *,
107 struct in6_addr *, caddr_t, int);
108 static void dad_addref(struct dadq *, int);
109 static void dad_remref(struct dadq *);
110 static struct dadq *nd6_dad_attach(struct dadq *, struct ifaddr *);
111 static void nd6_dad_detach(struct dadq *, struct ifaddr *);
112
113 static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */
114
115 static unsigned int dad_size; /* size of zone element */
116 static 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
150 extern lck_mtx_t *dad6_mutex;
151 extern lck_mtx_t *nd6_mutex;
152
153 static int nd6_llreach_base = (LL_BASE_REACHABLE / 1000); /* seconds */
154
155 static struct sockaddr_in6 hostrtmask;
156
157 SYSCTL_DECL(_net_inet6_icmp6);
158
159 SYSCTL_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 */
168 void
169 nd6_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
231 void
232 nd6_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 */
244 void
245 nd6_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 */
542 void
543 nd6_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
808 exit:
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
818 bad:
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 */
833 void
834 nd6_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
1191 bad:
1192 icmp6stat.icp6s_badna++;
1193 /* fall through */
1194
1195 freeit:
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 */
1211 void
1212 nd6_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
1400 exit:
1401 if (im6o != NULL)
1402 IM6O_REMREF(im6o);
1403
1404 ROUTE_RELEASE(&ro);
1405 return;
1406
1407 bad:
1408 m_freem(m);
1409 goto exit;
1410 }
1411
1412 caddr_t
1413 nd6_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
1439 TAILQ_HEAD(dadq_head, dadq);
1440 struct 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
1455 static struct dadq_head dadq;
1456
1457 void
1458 nd6_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
1480 static struct dadq *
1481 nd6_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
1500 void
1501 nd6_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 */
1511 void
1512 nd6_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
1612 static struct dadq *
1613 nd6_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
1634 static void
1635 nd6_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 */
1658 void
1659 nd6_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
1675 static void
1676 nd6_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
1702 static void
1703 nd6_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
1839 done:
1840 if (dp != NULL)
1841 DAD_REMREF(dp); /* drop our reference */
1842 }
1843
1844 void
1845 nd6_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
1901 static void
1902 nd6_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
1927 static void
1928 nd6_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
2012 static struct mbuf *
2013 nd6_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
2166 done:
2167 IFA_LOCK_ASSERT_NOTHELD(ifa);
2168 IFA_REMREF(ifa);
2169 m_freem(m);
2170 return NULL;
2171 }
2172
2173 static void
2174 dad_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
2189 static void
2190 dad_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
2219 void
2220 nd6_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
2229 void
2230 nd6_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
2311 void
2312 nd6_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
2361 void
2362 nd6_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 }