aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/route.h19
-rw-r--r--net/dccp/ipv4.c10
-rw-r--r--net/ipv4/tcp_ipv4.c6
3 files changed, 23 insertions, 12 deletions
diff --git a/include/net/route.h b/include/net/route.h
index bf790c1c6ac8..b3f89ad04e0b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -200,16 +200,19 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
200} 200}
201 201
202static inline int ip_route_newports(struct rtable **rp, u8 protocol, 202static inline int ip_route_newports(struct rtable **rp, u8 protocol,
203 __be16 orig_sport, __be16 orig_dport,
203 __be16 sport, __be16 dport, struct sock *sk) 204 __be16 sport, __be16 dport, struct sock *sk)
204{ 205{
205 if (sport != (*rp)->fl.fl_ip_sport || 206 if (sport != orig_sport || dport != orig_dport) {
206 dport != (*rp)->fl.fl_ip_dport) { 207 struct flowi fl = { .oif = (*rp)->fl.oif,
207 struct flowi fl; 208 .mark = (*rp)->fl.mark,
208 209 .fl4_dst = (*rp)->fl.fl4_dst,
209 memcpy(&fl, &(*rp)->fl, sizeof(fl)); 210 .fl4_src = (*rp)->fl.fl4_src,
210 fl.fl_ip_sport = sport; 211 .fl4_tos = (*rp)->fl.fl4_tos,
211 fl.fl_ip_dport = dport; 212 .proto = (*rp)->fl.proto,
212 fl.proto = protocol; 213 .fl_ip_sport = sport,
214 .fl_ip_dport = dport };
215
213 if (inet_sk(sk)->transparent) 216 if (inet_sk(sk)->transparent)
214 fl.flags |= FLOWI_FLAG_ANYSRC; 217 fl.flags |= FLOWI_FLAG_ANYSRC;
215 if (protocol == IPPROTO_TCP) 218 if (protocol == IPPROTO_TCP)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 45a434f94169..937989199c80 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -43,6 +43,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
43 struct inet_sock *inet = inet_sk(sk); 43 struct inet_sock *inet = inet_sk(sk);
44 struct dccp_sock *dp = dccp_sk(sk); 44 struct dccp_sock *dp = dccp_sk(sk);
45 const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; 45 const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
46 __be16 orig_sport, orig_dport;
46 struct rtable *rt; 47 struct rtable *rt;
47 __be32 daddr, nexthop; 48 __be32 daddr, nexthop;
48 int tmp; 49 int tmp;
@@ -63,10 +64,12 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
63 nexthop = inet->opt->faddr; 64 nexthop = inet->opt->faddr;
64 } 65 }
65 66
67 orig_sport = inet->inet_sport;
68 orig_dport = usin->sin_port;
66 tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, 69 tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
67 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, 70 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
68 IPPROTO_DCCP, 71 IPPROTO_DCCP,
69 inet->inet_sport, usin->sin_port, sk, 1); 72 orig_sport, orig_dport, sk, 1);
70 if (tmp < 0) 73 if (tmp < 0)
71 return tmp; 74 return tmp;
72 75
@@ -99,8 +102,9 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
99 if (err != 0) 102 if (err != 0)
100 goto failure; 103 goto failure;
101 104
102 err = ip_route_newports(&rt, IPPROTO_DCCP, inet->inet_sport, 105 err = ip_route_newports(&rt, IPPROTO_DCCP,
103 inet->inet_dport, sk); 106 orig_sport, orig_dport,
107 inet->inet_sport, inet->inet_dport, sk);
104 if (err != 0) 108 if (err != 0)
105 goto failure; 109 goto failure;
106 110
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ef5a90beb9b0..27a0cc8cc888 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -149,6 +149,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
149 struct inet_sock *inet = inet_sk(sk); 149 struct inet_sock *inet = inet_sk(sk);
150 struct tcp_sock *tp = tcp_sk(sk); 150 struct tcp_sock *tp = tcp_sk(sk);
151 struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; 151 struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
152 __be16 orig_sport, orig_dport;
152 struct rtable *rt; 153 struct rtable *rt;
153 __be32 daddr, nexthop; 154 __be32 daddr, nexthop;
154 int tmp; 155 int tmp;
@@ -167,10 +168,12 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
167 nexthop = inet->opt->faddr; 168 nexthop = inet->opt->faddr;
168 } 169 }
169 170
171 orig_sport = inet->inet_sport;
172 orig_dport = usin->sin_port;
170 tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, 173 tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
171 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, 174 RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
172 IPPROTO_TCP, 175 IPPROTO_TCP,
173 inet->inet_sport, usin->sin_port, sk, 1); 176 orig_sport, orig_dport, sk, 1);
174 if (tmp < 0) { 177 if (tmp < 0) {
175 if (tmp == -ENETUNREACH) 178 if (tmp == -ENETUNREACH)
176 IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 179 IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
@@ -234,6 +237,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
234 goto failure; 237 goto failure;
235 238
236 err = ip_route_newports(&rt, IPPROTO_TCP, 239 err = ip_route_newports(&rt, IPPROTO_TCP,
240 orig_sport, orig_dport,
237 inet->inet_sport, inet->inet_dport, sk); 241 inet->inet_sport, inet->inet_dport, sk);
238 if (err) 242 if (err)
239 goto failure; 243 goto failure;