diff options
author | David S. Miller <davem@davemloft.net> | 2011-04-26 16:28:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-27 16:59:04 -0400 |
commit | 2d7192d6cbab20e153c47fa1559ffd41ceef0e79 (patch) | |
tree | aac4c4132f5b4a173ad8f8d0bf24427e039bbc89 /net/ipv4/tcp_ipv4.c | |
parent | 15ecd039b7182d725f4294e01f2fb12c3a88db17 (diff) |
ipv4: Sanitize and simplify ip_route_{connect,newports}()
These functions are used together as a unit for route resolution
during connect(). They address the chicken-and-egg problem that
exists when ports need to be allocated during connect() processing,
yet such port allocations require addressing information from the
routing code.
It's currently more heavy handed than it needs to be, and in
particular we allocate and initialize a flow object twice.
Let the callers provide the on-stack flow object. That way we only
need to initialize it once in the ip_route_connect() call.
Later, if ip_route_newports() needs to do anything, it re-uses that
flow object as-is except for the ports which it updates before the
route re-lookup.
Also, describe why this set of facilities are needed and how it works
in a big comment.
Signed-off-by: David S. Miller <davem@davemloft.net>
Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index edf18bd74b87..310454c2f4d1 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -146,12 +146,13 @@ EXPORT_SYMBOL_GPL(tcp_twsk_unique); | |||
146 | /* This will initiate an outgoing connection. */ | 146 | /* This will initiate an outgoing connection. */ |
147 | int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 147 | int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
148 | { | 148 | { |
149 | struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; | ||
149 | struct inet_sock *inet = inet_sk(sk); | 150 | struct inet_sock *inet = inet_sk(sk); |
150 | struct tcp_sock *tp = tcp_sk(sk); | 151 | struct tcp_sock *tp = tcp_sk(sk); |
151 | struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; | ||
152 | __be16 orig_sport, orig_dport; | 152 | __be16 orig_sport, orig_dport; |
153 | struct rtable *rt; | ||
154 | __be32 daddr, nexthop; | 153 | __be32 daddr, nexthop; |
154 | struct flowi4 fl4; | ||
155 | struct rtable *rt; | ||
155 | int err; | 156 | int err; |
156 | 157 | ||
157 | if (addr_len < sizeof(struct sockaddr_in)) | 158 | if (addr_len < sizeof(struct sockaddr_in)) |
@@ -169,7 +170,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
169 | 170 | ||
170 | orig_sport = inet->inet_sport; | 171 | orig_sport = inet->inet_sport; |
171 | orig_dport = usin->sin_port; | 172 | orig_dport = usin->sin_port; |
172 | rt = ip_route_connect(nexthop, inet->inet_saddr, | 173 | rt = ip_route_connect(&fl4, nexthop, inet->inet_saddr, |
173 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, | 174 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, |
174 | IPPROTO_TCP, | 175 | IPPROTO_TCP, |
175 | orig_sport, orig_dport, sk, true); | 176 | orig_sport, orig_dport, sk, true); |
@@ -236,8 +237,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
236 | if (err) | 237 | if (err) |
237 | goto failure; | 238 | goto failure; |
238 | 239 | ||
239 | rt = ip_route_newports(rt, IPPROTO_TCP, | 240 | rt = ip_route_newports(&fl4, rt, orig_sport, orig_dport, |
240 | orig_sport, orig_dport, | ||
241 | inet->inet_sport, inet->inet_dport, sk); | 241 | inet->inet_sport, inet->inet_dport, sk); |
242 | if (IS_ERR(rt)) { | 242 | if (IS_ERR(rt)) { |
243 | err = PTR_ERR(rt); | 243 | err = PTR_ERR(rt); |