aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-02-04 17:37:30 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-04 17:37:30 -0500
commit0131ba451e20239c5dc701027c1a2edef95e1a6e (patch)
tree880906b7030daf840fc1e903de4381cb70cf473c /net/ipv4/route.c
parentbd4a6974cc9090ef3851e5b0a2071e5383565c7c (diff)
ipv4: Don't miss existing cached metrics in new routes.
Always lookup to see if we have an existing inetpeer entry for a route. Let FLOWI_FLAG_PRECOW_METRICS merely influence the "create" argument to rt_bind_peer(). Also, call rt_bind_peer() unconditionally since it is not possible for rt->peer to be non-NULL at this point. Signed-off-by: David S. Miller <davem@davemloft.net>
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