1 /* $OpenBSD: nd6_rtr.c,v 1.50 2009/01/30 11:56:59 rainer Exp $ */ 2 /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/malloc.h> 36 #include <sys/mbuf.h> 37 #include <sys/socket.h> 38 #include <sys/sockio.h> 39 #include <sys/time.h> 40 #include <sys/kernel.h> 41 #include <sys/errno.h> 42 #include <sys/ioctl.h> 43 #include <sys/syslog.h> 44 #include <sys/queue.h> 45 #include <dev/rndvar.h> 46 47 #include <net/if.h> 48 #include <net/if_types.h> 49 #include <net/if_dl.h> 50 #include <net/route.h> 51 #include <net/radix.h> 52 53 #include <netinet/in.h> 54 #include <netinet6/in6_var.h> 55 #include <netinet/ip6.h> 56 #include <netinet6/ip6_var.h> 57 #include <netinet6/nd6.h> 58 #include <netinet/icmp6.h> 59 60 #define SDL(s) ((struct sockaddr_dl *)s) 61 62 static int rtpref(struct nd_defrouter *); 63 static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *); 64 static struct in6_ifaddr *in6_ifadd(struct nd_prefix *); 65 static struct nd_pfxrouter *pfxrtr_lookup(struct nd_prefix *, 66 struct nd_defrouter *); 67 static void pfxrtr_add(struct nd_prefix *, struct nd_defrouter *); 68 static void pfxrtr_del(struct nd_pfxrouter *); 69 static struct nd_pfxrouter *find_pfxlist_reachable_router(struct nd_prefix *); 70 static void defrouter_delreq(struct nd_defrouter *); 71 static void nd6_rtmsg(int, struct rtentry *); 72 static void purge_detached(struct ifnet *); 73 74 static void in6_init_address_ltimes(struct nd_prefix *, 75 struct in6_addrlifetime *); 76 77 static int rt6_deleteroute(struct radix_node *, void *); 78 79 extern int nd6_recalc_reachtm_interval; 80 81 static struct ifnet *nd6_defifp; 82 int nd6_defifindex; 83 84 /* 85 * Receive Router Solicitation Message - just for routers. 86 * Router solicitation/advertisement is mostly managed by userland program 87 * (rtadvd) so here we have no function like nd6_ra_output(). 88 * 89 * Based on RFC 2461 90 */ 91 void 92 nd6_rs_input(struct mbuf *m, int off, int icmp6len) 93 { 94 struct ifnet *ifp = m->m_pkthdr.rcvif; 95 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 96 struct nd_router_solicit *nd_rs; 97 struct in6_addr saddr6 = ip6->ip6_src; 98 #if 0 99 struct in6_addr daddr6 = ip6->ip6_dst; 100 #endif 101 char *lladdr = NULL; 102 int lladdrlen = 0; 103 #if 0 104 struct sockaddr_dl *sdl = (struct sockaddr_dl *)NULL; 105 struct llinfo_nd6 *ln = (struct llinfo_nd6 *)NULL; 106 struct rtentry *rt = NULL; 107 int is_newentry; 108 #endif 109 union nd_opts ndopts; 110 111 /* If I'm not a router, ignore it. */ 112 if (ip6_accept_rtadv != 0 || !ip6_forwarding) 113 goto freeit; 114 115 /* Sanity checks */ 116 if (ip6->ip6_hlim != 255) { 117 nd6log((LOG_ERR, 118 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n", 119 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 120 ip6_sprintf(&ip6->ip6_dst), ifp->if_xname)); 121 goto bad; 122 } 123 124 /* 125 * Don't update the neighbor cache, if src = ::. 126 * This indicates that the src has no IP address assigned yet. 127 */ 128 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) 129 goto freeit; 130 131 IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len); 132 if (nd_rs == NULL) { 133 icmp6stat.icp6s_tooshort++; 134 return; 135 } 136 137 icmp6len -= sizeof(*nd_rs); 138 nd6_option_init(nd_rs + 1, icmp6len, &ndopts); 139 if (nd6_options(&ndopts) < 0) { 140 nd6log((LOG_INFO, 141 "nd6_rs_input: invalid ND option, ignored\n")); 142 /* nd6_options have incremented stats */ 143 goto freeit; 144 } 145 146 if (ndopts.nd_opts_src_lladdr) { 147 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 148 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 149 } 150 151 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 152 nd6log((LOG_INFO, 153 "nd6_rs_input: lladdrlen mismatch for %s " 154 "(if %d, RS packet %d)\n", 155 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2)); 156 goto bad; 157 } 158 159 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0); 160 161 freeit: 162 m_freem(m); 163 return; 164 165 bad: 166 icmp6stat.icp6s_badrs++; 167 m_freem(m); 168 } 169 170 /* 171 * Receive Router Advertisement Message. 172 * 173 * Based on RFC 2461 174 * TODO: on-link bit on prefix information 175 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing 176 */ 177 void 178 nd6_ra_input(struct mbuf *m, int off, int icmp6len) 179 { 180 struct ifnet *ifp = m->m_pkthdr.rcvif; 181 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 182 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 183 struct nd_router_advert *nd_ra; 184 struct in6_addr saddr6 = ip6->ip6_src; 185 #if 0 186 struct in6_addr daddr6 = ip6->ip6_dst; 187 int flags; /* = nd_ra->nd_ra_flags_reserved; */ 188 int is_managed = ((flags & ND_RA_FLAG_MANAGED) != 0); 189 int is_other = ((flags & ND_RA_FLAG_OTHER) != 0); 190 #endif 191 union nd_opts ndopts; 192 struct nd_defrouter *dr; 193 194 /* 195 * We only accept RAs only when 196 * the system-wide variable allows the acceptance, and 197 * per-interface variable allows RAs on the receiving interface. 198 */ 199 if (ip6_accept_rtadv == 0) 200 goto freeit; 201 if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) 202 goto freeit; 203 204 if (ip6->ip6_hlim != 255) { 205 nd6log((LOG_ERR, 206 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", 207 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 208 ip6_sprintf(&ip6->ip6_dst), ifp->if_xname)); 209 goto bad; 210 } 211 212 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { 213 nd6log((LOG_ERR, 214 "nd6_ra_input: src %s is not link-local\n", 215 ip6_sprintf(&saddr6))); 216 goto bad; 217 } 218 219 IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len); 220 if (nd_ra == NULL) { 221 icmp6stat.icp6s_tooshort++; 222 return; 223 } 224 225 icmp6len -= sizeof(*nd_ra); 226 nd6_option_init(nd_ra + 1, icmp6len, &ndopts); 227 if (nd6_options(&ndopts) < 0) { 228 nd6log((LOG_INFO, 229 "nd6_ra_input: invalid ND option, ignored\n")); 230 /* nd6_options have incremented stats */ 231 goto freeit; 232 } 233 234 { 235 struct nd_defrouter dr0; 236 u_int32_t advreachable = nd_ra->nd_ra_reachable; 237 238 Bzero(&dr0, sizeof(dr0)); 239 dr0.rtaddr = saddr6; 240 dr0.flags = nd_ra->nd_ra_flags_reserved; 241 dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime); 242 dr0.expire = time_second + dr0.rtlifetime; 243 dr0.ifp = ifp; 244 /* unspecified or not? (RFC 2461 6.3.4) */ 245 if (advreachable) { 246 NTOHL(advreachable); 247 if (advreachable <= MAX_REACHABLE_TIME && 248 ndi->basereachable != advreachable) { 249 ndi->basereachable = advreachable; 250 ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable); 251 ndi->recalctm = nd6_recalc_reachtm_interval; /* reset */ 252 } 253 } 254 if (nd_ra->nd_ra_retransmit) 255 ndi->retrans = ntohl(nd_ra->nd_ra_retransmit); 256 if (nd_ra->nd_ra_curhoplimit) 257 ndi->chlim = nd_ra->nd_ra_curhoplimit; 258 dr = defrtrlist_update(&dr0); 259 } 260 261 /* 262 * prefix 263 */ 264 if (ndopts.nd_opts_pi) { 265 struct nd_opt_hdr *pt; 266 struct nd_opt_prefix_info *pi = NULL; 267 struct nd_prefix pr; 268 269 for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi; 270 pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end; 271 pt = (struct nd_opt_hdr *)((caddr_t)pt + 272 (pt->nd_opt_len << 3))) { 273 if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION) 274 continue; 275 pi = (struct nd_opt_prefix_info *)pt; 276 277 if (pi->nd_opt_pi_len != 4) { 278 nd6log((LOG_INFO, 279 "nd6_ra_input: invalid option " 280 "len %d for prefix information option, " 281 "ignored\n", pi->nd_opt_pi_len)); 282 continue; 283 } 284 285 if (128 < pi->nd_opt_pi_prefix_len) { 286 nd6log((LOG_INFO, 287 "nd6_ra_input: invalid prefix " 288 "len %d for prefix information option, " 289 "ignored\n", pi->nd_opt_pi_prefix_len)); 290 continue; 291 } 292 293 if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) 294 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) { 295 nd6log((LOG_INFO, 296 "nd6_ra_input: invalid prefix " 297 "%s, ignored\n", 298 ip6_sprintf(&pi->nd_opt_pi_prefix))); 299 continue; 300 } 301 302 /* aggregatable unicast address, rfc2374 */ 303 if ((pi->nd_opt_pi_prefix.s6_addr8[0] & 0xe0) == 0x20 304 && pi->nd_opt_pi_prefix_len != 64) { 305 nd6log((LOG_INFO, 306 "nd6_ra_input: invalid prefixlen " 307 "%d for rfc2374 prefix %s, ignored\n", 308 pi->nd_opt_pi_prefix_len, 309 ip6_sprintf(&pi->nd_opt_pi_prefix))); 310 continue; 311 } 312 313 bzero(&pr, sizeof(pr)); 314 pr.ndpr_prefix.sin6_family = AF_INET6; 315 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix); 316 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix; 317 pr.ndpr_ifp = (struct ifnet *)m->m_pkthdr.rcvif; 318 319 pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved & 320 ND_OPT_PI_FLAG_ONLINK) ? 1 : 0; 321 pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved & 322 ND_OPT_PI_FLAG_AUTO) ? 1 : 0; 323 pr.ndpr_plen = pi->nd_opt_pi_prefix_len; 324 pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); 325 pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time); 326 pr.ndpr_lastupdate = time_second; 327 328 if (in6_init_prefix_ltimes(&pr)) 329 continue; /* prefix lifetime init failed */ 330 331 (void)prelist_update(&pr, dr, m); 332 } 333 } 334 335 /* 336 * MTU 337 */ 338 if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) { 339 u_long mtu; 340 u_long maxmtu; 341 342 mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); 343 344 /* lower bound */ 345 if (mtu < IPV6_MMTU) { 346 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option " 347 "mtu=%lu sent from %s, ignoring\n", 348 mtu, ip6_sprintf(&ip6->ip6_src))); 349 goto skip; 350 } 351 352 /* upper bound */ 353 maxmtu = (ndi->maxmtu && ndi->maxmtu < ifp->if_mtu) 354 ? ndi->maxmtu : ifp->if_mtu; 355 if (mtu <= maxmtu) { 356 int change = (ndi->linkmtu != mtu); 357 358 ndi->linkmtu = mtu; 359 if (change) /* in6_maxmtu may change */ 360 in6_setmaxmtu(); 361 } else { 362 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu " 363 "mtu=%lu sent from %s; " 364 "exceeds maxmtu %lu, ignoring\n", 365 mtu, ip6_sprintf(&ip6->ip6_src), maxmtu)); 366 } 367 } 368 369 skip: 370 371 /* 372 * Source link layer address 373 */ 374 { 375 char *lladdr = NULL; 376 int lladdrlen = 0; 377 378 if (ndopts.nd_opts_src_lladdr) { 379 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 380 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 381 } 382 383 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 384 nd6log((LOG_INFO, 385 "nd6_ra_input: lladdrlen mismatch for %s " 386 "(if %d, RA packet %d)\n", ip6_sprintf(&saddr6), 387 ifp->if_addrlen, lladdrlen - 2)); 388 goto bad; 389 } 390 391 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_ADVERT, 0); 392 393 /* 394 * Installing a link-layer address might change the state of the 395 * router's neighbor cache, which might also affect our on-link 396 * detection of adveritsed prefixes. 397 */ 398 pfxlist_onlink_check(); 399 } 400 401 freeit: 402 m_freem(m); 403 return; 404 405 bad: 406 icmp6stat.icp6s_badra++; 407 m_freem(m); 408 } 409 410 /* 411 * default router list processing sub routines 412 */ 413 414 /* tell the change to user processes watching the routing socket. */ 415 static void 416 nd6_rtmsg(int cmd, struct rtentry *rt) 417 { 418 struct rt_addrinfo info; 419 420 bzero((caddr_t)&info, sizeof(info)); 421 info.rti_info[RTAX_DST] = rt_key(rt); 422 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 423 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 424 if (rt->rt_ifp) { 425 info.rti_info[RTAX_IFP] = 426 TAILQ_FIRST(&rt->rt_ifp->if_addrlist)->ifa_addr; 427 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 428 } 429 430 rt_missmsg(cmd, &info, rt->rt_flags, rt->rt_ifp, 0, 0); 431 } 432 433 void 434 defrouter_addreq(struct nd_defrouter *new) 435 { 436 struct rt_addrinfo info; 437 struct sockaddr_in6 def, mask, gate; 438 struct rtentry *newrt = NULL; 439 int s; 440 int error; 441 442 Bzero(&def, sizeof(def)); 443 Bzero(&mask, sizeof(mask)); 444 Bzero(&gate, sizeof(gate)); /* for safety */ 445 Bzero(&info, sizeof(info)); 446 447 def.sin6_len = mask.sin6_len = gate.sin6_len = 448 sizeof(struct sockaddr_in6); 449 def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6; 450 gate.sin6_addr = new->rtaddr; 451 gate.sin6_scope_id = 0; /* XXX */ 452 453 info.rti_flags = RTF_GATEWAY; 454 info.rti_info[RTAX_DST] = (struct sockaddr *)&def; 455 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gate; 456 info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; 457 458 s = splsoftnet(); 459 error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &newrt, 0); 460 if (newrt) { 461 nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ 462 newrt->rt_refcnt--; 463 } 464 if (error == 0) 465 new->installed = 1; 466 splx(s); 467 return; 468 } 469 470 struct nd_defrouter * 471 defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp) 472 { 473 struct nd_defrouter *dr; 474 475 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 476 dr = TAILQ_NEXT(dr, dr_entry)) { 477 if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) { 478 return (dr); 479 } 480 } 481 482 return (NULL); /* search failed */ 483 } 484 485 void 486 defrtrlist_del(dr) 487 struct nd_defrouter *dr; 488 { 489 struct nd_defrouter *deldr = NULL; 490 struct in6_ifextra *ext = dr->ifp->if_afdata[AF_INET6]; 491 struct nd_prefix *pr; 492 493 /* 494 * Flush all the routing table entries that use the router 495 * as a next hop. 496 */ 497 if (!ip6_forwarding && ip6_accept_rtadv) /* XXX: better condition? */ 498 rt6_flush(&dr->rtaddr, dr->ifp); 499 500 if (dr->installed) { 501 deldr = dr; 502 defrouter_delreq(dr); 503 } 504 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); 505 506 /* 507 * Also delete all the pointers to the router in each prefix lists. 508 */ 509 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 510 struct nd_pfxrouter *pfxrtr; 511 if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL) 512 pfxrtr_del(pfxrtr); 513 } 514 pfxlist_onlink_check(); 515 516 /* 517 * If the router is the primary one, choose a new one. 518 * Note that defrouter_select() will remove the current gateway 519 * from the routing table. 520 */ 521 if (deldr) 522 defrouter_select(); 523 524 ext->ndefrouters--; 525 if (ext->ndefrouters < 0) { 526 log(LOG_WARNING, "defrtrlist_del: negative count on %s\n", 527 dr->ifp->if_xname); 528 } 529 530 free(dr, M_IP6NDP); 531 } 532 533 /* 534 * Remove the default route for a given router. 535 * This is just a subroutine function for defrouter_select(), and should 536 * not be called from anywhere else. 537 */ 538 static void 539 defrouter_delreq(struct nd_defrouter *dr) 540 { 541 struct rt_addrinfo info; 542 struct sockaddr_in6 def, mask, gw; 543 struct rtentry *oldrt = NULL; 544 545 #ifdef DIAGNOSTIC 546 if (!dr) 547 panic("dr == NULL in defrouter_delreq"); 548 #endif 549 550 Bzero(&info, sizeof(info)); 551 Bzero(&def, sizeof(def)); 552 Bzero(&mask, sizeof(mask)); 553 Bzero(&gw, sizeof(gw)); /* for safety */ 554 555 def.sin6_len = mask.sin6_len = gw.sin6_len = 556 sizeof(struct sockaddr_in6); 557 def.sin6_family = mask.sin6_family = gw.sin6_family = AF_INET6; 558 gw.sin6_addr = dr->rtaddr; 559 gw.sin6_scope_id = 0; /* XXX */ 560 561 info.rti_flags = RTF_GATEWAY; 562 info.rti_info[RTAX_DST] = (struct sockaddr *)&def; 563 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw; 564 info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask; 565 566 rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &oldrt, 0); 567 if (oldrt) { 568 nd6_rtmsg(RTM_DELETE, oldrt); 569 if (oldrt->rt_refcnt <= 0) { 570 /* 571 * XXX: borrowed from the RTM_DELETE case of 572 * rtrequest1(). 573 */ 574 oldrt->rt_refcnt++; 575 rtfree(oldrt); 576 } 577 } 578 579 dr->installed = 0; 580 } 581 582 /* 583 * remove all default routes from default router list 584 */ 585 void 586 defrouter_reset() 587 { 588 struct nd_defrouter *dr; 589 590 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 591 dr = TAILQ_NEXT(dr, dr_entry)) 592 defrouter_delreq(dr); 593 594 /* 595 * XXX should we also nuke any default routers in the kernel, by 596 * going through them by rtalloc1()? 597 */ 598 } 599 600 /* 601 * Default Router Selection according to Section 6.3.6 of RFC 2461 and 602 * draft-ietf-ipngwg-router-selection: 603 * 1) Routers that are reachable or probably reachable should be preferred. 604 * If we have more than one (probably) reachable router, prefer ones 605 * with the highest router preference. 606 * 2) When no routers on the list are known to be reachable or 607 * probably reachable, routers SHOULD be selected in a round-robin 608 * fashion, regardless of router preference values. 609 * 3) If the Default Router List is empty, assume that all 610 * destinations are on-link. 611 * 612 * We assume nd_defrouter is sorted by router preference value. 613 * Since the code below covers both with and without router preference cases, 614 * we do not need to classify the cases by ifdef. 615 * 616 * At this moment, we do not try to install more than one default router, 617 * even when the multipath routing is available, because we're not sure about 618 * the benefits for stub hosts comparing to the risk of making the code 619 * complicated and the possibility of introducing bugs. 620 */ 621 void 622 defrouter_select(void) 623 { 624 int s = splsoftnet(); 625 struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL; 626 struct rtentry *rt = NULL; 627 struct llinfo_nd6 *ln = NULL; 628 629 /* 630 * This function should be called only when acting as an autoconfigured 631 * host. Although the remaining part of this function is not effective 632 * if the node is not an autoconfigured host, we explicitly exclude 633 * such cases here for safety. 634 */ 635 if (ip6_forwarding || !ip6_accept_rtadv) { 636 nd6log((LOG_WARNING, 637 "defrouter_select: called unexpectedly (forwarding=%d, " 638 "accept_rtadv=%d)\n", ip6_forwarding, ip6_accept_rtadv)); 639 splx(s); 640 return; 641 } 642 643 /* 644 * Let's handle easy case (3) first: 645 * If default router list is empty, there's nothing to be done. 646 */ 647 if (!TAILQ_FIRST(&nd_defrouter)) { 648 splx(s); 649 return; 650 } 651 652 /* 653 * Search for a (probably) reachable router from the list. 654 * We just pick up the first reachable one (if any), assuming that 655 * the ordering rule of the list described in defrtrlist_update(). 656 */ 657 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 658 dr = TAILQ_NEXT(dr, dr_entry)) { 659 if (!selected_dr && 660 (rt = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) && 661 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 662 ND6_IS_LLINFO_PROBREACH(ln)) { 663 selected_dr = dr; 664 } 665 666 if (dr->installed && !installed_dr) 667 installed_dr = dr; 668 else if (dr->installed && installed_dr) { 669 /* this should not happen. warn for diagnosis. */ 670 log(LOG_ERR, "defrouter_select: more than one router" 671 " is installed\n"); 672 } 673 } 674 /* 675 * If none of the default routers was found to be reachable, 676 * round-robin the list regardless of preference. 677 * Otherwise, if we have an installed router, check if the selected 678 * (reachable) router should really be preferred to the installed one. 679 * We only prefer the new router when the old one is not reachable 680 * or when the new one has a really higher preference value. 681 */ 682 if (!selected_dr) { 683 if (!installed_dr || !TAILQ_NEXT(installed_dr, dr_entry)) 684 selected_dr = TAILQ_FIRST(&nd_defrouter); 685 else 686 selected_dr = TAILQ_NEXT(installed_dr, dr_entry); 687 } else if (installed_dr && 688 (rt = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) && 689 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 690 ND6_IS_LLINFO_PROBREACH(ln) && 691 rtpref(selected_dr) <= rtpref(installed_dr)) { 692 selected_dr = installed_dr; 693 } 694 695 /* 696 * If the selected router is different than the installed one, 697 * remove the installed router and install the selected one. 698 * Note that the selected router is never NULL here. 699 */ 700 if (installed_dr != selected_dr) { 701 if (installed_dr) 702 defrouter_delreq(installed_dr); 703 defrouter_addreq(selected_dr); 704 } 705 706 splx(s); 707 return; 708 } 709 710 /* 711 * for default router selection 712 * regards router-preference field as a 2-bit signed integer 713 */ 714 static int 715 rtpref(struct nd_defrouter *dr) 716 { 717 #ifdef RTPREF 718 switch (dr->flags & ND_RA_FLAG_RTPREF_MASK) { 719 case ND_RA_FLAG_RTPREF_HIGH: 720 return RTPREF_HIGH; 721 case ND_RA_FLAG_RTPREF_MEDIUM: 722 case ND_RA_FLAG_RTPREF_RSV: 723 return RTPREF_MEDIUM; 724 case ND_RA_FLAG_RTPREF_LOW: 725 return RTPREF_LOW; 726 default: 727 /* 728 * This case should never happen. If it did, it would mean a 729 * serious bug of kernel internal. We thus always bark here. 730 * Or, can we even panic? 731 */ 732 log(LOG_ERR, "rtpref: impossible RA flag %x", dr->flags); 733 return RTPREF_INVALID; 734 } 735 /* NOTREACHED */ 736 #else 737 return 0; 738 #endif 739 } 740 741 static struct nd_defrouter * 742 defrtrlist_update(struct nd_defrouter *new) 743 { 744 struct nd_defrouter *dr, *n; 745 struct in6_ifextra *ext = new->ifp->if_afdata[AF_INET6]; 746 int s = splsoftnet(); 747 748 if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) { 749 /* entry exists */ 750 if (new->rtlifetime == 0) { 751 defrtrlist_del(dr); 752 dr = NULL; 753 } else { 754 int oldpref = rtpref(dr); 755 756 /* override */ 757 dr->flags = new->flags; /* xxx flag check */ 758 dr->rtlifetime = new->rtlifetime; 759 dr->expire = new->expire; 760 761 if (!dr->installed) 762 defrouter_select(); 763 764 /* 765 * If the preference does not change, there's no need 766 * to sort the entries. 767 */ 768 if (rtpref(new) == oldpref) { 769 splx(s); 770 return (dr); 771 } 772 773 /* 774 * preferred router may be changed, so relocate 775 * this router. 776 * XXX: calling TAILQ_REMOVE directly is a bad manner. 777 * However, since defrtrlist_del() has many side 778 * effects, we intentionally do so here. 779 * defrouter_select() below will handle routing 780 * changes later. 781 */ 782 TAILQ_REMOVE(&nd_defrouter, dr, dr_entry); 783 n = dr; 784 goto insert; 785 } 786 splx(s); 787 return (dr); 788 } 789 790 /* entry does not exist */ 791 if (new->rtlifetime == 0) { 792 splx(s); 793 return (NULL); 794 } 795 796 if (ip6_maxifdefrouters >= 0 && 797 ext->ndefrouters >= ip6_maxifdefrouters) { 798 splx(s); 799 return (NULL); 800 } 801 802 n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO); 803 if (n == NULL) { 804 splx(s); 805 return (NULL); 806 } 807 *n = *new; 808 809 insert: 810 /* 811 * Insert the new router in the Default Router List; 812 * The Default Router List should be in the descending order 813 * of router-preference. Routers with the same preference are 814 * sorted in the arriving time order. 815 */ 816 817 /* insert at the end of the group */ 818 for (dr = TAILQ_FIRST(&nd_defrouter); dr; 819 dr = TAILQ_NEXT(dr, dr_entry)) { 820 if (rtpref(n) > rtpref(dr)) 821 break; 822 } 823 if (dr) 824 TAILQ_INSERT_BEFORE(dr, n, dr_entry); 825 else 826 TAILQ_INSERT_TAIL(&nd_defrouter, n, dr_entry); 827 828 defrouter_select(); 829 830 ext->ndefrouters++; 831 832 splx(s); 833 834 return (n); 835 } 836 837 static struct nd_pfxrouter * 838 pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr) 839 { 840 struct nd_pfxrouter *search; 841 842 LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) { 843 if (search->router == dr) 844 break; 845 } 846 847 return (search); 848 } 849 850 static void 851 pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr) 852 { 853 struct nd_pfxrouter *new; 854 855 new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO); 856 if (new == NULL) 857 return; 858 new->router = dr; 859 860 LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry); 861 862 pfxlist_onlink_check(); 863 } 864 865 static void 866 pfxrtr_del(struct nd_pfxrouter *pfr) 867 { 868 LIST_REMOVE(pfr, pfr_entry); 869 free(pfr, M_IP6NDP); 870 } 871 872 struct nd_prefix * 873 nd6_prefix_lookup(struct nd_prefix *pr) 874 { 875 struct nd_prefix *search; 876 877 LIST_FOREACH(search, &nd_prefix, ndpr_entry) { 878 if (pr->ndpr_ifp == search->ndpr_ifp && 879 pr->ndpr_plen == search->ndpr_plen && 880 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 881 &search->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { 882 break; 883 } 884 } 885 886 return (search); 887 } 888 889 static void 890 purge_detached(struct ifnet *ifp) 891 { 892 struct nd_prefix *pr, *pr_next; 893 struct in6_ifaddr *ia; 894 struct ifaddr *ifa, *ifa_next; 895 896 for (pr = nd_prefix.lh_first; pr; pr = pr_next) { 897 pr_next = pr->ndpr_next; 898 899 /* 900 * This function is called when we need to make more room for 901 * new prefixes rather than keeping old, possibly stale ones. 902 * Detached prefixes would be a good candidate; if all routers 903 * that advertised the prefix expired, the prefix is also 904 * probably stale. 905 */ 906 if (pr->ndpr_ifp != ifp || 907 IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) || 908 ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 909 !LIST_EMPTY(&pr->ndpr_advrtrs))) 910 continue; 911 912 for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa_next) { 913 ifa_next = ifa->ifa_list.tqe_next; 914 if (ifa->ifa_addr->sa_family != AF_INET6) 915 continue; 916 ia = (struct in6_ifaddr *)ifa; 917 if ((ia->ia6_flags & IN6_IFF_AUTOCONF) == 918 IN6_IFF_AUTOCONF && ia->ia6_ndpr == pr) { 919 in6_purgeaddr(ifa); 920 } 921 } 922 if (pr->ndpr_refcnt == 0) 923 prelist_remove(pr); 924 } 925 } 926 927 int 928 nd6_prelist_add(struct nd_prefix *pr, struct nd_defrouter *dr, 929 struct nd_prefix **newp) 930 { 931 struct nd_prefix *new = NULL; 932 int i, s; 933 struct in6_ifextra *ext = pr->ndpr_ifp->if_afdata[AF_INET6]; 934 935 if (ip6_maxifprefixes >= 0) { 936 if (ext->nprefixes >= ip6_maxifprefixes / 2) 937 purge_detached(pr->ndpr_ifp); 938 if (ext->nprefixes >= ip6_maxifprefixes) 939 return(ENOMEM); 940 } 941 942 new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO); 943 if (new == NULL) 944 return ENOMEM; 945 *new = *pr; 946 if (newp != NULL) 947 *newp = new; 948 949 /* initialization */ 950 LIST_INIT(&new->ndpr_advrtrs); 951 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen); 952 /* make prefix in the canonical form */ 953 for (i = 0; i < 4; i++) 954 new->ndpr_prefix.sin6_addr.s6_addr32[i] &= 955 new->ndpr_mask.s6_addr32[i]; 956 957 s = splsoftnet(); 958 /* link ndpr_entry to nd_prefix list */ 959 LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry); 960 splx(s); 961 962 /* ND_OPT_PI_FLAG_ONLINK processing */ 963 if (new->ndpr_raf_onlink) { 964 int e; 965 966 if ((e = nd6_prefix_onlink(new)) != 0) { 967 nd6log((LOG_ERR, "nd6_prelist_add: failed to make " 968 "the prefix %s/%d on-link on %s (errno=%d)\n", 969 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 970 pr->ndpr_plen, pr->ndpr_ifp->if_xname, e)); 971 /* proceed anyway. XXX: is it correct? */ 972 } 973 } 974 975 if (dr) 976 pfxrtr_add(new, dr); 977 978 ext->nprefixes++; 979 980 return 0; 981 } 982 983 void 984 prelist_remove(struct nd_prefix *pr) 985 { 986 struct nd_pfxrouter *pfr, *next; 987 int e, s; 988 struct in6_ifextra *ext = pr->ndpr_ifp->if_afdata[AF_INET6]; 989 990 /* make sure to invalidate the prefix until it is really freed. */ 991 pr->ndpr_vltime = 0; 992 pr->ndpr_pltime = 0; 993 #if 0 994 /* 995 * Though these flags are now meaningless, we'd rather keep the value 996 * not to confuse users when executing "ndp -p". 997 */ 998 pr->ndpr_raf_onlink = 0; 999 pr->ndpr_raf_auto = 0; 1000 #endif 1001 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 && 1002 (e = nd6_prefix_offlink(pr)) != 0) { 1003 nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink " 1004 "on %s, errno=%d\n", 1005 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1006 pr->ndpr_plen, pr->ndpr_ifp->if_xname, e)); 1007 /* what should we do? */ 1008 } 1009 1010 if (pr->ndpr_refcnt > 0) 1011 return; /* notice here? */ 1012 1013 s = splsoftnet(); 1014 1015 /* unlink ndpr_entry from nd_prefix list */ 1016 LIST_REMOVE(pr, ndpr_entry); 1017 1018 /* free list of routers that adversed the prefix */ 1019 for (pfr = LIST_FIRST(&pr->ndpr_advrtrs); pfr != NULL; pfr = next) { 1020 next = LIST_NEXT(pfr, pfr_entry); 1021 1022 free(pfr, M_IP6NDP); 1023 } 1024 1025 ext->nprefixes--; 1026 if (ext->nprefixes < 0) { 1027 log(LOG_WARNING, "prelist_remove: negative count on %s\n", 1028 pr->ndpr_ifp->if_xname); 1029 } 1030 splx(s); 1031 1032 free(pr, M_IP6NDP); 1033 1034 pfxlist_onlink_check(); 1035 } 1036 1037 /* 1038 * dr - may be NULL 1039 */ 1040 1041 int 1042 prelist_update(struct nd_prefix *new, struct nd_defrouter *dr, 1043 struct mbuf *m) 1044 { 1045 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL; 1046 struct ifaddr *ifa; 1047 struct ifnet *ifp = new->ndpr_ifp; 1048 struct nd_prefix *pr; 1049 int s = splsoftnet(); 1050 int error = 0; 1051 int auth; 1052 struct in6_addrlifetime lt6_tmp; 1053 1054 auth = 0; 1055 if (m) { 1056 /* 1057 * Authenticity for NA consists authentication for 1058 * both IP header and IP datagrams, doesn't it ? 1059 */ 1060 auth = ((m->m_flags & M_AUTH_AH) && (m->m_flags & M_AUTH)); 1061 } 1062 1063 if ((pr = nd6_prefix_lookup(new)) != NULL) { 1064 /* 1065 * nd6_prefix_lookup() ensures that pr and new have the same 1066 * prefix on a same interface. 1067 */ 1068 1069 /* 1070 * Update prefix information. Note that the on-link (L) bit 1071 * and the autonomous (A) bit should NOT be changed from 1 1072 * to 0. 1073 */ 1074 if (new->ndpr_raf_onlink == 1) 1075 pr->ndpr_raf_onlink = 1; 1076 if (new->ndpr_raf_auto == 1) 1077 pr->ndpr_raf_auto = 1; 1078 if (new->ndpr_raf_onlink) { 1079 pr->ndpr_vltime = new->ndpr_vltime; 1080 pr->ndpr_pltime = new->ndpr_pltime; 1081 pr->ndpr_preferred = new->ndpr_preferred; 1082 pr->ndpr_expire = new->ndpr_expire; 1083 pr->ndpr_lastupdate = new->ndpr_lastupdate; 1084 } 1085 1086 if (new->ndpr_raf_onlink && 1087 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1088 int e; 1089 1090 if ((e = nd6_prefix_onlink(pr)) != 0) { 1091 nd6log((LOG_ERR, 1092 "prelist_update: failed to make " 1093 "the prefix %s/%d on-link on %s " 1094 "(errno=%d)\n", 1095 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1096 pr->ndpr_plen, pr->ndpr_ifp->if_xname, e)); 1097 /* proceed anyway. XXX: is it correct? */ 1098 } 1099 } 1100 1101 if (dr && pfxrtr_lookup(pr, dr) == NULL) 1102 pfxrtr_add(pr, dr); 1103 } else { 1104 struct nd_prefix *newpr = NULL; 1105 1106 if (new->ndpr_vltime == 0) 1107 goto end; 1108 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0) 1109 goto end; 1110 1111 error = nd6_prelist_add(new, dr, &newpr); 1112 if (error != 0 || newpr == NULL) { 1113 nd6log((LOG_NOTICE, "prelist_update: " 1114 "nd6_prelist_add failed for %s/%d on %s " 1115 "errno=%d, returnpr=%p\n", 1116 ip6_sprintf(&new->ndpr_prefix.sin6_addr), 1117 new->ndpr_plen, new->ndpr_ifp->if_xname, 1118 error, newpr)); 1119 goto end; /* we should just give up in this case. */ 1120 } 1121 1122 /* 1123 * XXX: from the ND point of view, we can ignore a prefix 1124 * with the on-link bit being zero. However, we need a 1125 * prefix structure for references from autoconfigured 1126 * addresses. Thus, we explicitly make sure that the prefix 1127 * itself expires now. 1128 */ 1129 if (newpr->ndpr_raf_onlink == 0) { 1130 newpr->ndpr_vltime = 0; 1131 newpr->ndpr_pltime = 0; 1132 in6_init_prefix_ltimes(newpr); 1133 } 1134 1135 pr = newpr; 1136 } 1137 1138 /* 1139 * Address autoconfiguration based on Section 5.5.3 of RFC 2462. 1140 * Note that pr must be non NULL at this point. 1141 */ 1142 1143 /* 5.5.3 (a). Ignore the prefix without the A bit set. */ 1144 if (!new->ndpr_raf_auto) 1145 goto end; 1146 1147 /* 1148 * 5.5.3 (b). the link-local prefix should have been ignored in 1149 * nd6_ra_input. 1150 */ 1151 1152 /* 1153 * 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. 1154 * This should have been done in nd6_ra_input. 1155 */ 1156 1157 /* 1158 * 5.5.3 (d). If the prefix advertised does not match the prefix of an 1159 * address already in the list, and the Valid Lifetime is not 0, 1160 * form an address. Note that even a manually configured address 1161 * should reject autoconfiguration of a new address. 1162 */ 1163 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1164 struct in6_ifaddr *ifa6; 1165 int ifa_plen; 1166 u_int32_t storedlifetime; 1167 1168 if (ifa->ifa_addr->sa_family != AF_INET6) 1169 continue; 1170 1171 ifa6 = (struct in6_ifaddr *)ifa; 1172 1173 /* 1174 * Spec is not clear here, but I believe we should concentrate 1175 * on unicast (i.e. not anycast) addresses. 1176 * XXX: other ia6_flags? detached or duplicated? 1177 */ 1178 if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0) 1179 continue; 1180 1181 ifa_plen = in6_mask2len(&ifa6->ia_prefixmask.sin6_addr, NULL); 1182 if (ifa_plen != new->ndpr_plen || 1183 !in6_are_prefix_equal(&ifa6->ia_addr.sin6_addr, 1184 &new->ndpr_prefix.sin6_addr, ifa_plen)) 1185 continue; 1186 1187 if (ia6_match == NULL) /* remember the first one */ 1188 ia6_match = ifa6; 1189 1190 if ((ifa6->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1191 continue; 1192 1193 /* 1194 * An already autoconfigured address matched. Now that we 1195 * are sure there is at least one matched address, we can 1196 * proceed to 5.5.3. (e): update the lifetimes according to the 1197 * "two hours" rule and the privacy extension. 1198 */ 1199 #define TWOHOUR (120*60) 1200 /* 1201 * RFC2462 introduces the notion of StoredLifetime to the 1202 * "two hours" rule as follows: 1203 * the Lifetime associated with the previously autoconfigured 1204 * address. 1205 * Our interpretation of this definition is "the remaining 1206 * lifetime to expiration at the evaluation time". One might 1207 * be wondering if this interpretation is really conform to the 1208 * RFC, because the text can read that "Lifetimes" are never 1209 * decreased, and our definition of the "storedlifetime" below 1210 * essentially reduces the "Valid Lifetime" advertised in the 1211 * previous RA. But, this is due to the wording of the text, 1212 * and our interpretation is the same as an author's intention. 1213 * See the discussion in the IETF ipngwg ML in August 2001, 1214 * with the Subject "StoredLifetime in RFC 2462". 1215 */ 1216 lt6_tmp = ifa6->ia6_lifetime; 1217 if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) 1218 storedlifetime = ND6_INFINITE_LIFETIME; 1219 else if (time_second - ifa6->ia6_updatetime > 1220 lt6_tmp.ia6t_vltime) { 1221 /* 1222 * The case of "invalid" address. We should usually 1223 * not see this case. 1224 */ 1225 storedlifetime = 0; 1226 } else 1227 storedlifetime = lt6_tmp.ia6t_vltime - 1228 (time_second - ifa6->ia6_updatetime); 1229 if (TWOHOUR < new->ndpr_vltime || 1230 storedlifetime < new->ndpr_vltime) { 1231 lt6_tmp.ia6t_vltime = new->ndpr_vltime; 1232 } else if (storedlifetime <= TWOHOUR 1233 #if 0 1234 /* 1235 * This condition is logically redundant, so we just 1236 * omit it. 1237 * See IPng 6712, 6717, and 6721. 1238 */ 1239 && new->ndpr_vltime <= storedlifetime 1240 #endif 1241 ) { 1242 if (auth) { 1243 lt6_tmp.ia6t_vltime = new->ndpr_vltime; 1244 } 1245 } else { 1246 /* 1247 * new->ndpr_vltime <= TWOHOUR && 1248 * TWOHOUR < storedlifetime 1249 */ 1250 lt6_tmp.ia6t_vltime = TWOHOUR; 1251 } 1252 1253 /* The 2 hour rule is not imposed for preferred lifetime. */ 1254 lt6_tmp.ia6t_pltime = new->ndpr_pltime; 1255 1256 in6_init_address_ltimes(pr, <6_tmp); 1257 1258 ifa6->ia6_lifetime = lt6_tmp; 1259 ifa6->ia6_updatetime = time_second; 1260 } 1261 if (ia6_match == NULL && new->ndpr_vltime) { 1262 /* 1263 * No address matched and the valid lifetime is non-zero. 1264 * Create a new address. 1265 */ 1266 if ((ia6 = in6_ifadd(new)) != NULL) { 1267 /* 1268 * note that we should use pr (not new) for reference. 1269 */ 1270 pr->ndpr_refcnt++; 1271 ia6->ia6_ndpr = pr; 1272 1273 /* 1274 * A newly added address might affect the status 1275 * of other addresses, so we check and update it. 1276 * XXX: what if address duplication happens? 1277 */ 1278 pfxlist_onlink_check(); 1279 } else { 1280 /* just set an error. do not bark here. */ 1281 error = EADDRNOTAVAIL; /* XXX: might be unused. */ 1282 } 1283 } 1284 1285 end: 1286 splx(s); 1287 return error; 1288 } 1289 1290 /* 1291 * A supplement function used in the on-link detection below; 1292 * detect if a given prefix has a (probably) reachable advertising router. 1293 * XXX: lengthy function name... 1294 */ 1295 static struct nd_pfxrouter * 1296 find_pfxlist_reachable_router(struct nd_prefix *pr) 1297 { 1298 struct nd_pfxrouter *pfxrtr; 1299 struct rtentry *rt; 1300 struct llinfo_nd6 *ln; 1301 1302 for (pfxrtr = LIST_FIRST(&pr->ndpr_advrtrs); pfxrtr; 1303 pfxrtr = LIST_NEXT(pfxrtr, pfr_entry)) { 1304 if ((rt = nd6_lookup(&pfxrtr->router->rtaddr, 0, 1305 pfxrtr->router->ifp)) && 1306 (ln = (struct llinfo_nd6 *)rt->rt_llinfo) && 1307 ND6_IS_LLINFO_PROBREACH(ln)) 1308 break; /* found */ 1309 } 1310 1311 return (pfxrtr); 1312 } 1313 1314 /* 1315 * Check if each prefix in the prefix list has at least one available router 1316 * that advertised the prefix (a router is "available" if its neighbor cache 1317 * entry is reachable or probably reachable). 1318 * If the check fails, the prefix may be off-link, because, for example, 1319 * we have moved from the network but the lifetime of the prefix has not 1320 * expired yet. So we should not use the prefix if there is another prefix 1321 * that has an available router. 1322 * But, if there is no prefix that has an available router, we still regards 1323 * all the prefixes as on-link. This is because we can't tell if all the 1324 * routers are simply dead or if we really moved from the network and there 1325 * is no router around us. 1326 */ 1327 void 1328 pfxlist_onlink_check(void) 1329 { 1330 struct nd_prefix *pr; 1331 struct in6_ifaddr *ifa; 1332 1333 /* 1334 * Check if there is a prefix that has a reachable advertising 1335 * router. 1336 */ 1337 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 1338 if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr)) 1339 break; 1340 } 1341 if (pr != NULL || TAILQ_FIRST(&nd_defrouter) != NULL) { 1342 /* 1343 * There is at least one prefix that has a reachable router, 1344 * or at least a router which probably does not advertise 1345 * any prefixes. The latter would be the case when we move 1346 * to a new link where we have a router that does not provide 1347 * prefixes and we configure an address by hand. 1348 * Detach prefixes which have no reachable advertising 1349 * router, and attach other prefixes. 1350 */ 1351 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 1352 /* XXX: a link-local prefix should never be detached */ 1353 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1354 continue; 1355 1356 /* 1357 * we aren't interested in prefixes without the L bit 1358 * set. 1359 */ 1360 if (pr->ndpr_raf_onlink == 0) 1361 continue; 1362 1363 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1364 find_pfxlist_reachable_router(pr) == NULL) 1365 pr->ndpr_stateflags |= NDPRF_DETACHED; 1366 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && 1367 find_pfxlist_reachable_router(pr) != 0) 1368 pr->ndpr_stateflags &= ~NDPRF_DETACHED; 1369 } 1370 } else { 1371 /* there is no prefix that has a reachable router */ 1372 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 1373 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1374 continue; 1375 1376 if (pr->ndpr_raf_onlink == 0) 1377 continue; 1378 1379 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0) 1380 pr->ndpr_stateflags &= ~NDPRF_DETACHED; 1381 } 1382 } 1383 1384 /* 1385 * Remove each interface route associated with a (just) detached 1386 * prefix, and reinstall the interface route for a (just) attached 1387 * prefix. Note that all attempt of reinstallation does not 1388 * necessarily success, when a same prefix is shared among multiple 1389 * interfaces. Such cases will be handled in nd6_prefix_onlink, 1390 * so we don't have to care about them. 1391 */ 1392 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 1393 int e; 1394 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_ONLINK) != 0) { 1403 if ((e = nd6_prefix_offlink(pr)) != 0) { 1404 nd6log((LOG_ERR, 1405 "pfxlist_onlink_check: failed to " 1406 "make %s/%d offlink, errno=%d\n", 1407 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1408 pr->ndpr_plen, e)); 1409 } 1410 } 1411 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1412 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 && 1413 pr->ndpr_raf_onlink) { 1414 if ((e = nd6_prefix_onlink(pr)) != 0) { 1415 nd6log((LOG_ERR, 1416 "pfxlist_onlink_check: failed to " 1417 "make %s/%d offlink, errno=%d\n", 1418 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1419 pr->ndpr_plen, e)); 1420 } 1421 } 1422 } 1423 1424 /* 1425 * Changes on the prefix status might affect address status as well. 1426 * Make sure that all addresses derived from an attached prefix are 1427 * attached, and that all addresses derived from a detached prefix are 1428 * detached. Note, however, that a manually configured address should 1429 * always be attached. 1430 * The precise detection logic is same as the one for prefixes. 1431 */ 1432 for (ifa = in6_ifaddr; ifa; ifa = ifa->ia_next) { 1433 if (!(ifa->ia6_flags & IN6_IFF_AUTOCONF)) 1434 continue; 1435 1436 if (ifa->ia6_ndpr == NULL) { 1437 /* 1438 * This can happen when we first configure the address 1439 * (i.e. the address exists, but the prefix does not). 1440 * XXX: complicated relationships... 1441 */ 1442 continue; 1443 } 1444 1445 if (find_pfxlist_reachable_router(ifa->ia6_ndpr)) 1446 break; 1447 } 1448 if (ifa) { 1449 for (ifa = in6_ifaddr; ifa; ifa = ifa->ia_next) { 1450 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1451 continue; 1452 1453 if (ifa->ia6_ndpr == NULL) /* XXX: see above. */ 1454 continue; 1455 1456 if (find_pfxlist_reachable_router(ifa->ia6_ndpr)) 1457 ifa->ia6_flags &= ~IN6_IFF_DETACHED; 1458 else 1459 ifa->ia6_flags |= IN6_IFF_DETACHED; 1460 } 1461 } 1462 else { 1463 for (ifa = in6_ifaddr; ifa; ifa = ifa->ia_next) { 1464 if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0) 1465 continue; 1466 1467 ifa->ia6_flags &= ~IN6_IFF_DETACHED; 1468 } 1469 } 1470 } 1471 1472 int 1473 nd6_prefix_onlink(struct nd_prefix *pr) 1474 { 1475 struct rt_addrinfo info; 1476 struct ifaddr *ifa; 1477 struct ifnet *ifp = pr->ndpr_ifp; 1478 struct sockaddr_in6 mask6; 1479 struct nd_prefix *opr; 1480 u_long rtflags; 1481 int error = 0; 1482 struct rtentry *rt = NULL; 1483 1484 /* sanity check */ 1485 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1486 nd6log((LOG_ERR, 1487 "nd6_prefix_onlink: %s/%d is already on-link\n", 1488 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen)); 1489 return (EEXIST); 1490 } 1491 1492 /* 1493 * Add the interface route associated with the prefix. Before 1494 * installing the route, check if there's the same prefix on another 1495 * interface, and the prefix has already installed the interface route. 1496 * Although such a configuration is expected to be rare, we explicitly 1497 * allow it. 1498 */ 1499 LIST_FOREACH(opr, &nd_prefix, ndpr_entry) { 1500 if (opr == pr) 1501 continue; 1502 1503 if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) 1504 continue; 1505 1506 if (opr->ndpr_plen == pr->ndpr_plen && 1507 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 1508 &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) 1509 return (0); 1510 } 1511 1512 /* 1513 * We prefer link-local addresses as the associated interface address. 1514 */ 1515 /* search for a link-local addr */ 1516 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 1517 IN6_IFF_NOTREADY | IN6_IFF_ANYCAST); 1518 if (ifa == NULL) { 1519 /* XXX: freebsd does not have ifa_ifwithaf */ 1520 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1521 if (ifa->ifa_addr->sa_family == AF_INET6) 1522 break; 1523 } 1524 /* should we care about ia6_flags? */ 1525 } 1526 if (ifa == NULL) { 1527 /* 1528 * This can still happen, when, for example, we receive an RA 1529 * containing a prefix with the L bit set and the A bit clear, 1530 * after removing all IPv6 addresses on the receiving 1531 * interface. This should, of course, be rare though. 1532 */ 1533 nd6log((LOG_NOTICE, 1534 "nd6_prefix_onlink: failed to find any ifaddr" 1535 " to add route for a prefix(%s/%d) on %s\n", 1536 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1537 pr->ndpr_plen, ifp->if_xname)); 1538 return (0); 1539 } 1540 1541 /* 1542 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. 1543 * ifa->ifa_rtrequest = nd6_rtrequest; 1544 */ 1545 bzero(&mask6, sizeof(mask6)); 1546 mask6.sin6_len = sizeof(mask6); 1547 mask6.sin6_addr = pr->ndpr_mask; 1548 /* rtrequest1() will probably set RTF_UP, but we're not sure. */ 1549 rtflags = ifa->ifa_flags | RTF_UP; 1550 if (nd6_need_cache(ifp)) { 1551 /* explicitly set in case ifa_flags does not set the flag. */ 1552 rtflags |= RTF_CLONING; 1553 } else { 1554 /* 1555 * explicitly clear the cloning bit in case ifa_flags sets it. 1556 */ 1557 rtflags &= ~RTF_CLONING; 1558 } 1559 1560 bzero(&info, sizeof(info)); 1561 info.rti_flags = rtflags; 1562 info.rti_info[RTAX_DST] = (struct sockaddr *)&pr->ndpr_prefix; 1563 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; 1564 info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; 1565 1566 error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &rt, 0); 1567 if (error == 0) { 1568 if (rt != NULL) /* this should be non NULL, though */ 1569 nd6_rtmsg(RTM_ADD, rt); 1570 pr->ndpr_stateflags |= NDPRF_ONLINK; 1571 } else { 1572 nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a" 1573 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx " 1574 "errno = %d\n", 1575 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1576 pr->ndpr_plen, ifp->if_xname, 1577 ip6_sprintf(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr), 1578 ip6_sprintf(&mask6.sin6_addr), rtflags, error)); 1579 } 1580 1581 if (rt != NULL) 1582 rt->rt_refcnt--; 1583 1584 return (error); 1585 } 1586 1587 int 1588 nd6_prefix_offlink(struct nd_prefix *pr) 1589 { 1590 struct rt_addrinfo info; 1591 int error = 0; 1592 struct ifnet *ifp = pr->ndpr_ifp; 1593 struct nd_prefix *opr; 1594 struct sockaddr_in6 sa6, mask6; 1595 struct rtentry *rt = NULL; 1596 1597 /* sanity check */ 1598 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1599 nd6log((LOG_ERR, 1600 "nd6_prefix_offlink: %s/%d is already off-link\n", 1601 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen)); 1602 return (EEXIST); 1603 } 1604 1605 bzero(&sa6, sizeof(sa6)); 1606 sa6.sin6_family = AF_INET6; 1607 sa6.sin6_len = sizeof(sa6); 1608 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr, 1609 sizeof(struct in6_addr)); 1610 bzero(&mask6, sizeof(mask6)); 1611 mask6.sin6_family = AF_INET6; 1612 mask6.sin6_len = sizeof(sa6); 1613 bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); 1614 bzero(&info, sizeof(info)); 1615 info.rti_info[RTAX_DST] = (struct sockaddr *)&sa6; 1616 info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&mask6; 1617 error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &rt, 0); 1618 if (error == 0) { 1619 pr->ndpr_stateflags &= ~NDPRF_ONLINK; 1620 1621 /* report the route deletion to the routing socket. */ 1622 if (rt != NULL) 1623 nd6_rtmsg(RTM_DELETE, rt); 1624 1625 /* 1626 * There might be the same prefix on another interface, 1627 * the prefix which could not be on-link just because we have 1628 * the interface route (see comments in nd6_prefix_onlink). 1629 * If there's one, try to make the prefix on-link on the 1630 * interface. 1631 */ 1632 LIST_FOREACH(opr, &nd_prefix, ndpr_entry) { 1633 if (opr == pr) 1634 continue; 1635 1636 if ((opr->ndpr_stateflags & NDPRF_ONLINK) != 0) 1637 continue; 1638 1639 /* 1640 * KAME specific: detached prefixes should not be 1641 * on-link. 1642 */ 1643 if ((opr->ndpr_stateflags & NDPRF_DETACHED) != 0) 1644 continue; 1645 1646 if (opr->ndpr_plen == pr->ndpr_plen && 1647 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 1648 &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { 1649 int e; 1650 1651 if ((e = nd6_prefix_onlink(opr)) != 0) { 1652 nd6log((LOG_ERR, 1653 "nd6_prefix_offlink: failed to " 1654 "recover a prefix %s/%d from %s " 1655 "to %s (errno = %d)\n", 1656 ip6_sprintf(&opr->ndpr_prefix.sin6_addr), 1657 opr->ndpr_plen, ifp->if_xname, 1658 opr->ndpr_ifp->if_xname, e)); 1659 } 1660 } 1661 } 1662 } else { 1663 /* XXX: can we still set the NDPRF_ONLINK flag? */ 1664 nd6log((LOG_ERR, 1665 "nd6_prefix_offlink: failed to delete route: " 1666 "%s/%d on %s (errno = %d)\n", 1667 ip6_sprintf(&sa6.sin6_addr), pr->ndpr_plen, ifp->if_xname, 1668 error)); 1669 } 1670 1671 if (rt != NULL) { 1672 if (rt->rt_refcnt <= 0) { 1673 /* XXX: we should free the entry ourselves. */ 1674 rt->rt_refcnt++; 1675 rtfree(rt); 1676 } 1677 } 1678 1679 return (error); 1680 } 1681 1682 static struct in6_ifaddr * 1683 in6_ifadd(struct nd_prefix *pr) 1684 { 1685 struct ifnet *ifp = pr->ndpr_ifp; 1686 struct ifaddr *ifa; 1687 struct in6_aliasreq ifra; 1688 struct in6_ifaddr *ia, *ib; 1689 int error, s, plen0; 1690 struct in6_addr mask; 1691 int prefixlen = pr->ndpr_plen; 1692 1693 in6_prefixlen2mask(&mask, prefixlen); 1694 1695 /* 1696 * find a link-local address (will be interface ID). 1697 * Is it really mandatory? Theoretically, a global or a site-local 1698 * address can be configured without a link-local address, if we 1699 * have a unique interface identifier... 1700 * 1701 * it is not mandatory to have a link-local address, we can generate 1702 * interface identifier on the fly. we do this because: 1703 * (1) it should be the easiest way to find interface identifier. 1704 * (2) RFC2462 5.4 suggesting the use of the same interface identifier 1705 * for multiple addresses on a single interface, and possible shortcut 1706 * of DAD. we omitted DAD for this reason in the past. 1707 * (3) a user can prevent autoconfiguration of global address 1708 * by removing link-local address by hand (this is partly because we 1709 * don't have other way to control the use of IPv6 on a interface. 1710 * this has been our design choice - cf. NRL's "ifconfig auto"). 1711 * (4) it is easier to manage when an interface has addresses 1712 * with the same interface identifier, than to have multiple addresses 1713 * with different interface identifiers. 1714 */ 1715 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */ 1716 if (ifa) 1717 ib = (struct in6_ifaddr *)ifa; 1718 else 1719 return NULL; 1720 1721 #if 0 /* don't care link local addr state, and always do DAD */ 1722 /* if link-local address is not eligible, do not autoconfigure. */ 1723 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) { 1724 printf("in6_ifadd: link-local address not ready\n"); 1725 return NULL; 1726 } 1727 #endif 1728 1729 /* prefixlen + ifidlen must be equal to 128 */ 1730 plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL); 1731 if (prefixlen != plen0) { 1732 nd6log((LOG_INFO, "in6_ifadd: wrong prefixlen for %s " 1733 "(prefix=%d ifid=%d)\n", 1734 ifp->if_xname, prefixlen, 128 - plen0)); 1735 return NULL; 1736 } 1737 1738 /* make ifaddr */ 1739 1740 bzero(&ifra, sizeof(ifra)); 1741 /* 1742 * in6_update_ifa() does not use ifra_name, but we accurately set it 1743 * for safety. 1744 */ 1745 strncpy(ifra.ifra_name, ifp->if_xname, sizeof(ifra.ifra_name)); 1746 ifra.ifra_addr.sin6_family = AF_INET6; 1747 ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6); 1748 /* prefix */ 1749 bcopy(&pr->ndpr_prefix.sin6_addr, &ifra.ifra_addr.sin6_addr, 1750 sizeof(ifra.ifra_addr.sin6_addr)); 1751 ifra.ifra_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0]; 1752 ifra.ifra_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1]; 1753 ifra.ifra_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2]; 1754 ifra.ifra_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3]; 1755 1756 /* interface ID */ 1757 ifra.ifra_addr.sin6_addr.s6_addr32[0] |= 1758 (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]); 1759 ifra.ifra_addr.sin6_addr.s6_addr32[1] |= 1760 (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]); 1761 ifra.ifra_addr.sin6_addr.s6_addr32[2] |= 1762 (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]); 1763 ifra.ifra_addr.sin6_addr.s6_addr32[3] |= 1764 (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]); 1765 1766 /* new prefix mask. */ 1767 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6); 1768 ifra.ifra_prefixmask.sin6_family = AF_INET6; 1769 bcopy(&mask, &ifra.ifra_prefixmask.sin6_addr, 1770 sizeof(ifra.ifra_prefixmask.sin6_addr)); 1771 1772 /* 1773 * lifetime. 1774 * XXX: in6_init_address_ltimes would override these values later. 1775 * We should reconsider this logic. 1776 */ 1777 ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime; 1778 ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime; 1779 1780 /* XXX: scope zone ID? */ 1781 1782 ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */ 1783 1784 /* allocate ifaddr structure, link into chain, etc. */ 1785 s = splsoftnet(); 1786 error = in6_update_ifa(ifp, &ifra, NULL); 1787 splx(s); 1788 1789 if (error != 0) { 1790 nd6log((LOG_ERR, 1791 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n", 1792 ip6_sprintf(&ifra.ifra_addr.sin6_addr), ifp->if_xname, 1793 error)); 1794 return (NULL); /* ifaddr must not have been allocated. */ 1795 } 1796 1797 ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr); 1798 1799 return (ia); /* this is always non-NULL */ 1800 } 1801 1802 int 1803 in6_init_prefix_ltimes(struct nd_prefix *ndpr) 1804 { 1805 1806 /* check if preferred lifetime > valid lifetime. RFC2462 5.5.3 (c) */ 1807 if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) { 1808 nd6log((LOG_INFO, "in6_init_prefix_ltimes: preferred lifetime" 1809 "(%d) is greater than valid lifetime(%d)\n", 1810 (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime)); 1811 return (EINVAL); 1812 } 1813 if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME) 1814 ndpr->ndpr_preferred = 0; 1815 else 1816 ndpr->ndpr_preferred = time_second + ndpr->ndpr_pltime; 1817 if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME) 1818 ndpr->ndpr_expire = 0; 1819 else 1820 ndpr->ndpr_expire = time_second + ndpr->ndpr_vltime; 1821 1822 return 0; 1823 } 1824 1825 static void 1826 in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6) 1827 { 1828 1829 /* Valid lifetime must not be updated unless explicitly specified. */ 1830 /* init ia6t_expire */ 1831 if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME) 1832 lt6->ia6t_expire = 0; 1833 else { 1834 lt6->ia6t_expire = time_second; 1835 lt6->ia6t_expire += lt6->ia6t_vltime; 1836 } 1837 1838 /* init ia6t_preferred */ 1839 if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME) 1840 lt6->ia6t_preferred = 0; 1841 else { 1842 lt6->ia6t_preferred = time_second; 1843 lt6->ia6t_preferred += lt6->ia6t_pltime; 1844 } 1845 } 1846 1847 /* 1848 * Delete all the routing table entries that use the specified gateway. 1849 * XXX: this function causes search through all entries of routing table, so 1850 * it shouldn't be called when acting as a router. 1851 */ 1852 void 1853 rt6_flush(struct in6_addr *gateway, struct ifnet *ifp) 1854 { 1855 struct radix_node_head *rnh = rt_gettable(AF_INET6, 0); 1856 int s = splsoftnet(); 1857 1858 /* We'll care only link-local addresses */ 1859 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) { 1860 splx(s); 1861 return; 1862 } 1863 /* XXX: hack for KAME's link-local address kludge */ 1864 gateway->s6_addr16[1] = htons(ifp->if_index); 1865 1866 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway); 1867 splx(s); 1868 } 1869 1870 static int 1871 rt6_deleteroute(struct radix_node *rn, void *arg) 1872 { 1873 #define SIN6(s) ((struct sockaddr_in6 *)s) 1874 struct rt_addrinfo info; 1875 struct rtentry *rt = (struct rtentry *)rn; 1876 struct in6_addr *gate = (struct in6_addr *)arg; 1877 1878 if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) 1879 return (0); 1880 1881 if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) 1882 return (0); 1883 1884 /* 1885 * Do not delete a static route. 1886 * XXX: this seems to be a bit ad-hoc. Should we consider the 1887 * 'cloned' bit instead? 1888 */ 1889 if ((rt->rt_flags & RTF_STATIC) != 0) 1890 return (0); 1891 1892 /* 1893 * We delete only host route. This means, in particular, we don't 1894 * delete default route. 1895 */ 1896 if ((rt->rt_flags & RTF_HOST) == 0) 1897 return (0); 1898 1899 bzero(&info, sizeof(info)); 1900 info.rti_flags = rt->rt_flags; 1901 info.rti_info[RTAX_DST] = rt_key(rt); 1902 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1903 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1904 return (rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, NULL, 0)); 1905 #undef SIN6 1906 } 1907 1908 int 1909 nd6_setdefaultiface(int ifindex) 1910 { 1911 int error = 0; 1912 1913 if (ifindex < 0 || if_indexlim <= ifindex) 1914 return (EINVAL); 1915 if (ifindex != 0 && !ifindex2ifnet[ifindex]) 1916 return (EINVAL); 1917 1918 if (nd6_defifindex != ifindex) { 1919 nd6_defifindex = ifindex; 1920 if (nd6_defifindex > 0) { 1921 nd6_defifp = ifindex2ifnet[nd6_defifindex]; 1922 } else 1923 nd6_defifp = NULL; 1924 } 1925 1926 return (error); 1927 } 1928