[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>
This commit is contained in:
committed by
David S. Miller
parent
1e796fda00
commit
051578ccbc
@@ -256,11 +256,16 @@ extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
|
|||||||
static inline void
|
static inline void
|
||||||
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
|
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 *);
|
void (*decodefn)(struct sk_buff *, struct flowi *);
|
||||||
|
|
||||||
if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
|
if (family == AF_INET) {
|
||||||
decodefn(skb, fl);
|
rcu_read_lock();
|
||||||
|
decodefn = rcu_dereference(ip_nat_decode_session);
|
||||||
|
if (decodefn)
|
||||||
|
decodefn(skb, fl);
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -332,7 +332,7 @@ static int __init nf_nat_standalone_init(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_XFRM
|
#ifdef CONFIG_XFRM
|
||||||
BUG_ON(ip_nat_decode_session != NULL);
|
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
|
#endif
|
||||||
ret = nf_nat_rule_init();
|
ret = nf_nat_rule_init();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -350,7 +350,7 @@ static int __init nf_nat_standalone_init(void)
|
|||||||
nf_nat_rule_cleanup();
|
nf_nat_rule_cleanup();
|
||||||
cleanup_decode_session:
|
cleanup_decode_session:
|
||||||
#ifdef CONFIG_XFRM
|
#ifdef CONFIG_XFRM
|
||||||
ip_nat_decode_session = NULL;
|
rcu_assign_pointer(ip_nat_decode_session, NULL);
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
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_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
|
||||||
nf_nat_rule_cleanup();
|
nf_nat_rule_cleanup();
|
||||||
#ifdef CONFIG_XFRM
|
#ifdef CONFIG_XFRM
|
||||||
ip_nat_decode_session = NULL;
|
rcu_assign_pointer(ip_nat_decode_session, NULL);
|
||||||
synchronize_net();
|
synchronize_net();
|
||||||
#endif
|
#endif
|
||||||
/* Conntrack caches are unregistered in nf_conntrack_cleanup */
|
/* Conntrack caches are unregistered in nf_conntrack_cleanup */
|
||||||
|
Reference in New Issue
Block a user