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) static void rt_init_metrics(struct rtable *rt, struct fib_info *fi) { - if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) { - no_cow: + struct inet_peer *peer; + int create = 0; + + /* If a peer entry exists for this destination, we must hook + * it up in order to get at cached metrics. + */ + if (rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS) + create = 1; + + rt_bind_peer(rt, create); + peer = rt->peer; + if (peer) { + if (inet_metrics_new(peer)) + memcpy(peer->metrics, fi->fib_metrics, + sizeof(u32) * RTAX_MAX); + dst_init_metrics(&rt->dst, peer->metrics, false); + } else { if (fi->fib_metrics != (u32 *) dst_default_metrics) { rt->fi = fi; atomic_inc(&fi->fib_clntref); } dst_init_metrics(&rt->dst, fi->fib_metrics, true); - } else { - struct inet_peer *peer; - - if (!rt->peer) - rt_bind_peer(rt, 1); - peer = rt->peer; - if (!peer) - goto no_cow; - if (inet_metrics_new(peer)) - memcpy(peer->metrics, fi->fib_metrics, - sizeof(u32) * RTAX_MAX); - dst_init_metrics(&rt->dst, peer->metrics, false); } }