// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * (C) 2012 Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * This software has been sponsored by Vyatta Inc. <http://www.vyatta.com>
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/rculist.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/capability.h>
#include <net/netlink.h>
#include <net/sock.h>

#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_conntrack_ecache.h>

#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <linux/netfilter/nfnetlink_cthelper.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
MODULE_DESCRIPTION("nfnl_cthelper: User-space connection tracking helpers");

struct nfnl_cthelper {
	struct list_head		list;
	struct nf_conntrack_helper	helper;
};

static LIST_HEAD(nfnl_cthelper_list);

static int
nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
			struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
	const struct nf_conn_help *help;
	struct nf_conntrack_helper *helper;

	help = nfct_help(ct);
	if (help == NULL)
		return NF_DROP;

	/* rcu_read_lock()ed by nf_hook_thresh */
	helper = rcu_dereference(help->helper);
	if (helper == NULL)
		return NF_DROP;

	/* This is a user-space helper not yet configured, skip. */
	if ((helper->flags &
	    (NF_CT_HELPER_F_USERSPACE | NF_CT_HELPER_F_CONFIGURED)) ==
	     NF_CT_HELPER_F_USERSPACE)
		return NF_ACCEPT;

	/* If the user-space helper is not available, don't block traffic. */
	return NF_QUEUE_NR(helper->queue_num) | NF_VERDICT_FLAG_QUEUE_BYPASS;
}

static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = {
	[NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, },
	[NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, },
};

static int
nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple,
			  const struct nlattr *attr)
{
	int err;
	struct nlattr *tb[NFCTH_TUPLE_MAX+1];

	err = nla_parse_nested_deprecated(tb, NFCTH_TUPLE_MAX, attr,
					  nfnl_cthelper_tuple_pol, NULL);
	if (err < 0)
		return err;

	if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM])
		return -EINVAL;

	/* Not all fields are initialized so first zero the tuple */
	memset(tuple, 0, sizeof(struct nf_conntrack_tuple));

	tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM]));
	tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]);

	return 0;
}

static int
nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct)
{
	struct nf_conn_help *help = nfct_help(ct);

	if (attr == NULL)
		return -EINVAL;

	if (help->helper->data_len == 0)
		return -EINVAL;

	nla_memcpy(help->data, attr, sizeof(help->data));
	return 0;
}

static int
nfnl_cthelper_to_nlattr(struct sk_buff *skb, const struct nf_conn *ct)
{
	const struct nf_conn_help *help = nfct_help(ct);

	if (help->helper->data_len &&
	    nla_put(skb, CTA_HELP_INFO, help->helper->data_len, &help->data))
		goto nla_put_failure;

	return 0;

nla_put_failure:
	return -ENOSPC;
}

static const struct nla_policy nfnl_cthelper_expect_pol[NFCTH_POLICY_MAX+1] = {
	[NFCTH_POLICY_NAME] = { .type = NLA_NUL_STRING,
				.len = NF_CT_HELPER_NAME_LEN-1 },
	[NFCTH_POLICY_EXPECT_MAX] = { .type = NLA_U32, },
	[NFCTH_POLICY_EXPECT_TIMEOUT] = { .type = NLA_U32, },
};

static int
nfnl_cthelper_expect_policy(struct nf_conntrack_expect_policy *expect_policy,
			    const struct nlattr *attr)
{
	int err;
	struct nlattr *tb[NFCTH_POLICY_MAX+1];

	err = nla_parse_nested_deprecated(tb, NFCTH_POLICY_MAX, attr,
					  nfnl_cthelper_expect_pol, NULL);
	if (err < 0)
		return err;

	if (!tb[NFCTH_POLICY_NAME] ||
	    !tb[NFCTH_POLICY_EXPECT_MAX] ||
	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
		return -EINVAL;

	nla_strscpy(expect_policy->name,
		    tb[NFCTH_POLICY_NAME], NF_CT_HELPER_NAME_LEN);
	expect_policy->max_expected =
		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
	if (expect_policy->max_expected > NF_CT_EXPECT_MAX_CNT)
		return -EINVAL;

	expect_policy->timeout =
		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT]));

	return 0;
}

static const struct nla_policy
nfnl_cthelper_expect_policy_set[NFCTH_POLICY_SET_MAX+1] = {
	[NFCTH_POLICY_SET_NUM] = { .type = NLA_U32, },
};

static int
nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
				  const struct nlattr *attr)
{
	int i, ret;
	struct nf_conntrack_expect_policy *expect_policy;
	struct nlattr *tb[NFCTH_POLICY_SET_MAX+1];
	unsigned int class_max;

	ret = nla_parse_nested_deprecated(tb, NFCTH_POLICY_SET_MAX, attr,
					  nfnl_cthelper_expect_policy_set,
					  NULL);
	if (ret < 0)
		return ret;

	if (!tb[NFCTH_POLICY_SET_NUM])
		return -EINVAL;

	class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
	if (class_max == 0)
		return -EINVAL;
	if (class_max > NF_CT_MAX_EXPECT_CLASSES)
		return -EOVERFLOW;

	expect_policy = kcalloc(class_max,
				sizeof(struct nf_conntrack_expect_policy),
				GFP_KERNEL);
	if (expect_policy == NULL)
		return -ENOMEM;

	for (i = 0; i < class_max; i++) {
		if (!tb[NFCTH_POLICY_SET+i])
			goto err;

		ret = nfnl_cthelper_expect_policy(&expect_policy[i],
						  tb[NFCTH_POLICY_SET+i]);
		if (ret < 0)
			goto err;
	}

	helper->expect_class_max = class_max - 1;
	helper->expect_policy = expect_policy;
	return 0;
err:
	kfree(expect_policy);
	return -EINVAL;
}

static int
nfnl_cthelper_create(const struct nlattr * const tb[],
		     struct nf_conntrack_tuple *tuple)
{
	struct nf_conntrack_helper *helper;
	struct nfnl_cthelper *nfcth;
	unsigned int size;
	int ret;

	if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN])
		return -EINVAL;

	nfcth = kzalloc(sizeof(*nfcth), GFP_KERNEL);
	if (nfcth == NULL)
		return -ENOMEM;
	helper = &nfcth->helper;

	ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY]);
	if (ret < 0)
		goto err1;

	nla_strscpy(helper->name,
		    tb[NFCTH_NAME], NF_CT_HELPER_NAME_LEN);
	size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN]));
	if (size > sizeof_field(struct nf_conn_help, data)) {
		ret = -ENOMEM;
		goto err2;
	}
	helper->data_len = size;

	helper->flags |= NF_CT_HELPER_F_USERSPACE;
	memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple));

	helper->me = THIS_MODULE;
	helper->help = nfnl_userspace_cthelper;
	helper->from_nlattr = nfnl_cthelper_from_nlattr;
	helper->to_nlattr = nfnl_cthelper_to_nlattr;

	/* Default to queue number zero, this can be updated at any time. */
	if (tb[NFCTH_QUEUE_NUM])
		helper->queue_num = ntohl(nla_get_be32(tb[NFCTH_QUEUE_NUM]));

	if (tb[NFCTH_STATUS]) {
		int status = ntohl(nla_get_be32(tb[NFCTH_STATUS]));

		switch(status) {
		case NFCT_HELPER_STATUS_ENABLED:
			helper->flags |= NF_CT_HELPER_F_CONFIGURED;
			break;
		case NFCT_HELPER_STATUS_DISABLED:
			helper->flags &= ~NF_CT_HELPER_F_CONFIGURED;
			break;
		}
	}

	ret = nf_conntrack_helper_register(helper);
	if (ret < 0)
		goto err2;

	list_add_tail(&nfcth->list, &nfnl_cthelper_list);
	return 0;
err2:
	kfree(helper->expect_policy);
err1:
	kfree(nfcth);
	return ret;
}

static int
nfnl_cthelper_update_policy_one(const struct nf_conntrack_expect_policy *policy,
				struct nf_conntrack_expect_policy *new_policy,
				const struct nlattr *attr)
{
	struct nlattr *tb[NFCTH_POLICY_MAX + 1];
	int err;

	err = nla_parse_nested_deprecated(tb, NFCTH_POLICY_MAX, attr,
					  nfnl_cthelper_expect_pol, NULL);
	if (err < 0)
		return err;

	if (!tb[NFCTH_POLICY_NAME] ||
	    !tb[NFCTH_POLICY_EXPECT_MAX] ||
	    !tb[NFCTH_POLICY_EXPECT_TIMEOUT])
		return -EINVAL;

	if (nla_strcmp(tb[NFCTH_POLICY_NAME], policy->name))
		return -EBUSY;

	new_policy->max_expected =
		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_MAX]));
	if (new_policy->max_expected > NF_CT_EXPECT_MAX_CNT)
		return -EINVAL;

	new_policy->timeout =
		ntohl(nla_get_be32(tb[NFCTH_POLICY_EXPECT_TIMEOUT]));

	return 0;
}

static int nfnl_cthelper_update_policy_all(struct nlattr *tb[],
					   struct nf_conntrack_helper *helper)
{
	struct nf_conntrack_expect_policy *new_policy;
	struct nf_conntrack_expect_policy *policy;
	int i, ret = 0;

	new_policy = kmalloc_array(helper->expect_class_max + 1,
				   sizeof(*new_policy), GFP_KERNEL);
	if (!new_policy)
		return -ENOMEM;

	/* Check first that all policy attributes are well-formed, so we don't
	 * leave things in inconsistent state on errors.
	 */
	for (i = 0; i < helper->expect_class_max + 1; i++) {

		if (!tb[NFCTH_POLICY_SET + i]) {
			ret = -EINVAL;
			goto err;
		}

		ret = nfnl_cthelper_update_policy_one(&helper->expect_policy[i],
						      &new_policy[i],
						      tb[NFCTH_POLICY_SET + i]);
		if (ret < 0)
			goto err;
	}
	/* Now we can safely update them. */
	for (i = 0; i < helper->expect_class_max + 1; i++) {
		policy = (struct nf_conntrack_expect_policy *)
				&helper->expect_policy[i];
		policy->max_expected = new_policy->max_expected;
		policy->timeout	= new_policy->timeout;
	}

err:
	kfree(new_policy);
	return ret;
}

static int nfnl_cthelper_update_policy(struct nf_conntrack_helper *helper,
				       const struct nlattr *attr)
{
	struct nlattr *tb[NFCTH_POLICY_SET_MAX + 1];
	unsigned int class_max;
	int err;

	err = nla_parse_nested_deprecated(tb, NFCTH_POLICY_SET_MAX, attr,
					  nfnl_cthelper_expect_policy_set,
					  NULL);
	if (err < 0)
		return err;

	if (!tb[NFCTH_POLICY_SET_NUM])
		return -EINVAL;

	class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
	if (helper->expect_class_max + 1 != class_max)
		return -EBUSY;

	return nfnl_cthelper_update_policy_all(tb, helper);
}

static int
nfnl_cthelper_update(const struct nlattr * const tb[],
		     struct nf_conntrack_helper *helper)
{
	int ret;

	if (tb[NFCTH_PRIV_DATA_LEN])
		return -EBUSY;

	if (tb[NFCTH_POLICY]) {
		ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]);
		if (ret < 0)
			return ret;
	}
	if (tb[NFCTH_QUEUE_NUM])
		helper->queue_num = ntohl(nla_get_be32(tb[NFCTH_QUEUE_NUM]));

	if (tb[NFCTH_STATUS]) {
		int status = ntohl(nla_get_be32(tb[NFCTH_STATUS]));

		switch(status) {
		case NFCT_HELPER_STATUS_ENABLED:
			helper->flags |= NF_CT_HELPER_F_CONFIGURED;
			break;
		case NFCT_HELPER_STATUS_DISABLED:
			helper->flags &= ~NF_CT_HELPER_F_CONFIGURED;
			break;
		}
	}
	return 0;
}

static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
			     struct sk_buff *skb, const struct nlmsghdr *nlh,
			     const struct nlattr * const tb[],
			     struct netlink_ext_ack *extack)
{
	const char *helper_name;
	struct nf_conntrack_helper *cur, *helper = NULL;
	struct nf_conntrack_tuple tuple;
	struct nfnl_cthelper *nlcth;
	int ret = 0;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE])
		return -EINVAL;

	helper_name = nla_data(tb[NFCTH_NAME]);

	ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]);
	if (ret < 0)
		return ret;

	list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
		cur = &nlcth->helper;

		if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
			continue;

		if ((tuple.src.l3num != cur->tuple.src.l3num ||
		     tuple.dst.protonum != cur->tuple.dst.protonum))
			continue;

		if (nlh->nlmsg_flags & NLM_F_EXCL)
			return -EEXIST;

		helper = cur;
		break;
	}

	if (helper == NULL)
		ret = nfnl_cthelper_create(tb, &tuple);
	else
		ret = nfnl_cthelper_update(tb, helper);

	return ret;
}

static int
nfnl_cthelper_dump_tuple(struct sk_buff *skb,
			 struct nf_conntrack_helper *helper)
{
	struct nlattr *nest_parms;

	nest_parms = nla_nest_start(skb, NFCTH_TUPLE);
	if (nest_parms == NULL)
		goto nla_put_failure;

	if (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM,
			 htons(helper->tuple.src.l3num)))
		goto nla_put_failure;

	if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->tuple.dst.protonum))
		goto nla_put_failure;

	nla_nest_end(skb, nest_parms);
	return 0;

nla_put_failure:
	return -1;
}

static int
nfnl_cthelper_dump_policy(struct sk_buff *skb,
			struct nf_conntrack_helper *helper)
{
	int i;
	struct nlattr *nest_parms1, *nest_parms2;

	nest_parms1 = nla_nest_start(skb, NFCTH_POLICY);
	if (nest_parms1 == NULL)
		goto nla_put_failure;

	if (nla_put_be32(skb, NFCTH_POLICY_SET_NUM,
			 htonl(helper->expect_class_max + 1)))
		goto nla_put_failure;

	for (i = 0; i < helper->expect_class_max + 1; i++) {
		nest_parms2 = nla_nest_start(skb, (NFCTH_POLICY_SET + i));
		if (nest_parms2 == NULL)
			goto nla_put_failure;

		if (nla_put_string(skb, NFCTH_POLICY_NAME,
				   helper->expect_policy[i].name))
			goto nla_put_failure;

		if (nla_put_be32(skb, NFCTH_POLICY_EXPECT_MAX,
				 htonl(helper->expect_policy[i].max_expected)))
			goto nla_put_failure;

		if (nla_put_be32(skb, NFCTH_POLICY_EXPECT_TIMEOUT,
				 htonl(helper->expect_policy[i].timeout)))
			goto nla_put_failure;

		nla_nest_end(skb, nest_parms2);
	}
	nla_nest_end(skb, nest_parms1);
	return 0;

nla_put_failure:
	return -1;
}

static int
nfnl_cthelper_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
			int event, struct nf_conntrack_helper *helper)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfmsg;
	unsigned int flags = portid ? NLM_F_MULTI : 0;
	int status;

	event = nfnl_msg_type(NFNL_SUBSYS_CTHELPER, event);
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
	if (nlh == NULL)
		goto nlmsg_failure;

	nfmsg = nlmsg_data(nlh);
	nfmsg->nfgen_family = AF_UNSPEC;
	nfmsg->version = NFNETLINK_V0;
	nfmsg->res_id = 0;

	if (nla_put_string(skb, NFCTH_NAME, helper->name))
		goto nla_put_failure;

	if (nla_put_be32(skb, NFCTH_QUEUE_NUM, htonl(helper->queue_num)))
		goto nla_put_failure;

	if (nfnl_cthelper_dump_tuple(skb, helper) < 0)
		goto nla_put_failure;

	if (nfnl_cthelper_dump_policy(skb, helper) < 0)
		goto nla_put_failure;

	if (nla_put_be32(skb, NFCTH_PRIV_DATA_LEN, htonl(helper->data_len)))
		goto nla_put_failure;

	if (helper->flags & NF_CT_HELPER_F_CONFIGURED)
		status = NFCT_HELPER_STATUS_ENABLED;
	else
		status = NFCT_HELPER_STATUS_DISABLED;

	if (nla_put_be32(skb, NFCTH_STATUS, htonl(status)))
		goto nla_put_failure;

	nlmsg_end(skb, nlh);
	return skb->len;

nlmsg_failure:
nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -1;
}

static int
nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct nf_conntrack_helper *cur, *last;

	rcu_read_lock();
	last = (struct nf_conntrack_helper *)cb->args[1];
	for (; cb->args[0] < nf_ct_helper_hsize; cb->args[0]++) {
restart:
		hlist_for_each_entry_rcu(cur,
				&nf_ct_helper_hash[cb->args[0]], hnode) {

			/* skip non-userspace conntrack helpers. */
			if (!(cur->flags & NF_CT_HELPER_F_USERSPACE))
				continue;

			if (cb->args[1]) {
				if (cur != last)
					continue;
				cb->args[1] = 0;
			}
			if (nfnl_cthelper_fill_info(skb,
					    NETLINK_CB(cb->skb).portid,
					    cb->nlh->nlmsg_seq,
					    NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
					    NFNL_MSG_CTHELPER_NEW, cur) < 0) {
				cb->args[1] = (unsigned long)cur;
				goto out;
			}
		}
	}
	if (cb->args[1]) {
		cb->args[1] = 0;
		goto restart;
	}
out:
	rcu_read_unlock();
	return skb->len;
}

static int nfnl_cthelper_get(struct net *net, struct sock *nfnl,
			     struct sk_buff *skb, const struct nlmsghdr *nlh,
			     const struct nlattr * const tb[],
			     struct netlink_ext_ack *extack)
{
	int ret = -ENOENT;
	struct nf_conntrack_helper *cur;
	struct sk_buff *skb2;
	char *helper_name = NULL;
	struct nf_conntrack_tuple tuple;
	struct nfnl_cthelper *nlcth;
	bool tuple_set = false;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (nlh->nlmsg_flags & NLM_F_DUMP) {
		struct netlink_dump_control c = {
			.dump = nfnl_cthelper_dump_table,
		};
		return netlink_dump_start(nfnl, skb, nlh, &c);
	}

	if (tb[NFCTH_NAME])
		helper_name = nla_data(tb[NFCTH_NAME]);

	if (tb[NFCTH_TUPLE]) {
		ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]);
		if (ret < 0)
			return ret;

		tuple_set = true;
	}

	list_for_each_entry(nlcth, &nfnl_cthelper_list, list) {
		cur = &nlcth->helper;
		if (helper_name &&
		    strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
			continue;

		if (tuple_set &&
		    (tuple.src.l3num != cur->tuple.src.l3num ||
		     tuple.dst.protonum != cur->tuple.dst.protonum))
			continue;

		skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
		if (skb2 == NULL) {
			ret = -ENOMEM;
			break;
		}

		ret = nfnl_cthelper_fill_info(skb2, NETLINK_CB(skb).portid,
					      nlh->nlmsg_seq,
					      NFNL_MSG_TYPE(nlh->nlmsg_type),
					      NFNL_MSG_CTHELPER_NEW, cur);
		if (ret <= 0) {
			kfree_skb(skb2);
			break;
		}

		ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
				      MSG_DONTWAIT);
		if (ret > 0)
			ret = 0;

		/* this avoids a loop in nfnetlink. */
		return ret == -EAGAIN ? -ENOBUFS : ret;
	}
	return ret;
}

static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
			     struct sk_buff *skb, const struct nlmsghdr *nlh,
			     const struct nlattr * const tb[],
			     struct netlink_ext_ack *extack)
{
	char *helper_name = NULL;
	struct nf_conntrack_helper *cur;
	struct nf_conntrack_tuple tuple;
	bool tuple_set = false, found = false;
	struct nfnl_cthelper *nlcth, *n;
	int j = 0, ret;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (tb[NFCTH_NAME])
		helper_name = nla_data(tb[NFCTH_NAME]);

	if (tb[NFCTH_TUPLE]) {
		ret = nfnl_cthelper_parse_tuple(&tuple, tb[NFCTH_TUPLE]);
		if (ret < 0)
			return ret;

		tuple_set = true;
	}

	ret = -ENOENT;
	list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
		cur = &nlcth->helper;
		j++;

		if (helper_name &&
		    strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
			continue;

		if (tuple_set &&
		    (tuple.src.l3num != cur->tuple.src.l3num ||
		     tuple.dst.protonum != cur->tuple.dst.protonum))
			continue;

		if (refcount_dec_if_one(&cur->refcnt)) {
			found = true;
			nf_conntrack_helper_unregister(cur);
			kfree(cur->expect_policy);

			list_del(&nlcth->list);
			kfree(nlcth);
		} else {
			ret = -EBUSY;
		}
	}

	/* Make sure we return success if we flush and there is no helpers */
	return (found || j == 0) ? 0 : ret;
}

static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = {
	[NFCTH_NAME] = { .type = NLA_NUL_STRING,
			 .len = NF_CT_HELPER_NAME_LEN-1 },
	[NFCTH_QUEUE_NUM] = { .type = NLA_U32, },
	[NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, },
	[NFCTH_STATUS] = { .type = NLA_U32, },
};

static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = {
	[NFNL_MSG_CTHELPER_NEW]		= { .call = nfnl_cthelper_new,
					    .attr_count = NFCTH_MAX,
					    .policy = nfnl_cthelper_policy },
	[NFNL_MSG_CTHELPER_GET]		= { .call = nfnl_cthelper_get,
					    .attr_count = NFCTH_MAX,
					    .policy = nfnl_cthelper_policy },
	[NFNL_MSG_CTHELPER_DEL]		= { .call = nfnl_cthelper_del,
					    .attr_count = NFCTH_MAX,
					    .policy = nfnl_cthelper_policy },
};

static const struct nfnetlink_subsystem nfnl_cthelper_subsys = {
	.name				= "cthelper",
	.subsys_id			= NFNL_SUBSYS_CTHELPER,
	.cb_count			= NFNL_MSG_CTHELPER_MAX,
	.cb				= nfnl_cthelper_cb,
};

MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTHELPER);

static int __init nfnl_cthelper_init(void)
{
	int ret;

	ret = nfnetlink_subsys_register(&nfnl_cthelper_subsys);
	if (ret < 0) {
		pr_err("nfnl_cthelper: cannot register with nfnetlink.\n");
		goto err_out;
	}
	return 0;
err_out:
	return ret;
}

static void __exit nfnl_cthelper_exit(void)
{
	struct nf_conntrack_helper *cur;
	struct nfnl_cthelper *nlcth, *n;

	nfnetlink_subsys_unregister(&nfnl_cthelper_subsys);

	list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
		cur = &nlcth->helper;

		nf_conntrack_helper_unregister(cur);
		kfree(cur->expect_policy);
		kfree(nlcth);
	}
}

module_init(nfnl_cthelper_init);
module_exit(nfnl_cthelper_exit);
