]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/nd6_rtr.c
xnu-1456.1.26.tar.gz
[apple/xnu.git] / bsd / netinet6 / nd6_rtr.c
1 /*
2 * Copyright (c) 2003-2008 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 /* $FreeBSD: src/sys/netinet6/nd6_rtr.c,v 1.11 2002/04/19 04:46:23 suz Exp $ */
30 /* $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $ */
31
32 /*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 */
60
61
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/malloc.h>
65 #include <sys/mbuf.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
68 #include <sys/time.h>
69 #include <sys/kernel.h>
70 #include <sys/errno.h>
71 #include <sys/syslog.h>
72 #include <sys/queue.h>
73 #include <kern/lock.h>
74
75 #include <net/if.h>
76 #include <net/if_types.h>
77 #include <net/if_dl.h>
78 #include <net/route.h>
79 #include <net/radix.h>
80
81 #include <netinet/in.h>
82 #include <netinet6/in6_var.h>
83 #include <netinet6/in6_ifattach.h>
84 #include <netinet/ip6.h>
85 #include <netinet6/ip6_var.h>
86 #include <netinet6/nd6.h>
87 #include <netinet/icmp6.h>
88 #include <netinet6/scope6_var.h>
89
90 #include <net/net_osdep.h>
91
92 #define SDL(s) ((struct sockaddr_dl *)s)
93
94 static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
95 static struct in6_ifaddr *in6_ifadd(struct nd_prefix *,
96 struct in6_addr *);
97 static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *,
98 struct nd_defrouter *);
99 static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *);
100 static void pfxrtr_del(struct nd_pfxrouter *);
101 static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *);
102 static void defrouter_addifreq(struct ifnet *);
103 static void nd6_rtmsg(int, struct rtentry *);
104
105 static void in6_init_address_ltimes(struct nd_prefix *ndpr,
106 struct in6_addrlifetime *lt6);
107
108 static int rt6_deleteroute(struct radix_node *, void *);
109
110 extern int nd6_recalc_reachtm_interval;
111
112 static struct ifnet *nd6_defifp;
113 int nd6_defifindex;
114
115 int ip6_use_tempaddr = 0;
116
117 int ip6_desync_factor;
118 u_int32_t ip6_temp_preferred_lifetime = DEF_TEMP_PREFERRED_LIFETIME;
119 u_int32_t ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME;
120 /*
121 * shorter lifetimes for debugging purposes.
122 int ip6_temp_preferred_lifetime = 800;
123 static int ip6_temp_valid_lifetime = 1800;
124 */
125 int ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE;
126
127 extern lck_mtx_t *nd6_mutex;
128
129 /*
130 * Receive Router Solicitation Message - just for routers.
131 * Router solicitation/advertisement is mostly managed by userland program
132 * (rtadvd) so here we have no function like nd6_ra_output().
133 *
134 * Based on RFC 2461
135 */
136 void
137 nd6_rs_input(
138 struct mbuf *m,
139 int off,
140 int icmp6len)
141 {
142 struct ifnet *ifp = m->m_pkthdr.rcvif;
143 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
144 struct nd_router_solicit *nd_rs;
145 struct in6_addr saddr6 = ip6->ip6_src;
146 #if 0
147 struct in6_addr daddr6 = ip6->ip6_dst;
148 #endif
149 char *lladdr = NULL;
150 int lladdrlen = 0;
151 #if 0
152 struct sockaddr_dl *sdl = (struct sockaddr_dl *)NULL;
153 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)NULL;
154 struct rtentry *rt = NULL;
155 int is_newentry;
156 #endif
157 union nd_opts ndopts;
158
159 /* If I'm not a router, ignore it. */
160 if (ip6_accept_rtadv != 0 || (ifp->if_eflags & IFEF_ACCEPT_RTADVD) || ip6_forwarding != 1)
161 goto freeit;
162
163 /* Sanity checks */
164 if (ip6->ip6_hlim != 255) {
165 nd6log((LOG_ERR,
166 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n",
167 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
168 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
169 goto bad;
170 }
171
172 /*
173 * Don't update the neighbor cache, if src = ::.
174 * This indicates that the src has no IP address assigned yet.
175 */
176 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
177 goto freeit;
178
179 #ifndef PULLDOWN_TEST
180 IP6_EXTHDR_CHECK(m, off, icmp6len, return);
181 nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
182 #else
183 IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len);
184 if (nd_rs == NULL) {
185 icmp6stat.icp6s_tooshort++;
186 return;
187 }
188 #endif
189
190 icmp6len -= sizeof(*nd_rs);
191 nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
192 if (nd6_options(&ndopts) < 0) {
193 nd6log((LOG_INFO,
194 "nd6_rs_input: invalid ND option, ignored\n"));
195 /* nd6_options have incremented stats */
196 goto freeit;
197 }
198
199 if (ndopts.nd_opts_src_lladdr) {
200 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
201 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
202 }
203
204 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
205 nd6log((LOG_INFO,
206 "nd6_rs_input: lladdrlen mismatch for %s "
207 "(if %d, RS packet %d)\n",
208 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
209 goto bad;
210 }
211
212 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0);
213
214 freeit:
215 m_freem(m);
216 return;
217
218 bad:
219 icmp6stat.icp6s_badrs++;
220 m_freem(m);
221 }
222
223 /*
224 * Receive Router Advertisement Message.
225 *
226 * Based on RFC 2461
227 * TODO: on-link bit on prefix information
228 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing
229 */
230 void
231 nd6_ra_input(
232 struct mbuf *m,
233 int off,
234 int icmp6len)
235 {
236 struct ifnet *ifp = m->m_pkthdr.rcvif;
237 struct nd_ifinfo *ndi = NULL;
238 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
239 struct nd_router_advert *nd_ra;
240 struct in6_addr saddr6 = ip6->ip6_src;
241 #if 0
242 struct in6_addr daddr6 = ip6->ip6_dst;
243 int flags; /* = nd_ra->nd_ra_flags_reserved; */
244 int is_managed = ((flags & ND_RA_FLAG_MANAGED) != 0);
245 int is_other = ((flags & ND_RA_FLAG_OTHER) != 0);
246 #endif
247 union nd_opts ndopts;
248 struct nd_defrouter *dr;
249 struct timeval timenow;
250
251 getmicrotime(&timenow);
252
253 if (ip6_accept_rtadv == 0 && ((ifp->if_eflags & IFEF_ACCEPT_RTADVD) == 0))
254 goto freeit;
255
256 if (ip6->ip6_hlim != 255) {
257 nd6log((LOG_ERR,
258 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n",
259 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src),
260 ip6_sprintf(&ip6->ip6_dst), if_name(ifp)));
261 goto bad;
262 }
263
264 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
265 nd6log((LOG_ERR,
266 "nd6_ra_input: src %s is not link-local\n",
267 ip6_sprintf(&saddr6)));
268 goto bad;
269 }
270
271 #ifndef PULLDOWN_TEST
272 IP6_EXTHDR_CHECK(m, off, icmp6len, return);
273 nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
274 #else
275 IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len);
276 if (nd_ra == NULL) {
277 icmp6stat.icp6s_tooshort++;
278 return;
279 }
280 #endif
281
282 icmp6len -= sizeof(*nd_ra);
283 nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
284 if (nd6_options(&ndopts) < 0) {
285 nd6log((LOG_INFO,
286 "nd6_ra_input: invalid ND option, ignored\n"));
287 /* nd6_options have incremented stats */
288 goto freeit;
289 }
290
291 {
292 struct nd_defrouter dr0;
293 u_int32_t advreachable = nd_ra->nd_ra_reachable;
294
295 lck_rw_lock_shared(nd_if_rwlock);
296 if (ifp->if_index >= nd_ifinfo_indexlim) {
297 lck_rw_done(nd_if_rwlock);
298 goto freeit;
299 }
300 ndi = &nd_ifinfo[ifp->if_index];
301 dr0.rtaddr = saddr6;
302 dr0.flags = nd_ra->nd_ra_flags_reserved;
303 dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
304 dr0.expire = timenow.tv_sec + dr0.rtlifetime;
305 dr0.ifp = ifp;
306 dr0.advint = 0; /* Mobile IPv6 */
307 dr0.advint_expire = 0; /* Mobile IPv6 */
308 dr0.advints_lost = 0; /* Mobile IPv6 */
309 /* unspecified or not? (RFC 2461 6.3.4) */
310 if (advreachable) {
311 advreachable = ntohl(advreachable);
312 if (advreachable <= MAX_REACHABLE_TIME &&
313 ndi->basereachable != advreachable) {
314 ndi->basereachable = advreachable;
315 ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
316 ndi->recalctm = nd6_recalc_reachtm_interval; /* reset */
317 }
318 }
319 if (nd_ra->nd_ra_retransmit)
320 ndi->retrans = ntohl(nd_ra->nd_ra_retransmit);
321 if (nd_ra->nd_ra_curhoplimit)
322 ndi->chlim = nd_ra->nd_ra_curhoplimit;
323 lck_rw_done(nd_if_rwlock);
324 ndi = NULL;
325 dr = defrtrlist_update(&dr0);
326 }
327
328 /*
329 * prefix
330 */
331 if (ndopts.nd_opts_pi) {
332 struct nd_opt_hdr *pt;
333 struct nd_opt_prefix_info *pi = NULL;
334 struct nd_prefix pr;
335
336 for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi;
337 pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end;
338 pt = (struct nd_opt_hdr *)((caddr_t)pt +
339 (pt->nd_opt_len << 3))) {
340 if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION)
341 continue;
342 pi = (struct nd_opt_prefix_info *)pt;
343
344 if (pi->nd_opt_pi_len != 4) {
345 nd6log((LOG_INFO,
346 "nd6_ra_input: invalid option "
347 "len %d for prefix information option, "
348 "ignored\n", pi->nd_opt_pi_len));
349 continue;
350 }
351
352 if (128 < pi->nd_opt_pi_prefix_len) {
353 nd6log((LOG_INFO,
354 "nd6_ra_input: invalid prefix "
355 "len %d for prefix information option, "
356 "ignored\n", pi->nd_opt_pi_prefix_len));
357 continue;
358 }
359
360 if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix)
361 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) {
362 nd6log((LOG_INFO,
363 "nd6_ra_input: invalid prefix "
364 "%s, ignored\n",
365 ip6_sprintf(&pi->nd_opt_pi_prefix)));
366 continue;
367 }
368
369 /* aggregatable unicast address, rfc2374 */
370 if ((pi->nd_opt_pi_prefix.s6_addr8[0] & 0xe0) == 0x20
371 && pi->nd_opt_pi_prefix_len != 64) {
372 nd6log((LOG_INFO,
373 "nd6_ra_input: invalid prefixlen "
374 "%d for rfc2374 prefix %s, ignored\n",
375 pi->nd_opt_pi_prefix_len,
376 ip6_sprintf(&pi->nd_opt_pi_prefix)));
377 continue;
378 }
379
380 bzero(&pr, sizeof(pr));
381 pr.ndpr_prefix.sin6_family = AF_INET6;
382 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix);
383 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix;
384 pr.ndpr_ifp = m->m_pkthdr.rcvif;
385
386 pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved &
387 ND_OPT_PI_FLAG_ONLINK) ? 1 : 0;
388 pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved &
389 ND_OPT_PI_FLAG_AUTO) ? 1 : 0;
390 pr.ndpr_plen = pi->nd_opt_pi_prefix_len;
391 pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time);
392 pr.ndpr_pltime =
393 ntohl(pi->nd_opt_pi_preferred_time);
394
395 if (in6_init_prefix_ltimes(&pr))
396 continue; /* prefix lifetime init failed */
397
398 (void)prelist_update(&pr, dr, m);
399 }
400 }
401
402 /*
403 * MTU
404 */
405 if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) {
406 u_int32_t mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu);
407
408 /* lower bound */
409 if (mtu < IPV6_MMTU) {
410 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option "
411 "mtu=%d sent from %s, ignoring\n",
412 mtu, ip6_sprintf(&ip6->ip6_src)));
413 goto skip;
414 }
415
416 lck_rw_lock_shared(nd_if_rwlock);
417 if (ifp->if_index >= nd_ifinfo_indexlim) {
418 lck_rw_done(nd_if_rwlock);
419 goto freeit;
420 }
421 ndi = &nd_ifinfo[ifp->if_index];
422 /* upper bound */
423 if (ndi->maxmtu) {
424 if (mtu <= ndi->maxmtu) {
425 int change = (ndi->linkmtu != mtu);
426
427 ndi->linkmtu = mtu;
428 lck_rw_done(nd_if_rwlock);
429 if (change) /* in6_maxmtu may change */
430 in6_setmaxmtu();
431 } else {
432 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu "
433 "mtu=%d sent from %s; "
434 "exceeds maxmtu %d, ignoring\n",
435 mtu, ip6_sprintf(&ip6->ip6_src),
436 ndi->maxmtu));
437 lck_rw_done(nd_if_rwlock);
438 }
439 } else {
440 lck_rw_done(nd_if_rwlock);
441 nd6log((LOG_INFO, "nd6_ra_input: mtu option "
442 "mtu=%d sent from %s; maxmtu unknown, "
443 "ignoring\n",
444 mtu, ip6_sprintf(&ip6->ip6_src)));
445 }
446 ndi = NULL;
447 }
448
449 skip:
450
451 /*
452 * Source link layer address
453 */
454 {
455 char *lladdr = NULL;
456 int lladdrlen = 0;
457
458 if (ndopts.nd_opts_src_lladdr) {
459 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
460 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
461 }
462
463 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
464 nd6log((LOG_INFO,
465 "nd6_ra_input: lladdrlen mismatch for %s "
466 "(if %d, RA packet %d)\n",
467 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2));
468 goto bad;
469 }
470
471 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_ADVERT, 0);
472
473 /*
474 * Installing a link-layer address might change the state of the
475 * router's neighbor cache, which might also affect our on-link
476 * detection of adveritsed prefixes.
477 */
478 pfxlist_onlink_check(0);
479 }
480
481 freeit:
482 m_freem(m);
483 return;
484
485 bad:
486 icmp6stat.icp6s_badra++;
487 m_freem(m);
488 }
489
490 /*
491 * default router list proccessing sub routines
492 */
493
494 /* tell the change to user processes watching the routing socket. */
495 static void
496 nd6_rtmsg(cmd, rt)
497 int cmd;
498 struct rtentry *rt;
499 {
500 struct rt_addrinfo info;
501 struct ifnet *ifp = rt->rt_ifp;
502
503 RT_LOCK_ASSERT_HELD(rt);
504
505 bzero((caddr_t)&info, sizeof(info));
506 /* Lock ifp for if_addrlist */
507 ifnet_lock_shared(ifp);
508 info.rti_info[RTAX_DST] = rt_key(rt);
509 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
510 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
511 info.rti_info[RTAX_IFP] =
512 TAILQ_FIRST(&ifp->if_addrlist)->ifa_addr;
513 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
514
515 rt_missmsg(cmd, &info, rt->rt_flags, 0);
516 ifnet_lock_done(ifp);
517 }
518
519 void
520 defrouter_addreq(
521 struct nd_defrouter *new)
522 {
523 struct sockaddr_in6 def, mask, gate;
524 struct rtentry *newrt = NULL;
525
526 Bzero(&def, sizeof(def));
527 Bzero(&mask, sizeof(mask));
528 Bzero(&gate, sizeof(gate));
529
530 def.sin6_len = mask.sin6_len = gate.sin6_len
531 = sizeof(struct sockaddr_in6);
532 def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
533 gate.sin6_addr = new->rtaddr;
534
535 (void) rtrequest(RTM_ADD, (struct sockaddr *)&def,
536 (struct sockaddr *)&gate, (struct sockaddr *)&mask,
537 RTF_GATEWAY, &newrt);
538 if (newrt) {
539 RT_LOCK(newrt);
540 nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
541 RT_REMREF_LOCKED(newrt);
542 RT_UNLOCK(newrt);
543 }
544 return;
545 }
546
547 /* Add a route to a given interface as default */
548 void
549 defrouter_addifreq(
550 struct ifnet *ifp)
551 {
552 struct sockaddr_in6 def, mask;
553 struct ifaddr *ifa = NULL;
554 struct rtentry *newrt = NULL;
555 int error;
556 u_int32_t flags;
557
558 bzero(&def, sizeof(def));
559 bzero(&mask, sizeof(mask));
560
561 def.sin6_len = mask.sin6_len = sizeof(struct sockaddr_in6);
562 def.sin6_family = mask.sin6_family = AF_INET6;
563
564 /*
565 * Search for an ifaddr beloging to the specified interface.
566 * XXX: An IPv6 address are required to be assigned on the interface.
567 */
568 if ((ifa = ifaof_ifpforaddr((struct sockaddr *)&def, ifp)) == NULL) {
569 nd6log((LOG_ERR, /* better error? */
570 "defrouter_addifreq: failed to find an ifaddr "
571 "to install a route to interface %s\n",
572 if_name(ifp)));
573 return;
574 }
575
576 flags = ifa->ifa_flags;
577 error = rtrequest(RTM_ADD, (struct sockaddr *)&def, ifa->ifa_addr,
578 (struct sockaddr *)&mask, flags, &newrt);
579 if (error != 0) {
580 nd6log((LOG_ERR,
581 "defrouter_addifreq: failed to install a route to "
582 "interface %s (errno = %d)\n",
583 if_name(ifp), error));
584 } else {
585 if (newrt) {
586 RT_LOCK(newrt);
587 nd6_rtmsg(RTM_ADD, newrt);
588 RT_REMREF_LOCKED(newrt);
589 RT_UNLOCK(newrt);
590 }
591 in6_post_msg(ifp, KEV_INET6_DEFROUTER, (struct in6_ifaddr *)ifa);
592 }
593 ifafree(ifa);
594 }
595
596 struct nd_defrouter *
597 defrouter_lookup(
598 struct in6_addr *addr,
599 struct ifnet *ifp)
600 {
601 struct nd_defrouter *dr;
602
603
604 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
605
606 for (dr = TAILQ_FIRST(&nd_defrouter); dr;
607 dr = TAILQ_NEXT(dr, dr_entry)) {
608 if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr))
609 return(dr);
610 }
611
612 return(NULL); /* search failed */
613 }
614
615 void
616 defrouter_delreq(
617 struct nd_defrouter *dr,
618 int dofree)
619 {
620 struct sockaddr_in6 def, mask, gate;
621 struct rtentry *oldrt = NULL;
622
623 Bzero(&def, sizeof(def));
624 Bzero(&mask, sizeof(mask));
625 Bzero(&gate, sizeof(gate));
626
627 def.sin6_len = mask.sin6_len = gate.sin6_len
628 = sizeof(struct sockaddr_in6);
629 def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6;
630 gate.sin6_addr = dr->rtaddr;
631
632 (void) rtrequest(RTM_DELETE, (struct sockaddr *)&def,
633 (struct sockaddr *)&gate, (struct sockaddr *)&mask,
634 RTF_GATEWAY, &oldrt);
635 if (oldrt) {
636 RT_LOCK(oldrt);
637 nd6_rtmsg(RTM_DELETE, oldrt);
638 RT_UNLOCK(oldrt);
639 rtfree(oldrt);
640 }
641
642 if (dofree) /* XXX: necessary? */
643 FREE(dr, M_IP6NDP);
644 }
645
646 void
647 defrtrlist_del(
648 struct nd_defrouter *dr, int nd6locked)
649 {
650 struct nd_defrouter *deldr = NULL;
651 struct nd_prefix *pr;
652 struct ifnet *ifp = dr->ifp;
653
654 /*
655 * Flush all the routing table entries that use the router
656 * as a next hop.
657 */
658 if (!ip6_forwarding &&
659 (ip6_accept_rtadv || (ifp->if_eflags & IFEF_ACCEPT_RTADVD))) {
660 /* above is a good condition? */
661 rt6_flush(&dr->rtaddr, ifp);
662 }
663
664 if (nd6locked == 0)
665 lck_mtx_lock(nd6_mutex);
666 if (dr == TAILQ_FIRST(&nd_defrouter))
667 deldr = dr; /* The router is primary. */
668
669 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
670
671 /*
672 * Also delete all the pointers to the router in each prefix lists.
673 */
674 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
675 struct nd_pfxrouter *pfxrtr;
676 if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
677 pfxrtr_del(pfxrtr);
678 }
679 pfxlist_onlink_check(1);
680
681 /*
682 * If the router is the primary one, choose a new one.
683 * Note that defrouter_select() will remove the current gateway
684 * from the routing table.
685 */
686 if (deldr)
687 defrouter_select();
688
689 lck_rw_lock_shared(nd_if_rwlock);
690 if (ifp->if_index < nd_ifinfo_indexlim) {
691 struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
692 ndi->ndefrouters--;
693 if (ndi->ndefrouters < 0) {
694 log(LOG_WARNING, "defrtrlist_del: negative "
695 "count on %s\n", if_name(ifp));
696 }
697 }
698 lck_rw_done(nd_if_rwlock);
699
700 if (nd6locked == 0)
701 lck_mtx_unlock(nd6_mutex);
702
703 FREE(dr, M_IP6NDP);
704 }
705
706 /*
707 * Default Router Selection according to Section 6.3.6 of RFC 2461:
708 * 1) Routers that are reachable or probably reachable should be
709 * preferred.
710 * 2) When no routers on the list are known to be reachable or
711 * probably reachable, routers SHOULD be selected in a round-robin
712 * fashion.
713 * 3) If the Default Router List is empty, assume that all
714 * destinations are on-link.
715 */
716 void
717 defrouter_select()
718 {
719 struct nd_defrouter *dr, anydr;
720 struct rtentry *rt = NULL;
721 struct llinfo_nd6 *ln = NULL;
722
723 /*
724 * Search for a (probably) reachable router from the list.
725 */
726 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
727
728 for (dr = TAILQ_FIRST(&nd_defrouter); dr;
729 dr = TAILQ_NEXT(dr, dr_entry)) {
730 /* Callee returns a locked route upon success */
731 if ((rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp, 0)) != NULL) {
732 RT_LOCK_ASSERT_HELD(rt);
733 if ((ln = rt->rt_llinfo) != NULL &&
734 ND6_IS_LLINFO_PROBREACH(ln)) {
735 RT_REMREF_LOCKED(rt);
736 RT_UNLOCK(rt);
737 /* Got it, and move it to the head */
738 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry);
739 TAILQ_INSERT_HEAD(&nd_defrouter, dr, dr_entry);
740 break;
741 }
742 RT_REMREF_LOCKED(rt);
743 RT_UNLOCK(rt);
744 }
745 }
746
747 if ((dr = TAILQ_FIRST(&nd_defrouter))) {
748 /*
749 * De-install the previous default gateway and install
750 * a new one.
751 * Note that if there is no reachable router in the list,
752 * the head entry will be used anyway.
753 * XXX: do we have to check the current routing table entry?
754 */
755 bzero(&anydr, sizeof(anydr));
756 defrouter_delreq(&anydr, 0);
757 defrouter_addreq(dr);
758 }
759 else {
760 /*
761 * The Default Router List is empty, so install the default
762 * route to an inteface.
763 * XXX: The specification does not say this mechanism should
764 * be restricted to hosts, but this would be not useful
765 * (even harmful) for routers.
766 */
767 if (!ip6_forwarding) {
768 /*
769 * De-install the current default route
770 * in advance.
771 */
772 bzero(&anydr, sizeof(anydr));
773 defrouter_delreq(&anydr, 0);
774 if (nd6_defifp) {
775 /*
776 * Install a route to the default interface
777 * as default route.
778 * XXX: we enable this for host only, because
779 * this may override a default route installed
780 * a user process (e.g. routing daemon) in a
781 * router case.
782 */
783 defrouter_addifreq(nd6_defifp);
784 } else {
785 nd6log((LOG_INFO, "defrouter_select: "
786 "there's no default router and no default"
787 " interface\n"));
788 }
789 }
790 }
791
792 return;
793 }
794
795 static struct nd_defrouter *
796 defrtrlist_update(
797 struct nd_defrouter *new)
798 {
799 struct nd_defrouter *dr, *n;
800 struct ifnet *ifp = new->ifp;
801 struct nd_ifinfo *ndi;
802
803 lck_mtx_lock(nd6_mutex);
804 if ((dr = defrouter_lookup(&new->rtaddr, ifp)) != NULL) {
805 /* entry exists */
806 if (new->rtlifetime == 0) {
807 defrtrlist_del(dr, 1);
808 dr = NULL;
809 } else {
810 /* override */
811 dr->flags = new->flags; /* xxx flag check */
812 dr->rtlifetime = new->rtlifetime;
813 dr->expire = new->expire;
814 }
815 lck_mtx_unlock(nd6_mutex);
816 return(dr);
817 }
818
819 /* entry does not exist */
820 if (new->rtlifetime == 0) {
821 lck_mtx_unlock(nd6_mutex);
822 return(NULL);
823 }
824
825 n = (struct nd_defrouter *)_MALLOC(sizeof(*n), M_IP6NDP, M_NOWAIT);
826 if (n == NULL) {
827 lck_mtx_unlock(nd6_mutex);
828 return(NULL);
829 }
830
831 lck_rw_lock_shared(nd_if_rwlock);
832 if (ifp->if_index >= nd_ifinfo_indexlim)
833 goto freeit;
834 ndi = &nd_ifinfo[ifp->if_index];
835 if (ip6_maxifdefrouters >= 0 &&
836 ndi->ndefrouters >= ip6_maxifdefrouters) {
837 freeit:
838 lck_rw_done(nd_if_rwlock);
839 lck_mtx_unlock(nd6_mutex);
840 FREE(n, M_IP6NDP);
841 return (NULL);
842 }
843 ndi->ndefrouters++;
844 lck_rw_done(nd_if_rwlock);
845
846 bzero(n, sizeof(*n));
847 *n = *new;
848
849 /*
850 * Insert the new router at the end of the Default Router List.
851 * If there is no other router, install it anyway. Otherwise,
852 * just continue to use the current default router.
853 */
854 TAILQ_INSERT_TAIL(&nd_defrouter, n, dr_entry);
855 if (TAILQ_FIRST(&nd_defrouter) == n)
856 defrouter_select();
857
858 lck_mtx_unlock(nd6_mutex);
859 return(n);
860 }
861
862 static struct nd_pfxrouter *
863 pfxrtr_lookup(
864 struct nd_prefix *pr,
865 struct nd_defrouter *dr)
866 {
867 struct nd_pfxrouter *search;
868
869 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
870 for (search = pr->ndpr_advrtrs.lh_first; search; search = search->pfr_next) {
871 if (search->router == dr)
872 break;
873 }
874
875 return(search);
876 }
877
878 static void
879 pfxrtr_add(
880 struct nd_prefix *pr,
881 struct nd_defrouter *dr)
882 {
883 struct nd_pfxrouter *new;
884
885 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
886
887 new = (struct nd_pfxrouter *)_MALLOC(sizeof(*new), M_IP6NDP, M_NOWAIT);
888 if (new == NULL)
889 return;
890 bzero(new, sizeof(*new));
891 new->router = dr;
892
893 LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
894
895 pfxlist_onlink_check(1);
896 }
897
898 static void
899 pfxrtr_del(
900 struct nd_pfxrouter *pfr)
901 {
902 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
903 LIST_REMOVE(pfr, pfr_entry);
904 FREE(pfr, M_IP6NDP);
905 }
906
907 struct nd_prefix *
908 nd6_prefix_lookup(
909 struct nd_prefix *pr)
910 {
911 struct nd_prefix *search;
912
913 lck_mtx_lock(nd6_mutex);
914 for (search = nd_prefix.lh_first; search; search = search->ndpr_next) {
915 if (pr->ndpr_ifp == search->ndpr_ifp &&
916 pr->ndpr_plen == search->ndpr_plen &&
917 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
918 &search->ndpr_prefix.sin6_addr,
919 pr->ndpr_plen)
920 ) {
921 break;
922 }
923 }
924 if (search != NULL)
925 ndpr_hold(search, TRUE);
926 lck_mtx_unlock(nd6_mutex);
927
928 return(search);
929 }
930
931 void
932 ndpr_hold(struct nd_prefix *pr, boolean_t locked)
933 {
934 if (!locked)
935 lck_mtx_lock(nd6_mutex);
936
937 if (pr->ndpr_usecnt < 0)
938 panic("%s: bad usecnt %d for pr %p\n", __func__,
939 pr->ndpr_usecnt, pr);
940
941 pr->ndpr_usecnt++;
942
943 if (!locked)
944 lck_mtx_unlock(nd6_mutex);
945 }
946
947 void
948 ndpr_rele(struct nd_prefix *pr, boolean_t locked)
949 {
950 if (!locked)
951 lck_mtx_lock(nd6_mutex);
952
953 if (pr->ndpr_usecnt <= 0)
954 panic("%s: bad usecnt %d for pr %p\n", __func__,
955 pr->ndpr_usecnt, pr);
956
957 pr->ndpr_usecnt--;
958
959 if (!locked)
960 lck_mtx_unlock(nd6_mutex);
961 }
962
963 static void
964 purge_detached(struct ifnet *ifp)
965 {
966 struct nd_prefix *pr, *pr_next;
967 struct in6_ifaddr *ia;
968 struct ifaddr *ifa, *ifa_next;
969
970 lck_mtx_lock(nd6_mutex);
971
972 for (pr = nd_prefix.lh_first; pr; pr = pr_next) {
973 pr_next = pr->ndpr_next;
974 if (pr->ndpr_ifp != ifp ||
975 IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
976 ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
977 !LIST_EMPTY(&pr->ndpr_advrtrs)))
978 continue;
979 repeat:
980 ifnet_lock_shared(ifp);
981 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa_next) {
982 ifa_next = ifa->ifa_list.tqe_next;
983 if (ifa->ifa_addr->sa_family != AF_INET6)
984 continue;
985 ia = (struct in6_ifaddr *)ifa;
986 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) ==
987 IN6_IFF_AUTOCONF && ia->ia6_ndpr == pr) {
988 ifaref(ifa);
989 /*
990 * Purging the address requires writer access
991 * to the address list, so drop the ifnet lock
992 * now and repeat from beginning.
993 */
994 ifnet_lock_done(ifp);
995 in6_purgeaddr(ifa, 1);
996 ifafree(ifa);
997 goto repeat;
998 }
999 }
1000 ifnet_lock_done(ifp);
1001 if (pr->ndpr_refcnt == 0)
1002 prelist_remove(pr, 1);
1003 }
1004
1005 lck_mtx_unlock(nd6_mutex);
1006 }
1007
1008 int
1009 nd6_prelist_add(
1010 struct nd_prefix *pr,
1011 struct nd_defrouter *dr,
1012 struct nd_prefix **newp)
1013 {
1014 struct nd_prefix *new = NULL;
1015 struct ifnet *ifp = pr->ndpr_ifp;
1016 struct nd_ifinfo *ndi = NULL;
1017 int i;
1018
1019 if (ip6_maxifprefixes >= 0) {
1020 lck_rw_lock_shared(nd_if_rwlock);
1021 if (ifp->if_index >= nd_ifinfo_indexlim) {
1022 lck_rw_done(nd_if_rwlock);
1023 return (EINVAL);
1024 }
1025 ndi = &nd_ifinfo[ifp->if_index];
1026 if (ndi->nprefixes >= ip6_maxifprefixes / 2) {
1027 lck_rw_done(nd_if_rwlock);
1028 purge_detached(ifp);
1029 lck_rw_lock_shared(nd_if_rwlock);
1030 /*
1031 * Refresh pointer since nd_ifinfo[] may have grown;
1032 * repeating the bounds check against nd_ifinfo_indexlim
1033 * isn't necessary since the array never shrinks.
1034 */
1035 ndi = &nd_ifinfo[ifp->if_index];
1036 }
1037 if (ndi->nprefixes >= ip6_maxifprefixes) {
1038 lck_rw_done(nd_if_rwlock);
1039 return(ENOMEM);
1040 }
1041 lck_rw_done(nd_if_rwlock);
1042 }
1043
1044 new = (struct nd_prefix *)_MALLOC(sizeof(*new), M_IP6NDP, M_NOWAIT);
1045 if (new == NULL)
1046 return ENOMEM;
1047 bzero(new, sizeof(*new));
1048 *new = *pr;
1049 if (newp != NULL)
1050 *newp = new;
1051
1052 /* initilization */
1053 LIST_INIT(&new->ndpr_advrtrs);
1054 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen);
1055 /* make prefix in the canonical form */
1056 for (i = 0; i < 4; i++)
1057 new->ndpr_prefix.sin6_addr.s6_addr32[i] &=
1058 new->ndpr_mask.s6_addr32[i];
1059
1060 /* link ndpr_entry to nd_prefix list */
1061 lck_mtx_lock(nd6_mutex);
1062 LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry);
1063
1064 new->ndpr_usecnt = 0;
1065 ndpr_hold(new, TRUE);
1066
1067 /* ND_OPT_PI_FLAG_ONLINK processing */
1068 if (new->ndpr_raf_onlink) {
1069 int e;
1070
1071 if ((e = nd6_prefix_onlink(new, 0, 1)) != 0) {
1072 nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
1073 "the prefix %s/%d on-link on %s (errno=%d)\n",
1074 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1075 pr->ndpr_plen, if_name(ifp), e));
1076 /* proceed anyway. XXX: is it correct? */
1077 }
1078 }
1079
1080 if (dr) {
1081 pfxrtr_add(new, dr);
1082 }
1083
1084 lck_rw_lock_shared(nd_if_rwlock);
1085 /*
1086 * Refresh pointer since nd_ifinfo[] may have grown;
1087 * repeating the bounds check against nd_ifinfo_indexlim
1088 * isn't necessary since the array never shrinks.
1089 */
1090 ndi = &nd_ifinfo[ifp->if_index];
1091 ndi->nprefixes++;
1092 lck_rw_done(nd_if_rwlock);
1093
1094 lck_mtx_unlock(nd6_mutex);
1095
1096 return 0;
1097 }
1098
1099 void
1100 prelist_remove(
1101 struct nd_prefix *pr, int nd6locked)
1102 {
1103 struct nd_pfxrouter *pfr, *next;
1104 struct ifnet *ifp = pr->ndpr_ifp;
1105 int e;
1106
1107 /* make sure to invalidate the prefix until it is really freed. */
1108 pr->ndpr_vltime = 0;
1109 pr->ndpr_pltime = 0;
1110 #if 0
1111 /*
1112 * Though these flags are now meaningless, we'd rather keep the value
1113 * not to confuse users when executing "ndp -p".
1114 */
1115 pr->ndpr_raf_onlink = 0;
1116 pr->ndpr_raf_auto = 0;
1117 #endif
1118 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 &&
1119 (e = nd6_prefix_offlink(pr)) != 0) {
1120 nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink "
1121 "on %s, errno=%d\n",
1122 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1123 pr->ndpr_plen, if_name(ifp), e));
1124 /* what should we do? */
1125 }
1126
1127 if (nd6locked == 0)
1128 lck_mtx_lock(nd6_mutex);
1129
1130 if (pr->ndpr_usecnt > 0 || pr->ndpr_refcnt > 0)
1131 goto done; /* notice here? */
1132
1133 /* unlink ndpr_entry from nd_prefix list */
1134 LIST_REMOVE(pr, ndpr_entry);
1135
1136 /* free list of routers that adversed the prefix */
1137 for (pfr = pr->ndpr_advrtrs.lh_first; pfr; pfr = next) {
1138 next = pfr->pfr_next;
1139
1140 FREE(pfr, M_IP6NDP);
1141 }
1142
1143 lck_rw_lock_shared(nd_if_rwlock);
1144 if (ifp->if_index < nd_ifinfo_indexlim) {
1145 struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
1146 ndi->nprefixes--;
1147 if (ndi->nprefixes < 0) {
1148 log(LOG_WARNING, "prelist_remove: negative "
1149 "count on %s\n", if_name(ifp));
1150 }
1151 }
1152 lck_rw_done(nd_if_rwlock);
1153
1154 FREE(pr, M_IP6NDP);
1155
1156 pfxlist_onlink_check(1);
1157 done:
1158 if (nd6locked == 0)
1159 lck_mtx_unlock(nd6_mutex);
1160 }
1161
1162 int
1163 prelist_update(
1164 struct nd_prefix *new,
1165 struct nd_defrouter *dr, /* may be NULL */
1166 struct mbuf *m)
1167 {
1168 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
1169 struct ifaddr *ifa;
1170 struct ifnet *ifp = new->ndpr_ifp;
1171 struct nd_prefix *pr;
1172 int error = 0;
1173 int newprefix = 0;
1174 int auth;
1175 struct in6_addrlifetime lt6_tmp;
1176 struct timeval timenow;
1177
1178 auth = 0;
1179 if (m) {
1180 /*
1181 * Authenticity for NA consists authentication for
1182 * both IP header and IP datagrams, doesn't it ?
1183 */
1184 #if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM)
1185 auth = (m->m_flags & M_AUTHIPHDR
1186 && m->m_flags & M_AUTHIPDGM) ? 1 : 0;
1187 #endif
1188 }
1189
1190
1191 if ((pr = nd6_prefix_lookup(new)) != NULL) {
1192 /*
1193 * nd6_prefix_lookup() ensures that pr and new have the same
1194 * prefix on a same interface.
1195 */
1196
1197 /*
1198 * Update prefix information. Note that the on-link (L) bit
1199 * and the autonomous (A) bit should NOT be changed from 1
1200 * to 0.
1201 */
1202 if (new->ndpr_raf_onlink == 1)
1203 pr->ndpr_raf_onlink = 1;
1204 if (new->ndpr_raf_auto == 1)
1205 pr->ndpr_raf_auto = 1;
1206 if (new->ndpr_raf_onlink) {
1207 pr->ndpr_vltime = new->ndpr_vltime;
1208 pr->ndpr_pltime = new->ndpr_pltime;
1209 pr->ndpr_preferred = new->ndpr_preferred;
1210 pr->ndpr_expire = new->ndpr_expire;
1211 }
1212
1213 if (new->ndpr_raf_onlink &&
1214 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
1215 int e;
1216
1217 if ((e = nd6_prefix_onlink(pr, 0, 0)) != 0) {
1218 nd6log((LOG_ERR,
1219 "prelist_update: failed to make "
1220 "the prefix %s/%d on-link on %s "
1221 "(errno=%d)\n",
1222 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1223 pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
1224 /* proceed anyway. XXX: is it correct? */
1225 }
1226 }
1227
1228 lck_mtx_lock(nd6_mutex);
1229 if (dr && pfxrtr_lookup(pr, dr) == NULL)
1230 pfxrtr_add(pr, dr);
1231 lck_mtx_unlock(nd6_mutex);
1232 } else {
1233 struct nd_prefix *newpr = NULL;
1234
1235 newprefix = 1;
1236
1237 if (new->ndpr_vltime == 0)
1238 goto end;
1239 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0)
1240 goto end;
1241
1242 bzero(&new->ndpr_addr, sizeof(struct in6_addr));
1243
1244 error = nd6_prelist_add(new, dr, &newpr);
1245 if (error != 0 || newpr == NULL) {
1246 nd6log((LOG_NOTICE, "prelist_update: "
1247 "nd6_prelist_add failed for %s/%d on %s "
1248 "errno=%d, returnpr=%p\n",
1249 ip6_sprintf(&new->ndpr_prefix.sin6_addr),
1250 new->ndpr_plen, if_name(new->ndpr_ifp),
1251 error, newpr));
1252 goto end; /* we should just give up in this case. */
1253 }
1254
1255 /*
1256 * XXX: from the ND point of view, we can ignore a prefix
1257 * with the on-link bit being zero. However, we need a
1258 * prefix structure for references from autoconfigured
1259 * addresses. Thus, we explicitly make suret that the prefix
1260 * itself expires now.
1261 */
1262 if (newpr->ndpr_raf_onlink == 0) {
1263 newpr->ndpr_vltime = 0;
1264 newpr->ndpr_pltime = 0;
1265 in6_init_prefix_ltimes(newpr);
1266 }
1267
1268 pr = newpr;
1269 }
1270
1271 /*
1272 * Address autoconfiguration based on Section 5.5.3 of RFC 2462.
1273 * Note that pr must be non NULL at this point.
1274 */
1275
1276 /* 5.5.3 (a). Ignore the prefix without the A bit set. */
1277 if (!new->ndpr_raf_auto)
1278 goto afteraddrconf;
1279
1280 /*
1281 * 5.5.3 (b). the link-local prefix should have been ignored in
1282 * nd6_ra_input.
1283 */
1284
1285 /*
1286 * 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime.
1287 * This should have been done in nd6_ra_input.
1288 */
1289
1290 /*
1291 * 5.5.3 (d). If the prefix advertised does not match the prefix of an
1292 * address already in the list, and the Valid Lifetime is not 0,
1293 * form an address. Note that even a manually configured address
1294 * should reject autoconfiguration of a new address.
1295 */
1296 getmicrotime(&timenow);
1297
1298 ifnet_lock_exclusive(ifp);
1299 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1300 {
1301 struct in6_ifaddr *ifa6;
1302 int ifa_plen;
1303 u_int32_t storedlifetime;
1304
1305 if (ifa->ifa_addr->sa_family != AF_INET6)
1306 continue;
1307
1308 ifa6 = (struct in6_ifaddr *)ifa;
1309
1310 /*
1311 * Spec is not clear here, but I believe we should concentrate
1312 * on unicast (i.e. not anycast) addresses.
1313 * XXX: other ia6_flags? detached or duplicated?
1314 */
1315 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0)
1316 continue;
1317
1318 ifa_plen = in6_mask2len(&ifa6->ia_prefixmask.sin6_addr, NULL);
1319 if (ifa_plen != new->ndpr_plen ||
1320 !in6_are_prefix_equal(&ifa6->ia_addr.sin6_addr,
1321 &new->ndpr_prefix.sin6_addr,
1322 ifa_plen))
1323 continue;
1324
1325 if (ia6_match == NULL) /* remember the first one */
1326 ia6_match = ifa6;
1327
1328 if ((ifa6->ia6_flags & IN6_IFF_AUTOCONF) == 0)
1329 continue;
1330
1331 /*
1332 * An already autoconfigured address matched. Now that we
1333 * are sure there is at least one matched address, we can
1334 * proceed to 5.5.3. (e): update the lifetimes according to the
1335 * "two hours" rule and the privacy extension.
1336 */
1337 #define TWOHOUR (120*60)
1338 lt6_tmp = ifa6->ia6_lifetime;
1339
1340 storedlifetime = IFA6_IS_INVALID(ifa6) ? 0 :
1341 (lt6_tmp.ia6t_expire - timenow.tv_sec);
1342
1343 if (TWOHOUR < new->ndpr_vltime ||
1344 storedlifetime < new->ndpr_vltime) {
1345 lt6_tmp.ia6t_vltime = new->ndpr_vltime;
1346 } else if (storedlifetime <= TWOHOUR
1347 #if 0
1348 /*
1349 * This condition is logically redundant, so we just
1350 * omit it.
1351 * See IPng 6712, 6717, and 6721.
1352 */
1353 && new->ndpr_vltime <= storedlifetime
1354 #endif
1355 ) {
1356 if (auth) {
1357 lt6_tmp.ia6t_vltime = new->ndpr_vltime;
1358 }
1359 } else {
1360 /*
1361 * new->ndpr_vltime <= TWOHOUR &&
1362 * TWOHOUR < storedlifetime
1363 */
1364 lt6_tmp.ia6t_vltime = TWOHOUR;
1365 }
1366
1367 /* The 2 hour rule is not imposed for preferred lifetime. */
1368 lt6_tmp.ia6t_pltime = new->ndpr_pltime;
1369
1370 in6_init_address_ltimes(pr, &lt6_tmp);
1371
1372 /*
1373 * When adjusting the lifetimes of an existing temporary
1374 * address, only lower the lifetimes.
1375 * RFC 3041 3.3. (1).
1376 * XXX: how should we modify ia6t_[pv]ltime?
1377 */
1378 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
1379 if (lt6_tmp.ia6t_expire == 0 || /* no expire */
1380 lt6_tmp.ia6t_expire >
1381 ifa6->ia6_lifetime.ia6t_expire) {
1382 lt6_tmp.ia6t_expire =
1383 ifa6->ia6_lifetime.ia6t_expire;
1384 }
1385 if (lt6_tmp.ia6t_preferred == 0 || /* no expire */
1386 lt6_tmp.ia6t_preferred >
1387 ifa6->ia6_lifetime.ia6t_preferred) {
1388 lt6_tmp.ia6t_preferred =
1389 ifa6->ia6_lifetime.ia6t_preferred;
1390 }
1391 }
1392
1393 ifa6->ia6_lifetime = lt6_tmp;
1394 }
1395 ifnet_lock_done(ifp);
1396 if (ia6_match == NULL && new->ndpr_vltime) {
1397 /*
1398 * No address matched and the valid lifetime is non-zero.
1399 * Create a new address.
1400 */
1401 if ((ia6 = in6_ifadd(new, NULL)) != NULL) {
1402 /*
1403 * note that we should use pr (not new) for reference.
1404 */
1405 lck_mtx_lock(nd6_mutex);
1406 pr->ndpr_refcnt++;
1407 lck_mtx_unlock(nd6_mutex);
1408 ia6->ia6_ndpr = pr;
1409
1410 #if 0
1411 /* XXXYYY Don't do this, according to Jinmei. */
1412 pr->ndpr_addr = new->ndpr_addr;
1413 #endif
1414
1415 /*
1416 * RFC 3041 3.3 (2).
1417 * When a new public address is created as described
1418 * in RFC2462, also create a new temporary address.
1419 *
1420 * RFC 3041 3.5.
1421 * When an interface connects to a new link, a new
1422 * randomized interface identifier should be generated
1423 * immediately together with a new set of temporary
1424 * addresses. Thus, we specifiy 1 as the 2nd arg of
1425 * in6_tmpifadd().
1426 */
1427 if (ip6_use_tempaddr) {
1428 int e;
1429 if ((e = in6_tmpifadd(ia6, 1, M_NOWAIT)) != 0) {
1430 nd6log((LOG_NOTICE, "prelist_update: "
1431 "failed to create a temporary "
1432 "address, errno=%d\n",
1433 e));
1434 }
1435 }
1436 ifafree(&ia6->ia_ifa);
1437 ia6 = NULL;
1438
1439 /*
1440 * A newly added address might affect the status
1441 * of other addresses, so we check and update it.
1442 * XXX: what if address duplication happens?
1443 */
1444 pfxlist_onlink_check(0);
1445 } else {
1446 /* just set an error. do not bark here. */
1447 error = EADDRNOTAVAIL; /* XXX: might be unused. */
1448 }
1449 }
1450
1451 afteraddrconf:
1452
1453 end:
1454 if (pr != NULL)
1455 ndpr_rele(pr, FALSE);
1456
1457 return error;
1458 }
1459
1460 /*
1461 * A supplement function used in the on-link detection below;
1462 * detect if a given prefix has a (probably) reachable advertising router.
1463 * XXX: lengthy function name...
1464 */
1465 static struct nd_pfxrouter *
1466 find_pfxlist_reachable_router(
1467 struct nd_prefix *pr)
1468 {
1469 struct nd_pfxrouter *pfxrtr;
1470 struct rtentry *rt;
1471 struct llinfo_nd6 *ln;
1472
1473 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1474
1475 for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr;
1476 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) {
1477 /* Callee returns a locked route upon success */
1478 if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0,
1479 pfxrtr->router->ifp, 0)) != NULL) {
1480 RT_LOCK_ASSERT_HELD(rt);
1481 if ((ln = rt->rt_llinfo) != NULL &&
1482 ND6_IS_LLINFO_PROBREACH(ln)) {
1483 RT_REMREF_LOCKED(rt);
1484 RT_UNLOCK(rt);
1485 break; /* found */
1486 }
1487 RT_REMREF_LOCKED(rt);
1488 RT_UNLOCK(rt);
1489 }
1490 }
1491
1492 return(pfxrtr);
1493
1494 }
1495
1496 /*
1497 * Check if each prefix in the prefix list has at least one available router
1498 * that advertised the prefix (a router is "available" if its neighbor cache
1499 * entry is reachable or probably reachable).
1500 * If the check fails, the prefix may be off-link, because, for example,
1501 * we have moved from the network but the lifetime of the prefix has not
1502 * expired yet. So we should not use the prefix if there is another prefix
1503 * that has an available router.
1504 * But, if there is no prefix that has an available router, we still regards
1505 * all the prefixes as on-link. This is because we can't tell if all the
1506 * routers are simply dead or if we really moved from the network and there
1507 * is no router around us.
1508 */
1509 void
1510 pfxlist_onlink_check(int nd6locked)
1511 {
1512 struct nd_prefix *pr;
1513 struct in6_ifaddr *ifa;
1514
1515 /*
1516 * Check if there is a prefix that has a reachable advertising
1517 * router.
1518 */
1519 if (nd6locked == 0)
1520 lck_mtx_lock(nd6_mutex);
1521 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1522 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1523 if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr))
1524 break;
1525 }
1526
1527 if (pr) {
1528 /*
1529 * There is at least one prefix that has a reachable router.
1530 * Detach prefixes which have no reachable advertising
1531 * router, and attach other prefixes.
1532 */
1533 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1534 /* XXX: a link-local prefix should never be detached */
1535 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1536 continue;
1537
1538 /*
1539 * we aren't interested in prefixes without the L bit
1540 * set.
1541 */
1542 if (pr->ndpr_raf_onlink == 0)
1543 continue;
1544
1545 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
1546 find_pfxlist_reachable_router(pr) == NULL)
1547 pr->ndpr_stateflags |= NDPRF_DETACHED;
1548 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
1549 find_pfxlist_reachable_router(pr) != 0)
1550 pr->ndpr_stateflags &= ~NDPRF_DETACHED;
1551 }
1552 } else {
1553 /* there is no prefix that has a reachable router */
1554 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1555 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1556 continue;
1557
1558 if (pr->ndpr_raf_onlink == 0)
1559 continue;
1560
1561 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0)
1562 pr->ndpr_stateflags &= ~NDPRF_DETACHED;
1563 }
1564 }
1565
1566 /*
1567 * Remove each interface route associated with a (just) detached
1568 * prefix, and reinstall the interface route for a (just) attached
1569 * prefix. Note that all attempt of reinstallation does not
1570 * necessarily success, when a same prefix is shared among multiple
1571 * interfaces. Such cases will be handled in nd6_prefix_onlink,
1572 * so we don't have to care about them.
1573 */
1574 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) {
1575 int e;
1576
1577 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr))
1578 continue;
1579
1580 if (pr->ndpr_raf_onlink == 0)
1581 continue;
1582
1583 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
1584 (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
1585 if ((e = nd6_prefix_offlink(pr)) != 0) {
1586 nd6log((LOG_ERR,
1587 "pfxlist_onlink_check: failed to "
1588 "make %s/%d offlink, errno=%d\n",
1589 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1590 pr->ndpr_plen, e));
1591 }
1592 }
1593 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
1594 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 &&
1595 pr->ndpr_raf_onlink) {
1596 if ((e = nd6_prefix_onlink(pr, 0, 1)) != 0) {
1597 nd6log((LOG_ERR,
1598 "pfxlist_onlink_check: failed to "
1599 "make %s/%d offlink, errno=%d\n",
1600 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1601 pr->ndpr_plen, e));
1602 }
1603 }
1604 }
1605
1606 /*
1607 * Changes on the prefix status might affect address status as well.
1608 * Make sure that all addresses derived from an attached prefix are
1609 * attached, and that all addresses derived from a detached prefix are
1610 * detached. Note, however, that a manually configured address should
1611 * always be attached.
1612 * The precise detection logic is same as the one for prefixes.
1613 */
1614 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) {
1615 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
1616 continue;
1617
1618 if (ifa->ia6_ndpr == NULL) {
1619 /*
1620 * This can happen when we first configure the address
1621 * (i.e. the address exists, but the prefix does not).
1622 * XXX: complicated relationships...
1623 */
1624 continue;
1625 }
1626
1627 if (find_pfxlist_reachable_router(ifa->ia6_ndpr))
1628 break;
1629 }
1630 if (ifa) {
1631 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) {
1632 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
1633 continue;
1634
1635 if (ifa->ia6_ndpr == NULL) /* XXX: see above. */
1636 continue;
1637
1638 if (find_pfxlist_reachable_router(ifa->ia6_ndpr))
1639 ifa->ia6_flags &= ~IN6_IFF_DETACHED;
1640 else
1641 ifa->ia6_flags |= IN6_IFF_DETACHED;
1642 }
1643 }
1644 else {
1645 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) {
1646 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
1647 continue;
1648
1649 ifa->ia6_flags &= ~IN6_IFF_DETACHED;
1650 }
1651 }
1652 if (nd6locked == 0)
1653 lck_mtx_unlock(nd6_mutex);
1654 }
1655
1656 int
1657 nd6_prefix_onlink(
1658 struct nd_prefix *pr, int rtlocked, int nd6locked)
1659 {
1660 struct ifaddr *ifa;
1661 struct ifnet *ifp = pr->ndpr_ifp;
1662 struct sockaddr_in6 mask6;
1663 struct nd_prefix *opr;
1664 u_int32_t rtflags;
1665 int error = 0;
1666 struct rtentry *rt = NULL;
1667
1668 /* sanity check */
1669 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
1670 nd6log((LOG_ERR,
1671 "nd6_prefix_onlink: %s/%d is already on-link\n",
1672 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen);
1673 return(EEXIST));
1674 }
1675
1676 /*
1677 * Add the interface route associated with the prefix. Before
1678 * installing the route, check if there's the same prefix on another
1679 * interface, and the prefix has already installed the interface route.
1680 * Although such a configuration is expected to be rare, we explicitly
1681 * allow it.
1682 */
1683 if (nd6locked == 0)
1684 lck_mtx_lock(nd6_mutex);
1685 else
1686 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1687 for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) {
1688 if (opr == pr)
1689 continue;
1690
1691 if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0)
1692 continue;
1693
1694 if (opr->ndpr_plen == pr->ndpr_plen &&
1695 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
1696 &opr->ndpr_prefix.sin6_addr,
1697 pr->ndpr_plen)) {
1698 if (nd6locked == 0)
1699 lck_mtx_unlock(nd6_mutex);
1700 return(0);
1701 }
1702 }
1703
1704 if (nd6locked == 0)
1705 lck_mtx_unlock(nd6_mutex);
1706 /*
1707 * We prefer link-local addresses as the associated interface address.
1708 */
1709 /* search for a link-local addr */
1710 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
1711 IN6_IFF_NOTREADY|
1712 IN6_IFF_ANYCAST);
1713 if (ifa == NULL) {
1714 /* XXX: freebsd does not have ifa_ifwithaf */
1715 ifnet_lock_exclusive(ifp);
1716 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1717 {
1718 if (ifa->ifa_addr->sa_family == AF_INET6)
1719 break;
1720 }
1721 if (ifa != NULL)
1722 ifaref(ifa);
1723 ifnet_lock_done(ifp);
1724 /* should we care about ia6_flags? */
1725 }
1726 if (ifa == NULL) {
1727 /*
1728 * This can still happen, when, for example, we receive an RA
1729 * containing a prefix with the L bit set and the A bit clear,
1730 * after removing all IPv6 addresses on the receiving
1731 * interface. This should, of course, be rare though.
1732 */
1733 nd6log((LOG_NOTICE,
1734 "nd6_prefix_onlink: failed to find any ifaddr"
1735 " to add route for a prefix(%s/%d) on %s\n",
1736 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1737 pr->ndpr_plen, if_name(ifp)));
1738 return(0);
1739 }
1740
1741 /*
1742 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs.
1743 * ifa->ifa_rtrequest = nd6_rtrequest;
1744 */
1745 bzero(&mask6, sizeof(mask6));
1746 mask6.sin6_len = sizeof(mask6);
1747 mask6.sin6_addr = pr->ndpr_mask;
1748
1749 if (rtlocked == 0)
1750 lck_mtx_lock(rnh_lock);
1751
1752 rtflags = ifa->ifa_flags | RTF_CLONING | RTF_UP;
1753 if (nd6_need_cache(ifp)) {
1754 /* explicitly set in case ifa_flags does not set the flag. */
1755 rtflags |= RTF_CLONING;
1756 } else {
1757 /*
1758 * explicitly clear the cloning bit in case ifa_flags sets it.
1759 */
1760 rtflags &= ~RTF_CLONING;
1761 }
1762 error = rtrequest_locked(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix,
1763 ifa->ifa_addr, (struct sockaddr *)&mask6,
1764 rtflags, &rt);
1765 if (error == 0) {
1766 if (rt != NULL) { /* this should be non NULL, though */
1767 RT_LOCK(rt);
1768 nd6_rtmsg(RTM_ADD, rt);
1769 RT_UNLOCK(rt);
1770 }
1771 pr->ndpr_stateflags |= NDPRF_ONLINK;
1772 }
1773 else {
1774 nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a"
1775 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx "
1776 "errno = %d\n",
1777 ip6_sprintf(&pr->ndpr_prefix.sin6_addr),
1778 pr->ndpr_plen, if_name(ifp),
1779 ip6_sprintf(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr),
1780 ip6_sprintf(&mask6.sin6_addr), rtflags, error));
1781 }
1782
1783 if (rt != NULL)
1784 RT_REMREF(rt);
1785
1786 if (rtlocked == 0)
1787 lck_mtx_unlock(rnh_lock);
1788
1789 ifafree(ifa);
1790
1791 return(error);
1792 }
1793
1794 int
1795 nd6_prefix_offlink(
1796 struct nd_prefix *pr)
1797 {
1798 int error = 0;
1799 struct ifnet *ifp = pr->ndpr_ifp;
1800 struct nd_prefix *opr;
1801 struct sockaddr_in6 sa6, mask6;
1802 struct rtentry *rt = NULL;
1803
1804 /* sanity check */
1805 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
1806 nd6log((LOG_ERR,
1807 "nd6_prefix_offlink: %s/%d is already off-link\n",
1808 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen));
1809 return(EEXIST);
1810 }
1811
1812 bzero(&sa6, sizeof(sa6));
1813 sa6.sin6_family = AF_INET6;
1814 sa6.sin6_len = sizeof(sa6);
1815 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr,
1816 sizeof(struct in6_addr));
1817 bzero(&mask6, sizeof(mask6));
1818 mask6.sin6_family = AF_INET6;
1819 mask6.sin6_len = sizeof(sa6);
1820 bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr));
1821 lck_mtx_lock(rnh_lock);
1822 error = rtrequest_locked(RTM_DELETE, (struct sockaddr *)&sa6, NULL,
1823 (struct sockaddr *)&mask6, 0, &rt);
1824 if (error == 0) {
1825 pr->ndpr_stateflags &= ~NDPRF_ONLINK;
1826
1827 /* report the route deletion to the routing socket. */
1828 if (rt != NULL) {
1829 RT_LOCK(rt);
1830 nd6_rtmsg(RTM_DELETE, rt);
1831 RT_UNLOCK(rt);
1832 }
1833
1834 /*
1835 * There might be the same prefix on another interface,
1836 * the prefix which could not be on-link just because we have
1837 * the interface route (see comments in nd6_prefix_onlink).
1838 * If there's one, try to make the prefix on-link on the
1839 * interface.
1840 */
1841 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED);
1842 for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) {
1843 if (opr == pr)
1844 continue;
1845
1846 if ((opr->ndpr_stateflags & NDPRF_ONLINK) != 0)
1847 continue;
1848
1849 /*
1850 * KAME specific: detached prefixes should not be
1851 * on-link.
1852 */
1853 if ((opr->ndpr_stateflags & NDPRF_DETACHED) != 0)
1854 continue;
1855
1856 if (opr->ndpr_plen == pr->ndpr_plen &&
1857 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
1858 &opr->ndpr_prefix.sin6_addr,
1859 pr->ndpr_plen)) {
1860 int e;
1861
1862 if ((e = nd6_prefix_onlink(opr, 1, 1)) != 0) {
1863 nd6log((LOG_ERR,
1864 "nd6_prefix_offlink: failed to "
1865 "recover a prefix %s/%d from %s "
1866 "to %s (errno = %d)\n",
1867 ip6_sprintf(&opr->ndpr_prefix.sin6_addr),
1868 opr->ndpr_plen, if_name(ifp),
1869 if_name(opr->ndpr_ifp), e));
1870 }
1871 }
1872 }
1873 }
1874 else {
1875 /* XXX: can we still set the NDPRF_ONLINK flag? */
1876 nd6log((LOG_ERR,
1877 "nd6_prefix_offlink: failed to delete route: "
1878 "%s/%d on %s (errno = %d)\n",
1879 ip6_sprintf(&sa6.sin6_addr), pr->ndpr_plen, if_name(ifp),
1880 error));
1881 }
1882
1883 if (rt != NULL)
1884 rtfree_locked(rt);
1885
1886 lck_mtx_unlock(rnh_lock);
1887
1888 return(error);
1889 }
1890
1891 static struct in6_ifaddr *
1892 in6_ifadd(
1893 struct nd_prefix *pr,
1894 struct in6_addr *ifid) /* Mobile IPv6 addition */
1895 {
1896 struct ifnet *ifp = pr->ndpr_ifp;
1897 struct ifaddr *ifa;
1898 struct in6_aliasreq ifra;
1899 struct in6_ifaddr *ia, *ib;
1900 int error, plen0;
1901 struct in6_addr mask;
1902 int prefixlen = pr->ndpr_plen;
1903
1904 in6_len2mask(&mask, prefixlen);
1905
1906 /*
1907 * find a link-local address (will be interface ID).
1908 * Is it really mandatory? Theoretically, a global or a site-local
1909 * address can be configured without a link-local address, if we
1910 * have a unique interface identifier...
1911 *
1912 * it is not mandatory to have a link-local address, we can generate
1913 * interface identifier on the fly. we do this because:
1914 * (1) it should be the easiest way to find interface identifier.
1915 * (2) RFC2462 5.4 suggesting the use of the same interface identifier
1916 * for multiple addresses on a single interface, and possible shortcut
1917 * of DAD. we omitted DAD for this reason in the past.
1918 * (3) a user can prevent autoconfiguration of global address
1919 * by removing link-local address by hand (this is partly because we
1920 * don't have other way to control the use of IPv6 on a interface.
1921 * this has been our design choice - cf. NRL's "ifconfig auto").
1922 * (4) it is easier to manage when an interface has addresses
1923 * with the same interface identifier, than to have multiple addresses
1924 * with different interface identifiers.
1925 *
1926 * Mobile IPv6 addition: allow for caller to specify a wished interface
1927 * ID. This is to not break connections when moving addresses between
1928 * interfaces.
1929 */
1930 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);/* 0 is OK? */
1931 if (ifa)
1932 ib = (struct in6_ifaddr *)ifa;
1933 else
1934 return NULL;
1935
1936 #if 0 /* don't care link local addr state, and always do DAD */
1937 /* if link-local address is not eligible, do not autoconfigure. */
1938 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) {
1939 printf("in6_ifadd: link-local address not ready\n");
1940 ifafree(ifa);
1941 return NULL;
1942 }
1943 #endif
1944
1945 /* prefixlen + ifidlen must be equal to 128 */
1946 plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
1947 if (prefixlen != plen0) {
1948 nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s "
1949 "(prefix=%d ifid=%d)\n",
1950 if_name(ifp), prefixlen, 128 - plen0));
1951 ifafree(ifa);
1952 return NULL;
1953 }
1954
1955 /* make ifaddr */
1956
1957 bzero(&ifra, sizeof(ifra));
1958 /*
1959 * in6_update_ifa() does not use ifra_name, but we accurately set it
1960 * for safety.
1961 */
1962 strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
1963 ifra.ifra_addr.sin6_family = AF_INET6;
1964 ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
1965 /* prefix */
1966 bcopy(&pr->ndpr_prefix.sin6_addr, &ifra.ifra_addr.sin6_addr,
1967 sizeof(ifra.ifra_addr.sin6_addr));
1968 ifra.ifra_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0];
1969 ifra.ifra_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1];
1970 ifra.ifra_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2];
1971 ifra.ifra_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3];
1972
1973 /* interface ID */
1974 if (ifid == NULL || IN6_IS_ADDR_UNSPECIFIED(ifid))
1975 ifid = &ib->ia_addr.sin6_addr;
1976 ifra.ifra_addr.sin6_addr.s6_addr32[0]
1977 |= (ifid->s6_addr32[0] & ~mask.s6_addr32[0]);
1978 ifra.ifra_addr.sin6_addr.s6_addr32[1]
1979 |= (ifid->s6_addr32[1] & ~mask.s6_addr32[1]);
1980 ifra.ifra_addr.sin6_addr.s6_addr32[2]
1981 |= (ifid->s6_addr32[2] & ~mask.s6_addr32[2]);
1982 ifra.ifra_addr.sin6_addr.s6_addr32[3]
1983 |= (ifid->s6_addr32[3] & ~mask.s6_addr32[3]);
1984
1985 /* new prefix mask. */
1986 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1987 ifra.ifra_prefixmask.sin6_family = AF_INET6;
1988 bcopy(&mask, &ifra.ifra_prefixmask.sin6_addr,
1989 sizeof(ifra.ifra_prefixmask.sin6_addr));
1990
1991 /*
1992 * lifetime.
1993 * XXX: in6_init_address_ltimes would override these values later.
1994 * We should reconsider this logic.
1995 */
1996 ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
1997 ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
1998
1999 /* XXX: scope zone ID? */
2000
2001 ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
2002 /*
2003 * temporarily set the nopfx flag to avoid conflict.
2004 * XXX: we should reconsider the entire mechanism about prefix
2005 * manipulation.
2006 */
2007 ifra.ifra_flags |= IN6_IFF_NOPFX;
2008
2009 /*
2010 * keep the new address, regardless of the result of in6_update_ifa.
2011 * XXX: this address is now meaningless.
2012 * We should reconsider its role.
2013 */
2014 pr->ndpr_addr = ifra.ifra_addr.sin6_addr;
2015
2016 ifafree(ifa);
2017 ifa = NULL;
2018
2019 /* allocate ifaddr structure, link into chain, etc. */
2020 if ((error = in6_update_ifa(ifp, &ifra, NULL, M_NOWAIT)) != 0) {
2021 nd6log((LOG_ERR,
2022 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n",
2023 ip6_sprintf(&ifra.ifra_addr.sin6_addr), if_name(ifp),
2024 error));
2025 return(NULL); /* ifaddr must not have been allocated. */
2026 }
2027
2028 ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
2029
2030 in6_post_msg(ifp, KEV_INET6_NEW_RTADV_ADDR, ia);
2031
2032 return(ia); /* this must NOT be NULL. */
2033 }
2034
2035 int
2036 in6_tmpifadd(
2037 const struct in6_ifaddr *ia0, /* corresponding public address */
2038 int forcegen,
2039 int how)
2040 {
2041 struct ifnet *ifp = ia0->ia_ifa.ifa_ifp;
2042 struct in6_ifaddr *ia, *newia;
2043 struct in6_aliasreq ifra;
2044 int i, error;
2045 int trylimit = 3; /* XXX: adhoc value */
2046 u_int32_t randid[2];
2047 time_t vltime0, pltime0;
2048 struct timeval timenow;
2049
2050 getmicrotime(&timenow);
2051
2052 bzero(&ifra, sizeof(ifra));
2053 strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
2054 ifra.ifra_addr = ia0->ia_addr;
2055 /* copy prefix mask */
2056 ifra.ifra_prefixmask = ia0->ia_prefixmask;
2057 /* clear the old IFID */
2058 for (i = 0; i < 4; i++) {
2059 ifra.ifra_addr.sin6_addr.s6_addr32[i]
2060 &= ifra.ifra_prefixmask.sin6_addr.s6_addr32[i];
2061 }
2062
2063 again:
2064 in6_get_tmpifid(ifp, (u_int8_t *)randid,
2065 (const u_int8_t *)&ia0->ia_addr.sin6_addr.s6_addr[8],
2066 forcegen);
2067 ifra.ifra_addr.sin6_addr.s6_addr32[2]
2068 |= (randid[0] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[2]));
2069 ifra.ifra_addr.sin6_addr.s6_addr32[3]
2070 |= (randid[1] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[3]));
2071
2072 /*
2073 * If by chance the new temporary address is the same as an address
2074 * already assigned to the interface, generate a new randomized
2075 * interface identifier and repeat this step.
2076 * RFC 3041 3.3 (4).
2077 */
2078 if ((ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr)) != NULL) {
2079 ifafree(&ia->ia_ifa);
2080 if (trylimit-- == 0) {
2081 nd6log((LOG_NOTICE, "in6_tmpifadd: failed to find "
2082 "a unique random IFID\n"));
2083 return(EEXIST);
2084 }
2085 forcegen = 1;
2086 goto again;
2087 }
2088
2089 /*
2090 * The Valid Lifetime is the lower of the Valid Lifetime of the
2091 * public address or TEMP_VALID_LIFETIME.
2092 * The Preferred Lifetime is the lower of the Preferred Lifetime
2093 * of the public address or TEMP_PREFERRED_LIFETIME -
2094 * DESYNC_FACTOR.
2095 */
2096 if (ia0->ia6_lifetime.ia6t_expire != 0) {
2097 vltime0 = IFA6_IS_INVALID(ia0) ? 0 :
2098 (ia0->ia6_lifetime.ia6t_expire - timenow.tv_sec);
2099 if (vltime0 > ip6_temp_valid_lifetime)
2100 vltime0 = ip6_temp_valid_lifetime;
2101 } else
2102 vltime0 = ip6_temp_valid_lifetime;
2103 if (ia0->ia6_lifetime.ia6t_preferred != 0) {
2104 pltime0 = IFA6_IS_DEPRECATED(ia0) ? 0 :
2105 (ia0->ia6_lifetime.ia6t_preferred - timenow.tv_sec);
2106 if (pltime0 > ip6_temp_preferred_lifetime - ip6_desync_factor){
2107 pltime0 = ip6_temp_preferred_lifetime -
2108 ip6_desync_factor;
2109 }
2110 } else
2111 pltime0 = ip6_temp_preferred_lifetime - ip6_desync_factor;
2112 ifra.ifra_lifetime.ia6t_vltime = vltime0;
2113 ifra.ifra_lifetime.ia6t_pltime = pltime0;
2114
2115 /*
2116 * A temporary address is created only if this calculated Preferred
2117 * Lifetime is greater than REGEN_ADVANCE time units.
2118 */
2119 if (ifra.ifra_lifetime.ia6t_pltime <= ip6_temp_regen_advance)
2120 return(0);
2121
2122 /* XXX: scope zone ID? */
2123
2124 ifra.ifra_flags |= (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY);
2125
2126 /* allocate ifaddr structure, link into chain, etc. */
2127 if ((error = in6_update_ifa(ifp, &ifra, NULL, how)) != 0)
2128 return(error);
2129
2130 newia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
2131 if (newia == NULL) { /* XXX: can it happen? */
2132 nd6log((LOG_ERR,
2133 "in6_tmpifadd: ifa update succeeded, but we got "
2134 "no ifaddr\n"));
2135 return(EINVAL); /* XXX */
2136 }
2137 lck_mtx_lock(nd6_mutex);
2138 newia->ia6_ndpr = ia0->ia6_ndpr;
2139 newia->ia6_ndpr->ndpr_refcnt++;
2140 /*
2141 * A newly added address might affect the status of other addresses.
2142 * XXX: when the temporary address is generated with a new public
2143 * address, the onlink check is redundant. However, it would be safe
2144 * to do the check explicitly everywhere a new address is generated,
2145 * and, in fact, we surely need the check when we create a new
2146 * temporary address due to deprecation of an old temporary address.
2147 */
2148 pfxlist_onlink_check(1);
2149 lck_mtx_unlock(nd6_mutex);
2150 ifafree(&newia->ia_ifa);
2151
2152 return(0);
2153 }
2154
2155 int
2156 in6_init_prefix_ltimes(struct nd_prefix *ndpr)
2157 {
2158 struct timeval timenow;
2159
2160 getmicrotime(&timenow);
2161 /* check if preferred lifetime > valid lifetime. RFC2462 5.5.3 (c) */
2162 if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) {
2163 nd6log((LOG_INFO, "in6_init_prefix_ltimes: preferred lifetime"
2164 "(%d) is greater than valid lifetime(%d)\n",
2165 (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime));
2166 return (EINVAL);
2167 }
2168 if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
2169 ndpr->ndpr_preferred = 0;
2170 else
2171 ndpr->ndpr_preferred = timenow.tv_sec + ndpr->ndpr_pltime;
2172 if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
2173 ndpr->ndpr_expire = 0;
2174 else
2175 ndpr->ndpr_expire = timenow.tv_sec + ndpr->ndpr_vltime;
2176
2177 return 0;
2178 }
2179
2180 static void
2181 in6_init_address_ltimes(__unused struct nd_prefix *new, struct in6_addrlifetime *lt6)
2182 {
2183 struct timeval timenow;
2184
2185 getmicrotime(&timenow);
2186 /* Valid lifetime must not be updated unless explicitly specified. */
2187 /* init ia6t_expire */
2188 if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
2189 lt6->ia6t_expire = 0;
2190 else {
2191 lt6->ia6t_expire = timenow.tv_sec;
2192 lt6->ia6t_expire += lt6->ia6t_vltime;
2193 }
2194
2195 /* init ia6t_preferred */
2196 if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
2197 lt6->ia6t_preferred = 0;
2198 else {
2199 lt6->ia6t_preferred = timenow.tv_sec;
2200 lt6->ia6t_preferred += lt6->ia6t_pltime;
2201 }
2202 }
2203
2204 /*
2205 * Delete all the routing table entries that use the specified gateway.
2206 * XXX: this function causes search through all entries of routing table, so
2207 * it shouldn't be called when acting as a router.
2208 */
2209 void
2210 rt6_flush(
2211 struct in6_addr *gateway,
2212 struct ifnet *ifp)
2213 {
2214 struct radix_node_head *rnh = rt_tables[AF_INET6];
2215
2216 /* We'll care only link-local addresses */
2217 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) {
2218 return;
2219 }
2220 lck_mtx_lock(rnh_lock);
2221 /* XXX: hack for KAME's link-local address kludge */
2222 gateway->s6_addr16[1] = htons(ifp->if_index);
2223
2224 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway);
2225 lck_mtx_unlock(rnh_lock);
2226 }
2227
2228 static int
2229 rt6_deleteroute(
2230 struct radix_node *rn,
2231 void *arg)
2232 {
2233 #define SIN6(s) ((struct sockaddr_in6 *)s)
2234 struct rtentry *rt = (struct rtentry *)rn;
2235 struct in6_addr *gate = (struct in6_addr *)arg;
2236
2237 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
2238
2239 RT_LOCK(rt);
2240 if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) {
2241 RT_UNLOCK(rt);
2242 return(0);
2243 }
2244
2245 if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) {
2246 RT_UNLOCK(rt);
2247 return(0);
2248 }
2249 /*
2250 * Do not delete a static route.
2251 * XXX: this seems to be a bit ad-hoc. Should we consider the
2252 * 'cloned' bit instead?
2253 */
2254 if ((rt->rt_flags & RTF_STATIC) != 0) {
2255 RT_UNLOCK(rt);
2256 return(0);
2257 }
2258 /*
2259 * We delete only host route. This means, in particular, we don't
2260 * delete default route.
2261 */
2262 if ((rt->rt_flags & RTF_HOST) == 0) {
2263 RT_UNLOCK(rt);
2264 return(0);
2265 }
2266
2267 /*
2268 * Safe to drop rt_lock and use rt_key, rt_gateway, since holding
2269 * rnh_lock here prevents another thread from calling rt_setgate()
2270 * on this route.
2271 */
2272 RT_UNLOCK(rt);
2273 return (rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
2274 rt_mask(rt), rt->rt_flags, 0));
2275 #undef SIN6
2276 }
2277
2278 int
2279 nd6_setdefaultiface(
2280 int ifindex)
2281 {
2282 int error = 0;
2283 ifnet_t def_ifp = NULL;
2284
2285 ifnet_head_lock_shared();
2286 if (ifindex < 0 || if_index < ifindex) {
2287 ifnet_head_done();
2288 return(EINVAL);
2289 }
2290 def_ifp = ifindex2ifnet[ifindex];
2291 ifnet_head_done();
2292
2293 lck_mtx_lock(nd6_mutex);
2294 if (nd6_defifindex != ifindex) {
2295 nd6_defifindex = ifindex;
2296 if (nd6_defifindex > 0)
2297 nd6_defifp = def_ifp;
2298 else
2299 nd6_defifp = NULL;
2300
2301 /*
2302 * If the Default Router List is empty, install a route
2303 * to the specified interface as default or remove the default
2304 * route when the default interface becomes canceled.
2305 * The check for the queue is actually redundant, but
2306 * we do this here to avoid re-install the default route
2307 * if the list is NOT empty.
2308 */
2309 if (TAILQ_FIRST(&nd_defrouter) == NULL)
2310 defrouter_select();
2311
2312 /*
2313 * Our current implementation assumes one-to-one maping between
2314 * interfaces and links, so it would be natural to use the
2315 * default interface as the default link.
2316 */
2317 scope6_setdefault(nd6_defifp);
2318 }
2319
2320 lck_mtx_unlock(nd6_mutex);
2321 return(error);
2322 }