// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * NetLabel CIPSO/IPv4 Support
 *
 * This file defines the CIPSO/IPv4 functions for the NetLabel system.  The
 * NetLabel system manages static and dynamic label mappings for network
 * protocols such as CIPSO and RIPSO.
 *
 * Author: Paul Moore <paul@paul-moore.com>
 */

/*
 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
 */

#include <linux/types.h>
#include <linux/socket.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/audit.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <linux/atomic.h>

#include "netlabel_user.h"
#include "netlabel_cipso_v4.h"
#include "netlabel_mgmt.h"
#include "netlabel_domainhash.h"

/* Argument struct for cipso_v4_doi_walk() */
struct netlbl_cipsov4_doiwalk_arg {
	struct netlink_callback *nl_cb;
	struct sk_buff *skb;
	u32 seq;
};

/* Argument struct for netlbl_domhsh_walk() */
struct netlbl_domhsh_walk_arg {
	struct netlbl_audit *audit_info;
	u32 doi;
};

/* NetLabel Generic NETLINK CIPSOv4 family */
static struct genl_family netlbl_cipsov4_gnl_family;
/* NetLabel Netlink attribute policy */
static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = {
	[NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 },
	[NLBL_CIPSOV4_A_TAGLST] = { .type = NLA_NESTED },
	[NLBL_CIPSOV4_A_MLSLVLLOC] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_MLSLVLREM] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_MLSLVL] = { .type = NLA_NESTED },
	[NLBL_CIPSOV4_A_MLSLVLLST] = { .type = NLA_NESTED },
	[NLBL_CIPSOV4_A_MLSCATLOC] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_MLSCATREM] = { .type = NLA_U32 },
	[NLBL_CIPSOV4_A_MLSCAT] = { .type = NLA_NESTED },
	[NLBL_CIPSOV4_A_MLSCATLST] = { .type = NLA_NESTED },
};

/*
 * Helper Functions
 */

/**
 * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
 * @info: the Generic NETLINK info block
 * @doi_def: the CIPSO V4 DOI definition
 *
 * Description:
 * Parse the common sections of a ADD message and fill in the related values
 * in @doi_def.  Returns zero on success, negative values on failure.
 *
 */
static int netlbl_cipsov4_add_common(struct genl_info *info,
				     struct cipso_v4_doi *doi_def)
{
	struct nlattr *nla;
	int nla_rem;
	u32 iter = 0;

	doi_def->doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);

	if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_TAGLST],
					   NLBL_CIPSOV4_A_MAX,
					   netlbl_cipsov4_genl_policy,
					   NULL) != 0)
		return -EINVAL;

	nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
		if (nla_type(nla) == NLBL_CIPSOV4_A_TAG) {
			if (iter >= CIPSO_V4_TAG_MAXCNT)
				return -EINVAL;
			doi_def->tags[iter++] = nla_get_u8(nla);
		}
	while (iter < CIPSO_V4_TAG_MAXCNT)
		doi_def->tags[iter++] = CIPSO_V4_TAG_INVALID;

	return 0;
}

/*
 * NetLabel Command Handlers
 */

/**
 * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
 * @info: the Generic NETLINK info block
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
 * message and add it to the CIPSO V4 engine.  Return zero on success and
 * non-zero on error.
 *
 */
static int netlbl_cipsov4_add_std(struct genl_info *info,
				  struct netlbl_audit *audit_info)
{
	int ret_val = -EINVAL;
	struct cipso_v4_doi *doi_def = NULL;
	struct nlattr *nla_a;
	struct nlattr *nla_b;
	int nla_a_rem;
	int nla_b_rem;
	u32 iter;

	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
	    !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
		return -EINVAL;

	if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
					   NLBL_CIPSOV4_A_MAX,
					   netlbl_cipsov4_genl_policy,
					   NULL) != 0)
		return -EINVAL;

	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
	if (doi_def == NULL)
		return -ENOMEM;
	doi_def->map.std = kzalloc(sizeof(*doi_def->map.std), GFP_KERNEL);
	if (doi_def->map.std == NULL) {
		kfree(doi_def);
		return -ENOMEM;
	}
	doi_def->type = CIPSO_V4_MAP_TRANS;

	ret_val = netlbl_cipsov4_add_common(info, doi_def);
	if (ret_val != 0)
		goto add_std_failure;
	ret_val = -EINVAL;

	nla_for_each_nested(nla_a,
			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
			    nla_a_rem)
		if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
			if (nla_validate_nested_deprecated(nla_a,
							   NLBL_CIPSOV4_A_MAX,
							   netlbl_cipsov4_genl_policy,
							   NULL) != 0)
				goto add_std_failure;
			nla_for_each_nested(nla_b, nla_a, nla_b_rem)
				switch (nla_type(nla_b)) {
				case NLBL_CIPSOV4_A_MLSLVLLOC:
					if (nla_get_u32(nla_b) >
					    CIPSO_V4_MAX_LOC_LVLS)
						goto add_std_failure;
					if (nla_get_u32(nla_b) >=
					    doi_def->map.std->lvl.local_size)
					     doi_def->map.std->lvl.local_size =
						     nla_get_u32(nla_b) + 1;
					break;
				case NLBL_CIPSOV4_A_MLSLVLREM:
					if (nla_get_u32(nla_b) >
					    CIPSO_V4_MAX_REM_LVLS)
						goto add_std_failure;
					if (nla_get_u32(nla_b) >=
					    doi_def->map.std->lvl.cipso_size)
					     doi_def->map.std->lvl.cipso_size =
						     nla_get_u32(nla_b) + 1;
					break;
				}
		}
	doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
					      sizeof(u32),
					      GFP_KERNEL | __GFP_NOWARN);
	if (doi_def->map.std->lvl.local == NULL) {
		ret_val = -ENOMEM;
		goto add_std_failure;
	}
	doi_def->map.std->lvl.cipso = kcalloc(doi_def->map.std->lvl.cipso_size,
					      sizeof(u32),
					      GFP_KERNEL | __GFP_NOWARN);
	if (doi_def->map.std->lvl.cipso == NULL) {
		ret_val = -ENOMEM;
		goto add_std_failure;
	}
	for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
		doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
	for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
		doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
	nla_for_each_nested(nla_a,
			    info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
			    nla_a_rem)
		if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSLVL) {
			struct nlattr *lvl_loc;
			struct nlattr *lvl_rem;

			lvl_loc = nla_find_nested(nla_a,
						  NLBL_CIPSOV4_A_MLSLVLLOC);
			lvl_rem = nla_find_nested(nla_a,
						  NLBL_CIPSOV4_A_MLSLVLREM);
			if (lvl_loc == NULL || lvl_rem == NULL)
				goto add_std_failure;
			doi_def->map.std->lvl.local[nla_get_u32(lvl_loc)] =
				nla_get_u32(lvl_rem);
			doi_def->map.std->lvl.cipso[nla_get_u32(lvl_rem)] =
				nla_get_u32(lvl_loc);
		}

	if (info->attrs[NLBL_CIPSOV4_A_MLSCATLST]) {
		if (nla_validate_nested_deprecated(info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
						   NLBL_CIPSOV4_A_MAX,
						   netlbl_cipsov4_genl_policy,
						   NULL) != 0)
			goto add_std_failure;

		nla_for_each_nested(nla_a,
				    info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
				    nla_a_rem)
			if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
				if (nla_validate_nested_deprecated(nla_a,
								   NLBL_CIPSOV4_A_MAX,
								   netlbl_cipsov4_genl_policy,
								   NULL) != 0)
					goto add_std_failure;
				nla_for_each_nested(nla_b, nla_a, nla_b_rem)
					switch (nla_type(nla_b)) {
					case NLBL_CIPSOV4_A_MLSCATLOC:
						if (nla_get_u32(nla_b) >
						    CIPSO_V4_MAX_LOC_CATS)
							goto add_std_failure;
						if (nla_get_u32(nla_b) >=
					      doi_def->map.std->cat.local_size)
					     doi_def->map.std->cat.local_size =
						     nla_get_u32(nla_b) + 1;
						break;
					case NLBL_CIPSOV4_A_MLSCATREM:
						if (nla_get_u32(nla_b) >
						    CIPSO_V4_MAX_REM_CATS)
							goto add_std_failure;
						if (nla_get_u32(nla_b) >=
					      doi_def->map.std->cat.cipso_size)
					     doi_def->map.std->cat.cipso_size =
						     nla_get_u32(nla_b) + 1;
						break;
					}
			}
		doi_def->map.std->cat.local = kcalloc(
					      doi_def->map.std->cat.local_size,
					      sizeof(u32),
					      GFP_KERNEL | __GFP_NOWARN);
		if (doi_def->map.std->cat.local == NULL) {
			ret_val = -ENOMEM;
			goto add_std_failure;
		}
		doi_def->map.std->cat.cipso = kcalloc(
					      doi_def->map.std->cat.cipso_size,
					      sizeof(u32),
					      GFP_KERNEL | __GFP_NOWARN);
		if (doi_def->map.std->cat.cipso == NULL) {
			ret_val = -ENOMEM;
			goto add_std_failure;
		}
		for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
			doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
		for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
			doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
		nla_for_each_nested(nla_a,
				    info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
				    nla_a_rem)
			if (nla_type(nla_a) == NLBL_CIPSOV4_A_MLSCAT) {
				struct nlattr *cat_loc;
				struct nlattr *cat_rem;

				cat_loc = nla_find_nested(nla_a,
						     NLBL_CIPSOV4_A_MLSCATLOC);
				cat_rem = nla_find_nested(nla_a,
						     NLBL_CIPSOV4_A_MLSCATREM);
				if (cat_loc == NULL || cat_rem == NULL)
					goto add_std_failure;
				doi_def->map.std->cat.local[
							nla_get_u32(cat_loc)] =
					nla_get_u32(cat_rem);
				doi_def->map.std->cat.cipso[
							nla_get_u32(cat_rem)] =
					nla_get_u32(cat_loc);
			}
	}

	ret_val = cipso_v4_doi_add(doi_def, audit_info);
	if (ret_val != 0)
		goto add_std_failure;
	return 0;

add_std_failure:
	cipso_v4_doi_free(doi_def);
	return ret_val;
}

/**
 * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
 * @info: the Generic NETLINK info block
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
 * and add it to the CIPSO V4 engine.  Return zero on success and non-zero on
 * error.
 *
 */
static int netlbl_cipsov4_add_pass(struct genl_info *info,
				   struct netlbl_audit *audit_info)
{
	int ret_val;
	struct cipso_v4_doi *doi_def = NULL;

	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
		return -EINVAL;

	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
	if (doi_def == NULL)
		return -ENOMEM;
	doi_def->type = CIPSO_V4_MAP_PASS;

	ret_val = netlbl_cipsov4_add_common(info, doi_def);
	if (ret_val != 0)
		goto add_pass_failure;

	ret_val = cipso_v4_doi_add(doi_def, audit_info);
	if (ret_val != 0)
		goto add_pass_failure;
	return 0;

add_pass_failure:
	cipso_v4_doi_free(doi_def);
	return ret_val;
}

/**
 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
 * @info: the Generic NETLINK info block
 * @audit_info: NetLabel audit information
 *
 * Description:
 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
 * message and add it to the CIPSO V4 engine.  Return zero on success and
 * non-zero on error.
 *
 */
static int netlbl_cipsov4_add_local(struct genl_info *info,
				    struct netlbl_audit *audit_info)
{
	int ret_val;
	struct cipso_v4_doi *doi_def = NULL;

	if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
		return -EINVAL;

	doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
	if (doi_def == NULL)
		return -ENOMEM;
	doi_def->type = CIPSO_V4_MAP_LOCAL;

	ret_val = netlbl_cipsov4_add_common(info, doi_def);
	if (ret_val != 0)
		goto add_local_failure;

	ret_val = cipso_v4_doi_add(doi_def, audit_info);
	if (ret_val != 0)
		goto add_local_failure;
	return 0;

add_local_failure:
	cipso_v4_doi_free(doi_def);
	return ret_val;
}

/**
 * netlbl_cipsov4_add - Handle an ADD message
 * @skb: the NETLINK buffer
 * @info: the Generic NETLINK info block
 *
 * Description:
 * Create a new DOI definition based on the given ADD message and add it to the
 * CIPSO V4 engine.  Returns zero on success, negative values on failure.
 *
 */
static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)

{
	int ret_val = -EINVAL;
	struct netlbl_audit audit_info;

	if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
	    !info->attrs[NLBL_CIPSOV4_A_MTYPE])
		return -EINVAL;

	netlbl_netlink_auditinfo(&audit_info);
	switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
	case CIPSO_V4_MAP_TRANS:
		ret_val = netlbl_cipsov4_add_std(info, &audit_info);
		break;
	case CIPSO_V4_MAP_PASS:
		ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
		break;
	case CIPSO_V4_MAP_LOCAL:
		ret_val = netlbl_cipsov4_add_local(info, &audit_info);
		break;
	}
	if (ret_val == 0)
		atomic_inc(&netlabel_mgmt_protocount);

	return ret_val;
}

/**
 * netlbl_cipsov4_list - Handle a LIST message
 * @skb: the NETLINK buffer
 * @info: the Generic NETLINK info block
 *
 * Description:
 * Process a user generated LIST message and respond accordingly.  While the
 * response message generated by the kernel is straightforward, determining
 * before hand the size of the buffer to allocate is not (we have to generate
 * the message to know the size).  In order to keep this function sane what we
 * do is allocate a buffer of NLMSG_GOODSIZE and try to fit the response in
 * that size, if we fail then we restart with a larger buffer and try again.
 * We continue in this manner until we hit a limit of failed attempts then we
 * give up and just send an error message.  Returns zero on success and
 * negative values on error.
 *
 */
static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info)
{
	int ret_val;
	struct sk_buff *ans_skb = NULL;
	u32 nlsze_mult = 1;
	void *data;
	u32 doi;
	struct nlattr *nla_a;
	struct nlattr *nla_b;
	struct cipso_v4_doi *doi_def;
	u32 iter;

	if (!info->attrs[NLBL_CIPSOV4_A_DOI]) {
		ret_val = -EINVAL;
		goto list_failure;
	}

list_start:
	ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE * nlsze_mult, GFP_KERNEL);
	if (ans_skb == NULL) {
		ret_val = -ENOMEM;
		goto list_failure;
	}
	data = genlmsg_put_reply(ans_skb, info, &netlbl_cipsov4_gnl_family,
				 0, NLBL_CIPSOV4_C_LIST);
	if (data == NULL) {
		ret_val = -ENOMEM;
		goto list_failure;
	}

	doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);

	rcu_read_lock();
	doi_def = cipso_v4_doi_getdef(doi);
	if (doi_def == NULL) {
		ret_val = -EINVAL;
		goto list_failure_lock;
	}

	ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
	if (ret_val != 0)
		goto list_failure_lock;

	nla_a = nla_nest_start_noflag(ans_skb, NLBL_CIPSOV4_A_TAGLST);
	if (nla_a == NULL) {
		ret_val = -ENOMEM;
		goto list_failure_lock;
	}
	for (iter = 0;
	     iter < CIPSO_V4_TAG_MAXCNT &&
	       doi_def->tags[iter] != CIPSO_V4_TAG_INVALID;
	     iter++) {
		ret_val = nla_put_u8(ans_skb,
				     NLBL_CIPSOV4_A_TAG,
				     doi_def->tags[iter]);
		if (ret_val != 0)
			goto list_failure_lock;
	}
	nla_nest_end(ans_skb, nla_a);

	switch (doi_def->type) {
	case CIPSO_V4_MAP_TRANS:
		nla_a = nla_nest_start_noflag(ans_skb,
					      NLBL_CIPSOV4_A_MLSLVLLST);
		if (nla_a == NULL) {
			ret_val = -ENOMEM;
			goto list_failure_lock;
		}
		for (iter = 0;
		     iter < doi_def->map.std->lvl.local_size;
		     iter++) {
			if (doi_def->map.std->lvl.local[iter] ==
			    CIPSO_V4_INV_LVL)
				continue;

			nla_b = nla_nest_start_noflag(ans_skb,
						      NLBL_CIPSOV4_A_MLSLVL);
			if (nla_b == NULL) {
				ret_val = -ENOMEM;
				goto list_retry;
			}
			ret_val = nla_put_u32(ans_skb,
					      NLBL_CIPSOV4_A_MLSLVLLOC,
					      iter);
			if (ret_val != 0)
				goto list_retry;
			ret_val = nla_put_u32(ans_skb,
					    NLBL_CIPSOV4_A_MLSLVLREM,
					    doi_def->map.std->lvl.local[iter]);
			if (ret_val != 0)
				goto list_retry;
			nla_nest_end(ans_skb, nla_b);
		}
		nla_nest_end(ans_skb, nla_a);

		nla_a = nla_nest_start_noflag(ans_skb,
					      NLBL_CIPSOV4_A_MLSCATLST);
		if (nla_a == NULL) {
			ret_val = -ENOMEM;
			goto list_retry;
		}
		for (iter = 0;
		     iter < doi_def->map.std->cat.local_size;
		     iter++) {
			if (doi_def->map.std->cat.local[iter] ==
			    CIPSO_V4_INV_CAT)
				continue;

			nla_b = nla_nest_start_noflag(ans_skb,
						      NLBL_CIPSOV4_A_MLSCAT);
			if (nla_b == NULL) {
				ret_val = -ENOMEM;
				goto list_retry;
			}
			ret_val = nla_put_u32(ans_skb,
					      NLBL_CIPSOV4_A_MLSCATLOC,
					      iter);
			if (ret_val != 0)
				goto list_retry;
			ret_val = nla_put_u32(ans_skb,
					    NLBL_CIPSOV4_A_MLSCATREM,
					    doi_def->map.std->cat.local[iter]);
			if (ret_val != 0)
				goto list_retry;
			nla_nest_end(ans_skb, nla_b);
		}
		nla_nest_end(ans_skb, nla_a);

		break;
	}
	cipso_v4_doi_putdef(doi_def);
	rcu_read_unlock();

	genlmsg_end(ans_skb, data);
	return genlmsg_reply(ans_skb, info);

list_retry:
	/* XXX - this limit is a guesstimate */
	if (nlsze_mult < 4) {
		cipso_v4_doi_putdef(doi_def);
		rcu_read_unlock();
		kfree_skb(ans_skb);
		nlsze_mult *= 2;
		goto list_start;
	}
list_failure_lock:
	cipso_v4_doi_putdef(doi_def);
	rcu_read_unlock();
list_failure:
	kfree_skb(ans_skb);
	return ret_val;
}

/**
 * netlbl_cipsov4_listall_cb - cipso_v4_doi_walk() callback for LISTALL
 * @doi_def: the CIPSOv4 DOI definition
 * @arg: the netlbl_cipsov4_doiwalk_arg structure
 *
 * Description:
 * This function is designed to be used as a callback to the
 * cipso_v4_doi_walk() function for use in generating a response for a LISTALL
 * message.  Returns the size of the message on success, negative values on
 * failure.
 *
 */
static int netlbl_cipsov4_listall_cb(struct cipso_v4_doi *doi_def, void *arg)
{
	int ret_val = -ENOMEM;
	struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg;
	void *data;

	data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
			   cb_arg->seq, &netlbl_cipsov4_gnl_family,
			   NLM_F_MULTI, NLBL_CIPSOV4_C_LISTALL);
	if (data == NULL)
		goto listall_cb_failure;

	ret_val = nla_put_u32(cb_arg->skb, NLBL_CIPSOV4_A_DOI, doi_def->doi);
	if (ret_val != 0)
		goto listall_cb_failure;
	ret_val = nla_put_u32(cb_arg->skb,
			      NLBL_CIPSOV4_A_MTYPE,
			      doi_def->type);
	if (ret_val != 0)
		goto listall_cb_failure;

	genlmsg_end(cb_arg->skb, data);
	return 0;

listall_cb_failure:
	genlmsg_cancel(cb_arg->skb, data);
	return ret_val;
}

/**
 * netlbl_cipsov4_listall - Handle a LISTALL message
 * @skb: the NETLINK buffer
 * @cb: the NETLINK callback
 *
 * Description:
 * Process a user generated LISTALL message and respond accordingly.  Returns
 * zero on success and negative values on error.
 *
 */
static int netlbl_cipsov4_listall(struct sk_buff *skb,
				  struct netlink_callback *cb)
{
	struct netlbl_cipsov4_doiwalk_arg cb_arg;
	u32 doi_skip = cb->args[0];

	cb_arg.nl_cb = cb;
	cb_arg.skb = skb;
	cb_arg.seq = cb->nlh->nlmsg_seq;

	cipso_v4_doi_walk(&doi_skip, netlbl_cipsov4_listall_cb, &cb_arg);

	cb->args[0] = doi_skip;
	return skb->len;
}

/**
 * netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
 * @entry: LSM domain mapping entry
 * @arg: the netlbl_domhsh_walk_arg structure
 *
 * Description:
 * This function is intended for use by netlbl_cipsov4_remove() as the callback
 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
 * which are associated with the CIPSO DOI specified in @arg.  Returns zero on
 * success, negative values on failure.
 *
 */
static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
{
	struct netlbl_domhsh_walk_arg *cb_arg = arg;

	if (entry->def.type == NETLBL_NLTYPE_CIPSOV4 &&
	    entry->def.cipso->doi == cb_arg->doi)
		return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);

	return 0;
}

/**
 * netlbl_cipsov4_remove - Handle a REMOVE message
 * @skb: the NETLINK buffer
 * @info: the Generic NETLINK info block
 *
 * Description:
 * Process a user generated REMOVE message and respond accordingly.  Returns
 * zero on success, negative values on failure.
 *
 */
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{
	int ret_val = -EINVAL;
	struct netlbl_domhsh_walk_arg cb_arg;
	struct netlbl_audit audit_info;
	u32 skip_bkt = 0;
	u32 skip_chain = 0;

	if (!info->attrs[NLBL_CIPSOV4_A_DOI])
		return -EINVAL;

	netlbl_netlink_auditinfo(&audit_info);
	cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
	cb_arg.audit_info = &audit_info;
	ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
				     netlbl_cipsov4_remove_cb, &cb_arg);
	if (ret_val == 0 || ret_val == -ENOENT) {
		ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
		if (ret_val == 0)
			atomic_dec(&netlabel_mgmt_protocount);
	}

	return ret_val;
}

/*
 * NetLabel Generic NETLINK Command Definitions
 */

static const struct genl_small_ops netlbl_cipsov4_ops[] = {
	{
	.cmd = NLBL_CIPSOV4_C_ADD,
	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
	.flags = GENL_ADMIN_PERM,
	.doit = netlbl_cipsov4_add,
	.dumpit = NULL,
	},
	{
	.cmd = NLBL_CIPSOV4_C_REMOVE,
	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
	.flags = GENL_ADMIN_PERM,
	.doit = netlbl_cipsov4_remove,
	.dumpit = NULL,
	},
	{
	.cmd = NLBL_CIPSOV4_C_LIST,
	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
	.flags = 0,
	.doit = netlbl_cipsov4_list,
	.dumpit = NULL,
	},
	{
	.cmd = NLBL_CIPSOV4_C_LISTALL,
	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
	.flags = 0,
	.doit = NULL,
	.dumpit = netlbl_cipsov4_listall,
	},
};

static struct genl_family netlbl_cipsov4_gnl_family __ro_after_init = {
	.hdrsize = 0,
	.name = NETLBL_NLTYPE_CIPSOV4_NAME,
	.version = NETLBL_PROTO_VERSION,
	.maxattr = NLBL_CIPSOV4_A_MAX,
	.policy = netlbl_cipsov4_genl_policy,
	.module = THIS_MODULE,
	.small_ops = netlbl_cipsov4_ops,
	.n_small_ops = ARRAY_SIZE(netlbl_cipsov4_ops),
};

/*
 * NetLabel Generic NETLINK Protocol Functions
 */

/**
 * netlbl_cipsov4_genl_init - Register the CIPSOv4 NetLabel component
 *
 * Description:
 * Register the CIPSOv4 packet NetLabel component with the Generic NETLINK
 * mechanism.  Returns zero on success, negative values on failure.
 *
 */
int __init netlbl_cipsov4_genl_init(void)
{
	return genl_register_family(&netlbl_cipsov4_gnl_family);
}
