aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c106
1 files changed, 56 insertions, 50 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c03d7e9688c8..4138630556e3 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -89,12 +89,11 @@ static struct socket *tcp_socket;
89void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, 89void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
90 struct sk_buff *skb); 90 struct sk_buff *skb);
91 91
92struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = { 92struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
93 .__tcp_lhash_lock = RW_LOCK_UNLOCKED, 93 .lhash_lock = RW_LOCK_UNLOCKED,
94 .__tcp_lhash_users = ATOMIC_INIT(0), 94 .lhash_users = ATOMIC_INIT(0),
95 .__tcp_lhash_wait 95 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
96 = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait), 96 .portalloc_lock = SPIN_LOCK_UNLOCKED,
97 .__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED
98}; 97};
99 98
100/* 99/*
@@ -105,14 +104,14 @@ struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
105int sysctl_local_port_range[2] = { 1024, 4999 }; 104int sysctl_local_port_range[2] = { 1024, 4999 };
106int tcp_port_rover = 1024 - 1; 105int tcp_port_rover = 1024 - 1;
107 106
108/* Allocate and initialize a new TCP local port bind bucket. 107/* Allocate and initialize a new local port bind bucket.
109 * The bindhash mutex for snum's hash chain must be held here. 108 * The bindhash mutex for snum's hash chain must be held here.
110 */ 109 */
111struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head, 110struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep,
112 unsigned short snum) 111 struct inet_bind_hashbucket *head,
112 const unsigned short snum)
113{ 113{
114 struct tcp_bind_bucket *tb = kmem_cache_alloc(tcp_bucket_cachep, 114 struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, SLAB_ATOMIC);
115 SLAB_ATOMIC);
116 if (tb) { 115 if (tb) {
117 tb->port = snum; 116 tb->port = snum;
118 tb->fastreuse = 0; 117 tb->fastreuse = 0;
@@ -123,20 +122,21 @@ struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
123} 122}
124 123
125/* Caller must hold hashbucket lock for this tb with local BH disabled */ 124/* Caller must hold hashbucket lock for this tb with local BH disabled */
126void tcp_bucket_destroy(struct tcp_bind_bucket *tb) 125void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb)
127{ 126{
128 if (hlist_empty(&tb->owners)) { 127 if (hlist_empty(&tb->owners)) {
129 __hlist_del(&tb->node); 128 __hlist_del(&tb->node);
130 kmem_cache_free(tcp_bucket_cachep, tb); 129 kmem_cache_free(cachep, tb);
131 } 130 }
132} 131}
133 132
134/* Caller must disable local BH processing. */ 133/* Caller must disable local BH processing. */
135static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child) 134static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
136{ 135{
137 struct tcp_bind_hashbucket *head = 136 struct inet_bind_hashbucket *head =
138 &tcp_bhash[tcp_bhashfn(inet_sk(child)->num)]; 137 &tcp_bhash[inet_bhashfn(inet_sk(child)->num,
139 struct tcp_bind_bucket *tb; 138 tcp_bhash_size)];
139 struct inet_bind_bucket *tb;
140 140
141 spin_lock(&head->lock); 141 spin_lock(&head->lock);
142 tb = tcp_sk(sk)->bind_hash; 142 tb = tcp_sk(sk)->bind_hash;
@@ -152,15 +152,15 @@ inline void tcp_inherit_port(struct sock *sk, struct sock *child)
152 local_bh_enable(); 152 local_bh_enable();
153} 153}
154 154
155void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, 155void tcp_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
156 unsigned short snum) 156 const unsigned short snum)
157{ 157{
158 inet_sk(sk)->num = snum; 158 inet_sk(sk)->num = snum;
159 sk_add_bind_node(sk, &tb->owners); 159 sk_add_bind_node(sk, &tb->owners);
160 tcp_sk(sk)->bind_hash = tb; 160 tcp_sk(sk)->bind_hash = tb;
161} 161}
162 162
163static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb) 163static inline int tcp_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb)
164{ 164{
165 const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); 165 const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk);
166 struct sock *sk2; 166 struct sock *sk2;
@@ -190,9 +190,9 @@ static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
190 */ 190 */
191static int tcp_v4_get_port(struct sock *sk, unsigned short snum) 191static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
192{ 192{
193 struct tcp_bind_hashbucket *head; 193 struct inet_bind_hashbucket *head;
194 struct hlist_node *node; 194 struct hlist_node *node;
195 struct tcp_bind_bucket *tb; 195 struct inet_bind_bucket *tb;
196 int ret; 196 int ret;
197 197
198 local_bh_disable(); 198 local_bh_disable();
@@ -211,9 +211,9 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
211 rover++; 211 rover++;
212 if (rover > high) 212 if (rover > high)
213 rover = low; 213 rover = low;
214 head = &tcp_bhash[tcp_bhashfn(rover)]; 214 head = &tcp_bhash[inet_bhashfn(rover, tcp_bhash_size)];
215 spin_lock(&head->lock); 215 spin_lock(&head->lock);
216 tb_for_each(tb, node, &head->chain) 216 inet_bind_bucket_for_each(tb, node, &head->chain)
217 if (tb->port == rover) 217 if (tb->port == rover)
218 goto next; 218 goto next;
219 break; 219 break;
@@ -238,9 +238,9 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
238 */ 238 */
239 snum = rover; 239 snum = rover;
240 } else { 240 } else {
241 head = &tcp_bhash[tcp_bhashfn(snum)]; 241 head = &tcp_bhash[inet_bhashfn(snum, tcp_bhash_size)];
242 spin_lock(&head->lock); 242 spin_lock(&head->lock);
243 tb_for_each(tb, node, &head->chain) 243 inet_bind_bucket_for_each(tb, node, &head->chain)
244 if (tb->port == snum) 244 if (tb->port == snum)
245 goto tb_found; 245 goto tb_found;
246 } 246 }
@@ -261,7 +261,7 @@ tb_found:
261 } 261 }
262tb_not_found: 262tb_not_found:
263 ret = 1; 263 ret = 1;
264 if (!tb && (tb = tcp_bucket_create(head, snum)) == NULL) 264 if (!tb && (tb = inet_bind_bucket_create(tcp_bucket_cachep, head, snum)) == NULL)
265 goto fail_unlock; 265 goto fail_unlock;
266 if (hlist_empty(&tb->owners)) { 266 if (hlist_empty(&tb->owners)) {
267 if (sk->sk_reuse && sk->sk_state != TCP_LISTEN) 267 if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
@@ -290,15 +290,16 @@ fail:
290static void __tcp_put_port(struct sock *sk) 290static void __tcp_put_port(struct sock *sk)
291{ 291{
292 struct inet_sock *inet = inet_sk(sk); 292 struct inet_sock *inet = inet_sk(sk);
293 struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(inet->num)]; 293 struct inet_bind_hashbucket *head = &tcp_bhash[inet_bhashfn(inet->num,
294 struct tcp_bind_bucket *tb; 294 tcp_bhash_size)];
295 struct inet_bind_bucket *tb;
295 296
296 spin_lock(&head->lock); 297 spin_lock(&head->lock);
297 tb = tcp_sk(sk)->bind_hash; 298 tb = tcp_sk(sk)->bind_hash;
298 __sk_del_bind_node(sk); 299 __sk_del_bind_node(sk);
299 tcp_sk(sk)->bind_hash = NULL; 300 tcp_sk(sk)->bind_hash = NULL;
300 inet->num = 0; 301 inet->num = 0;
301 tcp_bucket_destroy(tb); 302 inet_bind_bucket_destroy(tcp_bucket_cachep, tb);
302 spin_unlock(&head->lock); 303 spin_unlock(&head->lock);
303} 304}
304 305
@@ -344,7 +345,7 @@ static __inline__ void __tcp_v4_hash(struct sock *sk, const int listen_possible)
344 345
345 BUG_TRAP(sk_unhashed(sk)); 346 BUG_TRAP(sk_unhashed(sk));
346 if (listen_possible && sk->sk_state == TCP_LISTEN) { 347 if (listen_possible && sk->sk_state == TCP_LISTEN) {
347 list = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)]; 348 list = &tcp_listening_hash[inet_sk_listen_hashfn(sk)];
348 lock = &tcp_lhash_lock; 349 lock = &tcp_lhash_lock;
349 tcp_listen_wlock(); 350 tcp_listen_wlock();
350 } else { 351 } else {
@@ -381,7 +382,7 @@ void tcp_unhash(struct sock *sk)
381 tcp_listen_wlock(); 382 tcp_listen_wlock();
382 lock = &tcp_lhash_lock; 383 lock = &tcp_lhash_lock;
383 } else { 384 } else {
384 struct tcp_ehash_bucket *head = &tcp_ehash[sk->sk_hashent]; 385 struct inet_ehash_bucket *head = &tcp_ehash[sk->sk_hashent];
385 lock = &head->lock; 386 lock = &head->lock;
386 write_lock_bh(&head->lock); 387 write_lock_bh(&head->lock);
387 } 388 }
@@ -401,8 +402,10 @@ void tcp_unhash(struct sock *sk)
401 * connection. So always assume those are both wildcarded 402 * connection. So always assume those are both wildcarded
402 * during the search since they can never be otherwise. 403 * during the search since they can never be otherwise.
403 */ 404 */
404static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head, u32 daddr, 405static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head,
405 unsigned short hnum, int dif) 406 const u32 daddr,
407 const unsigned short hnum,
408 const int dif)
406{ 409{
407 struct sock *result = NULL, *sk; 410 struct sock *result = NULL, *sk;
408 struct hlist_node *node; 411 struct hlist_node *node;
@@ -438,14 +441,15 @@ static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head, u32 daddr,
438} 441}
439 442
440/* Optimize the common listener case. */ 443/* Optimize the common listener case. */
441static inline struct sock *tcp_v4_lookup_listener(u32 daddr, 444static inline struct sock *tcp_v4_lookup_listener(const u32 daddr,
442 unsigned short hnum, int dif) 445 const unsigned short hnum,
446 const int dif)
443{ 447{
444 struct sock *sk = NULL; 448 struct sock *sk = NULL;
445 struct hlist_head *head; 449 struct hlist_head *head;
446 450
447 read_lock(&tcp_lhash_lock); 451 read_lock(&tcp_lhash_lock);
448 head = &tcp_listening_hash[tcp_lhashfn(hnum)]; 452 head = &tcp_listening_hash[inet_lhashfn(hnum)];
449 if (!hlist_empty(head)) { 453 if (!hlist_empty(head)) {
450 struct inet_sock *inet = inet_sk((sk = __sk_head(head))); 454 struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
451 455
@@ -470,11 +474,13 @@ sherry_cache:
470 * Local BH must be disabled here. 474 * Local BH must be disabled here.
471 */ 475 */
472 476
473static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport, 477static inline struct sock *__tcp_v4_lookup_established(const u32 saddr,
474 u32 daddr, u16 hnum, 478 const u16 sport,
475 int dif) 479 const u32 daddr,
480 const u16 hnum,
481 const int dif)
476{ 482{
477 struct tcp_ehash_bucket *head; 483 struct inet_ehash_bucket *head;
478 TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) 484 TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
479 __u32 ports = TCP_COMBINED_PORTS(sport, hnum); 485 __u32 ports = TCP_COMBINED_PORTS(sport, hnum);
480 struct sock *sk; 486 struct sock *sk;
@@ -546,7 +552,7 @@ static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
546 TCP_V4_ADDR_COOKIE(acookie, saddr, daddr) 552 TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
547 __u32 ports = TCP_COMBINED_PORTS(inet->dport, lport); 553 __u32 ports = TCP_COMBINED_PORTS(inet->dport, lport);
548 const int hash = inet_ehashfn(daddr, lport, saddr, inet->dport, tcp_ehash_size); 554 const int hash = inet_ehashfn(daddr, lport, saddr, inet->dport, tcp_ehash_size);
549 struct tcp_ehash_bucket *head = &tcp_ehash[hash]; 555 struct inet_ehash_bucket *head = &tcp_ehash[hash];
550 struct sock *sk2; 556 struct sock *sk2;
551 struct hlist_node *node; 557 struct hlist_node *node;
552 struct tcp_tw_bucket *tw; 558 struct tcp_tw_bucket *tw;
@@ -639,9 +645,9 @@ static inline u32 connect_port_offset(const struct sock *sk)
639 */ 645 */
640static inline int tcp_v4_hash_connect(struct sock *sk) 646static inline int tcp_v4_hash_connect(struct sock *sk)
641{ 647{
642 unsigned short snum = inet_sk(sk)->num; 648 const unsigned short snum = inet_sk(sk)->num;
643 struct tcp_bind_hashbucket *head; 649 struct inet_bind_hashbucket *head;
644 struct tcp_bind_bucket *tb; 650 struct inet_bind_bucket *tb;
645 int ret; 651 int ret;
646 652
647 if (!snum) { 653 if (!snum) {
@@ -658,14 +664,14 @@ static inline int tcp_v4_hash_connect(struct sock *sk)
658 local_bh_disable(); 664 local_bh_disable();
659 for (i = 1; i <= range; i++) { 665 for (i = 1; i <= range; i++) {
660 port = low + (i + offset) % range; 666 port = low + (i + offset) % range;
661 head = &tcp_bhash[tcp_bhashfn(port)]; 667 head = &tcp_bhash[inet_bhashfn(port, tcp_bhash_size)];
662 spin_lock(&head->lock); 668 spin_lock(&head->lock);
663 669
664 /* Does not bother with rcv_saddr checks, 670 /* Does not bother with rcv_saddr checks,
665 * because the established check is already 671 * because the established check is already
666 * unique enough. 672 * unique enough.
667 */ 673 */
668 tb_for_each(tb, node, &head->chain) { 674 inet_bind_bucket_for_each(tb, node, &head->chain) {
669 if (tb->port == port) { 675 if (tb->port == port) {
670 BUG_TRAP(!hlist_empty(&tb->owners)); 676 BUG_TRAP(!hlist_empty(&tb->owners));
671 if (tb->fastreuse >= 0) 677 if (tb->fastreuse >= 0)
@@ -678,7 +684,7 @@ static inline int tcp_v4_hash_connect(struct sock *sk)
678 } 684 }
679 } 685 }
680 686
681 tb = tcp_bucket_create(head, port); 687 tb = inet_bind_bucket_create(tcp_bucket_cachep, head, port);
682 if (!tb) { 688 if (!tb) {
683 spin_unlock(&head->lock); 689 spin_unlock(&head->lock);
684 break; 690 break;
@@ -713,7 +719,7 @@ ok:
713 goto out; 719 goto out;
714 } 720 }
715 721
716 head = &tcp_bhash[tcp_bhashfn(snum)]; 722 head = &tcp_bhash[inet_bhashfn(snum, tcp_bhash_size)];
717 tb = tcp_sk(sk)->bind_hash; 723 tb = tcp_sk(sk)->bind_hash;
718 spin_lock_bh(&head->lock); 724 spin_lock_bh(&head->lock);
719 if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { 725 if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
@@ -2055,7 +2061,7 @@ start_req:
2055 } 2061 }
2056 read_unlock_bh(&tp->accept_queue.syn_wait_lock); 2062 read_unlock_bh(&tp->accept_queue.syn_wait_lock);
2057 } 2063 }
2058 if (++st->bucket < TCP_LHTABLE_SIZE) { 2064 if (++st->bucket < INET_LHTABLE_SIZE) {
2059 sk = sk_head(&tcp_listening_hash[st->bucket]); 2065 sk = sk_head(&tcp_listening_hash[st->bucket]);
2060 goto get_sk; 2066 goto get_sk;
2061 } 2067 }
@@ -2506,7 +2512,7 @@ void __init tcp_v4_init(struct net_proto_family *ops)
2506 2512
2507EXPORT_SYMBOL(ipv4_specific); 2513EXPORT_SYMBOL(ipv4_specific);
2508EXPORT_SYMBOL(tcp_bind_hash); 2514EXPORT_SYMBOL(tcp_bind_hash);
2509EXPORT_SYMBOL(tcp_bucket_create); 2515EXPORT_SYMBOL(inet_bind_bucket_create);
2510EXPORT_SYMBOL(tcp_hashinfo); 2516EXPORT_SYMBOL(tcp_hashinfo);
2511EXPORT_SYMBOL(tcp_inherit_port); 2517EXPORT_SYMBOL(tcp_inherit_port);
2512EXPORT_SYMBOL(tcp_listen_wlock); 2518EXPORT_SYMBOL(tcp_listen_wlock);