]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/inet_timewait_sock.c
Merge branch 'x86/prototypes' into x86-v28-for-linus-phase1
[linux-2.6-omap-h63xx.git] / net / ipv4 / inet_timewait_sock.c
index 75c2def8f9a0cbcd04a0a324e28cde2e756bb480..743f011b9a84189bd9284721e4a1ac2a704e68b8 100644 (file)
@@ -86,7 +86,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
                        hashinfo->bhash_size)];
        spin_lock(&bhead->lock);
        tw->tw_tb = icsk->icsk_bind_hash;
-       BUG_TRAP(icsk->icsk_bind_hash);
+       WARN_ON(!icsk->icsk_bind_hash);
        inet_twsk_add_bind_node(tw, &tw->tw_tb->owners);
        spin_unlock(&bhead->lock);
 
@@ -409,3 +409,38 @@ out:
 }
 
 EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick);
+
+void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
+                    struct inet_timewait_death_row *twdr, int family)
+{
+       struct inet_timewait_sock *tw;
+       struct sock *sk;
+       struct hlist_node *node;
+       int h;
+
+       local_bh_disable();
+       for (h = 0; h < (hashinfo->ehash_size); h++) {
+               struct inet_ehash_bucket *head =
+                       inet_ehash_bucket(hashinfo, h);
+               rwlock_t *lock = inet_ehash_lockp(hashinfo, h);
+restart:
+               write_lock(lock);
+               sk_for_each(sk, node, &head->twchain) {
+
+                       tw = inet_twsk(sk);
+                       if (!net_eq(twsk_net(tw), net) ||
+                           tw->tw_family != family)
+                               continue;
+
+                       atomic_inc(&tw->tw_refcnt);
+                       write_unlock(lock);
+                       inet_twsk_deschedule(tw, twdr);
+                       inet_twsk_put(tw);
+
+                       goto restart;
+               }
+               write_unlock(lock);
+       }
+       local_bh_enable();
+}
+EXPORT_SYMBOL_GPL(inet_twsk_purge);