• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /macosx-10.10/xnu-2782.1.97/bsd/net/

Lines Matching refs:rt

457  * route; dst typically comes from rt_key(rt) but may be coming from
458 * a separate place when rt is in the process of being created.
461 rt_primary_default(struct rtentry *rt, struct sockaddr *dst)
463 return (SA_DEFAULT(dst) && !(rt->rt_flags & RTF_IFSCOPE));
796 struct rtentry *rt = (struct rtentry *)rn;
798 int af = rt_key(rt)->sa_family;
800 if (!(rt->rt_flags & RTF_IFSCOPE) || (af != AF_INET && af != AF_INET6))
804 (SINIFSCOPE(rt_key(rt))->sin_scope_id == ma->ifscope) :
805 (SIN6IFSCOPE(rt_key(rt))->sin6_scope_id == ma->ifscope));
853 struct rtentry *rt;
855 if ((rt = ro->ro_rt) != NULL) {
856 RT_LOCK_SPIN(rt);
857 if (rt->rt_ifp != NULL && !ROUTE_UNUSABLE(ro)) {
858 RT_UNLOCK(rt);
861 RT_UNLOCK(rt);
911 struct rtentry *rt, *newrt = NULL;
923 rt = rt_lookup(FALSE, dst, NULL, rnh, ifscope);
924 if (rt == NULL)
927 RT_LOCK_SPIN(rt);
928 newrt = rt;
929 nflags = rt->rt_flags & ~ignflags;
930 RT_UNLOCK(rt);
945 newrt = rt;
954 rtfree_locked(rt);
955 if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
1015 rtfree_locked(struct rtentry *rt)
1017 rtfree_common(rt, TRUE);
1021 rtfree_common(struct rtentry *rt, boolean_t locked)
1032 RT_LOCK_SPIN(rt);
1033 if (rtunref(rt) > 0) {
1034 RT_UNLOCK(rt);
1054 RT_ADDREF_LOCKED(rt);
1055 RT_UNLOCK(rt);
1057 RT_LOCK_SPIN(rt);
1058 if (rtunref(rt) > 0) {
1060 RT_UNLOCK(rt);
1069 RT_CONVERT_LOCK(rt);
1074 if (rt->rt_refcnt != 0) {
1075 panic("rt %p invalid refcnt %d", rt, rt->rt_refcnt);
1079 VERIFY(!(rt->rt_flags & RTF_IFREF));
1085 rnh = rt_tables[rt_key(rt)->sa_family];
1096 rnh->rnh_close((struct radix_node *)rt, rnh);
1102 if (!(rt->rt_flags & RTF_UP)) {
1106 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) {
1107 panic("rt %p freed while in radix tree\n", rt);
1116 TAILQ_REMOVE(&rttrash_head, (struct rtentry_dbg *)rt,
1124 if ((rt_parent = rt->rt_parent) != NULL)
1125 rt->rt_parent = NULL;
1127 if ((rt_ifa = rt->rt_ifa) != NULL)
1128 rt->rt_ifa = NULL;
1133 if (rt->rt_llinfo != NULL) {
1134 if (rt->rt_llinfo_free != NULL)
1135 (*rt->rt_llinfo_free)(rt->rt_llinfo);
1137 R_Free(rt->rt_llinfo);
1138 rt->rt_llinfo = NULL;
1145 RT_UNLOCK(rt);
1158 R_Free(rt_key(rt));
1163 nstat_route_detach(rt);
1168 rte_lock_destroy(rt);
1169 rte_free(rt);
1176 RT_UNLOCK(rt);
1184 rtfree(struct rtentry *rt)
1186 rtfree_common(rt, FALSE);
1271 rtsetifa(struct rtentry *rt, struct ifaddr *ifa)
1275 RT_LOCK_ASSERT_HELD(rt);
1277 if (rt->rt_ifa == ifa)
1281 RT_CONVERT_LOCK(rt);
1284 if (rt->rt_ifa)
1285 IFA_REMREF(rt->rt_ifa);
1288 rt->rt_ifa = ifa;
1291 if (rt->rt_ifa)
1292 IFA_ADDREF(rt->rt_ifa);
1306 struct rtentry *rt = NULL;
1341 rt = rtalloc1_scoped_locked(dst, 0, RTF_CLONING|RTF_PRCLONING, ifscope);
1342 if (rt != NULL)
1343 RT_LOCK(rt);
1353 if (!(flags & RTF_DONE) && rt != NULL &&
1354 (!equal(src, rt->rt_gateway) || !equal(rt->rt_ifa->ifa_addr,
1372 if (rt != NULL)
1373 RT_UNLOCK(rt);
1383 if ((rt == NULL) || (rt_mask(rt) != NULL && rt_mask(rt)->sa_len < 2))
1389 RT_LOCK_ASSERT_HELD(rt);
1390 if (rt->rt_flags & RTF_GATEWAY) {
1391 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
1399 if (rt != NULL)
1400 RT_UNLOCK(rt);
1410 rt->rt_flags |= RTF_MODIFIED;
1416 error = rt_setgate(rt, rt_key(rt), gateway);
1417 RT_UNLOCK(rt);
1420 RT_UNLOCK(rt);
1424 if (rt != NULL) {
1425 RT_LOCK_ASSERT_NOTHELD(rt);
1427 *rtp = rt;
1429 rtfree_locked(rt);
1504 struct rtentry *rt = NULL;
1557 rt = rtalloc1_scoped_locked((struct sockaddr *)(size_t)dst,
1559 if (rt != NULL) {
1560 RT_LOCK_SPIN(rt);
1561 ifa = rt->rt_ifa;
1564 RT_CONVERT_LOCK(rt);
1567 RT_REMREF_LOCKED(rt);
1568 RT_UNLOCK(rt);
1569 rt = NULL;
1596 (rt = rtalloc1_scoped_locked((struct sockaddr *)(size_t)gw,
1600 RT_LOCK_SPIN(rt);
1601 ifa = rt->rt_ifa;
1604 RT_CONVERT_LOCK(rt);
1607 RT_REMREF_LOCKED(rt);
1608 RT_UNLOCK(rt);
1663 * RTF_IFSCOPE flag, callers can simply use its rt_key(rt) to clone it
1675 struct rtentry *rt;
1758 rt = (struct rtentry *)rn;
1760 RT_LOCK(rt);
1761 rt->rt_flags &= ~RTF_UP;
1766 rt_clear_idleref(rt);
1776 RT_ADDREF_LOCKED(rt);
1781 rt->rt_flags |= RTF_CONDEMNED;
1786 if (rt->rt_flags & RTF_ROUTER) {
1787 VERIFY(rt->rt_flags & RTF_HOST);
1788 rt->rt_flags &= ~RTF_ROUTER;
1795 if ((rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) &&
1796 rt_mask(rt)) {
1797 RT_UNLOCK(rt);
1798 rnh->rnh_walktree_from(rnh, dst, rt_mask(rt),
1799 rt_fixdelete, rt);
1800 RT_LOCK(rt);
1806 if ((gwrt = rt->rt_gwroute) != NULL)
1807 rt->rt_gwroute = NULL;
1812 if ((ifa = rt->rt_ifa) != NULL) {
1817 ifa_rtrequest(RTM_DELETE, rt, NULL);
1829 (struct rtentry_dbg *)rt, rtd_trash_link);
1836 if (rt_primary_default(rt, rt_key(rt))) {
1837 set_primary_ifscope(rt_key(rt)->sa_family,
1841 RT_UNLOCK(rt);
1847 * lock being acquired if gwrt is a clone of rt.
1859 *ret_nrt = rt;
1862 rtfree_locked(rt);
1873 if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)
1881 if (rt->rt_flags & RTF_REJECT) {
1882 if (rt->rt_flags & RTF_HOST) {
1898 ifa = rt->rt_ifa;
1900 flags = rt->rt_flags &
1903 gateway = rt->rt_gateway;
1904 if ((netmask = rt->rt_genmask) == NULL)
1926 (rt->rt_flags & RTF_PROXY)) {
1937 sin_get_ifscope(rt_key(rt)) :
1938 sin6_get_ifscope(rt_key(rt));
1940 ifscope = rt->rt_ifp->if_index;
1973 if ((rt = rte_alloc()) == NULL)
1975 Bzero(rt, sizeof(*rt));
1976 rte_lock_init(rt);
1978 rt->base_calendartime = caltime.tv_sec;
1979 rt->base_uptime = net_uptime();
1980 RT_LOCK(rt);
1981 rt->rt_flags = RTF_UP | flags;
1988 rt->rt_tree_genid = &route_genid_inet;
1992 rt->rt_tree_genid = &route_genid_inet6;
2003 if ((error = rt_setgate(rt, dst, gateway)) != 0) {
2005 RT_UNLOCK(rt);
2006 nstat_route_detach(rt);
2007 rte_lock_destroy(rt);
2008 rte_free(rt);
2015 ndst = rt_key(rt);
2030 rtsetifa(rt, ifa);
2031 rt->rt_ifp = rt->rt_ifa->ifa_ifp;
2036 rnh, rt->rt_nodes);
2063 (caddr_t)netmask, rnh, rt->rt_nodes);
2076 rt_set_gwroute(rt, rt_key(rt), NULL);
2077 if (rt->rt_ifa) {
2078 IFA_REMREF(rt->rt_ifa);
2079 rt->rt_ifa = NULL;
2081 R_Free(rt_key(rt));
2082 RT_UNLOCK(rt);
2083 nstat_route_detach(rt);
2084 rte_lock_destroy(rt);
2085 rte_free(rt);
2089 rt->rt_parent = NULL;
2106 rt->rt_rmx = (*ret_nrt)->rt_rmx;
2107 rt_setexpire(rt, (*ret_nrt)->rt_expire);
2110 rt->rt_parent = (*ret_nrt);
2124 ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : NULL));
2132 if (rt_primary_default(rt, rt_key(rt))) {
2133 set_primary_ifscope(rt_key(rt)->sa_family,
2134 rt->rt_ifp->if_index);
2142 *ret_nrt = rt;
2143 RT_ADDREF_LOCKED(rt);
2153 RT_GENID_SYNC(rt);
2160 if ((rt->rt_flags & RTF_GATEWAY) && rt->rt_gwroute != NULL)
2161 rt_set_gwroute(rt, rt_key(rt), rt->rt_gwroute);
2164 !(rt->rt_flags & RTF_HOST) && rt_mask(rt) != NULL) {
2167 arg.rt0 = rt;
2168 RT_UNLOCK(rt);
2169 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
2172 RT_UNLOCK(rt);
2175 nstat_route_new_entry(rt);
2221 struct rtentry *rt = (struct rtentry *)rn;
2226 RT_LOCK(rt);
2227 if (rt->rt_parent == rt0 &&
2228 !(rt->rt_flags & (RTF_CLONING | RTF_PRCLONING))) {
2234 RT_UNLOCK(rt);
2235 return (rtrequest_locked(RTM_DELETE, rt_key(rt), NULL,
2236 rt_mask(rt), rt->rt_flags, NULL));
2238 RT_UNLOCK(rt);
2247 * of rt->rt_parent is insufficient; each candidate route must be tested
2258 struct rtentry *rt = (struct rtentry *)rn;
2267 RT_LOCK(rt);
2269 if (!rt->rt_parent ||
2270 (rt->rt_flags & (RTF_CLONING | RTF_PRCLONING))) {
2271 RT_UNLOCK(rt);
2275 if (rt->rt_parent == rt0)
2282 len = imin(rt_key(rt0)->sa_len, rt_key(rt)->sa_len);
2286 xk2 = (u_char *)rt_key(rt);
2290 * route (rt->rt_parent) is a network route, since otherwise its mask
2293 if ((xmp = (u_char *)rt_mask(rt->rt_parent)) != NULL) {
2294 int mlen = rt_mask(rt->rt_parent)->sa_len;
2296 RT_UNLOCK(rt);
2302 RT_UNLOCK(rt);
2310 RT_UNLOCK(rt);
2324 RT_UNLOCK(rt);
2325 return (rtrequest_locked(RTM_DELETE, rt_key(rt), NULL,
2326 rt_mask(rt), rt->rt_flags, NULL));
2348 rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
2360 RT_LOCK_ASSERT_HELD(rt);
2366 if (rt->rt_flags & RTF_CONDEMNED) {
2371 RT_ADDREF_LOCKED(rt);
2373 if (rt->rt_flags & RTF_GATEWAY) {
2392 if (((rt->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) ==
2395 RT_REMREF_LOCKED(rt);
2404 if (((rt->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) ==
2410 if (rt_key(rt) != NULL) {
2416 RT_UNLOCK(rt);
2417 (void) rtrequest_locked(RTM_DELETE, rt_key(rt),
2418 rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
2419 RT_LOCK(rt);
2422 RT_REMREF_LOCKED(rt);
2430 if (rt->rt_flags & RTF_GATEWAY) {
2441 RT_UNLOCK(rt);
2450 RT_LOCK(rt);
2462 * when we get rt->rt_output(). It implies that a route to
2466 if (gwrt == rt) {
2469 RT_REMREF_LOCKED(rt);
2478 if (ifscope != IFSCOPE_NONE && (rt->rt_flags & RTF_IFSCOPE) &&
2481 rtfree_locked(gwrt); /* rt != gwrt, no deadlock */
2483 RT_REMREF_LOCKED(rt);
2484 return ((rt->rt_flags & RTF_HOST) ?
2489 if (rt->rt_flags & RTF_CONDEMNED) {
2493 RT_REMREF_LOCKED(rt);
2498 rt_set_gwroute(rt, dst, gwrt);
2506 if (rt_primary_default(rt, dst) && rt->rt_ifp != NULL) {
2508 rt->rt_ifp->if_index);
2539 if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway->sa_len)) {
2546 rt_set_gwroute(rt, dst, NULL);
2548 RT_REMREF_LOCKED(rt);
2553 * Copy from 'dst' and not rt_key(rt) because we can get
2555 * which case rt_key(rt) is NULL (and so does rt_gateway).
2559 R_Free(rt_key(rt)); /* free old block; NULL is okay */
2560 rt->rt_nodes->rn_key = new;
2561 rt->rt_gateway = (struct sockaddr *)(new + dlen);
2567 Bcopy(gate, rt->rt_gateway, gate->sa_len);
2572 if ((rt->rt_flags & RTF_GATEWAY) && rt->rt_gwroute != NULL &&
2573 (rt->rt_gwroute->rt_flags & RTF_IFSCOPE)) {
2574 if (rt->rt_gateway->sa_family == AF_INET &&
2575 rt_key(rt->rt_gwroute)->sa_family == AF_INET) {
2576 sin_set_ifscope(rt->rt_gateway,
2577 sin_get_ifscope(rt_key(rt->rt_gwroute)));
2578 } else if (rt->rt_gateway->sa_family == AF_INET6 &&
2579 rt_key(rt->rt_gwroute)->sa_family == AF_INET6) {
2580 sin6_set_ifscope(rt->rt_gateway,
2581 sin6_get_ifscope(rt_key(rt->rt_gwroute)));
2590 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
2593 arg.rt0 = rt;
2594 RT_UNLOCK(rt);
2595 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
2597 RT_LOCK(rt);
2601 RT_REMREF_LOCKED(rt);
2608 rt_set_gwroute(struct rtentry *rt, struct sockaddr *dst, struct rtentry *gwrt)
2613 RT_LOCK_ASSERT_HELD(rt);
2623 if (rt->rt_gwroute != NULL) {
2624 struct rtentry *ogwrt = rt->rt_gwroute;
2626 VERIFY(rt != ogwrt); /* sanity check */
2627 rt->rt_gwroute = NULL;
2628 RT_UNLOCK(rt);
2630 RT_LOCK(rt);
2631 VERIFY(rt->rt_gwroute == NULL);
2637 if ((rt->rt_gwroute = gwrt) != NULL) {
2638 RT_ADDREF(gwrt); /* for rt */
2640 if (rt->rt_flags & RTF_WASCLONED) {
2641 /* rt_parent might be NULL if rt is embryonic */
2642 gwrt_isrouter = (rt->rt_parent != NULL &&
2643 SA_DEFAULT(rt_key(rt->rt_parent)) &&
2644 !RT_HOST(rt->rt_parent));
2646 gwrt_isrouter = (SA_DEFAULT(dst) && !RT_HOST(rt));
2854 struct rtentry *rt = RT(rn);
2855 if (!(rt->rt_ifp->if_flags & IFF_LOOPBACK)) {
2856 if (rt->rt_ifp->if_index != ifscope) {
2866 ifscope = rt->rt_ifp->if_index;
2869 } else if (!(rt->rt_flags & RTF_IFSCOPE)) {
2953 rt_validate(struct rtentry *rt)
2955 RT_LOCK_ASSERT_HELD(rt);
2957 if ((rt->rt_flags & (RTF_UP | RTF_CONDEMNED)) == RTF_UP) {
2958 int af = rt_key(rt)->sa_family;
2961 (void) in_validate(RN(rt));
2963 (void) in6_validate(RN(rt));
2965 rt = NULL;
2968 return (rt != NULL);
2996 struct rtentry *rt = NULL;
3068 rt = rt_lookup_coarse(TRUE, dst, NULL, rnh);
3069 if (rt != NULL) {
3070 rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
3076 RT_LOCK(rt);
3077 if (rt->rt_ifa != ifa) {
3090 gbuf, ((rt->rt_ifp != NULL) ?
3091 rt->rt_ifp->if_xname : ""),
3092 rt->rt_flags, RTF_BITS, abuf,
3094 rt->rt_ifa),
3097 RT_REMREF_LOCKED(rt);
3098 RT_UNLOCK(rt);
3099 rt = NULL;
3103 } else if (rt->rt_flags & RTF_STATIC) {
3112 dbuf, gbuf, ((rt->rt_ifp != NULL) ?
3113 rt->rt_ifp->if_xname : ""),
3114 rt->rt_flags, RTF_BITS, abuf);
3116 RT_REMREF_LOCKED(rt);
3117 RT_UNLOCK(rt);
3118 rt = NULL;
3126 ((rt->rt_ifp != NULL) ?
3127 rt->rt_ifp->if_xname : ""),
3128 rt->rt_flags, RTF_BITS, abuf);
3130 RT_REMREF_LOCKED(rt);
3131 RT_UNLOCK(rt);
3132 rt = NULL;
3139 flags | ifa->ifa_flags, &rt)) != 0)
3142 VERIFY(rt != NULL);
3144 rt_str(rt, dbuf, sizeof (dbuf), gbuf, sizeof (gbuf));
3153 RT_LOCK(rt);
3154 rt_newaddrmsg(cmd, ifa, error, rt);
3155 RT_UNLOCK(rt);
3159 ((rt->rt_ifp != NULL) ? rt->rt_ifp->if_xname : ""),
3160 rt->rt_flags, RTF_BITS, abuf);
3162 rtfree_locked(rt);
3172 RT_LOCK(rt);
3173 if (rt->rt_ifa != ifa) {
3177 if (!(rt->rt_ifa->ifa_ifp->if_flags &
3182 dbuf, gbuf, ((rt->rt_ifp != NULL) ?
3183 rt->rt_ifp->if_xname : ""), rt->rt_flags,
3185 (uint64_t)VM_KERNEL_ADDRPERM(rt->rt_ifa),
3193 dbuf, gbuf, ((rt->rt_ifp != NULL) ?
3194 rt->rt_ifp->if_xname : ""), rt->rt_flags,
3196 (uint64_t)VM_KERNEL_ADDRPERM(rt->rt_ifa),
3205 ifa_rtrequest = rt->rt_ifa->ifa_rtrequest;
3207 ifa_rtrequest(RTM_DELETE, rt, NULL);
3211 rtsetifa(rt, ifa);
3213 if (rt->rt_ifp != ifa->ifa_ifp) {
3217 if (rt->rt_llinfo_purge != NULL)
3218 rt->rt_llinfo_purge(rt);
3222 if (rt->rt_if_ref_fn != NULL) {
3223 rt->rt_if_ref_fn(ifa->ifa_ifp, 1);
3224 rt->rt_if_ref_fn(rt->rt_ifp, -1);
3232 rt->rt_ifp = ifa->ifa_ifp;
3237 if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
3238 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
3246 ifa_rtrequest(RTM_ADD, rt, NULL);
3251 gbuf, ((rt->rt_ifp != NULL) ?
3252 rt->rt_ifp->if_xname : ""), rt->rt_flags,
3259 rt_newaddrmsg(cmd, ifa, error, rt);
3267 RT_REMREF_LOCKED(rt);
3268 RT_UNLOCK(rt);
3280 rt_set_idleref(struct rtentry *rt)
3282 RT_LOCK_ASSERT_HELD(rt);
3288 if (rt->rt_parent != NULL && !(rt->rt_flags &
3290 (rt->rt_flags & (RTF_UP|RTF_WASCLONED|RTF_IFREF)) ==
3292 rt_clear_idleref(rt); /* drop existing refcnt if any */
3293 rt->rt_if_ref_fn = rte_if_ref;
3295 RT_CONVERT_LOCK(rt);
3296 rt->rt_if_ref_fn(rt->rt_ifp, 1);
3297 rt->rt_flags |= RTF_IFREF;
3302 rt_clear_idleref(struct rtentry *rt)
3304 RT_LOCK_ASSERT_HELD(rt);
3306 if (rt->rt_if_ref_fn != NULL) {
3307 VERIFY((rt->rt_flags & (RTF_NOIFREF | RTF_IFREF)) == RTF_IFREF);
3309 RT_CONVERT_LOCK(rt);
3310 rt->rt_if_ref_fn(rt->rt_ifp, -1);
3311 rt->rt_flags &= ~RTF_IFREF;
3312 rt->rt_if_ref_fn = NULL;
3317 rt_set_proxy(struct rtentry *rt, boolean_t set)
3320 RT_LOCK(rt);
3325 if (rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) {
3326 struct radix_node_head *rnh = rt_tables[rt_key(rt)->sa_family];
3329 rt->rt_flags |= RTF_PROXY;
3331 rt->rt_flags &= ~RTF_PROXY;
3333 RT_UNLOCK(rt);
3334 if (rnh != NULL && rt_mask(rt)) {
3335 rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
3336 rt_fixdelete, rt);
3339 RT_UNLOCK(rt);
3345 rte_lock_init(struct rtentry *rt)
3347 lck_mtx_init(&rt->rt_lock, rte_mtx_grp, rte_mtx_attr);
3351 rte_lock_destroy(struct rtentry *rt)
3353 RT_LOCK_ASSERT_NOTHELD(rt);
3354 lck_mtx_destroy(&rt->rt_lock, rte_mtx_grp);
3358 rt_lock(struct rtentry *rt, boolean_t spin)
3360 RT_LOCK_ASSERT_NOTHELD(rt);
3362 lck_mtx_lock_spin(&rt->rt_lock);
3364 lck_mtx_lock(&rt->rt_lock);
3366 rte_lock_debug((struct rtentry_dbg *)rt);
3370 rt_unlock(struct rtentry *rt)
3373 rte_unlock_debug((struct rtentry_dbg *)rt);
3374 lck_mtx_unlock(&rt->rt_lock);
3527 /* Copy everything (rt, srcif, flags, dst) from src */
3551 * Copy everything (rt, srcia, flags, dst) from src; the
3552 * references to rt and/or srcia were held at the time
3608 struct rtentry *rt = hint0, *hint = hint0;
3615 if (rt == NULL)
3630 RT_LOCK_SPIN(rt);
3631 ifindex = rt->rt_ifp->if_index;
3632 RT_ADDREF_LOCKED(rt);
3633 if (!(rt->rt_flags & RTF_UP)) {
3634 RT_REMREF_LOCKED(rt);
3635 RT_UNLOCK(rt);
3637 hint = rt = rtalloc1_scoped((struct sockaddr *)
3640 RT_LOCK_SPIN(rt);
3641 ifindex = rt->rt_ifp->if_index;
3648 * We have a reference to "rt" by now; it will either
3651 RT_LOCK_ASSERT_HELD(rt);
3652 if ((gwroute = (rt->rt_flags & RTF_GATEWAY))) {
3653 struct rtentry *gwrt = rt->rt_gwroute;
3657 VERIFY(rt == hint);
3660 /* If there's no gateway rt, look it up */
3662 bcopy(rt->rt_gateway, gw, MIN(sizeof (ss),
3663 rt->rt_gateway->sa_len));
3664 RT_UNLOCK(rt);
3668 RT_CONVERT_LOCK(rt);
3673 * to "rt", so no lock ordering issues.
3677 rt->rt_gwroute = NULL;
3679 bcopy(rt->rt_gateway, gw, MIN(sizeof (ss),
3680 rt->rt_gateway->sa_len));
3681 RT_UNLOCK(rt);
3687 RT_LOCK(rt);
3691 * gateway portion of "rt" has changed.
3693 if (!(rt->rt_flags & RTF_UP) || gwrt == NULL ||
3694 gwrt == rt || !equal(gw, rt->rt_gateway)) {
3695 if (gwrt == rt) {
3699 VERIFY(rt == hint);
3702 RT_UNLOCK(rt);
3714 rt_set_gwroute(rt, rt_key(rt), gwrt);
3715 VERIFY(rt == hint);
3716 RT_REMREF_LOCKED(rt); /* hint still holds a refcnt */
3717 RT_UNLOCK(rt);
3719 rt = gwrt;
3723 VERIFY(rt == hint);
3724 RT_REMREF_LOCKED(rt); /* hint still holds a refcnt */
3725 RT_UNLOCK(rt);
3726 rt = gwrt;
3728 VERIFY(rt == gwrt && rt != hint);
3734 * a reference to it. rt == gwrt.
3745 rt_revalidate_gwroute(prt, rt);
3758 /* rt == gwrt; if it is now down, give up */
3759 RT_LOCK_SPIN(rt);
3760 if (!(rt->rt_flags & RTF_UP)) {
3761 RT_UNLOCK(rt);
3766 if (rt->rt_flags & RTF_REJECT) {
3767 VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0);
3768 VERIFY(rt->rt_expire != 0 || rt->rt_rmx.rmx_expire == 0);
3770 if (rt->rt_expire == 0 || timenow < rt->rt_expire) {
3771 RT_UNLOCK(rt);
3777 RT_CONVERT_LOCK(rt);
3779 /* Caller is responsible for cleaning up "rt" */
3780 *out_route = rt;
3784 /* Clean up route (either it is "rt" or "gwrt") */
3785 if (rt != NULL) {
3786 RT_LOCK_SPIN(rt);
3787 if (rt == hint0) {
3788 RT_REMREF_LOCKED(rt);
3789 RT_UNLOCK(rt);
3791 RT_UNLOCK(rt);
3792 rtfree(rt);
3800 rt_revalidate_gwroute(struct rtentry *rt, struct rtentry *gwrt)
3804 RT_LOCK_SPIN(rt);
3805 if ((rt->rt_flags & (RTF_GATEWAY | RTF_UP)) == (RTF_GATEWAY | RTF_UP) &&
3806 rt->rt_ifp == gwrt->rt_ifp && rt->rt_gateway->sa_family ==
3807 rt_key(gwrt)->sa_family && (rt->rt_gwroute == NULL ||
3808 !(rt->rt_gwroute->rt_flags & RTF_UP))) {
3810 VERIFY(rt->rt_flags & (RTF_CLONING | RTF_PRCLONING));
3812 if (rt->rt_gateway->sa_family == AF_INET ||
3813 rt->rt_gateway->sa_family == AF_INET6) {
3820 (void) sa_copy(rt->rt_gateway, &gw_ss, NULL);
3824 isequal = equal(rt_key(gwrt), rt->rt_gateway);
3829 RT_UNLOCK(rt);
3831 RT_LOCK(rt);
3832 rt_set_gwroute(rt, rt_key(rt), gwrt);
3833 RT_UNLOCK(rt);
3836 RT_UNLOCK(rt);
3839 RT_UNLOCK(rt);
3844 rt_str4(struct rtentry *rt, char *ds, uint32_t dslen, char *gs, uint32_t gslen)
3846 VERIFY(rt_key(rt)->sa_family == AF_INET);
3850 &SIN(rt_key(rt))->sin_addr.s_addr, ds, dslen);
3852 if (rt->rt_flags & RTF_GATEWAY) {
3854 &SIN(rt->rt_gateway)->sin_addr.s_addr, gs, gslen);
3855 } else if (rt->rt_ifp != NULL) {
3856 snprintf(gs, gslen, "link#%u", rt->rt_ifp->if_unit);
3865 rt_str6(struct rtentry *rt, char *ds, uint32_t dslen, char *gs, uint32_t gslen)
3867 VERIFY(rt_key(rt)->sa_family == AF_INET6);
3871 &SIN6(rt_key(rt))->sin6_addr, ds, dslen);
3873 if (rt->rt_flags & RTF_GATEWAY) {
3875 &SIN6(rt->rt_gateway)->sin6_addr, gs, gslen);
3876 } else if (rt->rt_ifp != NULL) {
3877 snprintf(gs, gslen, "link#%u", rt->rt_ifp->if_unit);
3887 rt_str(struct rtentry *rt, char *ds, uint32_t dslen, char *gs, uint32_t gslen)
3889 switch (rt_key(rt)->sa_family) {
3891 rt_str4(rt, ds, dslen, gs, gslen);
3895 rt_str6(rt, ds, dslen, gs, gslen);