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>
This commit is contained in:
parent
bd4a6974cc
commit
0131ba451e
|
@ -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)
|
static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
|
||||||
{
|
{
|
||||||
if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) {
|
struct inet_peer *peer;
|
||||||
no_cow:
|
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) {
|
if (fi->fib_metrics != (u32 *) dst_default_metrics) {
|
||||||
rt->fi = fi;
|
rt->fi = fi;
|
||||||
atomic_inc(&fi->fib_clntref);
|
atomic_inc(&fi->fib_clntref);
|
||||||
}
|
}
|
||||||
dst_init_metrics(&rt->dst, fi->fib_metrics, true);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue