Lines Matching defs:ire

85  *	- bucket lock of the forwarding table in which is ire stored.
152 * Each irb_t - ire bucket structure has a lock to protect
164 * The ire_refhold/ire_refrele functions operate on the ire which increments/
165 * decrements the reference count, ire_refcnt, atomically on the ire.
169 * CREATE an ire with reference count initialized to 1.
171 * ADDITION of an ire holds the bucket lock, checks for duplicates
172 * and then adds the ire. ire_add returns the ire after
175 * work with the ire after adding.
177 * LOOKUP of an ire bumps up the reference count using ire_refhold
179 * after the lookup has returned an ire. Following are the lookup
180 * functions that return an HELD ire :
184 * DELETION of an ire holds the bucket lock, removes it from the list
187 * the ire, the reference count would have been bumped up and hence
188 * this ire will not be freed once deleted. It will be freed once the
195 * that is passing the ire as an argument.
199 * IRE_IS_CONDEMNED signifies that the ire has been logically deleted and is
223 static ire_t *ire_add_v4(ire_t *ire);
224 static void ire_delete_v4(ire_t *ire);
237 * count of the IREs and IRBs (ire bucket).
256 * the same thread could end up deleting the ire or the ire pointed by
257 * ire_next. ire_refholding the ire or ire_next is not sufficient as
258 * a delete will still remove the ire from the bucket while we have
264 * the ire and irb as CONDEMNED. When the
302 * we simply clean up the ire list and continue.
334 ire_refhold(ire_t *ire)
336 atomic_add_32(&(ire)->ire_refcnt, 1);
337 ASSERT((ire)->ire_refcnt != 0);
339 ire_trace_ref(ire);
344 ire_refhold_notr(ire_t *ire)
346 atomic_add_32(&(ire)->ire_refcnt, 1);
347 ASSERT((ire)->ire_refcnt != 0);
351 ire_refhold_locked(ire_t *ire)
354 ire_trace_ref(ire);
356 ire->ire_refcnt++;
367 * sure that the ire has not been deleted and won't be deleted.
375 ire_refrele(ire_t *ire)
378 ire_untrace_ref(ire);
380 ASSERT((ire)->ire_refcnt != 0);
382 if (atomic_add_32_nv(&(ire)->ire_refcnt, -1) == 0)
383 ire_inactive(ire);
387 ire_refrele_notr(ire_t *ire)
389 ASSERT((ire)->ire_refcnt != 0);
391 if (atomic_add_32_nv(&(ire)->ire_refcnt, -1) == 0)
392 ire_inactive(ire);
419 ire_t *ire;
467 ire = ire_ftable_lookup_v4(v4addr, 0, 0, 0, NULL,
473 ire = ire_ftable_lookup_v6(&v6addr, NULL, NULL, 0, NULL,
476 if (ire != NULL) {
478 ip_rts_change(RTM_LOSING, ire->ire_addr,
479 ire->ire_gateway_addr, ire->ire_mask,
482 ire->ire_ipst);
484 (void) ire_no_good(ire);
485 ire_refrele(ire);
491 * Initialize the ire that is specific to IPv4 part and call
496 ire_init_v4(ire_t *ire, uchar_t *addr, uchar_t *mask, uchar_t *gateway,
512 bcopy(addr, &ire->ire_addr, IP_ADDR_LEN);
514 bcopy(gateway, &ire->ire_gateway_addr, IP_ADDR_LEN);
523 ire->ire_mask = IP_HOST_MASK;
524 ire->ire_masklen = IPV4_ABITS;
531 bcopy(mask, &ire->ire_mask, IP_ADDR_LEN);
532 ire->ire_masklen = ip_mask_to_plen(ire->ire_mask);
544 error = ire_init_common(ire, type, ill, zoneid, flags, IPV4_VERSION,
550 ire->ire_postfragfn = ip_xmit; /* Common case */
552 switch (ire->ire_type) {
554 ire->ire_sendfn = ire_send_local_v4;
555 ire->ire_recvfn = ire_recv_local_v4;
556 ASSERT(ire->ire_ill != NULL);
557 if (ire->ire_ill->ill_flags & ILLF_NOACCEPT)
558 ire->ire_recvfn = ire_recv_noaccept_v6;
561 ire->ire_sendfn = ire_send_local_v4;
562 ire->ire_recvfn = ire_recv_loopback_v4;
565 ire->ire_postfragfn = ip_postfrag_loopcheck;
566 ire->ire_sendfn = ire_send_broadcast_v4;
567 ire->ire_recvfn = ire_recv_broadcast_v4;
570 ire->ire_postfragfn = ip_postfrag_loopcheck;
571 ire->ire_sendfn = ire_send_multicast_v4;
572 ire->ire_recvfn = ire_recv_multicast_v4;
579 ire->ire_sendfn = ire_send_wire_v4;
580 ire->ire_recvfn = ire_recv_forward_v4;
583 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
584 ire->ire_sendfn = ire_send_noroute_v4;
585 ire->ire_recvfn = ire_recv_noroute_v4;
586 } else if (ire->ire_flags & RTF_MULTIRT) {
587 ire->ire_postfragfn = ip_postfrag_multirt_v4;
588 ire->ire_sendfn = ire_send_multirt_v4;
590 if (ire->ire_type != IRE_BROADCAST)
591 ire->ire_recvfn = ire_recv_multirt_v4;
593 ire->ire_nce_capable = ire_determine_nce_capable(ire);
601 ire_determine_nce_capable(ire_t *ire)
605 if ((ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) ||
606 (ire->ire_type & IRE_MULTICAST))
609 if (ire->ire_ipversion == IPV4_VERSION)
614 if ((ire->ire_type & IRE_ONLINK) && ire->ire_masklen == max_masklen)
630 ire_t *ire;
633 ire = kmem_cache_alloc(ire_cache, KM_NOSLEEP);
634 if (ire == NULL) {
638 *ire = ire_null;
640 error = ire_init_v4(ire, addr, mask, gateway, type, ill, zoneid, flags,
643 DTRACE_PROBE2(ire__init, ire_t *, ire, int, error);
644 kmem_cache_free(ire_cache, ire);
647 return (ire);
655 ire_init_common(ire_t *ire, ushort_t type, ill_t *ill, zoneid_t zoneid,
683 error = tsol_ire_init_gwattr(ire, ipversion, gc);
689 ire->ire_type = type;
690 ire->ire_flags = RTF_UP | flags;
691 ire->ire_create_time = (uint32_t)gethrestime_sec();
692 ire->ire_generation = IRE_GENERATION_INITIAL;
702 ire->ire_ill = ill;
703 ire->ire_zoneid = zoneid;
704 ire->ire_ipversion = ipversion;
706 mutex_init(&ire->ire_lock, NULL, MUTEX_DEFAULT, NULL);
707 ire->ire_refcnt = 1;
708 ire->ire_identical_ref = 1; /* Number of ire_delete's needed */
709 ire->ire_ipst = ipst; /* No netstack_hold */
710 ire->ire_trace_disable = B_FALSE;
751 ire_t *ire;
760 ire = ire_ftable_lookup_v4(
772 return (ire);
860 ire_walk_ill_match(uint_t match_flags, uint_t ire_type, ire_t *ire,
863 ill_t *dst_ill = ire->ire_ill;
867 if (zoneid != ALL_ZONES && zoneid != ire->ire_zoneid &&
868 ire->ire_zoneid != ALL_ZONES) {
879 if (ire->ire_type & IRE_ONLINK) {
900 if (dst_ill != NULL && (ire->ire_type & IRE_OFFLINK)) {
925 if ((ire->ire_type & IRE_OFFLINK) && zoneid != ALL_ZONES) {
929 if (ire->ire_ipversion == IPV4_VERSION) {
930 reach = ire_gateway_ok_zone_v4(ire->ire_gateway_addr,
933 ASSERT(ire->ire_ipversion == IPV6_VERSION);
934 mutex_enter(&ire->ire_lock);
935 gw_addr_v6 = ire->ire_gateway_addr_v6;
936 mutex_exit(&ire->ire_lock);
949 if (ire->ire_ipversion == IPV4_VERSION) {
951 ire->ire_gateway_addr, ALL_ZONES,
968 (ire->ire_type & ire_type)) &&
983 ire_t *ire;
989 for (ire = irb->irb_ire; ire != NULL; ire = ire->ire_next) {
993 rtf->rt_ire_type, ire,
999 (*rtf->rt_func)(ire, rtf->rt_arg);
1015 ire_t *ire;
1034 for (ire = irb->irb_ire; ire != NULL;
1035 ire = ire->ire_next) {
1043 ire_type, ire, ill,
1047 (*func)(ire, arg);
1094 ire_atomic_end(irb_t *irb_ptr, ire_t *ire)
1098 ill = ire->ire_ill;
1106 * with the new ire is not going away i.e., we check ILL_CONDEMNED.
1109 ire_atomic_start(irb_t *irb_ptr, ire_t *ire)
1113 ill = ire->ire_ill;
1126 ire_atomic_end(irb_ptr, ire);
1127 DTRACE_PROBE1(ire__add__on__dying__ill, ire_t *, ire);
1135 IRE_HIDDEN_TYPE(ire->ire_type) &&
1136 !ire->ire_testhidden) {
1141 ire_atomic_end(irb_ptr, ire);
1159 ire_add(ire_t *ire)
1161 if (IRE_HIDDEN_TYPE(ire->ire_type) &&
1162 ire->ire_ill != NULL && IS_UNDER_IPMP(ire->ire_ill)) {
1171 ire->ire_testhidden = B_TRUE;
1174 if (ire->ire_ipversion == IPV6_VERSION)
1175 return (ire_add_v6(ire));
1177 return (ire_add_v4(ire));
1189 ire_add_v4(ire_t *ire)
1196 ip_stack_t *ipst = ire->ire_ipst;
1198 if (ire->ire_ill != NULL)
1199 ASSERT(!MUTEX_HELD(&ire->ire_ill->ill_lock));
1200 ASSERT(ire->ire_ipversion == IPV4_VERSION);
1203 ire->ire_addr &= ire->ire_mask;
1207 if (ire->ire_ill != NULL) {
1210 irb_ptr = ire_get_bucket(ire);
1212 printf("no bucket for %p\n", (void *)ire);
1213 ire_delete(ire);
1218 * Start the atomic add of the ire. Grab the ill lock,
1221 error = ire_atomic_start(irb_ptr, ire);
1223 printf("no ire_atomic_start for %p\n", (void *)ire);
1224 ire_delete(ire);
1234 if (ire->ire_testhidden)
1247 if (ire1->ire_zoneid != ire->ire_zoneid)
1250 if (ire1->ire_type != ire->ire_type)
1260 if (ire_match_args(ire1, ire->ire_addr, ire->ire_mask,
1261 ire->ire_gateway_addr, ire->ire_type, ire->ire_ill,
1262 ire->ire_zoneid, NULL, match_flags)) {
1264 * Return the old ire after doing a REFHOLD.
1266 * after adding, we return a held ire. This will
1271 * so, if the is an IF_CLONE, return the ire without
1274 if (ire->ire_type != IRE_IF_CLONE) {
1277 ire_t *, ire);
1280 ire_atomic_end(irb_ptr, ire);
1281 ire_delete(ire);
1300 if ((ire->ire_type & IRE_IF_CLONE) ||
1301 ((ire->ire_type & IRE_BROADCAST) &&
1302 !(ire->ire_flags & RTF_MULTIRT))) {
1309 ire1->ire_ptpn = &ire->ire_next;
1310 ire->ire_next = ire1;
1312 ire->ire_ptpn = irep;
1316 * a lock. Before we point to the new ire, we want to make
1317 * sure the store that sets the ire_next of the new ire
1320 * of the new ire gets set after we do "*irep = ire" due
1322 * once it accesses the ire_next of the new ire.
1327 *irep = ire;
1328 ire->ire_bucket = irb_ptr;
1340 ire_refhold_locked(ire);
1347 if (ire->ire_ill != NULL) {
1348 ire->ire_ill->ill_ire_cnt++;
1349 ASSERT(ire->ire_ill->ill_ire_cnt != 0); /* Wraparound */
1352 ire_atomic_end(irb_ptr, ire);
1355 ire_flush_cache_v4(ire, IRE_FLUSH_ADD);
1357 if (ire->ire_ill != NULL)
1358 ASSERT(!MUTEX_HELD(&ire->ire_ill->ill_lock));
1360 return (ire);
1365 * do the final cleanup for this ire.
1368 ire_cleanup(ire_t *ire)
1371 ip_stack_t *ipst = ire->ire_ipst;
1373 ASSERT(ire != NULL);
1375 while (ire != NULL) {
1376 ire_next = ire->ire_next;
1377 if (ire->ire_ipversion == IPV4_VERSION) {
1378 ire_delete_v4(ire);
1382 ASSERT(ire->ire_ipversion == IPV6_VERSION);
1383 ire_delete_v6(ire);
1392 ire->ire_next = NULL;
1393 ire_refrele_notr(ire);
1394 ire = ire_next;
1405 ire_t *ire;
1416 for (ire = irb->irb_ire; ire != NULL; ire = ire1) {
1417 ire1 = ire->ire_next;
1418 if (IRE_IS_CONDEMNED(ire)) {
1419 ptpn = ire->ire_ptpn;
1420 ire1 = ire->ire_next;
1424 ire->ire_ptpn = NULL;
1425 ire->ire_next = NULL;
1438 ire->ire_next = ire_list;
1439 ire_list = ire;
1447 * Clean up the radix node for this ire. Must be called by irb_refrele
1448 * when there are no ire's left in the bucket. Returns TRUE if the bucket
1488 ire_delete(ire_t *ire)
1493 ip_stack_t *ipst = ire->ire_ipst;
1495 if ((irb = ire->ire_bucket) == NULL) {
1500 ire_make_condemned(ire);
1501 ire_refrele_notr(ire);
1510 if (ire->ire_type & IRE_IF_CLONE) {
1514 if ((parent = ire->ire_dep_parent) != NULL) {
1515 parent->ire_ob_pkt_count += ire->ire_ob_pkt_count;
1516 parent->ire_ib_pkt_count += ire->ire_ib_pkt_count;
1517 ire->ire_ob_pkt_count = 0;
1518 ire->ire_ib_pkt_count = 0;
1524 if (ire->ire_ptpn == NULL) {
1533 if (!IRE_IS_CONDEMNED(ire)) {
1535 ASSERT(ire->ire_identical_ref >= 1);
1536 if (atomic_add_32_nv(&ire->ire_identical_ref, -1) != 0) {
1543 ire_make_condemned(ire);
1549 * delete this ire.
1557 * Normally to delete an ire, we walk the bucket. While we
1559 * we return from above where we mark CONDEMNED and the ire
1561 * knows the ire e.g by doing a lookup, and wants to delete the
1565 ptpn = ire->ire_ptpn;
1566 ire1 = ire->ire_next;
1571 ire->ire_ptpn = NULL;
1572 ire->ire_next = NULL;
1573 if (ire->ire_ipversion == IPV6_VERSION) {
1581 if (ire->ire_ipversion == IPV6_VERSION) {
1582 ire_delete_v6(ire);
1584 ire_delete_v4(ire);
1590 ire_refrele_notr(ire);
1598 * NOTE : This function is called only if the ire was added
1602 ire_delete_v4(ire_t *ire)
1604 ip_stack_t *ipst = ire->ire_ipst;
1606 ASSERT(ire->ire_refcnt >= 1);
1607 ASSERT(ire->ire_ipversion == IPV4_VERSION);
1609 ire_flush_cache_v4(ire, IRE_FLUSH_DELETE);
1610 if (ire->ire_type == IRE_DEFAULT) {
1616 ire_delete_host_redirects(ire->ire_gateway_addr, ipst);
1624 if ((ire->ire_type & IRE_INTERFACE) && ire->ire_dep_children != NULL)
1625 ire_dep_delete_if_clone(ire);
1629 if (ire->ire_dep_parent != NULL)
1630 ire_dep_remove(ire);
1632 while (ire->ire_dep_children != NULL)
1633 ire_dep_remove(ire->ire_dep_children);
1639 * to free the ire when the reference count goes to zero.
1642 ire_inactive(ire_t *ire)
1646 ip_stack_t *ipst = ire->ire_ipst;
1648 ASSERT(ire->ire_refcnt == 0);
1649 ASSERT(ire->ire_ptpn == NULL);
1650 ASSERT(ire->ire_next == NULL);
1653 ASSERT(IRE_IS_CONDEMNED(ire));
1656 if (ire->ire_gw_secattr != NULL) {
1657 ire_gw_secattr_free(ire->ire_gw_secattr);
1658 ire->ire_gw_secattr = NULL;
1663 * set it once the ire is marked condemned.
1665 ASSERT(ire->ire_nce_cache == NULL);
1671 ASSERT(ire->ire_dep_parent == NULL);
1672 ASSERT(ire->ire_dep_sib_next == NULL);
1673 ASSERT(ire->ire_dep_sib_ptpn == NULL);
1679 ASSERT(ire->ire_dep_children == NULL);
1685 irb = ire->ire_bucket;
1686 ill = ire->ire_ill;
1691 (char *), "ire", (void *), ire);
1700 ire->ire_ill = NULL;
1719 ire_trace_cleanup(ire);
1721 mutex_destroy(&ire->ire_lock);
1722 if (ire->ire_ipversion == IPV6_VERSION) {
1727 kmem_cache_free(ire_cache, ire);
1756 ire_t *ire;
1768 * irb_ire list without fear of having a condemned ire removed from
1775 for (ire = irb->irb_ire; ire != NULL; ire = ire->ire_next) {
1776 if (!IRE_IS_CONDEMNED(ire))
1777 ire_increment_generation(ire); /* Ourselves */
1778 ire_dep_incr_generation_locked(ire); /* Dependants */
1793 ire_flush_cache_v4(ire_t *ire, int flag)
1795 irb_t *irb = ire->ire_bucket;
1797 ip_stack_t *ipst = ire->ire_ipst;
1800 * IRE_IF_CLONE ire's don't provide any new information
1804 if (ire->ire_type & IRE_IF_CLONE)
1810 * either the old ire and old generation number, or a new ire and new
1826 if (ire->ire_type == IRE_DEFAULT && flag == IRE_FLUSH_ADD) {
1838 ire_dep_incr_generation(ire);
1854 * Matches the arguments passed with the values in the ire.
1860 ire_match_args(ire_t *ire, ipaddr_t addr, ipaddr_t mask, ipaddr_t gateway,
1865 ip_stack_t *ipst = ire->ire_ipst;
1867 ASSERT(ire->ire_ipversion == IPV4_VERSION);
1868 ASSERT((ire->ire_addr & ~ire->ire_mask) == 0);
1876 if (ire->ire_testhidden) {
1881 if (zoneid != ALL_ZONES && zoneid != ire->ire_zoneid &&
1882 ire->ire_zoneid != ALL_ZONES) {
1912 if (ire->ire_type & IRE_LOOPBACK)
1915 if (ire->ire_type & IRE_LOCAL)
1925 dst_ill = ire->ire_ill;
1926 if (ire->ire_type & IRE_ONLINK) {
1958 if (dst_ill != NULL && (ire->ire_type & IRE_OFFLINK)) {
1978 ire_ill = ire->ire_ill;
1991 !(ire->ire_type & IRE_LOCAL)) {
1992 if (ire->ire_ill != ill)
2015 if ((ire->ire_addr == (addr & mask)) &&
2017 (ire->ire_gateway_addr == gateway)) &&
2019 !(ire->ire_flags & RTF_INDIRECT)) &&
2020 ((!(match_flags & MATCH_IRE_TYPE)) || (ire->ire_type & type)) &&
2021 ((!(match_flags & MATCH_IRE_TESTHIDDEN)) || ire->ire_testhidden) &&
2022 ((!(match_flags & MATCH_IRE_MASK)) || (ire->ire_mask == mask)) &&
2025 (tsol_ire_match_gwattr(ire, tsl) == 0))) {
2039 ire_alt_local(ire_t *ire, zoneid_t zoneid, const ts_label_t *tsl,
2042 ip_stack_t *ipst = ire->ire_ipst;
2048 ASSERT(ire->ire_type & IRE_LOCAL);
2049 ASSERT(ire->ire_ill != NULL);
2063 if (ire->ire_ipversion == IPV4_VERSION) {
2064 alt_ire = ire_route_recursive_v4(ire->ire_addr, ire_type,
2068 alt_ire = ire_route_recursive_v6(&ire->ire_addr_v6, ire_type,
2074 if (alt_ire->ire_ill == ire->ire_ill) {
2079 ire_refrele(ire);
2080 ire = alt_ire;
2084 return (ire);
2092 ire_t *ire;
2103 for (ire = irb->irb_ire; ire != NULL; ire = ire->ire_next) {
2104 if (IRE_IS_CONDEMNED(ire))
2107 if (!(ire->ire_type & IRE_INTERFACE))
2110 if (ire->ire_zoneid != ALL_ZONES &&
2111 ire->ire_zoneid != margs->ift_zoneid)
2114 if (margs->ift_ill != NULL && margs->ift_ill != ire->ire_ill)
2118 tsol_ire_match_gwattr(ire, margs->ift_tsl) != 0)
2176 ire_delete_reclaim(ire_t *ire, char *arg)
2178 ip_stack_t *ipst = ire->ire_ipst;
2182 if ((ire->ire_flags & RTF_DYNAMIC) ||
2183 (ire->ire_type & IRE_IF_CLONE)) {
2187 IRE_ADDR_HASH_V6(ire->ire_addr_v6, 256);
2192 ire_delete(ire);
2214 * Walk all CONNs that can have a reference on an ire, nce or dce.
2294 ire_t *ire;
2315 ire = kmem_cache_alloc(ire_cache, KM_SLEEP);
2316 *ire = ire_null;
2317 error = ire_init_v4(ire, 0, 0, 0, IRE_NOROUTE, NULL, ALL_ZONES,
2320 ipst->ips_ire_reject_v4 = ire;
2322 ire = kmem_cache_alloc(ire_cache, KM_SLEEP);
2323 *ire = ire_null;
2324 error = ire_init_v6(ire, 0, 0, 0, IRE_NOROUTE, NULL, ALL_ZONES,
2327 ipst->ips_ire_reject_v6 = ire;
2329 ire = kmem_cache_alloc(ire_cache, KM_SLEEP);
2330 *ire = ire_null;
2331 error = ire_init_v4(ire, 0, 0, 0, IRE_NOROUTE, NULL, ALL_ZONES,
2334 ipst->ips_ire_blackhole_v4 = ire;
2336 ire = kmem_cache_alloc(ire_cache, KM_SLEEP);
2337 *ire = ire_null;
2338 error = ire_init_v6(ire, 0, 0, 0, IRE_NOROUTE, NULL, ALL_ZONES,
2341 ipst->ips_ire_blackhole_v6 = ire;
2411 ire_trace_ref(ire_t *ire)
2413 mutex_enter(&ire->ire_lock);
2414 if (ire->ire_trace_disable) {
2415 mutex_exit(&ire->ire_lock);
2419 if (th_trace_ref(ire, ire->ire_ipst)) {
2420 mutex_exit(&ire->ire_lock);
2422 ire->ire_trace_disable = B_TRUE;
2423 mutex_exit(&ire->ire_lock);
2424 ire_trace_cleanup(ire);
2429 ire_untrace_ref(ire_t *ire)
2431 mutex_enter(&ire->ire_lock);
2432 if (!ire->ire_trace_disable)
2433 th_trace_unref(ire);
2434 mutex_exit(&ire->ire_lock);
2438 ire_trace_cleanup(const ire_t *ire)
2440 th_trace_cleanup(ire, ire->ire_trace_disable);
2462 * For unicast ire entries,
2605 * The caller should hold irb_lock as a writer if the ire is in a bucket.
2607 * set ire_nce_cache after the ire is marked condemned.
2610 ire_make_condemned(ire_t *ire)
2612 ip_stack_t *ipst = ire->ire_ipst;
2615 mutex_enter(&ire->ire_lock);
2616 ASSERT(ire->ire_bucket == NULL ||
2617 RW_WRITE_HELD(&ire->ire_bucket->irb_lock));
2618 ASSERT(!IRE_IS_CONDEMNED(ire));
2619 ire->ire_generation = IRE_GENERATION_CONDEMNED;
2622 nce = ire->ire_nce_cache;
2623 ire->ire_nce_cache = NULL;
2624 mutex_exit(&ire->ire_lock);
2633 ire_increment_generation(ire_t *ire)
2637 mutex_enter(&ire->ire_lock);
2642 if (!IRE_IS_CONDEMNED(ire)) {
2643 generation = ire->ire_generation + 1;
2647 ire->ire_generation = generation;
2649 mutex_exit(&ire->ire_lock);
2686 ire_t *ire;
2689 ire = ipst->ips_ire_reject_v6;
2691 ire = ipst->ips_ire_reject_v4;
2693 ASSERT(ire->ire_generation != IRE_GENERATION_CONDEMNED);
2694 ire_refhold(ire);
2695 return (ire);
2704 ire_t *ire;
2707 ire = ipst->ips_ire_blackhole_v6;
2709 ire = ipst->ips_ire_blackhole_v4;
2711 ASSERT(ire->ire_generation != IRE_GENERATION_CONDEMNED);
2712 ire_refhold(ire);
2713 return (ire);
2722 ire_t *ire = ill->ill_ire_multicast;
2724 ASSERT(ire == NULL || ire->ire_generation != IRE_GENERATION_CONDEMNED);
2725 if (ire == NULL)
2726 ire = ire_blackhole(ill->ill_ipst, ill->ill_isv6);
2728 ire_refhold(ire);
2729 return (ire);
2743 ire_nexthop(ire_t *ire)
2745 ip_stack_t *ipst = ire->ire_ipst;
2749 while (ire != NULL) {
2750 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
2765 if (ire->ire_type & IRE_ONLINK)
2767 ire = ire->ire_dep_parent;
2773 ire_refhold(ire);
2775 return (ire);
2784 ire_nexthop_ill(ire_t *ire)
2788 ire = ire_nexthop(ire);
2789 if (ire == NULL)
2792 /* ire_ill can not change for an existing ire */
2793 ill = ire->ire_ill;
2796 ire_refrele(ire);
2804 ire_t *ire;
2807 ire = parent->ire_dep_children;
2809 while (ire != NULL) {
2811 ASSERT(ire->ire_dep_sib_ptpn ==
2814 ASSERT(ire->ire_dep_sib_ptpn ==
2817 if (ire == child)
2819 prev = ire;
2820 ire = ire->ire_dep_sib_next;
2826 ire_dep_verify(ire_t *ire)
2828 ire_t *parent = ire->ire_dep_parent;
2829 ire_t *child = ire->ire_dep_children;
2831 ASSERT(ire->ire_ipversion == IPV4_VERSION ||
2832 ire->ire_ipversion == IPV6_VERSION);
2837 ASSERT(parent_has_child(parent, ire));
2842 ASSERT(child->ire_dep_parent == ire);
2844 ASSERT(parent_has_child(ire, child));
2853 ire_dep_remove(ire_t *ire)
2855 ip_stack_t *ipst = ire->ire_ipst;
2856 ire_t *parent = ire->ire_dep_parent;
2861 ASSERT(ire->ire_dep_parent != NULL);
2862 ASSERT(ire->ire_dep_sib_ptpn != NULL);
2865 ire_dep_verify(ire);
2869 next = ire->ire_dep_sib_next;
2871 next->ire_dep_sib_ptpn = ire->ire_dep_sib_ptpn;
2873 ASSERT(*(ire->ire_dep_sib_ptpn) == ire);
2874 *(ire->ire_dep_sib_ptpn) = ire->ire_dep_sib_next;
2876 ire->ire_dep_sib_ptpn = NULL;
2877 ire->ire_dep_sib_next = NULL;
2879 mutex_enter(&ire->ire_lock);
2880 parent = ire->ire_dep_parent;
2881 ire->ire_dep_parent = NULL;
2882 mutex_exit(&ire->ire_lock);
2890 if (ire->ire_dep_children != NULL)
2891 ire_dep_invalidate_children(ire->ire_dep_children);
2897 mutex_enter(&ire->ire_lock);
2898 nce = ire->ire_nce_cache;
2899 ire->ire_nce_cache = NULL;
2900 mutex_exit(&ire->ire_lock);
2905 ire_dep_verify(ire);
2910 ire_refrele_notr(ire);
2972 ire_t *ire = ires[0];
2981 ipst = ire->ire_ipst;
3052 * IRE_DEFAULT (ECMP)). We mark the ire as bad so a hopefully
3066 ire_handle_condemned_nce(nce_t *nce, ire_t *ire, ipha_t *ipha, ip6_t *ip6h,
3070 if (ire_no_good(ire) && fail_if_better) {
3078 if (ire_revalidate_nce(ire) == ENETUNREACH) {
3080 (void) ire_no_good(ire);
3083 if (ire->ire_ipversion == IPV4_VERSION) {
3085 nce = ire_to_nce(ire, ipha->ipha_dst, NULL);
3088 nce = ire_to_nce(ire, INADDR_ANY, &ip6h->ip6_dst);
3101 * The caller has found that the ire is bad, either due to a reference to an NCE
3115 * Any time ip_select_route find an ire with a condemned ire_nce_cache
3121 ire_no_good(ire_t *ire)
3123 ip_stack_t *ipst = ire->ire_ipst;
3127 if (ire->ire_flags & RTF_DYNAMIC) {
3128 ire_delete(ire);
3131 if (ire->ire_flags & RTF_INDIRECT) {
3134 if (ire->ire_dep_parent != NULL &&
3135 (ire->ire_dep_parent->ire_flags & RTF_DYNAMIC)) {
3136 ire2 = ire->ire_dep_parent;
3158 mutex_enter(&ire->ire_lock);
3159 ire->ire_badcnt++;
3160 ire->ire_last_badcnt = TICK_TO_SEC(ddi_get_lbolt64());
3161 nce = ire->ire_nce_cache;
3164 ire->ire_nce_cache = NULL;
3167 mutex_exit(&ire->ire_lock);
3171 ire_increment_generation(ire);
3172 ire_dep_incr_generation(ire);
3174 return (ire->ire_bucket->irb_ire_cnt > 1);
3186 ire_dep_validate_generations(ire_t *ire)
3188 ip_stack_t *ipst = ire->ire_ipst;
3193 generation = ire->ire_generation; /* Assuming things match */
3194 for (ire1 = ire; ire1 != NULL; ire1 = ire1->ire_dep_parent) {
3209 while (ire != ire1) {
3210 ASSERT(ire->ire_ipversion == IPV4_VERSION ||
3211 ire->ire_ipversion == IPV6_VERSION);
3212 mutex_enter(&ire->ire_lock);
3213 ire->ire_dep_parent_generation = IRE_GENERATION_VERIFY;
3214 mutex_exit(&ire->ire_lock);
3215 ire = ire->ire_dep_parent;
3222 * Used when we need to return an ire with ire_dep_parent, but we
3228 ire_dep_invalidate_generations(ire_t *ire)
3230 ip_stack_t *ipst = ire->ire_ipst;
3233 while (ire != NULL) {
3234 ASSERT(ire->ire_ipversion == IPV4_VERSION ||
3235 ire->ire_ipversion == IPV6_VERSION);
3236 mutex_enter(&ire->ire_lock);
3237 ire->ire_dep_parent_generation = IRE_GENERATION_VERIFY;
3238 mutex_exit(&ire->ire_lock);
3239 ire = ire->ire_dep_parent;
3281 * Walk all the children of this ire recursively and increment their
3308 * In the in.mpathd case, the ire will have ire_testhidden
3313 * error to mark potentially bad ire's. For all the other callers, an
3316 * case (transient error), we would leave the old stale ire/ire_nce_cache
3323 ire_revalidate_nce(ire_t *ire)
3332 if (ire->ire_type & IRE_MULTICAST)
3336 ASSERT(!ire->ire_testhidden || !IS_IPMP(ire->ire_ill));
3338 nexthop = ire_nexthop(ire);
3341 (void) ire_no_good(ire);
3344 if (ire->ire_type & (IRE_LOCAL|IRE_LOOPBACK)) {
3345 ASSERT(ire->ire_ill != NULL);
3347 if (ire->ire_ipversion == IPV4_VERSION)
3348 nce = nce_lookup_v4(ire->ire_ill, &ire->ire_addr);
3350 nce = nce_lookup_v6(ire->ire_ill, &ire->ire_addr_v6);
3353 if (ire->ire_ipversion == IPV4_VERSION) {
3370 if (nexthop != ire) {
3371 /* Update the nexthop ire */
3386 mutex_enter(&ire->ire_lock);
3387 old_nce = ire->ire_nce_cache;
3388 if (!IRE_IS_CONDEMNED(ire)) {
3390 ire->ire_nce_cache = nce;
3392 ire->ire_nce_cache = NULL;
3394 mutex_exit(&ire->ire_lock);
3403 * Get a held nce for a given ire.
3412 ire_to_nce(ire_t *ire, ipaddr_t v4nexthop, const in6_addr_t *v6nexthop)
3416 if (ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE))
3420 ASSERT(!ire->ire_testhidden || !IS_IPMP(ire->ire_ill));
3422 mutex_enter(&ire->ire_lock);
3423 nce = ire->ire_nce_cache;
3426 mutex_exit(&ire->ire_lock);
3429 mutex_exit(&ire->ire_lock);
3431 if (ire->ire_type & IRE_MULTICAST) {
3432 ASSERT(ire->ire_ill != NULL);
3434 if (ire->ire_ipversion == IPV4_VERSION) {
3437 nce = arp_nce_init(ire->ire_ill, v4nexthop,
3438 ire->ire_type);
3442 nce = ndp_nce_init(ire->ire_ill, v6nexthop,
3443 ire->ire_type);
3451 ire_to_nce_pkt(ire_t *ire, mblk_t *mp)
3458 return (ire_to_nce(ire, ipha->ipha_dst, NULL));
3461 return (ire_to_nce(ire, INADDR_ANY, &ip6h->ip6_dst));
3482 ire_t *ire;
3492 ire = ire_create(
3504 ire = ire_create_v6(
3515 if (ire == NULL)
3519 ire->ire_metrics = ire_if->ire_metrics;
3521 nire = ire_add(ire);
3582 ire_rebind(ire_t *ire)
3587 boolean_t isv6 = (ire->ire_ipversion == IPV6_VERSION);
3588 ip_stack_t *ipst = ire->ire_ipst;
3590 ASSERT(ire->ire_unbound);
3593 gw_ire = ire_ftable_lookup_v6(&ire->ire_gateway_addr_v6, 0, 0,
3597 gw_ire = ire_ftable_lookup_v4(ire->ire_gateway_addr, 0, 0,
3611 new_ire = ire_create_v6(&ire->ire_addr_v6, &ire->ire_mask_v6,
3612 &ire->ire_gateway_addr_v6, ire->ire_type, gw_ill,
3613 ire->ire_zoneid, ire->ire_flags, NULL, ipst);
3615 new_ire = ire_create((uchar_t *)&ire->ire_addr,
3616 (uchar_t *)&ire->ire_mask,
3617 (uchar_t *)&ire->ire_gateway_addr, ire->ire_type, gw_ill,
3618 ire->ire_zoneid, ire->ire_flags, NULL, ipst);