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