diff options
-rw-r--r-- | net/netfilter/nfnetlink_log.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 2002d579c3ba..a5b9680a1821 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -825,6 +825,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, struct net *net = sock_net(ctnl); struct nfnl_log_net *log = nfnl_log_pernet(net); int ret = 0; + u16 flags; if (nfula[NFULA_CFG_CMD]) { u_int8_t pf = nfmsg->nfgen_family; @@ -846,6 +847,28 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, goto out_put; } + /* Check if we support these flags in first place, dependencies should + * be there too not to break atomicity. + */ + if (nfula[NFULA_CFG_FLAGS]) { + flags = ntohs(nla_get_be16(nfula[NFULA_CFG_FLAGS])); + + if ((flags & NFULNL_CFG_F_CONNTRACK) && + !rcu_access_pointer(nfnl_ct_hook)) { +#ifdef CONFIG_MODULES + nfnl_unlock(NFNL_SUBSYS_ULOG); + request_module("ip_conntrack_netlink"); + nfnl_lock(NFNL_SUBSYS_ULOG); + if (rcu_access_pointer(nfnl_ct_hook)) { + ret = -EAGAIN; + goto out_put; + } +#endif + ret = -EOPNOTSUPP; + goto out_put; + } + } + if (cmd != NULL) { switch (cmd->command) { case NFULNL_CFG_CMD_BIND: @@ -905,26 +928,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, nfulnl_set_qthresh(inst, ntohl(qthresh)); } - if (nfula[NFULA_CFG_FLAGS]) { - u16 flags = ntohs(nla_get_be16(nfula[NFULA_CFG_FLAGS])); - - if (flags & NFULNL_CFG_F_CONNTRACK && - !rcu_access_pointer(nfnl_ct_hook)) { -#ifdef CONFIG_MODULES - nfnl_unlock(NFNL_SUBSYS_ULOG); - request_module("ip_conntrack_netlink"); - nfnl_lock(NFNL_SUBSYS_ULOG); - if (rcu_access_pointer(nfnl_ct_hook)) { - ret = -EAGAIN; - goto out; - } -#endif - ret = -EOPNOTSUPP; - goto out; - } - + if (nfula[NFULA_CFG_FLAGS]) nfulnl_set_flags(inst, flags); - } out_put: instance_put(inst); |