aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/route.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 68cee358d9a3..dd57f4896736 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1857,6 +1857,28 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
1857 return mtu; 1857 return mtu;
1858} 1858}
1859 1859
1860static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
1861{
1862 if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) {
1863 no_cow:
1864 rt->fi = fi;
1865 atomic_inc(&fi->fib_clntref);
1866 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1867 } else {
1868 struct inet_peer *peer;
1869
1870 if (!rt->peer)
1871 rt_bind_peer(rt, 1);
1872 peer = rt->peer;
1873 if (!peer)
1874 goto no_cow;
1875 if (inet_metrics_new(peer))
1876 memcpy(peer->metrics, fi->fib_metrics,
1877 sizeof(u32) * RTAX_MAX);
1878 dst_init_metrics(&rt->dst, peer->metrics, false);
1879 }
1880}
1881
1860static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) 1882static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
1861{ 1883{
1862 struct dst_entry *dst = &rt->dst; 1884 struct dst_entry *dst = &rt->dst;
@@ -1866,9 +1888,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
1866 if (FIB_RES_GW(*res) && 1888 if (FIB_RES_GW(*res) &&
1867 FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 1889 FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
1868 rt->rt_gateway = FIB_RES_GW(*res); 1890 rt->rt_gateway = FIB_RES_GW(*res);
1869 rt->fi = fi; 1891 rt_init_metrics(rt, fi);
1870 atomic_inc(&fi->fib_clntref);
1871 dst_init_metrics(dst, fi->fib_metrics, true);
1872#ifdef CONFIG_IP_ROUTE_CLASSID 1892#ifdef CONFIG_IP_ROUTE_CLASSID
1873 dst->tclassid = FIB_RES_NH(*res).nh_tclassid; 1893 dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
1874#endif 1894#endif