diff options
author | Florian Westphal <fw@strlen.de> | 2013-07-29 09:41:55 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-08-09 06:03:33 -0400 |
commit | c655bc6896b94ee0223393f26155c6daf1e2d148 (patch) | |
tree | 493664303eefd739303a67b891c0f7f89c92eb09 /net | |
parent | 54e35cc52346149a7bce8a2f622e215ed17bb56d (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.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_MASQUERADE.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 36 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto.c | 4 | ||||
-rw-r--r-- | net/netfilter/nf_nat_core.c | 6 |
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 | ||
1247 | void nf_ct_iterate_cleanup(struct net *net, | 1247 | void 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 | } |
1264 | EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup); | 1264 | EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup); |
1265 | 1265 | ||
1266 | struct __nf_ct_flush_report { | ||
1267 | u32 portid; | ||
1268 | int report; | ||
1269 | }; | ||
1270 | |||
1271 | static 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 | |||
1290 | static int kill_all(struct nf_conn *i, void *data) | 1266 | static 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 | ||
1305 | void nf_conntrack_flush_report(struct net *net, u32 portid, int report) | 1281 | void 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 | } |
1313 | EXPORT_SYMBOL_GPL(nf_conntrack_flush_report); | 1285 | EXPORT_SYMBOL_GPL(nf_conntrack_flush_report); |
1314 | 1286 | ||
@@ -1389,7 +1361,7 @@ void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list) | |||
1389 | i_see_dead_people: | 1361 | i_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 | } |
286 | EXPORT_SYMBOL_GPL(nf_ct_l3proto_pernet_unregister); | 286 | EXPORT_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 | } |
481 | EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister); | 481 | EXPORT_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 | } |