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