netfilter: add struct nf_nat_hook and use it

Move decode_session() and parse_nat_setup_hook() indirections to struct
nf_nat_hook structure.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Pablo Neira Ayuso 2018-05-23 09:17:19 +02:00
parent 1f4b24397d
commit 2c205dd398
6 changed files with 36 additions and 38 deletions

View File

@ -320,18 +320,29 @@ int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry); int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry);
#include <net/flow.h> #include <net/flow.h>
extern void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
struct nf_conn;
enum nf_nat_manip_type;
struct nlattr;
struct nf_nat_hook {
int (*parse_nat_setup)(struct nf_conn *ct, enum nf_nat_manip_type manip,
const struct nlattr *attr);
void (*decode_session)(struct sk_buff *skb, struct flowi *fl);
};
extern struct nf_nat_hook __rcu *nf_nat_hook;
static inline void static inline void
nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
{ {
#ifdef CONFIG_NF_NAT_NEEDED #ifdef CONFIG_NF_NAT_NEEDED
void (*decodefn)(struct sk_buff *, struct flowi *); struct nf_nat_hook *nat_hook;
rcu_read_lock(); rcu_read_lock();
decodefn = rcu_dereference(nf_nat_decode_session_hook); nat_hook = rcu_dereference(nf_nat_hook);
if (decodefn) if (nat_hook->decode_session)
decodefn(skb, fl); nat_hook->decode_session(skb, fl);
rcu_read_unlock(); rcu_read_unlock();
#endif #endif
} }

View File

@ -26,11 +26,4 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
return ct->status & IPS_DST_NAT_DONE; return ct->status & IPS_DST_NAT_DONE;
} }
struct nlattr;
extern int
(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
enum nf_nat_manip_type manip,
const struct nlattr *attr);
#endif /* _NF_NAT_CORE_H */ #endif /* _NF_NAT_CORE_H */

View File

@ -574,6 +574,9 @@ void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *)
__rcu __read_mostly; __rcu __read_mostly;
EXPORT_SYMBOL(ip_ct_attach); EXPORT_SYMBOL(ip_ct_attach);
struct nf_nat_hook __rcu *nf_nat_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_hook);
void nf_ct_attach(struct sk_buff *new, const struct sk_buff *skb) void nf_ct_attach(struct sk_buff *new, const struct sk_buff *skb)
{ {
void (*attach)(struct sk_buff *, const struct sk_buff *); void (*attach)(struct sk_buff *, const struct sk_buff *);
@ -608,11 +611,6 @@ const struct nf_conntrack_zone nf_ct_zone_dflt = {
EXPORT_SYMBOL_GPL(nf_ct_zone_dflt); EXPORT_SYMBOL_GPL(nf_ct_zone_dflt);
#endif /* CONFIG_NF_CONNTRACK */ #endif /* CONFIG_NF_CONNTRACK */
#ifdef CONFIG_NF_NAT_NEEDED
void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
EXPORT_SYMBOL(nf_nat_decode_session_hook);
#endif
static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max) static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max)
{ {
int h; int h;

View File

@ -58,11 +58,6 @@
#include "nf_internals.h" #include "nf_internals.h"
int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
enum nf_nat_manip_type manip,
const struct nlattr *attr) __read_mostly;
EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
__cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS]; __cacheline_aligned_in_smp spinlock_t nf_conntrack_locks[CONNTRACK_LOCKS];
EXPORT_SYMBOL_GPL(nf_conntrack_locks); EXPORT_SYMBOL_GPL(nf_conntrack_locks);

View File

@ -1431,11 +1431,11 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
enum nf_nat_manip_type manip, enum nf_nat_manip_type manip,
const struct nlattr *attr) const struct nlattr *attr)
{ {
typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup; struct nf_nat_hook *nat_hook;
int err; int err;
parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook); nat_hook = rcu_dereference(nf_nat_hook);
if (!parse_nat_setup) { if (!nat_hook) {
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
rcu_read_unlock(); rcu_read_unlock();
nfnl_unlock(NFNL_SUBSYS_CTNETLINK); nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
@ -1446,13 +1446,13 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
} }
nfnl_lock(NFNL_SUBSYS_CTNETLINK); nfnl_lock(NFNL_SUBSYS_CTNETLINK);
rcu_read_lock(); rcu_read_lock();
if (nfnetlink_parse_nat_setup_hook) if (nat_hook->parse_nat_setup)
return -EAGAIN; return -EAGAIN;
#endif #endif
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
err = parse_nat_setup(ct, manip, attr); err = nat_hook->parse_nat_setup(ct, manip, attr);
if (err == -EAGAIN) { if (err == -EAGAIN) {
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
rcu_read_unlock(); rcu_read_unlock();

View File

@ -1026,6 +1026,13 @@ static struct pernet_operations nat_net_ops = {
.size = sizeof(struct nat_net), .size = sizeof(struct nat_net),
}; };
struct nf_nat_hook nat_hook = {
.parse_nat_setup = nfnetlink_parse_nat_setup,
#ifdef CONFIG_XFRM
.decode_session = __nf_nat_decode_session,
#endif
};
static int __init nf_nat_init(void) static int __init nf_nat_init(void)
{ {
int ret, i; int ret, i;
@ -1057,13 +1064,9 @@ static int __init nf_nat_init(void)
nf_ct_helper_expectfn_register(&follow_master_nat); nf_ct_helper_expectfn_register(&follow_master_nat);
BUG_ON(nfnetlink_parse_nat_setup_hook != NULL); WARN_ON(nf_nat_hook != NULL);
RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, RCU_INIT_POINTER(nf_nat_hook, &nat_hook);
nfnetlink_parse_nat_setup);
#ifdef CONFIG_XFRM
BUG_ON(nf_nat_decode_session_hook != NULL);
RCU_INIT_POINTER(nf_nat_decode_session_hook, __nf_nat_decode_session);
#endif
return 0; return 0;
} }
@ -1076,10 +1079,8 @@ static void __exit nf_nat_cleanup(void)
nf_ct_extend_unregister(&nat_extend); nf_ct_extend_unregister(&nat_extend);
nf_ct_helper_expectfn_unregister(&follow_master_nat); nf_ct_helper_expectfn_unregister(&follow_master_nat);
RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL); RCU_INIT_POINTER(nf_nat_hook, NULL);
#ifdef CONFIG_XFRM
RCU_INIT_POINTER(nf_nat_decode_session_hook, NULL);
#endif
synchronize_rcu(); synchronize_rcu();
for (i = 0; i < NFPROTO_NUMPROTO; i++) for (i = 0; i < NFPROTO_NUMPROTO; i++)