summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-12-18 09:42:51 +0300
committerDavid S. Miller <davem@davemloft.net>2008-01-29 01:59:06 +0300
commit051578ccbcdad3b24b621dfb652194e36759e8d5 (patch)
treed0afda1f43bd1e6de4d38e9efa4c498723e7f206
parent1e796fda00f06bac584f0e4ad8750ab9430d79d3 (diff)
downloadlinux-051578ccbcdad3b24b621dfb652194e36759e8d5.tar.xz
[NETFILTER]: nf_nat: properly use RCU for ip_nat_decode_session
We need to use rcu_assign_pointer/rcu_dereference to avoid races. Also remove an obsolete CONFIG_IP_NAT_NEEDED ifdef. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter.h11
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c6
2 files changed, 11 insertions, 6 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 0947424d01d6..1a8487325a4f 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -256,11 +256,16 @@ extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
{
-#if defined(CONFIG_IP_NF_NAT_NEEDED) || defined(CONFIG_NF_NAT_NEEDED)
+#ifdef CONFIG_NF_NAT_NEEDED
void (*decodefn)(struct sk_buff *, struct flowi *);
- if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
- decodefn(skb, fl);
+ if (family == AF_INET) {
+ rcu_read_lock();
+ decodefn = rcu_dereference(ip_nat_decode_session);
+ if (decodefn)
+ decodefn(skb, fl);
+ rcu_read_unlock();
+ }
#endif
}
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index a2b02f01cc5c..99b2c788d5a8 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -332,7 +332,7 @@ static int __init nf_nat_standalone_init(void)
#ifdef CONFIG_XFRM
BUG_ON(ip_nat_decode_session != NULL);
- ip_nat_decode_session = nat_decode_session;
+ rcu_assign_pointer(ip_nat_decode_session, nat_decode_session);
#endif
ret = nf_nat_rule_init();
if (ret < 0) {
@@ -350,7 +350,7 @@ static int __init nf_nat_standalone_init(void)
nf_nat_rule_cleanup();
cleanup_decode_session:
#ifdef CONFIG_XFRM
- ip_nat_decode_session = NULL;
+ rcu_assign_pointer(ip_nat_decode_session, NULL);
synchronize_net();
#endif
return ret;
@@ -361,7 +361,7 @@ static void __exit nf_nat_standalone_fini(void)
nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
nf_nat_rule_cleanup();
#ifdef CONFIG_XFRM
- ip_nat_decode_session = NULL;
+ rcu_assign_pointer(ip_nat_decode_session, NULL);
synchronize_net();
#endif
/* Conntrack caches are unregistered in nf_conntrack_cleanup */