aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:07:13 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:40:29 -0400
commit2d8c4ce51903636ce0f60addc8134aa50ab8fa76 (patch)
tree1ea4d4faf831b832489b30b13d8910777020feed /net/ipv4/tcp_ipv4.c
parentff21d5774b4a186c98be6398eacde75d896db804 (diff)
[INET]: Generalise tcp_bind_hash & tcp_inherit_port
This required moving tcp_bucket_cachep to inet_hashinfo. 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.c68
1 files changed, 4 insertions, 64 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 10a9b3ae3442..40fe4f5fca1c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -104,37 +104,6 @@ struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
104int sysctl_local_port_range[2] = { 1024, 4999 }; 104int sysctl_local_port_range[2] = { 1024, 4999 };
105int tcp_port_rover = 1024 - 1; 105int tcp_port_rover = 1024 - 1;
106 106
107/* Caller must disable local BH processing. */
108static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
109{
110 struct inet_bind_hashbucket *head =
111 &tcp_bhash[inet_bhashfn(inet_sk(child)->num,
112 tcp_bhash_size)];
113 struct inet_bind_bucket *tb;
114
115 spin_lock(&head->lock);
116 tb = inet_sk(sk)->bind_hash;
117 sk_add_bind_node(child, &tb->owners);
118 inet_sk(child)->bind_hash = tb;
119 spin_unlock(&head->lock);
120}
121
122inline void tcp_inherit_port(struct sock *sk, struct sock *child)
123{
124 local_bh_disable();
125 __tcp_inherit_port(sk, child);
126 local_bh_enable();
127}
128
129void tcp_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
130 const unsigned short snum)
131{
132 struct inet_sock *inet = inet_sk(sk);
133 inet->num = snum;
134 sk_add_bind_node(sk, &tb->owners);
135 inet->bind_hash = tb;
136}
137
138static inline int tcp_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb) 107static inline int tcp_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb)
139{ 108{
140 const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); 109 const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk);
@@ -248,7 +217,7 @@ tb_not_found:
248 tb->fastreuse = 0; 217 tb->fastreuse = 0;
249success: 218success:
250 if (!inet_sk(sk)->bind_hash) 219 if (!inet_sk(sk)->bind_hash)
251 tcp_bind_hash(sk, tb, snum); 220 inet_bind_hash(sk, tb, snum);
252 BUG_TRAP(inet_sk(sk)->bind_hash == tb); 221 BUG_TRAP(inet_sk(sk)->bind_hash == tb);
253 ret = 0; 222 ret = 0;
254 223
@@ -259,32 +228,6 @@ fail:
259 return ret; 228 return ret;
260} 229}
261 230
262/* Get rid of any references to a local port held by the
263 * given sock.
264 */
265static void __tcp_put_port(struct sock *sk)
266{
267 struct inet_sock *inet = inet_sk(sk);
268 struct inet_bind_hashbucket *head = &tcp_bhash[inet_bhashfn(inet->num,
269 tcp_bhash_size)];
270 struct inet_bind_bucket *tb;
271
272 spin_lock(&head->lock);
273 tb = inet->bind_hash;
274 __sk_del_bind_node(sk);
275 inet->bind_hash = NULL;
276 inet->num = 0;
277 inet_bind_bucket_destroy(tcp_bucket_cachep, tb);
278 spin_unlock(&head->lock);
279}
280
281void tcp_put_port(struct sock *sk)
282{
283 local_bh_disable();
284 __tcp_put_port(sk);
285 local_bh_enable();
286}
287
288/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP. 231/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP.
289 * Look, when several writers sleep and reader wakes them up, all but one 232 * Look, when several writers sleep and reader wakes them up, all but one
290 * immediately hit write lock and grab all the cpus. Exclusive sleep solves 233 * immediately hit write lock and grab all the cpus. Exclusive sleep solves
@@ -678,7 +621,7 @@ ok:
678 hint += i; 621 hint += i;
679 622
680 /* Head lock still held and bh's disabled */ 623 /* Head lock still held and bh's disabled */
681 tcp_bind_hash(sk, tb, port); 624 inet_bind_hash(sk, tb, port);
682 if (sk_unhashed(sk)) { 625 if (sk_unhashed(sk)) {
683 inet_sk(sk)->sport = htons(port); 626 inet_sk(sk)->sport = htons(port);
684 __tcp_v4_hash(sk, 0); 627 __tcp_v4_hash(sk, 0);
@@ -1537,7 +1480,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1537 tcp_initialize_rcv_mss(newsk); 1480 tcp_initialize_rcv_mss(newsk);
1538 1481
1539 __tcp_v4_hash(newsk, 0); 1482 __tcp_v4_hash(newsk, 0);
1540 __tcp_inherit_port(sk, newsk); 1483 __inet_inherit_port(&tcp_hashinfo, sk, newsk);
1541 1484
1542 return newsk; 1485 return newsk;
1543 1486
@@ -1942,7 +1885,7 @@ int tcp_v4_destroy_sock(struct sock *sk)
1942 1885
1943 /* Clean up a referenced TCP bind bucket. */ 1886 /* Clean up a referenced TCP bind bucket. */
1944 if (inet_sk(sk)->bind_hash) 1887 if (inet_sk(sk)->bind_hash)
1945 tcp_put_port(sk); 1888 inet_put_port(&tcp_hashinfo, sk);
1946 1889
1947 /* 1890 /*
1948 * If sendmsg cached page exists, toss it. 1891 * If sendmsg cached page exists, toss it.
@@ -2486,14 +2429,11 @@ void __init tcp_v4_init(struct net_proto_family *ops)
2486} 2429}
2487 2430
2488EXPORT_SYMBOL(ipv4_specific); 2431EXPORT_SYMBOL(ipv4_specific);
2489EXPORT_SYMBOL(tcp_bind_hash);
2490EXPORT_SYMBOL(inet_bind_bucket_create); 2432EXPORT_SYMBOL(inet_bind_bucket_create);
2491EXPORT_SYMBOL(tcp_hashinfo); 2433EXPORT_SYMBOL(tcp_hashinfo);
2492EXPORT_SYMBOL(tcp_inherit_port);
2493EXPORT_SYMBOL(tcp_listen_wlock); 2434EXPORT_SYMBOL(tcp_listen_wlock);
2494EXPORT_SYMBOL(tcp_port_rover); 2435EXPORT_SYMBOL(tcp_port_rover);
2495EXPORT_SYMBOL(tcp_prot); 2436EXPORT_SYMBOL(tcp_prot);
2496EXPORT_SYMBOL(tcp_put_port);
2497EXPORT_SYMBOL(tcp_unhash); 2437EXPORT_SYMBOL(tcp_unhash);
2498EXPORT_SYMBOL(tcp_v4_conn_request); 2438EXPORT_SYMBOL(tcp_v4_conn_request);
2499EXPORT_SYMBOL(tcp_v4_connect); 2439EXPORT_SYMBOL(tcp_v4_connect);