All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Fix hang on netfilter module unload
@ 2005-03-15  5:06 Phil Oester
  2005-03-15 12:57 ` Pablo Neira
  2005-03-15 17:23 ` Phil Oester
  0 siblings, 2 replies; 9+ messages in thread
From: Phil Oester @ 2005-03-15  5:06 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1476 bytes --]

At module unload time, we use ip_conntrack_count to determine how many
conntracks need to be destroyed before we can unload.  get_next_corpse
looks in the hash tables and unconfirmed list for the conntracks until
ip_conntrack_count == 0.  

Unfortunately, conntracks occasionally get pinned by an skb which for
some reason or another won't go away.  So ct_general->use never reduces
to 1 for these conntracks, and they do not appear in either the
hashes or the unconfirmed list.  As such, we loop around forever at
i_see_dead_people trying to kill a conntrack which we will never find.

The below patch attempts to fix this by doing two things:

1) when a conntrack is removed from the hashes in clean_from_lists,
   add it to a new 'cleaned' list, similar to how the unconfirmed list
   works.  This ensures that we never lose sight of a conntrack --
   it moves from unconfirmed->hashed->cleaned in its lifetime.
   get_next_corpse now checks the cleaned list for conntracks also.

2) change get_next_corpse to set the usage count of conntracks to
   1 once they are found.  Otherwise, these pinned conntracks will never
   be able to be removed, since use will be > 1 

Without the below, I can trivially hang a box on module unload by
using NetworkManager on FC3 -- seems to be related to the DHCP process.
With this patch, unload works every time.

This fixes Netfilter bugzilla #91 and Redhat bugzilla #112630.

Phil

Signed-off-by: Phil Oester <kernel@linuxace.com>




[-- Attachment #2: patch-unload --]
[-- Type: text/plain, Size: 1834 bytes --]

diff -ruN linux-orig/net/ipv4/netfilter/ip_conntrack_core.c linux-new/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-orig/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-02 02:37:30.000000000 -0500
+++ linux-new/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-14 20:18:46.289349488 -0500
@@ -74,6 +74,7 @@
 struct ip_conntrack ip_conntrack_untracked;
 unsigned int ip_ct_log_invalid;
 static LIST_HEAD(unconfirmed);
+static LIST_HEAD(cleaned);
 static int ip_conntrack_vmalloc;
 
 DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat);
@@ -216,6 +217,9 @@
 	LIST_DELETE(&ip_conntrack_hash[ho], &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
 	LIST_DELETE(&ip_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
 
+	/* Overload tuple linked list to put us in cleaned list. */
+	list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list, &cleaned);
+
 	/* Destroy all pending expectations */
 	remove_expectations(ct);
 }
@@ -247,11 +251,9 @@
 	 * too. */
 	remove_expectations(ct);
 
-	/* We overload first tuple to link into unconfirmed list. */
-	if (!is_confirmed(ct)) {
-		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
-		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
-	}
+	/* We overload first tuple to link into unconfirmed or cleaned list.
+	   Will always be on one or the other at this point */
+	list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
 
 	CONNTRACK_STAT_INC(delete);
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -1019,8 +1021,11 @@
 	if (!h)
 		h = LIST_FIND_W(&unconfirmed, do_iter,
 				struct ip_conntrack_tuple_hash *, iter, data);
+	if (!h)
+		h = LIST_FIND_W(&cleaned, do_iter,
+				struct ip_conntrack_tuple_hash *, iter, data);
 	if (h)
-		atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
+		atomic_set(&tuplehash_to_ctrack(h)->ct_general.use, 1);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 
 	return h;

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2005-03-15 21:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-15  5:06 [PATCH] Fix hang on netfilter module unload Phil Oester
2005-03-15 12:57 ` Pablo Neira
2005-03-15 17:23 ` Phil Oester
2005-03-15 19:25   ` Patrick McHardy
2005-03-15 19:46     ` Phil Oester
2005-03-15 19:53       ` Patrick McHardy
2005-03-15 20:09         ` Patrick McHardy
2005-03-15 21:48           ` Patrick McHardy
2005-03-15 20:25         ` Phil Oester

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.