diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:09:46 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:42:18 -0400 |
commit | e48c414ee61f4ac8d5cff2973e66a7cbc8a93aa5 (patch) | |
tree | c4656efe48b75adf5742514c3e4286007f20bdca /net/ipv4/tcp_ipv4.c | |
parent | 8feaf0c0a5488b3d898a9c207eb6678f44ba3f26 (diff) |
[INET]: Generalise the TCP sock ID lookup routines
And also some TIME_WAIT functions.
[acme@toy net-2.6.14]$ grep built-in /tmp/before.size /tmp/after.size
/tmp/before.size: 282955 13122 9312 305389 4a8ed net/ipv4/built-in.o
/tmp/after.size: 281566 13122 9312 304000 4a380 net/ipv4/built-in.o
[acme@toy net-2.6.14]$
I kept them still inlined, will uninline at some point to see what
would be the performance difference.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 83 |
1 files changed, 8 insertions, 75 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ce423e48ebe0..e7e91e60ac74 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -238,71 +238,6 @@ void tcp_unhash(struct sock *sk) | |||
238 | inet_unhash(&tcp_hashinfo, sk); | 238 | inet_unhash(&tcp_hashinfo, sk); |
239 | } | 239 | } |
240 | 240 | ||
241 | /* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so | ||
242 | * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM | ||
243 | * | ||
244 | * Local BH must be disabled here. | ||
245 | */ | ||
246 | |||
247 | static inline struct sock *__tcp_v4_lookup_established(const u32 saddr, | ||
248 | const u16 sport, | ||
249 | const u32 daddr, | ||
250 | const u16 hnum, | ||
251 | const int dif) | ||
252 | { | ||
253 | struct inet_ehash_bucket *head; | ||
254 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
255 | const __u32 ports = INET_COMBINED_PORTS(sport, hnum); | ||
256 | struct sock *sk; | ||
257 | const struct hlist_node *node; | ||
258 | /* Optimize here for direct hit, only listening connections can | ||
259 | * have wildcards anyways. | ||
260 | */ | ||
261 | const int hash = inet_ehashfn(daddr, hnum, saddr, sport, tcp_hashinfo.ehash_size); | ||
262 | head = &tcp_hashinfo.ehash[hash]; | ||
263 | read_lock(&head->lock); | ||
264 | sk_for_each(sk, node, &head->chain) { | ||
265 | if (INET_MATCH(sk, acookie, saddr, daddr, ports, dif)) | ||
266 | goto hit; /* You sunk my battleship! */ | ||
267 | } | ||
268 | |||
269 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
270 | sk_for_each(sk, node, &(head + tcp_hashinfo.ehash_size)->chain) { | ||
271 | if (INET_TW_MATCH(sk, acookie, saddr, daddr, ports, dif)) | ||
272 | goto hit; | ||
273 | } | ||
274 | sk = NULL; | ||
275 | out: | ||
276 | read_unlock(&head->lock); | ||
277 | return sk; | ||
278 | hit: | ||
279 | sock_hold(sk); | ||
280 | goto out; | ||
281 | } | ||
282 | |||
283 | static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport, | ||
284 | u32 daddr, u16 hnum, int dif) | ||
285 | { | ||
286 | struct sock *sk = __tcp_v4_lookup_established(saddr, sport, | ||
287 | daddr, hnum, dif); | ||
288 | |||
289 | return sk ? : inet_lookup_listener(&tcp_hashinfo, daddr, hnum, dif); | ||
290 | } | ||
291 | |||
292 | inline struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, | ||
293 | u16 dport, int dif) | ||
294 | { | ||
295 | struct sock *sk; | ||
296 | |||
297 | local_bh_disable(); | ||
298 | sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif); | ||
299 | local_bh_enable(); | ||
300 | |||
301 | return sk; | ||
302 | } | ||
303 | |||
304 | EXPORT_SYMBOL_GPL(tcp_v4_lookup); | ||
305 | |||
306 | static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) | 241 | static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) |
307 | { | 242 | { |
308 | return secure_tcp_sequence_number(skb->nh.iph->daddr, | 243 | return secure_tcp_sequence_number(skb->nh.iph->daddr, |
@@ -751,8 +686,8 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) | |||
751 | return; | 686 | return; |
752 | } | 687 | } |
753 | 688 | ||
754 | sk = tcp_v4_lookup(iph->daddr, th->dest, iph->saddr, | 689 | sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr, |
755 | th->source, tcp_v4_iif(skb)); | 690 | th->source, tcp_v4_iif(skb)); |
756 | if (!sk) { | 691 | if (!sk) { |
757 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 692 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
758 | return; | 693 | return; |
@@ -1359,11 +1294,9 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
1359 | if (req) | 1294 | if (req) |
1360 | return tcp_check_req(sk, skb, req, prev); | 1295 | return tcp_check_req(sk, skb, req, prev); |
1361 | 1296 | ||
1362 | nsk = __tcp_v4_lookup_established(skb->nh.iph->saddr, | 1297 | nsk = __inet_lookup_established(&tcp_hashinfo, skb->nh.iph->saddr, |
1363 | th->source, | 1298 | th->source, skb->nh.iph->daddr, |
1364 | skb->nh.iph->daddr, | 1299 | ntohs(th->dest), tcp_v4_iif(skb)); |
1365 | ntohs(th->dest), | ||
1366 | tcp_v4_iif(skb)); | ||
1367 | 1300 | ||
1368 | if (nsk) { | 1301 | if (nsk) { |
1369 | if (nsk->sk_state != TCP_TIME_WAIT) { | 1302 | if (nsk->sk_state != TCP_TIME_WAIT) { |
@@ -1505,9 +1438,9 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1505 | TCP_SKB_CB(skb)->flags = skb->nh.iph->tos; | 1438 | TCP_SKB_CB(skb)->flags = skb->nh.iph->tos; |
1506 | TCP_SKB_CB(skb)->sacked = 0; | 1439 | TCP_SKB_CB(skb)->sacked = 0; |
1507 | 1440 | ||
1508 | sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source, | 1441 | sk = __inet_lookup(&tcp_hashinfo, skb->nh.iph->saddr, th->source, |
1509 | skb->nh.iph->daddr, ntohs(th->dest), | 1442 | skb->nh.iph->daddr, ntohs(th->dest), |
1510 | tcp_v4_iif(skb)); | 1443 | tcp_v4_iif(skb)); |
1511 | 1444 | ||
1512 | if (!sk) | 1445 | if (!sk) |
1513 | goto no_tcp_socket; | 1446 | goto no_tcp_socket; |