Move rt_setmetrics() from rtsock.c to route.c.

All rtsock-initiated rte creation/modification are now
performed in route.c holding radix tree write lock.
This reduces the need for per-rte mutex.

Sponsored by:	Yandex LLC
MFC after:	1 month
This commit is contained in:
Alexander V. Chernikov 2014-04-29 19:14:42 +00:00
parent d3f44b8d74
commit 0fb9298db9
3 changed files with 25 additions and 16 deletions

View File

@ -142,6 +142,7 @@ static VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */
static int rtrequest1_fib_change(struct radix_node_head *, struct rt_addrinfo *,
struct rtentry **, u_int);
static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *);
/*
* handler for net.my_fibnum
@ -1401,6 +1402,8 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
if (ifa->ifa_rtrequest)
ifa->ifa_rtrequest(req, rt, info);
rt_setmetrics(info, rt);
/*
* actually return a resultant rtentry and
* give the caller a single reference.
@ -1506,6 +1509,8 @@ rtrequest1_fib_change(struct radix_node_head *rnh, struct rt_addrinfo *info,
if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest != NULL)
rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info);
rt_setmetrics(info, rt);
if (ret_nrt) {
*ret_nrt = rt;
RT_ADDREF(rt);
@ -1517,6 +1522,20 @@ rtrequest1_fib_change(struct radix_node_head *rnh, struct rt_addrinfo *info,
return (error);
}
static void
rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt)
{
if (info->rti_mflags & RTV_MTU)
rt->rt_mtu = info->rti_rmx->rmx_mtu;
if (info->rti_mflags & RTV_WEIGHT)
rt->rt_weight = info->rti_rmx->rmx_weight;
/* Kernel -> userland timebase conversion. */
if (info->rti_mflags & RTV_EXPIRE)
rt->rt_expire = info->rti_rmx->rmx_expire ?
info->rti_rmx->rmx_expire - time_second + time_uptime : 0;
}
int
rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
{

View File

@ -261,6 +261,8 @@ struct rt_addrinfo {
int rti_flags;
struct ifaddr *rti_ifa;
struct ifnet *rti_ifp;
u_long rti_mflags;
struct rt_metrics *rti_rmx;
};
/*

View File

@ -160,7 +160,6 @@ static int sysctl_dumpentry(struct radix_node *rn, void *vw);
static int sysctl_iflist(int af, struct walkarg *w);
static int sysctl_ifmalist(int af, struct walkarg *w);
static int route_output(struct mbuf *m, struct socket *so);
static void rt_setmetrics(const struct rt_msghdr *rtm, struct rtentry *rt);
static void rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out);
static void rt_dispatch(struct mbuf *, sa_family_t);
@ -584,6 +583,10 @@ route_output(struct mbuf *m, struct socket *so)
rtm->rtm_pid = curproc->p_pid;
info.rti_addrs = rtm->rtm_addrs;
info.rti_mflags = rtm->rtm_inits;
info.rti_rmx = &rtm->rtm_rmx;
/*
* rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6
* link-local address because rtrequest requires addresses with
@ -670,7 +673,6 @@ route_output(struct mbuf *m, struct socket *so)
rti_need_deembed = (V_deembed_scopeid) ? 1 : 0;
#endif
RT_LOCK(saved_nrt);
rt_setmetrics(rtm, saved_nrt);
rtm->rtm_index = saved_nrt->rt_ifp->if_index;
RT_REMREF(saved_nrt);
RT_UNLOCK(saved_nrt);
@ -919,20 +921,6 @@ route_output(struct mbuf *m, struct socket *so)
return (error);
}
static void
rt_setmetrics(const struct rt_msghdr *rtm, struct rtentry *rt)
{
if (rtm->rtm_inits & RTV_MTU)
rt->rt_mtu = rtm->rtm_rmx.rmx_mtu;
if (rtm->rtm_inits & RTV_WEIGHT)
rt->rt_weight = rtm->rtm_rmx.rmx_weight;
/* Kernel -> userland timebase conversion. */
if (rtm->rtm_inits & RTV_EXPIRE)
rt->rt_expire = rtm->rtm_rmx.rmx_expire ?
rtm->rtm_rmx.rmx_expire - time_second + time_uptime : 0;
}
static void
rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out)
{