Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 051578cc authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1e796fda
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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)
	if (family == AF_INET) {
		rcu_read_lock();
		decodefn = rcu_dereference(ip_nat_decode_session);
		if (decodefn)
			decodefn(skb, fl);
		rcu_read_unlock();
	}
#endif
}

+3 −3
Original line number Diff line number Diff line
@@ -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 */