static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
 {
-       return inet_sk(sk)->transparent ? FLOWI_FLAG_ANYSRC : 0;
+       __u8 flags = 0;
+
+       if (inet_sk(sk)->transparent)
+               flags |= FLOWI_FLAG_ANYSRC;
+       if (sk->sk_protocol == IPPROTO_TCP)
+               flags |= FLOWI_FLAG_PRECOW_METRICS;
+       return flags;
 }
 
 #endif /* _INET_SOCK_H */
 
 
        if (inet_sk(sk)->transparent)
                fl.flags |= FLOWI_FLAG_ANYSRC;
+       if (protocol == IPPROTO_TCP)
+               fl.flags |= FLOWI_FLAG_PRECOW_METRICS;
 
        if (!dst || !src) {
                err = __ip_route_output_key(net, rp, &fl);
                fl.proto = protocol;
                if (inet_sk(sk)->transparent)
                        fl.flags |= FLOWI_FLAG_ANYSRC;
+               if (protocol == IPPROTO_TCP)
+                       fl.flags |= FLOWI_FLAG_PRECOW_METRICS;
                ip_rt_put(*rp);
                *rp = NULL;
                security_sk_classify_flow(sk, &fl);
 
        return mtu;
 }
 
+static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
+{
+       if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) {
+       no_cow:
+               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);
+       }
+}
+
 static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
 {
        struct dst_entry *dst = &rt->dst;
                if (FIB_RES_GW(*res) &&
                    FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
                        rt->rt_gateway = FIB_RES_GW(*res);
-               rt->fi = fi;
-               atomic_inc(&fi->fib_clntref);
-               dst_init_metrics(dst, fi->fib_metrics, true);
+               rt_init_metrics(rt, fi);
 #ifdef CONFIG_IP_ROUTE_CLASSID
                dst->tclassid = FIB_RES_NH(*res).nh_tclassid;
 #endif