diff options
Diffstat (limited to 'net/netfilter/nf_conntrack_core.c')
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 622d7c671cb..90ce9ddb945 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -39,13 +39,13 @@ #include <net/netfilter/nf_conntrack_extend.h> #include <net/netfilter/nf_conntrack_acct.h> #include <net/netfilter/nf_nat.h> +#include <net/netfilter/nf_nat_core.h> #define NF_CONNTRACK_VERSION "0.5.0" -unsigned int -(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, - enum nf_nat_manip_type manip, - struct nlattr *attr) __read_mostly; +int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, + enum nf_nat_manip_type manip, + struct nlattr *attr) __read_mostly; EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); DEFINE_SPINLOCK(nf_conntrack_lock); @@ -181,7 +181,8 @@ destroy_conntrack(struct nf_conntrack *nfct) NF_CT_ASSERT(atomic_read(&nfct->use) == 0); NF_CT_ASSERT(!timer_pending(&ct->timeout)); - nf_conntrack_event(IPCT_DESTROY, ct); + if (!test_bit(IPS_DYING_BIT, &ct->status)) + nf_conntrack_event(IPCT_DESTROY, ct); set_bit(IPS_DYING_BIT, &ct->status); /* To make sure we don't get any weird locking issues here: @@ -305,9 +306,7 @@ void nf_conntrack_hash_insert(struct nf_conn *ct) hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); - spin_lock_bh(&nf_conntrack_lock); __nf_conntrack_hash_insert(ct, hash, repl_hash); - spin_unlock_bh(&nf_conntrack_lock); } EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert); @@ -470,7 +469,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, const struct nf_conntrack_tuple *repl, gfp_t gfp) { - struct nf_conn *ct = NULL; + struct nf_conn *ct; if (unlikely(!nf_conntrack_hash_rnd_initted)) { get_random_bytes(&nf_conntrack_hash_rnd, 4); @@ -552,7 +551,7 @@ init_conntrack(struct net *net, } ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC); - if (ct == NULL || IS_ERR(ct)) { + if (IS_ERR(ct)) { pr_debug("Can't allocate conntrack.\n"); return (struct nf_conntrack_tuple_hash *)ct; } @@ -588,14 +587,7 @@ init_conntrack(struct net *net, nf_conntrack_get(&ct->master->ct_general); NF_CT_STAT_INC(net, expect_new); } else { - struct nf_conntrack_helper *helper; - - helper = __nf_ct_helper_find(&repl_tuple); - if (helper) { - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); - if (help) - rcu_assign_pointer(help->helper, helper); - } + __nf_ct_try_assign_helper(ct, GFP_ATOMIC); NF_CT_STAT_INC(net, new); } @@ -772,7 +764,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, const struct nf_conntrack_tuple *newreply) { struct nf_conn_help *help = nfct_help(ct); - struct nf_conntrack_helper *helper; /* Should be unconfirmed, so not in hash table yet */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); @@ -785,23 +776,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, return; rcu_read_lock(); - helper = __nf_ct_helper_find(newreply); - if (helper == NULL) { - if (help) - rcu_assign_pointer(help->helper, NULL); - goto out; - } - - if (help == NULL) { - help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); - if (help == NULL) - goto out; - } else { - memset(&help->help, 0, sizeof(help->help)); - } - - rcu_assign_pointer(help->helper, helper); -out: + __nf_ct_try_assign_helper(ct, GFP_ATOMIC); rcu_read_unlock(); } EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); @@ -996,8 +971,20 @@ void nf_ct_iterate_cleanup(struct net *net, } EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup); +struct __nf_ct_flush_report { + u32 pid; + int report; +}; + static int kill_all(struct nf_conn *i, void *data) { + struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data; + + /* get_next_corpse sets the dying bit for us */ + nf_conntrack_event_report(IPCT_DESTROY, + i, + fr->pid, + fr->report); return 1; } @@ -1011,9 +998,13 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s } EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); -void nf_conntrack_flush(struct net *net) +void nf_conntrack_flush(struct net *net, u32 pid, int report) { - nf_ct_iterate_cleanup(net, kill_all, NULL); + struct __nf_ct_flush_report fr = { + .pid = pid, + .report = report, + }; + nf_ct_iterate_cleanup(net, kill_all, &fr); } EXPORT_SYMBOL_GPL(nf_conntrack_flush); @@ -1029,7 +1020,7 @@ static void nf_conntrack_cleanup_net(struct net *net) nf_ct_event_cache_flush(net); nf_conntrack_ecache_fini(net); i_see_dead_people: - nf_conntrack_flush(net); + nf_conntrack_flush(net, 0, 0); if (atomic_read(&net->ct.count) != 0) { schedule(); goto i_see_dead_people; |