}
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;