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