|
@@ -56,42 +56,6 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win)
|
|
|
|
|
|
int tcp_tw_count;
|
|
|
|
|
|
-
|
|
|
-/* Must be called with locally disabled BHs. */
|
|
|
-static void tcp_timewait_kill(struct inet_timewait_sock *tw)
|
|
|
-{
|
|
|
- struct inet_bind_hashbucket *bhead;
|
|
|
- struct inet_bind_bucket *tb;
|
|
|
- /* Unlink from established hashes. */
|
|
|
- struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[tw->tw_hashent];
|
|
|
-
|
|
|
- write_lock(&ehead->lock);
|
|
|
- if (hlist_unhashed(&tw->tw_node)) {
|
|
|
- write_unlock(&ehead->lock);
|
|
|
- return;
|
|
|
- }
|
|
|
- __hlist_del(&tw->tw_node);
|
|
|
- sk_node_init(&tw->tw_node);
|
|
|
- write_unlock(&ehead->lock);
|
|
|
-
|
|
|
- /* Disassociate with bind bucket. */
|
|
|
- bhead = &tcp_hashinfo.bhash[inet_bhashfn(tw->tw_num, tcp_hashinfo.bhash_size)];
|
|
|
- spin_lock(&bhead->lock);
|
|
|
- tb = tw->tw_tb;
|
|
|
- __hlist_del(&tw->tw_bind_node);
|
|
|
- tw->tw_tb = NULL;
|
|
|
- inet_bind_bucket_destroy(tcp_hashinfo.bind_bucket_cachep, tb);
|
|
|
- spin_unlock(&bhead->lock);
|
|
|
-
|
|
|
-#ifdef SOCK_REFCNT_DEBUG
|
|
|
- if (atomic_read(&tw->tw_refcnt) != 1) {
|
|
|
- printk(KERN_DEBUG "%s timewait_sock %p refcnt=%d\n",
|
|
|
- tw->tw_prot->name, tw, atomic_read(&tw->tw_refcnt));
|
|
|
- }
|
|
|
-#endif
|
|
|
- inet_twsk_put(tw);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* * Main purpose of TIME-WAIT state is to close connection gracefully,
|
|
|
* when one of ends sits in LAST-ACK or CLOSING retransmitting FIN
|
|
@@ -290,40 +254,6 @@ kill:
|
|
|
return TCP_TW_SUCCESS;
|
|
|
}
|
|
|
|
|
|
-/* Enter the time wait state. This is called with locally disabled BH.
|
|
|
- * Essentially we whip up a timewait bucket, copy the
|
|
|
- * relevant info into it from the SK, and mess with hash chains
|
|
|
- * and list linkage.
|
|
|
- */
|
|
|
-static void __tcp_tw_hashdance(struct sock *sk, struct inet_timewait_sock *tw)
|
|
|
-{
|
|
|
- const struct inet_sock *inet = inet_sk(sk);
|
|
|
- struct inet_ehash_bucket *ehead = &tcp_hashinfo.ehash[sk->sk_hashent];
|
|
|
- struct inet_bind_hashbucket *bhead;
|
|
|
- /* Step 1: Put TW into bind hash. Original socket stays there too.
|
|
|
- Note, that any socket with inet->num != 0 MUST be bound in
|
|
|
- binding cache, even if it is closed.
|
|
|
- */
|
|
|
- bhead = &tcp_hashinfo.bhash[inet_bhashfn(inet->num, tcp_hashinfo.bhash_size)];
|
|
|
- spin_lock(&bhead->lock);
|
|
|
- tw->tw_tb = inet->bind_hash;
|
|
|
- BUG_TRAP(inet->bind_hash);
|
|
|
- inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
|
|
|
- spin_unlock(&bhead->lock);
|
|
|
-
|
|
|
- write_lock(&ehead->lock);
|
|
|
-
|
|
|
- /* Step 2: Remove SK from established hash. */
|
|
|
- if (__sk_del_node_init(sk))
|
|
|
- sock_prot_dec_use(sk->sk_prot);
|
|
|
-
|
|
|
- /* Step 3: Hash TW into TIMEWAIT half of established hash table. */
|
|
|
- inet_twsk_add_node(tw, &(ehead + tcp_hashinfo.ehash_size)->chain);
|
|
|
- atomic_inc(&tw->tw_refcnt);
|
|
|
-
|
|
|
- write_unlock(&ehead->lock);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Move a socket to time-wait or dead fin-wait-2 state.
|
|
|
*/
|
|
@@ -381,7 +311,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
|
|
|
tw->tw_ipv6only = 0;
|
|
|
#endif
|
|
|
/* Linkage updates. */
|
|
|
- __tcp_tw_hashdance(sk, tw);
|
|
|
+ __inet_twsk_hashdance(tw, sk, &tcp_hashinfo);
|
|
|
|
|
|
/* Get the TIME_WAIT timeout firing. */
|
|
|
if (timeo < rto)
|
|
@@ -448,7 +378,7 @@ rescan:
|
|
|
inet_twsk_for_each_inmate(tw, node, &tcp_tw_death_row[slot]) {
|
|
|
__inet_twsk_del_dead_node(tw);
|
|
|
spin_unlock(&tw_death_lock);
|
|
|
- tcp_timewait_kill(tw);
|
|
|
+ __inet_twsk_kill(tw, &tcp_hashinfo);
|
|
|
inet_twsk_put(tw);
|
|
|
killed++;
|
|
|
spin_lock(&tw_death_lock);
|
|
@@ -544,7 +474,7 @@ void tcp_tw_deschedule(struct inet_timewait_sock *tw)
|
|
|
del_timer(&tcp_tw_timer);
|
|
|
}
|
|
|
spin_unlock(&tw_death_lock);
|
|
|
- tcp_timewait_kill(tw);
|
|
|
+ __inet_twsk_kill(tw, &tcp_hashinfo);
|
|
|
}
|
|
|
|
|
|
/* Short-time timewait calendar */
|
|
@@ -653,7 +583,7 @@ void tcp_twcal_tick(unsigned long dummy)
|
|
|
inet_twsk_for_each_inmate_safe(tw, node, safe,
|
|
|
&tcp_twcal_row[slot]) {
|
|
|
__inet_twsk_del_dead_node(tw);
|
|
|
- tcp_timewait_kill(tw);
|
|
|
+ __inet_twsk_kill(tw, &tcp_hashinfo);
|
|
|
inet_twsk_put(tw);
|
|
|
killed++;
|
|
|
}
|