diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-10-14 11:58:31 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-14 11:58:31 -0700 |
commit | e6a7d3c04f8fe49099521e6dc9a46b0272381f2f (patch) | |
tree | 4717fcfe05549d39c9281b3b23310b775ad38d16 /net/netfilter/nfnetlink.c | |
parent | 129404a1f117c35c6224e020444fc27eb4479817 (diff) |
netfilter: ctnetlink: remove bogus module dependency between ctnetlink and nf_nat
This patch removes the module dependency between ctnetlink and
nf_nat by means of an indirect call that is initialized when
nf_nat is loaded. Now, nf_conntrack_netlink only requires
nf_conntrack and nfnetlink.
This patch puts nfnetlink_parse_nat_setup_hook into the
nf_conntrack_core to avoid dependencies between ctnetlink,
nf_conntrack_ipv4 and nf_conntrack_ipv6.
This patch also introduces the function ctnetlink_change_nat
that is only invoked from the creation path. Actually, the
nat handling cannot be invoked from the update path since
this is not allowed. By introducing this function, we remove
the useless nat handling in the update path and we avoid
deadlock-prone code.
This patch also adds the required EAGAIN logic for nfnetlink.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/nfnetlink.c')
-rw-r--r-- | net/netfilter/nfnetlink.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index b75c9c4a995d..4739f9f961d8 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -44,15 +44,17 @@ static struct sock *nfnl = NULL; static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; static DEFINE_MUTEX(nfnl_mutex); -static inline void nfnl_lock(void) +void nfnl_lock(void) { mutex_lock(&nfnl_mutex); } +EXPORT_SYMBOL_GPL(nfnl_lock); -static inline void nfnl_unlock(void) +void nfnl_unlock(void) { mutex_unlock(&nfnl_mutex); } +EXPORT_SYMBOL_GPL(nfnl_unlock); int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) { @@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return 0; type = nlh->nlmsg_type; +replay: ss = nfnetlink_get_subsys(type); if (!ss) { #ifdef CONFIG_KMOD @@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } else return -EINVAL; - return nc->call(nfnl, skb, nlh, cda); + err = nc->call(nfnl, skb, nlh, cda); + if (err == -EAGAIN) + goto replay; + return err; } } |