aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2013-07-29 09:41:55 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2013-08-09 06:03:33 -0400
commitc655bc6896b94ee0223393f26155c6daf1e2d148 (patch)
tree493664303eefd739303a67b891c0f7f89c92eb09 /net
parent54e35cc52346149a7bce8a2f622e215ed17bb56d (diff)
netfilter: nf_conntrack: don't send destroy events from iterator
Let nf_ct_delete handle delivery of the DESTROY event. Based on earlier patch from Pablo Neira. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c2
-rw-r--r--net/ipv6/netfilter/ip6t_MASQUERADE.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c36
-rw-r--r--net/netfilter/nf_conntrack_proto.c4
-rw-r--r--net/netfilter/nf_nat_core.c6
5 files changed, 11 insertions, 39 deletions
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 30e4de940567..00352ce0f0de 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -118,7 +118,7 @@ static int masq_device_event(struct notifier_block *this,
118 NF_CT_ASSERT(dev->ifindex != 0); 118 NF_CT_ASSERT(dev->ifindex != 0);
119 119
120 nf_ct_iterate_cleanup(net, device_cmp, 120 nf_ct_iterate_cleanup(net, device_cmp,
121 (void *)(long)dev->ifindex); 121 (void *)(long)dev->ifindex, 0, 0);
122 } 122 }
123 123
124 return NOTIFY_DONE; 124 return NOTIFY_DONE;
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
index 47bff6107519..3e4e92d5e157 100644
--- a/net/ipv6/netfilter/ip6t_MASQUERADE.c
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -76,7 +76,7 @@ static int masq_device_event(struct notifier_block *this,
76 76
77 if (event == NETDEV_DOWN) 77 if (event == NETDEV_DOWN)
78 nf_ct_iterate_cleanup(net, device_cmp, 78 nf_ct_iterate_cleanup(net, device_cmp,
79 (void *)(long)dev->ifindex); 79 (void *)(long)dev->ifindex, 0, 0);
80 80
81 return NOTIFY_DONE; 81 return NOTIFY_DONE;
82} 82}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 0934611ff9f3..da6f1787a102 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1246,7 +1246,7 @@ found:
1246 1246
1247void nf_ct_iterate_cleanup(struct net *net, 1247void nf_ct_iterate_cleanup(struct net *net,
1248 int (*iter)(struct nf_conn *i, void *data), 1248 int (*iter)(struct nf_conn *i, void *data),
1249 void *data) 1249 void *data, u32 portid, int report)
1250{ 1250{
1251 struct nf_conn *ct; 1251 struct nf_conn *ct;
1252 unsigned int bucket = 0; 1252 unsigned int bucket = 0;
@@ -1254,7 +1254,7 @@ void nf_ct_iterate_cleanup(struct net *net,
1254 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) { 1254 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
1255 /* Time to push up daises... */ 1255 /* Time to push up daises... */
1256 if (del_timer(&ct->timeout)) 1256 if (del_timer(&ct->timeout))
1257 death_by_timeout((unsigned long)ct); 1257 nf_ct_delete(ct, portid, report);
1258 1258
1259 /* ... else the timer will get him soon. */ 1259 /* ... else the timer will get him soon. */
1260 1260
@@ -1263,30 +1263,6 @@ void nf_ct_iterate_cleanup(struct net *net,
1263} 1263}
1264EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup); 1264EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
1265 1265
1266struct __nf_ct_flush_report {
1267 u32 portid;
1268 int report;
1269};
1270
1271static int kill_report(struct nf_conn *i, void *data)
1272{
1273 struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
1274 struct nf_conn_tstamp *tstamp;
1275
1276 tstamp = nf_conn_tstamp_find(i);
1277 if (tstamp && tstamp->stop == 0)
1278 tstamp->stop = ktime_to_ns(ktime_get_real());
1279
1280 /* If we fail to deliver the event, death_by_timeout() will retry */
1281 if (nf_conntrack_event_report(IPCT_DESTROY, i,
1282 fr->portid, fr->report) < 0)
1283 return 1;
1284
1285 /* Avoid the delivery of the destroy event in death_by_timeout(). */
1286 set_bit(IPS_DYING_BIT, &i->status);
1287 return 1;
1288}
1289
1290static int kill_all(struct nf_conn *i, void *data) 1266static int kill_all(struct nf_conn *i, void *data)
1291{ 1267{
1292 return 1; 1268 return 1;
@@ -1304,11 +1280,7 @@ EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1304 1280
1305void nf_conntrack_flush_report(struct net *net, u32 portid, int report) 1281void nf_conntrack_flush_report(struct net *net, u32 portid, int report)
1306{ 1282{
1307 struct __nf_ct_flush_report fr = { 1283 nf_ct_iterate_cleanup(net, kill_all, NULL, portid, report);
1308 .portid = portid,
1309 .report = report,
1310 };
1311 nf_ct_iterate_cleanup(net, kill_report, &fr);
1312} 1284}
1313EXPORT_SYMBOL_GPL(nf_conntrack_flush_report); 1285EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
1314 1286
@@ -1389,7 +1361,7 @@ void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
1389i_see_dead_people: 1361i_see_dead_people:
1390 busy = 0; 1362 busy = 0;
1391 list_for_each_entry(net, net_exit_list, exit_list) { 1363 list_for_each_entry(net, net_exit_list, exit_list) {
1392 nf_ct_iterate_cleanup(net, kill_all, NULL); 1364 nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0);
1393 nf_ct_release_dying_list(net); 1365 nf_ct_release_dying_list(net);
1394 if (atomic_read(&net->ct.count) != 0) 1366 if (atomic_read(&net->ct.count) != 0)
1395 busy = 1; 1367 busy = 1;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 0ab9636ac57e..ce3004156eeb 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -281,7 +281,7 @@ void nf_ct_l3proto_pernet_unregister(struct net *net,
281 nf_ct_l3proto_unregister_sysctl(net, proto); 281 nf_ct_l3proto_unregister_sysctl(net, proto);
282 282
283 /* Remove all contrack entries for this protocol */ 283 /* Remove all contrack entries for this protocol */
284 nf_ct_iterate_cleanup(net, kill_l3proto, proto); 284 nf_ct_iterate_cleanup(net, kill_l3proto, proto, 0, 0);
285} 285}
286EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister); 286EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister);
287 287
@@ -476,7 +476,7 @@ void nf_ct_l4proto_pernet_unregister(struct net *net,
476 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto); 476 nf_ct_l4proto_unregister_sysctl(net, pn, l4proto);
477 477
478 /* Remove all contrack entries for this protocol */ 478 /* Remove all contrack entries for this protocol */
479 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); 479 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto, 0, 0);
480} 480}
481EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister); 481EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);
482 482
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 038eee5c8f85..6ff808375b5e 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -497,7 +497,7 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
497 497
498 rtnl_lock(); 498 rtnl_lock();
499 for_each_net(net) 499 for_each_net(net)
500 nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); 500 nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean, 0, 0);
501 rtnl_unlock(); 501 rtnl_unlock();
502} 502}
503 503
@@ -511,7 +511,7 @@ static void nf_nat_l3proto_clean(u8 l3proto)
511 rtnl_lock(); 511 rtnl_lock();
512 512
513 for_each_net(net) 513 for_each_net(net)
514 nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); 514 nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean, 0, 0);
515 rtnl_unlock(); 515 rtnl_unlock();
516} 516}
517 517
@@ -749,7 +749,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
749{ 749{
750 struct nf_nat_proto_clean clean = {}; 750 struct nf_nat_proto_clean clean = {};
751 751
752 nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean); 752 nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
753 synchronize_rcu(); 753 synchronize_rcu();
754 nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); 754 nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
755} 755}