Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/route.c
Show First 20 Lines • Show All 420 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Remove a reference count from an rtentry. | * Remove a reference count from an rtentry. | ||||
* If the count gets low enough, take it out of the routing table | * If the count gets low enough, take it out of the routing table | ||||
*/ | */ | ||||
void | void | ||||
rtfree(struct rtentry *rt) | rtfree(struct rtentry *rt) | ||||
{ | { | ||||
struct rib_head *rnh; | |||||
KASSERT(rt != NULL,("%s: NULL rt", __func__)); | KASSERT(rt != NULL,("%s: NULL rt", __func__)); | ||||
rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family); | |||||
KASSERT(rnh != NULL,("%s: NULL rnh", __func__)); | |||||
RT_LOCK_ASSERT(rt); | RT_LOCK_ASSERT(rt); | ||||
/* | /* | ||||
* The callers should use RTFREE_LOCKED() or RTFREE(), so | * The callers should use RTFREE_LOCKED() or RTFREE(), so | ||||
* we should come here exactly with the last reference. | * we should come here exactly with the last reference. | ||||
*/ | */ | ||||
RT_REMREF(rt); | RT_REMREF(rt); | ||||
if (rt->rt_refcnt > 0) { | if (rt->rt_refcnt > 0) { | ||||
log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt); | log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt); | ||||
goto done; | goto done; | ||||
} | } | ||||
/* | /* | ||||
* On last reference give the "close method" a chance | |||||
* to cleanup private state. This also permits (for | |||||
* IPv4 and IPv6) a chance to decide if the routing table | |||||
* entry should be purged immediately or at a later time. | |||||
* When an immediate purge is to happen the close routine | |||||
* typically calls rtexpunge which clears the RTF_UP flag | |||||
* on the entry so that the code below reclaims the storage. | |||||
*/ | |||||
if (rt->rt_refcnt == 0 && rnh->rnh_close) | |||||
rnh->rnh_close((struct radix_node *)rt, &rnh->head); | |||||
/* | |||||
* If we are no longer "up" (and ref == 0) | * If we are no longer "up" (and ref == 0) | ||||
* then we can free the resources associated | * then we can free the resources associated | ||||
* with the route. | * with the route. | ||||
*/ | */ | ||||
if ((rt->rt_flags & RTF_UP) == 0) { | if ((rt->rt_flags & RTF_UP) == 0) { | ||||
if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) | if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT)) | ||||
panic("rtfree 2"); | panic("rtfree 2"); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,028 Lines • ▼ Show 20 Lines | add_route(struct rib_head *rnh, struct rt_addrinfo *info, | ||||
rt = uma_zalloc(V_rtzone, M_NOWAIT); | rt = uma_zalloc(V_rtzone, M_NOWAIT); | ||||
if (rt == NULL) { | if (rt == NULL) { | ||||
ifa_free(info->rti_ifa); | ifa_free(info->rti_ifa); | ||||
nhop_free(nh); | nhop_free(nh); | ||||
return (ENOBUFS); | return (ENOBUFS); | ||||
} | } | ||||
rt->rt_flags = RTF_UP | flags; | rt->rt_flags = RTF_UP | flags; | ||||
rt->rt_fibnum = rnh->rib_fibnum; | |||||
rt->rt_nhop = nh; | rt->rt_nhop = nh; | ||||
/* Fill in dst */ | /* Fill in dst */ | ||||
memcpy(&rt->rt_dst, dst, dst->sa_len); | memcpy(&rt->rt_dst, dst, dst->sa_len); | ||||
rt_key(rt) = &rt->rt_dst; | rt_key(rt) = &rt->rt_dst; | ||||
/* | /* | ||||
* point to the (possibly newly malloc'd) dest address. | * point to the (possibly newly malloc'd) dest address. | ||||
▲ Show 20 Lines • Show All 631 Lines • Show Last 20 Lines |