aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2014-04-29 19:14:42 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2014-04-29 19:14:42 +0000
commit0fb9298db94b5748098de2895abff4588dafb5a0 (patch)
tree834e65c0718c644286e009ce62e05bb92e67f636 /sys
parentd3f44b8d748cc63ca73a6510c9bc0df03a331e77 (diff)
downloadsrc-0fb9298db94b5748098de2895abff4588dafb5a0.tar.gz
src-0fb9298db94b5748098de2895abff4588dafb5a0.zip
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
Notes
Notes: svn path=/head/; revision=265103
Diffstat (limited to 'sys')
-rw-r--r--sys/net/route.c19
-rw-r--r--sys/net/route.h2
-rw-r--r--sys/net/rtsock.c20
3 files changed, 25 insertions, 16 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index ba86fec8d904..a9d256a80f8e 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -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 @@ bad:
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)
{
diff --git a/sys/net/route.h b/sys/net/route.h
index 913828a5ccce..d557af933baf 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -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;
};
/*
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index a40f067325b1..64d28ca9af1a 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -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);
@@ -920,20 +922,6 @@ flush:
}
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)
{