1/*
2 * Copyright (c) 2003-2022 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29/*
30 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. Neither the name of the project nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57#include <sys/param.h>
58#include <sys/systm.h>
59#include <sys/malloc.h>
60#include <sys/mbuf.h>
61#include <sys/socket.h>
62#include <sys/sockio.h>
63#include <sys/time.h>
64#include <sys/kernel.h>
65#include <sys/errno.h>
66#include <sys/syslog.h>
67#include <sys/queue.h>
68#include <sys/mcache.h>
69#include <sys/protosw.h>
70
71#include <dev/random/randomdev.h>
72
73#include <kern/locks.h>
74#include <kern/zalloc.h>
75#include <machine/machine_routines.h>
76
77#include <net/if.h>
78#include <net/if_var.h>
79#include <net/if_types.h>
80#include <net/if_dl.h>
81#include <net/route.h>
82#include <net/radix.h>
83
84#include <netinet/in.h>
85#include <netinet6/in6_var.h>
86#include <netinet6/in6_ifattach.h>
87#include <netinet/ip6.h>
88#include <netinet6/ip6_var.h>
89#include <netinet6/nd6.h>
90#include <netinet/icmp6.h>
91#include <netinet6/scope6_var.h>
92
93#include <net/net_osdep.h>
94
95#include <net/sockaddr_utils.h>
96
97static void defrouter_addreq(struct nd_defrouter *, struct nd_route_info *, boolean_t);
98static void defrouter_delreq(struct nd_defrouter *, struct nd_route_info *);
99static struct nd_defrouter *defrtrlist_update_common(struct nd_defrouter *,
100 struct nd_drhead *, boolean_t);
101static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
102static void pfxrtr_del(struct nd_pfxrouter *, struct nd_prefix *);
103static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
104static void nd6_rtmsg(u_char, struct rtentry *);
105
106static int nd6_prefix_onlink_common(struct nd_prefix *, boolean_t,
107 unsigned int);
108static struct nd_prefix *nd6_prefix_equal_lookup(struct nd_prefix *, boolean_t);
109static void nd6_prefix_sync(struct ifnet *);
110
111static void in6_init_address_ltimes(struct in6_addrlifetime *);
112static int rt6_deleteroute(struct radix_node *, void *);
113
114static struct nd_defrouter *nddr_alloc(zalloc_flags_t);
115static void nddr_free(struct nd_defrouter *);
116static void nddr_trace(struct nd_defrouter *, int);
117
118static struct nd_prefix *ndpr_alloc(int);
119static void ndpr_free(struct nd_prefix *);
120static void ndpr_trace(struct nd_prefix *, int);
121
122extern int nd6_recalc_reachtm_interval;
123
124static struct ifnet *nd6_defifp = NULL;
125int nd6_defifindex = 0;
126static unsigned int nd6_defrouter_genid;
127
128int ip6_use_tempaddr = IP6_USE_TMPADDR_DEFAULT; /* use temp addr by default for testing now */
129int ip6_ula_use_tempaddr = IP6_ULA_USE_TMPADDR_DEFAULT;
130
131int nd6_accept_6to4 = 1;
132
133int ip6_desync_factor;
134u_int32_t ip6_temp_preferred_lifetime = DEF_TEMP_PREFERRED_LIFETIME;
135u_int32_t ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME;
136/*
137 * shorter lifetimes for debugging purposes.
138 * u_int32_t ip6_temp_preferred_lifetime = 800;
139 * static u_int32_t ip6_temp_valid_lifetime = 1800;
140 */
141int ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE;
142
143/* Serialization variables for single thread access to nd_prefix */
144static boolean_t nd_prefix_busy;
145static void *nd_prefix_waitchan = &nd_prefix_busy;
146static int nd_prefix_waiters = 0;
147
148/* Serialization variables for single thread access to nd_defrouter */
149static boolean_t nd_defrouter_busy;
150static void *nd_defrouter_waitchan = &nd_defrouter_busy;
151static int nd_defrouter_waiters = 0;
152
153#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
154/* RTPREF_MEDIUM has to be 0! */
155#define RTPREF_HIGH 1
156#define RTPREF_MEDIUM 0
157#define RTPREF_LOW (-1)
158#define RTPREF_RESERVED (-2)
159#define RTPREF_INVALID (-3) /* internal */
160
161#define NDPR_TRACE_HIST_SIZE 32 /* size of trace history */
162
163/* For gdb */
164__private_extern__ unsigned int ndpr_trace_hist_size = NDPR_TRACE_HIST_SIZE;
165
166struct nd_prefix_dbg {
167 struct nd_prefix ndpr_pr; /* nd_prefix */
168 u_int16_t ndpr_refhold_cnt; /* # of ref */
169 u_int16_t ndpr_refrele_cnt; /* # of rele */
170 /*
171 * Circular lists of ndpr_addref and ndpr_remref callers.
172 */
173 ctrace_t ndpr_refhold[NDPR_TRACE_HIST_SIZE];
174 ctrace_t ndpr_refrele[NDPR_TRACE_HIST_SIZE];
175};
176
177static unsigned int ndpr_debug; /* debug flags */
178static struct zone *ndpr_zone; /* zone for nd_prefix */
179#define NDPR_ZONE_NAME "nd6_prefix" /* zone name */
180
181#define NDDR_TRACE_HIST_SIZE 32 /* size of trace history */
182
183/* For gdb */
184__private_extern__ unsigned int nddr_trace_hist_size = NDDR_TRACE_HIST_SIZE;
185
186struct nd_defrouter_dbg {
187 struct nd_defrouter nddr_dr; /* nd_defrouter */
188 uint16_t nddr_refhold_cnt; /* # of ref */
189 uint16_t nddr_refrele_cnt; /* # of rele */
190 /*
191 * Circular lists of nddr_addref and nddr_remref callers.
192 */
193 ctrace_t nddr_refhold[NDDR_TRACE_HIST_SIZE];
194 ctrace_t nddr_refrele[NDDR_TRACE_HIST_SIZE];
195};
196
197static unsigned int nddr_debug; /* debug flags */
198static struct zone *nddr_zone; /* zone for nd_defrouter */
199#define NDDR_ZONE_NAME "nd6_defrouter" /* zone name */
200
201static KALLOC_TYPE_DEFINE(ndprtr_zone, struct nd_pfxrouter, NET_KT_DEFAULT);
202
203#define TWOHOUR (120*60)
204extern int nd6_process_rti; /* Default to 0 for now */
205
206
207static void
208nd6_prefix_glb_init(void)
209{
210 PE_parse_boot_argn(arg_string: "ifa_debug", arg_ptr: &ndpr_debug, max_arg: sizeof(ndpr_debug));
211 vm_size_t ndpr_size = (ndpr_debug == 0) ? sizeof(struct nd_prefix) :
212 sizeof(struct nd_prefix_dbg);
213 ndpr_zone = zone_create(NDPR_ZONE_NAME, size: ndpr_size, flags: ZC_ZFREE_CLEARMEM);
214}
215
216static void
217nd6_defrouter_glb_init(void)
218{
219 PE_parse_boot_argn(arg_string: "ifa_debug", arg_ptr: &nddr_debug, max_arg: sizeof(nddr_debug));
220 vm_size_t nddr_size = (nddr_debug == 0) ? sizeof(struct nd_defrouter) :
221 sizeof(struct nd_defrouter_dbg);
222 nddr_zone = zone_create(NDDR_ZONE_NAME, size: nddr_size, flags: ZC_ZFREE_CLEARMEM);
223}
224
225void
226nd6_rtr_init(void)
227{
228 nd6_prefix_glb_init();
229 nd6_defrouter_glb_init();
230}
231
232/*
233 * Receive Router Solicitation Message - just for routers.
234 * Router solicitation/advertisement is mostly managed by userland program
235 * (rtadvd) so here we have no function like nd6_ra_output().
236 *
237 * Based on RFC 2461
238 */
239void
240nd6_rs_input(
241 struct mbuf *m,
242 int off,
243 int icmp6len)
244{
245 struct ifnet *ifp = m->m_pkthdr.rcvif;
246 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
247 struct nd_router_solicit *nd_rs = NULL;
248 struct in6_addr saddr6 = ip6->ip6_src;
249 char *lladdr = NULL;
250 int lladdrlen = 0;
251 union nd_opts ndopts = {};
252
253 /* Expect 32-bit aligned data pointer on strict-align platforms */
254 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
255
256 /* If I'm not a router, ignore it. */
257 if (!ip6_forwarding || ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_DISABLED) {
258 goto freeit;
259 }
260
261 /* Sanity checks */
262 if (ip6->ip6_hlim != IPV6_MAXHLIM) {
263 nd6log(error,
264 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
265 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
266 ip6_sprintf(&ip6->ip6_dst), if_name(ifp));
267 goto bad;
268 }
269
270 /*
271 * Don't update the neighbor cache, if src = :: or a non-neighbor.
272 * The former case indicates that the src has no IP address assigned
273 * yet. See nd6_ns_input() for the latter case.
274 */
275 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
276 goto freeit;
277 } else {
278 struct sockaddr_in6 src_sa6;
279
280 SOCKADDR_ZERO(&src_sa6, sizeof(src_sa6));
281 src_sa6.sin6_family = AF_INET6;
282 src_sa6.sin6_len = sizeof(src_sa6);
283 src_sa6.sin6_addr = ip6->ip6_src;
284 src_sa6.sin6_scope_id = (!in6_embedded_scope && IN6_IS_SCOPE_EMBED(&src_sa6.sin6_addr)) ? ip6_input_getsrcifscope(m) : IFSCOPE_NONE;
285 if (!nd6_is_addr_neighbor(&src_sa6, ifp, 0)) {
286 nd6log(info, "nd6_rs_input: "
287 "RS packet from non-neighbor\n");
288 goto freeit;
289 }
290 }
291
292 IP6_EXTHDR_CHECK(m, off, icmp6len, return );
293 ip6 = mtod(m, struct ip6_hdr *);
294 nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
295 icmp6len -= sizeof(*nd_rs);
296 nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
297 if (nd6_options(&ndopts) < 0) {
298 nd6log(info,
299 "nd6_rs_input: invalid ND option, ignored\n");
300 /* nd6_options have incremented stats */
301 goto freeit;
302 }
303
304 if (ndopts.nd_opts_src_lladdr) {
305 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
306 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
307 }
308
309 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
310 nd6log(info,
311 "nd6_rs_input: lladdrlen mismatch for %s "
312 "(if %d, RS packet %d)\n",
313 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2);
314 goto bad;
315 }
316
317 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0, NULL);
318
319freeit:
320 m_freem(m);
321 return;
322
323bad:
324 icmp6stat.icp6s_badrs++;
325 m_freem(m);
326}
327
328#define ND_OPT_LEN_TO_BYTE_SCALE 3 /* ND opt len is in units of 8 octets */
329
330#define ND_OPT_LEN_RTI_MIN 1
331#define ND_OPT_LEN_RTI_MAX 3
332#define ND_OPT_RTI_PFXLEN_MAX 128
333/*
334 * Receive Router Advertisement Message.
335 *
336 * Based on RFC 2461
337 * TODO: on-link bit on prefix information
338 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing
339 */
340void
341nd6_ra_input(
342 struct mbuf *m,
343 int off,
344 int icmp6len)
345{
346 struct ifnet *ifp = m->m_pkthdr.rcvif;
347 struct nd_ifinfo *ndi = NULL;
348 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
349 struct nd_router_advert *nd_ra;
350 struct in6_addr saddr6 = ip6->ip6_src;
351 int mcast = 0;
352 union nd_opts ndopts;
353 struct nd_defrouter *dr = NULL;
354 u_int32_t mtu = 0;
355 char *lladdr = NULL;
356 u_int32_t lladdrlen = 0;
357 struct nd_prefix_list *nd_prefix_list_head = NULL;
358 u_int32_t nd_prefix_list_length = 0;
359 struct in6_ifaddr *ia6 = NULL;
360 struct nd_prefix_list *prfl;
361 struct nd_defrouter dr0;
362 u_int32_t advreachable;
363 boolean_t rti_defrtr_processed = FALSE;
364
365#if (DEVELOPMENT || DEBUG)
366 if (ip6_accept_rtadv == 0) {
367 goto freeit;
368 }
369#endif /* (DEVELOPMENT || DEBUG) */
370 /* Expect 32-bit aligned data pointer on strict-align platforms */
371 MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
372
373 /*
374 * Accept the RA if IFEF_ACCEPT_RTADV is set, or when
375 * we're acting as a router and the RA is locally generated.
376 * For convenience, we allow locally generated (rtadvd)
377 * RAs to be processed on the advertising interface, as a router.
378 *
379 * Note that we don't test against ip6_forwarding as we could be
380 * both a host and a router on different interfaces, hence the
381 * check against the per-interface flags.
382 */
383 if ((ifp->if_eflags & IFEF_ACCEPT_RTADV) == 0) {
384 if (ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_EXCLUSIVE &&
385 (ia6 = ifa_foraddr6(&saddr6)) != NULL) {
386 /* accept locally generated RA */
387 } else {
388 goto freeit;
389 }
390 }
391
392 if (ia6 != NULL) {
393 ifa_remref(ifa: &ia6->ia_ifa);
394 ia6 = NULL;
395 }
396
397 if (ip6->ip6_hlim != IPV6_MAXHLIM) {
398 nd6log(error,
399 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
400 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
401 ip6_sprintf(&ip6->ip6_dst), if_name(ifp));
402 goto bad;
403 }
404
405 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
406 nd6log(error,
407 "nd6_ra_input: src %s is not link-local\n",
408 ip6_sprintf(&saddr6));
409 goto bad;
410 }
411
412 IP6_EXTHDR_CHECK(m, off, icmp6len, return );
413 ip6 = mtod(m, struct ip6_hdr *);
414 nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
415
416 icmp6len -= sizeof(*nd_ra);
417 nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
418 if (nd6_options(&ndopts) < 0) {
419 nd6log(info,
420 "nd6_ra_input: invalid ND option, ignored\n");
421 /* nd6_options have incremented stats */
422 goto freeit;
423 }
424
425 advreachable = nd_ra->nd_ra_reachable;
426
427 /* remember if this is a multicasted advertisement */
428 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
429 mcast = 1;
430 }
431
432 ndi = ND_IFINFO(ifp);
433 VERIFY(NULL != ndi && TRUE == ndi->initialized);
434 lck_mtx_lock(lck: &ndi->lock);
435 /* unspecified or not? (RFC 2461 6.3.4) */
436 if (advreachable) {
437 advreachable = ntohl(advreachable);
438 if (advreachable <= MAX_REACHABLE_TIME &&
439 ndi->basereachable != advreachable) {
440 ndi->basereachable = advreachable;
441 ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
442 ndi->recalctm = nd6_recalc_reachtm_interval; /* reset */
443 }
444 }
445 if (nd_ra->nd_ra_retransmit) {
446 ndi->retrans = ntohl(nd_ra->nd_ra_retransmit);
447 }
448 if (nd_ra->nd_ra_curhoplimit) {
449 if (ndi->chlim < nd_ra->nd_ra_curhoplimit) {
450 ndi->chlim = nd_ra->nd_ra_curhoplimit;
451 } else if (ndi->chlim != nd_ra->nd_ra_curhoplimit) {
452 nd6log(error,
453 "RA with a lower CurHopLimit sent from "
454 "%s on %s (current = %d, received = %d). "
455 "Ignored.\n", ip6_sprintf(&ip6->ip6_src),
456 if_name(ifp), ndi->chlim,
457 nd_ra->nd_ra_curhoplimit);
458 }
459 }
460 lck_mtx_unlock(lck: &ndi->lock);
461
462 /* Initialize nd_defrouter invariants for RA processing */
463 bzero(s: &dr0, n: sizeof(dr0));
464 dr0.rtaddr = saddr6;
465 dr0.ifp = ifp;
466
467 /*
468 * Route Information Option
469 */
470 if (ndopts.nd_opts_rti && IFNET_IS_ETHERNET(ifp)) {
471 struct nd_opt_hdr *rt = NULL;
472 struct sockaddr_in6 rti_gateway = {0};
473
474 rti_gateway.sin6_family = AF_INET6;
475 rti_gateway.sin6_len = sizeof(rti_gateway);
476 memcpy(dst: &rti_gateway.sin6_addr, src: &saddr6, n: sizeof(rti_gateway.sin6_addr));
477
478 for (rt = (struct nd_opt_hdr *)ndopts.nd_opts_rti;
479 rt <= (struct nd_opt_hdr *)ndopts.nd_opts_rti_end;
480 rt = (struct nd_opt_hdr *)((caddr_t)rt +
481 (rt->nd_opt_len << ND_OPT_LEN_TO_BYTE_SCALE))) {
482 struct sockaddr_in6 rti_prefix = {};
483 struct nd_route_info rti = {};
484 struct nd_opt_route_info *rti_opt = NULL;
485 u_int32_t rounded_prefix_bytes = 0;
486
487 if (rt->nd_opt_type != ND_OPT_ROUTE_INFO) {
488 continue;
489 }
490
491 rti_opt = (struct nd_opt_route_info *)rt;
492 if ((rti_opt->nd_opt_rti_len < ND_OPT_LEN_RTI_MIN) ||
493 (rti_opt->nd_opt_rti_len > ND_OPT_LEN_RTI_MAX)) {
494 nd6log(info,
495 "%s: invalid option "
496 "len %d for route information option, "
497 "ignored\n", __func__,
498 rti_opt->nd_opt_rti_len);
499 continue;
500 }
501
502 if (rti_opt->nd_opt_rti_prefixlen > ND_OPT_RTI_PFXLEN_MAX) {
503 nd6log(info,
504 "%s: invalid prefix length %d "
505 "in the route information option, "
506 "ignored\n", __func__, rti_opt->nd_opt_rti_prefixlen);
507 continue;
508 }
509
510 if (rti_opt->nd_opt_rti_prefixlen != 0 &&
511 rti_opt->nd_opt_rti_prefixlen <= 64 &&
512 rti_opt->nd_opt_rti_len == ND_OPT_LEN_RTI_MIN) {
513 nd6log(info,
514 "%s: invalid prefix "
515 "len %d is OOB for route information option, "
516 "with total option length of %d. Ignored.\n",
517 __func__, rti_opt->nd_opt_rti_prefixlen,
518 rti_opt->nd_opt_rti_len);
519 continue;
520 }
521
522 if (rti_opt->nd_opt_rti_prefixlen > 64 &&
523 rti_opt->nd_opt_rti_len != ND_OPT_LEN_RTI_MAX) {
524 nd6log(info,
525 "%s: invalid prefix "
526 "len %d is OOB for route information option, "
527 "with total option length of %d. Ignored.\n",
528 __func__, rti_opt->nd_opt_rti_prefixlen,
529 rti_opt->nd_opt_rti_len);
530 continue;
531 }
532
533 if ((rti_opt->nd_opt_rti_flags & ND_RA_FLAG_RTPREF_MASK) ==
534 ND_RA_FLAG_RTPREF_RSV) {
535 nd6log(info,
536 "%s: using reserved preference mask, "
537 "ignored\n", __func__);
538 continue;
539 }
540
541 rti_prefix.sin6_family = AF_INET6;
542 rti_prefix.sin6_len = sizeof(rti_prefix);
543
544 rounded_prefix_bytes = rti_opt->nd_opt_rti_prefixlen >> 3;
545 if (rti_opt->nd_opt_rti_prefixlen & 0x7) {
546 rounded_prefix_bytes++;
547 }
548 memcpy(dst: &rti_prefix.sin6_addr, src: rti_opt + 1, n: rounded_prefix_bytes);
549
550 nd6log(info, "%s: received RA with route opt, "
551 "prefix %s/%u pref %u lifetime %u\n", __func__,
552 ip6_sprintf(&rti_prefix.sin6_addr),
553 rti_opt->nd_opt_rti_prefixlen,
554 rti_opt->nd_opt_rti_flags,
555 ntohl(rti_opt->nd_opt_rti_lifetime));
556
557 dr0.flags = rti_opt->nd_opt_rti_flags;
558 dr0.stateflags = 0;
559
560 /*
561 * https://tools.ietf.org/html/rfc4191#section-3.1
562 * Type C Host requirements:
563 * The Router Preference and Lifetime values in a
564 * ::/0 Route Information Option override the
565 * preference and lifetime values in the Router
566 * Advertisement header.
567 */
568 if (IN6_IS_ADDR_UNSPECIFIED(&rti_prefix.sin6_addr)
569 && rti_opt->nd_opt_rti_prefixlen == 0) {
570 rti_defrtr_processed = TRUE;
571 /*
572 * If the router lifetime is 0, set the state flag
573 * to dummy, so that it is skipped and not used as a
574 * default router.
575 * Set the lifetime to 2 hrs to make sure we get rid
576 * of the router eventually if this was indeed for a router
577 * going away.
578 *
579 * We partly have to do this to ensure advertised prefixes
580 * stay onlink.
581 * A periodic RA would also keep refreshing the cached
582 * neighbor cache entry if it contains source link layer
583 * information.
584 */
585 if (rti_opt->nd_opt_rti_lifetime == 0) {
586 dr0.rtlifetime = TWOHOUR;
587 dr0.stateflags |= NDDRF_INELIGIBLE;
588 } else {
589 dr0.rtlifetime = ntohl(rti_opt->nd_opt_rti_lifetime);
590 }
591 dr0.expire = net_uptime() + dr0.rtlifetime;
592
593 lck_mtx_lock(nd6_mutex);
594 dr = defrtrlist_update(&dr0, NULL);
595 if (dr != NULL) {
596 dr->is_reachable = TRUE;
597 }
598 lck_mtx_unlock(nd6_mutex);
599 continue;
600 }
601
602 dr0.rtlifetime = ntohl(rti_opt->nd_opt_rti_lifetime);
603 dr0.expire = net_uptime() + dr0.rtlifetime;
604 bzero(s: &rti, n: sizeof(rti));
605 rti.nd_rti_prefixlen = rti_opt->nd_opt_rti_prefixlen;
606 rti.nd_rti_prefix = rti_prefix.sin6_addr;
607 nd6_rtilist_update(&rti, &dr0);
608 }
609 }
610
611 if (!rti_defrtr_processed) {
612 dr0.flags = nd_ra->nd_ra_flags_reserved;
613 dr0.stateflags = 0;
614 /*
615 * If the router lifetime is 0, set the state flag
616 * to dummy, so that it is skipped and not used as a
617 * default router.
618 * Set the lifetime to 2 hrs to make sure we get rid
619 * of the router eventually if this was indeed for a router
620 * going away.
621 *
622 * We partly have to do this to ensure advertised prefixes
623 * stay onlink.
624 * A periodic RA would also keep refreshing the cached
625 * neighbor cache entry if it contains source link layer
626 * information.
627 */
628 if (nd_ra->nd_ra_router_lifetime == 0) {
629 dr0.rtlifetime = TWOHOUR;
630 dr0.stateflags |= NDDRF_INELIGIBLE;
631 } else {
632 dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
633 }
634 dr0.expire = net_uptime() + dr0.rtlifetime;
635 lck_mtx_lock(nd6_mutex);
636 dr = defrtrlist_update(&dr0, NULL);
637 if (dr != NULL) {
638 dr->is_reachable = TRUE;
639 }
640 lck_mtx_unlock(nd6_mutex);
641 }
642
643 /*
644 * prefix
645 */
646 if (ndopts.nd_opts_pi) {
647 struct nd_opt_hdr *pt;
648 struct nd_opt_prefix_info *pi = NULL;
649 struct nd_prefix pr;
650
651 for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi;
652 pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end;
653 pt = (struct nd_opt_hdr *)((caddr_t)pt +
654 (pt->nd_opt_len << ND_OPT_LEN_TO_BYTE_SCALE))) {
655 struct in6_addr pi_mask;
656 bzero(s: &pi_mask, n: sizeof(pi_mask));
657
658 if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION) {
659 continue;
660 }
661 pi = (struct nd_opt_prefix_info *)pt;
662
663 if (pi->nd_opt_pi_len != 4) {
664 nd6log(info,
665 "nd6_ra_input: invalid option "
666 "len %d for prefix information option, "
667 "ignored\n", pi->nd_opt_pi_len);
668 continue;
669 }
670
671 if (128 < pi->nd_opt_pi_prefix_len) {
672 nd6log(info,
673 "nd6_ra_input: invalid prefix "
674 "len %d for prefix information option, "
675 "ignored\n", pi->nd_opt_pi_prefix_len);
676 continue;
677 }
678
679 /*
680 * To ignore ::/64 make sure bits beyond prefixlen
681 * are set to zero
682 */
683 in6_prefixlen2mask(maskp: &pi_mask, len: pi->nd_opt_pi_prefix_len);
684 pi->nd_opt_pi_prefix.s6_addr32[0] &= pi_mask.s6_addr32[0];
685 pi->nd_opt_pi_prefix.s6_addr32[1] &= pi_mask.s6_addr32[1];
686 pi->nd_opt_pi_prefix.s6_addr32[2] &= pi_mask.s6_addr32[2];
687 pi->nd_opt_pi_prefix.s6_addr32[3] &= pi_mask.s6_addr32[3];
688
689 if (IN6_IS_ADDR_UNSPECIFIED(&pi->nd_opt_pi_prefix) ||
690 IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) ||
691 IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) {
692 nd6log(info,
693 "%s: invalid prefix %s, ignored\n",
694 __func__,
695 ip6_sprintf(&pi->nd_opt_pi_prefix));
696 continue;
697 }
698
699 bzero(s: &pr, n: sizeof(pr));
700 lck_mtx_init(lck: &pr.ndpr_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
701 NDPR_LOCK(&pr);
702 pr.ndpr_prefix.sin6_family = AF_INET6;
703 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix);
704 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix;
705 pr.ndpr_ifp = m->m_pkthdr.rcvif;
706
707 pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved &
708 ND_OPT_PI_FLAG_ONLINK) ? 1 : 0;
709 pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved &
710 ND_OPT_PI_FLAG_AUTO) ? 1 : 0;
711 pr.ndpr_plen = pi->nd_opt_pi_prefix_len;
712 pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time);
713 pr.ndpr_pltime =
714 ntohl(pi->nd_opt_pi_preferred_time);
715
716 /*
717 * Exceptions to stateless autoconfiguration processing:
718 * + nd6_accept_6to4 == 0 && address has 6to4 prefix
719 * + ip6_only_allow_rfc4193_prefix != 0 &&
720 * address not RFC 4193
721 */
722 if (ip6_only_allow_rfc4193_prefix &&
723 !IN6_IS_ADDR_UNIQUE_LOCAL(&pi->nd_opt_pi_prefix)) {
724 nd6log(info,
725 "nd6_ra_input: no SLAAC on prefix %s "
726 "[not RFC 4193]\n",
727 ip6_sprintf(&pi->nd_opt_pi_prefix));
728 pr.ndpr_raf_auto = 0;
729 } else if (!nd6_accept_6to4 &&
730 IN6_IS_ADDR_6TO4(&pi->nd_opt_pi_prefix)) {
731 nd6log(info,
732 "%s: no SLAAC on prefix %s "
733 "[6to4]\n", __func__,
734 ip6_sprintf(&pi->nd_opt_pi_prefix));
735 pr.ndpr_raf_auto = 0;
736 }
737
738 if (in6_init_prefix_ltimes(ndpr: &pr)) {
739 NDPR_UNLOCK(&pr);
740 lck_mtx_destroy(lck: &pr.ndpr_lock, grp: &ifa_mtx_grp);
741 continue; /* prefix lifetime init failed */
742 } else {
743 NDPR_UNLOCK(&pr);
744 }
745 (void) prelist_update(&pr, dr, m, mcast);
746 lck_mtx_destroy(lck: &pr.ndpr_lock, grp: &ifa_mtx_grp);
747
748 /*
749 * We have to copy the values out after the
750 * prelist_update call since some of these values won't
751 * be properly set until after the router advertisement
752 * updating can vet the values.
753 */
754 prfl = kalloc_type(struct nd_prefix_list,
755 Z_WAITOK | Z_ZERO | Z_NOFAIL);
756
757 /* this is only for nd6_post_msg(), otherwise unused */
758 SOCKADDR_COPY(&pr.ndpr_prefix, &prfl->pr.ndpr_prefix,
759 sizeof(prfl->pr.ndpr_prefix));
760 prfl->pr.ndpr_raf = pr.ndpr_raf;
761 prfl->pr.ndpr_plen = pr.ndpr_plen;
762 prfl->pr.ndpr_vltime = pr.ndpr_vltime;
763 prfl->pr.ndpr_pltime = pr.ndpr_pltime;
764 prfl->pr.ndpr_expire = pr.ndpr_expire;
765 prfl->pr.ndpr_base_calendartime =
766 pr.ndpr_base_calendartime;
767 prfl->pr.ndpr_base_uptime = pr.ndpr_base_uptime;
768 prfl->pr.ndpr_stateflags = pr.ndpr_stateflags;
769 prfl->pr.ndpr_addrcnt = pr.ndpr_addrcnt;
770 prfl->pr.ndpr_ifp = pr.ndpr_ifp;
771
772 prfl->next = nd_prefix_list_head;
773 nd_prefix_list_head = prfl;
774 nd_prefix_list_length++;
775 }
776 }
777
778
779 /*
780 * MTU
781 */
782 if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) {
783 mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu);
784 /* lower bound */
785 if (mtu < IPV6_MMTU) {
786 nd6log(info, "nd6_ra_input: bogus mtu option "
787 "mtu=%d sent from %s, ignoring\n",
788 mtu, ip6_sprintf(&ip6->ip6_src));
789 goto skip;
790 }
791
792 lck_mtx_lock(lck: &ndi->lock);
793 /* upper bound */
794 if (ndi->maxmtu) {
795 if (mtu <= ndi->maxmtu) {
796 int change = (ndi->linkmtu != mtu);
797
798 ndi->linkmtu = mtu;
799 lck_mtx_unlock(lck: &ndi->lock);
800 if (change) { /* in6_maxmtu may change */
801 in6_setmaxmtu();
802 }
803 } else {
804 nd6log(info, "nd6_ra_input: bogus mtu "
805 "mtu=%d sent from %s; "
806 "exceeds maxmtu %d, ignoring\n",
807 mtu, ip6_sprintf(&ip6->ip6_src),
808 ndi->maxmtu);
809 lck_mtx_unlock(lck: &ndi->lock);
810 }
811 } else {
812 lck_mtx_unlock(lck: &ndi->lock);
813 nd6log(info, "nd6_ra_input: mtu option "
814 "mtu=%d sent from %s; maxmtu unknown, "
815 "ignoring\n",
816 mtu, ip6_sprintf(&ip6->ip6_src));
817 }
818 }
819
820skip:
821
822 /*
823 * Source link layer address
824 */
825 if (ndopts.nd_opts_src_lladdr) {
826 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
827 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
828 }
829
830 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
831 nd6log(info,
832 "nd6_ra_input: lladdrlen mismatch for %s "
833 "(if %d, RA packet %d)\n",
834 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2);
835 goto bad;
836 }
837
838 if (dr && dr->stateflags & NDDRF_MAPPED) {
839 saddr6 = dr->rtaddr_mapped;
840 }
841
842 nd6_cache_lladdr(ifp, &saddr6, lladdr, (int)lladdrlen,
843 ND_ROUTER_ADVERT, 0, NULL);
844
845 /* Post message */
846 nd6_post_msg(KEV_ND6_RA, nd_prefix_list_head, nd_prefix_list_length,
847 mtu);
848
849 /*
850 * Installing a link-layer address might change the state of the
851 * router's neighbor cache, which might also affect our on-link
852 * detection of adveritsed prefixes.
853 */
854 lck_mtx_lock(nd6_mutex);
855 pfxlist_onlink_check();
856 lck_mtx_unlock(nd6_mutex);
857
858freeit:
859 m_freem(m);
860 if (dr) {
861 NDDR_REMREF(dr);
862 }
863
864 prfl = NULL;
865 while ((prfl = nd_prefix_list_head) != NULL) {
866 nd_prefix_list_head = prfl->next;
867 kfree_type(struct nd_prefix_list, prfl);
868 }
869
870 return;
871
872bad:
873 icmp6stat.icp6s_badra++;
874 goto freeit;
875}
876
877/*
878 * default router list proccessing sub routines
879 */
880
881/* tell the change to user processes watching the routing socket. */
882static void
883nd6_rtmsg(u_char cmd, struct rtentry *rt)
884{
885 struct rt_addrinfo info;
886 struct ifnet *ifp = rt->rt_ifp;
887
888 RT_LOCK_ASSERT_HELD(rt);
889
890 bzero(s: (caddr_t)&info, n: sizeof(info));
891 /* It's not necessary to lock ifp for if_lladdr */
892 info.rti_info[RTAX_DST] = rt_key(rt);
893 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
894 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
895 /*
896 * ifa_addr pointers for both should always be valid
897 * in this context; no need to hold locks.
898 */
899 info.rti_info[RTAX_IFP] = ifp->if_lladdr->ifa_addr;
900 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
901
902 rt_missmsg(cmd, &info, rt->rt_flags, 0);
903}
904
905static void
906defrouter_addreq(struct nd_defrouter *new, struct nd_route_info *rti, boolean_t scoped)
907{
908 struct sockaddr_in6 key, mask, gate;
909 struct rtentry *newrt __single = NULL;
910 unsigned int ifscope;
911 int err;
912 struct nd_ifinfo *ndi = ND_IFINFO(new->ifp);
913 int rtflags = RTF_GATEWAY;
914
915 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
916 NDDR_LOCK_ASSERT_NOTHELD(new);
917 /*
918 * We're free to lock and unlock NDDR because our callers
919 * are holding an extra reference for us.
920 */
921
922 NDDR_LOCK(new);
923 if (new->stateflags & NDDRF_INSTALLED) {
924 goto out;
925 }
926 if (new->ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_EXCLUSIVE) {
927 nd6log2(info, "%s: ignoring router %s, scoped=%d, "
928 "static=%d on advertising interface\n", if_name(new->ifp),
929 ip6_sprintf(&new->rtaddr), scoped,
930 (new->stateflags & NDDRF_STATIC) ? 1 : 0);
931 goto out;
932 }
933
934 nd6log2(info, "%s: adding default router %s, scoped=%d, "
935 "static=%d\n", if_name(new->ifp), ip6_sprintf(&new->rtaddr),
936 scoped, (new->stateflags & NDDRF_STATIC) ? 1 : 0);
937
938 Bzero(&key, sizeof(key));
939 Bzero(&mask, sizeof(mask));
940 Bzero(&gate, sizeof(gate));
941
942 key.sin6_len = mask.sin6_len = gate.sin6_len
943 = sizeof(struct sockaddr_in6);
944 key.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
945
946 if (rti != NULL) {
947 key.sin6_addr = rti->nd_rti_prefix;
948 in6_len2mask(&mask.sin6_addr, rti->nd_rti_prefixlen);
949 if (rti->nd_rti_prefixlen == ND_OPT_RTI_PFXLEN_MAX) {
950 rtflags |= RTF_HOST;
951 } else {
952 rtflags |= RTF_PRCLONING;
953 }
954
955 if (IN6_IS_SCOPE_EMBED(&key.sin6_addr) ||
956 IN6_IS_ADDR_LOOPBACK(&key.sin6_addr)) {
957 nd6log2(info, "%s: ignoring router %s, rti prefix %s, scoped=%d, "
958 "static=%d on advertising interface\n", if_name(new->ifp),
959 ip6_sprintf(&new->rtaddr), ip6_sprintf(&rti->nd_rti_prefix), scoped,
960 (new->stateflags & NDDRF_STATIC) ? 1 : 0);
961 goto out;
962 }
963 }
964
965 if (new->stateflags & NDDRF_MAPPED) {
966 gate.sin6_addr = new->rtaddr_mapped;
967 } else {
968 gate.sin6_addr = new->rtaddr;
969 }
970 if (!in6_embedded_scope && IN6_IS_SCOPE_EMBED(&gate.sin6_addr)) {
971 gate.sin6_scope_id = new->ifp->if_index;
972 }
973
974 ifscope = scoped ? new->ifp->if_index : IFSCOPE_NONE;
975 NDDR_UNLOCK(new);
976
977 /*
978 * Cellular networks may have buggy deployments
979 * with gateway IPv6 link local address with same
980 * interface identifier as the one that has been
981 * assigned for the cellular context.
982 * If gateway is same as locally configured link local
983 * interface on cellular interface, generated a different one
984 * and store it in the nd_defrouter entry and use it to work
985 * on routing table
986 */
987 if (new->ifp->if_type == IFT_CELLULAR &&
988 !(new->stateflags & NDDRF_STATIC) &&
989 !(new->stateflags & NDDRF_MAPPED) &&
990 IN6_IS_ADDR_LINKLOCAL(&gate.sin6_addr) &&
991 ndi && !(ndi->flags & ND6_IFF_PERFORMNUD)) {
992 struct in6_ifaddr *tmp_ia6 = in6ifa_ifpforlinklocal(new->ifp, 0);
993
994 if (tmp_ia6 != NULL &&
995 !(tmp_ia6->ia6_flags & IN6_IFF_NOTMANUAL) &&
996 IN6_ARE_ADDR_EQUAL(&tmp_ia6->ia_addr.sin6_addr,
997 &gate.sin6_addr)) {
998 gate.sin6_addr.s6_addr8[15] += 1;
999 new->rtaddr_mapped = gate.sin6_addr;
1000 new->stateflags |= NDDRF_MAPPED;
1001
1002 nd6log(info, "%s: Default router %s mapped "
1003 "to ", if_name(new->ifp), ip6_sprintf(&new->rtaddr));
1004 nd6log(info, "%s\n", ip6_sprintf(&new->rtaddr_mapped));
1005 }
1006 }
1007
1008 err = rtrequest_scoped(RTM_ADD, SA(&key), SA(&gate), SA(&mask),
1009 rtflags, &newrt, ifscope);
1010
1011 if (newrt) {
1012 RT_LOCK(newrt);
1013 nd6_rtmsg(RTM_ADD, rt: newrt); /* tell user process */
1014 RT_REMREF_LOCKED(newrt);
1015 RT_UNLOCK(newrt);
1016 NDDR_LOCK(new);
1017 new->stateflags |= NDDRF_INSTALLED;
1018 if (ifscope != IFSCOPE_NONE) {
1019 new->stateflags |= NDDRF_IFSCOPE;
1020 }
1021 } else {
1022 nd6log(error, "%s: failed to add default router "
1023 "%s on %s scoped %d (errno = %d)\n", __func__,
1024 ip6_sprintf(&gate.sin6_addr), if_name(new->ifp),
1025 (ifscope != IFSCOPE_NONE), err);
1026 NDDR_LOCK(new);
1027 }
1028 new->err = err;
1029
1030out:
1031 NDDR_UNLOCK(new);
1032}
1033
1034void
1035defrouter_set_reachability(
1036 struct in6_addr *addr,
1037 struct ifnet *ifp,
1038 boolean_t is_reachable)
1039{
1040 struct nd_defrouter *dr = NULL;
1041
1042 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
1043
1044 lck_mtx_lock(nd6_mutex);
1045 dr = defrouter_lookup(NULL, addr, ifp);
1046 if (dr != NULL) {
1047 dr->is_reachable = is_reachable;
1048 NDDR_REMREF(dr);
1049 }
1050 lck_mtx_unlock(nd6_mutex);
1051}
1052
1053struct nd_defrouter *
1054defrouter_lookup(
1055 struct nd_drhead *nd_router_listp,
1056 struct in6_addr *addr,
1057 struct ifnet *ifp)
1058{
1059 struct nd_defrouter *dr;
1060
1061 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1062
1063 if (nd_router_listp == NULL) {
1064 nd_router_listp = &nd_defrouter_list;
1065 }
1066
1067 for (dr = TAILQ_FIRST(nd_router_listp); dr;
1068 dr = TAILQ_NEXT(dr, dr_entry)) {
1069 NDDR_LOCK(dr);
1070 if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
1071 NDDR_ADDREF(dr);
1072 NDDR_UNLOCK(dr);
1073 return dr;
1074 }
1075 NDDR_UNLOCK(dr);
1076 }
1077
1078 return NULL; /* search failed */
1079}
1080
1081/*
1082 * Remove the default route for a given router.
1083 * This is just a subroutine function for defrouter_select(), and should
1084 * not be called from anywhere else.
1085 */
1086static void
1087defrouter_delreq(struct nd_defrouter *dr, struct nd_route_info *rti)
1088{
1089 struct sockaddr_in6 key, mask, gate;
1090 struct rtentry *oldrt __single = NULL;
1091 unsigned int ifscope;
1092 int err;
1093
1094 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
1095 NDDR_LOCK_ASSERT_NOTHELD(dr);
1096 /*
1097 * We're free to lock and unlock NDDR because our callers
1098 * are holding an extra reference for us.
1099 */
1100 NDDR_LOCK(dr);
1101 /* ifp would be NULL for the "drany" case */
1102 if (dr->ifp != NULL && !(dr->stateflags & NDDRF_INSTALLED)) {
1103 goto out;
1104 }
1105
1106 nd6log2(info, "%s: removing default router %s, scoped=%d, "
1107 "static=%d\n", dr->ifp != NULL ? if_name(dr->ifp) : "ANY",
1108 ip6_sprintf(&dr->rtaddr), (dr->stateflags & NDDRF_IFSCOPE) ? 1 : 0,
1109 (dr->stateflags & NDDRF_STATIC) ? 1 : 0);
1110
1111 Bzero(&key, sizeof(key));
1112 Bzero(&mask, sizeof(mask));
1113 Bzero(&gate, sizeof(gate));
1114
1115 key.sin6_len = mask.sin6_len = gate.sin6_len
1116 = sizeof(struct sockaddr_in6);
1117 key.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
1118
1119
1120 if (rti != NULL) {
1121 key.sin6_addr = rti->nd_rti_prefix;
1122 in6_len2mask(&mask.sin6_addr, rti->nd_rti_prefixlen);
1123 }
1124 /*
1125 * The router entry may be mapped to a different address.
1126 * If that is the case, use the mapped address as gateway
1127 * to do operation on the routing table.
1128 * To get more context, read the related comment in
1129 * defrouter_addreq
1130 */
1131 if (dr->stateflags & NDDRF_MAPPED) {
1132 gate.sin6_addr = dr->rtaddr_mapped;
1133 } else {
1134 gate.sin6_addr = dr->rtaddr;
1135 }
1136
1137 if (dr->ifp != NULL) {
1138 ifscope = (dr->stateflags & NDDRF_IFSCOPE) ?
1139 dr->ifp->if_index : IFSCOPE_NONE;
1140 } else {
1141 ifscope = IFSCOPE_NONE;
1142 }
1143 NDDR_UNLOCK(dr);
1144
1145 err = rtrequest_scoped(RTM_DELETE, SA(&key), SA(&gate), SA(&mask),
1146 RTF_GATEWAY, &oldrt, ifscope);
1147
1148 if (oldrt) {
1149 RT_LOCK(oldrt);
1150 nd6_rtmsg(RTM_DELETE, rt: oldrt);
1151 RT_UNLOCK(oldrt);
1152 rtfree(oldrt);
1153 } else if (err != ESRCH) {
1154 nd6log(error, "%s: failed to delete default router "
1155 "%s on %s scoped %d (errno = %d)\n", __func__,
1156 ip6_sprintf(&gate.sin6_addr), dr->ifp != NULL ?
1157 if_name(dr->ifp) : "ANY", (ifscope != IFSCOPE_NONE), err);
1158 }
1159 NDDR_LOCK(dr);
1160 /* ESRCH means it's no longer in the routing table; ignore it */
1161 if (oldrt != NULL || err == ESRCH) {
1162 dr->stateflags &= ~NDDRF_INSTALLED;
1163 if (ifscope != IFSCOPE_NONE) {
1164 dr->stateflags &= ~NDDRF_IFSCOPE;
1165 }
1166 }
1167 dr->err = 0;
1168out:
1169 NDDR_UNLOCK(dr);
1170}
1171
1172
1173/*
1174 * remove all default routes from default router list
1175 */
1176void
1177defrouter_reset(void)
1178{
1179 struct nd_defrouter *dr, drany;
1180
1181 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1182
1183 dr = TAILQ_FIRST(&nd_defrouter_list);
1184 while (dr) {
1185 NDDR_LOCK(dr);
1186 if (dr->stateflags & NDDRF_INSTALLED) {
1187 NDDR_ADDREF(dr);
1188 NDDR_UNLOCK(dr);
1189 lck_mtx_unlock(nd6_mutex);
1190 defrouter_delreq(dr, NULL);
1191 lck_mtx_lock(nd6_mutex);
1192 NDDR_REMREF(dr);
1193 dr = TAILQ_FIRST(&nd_defrouter_list);
1194 } else {
1195 NDDR_UNLOCK(dr);
1196 dr = TAILQ_NEXT(dr, dr_entry);
1197 }
1198 }
1199
1200 /* Nuke primary (non-scoped) default router */
1201 bzero(s: &drany, n: sizeof(drany));
1202 lck_mtx_init(lck: &drany.nddr_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
1203 lck_mtx_unlock(nd6_mutex);
1204 defrouter_delreq(dr: &drany, NULL);
1205 lck_mtx_destroy(lck: &drany.nddr_lock, grp: &ifa_mtx_grp);
1206 lck_mtx_lock(nd6_mutex);
1207}
1208
1209int
1210defrtrlist_ioctl(u_long cmd, caddr_t data)
1211{
1212 struct nd_defrouter dr0;
1213 unsigned int ifindex;
1214 struct ifnet *dr_ifp;
1215 int error = 0, add = 0;
1216
1217 /* XXX Handle mapped default router entries */
1218 switch (cmd) {
1219 case SIOCDRADD_IN6_32: /* struct in6_defrouter_32 */
1220 case SIOCDRADD_IN6_64: /* struct in6_defrouter_64 */
1221 ++add;
1222 OS_FALLTHROUGH;
1223 case SIOCDRDEL_IN6_32: /* struct in6_defrouter_32 */
1224 case SIOCDRDEL_IN6_64: /* struct in6_defrouter_64 */
1225 bzero(s: &dr0, n: sizeof(dr0));
1226 if (cmd == SIOCDRADD_IN6_64 || cmd == SIOCDRDEL_IN6_64) {
1227 struct in6_defrouter_64 *r_64 =
1228 (struct in6_defrouter_64 *)(void *)data;
1229 u_int16_t i;
1230
1231 bcopy(src: &r_64->rtaddr.sin6_addr, dst: &dr0.rtaddr,
1232 n: sizeof(dr0.rtaddr));
1233 dr0.flags = r_64->flags;
1234 bcopy(src: &r_64->if_index, dst: &i, n: sizeof(i));
1235 ifindex = i;
1236 } else {
1237 struct in6_defrouter_32 *r_32 =
1238 (struct in6_defrouter_32 *)(void *)data;
1239 u_int16_t i;
1240
1241 bcopy(src: &r_32->rtaddr.sin6_addr, dst: &dr0.rtaddr,
1242 n: sizeof(dr0.rtaddr));
1243 dr0.flags = r_32->flags;
1244 bcopy(src: &r_32->if_index, dst: &i, n: sizeof(i));
1245 ifindex = i;
1246 }
1247 ifnet_head_lock_shared();
1248 /* Don't need to check is ifindex is < 0 since it's unsigned */
1249 if (!IF_INDEX_IN_RANGE(ifindex) ||
1250 (dr_ifp = ifindex2ifnet[ifindex]) == NULL) {
1251 ifnet_head_done();
1252 error = EINVAL;
1253 break;
1254 }
1255 dr0.ifp = dr_ifp;
1256 ifnet_head_done();
1257
1258 if (ND_IFINFO(dr_ifp) == NULL ||
1259 !ND_IFINFO(dr_ifp)->initialized) {
1260 error = ENXIO;
1261 break;
1262 }
1263
1264 if (IN6_IS_SCOPE_EMBED(&dr0.rtaddr) && in6_embedded_scope) {
1265 uint16_t *scope = &dr0.rtaddr.s6_addr16[1];
1266
1267 if (*scope == 0) {
1268 *scope = htons(dr_ifp->if_index);
1269 } else if (*scope != htons(dr_ifp->if_index)) {
1270 error = EINVAL;
1271 break;
1272 }
1273 }
1274 if (add) {
1275 error = defrtrlist_add_static(&dr0);
1276 }
1277 if (!add || error != 0) {
1278 int err = defrtrlist_del_static(&dr0);
1279 if (!add) {
1280 error = err;
1281 }
1282 }
1283 break;
1284
1285 default:
1286 error = EOPNOTSUPP; /* check for safety */
1287 break;
1288 }
1289
1290 return error;
1291}
1292
1293/*
1294 * XXX Please make sure to remove dr from the
1295 * global default router tailq list before this
1296 * function call.
1297 * Also ensure that you release the list reference
1298 * only after calling this routine.
1299 */
1300void
1301defrtrlist_del(struct nd_defrouter *dr, struct nd_drhead *nd_router_listp)
1302{
1303#if (DEVELOPMENT || DEBUG)
1304 struct nd_defrouter *dr_itr = NULL;
1305#endif
1306 struct nd_prefix *pr;
1307 struct ifnet *ifp = dr->ifp;
1308 struct nd_ifinfo *ndi = NULL;
1309 boolean_t resetmtu = FALSE;
1310 struct nd_route_info *rti = NULL;
1311
1312 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1313
1314 if (nd_router_listp == NULL) {
1315 nd_router_listp = &nd_defrouter_list;
1316 }
1317
1318 if (nd_router_listp != &nd_defrouter_list) {
1319 rti = (struct nd_route_info *)nd_router_listp;
1320 }
1321
1322#if (DEVELOPMENT || DEBUG)
1323 /*
1324 * Verify that the router is not in the global default
1325 * router list.
1326 * Can't use defrouter_lookup here because that just works
1327 * with address and ifp pointer.
1328 * We have to compare the memory here.
1329 * Also we can't use ASSERT here as that is not defined
1330 * for development builds.
1331 */
1332 TAILQ_FOREACH(dr_itr, nd_router_listp, dr_entry)
1333 VERIFY(dr != dr_itr);
1334#endif
1335 ++nd6_defrouter_genid;
1336 /*
1337 * Flush all the routing table entries that use the router
1338 * as a next hop.
1339 *
1340 * XXX Note that for a router advertising itself as default router
1341 * and also advertising route information option, the following
1342 * code will have the default router entry and router entry of
1343 * RTI step over each other.
1344 * The following therefore may not be efficient but won't be
1345 * causing blocking issues.
1346 */
1347 NDDR_ADDREF(dr);
1348 lck_mtx_unlock(nd6_mutex);
1349 if (dr->stateflags & NDDRF_MAPPED) {
1350 rt6_flush(&dr->rtaddr_mapped, ifp);
1351 } else {
1352 rt6_flush(&dr->rtaddr, ifp);
1353 }
1354 lck_mtx_lock(nd6_mutex);
1355 NDDR_REMREF(dr);
1356 nd6log2(info, "%s: freeing route to %s with gateway %s\n", if_name(dr->ifp),
1357 (rti == NULL)? "::" : ip6_sprintf(&rti->nd_rti_prefix),
1358 ip6_sprintf(&dr->rtaddr));
1359 /*
1360 * Delete it from the routing table.
1361 */
1362 NDDR_ADDREF(dr);
1363 lck_mtx_unlock(nd6_mutex);
1364 defrouter_delreq(dr, rti);
1365 lck_mtx_lock(nd6_mutex);
1366 NDDR_REMREF(dr);
1367
1368 /*
1369 * The following should mostly be limited to when we are working
1370 * with a default router entry and not a router entry from
1371 * rti router list.
1372 */
1373 if (rti == NULL) {
1374 /*
1375 * Also delete all the pointers to the router in each prefix lists.
1376 */
1377 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1378 struct nd_pfxrouter *pfxrtr;
1379
1380 NDPR_LOCK(pr);
1381 if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL) {
1382 pfxrtr_del(pfxrtr, pr);
1383 }
1384 NDPR_UNLOCK(pr);
1385 }
1386 pfxlist_onlink_check();
1387 }
1388 ndi = ND_IFINFO(ifp);
1389 VERIFY(NULL != ndi && TRUE == ndi->initialized);
1390 lck_mtx_lock(lck: &ndi->lock);
1391 VERIFY(ndi->ndefrouters >= 0);
1392 if (ndi->ndefrouters > 0 && --ndi->ndefrouters == 0) {
1393 nd6_ifreset(ifp);
1394 resetmtu = TRUE;
1395 }
1396 lck_mtx_unlock(lck: &ndi->lock);
1397 /*
1398 * If the router is the primary one, choose a new one.
1399 * We always try to pick another eligible router
1400 * on this interface as we do scoped routing
1401 */
1402 defrouter_select(ifp, nd_router_listp);
1403
1404 if (resetmtu) {
1405 nd6_setmtu(ifp);
1406 }
1407}
1408
1409int
1410defrtrlist_add_static(struct nd_defrouter *new)
1411{
1412 struct nd_defrouter *dr;
1413 int err = 0;
1414
1415 new->rtlifetime = -1;
1416 new->stateflags |= NDDRF_STATIC;
1417
1418 /* we only want the preference level */
1419 new->flags &= ND_RA_FLAG_RTPREF_MASK;
1420
1421 lck_mtx_lock(nd6_mutex);
1422 dr = defrouter_lookup(NULL, addr: &new->rtaddr, ifp: new->ifp);
1423 if (dr != NULL && !(dr->stateflags & NDDRF_STATIC)) {
1424 err = EINVAL;
1425 } else {
1426 if (dr != NULL) {
1427 NDDR_REMREF(dr);
1428 }
1429 dr = defrtrlist_update(new, NULL);
1430 if (dr != NULL) {
1431 err = dr->err;
1432 } else {
1433 err = ENOMEM;
1434 }
1435 }
1436 if (dr != NULL) {
1437 NDDR_REMREF(dr);
1438 }
1439 lck_mtx_unlock(nd6_mutex);
1440
1441 return err;
1442}
1443
1444int
1445defrtrlist_del_static(struct nd_defrouter *new)
1446{
1447 struct nd_defrouter *dr;
1448
1449 lck_mtx_lock(nd6_mutex);
1450 dr = defrouter_lookup(NULL, addr: &new->rtaddr, ifp: new->ifp);
1451 if (dr == NULL || !(dr->stateflags & NDDRF_STATIC)) {
1452 if (dr != NULL) {
1453 NDDR_REMREF(dr);
1454 }
1455 dr = NULL;
1456 } else {
1457 TAILQ_REMOVE(&nd_defrouter_list, dr, dr_entry);
1458 defrtrlist_del(dr, NULL);
1459 NDDR_REMREF(dr); /* remove list reference */
1460 NDDR_REMREF(dr);
1461 }
1462 lck_mtx_unlock(nd6_mutex);
1463
1464 return dr != NULL ? 0 : EINVAL;
1465}
1466
1467/*
1468 * for default router selection
1469 * regards router-preference field as a 2-bit signed integer
1470 */
1471static int
1472rtpref(struct nd_defrouter *dr)
1473{
1474 switch (dr->flags & ND_RA_FLAG_RTPREF_MASK) {
1475 case ND_RA_FLAG_RTPREF_HIGH:
1476 return RTPREF_HIGH;
1477 case ND_RA_FLAG_RTPREF_MEDIUM:
1478 case ND_RA_FLAG_RTPREF_RSV:
1479 return RTPREF_MEDIUM;
1480 case ND_RA_FLAG_RTPREF_LOW:
1481 return RTPREF_LOW;
1482 default:
1483 /*
1484 * This case should never happen. If it did, it would mean a
1485 * serious bug of kernel internal. We thus always bark here.
1486 * Or, can we even panic?
1487 */
1488 log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->flags);
1489 return RTPREF_INVALID;
1490 }
1491 /* NOTREACHED */
1492}
1493
1494/*
1495 * Default Router Selection according to Section 6.3.6 of RFC 2461 and RFC 4191:
1496 *
1497 * 1) Routers that are reachable or probably reachable should be preferred.
1498 * If we have more than one (probably) reachable router, prefer ones
1499 * with the highest router preference.
1500 * 2) When no routers on the list are known to be reachable or
1501 * probably reachable, routers SHOULD be selected in a round-robin
1502 * fashion, regardless of router preference values.
1503 * 3) If the Default Router List is empty, assume that all
1504 * destinations are on-link.
1505 *
1506 * When Scoped Routing is enabled, the selection logic is amended as follows:
1507 *
1508 * a) When a default interface is specified, the primary/non-scoped default
1509 * router will be set to the reachable router on that link (if any) with
1510 * the highest router preference.
1511 * b) When there are more than one routers on the same link, the one with
1512 * the highest router preference will be installed, either as scoped or
1513 * non-scoped route entry. If they all share the same preference value,
1514 * the one installed will be the static or the first encountered reachable
1515 * router, i.e. static one wins over dynamic.
1516 * c) When no routers on the list are known to be reachable, or probably
1517 * reachable, no round-robin selection will take place when the default
1518 * interface is set.
1519 *
1520 * We assume nd_defrouter is sorted by router preference value.
1521 * Since the code below covers both with and without router preference cases,
1522 * we do not need to classify the cases by ifdef.
1523 */
1524void
1525defrouter_select(struct ifnet *ifp, struct nd_drhead *nd_router_listp)
1526{
1527 struct nd_defrouter *dr = NULL;
1528 struct nd_defrouter *selected_dr = NULL;
1529 struct nd_defrouter *installed_dr = NULL;
1530 struct llinfo_nd6 *ln = NULL;
1531 struct rtentry *rt = NULL;
1532 struct nd_ifinfo *ndi = NULL;
1533 unsigned int genid = 0;
1534 boolean_t is_installed_reachable = FALSE;
1535 struct nd_route_info *rti = NULL;
1536 boolean_t scoped = TRUE;
1537 boolean_t is_rti_rtrlist = FALSE;
1538
1539 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1540
1541 if (nd_router_listp == NULL) {
1542 nd_router_listp = &nd_defrouter_list;
1543 }
1544
1545 if (nd_router_listp != &nd_defrouter_list) {
1546 rti = (struct nd_route_info *)nd_router_listp;
1547 /* XXX For now we treat RTI routes as un-scoped */
1548 scoped = FALSE;
1549 is_rti_rtrlist = TRUE;
1550 }
1551
1552
1553 if (ifp == NULL) {
1554 ifp = nd6_defifp;
1555 if (ifp == NULL) {
1556 nd6log2(info,
1557 "%s:%d: Return early. NULL interface",
1558 __func__, __LINE__);
1559 return;
1560 }
1561 nd6log2(info,
1562 "%s:%d: NULL interface passed. Setting to default interface %s.\n",
1563 __func__, __LINE__, if_name(ifp));
1564 }
1565
1566 /*
1567 * When we are working with RTI router list, the nd6_defifp may be
1568 * NULL. That is the scenario when the network may not have WAN
1569 * v6 connectivity and the only RAs we may be getting are with lifetime
1570 * 0.
1571 */
1572 if (ifp == lo_ifp && !is_rti_rtrlist) {
1573 nd6log2(info,
1574 "%s:%d: Return early. "
1575 "Default router select called for loopback.\n",
1576 __func__, __LINE__);
1577 return;
1578 }
1579
1580 if (ifp->if_ipv6_router_mode == IPV6_ROUTER_MODE_EXCLUSIVE) {
1581 nd6log2(info,
1582 "%s:%d: Return early. "
1583 "Default router select called for interface"
1584 " %s in IPV6_ROUTER_MODE_EXCLUSIVE\n",
1585 __func__, __LINE__, if_name(ifp));
1586 return;
1587 }
1588
1589 /*
1590 * Let's handle easy case (3) first:
1591 * If default router list is empty, there's nothing to be done.
1592 */
1593 if (!TAILQ_FIRST(nd_router_listp)) {
1594 nd6log2(info,
1595 "%s:%d: Return early. "
1596 "Default router is empty.\n", __func__, __LINE__);
1597 return;
1598 }
1599
1600 /*
1601 * Take an early exit if number of routers in nd_ifinfo is
1602 * 0 for the interface.
1603 */
1604 ndi = ND_IFINFO(ifp);
1605 if (!ndi || !ndi->initialized) {
1606 nd6log2(info,
1607 "%s:%d: Return early. "
1608 "Interface %s's nd_ifinfo not initialized.\n",
1609 __func__, __LINE__, if_name(ifp));
1610 return;
1611 }
1612
1613 /*
1614 * RTI router list routes are installed as unscoped.
1615 * Since there can be only one unscoped route, we need to
1616 * go through the entire list and consider all interfaces.
1617 * Further, for now, RTI option is only processed on Ethernet
1618 * type interfaces only.
1619 */
1620 if (ndi->ndefrouters == 0 && !is_rti_rtrlist) {
1621 nd6log2(info,
1622 "%s:%d: Return early. "
1623 "%s does not have any default routers.\n",
1624 __func__, __LINE__, if_name(ifp));
1625 return;
1626 }
1627
1628 /*
1629 * Due to the number of times we drop nd6_mutex, we need to
1630 * serialize this function.
1631 */
1632 while (nd_defrouter_busy) {
1633 nd_defrouter_waiters++;
1634 msleep(chan: nd_defrouter_waitchan, nd6_mutex, pri: (PZERO - 1),
1635 wmesg: __func__, NULL);
1636 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1637 }
1638 nd_defrouter_busy = TRUE;
1639
1640 /*
1641 * Search for a (probably) reachable router from the list.
1642 * We just pick up the first reachable one (if any), assuming that
1643 * the ordering rule of the list described in defrtrlist_update().
1644 *
1645 * For all intents and purposes of Scoped Routing:
1646 * selected_dr = candidate for primary router
1647 * installed_dr = currently installed primary router
1648 */
1649 genid = nd6_defrouter_genid;
1650 dr = TAILQ_FIRST(nd_router_listp);
1651
1652 while (dr != NULL) {
1653 struct in6_addr rtaddr;
1654 struct ifnet *drifp = NULL;
1655 struct nd_defrouter *drrele = NULL;
1656 boolean_t nd6_mutex_unlocked = FALSE;
1657
1658 NDDR_LOCK(dr);
1659 drifp = dr->ifp;
1660 if (drifp != ifp && !is_rti_rtrlist) {
1661 NDDR_UNLOCK(dr);
1662 dr = TAILQ_NEXT(dr, dr_entry);
1663 continue;
1664 }
1665
1666 if (dr->stateflags & NDDRF_INELIGIBLE) {
1667 NDDR_UNLOCK(dr);
1668 dr = TAILQ_NEXT(dr, dr_entry);
1669 nd6log(info, "Ignoring dummy entry for default router.");
1670 continue;
1671 }
1672
1673 /*
1674 * Optimize for the common case.
1675 * When the interface has only one default router
1676 * there's no point checking for reachability as
1677 * there's nothing else to choose from.
1678 */
1679 if (ndi->ndefrouters == 1 && !is_rti_rtrlist) {
1680 nd6log2(info,
1681 "%s:%d: Fast forward default router selection "
1682 "as interface %s has learned only one default "
1683 "router and there's nothing else to choose from.\n",
1684 __func__, __LINE__, if_name(ifp));
1685 VERIFY(selected_dr == NULL && installed_dr == NULL);
1686 selected_dr = dr;
1687 if (dr->stateflags & NDDRF_INSTALLED) {
1688 installed_dr = dr;
1689 }
1690 NDDR_ADDREF(selected_dr);
1691 NDDR_UNLOCK(dr);
1692 goto install_route;
1693 }
1694
1695 if (dr->stateflags & NDDRF_MAPPED) {
1696 rtaddr = dr->rtaddr_mapped;
1697 } else {
1698 rtaddr = dr->rtaddr;
1699 }
1700
1701 NDDR_ADDREF(dr); /* for this for loop */
1702 NDDR_UNLOCK(dr);
1703
1704 /* Callee returns a locked route upon success */
1705 if (selected_dr == NULL) {
1706 nd6_mutex_unlocked = TRUE;
1707 lck_mtx_unlock(nd6_mutex);
1708 if ((rt = nd6_lookup(&rtaddr, 0, drifp, 0)) != NULL &&
1709 (ln = rt->rt_llinfo) != NULL &&
1710 ND6_IS_LLINFO_PROBREACH(ln)) {
1711 RT_LOCK_ASSERT_HELD(rt);
1712 selected_dr = dr;
1713 NDDR_ADDREF(selected_dr);
1714 }
1715 }
1716
1717 if (rt) {
1718 RT_REMREF_LOCKED(rt);
1719 RT_UNLOCK(rt);
1720 rt = NULL;
1721 }
1722
1723 if (nd6_mutex_unlocked) {
1724 lck_mtx_lock(nd6_mutex);
1725 }
1726
1727 /*
1728 * Handle case (b)
1729 * When there are more than one routers on the same link, the one with
1730 * the highest router preference will be installed.
1731 * Since the list is in decreasing order of preference:
1732 * 1) If selected_dr is not NULL, only use dr if it is static and has
1733 * equal preference and selected_dr is not static.
1734 * 2) Else if selected_dr is NULL, and dr is static make selected_dr = dr
1735 */
1736 NDDR_LOCK(dr);
1737 if (((selected_dr && (rtpref(dr) >= rtpref(dr: selected_dr)) &&
1738 !(selected_dr->stateflags & NDDRF_STATIC)) ||
1739 (selected_dr == NULL)) &&
1740 (dr->stateflags & NDDRF_STATIC)) {
1741 if (selected_dr) {
1742 /* Release it later on */
1743 VERIFY(drrele == NULL);
1744 drrele = selected_dr;
1745 }
1746 selected_dr = dr;
1747 NDDR_ADDREF(selected_dr);
1748 }
1749
1750 /* Record the currently installed router */
1751 if (dr->stateflags & NDDRF_INSTALLED) {
1752 if (installed_dr == NULL) {
1753 installed_dr = dr;
1754 NDDR_ADDREF(installed_dr);
1755 if (dr->stateflags & NDDRF_MAPPED) {
1756 rtaddr = installed_dr->rtaddr_mapped;
1757 } else {
1758 rtaddr = installed_dr->rtaddr;
1759 }
1760 NDDR_UNLOCK(dr);
1761 lck_mtx_unlock(nd6_mutex);
1762 /* Callee returns a locked route upon success */
1763 if ((rt = nd6_lookup(&rtaddr, 0, installed_dr->ifp, 0)) != NULL) {
1764 RT_LOCK_ASSERT_HELD(rt);
1765 if ((ln = rt->rt_llinfo) != NULL &&
1766 ND6_IS_LLINFO_PROBREACH(ln)) {
1767 is_installed_reachable = TRUE;
1768 }
1769
1770 RT_REMREF_LOCKED(rt);
1771 RT_UNLOCK(rt);
1772 rt = NULL;
1773 }
1774 lck_mtx_lock(nd6_mutex);
1775 } else {
1776 /* this should not happen; warn for diagnosis */
1777 nd6log(error, "defrouter_select: more than one "
1778 "default router is installed for interface :%s.\n",
1779 if_name(installed_dr->ifp));
1780 NDDR_UNLOCK(dr);
1781 }
1782 } else {
1783 NDDR_UNLOCK(dr);
1784 }
1785
1786 NDDR_REMREF(dr); /* for this for loop */
1787 if (drrele != NULL) {
1788 NDDR_REMREF(drrele);
1789 }
1790
1791 /*
1792 * Check if the list changed when we gave up
1793 * the nd6_mutex lock
1794 */
1795 if (genid != nd6_defrouter_genid) {
1796 if (selected_dr) {
1797 NDDR_REMREF(selected_dr);
1798 selected_dr = NULL;
1799 }
1800
1801 if (installed_dr) {
1802 NDDR_REMREF(installed_dr);
1803 installed_dr = NULL;
1804 }
1805
1806 if (ndi->ndefrouters == 0 && !is_rti_rtrlist) {
1807 nd6log2(info,
1808 "%s:%d: Interface %s no longer "
1809 "has any default routers. Abort.\n",
1810 __func__, __LINE__, if_name(ifp));
1811 goto out;
1812 }
1813 nd6log2(info,
1814 "%s:%d: Iterate default router list again "
1815 "for interface %s, as the list seems to have "
1816 "changed during release-reaquire of global "
1817 "nd6_mutex lock.\n",
1818 __func__, __LINE__, if_name(ifp));
1819
1820 is_installed_reachable = FALSE;
1821 genid = nd6_defrouter_genid;
1822 dr = TAILQ_FIRST(nd_router_listp);
1823 } else {
1824 dr = TAILQ_NEXT(dr, dr_entry);
1825 }
1826 }
1827
1828 /*
1829 * If none of the default routers was found to be reachable,
1830 * round-robin the list regardless of preference.
1831 * Please note selected_dr equal to NULL implies that even
1832 * installed default router is not reachable
1833 */
1834 if (selected_dr == NULL) {
1835 if (installed_dr) {
1836 for (dr = TAILQ_NEXT(installed_dr, dr_entry); dr;
1837 dr = TAILQ_NEXT(dr, dr_entry)) {
1838 if (installed_dr->ifp != dr->ifp && !is_rti_rtrlist) {
1839 continue;
1840 }
1841 if (dr->stateflags & NDDRF_INELIGIBLE) {
1842 continue;
1843 }
1844 selected_dr = dr;
1845 break;
1846 }
1847 }
1848
1849 /*
1850 * If none was installed or the installed one if the last
1851 * one on the list, select the first one from the list
1852 */
1853 if ((installed_dr == NULL) || (selected_dr == NULL)) {
1854 for (dr = TAILQ_FIRST(nd_router_listp); dr;
1855 dr = TAILQ_NEXT(dr, dr_entry)) {
1856 if (dr->stateflags & NDDRF_INELIGIBLE) {
1857 continue;
1858 }
1859 if (dr->ifp == ifp || is_rti_rtrlist) {
1860 selected_dr = dr;
1861 break;
1862 }
1863 }
1864 }
1865
1866 if ((selected_dr == NULL) && (installed_dr == NULL)) {
1867 nd6log2(info,
1868 "%s:%d: Between release and reaquire of global "
1869 "nd6_mutex lock, the list seems to have changed "
1870 "and it does not have any default routers for "
1871 "interface %s.\n",
1872 __func__, __LINE__, if_name(ifp));
1873 goto out;
1874 }
1875
1876 if (selected_dr != installed_dr) {
1877 NDDR_ADDREF(selected_dr);
1878 }
1879 } else if (installed_dr != NULL) {
1880 if (installed_dr != selected_dr) {
1881 /*
1882 * This means that selected default router is reachable
1883 * while installed one may or may not be.
1884 * Static router should always be considered as reachable
1885 * for router selection process.
1886 */
1887 if ((installed_dr->stateflags & NDDRF_STATIC) &&
1888 rtpref(dr: installed_dr) >= rtpref(dr: selected_dr)) {
1889 NDDR_REMREF(selected_dr);
1890 selected_dr = installed_dr;
1891 } else if (is_installed_reachable) {
1892 if (rtpref(dr: selected_dr) <= rtpref(dr: installed_dr)) {
1893 NDDR_REMREF(selected_dr);
1894 selected_dr = installed_dr;
1895 }
1896 }
1897 } else {
1898 NDDR_REMREF(selected_dr);
1899 }
1900 }
1901
1902install_route:
1903 /*
1904 * If the selected router is different than the installed one,
1905 * remove the installed router and install the selected one.
1906 * Note that the selected router is never NULL here.
1907 * Else check if the route entry scope has to be changed.
1908 */
1909 lck_mtx_unlock(nd6_mutex);
1910 if (installed_dr != selected_dr) {
1911 nd6log(info,
1912 "%s:%d: Found a better router for interface "
1913 "%s. Installing new default route.\n",
1914 __func__, __LINE__, if_name(ifp));
1915 if (installed_dr != NULL) {
1916 defrouter_delreq(dr: installed_dr, rti);
1917 }
1918 /*
1919 * Install scoped route if the interface is not
1920 * the default nd6 interface.
1921 */
1922 defrouter_addreq(new: selected_dr, rti,
1923 scoped: scoped && (selected_dr->ifp != nd6_defifp));
1924 } else if (((installed_dr->stateflags & NDDRF_IFSCOPE) &&
1925 (installed_dr->ifp == nd6_defifp)) ||
1926 (scoped && !(installed_dr->stateflags & NDDRF_IFSCOPE) &&
1927 (installed_dr->ifp != nd6_defifp))) {
1928 nd6log(info,
1929 "%s:%d: Need to reinstall default route for interface "
1930 "%s as its scope has changed.\n",
1931 __func__, __LINE__, if_name(ifp));
1932 defrouter_delreq(dr: installed_dr, rti);
1933 defrouter_addreq(new: installed_dr, rti,
1934 scoped: scoped && (installed_dr->ifp != nd6_defifp));
1935 } else {
1936 nd6log2(info,
1937 "%s:%d: No need to change the default "
1938 "route for interface %s.\n",
1939 __func__, __LINE__, if_name(ifp));
1940 }
1941 lck_mtx_lock(nd6_mutex);
1942out:
1943 if (selected_dr && (selected_dr != installed_dr)) {
1944 NDDR_REMREF(selected_dr);
1945 }
1946 if (installed_dr) {
1947 NDDR_REMREF(installed_dr);
1948 }
1949 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1950 VERIFY(nd_defrouter_busy);
1951 nd_defrouter_busy = FALSE;
1952 if (nd_defrouter_waiters > 0) {
1953 nd_defrouter_waiters = 0;
1954 wakeup(chan: nd_defrouter_waitchan);
1955 }
1956}
1957
1958static struct nd_defrouter *
1959defrtrlist_update_common(struct nd_defrouter *new, struct nd_drhead *nd_router_listp, boolean_t scoped)
1960{
1961 struct nd_defrouter *dr, *n;
1962 struct ifnet *ifp = new->ifp;
1963 struct nd_ifinfo *ndi = NULL;
1964 struct timeval caltime;
1965
1966 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1967
1968 if (nd_router_listp == NULL) {
1969 nd_router_listp = &nd_defrouter_list;
1970 }
1971
1972 /*
1973 * If we are not operating on default router list,
1974 * it implies we are operating on RTI's router list.
1975 * XXX For now we manage RTI routes un-scoped.
1976 */
1977 if (nd_router_listp != &nd_defrouter_list) {
1978 scoped = FALSE;
1979 }
1980
1981 if ((dr = defrouter_lookup(nd_router_listp, addr: &new->rtaddr, ifp)) != NULL) {
1982 /* entry exists */
1983 /*
1984 * 1. If previous entry was not dummy and new is,
1985 * delete it and return NULL.
1986 * 2. If previous entry was dummy and the new one
1987 * is also dummy, simply return dr.
1988 * 3. If previous was dummy but new one is not,
1989 * make sure we perform default router selection again.
1990 */
1991 /* If the router was not added as a dummy and there's
1992 * been a change (lifetime advertised was 0, communicated
1993 * as NDDRF_INELIGIBLE flag), remove the entry.
1994 */
1995 if ((new->stateflags & NDDRF_INELIGIBLE) != 0 &&
1996 (dr->stateflags & NDDRF_INELIGIBLE) == 0) {
1997 TAILQ_REMOVE(nd_router_listp, dr, dr_entry);
1998 defrtrlist_del(dr, nd_router_listp);
1999 NDDR_REMREF(dr); /* remove list reference */
2000 NDDR_REMREF(dr);
2001 dr = NULL;
2002 return NULL;
2003 } else {
2004 int oldpref = rtpref(dr);
2005 struct nd_defrouter *p = NULL;
2006 boolean_t dummy_change = FALSE;
2007 /*
2008 * If new one is not dummy but the old one was,
2009 * reset the stateflag.
2010 */
2011 if ((new->stateflags & NDDRF_INELIGIBLE) == 0 &&
2012 (dr->stateflags & NDDRF_INELIGIBLE) != 0) {
2013 dummy_change = TRUE;
2014 dr->stateflags &= ~NDDRF_INELIGIBLE;
2015 }
2016
2017 /* override */
2018 dr->flags = new->flags; /* xxx flag check */
2019 dr->rtlifetime = new->rtlifetime;
2020 dr->expire = new->expire;
2021
2022 /*
2023 * If the preference does not change, there's no need
2024 * to sort the entries. If Scoped Routing is enabled,
2025 * put the primary/non-scoped router at the top of the
2026 * list of routers in the same preference band, unless
2027 * it's already at that position.
2028 */
2029 /* same preference and scoped; just return */
2030 if (rtpref(dr: new) == oldpref && scoped && dummy_change == FALSE) {
2031 return dr;
2032 }
2033
2034 n = TAILQ_FIRST(nd_router_listp);
2035 while (n != NULL) {
2036 /* preference changed; sort it */
2037 if (rtpref(dr: new) != oldpref) {
2038 break;
2039 }
2040
2041 /* not at the top of band; sort it */
2042 if (n != dr && rtpref(dr: n) == oldpref &&
2043 (!p || rtpref(dr: p) > rtpref(dr: n))) {
2044 break;
2045 }
2046
2047 p = n;
2048 n = TAILQ_NEXT(n, dr_entry);
2049 }
2050
2051 /* nothing has changed, just return */
2052 if (n == NULL && (scoped ||
2053 !(dr->stateflags & NDDRF_IFSCOPE)) && dummy_change == FALSE) {
2054 return dr;
2055 }
2056
2057 /*
2058 * preferred router may be changed, so relocate
2059 * this router.
2060 * XXX: calling TAILQ_REMOVE directly is a bad manner.
2061 * However, since defrtrlist_del() has many side
2062 * effects, we intentionally do so here.
2063 * defrouter_select() below will handle routing
2064 * changes later.
2065 */
2066 TAILQ_REMOVE(nd_router_listp, dr, dr_entry);
2067 new->stateflags = dr->stateflags;
2068
2069 n = dr;
2070 goto insert;
2071 }
2072 }
2073
2074 VERIFY(dr == NULL);
2075 n = nddr_alloc(Z_WAITOK);
2076
2077 ndi = ND_IFINFO(ifp);
2078 VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
2079 lck_mtx_lock(lck: &ndi->lock);
2080
2081 if (ip6_maxifdefrouters >= 0 &&
2082 ndi->ndefrouters >= ip6_maxifdefrouters) {
2083 lck_mtx_unlock(lck: &ndi->lock);
2084 nddr_free(n);
2085 nd6log(error, "%s: ignoring router addition as we have hit the "
2086 "max limit of %d for max default routers.\n", __func__,
2087 ip6_maxifdefrouters);
2088 return NULL;
2089 }
2090
2091 NDDR_ADDREF(n); /* for the nd_defrouter list */
2092 NDDR_ADDREF(n); /* for the caller */
2093
2094 ++nd6_defrouter_genid;
2095 ndi->ndefrouters++;
2096 VERIFY(ndi->ndefrouters != 0);
2097 lck_mtx_unlock(lck: &ndi->lock);
2098
2099 nd6log2(info, "%s: allocating defrouter %s\n", if_name(ifp),
2100 ip6_sprintf(&new->rtaddr));
2101
2102 getmicrotime(&caltime);
2103 NDDR_LOCK(n);
2104 memcpy(dst: &n->rtaddr, src: &new->rtaddr, n: sizeof(n->rtaddr));
2105 n->flags = new->flags;
2106 n->stateflags = new->stateflags;
2107 n->rtlifetime = new->rtlifetime;
2108 n->expire = new->expire;
2109 n->base_calendartime = caltime.tv_sec;
2110 n->base_uptime = net_uptime();
2111 n->ifp = new->ifp;
2112 n->err = new->err;
2113 n->is_reachable = TRUE;
2114 NDDR_UNLOCK(n);
2115insert:
2116 /* get nd6_service() to be scheduled as soon as it's convenient */
2117 ++nd6_sched_timeout_want;
2118
2119 /*
2120 * Insert the new router in the Default Router List;
2121 * The Default Router List should be in the descending order
2122 * of router-preferece. When Scoped Routing is disabled, routers
2123 * with the same preference are sorted in the arriving time order;
2124 * otherwise, the first entry in the list of routers having the same
2125 * preference is the primary default router, when the interface used
2126 * by the entry is the default interface.
2127 */
2128
2129 /* insert at the end of the group */
2130 for (dr = TAILQ_FIRST(nd_router_listp); dr;
2131 dr = TAILQ_NEXT(dr, dr_entry)) {
2132 if (rtpref(dr: n) > rtpref(dr) ||
2133 (!scoped && rtpref(dr: n) == rtpref(dr))) {
2134 break;
2135 }
2136 }
2137 if (dr) {
2138 TAILQ_INSERT_BEFORE(dr, n, dr_entry);
2139 } else {
2140 TAILQ_INSERT_TAIL(nd_router_listp, n, dr_entry);
2141 }
2142
2143 defrouter_select(ifp, nd_router_listp);
2144
2145 return n;
2146}
2147
2148struct nd_defrouter *
2149defrtrlist_update(struct nd_defrouter *new, struct nd_drhead *nd_router_list)
2150{
2151 struct nd_defrouter *dr;
2152
2153 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2154 dr = defrtrlist_update_common(new, nd_router_listp: nd_router_list,
2155 scoped: (nd6_defifp != NULL && new->ifp != nd6_defifp));
2156
2157 return dr;
2158}
2159
2160struct nd_pfxrouter *
2161pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
2162{
2163 struct nd_pfxrouter *search;
2164
2165 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2166 NDPR_LOCK_ASSERT_HELD(pr);
2167
2168 for (search = pr->ndpr_advrtrs.lh_first; search;
2169 search = search->pfr_next) {
2170 if (search->router == dr) {
2171 break;
2172 }
2173 }
2174
2175 return search;
2176}
2177
2178static void
2179pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
2180{
2181 struct nd_pfxrouter *new;
2182
2183 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2184 NDPR_LOCK_ASSERT_NOTHELD(pr);
2185
2186 new = zalloc_flags(ndprtr_zone, Z_WAITOK | Z_ZERO | Z_NOFAIL);
2187 new->router = dr;
2188
2189 NDPR_LOCK(pr);
2190 LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
2191 pr->ndpr_genid++;
2192 NDPR_UNLOCK(pr);
2193
2194 pfxlist_onlink_check();
2195}
2196
2197static void
2198pfxrtr_del(struct nd_pfxrouter *pfr, struct nd_prefix *pr)
2199{
2200 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2201 NDPR_LOCK_ASSERT_HELD(pr);
2202 pr->ndpr_genid++;
2203 LIST_REMOVE(pfr, pfr_entry);
2204 zfree(ndprtr_zone, pfr);
2205}
2206
2207/*
2208 * The routine has been modified to atomically refresh expiry
2209 * time for nd6 prefix as the part of lookup.
2210 * There's a corner case where a system going
2211 * in sleep gets rid of manual addresses configured in the system
2212 * and then schedules the prefix for deletion.
2213 * However before the prefix gets deleted, if system comes out
2214 * from sleep and configures same address before prefix deletion
2215 * , the later prefix deletion will remove the prefix route and
2216 * the system will not be able to communicate with other IPv6
2217 * neighbor nodes in the same subnet.
2218 */
2219struct nd_prefix *
2220nd6_prefix_lookup(struct nd_prefix *pr, int nd6_prefix_expiry)
2221{
2222 struct nd_prefix *search;
2223
2224 lck_mtx_lock(nd6_mutex);
2225 for (search = nd_prefix.lh_first; search; search = search->ndpr_next) {
2226 NDPR_LOCK(search);
2227 if (pr->ndpr_ifp == search->ndpr_ifp &&
2228 pr->ndpr_plen == search->ndpr_plen &&
2229 in6_are_prefix_equal(p1: &pr->ndpr_prefix.sin6_addr, ifscope1: pr->ndpr_prefix.sin6_scope_id,
2230 p2: &search->ndpr_prefix.sin6_addr, ifscope2: search->ndpr_prefix.sin6_scope_id, len: pr->ndpr_plen)) {
2231 if (nd6_prefix_expiry != ND6_PREFIX_EXPIRY_UNSPEC) {
2232 search->ndpr_expire = nd6_prefix_expiry;
2233 }
2234 NDPR_ADDREF(search);
2235 NDPR_UNLOCK(search);
2236 break;
2237 }
2238 NDPR_UNLOCK(search);
2239 }
2240 lck_mtx_unlock(nd6_mutex);
2241
2242 return search;
2243}
2244
2245int
2246nd6_prelist_add(struct nd_prefix *pr, struct nd_defrouter *dr,
2247 struct nd_prefix **newp, boolean_t force_scoped)
2248{
2249 struct nd_prefix *new = NULL;
2250 struct ifnet *ifp = pr->ndpr_ifp;
2251 struct nd_ifinfo *ndi = NULL;
2252 int i, error;
2253
2254 if (ip6_maxifprefixes >= 0) {
2255 ndi = ND_IFINFO(ifp);
2256 VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
2257 lck_mtx_lock(lck: &ndi->lock);
2258 if (ndi->nprefixes >= ip6_maxifprefixes) {
2259 lck_mtx_unlock(lck: &ndi->lock);
2260 return ENOMEM;
2261 }
2262 lck_mtx_unlock(lck: &ndi->lock);
2263 }
2264
2265 new = ndpr_alloc(M_WAITOK);
2266 if (new == NULL) {
2267 return ENOMEM;
2268 }
2269
2270 NDPR_LOCK(new);
2271 NDPR_LOCK(pr);
2272 new->ndpr_ifp = pr->ndpr_ifp;
2273 new->ndpr_prefix = pr->ndpr_prefix;
2274 new->ndpr_plen = pr->ndpr_plen;
2275 new->ndpr_vltime = pr->ndpr_vltime;
2276 new->ndpr_pltime = pr->ndpr_pltime;
2277 new->ndpr_flags = pr->ndpr_flags;
2278 if (pr->ndpr_stateflags & NDPRF_STATIC) {
2279 new->ndpr_stateflags |= NDPRF_STATIC;
2280 }
2281 NDPR_UNLOCK(pr);
2282 if ((error = in6_init_prefix_ltimes(ndpr: new)) != 0) {
2283 NDPR_UNLOCK(new);
2284 ndpr_free(new);
2285 return error;
2286 }
2287 new->ndpr_lastupdate = net_uptime();
2288 if (newp != NULL) {
2289 *newp = new;
2290 NDPR_ADDREF(new); /* for caller */
2291 }
2292 /* initialization */
2293 LIST_INIT(&new->ndpr_advrtrs);
2294 in6_prefixlen2mask(maskp: &new->ndpr_mask, len: new->ndpr_plen);
2295 /* make prefix in the canonical form */
2296 for (i = 0; i < 4; i++) {
2297 new->ndpr_prefix.sin6_addr.s6_addr32[i] &=
2298 new->ndpr_mask.s6_addr32[i];
2299 }
2300
2301 NDPR_UNLOCK(new);
2302
2303 /* get nd6_service() to be scheduled as soon as it's convenient */
2304 ++nd6_sched_timeout_want;
2305
2306 lck_mtx_lock(nd6_mutex);
2307 /* link ndpr_entry to nd_prefix list */
2308 LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry);
2309 new->ndpr_debug |= IFD_ATTACHED;
2310 NDPR_ADDREF(new); /* for nd_prefix list */
2311
2312 lck_mtx_lock(lck: &ndi->lock);
2313 ndi->nprefixes++;
2314 VERIFY(ndi->nprefixes != 0);
2315 lck_mtx_unlock(lck: &ndi->lock);
2316
2317 /* ND_OPT_PI_FLAG_ONLINK processing */
2318 if (new->ndpr_raf_onlink) {
2319 int e;
2320
2321 if ((e = nd6_prefix_onlink_common(new, force_scoped,
2322 new->ndpr_ifp->if_index)) != 0) {
2323 nd6log(error, "nd6_prelist_add: failed to make "
2324 "the prefix %s/%d on-link %s on %s (errno=%d)\n",
2325 ip6_sprintf(&new->ndpr_prefix.sin6_addr),
2326 new->ndpr_plen, force_scoped ? "scoped" :
2327 "non-scoped", if_name(ifp), e);
2328 /* proceed anyway. XXX: is it correct? */
2329 }
2330 }
2331
2332 if (dr) {
2333 pfxrtr_add(pr: new, dr);
2334 }
2335
2336 lck_mtx_unlock(nd6_mutex);
2337
2338 return 0;
2339}
2340
2341/*
2342 * Caller must have held an extra reference on nd_prefix.
2343 */
2344void
2345prelist_remove(struct nd_prefix *pr)
2346{
2347 struct nd_pfxrouter *pfr = NULL, *next = NULL;
2348 struct ifnet *ifp = pr->ndpr_ifp;
2349 struct nd_ifinfo *ndi = NULL;
2350 struct nd_prefix *tmp_pr = NULL;
2351 boolean_t pr_scoped;
2352 int err;
2353
2354 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
2355 NDPR_LOCK_ASSERT_HELD(pr);
2356
2357 if (pr->ndpr_stateflags & NDPRF_DEFUNCT) {
2358 return;
2359 }
2360
2361 pr_scoped = (pr->ndpr_stateflags & NDPRF_IFSCOPE) != 0;
2362 /*
2363 * If there are no more addresses, defunct the prefix. This is needed
2364 * because we don't want multiple threads calling prelist_remove() for
2365 * the same prefix and this might happen because we unlock nd6_mutex
2366 * down below.
2367 */
2368 if (pr->ndpr_addrcnt == 0) {
2369 pr->ndpr_stateflags |= NDPRF_DEFUNCT;
2370 }
2371
2372 /* make sure to invalidate the prefix until it is really freed. */
2373 pr->ndpr_vltime = 0;
2374 pr->ndpr_pltime = 0;
2375
2376 /*
2377 * Though these flags are now meaningless, we'd rather keep the value
2378 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users
2379 * when executing "ndp -p".
2380 */
2381 if (pr->ndpr_stateflags & NDPRF_ONLINK) {
2382 int error = 0;
2383 NDPR_ADDREF(pr);
2384 NDPR_UNLOCK(pr);
2385 lck_mtx_unlock(nd6_mutex);
2386 if ((error = nd6_prefix_offlink(pr)) != 0) {
2387 nd6log(error, "prelist_remove: failed to make "
2388 "%s/%d offlink on %s, errno=%d\n",
2389 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
2390 pr->ndpr_plen, if_name(ifp), error);
2391 /* what should we do? */
2392 }
2393 lck_mtx_lock(nd6_mutex);
2394 NDPR_LOCK(pr);
2395 if (NDPR_REMREF(pr) == NULL) {
2396 return;
2397 }
2398 }
2399
2400 /*
2401 * Check if there is a scoped version of this PR, if so
2402 * make it unscoped.
2403 */
2404 if (!pr_scoped && IN6_IS_ADDR_UNIQUE_LOCAL(&pr->ndpr_prefix.sin6_addr)) {
2405 tmp_pr = nd6_prefix_equal_lookup(pr, FALSE);
2406 if (tmp_pr != NULL) {
2407 NDPR_ADDREF(pr);
2408 NDPR_UNLOCK(pr);
2409
2410 lck_mtx_unlock(nd6_mutex);
2411 err = nd6_prefix_offlink(tmp_pr);
2412 lck_mtx_lock(nd6_mutex);
2413 if (err != 0) {
2414 nd6log(error,
2415 "%s: failed to make %s/%d offlink on %s, "
2416 "errno=%d\n", __func__,
2417 ip6_sprintf(&tmp_pr->ndpr_prefix.sin6_addr),
2418 tmp_pr->ndpr_plen, if_name(tmp_pr->ndpr_ifp), err);
2419 }
2420
2421 err = nd6_prefix_onlink_scoped(tmp_pr, IFSCOPE_NONE);
2422 if (err != 0) {
2423 nd6log(error,
2424 "%s: failed to make %s/%d onlink on %s, errno=%d\n",
2425 __func__, ip6_sprintf(&tmp_pr->ndpr_prefix.sin6_addr),
2426 tmp_pr->ndpr_plen, if_name(tmp_pr->ndpr_ifp), err);
2427 }
2428
2429 if (err != 0) {
2430 nd6log(error,
2431 "%s: error unscoping %s/%d from %s\n",
2432 __func__, ip6_sprintf(&tmp_pr->ndpr_prefix.sin6_addr),
2433 tmp_pr->ndpr_plen, if_name(tmp_pr->ndpr_ifp));
2434 } else {
2435 nd6log2(info,
2436 "%s: %s/%d unscoped, previously on %s\n",
2437 __func__, ip6_sprintf(&tmp_pr->ndpr_prefix.sin6_addr),
2438 tmp_pr->ndpr_plen, if_name(tmp_pr->ndpr_ifp));
2439 }
2440
2441 NDPR_REMREF(tmp_pr);
2442
2443 NDPR_LOCK(pr);
2444 if (NDPR_REMREF(pr) == NULL) {
2445 return;
2446 }
2447 }
2448 }
2449
2450 if (pr->ndpr_addrcnt > 0) {
2451 /*
2452 * The state might have changed if we called
2453 * nd6_prefix_offlink().
2454 */
2455 pr->ndpr_stateflags &= ~NDPRF_DEFUNCT;
2456 return; /* notice here? */
2457 }
2458
2459 /* unlink ndpr_entry from nd_prefix list */
2460 LIST_REMOVE(pr, ndpr_entry);
2461 pr->ndpr_debug &= ~IFD_ATTACHED;
2462
2463 /* free list of routers that adversed the prefix */
2464 for (pfr = pr->ndpr_advrtrs.lh_first; pfr; pfr = next) {
2465 next = pfr->pfr_next;
2466 pfxrtr_del(pfr, pr);
2467 }
2468
2469 ndi = ND_IFINFO(ifp);
2470 VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
2471 lck_mtx_lock(lck: &ndi->lock);
2472 VERIFY(ndi->nprefixes > 0);
2473 ndi->nprefixes--;
2474 lck_mtx_unlock(lck: &ndi->lock);
2475
2476 /* This must not be the last reference to the nd_prefix */
2477 if (NDPR_REMREF(pr) == NULL) {
2478 panic("%s: unexpected (missing) refcnt ndpr=%p", __func__, pr);
2479 /* NOTREACHED */
2480 }
2481
2482 /*
2483 * Don't call pfxlist_onlink_check() here because we are
2484 * holding the NDPR lock and this could cause a deadlock when
2485 * there are multiple threads executing pfxlist_onlink_check().
2486 */
2487}
2488
2489int
2490prelist_update(
2491 struct nd_prefix *new,
2492 struct nd_defrouter *dr, /* may be NULL */
2493 struct mbuf *m,
2494 int mcast)
2495{
2496 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
2497 struct ifaddr *ifa;
2498 struct ifnet *ifp = new->ndpr_ifp;
2499 struct nd_prefix *pr;
2500 int error = 0;
2501 int newprefix = 0;
2502 int auth;
2503 uint64_t timenow = net_uptime();
2504
2505 /* no need to lock "new" here, as it is local to the caller */
2506 NDPR_LOCK_ASSERT_NOTHELD(new);
2507
2508 auth = 0;
2509 if (m) {
2510 /*
2511 * Authenticity for NA consists authentication for
2512 * both IP header and IP datagrams, doesn't it ?
2513 */
2514#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM)
2515 auth = (m->m_flags & M_AUTHIPHDR) && (m->m_flags & M_AUTHIPDGM);
2516#endif
2517 }
2518
2519 if ((pr = nd6_prefix_lookup(pr: new, ND6_PREFIX_EXPIRY_UNSPEC)) != NULL) {
2520 /*
2521 * nd6_prefix_lookup() ensures that pr and new have the same
2522 * prefix on a same interface.
2523 */
2524
2525 /*
2526 * Update prefix information. Note that the on-link (L) bit
2527 * and the autonomous (A) bit should NOT be changed from 1
2528 * to 0.
2529 */
2530 lck_mtx_lock(nd6_mutex);
2531 NDPR_LOCK(pr);
2532 if (new->ndpr_raf_onlink == 1) {
2533 pr->ndpr_raf_onlink = 1;
2534 }
2535 if (new->ndpr_raf_auto == 1) {
2536 pr->ndpr_raf_auto = 1;
2537 }
2538 if (new->ndpr_raf_onlink) {
2539 pr->ndpr_vltime = new->ndpr_vltime;
2540 pr->ndpr_pltime = new->ndpr_pltime;
2541 (void) in6_init_prefix_ltimes(ndpr: pr); /* XXX error case? */
2542 pr->ndpr_lastupdate = net_uptime();
2543 }
2544
2545 NDPR_ADDREF(pr);
2546 if (new->ndpr_raf_onlink &&
2547 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
2548 int e;
2549
2550 NDPR_UNLOCK(pr);
2551 if ((e = nd6_prefix_onlink(pr)) != 0) {
2552 nd6log(error,
2553 "prelist_update: failed to make "
2554 "the prefix %s/%d on-link on %s "
2555 "(errno=%d)\n",
2556 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
2557 pr->ndpr_plen, if_name(pr->ndpr_ifp), e);
2558 /* proceed anyway. XXX: is it correct? */
2559 }
2560 NDPR_LOCK(pr);
2561 }
2562
2563 if (dr && pfxrtr_lookup(pr, dr) == NULL) {
2564 NDPR_UNLOCK(pr);
2565 pfxrtr_add(pr, dr);
2566 } else {
2567 NDPR_UNLOCK(pr);
2568 }
2569 NDPR_REMREF(pr);
2570 lck_mtx_unlock(nd6_mutex);
2571 } else {
2572 newprefix = 1;
2573
2574 if (new->ndpr_vltime == 0) {
2575 goto end;
2576 }
2577 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0) {
2578 goto end;
2579 }
2580
2581 bzero(s: &new->ndpr_addr, n: sizeof(struct in6_addr));
2582
2583 error = nd6_prelist_add(pr: new, dr, newp: &pr, FALSE);
2584 if (error != 0 || pr == NULL) {
2585 nd6log(info, "prelist_update: "
2586 "nd6_prelist_add failed for %s/%d on %s "
2587 "errno=%d, returnpr=0x%llx\n",
2588 ip6_sprintf(&new->ndpr_prefix.sin6_addr),
2589 new->ndpr_plen, if_name(new->ndpr_ifp),
2590 error, (uint64_t)VM_KERNEL_ADDRPERM(pr));
2591 goto end; /* we should just give up in this case. */
2592 }
2593 }
2594
2595 /*
2596 * Address autoconfiguration based on Section 5.5.3 of RFC 4862.
2597 * Note that pr must be non NULL at this point.
2598 */
2599
2600 /* 5.5.3 (a). Ignore the prefix without the A bit set. */
2601 if (!new->ndpr_raf_auto) {
2602 goto end;
2603 }
2604
2605 /*
2606 * 5.5.3 (b). the link-local prefix should have been ignored in
2607 * nd6_ra_input.
2608 */
2609
2610 /* 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. */
2611 if (new->ndpr_pltime > new->ndpr_vltime) {
2612 error = EINVAL; /* XXX: won't be used */
2613 goto end;
2614 }
2615
2616 /*
2617 * 5.5.3 (d). If the prefix advertised is not equal to the prefix of
2618 * an address configured by stateless autoconfiguration already in the
2619 * list of addresses associated with the interface, and the Valid
2620 * Lifetime is not 0, form an address. We first check if we have
2621 * a matching prefix.
2622 */
2623 ifnet_lock_shared(ifp);
2624 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
2625 struct in6_ifaddr *ifa6 = NULL;
2626 u_int32_t remaininglifetime = 0;
2627 struct in6_addrlifetime lt6_tmp = {};
2628
2629 IFA_LOCK(ifa);
2630 if (ifa->ifa_addr->sa_family != AF_INET6) {
2631 IFA_UNLOCK(ifa);
2632 continue;
2633 }
2634 ifa6 = (struct in6_ifaddr *)ifa;
2635
2636 /*
2637 * We only consider autoconfigured addresses as per RFC 4862.
2638 */
2639 if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF)) {
2640 IFA_UNLOCK(ifa);
2641 continue;
2642 }
2643 /*
2644 * Spec is not clear here, but I believe we should concentrate
2645 * on unicast (i.e. not anycast) addresses.
2646 * XXX: other ia6_flags? detached or duplicated?
2647 */
2648 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) {
2649 IFA_UNLOCK(ifa);
2650 continue;
2651 }
2652 /*
2653 * Ignore the address if it is not associated with a prefix
2654 * or is associated with a prefix that is different from this
2655 * one. (pr is never NULL here)
2656 */
2657 if (ifa6->ia6_ndpr != pr) {
2658 IFA_UNLOCK(ifa);
2659 continue;
2660 }
2661
2662 if (ia6_match == NULL) { /* remember the first one */
2663 ia6_match = ifa6;
2664 ifa_addref(ifa); /* for ia6_match */
2665 }
2666
2667 /*
2668 * An already autoconfigured address matched. Now that we
2669 * are sure there is at least one matched address, we can
2670 * proceed to 5.5.3. (e): update the lifetimes according to the
2671 * "two hours" rule and the privacy extension.
2672 */
2673 /* retrieve time as uptime (last arg is 0) */
2674 in6ifa_getlifetime(ifa6, &lt6_tmp, 0);
2675
2676 if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) {
2677 remaininglifetime = ND6_INFINITE_LIFETIME;
2678 } else if (timenow - ifa6->ia6_updatetime > lt6_tmp.ia6t_vltime) {
2679 /*
2680 * The case of "invalid" address. We should usually
2681 * not see this case.
2682 */
2683 remaininglifetime = 0;
2684 } else {
2685 remaininglifetime = lt6_tmp.ia6t_vltime -
2686 (uint32_t)(timenow - ifa6->ia6_updatetime);
2687 }
2688 /* when not updating, keep the current stored lifetime. */
2689 lt6_tmp.ia6t_vltime = remaininglifetime;
2690
2691 if (TWOHOUR < new->ndpr_vltime ||
2692 remaininglifetime < new->ndpr_vltime) {
2693 lt6_tmp.ia6t_vltime = new->ndpr_vltime;
2694 } else if (remaininglifetime <= TWOHOUR) {
2695 if (auth) {
2696 lt6_tmp.ia6t_vltime = new->ndpr_vltime;
2697 }
2698 } else {
2699 /*
2700 * new->ndpr_vltime <= TWOHOUR &&
2701 * TWOHOUR < remaininglifetime
2702 */
2703 lt6_tmp.ia6t_vltime = TWOHOUR;
2704 }
2705
2706 /* The 2 hour rule is not imposed for preferred lifetime. */
2707 lt6_tmp.ia6t_pltime = new->ndpr_pltime;
2708
2709 /* Special handling for lifetimes of temporary addresses. */
2710 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
2711 u_int32_t maxvltime, maxpltime;
2712
2713 /* Constrain lifetimes to system limits. */
2714 if (lt6_tmp.ia6t_vltime > ip6_temp_valid_lifetime) {
2715 lt6_tmp.ia6t_vltime = ip6_temp_valid_lifetime;
2716 }
2717 if (lt6_tmp.ia6t_pltime > ip6_temp_preferred_lifetime) {
2718 lt6_tmp.ia6t_pltime =
2719 ip6_temp_preferred_lifetime -
2720 ip6_desync_factor;
2721 }
2722
2723 /*
2724 * According to RFC 4941, section 3.3 (1), we only
2725 * update the lifetimes when they are in the maximum
2726 * intervals.
2727 */
2728 if (ip6_temp_valid_lifetime >
2729 (u_int32_t)((timenow - ifa6->ia6_createtime) +
2730 ip6_desync_factor)) {
2731 maxvltime = ip6_temp_valid_lifetime -
2732 (uint32_t)((timenow - ifa6->ia6_createtime) +
2733 ip6_desync_factor);
2734 } else {
2735 maxvltime = 0;
2736 }
2737 if (ip6_temp_preferred_lifetime >
2738 (u_int32_t)((timenow - ifa6->ia6_createtime) +
2739 ip6_desync_factor)) {
2740 maxpltime = ip6_temp_preferred_lifetime -
2741 (uint32_t)((timenow - ifa6->ia6_createtime) +
2742 ip6_desync_factor);
2743 } else {
2744 maxpltime = 0;
2745 }
2746
2747 if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME ||
2748 lt6_tmp.ia6t_vltime > maxvltime) {
2749 lt6_tmp.ia6t_vltime = maxvltime;
2750 }
2751
2752 if (lt6_tmp.ia6t_pltime == ND6_INFINITE_LIFETIME ||
2753 lt6_tmp.ia6t_pltime > maxpltime) {
2754 lt6_tmp.ia6t_pltime = maxpltime;
2755 }
2756 }
2757
2758 in6_init_address_ltimes(&lt6_tmp);
2759 in6ifa_setlifetime(ifa6, &lt6_tmp);
2760 ifa6->ia6_updatetime = timenow;
2761 IFA_UNLOCK(ifa);
2762 }
2763 ifnet_lock_done(ifp);
2764 if (ia6_match == NULL && new->ndpr_vltime) {
2765 /*
2766 * 5.5.3 (d) (continued)
2767 * No address matched and the valid lifetime is non-zero.
2768 * Create a new address.
2769 */
2770 if ((ia6 = in6_pfx_newpersistaddr(new, mcast, &error, FALSE, 0))
2771 != NULL) {
2772 /*
2773 * note that we should use pr (not new) for reference.
2774 */
2775 IFA_LOCK(&ia6->ia_ifa);
2776 NDPR_LOCK(pr);
2777 ia6->ia6_ndpr = pr;
2778 NDPR_ADDREF(pr); /* for addr reference */
2779 pr->ndpr_addrcnt++;
2780 VERIFY(pr->ndpr_addrcnt != 0);
2781 NDPR_UNLOCK(pr);
2782 IFA_UNLOCK(&ia6->ia_ifa);
2783
2784 /*
2785 * RFC 4941 3.3 (2).
2786 * When a new public address is created as described
2787 * in RFC 4862, also create a new temporary address.
2788 *
2789 * RFC 4941 3.5.
2790 * When an interface connects to a new link, a new
2791 * randomized interface identifier should be generated
2792 * immediately together with a new set of temporary
2793 * addresses. Thus, we specifiy 1 as the 2nd arg of
2794 * in6_tmpifadd().
2795 */
2796 if (ip6_use_tempaddr &&
2797 (!IN6_IS_ADDR_UNIQUE_LOCAL(&new->ndpr_prefix.sin6_addr)
2798 || ip6_ula_use_tempaddr)) {
2799 int e;
2800 if ((e = in6_tmpifadd(ia6, 1)) != 0) {
2801 nd6log(info, "prelist_update: "
2802 "failed to create a temporary "
2803 "address, errno=%d\n",
2804 e);
2805 }
2806 }
2807 ifa_remref(ifa: &ia6->ia_ifa);
2808 ia6 = NULL;
2809
2810 /*
2811 * If the interface is marked for CLAT46 configuration
2812 * try and configure the reserved IPv6 address for
2813 * stateless translation.
2814 */
2815 if (IS_INTF_CLAT46(ifp)) {
2816 if ((ia6 = in6_pfx_newpersistaddr(new, mcast,
2817 &error, TRUE, CLAT46_COLLISION_COUNT_OFFSET))
2818 != NULL) {
2819 IFA_LOCK(&ia6->ia_ifa);
2820 NDPR_LOCK(pr);
2821 ia6->ia6_ndpr = pr;
2822 NDPR_ADDREF(pr); /* for addr reference */
2823 pr->ndpr_addrcnt++;
2824 VERIFY(pr->ndpr_addrcnt != 0);
2825 pr->ndpr_stateflags |= NDPRF_CLAT46;
2826 NDPR_UNLOCK(pr);
2827 IFA_UNLOCK(&ia6->ia_ifa);
2828 ifa_remref(ifa: &ia6->ia_ifa);
2829 ia6 = NULL;
2830 } else if (error != EEXIST) {
2831 uuid_t tmp_uuid = {};
2832 /*
2833 * Only report the error if it is not
2834 * EEXIST.
2835 */
2836 ip6stat.ip6s_clat464_v6addr_conffail++;
2837 in6_clat46_event_enqueue_nwk_wq_entry(
2838 IN6_CLAT46_EVENT_V6_ADDR_CONFFAIL,
2839 0,
2840 tmp_uuid);
2841 nd6log0(error, "Could not configure CLAT46 address on interface %s.\n", ifp->if_xname);
2842 }
2843 /*
2844 * Reset the error as we do not want to
2845 * treat failure of CLAT46 address configuration
2846 * as complete failure in prelist update path.
2847 */
2848 error = 0;
2849 }
2850
2851 /*
2852 * A newly added address might affect the status
2853 * of other addresses, so we check and update it.
2854 * XXX: what if address duplication happens?
2855 */
2856 lck_mtx_lock(nd6_mutex);
2857 pfxlist_onlink_check();
2858 lck_mtx_unlock(nd6_mutex);
2859 }
2860 }
2861end:
2862 if (pr != NULL) {
2863 NDPR_REMREF(pr);
2864 }
2865 if (ia6_match != NULL) {
2866 ifa_remref(ifa: &ia6_match->ia_ifa);
2867 }
2868 return error;
2869}
2870
2871/*
2872 * Neighbor Discover Default Router structure reference counting routines.
2873 */
2874static struct nd_defrouter *
2875nddr_alloc(zalloc_flags_t how)
2876{
2877 struct nd_defrouter *dr;
2878
2879 dr = zalloc_flags(nddr_zone, how | Z_ZERO);
2880 if (dr) {
2881 lck_mtx_init(lck: &dr->nddr_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
2882 lck_mtx_init(lck: &dr->nddr_ref_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
2883 dr->nddr_debug |= IFD_ALLOC;
2884 if (nddr_debug != 0) {
2885 dr->nddr_debug |= IFD_DEBUG;
2886 dr->nddr_trace = nddr_trace;
2887 }
2888 }
2889 return dr;
2890}
2891
2892static void
2893nddr_free(struct nd_defrouter *dr)
2894{
2895 if (dr->nddr_debug & IFD_ATTACHED) {
2896 panic("%s: attached nddr %p is being freed", __func__, dr);
2897 /* NOTREACHED */
2898 } else if (!(dr->nddr_debug & IFD_ALLOC)) {
2899 panic("%s: nddr %p cannot be freed", __func__, dr);
2900 /* NOTREACHED */
2901 }
2902 dr->nddr_debug &= ~IFD_ALLOC;
2903 lck_mtx_destroy(lck: &dr->nddr_lock, grp: &ifa_mtx_grp);
2904 lck_mtx_destroy(lck: &dr->nddr_ref_lock, grp: &ifa_mtx_grp);
2905 zfree(nddr_zone, dr);
2906}
2907
2908static void
2909nddr_trace(struct nd_defrouter *dr, int refhold)
2910{
2911 struct nd_defrouter_dbg *dr_dbg = (struct nd_defrouter_dbg *)dr;
2912 ctrace_t *tr;
2913 uint32_t idx;
2914 uint16_t *cnt;
2915
2916 if (!(dr->nddr_debug & IFD_DEBUG)) {
2917 panic("%s: nddr %p has no debug structure", __func__, dr);
2918 /* NOTREACHED */
2919 }
2920 if (refhold) {
2921 cnt = &dr_dbg->nddr_refhold_cnt;
2922 tr = dr_dbg->nddr_refhold;
2923 } else {
2924 cnt = &dr_dbg->nddr_refrele_cnt;
2925 tr = dr_dbg->nddr_refrele;
2926 }
2927
2928 idx = os_atomic_inc_orig(cnt, relaxed) % NDDR_TRACE_HIST_SIZE;
2929 ctrace_record(&tr[idx]);
2930}
2931
2932void
2933nddr_addref(struct nd_defrouter *nddr)
2934{
2935 NDDR_REF_LOCK_SPIN(nddr);
2936 if (++nddr->nddr_refcount == 0) {
2937 panic("%s: nddr %p wraparound refcnt", __func__, nddr);
2938 /* NOTREACHED */
2939 } else if (nddr->nddr_trace != NULL) {
2940 (*nddr->nddr_trace)(nddr, TRUE);
2941 }
2942 NDDR_REF_UNLOCK(nddr);
2943}
2944
2945struct nd_defrouter *
2946nddr_remref(struct nd_defrouter *nddr)
2947{
2948 NDDR_REF_LOCK_SPIN(nddr);
2949 if (nddr->nddr_refcount == 0) {
2950 panic("%s: nddr %p negative refcnt", __func__, nddr);
2951 /* NOTREACHED */
2952 } else if (nddr->nddr_trace != NULL) {
2953 (*nddr->nddr_trace)(nddr, FALSE);
2954 }
2955
2956 if (--nddr->nddr_refcount == 0) {
2957 NDDR_REF_UNLOCK(nddr);
2958 nddr_free(dr: nddr);
2959 nddr = NULL;
2960 } else {
2961 NDDR_REF_UNLOCK(nddr);
2962 }
2963 return nddr;
2964}
2965
2966uint64_t
2967nddr_getexpire(struct nd_defrouter *dr)
2968{
2969 struct timeval caltime;
2970 uint64_t expiry;
2971
2972 if (dr->expire != 0) {
2973 /* account for system time change */
2974 getmicrotime(&caltime);
2975
2976 dr->base_calendartime +=
2977 NET_CALCULATE_CLOCKSKEW(caltime,
2978 dr->base_calendartime, net_uptime(), dr->base_uptime);
2979
2980 expiry = dr->base_calendartime +
2981 dr->expire - dr->base_uptime;
2982 } else {
2983 expiry = 0;
2984 }
2985 return expiry;
2986}
2987
2988/*
2989 * Neighbor Discover Prefix structure reference counting routines.
2990 */
2991static struct nd_prefix *
2992ndpr_alloc(int how)
2993{
2994 struct nd_prefix *pr;
2995
2996 pr = zalloc_flags(ndpr_zone, how | Z_ZERO);
2997 if (pr != NULL) {
2998 lck_mtx_init(lck: &pr->ndpr_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
2999 lck_mtx_init(lck: &pr->ndpr_ref_lock, grp: &ifa_mtx_grp, attr: &ifa_mtx_attr);
3000 RB_INIT(&pr->ndpr_prproxy_sols);
3001 pr->ndpr_debug |= IFD_ALLOC;
3002 if (ndpr_debug != 0) {
3003 pr->ndpr_debug |= IFD_DEBUG;
3004 pr->ndpr_trace = ndpr_trace;
3005 }
3006 }
3007 return pr;
3008}
3009
3010static void
3011ndpr_free(struct nd_prefix *pr)
3012{
3013 if (pr->ndpr_debug & IFD_ATTACHED) {
3014 panic("%s: attached ndpr %p is being freed", __func__, pr);
3015 /* NOTREACHED */
3016 } else if (!(pr->ndpr_debug & IFD_ALLOC)) {
3017 panic("%s: ndpr %p cannot be freed", __func__, pr);
3018 /* NOTREACHED */
3019 } else if (pr->ndpr_rt != NULL) {
3020 panic("%s: ndpr %p route %p not freed", __func__, pr,
3021 pr->ndpr_rt);
3022 /* NOTREACHED */
3023 } else if (pr->ndpr_prproxy_sols_cnt != 0) {
3024 panic("%s: ndpr %p non-zero solicitors count (%d)",
3025 __func__, pr, pr->ndpr_prproxy_sols_cnt);
3026 /* NOTREACHED */
3027 } else if (!RB_EMPTY(&pr->ndpr_prproxy_sols)) {
3028 panic("%s: ndpr %p non-empty solicitors tree", __func__, pr);
3029 /* NOTREACHED */
3030 }
3031 pr->ndpr_debug &= ~IFD_ALLOC;
3032 lck_mtx_destroy(lck: &pr->ndpr_lock, grp: &ifa_mtx_grp);
3033 lck_mtx_destroy(lck: &pr->ndpr_ref_lock, grp: &ifa_mtx_grp);
3034 zfree(ndpr_zone, pr);
3035}
3036
3037static void
3038ndpr_trace(struct nd_prefix *pr, int refhold)
3039{
3040 struct nd_prefix_dbg *pr_dbg = (struct nd_prefix_dbg *)pr;
3041 ctrace_t *tr;
3042 u_int32_t idx;
3043 u_int16_t *cnt;
3044
3045 if (!(pr->ndpr_debug & IFD_DEBUG)) {
3046 panic("%s: ndpr %p has no debug structure", __func__, pr);
3047 /* NOTREACHED */
3048 }
3049 if (refhold) {
3050 cnt = &pr_dbg->ndpr_refhold_cnt;
3051 tr = pr_dbg->ndpr_refhold;
3052 } else {
3053 cnt = &pr_dbg->ndpr_refrele_cnt;
3054 tr = pr_dbg->ndpr_refrele;
3055 }
3056
3057 idx = os_atomic_inc_orig(cnt, relaxed) % NDPR_TRACE_HIST_SIZE;
3058 ctrace_record(&tr[idx]);
3059}
3060
3061void
3062ndpr_addref(struct nd_prefix *ndpr)
3063{
3064 NDPR_REF_LOCK_SPIN(ndpr);
3065 if (++ndpr->ndpr_refcount == 0) {
3066 panic("%s: ndpr %p wraparound refcnt", __func__, ndpr);
3067 /* NOTREACHED */
3068 } else if (ndpr->ndpr_trace != NULL) {
3069 (*ndpr->ndpr_trace)(ndpr, TRUE);
3070 }
3071 NDPR_REF_UNLOCK(ndpr);
3072}
3073
3074struct nd_prefix *
3075ndpr_remref(struct nd_prefix *ndpr)
3076{
3077 NDPR_REF_LOCK_SPIN(ndpr);
3078 if (ndpr->ndpr_refcount == 0) {
3079 panic("%s: ndpr %p negative refcnt", __func__, ndpr);
3080 /* NOTREACHED */
3081 } else if (ndpr->ndpr_trace != NULL) {
3082 (*ndpr->ndpr_trace)(ndpr, FALSE);
3083 }
3084
3085 if (--ndpr->ndpr_refcount == 0) {
3086 if (ndpr->ndpr_addrcnt != 0) {
3087 panic("%s: freeing ndpr %p with outstanding address "
3088 "reference (%d)", __func__, ndpr,
3089 ndpr->ndpr_addrcnt);
3090 /* NOTREACHED */
3091 }
3092 NDPR_REF_UNLOCK(ndpr);
3093 ndpr_free(pr: ndpr);
3094 ndpr = NULL;
3095 } else {
3096 NDPR_REF_UNLOCK(ndpr);
3097 }
3098 return ndpr;
3099}
3100
3101uint64_t
3102ndpr_getexpire(struct nd_prefix *pr)
3103{
3104 struct timeval caltime;
3105 uint64_t expiry;
3106
3107 if (pr->ndpr_expire != 0 && pr->ndpr_vltime != ND6_INFINITE_LIFETIME) {
3108 /* account for system time change */
3109 getmicrotime(&caltime);
3110
3111 pr->ndpr_base_calendartime +=
3112 NET_CALCULATE_CLOCKSKEW(caltime,
3113 pr->ndpr_base_calendartime, net_uptime(),
3114 pr->ndpr_base_uptime);
3115
3116 expiry = pr->ndpr_base_calendartime +
3117 pr->ndpr_expire - pr->ndpr_base_uptime;
3118 } else {
3119 expiry = 0;
3120 }
3121 return expiry;
3122}
3123
3124/*
3125 * A supplement function used in the on-link detection below;
3126 * detect if a given prefix has a (probably) reachable advertising router.
3127 * XXX: lengthy function name...
3128 */
3129static struct nd_pfxrouter *
3130find_pfxlist_reachable_router(struct nd_prefix *pr)
3131{
3132 struct nd_pfxrouter *pfxrtr = NULL;
3133 struct ifnet *ifp = NULL;
3134
3135 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3136 NDPR_LOCK_ASSERT_HELD(pr);
3137
3138 pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs);
3139 while (pfxrtr) {
3140 /* XXX This should be same as prefixes interface. */
3141 ifp = pfxrtr->router->ifp;
3142
3143 /*
3144 * As long as there's a router advertisting this prefix
3145 * on cellular (for that matter any interface that is point
3146 * to point really), we treat the router as reachable.
3147 */
3148 if (ifp != NULL && ifp->if_type == IFT_CELLULAR) {
3149 break;
3150 }
3151
3152 if (pfxrtr->router->is_reachable) {
3153 break;
3154 }
3155 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry);
3156 }
3157 return pfxrtr;
3158}
3159
3160/*
3161 * Check if each prefix in the prefix list has at least one available router
3162 * that advertised the prefix (a router is "available" if its neighbor cache
3163 * entry is reachable or probably reachable).
3164 * If the check fails, the prefix may be off-link, because, for example,
3165 * we have moved from the network but the lifetime of the prefix has not
3166 * expired yet. So we should not use the prefix if there is another prefix
3167 * that has an available router.
3168 * But, if there is no prefix that has an available router, we still regards
3169 * all the prefixes as on-link. This is because we can't tell if all the
3170 * routers are simply dead or if we really moved from the network and there
3171 * is no router around us.
3172 */
3173void
3174pfxlist_onlink_check(void)
3175{
3176 struct nd_prefix *pr, *prclear;
3177 struct in6_ifaddr *ifa;
3178 struct nd_defrouter *dr;
3179 struct nd_pfxrouter *pfxrtr = NULL;
3180 int err, i, found = 0;
3181 struct ifaddr **ifap = NULL;
3182 struct nd_prefix *ndpr;
3183 u_int64_t timenow = net_uptime();
3184
3185 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3186
3187 while (nd_prefix_busy) {
3188 nd_prefix_waiters++;
3189 msleep(chan: nd_prefix_waitchan, nd6_mutex, pri: (PZERO - 1),
3190 wmesg: __func__, NULL);
3191 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3192 }
3193 nd_prefix_busy = TRUE;
3194
3195 /*
3196 * Check if there is a prefix that has a reachable advertising
3197 * router.
3198 */
3199 pr = nd_prefix.lh_first;
3200 while (pr) {
3201 NDPR_LOCK(pr);
3202 if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr) &&
3203 (pr->ndpr_debug & IFD_ATTACHED)) {
3204 NDPR_UNLOCK(pr);
3205 break;
3206 }
3207 NDPR_UNLOCK(pr);
3208 pr = pr->ndpr_next;
3209 }
3210 /*
3211 * If we have no such prefix, check whether we still have a router
3212 * that does not advertise any prefixes.
3213 */
3214 if (pr == NULL) {
3215 for (dr = TAILQ_FIRST(&nd_defrouter_list); dr;
3216 dr = TAILQ_NEXT(dr, dr_entry)) {
3217 struct nd_prefix *pr0;
3218
3219 for (pr0 = nd_prefix.lh_first; pr0;
3220 pr0 = pr0->ndpr_next) {
3221 NDPR_LOCK(pr0);
3222 if ((pfxrtr = pfxrtr_lookup(pr: pr0, dr)) != NULL) {
3223 NDPR_UNLOCK(pr0);
3224 break;
3225 }
3226 NDPR_UNLOCK(pr0);
3227 }
3228 if (pfxrtr != NULL) {
3229 break;
3230 }
3231 }
3232 }
3233 if (pr != NULL || (TAILQ_FIRST(&nd_defrouter_list) && pfxrtr == NULL)) {
3234 /*
3235 * There is at least one prefix that has a reachable router,
3236 * or at least a router which probably does not advertise
3237 * any prefixes. The latter would be the case when we move
3238 * to a new link where we have a router that does not provide
3239 * prefixes and we configure an address by hand.
3240 * Detach prefixes which have no reachable advertising
3241 * router, and attach other prefixes.
3242 */
3243 pr = nd_prefix.lh_first;
3244 while (pr) {
3245 NDPR_LOCK(pr);
3246 /*
3247 * We aren't interested prefixes already processed,
3248 * nor in prefixes without the L bit
3249 * set nor in static prefixes
3250 */
3251 if (pr->ndpr_raf_onlink == 0 ||
3252 pr->ndpr_stateflags & NDPRF_STATIC) {
3253 NDPR_UNLOCK(pr);
3254 pr = pr->ndpr_next;
3255 continue;
3256 }
3257 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
3258 find_pfxlist_reachable_router(pr) == NULL &&
3259 (pr->ndpr_debug & IFD_ATTACHED)) {
3260 pr->ndpr_stateflags |= NDPRF_DETACHED;
3261 }
3262 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
3263 find_pfxlist_reachable_router(pr) != NULL &&
3264 (pr->ndpr_debug & IFD_ATTACHED)) {
3265 pr->ndpr_stateflags &= ~NDPRF_DETACHED;
3266 }
3267 NDPR_UNLOCK(pr);
3268 pr = pr->ndpr_next;
3269 }
3270 } else {
3271 /* there is no prefix that has a reachable router */
3272 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3273 NDPR_LOCK(pr);
3274 if (pr->ndpr_raf_onlink == 0 ||
3275 pr->ndpr_stateflags & NDPRF_STATIC) {
3276 NDPR_UNLOCK(pr);
3277 continue;
3278 }
3279 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0) {
3280 pr->ndpr_stateflags &= ~NDPRF_DETACHED;
3281 }
3282 NDPR_UNLOCK(pr);
3283 }
3284 }
3285 /*
3286 * Instead of removing interface route for detached prefix,
3287 * keep the route and treat unreachability similar to the processing
3288 * of an RA that has just deprecated the prefix.
3289 * Keep around the detached flag just to be able to be able
3290 * to differentiate the scenario from explicit RA deprecation
3291 * of prefix.
3292 * Keep the logic to install the interface route for a (just) attached
3293 * prefix. Note that all attempt of reinstallation does not
3294 * necessarily success, when a same prefix is shared among multiple
3295 * interfaces. Such cases will be handled in nd6_prefix_onlink,
3296 * so we don't have to care about them.
3297 */
3298 pr = nd_prefix.lh_first;
3299 while (pr) {
3300 int error;
3301
3302 NDPR_LOCK(pr);
3303 if (pr->ndpr_raf_onlink == 0 ||
3304 pr->ndpr_stateflags & NDPRF_STATIC ||
3305 pr->ndpr_stateflags & NDPRF_PROCESSED_ONLINK ||
3306 pr->ndpr_stateflags & NDPRF_DEFUNCT) {
3307 NDPR_UNLOCK(pr);
3308 pr = pr->ndpr_next;
3309 continue;
3310 }
3311 pr->ndpr_stateflags |= NDPRF_PROCESSED_ONLINK;
3312 NDPR_ADDREF(pr);
3313 if (pr->ndpr_stateflags & NDPRF_DETACHED) {
3314 /*
3315 * When a prefix is detached, make it deprecated by setting pltime
3316 * to 0, and let it expire according to its advertised vltime.
3317 * If its original vltime is infinite or longer than 2hr,
3318 * set it to 2hr.
3319 */
3320 pr->ndpr_pltime = 0;
3321 uint32_t pr_remaining_lifetime;
3322 uint32_t original_lifetime = (uint32_t)(timenow - pr->ndpr_base_uptime);
3323 if (pr->ndpr_vltime > original_lifetime) {
3324 pr_remaining_lifetime = pr->ndpr_vltime - original_lifetime;
3325 } else {
3326 pr_remaining_lifetime = 0;
3327 }
3328 if (pr->ndpr_vltime == ND6_INFINITE_LIFETIME ||
3329 pr_remaining_lifetime >= TWOHOUR) {
3330 pr->ndpr_vltime = TWOHOUR;
3331 } else {
3332 pr->ndpr_vltime = pr_remaining_lifetime;
3333 }
3334 in6_init_prefix_ltimes(ndpr: pr);
3335 NDPR_UNLOCK(pr);
3336 } else if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
3337 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 &&
3338 pr->ndpr_raf_onlink) {
3339 NDPR_UNLOCK(pr);
3340 if ((error = nd6_prefix_onlink(pr)) != 0) {
3341 nd6log(error,
3342 "pfxlist_onlink_check: failed to "
3343 "make %s/%d offlink, errno=%d\n",
3344 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3345 pr->ndpr_plen, error);
3346 }
3347 NDPR_REMREF(pr);
3348 pr = nd_prefix.lh_first;
3349 continue;
3350 } else {
3351 NDPR_UNLOCK(pr);
3352 }
3353 NDPR_REMREF(pr);
3354 pr = pr->ndpr_next;
3355 }
3356 LIST_FOREACH(prclear, &nd_prefix, ndpr_entry) {
3357 NDPR_LOCK(prclear);
3358 prclear->ndpr_stateflags &= ~NDPRF_PROCESSED_ONLINK;
3359 NDPR_UNLOCK(prclear);
3360 }
3361 VERIFY(nd_prefix_busy);
3362 nd_prefix_busy = FALSE;
3363 if (nd_prefix_waiters > 0) {
3364 nd_prefix_waiters = 0;
3365 wakeup(chan: nd_prefix_waitchan);
3366 }
3367
3368 /*
3369 * Changes on the prefix status might affect address status as well.
3370 * Make sure that all addresses derived from an attached prefix are
3371 * attached, and that all addresses derived from a detached prefix are
3372 * detached. Note, however, that a manually configured address should
3373 * always be attached.
3374 * The precise detection logic is same as the one for prefixes.
3375 *
3376 * ifnet_get_address_list_family_internal() may fail due to memory
3377 * pressure, but we will eventually be called again when we receive
3378 * another NA, RA, or when the link status changes.
3379 */
3380 err = ifnet_get_address_list_family_internal(NULL, &ifap, AF_INET6, 0,
3381 M_NOWAIT, 0);
3382 if (err != 0 || ifap == NULL) {
3383 nd6log(error, "%s: ifnet_get_address_list_family_internal "
3384 "failed", __func__);
3385 return;
3386 }
3387 for (i = 0; ifap[i]; i++) {
3388 ifa = ifatoia6(ifap[i]);
3389 IFA_LOCK(&ifa->ia_ifa);
3390 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0 ||
3391 (ifap[i]->ifa_debug & IFD_ATTACHED) == 0) {
3392 IFA_UNLOCK(&ifa->ia_ifa);
3393 continue;
3394 }
3395 if ((ndpr = ifa->ia6_ndpr) == NULL) {
3396 /*
3397 * This can happen when we first configure the address
3398 * (i.e. the address exists, but the prefix does not).
3399 * XXX: complicated relationships...
3400 */
3401 IFA_UNLOCK(&ifa->ia_ifa);
3402 continue;
3403 }
3404 IFA_UNLOCK(&ifa->ia_ifa);
3405
3406 NDPR_LOCK(ndpr);
3407 if (find_pfxlist_reachable_router(pr: ndpr)) {
3408 NDPR_UNLOCK(ndpr);
3409 found = 1;
3410 break;
3411 }
3412 NDPR_UNLOCK(ndpr);
3413 }
3414 if (found) {
3415 for (i = 0; ifap[i]; i++) {
3416 struct in6_addrlifetime lt6_tmp = {};
3417
3418 ifa = ifatoia6(ifap[i]);
3419 IFA_LOCK(&ifa->ia_ifa);
3420 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0 ||
3421 (ifap[i]->ifa_debug & IFD_ATTACHED) == 0) {
3422 IFA_UNLOCK(&ifa->ia_ifa);
3423 continue;
3424 }
3425 if ((ndpr = ifa->ia6_ndpr) == NULL) {
3426 /* XXX: see above. */
3427 IFA_UNLOCK(&ifa->ia_ifa);
3428 continue;
3429 }
3430 IFA_UNLOCK(&ifa->ia_ifa);
3431 NDPR_LOCK(ndpr);
3432 if (find_pfxlist_reachable_router(pr: ndpr) == NULL) {
3433 /*
3434 * When the prefix of an addr is detached, make the address
3435 * deprecated by setting pltime to 0, and let it expire according
3436 * to its advertised vltime. If its original vltime is infinite
3437 * or longer than 2hr, set it to 2hr.
3438 */
3439 NDPR_UNLOCK(ndpr);
3440 IFA_LOCK(&ifa->ia_ifa);
3441 in6ifa_getlifetime(ifa, &lt6_tmp, 0);
3442 /* We want to immediately deprecate the address */
3443 lt6_tmp.ia6t_pltime = 0;
3444 /* Do not extend its valid lifetime */
3445 uint32_t remaining_lifetime;
3446 uint32_t original_lifetime = (uint32_t)(timenow - ifa->ia6_updatetime);
3447 if (lt6_tmp.ia6t_vltime > original_lifetime) {
3448 remaining_lifetime = lt6_tmp.ia6t_vltime - original_lifetime;
3449 } else {
3450 remaining_lifetime = 0;
3451 }
3452 if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME || remaining_lifetime >= TWOHOUR) {
3453 lt6_tmp.ia6t_vltime = TWOHOUR;
3454 } else {
3455 lt6_tmp.ia6t_vltime = remaining_lifetime;
3456 }
3457
3458 in6_init_address_ltimes(&lt6_tmp);
3459 in6ifa_setlifetime(ifa, &lt6_tmp);
3460 ifa->ia6_updatetime = timenow;
3461
3462 /*
3463 * The next nd6 service timer expiry will take
3464 * care of marking the addresses as deprecated
3465 * and issuing the notifications as well.
3466 */
3467 IFA_UNLOCK(&ifa->ia_ifa);
3468 } else {
3469 NDPR_UNLOCK(ndpr);
3470 }
3471 }
3472 }
3473 ifnet_free_address_list(addresses: ifap);
3474}
3475
3476static struct nd_prefix *
3477nd6_prefix_equal_lookup(struct nd_prefix *pr, boolean_t primary_only)
3478{
3479 struct nd_prefix *opr;
3480
3481 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3482
3483 for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) {
3484 if (opr == pr) {
3485 continue;
3486 }
3487
3488 NDPR_LOCK(opr);
3489 if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
3490 NDPR_UNLOCK(opr);
3491 continue;
3492 }
3493 if (opr->ndpr_plen == pr->ndpr_plen &&
3494 in6_are_prefix_equal(p1: &pr->ndpr_prefix.sin6_addr, ifscope1: pr->ndpr_prefix.sin6_scope_id,
3495 p2: &opr->ndpr_prefix.sin6_addr, ifscope2: opr->ndpr_prefix.sin6_scope_id, len: pr->ndpr_plen) &&
3496 (!primary_only ||
3497 !(opr->ndpr_stateflags & NDPRF_IFSCOPE))) {
3498 NDPR_ADDREF(opr);
3499 NDPR_UNLOCK(opr);
3500 return opr;
3501 }
3502 NDPR_UNLOCK(opr);
3503 }
3504 return NULL;
3505}
3506
3507/*
3508 * Synchronize the interface routes of similar prefixes on different
3509 * interfaces; the one using the default interface would be (re)installed
3510 * as a primary/non-scoped entry, and the rest as scoped entri(es).
3511 */
3512static void
3513nd6_prefix_sync(struct ifnet *ifp)
3514{
3515 struct nd_prefix *pr, *opr;
3516 int err = 0;
3517
3518 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3519
3520 if (ifp == NULL) {
3521 return;
3522 }
3523
3524 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
3525 NDPR_LOCK(pr);
3526 if (!(pr->ndpr_stateflags & NDPRF_ONLINK)) {
3527 NDPR_UNLOCK(pr);
3528 continue;
3529 }
3530 if (pr->ndpr_ifp == ifp &&
3531 (pr->ndpr_stateflags & NDPRF_IFSCOPE) &&
3532 !IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
3533 NDPR_UNLOCK(pr);
3534 break;
3535 }
3536 NDPR_UNLOCK(pr);
3537 }
3538
3539 if (pr == NULL) {
3540 return;
3541 }
3542
3543 /* Remove conflicting entries */
3544 opr = nd6_prefix_equal_lookup(pr, TRUE);
3545 if (opr != NULL) {
3546 lck_mtx_unlock(nd6_mutex);
3547 err = nd6_prefix_offlink(opr);
3548 lck_mtx_lock(nd6_mutex);
3549 if (err != 0) {
3550 nd6log(error,
3551 "%s: failed to make %s/%d offlink on %s, "
3552 "errno=%d\n", __func__,
3553 ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
3554 opr->ndpr_plen, if_name(opr->ndpr_ifp), err);
3555 }
3556 } else {
3557 nd6log(error,
3558 "%s: scoped %s/%d on %s has no matching unscoped prefix\n",
3559 __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3560 pr->ndpr_plen, if_name(pr->ndpr_ifp));
3561 }
3562
3563 lck_mtx_unlock(nd6_mutex);
3564 err = nd6_prefix_offlink(pr);
3565 lck_mtx_lock(nd6_mutex);
3566 if (err != 0) {
3567 nd6log(error,
3568 "%s: failed to make %s/%d offlink on %s, errno=%d\n",
3569 __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3570 pr->ndpr_plen, if_name(pr->ndpr_ifp), err);
3571 }
3572
3573 /* Add the entries back */
3574 if (opr != NULL) {
3575 err = nd6_prefix_onlink_scoped(opr, opr->ndpr_ifp->if_index);
3576 if (err != 0) {
3577 nd6log(error,
3578 "%s: failed to make %s/%d scoped onlink on %s, "
3579 "errno=%d\n", __func__,
3580 ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
3581 opr->ndpr_plen, if_name(opr->ndpr_ifp), err);
3582 }
3583 }
3584
3585 err = nd6_prefix_onlink_scoped(pr, IFSCOPE_NONE);
3586 if (err != 0) {
3587 nd6log(error,
3588 "%s: failed to make %s/%d onlink on %s, errno=%d\n",
3589 __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3590 pr->ndpr_plen, if_name(pr->ndpr_ifp), err);
3591 }
3592
3593 if (err != 0) {
3594 nd6log(error,
3595 "%s: error promoting %s/%d to %s from %s\n",
3596 __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3597 pr->ndpr_plen, if_name(pr->ndpr_ifp),
3598 (opr != NULL) ? if_name(opr->ndpr_ifp) : "NONE");
3599 } else {
3600 nd6log2(info,
3601 "%s: %s/%d promoted, previously on %s\n",
3602 if_name(pr->ndpr_ifp),
3603 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen,
3604 (opr != NULL) ? if_name(opr->ndpr_ifp) : "NONE");
3605 }
3606
3607 if (opr != NULL) {
3608 NDPR_REMREF(opr);
3609 }
3610}
3611
3612static int
3613nd6_prefix_onlink_common(struct nd_prefix *pr, boolean_t force_scoped,
3614 unsigned int ifscope)
3615{
3616 struct ifaddr *ifa;
3617 struct ifnet *ifp = pr->ndpr_ifp;
3618 struct sockaddr_in6 mask6, prefix;
3619 struct nd_prefix *opr;
3620 u_int32_t rtflags;
3621 int error = 0, prproxy = 0;
3622 struct rtentry *rt __single = NULL;
3623 u_char prefix_len = 0;
3624
3625 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_OWNED);
3626
3627 /* sanity check */
3628 NDPR_LOCK(pr);
3629 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
3630 nd6log(error,
3631 "%s: %s/%d on %s scoped=%d is already on-link\n",
3632 __func__, ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3633 pr->ndpr_plen, if_name(pr->ndpr_ifp),
3634 (pr->ndpr_stateflags & NDPRF_IFSCOPE) ? 1 : 0);
3635 NDPR_UNLOCK(pr);
3636 return EEXIST;
3637 }
3638 NDPR_UNLOCK(pr);
3639
3640 /*
3641 * Add the interface route associated with the prefix. Before
3642 * installing the route, check if there's the same prefix on another
3643 * interface, and the prefix has already installed the interface route.
3644 */
3645 opr = nd6_prefix_equal_lookup(pr, FALSE);
3646 if (opr != NULL) {
3647 NDPR_REMREF(opr);
3648 }
3649
3650 if (!force_scoped) {
3651 /*
3652 * If a primary/non-scoped interface route already exists,
3653 * install the new one as a scoped entry. If the existing
3654 * interface route is scoped, install new as non-scoped.
3655 */
3656 ifscope = (opr != NULL) ? ifp->if_index : IFSCOPE_NONE;
3657 opr = nd6_prefix_equal_lookup(pr, TRUE);
3658 if (opr != NULL) {
3659 NDPR_REMREF(opr);
3660 } else if (ifscope != IFSCOPE_NONE) {
3661 ifscope = IFSCOPE_NONE;
3662 }
3663 }
3664
3665 /*
3666 * We prefer link-local addresses as the associated interface address.
3667 */
3668 /* search for a link-local addr */
3669 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
3670 IN6_IFF_NOTREADY | IN6_IFF_ANYCAST);
3671 if (ifa == NULL) {
3672 struct in6_ifaddr *ia6;
3673 ifnet_lock_shared(ifp);
3674 IFP_TO_IA6(ifp, ia6);
3675 ifnet_lock_done(ifp);
3676 if (ia6 != NULL) {
3677 ifa = &ia6->ia_ifa;
3678 }
3679 /* should we care about ia6_flags? */
3680 }
3681 NDPR_LOCK(pr);
3682 if (ifa == NULL) {
3683 /*
3684 * This can still happen, when, for example, we receive an RA
3685 * containing a prefix with the L bit set and the A bit clear,
3686 * after removing all IPv6 addresses on the receiving
3687 * interface. This should, of course, be rare though.
3688 */
3689 nd6log(info,
3690 "nd6_prefix_onlink: failed to find any ifaddr"
3691 " to add route for a prefix(%s/%d) on %s\n",
3692 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3693 pr->ndpr_plen, if_name(ifp));
3694 NDPR_UNLOCK(pr);
3695 return 0;
3696 }
3697
3698 /*
3699 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs.
3700 * ifa->ifa_rtrequest = nd6_rtrequest;
3701 */
3702 SOCKADDR_ZERO(&mask6, sizeof(mask6));
3703 mask6.sin6_len = sizeof(mask6);
3704 mask6.sin6_addr = pr->ndpr_mask;
3705 prefix = pr->ndpr_prefix;
3706 prefix_len = pr->ndpr_plen;
3707 if ((rt = pr->ndpr_rt) != NULL) {
3708 pr->ndpr_rt = NULL;
3709 }
3710 NDPR_ADDREF(pr); /* keep reference for this routine */
3711 NDPR_UNLOCK(pr);
3712
3713 IFA_LOCK_SPIN(ifa);
3714 rtflags = ifa->ifa_flags | RTF_CLONING | RTF_UP;
3715 IFA_UNLOCK(ifa);
3716 if (nd6_need_cache(ifp)) {
3717 /* explicitly set in case ifa_flags does not set the flag. */
3718 rtflags |= RTF_CLONING;
3719 } else {
3720 /*
3721 * explicitly clear the cloning bit in case ifa_flags sets it.
3722 */
3723 rtflags &= ~RTF_CLONING;
3724 }
3725
3726 lck_mtx_unlock(nd6_mutex);
3727
3728 /*
3729 * check if it conflicts with a indirect prefix route added by RIO
3730 * if so, remove the rti entry.
3731 */
3732 if (ifscope == IFSCOPE_NONE) {
3733 struct rtentry *temp_route = NULL;
3734 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_NOTOWNED);
3735 lck_mtx_lock(rnh_lock);
3736 temp_route = rt_lookup(TRUE, SA(&prefix), SA(&mask6), rt_tables[AF_INET6], IFSCOPE_NONE);
3737 lck_mtx_unlock(rnh_lock);
3738
3739 if (temp_route != NULL && temp_route->rt_flags & RTF_GATEWAY && temp_route->rt_ifp != NULL) {
3740 struct nd_route_info rti = {};
3741 bzero(s: &rti, n: sizeof(rti));
3742 rti.nd_rti_prefixlen = prefix_len;
3743 rti.nd_rti_prefix = prefix.sin6_addr;
3744 lck_mtx_lock(nd6_mutex);
3745 nd6_rti_purge(&rti);
3746 lck_mtx_unlock(nd6_mutex);
3747 }
3748 if (temp_route != NULL) {
3749 rtfree(temp_route);
3750 }
3751 }
3752
3753 if (rt != NULL) {
3754 rtfree(rt);
3755 rt = NULL;
3756 }
3757
3758 error = rtrequest_scoped(RTM_ADD, SA(&prefix), ifa->ifa_addr, SA(&mask6),
3759 rtflags, &rt, ifscope);
3760
3761 /*
3762 * Serialize the setting of NDPRF_PRPROXY.
3763 */
3764 lck_mtx_lock(lck: &proxy6_lock);
3765
3766 if (rt != NULL) {
3767 RT_LOCK(rt);
3768 nd6_rtmsg(RTM_ADD, rt);
3769 RT_UNLOCK(rt);
3770 NDPR_LOCK(pr);
3771 } else {
3772 NDPR_LOCK(pr);
3773 nd6log(error, "nd6_prefix_onlink: failed to add route for a"
3774 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%x,"
3775 " scoped=%d, errno = %d\n",
3776 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3777 pr->ndpr_plen, if_name(ifp),
3778 ip6_sprintf(&SIN6(ifa->ifa_addr)->sin6_addr),
3779 ip6_sprintf(&mask6.sin6_addr), rtflags,
3780 (ifscope != IFSCOPE_NONE), error);
3781 }
3782 NDPR_LOCK_ASSERT_HELD(pr);
3783
3784 pr->ndpr_stateflags &= ~(NDPRF_IFSCOPE | NDPRF_PRPROXY);
3785
3786 /*
3787 * TODO: If the prefix route exists, we should really find it and
3788 * refer the prefix to it; otherwise ndpr_rt is NULL.
3789 */
3790 if (!(pr->ndpr_stateflags & NDPRF_DEFUNCT) &&
3791 (rt != NULL || error == EEXIST)) {
3792 struct nd_ifinfo *ndi = NULL;
3793
3794 VERIFY(pr->ndpr_prproxy_sols_cnt == 0);
3795 VERIFY(RB_EMPTY(&pr->ndpr_prproxy_sols));
3796
3797 ndi = ND_IFINFO(ifp);
3798 VERIFY((NULL != ndi) && (TRUE == ndi->initialized));
3799 lck_mtx_lock(lck: &ndi->lock);
3800
3801 pr->ndpr_rt = rt; /* keep reference from rtrequest */
3802 pr->ndpr_stateflags |= NDPRF_ONLINK;
3803 if (ifscope != IFSCOPE_NONE) {
3804 pr->ndpr_stateflags |= NDPRF_IFSCOPE;
3805 } else if ((rtflags & RTF_CLONING) &&
3806 (ndi->flags & ND6_IFF_PROXY_PREFIXES) &&
3807 !IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) {
3808 /*
3809 * At present, in order for the prefix to be eligible
3810 * as a proxying/proxied prefix, we require that the
3811 * prefix route entry be marked as a cloning route with
3812 * RTF_PROXY; i.e. nd6_need_cache() needs to return
3813 * true for the interface type, hence the test for
3814 * RTF_CLONING above.
3815 */
3816 pr->ndpr_stateflags |= NDPRF_PRPROXY;
3817 }
3818
3819 lck_mtx_unlock(lck: &ndi->lock);
3820 } else if (rt != NULL && pr->ndpr_stateflags & NDPRF_DEFUNCT) {
3821 rtfree(rt);
3822 }
3823
3824 prproxy = (pr->ndpr_stateflags & NDPRF_PRPROXY);
3825 VERIFY(!prproxy || !(pr->ndpr_stateflags & NDPRF_IFSCOPE));
3826 NDPR_UNLOCK(pr);
3827
3828 ifa_remref(ifa);
3829
3830 /*
3831 * If this is an upstream prefix, find the downstream ones (if any)
3832 * and re-configure their prefix routes accordingly. Otherwise,
3833 * this could be potentially be a downstream prefix, and so find the
3834 * upstream prefix, if any.
3835 */
3836 nd6_prproxy_prelist_update(pr, prproxy ? pr : NULL);
3837
3838 NDPR_REMREF(pr); /* release reference for this routine */
3839 lck_mtx_unlock(lck: &proxy6_lock);
3840
3841 lck_mtx_lock(nd6_mutex);
3842
3843 return error;
3844}
3845
3846int
3847nd6_prefix_onlink(struct nd_prefix *pr)
3848{
3849 return nd6_prefix_onlink_common(pr, FALSE, IFSCOPE_NONE);
3850}
3851
3852int
3853nd6_prefix_onlink_scoped(struct nd_prefix *pr, unsigned int ifscope)
3854{
3855 return nd6_prefix_onlink_common(pr, TRUE, ifscope);
3856}
3857
3858int
3859nd6_prefix_offlink(struct nd_prefix *pr)
3860{
3861 int plen, error = 0, prproxy;
3862 struct ifnet *ifp = pr->ndpr_ifp;
3863 struct sockaddr_in6 sa6, mask6, prefix;
3864 struct rtentry *rt __single = NULL, *ndpr_rt = NULL;
3865 unsigned int ifscope;
3866
3867 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
3868
3869 /* sanity check */
3870 NDPR_LOCK(pr);
3871 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
3872 nd6log(error,
3873 "nd6_prefix_offlink: %s/%d on %s scoped=%d is already "
3874 "off-link\n", ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
3875 pr->ndpr_plen, if_name(pr->ndpr_ifp),
3876 (pr->ndpr_stateflags & NDPRF_IFSCOPE) ? 1 : 0);
3877 NDPR_UNLOCK(pr);
3878 return EEXIST;
3879 }
3880
3881 SOCKADDR_ZERO(&sa6, sizeof(sa6));
3882 sa6.sin6_family = AF_INET6;
3883 sa6.sin6_len = sizeof(sa6);
3884 bcopy(src: &pr->ndpr_prefix.sin6_addr, dst: &sa6.sin6_addr,
3885 n: sizeof(struct in6_addr));
3886 SOCKADDR_ZERO(&mask6, sizeof(mask6));
3887 mask6.sin6_family = AF_INET6;
3888 mask6.sin6_len = sizeof(sa6);
3889 bcopy(src: &pr->ndpr_mask, dst: &mask6.sin6_addr, n: sizeof(struct in6_addr));
3890 prefix = pr->ndpr_prefix;
3891 plen = pr->ndpr_plen;
3892 if ((ndpr_rt = pr->ndpr_rt) != NULL) {
3893 pr->ndpr_rt = NULL;
3894 }
3895 NDPR_ADDREF(pr); /* keep reference for this routine */
3896 NDPR_UNLOCK(pr);
3897
3898 ifscope = (pr->ndpr_stateflags & NDPRF_IFSCOPE) ?
3899 ifp->if_index : IFSCOPE_NONE;
3900
3901 error = rtrequest_scoped(RTM_DELETE, SA(&sa6), NULL, SA(&mask6),
3902 0, &rt, ifscope);
3903
3904 if (rt != NULL) {
3905 /* report the route deletion to the routing socket. */
3906 RT_LOCK(rt);
3907 nd6_rtmsg(RTM_DELETE, rt);
3908 RT_UNLOCK(rt);
3909 rtfree(rt);
3910 } else {
3911 nd6log(error,
3912 "nd6_prefix_offlink: failed to delete route: "
3913 "%s/%d on %s, scoped %d, (errno = %d)\n",
3914 ip6_sprintf(&sa6.sin6_addr), plen, if_name(ifp),
3915 (ifscope != IFSCOPE_NONE), error);
3916 }
3917
3918 if (ndpr_rt != NULL) {
3919 rtfree(ndpr_rt);
3920 }
3921
3922 lck_mtx_lock(lck: &proxy6_lock);
3923
3924 NDPR_LOCK(pr);
3925 prproxy = (pr->ndpr_stateflags & NDPRF_PRPROXY);
3926 VERIFY(!prproxy || !(pr->ndpr_stateflags & NDPRF_IFSCOPE));
3927 pr->ndpr_stateflags &= ~(NDPRF_ONLINK | NDPRF_IFSCOPE | NDPRF_PRPROXY);
3928 if (pr->ndpr_prproxy_sols_cnt > 0) {
3929 VERIFY(prproxy);
3930 nd6_prproxy_sols_reap(pr);
3931 VERIFY(pr->ndpr_prproxy_sols_cnt == 0);
3932 VERIFY(RB_EMPTY(&pr->ndpr_prproxy_sols));
3933 }
3934 NDPR_UNLOCK(pr);
3935
3936 /*
3937 * If this was an upstream prefix, find the downstream ones and do
3938 * some cleanups. If this was a downstream prefix, the prefix route
3939 * has been removed from the routing table above, but there may be
3940 * other tasks to perform.
3941 */
3942 nd6_prproxy_prelist_update(pr, prproxy ? pr : NULL);
3943
3944 NDPR_REMREF(pr); /* release reference for this routine */
3945 lck_mtx_unlock(lck: &proxy6_lock);
3946
3947 return error;
3948}
3949
3950struct in6_ifaddr *
3951in6_pfx_newpersistaddr(struct nd_prefix *pr, int mcast, int *errorp,
3952 boolean_t is_clat46, uint8_t collision_count)
3953{
3954 struct in6_ifaddr *ia6 = NULL;
3955 struct ifnet *ifp = NULL;
3956 struct nd_ifinfo *ndi = NULL;
3957 struct in6_addr mask;
3958 struct in6_aliasreq ifra;
3959 int error, ifaupdate, iidlen, notcga;
3960
3961 VERIFY(pr != NULL);
3962 VERIFY(errorp != NULL);
3963
3964 NDPR_LOCK(pr);
3965 ifp = pr->ndpr_ifp;
3966 ia6 = NULL;
3967 error = 0;
3968
3969 /*
3970 * Prefix Length check:
3971 * If the sum of the prefix length and interface identifier
3972 * length does not equal 128 bits, the Prefix Information
3973 * option MUST be ignored. The length of the interface
3974 * identifier is defined in a separate link-type specific
3975 * document.
3976 */
3977 iidlen = in6_if2idlen(ifp);
3978 if (iidlen < 0) {
3979 error = EADDRNOTAVAIL;
3980 /* this should not happen, so we always log it. */
3981 log(LOG_ERR, "%s: IID length undefined (%s)\n",
3982 __func__, if_name(ifp));
3983 goto unlock1;
3984 } else if (iidlen != 64) {
3985 error = EADDRNOTAVAIL;
3986 /*
3987 * stateless autoconfiguration not yet well-defined for IID
3988 * lengths other than 64 octets. Just give up for now.
3989 */
3990 nd6log(info, "%s: IID length not 64 octets (%s)\n",
3991 __func__, if_name(ifp));
3992 goto unlock1;
3993 }
3994
3995 if (iidlen + pr->ndpr_plen != 128) {
3996 error = EADDRNOTAVAIL;
3997 nd6log(info,
3998 "%s: invalid prefix length %d for %s, ignored\n",
3999 __func__, pr->ndpr_plen, if_name(ifp));
4000 goto unlock1;
4001 }
4002
4003 bzero(s: &ifra, n: sizeof(ifra));
4004 strlcpy(dst: ifra.ifra_name, if_name(ifp), n: sizeof(ifra.ifra_name));
4005 ifra.ifra_addr.sin6_family = AF_INET6;
4006 ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
4007
4008 /* prefix */
4009 bcopy(src: &pr->ndpr_prefix.sin6_addr, dst: &ifra.ifra_addr.sin6_addr,
4010 n: sizeof(ifra.ifra_addr.sin6_addr));
4011 in6_len2mask(&mask, pr->ndpr_plen);
4012 ifra.ifra_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
4013 ifra.ifra_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
4014 ifra.ifra_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
4015 ifra.ifra_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
4016
4017 ndi = ND_IFINFO(ifp);
4018 VERIFY(ndi->initialized);
4019 lck_mtx_lock(lck: &ndi->lock);
4020
4021 notcga = nd6_send_opstate == ND6_SEND_OPMODE_DISABLED ||
4022 (ndi->flags & ND6_IFF_INSECURE) != 0;
4023
4024 lck_mtx_unlock(lck: &ndi->lock);
4025 NDPR_UNLOCK(pr);
4026
4027 if (notcga && !is_clat46) {
4028 ia6 = in6ifa_ifpforlinklocal(ifp, 0);
4029 if (ia6 == NULL) {
4030 error = EADDRNOTAVAIL;
4031 nd6log(info, "%s: no link-local address (%s)\n",
4032 __func__, if_name(ifp));
4033 goto done;
4034 }
4035
4036 IFA_LOCK(&ia6->ia_ifa);
4037 ifra.ifra_addr.sin6_addr.s6_addr32[0] |=
4038 (ia6->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]);
4039 ifra.ifra_addr.sin6_addr.s6_addr32[1] |=
4040 (ia6->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]);
4041 ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
4042 (ia6->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]);
4043 ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
4044 (ia6->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]);
4045 IFA_UNLOCK(&ia6->ia_ifa);
4046 ifa_remref(ifa: &ia6->ia_ifa);
4047 ia6 = NULL;
4048 } else {
4049 struct in6_cga_prepare local_cga_prepare;
4050 struct in6_cga_prepare *prepare_p;
4051
4052
4053 in6_cga_node_lock();
4054
4055 if (ndi->cga_initialized) {
4056 bcopy(src: &(ndi->local_cga_modifier),
4057 dst: &(local_cga_prepare.cga_modifier),
4058 n: sizeof(local_cga_prepare.cga_modifier));
4059 prepare_p = &local_cga_prepare;
4060 } else {
4061 prepare_p = NULL;
4062 }
4063 error = in6_cga_generate(prepare_p, collision_count,
4064 &ifra.ifra_addr.sin6_addr, ifp);
4065 in6_cga_node_unlock();
4066 if (error == 0) {
4067 ifra.ifra_flags |= IN6_IFF_SECURED;
4068 if (is_clat46) {
4069 ifra.ifra_flags |= IN6_IFF_CLAT46;
4070 }
4071 } else {
4072 if (!is_clat46) {
4073 nd6log(error, "%s: no CGA available (%s)\n",
4074 __func__, if_name(ifp));
4075 } else {
4076 nd6log(error, "%s: no CLAT46 available (%s)\n",
4077 __func__, if_name(ifp));
4078 }
4079 goto done;
4080 }
4081 }
4082
4083 VERIFY(ia6 == NULL);
4084
4085 /* new prefix mask. */
4086 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
4087 ifra.ifra_prefixmask.sin6_family = AF_INET6;
4088 bcopy(src: &mask, dst: &ifra.ifra_prefixmask.sin6_addr,
4089 n: sizeof(ifra.ifra_prefixmask.sin6_addr));
4090
4091 /* lifetimes. */
4092 ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
4093 ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
4094
4095 /* address flags */
4096 ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
4097
4098 /*
4099 * Make sure that we do not have this address already. This should
4100 * usually not happen, but we can still see this case, e.g., if we
4101 * have manually configured the exact address to be configured.
4102 */
4103 if ((ia6 = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr))
4104 != NULL) {
4105 error = EEXIST;
4106 ifa_remref(ifa: &ia6->ia_ifa);
4107 ia6 = NULL;
4108
4109 /* this should be rare enough to make an explicit log */
4110 log(LOG_INFO, "%s: %s is already configured!\n",
4111 __func__, ip6_sprintf(&ifra.ifra_addr.sin6_addr));
4112 goto done;
4113 }
4114
4115 /*
4116 * Allocate ifaddr structure, link into chain, etc.
4117 * If we are going to create a new address upon receiving a multicasted
4118 * RA, we need to impose a random delay before starting DAD.
4119 * [RFC 4862, Section 5.4.2]
4120 */
4121 ifaupdate = IN6_IFAUPDATE_NOWAIT;
4122 if (mcast) {
4123 ifaupdate |= IN6_IFAUPDATE_DADDELAY;
4124 }
4125 error = in6_update_ifa(ifp, &ifra, ifaupdate, &ia6);
4126 if (error != 0) {
4127 nd6log(error,
4128 "%s: failed to make ifaddr %s on %s (errno=%d)\n",
4129 __func__, ip6_sprintf(&ifra.ifra_addr.sin6_addr),
4130 if_name(ifp), error);
4131 error = EADDRNOTAVAIL;
4132 goto done;
4133 } else {
4134 /* remember the collision count */
4135 ia6->ia6_cga_collision_count = collision_count;
4136 }
4137
4138 VERIFY(ia6 != NULL);
4139 in6_post_msg(ifp, KEV_INET6_NEW_RTADV_ADDR, ia6, NULL);
4140 goto done;
4141
4142unlock1:
4143 NDPR_UNLOCK(pr);
4144
4145done:
4146 *errorp = error;
4147 return ia6;
4148}
4149
4150#define IA6_NONCONST(i) ((struct in6_ifaddr *)(uintptr_t)(i))
4151
4152int
4153in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen)
4154{
4155 struct ifnet *ifp = ia0->ia_ifa.ifa_ifp;
4156 struct in6_ifaddr *ia, *newia;
4157 struct in6_aliasreq ifra;
4158 int i, error, ifaupdate;
4159 int trylimit = 3; /* XXX: adhoc value */
4160 u_int32_t randid[2];
4161 uint32_t vltime0, pltime0;
4162 uint64_t timenow = net_uptime();
4163 struct in6_addr addr;
4164 struct nd_prefix *ndpr;
4165
4166 bzero(s: &ifra, n: sizeof(ifra));
4167 strlcpy(dst: ifra.ifra_name, if_name(ifp), n: sizeof(ifra.ifra_name));
4168 IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
4169 ifra.ifra_addr = ia0->ia_addr;
4170 /* copy prefix mask */
4171 ifra.ifra_prefixmask = ia0->ia_prefixmask;
4172 /* clear the old IFID */
4173 for (i = 0; i < 4; i++) {
4174 ifra.ifra_addr.sin6_addr.s6_addr32[i]
4175 &= ifra.ifra_prefixmask.sin6_addr.s6_addr32[i];
4176 }
4177 addr = ia0->ia_addr.sin6_addr;
4178 IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4179
4180again:
4181 in6_iid_mktmp(ifp, (u_int8_t *)randid,
4182 (const u_int8_t *)&addr.s6_addr[8], forcegen);
4183
4184 ifra.ifra_addr.sin6_addr.s6_addr32[2] |=
4185 (randid[0] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[2]));
4186 ifra.ifra_addr.sin6_addr.s6_addr32[3] |=
4187 (randid[1] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[3]));
4188
4189 /*
4190 * in6_iid_mktmp() quite likely provided a unique interface ID.
4191 * However, we may still have a chance to see collision, because
4192 * there may be a time lag between generation of the ID and generation
4193 * of the address. So, we'll do one more sanity check.
4194 */
4195 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr)) != NULL) {
4196 ifa_remref(ifa: &ia->ia_ifa);
4197 if (trylimit-- == 0) {
4198 nd6log(info, "in6_tmpifadd: failed to find "
4199 "a unique random IFID\n");
4200 return EEXIST;
4201 }
4202 forcegen = 1;
4203 goto again;
4204 }
4205
4206 /*
4207 * The Valid Lifetime is the lower of the Valid Lifetime of the
4208 * public address or TEMP_VALID_LIFETIME.
4209 * The Preferred Lifetime is the lower of the Preferred Lifetime
4210 * of the public address or TEMP_PREFERRED_LIFETIME -
4211 * DESYNC_FACTOR.
4212 */
4213 IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
4214 if (ia0->ia6_lifetime.ia6ti_vltime != ND6_INFINITE_LIFETIME) {
4215 vltime0 = IFA6_IS_INVALID(ia0, timenow) ? 0 :
4216 (ia0->ia6_lifetime.ia6ti_vltime -
4217 (uint32_t)(timenow - ia0->ia6_updatetime));
4218 if (vltime0 > ip6_temp_valid_lifetime) {
4219 vltime0 = ip6_temp_valid_lifetime;
4220 }
4221 } else {
4222 vltime0 = ip6_temp_valid_lifetime;
4223 }
4224 if (ia0->ia6_lifetime.ia6ti_pltime != ND6_INFINITE_LIFETIME) {
4225 pltime0 = IFA6_IS_DEPRECATED(ia0, timenow) ? 0 :
4226 (ia0->ia6_lifetime.ia6ti_pltime -
4227 (uint32_t)(timenow - ia0->ia6_updatetime));
4228 if (pltime0 > ip6_temp_preferred_lifetime - ip6_desync_factor) {
4229 pltime0 = ip6_temp_preferred_lifetime -
4230 ip6_desync_factor;
4231 }
4232 } else {
4233 pltime0 = ip6_temp_preferred_lifetime - ip6_desync_factor;
4234 }
4235 ifra.ifra_lifetime.ia6t_vltime = vltime0;
4236 ifra.ifra_lifetime.ia6t_pltime = pltime0;
4237 IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4238 /*
4239 * A temporary address is created only if this calculated Preferred
4240 * Lifetime is greater than REGEN_ADVANCE time units.
4241 */
4242 if (ifra.ifra_lifetime.ia6t_pltime <= ip6_temp_regen_advance) {
4243 return 0;
4244 }
4245
4246 /* XXX: scope zone ID? */
4247
4248 ifra.ifra_flags |= (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY);
4249
4250 /* allocate ifaddr structure, link into chain, etc. */
4251 ifaupdate = IN6_IFAUPDATE_NOWAIT | IN6_IFAUPDATE_DADDELAY;
4252 error = in6_update_ifa(ifp, &ifra, ifaupdate, &newia);
4253 if (error != 0) {
4254 nd6log(error, "in6_tmpifadd: failed to add address.\n");
4255 return error;
4256 }
4257 VERIFY(newia != NULL);
4258
4259 IFA_LOCK(&IA6_NONCONST(ia0)->ia_ifa);
4260 ndpr = ia0->ia6_ndpr;
4261 if (ndpr == NULL) {
4262 /*
4263 * We lost the race with another thread that has purged
4264 * ia0 address; in this case, purge the tmp addr as well.
4265 */
4266 nd6log(error, "in6_tmpifadd: no public address\n");
4267 VERIFY(!(ia0->ia6_flags & IN6_IFF_AUTOCONF));
4268 IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4269 in6_purgeaddr(&newia->ia_ifa);
4270 ifa_remref(ifa: &newia->ia_ifa);
4271 return EADDRNOTAVAIL;
4272 }
4273 NDPR_ADDREF(ndpr); /* for us */
4274 IFA_UNLOCK(&IA6_NONCONST(ia0)->ia_ifa);
4275 IFA_LOCK(&newia->ia_ifa);
4276 if (newia->ia6_ndpr != NULL) {
4277 NDPR_LOCK(newia->ia6_ndpr);
4278 VERIFY(newia->ia6_ndpr->ndpr_addrcnt != 0);
4279 newia->ia6_ndpr->ndpr_addrcnt--;
4280 NDPR_UNLOCK(newia->ia6_ndpr);
4281 NDPR_REMREF(newia->ia6_ndpr); /* release addr reference */
4282 }
4283 newia->ia6_ndpr = ndpr;
4284 NDPR_LOCK(newia->ia6_ndpr);
4285 newia->ia6_ndpr->ndpr_addrcnt++;
4286 VERIFY(newia->ia6_ndpr->ndpr_addrcnt != 0);
4287 NDPR_ADDREF(newia->ia6_ndpr); /* for addr reference */
4288 NDPR_UNLOCK(newia->ia6_ndpr);
4289 IFA_UNLOCK(&newia->ia_ifa);
4290 /*
4291 * A newly added address might affect the status of other addresses.
4292 * XXX: when the temporary address is generated with a new public
4293 * address, the onlink check is redundant. However, it would be safe
4294 * to do the check explicitly everywhere a new address is generated,
4295 * and, in fact, we surely need the check when we create a new
4296 * temporary address due to deprecation of an old temporary address.
4297 */
4298 lck_mtx_lock(nd6_mutex);
4299 pfxlist_onlink_check();
4300 lck_mtx_unlock(nd6_mutex);
4301 ifa_remref(ifa: &newia->ia_ifa);
4302
4303 /* remove our reference */
4304 NDPR_REMREF(ndpr);
4305
4306 return 0;
4307}
4308#undef IA6_NONCONST
4309
4310int
4311in6_init_prefix_ltimes(struct nd_prefix *ndpr)
4312{
4313 struct timeval caltime;
4314 u_int64_t timenow = net_uptime();
4315
4316 NDPR_LOCK_ASSERT_HELD(ndpr);
4317
4318 getmicrotime(&caltime);
4319 ndpr->ndpr_base_calendartime = caltime.tv_sec;
4320 ndpr->ndpr_base_uptime = timenow;
4321
4322 /* check if preferred lifetime > valid lifetime. RFC 4862 5.5.3 (c) */
4323 if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) {
4324 nd6log(info, "in6_init_prefix_ltimes: preferred lifetime"
4325 "(%d) is greater than valid lifetime(%d)\n",
4326 (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime);
4327 return EINVAL;
4328 }
4329 if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME) {
4330 ndpr->ndpr_preferred = 0;
4331 } else {
4332 ndpr->ndpr_preferred = timenow + ndpr->ndpr_pltime;
4333 }
4334 if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME) {
4335 ndpr->ndpr_expire = 0;
4336 } else {
4337 ndpr->ndpr_expire = timenow + ndpr->ndpr_vltime;
4338 }
4339
4340 return 0;
4341}
4342
4343static void
4344in6_init_address_ltimes(struct in6_addrlifetime *lt6)
4345{
4346 uint64_t timenow = net_uptime();
4347
4348 /* Valid lifetime must not be updated unless explicitly specified. */
4349 /* init ia6t_expire */
4350 if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME) {
4351 lt6->ia6t_expire = 0;
4352 } else {
4353 lt6->ia6t_expire = timenow;
4354 lt6->ia6t_expire += lt6->ia6t_vltime;
4355 }
4356
4357 /* init ia6t_preferred */
4358 if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME) {
4359 lt6->ia6t_preferred = 0;
4360 } else {
4361 lt6->ia6t_preferred = timenow;
4362 lt6->ia6t_preferred += lt6->ia6t_pltime;
4363 }
4364}
4365
4366/*
4367 * Delete all the routing table entries that use the specified gateway.
4368 * XXX: this function causes search through all entries of routing table, so
4369 * it shouldn't be called when acting as a router.
4370 *
4371 * This should really be working on entries that have a specific
4372 * parent route.
4373 */
4374void
4375rt6_flush(
4376 struct in6_addr *gateway,
4377 struct ifnet *ifp)
4378{
4379 struct radix_node_head *rnh = rt_tables[AF_INET6];
4380
4381 /* We'll care only link-local addresses */
4382 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) {
4383 return;
4384 }
4385 lck_mtx_lock(rnh_lock);
4386 /* XXX: hack for KAME's link-local address kludge */
4387 if (in6_embedded_scope) {
4388 gateway->s6_addr16[1] = htons(ifp->if_index);
4389 }
4390
4391 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway);
4392 lck_mtx_unlock(rnh_lock);
4393}
4394
4395static int
4396rt6_deleteroute(
4397 struct radix_node *rn,
4398 void *arg)
4399{
4400 struct rtentry *rt = (struct rtentry *)rn;
4401 struct in6_addr *gate = (struct in6_addr *)arg;
4402
4403 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
4404
4405 RT_LOCK(rt);
4406 if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) {
4407 RT_UNLOCK(rt);
4408 return 0;
4409 }
4410
4411 if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) {
4412 RT_UNLOCK(rt);
4413 return 0;
4414 }
4415 /*
4416 * Do not delete a static route.
4417 * XXX: this seems to be a bit ad-hoc. Should we consider the
4418 * 'cloned' bit instead?
4419 */
4420 if ((rt->rt_flags & RTF_STATIC) != 0) {
4421 RT_UNLOCK(rt);
4422 return 0;
4423 }
4424 /*
4425 * We delete only host route. This means, in particular, we don't
4426 * delete default route.
4427 */
4428 if ((rt->rt_flags & RTF_HOST) == 0) {
4429 RT_UNLOCK(rt);
4430 return 0;
4431 }
4432
4433 /*
4434 * Safe to drop rt_lock and use rt_key, rt_gateway, since holding
4435 * rnh_lock here prevents another thread from calling rt_setgate()
4436 * on this route.
4437 */
4438 RT_UNLOCK(rt);
4439 return rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
4440 rt_mask(rt), rt->rt_flags, 0);
4441}
4442
4443int
4444nd6_setdefaultiface(
4445 int ifindex)
4446{
4447 int error = 0;
4448 ifnet_t def_ifp = NULL;
4449
4450 LCK_MTX_ASSERT(nd6_mutex, LCK_MTX_ASSERT_NOTOWNED);
4451
4452 ifnet_head_lock_shared();
4453 if (!IF_INDEX_IN_RANGE(ifindex)) {
4454 ifnet_head_done();
4455 return EINVAL;
4456 }
4457 def_ifp = ifindex2ifnet[ifindex];
4458 ifnet_head_done();
4459
4460 lck_mtx_lock(nd6_mutex);
4461 if (nd6_defifindex != ifindex) {
4462 struct ifnet *odef_ifp = nd6_defifp;
4463
4464 nd6_defifindex = ifindex;
4465 if (nd6_defifindex > 0) {
4466 nd6_defifp = def_ifp;
4467 } else {
4468 nd6_defifp = NULL;
4469 }
4470
4471 if (nd6_defifp != NULL) {
4472 nd6log(info, "%s: is now the default "
4473 "interface (was %s)\n", if_name(nd6_defifp),
4474 odef_ifp != NULL ? if_name(odef_ifp) : "NONE");
4475 } else {
4476 nd6log(info, "No default interface set\n");
4477 }
4478
4479 /*
4480 * If the Default Router List is empty, install a route
4481 * to the specified interface as default or remove the default
4482 * route when the default interface becomes canceled.
4483 * The check for the queue is actually redundant, but
4484 * we do this here to avoid re-install the default route
4485 * if the list is NOT empty.
4486 */
4487 if (odef_ifp != NULL) {
4488 defrouter_select(ifp: odef_ifp, NULL);
4489 }
4490
4491 if (nd6_defifp != NULL) {
4492 defrouter_select(ifp: nd6_defifp, NULL);
4493 nd6_prefix_sync(ifp: nd6_defifp);
4494 }
4495
4496 /*
4497 * XXX For now we managed RTI routes as un-scoped.
4498 * Therefore we ignore the change in nd6_defifindex
4499 * for RTI routes for now.
4500 */
4501 /*
4502 * Our current implementation assumes one-to-one mapping between
4503 * interfaces and links, so it would be natural to use the
4504 * default interface as the default link.
4505 */
4506 scope6_setdefault(nd6_defifp);
4507 }
4508 lck_mtx_unlock(nd6_mutex);
4509 return error;
4510}
4511