Home | History | Annotate | Download | only in net

Lines Matching refs:rt

143 #define RT_REFCNT_TRACE(rt)	printf("%s:%d: rt=%p refcnt=%d\n", \
144 __func__, __LINE__, (rt), (rt)->rt_refcnt)
146 #define RT_REFCNT_TRACE(rt) do {} while (0)
330 rt_destroy(struct rtentry *rt)
332 if (rt->_rt_key != NULL)
333 sockaddr_free(rt->_rt_key);
334 if (rt->rt_gateway != NULL)
335 sockaddr_free(rt->rt_gateway);
336 if (rt_gettag(rt) != NULL)
337 sockaddr_free(rt_gettag(rt));
338 rt->_rt_key = rt->rt_gateway = rt->rt_tag = NULL;
342 rt_setkey(struct rtentry *rt, const struct sockaddr *key, int flags)
344 if (rt->_rt_key == key)
347 if (rt->_rt_key != NULL)
348 sockaddr_free(rt->_rt_key);
349 rt->_rt_key = sockaddr_dup(key, flags);
351 rt->rt_nodes->rn_key = (const char *)rt->_rt_key;
352 return rt->_rt_key;
356 rt_get_ifa(struct rtentry *rt)
360 ifa = rt->rt_ifa;
364 else if (ifa->ifa_seqno != NULL && *ifa->ifa_seqno == rt->rt_ifa_seqno)
368 ifa = (*ifa->ifa_getifa)(ifa, rt_getkey(rt));
371 rt_replace_ifa(rt, ifa);
377 rt_set_ifa1(struct rtentry *rt, struct ifaddr *ifa)
379 rt->rt_ifa = ifa;
381 rt->rt_ifa_seqno = *ifa->ifa_seqno;
388 rt_ifa_connected(const struct rtentry *rt, const struct ifaddr *ifa)
393 key = rt_getkey(rt);
394 dst = rt->rt_flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
399 if ((rt->rt_flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
409 rt_replace_ifa(struct rtentry *rt, struct ifaddr *ifa)
413 if (rt->rt_ifa == ifa)
416 if (rt->rt_ifa != ifa &&
417 rt->rt_ifa->ifa_flags & IFA_ROUTE &&
418 rt_ifa_connected(rt, rt->rt_ifa))
420 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
422 (void *)rt->_rt_key, (void *)rt->rt_ifa);
423 rt->rt_ifa->ifa_flags &= ~IFA_ROUTE;
424 if (rt_ifa_connected(rt, ifa)) {
425 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
427 (void *)rt->_rt_key, (void *)ifa);
433 old = rt->rt_ifa;
434 rt_set_ifa1(rt, ifa);
439 rt_set_ifa(struct rtentry *rt, struct ifaddr *ifa)
442 rt_set_ifa1(rt, ifa);
515 dump_rt(const struct rtentry *rt)
519 log(LOG_DEBUG, "rt: ");
520 log(LOG_DEBUG, "p=%p ", rt);
521 if (rt->_rt_key == NULL) {
524 sockaddr_format(rt->_rt_key, buf, sizeof(buf));
527 if (rt->rt_gateway == NULL) {
530 sockaddr_format(rt->_rt_key, buf, sizeof(buf));
533 log(LOG_DEBUG, "flags=%x ", rt->rt_flags);
534 if (rt->rt_ifp == NULL) {
537 log(LOG_DEBUG, "if=%s ", rt->rt_ifp->if_xname);
552 struct rtentry *rt;
563 rt = rt_matchaddr(rtbl, dst);
564 if (rt == NULL)
567 if (!ISSET(rt->rt_flags, RTF_UP))
571 if (ISSET(rt->rt_flags, RTF_UPDATING) &&
590 rt_ref(rt);
591 RT_REFCNT_TRACE(rt);
594 return rt;
611 struct rtentry *rt;
614 rt = rtalloc1_locked(dst, report, true, false);
617 return rt;
621 rt_ref(struct rtentry *rt)
624 KASSERTMSG(rt->rt_refcnt >= 0, "rt_refcnt=%d", rt->rt_refcnt);
625 atomic_inc_uint(&rt->rt_refcnt);
629 rt_unref(struct rtentry *rt)
632 KASSERT(rt != NULL);
633 KASSERTMSG(rt->rt_refcnt > 0, "refcnt=%d", rt->rt_refcnt);
635 atomic_dec_uint(&rt->rt_refcnt);
636 if (!ISSET(rt->rt_flags, RTF_UP) || ISSET(rt->rt_flags, RTF_UPDATING)) {
638 cv_broadcast(&rt->rt_cv);
661 rt_wait_refcnt(const char *title, struct rtentry *rt, int cnt)
664 while (rt->rt_refcnt > cnt) {
666 __func__, title, rt->rt_refcnt);
667 cv_wait(&rt->rt_cv, &rt_free_global.lock);
669 __func__, title, rt->rt_refcnt);
675 rt_wait_psref(struct rtentry *rt)
678 psref_target_destroy(&rt->rt_psref, rt_psref_class);
679 psref_target_init(&rt->rt_psref, rt_psref_class);
683 _rt_free(struct rtentry *rt)
695 RT_REFCNT_TRACE(rt);
696 KASSERTMSG(rt->rt_refcnt >= 0, "refcnt=%d", rt->rt_refcnt);
697 rt_wait_refcnt("free", rt, 0);
699 psref_target_destroy(&rt->rt_psref, rt_psref_class);
702 rt_assert_inactive(rt);
704 ifa = rt->rt_ifa;
705 rt->rt_ifa = NULL;
707 rt->rt_ifp = NULL;
708 cv_destroy(&rt->rt_cv);
709 rt_destroy(rt);
710 pool_put(&rtentry_pool, rt);
718 struct rtentry *rt;
721 if ((rt = SLIST_FIRST(&rt_free_global.queue)) == NULL) {
728 atomic_dec_uint(&rt->rt_refcnt);
729 _rt_free(rt);
734 rt_free(struct rtentry *rt)
737 KASSERTMSG(rt->rt_refcnt > 0, "rt_refcnt=%d", rt->rt_refcnt);
739 atomic_dec_uint(&rt->rt_refcnt);
740 _rt_free(rt);
746 SLIST_INSERT_HEAD(&rt_free_global.queue, rt, rt_free);
770 rt_update_prepare(struct rtentry *rt)
773 dlog(LOG_DEBUG, "%s: updating rt=%p lwp=%p\n", __func__, rt, curlwp);
777 if (!ISSET(rt->rt_flags, RTF_UP)) {
781 rt->rt_flags |= RTF_UPDATING;
786 dlog(LOG_DEBUG, "%s: waiting ongoing updating rt=%p lwp=%p\n",
787 __func__, rt, curlwp);
789 dlog(LOG_DEBUG, "%s: waited ongoing updating rt=%p lwp=%p\n",
790 __func__, rt, curlwp);
797 rt_wait_refcnt("update", rt, 1);
798 rt_wait_psref(rt);
804 rt_update_finish(struct rtentry *rt)
808 rt->rt_flags &= ~RTF_UPDATING;
817 dlog(LOG_DEBUG, "%s: updated rt=%p lwp=%p\n", __func__, rt, curlwp);
833 struct rtentry *rt;
845 rt = rtalloc1(dst, 0);
852 if (!(flags & RTF_DONE) && rt &&
853 (sockaddr_cmp(src, rt->rt_gateway) != 0 || rt->rt_ifa != ifa))
872 if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
878 if (rt->rt_flags & RTF_GATEWAY) {
879 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
885 if (rt != NULL)
886 rt_unref(rt);
894 rt = NULL;
895 error = rtrequest1(RTM_ADD, &info, &rt);
896 if (rt != NULL)
897 flags = rt->rt_flags;
899 rt_newmsg_dynamic(RTM_ADD, rt);
909 error = rt_update_prepare(rt);
913 error = rt_setgate(rt, gateway);
915 rt->rt_flags |= RTF_MODIFIED;
920 rt_update_finish(rt);
934 if (rt) {
936 *rtp = rt;
938 rt_unref(rt);
956 * It doesn't free a passed rt.
959 rtdeletemsg(struct rtentry *rt)
971 info.rti_info[RTAX_DST] = rt_getkey(rt);
972 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
973 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
974 info.rti_flags = rt->rt_flags;
1012 struct rtentry *rt;
1014 rt = rtalloc1_locked(gateway, 0, true, true);
1015 if (rt == NULL)
1017 if (rt->rt_flags & RTF_GATEWAY) {
1018 rt_unref(rt);
1026 IFADDR_READER_FOREACH(ifa, rt->rt_ifp) {
1027 if (ifa == rt->rt_ifa)
1033 rt_unref(rt);
1145 struct rtentry *rt;
1174 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
1176 if ((rt = rt_deladdr(rtbl, dst, netmask)) == NULL)
1178 rt->rt_flags &= ~RTF_UP;
1179 ifa = rt->rt_ifa;
1181 rt_ifa_connected(rt, ifa)) {
1182 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
1184 (void *)rt->_rt_key, (void *)ifa);
1188 ifa->ifa_rtrequest(RTM_DELETE, rt, info);
1192 *ret_nrt = rt;
1193 rt_ref(rt);
1194 RT_REFCNT_TRACE(rt);
1199 rt);
1206 rt_ref(rt);
1207 RT_REFCNT_TRACE(rt);
1208 rt_free(rt);
1223 rt = pool_get(&rtentry_pool, PR_NOWAIT);
1224 if (rt == NULL)
1226 memset(rt, 0, sizeof(*rt));
1227 rt->rt_flags = RTF_UP | (flags & ~RTF_DONTCHANGEIFA);
1228 LIST_INIT(&rt->rt_timer);
1230 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1234 rt_setkey(rt, (struct sockaddr *)&maskeddst, M_NOWAIT);
1236 rt_setkey(rt, dst, M_NOWAIT);
1238 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1239 if (rt_getkey(rt) == NULL ||
1240 rt_setgate(rt, gateway) != 0) {
1241 pool_put(&rtentry_pool, rt);
1245 rt_set_ifa(rt, ifa);
1248 tag = rt_settag(rt, info->rti_info[RTAX_TAG]);
1252 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1259 rt->rt_ifp = ifa2->ifa_ifp;
1261 rt->rt_ifp = ifa->ifa_ifp;
1263 rt->rt_ifp = ifa->ifa_ifp;
1265 cv_init(&rt->rt_cv, "rtentry");
1266 psref_target_init(&rt->rt_psref, rt_psref_class);
1268 ifa->ifa_rtrequest(req, rt, info);
1270 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1271 rc = rt_addaddr(rtbl, rt, netmask);
1272 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1275 cv_destroy(&rt->rt_cv);
1276 rt_destroy(rt);
1277 pool_put(&rtentry_pool, rt);
1280 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1286 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1288 *ret_nrt = rt;
1289 rt_ref(rt);
1290 RT_REFCNT_TRACE(rt);
1302 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
1305 *ret_nrt = rt;
1306 rt_ref(rt);
1307 RT_REFCNT_TRACE(rt);
1323 rt_setgate(struct rtentry *rt, const struct sockaddr *gate)
1328 KASSERT(rt->_rt_key != NULL);
1329 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1335 old = rt->rt_gateway;
1336 rt->rt_gateway = new;
1340 KASSERT(rt->_rt_key != NULL);
1341 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1343 if (rt->rt_flags & RTF_GATEWAY) {
1357 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
1358 rt->rt_rmx.rmx_mtu &&
1359 rt->rt_rmx.rmx_mtu > gwrt->rt_rmx.rmx_mtu) {
1360 rt->rt_rmx.rmx_mtu = gwrt->rt_rmx.rmx_mtu;
1365 KASSERT(rt->_rt_key != NULL);
1366 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
1371 rt_update_get_ifa(const struct rt_addrinfo *info, const struct rtentry *rt,
1416 ifa = ifa_ifwithroute_psref(rt->rt_flags, rt_getkey(rt),
1432 rt_update(struct rtentry *rt, struct rt_addrinfo *info, void *rtm)
1447 sockaddr_cmp(info->rti_info[RTAX_GATEWAY], rt->rt_gateway) != 0;
1460 error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]);
1466 tag = rt_settag(rt, info->rti_info[RTAX_TAG]);
1477 new_ifa = rt_update_get_ifa(info, rt, &new_ifp, &psref_new_ifp,
1484 struct ifaddr *oifa = rt->rt_ifa;
1488 oifa->ifa_rtrequest(RTM_DELETE, rt, info);
1489 rt_replace_ifa(rt, ifa);
1490 rt->rt_ifp = new_ifp;
1499 if (new_ifp && rt->rt_ifp != new_ifp && !if_is_deactivated(new_ifp)) {
1500 rt->rt_ifp = new_ifp;
1503 rt_setmetrics(rtm, rt);
1504 if (rt->rt_flags != info->rti_flags) {
1505 rt->rt_flags = (info->rti_flags & ~PRESERVED_RTF) |
1506 (rt->rt_flags & PRESERVED_RTF);
1508 if (rt->rt_ifa->ifa_rtrequest)
1509 rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info);
1511 if (ifp_changed && rt_mask(rt) != NULL)
1512 lltable_prefix_free(rt_getkey(rt)->sa_family, rt_getkey(rt),
1513 rt_mask(rt), 0);
1550 rt_newmsg(const int cmd, const struct rtentry *rt)
1555 info.rti_info[RTAX_DST] = rt_getkey(rt);
1556 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1557 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1558 if (rt->rt_ifp) {
1559 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr;
1560 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
1563 rt_missmsg(cmd, &info, rt->rt_flags, 0);
1570 rt_newmsg_dynamic(const int cmd, const struct rtentry *rt)
1573 struct sockaddr *gateway = rt->rt_gateway;
1600 info.rti_info[RTAX_DST] = rt_getkey(rt);
1602 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1603 if (rt->rt_ifp) {
1604 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr;
1605 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
1608 rt_missmsg(cmd, &info, rt->rt_flags, 0);
1618 struct rtentry *rt;
1633 if ((rt = rtalloc1(dst, 0)) != NULL) {
1634 if (rt->rt_ifa != ifa) {
1635 rt_unref(rt);
1639 rt_unref(rt);
1661 rt = nrt;
1662 RT_REFCNT_TRACE(rt);
1665 rt_newmsg(cmd, rt);
1666 rt_free(rt);
1670 ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);
1671 rt_newmsg(RTM_CHANGE, rt);
1672 rt_unref(rt);
1675 KASSERT(rt->rt_ifa == ifa);
1676 rt_newmsg(cmd, rt);
1677 rt_unref(rt);
1678 RT_REFCNT_TRACE(rt);
1691 struct rtentry *rt;
1695 rt = rtalloc1(ifa->ifa_addr, 0);
1697 if (rt != NULL)
1698 dump_rt(rt);
1700 if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
1701 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
1727 if (rt != NULL)
1728 rt_unref(rt);
1739 struct rtentry *rt;
1742 rt = rtalloc1(ifa->ifa_addr, 0);
1752 if (rt != NULL &&
1753 (rt->rt_flags & RTF_HOST) &&
1754 (rt->rt_ifp->if_flags & IFF_LOOPBACK))
1761 e = rtdeletemsg(rt);
1763 rt_unref(rt);
1764 rt_free(rt);
1765 rt = NULL;
1770 int error = rt_update_prepare(rt);
1772 rt_replace_ifa(rt, alt_ifa);
1773 rt_update_finish(rt);
1782 rt_replace_ifa(rt, alt_ifa);
1784 rt_newmsg(RTM_CHANGE, rt);
1788 if (rt != NULL)
1789 rt_unref(rt);
1908 rt_timer_remove_all(struct rtentry *rt)
1913 while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) {
1926 rt_timer_add(struct rtentry *rt,
1938 LIST_FOREACH(r, &rt->rt_timer, rtt_link) {
1959 r->rtt_rt = rt;
1963 LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
2016 struct rtentry *rt;
2023 rt = rtalloc1(rtcache_getdst(ro), flag);
2024 if (rt != NULL) {
2026 if (ISSET(rt->rt_flags, RTF_UP)) {
2027 ro->_ro_rt = rt;
2029 rtcache_ref(rt, ro);
2032 rt_unref(rt);
2064 struct rtentry *rt;
2071 rt = rtcache_validate(old_ro);
2080 new_ro->_ro_rt = rt;
2085 rtcache_unref(rt, old_ro);
2091 rtcache_trace(const char *func, struct rtentry *rt, struct route *ro)
2097 cpu_index(curcpu()), curlwp, &ro->ro_psref, &rt->rt_psref);
2099 #define RTCACHE_PSREF_TRACE(rt, ro) rtcache_trace(__func__, (rt), (ro))
2101 #define RTCACHE_PSREF_TRACE(rt, ro) do {} while (0)
2105 rtcache_ref(struct rtentry *rt, struct route *ro)
2108 KASSERT(rt != NULL);
2111 RTCACHE_PSREF_TRACE(rt, ro);
2115 psref_acquire(&ro->ro_psref, &rt->rt_psref, rt_psref_class);
2120 rtcache_unref(struct rtentry *rt, struct route *ro)
2123 if (rt == NULL)
2127 psref_release(&ro->ro_psref, &rt->rt_psref, rt_psref_class);
2129 RTCACHE_PSREF_TRACE(rt, ro);
2136 struct rtentry *rt = NULL;
2145 rt = NULL;
2149 rt = ro->_ro_rt;
2150 if (rt == NULL)
2153 if ((rt->rt_flags & RTF_UP) == 0) {
2154 rt = NULL;
2158 if (ISSET(rt->rt_flags, RTF_UPDATING)) {
2166 rt = NULL;
2170 rtcache_ref(rt, ro);
2173 return rt;
2181 struct rtentry *rt = NULL;
2192 rt = rtcache_validate(ro);
2193 if (rt == NULL) {
2202 return rt;
2207 rt = _rtcache_init(ro, clone);
2211 return rt;
2274 rt_settag(struct rtentry *rt, const struct sockaddr *tag)
2276 if (rt->rt_tag != tag) {
2277 if (rt->rt_tag != NULL)
2278 sockaddr_free(rt->rt_tag);
2279 rt->rt_tag = sockaddr_dup(tag, M_ZERO | M_NOWAIT);
2281 return rt->rt_tag;
2285 rt_gettag(const struct rtentry *rt)
2287 return rt->rt_tag;
2291 rt_check_reject_route(const struct rtentry *rt, const struct ifnet *ifp)
2294 if ((rt->rt_flags & RTF_REJECT) != 0) {
2297 return (rt->rt_flags & RTF_HOST) ?
2299 else if (rt->rt_rmx.rmx_expire == 0 ||
2300 time_uptime < rt->rt_rmx.rmx_expire)
2301 return (rt->rt_flags & RTF_GATEWAY) ?
2316 struct rtentry *rt, *retrt = NULL;
2320 rt = rtbl_search_matched_entry(family, f, v);
2321 if (rt == NULL) {
2326 rt_ref(rt);
2327 RT_REFCNT_TRACE(rt);
2331 error = rtrequest(RTM_DELETE, rt_getkey(rt), rt->rt_gateway,
2332 rt_mask(rt), rt->rt_flags, &retrt);
2334 KASSERT(retrt == rt);
2339 rt_unref(rt);
2340 RT_REFCNT_TRACE(rt);
2344 rt_unref(rt);
2345 RT_REFCNT_TRACE(rt);
2348 "error = %d\n", rt->rt_ifp->if_xname, rt, error);
2372 struct rtentry *rt;
2376 rt = rtbl_search_matched_entry(family, f, v);
2377 if (rt == NULL) {
2382 rt_ref(rt);
2383 RT_REFCNT_TRACE(rt);
2388 error = rt_update_prepare(rt);
2390 rt_replace_ifa(rt, ifa);
2391 rt_update_finish(rt);
2392 rt_newmsg(RTM_CHANGE, rt);
2401 rt_replace_ifa(rt, ifa);
2402 rt_newmsg(RTM_CHANGE, rt);
2404 rt_unref(rt);
2405 RT_REFCNT_TRACE(rt);
2484 db_show_rtentry(struct rtentry *rt, void *w)
2486 db_printf("rtentry=%p", rt);
2489 rt->rt_flags, rt->rt_refcnt,
2490 rt->rt_use, (uint64_t)rt->rt_expire);
2492 db_printf(" key="); db_print_sa(rt_getkey(rt));
2493 db_printf(" mask="); db_print_sa(rt_mask(rt));
2494 db_printf(" gw="); db_print_sa(rt->rt_gateway);
2496 db_printf(" ifp=%p ", rt->rt_ifp);
2497 if (rt->rt_ifp)
2498 db_printf("(%s)", rt->rt_ifp->if_xname);
2502 db_printf(" ifa=%p\n", rt->rt_ifa);
2503 db_print_ifa(rt->rt_ifa);
2506 rt->rt_gwroute, rt->rt_llinfo);