]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/netfilter/nf_conntrack_ecache.c
netfilter: use rcu_dereference_protected()
[net-next-2.6.git] / net / netfilter / nf_conntrack_ecache.c
index 849614af23228707d3849762370cae5ec1db25af..cdcc7649476b60e0e8584a7c2b2d31e7509a4bd4 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/percpu.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/slab.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
@@ -81,9 +82,12 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
 {
        int ret = 0;
+       struct nf_ct_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       if (nf_conntrack_event_cb != NULL) {
+       notify = rcu_dereference_protected(nf_conntrack_event_cb,
+                                          lockdep_is_held(&nf_ct_ecache_mutex));
+       if (notify != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
@@ -99,8 +103,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
 void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
 {
+       struct nf_ct_event_notifier *notify;
+
        mutex_lock(&nf_ct_ecache_mutex);
-       BUG_ON(nf_conntrack_event_cb != new);
+       notify = rcu_dereference_protected(nf_conntrack_event_cb,
+                                          lockdep_is_held(&nf_ct_ecache_mutex));
+       BUG_ON(notify != new);
        rcu_assign_pointer(nf_conntrack_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
@@ -109,9 +117,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
 {
        int ret = 0;
+       struct nf_exp_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       if (nf_expect_event_cb != NULL) {
+       notify = rcu_dereference_protected(nf_expect_event_cb,
+                                          lockdep_is_held(&nf_ct_ecache_mutex));
+       if (notify != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
@@ -127,8 +138,12 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
 void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
 {
+       struct nf_exp_event_notifier *notify;
+
        mutex_lock(&nf_ct_ecache_mutex);
-       BUG_ON(nf_expect_event_cb != new);
+       notify = rcu_dereference_protected(nf_expect_event_cb,
+                                          lockdep_is_held(&nf_ct_ecache_mutex));
+       BUG_ON(notify != new);
        rcu_assign_pointer(nf_expect_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }