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