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 94static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *); 95static struct in6_ifaddr *in6_ifadd(struct nd_prefix *, 96 struct in6_addr *); 97static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *, 98 struct nd_defrouter *); 99static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *); 100static void pfxrtr_del(struct nd_pfxrouter *); 101static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *); 102static void defrouter_addifreq(struct ifnet *); 103static void nd6_rtmsg(int, struct rtentry *); 104 105static void in6_init_address_ltimes(struct nd_prefix *ndpr, 106 struct in6_addrlifetime *lt6); 107 108static int rt6_deleteroute(struct radix_node *, void *); 109 110extern int nd6_recalc_reachtm_interval; 111 112static struct ifnet *nd6_defifp; 113int nd6_defifindex; 114 115int ip6_use_tempaddr = 0; 116 117int ip6_desync_factor; 118u_int32_t ip6_temp_preferred_lifetime = DEF_TEMP_PREFERRED_LIFETIME; 119u_int32_t ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME; 120/* 121 * shorter lifetimes for debugging purposes. 122int ip6_temp_preferred_lifetime = 800; 123static int ip6_temp_valid_lifetime = 1800; 124*/ 125int ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE; 126 127extern lck_mtx_t *rt_mtx; 128extern 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 */ 137void 138nd6_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 */ 231void 232nd6_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. */ 478static void 479nd6_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 498void 499defrouter_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 */ 527void 528defrouter_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 578struct nd_defrouter * 579defrouter_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 597void 598defrouter_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 629void 630defrtrlist_del( 631 struct nd_defrouter *dr, int nd6locked) 632{ 633 struct nd_defrouter *deldr = NULL; 634 struct nd_ifinfo *ndi = &nd_ifinfo[dr->ifp->if_index]; 635 struct nd_prefix *pr; 636 637 /* 638 * Flush all the routing table entries that use the router 639 * as a next hop. 640 */ 641 if (!ip6_forwarding && (ip6_accept_rtadv || (dr->ifp->if_eflags & IFEF_ACCEPT_RTADVD))) { 642 /* above is a good condition? */ 643 rt6_flush(&dr->rtaddr, dr->ifp); 644 } 645 646 if (nd6locked == 0) 647 lck_mtx_lock(nd6_mutex); 648 if (dr == TAILQ_FIRST(&nd_defrouter)) 649 deldr = dr; /* The router is primary. */ 650 651 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); 652 653 /* 654 * Also delete all the pointers to the router in each prefix lists. 655 */ 656 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 657 struct nd_pfxrouter *pfxrtr; 658 if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL) 659 pfxrtr_del(pfxrtr); 660 } 661 pfxlist_onlink_check(1); 662 663 /* 664 * If the router is the primary one, choose a new one. 665 * Note that defrouter_select() will remove the current gateway 666 * from the routing table. 667 */ 668 if (deldr) 669 defrouter_select(); 670 671 ndi->ndefrouters--; 672 if (ndi->ndefrouters < 0) { 673 log(LOG_WARNING, "defrtrlist_del: negative count on %s\n", 674 if_name(dr->ifp)); 675 } 676 677 if (nd6locked == 0) 678 lck_mtx_unlock(nd6_mutex); 679 680 FREE(dr, M_IP6NDP); 681} 682 683/* 684 * Default Router Selection according to Section 6.3.6 of RFC 2461: 685 * 1) Routers that are reachable or probably reachable should be 686 * preferred. 687 * 2) When no routers on the list are known to be reachable or 688 * probably reachable, routers SHOULD be selected in a round-robin 689 * fashion. 690 * 3) If the Default Router List is empty, assume that all 691 * destinations are on-link. 692 */ 693void 694defrouter_select() 695{ 696 struct nd_defrouter *dr, anydr; 697 struct rtentry *rt = NULL; 698 struct llinfo_nd6 *ln = NULL; 699 700 /* 701 * Search for a (probably) reachable router from the list. 702 */ 703 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 704 705 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 706 dr = TAILQ_NEXT(dr, dr_entry)) { 707 if ((rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp, 0)) && 708 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 709 ND6_IS_LLINFO_PROBREACH(ln)) { 710 /* Got it, and move it to the head */ 711 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); 712 TAILQ_INSERT_HEAD(&nd_defrouter, dr, dr_entry); 713 break; 714 } 715 } 716 717 if ((dr = TAILQ_FIRST(&nd_defrouter))) { 718 /* 719 * De-install the previous default gateway and install 720 * a new one. 721 * Note that if there is no reachable router in the list, 722 * the head entry will be used anyway. 723 * XXX: do we have to check the current routing table entry? 724 */ 725 bzero(&anydr, sizeof(anydr)); 726 defrouter_delreq(&anydr, 0); 727 defrouter_addreq(dr); 728 } 729 else { 730 /* 731 * The Default Router List is empty, so install the default 732 * route to an inteface. 733 * XXX: The specification does not say this mechanism should 734 * be restricted to hosts, but this would be not useful 735 * (even harmful) for routers. 736 */ 737 if (!ip6_forwarding) { 738 /* 739 * De-install the current default route 740 * in advance. 741 */ 742 bzero(&anydr, sizeof(anydr)); 743 defrouter_delreq(&anydr, 0); 744 if (nd6_defifp) { 745 /* 746 * Install a route to the default interface 747 * as default route. 748 * XXX: we enable this for host only, because 749 * this may override a default route installed 750 * a user process (e.g. routing daemon) in a 751 * router case. 752 */ 753 defrouter_addifreq(nd6_defifp); 754 } else { 755 nd6log((LOG_INFO, "defrouter_select: " 756 "there's no default router and no default" 757 " interface\n")); 758 } 759 } 760 } 761 762 return; 763} 764 765static struct nd_defrouter * 766defrtrlist_update( 767 struct nd_defrouter *new) 768{ 769 struct nd_defrouter *dr, *n; 770 struct nd_ifinfo *ndi = &nd_ifinfo[new->ifp->if_index]; 771 772 lck_mtx_lock(nd6_mutex); 773 if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) { 774 /* entry exists */ 775 if (new->rtlifetime == 0) { 776 defrtrlist_del(dr, 1); 777 dr = NULL; 778 } else { 779 /* override */ 780 dr->flags = new->flags; /* xxx flag check */ 781 dr->rtlifetime = new->rtlifetime; 782 dr->expire = new->expire; 783 } 784 lck_mtx_unlock(nd6_mutex); 785 return(dr); 786 } 787 788 /* entry does not exist */ 789 if (new->rtlifetime == 0) { 790 lck_mtx_unlock(nd6_mutex); 791 return(NULL); 792 } 793 794 if (ip6_maxifdefrouters >= 0 && 795 ndi->ndefrouters >= ip6_maxifdefrouters) { 796 lck_mtx_unlock(nd6_mutex); 797 return (NULL); 798 } 799 800 n = (struct nd_defrouter *)_MALLOC(sizeof(*n), M_IP6NDP, M_NOWAIT); 801 if (n == NULL) { 802 lck_mtx_unlock(nd6_mutex); 803 return(NULL); 804 } 805 bzero(n, sizeof(*n)); 806 *n = *new; 807 808 /* 809 * Insert the new router at the end of the Default Router List. 810 * If there is no other router, install it anyway. Otherwise, 811 * just continue to use the current default router. 812 */ 813 TAILQ_INSERT_TAIL(&nd_defrouter, n, dr_entry); 814 if (TAILQ_FIRST(&nd_defrouter) == n) 815 defrouter_select(); 816 817 ndi->ndefrouters++; 818 819 lck_mtx_unlock(nd6_mutex); 820 return(n); 821} 822 823static struct nd_pfxrouter * 824pfxrtr_lookup( 825 struct nd_prefix *pr, 826 struct nd_defrouter *dr) 827{ 828 struct nd_pfxrouter *search; 829 830 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 831 for (search = pr->ndpr_advrtrs.lh_first; search; search = search->pfr_next) { 832 if (search->router == dr) 833 break; 834 } 835 836 return(search); 837} 838 839static void 840pfxrtr_add( 841 struct nd_prefix *pr, 842 struct nd_defrouter *dr) 843{ 844 struct nd_pfxrouter *new; 845 846 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 847 848 new = (struct nd_pfxrouter *)_MALLOC(sizeof(*new), M_IP6NDP, M_NOWAIT); 849 if (new == NULL) 850 return; 851 bzero(new, sizeof(*new)); 852 new->router = dr; 853 854 LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry); 855 856 pfxlist_onlink_check(1); 857} 858 859static void 860pfxrtr_del( 861 struct nd_pfxrouter *pfr) 862{ 863 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 864 LIST_REMOVE(pfr, pfr_entry); 865 FREE(pfr, M_IP6NDP); 866} 867 868struct nd_prefix * 869nd6_prefix_lookup( 870 struct nd_prefix *pr) 871{ 872 struct nd_prefix *search; 873 874 lck_mtx_lock(nd6_mutex); 875 for (search = nd_prefix.lh_first; search; search = search->ndpr_next) { 876 if (pr->ndpr_ifp == search->ndpr_ifp && 877 pr->ndpr_plen == search->ndpr_plen && 878 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 879 &search->ndpr_prefix.sin6_addr, 880 pr->ndpr_plen) 881 ) { 882 break; 883 } 884 } 885 if (search != NULL) 886 ndpr_hold(search, TRUE); 887 lck_mtx_unlock(nd6_mutex); 888 889 return(search); 890} 891 892void 893ndpr_hold(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 908void 909ndpr_rele(struct nd_prefix *pr, boolean_t locked) 910{ 911 if (!locked) 912 lck_mtx_lock(nd6_mutex); 913 914 if (pr->ndpr_usecnt <= 0) 915 panic("%s: bad usecnt %d for pr %p\n", __func__, 916 pr->ndpr_usecnt, pr); 917 918 pr->ndpr_usecnt--; 919 920 if (!locked) 921 lck_mtx_unlock(nd6_mutex); 922} 923 924static void 925purge_detached(struct ifnet *ifp) 926{ 927 struct nd_prefix *pr, *pr_next; 928 struct in6_ifaddr *ia; 929 struct ifaddr *ifa, *ifa_next; 930 931 lck_mtx_lock(nd6_mutex); 932 933 for (pr = nd_prefix.lh_first; pr; pr = pr_next) { 934 pr_next = pr->ndpr_next; 935 if (pr->ndpr_ifp != ifp || 936 IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) || 937 ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 938 !LIST_EMPTY(&pr->ndpr_advrtrs))) 939 continue; 940 941 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa_next) { 942 ifa_next = ifa->ifa_list.tqe_next; 943 if (ifa->ifa_addr->sa_family != AF_INET6) 944 continue; 945 ia = (struct in6_ifaddr *)ifa; 946 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 947 IN6_IFF_AUTOCONF && ia->ia6_ndpr == pr) { 948 in6_purgeaddr(ifa, 1); 949 } 950 } 951 if (pr->ndpr_refcnt == 0) 952 prelist_remove(pr, 1); 953 } 954 955 lck_mtx_unlock(nd6_mutex); 956} 957 958int 959nd6_prelist_add( 960 struct nd_prefix *pr, 961 struct nd_defrouter *dr, 962 struct nd_prefix **newp) 963{ 964 struct nd_prefix *new = NULL; 965 int i; 966 struct nd_ifinfo *ndi = &nd_ifinfo[pr->ndpr_ifp->if_index]; 967 968 if (ip6_maxifprefixes >= 0) { 969 if (ndi->nprefixes >= ip6_maxifprefixes / 2) 970 purge_detached(pr->ndpr_ifp); 971 if (ndi->nprefixes >= ip6_maxifprefixes) 972 return(ENOMEM); 973 } 974 975 new = (struct nd_prefix *)_MALLOC(sizeof(*new), M_IP6NDP, M_NOWAIT); 976 if (new == NULL) 977 return ENOMEM; 978 bzero(new, sizeof(*new)); 979 *new = *pr; 980 if (newp != NULL) 981 *newp = new; 982 983 /* initilization */ 984 LIST_INIT(&new->ndpr_advrtrs); 985 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen); 986 /* make prefix in the canonical form */ 987 for (i = 0; i < 4; i++) 988 new->ndpr_prefix.sin6_addr.s6_addr32[i] &= 989 new->ndpr_mask.s6_addr32[i]; 990 991 /* link ndpr_entry to nd_prefix list */ 992 lck_mtx_lock(nd6_mutex); 993 LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry); 994 995 new->ndpr_usecnt = 0; 996 ndpr_hold(new, TRUE); 997 998 /* ND_OPT_PI_FLAG_ONLINK processing */ 999 if (new->ndpr_raf_onlink) { 1000 int e; 1001 1002 if ((e = nd6_prefix_onlink(new, 0, 1)) != 0) { 1003 nd6log((LOG_ERR, "nd6_prelist_add: failed to make " 1004 "the prefix %s/%d on-link on %s (errno=%d)\n", 1005 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1006 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 1007 /* proceed anyway. XXX: is it correct? */ 1008 } 1009 } 1010 1011 if (dr) { 1012 pfxrtr_add(new, dr); 1013 } 1014 1015 ndi->nprefixes++; 1016 1017 lck_mtx_unlock(nd6_mutex); 1018 1019 return 0; 1020} 1021 1022void 1023prelist_remove( 1024 struct nd_prefix *pr, int nd6locked) 1025{ 1026 struct nd_pfxrouter *pfr, *next; 1027 int e; 1028 struct nd_ifinfo *ndi = &nd_ifinfo[pr->ndpr_ifp->if_index]; 1029 1030 /* make sure to invalidate the prefix until it is really freed. */ 1031 pr->ndpr_vltime = 0; 1032 pr->ndpr_pltime = 0; 1033#if 0 1034 /* 1035 * Though these flags are now meaningless, we'd rather keep the value 1036 * not to confuse users when executing "ndp -p". 1037 */ 1038 pr->ndpr_raf_onlink = 0; 1039 pr->ndpr_raf_auto = 0; 1040#endif 1041 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 && 1042 (e = nd6_prefix_offlink(pr)) != 0) { 1043 nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink " 1044 "on %s, errno=%d\n", 1045 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1046 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 1047 /* what should we do? */ 1048 } 1049 1050 if (nd6locked == 0) 1051 lck_mtx_lock(nd6_mutex); 1052 1053 if (pr->ndpr_usecnt > 0 || pr->ndpr_refcnt > 0) 1054 goto done; /* notice here? */ 1055 1056 /* unlink ndpr_entry from nd_prefix list */ 1057 LIST_REMOVE(pr, ndpr_entry); 1058 1059 /* free list of routers that adversed the prefix */ 1060 for (pfr = pr->ndpr_advrtrs.lh_first; pfr; pfr = next) { 1061 next = pfr->pfr_next; 1062 1063 FREE(pfr, M_IP6NDP); 1064 } 1065 1066 ndi->nprefixes--; 1067 if (ndi->nprefixes < 0) { 1068 log(LOG_WARNING, "prelist_remove: negative count on %s\n", 1069 if_name(pr->ndpr_ifp)); 1070 } 1071 1072 FREE(pr, M_IP6NDP); 1073 1074 pfxlist_onlink_check(1); 1075done: 1076 if (nd6locked == 0) 1077 lck_mtx_unlock(nd6_mutex); 1078} 1079 1080int 1081prelist_update( 1082 struct nd_prefix *new, 1083 struct nd_defrouter *dr, /* may be NULL */ 1084 struct mbuf *m) 1085{ 1086 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL; 1087 struct ifaddr *ifa; 1088 struct ifnet *ifp = new->ndpr_ifp; 1089 struct nd_prefix *pr; 1090 int error = 0; 1091 int newprefix = 0; 1092 int auth; 1093 struct in6_addrlifetime lt6_tmp; 1094 struct timeval timenow; 1095 1096 auth = 0; 1097 if (m) { 1098 /* 1099 * Authenticity for NA consists authentication for 1100 * both IP header and IP datagrams, doesn't it ? 1101 */ 1102#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM) 1103 auth = (m->m_flags & M_AUTHIPHDR 1104 && m->m_flags & M_AUTHIPDGM) ? 1 : 0; 1105#endif 1106 } 1107 1108 1109 if ((pr = nd6_prefix_lookup(new)) != NULL) { 1110 /* 1111 * nd6_prefix_lookup() ensures that pr and new have the same 1112 * prefix on a same interface. 1113 */ 1114 1115 /* 1116 * Update prefix information. Note that the on-link (L) bit 1117 * and the autonomous (A) bit should NOT be changed from 1 1118 * to 0. 1119 */ 1120 if (new->ndpr_raf_onlink == 1) 1121 pr->ndpr_raf_onlink = 1; 1122 if (new->ndpr_raf_auto == 1) 1123 pr->ndpr_raf_auto = 1; 1124 if (new->ndpr_raf_onlink) { 1125 pr->ndpr_vltime = new->ndpr_vltime; 1126 pr->ndpr_pltime = new->ndpr_pltime; 1127 pr->ndpr_preferred = new->ndpr_preferred; 1128 pr->ndpr_expire = new->ndpr_expire; 1129 } 1130 1131 if (new->ndpr_raf_onlink && 1132 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1133 int e; 1134 1135 if ((e = nd6_prefix_onlink(pr, 0, 0)) != 0) { 1136 nd6log((LOG_ERR, 1137 "prelist_update: failed to make " 1138 "the prefix %s/%d on-link on %s " 1139 "(errno=%d)\n", 1140 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1141 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 1142 /* proceed anyway. XXX: is it correct? */ 1143 } 1144 } 1145 1146 lck_mtx_lock(nd6_mutex); 1147 if (dr && pfxrtr_lookup(pr, dr) == NULL) 1148 pfxrtr_add(pr, dr); 1149 lck_mtx_unlock(nd6_mutex); 1150 } else { 1151 struct nd_prefix *newpr = NULL; 1152 1153 newprefix = 1; 1154 1155 if (new->ndpr_vltime == 0) 1156 goto end; 1157 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0) 1158 goto end; 1159 1160 bzero(&new->ndpr_addr, sizeof(struct in6_addr)); 1161 1162 error = nd6_prelist_add(new, dr, &newpr); 1163 if (error != 0 || newpr == NULL) { 1164 nd6log((LOG_NOTICE, "prelist_update: " 1165 "nd6_prelist_add failed for %s/%d on %s " 1166 "errno=%d, returnpr=%p\n", 1167 ip6_sprintf(&new->ndpr_prefix.sin6_addr), 1168 new->ndpr_plen, if_name(new->ndpr_ifp), 1169 error, newpr)); 1170 goto end; /* we should just give up in this case. */ 1171 } 1172 1173 /* 1174 * XXX: from the ND point of view, we can ignore a prefix 1175 * with the on-link bit being zero. However, we need a 1176 * prefix structure for references from autoconfigured 1177 * addresses. Thus, we explicitly make suret that the prefix 1178 * itself expires now. 1179 */ 1180 if (newpr->ndpr_raf_onlink == 0) { 1181 newpr->ndpr_vltime = 0; 1182 newpr->ndpr_pltime = 0; 1183 in6_init_prefix_ltimes(newpr); 1184 } 1185 1186 pr = newpr; 1187 } 1188 1189 /* 1190 * Address autoconfiguration based on Section 5.5.3 of RFC 2462. 1191 * Note that pr must be non NULL at this point. 1192 */ 1193 1194 /* 5.5.3 (a). Ignore the prefix without the A bit set. */ 1195 if (!new->ndpr_raf_auto) 1196 goto afteraddrconf; 1197 1198 /* 1199 * 5.5.3 (b). the link-local prefix should have been ignored in 1200 * nd6_ra_input. 1201 */ 1202 1203 /* 1204 * 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. 1205 * This should have been done in nd6_ra_input. 1206 */ 1207 1208 /* 1209 * 5.5.3 (d). If the prefix advertised does not match the prefix of an 1210 * address already in the list, and the Valid Lifetime is not 0, 1211 * form an address. Note that even a manually configured address 1212 * should reject autoconfiguration of a new address. 1213 */ 1214 getmicrotime(&timenow); 1215 1216 ifnet_lock_exclusive(ifp); 1217 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1218 { 1219 struct in6_ifaddr *ifa6; 1220 int ifa_plen; 1221 u_int32_t storedlifetime; 1222 1223 if (ifa->ifa_addr->sa_family != AF_INET6) 1224 continue; 1225 1226 ifa6 = (struct in6_ifaddr *)ifa; 1227 1228 /* 1229 * Spec is not clear here, but I believe we should concentrate 1230 * on unicast (i.e. not anycast) addresses. 1231 * XXX: other ia6_flags? detached or duplicated? 1232 */ 1233 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) 1234 continue; 1235 1236 ifa_plen = in6_mask2len(&ifa6->ia_prefixmask.sin6_addr, NULL); 1237 if (ifa_plen != new->ndpr_plen || 1238 !in6_are_prefix_equal(&ifa6->ia_addr.sin6_addr, 1239 &new->ndpr_prefix.sin6_addr, 1240 ifa_plen)) 1241 continue; 1242 1243 if (ia6_match == NULL) /* remember the first one */ 1244 ia6_match = ifa6; 1245 1246 if ((ifa6->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1247 continue; 1248 1249 /* 1250 * An already autoconfigured address matched. Now that we 1251 * are sure there is at least one matched address, we can 1252 * proceed to 5.5.3. (e): update the lifetimes according to the 1253 * "two hours" rule and the privacy extension. 1254 */ 1255#define TWOHOUR (120*60) 1256 lt6_tmp = ifa6->ia6_lifetime; 1257 1258 storedlifetime = IFA6_IS_INVALID(ifa6) ? 0 : 1259 (lt6_tmp.ia6t_expire - timenow.tv_sec); 1260 1261 if (TWOHOUR < new->ndpr_vltime || 1262 storedlifetime < new->ndpr_vltime) { 1263 lt6_tmp.ia6t_vltime = new->ndpr_vltime; 1264 } else if (storedlifetime <= TWOHOUR 1265#if 0 1266 /* 1267 * This condition is logically redundant, so we just 1268 * omit it. 1269 * See IPng 6712, 6717, and 6721. 1270 */ 1271 && new->ndpr_vltime <= storedlifetime 1272#endif 1273 ) { 1274 if (auth) { 1275 lt6_tmp.ia6t_vltime = new->ndpr_vltime; 1276 } 1277 } else { 1278 /* 1279 * new->ndpr_vltime <= TWOHOUR && 1280 * TWOHOUR < storedlifetime 1281 */ 1282 lt6_tmp.ia6t_vltime = TWOHOUR; 1283 } 1284 1285 /* The 2 hour rule is not imposed for preferred lifetime. */ 1286 lt6_tmp.ia6t_pltime = new->ndpr_pltime; 1287 1288 in6_init_address_ltimes(pr, <6_tmp); 1289 1290 /* 1291 * When adjusting the lifetimes of an existing temporary 1292 * address, only lower the lifetimes. 1293 * RFC 3041 3.3. (1). 1294 * XXX: how should we modify ia6t_[pv]ltime? 1295 */ 1296 if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) { 1297 if (lt6_tmp.ia6t_expire == 0 || /* no expire */ 1298 lt6_tmp.ia6t_expire > 1299 ifa6->ia6_lifetime.ia6t_expire) { 1300 lt6_tmp.ia6t_expire = 1301 ifa6->ia6_lifetime.ia6t_expire; 1302 } 1303 if (lt6_tmp.ia6t_preferred == 0 || /* no expire */ 1304 lt6_tmp.ia6t_preferred > 1305 ifa6->ia6_lifetime.ia6t_preferred) { 1306 lt6_tmp.ia6t_preferred = 1307 ifa6->ia6_lifetime.ia6t_preferred; 1308 } 1309 } 1310 1311 ifa6->ia6_lifetime = lt6_tmp; 1312 } 1313 ifnet_lock_done(ifp); 1314 if (ia6_match == NULL && new->ndpr_vltime) { 1315 /* 1316 * No address matched and the valid lifetime is non-zero. 1317 * Create a new address. 1318 */ 1319 if ((ia6 = in6_ifadd(new, NULL)) != NULL) { 1320 /* 1321 * note that we should use pr (not new) for reference. 1322 */ 1323 lck_mtx_lock(nd6_mutex); 1324 pr->ndpr_refcnt++; 1325 lck_mtx_unlock(nd6_mutex); 1326 ia6->ia6_ndpr = pr; 1327 1328#if 0 1329 /* XXXYYY Don't do this, according to Jinmei. */ 1330 pr->ndpr_addr = new->ndpr_addr; 1331#endif 1332 1333 /* 1334 * RFC 3041 3.3 (2). 1335 * When a new public address is created as described 1336 * in RFC2462, also create a new temporary address. 1337 * 1338 * RFC 3041 3.5. 1339 * When an interface connects to a new link, a new 1340 * randomized interface identifier should be generated 1341 * immediately together with a new set of temporary 1342 * addresses. Thus, we specifiy 1 as the 2nd arg of 1343 * in6_tmpifadd(). 1344 */ 1345 if (ip6_use_tempaddr) { 1346 int e; 1347 if ((e = in6_tmpifadd(ia6, 1)) != 0) { 1348 nd6log((LOG_NOTICE, "prelist_update: " 1349 "failed to create a temporary " 1350 "address, errno=%d\n", 1351 e)); 1352 } 1353 } 1354 1355 /* 1356 * A newly added address might affect the status 1357 * of other addresses, so we check and update it. 1358 * XXX: what if address duplication happens? 1359 */ 1360 pfxlist_onlink_check(0); 1361 } else { 1362 /* just set an error. do not bark here. */ 1363 error = EADDRNOTAVAIL; /* XXX: might be unused. */ 1364 } 1365 } 1366 1367afteraddrconf: 1368 1369end: 1370 if (pr != NULL) 1371 ndpr_rele(pr, FALSE); 1372 1373 return error; 1374} 1375 1376/* 1377 * A supplement function used in the on-link detection below; 1378 * detect if a given prefix has a (probably) reachable advertising router. 1379 * XXX: lengthy function name... 1380 */ 1381static struct nd_pfxrouter * 1382find_pfxlist_reachable_router( 1383 struct nd_prefix *pr) 1384{ 1385 struct nd_pfxrouter *pfxrtr; 1386 struct rtentry *rt; 1387 struct llinfo_nd6 *ln; 1388 1389 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 1390 1391 for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr; 1392 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) { 1393 if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0, 1394 pfxrtr->router->ifp, 0)) && 1395 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 1396 ND6_IS_LLINFO_PROBREACH(ln)) 1397 break; /* found */ 1398 } 1399 1400 return(pfxrtr); 1401 1402} 1403 1404/* 1405 * Check if each prefix in the prefix list has at least one available router 1406 * that advertised the prefix (a router is "available" if its neighbor cache 1407 * entry is reachable or probably reachable). 1408 * If the check fails, the prefix may be off-link, because, for example, 1409 * we have moved from the network but the lifetime of the prefix has not 1410 * expired yet. So we should not use the prefix if there is another prefix 1411 * that has an available router. 1412 * But, if there is no prefix that has an available router, we still regards 1413 * all the prefixes as on-link. This is because we can't tell if all the 1414 * routers are simply dead or if we really moved from the network and there 1415 * is no router around us. 1416 */ 1417void 1418pfxlist_onlink_check(int nd6locked) 1419{ 1420 struct nd_prefix *pr; 1421 struct in6_ifaddr *ifa; 1422 1423 /* 1424 * Check if there is a prefix that has a reachable advertising 1425 * router. 1426 */ 1427 if (nd6locked == 0) 1428 lck_mtx_lock(nd6_mutex); 1429 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 1430 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1431 if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr)) 1432 break; 1433 } 1434 1435 if (pr) { 1436 /* 1437 * There is at least one prefix that has a reachable router. 1438 * Detach prefixes which have no reachable advertising 1439 * router, and attach other prefixes. 1440 */ 1441 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1442 /* XXX: a link-local prefix should never be detached */ 1443 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1444 continue; 1445 1446 /* 1447 * we aren't interested in prefixes without the L bit 1448 * set. 1449 */ 1450 if (pr->ndpr_raf_onlink == 0) 1451 continue; 1452 1453 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1454 find_pfxlist_reachable_router(pr) == NULL) 1455 pr->ndpr_stateflags |= NDPRF_DETACHED; 1456 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && 1457 find_pfxlist_reachable_router(pr) != 0) 1458 pr->ndpr_stateflags &= ~NDPRF_DETACHED; 1459 } 1460 } else { 1461 /* there is no prefix that has a reachable router */ 1462 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1463 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1464 continue; 1465 1466 if (pr->ndpr_raf_onlink == 0) 1467 continue; 1468 1469 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0) 1470 pr->ndpr_stateflags &= ~NDPRF_DETACHED; 1471 } 1472 } 1473 1474 /* 1475 * Remove each interface route associated with a (just) detached 1476 * prefix, and reinstall the interface route for a (just) attached 1477 * prefix. Note that all attempt of reinstallation does not 1478 * necessarily success, when a same prefix is shared among multiple 1479 * interfaces. Such cases will be handled in nd6_prefix_onlink, 1480 * so we don't have to care about them. 1481 */ 1482 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1483 int e; 1484 1485 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1486 continue; 1487 1488 if (pr->ndpr_raf_onlink == 0) 1489 continue; 1490 1491 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && 1492 (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1493 if ((e = nd6_prefix_offlink(pr)) != 0) { 1494 nd6log((LOG_ERR, 1495 "pfxlist_onlink_check: failed to " 1496 "make %s/%d offlink, errno=%d\n", 1497 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1498 pr->ndpr_plen, e)); 1499 } 1500 } 1501 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1502 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 && 1503 pr->ndpr_raf_onlink) { 1504 if ((e = nd6_prefix_onlink(pr, 0, 1)) != 0) { 1505 nd6log((LOG_ERR, 1506 "pfxlist_onlink_check: failed to " 1507 "make %s/%d offlink, errno=%d\n", 1508 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1509 pr->ndpr_plen, e)); 1510 } 1511 } 1512 } 1513 1514 /* 1515 * Changes on the prefix status might affect address status as well. 1516 * Make sure that all addresses derived from an attached prefix are 1517 * attached, and that all addresses derived from a detached prefix are 1518 * detached. Note, however, that a manually configured address should 1519 * always be attached. 1520 * The precise detection logic is same as the one for prefixes. 1521 */ 1522 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) { 1523 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1524 continue; 1525 1526 if (ifa->ia6_ndpr == NULL) { 1527 /* 1528 * This can happen when we first configure the address 1529 * (i.e. the address exists, but the prefix does not). 1530 * XXX: complicated relationships... 1531 */ 1532 continue; 1533 } 1534 1535 if (find_pfxlist_reachable_router(ifa->ia6_ndpr)) 1536 break; 1537 } 1538 if (ifa) { 1539 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) { 1540 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1541 continue; 1542 1543 if (ifa->ia6_ndpr == NULL) /* XXX: see above. */ 1544 continue; 1545 1546 if (find_pfxlist_reachable_router(ifa->ia6_ndpr)) 1547 ifa->ia6_flags &= ~IN6_IFF_DETACHED; 1548 else 1549 ifa->ia6_flags |= IN6_IFF_DETACHED; 1550 } 1551 } 1552 else { 1553 for (ifa = in6_ifaddrs; ifa; ifa = ifa->ia_next) { 1554 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1555 continue; 1556 1557 ifa->ia6_flags &= ~IN6_IFF_DETACHED; 1558 } 1559 } 1560 if (nd6locked == 0) 1561 lck_mtx_unlock(nd6_mutex); 1562} 1563 1564int 1565nd6_prefix_onlink( 1566 struct nd_prefix *pr, int rtlocked, int nd6locked) 1567{ 1568 struct ifaddr *ifa; 1569 struct ifnet *ifp = pr->ndpr_ifp; 1570 struct sockaddr_in6 mask6; 1571 struct nd_prefix *opr; 1572 u_long rtflags; 1573 int error = 0; 1574 struct rtentry *rt = NULL; 1575 1576 /* sanity check */ 1577 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1578 nd6log((LOG_ERR, 1579 "nd6_prefix_onlink: %s/%d is already on-link\n", 1580 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen); 1581 return(EEXIST)); 1582 } 1583 1584 /* 1585 * Add the interface route associated with the prefix. Before 1586 * installing the route, check if there's the same prefix on another 1587 * interface, and the prefix has already installed the interface route. 1588 * Although such a configuration is expected to be rare, we explicitly 1589 * allow it. 1590 */ 1591 if (nd6locked == 0) 1592 lck_mtx_lock(nd6_mutex); 1593 else 1594 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 1595 for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) { 1596 if (opr == pr) 1597 continue; 1598 1599 if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) 1600 continue; 1601 1602 if (opr->ndpr_plen == pr->ndpr_plen && 1603 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 1604 &opr->ndpr_prefix.sin6_addr, 1605 pr->ndpr_plen)) { 1606 if (nd6locked == 0) 1607 lck_mtx_unlock(nd6_mutex); 1608 return(0); 1609 } 1610 } 1611 1612 if (nd6locked == 0) 1613 lck_mtx_unlock(nd6_mutex); 1614 /* 1615 * We prefer link-local addresses as the associated interface address. 1616 */ 1617 /* search for a link-local addr */ 1618 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 1619 IN6_IFF_NOTREADY| 1620 IN6_IFF_ANYCAST); 1621 if (ifa == NULL) { 1622 /* XXX: freebsd does not have ifa_ifwithaf */ 1623 ifnet_lock_exclusive(ifp); 1624 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1625 { 1626 if (ifa->ifa_addr->sa_family == AF_INET6) 1627 break; 1628 } 1629 ifnet_lock_done(ifp); 1630 /* should we care about ia6_flags? */ 1631 } 1632 if (ifa == NULL) { 1633 /* 1634 * This can still happen, when, for example, we receive an RA 1635 * containing a prefix with the L bit set and the A bit clear, 1636 * after removing all IPv6 addresses on the receiving 1637 * interface. This should, of course, be rare though. 1638 */ 1639 nd6log((LOG_NOTICE, 1640 "nd6_prefix_onlink: failed to find any ifaddr" 1641 " to add route for a prefix(%s/%d) on %s\n", 1642 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1643 pr->ndpr_plen, if_name(ifp))); 1644 return(0); 1645 } 1646 1647 /* 1648 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. 1649 * ifa->ifa_rtrequest = nd6_rtrequest; 1650 */ 1651 bzero(&mask6, sizeof(mask6)); 1652 mask6.sin6_len = sizeof(mask6); 1653 mask6.sin6_addr = pr->ndpr_mask; 1654 1655 if (rtlocked == 0) 1656 lck_mtx_lock(rt_mtx); 1657 1658 rtflags = ifa->ifa_flags | RTF_CLONING | RTF_UP; 1659 if (nd6_need_cache(ifp)) { 1660 /* explicitly set in case ifa_flags does not set the flag. */ 1661 rtflags |= RTF_CLONING; 1662 } else { 1663 /* 1664 * explicitly clear the cloning bit in case ifa_flags sets it. 1665 */ 1666 rtflags &= ~RTF_CLONING; 1667 } 1668 error = rtrequest_locked(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix, 1669 ifa->ifa_addr, (struct sockaddr *)&mask6, 1670 rtflags, &rt); 1671 if (error == 0) { 1672 if (rt != NULL) /* this should be non NULL, though */ 1673 nd6_rtmsg(RTM_ADD, rt); 1674 pr->ndpr_stateflags |= NDPRF_ONLINK; 1675 } 1676 else { 1677 nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a" 1678 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx " 1679 "errno = %d\n", 1680 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1681 pr->ndpr_plen, if_name(ifp), 1682 ip6_sprintf(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr), 1683 ip6_sprintf(&mask6.sin6_addr), rtflags, error)); 1684 } 1685 1686 if (rt != NULL) 1687 rtunref(rt); 1688 1689 if (rtlocked == 0) 1690 lck_mtx_unlock(rt_mtx); 1691 return(error); 1692} 1693 1694int 1695nd6_prefix_offlink( 1696 struct nd_prefix *pr) 1697{ 1698 int error = 0; 1699 struct ifnet *ifp = pr->ndpr_ifp; 1700 struct nd_prefix *opr; 1701 struct sockaddr_in6 sa6, mask6; 1702 struct rtentry *rt = NULL; 1703 1704 /* sanity check */ 1705 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1706 nd6log((LOG_ERR, 1707 "nd6_prefix_offlink: %s/%d is already off-link\n", 1708 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen)); 1709 return(EEXIST); 1710 } 1711 1712 bzero(&sa6, sizeof(sa6)); 1713 sa6.sin6_family = AF_INET6; 1714 sa6.sin6_len = sizeof(sa6); 1715 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr, 1716 sizeof(struct in6_addr)); 1717 bzero(&mask6, sizeof(mask6)); 1718 mask6.sin6_family = AF_INET6; 1719 mask6.sin6_len = sizeof(sa6); 1720 bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); 1721 lck_mtx_lock(rt_mtx); 1722 error = rtrequest_locked(RTM_DELETE, (struct sockaddr *)&sa6, NULL, 1723 (struct sockaddr *)&mask6, 0, &rt); 1724 if (error == 0) { 1725 pr->ndpr_stateflags &= ~NDPRF_ONLINK; 1726 1727 /* report the route deletion to the routing socket. */ 1728 if (rt != NULL) 1729 nd6_rtmsg(RTM_DELETE, rt); 1730 1731 /* 1732 * There might be the same prefix on another interface, 1733 * the prefix which could not be on-link just because we have 1734 * the interface route (see comments in nd6_prefix_onlink). 1735 * If there's one, try to make the prefix on-link on the 1736 * interface. 1737 */ 1738 lck_mtx_assert(nd6_mutex, LCK_MTX_ASSERT_OWNED); 1739 for (opr = nd_prefix.lh_first; opr; opr = opr->ndpr_next) { 1740 if (opr == pr) 1741 continue; 1742 1743 if ((opr->ndpr_stateflags & NDPRF_ONLINK) != 0) 1744 continue; 1745 1746 /* 1747 * KAME specific: detached prefixes should not be 1748 * on-link. 1749 */ 1750 if ((opr->ndpr_stateflags & NDPRF_DETACHED) != 0) 1751 continue; 1752 1753 if (opr->ndpr_plen == pr->ndpr_plen && 1754 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 1755 &opr->ndpr_prefix.sin6_addr, 1756 pr->ndpr_plen)) { 1757 int e; 1758 1759 if ((e = nd6_prefix_onlink(opr, 1, 1)) != 0) { 1760 nd6log((LOG_ERR, 1761 "nd6_prefix_offlink: failed to " 1762 "recover a prefix %s/%d from %s " 1763 "to %s (errno = %d)\n", 1764 ip6_sprintf(&opr->ndpr_prefix.sin6_addr), 1765 opr->ndpr_plen, if_name(ifp), 1766 if_name(opr->ndpr_ifp), e)); 1767 } 1768 } 1769 } 1770 } 1771 else { 1772 /* XXX: can we still set the NDPRF_ONLINK flag? */ 1773 nd6log((LOG_ERR, 1774 "nd6_prefix_offlink: failed to delete route: " 1775 "%s/%d on %s (errno = %d)\n", 1776 ip6_sprintf(&sa6.sin6_addr), pr->ndpr_plen, if_name(ifp), 1777 error)); 1778 } 1779 1780 if (rt != NULL) 1781 rtfree_locked(rt); 1782 1783 lck_mtx_unlock(rt_mtx); 1784 1785 return(error); 1786} 1787 1788static struct in6_ifaddr * 1789in6_ifadd( 1790 struct nd_prefix *pr, 1791 struct in6_addr *ifid) /* Mobile IPv6 addition */ 1792{ 1793 struct ifnet *ifp = pr->ndpr_ifp; 1794 struct ifaddr *ifa; 1795 struct in6_aliasreq ifra; 1796 struct in6_ifaddr *ia, *ib; 1797 int error, plen0; 1798 struct in6_addr mask; 1799 int prefixlen = pr->ndpr_plen; 1800 1801 in6_len2mask(&mask, prefixlen); 1802 1803 /* 1804 * find a link-local address (will be interface ID). 1805 * Is it really mandatory? Theoretically, a global or a site-local 1806 * address can be configured without a link-local address, if we 1807 * have a unique interface identifier... 1808 * 1809 * it is not mandatory to have a link-local address, we can generate 1810 * interface identifier on the fly. we do this because: 1811 * (1) it should be the easiest way to find interface identifier. 1812 * (2) RFC2462 5.4 suggesting the use of the same interface identifier 1813 * for multiple addresses on a single interface, and possible shortcut 1814 * of DAD. we omitted DAD for this reason in the past. 1815 * (3) a user can prevent autoconfiguration of global address 1816 * by removing link-local address by hand (this is partly because we 1817 * don't have other way to control the use of IPv6 on a interface. 1818 * this has been our design choice - cf. NRL's "ifconfig auto"). 1819 * (4) it is easier to manage when an interface has addresses 1820 * with the same interface identifier, than to have multiple addresses 1821 * with different interface identifiers. 1822 * 1823 * Mobile IPv6 addition: allow for caller to specify a wished interface 1824 * ID. This is to not break connections when moving addresses between 1825 * interfaces. 1826 */ 1827 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0);/* 0 is OK? */ 1828 if (ifa) 1829 ib = (struct in6_ifaddr *)ifa; 1830 else 1831 return NULL; 1832 1833#if 0 /* don't care link local addr state, and always do DAD */ 1834 /* if link-local address is not eligible, do not autoconfigure. */ 1835 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) { 1836 printf("in6_ifadd: link-local address not ready\n"); 1837 return NULL; 1838 } 1839#endif 1840 1841 /* prefixlen + ifidlen must be equal to 128 */ 1842 plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL); 1843 if (prefixlen != plen0) { 1844 nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s " 1845 "(prefix=%d ifid=%d)\n", 1846 if_name(ifp), prefixlen, 128 - plen0)); 1847 return NULL; 1848 } 1849 1850 /* make ifaddr */ 1851 1852 bzero(&ifra, sizeof(ifra)); 1853 /* 1854 * in6_update_ifa() does not use ifra_name, but we accurately set it 1855 * for safety. 1856 */ 1857 strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name)); 1858 ifra.ifra_addr.sin6_family = AF_INET6; 1859 ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6); 1860 /* prefix */ 1861 bcopy(&pr->ndpr_prefix.sin6_addr, &ifra.ifra_addr.sin6_addr, 1862 sizeof(ifra.ifra_addr.sin6_addr)); 1863 ifra.ifra_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0]; 1864 ifra.ifra_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1]; 1865 ifra.ifra_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2]; 1866 ifra.ifra_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3]; 1867 1868 /* interface ID */ 1869 if (ifid == NULL || IN6_IS_ADDR_UNSPECIFIED(ifid)) 1870 ifid = &ib->ia_addr.sin6_addr; 1871 ifra.ifra_addr.sin6_addr.s6_addr32[0] 1872 |= (ifid->s6_addr32[0] & ~mask.s6_addr32[0]); 1873 ifra.ifra_addr.sin6_addr.s6_addr32[1] 1874 |= (ifid->s6_addr32[1] & ~mask.s6_addr32[1]); 1875 ifra.ifra_addr.sin6_addr.s6_addr32[2] 1876 |= (ifid->s6_addr32[2] & ~mask.s6_addr32[2]); 1877 ifra.ifra_addr.sin6_addr.s6_addr32[3] 1878 |= (ifid->s6_addr32[3] & ~mask.s6_addr32[3]); 1879 1880 /* new prefix mask. */ 1881 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6); 1882 ifra.ifra_prefixmask.sin6_family = AF_INET6; 1883 bcopy(&mask, &ifra.ifra_prefixmask.sin6_addr, 1884 sizeof(ifra.ifra_prefixmask.sin6_addr)); 1885 1886 /* 1887 * lifetime. 1888 * XXX: in6_init_address_ltimes would override these values later. 1889 * We should reconsider this logic. 1890 */ 1891 ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime; 1892 ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime; 1893 1894 /* XXX: scope zone ID? */ 1895 1896 ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */ 1897 /* 1898 * temporarily set the nopfx flag to avoid conflict. 1899 * XXX: we should reconsider the entire mechanism about prefix 1900 * manipulation. 1901 */ 1902 ifra.ifra_flags |= IN6_IFF_NOPFX; 1903 1904 /* 1905 * keep the new address, regardless of the result of in6_update_ifa. 1906 * XXX: this address is now meaningless. 1907 * We should reconsider its role. 1908 */ 1909 pr->ndpr_addr = ifra.ifra_addr.sin6_addr; 1910 1911 /* allocate ifaddr structure, link into chain, etc. */ 1912 if ((error = in6_update_ifa(ifp, &ifra, NULL)) != 0) { 1913 nd6log((LOG_ERR, 1914 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n", 1915 ip6_sprintf(&ifra.ifra_addr.sin6_addr), if_name(ifp), 1916 error)); 1917 return(NULL); /* ifaddr must not have been allocated. */ 1918 } 1919 1920 ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr); 1921 1922 in6_post_msg(ifp, KEV_INET6_NEW_RTADV_ADDR, ia); 1923 1924 return(ia); /* this must NOT be NULL. */ 1925} 1926 1927int 1928in6_tmpifadd( 1929 const struct in6_ifaddr *ia0, /* corresponding public address */ 1930 int forcegen) 1931{ 1932 struct ifnet *ifp = ia0->ia_ifa.ifa_ifp; 1933 struct in6_ifaddr *newia; 1934 struct in6_aliasreq ifra; 1935 int i, error; 1936 int trylimit = 3; /* XXX: adhoc value */ 1937 u_int32_t randid[2]; 1938 time_t vltime0, pltime0; 1939 struct timeval timenow; 1940 1941 getmicrotime(&timenow); 1942 1943 bzero(&ifra, sizeof(ifra)); 1944 strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name)); 1945 ifra.ifra_addr = ia0->ia_addr; 1946 /* copy prefix mask */ 1947 ifra.ifra_prefixmask = ia0->ia_prefixmask; 1948 /* clear the old IFID */ 1949 for (i = 0; i < 4; i++) { 1950 ifra.ifra_addr.sin6_addr.s6_addr32[i] 1951 &= ifra.ifra_prefixmask.sin6_addr.s6_addr32[i]; 1952 } 1953 1954 again: 1955 in6_get_tmpifid(ifp, (u_int8_t *)randid, 1956 (const u_int8_t *)&ia0->ia_addr.sin6_addr.s6_addr[8], 1957 forcegen); 1958 ifra.ifra_addr.sin6_addr.s6_addr32[2] 1959 |= (randid[0] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[2])); 1960 ifra.ifra_addr.sin6_addr.s6_addr32[3] 1961 |= (randid[1] & ~(ifra.ifra_prefixmask.sin6_addr.s6_addr32[3])); 1962 1963 /* 1964 * If by chance the new temporary address is the same as an address 1965 * already assigned to the interface, generate a new randomized 1966 * interface identifier and repeat this step. 1967 * RFC 3041 3.3 (4). 1968 */ 1969 if (in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr) != NULL) { 1970 if (trylimit-- == 0) { 1971 nd6log((LOG_NOTICE, "in6_tmpifadd: failed to find " 1972 "a unique random IFID\n")); 1973 return(EEXIST); 1974 } 1975 forcegen = 1; 1976 goto again; 1977 } 1978 1979 /* 1980 * The Valid Lifetime is the lower of the Valid Lifetime of the 1981 * public address or TEMP_VALID_LIFETIME. 1982 * The Preferred Lifetime is the lower of the Preferred Lifetime 1983 * of the public address or TEMP_PREFERRED_LIFETIME - 1984 * DESYNC_FACTOR. 1985 */ 1986 if (ia0->ia6_lifetime.ia6t_expire != 0) { 1987 vltime0 = IFA6_IS_INVALID(ia0) ? 0 : 1988 (ia0->ia6_lifetime.ia6t_expire - timenow.tv_sec); 1989 if (vltime0 > ip6_temp_valid_lifetime) 1990 vltime0 = ip6_temp_valid_lifetime; 1991 } else 1992 vltime0 = ip6_temp_valid_lifetime; 1993 if (ia0->ia6_lifetime.ia6t_preferred != 0) { 1994 pltime0 = IFA6_IS_DEPRECATED(ia0) ? 0 : 1995 (ia0->ia6_lifetime.ia6t_preferred - timenow.tv_sec); 1996 if (pltime0 > ip6_temp_preferred_lifetime - ip6_desync_factor){ 1997 pltime0 = ip6_temp_preferred_lifetime - 1998 ip6_desync_factor; 1999 } 2000 } else 2001 pltime0 = ip6_temp_preferred_lifetime - ip6_desync_factor; 2002 ifra.ifra_lifetime.ia6t_vltime = vltime0; 2003 ifra.ifra_lifetime.ia6t_pltime = pltime0; 2004 2005 /* 2006 * A temporary address is created only if this calculated Preferred 2007 * Lifetime is greater than REGEN_ADVANCE time units. 2008 */ 2009 if (ifra.ifra_lifetime.ia6t_pltime <= ip6_temp_regen_advance) 2010 return(0); 2011 2012 /* XXX: scope zone ID? */ 2013 2014 ifra.ifra_flags |= (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY); 2015 2016 /* allocate ifaddr structure, link into chain, etc. */ 2017 if ((error = in6_update_ifa(ifp, &ifra, NULL)) != 0) 2018 return(error); 2019 2020 newia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr); 2021 if (newia == NULL) { /* XXX: can it happen? */ 2022 nd6log((LOG_ERR, 2023 "in6_tmpifadd: ifa update succeeded, but we got " 2024 "no ifaddr\n")); 2025 return(EINVAL); /* XXX */ 2026 } 2027 lck_mtx_lock(nd6_mutex); 2028 newia->ia6_ndpr = ia0->ia6_ndpr; 2029 newia->ia6_ndpr->ndpr_refcnt++; 2030 2031 /* 2032 * A newly added address might affect the status of other addresses. 2033 * XXX: when the temporary address is generated with a new public 2034 * address, the onlink check is redundant. However, it would be safe 2035 * to do the check explicitly everywhere a new address is generated, 2036 * and, in fact, we surely need the check when we create a new 2037 * temporary address due to deprecation of an old temporary address. 2038 */ 2039 pfxlist_onlink_check(1); 2040 lck_mtx_unlock(nd6_mutex); 2041 2042 return(0); 2043} 2044 2045int 2046in6_init_prefix_ltimes(struct nd_prefix *ndpr) 2047{ 2048 struct timeval timenow; 2049 2050 getmicrotime(&timenow); 2051 /* check if preferred lifetime > valid lifetime. RFC2462 5.5.3 (c) */ 2052 if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) { 2053 nd6log((LOG_INFO, "in6_init_prefix_ltimes: preferred lifetime" 2054 "(%d) is greater than valid lifetime(%d)\n", 2055 (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime)); 2056 return (EINVAL); 2057 } 2058 if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME) 2059 ndpr->ndpr_preferred = 0; 2060 else 2061 ndpr->ndpr_preferred = timenow.tv_sec + ndpr->ndpr_pltime; 2062 if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME) 2063 ndpr->ndpr_expire = 0; 2064 else 2065 ndpr->ndpr_expire = timenow.tv_sec + ndpr->ndpr_vltime; 2066 2067 return 0; 2068} 2069 2070static void 2071in6_init_address_ltimes(__unused struct nd_prefix *new, struct in6_addrlifetime *lt6) 2072{ 2073 struct timeval timenow; 2074 2075 getmicrotime(&timenow); 2076 /* Valid lifetime must not be updated unless explicitly specified. */ 2077 /* init ia6t_expire */ 2078 if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME) 2079 lt6->ia6t_expire = 0; 2080 else { 2081 lt6->ia6t_expire = timenow.tv_sec; 2082 lt6->ia6t_expire += lt6->ia6t_vltime; 2083 } 2084 2085 /* init ia6t_preferred */ 2086 if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME) 2087 lt6->ia6t_preferred = 0; 2088 else { 2089 lt6->ia6t_preferred = timenow.tv_sec; 2090 lt6->ia6t_preferred += lt6->ia6t_pltime; 2091 } 2092} 2093 2094/* 2095 * Delete all the routing table entries that use the specified gateway. 2096 * XXX: this function causes search through all entries of routing table, so 2097 * it shouldn't be called when acting as a router. 2098 */ 2099void 2100rt6_flush( 2101 struct in6_addr *gateway, 2102 struct ifnet *ifp) 2103{ 2104 struct radix_node_head *rnh = rt_tables[AF_INET6]; 2105 2106 /* We'll care only link-local addresses */ 2107 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) { 2108 return; 2109 } 2110 lck_mtx_lock(rt_mtx); 2111 /* XXX: hack for KAME's link-local address kludge */ 2112 gateway->s6_addr16[1] = htons(ifp->if_index); 2113 2114 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway); 2115 lck_mtx_unlock(rt_mtx); 2116} 2117 2118static int 2119rt6_deleteroute( 2120 struct radix_node *rn, 2121 void *arg) 2122{ 2123#define SIN6(s) ((struct sockaddr_in6 *)s) 2124 struct rtentry *rt = (struct rtentry *)rn; 2125 struct in6_addr *gate = (struct in6_addr *)arg; 2126 2127 lck_mtx_assert(rt_mtx, LCK_MTX_ASSERT_OWNED); 2128 2129 if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) 2130 return(0); 2131 2132 if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) 2133 return(0); 2134 2135 /* 2136 * Do not delete a static route. 2137 * XXX: this seems to be a bit ad-hoc. Should we consider the 2138 * 'cloned' bit instead? 2139 */ 2140 if ((rt->rt_flags & RTF_STATIC) != 0) 2141 return(0); 2142 2143 /* 2144 * We delete only host route. This means, in particular, we don't 2145 * delete default route. 2146 */ 2147 if ((rt->rt_flags & RTF_HOST) == 0) 2148 return(0); 2149 2150 return(rtrequest_locked(RTM_DELETE, rt_key(rt), 2151 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0)); 2152#undef SIN6 2153} 2154 2155int 2156nd6_setdefaultiface( 2157 int ifindex) 2158{ 2159 int error = 0; 2160 2161 if (ifindex < 0 || if_index < ifindex) 2162 return(EINVAL); 2163 2164 lck_mtx_lock(nd6_mutex); 2165 if (nd6_defifindex != ifindex) { 2166 nd6_defifindex = ifindex; 2167 if (nd6_defifindex > 0) 2168 nd6_defifp = ifindex2ifnet[nd6_defifindex]; 2169 else 2170 nd6_defifp = NULL; 2171 2172 /* 2173 * If the Default Router List is empty, install a route 2174 * to the specified interface as default or remove the default 2175 * route when the default interface becomes canceled. 2176 * The check for the queue is actually redundant, but 2177 * we do this here to avoid re-install the default route 2178 * if the list is NOT empty. 2179 */ 2180 if (TAILQ_FIRST(&nd_defrouter) == NULL) 2181 defrouter_select(); 2182 2183 /* 2184 * Our current implementation assumes one-to-one maping between 2185 * interfaces and links, so it would be natural to use the 2186 * default interface as the default link. 2187 */ 2188 scope6_setdefault(nd6_defifp); 2189 } 2190 2191 lck_mtx_unlock(nd6_mutex); 2192 return(error); 2193} 2194