}
 
 static inline int ip_route_newports(struct rtable **rp, u8 protocol,
+                                   __be16 orig_sport, __be16 orig_dport,
                                    __be16 sport, __be16 dport, struct sock *sk)
 {
-       if (sport != (*rp)->fl.fl_ip_sport ||
-           dport != (*rp)->fl.fl_ip_dport) {
-               struct flowi fl;
-
-               memcpy(&fl, &(*rp)->fl, sizeof(fl));
-               fl.fl_ip_sport = sport;
-               fl.fl_ip_dport = dport;
-               fl.proto = protocol;
+       if (sport != orig_sport || dport != orig_dport) {
+               struct flowi fl = { .oif = (*rp)->fl.oif,
+                                   .mark = (*rp)->fl.mark,
+                                   .fl4_dst = (*rp)->fl.fl4_dst,
+                                   .fl4_src = (*rp)->fl.fl4_src,
+                                   .fl4_tos = (*rp)->fl.fl4_tos,
+                                   .proto = (*rp)->fl.proto,
+                                   .fl_ip_sport = sport,
+                                   .fl_ip_dport = dport };
+
                if (inet_sk(sk)->transparent)
                        fl.flags |= FLOWI_FLAG_ANYSRC;
                if (protocol == IPPROTO_TCP)
 
        struct inet_sock *inet = inet_sk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
        const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
+       __be16 orig_sport, orig_dport;
        struct rtable *rt;
        __be32 daddr, nexthop;
        int tmp;
                nexthop = inet->opt->faddr;
        }
 
+       orig_sport = inet->inet_sport;
+       orig_dport = usin->sin_port;
        tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
                               RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
                               IPPROTO_DCCP,
-                              inet->inet_sport, usin->sin_port, sk, 1);
+                              orig_sport, orig_dport, sk, 1);
        if (tmp < 0)
                return tmp;
 
        if (err != 0)
                goto failure;
 
-       err = ip_route_newports(&rt, IPPROTO_DCCP, inet->inet_sport,
-                               inet->inet_dport, sk);
+       err = ip_route_newports(&rt, IPPROTO_DCCP,
+                               orig_sport, orig_dport,
+                               inet->inet_sport, inet->inet_dport, sk);
        if (err != 0)
                goto failure;
 
 
        struct inet_sock *inet = inet_sk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
+       __be16 orig_sport, orig_dport;
        struct rtable *rt;
        __be32 daddr, nexthop;
        int tmp;
                nexthop = inet->opt->faddr;
        }
 
+       orig_sport = inet->inet_sport;
+       orig_dport = usin->sin_port;
        tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
                               RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
                               IPPROTO_TCP,
-                              inet->inet_sport, usin->sin_port, sk, 1);
+                              orig_sport, orig_dport, sk, 1);
        if (tmp < 0) {
                if (tmp == -ENETUNREACH)
                        IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
                goto failure;
 
        err = ip_route_newports(&rt, IPPROTO_TCP,
+                               orig_sport, orig_dport,
                                inet->inet_sport, inet->inet_dport, sk);
        if (err)
                goto failure;