All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: "David S. Miller" <davem@davemloft.net>
Cc: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
Subject: [PATCH 2.4 4/8]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup
Date: Fri, 04 Mar 2005 13:18:47 +0100	[thread overview]
Message-ID: <42285227.80403@trash.net> (raw)

[-- Attachment #1: 04.diff --]
[-- Type: text/x-patch, Size: 13945 bytes --]

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/04 00:45:34+01:00 kaber@coreworks.de 
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ipt_MASQUERADE.c
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +3 -3
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_helper.c
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +2 -2
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_core.c
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +3 -3
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_conntrack_standalone.c
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +3 -3
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_conntrack_core.c
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +33 -14
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv4/ip_conntrack.h
#   2005/03/04 00:45:32+01:00 kaber@coreworks.de +3 -3
#   [NETFILTER]: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup()
#   
#   Backport from 2.6, original patch from Rusty:
#   
#   Several places use ip_ct_selective_cleanup() as a general iterator, which it
#   was not intended for (it takes a const ip_conntrack *).  So rename it, and
#   make it take a non-const argument.
#   	
#   Also, it missed unconfirmed connections, which aren't in the hash table.  This
#   introduces a potential problem for users which expect to iterate all
#   connections (such as the helper deletion code).  So keep a linked list of
#   unconfirmed connections as well.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2005-03-04 01:52:04 +01:00
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2005-03-04 01:52:04 +01:00
@@ -253,10 +253,10 @@
 struct sk_buff *
 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
 
-/* Delete all conntracks which match. */
+/* Iterate over all conntracks: if iter returns true, it's deleted. */
 extern void
-ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
-			void *data);
+ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data),
+                      void *data);
 
 /* It's confirmed if it is, or has been in the hash table. */
 static inline int is_confirmed(struct ip_conntrack *ct)
diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-04 01:52:04 +01:00
+++ b/net/ipv4/netfilter/ip_conntrack_core.c	2005-03-04 01:52:04 +01:00
@@ -64,6 +64,7 @@
 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
 struct list_head *ip_conntrack_hash;
 static kmem_cache_t *ip_conntrack_cachep;
+static LIST_HEAD(unconfirmed);
 
 extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
 
@@ -329,6 +330,12 @@
 	if (ct->expecting)
 		remove_expectations(ct, 1);
 
+	/* 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);
+	}
+
 	/* Delete our master expectation */
 	if (ct->master) {
 		if (ct->master->expectant) {
@@ -463,6 +470,9 @@
 			  conntrack_tuple_cmp,
 			  struct ip_conntrack_tuple_hash *,
 			  &ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
+		/* Remove from unconfirmed list */
+		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+
 		list_prepend(&ip_conntrack_hash[hash],
 			     &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
 		list_prepend(&ip_conntrack_hash[repl_hash],
@@ -736,6 +746,10 @@
 		expected->expectant->expecting--;
 		nf_conntrack_get(&master_ct(conntrack)->infos[0]);
 	}
+	/* Overload tuple linked list to put us in unconfirmed list. */
+	list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list,
+	         &unconfirmed);
+
 	atomic_inc(&ip_conntrack_count);
 	WRITE_UNLOCK(&ip_conntrack_lock);
 
@@ -1155,6 +1169,7 @@
 	LIST_DELETE(&helpers, me);
 
 	/* Get rid of expecteds, set helpers to NULL. */
+	LIST_FIND_W(&unconfirmed, unhelp, struct ip_conntrack_tuple_hash*, me);
 	for (i = 0; i < ip_conntrack_htable_size; i++)
 		LIST_FIND_W(&ip_conntrack_hash[i], unhelp,
 			    struct ip_conntrack_tuple_hash *, me);
@@ -1248,40 +1263,44 @@
 }
 
 static inline int
-do_kill(const struct ip_conntrack_tuple_hash *i,
-	int (*kill)(const struct ip_conntrack *i, void *data),
+do_iter(const struct ip_conntrack_tuple_hash *i,
+        int (*iter)(struct ip_conntrack *i, void *data),
 	void *data)
 {
-	return kill(i->ctrack, data);
+	return iter(i->ctrack, data);
 }
 
 /* Bring out ya dead! */
 static struct ip_conntrack_tuple_hash *
-get_next_corpse(int (*kill)(const struct ip_conntrack *i, void *data),
+get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
 		void *data, unsigned int *bucket)
 {
 	struct ip_conntrack_tuple_hash *h = NULL;
 
-	READ_LOCK(&ip_conntrack_lock);
-	for (; !h && *bucket < ip_conntrack_htable_size; (*bucket)++) {
-		h = LIST_FIND(&ip_conntrack_hash[*bucket], do_kill,
-			      struct ip_conntrack_tuple_hash *, kill, data);
+	WRITE_LOCK(&ip_conntrack_lock);
+	for (; *bucket < ip_conntrack_htable_size; (*bucket)++) {
+		h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter,
+		                struct ip_conntrack_tuple_hash *, iter, data);
+		if (h)
+			break;
 	}
+	if (!h)
+		h = LIST_FIND_W(&unconfirmed, do_iter,
+		                struct ip_conntrack_tuple_hash *, iter, data);
 	if (h)
 		atomic_inc(&h->ctrack->ct_general.use);
-	READ_UNLOCK(&ip_conntrack_lock);
+	WRITE_UNLOCK(&ip_conntrack_lock);
 
 	return h;
 }
 
 void
-ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
-			void *data)
+ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *), void *data)
 {
 	struct ip_conntrack_tuple_hash *h;
 	unsigned int bucket = 0;
 
-	while ((h = get_next_corpse(kill, data, &bucket)) != NULL) {
+	while ((h = get_next_corpse(iter, data, &bucket)) != NULL) {
 		/* Time to push up daises... */
 		if (del_timer(&h->ctrack->timeout))
 			death_by_timeout((unsigned long)h->ctrack);
@@ -1350,7 +1369,7 @@
     SO_ORIGINAL_DST, SO_ORIGINAL_DST+1, &getorigdst,
     0, NULL };
 
-static int kill_all(const struct ip_conntrack *i, void *data)
+static int kill_all(struct ip_conntrack *i, void *data)
 {
 	return 1;
 }
@@ -1367,7 +1386,7 @@
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
  
  i_see_dead_people:
-	ip_ct_selective_cleanup(kill_all, NULL);
+	ip_ct_iterate_cleanup(kill_all, NULL);
 	if (atomic_read(&ip_conntrack_count) != 0) {
 		schedule();
 		goto i_see_dead_people;
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-03-04 01:52:04 +01:00
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2005-03-04 01:52:04 +01:00
@@ -39,7 +39,7 @@
 
 MODULE_LICENSE("GPL");
 
-static int kill_proto(const struct ip_conntrack *i, void *data)
+static int kill_proto(struct ip_conntrack *i, void *data)
 {
 	return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == 
 			*((u_int8_t *) data));
@@ -440,7 +440,7 @@
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
 
 	/* Remove all contrack entries for this protocol */
-	ip_ct_selective_cleanup(kill_proto, &proto->proto);
+	ip_ct_iterate_cleanup(kill_proto, &proto->proto);
 
 	MOD_DEC_USE_COUNT;
 }
@@ -467,7 +467,7 @@
 EXPORT_SYMBOL(ip_conntrack_get);
 EXPORT_SYMBOL(ip_conntrack_helper_register);
 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
-EXPORT_SYMBOL(ip_ct_selective_cleanup);
+EXPORT_SYMBOL(ip_ct_iterate_cleanup);
 EXPORT_SYMBOL(ip_ct_refresh);
 EXPORT_SYMBOL(ip_ct_find_proto);
 EXPORT_SYMBOL(__ip_ct_find_proto);
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c	2005-03-04 01:52:04 +01:00
+++ b/net/ipv4/netfilter/ip_nat_core.c	2005-03-04 01:52:04 +01:00
@@ -1028,16 +1028,16 @@
 }
 
 /* Clear NAT section of all conntracks, in case we're loaded again. */
-static int clean_nat(const struct ip_conntrack *i, void *data)
+static int clean_nat(struct ip_conntrack *i, void *data)
 {
-	memset((void *)&i->nat, 0, sizeof(i->nat));
+	memset(&i->nat, 0, sizeof(i->nat));
 	return 0;
 }
 
 /* Not __exit: called from ip_nat_standalone.c:init_or_cleanup() --RR */
 void ip_nat_cleanup(void)
 {
-	ip_ct_selective_cleanup(&clean_nat, NULL);
+	ip_ct_iterate_cleanup(&clean_nat, NULL);
 	ip_conntrack_destroyed = NULL;
 	vfree(bysource);
 }
diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
--- a/net/ipv4/netfilter/ip_nat_helper.c	2005-03-04 01:52:04 +01:00
+++ b/net/ipv4/netfilter/ip_nat_helper.c	2005-03-04 01:52:04 +01:00
@@ -520,7 +520,7 @@
 }
 
 static int
-kill_helper(const struct ip_conntrack *i, void *helper)
+kill_helper(struct ip_conntrack *i, void *helper)
 {
 	int ret;
 
@@ -554,7 +554,7 @@
 	   forces admins to gen fake RSTs or bounce box, either of
 	   which is just a long-winded way of making things
 	   worse. --RR */
-	ip_ct_selective_cleanup(kill_helper, me);
+	ip_ct_iterate_cleanup(kill_helper, me);
 
 	if (found)
 		MOD_DEC_USE_COUNT;
diff -Nru a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-03-04 01:52:04 +01:00
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c	2005-03-04 01:52:04 +01:00
@@ -125,7 +125,7 @@
 }
 
 static inline int
-device_cmp(const struct ip_conntrack *i, void *ifindex)
+device_cmp(struct ip_conntrack *i, void *ifindex)
 {
 	int ret;
 
@@ -148,7 +148,7 @@
 		   and forget them. */
 		IP_NF_ASSERT(dev->ifindex != 0);
  
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+		ip_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
 	}
 
 	return NOTIFY_DONE;
@@ -167,7 +167,7 @@
 		   and forget them. */
 		IP_NF_ASSERT(dev->ifindex != 0);
 
-		ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
+		ip_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex);
 	}
 
 	return NOTIFY_DONE;

                 reply	other threads:[~2005-03-04 12:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=42285227.80403@trash.net \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.