aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e4c81652f17d..0ba6a382b2b4 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1859,25 +1859,28 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
1859 1859
1860static void rt_init_metrics(struct rtable *rt, struct fib_info *fi) 1860static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
1861{ 1861{
1862 if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) { 1862 struct inet_peer *peer;
1863 no_cow: 1863 int create = 0;
1864 if (fi->fib_metrics != (u32 *) dst_default_metrics) {
1865 rt->fi = fi;
1866 atomic_inc(&fi->fib_clntref);
1867 }
1868 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1869 } else {
1870 struct inet_peer *peer;
1871 1864
1872 if (!rt->peer) 1865 /* If a peer entry exists for this destination, we must hook
1873 rt_bind_peer(rt, 1); 1866 * it up in order to get at cached metrics.
1874 peer = rt->peer; 1867 */
1875 if (!peer) 1868 if (rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)
1876 goto no_cow; 1869 create = 1;
1870
1871 rt_bind_peer(rt, create);
1872 peer = rt->peer;
1873 if (peer) {
1877 if (inet_metrics_new(peer)) 1874 if (inet_metrics_new(peer))
1878 memcpy(peer->metrics, fi->fib_metrics, 1875 memcpy(peer->metrics, fi->fib_metrics,
1879 sizeof(u32) * RTAX_MAX); 1876 sizeof(u32) * RTAX_MAX);
1880 dst_init_metrics(&rt->dst, peer->metrics, false); 1877 dst_init_metrics(&rt->dst, peer->metrics, false);
1878 } else {
1879 if (fi->fib_metrics != (u32 *) dst_default_metrics) {
1880 rt->fi = fi;
1881 atomic_inc(&fi->fib_clntref);
1882 }
1883 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1881 } 1884 }
1882} 1885}
1883 1886