diff options
-rw-r--r-- | include/net/netfilter/nf_conntrack.h | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 25 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 2 |
3 files changed, 11 insertions, 18 deletions
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index f1494feba79f..caca0c4d6b4b 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
@@ -182,7 +182,7 @@ __nf_conntrack_find(struct net *net, u16 zone, | |||
182 | 182 | ||
183 | extern int nf_conntrack_hash_check_insert(struct nf_conn *ct); | 183 | extern int nf_conntrack_hash_check_insert(struct nf_conn *ct); |
184 | extern void nf_ct_delete_from_lists(struct nf_conn *ct); | 184 | extern void nf_ct_delete_from_lists(struct nf_conn *ct); |
185 | extern void nf_ct_insert_dying_list(struct nf_conn *ct); | 185 | extern void nf_ct_dying_timeout(struct nf_conn *ct); |
186 | 186 | ||
187 | extern void nf_conntrack_flush_report(struct net *net, u32 pid, int report); | 187 | extern void nf_conntrack_flush_report(struct net *net, u32 pid, int report); |
188 | 188 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0f241be28f9e..af175166fffa 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -221,11 +221,9 @@ destroy_conntrack(struct nf_conntrack *nfct) | |||
221 | * too. */ | 221 | * too. */ |
222 | nf_ct_remove_expectations(ct); | 222 | nf_ct_remove_expectations(ct); |
223 | 223 | ||
224 | /* We overload first tuple to link into unconfirmed list. */ | 224 | /* We overload first tuple to link into unconfirmed or dying list.*/ |
225 | if (!nf_ct_is_confirmed(ct)) { | 225 | BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode)); |
226 | BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode)); | 226 | hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); |
227 | hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); | ||
228 | } | ||
229 | 227 | ||
230 | NF_CT_STAT_INC(net, delete); | 228 | NF_CT_STAT_INC(net, delete); |
231 | spin_unlock_bh(&nf_conntrack_lock); | 229 | spin_unlock_bh(&nf_conntrack_lock); |
@@ -247,6 +245,9 @@ void nf_ct_delete_from_lists(struct nf_conn *ct) | |||
247 | * Otherwise we can get spurious warnings. */ | 245 | * Otherwise we can get spurious warnings. */ |
248 | NF_CT_STAT_INC(net, delete_list); | 246 | NF_CT_STAT_INC(net, delete_list); |
249 | clean_from_lists(ct); | 247 | clean_from_lists(ct); |
248 | /* add this conntrack to the dying list */ | ||
249 | hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
250 | &net->ct.dying); | ||
250 | spin_unlock_bh(&nf_conntrack_lock); | 251 | spin_unlock_bh(&nf_conntrack_lock); |
251 | } | 252 | } |
252 | EXPORT_SYMBOL_GPL(nf_ct_delete_from_lists); | 253 | EXPORT_SYMBOL_GPL(nf_ct_delete_from_lists); |
@@ -268,31 +269,23 @@ static void death_by_event(unsigned long ul_conntrack) | |||
268 | } | 269 | } |
269 | /* we've got the event delivered, now it's dying */ | 270 | /* we've got the event delivered, now it's dying */ |
270 | set_bit(IPS_DYING_BIT, &ct->status); | 271 | set_bit(IPS_DYING_BIT, &ct->status); |
271 | spin_lock(&nf_conntrack_lock); | ||
272 | hlist_nulls_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); | ||
273 | spin_unlock(&nf_conntrack_lock); | ||
274 | nf_ct_put(ct); | 272 | nf_ct_put(ct); |
275 | } | 273 | } |
276 | 274 | ||
277 | void nf_ct_insert_dying_list(struct nf_conn *ct) | 275 | void nf_ct_dying_timeout(struct nf_conn *ct) |
278 | { | 276 | { |
279 | struct net *net = nf_ct_net(ct); | 277 | struct net *net = nf_ct_net(ct); |
280 | struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); | 278 | struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct); |
281 | 279 | ||
282 | BUG_ON(ecache == NULL); | 280 | BUG_ON(ecache == NULL); |
283 | 281 | ||
284 | /* add this conntrack to the dying list */ | ||
285 | spin_lock_bh(&nf_conntrack_lock); | ||
286 | hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
287 | &net->ct.dying); | ||
288 | spin_unlock_bh(&nf_conntrack_lock); | ||
289 | /* set a new timer to retry event delivery */ | 282 | /* set a new timer to retry event delivery */ |
290 | setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); | 283 | setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct); |
291 | ecache->timeout.expires = jiffies + | 284 | ecache->timeout.expires = jiffies + |
292 | (random32() % net->ct.sysctl_events_retry_timeout); | 285 | (random32() % net->ct.sysctl_events_retry_timeout); |
293 | add_timer(&ecache->timeout); | 286 | add_timer(&ecache->timeout); |
294 | } | 287 | } |
295 | EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list); | 288 | EXPORT_SYMBOL_GPL(nf_ct_dying_timeout); |
296 | 289 | ||
297 | static void death_by_timeout(unsigned long ul_conntrack) | 290 | static void death_by_timeout(unsigned long ul_conntrack) |
298 | { | 291 | { |
@@ -307,7 +300,7 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
307 | unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) { | 300 | unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) { |
308 | /* destroy event was not delivered */ | 301 | /* destroy event was not delivered */ |
309 | nf_ct_delete_from_lists(ct); | 302 | nf_ct_delete_from_lists(ct); |
310 | nf_ct_insert_dying_list(ct); | 303 | nf_ct_dying_timeout(ct); |
311 | return; | 304 | return; |
312 | } | 305 | } |
313 | set_bit(IPS_DYING_BIT, &ct->status); | 306 | set_bit(IPS_DYING_BIT, &ct->status); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 7bbfb3deea30..34370a928360 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -989,7 +989,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
989 | nlmsg_report(nlh)) < 0) { | 989 | nlmsg_report(nlh)) < 0) { |
990 | nf_ct_delete_from_lists(ct); | 990 | nf_ct_delete_from_lists(ct); |
991 | /* we failed to report the event, try later */ | 991 | /* we failed to report the event, try later */ |
992 | nf_ct_insert_dying_list(ct); | 992 | nf_ct_dying_timeout(ct); |
993 | nf_ct_put(ct); | 993 | nf_ct_put(ct); |
994 | return 0; | 994 | return 0; |
995 | } | 995 | } |