1 /* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/malloc.h> 35 #include <sys/mbuf.h> 36 #include <sys/socket.h> 37 #include <sys/sockio.h> 38 #include <sys/time.h> 39 #include <sys/errno.h> 40 #include <sys/syslog.h> 41 42 #include <net/if.h> 43 #include <net/if_types.h> 44 #include <net/if_dl.h> 45 #include <net/route.h> 46 #include <net/radix.h> 47 48 #include <netinet/in.h> 49 #include <netinet6/in6_var.h> 50 #include <netinet6/ip6.h> 51 #include <netinet6/ip6_var.h> 52 #include <netinet6/nd6.h> 53 #include <netinet6/icmp6.h> 54 55 #include <net/net_osdep.h> 56 57 #define SDL(s) ((struct sockaddr_dl *)s) 58 59 static struct nd_defrouter *defrtrlist_update __P((struct nd_defrouter *)); 60 static int prelist_add __P((struct nd_prefix *, struct nd_defrouter *)); 61 static struct nd_prefix *prefix_lookup __P((struct nd_prefix *)); 62 static struct in6_ifaddr *in6_ifadd __P((struct ifnet *, struct in6_addr *, 63 struct in6_addr *, int)); 64 static struct nd_pfxrouter *pfxrtr_lookup __P((struct nd_prefix *, 65 struct nd_defrouter *)); 66 static void pfxrtr_add __P((struct nd_prefix *, struct nd_defrouter *)); 67 static void pfxrtr_del __P((struct nd_pfxrouter *)); 68 static void pfxlist_onlink_check __P((void)); 69 static void nd6_detach_prefix __P((struct nd_prefix *)); 70 static void nd6_attach_prefix __P((struct nd_prefix *)); 71 72 static void in6_init_address_ltimes __P((struct nd_prefix *ndpr, 73 struct in6_addrlifetime *lt6)); 74 75 static int rt6_deleteroute __P((struct radix_node *, void *)); 76 77 extern int nd6_recalc_reachtm_interval; 78 79 /* 80 * Receive Router Solicitation Message - just for routers. 81 * Router solicitation/advertisement is mostly managed by userland program 82 * (rtadvd) so here we have no function like nd6_ra_output(). 83 * 84 * Based on RFC 2461 85 */ 86 void 87 nd6_rs_input(m, off, icmp6len) 88 struct mbuf *m; 89 int off, icmp6len; 90 { 91 struct ifnet *ifp = m->m_pkthdr.rcvif; 92 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 93 struct nd_router_solicit *nd_rs 94 = (struct nd_router_solicit *)((caddr_t)ip6 + off); 95 struct in6_addr saddr6 = ip6->ip6_src; 96 char *lladdr = NULL; 97 int lladdrlen = 0; 98 union nd_opts ndopts; 99 100 /* If I'm not a router, ignore it. */ 101 if (ip6_accept_rtadv != 0 || ip6_forwarding != 1) 102 return; 103 104 /* Sanity checks */ 105 if (ip6->ip6_hlim != 255) { 106 log(LOG_ERR, 107 "nd6_rs_input: invalid hlim %d\n", ip6->ip6_hlim); 108 return; 109 } 110 111 /* 112 * Don't update the neighbor cache, if src = ::. 113 * This indicates that the src has no IP address assigned yet. 114 */ 115 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) 116 return; 117 118 icmp6len -= sizeof(*nd_rs); 119 nd6_option_init(nd_rs + 1, icmp6len, &ndopts); 120 if (nd6_options(&ndopts) < 0) { 121 log(LOG_INFO, "nd6_rs_input: invalid ND option, ignored\n"); 122 return; 123 } 124 125 if (ndopts.nd_opts_src_lladdr) { 126 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 127 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 128 } 129 130 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 131 log(LOG_INFO, 132 "nd6_rs_input: lladdrlen mismatch for %s " 133 "(if %d, RS packet %d)\n", 134 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2); 135 } 136 137 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0); 138 } 139 140 /* 141 * Receive Router Advertisement Message. 142 * 143 * Based on RFC 2461 144 * TODO: on-link bit on prefix information 145 * TODO: ND_RA_FLAG_{OTHER,MANAGED} processing 146 */ 147 void 148 nd6_ra_input(m, off, icmp6len) 149 struct mbuf *m; 150 int off, icmp6len; 151 { 152 struct ifnet *ifp = m->m_pkthdr.rcvif; 153 struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index]; 154 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 155 struct nd_router_advert *nd_ra = 156 (struct nd_router_advert *)((caddr_t)ip6 + off); 157 struct in6_addr saddr6 = ip6->ip6_src; 158 union nd_opts ndopts; 159 struct nd_defrouter *dr; 160 161 if (ip6_accept_rtadv == 0) 162 return; 163 164 if (ip6->ip6_hlim != 255) { 165 log(LOG_ERR, 166 "nd6_ra_input: invalid hlim %d\n", ip6->ip6_hlim); 167 return; 168 } 169 170 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { 171 log(LOG_ERR, 172 "nd6_ra_input: src %s is not link-local\n", 173 ip6_sprintf(&saddr6)); 174 return; 175 } 176 177 icmp6len -= sizeof(*nd_ra); 178 nd6_option_init(nd_ra + 1, icmp6len, &ndopts); 179 if (nd6_options(&ndopts) < 0) { 180 log(LOG_INFO, "nd6_ra_input: invalid ND option, ignored\n"); 181 return; 182 } 183 184 { 185 struct nd_defrouter dr0; 186 u_int32_t advreachable = nd_ra->nd_ra_reachable; 187 188 dr0.rtaddr = saddr6; 189 dr0.flags = nd_ra->nd_ra_flags_reserved; 190 dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime); 191 dr0.expire = time_second + dr0.rtlifetime; 192 dr0.ifp = ifp; 193 /* unspecified or not? (RFC 2461 6.3.4) */ 194 if (advreachable) { 195 NTOHL(advreachable); 196 if (advreachable <= MAX_REACHABLE_TIME && 197 ndi->basereachable != advreachable) { 198 ndi->basereachable = advreachable; 199 ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable); 200 ndi->recalctm = nd6_recalc_reachtm_interval; /* reset */ 201 } 202 } 203 if (nd_ra->nd_ra_retransmit) 204 ndi->retrans = ntohl(nd_ra->nd_ra_retransmit); 205 if (nd_ra->nd_ra_curhoplimit) 206 ndi->chlim = nd_ra->nd_ra_curhoplimit; 207 dr = defrtrlist_update(&dr0); 208 } 209 210 /* 211 * prefix 212 */ 213 if (ndopts.nd_opts_pi) { 214 struct nd_opt_hdr *pt; 215 struct nd_opt_prefix_info *pi; 216 struct nd_prefix pr; 217 218 for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi; 219 pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end; 220 pt = (struct nd_opt_hdr *)((caddr_t)pt + 221 (pt->nd_opt_len << 3))) { 222 if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION) 223 continue; 224 pi = (struct nd_opt_prefix_info *)pt; 225 226 if (pi->nd_opt_pi_len != 4) { 227 log(LOG_INFO, "nd6_ra_input: invalid option " 228 "len %d for prefix information option, " 229 "ignored\n", pi->nd_opt_pi_len); 230 continue; 231 } 232 233 if (128 < pi->nd_opt_pi_prefix_len) { 234 log(LOG_INFO, "nd6_ra_input: invalid prefix " 235 "len %d for prefix information option, " 236 "ignored\n", pi->nd_opt_pi_prefix_len); 237 continue; 238 } 239 240 if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) 241 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) { 242 log(LOG_INFO, "nd6_ra_input: invalid prefix " 243 "%s, ignored\n", 244 ip6_sprintf(&pi->nd_opt_pi_prefix)); 245 continue; 246 } 247 248 /* aggregatable unicast address, rfc2374 */ 249 if ((pi->nd_opt_pi_prefix.s6_addr8[0] & 0xe0) == 0x20 250 && pi->nd_opt_pi_prefix_len != 64) { 251 log(LOG_INFO, "nd6_ra_input: invalid prefixlen " 252 "%d for rfc2374 prefix %s, ignored\n", 253 pi->nd_opt_pi_prefix_len, 254 ip6_sprintf(&pi->nd_opt_pi_prefix)); 255 continue; 256 } 257 258 bzero(&pr, sizeof(pr)); 259 pr.ndpr_prefix.sin6_family = AF_INET6; 260 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix); 261 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix; 262 pr.ndpr_ifp = (struct ifnet *)m->m_pkthdr.rcvif; 263 264 pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved & 265 ND_OPT_PI_FLAG_ONLINK) ? 1 : 0; 266 pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved & 267 ND_OPT_PI_FLAG_AUTO) ? 1 : 0; 268 pr.ndpr_plen = pi->nd_opt_pi_prefix_len; 269 pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); 270 pr.ndpr_pltime = 271 ntohl(pi->nd_opt_pi_preferred_time); 272 273 if (in6_init_prefix_ltimes(&pr)) 274 continue; /* prefix lifetime init failed */ 275 276 (void)prelist_update(&pr, dr, m); 277 } 278 } 279 280 /* 281 * MTU 282 */ 283 if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) { 284 u_int32_t mtu = ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); 285 286 /* lower bound */ 287 if (mtu < IPV6_MMTU) { 288 log(LOG_INFO, "nd6_ra_input: bogus mtu option " 289 "mtu=%d sent from %s, ignoring\n", 290 mtu, ip6_sprintf(&ip6->ip6_src)); 291 goto skip; 292 } 293 294 /* upper bound */ 295 if (ndi->maxmtu) { 296 if (mtu <= ndi->maxmtu) { 297 int change = (ndi->linkmtu != mtu); 298 299 ndi->linkmtu = mtu; 300 if (change) /* in6_maxmtu may change */ 301 in6_setmaxmtu(); 302 } else { 303 log(LOG_INFO, "nd6_ra_input: bogus mtu " 304 "mtu=%d sent from %s; " 305 "exceeds maxmtu %d, ignoring\n", 306 mtu, ip6_sprintf(&ip6->ip6_src), 307 ndi->maxmtu); 308 } 309 } else { 310 log(LOG_INFO, "nd6_ra_input: mtu option " 311 "mtu=%d sent from %s; maxmtu unknown, " 312 "ignoring\n", 313 mtu, ip6_sprintf(&ip6->ip6_src)); 314 } 315 } 316 317 skip: 318 319 /* 320 * Src linkaddress 321 */ 322 { 323 char *lladdr = NULL; 324 int lladdrlen = 0; 325 326 if (ndopts.nd_opts_src_lladdr) { 327 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 328 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 329 } 330 331 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 332 log(LOG_INFO, 333 "nd6_ra_input: lladdrlen mismatch for %s " 334 "(if %d, RA packet %d)\n", 335 ip6_sprintf(&saddr6), ifp->if_addrlen, lladdrlen - 2); 336 } 337 338 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_ADVERT, 0); 339 } 340 } 341 342 /* 343 * default router list proccessing sub routines 344 */ 345 void 346 defrouter_addreq(new) 347 struct nd_defrouter *new; 348 { 349 struct sockaddr_in6 def, mask, gate; 350 int s; 351 352 Bzero(&def, sizeof(def)); 353 Bzero(&mask, sizeof(mask)); 354 Bzero(&gate, sizeof(gate)); 355 356 def.sin6_len = mask.sin6_len = gate.sin6_len 357 = sizeof(struct sockaddr_in6); 358 def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6; 359 gate.sin6_addr = new->rtaddr; 360 361 s = splnet(); 362 (void)rtrequest(RTM_ADD, (struct sockaddr *)&def, 363 (struct sockaddr *)&gate, (struct sockaddr *)&mask, 364 RTF_GATEWAY, NULL); 365 splx(s); 366 return; 367 } 368 369 struct nd_defrouter * 370 defrouter_lookup(addr, ifp) 371 struct in6_addr *addr; 372 struct ifnet *ifp; 373 { 374 struct nd_defrouter *dr; 375 376 LIST_FOREACH(dr, &nd_defrouter, dr_entry) 377 if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) 378 return(dr); 379 380 return(NULL); /* search failed */ 381 } 382 383 void 384 defrouter_delreq(dr, dofree) 385 struct nd_defrouter *dr; 386 int dofree; 387 { 388 struct sockaddr_in6 def, mask, gate; 389 390 Bzero(&def, sizeof(def)); 391 Bzero(&mask, sizeof(mask)); 392 Bzero(&gate, sizeof(gate)); 393 394 def.sin6_len = mask.sin6_len = gate.sin6_len 395 = sizeof(struct sockaddr_in6); 396 def.sin6_family = mask.sin6_family = gate.sin6_family = AF_INET6; 397 gate.sin6_addr = dr->rtaddr; 398 399 rtrequest(RTM_DELETE, (struct sockaddr *)&def, 400 (struct sockaddr *)&gate, 401 (struct sockaddr *)&mask, 402 RTF_GATEWAY, (struct rtentry **)0); 403 404 if (dofree) 405 free(dr, M_IP6NDP); 406 407 if (!LIST_EMPTY(&nd_defrouter)) 408 defrouter_addreq(LIST_FIRST(&nd_defrouter)); 409 410 /* 411 * xxx update the Destination Cache entries for all 412 * destinations using that neighbor as a router (7.2.5) 413 */ 414 } 415 416 void 417 defrtrlist_del(dr) 418 struct nd_defrouter *dr; 419 { 420 struct nd_defrouter *deldr = NULL; 421 struct nd_prefix *pr; 422 423 /* 424 * Flush all the routing table entries that use the router 425 * as a next hop. 426 */ 427 if (!ip6_forwarding && ip6_accept_rtadv) { 428 /* above is a good condition? */ 429 rt6_flush(&dr->rtaddr, dr->ifp); 430 } 431 432 if (dr == LIST_FIRST(&nd_defrouter)) 433 deldr = dr; /* The router is primary. */ 434 435 LIST_REMOVE(dr, dr_entry); 436 437 /* 438 * Also delete all the pointers to the router in each prefix lists. 439 */ 440 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 441 struct nd_pfxrouter *pfxrtr; 442 if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL) 443 pfxrtr_del(pfxrtr); 444 } 445 pfxlist_onlink_check(); 446 447 /* 448 * If the router is the primary one, delete the default route 449 * entry in the routing table. 450 */ 451 if (deldr) 452 defrouter_delreq(deldr, 0); 453 free(dr, M_IP6NDP); 454 } 455 456 static struct nd_defrouter * 457 defrtrlist_update(new) 458 struct nd_defrouter *new; 459 { 460 struct nd_defrouter *dr, *n; 461 int s = splnet(); 462 463 if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) { 464 /* entry exists */ 465 if (new->rtlifetime == 0) { 466 defrtrlist_del(dr); 467 dr = NULL; 468 } else { 469 /* override */ 470 dr->flags = new->flags; /* xxx flag check */ 471 dr->rtlifetime = new->rtlifetime; 472 dr->expire = new->expire; 473 } 474 splx(s); 475 return(dr); 476 } 477 478 /* entry does not exist */ 479 if (new->rtlifetime == 0) { 480 splx(s); 481 return(NULL); 482 } 483 484 n = (struct nd_defrouter *)malloc(sizeof(*n), M_IP6NDP, M_NOWAIT); 485 if (n == NULL) { 486 splx(s); 487 return(NULL); 488 } 489 bzero(n, sizeof(*n)); 490 *n = *new; 491 if (LIST_EMPTY(&nd_defrouter)) { 492 LIST_INSERT_HEAD(&nd_defrouter, n, dr_entry); 493 defrouter_addreq(n); 494 } else { 495 LIST_INSERT_AFTER(LIST_FIRST(&nd_defrouter), n, dr_entry); 496 defrouter_addreq(n); 497 } 498 splx(s); 499 500 return(n); 501 } 502 503 static struct nd_pfxrouter * 504 pfxrtr_lookup(pr, dr) 505 struct nd_prefix *pr; 506 struct nd_defrouter *dr; 507 { 508 struct nd_pfxrouter *search; 509 510 LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) { 511 if (search->router == dr) 512 break; 513 } 514 515 return(search); 516 } 517 518 static void 519 pfxrtr_add(pr, dr) 520 struct nd_prefix *pr; 521 struct nd_defrouter *dr; 522 { 523 struct nd_pfxrouter *new; 524 525 new = (struct nd_pfxrouter *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); 526 if (new == NULL) 527 return; 528 bzero(new, sizeof(*new)); 529 new->router = dr; 530 531 LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry); 532 533 pfxlist_onlink_check(); 534 } 535 536 static void 537 pfxrtr_del(pfr) 538 struct nd_pfxrouter *pfr; 539 { 540 LIST_REMOVE(pfr, pfr_entry); 541 free(pfr, M_IP6NDP); 542 } 543 544 static struct nd_prefix * 545 prefix_lookup(pr) 546 struct nd_prefix *pr; 547 { 548 struct nd_prefix *search; 549 550 LIST_FOREACH(search, &nd_prefix, ndpr_entry) { 551 if (pr->ndpr_ifp == search->ndpr_ifp && 552 pr->ndpr_plen == search->ndpr_plen && 553 in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, 554 &search->ndpr_prefix.sin6_addr, 555 pr->ndpr_plen) 556 ) { 557 break; 558 } 559 } 560 561 return(search); 562 } 563 564 static int 565 prelist_add(pr, dr) 566 struct nd_prefix *pr; 567 struct nd_defrouter *dr; 568 { 569 struct nd_prefix *new; 570 int i, s; 571 572 new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); 573 if (new == NULL) 574 return ENOMEM; 575 bzero(new, sizeof(*new)); 576 *new = *pr; 577 578 /* initilization */ 579 new->ndpr_statef_onlink = pr->ndpr_statef_onlink; 580 LIST_INIT(&new->ndpr_advrtrs); 581 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen); 582 /* make prefix in the canonical form */ 583 for (i = 0; i < 4; i++) 584 new->ndpr_prefix.sin6_addr.s6_addr32[i] &= 585 new->ndpr_mask.s6_addr32[i]; 586 587 /* xxx ND_OPT_PI_FLAG_ONLINK processing */ 588 589 s = splnet(); 590 /* link ndpr_entry to nd_prefix list */ 591 LIST_INSERT_HEAD(&nd_prefix, new, ndpr_entry); 592 splx(s); 593 594 if (dr) 595 pfxrtr_add(new, dr); 596 597 return 0; 598 } 599 600 void 601 prelist_remove(pr) 602 struct nd_prefix *pr; 603 { 604 struct nd_pfxrouter *pfr, *next; 605 int s; 606 607 s = splnet(); 608 /* unlink ndpr_entry from nd_prefix list */ 609 LIST_REMOVE(pr, ndpr_entry); 610 splx(s); 611 612 /* free list of routers that adversed the prefix */ 613 for (pfr = LIST_FIRST(&pr->ndpr_advrtrs); pfr; pfr = next) { 614 next = LIST_NEXT(pfr, pfr_entry); 615 616 free(pfr, M_IP6NDP); 617 } 618 free(pr, M_IP6NDP); 619 620 pfxlist_onlink_check(); 621 } 622 623 /* 624 * NOTE: We set address lifetime to keep 625 * address lifetime <= prefix lifetime 626 * invariant. This is to simplify on-link determination code. 627 * If onlink determination is udated, this routine may have to be updated too. 628 */ 629 int 630 prelist_update(new, dr, m) 631 struct nd_prefix *new; 632 struct nd_defrouter *dr; /* may be NULL */ 633 struct mbuf *m; 634 { 635 struct in6_ifaddr *ia6 = NULL; 636 struct nd_prefix *pr; 637 int s = splnet(); 638 int error = 0; 639 int auth; 640 struct in6_addrlifetime *lt6; 641 642 auth = 0; 643 if (m) { 644 /* 645 * Authenticity for NA consists authentication for 646 * both IP header and IP datagrams, doesn't it ? 647 */ 648 #if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM) 649 auth = (m->m_flags & M_AUTHIPHDR 650 && m->m_flags & M_AUTHIPDGM) ? 1 : 0; 651 #endif 652 } 653 654 if ((pr = prefix_lookup(new)) != NULL) { 655 if (pr->ndpr_ifp != new->ndpr_ifp) { 656 error = EADDRNOTAVAIL; 657 goto end; 658 } 659 /* update prefix information */ 660 pr->ndpr_flags = new->ndpr_flags; 661 pr->ndpr_vltime = new->ndpr_vltime; 662 pr->ndpr_pltime = new->ndpr_pltime; 663 pr->ndpr_preferred = new->ndpr_preferred; 664 pr->ndpr_expire = new->ndpr_expire; 665 666 /* 667 * RFC 2462 5.5.3 (d) or (e) 668 * We got a prefix which we have seen in the past. 669 */ 670 if (!new->ndpr_raf_auto) 671 goto noautoconf1; 672 673 if (IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr)) 674 ia6 = NULL; 675 else 676 ia6 = in6ifa_ifpwithaddr(pr->ndpr_ifp, &pr->ndpr_addr); 677 678 if (ia6 == NULL) { 679 /* 680 * Special case: 681 * (1) We have seen the prefix advertised before, but 682 * we have never performed autoconfig for this prefix. 683 * This is because Autonomous bit was 0 previously, or 684 * autoconfig failed due to some other reasons. 685 * (2) We have seen the prefix advertised before and 686 * we have performed autoconfig in the past, but 687 * we seem to have no interface address right now. 688 * This is because the interface address have expired. 689 * 690 * This prefix is fresh, with respect to autoconfig 691 * process. 692 * 693 * Add an address based on RFC 2462 5.5.3 (d). 694 */ 695 ia6 = in6_ifadd(pr->ndpr_ifp, 696 &pr->ndpr_prefix.sin6_addr, &pr->ndpr_addr, 697 new->ndpr_plen); 698 if (!ia6) { 699 error = EADDRNOTAVAIL; 700 log(LOG_ERR, "prelist_update: failed to add a " 701 "new address\n"); 702 goto noautoconf1; 703 } 704 705 lt6 = &ia6->ia6_lifetime; 706 707 /* address lifetime <= prefix lifetime */ 708 lt6->ia6t_vltime = new->ndpr_vltime; 709 lt6->ia6t_pltime = new->ndpr_pltime; 710 in6_init_address_ltimes(new, lt6); 711 } else { 712 #define TWOHOUR (120*60) 713 /* 714 * We have seen the prefix before, and we have added 715 * interface address in the past. We still have 716 * the interface address assigned. 717 * 718 * update address lifetime based on RFC 2462 719 * 5.5.3 (e). 720 */ 721 int update = 0; 722 723 lt6 = &ia6->ia6_lifetime; 724 725 /* 726 * update to RFC 2462 5.5.3 (e) from Jim Bound, 727 * (ipng 6712) 728 */ 729 if (TWOHOUR < new->ndpr_vltime 730 || lt6->ia6t_vltime < new->ndpr_vltime) { 731 lt6->ia6t_vltime = new->ndpr_vltime; 732 update++; 733 } else if (auth) { 734 lt6->ia6t_vltime = new->ndpr_vltime; 735 update++; 736 } 737 738 /* jim bound rule is not imposed for pref lifetime */ 739 lt6->ia6t_pltime = new->ndpr_pltime; 740 741 update++; 742 if (update) 743 in6_init_address_ltimes(new, lt6); 744 } 745 746 noautoconf1: 747 748 if (dr && pfxrtr_lookup(pr, dr) == NULL) 749 pfxrtr_add(pr, dr); 750 } else { 751 int error_tmp; 752 753 if (new->ndpr_vltime == 0) goto end; 754 755 bzero(&new->ndpr_addr, sizeof(struct in6_addr)); 756 757 /* 758 * RFC 2462 5.5.3 (d) 759 * We got a fresh prefix. Perform some sanity checks 760 * and add an interface address by appending interface ID 761 * to the advertised prefix. 762 */ 763 if (!new->ndpr_raf_auto) 764 goto noautoconf2; 765 766 ia6 = in6_ifadd(new->ndpr_ifp, &new->ndpr_prefix.sin6_addr, 767 &new->ndpr_addr, new->ndpr_plen); 768 if (!ia6) { 769 error = EADDRNOTAVAIL; 770 log(LOG_ERR, "prelist_update: " 771 "failed to add a new address\n"); 772 goto noautoconf2; 773 } 774 /* set onlink bit if an interface route is configured */ 775 new->ndpr_statef_onlink = (ia6->ia_flags & IFA_ROUTE) ? 1 : 0; 776 777 lt6 = &ia6->ia6_lifetime; 778 779 /* address lifetime <= prefix lifetime */ 780 lt6->ia6t_vltime = new->ndpr_vltime; 781 lt6->ia6t_pltime = new->ndpr_pltime; 782 in6_init_address_ltimes(new, lt6); 783 784 noautoconf2: 785 error_tmp = prelist_add(new, dr); 786 error = error_tmp ? error_tmp : error; 787 } 788 789 end: 790 splx(s); 791 return error; 792 } 793 794 /* 795 * Check if each prefix in the prefix list has at least one available router 796 * that advertised the prefix. 797 * If the check fails, the prefix may be off-link because, for example, 798 * we have moved from the network but the lifetime of the prefix has not 799 * been expired yet. So we should not use the prefix if there is another 800 * prefix that has an available router. 801 * But if there is no prefix that has an availble router, we still regards 802 * all the prefixes as on-link. This is because we can't tell if all the 803 * routers are simply dead or if we really moved from the network and there 804 * is no router around us. 805 */ 806 static void 807 pfxlist_onlink_check() 808 { 809 struct nd_prefix *pr; 810 811 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) 812 if (!LIST_EMPTY(&pr->ndpr_advrtrs)) /* pr has an available router */ 813 break; 814 815 if (pr) { 816 /* 817 * There is at least one prefix that has a router. First, 818 * detach prefixes which has no advertising router and then 819 * attach other prefixes. The order is important since an 820 * attached prefix and a detached prefix may have a same 821 * interface route. 822 */ 823 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 824 if (LIST_EMPTY(&pr->ndpr_advrtrs) && 825 pr->ndpr_statef_onlink) { 826 pr->ndpr_statef_onlink = 0; 827 nd6_detach_prefix(pr); 828 } 829 } 830 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) { 831 if (!LIST_EMPTY(&pr->ndpr_advrtrs) && 832 pr->ndpr_statef_onlink == 0) 833 nd6_attach_prefix(pr); 834 } 835 } else { 836 /* there is no prefix that has a router */ 837 LIST_FOREACH(pr, &nd_prefix, ndpr_entry) 838 if (pr->ndpr_statef_onlink == 0) 839 nd6_attach_prefix(pr); 840 } 841 } 842 843 static void 844 nd6_detach_prefix(pr) 845 struct nd_prefix *pr; 846 { 847 struct in6_ifaddr *ia6; 848 struct sockaddr_in6 sa6, mask6; 849 850 /* 851 * Delete the interface route associated with the prefix. 852 */ 853 bzero(&sa6, sizeof(sa6)); 854 sa6.sin6_family = AF_INET6; 855 sa6.sin6_len = sizeof(sa6); 856 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr, 857 sizeof(struct in6_addr)); 858 bzero(&mask6, sizeof(mask6)); 859 mask6.sin6_family = AF_INET6; 860 mask6.sin6_len = sizeof(sa6); 861 bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); 862 { 863 int e; 864 865 e = rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, 866 (struct sockaddr *)&mask6, 0, NULL); 867 if (e) { 868 log(LOG_ERR, 869 "nd6_detach_prefix: failed to delete route: " 870 "%s/%d (errno = %d)\n", 871 ip6_sprintf(&sa6.sin6_addr), 872 pr->ndpr_plen, 873 e); 874 } 875 } 876 877 /* 878 * Mark the address derived from the prefix detached so that 879 * it won't be used as a source address for a new connection. 880 */ 881 if (IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr)) 882 ia6 = NULL; 883 else 884 ia6 = in6ifa_ifpwithaddr(pr->ndpr_ifp, &pr->ndpr_addr); 885 if (ia6) 886 ia6->ia6_flags |= IN6_IFF_DETACHED; 887 } 888 889 static void 890 nd6_attach_prefix(pr) 891 struct nd_prefix *pr; 892 { 893 struct ifaddr *ifa; 894 struct in6_ifaddr *ia6; 895 896 /* 897 * Add the interface route associated with the prefix(if necessary) 898 * Should we consider if the L bit is set in pr->ndpr_flags? 899 */ 900 ifa = ifaof_ifpforaddr((struct sockaddr *)&pr->ndpr_prefix, 901 pr->ndpr_ifp); 902 if (ifa == NULL) { 903 log(LOG_ERR, 904 "nd6_attach_prefix: failed to find any ifaddr" 905 " to add route for a prefix(%s/%d)\n", 906 ip6_sprintf(&pr->ndpr_addr), pr->ndpr_plen); 907 } else { 908 int e; 909 struct sockaddr_in6 mask6; 910 911 bzero(&mask6, sizeof(mask6)); 912 mask6.sin6_family = AF_INET6; 913 mask6.sin6_len = sizeof(mask6); 914 mask6.sin6_addr = pr->ndpr_mask; 915 e = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix, 916 ifa->ifa_addr, (struct sockaddr *)&mask6, 917 ifa->ifa_flags, NULL); 918 if (e == 0) 919 pr->ndpr_statef_onlink = 1; 920 else { 921 log(LOG_ERR, 922 "nd6_attach_prefix: failed to add route for" 923 " a prefix(%s/%d), errno = %d\n", 924 ip6_sprintf(&pr->ndpr_addr), pr->ndpr_plen, e); 925 } 926 } 927 928 /* 929 * Now the address derived from the prefix can be used as a source 930 * for a new connection, so clear the detached flag. 931 */ 932 if (IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr)) 933 ia6 = NULL; 934 else 935 ia6 = in6ifa_ifpwithaddr(pr->ndpr_ifp, &pr->ndpr_addr); 936 if (ia6) { 937 ia6->ia6_flags &= ~IN6_IFF_DETACHED; 938 if (pr->ndpr_statef_onlink) 939 ia6->ia_flags |= IFA_ROUTE; 940 } 941 } 942 943 static struct in6_ifaddr * 944 in6_ifadd(ifp, in6, addr, prefixlen) 945 struct ifnet *ifp; 946 struct in6_addr *in6; 947 struct in6_addr *addr; 948 int prefixlen; /* prefix len of the new prefix in "in6" */ 949 { 950 struct ifaddr *ifa; 951 struct in6_ifaddr *ia, *ib, *oia; 952 int s, error; 953 struct in6_addr mask; 954 955 in6_len2mask(&mask, prefixlen); 956 957 /* find link-local address (will be interface ID) */ 958 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp); 959 if (ifa) 960 ib = (struct in6_ifaddr *)ifa; 961 else 962 return NULL; 963 964 /* prefixlen + ifidlen must be equal to 128 */ 965 if (prefixlen != in6_mask2len(&ib->ia_prefixmask.sin6_addr)) { 966 log(LOG_ERR, "in6_ifadd: wrong prefixlen for %s" 967 "(prefix=%d ifid=%d)\n", if_name(ifp), 968 prefixlen, 969 128 - in6_mask2len(&ib->ia_prefixmask.sin6_addr)); 970 return NULL; 971 } 972 973 /* make ifaddr */ 974 ia = (struct in6_ifaddr *)malloc(sizeof(*ia), M_IFADDR, M_DONTWAIT); 975 if (ia == NULL) { 976 printf("ENOBUFS in in6_ifadd %d\n", __LINE__); 977 return NULL; 978 } 979 980 bzero((caddr_t)ia, sizeof(*ia)); 981 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 982 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 983 ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; 984 ia->ia_ifp = ifp; 985 986 /* link to in6_ifaddr */ 987 if ((oia = in6_ifaddr) != NULL) { 988 for( ; oia->ia_next; oia = oia->ia_next) 989 continue; 990 oia->ia_next = ia; 991 } else 992 in6_ifaddr = ia; 993 994 /* link to if_addrlist */ 995 if (!TAILQ_EMPTY(&ifp->if_addrlist)) { 996 TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia, 997 ifa_list); 998 } 999 1000 /* new address */ 1001 ia->ia_addr.sin6_len = sizeof(struct sockaddr_in6); 1002 ia->ia_addr.sin6_family = AF_INET6; 1003 /* prefix */ 1004 bcopy(in6, &ia->ia_addr.sin6_addr, sizeof(ia->ia_addr.sin6_addr)); 1005 ia->ia_addr.sin6_addr.s6_addr32[0] &= mask.s6_addr32[0]; 1006 ia->ia_addr.sin6_addr.s6_addr32[1] &= mask.s6_addr32[1]; 1007 ia->ia_addr.sin6_addr.s6_addr32[2] &= mask.s6_addr32[2]; 1008 ia->ia_addr.sin6_addr.s6_addr32[3] &= mask.s6_addr32[3]; 1009 /* interface ID */ 1010 ia->ia_addr.sin6_addr.s6_addr32[0] 1011 |= (ib->ia_addr.sin6_addr.s6_addr32[0] & ~mask.s6_addr32[0]); 1012 ia->ia_addr.sin6_addr.s6_addr32[1] 1013 |= (ib->ia_addr.sin6_addr.s6_addr32[1] & ~mask.s6_addr32[1]); 1014 ia->ia_addr.sin6_addr.s6_addr32[2] 1015 |= (ib->ia_addr.sin6_addr.s6_addr32[2] & ~mask.s6_addr32[2]); 1016 ia->ia_addr.sin6_addr.s6_addr32[3] 1017 |= (ib->ia_addr.sin6_addr.s6_addr32[3] & ~mask.s6_addr32[3]); 1018 1019 /* new prefix */ 1020 ia->ia_prefixmask.sin6_len = sizeof(struct sockaddr_in6); 1021 ia->ia_prefixmask.sin6_family = AF_INET6; 1022 bcopy(&mask, &ia->ia_prefixmask.sin6_addr, 1023 sizeof(ia->ia_prefixmask.sin6_addr)); 1024 1025 /* same routine */ 1026 ia->ia_ifa.ifa_rtrequest = 1027 (ifp->if_type == IFT_PPP) ? nd6_p2p_rtrequest : nd6_rtrequest; 1028 ia->ia_ifa.ifa_flags |= RTF_CLONING; 1029 ia->ia_ifa.ifa_metric = ifp->if_metric; 1030 1031 /* add interface route */ 1032 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP|RTF_CLONING))) { 1033 log(LOG_NOTICE, "in6_ifadd: failed to add an interface route " 1034 "for %s/%d on %s, errno = %d\n", 1035 ip6_sprintf(&ia->ia_addr.sin6_addr), prefixlen, 1036 if_name(ifp), error); 1037 } else 1038 ia->ia_flags |= IFA_ROUTE; 1039 1040 *addr = ia->ia_addr.sin6_addr; 1041 1042 if (ifp->if_flags & IFF_MULTICAST) { 1043 int error; /* not used */ 1044 struct in6_addr sol6; 1045 1046 /* join solicited node multicast address */ 1047 bzero(&sol6, sizeof(sol6)); 1048 sol6.s6_addr16[0] = htons(0xff02); 1049 sol6.s6_addr16[1] = htons(ifp->if_index); 1050 sol6.s6_addr32[1] = 0; 1051 sol6.s6_addr32[2] = htonl(1); 1052 sol6.s6_addr32[3] = ia->ia_addr.sin6_addr.s6_addr32[3]; 1053 sol6.s6_addr8[12] = 0xff; 1054 (void)in6_addmulti(&sol6, ifp, &error); 1055 } 1056 1057 ia->ia6_flags |= IN6_IFF_TENTATIVE; 1058 1059 /* 1060 * To make the interface up. Only AF_INET6 in ia is used... 1061 */ 1062 s = splimp(); 1063 if (ifp->if_ioctl && (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia)) { 1064 splx(s); 1065 return NULL; 1066 } 1067 splx(s); 1068 1069 /* Perform DAD, if needed. */ 1070 nd6_dad_start((struct ifaddr *)ia, NULL); 1071 1072 return ia; 1073 } 1074 1075 int 1076 in6_ifdel(ifp, in6) 1077 struct ifnet *ifp; 1078 struct in6_addr *in6; 1079 { 1080 struct in6_ifaddr *ia = (struct in6_ifaddr *)NULL; 1081 struct in6_ifaddr *oia = (struct in6_ifaddr *)NULL; 1082 1083 if (!ifp) 1084 return -1; 1085 1086 ia = in6ifa_ifpwithaddr(ifp, in6); 1087 if (!ia) 1088 return -1; 1089 1090 if (ifp->if_flags & IFF_MULTICAST) { 1091 /* 1092 * delete solicited multicast addr for deleting host id 1093 */ 1094 struct in6_multi *in6m; 1095 struct in6_addr llsol; 1096 bzero(&llsol, sizeof(struct in6_addr)); 1097 llsol.s6_addr16[0] = htons(0xff02); 1098 llsol.s6_addr16[1] = htons(ifp->if_index); 1099 llsol.s6_addr32[1] = 0; 1100 llsol.s6_addr32[2] = htonl(1); 1101 llsol.s6_addr32[3] = 1102 ia->ia_addr.sin6_addr.s6_addr32[3]; 1103 llsol.s6_addr8[12] = 0xff; 1104 1105 IN6_LOOKUP_MULTI(llsol, ifp, in6m); 1106 if (in6m) 1107 in6_delmulti(in6m); 1108 } 1109 1110 if (ia->ia_flags & IFA_ROUTE) { 1111 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 1112 ia->ia_flags &= ~IFA_ROUTE; 1113 } 1114 1115 TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list); 1116 1117 /* lladdr is never deleted */ 1118 oia = ia; 1119 if (oia == (ia = in6_ifaddr)) 1120 in6_ifaddr = ia->ia_next; 1121 else { 1122 while (ia->ia_next && (ia->ia_next != oia)) 1123 ia = ia->ia_next; 1124 if (ia->ia_next) 1125 ia->ia_next = oia->ia_next; 1126 else 1127 return -1; 1128 } 1129 1130 IFAFREE((&oia->ia_ifa)); 1131 /* xxx 1132 rtrequest(RTM_DELETE, 1133 (struct sockaddr *)&ia->ia_addr, 1134 (struct sockaddr *)0 1135 (struct sockaddr *)&ia->ia_prefixmask, 1136 RTF_UP|RTF_CLONING, 1137 (struct rtentry **)0); 1138 */ 1139 return 0; 1140 } 1141 1142 int 1143 in6_init_prefix_ltimes(struct nd_prefix *ndpr) 1144 { 1145 1146 /* check if preferred lifetime > valid lifetime */ 1147 if (ndpr->ndpr_pltime > ndpr->ndpr_vltime) { 1148 log(LOG_INFO, "in6_init_prefix_ltimes: preferred lifetime" 1149 "(%d) is greater than valid lifetime(%d)\n", 1150 (u_int)ndpr->ndpr_pltime, (u_int)ndpr->ndpr_vltime); 1151 return (EINVAL); 1152 } 1153 if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME) 1154 ndpr->ndpr_preferred = 0; 1155 else 1156 ndpr->ndpr_preferred = time_second + ndpr->ndpr_pltime; 1157 if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME) 1158 ndpr->ndpr_expire = 0; 1159 else 1160 ndpr->ndpr_expire = time_second + ndpr->ndpr_vltime; 1161 1162 return 0; 1163 } 1164 1165 static void 1166 in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6) 1167 { 1168 1169 /* init ia6t_expire */ 1170 if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME) 1171 lt6->ia6t_expire = 0; 1172 else { 1173 lt6->ia6t_expire = time_second; 1174 lt6->ia6t_expire += lt6->ia6t_vltime; 1175 } 1176 /* init ia6t_preferred */ 1177 if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME) 1178 lt6->ia6t_preferred = 0; 1179 else { 1180 lt6->ia6t_preferred = time_second; 1181 lt6->ia6t_preferred += lt6->ia6t_pltime; 1182 } 1183 /* ensure addr lifetime <= prefix lifetime */ 1184 if (new->ndpr_expire && lt6->ia6t_expire && 1185 new->ndpr_expire < lt6->ia6t_expire) 1186 lt6->ia6t_expire = new->ndpr_expire; 1187 if (new->ndpr_preferred && lt6->ia6t_preferred 1188 && new->ndpr_preferred < lt6->ia6t_preferred) 1189 lt6->ia6t_preferred = new->ndpr_preferred; 1190 } 1191 1192 /* 1193 * Delete all the routing table entries that use the specified gateway. 1194 * XXX: this function causes search through all entries of routing table, so 1195 * it shouldn't be called when acting as a router. 1196 */ 1197 void 1198 rt6_flush(gateway, ifp) 1199 struct in6_addr *gateway; 1200 struct ifnet *ifp; 1201 { 1202 struct radix_node_head *rnh = rt_tables[AF_INET6]; 1203 int s = splnet(); 1204 1205 /* We'll care only link-local addresses */ 1206 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) { 1207 splx(s); 1208 return; 1209 } 1210 /* XXX: hack for KAME's link-local address kludge */ 1211 gateway->s6_addr16[1] = htons(ifp->if_index); 1212 1213 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway); 1214 splx(s); 1215 } 1216 1217 static int 1218 rt6_deleteroute(rn, arg) 1219 struct radix_node *rn; 1220 void *arg; 1221 { 1222 #define SIN6(s) ((struct sockaddr_in6 *)s) 1223 struct rtentry *rt = (struct rtentry *)rn; 1224 struct in6_addr *gate = (struct in6_addr *)arg; 1225 1226 if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) 1227 return(0); 1228 1229 if (!IN6_ARE_ADDR_EQUAL(gate, &SIN6(rt->rt_gateway)->sin6_addr)) 1230 return(0); 1231 1232 /* 1233 * We delete only host route. This means, in particular, we don't 1234 * delete default route. 1235 */ 1236 if ((rt->rt_flags & RTF_HOST) == 0) 1237 return(0); 1238 1239 return(rtrequest(RTM_DELETE, rt_key(rt), 1240 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0)); 1241 #undef SIN6 1242 } 1243