aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:09:46 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:42:18 -0400
commite48c414ee61f4ac8d5cff2973e66a7cbc8a93aa5 (patch)
treec4656efe48b75adf5742514c3e4286007f20bdca /net/ipv4/tcp_ipv4.c
parent8feaf0c0a5488b3d898a9c207eb6678f44ba3f26 (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.c83
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
247static 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;
275out:
276 read_unlock(&head->lock);
277 return sk;
278hit:
279 sock_hold(sk);
280 goto out;
281}
282
283static 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
292inline 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
304EXPORT_SYMBOL_GPL(tcp_v4_lookup);
305
306static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) 241static 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;