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
}
#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) {
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;
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 */