: Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup
Subsystems (2)
PATCH 4/8 : Fix ip_ct_selective_cleanup(), and rename ip_ct_iterate_cleanup
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2005/03/04 00:45:34+01:00 [email protected]
# [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 <[email protected]>
#
# net/ipv4/netfilter/ipt_MASQUERADE.c
# 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # # net/ipv4/netfilter/ip_nat_helper.c # 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # # net/ipv4/netfilter/ip_nat_core.c # 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # # net/ipv4/netfilter/ip_conntrack_core.c # 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # # include/linux/netfilter_ipv4/ip_conntrack.h # 2005/03/04 00:45:32+01:00 [email protected] +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 <[email protected]> # 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)
net/ipv4/netfilter/ip_conntrack_core.c +33 -14
@@ -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;
net/ipv4/netfilter/ip_conntrack_standalone.c +3 -3
@@ -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);
net/ipv4/netfilter/ip_nat_core.c +3 -3
@@ -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); }
net/ipv4/netfilter/ip_nat_helper.c +2 -2
@@ -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 ;
net/ipv4/netfilter/ipt_MASQUERADE.c +3 -3
@@ -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 ;