1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright (c) 1990 Mentat Inc. 24 */ 25 26 /* 27 * This file contains routines that manipulate Internet Routing Entries (IREs). 28 */ 29 #include <sys/types.h> 30 #include <sys/stream.h> 31 #include <sys/stropts.h> 32 #include <sys/ddi.h> 33 #include <sys/cmn_err.h> 34 35 #include <sys/systm.h> 36 #include <sys/param.h> 37 #include <sys/socket.h> 38 #include <net/if.h> 39 #include <net/route.h> 40 #include <netinet/in.h> 41 #include <net/if_dl.h> 42 #include <netinet/ip6.h> 43 #include <netinet/icmp6.h> 44 45 #include <inet/common.h> 46 #include <inet/mi.h> 47 #include <inet/ip.h> 48 #include <inet/ip6.h> 49 #include <inet/ip_ndp.h> 50 #include <inet/ip_if.h> 51 #include <inet/ip_ire.h> 52 #include <inet/ipclassifier.h> 53 #include <inet/nd.h> 54 #include <inet/tunables.h> 55 #include <sys/kmem.h> 56 #include <sys/zone.h> 57 58 #include <sys/tsol/label.h> 59 #include <sys/tsol/tnet.h> 60 61 #define IS_DEFAULT_ROUTE_V6(ire) \ 62 (((ire)->ire_type & IRE_DEFAULT) || \ 63 (((ire)->ire_type & IRE_INTERFACE) && \ 64 (IN6_IS_ADDR_UNSPECIFIED(&(ire)->ire_addr_v6)))) 65 66 static ire_t ire_null; 67 68 static ire_t * 69 ire_ftable_lookup_impl_v6(const in6_addr_t *addr, const in6_addr_t *mask, 70 const in6_addr_t *gateway, int type, const ill_t *ill, 71 zoneid_t zoneid, const ts_label_t *tsl, int flags, 72 ip_stack_t *ipst); 73 74 /* 75 * Initialize the ire that is specific to IPv6 part and call 76 * ire_init_common to finish it. 77 * Returns zero or errno. 78 */ 79 int 80 ire_init_v6(ire_t *ire, const in6_addr_t *v6addr, const in6_addr_t *v6mask, 81 const in6_addr_t *v6gateway, ushort_t type, ill_t *ill, 82 zoneid_t zoneid, uint_t flags, tsol_gc_t *gc, ip_stack_t *ipst) 83 { 84 int error; 85 86 /* 87 * Reject IRE security attmakeribute creation/initialization 88 * if system is not running in Trusted mode. 89 */ 90 if (gc != NULL && !is_system_labeled()) 91 return (EINVAL); 92 93 BUMP_IRE_STATS(ipst->ips_ire_stats_v6, ire_stats_alloced); 94 if (v6addr != NULL) 95 ire->ire_addr_v6 = *v6addr; 96 if (v6gateway != NULL) 97 ire->ire_gateway_addr_v6 = *v6gateway; 98 99 /* Make sure we don't have stray values in some fields */ 100 switch (type) { 101 case IRE_LOOPBACK: 102 case IRE_HOST: 103 case IRE_LOCAL: 104 case IRE_IF_CLONE: 105 ire->ire_mask_v6 = ipv6_all_ones; 106 ire->ire_masklen = IPV6_ABITS; 107 break; 108 case IRE_PREFIX: 109 case IRE_DEFAULT: 110 case IRE_IF_RESOLVER: 111 case IRE_IF_NORESOLVER: 112 if (v6mask != NULL) { 113 ire->ire_mask_v6 = *v6mask; 114 ire->ire_masklen = 115 ip_mask_to_plen_v6(&ire->ire_mask_v6); 116 } 117 break; 118 case IRE_MULTICAST: 119 case IRE_NOROUTE: 120 ASSERT(v6mask == NULL); 121 break; 122 default: 123 ASSERT(0); 124 return (EINVAL); 125 } 126 127 error = ire_init_common(ire, type, ill, zoneid, flags, IPV6_VERSION, 128 gc, ipst); 129 if (error != NULL) 130 return (error); 131 132 /* Determine which function pointers to use */ 133 ire->ire_postfragfn = ip_xmit; /* Common case */ 134 135 switch (ire->ire_type) { 136 case IRE_LOCAL: 137 ire->ire_sendfn = ire_send_local_v6; 138 ire->ire_recvfn = ire_recv_local_v6; 139 ASSERT(ire->ire_ill != NULL); 140 if (ire->ire_ill->ill_flags & ILLF_NOACCEPT) 141 ire->ire_recvfn = ire_recv_noaccept_v6; 142 break; 143 case IRE_LOOPBACK: 144 ire->ire_sendfn = ire_send_local_v6; 145 ire->ire_recvfn = ire_recv_loopback_v6; 146 break; 147 case IRE_MULTICAST: 148 ire->ire_postfragfn = ip_postfrag_loopcheck; 149 ire->ire_sendfn = ire_send_multicast_v6; 150 ire->ire_recvfn = ire_recv_multicast_v6; 151 break; 152 default: 153 /* 154 * For IRE_IF_ALL and IRE_OFFLINK we forward received 155 * packets by default. 156 */ 157 ire->ire_sendfn = ire_send_wire_v6; 158 ire->ire_recvfn = ire_recv_forward_v6; 159 break; 160 } 161 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { 162 ire->ire_sendfn = ire_send_noroute_v6; 163 ire->ire_recvfn = ire_recv_noroute_v6; 164 } else if (ire->ire_flags & RTF_MULTIRT) { 165 ire->ire_postfragfn = ip_postfrag_multirt_v6; 166 ire->ire_sendfn = ire_send_multirt_v6; 167 ire->ire_recvfn = ire_recv_multirt_v6; 168 } 169 ire->ire_nce_capable = ire_determine_nce_capable(ire); 170 return (0); 171 } 172 173 /* 174 * ire_create_v6 is called to allocate and initialize a new IRE. 175 * 176 * NOTE : This is called as writer sometimes though not required 177 * by this function. 178 */ 179 /* ARGSUSED */ 180 ire_t * 181 ire_create_v6(const in6_addr_t *v6addr, const in6_addr_t *v6mask, 182 const in6_addr_t *v6gateway, ushort_t type, ill_t *ill, zoneid_t zoneid, 183 uint_t flags, tsol_gc_t *gc, ip_stack_t *ipst) 184 { 185 ire_t *ire; 186 int error; 187 188 ASSERT(!IN6_IS_ADDR_V4MAPPED(v6addr)); 189 190 ire = kmem_cache_alloc(ire_cache, KM_NOSLEEP); 191 if (ire == NULL) { 192 DTRACE_PROBE(kmem__cache__alloc); 193 return (NULL); 194 } 195 *ire = ire_null; 196 197 error = ire_init_v6(ire, v6addr, v6mask, v6gateway, 198 type, ill, zoneid, flags, gc, ipst); 199 200 if (error != 0) { 201 DTRACE_PROBE2(ire__init__v6, ire_t *, ire, int, error); 202 kmem_cache_free(ire_cache, ire); 203 return (NULL); 204 } 205 return (ire); 206 } 207 208 /* 209 * Find the ill matching a multicast group. 210 * Allows different routes for multicast addresses 211 * in the unicast routing table (akin to FF::0/8 but could be more specific) 212 * which point at different interfaces. This is used when IPV6_MULTICAST_IF 213 * isn't specified (when sending) and when IPV6_JOIN_GROUP doesn't 214 * specify the interface to join on. 215 * 216 * Supports link-local addresses by using ire_route_recursive which follows 217 * the ill when recursing. 218 * 219 * To handle CGTP, since we don't have a separate IRE_MULTICAST for each group 220 * and the MULTIRT property can be different for different groups, we 221 * extract RTF_MULTIRT from the special unicast route added for a group 222 * with CGTP and pass that back in the multirtp argument. 223 * This is used in ip_set_destination etc to set ixa_postfragfn for multicast. 224 * We have a setsrcp argument for the same reason. 225 */ 226 ill_t * 227 ire_lookup_multi_ill_v6(const in6_addr_t *group, zoneid_t zoneid, 228 ip_stack_t *ipst, boolean_t *multirtp, in6_addr_t *setsrcp) 229 { 230 ire_t *ire; 231 ill_t *ill; 232 233 ire = ire_route_recursive_v6(group, 0, NULL, zoneid, NULL, 234 MATCH_IRE_DSTONLY, IRR_NONE, 0, ipst, setsrcp, NULL, NULL); 235 ASSERT(ire != NULL); 236 237 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) { 238 ire_refrele(ire); 239 return (NULL); 240 } 241 242 if (multirtp != NULL) 243 *multirtp = (ire->ire_flags & RTF_MULTIRT) != 0; 244 245 ill = ire_nexthop_ill(ire); 246 ire_refrele(ire); 247 return (ill); 248 } 249 250 /* 251 * This function takes a mask and returns number of bits set in the 252 * mask (the represented prefix length). Assumes a contiguous mask. 253 */ 254 int 255 ip_mask_to_plen_v6(const in6_addr_t *v6mask) 256 { 257 int bits; 258 int plen = IPV6_ABITS; 259 int i; 260 261 for (i = 3; i >= 0; i--) { 262 if (v6mask->s6_addr32[i] == 0) { 263 plen -= 32; 264 continue; 265 } 266 bits = ffs(ntohl(v6mask->s6_addr32[i])) - 1; 267 if (bits == 0) 268 break; 269 plen -= bits; 270 } 271 272 return (plen); 273 } 274 275 /* 276 * Convert a prefix length to the mask for that prefix. 277 * Returns the argument bitmask. 278 */ 279 in6_addr_t * 280 ip_plen_to_mask_v6(uint_t plen, in6_addr_t *bitmask) 281 { 282 uint32_t *ptr; 283 284 if (plen < 0 || plen > IPV6_ABITS) 285 return (NULL); 286 *bitmask = ipv6_all_zeros; 287 if (plen == 0) 288 return (bitmask); 289 290 ptr = (uint32_t *)bitmask; 291 while (plen > 32) { 292 *ptr++ = 0xffffffffU; 293 plen -= 32; 294 } 295 *ptr = htonl(0xffffffffU << (32 - plen)); 296 return (bitmask); 297 } 298 299 /* 300 * Add a fully initialized IPv6 IRE to the forwarding table. 301 * This returns NULL on failure, or a held IRE on success. 302 * Normally the returned IRE is the same as the argument. But a different 303 * IRE will be returned if the added IRE is deemed identical to an existing 304 * one. In that case ire_identical_ref will be increased. 305 * The caller always needs to do an ire_refrele() on the returned IRE. 306 */ 307 ire_t * 308 ire_add_v6(ire_t *ire) 309 { 310 ire_t *ire1; 311 int mask_table_index; 312 irb_t *irb_ptr; 313 ire_t **irep; 314 int match_flags; 315 int error; 316 ip_stack_t *ipst = ire->ire_ipst; 317 318 ASSERT(ire->ire_ipversion == IPV6_VERSION); 319 320 /* Make sure the address is properly masked. */ 321 V6_MASK_COPY(ire->ire_addr_v6, ire->ire_mask_v6, ire->ire_addr_v6); 322 323 mask_table_index = ip_mask_to_plen_v6(&ire->ire_mask_v6); 324 if ((ipst->ips_ip_forwarding_table_v6[mask_table_index]) == NULL) { 325 irb_t *ptr; 326 int i; 327 328 ptr = (irb_t *)mi_zalloc((ipst->ips_ip6_ftable_hash_size * 329 sizeof (irb_t))); 330 if (ptr == NULL) { 331 ire_delete(ire); 332 return (NULL); 333 } 334 for (i = 0; i < ipst->ips_ip6_ftable_hash_size; i++) { 335 rw_init(&ptr[i].irb_lock, NULL, RW_DEFAULT, NULL); 336 ptr[i].irb_ipst = ipst; 337 } 338 mutex_enter(&ipst->ips_ire_ft_init_lock); 339 if (ipst->ips_ip_forwarding_table_v6[mask_table_index] == 340 NULL) { 341 ipst->ips_ip_forwarding_table_v6[mask_table_index] = 342 ptr; 343 mutex_exit(&ipst->ips_ire_ft_init_lock); 344 } else { 345 /* 346 * Some other thread won the race in 347 * initializing the forwarding table at the 348 * same index. 349 */ 350 mutex_exit(&ipst->ips_ire_ft_init_lock); 351 for (i = 0; i < ipst->ips_ip6_ftable_hash_size; i++) { 352 rw_destroy(&ptr[i].irb_lock); 353 } 354 mi_free(ptr); 355 } 356 } 357 irb_ptr = &(ipst->ips_ip_forwarding_table_v6[mask_table_index][ 358 IRE_ADDR_MASK_HASH_V6(ire->ire_addr_v6, ire->ire_mask_v6, 359 ipst->ips_ip6_ftable_hash_size)]); 360 361 match_flags = (MATCH_IRE_MASK | MATCH_IRE_TYPE | MATCH_IRE_GW); 362 if (ire->ire_ill != NULL) 363 match_flags |= MATCH_IRE_ILL; 364 /* 365 * Start the atomic add of the ire. Grab the bucket lock and the 366 * ill lock. Check for condemned. 367 */ 368 error = ire_atomic_start(irb_ptr, ire); 369 if (error != 0) { 370 ire_delete(ire); 371 return (NULL); 372 } 373 374 /* 375 * If we are creating a hidden IRE, make sure we search for 376 * hidden IREs when searching for duplicates below. 377 * Otherwise, we might find an IRE on some other interface 378 * that's not marked hidden. 379 */ 380 if (ire->ire_testhidden) 381 match_flags |= MATCH_IRE_TESTHIDDEN; 382 383 /* 384 * Atomically check for duplicate and insert in the table. 385 */ 386 for (ire1 = irb_ptr->irb_ire; ire1 != NULL; ire1 = ire1->ire_next) { 387 if (IRE_IS_CONDEMNED(ire1)) 388 continue; 389 /* 390 * Here we need an exact match on zoneid, i.e., 391 * ire_match_args doesn't fit. 392 */ 393 if (ire1->ire_zoneid != ire->ire_zoneid) 394 continue; 395 396 if (ire1->ire_type != ire->ire_type) 397 continue; 398 399 /* 400 * Note: We do not allow multiple routes that differ only 401 * in the gateway security attributes; such routes are 402 * considered duplicates. 403 * To change that we explicitly have to treat them as 404 * different here. 405 */ 406 if (ire_match_args_v6(ire1, &ire->ire_addr_v6, 407 &ire->ire_mask_v6, &ire->ire_gateway_addr_v6, 408 ire->ire_type, ire->ire_ill, ire->ire_zoneid, NULL, 409 match_flags)) { 410 /* 411 * Return the old ire after doing a REFHOLD. 412 * As most of the callers continue to use the IRE 413 * after adding, we return a held ire. This will 414 * avoid a lookup in the caller again. If the callers 415 * don't want to use it, they need to do a REFRELE. 416 * 417 * We only allow exactly one IRE_IF_CLONE for any dst, 418 * so, if the is an IF_CLONE, return the ire without 419 * an identical_ref, but with an ire_ref held. 420 */ 421 if (ire->ire_type != IRE_IF_CLONE) { 422 atomic_add_32(&ire1->ire_identical_ref, 1); 423 DTRACE_PROBE2(ire__add__exist, ire_t *, ire1, 424 ire_t *, ire); 425 } 426 ip1dbg(("found dup ire existing %p new %p", 427 (void *)ire1, (void *)ire)); 428 ire_refhold(ire1); 429 ire_atomic_end(irb_ptr, ire); 430 ire_delete(ire); 431 return (ire1); 432 } 433 } 434 435 /* 436 * Normally we do head insertion since most things do not care about 437 * the order of the IREs in the bucket. 438 * However, due to shared-IP zones (and restrict_interzone_loopback) 439 * we can have an IRE_LOCAL as well as IRE_IF_CLONE for the same 440 * address. For that reason we do tail insertion for IRE_IF_CLONE. 441 */ 442 irep = (ire_t **)irb_ptr; 443 if (ire->ire_type & IRE_IF_CLONE) { 444 while ((ire1 = *irep) != NULL) 445 irep = &ire1->ire_next; 446 } 447 /* Insert at *irep */ 448 ire1 = *irep; 449 if (ire1 != NULL) 450 ire1->ire_ptpn = &ire->ire_next; 451 ire->ire_next = ire1; 452 /* Link the new one in. */ 453 ire->ire_ptpn = irep; 454 /* 455 * ire_walk routines de-reference ire_next without holding 456 * a lock. Before we point to the new ire, we want to make 457 * sure the store that sets the ire_next of the new ire 458 * reaches global visibility, so that ire_walk routines 459 * don't see a truncated list of ires i.e if the ire_next 460 * of the new ire gets set after we do "*irep = ire" due 461 * to re-ordering, the ire_walk thread will see a NULL 462 * once it accesses the ire_next of the new ire. 463 * membar_producer() makes sure that the following store 464 * happens *after* all of the above stores. 465 */ 466 membar_producer(); 467 *irep = ire; 468 ire->ire_bucket = irb_ptr; 469 /* 470 * We return a bumped up IRE above. Keep it symmetrical 471 * so that the callers will always have to release. This 472 * helps the callers of this function because they continue 473 * to use the IRE after adding and hence they don't have to 474 * lookup again after we return the IRE. 475 * 476 * NOTE : We don't have to use atomics as this is appearing 477 * in the list for the first time and no one else can bump 478 * up the reference count on this yet. 479 */ 480 ire_refhold_locked(ire); 481 BUMP_IRE_STATS(ipst->ips_ire_stats_v6, ire_stats_inserted); 482 irb_ptr->irb_ire_cnt++; 483 484 if (ire->ire_ill != NULL) { 485 DTRACE_PROBE3(ill__incr__cnt, (ill_t *), ire->ire_ill, 486 (char *), "ire", (void *), ire); 487 ire->ire_ill->ill_ire_cnt++; 488 ASSERT(ire->ire_ill->ill_ire_cnt != 0); /* Wraparound */ 489 } 490 ire_atomic_end(irb_ptr, ire); 491 492 /* Make any caching of the IREs be notified or updated */ 493 ire_flush_cache_v6(ire, IRE_FLUSH_ADD); 494 495 return (ire); 496 } 497 498 /* 499 * Search for all HOST REDIRECT routes that are 500 * pointing at the specified gateway and 501 * delete them. This routine is called only 502 * when a default gateway is going away. 503 */ 504 static void 505 ire_delete_host_redirects_v6(const in6_addr_t *gateway, ip_stack_t *ipst) 506 { 507 irb_t *irb_ptr; 508 irb_t *irb; 509 ire_t *ire; 510 in6_addr_t gw_addr_v6; 511 int i; 512 513 /* get the hash table for HOST routes */ 514 irb_ptr = ipst->ips_ip_forwarding_table_v6[(IP6_MASK_TABLE_SIZE - 1)]; 515 if (irb_ptr == NULL) 516 return; 517 for (i = 0; (i < ipst->ips_ip6_ftable_hash_size); i++) { 518 irb = &irb_ptr[i]; 519 irb_refhold(irb); 520 for (ire = irb->irb_ire; ire != NULL; ire = ire->ire_next) { 521 if (!(ire->ire_flags & RTF_DYNAMIC)) 522 continue; 523 mutex_enter(&ire->ire_lock); 524 gw_addr_v6 = ire->ire_gateway_addr_v6; 525 mutex_exit(&ire->ire_lock); 526 if (IN6_ARE_ADDR_EQUAL(&gw_addr_v6, gateway)) 527 ire_delete(ire); 528 } 529 irb_refrele(irb); 530 } 531 } 532 533 /* 534 * Delete the specified IRE. 535 * All calls should use ire_delete(). 536 * Sometimes called as writer though not required by this function. 537 * 538 * NOTE : This function is called only if the ire was added 539 * in the list. 540 */ 541 void 542 ire_delete_v6(ire_t *ire) 543 { 544 in6_addr_t gw_addr_v6; 545 ip_stack_t *ipst = ire->ire_ipst; 546 547 /* 548 * Make sure ire_generation increases from ire_flush_cache happen 549 * after any lookup/reader has read ire_generation. 550 * Since the rw_enter makes us wait until any lookup/reader has 551 * completed we can exit the lock immediately. 552 */ 553 rw_enter(&ipst->ips_ip6_ire_head_lock, RW_WRITER); 554 rw_exit(&ipst->ips_ip6_ire_head_lock); 555 556 ASSERT(ire->ire_refcnt >= 1); 557 ASSERT(ire->ire_ipversion == IPV6_VERSION); 558 559 ire_flush_cache_v6(ire, IRE_FLUSH_DELETE); 560 561 if (ire->ire_type == IRE_DEFAULT) { 562 /* 563 * when a default gateway is going away 564 * delete all the host redirects pointing at that 565 * gateway. 566 */ 567 mutex_enter(&ire->ire_lock); 568 gw_addr_v6 = ire->ire_gateway_addr_v6; 569 mutex_exit(&ire->ire_lock); 570 ire_delete_host_redirects_v6(&gw_addr_v6, ipst); 571 } 572 573 /* 574 * If we are deleting an IRE_INTERFACE then we make sure we also 575 * delete any IRE_IF_CLONE that has been created from it. 576 * Those are always in ire_dep_children. 577 */ 578 if ((ire->ire_type & IRE_INTERFACE) && ire->ire_dep_children != 0) 579 ire_dep_delete_if_clone(ire); 580 581 /* Remove from parent dependencies and child */ 582 rw_enter(&ipst->ips_ire_dep_lock, RW_WRITER); 583 if (ire->ire_dep_parent != NULL) { 584 ire_dep_remove(ire); 585 } 586 while (ire->ire_dep_children != NULL) 587 ire_dep_remove(ire->ire_dep_children); 588 rw_exit(&ipst->ips_ire_dep_lock); 589 } 590 591 /* 592 * When an IRE is added or deleted this routine is called to make sure 593 * any caching of IRE information is notified or updated. 594 * 595 * The flag argument indicates if the flush request is due to addition 596 * of new route (IRE_FLUSH_ADD), deletion of old route (IRE_FLUSH_DELETE), 597 * or a change to ire_gateway_addr (IRE_FLUSH_GWCHANGE). 598 */ 599 void 600 ire_flush_cache_v6(ire_t *ire, int flag) 601 { 602 ip_stack_t *ipst = ire->ire_ipst; 603 604 /* 605 * IRE_IF_CLONE ire's don't provide any new information 606 * than the parent from which they are cloned, so don't 607 * perturb the generation numbers. 608 */ 609 if (ire->ire_type & IRE_IF_CLONE) 610 return; 611 612 /* 613 * Ensure that an ire_add during a lookup serializes the updates of 614 * the generation numbers under ire_head_lock so that the lookup gets 615 * either the old ire and old generation number, or a new ire and new 616 * generation number. 617 */ 618 rw_enter(&ipst->ips_ip6_ire_head_lock, RW_WRITER); 619 620 /* 621 * If a route was just added, we need to notify everybody that 622 * has cached an IRE_NOROUTE since there might now be a better 623 * route for them. 624 */ 625 if (flag == IRE_FLUSH_ADD) { 626 ire_increment_generation(ipst->ips_ire_reject_v6); 627 ire_increment_generation(ipst->ips_ire_blackhole_v6); 628 } 629 630 /* Adding a default can't otherwise provide a better route */ 631 if (ire->ire_type == IRE_DEFAULT && flag == IRE_FLUSH_ADD) { 632 rw_exit(&ipst->ips_ip6_ire_head_lock); 633 return; 634 } 635 636 switch (flag) { 637 case IRE_FLUSH_DELETE: 638 case IRE_FLUSH_GWCHANGE: 639 /* 640 * Update ire_generation for all ire_dep_children chains 641 * starting with this IRE 642 */ 643 ire_dep_incr_generation(ire); 644 break; 645 case IRE_FLUSH_ADD: { 646 in6_addr_t addr; 647 in6_addr_t mask; 648 ip_stack_t *ipst = ire->ire_ipst; 649 uint_t masklen; 650 651 /* 652 * Find an IRE which is a shorter match than the ire to be added 653 * For any such IRE (which we repeat) we update the 654 * ire_generation the same way as in the delete case. 655 */ 656 addr = ire->ire_addr_v6; 657 mask = ire->ire_mask_v6; 658 masklen = ip_mask_to_plen_v6(&mask); 659 660 ire = ire_ftable_lookup_impl_v6(&addr, &mask, NULL, 0, NULL, 661 ALL_ZONES, NULL, MATCH_IRE_SHORTERMASK, ipst); 662 while (ire != NULL) { 663 /* We need to handle all in the same bucket */ 664 irb_increment_generation(ire->ire_bucket); 665 666 mask = ire->ire_mask_v6; 667 ASSERT(masklen > ip_mask_to_plen_v6(&mask)); 668 masklen = ip_mask_to_plen_v6(&mask); 669 ire_refrele(ire); 670 ire = ire_ftable_lookup_impl_v6(&addr, &mask, NULL, 0, 671 NULL, ALL_ZONES, NULL, MATCH_IRE_SHORTERMASK, ipst); 672 } 673 } 674 break; 675 } 676 rw_exit(&ipst->ips_ip6_ire_head_lock); 677 } 678 679 /* 680 * Matches the arguments passed with the values in the ire. 681 * 682 * Note: for match types that match using "ill" passed in, ill 683 * must be checked for non-NULL before calling this routine. 684 */ 685 boolean_t 686 ire_match_args_v6(ire_t *ire, const in6_addr_t *addr, const in6_addr_t *mask, 687 const in6_addr_t *gateway, int type, const ill_t *ill, zoneid_t zoneid, 688 const ts_label_t *tsl, int match_flags) 689 { 690 in6_addr_t gw_addr_v6; 691 ill_t *ire_ill = NULL, *dst_ill; 692 ip_stack_t *ipst = ire->ire_ipst; 693 694 ASSERT(ire->ire_ipversion == IPV6_VERSION); 695 ASSERT(addr != NULL); 696 ASSERT(mask != NULL); 697 ASSERT((!(match_flags & MATCH_IRE_GW)) || gateway != NULL); 698 ASSERT((!(match_flags & (MATCH_IRE_ILL|MATCH_IRE_SRC_ILL))) || 699 (ill != NULL && ill->ill_isv6)); 700 701 /* 702 * If MATCH_IRE_TESTHIDDEN is set, then only return the IRE if it 703 * is in fact hidden, to ensure the caller gets the right one. 704 */ 705 if (ire->ire_testhidden) { 706 if (!(match_flags & MATCH_IRE_TESTHIDDEN)) 707 return (B_FALSE); 708 } 709 710 if (zoneid != ALL_ZONES && zoneid != ire->ire_zoneid && 711 ire->ire_zoneid != ALL_ZONES) { 712 /* 713 * If MATCH_IRE_ZONEONLY has been set and the supplied zoneid 714 * does not match that of ire_zoneid, a failure to 715 * match is reported at this point. Otherwise, since some IREs 716 * that are available in the global zone can be used in local 717 * zones, additional checks need to be performed: 718 * 719 * IRE_LOOPBACK 720 * entries should never be matched in this situation. 721 * Each zone has its own IRE_LOOPBACK. 722 * 723 * IRE_LOCAL 724 * We allow them for any zoneid. ire_route_recursive 725 * does additional checks when 726 * ip_restrict_interzone_loopback is set. 727 * 728 * If ill_usesrc_ifindex is set 729 * Then we check if the zone has a valid source address 730 * on the usesrc ill. 731 * 732 * If ire_ill is set, then check that the zone has an ipif 733 * on that ill. 734 * 735 * Outside of this function (in ire_round_robin) we check 736 * that any IRE_OFFLINK has a gateway that reachable from the 737 * zone when we have multiple choices (ECMP). 738 */ 739 if (match_flags & MATCH_IRE_ZONEONLY) 740 return (B_FALSE); 741 if (ire->ire_type & IRE_LOOPBACK) 742 return (B_FALSE); 743 744 if (ire->ire_type & IRE_LOCAL) 745 goto matchit; 746 747 /* 748 * The normal case of IRE_ONLINK has a matching zoneid. 749 * Here we handle the case when shared-IP zones have been 750 * configured with IP addresses on vniN. In that case it 751 * is ok for traffic from a zone to use IRE_ONLINK routes 752 * if the ill has a usesrc pointing at vniN 753 * Applies to IRE_INTERFACE. 754 */ 755 dst_ill = ire->ire_ill; 756 if (ire->ire_type & IRE_ONLINK) { 757 uint_t ifindex; 758 759 /* 760 * Note there is no IRE_INTERFACE on vniN thus 761 * can't do an IRE lookup for a matching route. 762 */ 763 ifindex = dst_ill->ill_usesrc_ifindex; 764 if (ifindex == 0) 765 return (B_FALSE); 766 767 /* 768 * If there is a usable source address in the 769 * zone, then it's ok to return this IRE_INTERFACE 770 */ 771 if (!ipif_zone_avail(ifindex, dst_ill->ill_isv6, 772 zoneid, ipst)) { 773 ip3dbg(("ire_match_args: no usrsrc for zone" 774 " dst_ill %p\n", (void *)dst_ill)); 775 return (B_FALSE); 776 } 777 } 778 /* 779 * For example, with 780 * route add 11.0.0.0 gw1 -ifp bge0 781 * route add 11.0.0.0 gw2 -ifp bge1 782 * this code would differentiate based on 783 * where the sending zone has addresses. 784 * Only if the zone has an address on bge0 can it use the first 785 * route. It isn't clear if this behavior is documented 786 * anywhere. 787 */ 788 if (dst_ill != NULL && (ire->ire_type & IRE_OFFLINK)) { 789 ipif_t *tipif; 790 791 mutex_enter(&dst_ill->ill_lock); 792 for (tipif = dst_ill->ill_ipif; 793 tipif != NULL; tipif = tipif->ipif_next) { 794 if (!IPIF_IS_CONDEMNED(tipif) && 795 (tipif->ipif_flags & IPIF_UP) && 796 (tipif->ipif_zoneid == zoneid || 797 tipif->ipif_zoneid == ALL_ZONES)) 798 break; 799 } 800 mutex_exit(&dst_ill->ill_lock); 801 if (tipif == NULL) 802 return (B_FALSE); 803 } 804 } 805 806 matchit: 807 ire_ill = ire->ire_ill; 808 if (match_flags & MATCH_IRE_GW) { 809 mutex_enter(&ire->ire_lock); 810 gw_addr_v6 = ire->ire_gateway_addr_v6; 811 mutex_exit(&ire->ire_lock); 812 } 813 if (match_flags & MATCH_IRE_ILL) { 814 815 /* 816 * If asked to match an ill, we *must* match 817 * on the ire_ill for ipmp test addresses, or 818 * any of the ill in the group for data addresses. 819 * If we don't, we may as well fail. 820 * However, we need an exception for IRE_LOCALs to ensure 821 * we loopback packets even sent to test addresses on different 822 * interfaces in the group. 823 */ 824 if ((match_flags & MATCH_IRE_TESTHIDDEN) && 825 !(ire->ire_type & IRE_LOCAL)) { 826 if (ire->ire_ill != ill) 827 return (B_FALSE); 828 } else { 829 match_flags &= ~MATCH_IRE_TESTHIDDEN; 830 /* 831 * We know that ill is not NULL, but ire_ill could be 832 * NULL 833 */ 834 if (ire_ill == NULL || !IS_ON_SAME_LAN(ill, ire_ill)) 835 return (B_FALSE); 836 } 837 } 838 if (match_flags & MATCH_IRE_SRC_ILL) { 839 if (ire_ill == NULL) 840 return (B_FALSE); 841 if (!IS_ON_SAME_LAN(ill, ire_ill)) { 842 if (ire_ill->ill_usesrc_ifindex == 0 || 843 (ire_ill->ill_usesrc_ifindex != 844 ill->ill_phyint->phyint_ifindex)) 845 return (B_FALSE); 846 } 847 } 848 849 /* No ire_addr_v6 bits set past the mask */ 850 ASSERT(V6_MASK_EQ(ire->ire_addr_v6, ire->ire_mask_v6, 851 ire->ire_addr_v6)); 852 if (V6_MASK_EQ(*addr, *mask, ire->ire_addr_v6) && 853 ((!(match_flags & MATCH_IRE_GW)) || 854 ((!(match_flags & MATCH_IRE_DIRECT)) || 855 !(ire->ire_flags & RTF_INDIRECT)) && 856 IN6_ARE_ADDR_EQUAL(&gw_addr_v6, gateway)) && 857 ((!(match_flags & MATCH_IRE_TYPE)) || (ire->ire_type & type)) && 858 ((!(match_flags & MATCH_IRE_TESTHIDDEN)) || ire->ire_testhidden) && 859 ((!(match_flags & MATCH_IRE_MASK)) || 860 (IN6_ARE_ADDR_EQUAL(&ire->ire_mask_v6, mask))) && 861 ((!(match_flags & MATCH_IRE_SECATTR)) || 862 (!is_system_labeled()) || 863 (tsol_ire_match_gwattr(ire, tsl) == 0))) { 864 /* We found the matched IRE */ 865 return (B_TRUE); 866 } 867 return (B_FALSE); 868 } 869 870 /* 871 * Check if the zoneid (not ALL_ZONES) has an IRE_INTERFACE for the specified 872 * gateway address. If ill is non-NULL we also match on it. 873 * The caller must hold a read lock on RADIX_NODE_HEAD if lock_held is set. 874 */ 875 boolean_t 876 ire_gateway_ok_zone_v6(const in6_addr_t *gateway, zoneid_t zoneid, ill_t *ill, 877 const ts_label_t *tsl, ip_stack_t *ipst, boolean_t lock_held) 878 { 879 ire_t *ire; 880 uint_t match_flags; 881 882 if (lock_held) 883 ASSERT(RW_READ_HELD(&ipst->ips_ip6_ire_head_lock)); 884 else 885 rw_enter(&ipst->ips_ip6_ire_head_lock, RW_READER); 886 887 match_flags = MATCH_IRE_TYPE | MATCH_IRE_SECATTR; 888 if (ill != NULL) 889 match_flags |= MATCH_IRE_ILL; 890 891 ire = ire_ftable_lookup_impl_v6(gateway, &ipv6_all_zeros, 892 &ipv6_all_zeros, IRE_INTERFACE, ill, zoneid, tsl, match_flags, 893 ipst); 894 895 if (!lock_held) 896 rw_exit(&ipst->ips_ip6_ire_head_lock); 897 if (ire != NULL) { 898 ire_refrele(ire); 899 return (B_TRUE); 900 } else { 901 return (B_FALSE); 902 } 903 } 904 905 /* 906 * Lookup a route in forwarding table. 907 * specific lookup is indicated by passing the 908 * required parameters and indicating the 909 * match required in flag field. 910 * 911 * Supports link-local addresses by following the ipif/ill when recursing. 912 */ 913 ire_t * 914 ire_ftable_lookup_v6(const in6_addr_t *addr, const in6_addr_t *mask, 915 const in6_addr_t *gateway, int type, const ill_t *ill, 916 zoneid_t zoneid, const ts_label_t *tsl, int flags, 917 uint32_t xmit_hint, ip_stack_t *ipst, uint_t *generationp) 918 { 919 ire_t *ire = NULL; 920 921 ASSERT(addr != NULL); 922 ASSERT((!(flags & MATCH_IRE_MASK)) || mask != NULL); 923 ASSERT((!(flags & MATCH_IRE_GW)) || gateway != NULL); 924 ASSERT(ill == NULL || ill->ill_isv6); 925 926 ASSERT(!IN6_IS_ADDR_V4MAPPED(addr)); 927 928 /* 929 * ire_match_args_v6() will dereference ill if MATCH_IRE_ILL 930 * or MATCH_IRE_SRC_ILL is set. 931 */ 932 if ((flags & (MATCH_IRE_ILL|MATCH_IRE_SRC_ILL)) && (ill == NULL)) 933 return (NULL); 934 935 rw_enter(&ipst->ips_ip6_ire_head_lock, RW_READER); 936 ire = ire_ftable_lookup_impl_v6(addr, mask, gateway, type, ill, zoneid, 937 tsl, flags, ipst); 938 if (ire == NULL) { 939 rw_exit(&ipst->ips_ip6_ire_head_lock); 940 return (NULL); 941 } 942 943 /* 944 * round-robin only if we have more than one route in the bucket. 945 * ips_ip_ecmp_behavior controls when we do ECMP 946 * 2: always 947 * 1: for IRE_DEFAULT and /0 IRE_INTERFACE 948 * 0: never 949 * 950 * Note: if we found an IRE_IF_CLONE we won't look at the bucket with 951 * other ECMP IRE_INTERFACEs since the IRE_IF_CLONE is a /128 match 952 * and the IRE_INTERFACESs are likely to be shorter matches. 953 */ 954 if (ire->ire_bucket->irb_ire_cnt > 1 && !(flags & MATCH_IRE_GW)) { 955 if (ipst->ips_ip_ecmp_behavior == 2 || 956 (ipst->ips_ip_ecmp_behavior == 1 && 957 IS_DEFAULT_ROUTE_V6(ire))) { 958 ire_t *next_ire; 959 ire_ftable_args_t margs; 960 961 bzero(&margs, sizeof (margs)); 962 margs.ift_addr_v6 = *addr; 963 if (mask != NULL) 964 margs.ift_mask_v6 = *mask; 965 if (gateway != NULL) 966 margs.ift_gateway_v6 = *gateway; 967 margs.ift_type = type; 968 margs.ift_ill = ill; 969 margs.ift_zoneid = zoneid; 970 margs.ift_tsl = tsl; 971 margs.ift_flags = flags; 972 973 next_ire = ire_round_robin(ire->ire_bucket, &margs, 974 xmit_hint, ire, ipst); 975 if (next_ire == NULL) { 976 /* keep ire if next_ire is null */ 977 goto done; 978 } 979 ire_refrele(ire); 980 ire = next_ire; 981 } 982 } 983 984 done: 985 /* Return generation before dropping lock */ 986 if (generationp != NULL) 987 *generationp = ire->ire_generation; 988 989 rw_exit(&ipst->ips_ip6_ire_head_lock); 990 991 /* 992 * For shared-IP zones we need additional checks to what was 993 * done in ire_match_args to make sure IRE_LOCALs are handled. 994 * 995 * When ip_restrict_interzone_loopback is set, then 996 * we ensure that IRE_LOCAL are only used for loopback 997 * between zones when the logical "Ethernet" would 998 * have looped them back. That is, if in the absense of 999 * the IRE_LOCAL we would have sent to packet out the 1000 * same ill. 1001 */ 1002 if ((ire->ire_type & IRE_LOCAL) && zoneid != ALL_ZONES && 1003 ire->ire_zoneid != zoneid && ire->ire_zoneid != ALL_ZONES && 1004 ipst->ips_ip_restrict_interzone_loopback) { 1005 ire = ire_alt_local(ire, zoneid, tsl, ill, generationp); 1006 ASSERT(ire != NULL); 1007 } 1008 1009 return (ire); 1010 } 1011 1012 /* 1013 * Look up a single ire. The caller holds either the read or write lock. 1014 */ 1015 ire_t * 1016 ire_ftable_lookup_impl_v6(const in6_addr_t *addr, const in6_addr_t *mask, 1017 const in6_addr_t *gateway, int type, const ill_t *ill, 1018 zoneid_t zoneid, const ts_label_t *tsl, int flags, 1019 ip_stack_t *ipst) 1020 { 1021 irb_t *irb_ptr; 1022 ire_t *ire = NULL; 1023 int i; 1024 1025 ASSERT(RW_LOCK_HELD(&ipst->ips_ip6_ire_head_lock)); 1026 1027 /* 1028 * If the mask is known, the lookup 1029 * is simple, if the mask is not known 1030 * we need to search. 1031 */ 1032 if (flags & MATCH_IRE_MASK) { 1033 uint_t masklen; 1034 1035 masklen = ip_mask_to_plen_v6(mask); 1036 if (ipst->ips_ip_forwarding_table_v6[masklen] == NULL) { 1037 return (NULL); 1038 } 1039 irb_ptr = &(ipst->ips_ip_forwarding_table_v6[masklen][ 1040 IRE_ADDR_MASK_HASH_V6(*addr, *mask, 1041 ipst->ips_ip6_ftable_hash_size)]); 1042 rw_enter(&irb_ptr->irb_lock, RW_READER); 1043 for (ire = irb_ptr->irb_ire; ire != NULL; 1044 ire = ire->ire_next) { 1045 if (IRE_IS_CONDEMNED(ire)) 1046 continue; 1047 if (ire_match_args_v6(ire, addr, mask, gateway, type, 1048 ill, zoneid, tsl, flags)) 1049 goto found_ire; 1050 } 1051 rw_exit(&irb_ptr->irb_lock); 1052 } else { 1053 uint_t masklen; 1054 1055 /* 1056 * In this case we don't know the mask, we need to 1057 * search the table assuming different mask sizes. 1058 */ 1059 if (flags & MATCH_IRE_SHORTERMASK) { 1060 masklen = ip_mask_to_plen_v6(mask); 1061 if (masklen == 0) { 1062 /* Nothing shorter than zero */ 1063 return (NULL); 1064 } 1065 masklen--; 1066 } else { 1067 masklen = IP6_MASK_TABLE_SIZE - 1; 1068 } 1069 1070 for (i = masklen; i >= 0; i--) { 1071 in6_addr_t tmpmask; 1072 1073 if ((ipst->ips_ip_forwarding_table_v6[i]) == NULL) 1074 continue; 1075 (void) ip_plen_to_mask_v6(i, &tmpmask); 1076 irb_ptr = &ipst->ips_ip_forwarding_table_v6[i][ 1077 IRE_ADDR_MASK_HASH_V6(*addr, tmpmask, 1078 ipst->ips_ip6_ftable_hash_size)]; 1079 rw_enter(&irb_ptr->irb_lock, RW_READER); 1080 for (ire = irb_ptr->irb_ire; ire != NULL; 1081 ire = ire->ire_next) { 1082 if (IRE_IS_CONDEMNED(ire)) 1083 continue; 1084 if (ire_match_args_v6(ire, addr, 1085 &ire->ire_mask_v6, gateway, type, ill, 1086 zoneid, tsl, flags)) 1087 goto found_ire; 1088 } 1089 rw_exit(&irb_ptr->irb_lock); 1090 } 1091 } 1092 ASSERT(ire == NULL); 1093 ip1dbg(("ire_ftable_lookup_v6: returning NULL ire")); 1094 return (NULL); 1095 1096 found_ire: 1097 ire_refhold(ire); 1098 rw_exit(&irb_ptr->irb_lock); 1099 return (ire); 1100 } 1101 1102 1103 /* 1104 * This function is called by 1105 * ip_input/ire_route_recursive when doing a route lookup on only the 1106 * destination address. 1107 * 1108 * The optimizations of this function over ire_ftable_lookup are: 1109 * o removing unnecessary flag matching 1110 * o doing longest prefix match instead of overloading it further 1111 * with the unnecessary "best_prefix_match" 1112 * 1113 * If no route is found we return IRE_NOROUTE. 1114 */ 1115 ire_t * 1116 ire_ftable_lookup_simple_v6(const in6_addr_t *addr, uint32_t xmit_hint, 1117 ip_stack_t *ipst, uint_t *generationp) 1118 { 1119 ire_t *ire; 1120 1121 ire = ire_ftable_lookup_v6(addr, NULL, NULL, 0, NULL, ALL_ZONES, NULL, 1122 MATCH_IRE_DSTONLY, xmit_hint, ipst, generationp); 1123 if (ire == NULL) { 1124 ire = ire_reject(ipst, B_TRUE); 1125 if (generationp != NULL) 1126 *generationp = IRE_GENERATION_VERIFY; 1127 } 1128 /* ftable_lookup did round robin */ 1129 return (ire); 1130 } 1131 1132 ire_t * 1133 ip_select_route_v6(const in6_addr_t *dst, const in6_addr_t src, 1134 ip_xmit_attr_t *ixa, uint_t *generationp, in6_addr_t *setsrcp, 1135 int *errorp, boolean_t *multirtp) 1136 { 1137 ASSERT(!(ixa->ixa_flags & IXAF_IS_IPV4)); 1138 1139 return (ip_select_route(dst, src, ixa, generationp, setsrcp, errorp, 1140 multirtp)); 1141 } 1142 1143 /* 1144 * Recursively look for a route to the destination. Can also match on 1145 * the zoneid, ill, and label. Used for the data paths. See also 1146 * ire_route_recursive_dstonly. 1147 * 1148 * If IRR_ALLOCATE is not set then we will only inspect the existing IREs; never 1149 * create an IRE_IF_CLONE. This is used on the receive side when we are not 1150 * forwarding. 1151 * If IRR_INCOMPLETE is set then we return the IRE even if we can't correctly 1152 * resolve the gateway. 1153 * 1154 * Note that this function never returns NULL. It returns an IRE_NOROUTE 1155 * instead. 1156 * 1157 * If we find any IRE_LOCAL|BROADCAST etc past the first iteration it 1158 * is an error. 1159 * Allow at most one RTF_INDIRECT. 1160 */ 1161 ire_t * 1162 ire_route_recursive_impl_v6(ire_t *ire, 1163 const in6_addr_t *nexthop, uint_t ire_type, const ill_t *ill_arg, 1164 zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, 1165 uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, 1166 in6_addr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) 1167 { 1168 int i, j; 1169 in6_addr_t v6nexthop = *nexthop; 1170 ire_t *ires[MAX_IRE_RECURSION]; 1171 uint_t generation; 1172 uint_t generations[MAX_IRE_RECURSION]; 1173 boolean_t need_refrele = B_FALSE; 1174 boolean_t invalidate = B_FALSE; 1175 ill_t *ill = NULL; 1176 uint_t maskoff = (IRE_LOCAL|IRE_LOOPBACK); 1177 1178 if (setsrcp != NULL) 1179 ASSERT(IN6_IS_ADDR_UNSPECIFIED(setsrcp)); 1180 if (gwattrp != NULL) 1181 ASSERT(*gwattrp == NULL); 1182 1183 /* 1184 * We iterate up to three times to resolve a route, even though 1185 * we have four slots in the array. The extra slot is for an 1186 * IRE_IF_CLONE we might need to create. 1187 */ 1188 i = 0; 1189 while (i < MAX_IRE_RECURSION - 1) { 1190 /* ire_ftable_lookup handles round-robin/ECMP */ 1191 if (ire == NULL) { 1192 ire = ire_ftable_lookup_v6(&v6nexthop, 0, 0, ire_type, 1193 (ill != NULL ? ill : ill_arg), zoneid, tsl, 1194 match_args, xmit_hint, ipst, &generation); 1195 } else { 1196 /* Caller passed it; extra hold since we will rele */ 1197 ire_refhold(ire); 1198 if (generationp != NULL) 1199 generation = *generationp; 1200 else 1201 generation = IRE_GENERATION_VERIFY; 1202 } 1203 1204 if (ire == NULL) { 1205 if (i > 0 && (irr_flags & IRR_INCOMPLETE)) { 1206 ire = ires[0]; 1207 ire_refhold(ire); 1208 } else { 1209 ire = ire_reject(ipst, B_TRUE); 1210 } 1211 goto error; 1212 } 1213 1214 /* Need to return the ire with RTF_REJECT|BLACKHOLE */ 1215 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) 1216 goto error; 1217 1218 ASSERT(!(ire->ire_type & IRE_MULTICAST)); /* Not in ftable */ 1219 /* 1220 * Verify that the IRE_IF_CLONE has a consistent generation 1221 * number. 1222 */ 1223 if ((ire->ire_type & IRE_IF_CLONE) && !ire_clone_verify(ire)) { 1224 ire_refrele(ire); 1225 ire = NULL; 1226 continue; 1227 } 1228 1229 /* 1230 * Don't allow anything unusual past the first iteration. 1231 * After the first lookup, we should no longer look for 1232 * (IRE_LOCAL|IRE_LOOPBACK) or RTF_INDIRECT routes. 1233 * 1234 * In addition, after we have found a direct IRE_OFFLINK, 1235 * we should only look for interface or clone routes. 1236 */ 1237 match_args |= MATCH_IRE_DIRECT; /* no more RTF_INDIRECTs */ 1238 if ((ire->ire_type & IRE_OFFLINK) && 1239 !(ire->ire_flags & RTF_INDIRECT)) { 1240 ire_type = IRE_IF_ALL; 1241 } else { 1242 if (!(match_args & MATCH_IRE_TYPE)) 1243 ire_type = (IRE_OFFLINK|IRE_ONLINK); 1244 ire_type &= ~maskoff; /* no more LOCAL, LOOPBACK */ 1245 } 1246 match_args |= MATCH_IRE_TYPE; 1247 /* We have a usable IRE */ 1248 ires[i] = ire; 1249 generations[i] = generation; 1250 i++; 1251 1252 /* The first RTF_SETSRC address is passed back if setsrcp */ 1253 if ((ire->ire_flags & RTF_SETSRC) && 1254 setsrcp != NULL && IN6_IS_ADDR_UNSPECIFIED(setsrcp)) { 1255 ASSERT(!IN6_IS_ADDR_UNSPECIFIED( 1256 &ire->ire_setsrc_addr_v6)); 1257 *setsrcp = ire->ire_setsrc_addr_v6; 1258 } 1259 1260 /* The first ire_gw_secattr is passed back if gwattrp */ 1261 if (ire->ire_gw_secattr != NULL && 1262 gwattrp != NULL && *gwattrp == NULL) 1263 *gwattrp = ire->ire_gw_secattr; 1264 1265 /* 1266 * Check if we have a short-cut pointer to an IRE for this 1267 * destination, and that the cached dependency isn't stale. 1268 * In that case we've rejoined an existing tree towards a 1269 * parent, thus we don't need to continue the loop to 1270 * discover the rest of the tree. 1271 */ 1272 mutex_enter(&ire->ire_lock); 1273 if (ire->ire_dep_parent != NULL && 1274 ire->ire_dep_parent->ire_generation == 1275 ire->ire_dep_parent_generation) { 1276 mutex_exit(&ire->ire_lock); 1277 ire = NULL; 1278 goto done; 1279 } 1280 mutex_exit(&ire->ire_lock); 1281 1282 /* 1283 * If this type should have an ire_nce_cache (even if it 1284 * doesn't yet have one) then we are done. Includes 1285 * IRE_INTERFACE with a full 128 bit mask. 1286 */ 1287 if (ire->ire_nce_capable) { 1288 ire = NULL; 1289 goto done; 1290 } 1291 ASSERT(!(ire->ire_type & IRE_IF_CLONE)); 1292 /* 1293 * For an IRE_INTERFACE we create an IRE_IF_CLONE for this 1294 * particular destination 1295 */ 1296 if (ire->ire_type & IRE_INTERFACE) { 1297 ire_t *clone; 1298 1299 ASSERT(ire->ire_masklen != IPV6_ABITS); 1300 1301 /* 1302 * In the case of ip_input and ILLF_FORWARDING not 1303 * being set, and in the case of RTM_GET, there is 1304 * no point in allocating an IRE_IF_CLONE. We return 1305 * the IRE_INTERFACE. Note that !IRR_ALLOCATE can 1306 * result in a ire_dep_parent which is IRE_IF_* 1307 * without an IRE_IF_CLONE. 1308 * We recover from that when we need to send packets 1309 * by ensuring that the generations become 1310 * IRE_GENERATION_VERIFY in this case. 1311 */ 1312 if (!(irr_flags & IRR_ALLOCATE)) { 1313 invalidate = B_TRUE; 1314 ire = NULL; 1315 goto done; 1316 } 1317 1318 clone = ire_create_if_clone(ire, &v6nexthop, 1319 &generation); 1320 if (clone == NULL) { 1321 /* 1322 * Temporary failure - no memory. 1323 * Don't want caller to cache IRE_NOROUTE. 1324 */ 1325 invalidate = B_TRUE; 1326 ire = ire_blackhole(ipst, B_TRUE); 1327 goto error; 1328 } 1329 /* 1330 * Make clone next to last entry and the 1331 * IRE_INTERFACE the last in the dependency 1332 * chain since the clone depends on the 1333 * IRE_INTERFACE. 1334 */ 1335 ASSERT(i >= 1); 1336 ASSERT(i < MAX_IRE_RECURSION); 1337 1338 ires[i] = ires[i-1]; 1339 generations[i] = generations[i-1]; 1340 ires[i-1] = clone; 1341 generations[i-1] = generation; 1342 i++; 1343 1344 ire = NULL; 1345 goto done; 1346 } 1347 1348 /* 1349 * We only match on the type and optionally ILL when 1350 * recursing. The type match is used by some callers 1351 * to exclude certain types (such as IRE_IF_CLONE or 1352 * IRE_LOCAL|IRE_LOOPBACK). 1353 * 1354 * In the MATCH_IRE_SRC_ILL case, ill_arg may be the 'srcof' 1355 * ire->ire_ill, and we want to find the IRE_INTERFACE for 1356 * ire_ill, so we set ill to the ire_ill 1357 */ 1358 match_args &= (MATCH_IRE_TYPE | MATCH_IRE_DIRECT); 1359 v6nexthop = ire->ire_gateway_addr_v6; 1360 if (ill == NULL && ire->ire_ill != NULL) { 1361 ill = ire->ire_ill; 1362 need_refrele = B_TRUE; 1363 ill_refhold(ill); 1364 match_args |= MATCH_IRE_ILL; 1365 } 1366 ire = NULL; 1367 } 1368 ASSERT(ire == NULL); 1369 ire = ire_reject(ipst, B_TRUE); 1370 1371 error: 1372 ASSERT(ire != NULL); 1373 if (need_refrele) 1374 ill_refrele(ill); 1375 1376 /* 1377 * In the case of MULTIRT we want to try a different IRE the next 1378 * time. We let the next packet retry in that case. 1379 */ 1380 if (i > 0 && (ires[0]->ire_flags & RTF_MULTIRT)) 1381 (void) ire_no_good(ires[0]); 1382 1383 cleanup: 1384 /* cleanup ires[i] */ 1385 ire_dep_unbuild(ires, i); 1386 for (j = 0; j < i; j++) 1387 ire_refrele(ires[j]); 1388 1389 ASSERT((ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) || 1390 (irr_flags & IRR_INCOMPLETE)); 1391 /* 1392 * Use IRE_GENERATION_VERIFY to ensure that ip_output will redo the 1393 * ip_select_route since the reject or lack of memory might be gone. 1394 */ 1395 if (generationp != NULL) 1396 *generationp = IRE_GENERATION_VERIFY; 1397 return (ire); 1398 1399 done: 1400 ASSERT(ire == NULL); 1401 if (need_refrele) 1402 ill_refrele(ill); 1403 1404 /* Build dependencies */ 1405 if (i > 1 && !ire_dep_build(ires, generations, i)) { 1406 /* Something in chain was condemned; tear it apart */ 1407 ire = ire_blackhole(ipst, B_TRUE); 1408 goto cleanup; 1409 } 1410 1411 /* 1412 * Release all refholds except the one for ires[0] that we 1413 * will return to the caller. 1414 */ 1415 for (j = 1; j < i; j++) 1416 ire_refrele(ires[j]); 1417 1418 if (invalidate) { 1419 /* 1420 * Since we needed to allocate but couldn't we need to make 1421 * sure that the dependency chain is rebuilt the next time. 1422 */ 1423 ire_dep_invalidate_generations(ires[0]); 1424 generation = IRE_GENERATION_VERIFY; 1425 } else { 1426 /* 1427 * IREs can have been added or deleted while we did the 1428 * recursive lookup and we can't catch those until we've built 1429 * the dependencies. We verify the stored 1430 * ire_dep_parent_generation to catch any such changes and 1431 * return IRE_GENERATION_VERIFY (which will cause 1432 * ip_select_route to be called again so we can redo the 1433 * recursive lookup next time we send a packet. 1434 */ 1435 if (ires[0]->ire_dep_parent == NULL) 1436 generation = ires[0]->ire_generation; 1437 else 1438 generation = ire_dep_validate_generations(ires[0]); 1439 if (generations[0] != ires[0]->ire_generation) { 1440 /* Something changed at the top */ 1441 generation = IRE_GENERATION_VERIFY; 1442 } 1443 } 1444 if (generationp != NULL) 1445 *generationp = generation; 1446 1447 return (ires[0]); 1448 } 1449 1450 ire_t * 1451 ire_route_recursive_v6(const in6_addr_t *nexthop, uint_t ire_type, 1452 const ill_t *ill, zoneid_t zoneid, const ts_label_t *tsl, uint_t match_args, 1453 uint_t irr_flags, uint32_t xmit_hint, ip_stack_t *ipst, 1454 in6_addr_t *setsrcp, tsol_ire_gw_secattr_t **gwattrp, uint_t *generationp) 1455 { 1456 return (ire_route_recursive_impl_v6(NULL, nexthop, ire_type, ill, 1457 zoneid, tsl, match_args, irr_flags, xmit_hint, ipst, setsrcp, 1458 gwattrp, generationp)); 1459 } 1460 1461 /* 1462 * Recursively look for a route to the destination. 1463 * We only handle a destination match here, yet we have the same arguments 1464 * as the full match to allow function pointers to select between the two. 1465 * 1466 * Note that this function never returns NULL. It returns an IRE_NOROUTE 1467 * instead. 1468 * 1469 * If we find any IRE_LOCAL|BROADCAST etc past the first iteration it 1470 * is an error. 1471 * Allow at most one RTF_INDIRECT. 1472 */ 1473 ire_t * 1474 ire_route_recursive_dstonly_v6(const in6_addr_t *nexthop, uint_t irr_flags, 1475 uint32_t xmit_hint, ip_stack_t *ipst) 1476 { 1477 ire_t *ire; 1478 ire_t *ire1; 1479 uint_t generation; 1480 1481 /* ire_ftable_lookup handles round-robin/ECMP */ 1482 ire = ire_ftable_lookup_simple_v6(nexthop, xmit_hint, ipst, 1483 &generation); 1484 ASSERT(ire != NULL); 1485 1486 /* 1487 * If the IRE has a current cached parent we know that the whole 1488 * parent chain is current, hence we don't need to discover and 1489 * build any dependencies by doing a recursive lookup. 1490 */ 1491 mutex_enter(&ire->ire_lock); 1492 if (ire->ire_dep_parent != NULL) { 1493 if (ire->ire_dep_parent->ire_generation == 1494 ire->ire_dep_parent_generation) { 1495 mutex_exit(&ire->ire_lock); 1496 return (ire); 1497 } 1498 mutex_exit(&ire->ire_lock); 1499 } else { 1500 mutex_exit(&ire->ire_lock); 1501 /* 1502 * If this type should have an ire_nce_cache (even if it 1503 * doesn't yet have one) then we are done. Includes 1504 * IRE_INTERFACE with a full 128 bit mask. 1505 */ 1506 if (ire->ire_nce_capable) 1507 return (ire); 1508 } 1509 1510 /* 1511 * Fallback to loop in the normal code starting with the ire 1512 * we found. Normally this would return the same ire. 1513 */ 1514 ire1 = ire_route_recursive_impl_v6(ire, nexthop, 0, NULL, ALL_ZONES, 1515 NULL, MATCH_IRE_DSTONLY, irr_flags, xmit_hint, ipst, NULL, NULL, 1516 &generation); 1517 ire_refrele(ire); 1518 return (ire1); 1519 } 1520