diff options
Diffstat (limited to 'net/ipv4/inet_hashtables.c')
-rw-r--r-- | net/ipv4/inet_hashtables.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 67704da04fc4..8dfd5a691e5f 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -267,6 +267,48 @@ static inline u32 inet_sk_port_offset(const struct sock *sk) | |||
267 | inet->dport); | 267 | inet->dport); |
268 | } | 268 | } |
269 | 269 | ||
270 | void __inet_hash_nolisten(struct inet_hashinfo *hashinfo, struct sock *sk) | ||
271 | { | ||
272 | struct hlist_head *list; | ||
273 | rwlock_t *lock; | ||
274 | struct inet_ehash_bucket *head; | ||
275 | |||
276 | BUG_TRAP(sk_unhashed(sk)); | ||
277 | |||
278 | sk->sk_hash = inet_sk_ehashfn(sk); | ||
279 | head = inet_ehash_bucket(hashinfo, sk->sk_hash); | ||
280 | list = &head->chain; | ||
281 | lock = inet_ehash_lockp(hashinfo, sk->sk_hash); | ||
282 | |||
283 | write_lock(lock); | ||
284 | __sk_add_node(sk, list); | ||
285 | sock_prot_inc_use(sk->sk_prot); | ||
286 | write_unlock(lock); | ||
287 | } | ||
288 | EXPORT_SYMBOL_GPL(__inet_hash_nolisten); | ||
289 | |||
290 | void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) | ||
291 | { | ||
292 | struct hlist_head *list; | ||
293 | rwlock_t *lock; | ||
294 | |||
295 | if (sk->sk_state != TCP_LISTEN) { | ||
296 | __inet_hash_nolisten(hashinfo, sk); | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | BUG_TRAP(sk_unhashed(sk)); | ||
301 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | ||
302 | lock = &hashinfo->lhash_lock; | ||
303 | |||
304 | inet_listen_wlock(hashinfo); | ||
305 | __sk_add_node(sk, list); | ||
306 | sock_prot_inc_use(sk->sk_prot); | ||
307 | write_unlock(lock); | ||
308 | wake_up(&hashinfo->lhash_wait); | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(__inet_hash); | ||
311 | |||
270 | /* | 312 | /* |
271 | * Bind a port for a connect operation and hash it. | 313 | * Bind a port for a connect operation and hash it. |
272 | */ | 314 | */ |
@@ -334,7 +376,7 @@ ok: | |||
334 | inet_bind_hash(sk, tb, port); | 376 | inet_bind_hash(sk, tb, port); |
335 | if (sk_unhashed(sk)) { | 377 | if (sk_unhashed(sk)) { |
336 | inet_sk(sk)->sport = htons(port); | 378 | inet_sk(sk)->sport = htons(port); |
337 | __inet_hash(hinfo, sk, 0); | 379 | __inet_hash_nolisten(hinfo, sk); |
338 | } | 380 | } |
339 | spin_unlock(&head->lock); | 381 | spin_unlock(&head->lock); |
340 | 382 | ||
@@ -351,7 +393,7 @@ ok: | |||
351 | tb = inet_csk(sk)->icsk_bind_hash; | 393 | tb = inet_csk(sk)->icsk_bind_hash; |
352 | spin_lock_bh(&head->lock); | 394 | spin_lock_bh(&head->lock); |
353 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 395 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
354 | __inet_hash(hinfo, sk, 0); | 396 | __inet_hash_nolisten(hinfo, sk); |
355 | spin_unlock_bh(&head->lock); | 397 | spin_unlock_bh(&head->lock); |
356 | return 0; | 398 | return 0; |
357 | } else { | 399 | } else { |