aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-12-18 01:42:51 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:06 -0500
commit051578ccbcdad3b24b621dfb652194e36759e8d5 (patch)
treed0afda1f43bd1e6de4d38e9efa4c498723e7f206
parent1e796fda00f06bac584f0e4ad8750ab9430d79d3 (diff)
[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 *);
256static inline void 256static inline void
257nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) 257nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
258{ 258{
259#if defined(CONFIG_IP_NF_NAT_NEEDED) || defined(CONFIG_NF_NAT_NEEDED) 259#ifdef CONFIG_NF_NAT_NEEDED
260 void (*decodefn)(struct sk_buff *, struct flowi *); 260 void (*decodefn)(struct sk_buff *, struct flowi *);
261 261
262 if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL) 262 if (family == AF_INET) {
263 decodefn(skb, fl); 263 rcu_read_lock();
264 decodefn = rcu_dereference(ip_nat_decode_session);
265 if (decodefn)
266 decodefn(skb, fl);
267 rcu_read_unlock();
268 }
264#endif 269#endif
265} 270}
266 271
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)
332 332
333#ifdef CONFIG_XFRM 333#ifdef CONFIG_XFRM
334 BUG_ON(ip_nat_decode_session != NULL); 334 BUG_ON(ip_nat_decode_session != NULL);
335 ip_nat_decode_session = nat_decode_session; 335 rcu_assign_pointer(ip_nat_decode_session, nat_decode_session);
336#endif 336#endif
337 ret = nf_nat_rule_init(); 337 ret = nf_nat_rule_init();
338 if (ret < 0) { 338 if (ret < 0) {
@@ -350,7 +350,7 @@ static int __init nf_nat_standalone_init(void)
350 nf_nat_rule_cleanup(); 350 nf_nat_rule_cleanup();
351 cleanup_decode_session: 351 cleanup_decode_session:
352#ifdef CONFIG_XFRM 352#ifdef CONFIG_XFRM
353 ip_nat_decode_session = NULL; 353 rcu_assign_pointer(ip_nat_decode_session, NULL);
354 synchronize_net(); 354 synchronize_net();
355#endif 355#endif
356 return ret; 356 return ret;
@@ -361,7 +361,7 @@ static void __exit nf_nat_standalone_fini(void)
361 nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops)); 361 nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
362 nf_nat_rule_cleanup(); 362 nf_nat_rule_cleanup();
363#ifdef CONFIG_XFRM 363#ifdef CONFIG_XFRM
364 ip_nat_decode_session = NULL; 364 rcu_assign_pointer(ip_nat_decode_session, NULL);
365 synchronize_net(); 365 synchronize_net();
366#endif 366#endif
367 /* Conntrack caches are unregistered in nf_conntrack_cleanup */ 367 /* Conntrack caches are unregistered in nf_conntrack_cleanup */