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 */